pyforestry.base.pricelist package#
Submodules#
pyforestry.base.pricelist.pricelist module#
Pricelist utilities and interfaces.
A price list is where a projection’s money comes from, so it carries a
PricelistIdentity – a name, the currency its prices are quoted in, and
who published it – alongside the prices themselves. That is what lets a run
manifest state what its revenue figures are in and which list produced them,
rather than leaving two runs’ money columns indistinguishable.
- class pyforestry.base.pricelist.pricelist.DiameterRange(Min: float, Max: float)[source]#
Bases:
objectThe inclusive top-diameter span, in cm, over which an assortment is priced.
- class pyforestry.base.pricelist.pricelist.LengthCorrections(corrections: Dict[int, Dict[int, int]] | None = None)[source]#
Bases:
objectHolds logic for how the length modifies price (absolute or percent).
Now accepts a dictionary of corrections in the form:
{diameter: {length: correction_percentage, ...}, ...}
- class pyforestry.base.pricelist.pricelist.LengthRange(Min: float, Max: float)[source]#
Bases:
objectThe inclusive log-length span, in metres, an assortment accepts.
Metres because that is what every price list in this package states and what the only consumer reads:
Nasberg_1985_BranchBoundconverts these to decimetres by multiplying by ten. This docstring used to say decimetres and thePricelistdefaults were written as decimetres –LengthRange(30, 50)– which the bucker then read as thirty to fifty metres, so no log a Swedish forest grows could satisfy them.
- class pyforestry.base.pricelist.pricelist.Pricelist(*, identity: PricelistIdentity | None = None)[source]#
Bases:
objectHolds the combined pulpwood, timber, etc. prices and constraints.
Alongside the prices it carries its
PricelistIdentity: what the list is called, what money its prices are in, and who published it. Every monetary figure a projection reports comes from here, so a run that records what it earned records that too.- get_pulpwood_fuelwood_proportion(species: str | TreeName) float[source]#
Proportion (0-1) of a pulpwood log downgraded to fuelwood.
Placeholder returning
0.0(no downgrade); override per species as needed. Seeget_pulpwood_waste_proportion().
- get_pulpwood_waste_proportion(species: str | TreeName) float[source]#
Proportion (0-1) of a pulpwood log downgraded to waste/harvest residue.
Placeholder returning
0.0(no downgrade), mirroring the timber-sideTimberPricelist.get_timber_weight()hook. Consumed by the pulp branch of the Näsberg (1985) bucking optimiser whenBuckingConfig.use_downgradingis set; override per species once real downgrade data is available.
- class pyforestry.base.pricelist.pricelist.PricelistIdentity(name: str, currency: str, source: SourceReference)[source]#
Bases:
objectWhich price list a figure of money came from, and what money it is in.
A price list is what turns a volume into a sum, so every monetary figure a run reports is a figure in this list’s currency, against this list’s prices. Two runs’ revenues are comparable only under the same list, which is why a run that reports money records this:
run_scenario()writes it into its manifest’svaluationblock.- Parameters:
name – What the list is called, e.g.
"Mellanskog 2013".currency – The currency its prices are quoted in, e.g.
"SEK". Per cubic metre; which volume basis is each timber table’s own business, declared inTimberPricelist.volume_type, so it is not repeated here.source – Who published it, and when. A price list is regional market data with a publisher and a year, so this is a genuine citation rather than a stated choice – and a table assembled by whoever ran the model says so through the
(none)/year-0 sentinel thatUNATTRIBUTED_PRICELIST_IDENTITYcarries.
- Raises:
ValueError – If the name or the currency is blank. An unnamed list is a real state, and
UNATTRIBUTED_PRICELIST_IDENTITYnames itself as one; an empty string in a manifest names nothing.
- property is_cited: bool#
Whether this list traces to a publisher rather than to whoever ran the model.
- class pyforestry.base.pricelist.pricelist.PulpPricelist[source]#
Bases:
objectPlaceholder for pulp prices per species.
- class pyforestry.base.pricelist.pricelist.TimberPriceForDiameter(butt_price: float, middle_price: float, top_price: float)[source]#
Bases:
objectRepresents the set of prices for a given diameter, for each log part type. E.g. an entry might store: PriceButt, PriceMiddle, PriceTop, …
- class pyforestry.base.pricelist.pricelist.TimberPricelist(min_diameter: int, max_diameter: int, volume_type: str = 'm3to')[source]#
Bases:
objectStores the entire set of timber prices by diameter class, etc.
- class LogParts(*values)[source]#
Bases:
IntEnumWhere along the stem a log came from, which is what it is priced by.
A butt log, a middle log and a top log of the same dimensions fetch different prices, so every price lookup is keyed by this alongside the diameter class. The integer values are the column order the price tables use.
- Butt = 0#
- Middle = 1#
- Top = 2#
- get_nearest_diameter_class(diameter_cm: float) int[source]#
Returns the closest available diameter class (floored down to available class). If the requested diameter is smaller than
min, returnsmin. If larger thanmax, returnsmax.
- get_timber_weight(log_part: LogParts)[source]#
If you’re applying downgrading or certain proportions for pulp/fuel/cull, this returns an object with attributes like
.PulpwoodPercentage,.FuelWoodPercentageand.LogCullPercentage. This is a placeholder.
- price_for_log_part(log_part: LogParts, diameter_cm: float) float[source]#
Get the price for a given log part (Butt, Middle, Top) at a given diameter (cm). Rounds or floors the diameter to the nearest available diameter class.
- set_price_for_diameter(diameter: int, price_struct: TimberPriceForDiameter)[source]#
Store a price entry for a certain diameter class.
- pyforestry.base.pricelist.pricelist.UNATTRIBUTED_PRICELIST_IDENTITY = PricelistIdentity(name='(unnamed price list)', currency='(unspecified)', source=SourceReference(author='(none)', year=0, title='Prices supplied by whoever configured the run', appendix='', note="No publisher named, so the figures this list produces are the caller's own. year=0 is a sentinel for 'not applicable', not a citation date."))#
What a price list carries when nobody has said whose it is – a hand-built table in a test, or a caller’s own figures. It is a real state rather than a missing one, so it is named: a run manifest reporting money against this says plainly that the prices are the analyst’s, which is what keeps it apart from a run priced against a published list. The
(none)/year-0 form is the one the rest of the package uses for anything authored rather than published.
- pyforestry.base.pricelist.pricelist.create_pricelist_from_data(price_data: dict, species_to_load: str | Sequence[str] | None = None, *, identity: PricelistIdentity | None = None) Pricelist[source]#
Build a Pricelist from a dictionary.
- Parameters:
price_data (dict) – The complete price dictionary (must contain the ‘Common’ block).
species_to_load (str | Sequence[str] | None, default None) –
None - load all species that have timber price tables.
str - load just that species.
iterable - load every species in the iterable; it is not an error if some of them have only pulp prices.
identity (PricelistIdentity | None, default None) – Which list this data is, what currency it is in, and who published it. A run manifest records it, so pass it whenever the figures will be reported: the shipped example data publishes its own alongside the prices (see
MELLANSKOG_2013_IDENTITY). It is deliberately not read out ofprice_data, which is hashed as-is to validate aSolutionCubeagainst the prices it was built from. Defaults to UNATTRIBUTED_PRICELIST_IDENTITY.
- Returns:
A fully populated Pricelist instance.
- Return type:
pyforestry.base.pricelist.solutioncube module#
Utilities for generating and querying precomputed bucking solutions.
- class pyforestry.base.pricelist.solutioncube.SolutionCube(dataset: Dataset)[source]#
Bases:
objectContainer for precomputed bucking solutions.
- classmethod generate(pricelist_data: ~typing.Dict[str, ~typing.Any], taper_model: ~typing.Type[~pyforestry.base.taper.taper.Taper], species_list: list[str], dbh_range: ~typing.Tuple[float, float], height_range: ~typing.Tuple[float, float], dbh_step: int = 2, height_step: float = 0.2, timber_class: ~typing.Type[~pyforestry.base.timber.timber_base.timber.Timber] = <class 'pyforestry.base.timber.timber_base.timber.Timber'>, workers: int = -1)[source]#
Generates the solution cube by running the optimizer in parallel.
- classmethod load(path: str, pricelist_to_verify: Dict | None = None)[source]#
Loads a solution cube from a netCDF file.
- lookup(species: str, dbh: float, height: float) Tuple[float, list][source]#
Performs a fast lookup for a given tree’s properties. Uses nearest-neighbor interpolation.
Module contents#
Public API for pricelist utilities.