Skip to content

Commit 6c0952c

Browse files
committed
Update CLAUDE.md with LS and PN variant infrastructure details
Document bark ratio, crown ratio, mortality, volume, and SDI maximums for both LS and PN variants. Update PN expected yields to actual smoke test values. Add steps 6-10 to Adding New Variants guide covering infrastructure modules. Add OP variant entries throughout.
1 parent 5dc76a6 commit 6c0952c

File tree

1 file changed

+71
-8
lines changed

1 file changed

+71
-8
lines changed

CLAUDE.md

Lines changed: 71 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Forest Vegetation Simulator (FVS) - Python implementation supporting multiple FV
1313
- **WC (West Cascades)** - 37 species for western Oregon and Washington Cascades including Douglas-fir, Western Hemlock, and Western Red Cedar
1414
- **NE (Northeast)** - 108 species for New England and Mid-Atlantic (CT, DE, MA, MD, ME, NH, NJ, NY, OH, PA, RI, VT, WV) including Red Maple, Sugar Maple, Northern Red Oak, Eastern White Pine
1515
- **CS (Central States)** - 96 species for Midwest oak-hickory forests (IL, IN, IA, MO) including White Oak, Northern Red Oak, Sugar Maple, Black Walnut
16+
- **OP (ORGANON Pacific Northwest)** - 18 species for intensively managed PNW plantations including Douglas-fir, Western Hemlock, Red Alder
1617

1718
## Key Development Commands
1819

@@ -93,8 +94,8 @@ tree.py
9394
├── pn_diameter_growth.py (18-coef ln(DDS) with topographic effects, PN variant)
9495
├── wc_diameter_growth.py (19-coef ln(DDS) with topographic effects, WC variant)
9596
├── height_diameter.py (Curtis-Arney/Wykoff equations, variant-aware)
96-
├── crown_ratio.py (Weibull-based crown ratio)
97-
├── bark_ratio.py (Clark 1991 DIB/DOB)
97+
├── crown_ratio.py (Weibull-based crown ratio, SN/LS/PN variant models)
98+
├── bark_ratio.py (Clark 1991 DIB/DOB, SN/LS/PN variant models)
9899
├── crown_width.py (forest/open grown equations)
99100
├── volume_library.py (Amateis & Burkhart equations)
100101
└── species.py (SpeciesCode enum)
@@ -130,6 +131,8 @@ src/pyfvs/cfg/
130131
├── pn/ # PN (Pacific Northwest Coast) variant
131132
│ ├── pn_diameter_growth_coefficients.json # 20 coefficient sets
132133
│ ├── pn_height_diameter_coefficients.json # Curtis-Arney P2,P3,P4
134+
│ ├── pn_bark_ratio_coefficients.json # 3 equation types, 16 groups
135+
│ ├── pn_crown_ratio_coefficients.json # Weibull, 17 groups + Redwood logistic
133136
│ ├── pn_species_config.yaml
134137
│ └── species/*.yaml # PN species configs (39 species)
135138
├── wc/ # WC (West Cascades) variant
@@ -198,29 +201,48 @@ src/pyfvs/cfg/
198201
25. **String Normalization Utilities** - Added `utils/string_utils.py` with `normalize_code()`, `normalize_species_code()`, and `normalize_ecounit()` functions for consistent string handling throughout the codebase.
199202
26. **Test Fixtures Consolidation** - Created `tests/conftest.py` with 30+ shared pytest fixtures for trees (seedling, small, transition, large, mature), tree lists (sample, mixed species, density levels), and stands (young, mature, high/low site, ecounits).
200203
27. **VolumeCalculator Caching** - Added module-level cache for VolumeCalculator instances in `volume_library.py`, keyed by species code. The `get_volume_library()` function returns cached instances for performance.
201-
28. **Multi-Variant Architecture** - Added support for multiple FVS regional variants. Implemented Lake States (LS), Pacific Northwest Coast (PN), West Cascades (WC), Northeast (NE), and Central States (CS) variants alongside existing Southern (SN) variant. Key changes:
204+
28. **Multi-Variant Architecture** - Added support for multiple FVS regional variants. Implemented Lake States (LS), Pacific Northwest Coast (PN), West Cascades (WC), Northeast (NE), Central States (CS), and ORGANON Pacific Northwest (OP) variants alongside existing Southern (SN) variant. Key changes:
202205
- `config_loader.py`: Added `SUPPORTED_VARIANTS` dict, `set_default_variant()`, `get_default_variant()` functions
203206
- `ls_diameter_growth.py`: New module implementing LS 12-coefficient linear DDS equation
204207
- `pn_diameter_growth.py`: New module implementing PN 18-coefficient ln(DDS) equation with topographic effects
205208
- `wc_diameter_growth.py`: New module implementing WC 19-coefficient ln(DDS) equation (same structure as PN)
206209
- `ne_diameter_growth.py`: New module implementing NE-TWIGS iterative BA growth model
207210
- `cs_diameter_growth.py`: New module implementing CS linear DDS equation (same structure as LS)
208-
- `tree.py`: Added variant parameter, variant-specific growth methods (`_grow_large_tree_ls()`, `_grow_large_tree_pn()`, `_grow_large_tree_wc()`, `_grow_large_tree_ne()`, `_grow_large_tree_cs()`)
211+
- `op_diameter_growth.py`: New module implementing ORGANON ln(DG) equation (predicts diameter growth directly, not DDS)
212+
- `tree.py`: Added variant parameter, variant-specific growth methods (`_grow_large_tree_ls()`, `_grow_large_tree_pn()`, `_grow_large_tree_wc()`, `_grow_large_tree_ne()`, `_grow_large_tree_cs()`, `_grow_large_tree_op()`)
209213
- `stand.py`: Added variant parameter, `_calculate_qmd_ge5()` for RELDBH computation
210214
- `height_diameter.py`: Added `VARIANT_COEFFICIENT_FILES` mapping for variant-aware coefficient loading
211215
- Created `cfg/ls/` with 71 configuration files (LS: 67 species)
212216
- Created `cfg/pn/` with coefficient files and species configs (PN: 39 species)
213217
- Created `cfg/wc/` with coefficient files and species configs (WC: 37 species)
214218
- Created `cfg/ne/` with coefficient files and species configs (NE: 108 species)
215219
- Created `cfg/cs/` with coefficient files and species configs (CS: 96 species)
220+
- Created `cfg/op/` with coefficient files and species configs (OP: 18 species) - ORGANON-based variant
221+
29. **LS Variant Infrastructure** - Full infrastructure for Lake States variant:
222+
- `bark_ratio.py`: Added `LSBarkRatioModel` - constant bark ratio per species from Raile (1982)
223+
- `crown_ratio.py`: Added `LSCrownRatioModel` - TWIGS model `ACR=10*(BCR1/(1+BCR2*BA)+BCR3*(1-exp(BCR4*D)))`
224+
- `mortality.py`: Added `LSMortalityModel` - 4-group background mortality with VARADJ shade tolerance
225+
- `volume_library.py`: Added 25+ LS species combined-variable volume coefficients
226+
- `stand_metrics.py`: Added `LS_SDI_MAXIMUMS` dict (67 species)
227+
- Created `cfg/ls/ls_bark_ratio_coefficients.json`, `cfg/ls/ls_crown_ratio_coefficients.json`, `cfg/ls/ls_mortality_coefficients.json`
228+
- 42 tests in `tests/test_ls_variant.py`
229+
30. **PN Variant Infrastructure** - Full infrastructure for Pacific Northwest Coast variant:
230+
- `bark_ratio.py`: Added `PNBarkRatioModel` - 3 equation types (power `DIB=a*DOB^b`, linear `DIB=a+b*DOB`, constant `DIB=a*DOB`), 16 species groups via JBARK
231+
- `crown_ratio.py`: Added `PNCrownRatioModel` - Weibull with linear mean CR, 17 species groups via IMAP, special Redwood logistic equation
232+
- `mortality.py`: PN uses `MortalityModel` (same as SN) with PN-specific SDI maximums
233+
- `volume_library.py`: Added 17+ PNW species (DF, WH, RC, SS, SF, GF, etc.) combined-variable coefficients from Brackett (1977)
234+
- `stand_metrics.py`: Added `PN_SDI_MAXIMUMS` dict (37 species, range 300-1000)
235+
- Created `cfg/pn/pn_bark_ratio_coefficients.json`, `cfg/pn/pn_crown_ratio_coefficients.json`
236+
- 47 tests in `tests/test_pn_variant.py`
237+
- Smoke test: 400 TPA DF SI=120 50yr → 333 TPA, 14.5" QMD, 383 BA, 15,029 cuft
216238

217239
## Recent Refactoring (2025)
218240

219241
### ParameterizedModel Architecture
220242
All growth model classes now inherit from `ParameterizedModel` (`model_base.py`):
221-
- **BarkRatioModel** (`bark_ratio.py`)
243+
- **BarkRatioModel**, **LSBarkRatioModel**, **PNBarkRatioModel** (`bark_ratio.py`)
222244
- **CrownWidthModel** (`crown_width.py`)
223-
- **CrownRatioModel** (`crown_ratio.py`)
245+
- **CrownRatioModel**, **LSCrownRatioModel**, **PNCrownRatioModel** (`crown_ratio.py`)
224246
- **CrownCompetitionFactorModel** (`crown_competition_factor.py`)
225247
- **HeightDiameterModel** (`height_diameter.py`)
226248
- **LargeTreeHeightGrowthModel** (`large_tree_height_growth.py`)
@@ -229,6 +251,7 @@ All growth model classes now inherit from `ParameterizedModel` (`model_base.py`)
229251
- **WCDiameterGrowthModel** (`wc_diameter_growth.py`) - West Cascades variant
230252
- **NEDiameterGrowthModel** (`ne_diameter_growth.py`) - Northeast variant
231253
- **CSDiameterGrowthModel** (`cs_diameter_growth.py`) - Central States variant
254+
- **OPDiameterGrowthModel** (`op_diameter_growth.py`) - ORGANON Pacific Northwest variant
232255

233256
Benefits:
234257
- Standardized coefficient loading from JSON files via `ConfigLoader`
@@ -300,6 +323,7 @@ PyFVS supports multiple FVS regional variants with variant-specific growth equat
300323
| **WC** | West Cascades (OR, WA interior) | 37 | DF (Douglas-fir) | 10 years | ln(DDS) = f(D, CR, RELHT, SI, BA, BAL, elev, slope, aspect) |
301324
| **NE** | Northeast (New England, Mid-Atlantic) | 108 | RM (Red Maple) | 10 years | BA Growth = B1 * SI * (1 - exp(-B2 * DBH)) |
302325
| **CS** | Central States (IL, IN, IA, MO) | 96 | WO (White Oak) | 10 years | ln(DDS) = f(D, CR, RELDBH, SI, BA, BAL) |
326+
| **OP** | ORGANON Pacific Northwest (OR, WA) | 18 | DF (Douglas-fir) | 5 years | ln(DG) = f(D, CR, SI, BA, BAL) - direct diameter growth |
303327

304328
### Key Model Differences
305329

@@ -314,6 +338,11 @@ PyFVS supports multiple FVS regional variants with variant-specific growth equat
314338
- Competition via RELDBH (relative DBH to QMD of trees ≥5" DBH)
315339
- 12 coefficients: INTERC, VDBHC, DBHC, DBH2C, RDBHC, RDBHSQC, CRWNC, CRSQC, SBAC, BALC, SITEC
316340
- Curtis-Arney height-diameter relationship
341+
- **Bark ratio**: Constant per species from Raile (1982)
342+
- **Crown ratio**: TWIGS model `ACR=10*(BCR1/(1+BCR2*BA)+BCR3*(1-exp(BCR4*D)))`
343+
- **Mortality**: 4-group background mortality with VARADJ shade tolerance adjustment
344+
- **Volume**: 25+ LS species with combined-variable equations
345+
- **SDI maximums**: Per-species values (67 species)
317346

318347
**PN (Pacific Northwest Coast) Variant:**
319348
- Uses ln(DDS) transformation like SN but with topographic effects
@@ -322,6 +351,11 @@ PyFVS supports multiple FVS regional variants with variant-specific growth equat
322351
- Major species: Douglas-fir (DF), Western Hemlock (WH), Western Red Cedar (RC), Sitka Spruce (SS)
323352
- Very high productivity region (SI 100-200 feet common)
324353
- Species-specific site index curves for height growth
354+
- **Bark ratio**: 3 equation types (power/linear/constant) from bratio.f, 16 species groups via JBARK mapping
355+
- **Crown ratio**: Weibull distribution with linear mean CR `ACR = C0 + C1 * RELSDI * 100`, 17 species groups via IMAP; Redwood uses logistic equation
356+
- **Mortality**: Uses standard SDI mortality model (same as SN) with PN-specific SDI maximums (DF=850, WH=900, RC=850, SF=1000)
357+
- **Volume**: 17+ PNW species with combined-variable equations from Brackett (1977), Curtis et al.
358+
- **SDI maximums**: Per-species values derived from ecocls.f (range 300-1000)
325359

326360
**WC (West Cascades) Variant:**
327361
- Uses same ln(DDS) equation structure as PN (shares code)
@@ -350,6 +384,18 @@ PyFVS supports multiple FVS regional variants with variant-specific growth equat
350384
- Major species: White Oak (WO), Northern Red Oak (RO), Sugar Maple (SM), Black Walnut (WN), Yellow-Poplar (YP)
351385
- Curtis-Arney height-diameter relationship
352386

387+
**OP (ORGANON Pacific Northwest) Variant:**
388+
- **Key difference: Predicts diameter growth directly**, not DDS (diameter squared increment)
389+
- Based on ORGANON model developed at Oregon State University (Hann et al.)
390+
- Equation: ln(DG) = B0 + B1*ln(DBH+K1) + B2*DBH^K2 + B3*ln((CR+0.2)/1.2) + B4*ln(SI-4.5) + B5*(BAL^K3/ln(DBH+K4)) + B6*sqrt(BA)
391+
- Base cycle is 5 years (like SN)
392+
- 18 species for intensively managed Pacific Northwest plantations
393+
- Major species: Douglas-fir (DF), Western Hemlock (WH), Western Red Cedar (RC), Red Alder (RA)
394+
- Has 4 sub-versions: SWO (Southwest Oregon), NWO (Northwest Oregon), SMC (Stand Management Cooperative), RAP (Red Alder Plantation)
395+
- Calibrated for higher productivity plantation conditions
396+
- Curtis-Arney height-diameter relationship
397+
- Source: Zumrawi & Hann (1993), Hann et al. (2006)
398+
353399
### Variant Usage
354400

355401
```python
@@ -383,7 +429,7 @@ stand_pn = Stand.initialize_planted(
383429
variant='PN' # Pacific Northwest Coast variant
384430
)
385431
stand_pn.grow(years=50)
386-
# Produces ~480 sq ft BA, ~15" QMD, ~18,000 cu ft/acre
432+
# Produces ~383 sq ft BA, ~14.5" QMD, ~15,029 cu ft/acre
387433

388434
# WC variant (West Cascades)
389435
stand_wc = Stand.initialize_planted(
@@ -414,6 +460,16 @@ stand_cs = Stand.initialize_planted(
414460
)
415461
stand_cs.grow(years=50)
416462
# Produces ~209 sq ft BA, ~9.4" QMD (Midwest oak-hickory)
463+
464+
# OP variant (ORGANON Pacific Northwest)
465+
stand_op = Stand.initialize_planted(
466+
trees_per_acre=400,
467+
site_index=120, # High PNW sites SI 100-180
468+
species='DF', # Douglas-fir (OP default)
469+
variant='OP' # ORGANON Pacific Northwest variant
470+
)
471+
stand_op.grow(years=50)
472+
# Produces ~590 sq ft BA, ~18.5" QMD (intensive plantation)
417473
```
418474

419475
### Adding New Variants
@@ -424,6 +480,11 @@ To add a new FVS variant:
424480
3. Add variant-specific logic to `tree.py` growth methods
425481
4. Update `HeightDiameterModel` with variant coefficient file mapping
426482
5. Create species configs in `cfg/<variant>/species/`
483+
6. Add variant bark ratio model to `bark_ratio.py` and update `create_bark_ratio_model()` factory
484+
7. Add variant crown ratio model to `crown_ratio.py` and update `create_crown_ratio_model()` factory
485+
8. Add variant SDI maximums to `stand_metrics.py` and update `_get_sdi_maximums()`
486+
9. Add variant mortality dispatch in `mortality.py:create_mortality_model()`
487+
10. Add variant species volume coefficients to `volume_library.py`
427488

428489
## Ecological Unit Effects on Growth
429490

@@ -524,7 +585,9 @@ See `test_output/manuscript_validation/` for validation reports
524585
3. ~~**ParameterizedModel Refactoring**~~ **DONE** - All growth models inherit from base class (see Recent Refactoring 2025)
525586
4. ~~**GrowthParameters Dataclass**~~ **DONE** - Encapsulates tree growth inputs (see Recently Fixed #23)
526587
5. ~~**SpeciesCode Enum**~~ **DONE** - Type-safe species handling (see Recently Fixed #24)
527-
6. ~~**Multi-Variant Support**~~ **DONE** - 6 variants implemented: SN (90), LS (67), PN (39), WC (37), NE (108), CS (96 species) - Eastern variants 100% complete - see Recently Fixed #28
588+
6. ~~**Multi-Variant Support**~~ **DONE** - 7 variants implemented: SN (90), LS (67), PN (39), WC (37), NE (108), CS (96), OP (18 species) - see Recently Fixed #28
589+
7. ~~**LS Variant Infrastructure**~~ **DONE** - Bark ratio, crown ratio, mortality, volume, SDI maximums (42 tests)
590+
8. ~~**PN Variant Infrastructure**~~ **DONE** - Bark ratio (3 eq types), crown ratio (Weibull+Redwood logistic), mortality, volume (17+ species), SDI maximums (47 tests)
528591

529592
### Testing & Validation
530593
1. ~~Re-run manuscript validation tests with appropriate ecounit settings~~ **DONE**

0 commit comments

Comments
 (0)