Skip to main content

nsvb

National Scale Volume and Biomass Estimators — a Python implementation of Westfall et al. (2024), A national-scale tree volume, biomass, and carbon modeling system for the United States, USDA Forest Service GTR WO-104 (doi:10.2737/WO-GTR-104).

Every estimator is validated against the four worked examples in the GTR's "Examples of Tree-Level Calculations" section, to the 12 decimal places the publication prints.

Installation

pip install nsvb

Quick start

from nsvb import estimators

# A live Douglas-fir, 20 in DBH, 110 ft tall, in the Marine ecodivision.
estimators.total_aboveground_biomass(202, 20.0, 110.0, "240")   # 3154.55 lb
estimators.carbon_content(202, 20.0, 110.0, "240")              # 1626.47 lb C

The first four arguments are always spcd, dia, ht, division:

argument meaning units
spcd FIA species code (FIADB REF_SPECIES)
dia diameter at breast height inches
ht total height feet
division Cleland ecodivision code, e.g. "240", "M220"

Everything else is optional and describes deductions:

argument meaning default
cull rotten/missing cull, as a percentage (0–100) 0
ah actual height of a broken top; None if intact None
decaycd FIA decay class: 0/None = live, 15 = standing dead 0
cr observed crown ratio, as a decimal fraction (0–1] None
province Cleland ecoprovince, for the Table S11 default crown ratio ""
stdorgcd stand origin: 0 natural, 1 planted (keyword-only) 0

cull is a percentage and cr is a fraction — a 30 percent crown ratio is cr=0.30, not cr=30. Passing cr=30 raises.

Dead trees and decay class

Dead-tree reduction is applied through decaycd. Following GTR table 1, the stem wood is scaled by a wood density proportion, bark and branches by further proportions, and foliage is zero for any dead tree. Dead trees also use a different carbon fraction (table S10b, by decay class) than live trees (table S10a, by species).

# A dead tanoak, decay class 2, 10% cull, broken top at 21 ft.
estimators.agb_predicted_reduced(
    631, 11.3, 28.0, "M240", cull=10.0, ah=21.0, decaycd=2, province="M242",
)                                                               # 241.97 lb
estimators.carbon_content(
    631, 11.3, 28.0, "M240", cull=10.0, ah=21.0, decaycd=2, province="M242",
)                                                               # 114.45 lb C

FIADB populates DECAYCD only for standing dead trees, so live trees arrive as NULL. decaycd=None and decaycd=NaN are both treated as live.

Broken tops and province

For a broken-top tree the remaining branch and foliage mass depends on the crown ratio. If you observed one, pass cr. If you did not, the estimator falls back to the Table S11 regional mean, which is keyed by ecoprovince (e.g. "M242"), not ecodivision ("M240"). Passing a division where a province is expected still returns a number, but a different one — up to about 27 percent on branch biomass — so the package warns rather than resolving it silently. Omitting province falls back to a national mean and warns too.

Gross vs. reduced

Bare names are the gross model prediction with no deductions; the _reduced and _sound suffixes carry the cull, dead-tree and broken-top reductions. The gross forms are not just a convenience — agb_reduce_factor needs them undeducted for its denominator.

estimators.total_stem_wood_dry_weight(...)          # Wtotib   (gross)
estimators.total_stem_wood_dry_weight_reduced(...)  # Wtotibred

What's available

Roughly following the GTR's numbered steps:

functions
Volumes (steps 1–3, 6) total_inside_bark_wood_volume, total_bark_wood_volume, total_outside_bark_volume, and merchantable_*, sawlog_*, stump_*, top_*, missing_* variants, each with a _sound counterpart
Heights and ratios (steps 4–5) merchantable_height, sawlog_height, stump_volume_ratio, merchantable_volume_ratio, sawlog_volume_ratio, broken_top_volume_ratio
Component weights (steps 7–9, 15) total_stem_wood_dry_weight, total_stem_bark_weight, total_branch_weight, total_foliage_dry_weight, plus _reduced variants
Harmonization (steps 10–13) total_aboveground_biomass, agb_component_reduced, agb_reduce_factor, agb_predicted_reduced, agb_difference, harmonized_wood/_bark/_branch, adjusted_wood_density, adjusted_bark_density
FIADB components (steps 14, 16) merchantable_outside_bark_weight (DRYBIO_BOLE), sawlog_outside_bark_weight (DRYBIO_SAWLOG), stump_outside_bark_weight (DRYBIO_STUMP), drybio_top (DRYBIO_TOP)
Carbon (step 17) carbon_content

Not implemented

Belowground coarse-root biomass. The GTR describes it in a single sentence (p. 11) — the approach of Heath et al. (2009), modified to use NSVB merchantable stem wood volume and the table 1 density proportions for standing dead trees — but publishes no equation, no coefficients (there is no belowground table among S1–S20), and no worked example. Implementing it needs the Heath et al. (2009) method, and substituting a different published root model would not be the NSVB quantity. Note that FIADB REF_SPECIES ships JENKINS_ROOT_RATIO_B1/B2, but those are the Jenkins et al. (2003) ratio applied to aboveground biomass — a different method from the one the GTR describes.

Arrays

Every estimator accepts scalars or array-likes and returns the matching shape, so a whole inventory can go through in one call:

import numpy as np

estimators.carbon_content(
    np.array([202, 631]),
    np.array([20.0, 11.3]),
    np.array([110.0, 28.0]),
    np.array(["240", "M240"]),
    np.array([0.0, 10.0]),          # cull
    np.array([np.nan, 21.0]),       # ah — NaN means an intact top
    np.array([0, 2]),               # decaycd
    np.array([np.nan, np.nan]),     # cr — NaN means use the Table S11 default
    np.array(["", "M242"]),         # province
)

Missing measurements propagate as NaN rather than raising, so a batch with unrecorded heights yields NaN for those rows and real numbers everywhere else. Out-of-domain values (negative diameter, cull > 100, ah > ht, an unknown species code) raise ValueError — the underlying models are unguarded power functions that would otherwise return complex numbers or silently wrong results.

Accuracy notes

Two quantities cannot be reproduced from the published supplementary CSVs to the precision of the GTR's printed examples:

  • Ten rows in tables S2a/S6a/S7a store the a coefficient in Excel scientific notation truncated to three significant figures (e.g. 3.19E-05 where the GTR text uses 0.000031886237), which drifts bark quantities by up to ~4e-4 relative.
  • The GTR's printed merchantable and sawlog heights are under-converged iterates — the residual of equation 7 at the published values is ~1e-6. This package solves to ~1e-14, so the two differ by ~1e-6 relative.

Both are publication-precision limits rather than implementation differences, and the test suite documents each one where it applies.

References

Westfall, James A.; Coulston, John W.; Gray, Andrew N.; Shaw, John D.; Radtke, Philip J.; Walker, David M.; Weiskittel, Aaron R.; MacFarlane, David W.; Affleck, David L.R.; Zhao, Dehai; Temesgen, Hailemariam; Poudel, Krishna P.; Frank, Jereme M.; Prisley, Stephen P.; Wang, Yingfang; Sánchez Meador, Andrew J.; Auty, David; Domke, Grant M. 2024. A national-scale tree volume, biomass, and carbon modeling system for the United States. Gen. Tech. Rep. WO-104. Washington, DC: U.S. Department of Agriculture, Forest Service. 37 p. https://doi.org/10.2737/WO-GTR-104

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nsvb-0.3.0.tar.gz (4.4 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

nsvb-0.3.0-py3-none-any.whl (4.4 MB view details)

Uploaded Python 3

File details

Details for the file nsvb-0.3.0.tar.gz.

File metadata

  • Download URL: nsvb-0.3.0.tar.gz
  • Upload date:
  • Size: 4.4 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.14.7

File hashes

Hashes for nsvb-0.3.0.tar.gz
Algorithm Hash digest
SHA256 17f9771a229ec7871c0e1d0f085078e10d5963d9bf2e66b25ea89075e11168c8
MD5 d1444e4799a5e27f0314bbc272e3f3fe
BLAKE2b-256 99dcd1739ec1192d7f524250401392f65aa1a0fe4d14171060ae3e4115fbfede

See more details on using hashes here.

File details

Details for the file nsvb-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: nsvb-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 4.4 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.14.7

File hashes

Hashes for nsvb-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1eefd260206e837889614eaa6c6a9421cc03ff25e556625ab3137a340e5b4dd9
MD5 cf4808d0e806929f24d7db193e025773
BLAKE2b-256 10dd555e996ff4311845aef6289a5443ec9eb85ebd8cf5e52768a615c125fa6f

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 files

0.2.1

2 files

0.1.1

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page