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: object

One 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.

rate_for(unit_system)[source]
unit_for(unit_system)[source]
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.xlsx of 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: object

Cost, 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.

  • rates (tuple) – percentage rates. Defaults to RATES.

  • 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:
Returns:

the quantities set, for inspection.

Return type:

dict

costs()[source]

The bill of quantities, its group subtotals, and the applied rates.

Returns:

lines, groups, construction, applied and total.

Return type:

dict

static habitat_gain(before, after)[source]

Net gain in seasonal habitat area between two conditions.

Parameters:
Returns:

before, after, gain and relative (the gain as a fraction of the existing habitat).

Return type:

dict

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:

dict

write_report(result, output_dir)[source]

Write the bill of quantities as CSV.

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_length defined name of its workbook and used it to turn a mapped area into a count of logs, assuming each occupies log_length squared. It is the only way an area-based feature map can price a per-piece item, and it is an assumption worth stating.