pyforestry.norway.growth package#

Submodules#

pyforestry.norway.growth.allen_2020 module#

Allen et al. (2020) stand-level growth & yield model for Norway spruce.

Implements the whole-stand growth-and-yield system of

Allen, M.G. II, Anton-Fernandez, C. & Astrup, R. (2020). “A stand-level growth and yield model for thinned and unthinned managed Norway spruce forests in Norway.” Scandinavian Journal of Forest Research 35(5-6):238-251. DOI 10.1080/02827581.2020.1773525.

Coefficients are from the paper’s Table 4. The equation forms were cross-checked against the authors’ own reference implementation (R package mickyallen10/sprucesim); that package is an indication only – the paper is the source of record.

Single species: Norway spruce (Picea abies). Stand age A is age FROM PLANTING (total age); site index S is dominant height (m) at base age 40 years.

The dominant-height projection (Eq. 4) uses the exponent (b2 + b3)/X0 exactly as published in Allen et al. (2020) and as coded in the authors’ sprucesim R package.

pyforestry.norway.growth.allen_2020.allen_2020_basal_area(basal_area1: StandBasalArea | float, age1: AgeMeasurement, age2: AgeMeasurement, dominant_height1: float, dominant_height2: float, stems1: Stems | float, stems2: Stems | float, *, thinning_quotient: float = 1.0, height_at_thinning: float | None = None) → StandBasalArea[source]#

Project basal area (m2/ha). Allen et al. (2020) Eq. (2).

G2 = G1^(H1/H2) * exp[ b1 * (N2/N1)^b2 * (1 - H1/H2) * TR ] TR = (GA/GB)^( b3 * HT/H2 ) (thinning response; TR = 1 unthinned)

Per Eq. (2) the thinning response TR sits INSIDE the exponential, scaling the whole exponent argument – not as a factor on G2 outside the exp. b1 is the single linear multiplier and b2 is the EXPONENT on the density ratio N2/N1 (contrast with the mis-typeset Maleki et al. 2022 variant). Pass the observed/projected dominant heights explicitly. For an unthinned period leave thinning_quotient=1.0 / height_at_thinning=None.

pyforestry.norway.growth.allen_2020.allen_2020_basal_area_after_thinning_ratio(stem_quotient: float) → float[source]#

Basal-area-after / before ratio (GA/GB). Allen et al. (2020) Eq. (5b).

GA/GB = ( log(NA/NB) - b1 ) / b2

Algebraic inverse of allen_2020_stems_after_thinning_ratio(); use to convert a specified stem removal into the corresponding basal-area removal.

pyforestry.norway.growth.allen_2020.allen_2020_dominant_height(dominant_height_m: float, age1: AgeMeasurement, age2: AgeMeasurement) → float[source]#

Project Norway spruce dominant height (m) from age1 to age2.

Allen et al. (2020) Eq. (4), GADA Chapman-Richards (Cieszewski & Bailey 2000):

L = ln(1 - exp(-b1 * A1)) X0 = 0.5 * ( ln(H1) + b2*L + sqrt( (ln(H1) + b2*L)^2 - 4*b3*L ) ) H2 = H1 * [ (1 - exp(-b1*A2)) / (1 - exp(-b1*A1)) ] ^ ( (b2 + b3)/X0 )

pyforestry.norway.growth.allen_2020.allen_2020_quadratic_mean_diameter(basal_area: StandBasalArea | float, stems: Stems | float) → QuadraticMeanDiameter[source]#

Return quadratic mean diameter (cm) from basal area and stem number.

QMD = 200 * sqrt( G / (pi * N) ) (G in m2/ha, N in stems/ha)

pyforestry.norway.growth.allen_2020.allen_2020_site_index(dominant_height_m: float, age: AgeMeasurement) → SiteIndexValue[source]#

Return site index (dominant height at base age 40 yr) as a SiteIndexValue.

pyforestry.norway.growth.allen_2020.allen_2020_stand_volume(basal_area2: StandBasalArea | float, dominant_height2: float, age2: AgeMeasurement) → StandVolume[source]#

Return stand volume (m3/ha). Allen et al. (2020) Eq. (1).

V2 = b1 * G2^b2 * H2^b3 * exp( b4 / A2 )

Total stem volume base data from Vestjordet (1967). Single equation for thinned and unthinned stands.

pyforestry.norway.growth.allen_2020.allen_2020_stem_survival(stems1: Stems | float, age1: AgeMeasurement, age2: AgeMeasurement, si_h40: SiteIndexValue | float, *, thinning_quotient: float = 1.0) → Stems[source]#

Project surviving stems per hectare. Allen et al. (2020) Eq. (3).

N2 = ( N1^b1 + b2 * (GA/GB) * (S/1000)^b3 * (A2^b4 - A1^b4) )^(1/b5)

thinning_quotient is the basal-area thinning quotient GA/GB (= 1.0 for an unthinned period); thinning (GA/GB < 1) reduces the additive mortality term.

pyforestry.norway.growth.allen_2020.allen_2020_stems_after_thinning_ratio(basal_area_quotient: float) → float[source]#

Trees-after / trees-before ratio (NA/NB). Allen et al. (2020) Eq. (5a).

NA/NB = exp( b1 + b2 * (GA/GB) )

basal_area_quotient is GA/GB (basal area after / before thinning). Use to convert a specified basal-area removal into the corresponding stem removal under the paper’s thinning-from-below assumption.

pyforestry.norway.growth.bollandsas_2008 module#

Bollandsås size-class matrix model for mixed stands in Norway.

Implements the transition-matrix model of Bollandsås, Buongiorno & Gobakken (2008), Scand. J. For. Res. 23(2):167-178. All coefficients are taken from that paper and verified term-by-term against its published tables: recruitment probability (Table V, eq. 4), conditional recruits (Table VI, eq. 5), diameter increment (Table VII) and mortality (Table VIII).

class pyforestry.norway.growth.bollandsas_2008.Bollandsas2008(site_index_by_species: Mapping[str, float], latitude_deg: float, *, n_classes: int = 15, class_width_mm: float = 50.0)[source]#

Bases: object

Size-class stand model with recruitment, increment, and mortality.

SPECIES: tuple[str, ...] = ('spruce', 'pine', 'birch', 'other_broadleaves')#
compute_stand_basal_area_by_species(state: Mapping[str, ndarray]) → dict[str, StandBasalArea][source]#

Compute stand basal area (m2/ha) for each model species group.

static logistic(x: float) → float[source]#

Return numerically stable logistic transform.

simulate_years(state0: Mapping[str, ndarray], years: int, harvest_schedule: Mapping[int, Mapping[str, ndarray]] | None = None) → list[dict[str, ndarray]][source]#

Simulate a stand trajectory in 5-year steps.

stand_to_state(stand: Stand) → dict[str, ndarray][source]#

Bin tree-list plot data into model diameter classes (stems/ha).

step_5y(state: Mapping[str, ndarray], harvest_by_species: Mapping[str, ndarray] | None = None) → dict[str, ndarray][source]#

Run one 5-year transition step with optional class-wise harvest.

pyforestry.norway.growth.kuehne_2022 module#

Kuehne et al. (2022) stand-level growth & yield kernels for Scots pine, Norway.

Implements the stem-density, basal-area, volume and thinning-reduction component equations (Eqs. 6-10) of

Kuehne, C., McLean, J.P., Maleki, K., Anton-Fernandez, C. & Astrup, R. (2022). “A stand-level growth and yield model for thinned and unthinned even-aged Scots pine forests in Norway.” Silva Fennica 56(1) article id 10627. DOI 10.14214/sf.10627.

The dominant-height / site-index component (Eq. 5) lives in pyforestry.norway.siteindex.kuehne_2022. Coefficients are Table 3 of the paper (columns TPH2, BA2, VOL2, TPHAFTER/TPHBEFORE). Equation forms were read directly from the published equations (Eqs. 6-10); the authors’ forester R package agrees except for a linear AGE2*b4 - AGE1*b4 in stem density, which the paper writes as the power form AGE2^b4 - AGE1^b4 (used here).

Single species: Scots pine (Pinus sylvestris). Ages are TOTAL age; si40 is site index (dominant height, m) at base age 40. Thinning enters via the basal- area thinning quotient BA_AFTER/BA_BEFORE (= 1.0 for an unthinned period).

pyforestry.norway.growth.kuehne_2022.kuehne_2022_basal_area(basal_area1: StandBasalArea | float, age1: AgeMeasurement, age2: AgeMeasurement, dominant_height1: float, dominant_height2: float, stems1: Stems | float, stems2: Stems | float, *, thinning_quotient: float = 1.0, age_thin: float | None = None) → StandBasalArea[source]#

Project total basal area (m2/ha). Kuehne et al. (2022) Eq. (7).

BA2 = exp[ (A1/A2)*ln(BA1) + b1*(1 - A1/A2)
  • b2*(ln(H2) - (A1/A2)*ln(H1))

  • b3*(ln(TPH2) - (A1/A2)*ln(TPH1))

  • b4*((ln(TPH2) - ln(TPH1))/A2)

  • b5*((BA_rem/BA_before / AGE_thin)*(1/A2 - 1/A1)) ]

Modified Brooks (1992) ADA form with a thinning modifier. thinning_quotient is BA_AFTER/BA_BEFORE (so BA_rem/BA_before = 1 - thinning_quotient); age_thin is the total stand age at thinning. The b5 term vanishes for an unthinned period (thinning_quotient = 1.0 or age_thin = None).

pyforestry.norway.growth.kuehne_2022.kuehne_2022_basal_area_after_thinning_ratio(stem_quotient: float) → float[source]#

Basal-area-after / before ratio. Kuehne et al. (2022) Eq. (10).

BA_after/BA_before = ( ln(TPH_after/TPH_before) - b1 ) / b2

Algebraic inverse of kuehne_2022_stems_after_thinning_ratio().

pyforestry.norway.growth.kuehne_2022.kuehne_2022_stand_volume(basal_area2: StandBasalArea | float, dominant_height2: float, age2: AgeMeasurement, *, thinning_quotient: float = 1.0, age_thin: float | None = None) → StandVolume[source]#

Return total stem volume (m3/ha). Kuehne et al. (2022) Eq. (8).

VOL2 = b1 * BA2^b2 * HTDOM2^b3 * exp(b4/A2)
  • (BA_after/BA_before)^( b5 * (AGE_thin/A2) )

The thinning factor is 1.0 for an unthinned period (thinning_quotient = 1.0 or age_thin = None). Volume base data: individual-tree over-bark functions of Braastad (1966), Brantseg (1967) and Vestjordet (1967).

pyforestry.norway.growth.kuehne_2022.kuehne_2022_stem_density(stems1: Stems | float, age1: AgeMeasurement, age2: AgeMeasurement, si40: SiteIndexValue | float, *, thinning_quotient: float = 1.0) → Stems[source]#

Project stem density per hectare. Kuehne et al. (2022) Eq. (6).

TPH2 = ( TPH1^b1 + b2 * (BA_after/BA_before) * (SI40/10000)^b3
  • (AGE2^b4 - AGE1^b4) )^(1/b1)

thinning_quotient is BA_AFTER/BA_BEFORE (= 1.0 unthinned); si40 is site index (m) at base age 40. b2 (the thinning-modifier coefficient) is retained even when unthinned.

pyforestry.norway.growth.kuehne_2022.kuehne_2022_stems_after_thinning_ratio(basal_area_quotient: float) → float[source]#

Trees-after / trees-before ratio. Kuehne et al. (2022) Eq. (9).

TPH_after/TPH_before = exp( b1 + b2 * (BA_after/BA_before) )

Converts a specified basal-area thinning into the corresponding stem removal.

pyforestry.norway.growth.maleki_2022 module#

Maleki et al. (2022) stand-level kernels for Norway.

The functions in this module implement the equations provided in the Norway asset model draft and expose explicit primitive-based interfaces.

class pyforestry.norway.growth.maleki_2022.Maleki2022Species(*values)[source]#

Bases: str, Enum

Supported species groups in Maleki et al. (2022).

BROADLEAVES = 'broadleaves'#
NORWAY_SPRUCE = 'norway_spruce'#
SCOTS_PINE = 'scots_pine'#
pyforestry.norway.growth.maleki_2022.maleki_2022_basal_area_projection(species: Maleki2022Species | str, basal_area1: StandBasalArea | float, age1: AgeMeasurement, age2: AgeMeasurement, si_h40: SiteIndexValue, stems1: Stems | float, stems2: Stems | float) → StandBasalArea[source]#

Return projected basal area (m2/ha) for the selected species group.

pyforestry.norway.growth.maleki_2022.maleki_2022_height_trajectory(species: Maleki2022Species | str, dominant_height_m: float, age1: AgeMeasurement, age2: AgeMeasurement) → float[source]#

Return projected dominant height (m) at age2.

pyforestry.norway.growth.maleki_2022.maleki_2022_ingrowth_count(species: Maleki2022Species | str, *, basal_area: StandBasalArea | float | None = None, qmd: QuadraticMeanDiameter | float | None = None) → float[source]#

Return expected ingrowth count per 5-year period.

pyforestry.norway.growth.maleki_2022.maleki_2022_ingrowth_probability(species: Maleki2022Species | str, qmd: QuadraticMeanDiameter | float, stems: Stems | float) → float[source]#

Return probability of ingrowth occurrence for the next 5-year period.

pyforestry.norway.growth.maleki_2022.maleki_2022_stand_volume(species: Maleki2022Species | str, dominant_height_m: float, basal_area: StandBasalArea | float, age: AgeMeasurement) → StandVolume[source]#

Return stand volume (m3/ha) for the selected Maleki species group.

pyforestry.norway.growth.maleki_2022.maleki_2022_stem_density(species: Maleki2022Species | str, age1: AgeMeasurement, age2: AgeMeasurement, stems1: Stems | float, si_h40: SiteIndexValue) → Stems[source]#

Return projected stem density per hectare.

pyforestry.norway.growth.maleki_2022.maleki_2022_stem_survival(species: Maleki2022Species | str, age1: AgeMeasurement, age2: AgeMeasurement, stems1: Stems | float, si_h40: SiteIndexValue) → Stems[source]#

Return projected surviving stems per hectare.

Module contents#

Growth and yield formula kernels for Norway models.