femic.pipeline.siteprod Module
The femic.pipeline.siteprod module owns FEMIC’s SiteProd raster
resolution and assignment seam. It handles the species-code mapping between VRI
and SiteProd layers, loads the canonical SiteProd band-map sidecar when a
pre-stacked multiband TIFF is available, falls back to ArcRasterRescue or
native ArcGIS Pro export when that canonical artifact is unavailable, and
computes per-stand mean site productivity values from the chosen raster.
If you are debugging why Stage 00 selected the wrong SiteProd band for a
species, why FEMIC is trying to export rasters from the FileGDB instead of
using the canonical siteprod.tif, or why stand-level siteprod values
look wrong after raster masking, this is the first module to read. In practice
it owns:
species-code normalization from VRI-style codes into the 22-layer SiteProd code space
canonical
siteprod.bandmap.jsonloading and validationArcRasterRescue executable resolution plus Windows ArcGIS Pro fallback
per-species raster export and multiband stacking when canonical artifacts are unavailable
stand-level mean SiteProd assignment from the selected stacked raster
Start Here If…
Use this page first if you are trying to:
understand why FEMIC prefers a published
siteprod.tif+siteprod.bandmap.jsonpair over live FileGDB exportdebug whether SiteProd layer discovery should use ArcRasterRescue or Windows ArcGIS Pro fallback
inspect how VRI species codes like
FDIorPLImap onto SiteProd layer codestrace how one stand row gets its mean SiteProd value from the stacked raster
figure out whether a SiteProd problem belongs here, in
femic.pipeline.io, or in the broader geospatial bootstrap/runtime setup
Typical maintenance path:
Start with
load_siteprod_bandmap()if the issue is about the canonical band-map sidecar or species-to-band indexing.Move to
list_siteprod_layers()andresolve_arc_raster_rescue_executable_path()if the failure involves FileGDB discovery, ArcRasterRescue, or Windows fallback behavior.Read
export_and_stack_siteprod_layers()if FEMIC is rebuilding the multiband TIFF from individual exports.Finish with
assign_siteprod_from_raster()andmean_siteprod_for_row()if the problem is in the stand-level raster masking or species-band selection itself.
Typical Usage
The preferred maintenance path is to load the canonical band map for a
published siteprod.tif pair rather than re-exporting from the FileGDB:
from pathlib import Path
from femic.pipeline.siteprod import load_siteprod_bandmap
layer_species, species_layer = load_siteprod_bandmap(
bandmap_path=Path("external/femic-public-data/data/bc/siteprod/siteprod.bandmap.json")
)
How This Fits Into The Pipeline
This module sits inside the Stage 00 geospatial/data-prep path. Its job is to turn the available SiteProd source artifacts into one reliable assignment surface for stand records:
femic.pipeline.iodecides whether FEMIC should use instance-local or canonical SiteProd artifactsthis module loads the canonical band map when a paired TIFF + JSON sidecar exists, or falls back to live layer discovery/export when it does not
the chosen stacked raster is masked per stand geometry to derive mean positive SiteProd values
downstream Stage 00/01a logic consumes those stand-level SiteProd values as part of inventory conditioning and yield-curve preparation
That means this module is the code-level owner of the SiteProd-specific logic,
not of overall instance-root artifact selection. If FEMIC picked the wrong data
root, inspect femic.pipeline.io first. If it picked the right SiteProd
artifacts but still mapped bands, species, or raster values incorrectly, the
bug usually lives here.
Key Entry Surfaces
The highest-value entrypoints in this module are:
siteprod_species_lookup()Normalize VRI-style species codes into SiteProd layer codes with explicit first-letter fallbacks.load_siteprod_bandmap()Load the canonical JSON sidecar describing SiteProd band ordering.resolve_arc_raster_rescue_executable_path()Find the effective ArcRasterRescue executable using config, env, instance root, and source-root fallbacks.list_siteprod_layers()Discover the available SiteProd layers from ArcRasterRescue or Windows ArcGIS Pro fallback.export_and_stack_siteprod_layers()Export per-species rasters and stack them into the multibandsiteprod.tifsurface.assign_siteprod_from_raster()Compute stand-level mean SiteProd values from the chosen stacked raster.mean_siteprod_for_row()Core helper for per-row masking and positive-value averaging.
Canonical Artifact And Fallback Rules
The most important runtime contracts in this module are:
the preferred runtime path is a canonical paired
siteprod.tif+siteprod.bandmap.jsonartifact setthe band-map sidecar may be expressed through
bands_0_based,bands_1_based, orordered_species, and this module normalizes those representations into one species<->band mappingwhen canonical artifacts are unavailable, FEMIC falls back to live FileGDB layer discovery and per-species export
ArcRasterRescue is the preferred live-export path when its executable is available; on Windows only, ArcGIS Pro Python is the documented fallback
temporary per-species GeoTIFF exports are stacked into one multiband raster and then cleaned up
These rules are why SiteProd behavior is so environment-sensitive. A checkout with published canonical artifacts should avoid heavyweight export work. A checkout without them must have a usable ArcRasterRescue or Windows ArcGIS Pro surface before Stage 00 can continue reliably.
Platform-Sensitive Runtime Behavior
One of the most important behaviors in this module is the split between the preferred cross-platform helper and the Windows-only fallback:
ArcRasterRescue is resolved from explicit env override, configured path, and source-root or instance-root-relative fallbacks
FileGDB paths are normalized with a trailing
.gdb/form when needed for ArcRasterRescueFEMIC_ARC_RASTER_RESCUE_TIMEOUT_SECcontrols export timeout behavior and falls back to 900 seconds when unset or invalidif ArcRasterRescue is unavailable and the host is Windows, FEMIC falls back to ArcGIS Pro Python for layer listing and raster export
if ArcRasterRescue is unavailable on non-Windows hosts, the export path fails fast instead of guessing a different geoprocessing stack
This is the code-level owner of the platform guidance documented in the Stage 00 and geospatial bootstrap guides.
Stand-Level Assignment Contract
Once a stacked SiteProd raster exists, the assignment contract is:
choose the species layer for each stand from
SPECIES_CD_1or an explicit lookup fallbackmask the raster by stand geometry
keep only positive values from the selected species band
write the mean of those values to the target output column, defaulting to
siteprod
If that output looks wrong, the likely failure modes are a bad species mapping,
an incorrect band map, geometry/masking issues, or all-positive values being
filtered away to NaN.
Failure Seams To Watch
The common failure boundaries in this module are:
species-code drift unexpected VRI species codes can fall through the lookup table and raise
ValueErrorif no first-letter fallback existsinvalid or missing band-map sidecar malformed JSON or missing required band-order fields breaks the canonical pre-stacked path
ArcRasterRescue resolution failures a configured relative path may resolve differently across source checkout, instance-root, and env-override contexts
export/stack runtime failures ArcRasterRescue can time out or return stderr-only failures, and Windows ArcGIS Pro fallback depends on an explicit Pro Python installation
raster masking surprises wrong geometry, wrong species-band mapping, or no positive values in the selected band can silently degrade stand-level SiteProd assignment
Cross-References
Guides and references that pair especially closely with this module:
Related API pages:
Helpers for legacy site productivity raster export/stack orchestration.
- femic.pipeline.siteprod.assign_siteprod_from_raster(*, f_table, siteprod_tif_path, siteprod_specieslayer, rio_module, mask_fn, np_module, row_apply_fn, species_lookup_fn=<function siteprod_species_lookup>, out_col='siteprod')[source]
Assign siteprod column by masking the stacked siteprod raster per stand row.
- Parameters:
f_table (Any)
siteprod_tif_path (str | Path)
siteprod_specieslayer (Mapping[str, int])
rio_module (Any)
mask_fn (Callable[[...], Any])
np_module (Any)
row_apply_fn (Callable[[...], Any])
species_lookup_fn (Callable[[str], str])
out_col (str)
- Return type:
Any
- femic.pipeline.siteprod.build_siteprod_layer_tif_path(*, siteprod_tmpexport_tif_path_prefix, species)[source]
Build temporary GeoTIFF path for one species export.
- Parameters:
siteprod_tmpexport_tif_path_prefix (str | Path)
species (str)
- Return type:
Path
- femic.pipeline.siteprod.enumerate_siteprod_layer_tif_paths(*, siteprod_tmpexport_tif_path_prefix)[source]
Enumerate exported temporary siteprod layer GeoTIFF paths.
- Parameters:
siteprod_tmpexport_tif_path_prefix (str | Path)
- Return type:
list[Path]
- femic.pipeline.siteprod.export_and_stack_siteprod_layers(*, arc_raster_rescue_exe_path, site_prod_bc_gdb_path, site_prod_bc_layerspecies, siteprod_layerspecies, siteprod_tmpexport_tif_path_prefix, siteprod_tif_path, run_fn, rio_module, message_fn=<built-in function print>)[source]
Export per-species rasters, stack into one GeoTIFF, and clean temps.
- Parameters:
arc_raster_rescue_exe_path (str | Path)
site_prod_bc_gdb_path (str | Path)
site_prod_bc_layerspecies (Mapping[int, str])
siteprod_layerspecies (Mapping[int, str])
siteprod_tmpexport_tif_path_prefix (str | Path)
siteprod_tif_path (str | Path)
run_fn (Callable[[...], Any])
rio_module (Any)
message_fn (Callable[[...], Any])
- Return type:
None
- femic.pipeline.siteprod.list_siteprod_layers(*, arc_raster_rescue_exe_path, siteprod_gdb_path, run_fn)[source]
Run ArcRasterRescue layer listing and return parsed species mappings.
- Parameters:
arc_raster_rescue_exe_path (str | Path)
siteprod_gdb_path (str | Path)
run_fn (Callable[[...], Any])
- Return type:
tuple[dict[int, str], dict[str, int]]
- femic.pipeline.siteprod.load_siteprod_bandmap(*, bandmap_path)[source]
Load canonical SiteProd species<->band mappings from JSON sidecar.
- Parameters:
bandmap_path (str | Path)
- Return type:
tuple[dict[int, str], dict[str, int]]
- femic.pipeline.siteprod.mean_siteprod_for_row(*, row, raster_src, mask_fn, np_module, siteprod_specieslayer, species_lookup_fn=<function siteprod_species_lookup>)[source]
Compute mean positive siteprod value for one stand record.
- Parameters:
row (Any)
raster_src (Any)
mask_fn (Callable[[...], Any])
np_module (Any)
siteprod_specieslayer (Mapping[str, int])
species_lookup_fn (Callable[[str], str])
- Return type:
float
- femic.pipeline.siteprod.parse_arc_raster_rescue_layer_mappings(*, stdout_text)[source]
Parse ArcRasterRescue layer listing into index<->species mappings.
- Parameters:
stdout_text (str)
- Return type:
tuple[dict[int, str], dict[str, int]]
- femic.pipeline.siteprod.resolve_arc_raster_rescue_executable_path(*, configured_path, source_root_env=None, instance_root_env=None, env_override=None)[source]
Resolve ArcRasterRescue executable using override + source-root fallbacks.
- Parameters:
configured_path (str | Path)
source_root_env (str | None)
instance_root_env (str | None)
env_override (str | None)
- Return type:
Path
- femic.pipeline.siteprod.siteprod_species_lookup(species_code, *, mapping={'A': 'AT', 'AC': 'AT', 'ACB': 'AT', 'ACT': 'AT', 'AX': 'AT', 'B': 'BL', 'BB': 'BL', 'BM': 'BL', 'C': 'CW', 'D': 'DR', 'E': 'EP', 'EA': 'EP', 'F': 'FD', 'FDI': 'FD', 'G': 'DR', 'H': 'HW', 'L': 'LT', 'LA': 'LT', 'M': 'AT', 'MB': 'AT', 'MV': 'AT', 'P': 'PL', 'PJ': 'PL', 'PLI': 'PL', 'Q': 'AT', 'R': 'DR', 'S': 'SW', 'SXL': 'SX', 'SXW': 'SX', 'T': 'LT', 'V': 'DR', 'W': 'EP', 'WS': 'EP', 'X': 'SW', 'XC': 'PL', 'XD': 'SW', 'Y': 'YC', 'Z': 'SW'})[source]
Map VRI species code to siteprod layer code with first-letter fallback.
- Parameters:
species_code (str)
mapping (Mapping[str, str])
- Return type:
str