> ## Documentation Index
> Fetch the complete documentation index at: https://pyfia.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# volume

# `pyfia.estimation.estimators.volume`

Volume estimation for FIA data.

Simple, straightforward implementation for calculating tree volume
without unnecessary abstractions.

## Functions

### `volume` <sup><a href="https://github.com/mihiarc/pyfia/blob/main/src/pyfia/estimation/estimators/volume.py#L301" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>

```python theme={null}
volume(db: str | FIA, grp_by: str | list[str] | None = None, by_species: bool = False, by_size_class: bool = False, land_type: str = 'forest', tree_type: str = 'live', vol_type: str = 'net', tree_domain: str | None = None, area_domain: str | None = None, plot_domain: str | None = None, totals: bool = True, variance: bool = False, most_recent: bool = False, eval_type: str | None = None) -> pl.DataFrame
```

Estimate tree volume from FIA data.

Calculates volume estimates using FIA's design-based estimation methods
with proper expansion factors and stratification. Automatically handles
EVALID selection to prevent overcounting from multiple evaluations.

**Args:**

* `db`: Database connection or path to FIA database. Can be either a path
  string to a DuckDB/SQLite file or an existing FIA connection object.
* `grp_by`: Column name(s) to group results by. Can be any column from the
  TREE, COND, and PLOT tables. Common grouping columns include:

**Tree Characteristics:**

* 'SPCD': Species code (see REF\_SPECIES table)
* 'SPGRPCD': Species group code (hardwood/softwood groups)
* 'DIA': Diameter at breast height (continuous, use with caution)
* 'HT': Total tree height in feet
* 'CR': Crown ratio (percent of bole with live crown)
* 'CCLCD': Crown class code (1=Open grown, 2=Dominant, 3=Codominant,
  4=Intermediate, 5=Overtopped)
* 'TREECLCD': Tree class code (2=Growing stock, 3=Rough cull, 4=Rotten cull)
* 'DECAYCD': Decay class for standing dead trees

**Ownership and Management:**

* 'OWNGRPCD': Ownership group (10=National Forest, 20=Other Federal,
  30=State/Local, 40=Private)
* 'OWNCD': Detailed ownership code (see REF\_RESEARCH\_STATION)
* 'ADFORCD': Administrative forest code
* 'RESERVCD': Reserved status (0=Not reserved, 1=Reserved)

**Forest Characteristics:**

* 'FORTYPCD': Forest type code (see REF\_FOREST\_TYPE)
* 'STDSZCD': Stand size class (1=Large diameter, 2=Medium diameter,
  3=Small diameter, 4=Seedling/sapling, 5=Nonstocked)
* 'STDORGCD': Stand origin (0=Natural, 1=Planted)
* 'STDAGE': Stand age in years

**Site Characteristics:**

* 'SITECLCD': Site productivity class (1=225+ cu ft/ac/yr,
  2=165-224, 3=120-164, 4=85-119, 5=50-84, 6=20-49, 7=0-19)
* 'PHYSCLCD': Physiographic class code
* 'SLOPE': Slope in percent
* 'ASPECT': Aspect in degrees (0-360)

**Location:**

* 'STATECD': State FIPS code
* 'UNITCD': FIA survey unit code
* 'COUNTYCD': County code
* 'INVYR': Inventory year

**Disturbance and Treatment:**

* 'DSTRBCD1', 'DSTRBCD2', 'DSTRBCD3': Disturbance codes
* 'TRTCD1', 'TRTCD2', 'TRTCD3': Treatment codes

For complete column descriptions, see USDA FIA Database User Guide.

* `by_species`: If True, group results by species code (SPCD). This is a convenience
  parameter equivalent to adding 'SPCD' to grp\_by.

* `by_size_class`: If True, group results by diameter size classes. Size classes are
  defined as: 1.0-4.9", 5.0-9.9", 10.0-19.9", 20.0-29.9", 30.0+".

* `land_type`: Land type to include in estimation:

* 'forest': All forestland (COND\_STATUS\_CD = 1)

* 'timber': Timberland only (unreserved, productive forestland with
  SITECLCD \< 7 and RESERVCD = 0)

* 'all': All land types including non-forest

* `tree_type`: Tree type to include:

* 'live': All live trees (STATUSCD = 1)

* 'dead': Standing dead trees (STATUSCD = 2)

* 'gs': Growing stock trees (live, TREECLCD = 2, no defects)

* 'all': All trees regardless of status

* `vol_type`: Volume type to estimate:

* 'net': Net cubic foot volume (VOLCFNET) - gross minus defects

* 'gross': Gross cubic foot volume (VOLCFGRS) - total stem volume

* 'sound': Sound cubic foot volume (VOLCFSND) - gross minus rot

* 'sawlog': Sawlog board foot volume (VOLBFNET) - net board feet

* `tree_domain`: SQL-like filter expression for tree-level attributes. Examples:

* "DIA >= 10.0": Trees 10 inches DBH and larger

* "SPCD IN (131, 110)": Specific species (loblolly and Virginia pine)

* "DIA BETWEEN 10 AND 20": Mid-sized trees

* "HT > 50 AND CR > 30": Tall trees with good crowns

* `area_domain`: SQL-like filter expression for COND-level attributes. Examples:

* "STDAGE > 50": Stands older than 50 years

* "FORTYPCD IN (161, 162)": Specific forest types

* "OWNGRPCD == 40": Private lands only

* "SLOPE \< 30 AND ASPECT BETWEEN 135 AND 225": Gentle south-facing slopes

* `totals`: If True, include total volume estimates expanded to population level.
  If False, only return per-acre values.

* `variance`: If True, return variance instead of standard error.

* `most_recent`: If True, automatically select the most recent evaluation for each
  state/region. Equivalent to calling db.clip\_most\_recent() first.

* `eval_type`: Evaluation type to select if most\_recent=True. Options:
  'ALL', 'VOL', 'GROW', 'MORT', 'REMV', 'CHANGE', 'DWM', 'INV'.
  Default is 'VOL' for volume estimation.

**Returns:**

* Volume estimates with the following columns:

* **YEAR** : int
  Inventory year

* **\[grouping columns]** : varies
  Any columns specified in grp\_by parameter

* **VOLCFNET\_ACRE** : float (if vol\_type='net')
  Net cubic foot volume per acre

* **VOLCFGRS\_ACRE** : float (if vol\_type='gross')
  Gross cubic foot volume per acre

* **VOLCFSND\_ACRE** : float (if vol\_type='sound')
  Sound cubic foot volume per acre

* **VOLBFNET\_ACRE** : float (if vol\_type='sawlog')
  Net board foot volume per acre

* **VOLCFNET\_ACRE\_SE** : float (if variance=False)
  Standard error of per-acre volume estimate

* **VOLCFNET\_ACRE\_VAR** : float (if variance=True)
  Variance of per-acre volume estimate

* **N\_PLOTS** : int
  Number of plots in estimate

* **N\_TREES** : int
  Number of trees in estimate

* **AREA\_TOTAL** : float
  Total area (acres) represented by the estimation

* **VOLCFNET\_TOTAL** : float (if totals=True)
  Total volume expanded to population level

* **VOLCFNET\_TOTAL\_SE** : float (if totals=True and variance=False)
  Standard error of total volume

**Examples:**

Basic net volume on forestland:

> > > from pyfia import FIA, volume
> > > with FIA("path/to/fia.duckdb") as db:
> > > ...     db.clip\_by\_state(37)  # North Carolina
> > > ...     results = volume(db, land\_type="forest", vol\_type="net")
> > > Volume by species on timberland:
> > > results = volume(
> > > ...     db,
> > > ...     by\_species=True,
> > > ...     land\_type="timber",
> > > ...     tree\_type="gs"  # Growing stock only
> > > ... )
> > >
> > > # Find top species by volume
> > >
> > > if not results.is\_empty():
> > > ...     top\_species = results.sort(by='VOLCFNET\_ACRE', descending=True).head(5)
> > > Large tree volume by ownership:
> > > results = volume(
> > > ...     db,
> > > ...     grp\_by="OWNGRPCD",
> > > ...     tree\_domain="DIA >= 20.0",
> > > ...     variance=True
> > > ... )
> > > Sawlog volume by forest type:
> > > results = volume(
> > > ...     db,
> > > ...     grp\_by="FORTYPCD",
> > > ...     vol\_type="sawlog",
> > > ...     tree\_type="gs",
> > > ...     tree\_domain="DIA >= 11.0"  # Hardwood sawtimber size
> > > ... )
> > > Volume by multiple grouping variables:
> > > results = volume(
> > > ...     db,
> > > ...     grp\_by=\["STATECD", "OWNGRPCD", "STDSZCD"],
> > > ...     land\_type="forest",
> > > ...     totals=True
> > > ... )
> > > Complex filtering with domain expressions:
> > >
> > > # High-value timber on productive sites
> > >
> > > results = volume(
> > > ...     db,
> > > ...     grp\_by="SPCD",
> > > ...     land\_type="timber",
> > > ...     tree\_domain="DIA >= 16.0 AND TREECLCD == 2",
> > > ...     area\_domain="SITECLCD \<= 3 AND SLOPE \< 35"
> > > ... )
> > > Dead tree volume assessment:
> > > \>>> results = volume(
> > > ...     db,
> > > ...     tree\_type="dead",
> > > ...     by\_species=True,
> > > ...     tree\_domain="DIA >= 10.0 AND DECAYCD IN (1, 2)"  # Sound dead trees
> > > ... )

## Classes

### `VolumeEstimator` <sup><a href="https://github.com/mihiarc/pyfia/blob/main/src/pyfia/estimation/estimators/volume.py#L27" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>

Volume estimator for FIA data.

Estimates tree volume (cubic feet) using standard FIA methods.

**Methods:**

#### `get_required_tables` <sup><a href="https://github.com/mihiarc/pyfia/blob/main/src/pyfia/estimation/estimators/volume.py#L38" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>

```python theme={null}
get_required_tables(self) -> list[str]
```

Volume estimation requires tree, condition, and stratification tables.

#### `get_tree_columns` <sup><a href="https://github.com/mihiarc/pyfia/blob/main/src/pyfia/estimation/estimators/volume.py#L42" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>

```python theme={null}
get_tree_columns(self) -> list[str]
```

Required tree columns for volume estimation.

Uses centralized column resolution from columns.py to reduce duplication.
Volume estimation requires volume columns based on vol\_type configuration.

#### `get_cond_columns` <sup><a href="https://github.com/mihiarc/pyfia/blob/main/src/pyfia/estimation/estimators/volume.py#L62" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>

```python theme={null}
get_cond_columns(self) -> list[str]
```

Required condition columns.

Uses centralized column resolution from columns.py to reduce duplication.
Volume estimation needs PROP\_BASIS for area adjustment calculations.

#### `calculate_values` <sup><a href="https://github.com/mihiarc/pyfia/blob/main/src/pyfia/estimation/estimators/volume.py#L74" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>

```python theme={null}
calculate_values(self, data: pl.LazyFrame) -> pl.LazyFrame
```

Calculate volume per acre.

Volume calculation: VOLUME \* TPA\_UNADJ

#### `aggregate_results` <sup><a href="https://github.com/mihiarc/pyfia/blob/main/src/pyfia/estimation/estimators/volume.py#L107" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>

```python theme={null}
aggregate_results(self, data: pl.LazyFrame | None) -> AggregationResult
```

Aggregate volume with two-stage aggregation for correct per-acre estimates.

CRITICAL FIX: This method implements two-stage aggregation following FIA
methodology. The previous single-stage approach caused \~22x underestimation
by having each tree contribute its condition proportion to the denominator.

Stage 1: Aggregate trees to plot-condition level
Stage 2: Apply expansion factors and calculate ratio-of-means

**Returns:**

* Bundle containing results, plot\_tree\_data, and group\_cols for
  explicit variance calculation.

#### `calculate_variance` <sup><a href="https://github.com/mihiarc/pyfia/blob/main/src/pyfia/estimation/estimators/volume.py#L208" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>

```python theme={null}
calculate_variance(self, agg_result: AggregationResult) -> pl.DataFrame
```

Calculate variance for volume estimates using domain total variance formula.

Uses the stratified domain total variance formula from Bechtold & Patterson (2005):
V(Ŷ) = Σ\_h w\_h² × s²\_yh × n\_h

This matches EVALIDator's variance calculation for tree-based estimates.

#### `format_output` <sup><a href="https://github.com/mihiarc/pyfia/blob/main/src/pyfia/estimation/estimators/volume.py#L246" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>

```python theme={null}
format_output(self, results: pl.DataFrame) -> pl.DataFrame
```

Format volume estimation output.
