pyforestry.sweden.adapters package#
Submodules#
pyforestry.sweden.adapters.elfving_1982 module#
Hugin young-stand survey functions, Elfving (1982) Rapport 27.
This module provides: - Mean height / mean age functions for main saplings (Hugin height model). - Crop-tree probability (Hugin cleaning proxy). - NYSKOG reconstruction step functions for young-stand height distributions.
- class pyforestry.sweden.adapters.elfving_1982.HuginCropTreeProbability[source]#
Bases:
objectProbability that a tree remains after cleaning (Hugin crop tree proxy).
- static crop_tree_probability(*, height_m: float, mean_height_m: float, conifer_stems_per_100m2: float, rec_stems_per_ha: float, coniferous: bool) float[source]#
Compute crop-tree probability for a single tree.
- Parameters:
height_m (float) – Tree height in meters.
mean_height_m (float) – Mean height in meters.
conifer_stems_per_100m2 (float) – Conifer stems per 100 m2.
rec_stems_per_ha (float) – Recommended stems per ha after cleaning.
coniferous (bool) – Whether the tree is coniferous.
- Returns:
Probability in [0, 1].
- Return type:
float
- static probabilities_from_tree_list(trees: Sequence[Tree], *, rec_stems_per_ha: float, expansion_factor: float = 1.0) list[float][source]#
Compute crop-tree probabilities for a tree list.
- Parameters:
trees (Sequence[Tree]) – Trees with
height_mandweight_nset.rec_stems_per_ha (float) – Recommended stems/ha to remain after cleaning.
expansion_factor (float) – Factor to convert tree weights to per-ha stems.
- Returns:
Crop-tree probabilities, same order as input trees.
- Return type:
list[float]
- class pyforestry.sweden.adapters.elfving_1982.HuginMeanHeightModel[source]#
Bases:
objectMean height and mean age functions for main saplings (Hugin 1982).
- The model is defined as:
H = SI / (exp(Y) + 1) Y = b0 + b1 * ln(A) + b2 * ln(A)^2
where A is total age (years) and SI is species-specific site index (m).
- static mean_age(*, mean_height_m: float, species: TreeName, site_index_pine_m: float, site_index_spruce_m: float) float[source]#
Invert mean height to mean age (years).
- Parameters:
mean_height_m (float) – Mean height (m).
species (TreeName) – Tree species.
site_index_pine_m (float) – Pine site index (m).
site_index_spruce_m (float) – Spruce site index (m).
- Returns:
Mean age (years).
- Return type:
float
- static mean_height(*, age_years: float, species: TreeName, site_index_pine_m: float, site_index_spruce_m: float) float[source]#
Compute mean height (m) from total age and site indices.
- Parameters:
age_years (float) – Total age in years.
species (TreeName) – Tree species.
site_index_pine_m (float) – Pine site index (m).
site_index_spruce_m (float) – Spruce site index (m).
- Returns:
Mean height (m), truncated to >= 0.3.
- Return type:
float
- static site_index_for_species(species: TreeName, *, site_index_pine_m: float, site_index_spruce_m: float) float[source]#
Translate pine/spruce site indices to a species-specific site index.
- Parameters:
species (TreeName) – Tree species to translate.
site_index_pine_m (float) – Pine site index (m).
site_index_spruce_m (float) – Spruce site index (m).
- Returns:
Species-specific site index (m).
- Return type:
float
- class pyforestry.sweden.adapters.elfving_1982.NfiRegion(*values)[source]#
Bases:
EnumNFI region codes used in NYSKOG deciduous proportions.
- REG1 = 'Reg1'#
- REG21 = 'Reg21'#
- REG22 = 'Reg22'#
- REG3 = 'Reg3'#
- REG4 = 'Reg4'#
- REG5 = 'Reg5'#
- class pyforestry.sweden.adapters.elfving_1982.NyskogReconstruction[source]#
Bases:
objectStepwise NYSKOG reconstruction functions for young-stand states.
Step 3: Dominant conifer share.
- Parameters:
regeneration_type (RegenerationType) – Regeneration category.
qind (float) – Production potential indicator.
ln_si (float) – Log(site index).
wet (int) – Wet site indicator (0/1).
dry (int) – Dry site indicator (0/1).
rich (int) – Rich site indicator (0/1).
poor (int) – Poor site indicator (0/1).
hwod (int) – HWOD indicator (0/1).
hwd (int) – HWD indicator (0/1).
shrubs (int) – Shrubs indicator (0/1).
lichen (int) – Lichen indicator (0/1).
deterministic (bool) – If True, apply bias correction.
noise (float) – Stochastic noise multiplier.
- Returns:
Proportion of dominant conifer within conifers (0..1).
- Return type:
float
- static height_variation(*, species: TreeName, species_height_m: float, q: float, ln_q: float, self_rejuvenated: int, deterministic: bool = True, noise: float = 0.0, min_cv: float = 0.1, max_cv: float = 1.0) float[source]#
Step 4B: Height variation (CV).
- Parameters:
species (TreeName) – Species for CVH model.
species_height_m (float) – Mean height of species (m).
q (float) – Production potential Q.
ln_q (float) – Log(Q).
self_rejuvenated (int) – Self-rejuvenation indicator (0/1).
deterministic (bool) – If True, use deterministic output.
noise (float) – Stochastic noise multiplier.
min_cv (float) – Minimum CV bound.
max_cv (float) – Maximum CV bound.
- Returns:
Height variation (coefficient of variation).
- Return type:
float
- static production_potential_q(asinw: float) float[source]#
Compute production potential Q (0-100) from ASINW = arcsin(sqrt(W)).
Elfving (1982), the Hugin young-stand survey report. q = 100 * W with W = sin^2(asinw).
- Parameters:
asinw (float) – ASINW value (radians), = arcsin(sqrt(W)).
- Returns:
Production potential Q (0-100).
- Return type:
float
- static proportion_conifer(*, regeneration_type: RegenerationType, q: float, ln_qind: float, stem_total: float, ln_si: float, wet: int, dry: int, rich: int, poor: int, deterministic: bool = True, noise: float = 0.0) float[source]#
Step 2: Proportion conifer.
- Parameters:
regeneration_type (RegenerationType) – Regeneration category.
q (float) – Production potential Q.
ln_qind (float) – Log(Q) for indicator model.
stem_total (float) – Total stems per ha.
ln_si (float) – Log(site index).
wet (int) – Wet site indicator (0/1).
dry (int) – Dry site indicator (0/1).
rich (int) – Rich site indicator (0/1).
poor (int) – Poor site indicator (0/1).
deterministic (bool) – If True, apply bias correction.
noise (float) – Stochastic noise multiplier.
- Returns:
Proportion of conifer stems (0..1).
- Return type:
float
- static reconstruct_summary(*, asinw: float, mean_height_main_m: float, site_index_m: float, regeneration_type: RegenerationType, species_to_plant: TreeName, nfi_region: NfiRegion, field_layer: SwedenFieldLayer | None = None, soil_moisture: SwedenSoilMoisture | None = None, indicators: dict[str, int] | None = None, deterministic: bool = True, noise: float = 0.0, rng: float | None = None) NyskogReconstructionSummary[source]#
Run the full NYSKOG reconstruction workflow and return summary outputs.
- static secondary_mean_height(*, regeneration_type: RegenerationType, secondary_species: TreeName, site_index_m: float, mean_height_main_m: float, herb: int, dry: int, wet: int, deterministic: bool = True, noise: float = 0.0) float[source]#
Step 4A: Mean height for secondary species.
- Parameters:
regeneration_type (RegenerationType) – Regeneration category.
secondary_species (TreeName) – Species for the secondary cohort.
site_index_m (float) – Site index for the secondary species (m).
mean_height_main_m (float) – Mean height of main cohort (m).
herb (int) – Herb indicator (0/1).
dry (int) – Dry site indicator (0/1).
wet (int) – Wet site indicator (0/1).
deterministic (bool) – If True, apply bias correction.
noise (float) – Stochastic noise multiplier.
- Returns:
Mean height (m) of the secondary species.
- Return type:
float
- static stems_per_species(*, regeneration_type: RegenerationType, species_to_plant: TreeName, stem_total: float, prop_conifer: float, prop_dom_conifer: float, site_index_m: float, nfi_region: NfiRegion) dict[str, float][source]#
Step 3: Resolve stems per species group (pine/spruce/contorta/birch/other).
- Parameters:
regeneration_type (RegenerationType) – Regeneration category.
species_to_plant (TreeName) – Intended planted species.
stem_total (float) – Total stems per ha.
prop_conifer (float) – Proportion conifers (0..1).
prop_dom_conifer (float) – Proportion of dominant conifer (0..1).
site_index_m (float) – Site index for planted species (m).
nfi_region (NfiRegion) – NFI region for deciduous split.
- Returns:
Stems per species group (per ha).
- Return type:
dict[str, float]
- static total_stems(*, regeneration_type: RegenerationType, mean_height_main_m: float, q: float, ln_q: float, ln_si: float, under_dimension_prob: float, wet: int, dry: int, height_indicator_dm: float, deterministic: bool = True, noise: float = 0.0) float[source]#
Step 1: Total stems per ha.
- Parameters:
regeneration_type (RegenerationType) – Regeneration category.
mean_height_main_m (float) – Mean height of main saplings (m).
q (float) – Production potential Q.
ln_q (float) – Log(Q).
ln_si (float) – Log(site index).
under_dimension_prob (float) – Under-dimension probability (0..1).
wet (int) – Wet site indicator (0/1).
dry (int) – Dry site indicator (0/1).
height_indicator_dm (float) – HIND in decimetres (often max(15, 10*H)).
deterministic (bool) – If True, use bias-corrected estimate.
noise (float) – Stochastic noise multiplier.
- Returns:
Total stems per hectare.
- Return type:
float
- static udim_probability(q: float, *, deterministic: bool = True, rng: float | None = None) float[source]#
Probability/indicator for under-dimensioned trees.
- Parameters:
q (float) – Production potential Q.
deterministic (bool) – If True, return probability; otherwise return 0/1.
rng (float | None) – Optional random draw in [0, 1] for stochastic mode.
- Returns:
Probability or indicator for under-dimensioned trees.
- Return type:
float
- static weibull_parameters(*, species: TreeName, cvh: float, mean_height_m: float) tuple[float, float][source]#
Step 5: Weibull scale (beta) and shape (lambda).
- Parameters:
species (TreeName) – Species for Weibull parameters.
cvh (float) – Height variation (CV).
mean_height_m (float) – Mean height (m).
- Returns:
(beta, lambda) parameters.
- Return type:
tuple[float, float]
- static young_stand_quality_asinw(*, stocking_arcsine_radians: float, regeneration_type: RegenerationType, latitude_deg: float | None = None) float[source]#
Young-stand quality ASINW = arcsin(sqrt(W)) from regeneration stocking.
- Reference:
Elfving, B. (1982). Hugins ungskogstaxering 1976-1979. SLU, Projekt Hugin, Rapport 27. The young-stand quality W is a deterministic function of the arcsine- transformed regeneration stocking (SLH); the returned ASINW feeds
production_potential_q()(q = 100*sin^2(asinw)). Cultivations carry a latitude dummy -0.031*NS (NS = latitude > 60 N).
- Parameters:
stocking_arcsine_radians (float) – SLH linear predictor (= 2*asinslh).
regeneration_type (RegenerationType) – Natural/extensive vs cultivation.
latitude_deg (float | None) – Latitude for the NS dummy (cultivation only).
- Returns:
ASINW value (radians).
- Return type:
float
- class pyforestry.sweden.adapters.elfving_1982.NyskogReconstructionSummary(q: float, qind: float, udim: float, stem_total: float, prop_conifer: float, prop_dom_conifer: float, stems_per_species: dict[str, float], mean_heights_m: dict[str, float], cvh: dict[str, float], weibull_params: dict[str, tuple[float, float]], main_species_key: str)[source]#
Bases:
objectSummary outputs from the NYSKOG reconstruction workflow.
- class pyforestry.sweden.adapters.elfving_1982.RegenerationType(*values)[source]#
Bases:
EnumRegeneration type categories used in Hugin/NYSKOG functions.
- CONTORTA_PLANTATION = 'contorta_plantation'#
- DECIDUOUS_PLANTATION = 'deciduous_plantation'#
- EXTENSIVE = 'extensive'#
- NATURAL = 'natural_regeneration'#
- PINE_PLANTATION = 'pine_plantation'#
- SOWN = 'sown'#
- SPRUCE_PLANTATION = 'spruce_plantation'#
- pyforestry.sweden.adapters.elfving_1982.nyskog_indicators_from_site(*, field_layer: SwedenFieldLayer | None, soil_moisture: SwedenSoilMoisture | None) dict[str, int][source]#
Backward-compatible typed wrapper delegating to extracted formulas.
pyforestry.sweden.adapters.elfving_2010 module#
Elfving tree and stand growth models for Sweden.
- This module implements two published functions:
Single-tree diameter increment (Elfving 2010, tracing to Elfving 2003).
Stand-level basal-area growth and calibration (Elfving 2009).
Notes
Diameter inputs/outputs are in centimeters. Basal area is in m²/ha at stand scale.
Growth functions are calibrated for 5-year periods. We scale linearly when
dt != 5.The published pine equation applies the rich-vegetation term additively, and we follow the published form. An inconsistency in one downstream implementation would instead fold that term into the fertilisation term, which we do not reproduce.
- class pyforestry.sweden.adapters.elfving_2010.Elfving2010Config(include_thinning_effect: bool = True, stand_growth_min_diameter_cm: float = 10.0, site_index_adjustment_factor: float = 1.0, use_edge_effects: bool = False, max_mean_dgv_cm: float = 70.0, max_bal_over_dbh: float = 3.0)[source]#
Bases:
objectConfiguration for Elfving 2010 growth model.
- include_thinning_effect: bool = True#
- max_bal_over_dbh: float = 3.0#
- max_mean_dgv_cm: float = 70.0#
- site_index_adjustment_factor: float = 1.0#
- stand_growth_min_diameter_cm: float = 10.0#
- use_edge_effects: bool = False#
- class pyforestry.sweden.adapters.elfving_2010.Elfving2010Inputs(site_index_m: float, temperature_sum_dd: float, latitude_deg: float, altitude_m: float, distance_to_coast_km: float, dominant_species: TreeName | None = None, field_estimated_basal_area_m2_ha: float | None = None, is_split_plot: bool = False, is_edge_plot: bool = False, thinned_0_10_years: bool = False, thinned_11_25_years: bool = False, thinned_11_30_years: bool = False)[source]#
Bases:
objectWhat the Elfving functions need to know about the site, resolved once.
These are facts about where the stand is, not about what has happened to it during a run: latitude does not change because five years passed. They are read at
Elfving2010Model.build_context()from the stand’sSwedishSitewhere it carries them typed, and fromctx.attrswhere it does not.Units are in the field names because the equations are unit-specific and the names are the only place a caller sees them: metres, degree-days, decimal degrees, metres above sea level, kilometres, m²/ha.
Deliberately not here:
thinning_simulated,thinning_historyandfertilized_remaining_years. A thinning or a fertilisation performed during the run changes those, and a model that had frozen them at build time would stop responding to its own management.thinned_0_10_yearsandthinned_11_30_yearsdo belong here – they describe the stand’s history before the run, which is an input.- field_estimated_basal_area_m2_ha: float | None = None#
- is_edge_plot: bool = False#
- is_split_plot: bool = False#
- thinned_0_10_years: bool = False#
- thinned_11_25_years: bool = False#
- thinned_11_30_years: bool = False#
- class pyforestry.sweden.adapters.elfving_2010.Elfving2010Model(config: Elfving2010Config | None = None)[source]#
Bases:
GrowthModelSimulation adapter for the Elfving 2010 tree + stand growth model.
- Inputs#
alias of
Elfving2010Inputs
- property component_id: str#
Stable identifier for the Elfving 2010 growth model.
- requirements() Requirements[source]#
Declare that this model accepts either inventory mode and needs site data.
- resolve_inputs(ctx: SimulationContext) Elfving2010Inputs[source]#
Read the site inputs once, at build time, instead of once per kernel call.
Every value here used to be re-read from
ctx.attrson each step, with a default supplied at the point of use – so an absent temperature sum surfaced as aValueErrorfrom inside a growth kernel, and a mistypedlatitiude_degwas indistinguishable from a site that had none. Now a missing required input fails here, named, before any growth is computed.Site index is resolved from the stand as it stands at build time. Where neither
attrsnor a dominant species determines it, the fallback picks between the site’s pine and spruce indices by which group carries more basal area; resolving that once means a projection keeps the site quality it started with, rather than switching curves partway through because the mixture drifted. Site index is a property of the site, not of the crop standing on it.- Raises:
ValueError – If temperature sum, latitude/altitude or site index cannot be resolved.
- property source: SourceReference#
Bibliographic provenance for the Elfving growth model.
- update_step(ctx: SimulationContext, dt: float) None[source]#
Advance one simulation step and route to tree-list or aggregate update.
pyforestry.sweden.adapters.soderberg_1986_growth module#
Soderberg (1986) single-tree diameter growth model for Sweden.
This module implements Söderberg’s single-tree diameter growth functions at tree level for 5-year growth periods.
- Primary reference:
Söderberg, U. (1986). Report 14, SLU, Umeå (Appendix 4 and related growth notes).
- class pyforestry.sweden.adapters.soderberg_1986_growth.Soderberg1986Config(include_thinning_effect: bool = True)[source]#
Bases:
objectConfiguration options for
Soderberg1986Model.- Variables:
include_thinning_effect (bool) – If
True, apply Söderberg’s thinning-response terms (the thinned 0-5 yr / 6-25 yr state indicators in the published diameter-growth functions). When thinning is simulated in this period, the thinning-history indicators are ignored for this step.
- include_thinning_effect: bool = True#
- class pyforestry.sweden.adapters.soderberg_1986_growth.Soderberg1986Model(config: Soderberg1986Config | None = None)[source]#
Bases:
GrowthModelSimulation-engine adapter for the Söderberg (1986) diameter-growth equations.
- property component_id: str#
Stable identifier for the Soderberg 1986 growth model.
- requirements() Requirements[source]#
Return model inventory/site requirements.
- property source: SourceReference#
Bibliographic provenance for the Soderberg 1986 growth model.
- update_step(ctx: SimulationContext, dt: float) None[source]#
Update one simulation step for tree-list or spatial contexts.
Module contents#
Runtime bindings for Swedish equations — glue, not science.
An adapter’s job is to make published equations runnable: read what a model
needs off a Stand, call the equation
kernels that live in the domain packages (sweden/growth, sweden/height,
sweden/volume, sweden/regeneration, …), and write the results back
through the simulation contract. That is the whole remit.
The line this package draws is enforceable rather than aspirational: an
adapter carries no scientific coefficient literals. If a number here has more
than a couple of decimals and is not a unit factor, it is a fitted coefficient
that has escaped its publication, and AL001 in
scripts/check_architecture_lint.py will say so. Whole published growth-and-
yield systems, which do own their coefficients, live one directory over in
pyforestry.sweden.systems.
So: to check a number against a paper, open systems/ or a domain package.
To check how a model is driven, open this one.