crop_params¶
Crop-specific parameters for Lintul5.
This module ports the constant crop-level inputs of the SIMPLACE Lintul5
component family (Lintul5.java, Phenology.java,
RadiationUseEfficiency.java) to a single PyTorch-friendly dataclass.
All scalar fields are stored as torch.Tensor so they can be made
learnable by wrapping them with torch.nn.Parameter. Table fields
(..._tb / ..._table) carry shape [N, 2] (or [B, N, 2] if the
table itself is batch-varying), where column 0 is the abscissa (DVS or
temperature) and column 1 is the value. Tables are interpolated by
torchcrop.functions.interpolate.
Naming conventions:
* Field names follow the original Lintul5 (Wolf, 2012) symbol,
lowercased.
* Constants prefixed with c in SIMPLACE drop the c prefix here.
* Tables originally named cXxxTableY are concatenated into a single
two-column tensor named xxx_tb (or xxx_table).
References
Wolf, J. (2012). User guide for LINTUL5. Wageningen UR.
CropParameters
dataclass
¶
Species-specific Lintul5 crop parameters.
Scalar fields have shape [] or [B] (broadcastable against the
batch dimension). Table fields have shape [N, 2] or [B, N, 2].
Default values reproduce the SIMPLACE Lintul5 defaults (wheat-like).
Source code in torchcrop/parameters/crop_params.py
@dataclass
class CropParameters:
"""Species-specific Lintul5 crop parameters.
Scalar fields have shape ``[]`` or ``[B]`` (broadcastable against the
batch dimension). Table fields have shape ``[N, 2]`` or ``[B, N, 2]``.
Default values reproduce the SIMPLACE Lintul5 defaults (wheat-like).
"""
# ------------------------------------------------------------------ #
# 1. Phenology (from Phenology.java)
# ------------------------------------------------------------------ #
idsl: torch.Tensor = field(default_factory=lambda: _t(0.0))
"""``cIDSL``. Phenology mode selector:
``0`` → temperature only; ``1`` → temperature + day length;
``2`` → temperature + day length + vernalisation. Stored as float so it
can be used in differentiable masking; cast to int for branching."""
tbasem: torch.Tensor = field(default_factory=lambda: _t(0.0))
"""``cTBASEM``. Lower threshold (base) temperature [°C] for
accumulation of temperature sum **before** crop emergence."""
teffmx: torch.Tensor = field(default_factory=lambda: _t(30.0))
"""``cTEFFMX``. Maximum effective temperature [°C] used when
accumulating temperature sum **before** emergence (caps TEFF)."""
tsumem: torch.Tensor = field(default_factory=lambda: _t(110.0))
"""``cTSUMEM``. Required temperature sum [°C·d] from sowing to
emergence."""
tsum1: torch.Tensor = field(default_factory=lambda: _t(900.0))
"""``cTSUM1``. Required temperature sum [°C·d] from emergence to
flowering / anthesis (vegetative period, DVS 0 → 1)."""
tsum2: torch.Tensor = field(default_factory=lambda: _t(700.0))
"""``cTSUM2``. Required temperature sum [°C·d] from anthesis to
maturity (generative period, DVS 1 → 2)."""
tsum_branching: torch.Tensor = field(default_factory=lambda: _t(700.0))
"""``cTSUMBranching``. Optional temperature sum [°C·d] from emergence
to branching (used by some calibrations; ignored otherwise)."""
tsum_milkripeness: torch.Tensor = field(default_factory=lambda: _t(700.0))
"""``cTSUMMilkripeness``. Optional temperature sum [°C·d] from
anthesis to milk-ripeness."""
dvsi: torch.Tensor = field(default_factory=lambda: _t(0.0))
"""``cDVSI``. Initial development stage of the crop at the start of
the simulation (in the range ``0`` … ``2``)."""
dtsmtb: torch.Tensor = field(
default_factory=lambda: _table(
[(-5.0, 0.0), (0.0, 0.0), (30.0, 30.0), (45.0, 30.0)]
)
)
"""``cDTSMTB`` (= ``cTsumIncrementTableMeanTemp`` × ``cTsumIncrementTableRate``).
Daily increment of temperature sum [°C·d] as a function of mean daily
air temperature [°C]. Shape ``[N, 2]`` with x = T̄, y = ΔTsum/d."""
phottb: torch.Tensor = field(
default_factory=lambda: _table(
[(0.0, 0.0), (8.0, 1.0), (12.0, 1.0), (18.0, 1.0)]
)
)
"""``cPHOTTB`` (= ``cPhotoperiodTableHour`` × ``cPhotoperiodTableFactor``).
Photoperiod reduction factor [-] of development rate (until anthesis)
as a function of day length [h]."""
vernrt: torch.Tensor = field(
default_factory=lambda: _table([(0.0, 1.0), (1.0, 1.0)])
)
"""``cVERNRT`` (= ``cVernalisationTableMeanTemp`` × ``cVernalisationTableRate``).
Daily vernal-day rate [-] as a function of mean daily temperature [°C].
Used only when `idsl` ≥ 2."""
vbase: torch.Tensor = field(default_factory=lambda: _t(0.0))
"""``cVBASE``. Vernalisation base [thermal day]: vernal days
accumulated below this value contribute nothing to the vernalisation
factor."""
versat: torch.Tensor = field(default_factory=lambda: _t(0.0))
"""``cVERSAT``. Vernalisation saturation [thermal day]: number of
vernal days above which the vernalisation factor is fully released
(=1)."""
vernalisation_devstage: torch.Tensor = field(default_factory=lambda: _t(0.3))
"""``cVernalisationDevStage``. Maximum DVS [-] up to which the
vernalisation factor is applied; beyond this stage VERNFAC = 1."""
minimal_vernalisation_factor: torch.Tensor = field(default_factory=lambda: _t(0.0))
"""``cMinimalVernalisationFactor``. Lower bound [0–1] on the
vernalisation factor used to limit pheno-rate suppression."""
# ------------------------------------------------------------------ #
# 2. Radiation use efficiency / RUE (from RadiationUseEfficiency.java)
# ------------------------------------------------------------------ #
co2: torch.Tensor = field(default_factory=lambda: _t(360.0))
"""``cCO``. Atmospheric CO₂ concentration [ppm] used both as input to
the RUE CO₂ correction (`cotb`) and the ET₀ CO₂ correction.
Default is the original Lintul5 reference."""
day_temp_factor: torch.Tensor = field(default_factory=lambda: _t(0.25))
"""``cDayTempFactor``. Weight ``f`` in
``T_day = TMAX − f·(TMAX − TMIN)`` used to derive a *daytime* mean
temperature from min/max. ``f = 0.25`` → daytime mean (default);
``f = 0.5`` → 24-h mean."""
rue: torch.Tensor = field(default_factory=lambda: _t(3.0))
"""``cRUETableRUE`` (scalar surrogate). Reference radiation use
efficiency [g DM · MJ⁻¹ PAR] used when `ruetb` is omitted.
Lintul5 wheat default is 3.0 g · MJ⁻¹."""
ruetb: torch.Tensor = field(
default_factory=lambda: _table(
[(0.0, 3.0), (1.0, 3.0), (1.3, 3.0), (2.0, 0.4)]
)
)
"""``cRUETB`` (= ``cRUETableDVS`` × ``cRUETableRUE``). Radiation use
efficiency [g DM · MJ⁻¹ PAR] as a function of DVS (declines after
grain filling)."""
tmpftb: torch.Tensor = field(
default_factory=lambda: _table(
[
(-1.0, 0.0),
(0.0, 0.0),
(10.0, 0.6),
(15.0, 1.0),
(30.0, 1.0),
(35.0, 0.0),
(40.0, 0.0),
]
)
)
"""``cTMPFTB``. RUE reduction factor [-] as a function of mean daytime
temperature [°C] (high- and low-temperature stress)."""
tmnftb: torch.Tensor = field(
default_factory=lambda: _table(
[(-5.0, 0.0), (0.0, 0.0), (3.0, 1.0), (30.0, 1.0)]
)
)
"""``cTMNFTB``. RUE reduction factor [-] as a function of daily
minimum temperature [°C] (cold-night stress)."""
cotb: torch.Tensor = field(
default_factory=lambda: _table(
[(40.0, 0.0), (360.0, 1.0), (720.0, 1.35), (1000.0, 1.50), (2000.0, 1.50)]
)
)
"""``cCOTB``. CO₂ correction factor [-] applied to RUE as a function of
atmospheric CO₂ concentration [ppm]."""
scale_factor_rue: torch.Tensor = field(default_factory=lambda: _t(1.0))
"""``cScaleFactorRUE``. Multiplicative scale factor on the y-values of
`ruetb` for sensitivity analysis / calibration."""
# ------------------------------------------------------------------ #
# 3. Light interception / canopy (from Lintul5.java)
# ------------------------------------------------------------------ #
k: torch.Tensor = field(default_factory=lambda: _t(0.60))
"""Effective canopy light extinction coefficient [-]; scalar fallback
when `kdiftb` is collapsed to a constant."""
kdiftb: torch.Tensor = field(
default_factory=lambda: _table([(0.0, 0.6), (2.0, 0.6)])
)
"""``cKDIFTB``. Extinction coefficient [-] for diffuse PAR as a
function of DVS."""
scale_factor_kdif: torch.Tensor = field(default_factory=lambda: _t(1.0))
"""``cScaleFactorKDIF``. Scale factor on `kdiftb` y-values."""
laicr: torch.Tensor = field(default_factory=lambda: _t(4.0))
"""``cLAICR``. Critical leaf area index [m² m⁻²] above which leaves
suffer self-shading mortality."""
# ------------------------------------------------------------------ #
# 4. Initial biomass and rooting (from Lintul5.java)
# ------------------------------------------------------------------ #
tdwi: torch.Tensor = field(default_factory=lambda: _t(210.0))
"""``cTDWI``. Initial total crop dry weight [g DM m⁻²] at sowing /
emergence; partitioned to organs via the partitioning tables."""
rdi: torch.Tensor = field(default_factory=lambda: _t(0.10))
"""``cRDI``. Initial rooting depth [m] (also used by WaterBalance)."""
rri: torch.Tensor = field(default_factory=lambda: _t(0.012))
"""``cRRI``. Maximum daily increase in rooting depth [m d⁻¹]."""
rdmcr: torch.Tensor = field(default_factory=lambda: _t(1.20))
"""``cRDMCR``. Crop-specific maximum rooting depth [m]."""
rwrti: torch.Tensor = field(default_factory=lambda: _t(0.0))
"""``cRWRTI``. Initial change in living root biomass
[g DM m⁻² d⁻¹]."""
# ------------------------------------------------------------------ #
# 5. Leaf dynamics & senescence (from Lintul5.java)
# ------------------------------------------------------------------ #
sla: torch.Tensor = field(default_factory=lambda: _t(0.0212))
"""Reference specific leaf area [m² leaf · g⁻¹ DM]; scalar fallback
used when `slatb` is collapsed."""
slatb: torch.Tensor = field(
default_factory=lambda: _table([(0.0, 0.0212), (2.0, 0.0212)])
)
"""``cSLATB``. Specific leaf area [m² g⁻¹] as a function of DVS."""
scale_factor_sla: torch.Tensor = field(default_factory=lambda: _t(1.0))
"""``cScaleFactorSLA``. Scale factor on `slatb` y-values."""
laii: torch.Tensor = field(default_factory=lambda: _t(0.012))
"""``LAII`` initial leaf area index [m² m⁻²] at emergence (Lintul5
output, persisted here as a parameter for re-init)."""
rgrl: torch.Tensor = field(default_factory=lambda: _t(0.009))
"""``cRGRLAI``. Maximum relative increase in LAI [d⁻¹] during the
juvenile (exponential) phase."""
tbase: torch.Tensor = field(default_factory=lambda: _t(0.0))
"""``cTBASE``. Lower threshold temperature [°C] for LAI increase."""
rdrshm: torch.Tensor = field(default_factory=lambda: _t(0.03))
"""``cRDRSHM``. Maximum relative death rate of leaves [d⁻¹] caused by
shading when LAI > `laicr`."""
rdrl: torch.Tensor = field(default_factory=lambda: _t(0.05))
"""``cRDRL``. Maximum relative death rate of leaves [d⁻¹] due to
water stress."""
rdrns: torch.Tensor = field(default_factory=lambda: _t(0.05))
"""``cRDRNS``. Maximum relative death rate of leaves [d⁻¹] due to
NPK (nutrient) stress."""
rdrltb: torch.Tensor = field(
default_factory=lambda: _table(
[(-10.0, 0.0), (10.0, 0.02), (15.0, 0.03), (30.0, 0.05), (50.0, 0.09)]
)
)
"""``cRDRLTB``. Relative death rate of leaves [d⁻¹] as a function of
mean daily temperature [°C] (heat-stress curve)."""
rdrrtb: torch.Tensor = field(
default_factory=lambda: _table(
[(0.0, 0.0), (1.5, 0.0), (1.5001, 0.02), (2.0, 0.02)]
)
)
"""``cRDRRTB``. Relative death rate of roots [d⁻¹] as a function of
DVS."""
rdrstb: torch.Tensor = field(
default_factory=lambda: _table(
[(0.0, 0.0), (1.5, 0.0), (1.5001, 0.02), (2.0, 0.02)]
)
)
"""``cRDRSTB``. Relative death rate of stems [d⁻¹] as a function of
DVS."""
scale_factor_rdr_leaves: torch.Tensor = field(default_factory=lambda: _t(1.0))
"""``cScaleFactorRDRLeaves``. Scale factor on `rdrltb`."""
scale_factor_rdr_stems: torch.Tensor = field(default_factory=lambda: _t(1.0))
"""``cScaleFactorRDRStems``. Scale factor on `rdrstb`."""
scale_factor_rdr_roots: torch.Tensor = field(default_factory=lambda: _t(1.0))
"""``cScaleFactorRDRRoots``. Scale factor on `rdrrtb`."""
# ------------------------------------------------------------------ #
# 6. Biomass partitioning (from Lintul5.java)
# ------------------------------------------------------------------ #
frtb: torch.Tensor = field(
default_factory=lambda: _table(
[
(0.0, 0.50),
(0.1, 0.50),
(0.2, 0.40),
(0.35, 0.22),
(0.4, 0.17),
(0.5, 0.13),
(0.7, 0.07),
(0.9, 0.03),
(1.2, 0.0),
(2.0, 0.0),
]
)
)
"""``cFRTB``. Fraction of total daily DM growth allocated to **roots**
as a function of DVS. The remainder (``1 − FR``) is split among leaves,
stems and storage organs by ``FLTB``, ``FSTB``, ``FOTB``."""
fltb: torch.Tensor = field(
default_factory=lambda: _table(
[
(0.0, 0.65),
(0.1, 0.65),
(0.25, 0.70),
(0.5, 0.50),
(0.646, 0.30),
(0.95, 0.0),
(2.0, 0.0),
]
)
)
"""``cFLTB``. Fraction of above-ground DM allocated to **leaves** as a
function of DVS."""
fstb: torch.Tensor = field(
default_factory=lambda: _table(
[
(0.0, 0.35),
(0.1, 0.35),
(0.25, 0.30),
(0.5, 0.50),
(0.646, 0.70),
(0.95, 1.0),
(1.0, 0.0),
(2.0, 0.0),
]
)
)
"""``cFSTB``. Fraction of above-ground DM allocated to **stems** as a
function of DVS."""
fotb: torch.Tensor = field(
default_factory=lambda: _table(
[(0.0, 0.0), (0.95, 0.0), (1.0, 1.0), (2.0, 1.0)]
)
)
"""``cFOTB``. Fraction of above-ground DM allocated to **storage
organs** as a function of DVS."""
# ------------------------------------------------------------------ #
# 7. NPK demand and concentration limits (from Lintul5.java)
# ------------------------------------------------------------------ #
nmxlv: torch.Tensor = field(
default_factory=lambda: _table(
[(0.0, 0.06), (0.4, 0.04), (0.7, 0.03), (1.0, 0.02), (2.0, 0.014), (2.1, 0.017)]
)
)
"""``cNMXLV``. Maximum N concentration in leaves [g N · g⁻¹ DM] as a
function of DVS. Drives N demand and the N nutrition index NNI."""
pmxlv: torch.Tensor = field(
default_factory=lambda: _table(
[(0.0, 0.011), (0.4, 0.008), (0.7, 0.006), (1.0, 0.004), (2.0, 0.0027), (2.1, 0.0027)]
)
)
"""``cPMXLV``. Maximum P concentration in leaves [g P · g⁻¹ DM] vs
DVS."""
kmxlv: torch.Tensor = field(
default_factory=lambda: _table(
[(0.0, 0.12), (0.4, 0.08), (0.7, 0.06), (1.0, 0.04), (2.0, 0.028), (2.1, 0.028)]
)
)
"""``cKMXLV``. Maximum K concentration in leaves [g K · g⁻¹ DM] vs
DVS."""
nmaxso: torch.Tensor = field(default_factory=lambda: _t(0.0176))
"""``cNMAXSO``. Maximum N concentration [g N · g⁻¹ DM] in storage
organs."""
pmaxso: torch.Tensor = field(default_factory=lambda: _t(0.0026))
"""``cPMAXSO``. Maximum P concentration in storage organs."""
kmaxso: torch.Tensor = field(default_factory=lambda: _t(0.0048))
"""``cKMAXSO``. Maximum K concentration in storage organs."""
lrnr: torch.Tensor = field(default_factory=lambda: _t(0.5))
"""``cLRNR``. Maximum N concentration in **roots** expressed as a
fraction of the maximum N concentration in leaves [-]."""
lrpr: torch.Tensor = field(default_factory=lambda: _t(0.5))
"""``cLRPR``. As `lrnr` but for P."""
lrkr: torch.Tensor = field(default_factory=lambda: _t(0.5))
"""``cLRKR``. As `lrnr` but for K."""
lsnr: torch.Tensor = field(default_factory=lambda: _t(0.5))
"""``cLSNR``. Maximum N concentration in **stems** as a fraction of
the maximum N concentration in leaves [-]."""
lspr: torch.Tensor = field(default_factory=lambda: _t(0.5))
"""``cLSPR``. As `lsnr` but for P."""
lskr: torch.Tensor = field(default_factory=lambda: _t(0.5))
"""``cLSKR``. As `lsnr` but for K."""
frnx: torch.Tensor = field(default_factory=lambda: _t(1.0))
"""``cFRNX``. Optimal N concentration as a fraction of the maximum N
concentration [-] — controls the N stress index NNI."""
frpx: torch.Tensor = field(default_factory=lambda: _t(1.0))
"""``cFRPX``. Optimal P concentration as a fraction of maximum P [-]."""
frkx: torch.Tensor = field(default_factory=lambda: _t(1.0))
"""``cFRKX``. Optimal K concentration as a fraction of maximum K [-]."""
rnflv: torch.Tensor = field(default_factory=lambda: _t(0.004))
"""``cRNFLV``. Residual (non-translocatable) N concentration in
leaves [g N · g⁻¹ DM]."""
rnfst: torch.Tensor = field(default_factory=lambda: _t(0.002))
"""``cRNFST``. Residual N concentration in stems."""
rnfrt: torch.Tensor = field(default_factory=lambda: _t(0.002))
"""``cRNFRT``. Residual N concentration in roots."""
rpflv: torch.Tensor = field(default_factory=lambda: _t(0.0005))
"""``cRPFLV``. Residual P concentration in leaves."""
rpfst: torch.Tensor = field(default_factory=lambda: _t(0.0003))
"""``cRPFST``. Residual P concentration in stems."""
rpfrt: torch.Tensor = field(default_factory=lambda: _t(0.0003))
"""``cRPFRT``. Residual P concentration in roots."""
rkflv: torch.Tensor = field(default_factory=lambda: _t(0.009))
"""``cRKFLV``. Residual K concentration in leaves."""
rkfst: torch.Tensor = field(default_factory=lambda: _t(0.005))
"""``cRKFST``. Residual K concentration in stems."""
rkfrt: torch.Tensor = field(default_factory=lambda: _t(0.005))
"""``cRKFRT``. Residual K concentration in roots."""
fntrt: torch.Tensor = field(default_factory=lambda: _t(0.15))
"""``cFNTRT``. NPK translocation from **roots** expressed as a
fraction of the total NPK translocated from leaves and stems [-]."""
tcnt: torch.Tensor = field(default_factory=lambda: _t(10.0))
"""``cTCNT``. Time constant [d] for N translocation to storage
organs (first-order kinetics)."""
tcpt: torch.Tensor = field(default_factory=lambda: _t(10.0))
"""``cTCPT``. Time constant [d] for P translocation to storage
organs."""
tckt: torch.Tensor = field(default_factory=lambda: _t(10.0))
"""``cTCKT``. Time constant [d] for K translocation to storage
organs."""
nfixf: torch.Tensor = field(default_factory=lambda: _t(0.0))
"""``cNFIXF``. Fraction of crop N uptake supplied by biological N₂
fixation [-]; > 0 for legumes."""
# ------------------------------------------------------------------ #
# 8. Stress sensitivities (from Lintul5.java)
# ------------------------------------------------------------------ #
nlue: torch.Tensor = field(default_factory=lambda: _t(1.1))
"""``cNLUE``. Coefficient of the reduction of RUE due to NPK
(nutrient) stress."""
nlai: torch.Tensor = field(default_factory=lambda: _t(1.0))
"""``cNLAI``. Coefficient of the reduction of LAI growth (juvenile
phase) due to nutrient stress."""
nsla: torch.Tensor = field(default_factory=lambda: _t(0.5))
"""``cNSLA``. Coefficient of the reduction of SLA due to nutrient
stress."""
npart: torch.Tensor = field(default_factory=lambda: _t(1.0))
"""``cNPART``. Coefficient of the N-stress effect on leaf biomass
reduction (re-allocation away from leaves under N deficiency)."""
# ------------------------------------------------------------------ #
# 9. DVS thresholds for NPK dynamics (from Lintul5.java)
# ------------------------------------------------------------------ #
dvsnt: torch.Tensor = field(default_factory=lambda: _t(0.8))
"""``cDVSNT``. DVS above which N, P and K **translocation** to
storage organs occurs."""
dvsnlt: torch.Tensor = field(default_factory=lambda: _t(1.3))
"""``cDVSNLT``. DVS above which crop **uptake** of N, P and K stops."""
dvsdr: torch.Tensor = field(default_factory=lambda: _t(1.0))
"""``cDVSDR``. DVS above which death of roots and stems begins."""
dvsdlt: torch.Tensor = field(default_factory=lambda: _t(1.0))
"""``cDVSDLT``. DVS above which leaf death (controlled by mean
temperature, see `rdrltb`) begins."""
# ------------------------------------------------------------------ #
# 10. Fertiliser application & recovery (from Lintul5.java)
# ------------------------------------------------------------------ #
nrf: torch.Tensor = field(default_factory=lambda: _t(0.7))
"""``cNRF``. Default recovery fraction [0–1] of applied fertiliser N
(used when no day-resolved `nrftab` is provided)."""
prf: torch.Tensor = field(default_factory=lambda: _t(0.2))
"""``cPRF``. Default recovery fraction [0–1] of applied fertiliser P."""
krf: torch.Tensor = field(default_factory=lambda: _t(0.6))
"""``cKRF``. Default recovery fraction [0–1] of applied fertiliser K."""
nrftab: torch.Tensor | None = None
"""``cNRFTAB``. Optional day-resolved table of N fertiliser recovery
fractions [-] (shape ``[N, 2]``: x = day, y = fraction)."""
prftab: torch.Tensor | None = None
"""``cPRFTAB``. Optional day-resolved table of P recovery fractions."""
krftab: torch.Tensor | None = None
"""``cKRFTAB``. Optional day-resolved table of K recovery fractions."""
ferntab: torch.Tensor | None = None
"""``cFERNTAB``. Optional table of N fertiliser applications
[g N · m⁻² · d⁻¹] at given calendar days. Shape ``[N, 2]``."""
ferptab: torch.Tensor | None = None
"""``cFERPTAB``. Optional table of P fertiliser applications."""
ferktab: torch.Tensor | None = None
"""``cFERKTAB``. Optional table of K fertiliser applications."""
scale_factor_fern: torch.Tensor = field(default_factory=lambda: _t(1.0))
"""``cScaleFactorFERN``. Scale factor on `ferntab` y-values."""
scale_factor_ferp: torch.Tensor = field(default_factory=lambda: _t(1.0))
"""``cScaleFactorFERP``. Scale factor on `ferptab` y-values."""
scale_factor_ferk: torch.Tensor = field(default_factory=lambda: _t(1.0))
"""``cScaleFactorFERK``. Scale factor on `ferktab` y-values."""
# ------------------------------------------------------------------ #
# 11. Run-control flags (from Lintul5.java)
# ------------------------------------------------------------------ #
iopt: torch.Tensor = field(default_factory=lambda: _t(1.0))
"""``cIOPT``. Run mode selector:
``1`` → optimal (no stresses), ``2`` → water-limited,
``3`` → water + N limited, ``4`` → water + N + P + K limited.
Stored as float so it can be used in masking; cast to int for branching."""
# ------------------------------------------------------------------ #
# 12. Scaffold convenience scalars
# ------------------------------------------------------------------ #
# The fields below are simplified scalar surrogates used by the v0.0.1
# process scaffold (single-value alternatives to the SIMPLACE
# interpolation tables / fraction-based per-organ derivations above).
# They are retained so existing process modules keep importing while
# the table-based equations are progressively wired in.
# ------------------------------------------------------------------ #
rootdi: torch.Tensor = field(default_factory=lambda: _t(0.10))
"""Scaffold alias of `rdi` — initial rooting depth [m]."""
rootdm: torch.Tensor = field(default_factory=lambda: _t(1.20))
"""Scaffold alias of `rdmcr` — maximum rooting depth [m]."""
rrdmax: torch.Tensor = field(default_factory=lambda: _t(0.012))
"""Scaffold alias of `rri` — maximum daily root-depth growth
rate [m d⁻¹]."""
rdrtb: torch.Tensor = field(
default_factory=lambda: _table(
[(0.0, 0.0), (1.0, 0.0), (1.5, 0.02), (2.0, 0.05)]
)
)
"""Simplified DVS-indexed leaf relative-death-rate table [d⁻¹] used
by `LeafDynamics` for developmental senescence. Not a direct
SIMPLACE constant (SIMPLACE separates leaf senescence into
`rdrltb` (vs T), `rdrrtb` and `rdrstb` (vs DVS))."""
nmaxlv: torch.Tensor = field(default_factory=lambda: _t(0.050))
"""Scalar max N concentration in leaves [g N · g⁻¹ DM] (scaffold
surrogate of `nmxlv` table)."""
nmaxst: torch.Tensor = field(default_factory=lambda: _t(0.020))
"""Scalar max N concentration in stems (≈ ``lsnr × nmaxlv``)."""
nmaxrt: torch.Tensor = field(default_factory=lambda: _t(0.015))
"""Scalar max N concentration in roots (≈ ``lrnr × nmaxlv``)."""
pmaxlv: torch.Tensor = field(default_factory=lambda: _t(0.008))
"""Scalar max P concentration in leaves (scaffold surrogate of
`pmxlv` table)."""
pmaxst: torch.Tensor = field(default_factory=lambda: _t(0.004))
"""Scalar max P concentration in stems (≈ ``lspr × pmaxlv``)."""
pmaxrt: torch.Tensor = field(default_factory=lambda: _t(0.003))
"""Scalar max P concentration in roots (≈ ``lrpr × pmaxlv``)."""
kmaxlv: torch.Tensor = field(default_factory=lambda: _t(0.040))
"""Scalar max K concentration in leaves (scaffold surrogate of
`kmxlv` table)."""
kmaxst: torch.Tensor = field(default_factory=lambda: _t(0.025))
"""Scalar max K concentration in stems (≈ ``lskr × kmaxlv``)."""
kmaxrt: torch.Tensor = field(default_factory=lambda: _t(0.015))
"""Scalar max K concentration in roots (≈ ``lrkr × kmaxlv``)."""
nresid: torch.Tensor = field(default_factory=lambda: _t(0.004))
"""Aggregated residual N concentration [g N · g⁻¹ DM] used by the
scaffold (compare per-organ `rnflv`/`rnfst`/`rnfrt`)."""
presid: torch.Tensor = field(default_factory=lambda: _t(0.001))
"""Aggregated residual P concentration."""
kresid: torch.Tensor = field(default_factory=lambda: _t(0.005))
"""Aggregated residual K concentration."""
tmpf_tb: torch.Tensor = field(
default_factory=lambda: _table(
[(-10.0, 0.0), (0.0, 0.0), (10.0, 0.6), (20.0, 1.0), (30.0, 1.0), (40.0, 0.0)]
)
)
"""Scaffold alias of `tmpftb` (T-response of RUE) used by the
current `Photosynthesis` module. Will be merged with
`tmpftb` once the full SIMPLACE RUE chain is wired in."""
# ------------------------------------------------------------------ #
# Helpers
# ------------------------------------------------------------------ #
def to(
self,
dtype: torch.dtype | None = None,
device: torch.device | str | None = None,
) -> "CropParameters":
"""Cast and/or move all tensor fields to a new dtype/device.
Args:
dtype: Target tensor dtype, or ``None`` to leave unchanged.
device: Target torch device, or ``None`` to leave unchanged.
Returns:
A new `CropParameters` with every tensor field moved /
cast; non-tensor fields (e.g., optional tables set to ``None``)
are copied through unchanged.
"""
kwargs: dict[str, Any] = {}
for f in fields(self):
t = getattr(self, f.name)
if isinstance(t, torch.Tensor):
kwargs[f.name] = t.to(dtype=dtype, device=device)
else:
kwargs[f.name] = t
return CropParameters(**kwargs)
co2: Tensor
dataclass-field
¶
cCO. Atmospheric CO₂ concentration [ppm] used both as input to
the RUE CO₂ correction (cotb) and the ET₀ CO₂ correction.
Default is the original Lintul5 reference.
cotb: Tensor
dataclass-field
¶
cCOTB. CO₂ correction factor [-] applied to RUE as a function of
atmospheric CO₂ concentration [ppm].
day_temp_factor: Tensor
dataclass-field
¶
cDayTempFactor. Weight f in
T_day = TMAX − f·(TMAX − TMIN) used to derive a daytime mean
temperature from min/max. f = 0.25 → daytime mean (default);
f = 0.5 → 24-h mean.
dtsmtb: Tensor
dataclass-field
¶
cDTSMTB (= cTsumIncrementTableMeanTemp × cTsumIncrementTableRate).
Daily increment of temperature sum [°C·d] as a function of mean daily
air temperature [°C]. Shape [N, 2] with x = T̄, y = ΔTsum/d.
dvsdlt: Tensor
dataclass-field
¶
cDVSDLT. DVS above which leaf death (controlled by mean
temperature, see rdrltb) begins.
dvsdr: Tensor
dataclass-field
¶
cDVSDR. DVS above which death of roots and stems begins.
dvsi: Tensor
dataclass-field
¶
cDVSI. Initial development stage of the crop at the start of
the simulation (in the range 0 … 2).
dvsnlt: Tensor
dataclass-field
¶
cDVSNLT. DVS above which crop uptake of N, P and K stops.
dvsnt: Tensor
dataclass-field
¶
cDVSNT. DVS above which N, P and K translocation to
storage organs occurs.
ferktab: torch.Tensor | None
dataclass-field
¶
cFERKTAB. Optional table of K fertiliser applications.
ferntab: torch.Tensor | None
dataclass-field
¶
cFERNTAB. Optional table of N fertiliser applications
[g N · m⁻² · d⁻¹] at given calendar days. Shape [N, 2].
ferptab: torch.Tensor | None
dataclass-field
¶
cFERPTAB. Optional table of P fertiliser applications.
fltb: Tensor
dataclass-field
¶
cFLTB. Fraction of above-ground DM allocated to leaves as a
function of DVS.
fntrt: Tensor
dataclass-field
¶
cFNTRT. NPK translocation from roots expressed as a
fraction of the total NPK translocated from leaves and stems [-].
fotb: Tensor
dataclass-field
¶
cFOTB. Fraction of above-ground DM allocated to storage
organs as a function of DVS.
frkx: Tensor
dataclass-field
¶
cFRKX. Optimal K concentration as a fraction of maximum K [-].
frnx: Tensor
dataclass-field
¶
cFRNX. Optimal N concentration as a fraction of the maximum N
concentration [-] — controls the N stress index NNI.
frpx: Tensor
dataclass-field
¶
cFRPX. Optimal P concentration as a fraction of maximum P [-].
frtb: Tensor
dataclass-field
¶
cFRTB. Fraction of total daily DM growth allocated to roots
as a function of DVS. The remainder (1 − FR) is split among leaves,
stems and storage organs by FLTB, FSTB, FOTB.
fstb: Tensor
dataclass-field
¶
cFSTB. Fraction of above-ground DM allocated to stems as a
function of DVS.
idsl: Tensor
dataclass-field
¶
cIDSL. Phenology mode selector:
0 → temperature only; 1 → temperature + day length;
2 → temperature + day length + vernalisation. Stored as float so it
can be used in differentiable masking; cast to int for branching.
iopt: Tensor
dataclass-field
¶
cIOPT. Run mode selector:
1 → optimal (no stresses), 2 → water-limited,
3 → water + N limited, 4 → water + N + P + K limited.
Stored as float so it can be used in masking; cast to int for branching.
k: Tensor
dataclass-field
¶
Effective canopy light extinction coefficient [-]; scalar fallback
when kdiftb is collapsed to a constant.
kdiftb: Tensor
dataclass-field
¶
cKDIFTB. Extinction coefficient [-] for diffuse PAR as a
function of DVS.
kmaxlv: Tensor
dataclass-field
¶
Scalar max K concentration in leaves (scaffold surrogate of
kmxlv table).
kmaxrt: Tensor
dataclass-field
¶
Scalar max K concentration in roots (≈ lrkr × kmaxlv).
kmaxso: Tensor
dataclass-field
¶
cKMAXSO. Maximum K concentration in storage organs.
kmaxst: Tensor
dataclass-field
¶
Scalar max K concentration in stems (≈ lskr × kmaxlv).
kmxlv: Tensor
dataclass-field
¶
cKMXLV. Maximum K concentration in leaves [g K · g⁻¹ DM] vs
DVS.
kresid: Tensor
dataclass-field
¶
Aggregated residual K concentration.
krf: Tensor
dataclass-field
¶
cKRF. Default recovery fraction [0–1] of applied fertiliser K.
krftab: torch.Tensor | None
dataclass-field
¶
cKRFTAB. Optional day-resolved table of K recovery fractions.
laicr: Tensor
dataclass-field
¶
cLAICR. Critical leaf area index [m² m⁻²] above which leaves
suffer self-shading mortality.
laii: Tensor
dataclass-field
¶
LAII initial leaf area index [m² m⁻²] at emergence (Lintul5
output, persisted here as a parameter for re-init).
lrkr: Tensor
dataclass-field
¶
cLRKR. As lrnr but for K.
lrnr: Tensor
dataclass-field
¶
cLRNR. Maximum N concentration in roots expressed as a
fraction of the maximum N concentration in leaves [-].
lrpr: Tensor
dataclass-field
¶
cLRPR. As lrnr but for P.
lskr: Tensor
dataclass-field
¶
cLSKR. As lsnr but for K.
lsnr: Tensor
dataclass-field
¶
cLSNR. Maximum N concentration in stems as a fraction of
the maximum N concentration in leaves [-].
lspr: Tensor
dataclass-field
¶
cLSPR. As lsnr but for P.
minimal_vernalisation_factor: Tensor
dataclass-field
¶
cMinimalVernalisationFactor. Lower bound [0–1] on the
vernalisation factor used to limit pheno-rate suppression.
nfixf: Tensor
dataclass-field
¶
cNFIXF. Fraction of crop N uptake supplied by biological N₂
fixation [-]; > 0 for legumes.
nlai: Tensor
dataclass-field
¶
cNLAI. Coefficient of the reduction of LAI growth (juvenile
phase) due to nutrient stress.
nlue: Tensor
dataclass-field
¶
cNLUE. Coefficient of the reduction of RUE due to NPK
(nutrient) stress.
nmaxlv: Tensor
dataclass-field
¶
Scalar max N concentration in leaves [g N · g⁻¹ DM] (scaffold
surrogate of nmxlv table).
nmaxrt: Tensor
dataclass-field
¶
Scalar max N concentration in roots (≈ lrnr × nmaxlv).
nmaxso: Tensor
dataclass-field
¶
cNMAXSO. Maximum N concentration [g N · g⁻¹ DM] in storage
organs.
nmaxst: Tensor
dataclass-field
¶
Scalar max N concentration in stems (≈ lsnr × nmaxlv).
nmxlv: Tensor
dataclass-field
¶
cNMXLV. Maximum N concentration in leaves [g N · g⁻¹ DM] as a
function of DVS. Drives N demand and the N nutrition index NNI.
npart: Tensor
dataclass-field
¶
cNPART. Coefficient of the N-stress effect on leaf biomass
reduction (re-allocation away from leaves under N deficiency).
nresid: Tensor
dataclass-field
¶
Aggregated residual N concentration [g N · g⁻¹ DM] used by the
scaffold (compare per-organ rnflv/rnfst/rnfrt).
nrf: Tensor
dataclass-field
¶
cNRF. Default recovery fraction [0–1] of applied fertiliser N
(used when no day-resolved nrftab is provided).
nrftab: torch.Tensor | None
dataclass-field
¶
cNRFTAB. Optional day-resolved table of N fertiliser recovery
fractions [-] (shape [N, 2]: x = day, y = fraction).
nsla: Tensor
dataclass-field
¶
cNSLA. Coefficient of the reduction of SLA due to nutrient
stress.
phottb: Tensor
dataclass-field
¶
cPHOTTB (= cPhotoperiodTableHour × cPhotoperiodTableFactor).
Photoperiod reduction factor [-] of development rate (until anthesis)
as a function of day length [h].
pmaxlv: Tensor
dataclass-field
¶
Scalar max P concentration in leaves (scaffold surrogate of
pmxlv table).
pmaxrt: Tensor
dataclass-field
¶
Scalar max P concentration in roots (≈ lrpr × pmaxlv).
pmaxso: Tensor
dataclass-field
¶
cPMAXSO. Maximum P concentration in storage organs.
pmaxst: Tensor
dataclass-field
¶
Scalar max P concentration in stems (≈ lspr × pmaxlv).
pmxlv: Tensor
dataclass-field
¶
cPMXLV. Maximum P concentration in leaves [g P · g⁻¹ DM] vs
DVS.
presid: Tensor
dataclass-field
¶
Aggregated residual P concentration.
prf: Tensor
dataclass-field
¶
cPRF. Default recovery fraction [0–1] of applied fertiliser P.
prftab: torch.Tensor | None
dataclass-field
¶
cPRFTAB. Optional day-resolved table of P recovery fractions.
rdi: Tensor
dataclass-field
¶
cRDI. Initial rooting depth [m] (also used by WaterBalance).
rdmcr: Tensor
dataclass-field
¶
cRDMCR. Crop-specific maximum rooting depth [m].
rdrl: Tensor
dataclass-field
¶
cRDRL. Maximum relative death rate of leaves [d⁻¹] due to
water stress.
rdrltb: Tensor
dataclass-field
¶
cRDRLTB. Relative death rate of leaves [d⁻¹] as a function of
mean daily temperature [°C] (heat-stress curve).
rdrns: Tensor
dataclass-field
¶
cRDRNS. Maximum relative death rate of leaves [d⁻¹] due to
NPK (nutrient) stress.
rdrrtb: Tensor
dataclass-field
¶
cRDRRTB. Relative death rate of roots [d⁻¹] as a function of
DVS.
rdrshm: Tensor
dataclass-field
¶
cRDRSHM. Maximum relative death rate of leaves [d⁻¹] caused by
shading when LAI > laicr.
rdrstb: Tensor
dataclass-field
¶
cRDRSTB. Relative death rate of stems [d⁻¹] as a function of
DVS.
rdrtb: Tensor
dataclass-field
¶
Simplified DVS-indexed leaf relative-death-rate table [d⁻¹] used
by LeafDynamics for developmental senescence. Not a direct
SIMPLACE constant (SIMPLACE separates leaf senescence into
rdrltb (vs T), rdrrtb and rdrstb (vs DVS)).
rgrl: Tensor
dataclass-field
¶
cRGRLAI. Maximum relative increase in LAI [d⁻¹] during the
juvenile (exponential) phase.
rkflv: Tensor
dataclass-field
¶
cRKFLV. Residual K concentration in leaves.
rkfrt: Tensor
dataclass-field
¶
cRKFRT. Residual K concentration in roots.
rkfst: Tensor
dataclass-field
¶
cRKFST. Residual K concentration in stems.
rnflv: Tensor
dataclass-field
¶
cRNFLV. Residual (non-translocatable) N concentration in
leaves [g N · g⁻¹ DM].
rnfrt: Tensor
dataclass-field
¶
cRNFRT. Residual N concentration in roots.
rnfst: Tensor
dataclass-field
¶
cRNFST. Residual N concentration in stems.
rootdi: Tensor
dataclass-field
¶
Scaffold alias of rdi — initial rooting depth [m].
rootdm: Tensor
dataclass-field
¶
Scaffold alias of rdmcr — maximum rooting depth [m].
rpflv: Tensor
dataclass-field
¶
cRPFLV. Residual P concentration in leaves.
rpfrt: Tensor
dataclass-field
¶
cRPFRT. Residual P concentration in roots.
rpfst: Tensor
dataclass-field
¶
cRPFST. Residual P concentration in stems.
rrdmax: Tensor
dataclass-field
¶
Scaffold alias of rri — maximum daily root-depth growth
rate [m d⁻¹].
rri: Tensor
dataclass-field
¶
cRRI. Maximum daily increase in rooting depth [m d⁻¹].
rue: Tensor
dataclass-field
¶
cRUETableRUE (scalar surrogate). Reference radiation use
efficiency [g DM · MJ⁻¹ PAR] used when ruetb is omitted.
Lintul5 wheat default is 3.0 g · MJ⁻¹.
ruetb: Tensor
dataclass-field
¶
cRUETB (= cRUETableDVS × cRUETableRUE). Radiation use
efficiency [g DM · MJ⁻¹ PAR] as a function of DVS (declines after
grain filling).
rwrti: Tensor
dataclass-field
¶
cRWRTI. Initial change in living root biomass
[g DM m⁻² d⁻¹].
scale_factor_ferk: Tensor
dataclass-field
¶
cScaleFactorFERK. Scale factor on ferktab y-values.
scale_factor_fern: Tensor
dataclass-field
¶
cScaleFactorFERN. Scale factor on ferntab y-values.
scale_factor_ferp: Tensor
dataclass-field
¶
cScaleFactorFERP. Scale factor on ferptab y-values.
scale_factor_kdif: Tensor
dataclass-field
¶
cScaleFactorKDIF. Scale factor on kdiftb y-values.
scale_factor_rdr_leaves: Tensor
dataclass-field
¶
cScaleFactorRDRLeaves. Scale factor on rdrltb.
scale_factor_rdr_roots: Tensor
dataclass-field
¶
cScaleFactorRDRRoots. Scale factor on rdrrtb.
scale_factor_rdr_stems: Tensor
dataclass-field
¶
cScaleFactorRDRStems. Scale factor on rdrstb.
scale_factor_rue: Tensor
dataclass-field
¶
cScaleFactorRUE. Multiplicative scale factor on the y-values of
ruetb for sensitivity analysis / calibration.
scale_factor_sla: Tensor
dataclass-field
¶
cScaleFactorSLA. Scale factor on slatb y-values.
sla: Tensor
dataclass-field
¶
Reference specific leaf area [m² leaf · g⁻¹ DM]; scalar fallback
used when slatb is collapsed.
slatb: Tensor
dataclass-field
¶
cSLATB. Specific leaf area [m² g⁻¹] as a function of DVS.
tbase: Tensor
dataclass-field
¶
cTBASE. Lower threshold temperature [°C] for LAI increase.
tbasem: Tensor
dataclass-field
¶
cTBASEM. Lower threshold (base) temperature [°C] for
accumulation of temperature sum before crop emergence.
tckt: Tensor
dataclass-field
¶
cTCKT. Time constant [d] for K translocation to storage
organs.
tcnt: Tensor
dataclass-field
¶
cTCNT. Time constant [d] for N translocation to storage
organs (first-order kinetics).
tcpt: Tensor
dataclass-field
¶
cTCPT. Time constant [d] for P translocation to storage
organs.
tdwi: Tensor
dataclass-field
¶
cTDWI. Initial total crop dry weight [g DM m⁻²] at sowing /
emergence; partitioned to organs via the partitioning tables.
teffmx: Tensor
dataclass-field
¶
cTEFFMX. Maximum effective temperature [°C] used when
accumulating temperature sum before emergence (caps TEFF).
tmnftb: Tensor
dataclass-field
¶
cTMNFTB. RUE reduction factor [-] as a function of daily
minimum temperature [°C] (cold-night stress).
tmpf_tb: Tensor
dataclass-field
¶
Scaffold alias of tmpftb (T-response of RUE) used by the
current Photosynthesis module. Will be merged with
tmpftb once the full SIMPLACE RUE chain is wired in.
tmpftb: Tensor
dataclass-field
¶
cTMPFTB. RUE reduction factor [-] as a function of mean daytime
temperature [°C] (high- and low-temperature stress).
tsum1: Tensor
dataclass-field
¶
cTSUM1. Required temperature sum [°C·d] from emergence to
flowering / anthesis (vegetative period, DVS 0 → 1).
tsum2: Tensor
dataclass-field
¶
cTSUM2. Required temperature sum [°C·d] from anthesis to
maturity (generative period, DVS 1 → 2).
tsum_branching: Tensor
dataclass-field
¶
cTSUMBranching. Optional temperature sum [°C·d] from emergence
to branching (used by some calibrations; ignored otherwise).
tsum_milkripeness: Tensor
dataclass-field
¶
cTSUMMilkripeness. Optional temperature sum [°C·d] from
anthesis to milk-ripeness.
tsumem: Tensor
dataclass-field
¶
cTSUMEM. Required temperature sum [°C·d] from sowing to
emergence.
vbase: Tensor
dataclass-field
¶
cVBASE. Vernalisation base [thermal day]: vernal days
accumulated below this value contribute nothing to the vernalisation
factor.
vernalisation_devstage: Tensor
dataclass-field
¶
cVernalisationDevStage. Maximum DVS [-] up to which the
vernalisation factor is applied; beyond this stage VERNFAC = 1.
vernrt: Tensor
dataclass-field
¶
cVERNRT (= cVernalisationTableMeanTemp × cVernalisationTableRate).
Daily vernal-day rate [-] as a function of mean daily temperature [°C].
Used only when idsl ≥ 2.
versat: Tensor
dataclass-field
¶
cVERSAT. Vernalisation saturation [thermal day]: number of
vernal days above which the vernalisation factor is fully released
(=1).
to(self, dtype=None, device=None)
¶
Cast and/or move all tensor fields to a new dtype/device.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dtype |
torch.dtype | None |
Target tensor dtype, or |
None |
device |
torch.device | str | None |
Target torch device, or |
None |
Returns:
| Type | Description |
|---|---|
'CropParameters' |
A new |
Source code in torchcrop/parameters/crop_params.py
def to(
self,
dtype: torch.dtype | None = None,
device: torch.device | str | None = None,
) -> "CropParameters":
"""Cast and/or move all tensor fields to a new dtype/device.
Args:
dtype: Target tensor dtype, or ``None`` to leave unchanged.
device: Target torch device, or ``None`` to leave unchanged.
Returns:
A new `CropParameters` with every tensor field moved /
cast; non-tensor fields (e.g., optional tables set to ``None``)
are copied through unchanged.
"""
kwargs: dict[str, Any] = {}
for f in fields(self):
t = getattr(self, f.name)
if isinstance(t, torch.Tensor):
kwargs[f.name] = t.to(dtype=dtype, device=device)
else:
kwargs[f.name] = t
return CropParameters(**kwargs)
default_wheat_params(dtype=torch.float32)
¶
Return the SIMPLACE Lintul5 wheat-like default parameter set.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dtype |
torch.dtype |
Target tensor dtype for all scalar/tabular fields. |
torch.float32 |
Returns:
| Type | Description |
|---|---|
CropParameters |
A fresh |
Source code in torchcrop/parameters/crop_params.py
def default_wheat_params(dtype: torch.dtype = torch.float32) -> CropParameters:
"""Return the SIMPLACE Lintul5 wheat-like default parameter set.
Args:
dtype: Target tensor dtype for all scalar/tabular fields.
Returns:
A fresh `CropParameters` with the Lintul5 wheat defaults
cast to ``dtype``.
"""
return CropParameters().to(dtype=dtype)