alsdb.processing.biomass.calibrate_naesset#

alsdb.processing.biomass.calibrate_naesset(h95: ndarray, cc: ndarray, agb_field: ndarray, p0: tuple[float, float, float] = (0.8, 1.8, 0.5), return_cov: bool = False) tuple[float, float, float] | tuple[tuple[float, float, float], ndarray][source]#

Fit Næsset power-law AGB coefficients (a, b, c) to field-plot data.

Solves AGB = a × h95^b × cc^c via nonlinear least-squares (scipy.optimize.curve_fit).

Parameters:
  • h95 – P95 canopy height from ALS (m), one value per field plot.

  • cc – Canopy cover fraction (0–1), one value per field plot.

  • agb_field – Measured AGB from field inventory (Mg ha⁻¹), one value per field plot.

  • p0 – Initial parameter guess (a, b, c). Defaults to the generic priors.

  • return_cov – If True, also return the 3×3 parameter covariance matrix from curve_fit so callers can assess calibration uncertainty. Diagonal elements are the variance of each coefficient; off-diagonals are cross-covariances. Infinite values indicate a poorly constrained fit.

Returns:

Fitted (a, b, c) coefficients for use in naesset_model. When return_cov=True, returns ((a, b, c), pcov) instead.

Return type:

tuple[float, float, float]

Raises:

ValueError – If fewer than 20 valid (non-NaN, non-zero) field plots are provided. A 3-parameter power-law model fit on fewer plots has nearly zero degrees of freedom and will be severely overfit.

Warns:

UserWarning – If valid plot count is below 50, a calibration-quality warning is emitted. Reliable coefficient estimation typically requires ≥ 50 independent plots (Næsset 2002; Andersen et al. 2011).

Example

a, b, c = calibrate_naesset(h95_plots, cc_plots, agb_plots)
compute_biomass(provider, store, resolution=10.0, year=2021,
                model_fn=lambda m: naesset_model(m, a=a, b=b, c=c))

# With uncertainty:
(a, b, c), pcov = calibrate_naesset(h95_plots, cc_plots, agb_plots,
                                     return_cov=True)
a_std, b_std, c_std = np.sqrt(np.diag(pcov))