riverarchitect.projectmaker
Project Maker: what a design costs, and what it buys in habitat.
The open-source replacement for the ArcGIS ProjectMaker module. It is the last step of
the chain and the only one that produces a number a funding body recognises: the cost of the
works, the gain in seasonal habitat area, and the ratio between them.
The two halves
Cost is a bill of quantities. Every task in COST_ITEMS carries a unit rate; the
quantity comes from what the earlier modules mapped - the per-feature areas of
riverarchitect.maxlifespan.MaxLifespan, the excavation volume of
riverarchitect.terraforming.Terraforming. Percentage rates for mobilisation,
contingency, markups and permitting are applied on top, in that order, as the original’s
workbook did.
Benefit is the difference in SHArea between two conditions - the existing state and the
state with the project built - for one species and lifestage. Both come from
riverarchitect.sharc.SHArC.run(), so the comparison is like for like.
Their ratio, cost per unit of habitat gained, is the metric that lets two designs be compared when one is cheap and small and the other expensive and large.
Relation to the original
The original kept the unit rates in a binary workbook of cross-sheet formulas
(Project_assessment_vii.xlsx), pulled quantities from a second sheet that a separate
arcpy step filled in, and computed the total with Excel. The rates are Python here, so a
change to them shows up in review, and the arithmetic is explicit rather than hidden in cell
references. The rates themselves are the workbook’s, unchanged; several were averages of a
range, and those are recorded as the average with the range in the note.
- class riverarchitect.projectmaker.CostItem(key, group, task, rate, unit, source='', note='')[source]
Bases:
objectOne line of the bill of quantities.
- Parameters:
key (str) – short identifier, used to supply a quantity.
group (str) – the section it sums into.
task (str) – what the money buys.
rate (dict) –
{"us": float, "si": float}unit rate in US dollars.unit (dict) –
{"us": str, "si": str}the unit the rate is per.source (str) – where the quantity comes from by default, or “” when it must be given.
note (str) – provenance of the rate, e.g. the range it averages.
- riverarchitect.projectmaker.COST_ITEMS = (CostItem('clearing', 'Clearing (vegetation)'), CostItem('earthworks', 'Excavate/fill alluvial material (incl. transport)'), CostItem('groin_cavities', 'Groin cavities'), CostItem('log_anchoring', 'Anchoring (logs for plant stability)'), CostItem('log_jam', 'Engineered log jam, log-wise'), CostItem('root_wad', 'Engineered log jam, root-wise'), CostItem('streamwood', 'Streamwood (non-anchored)'), CostItem('boulders', 'Angular boulder placement (instream)'), CostItem('ball_method', 'Ball method (small trees)'), CostItem('container_trees', 'Container trees'), CostItem('pod_cottonwood', 'Pod method (Cottonwood)'), CostItem('pod_willow', 'Pod method (Willow)'), CostItem('stinger_cottonwood', 'Stinger method (Cottonwood)'), CostItem('stinger_willow', 'Stinger method (Willow)'), CostItem('box_elder', 'Other planting methods (Box Elder)'), CostItem('white_alder', 'Other planting methods (White Alder)'), CostItem('fascine', 'Fascine'), CostItem('fascine_slopes', 'Fascine on slopes'), CostItem('geotextile', 'Geotextile'), CostItem('brush_layers', 'Lateral brush layers (ramified willow branches)'), CostItem('rock_paving', 'Rock paving / layering (individually placed rocks)'), CostItem('fine_sediment', 'Fine sediment'), CostItem('gravel', 'Gravel (spawning substrate)'), CostItem('culvert_concrete', 'Culvert: concrete PC 300'), CostItem('culvert_steel', 'Culvert: reinforcement steel'), CostItem('road_existing', 'Roads: develop existing'), CostItem('road_new_easy', 'Roads: new (easy terrain)'), CostItem('road_new_complex', 'Roads: new (complex terrain)'), CostItem('bridge_new', 'Roads: new bridge'), CostItem('bridge_reinforce', 'Roads: reinforce existing bridge'), CostItem('land', 'Terrain acquisition'))
Unit rates, reproducing
Project_assessment_vii.xlsxof the original. US dollars. Kept as Python rather than a workbook so a change to a rate is reviewable.
- riverarchitect.projectmaker.RATES = (('mobilisation', 'Site (de-)mobilization', 0.1), ('contingency', 'Unexpected', 0.1), ('markups', 'Markups (overhead, profit, insurance)', 0.165), ('permitting', 'Permitting', 0.35))
Percentage rates applied to the construction subtotal, in the order the workbook applies them: each is a fraction of the running total before it.
- class riverarchitect.projectmaker.ProjectMaker(name='project', unit='us', quantities=None, rates=(('mobilisation', 'Site (de-)mobilization', 0.1), ('contingency', 'Unexpected', 0.1), ('markups', 'Markups (overhead, profit, insurance)', 0.165), ('permitting', 'Permitting', 0.35)), log_length=25.0)[source]
Bases:
objectCost, habitat gain, and the ratio between them.
- Parameters:
name (str) – project name, used for the output folder.
unit (str) –
"us"or"si"; selects the rate column and the units it is per.quantities (dict) –
{item key: quantity}in the unit each item is priced per. Anything not given is zero, so a partial bill still totals.log_length (float) – length of one log, for turning a mapped area into a count of pieces. See
LOG_LENGTH.
- Variables:
error (bool) – True when something could not be quantified.
- quantities_from_lifespan(summary, terraforming=None, project_area=None)[source]
Fill the quantities from what the earlier modules reported.
- Parameters:
summary (dict or list) – the result of
riverarchitect.maxlifespan.MaxLifespan.run(), or itsfeatureslist. Each feature’s area is matched to the cost item that names it as its source.terraforming (dict) – the result of
riverarchitect.terraforming.Terraforming.run(), for the earthworks volume and the area cleared.project_area (float) – total area acquired, in the area unit of the condition.
- Returns:
the quantities set, for inspection.
- Return type:
- costs()[source]
The bill of quantities, its group subtotals, and the applied rates.
- Returns:
lines,groups,construction,appliedandtotal.- Return type:
- static habitat_gain(before, after)[source]
Net gain in seasonal habitat area between two conditions.
- Parameters:
before (dict or float) – the existing condition’s
riverarchitect.sharc.SHArC.run()result, or its SHArea directly.after (dict or float) – the with-project condition, likewise.
- Returns:
before,after,gainandrelative(the gain as a fraction of the existing habitat).- Return type:
- Raises:
ValueError – when a result carries no
sharea- which means its condition had no flow duration curve, and the two numbers would not be comparable.
- run(before=None, after=None, output_dir=None, write_report=True)[source]
Cost the works, compare the habitat, and report the trade-off.
- Parameters:
before (dict or float) – the two SHArC results, or their SHArea values. Omit both to cost the works without a benefit.
after (dict or float) – the two SHArC results, or their SHArea values. Omit both to cost the works without a benefit.
output_dir (str) – where the report goes.
write_report (bool) – write a CSV bill of quantities.
- Returns:
the costs, the habitat gain, and the cost per unit of habitat gained.
- Return type:
- riverarchitect.projectmaker.cost_items(group=None)[source]
The cost items, optionally restricted to one group.
- riverarchitect.projectmaker.FT2_PER_ACRE = 43560.0
Square feet per acre, and cubic feet per cubic yard - the units the U.S. rates are per.
- riverarchitect.projectmaker.LOG_LENGTH = 25.0
Length of one log, in the project’s length unit. The original carried it as the
log_lengthdefined name of its workbook and used it to turn a mapped area into a count of logs, assuming each occupieslog_lengthsquared. It is the only way an area-based feature map can price a per-piece item, and it is an assumption worth stating.