Calculations¶
GridFIA provides 15+ forest metrics through a flexible plugin-based calculation framework.
Calculations are registered with a central registry and can be executed via the GridFIA.calculate_metrics() method.
Overview¶
Diversity Metrics¶
| Calculation | Description | Units |
|---|---|---|
species_richness |
Count of species per pixel | count |
shannon_diversity |
Shannon diversity index (H') | nats or bits |
simpson_diversity |
Simpson diversity index (1-D) | unitless |
evenness |
Pielou's evenness (J) | unitless |
Biomass Metrics¶
| Calculation | Description | Units |
|---|---|---|
total_biomass |
Sum of biomass across all species | Mg/ha |
species_proportion |
Species as proportion of total | ratio |
species_percentage |
Species as percentage of total | percent |
species_group_proportion |
Group-level proportions | ratio |
biomass_threshold |
Pixels exceeding threshold | binary |
Species Analysis¶
| Calculation | Description | Units |
|---|---|---|
dominant_species |
Most abundant species per pixel | species index |
species_presence |
Presence/absence mapping | binary |
species_dominance |
Dominance indices | unitless |
rare_species |
Species with low biomass | count |
common_species |
Widely distributed species | count |
Quick Start¶
from gridfia import GridFIA
api = GridFIA()
# List all available calculations
calcs = api.list_calculations()
print(f"Available: {calcs}")
# Run specific calculations
results = api.calculate_metrics(
"data/forest.zarr",
calculations=["species_richness", "shannon_diversity", "total_biomass"]
)
for result in results:
print(f"{result.name}: {result.output_path}")
Using the Registry Directly¶
For advanced use cases, access the calculation registry directly:
from gridfia.core.calculations import registry
import numpy as np
# List all calculations
calcs = registry.list_calculations()
# Get a calculation instance with parameters
calc = registry.get('species_richness', biomass_threshold=1.0)
# Run on data (3D array: species x height x width)
biomass_data = np.random.rand(10, 100, 100) * 50
result = calc.calculate(biomass_data)
print(f"Richness range: {result.min()} - {result.max()}")
Calculation Reference¶
species_richness¶
Count of species with biomass above threshold at each pixel.
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
biomass_threshold |
float |
0.0 |
Minimum biomass to count species |
exclude_total_layer |
bool |
True |
Exclude pre-calculated total layer |
Example:
from gridfia import GridFIA
api = GridFIA()
results = api.calculate_metrics(
"data.zarr",
calculations=["species_richness"]
)
# With custom threshold via config
from gridfia.config import CalculationConfig, GridFIASettings
settings = GridFIASettings(
calculations=[
CalculationConfig(
name="species_richness",
parameters={"biomass_threshold": 0.5}
)
]
)
api = GridFIA(config=settings)
results = api.calculate_metrics("data.zarr")
shannon_diversity¶
Shannon diversity index (H') measuring species diversity.
Where \(p_i\) is the proportion of species \(i\).
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
base |
str |
'e' |
Logarithm base ('e', '2', or '10') |
exclude_total_layer |
bool |
True |
Exclude pre-calculated total |
Example:
simpson_diversity¶
Simpson diversity index (1-D) measuring the probability that two randomly selected individuals belong to different species.
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
exclude_total_layer |
bool |
True |
Exclude pre-calculated total |
Example:
evenness¶
Pielou's evenness index (J) measuring how evenly species abundances are distributed.
Where \(H'\) is Shannon diversity and \(S\) is species richness.
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
exclude_total_layer |
bool |
True |
Exclude pre-calculated total |
total_biomass¶
Sum of biomass across all species at each pixel.
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
exclude_total_layer |
bool |
True |
Calculate from species (vs. use pre-calculated) |
Example:
dominant_species¶
Index of the species with highest biomass at each pixel.
Output: Integer array with species indices
Example:
from gridfia import GridFIA
from gridfia.utils.zarr_utils import ZarrStore
api = GridFIA()
results = api.calculate_metrics(
"data.zarr",
calculations=["dominant_species"]
)
# Map indices to species names
with ZarrStore.open("data.zarr") as store:
species_names = store.species_names
# dominant_index = result array
# species_names[dominant_index] gives species name
species_presence¶
Binary presence/absence for specific species.
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
species_index |
int |
(required) | Index of species to check |
biomass_threshold |
float |
0.0 |
Minimum biomass for presence |
Custom Calculations¶
Create custom calculations by inheriting from ForestCalculation:
import numpy as np
from gridfia.core.calculations.base import ForestCalculation
from gridfia.core.calculations.registry import registry
class BiomassDensityRatio(ForestCalculation):
"""Calculate ratio of hardwood to softwood biomass."""
def __init__(self, hardwood_indices: list = None, softwood_indices: list = None):
super().__init__(
name="biomass_density_ratio",
description="Ratio of hardwood to softwood biomass",
units="ratio"
)
self.hardwood_indices = hardwood_indices or []
self.softwood_indices = softwood_indices or []
def calculate(self, biomass_data: np.ndarray, **kwargs) -> np.ndarray:
"""Calculate hardwood/softwood ratio."""
hardwood = biomass_data[self.hardwood_indices].sum(axis=0)
softwood = biomass_data[self.softwood_indices].sum(axis=0)
# Avoid division by zero
with np.errstate(divide='ignore', invalid='ignore'):
ratio = np.where(softwood > 0, hardwood / softwood, np.nan)
return ratio
def validate_data(self, biomass_data: np.ndarray) -> bool:
"""Validate input data."""
if biomass_data.ndim != 3:
return False
if max(self.hardwood_indices + self.softwood_indices) >= biomass_data.shape[0]:
return False
return True
# Register the custom calculation
@registry.register("biomass_density_ratio")
def create_biomass_ratio(**kwargs):
return BiomassDensityRatio(**kwargs)
Base Class Reference¶
Bases: ABC
Abstract base class for forest calculations.
Initialize a forest calculation.
Parameters¶
name : str Unique name for the calculation description : str Human-readable description units : str Units of the calculated metric **kwargs : dict Additional configuration parameters
calculate
abstractmethod
¶
Calculate metric from biomass data.
Parameters¶
biomass_data : np.ndarray 3D array (species, height, width) of biomass values **kwargs : dict Additional calculation parameters
Returns¶
np.ndarray 2D array of calculated metric values. For areas with no valid data (e.g., no forest), implementations should return appropriate values: - Zero for counts/indices where absence is meaningful - NaN for ratios/proportions where division would be undefined
Notes¶
If the calculation fails entirely (e.g., due to invalid input data), the ForestMetricsProcessor will return NaN-filled arrays for float types or sentinel values for integer types. Individual pixels with valid but zero-value results (e.g., no species present) should still return 0.
validate_data
abstractmethod
¶
preprocess_data
¶
Preprocess data before calculation.
Can be overridden by subclasses for custom preprocessing.
postprocess_result
¶
Postprocess calculation result.
Can be overridden by subclasses for custom postprocessing.
Registry Reference¶
Registry for managing available forest calculations.
Initialize the calculation registry.
register
¶
register(name: str, calculation_class: Type[ForestCalculation])
Register a new calculation type.
Parameters¶
name : str Unique name for the calculation calculation_class : Type[ForestCalculation] Class that implements ForestCalculation
get
¶
get(name: str, **kwargs) -> ForestCalculation
Performance Tips¶
Memory Management¶
For large datasets, calculations process data in chunks:
from gridfia import GridFIA, GridFIASettings
from gridfia.config import ProcessingConfig
settings = GridFIASettings(
processing=ProcessingConfig(
memory_limit_gb=16.0,
max_workers=4
)
)
api = GridFIA(config=settings)
results = api.calculate_metrics("large_data.zarr")
Output Formats¶
Choose output format based on use case:
| Format | Best For | Size |
|---|---|---|
| GeoTIFF | GIS software, QGIS | Compressed |
| Zarr | Large outputs, cloud | Chunked |
| NetCDF | xarray, scientific | Compressed |
from gridfia.config import CalculationConfig, OutputFormat
calc = CalculationConfig(
name="total_biomass",
output_format=OutputFormat.ZARR # For large outputs
)
Parallel Processing¶
Multiple calculations run in parallel when possible:
# Run multiple calculations efficiently
results = api.calculate_metrics(
"data.zarr",
calculations=[
"species_richness",
"shannon_diversity",
"simpson_diversity",
"evenness",
"total_biomass"
]
)
See Also¶
- GridFIA Class - Main API for running calculations
- Configuration - Calculation configuration
- Utilities - Working with Zarr stores