2Photosynthesis parameter structures and data classes for PyHelios.
4This module provides Python data structures that mirror the C++ parameter
5classes used by the PhotosynthesisModel plugin, with proper defaults and
9from dataclasses
import dataclass, field
10from typing
import List, Optional, Union
14PHOTOSYNTHESIS_SPECIES = [
15 "Almond",
"Apple",
"Cherry",
"Prune",
"Pear",
16 "PistachioFemale",
"PistachioMale",
"Walnut",
18 "Elderberry",
"Toyon",
"Big_Leaf_Maple",
"Western_Redbud",
"Baylaurel",
"Olive",
19 "EasternRedbudSunlit",
"EasternRedbudShaded"
30 "pistachiofemale":
"PistachioFemale",
31 "pistachiomale":
"PistachioMale",
34 "elderberry":
"Elderberry",
36 "big_leaf_maple":
"Big_Leaf_Maple",
37 "western_redbud":
"Western_Redbud",
38 "baylaurel":
"Baylaurel",
40 "easternredbudsunlit":
"EasternRedbudSunlit",
41 "easternredbudshaded":
"EasternRedbudShaded",
44 "bigleafmaple":
"Big_Leaf_Maple",
45 "bigmaple":
"Big_Leaf_Maple",
46 "westernredbud":
"Western_Redbud",
47 "redbud":
"Western_Redbud",
48 "easternredbud":
"EasternRedbudSunlit",
49 "pistachio":
"PistachioFemale",
51 "cabernetSauvignon":
"Grape",
59 Temperature response parameters for photosynthetic processes.
61 These parameters define how photosynthetic rates vary with temperature
62 using the modified Arrhenius equation.
65 value_at_25C: Value of the parameter at 25°C
66 dHa: Activation energy (rate of increase parameter)
67 dHd: Deactivation energy (rate of decrease parameter)
68 Topt: Optimum temperature in Kelvin (10000K means no optimum)
70 value_at_25C: float = 100.0
76 """Validate parameter values after initialization."""
78 raise ValueError(
"value_at_25C must be finite")
79 if not math.isfinite(self.
dHa)
or self.
dHa < 0:
80 raise ValueError(
"dHa must be finite and non-negative")
81 if not math.isfinite(self.
dHd)
or self.
dHd < 0:
82 raise ValueError(
"dHd must be finite and non-negative")
83 if not math.isfinite(self.
Topt)
or self.
Topt < 0:
84 raise ValueError(
"Topt must be finite and non-negative")
90 Empirical photosynthesis model coefficients.
92 This model uses empirical relationships to estimate photosynthetic
93 rates based on environmental conditions.
96 Tref: Reference temperature (K)
97 Ci_ref: Reference CO2 concentration (μmol CO2/mol air)
98 Asat: Light-saturated photosynthetic rate (μmol/m²/s)
99 theta: Half-saturation light level (W/m²)
100 Tmin: Minimum temperature for photosynthesis (K)
101 Topt: Optimum temperature for photosynthesis (K)
102 q: Temperature response parameter (unitless)
103 R: Respiration temperature coefficient (μmol·K^0.5/m²/s)
104 ER: Respiration activation energy (1/K)
105 kC: CO2 response coefficient (unitless)
108 Ci_ref: float = 290.0
119 """Validate parameter values after initialization."""
121 raise ValueError(
"Reference temperature must be positive")
123 raise ValueError(
"Reference CO2 concentration must be positive")
125 raise ValueError(
"Light-saturated photosynthetic rate cannot be negative")
127 raise ValueError(
"Half-saturation light level must be positive")
129 raise ValueError(
"Minimum temperature must be positive")
131 raise ValueError(
"Optimum temperature must be positive")
133 raise ValueError(
"Minimum temperature must be less than optimum temperature")
135 raise ValueError(
"Temperature response parameter must be positive")
137 raise ValueError(
"Respiration coefficient cannot be negative")
139 raise ValueError(
"Respiration activation energy cannot be negative")
141 raise ValueError(
"CO2 response coefficient cannot be negative")
144 """Convert to float array for C++ interface."""
151 def from_array(cls, coefficients: List[float]) ->
'EmpiricalModelCoefficients':
152 """Create from float array (from C++ interface)."""
153 if len(coefficients) < 10:
154 raise ValueError(
"Need at least 10 coefficients for empirical model")
156 Tref=coefficients[0], Ci_ref=coefficients[1], Asat=coefficients[2],
157 theta=coefficients[3], Tmin=coefficients[4], Topt=coefficients[5],
158 q=coefficients[6], R=coefficients[7], ER=coefficients[8], kC=coefficients[9]
165 Farquhar-von Caemmerer-Berry photosynthesis model coefficients.
167 This model provides a mechanistic description of leaf photosynthesis
168 based on biochemical limitations and temperature responses.
170 Core Parameters (at 25°C):
171 Vcmax: Maximum carboxylation rate (μmol/m²/s, -1 = uninitialized)
172 Jmax: Maximum electron transport rate (μmol/m²/s, -1 = uninitialized)
173 alpha: Quantum efficiency of photosystem II (μmol electrons/μmol photons)
174 Rd: Dark respiration rate (μmol/m²/s, -1 = uninitialized)
175 O: Ambient oxygen concentration (mmol/mol)
176 TPU_flag: Enable triose phosphate utilization limitation (0/1)
178 Temperature Response Parameters:
179 c_*: Scaling factor for Arrhenius equation
180 dH_*: Activation energy for temperature response
192 c_Vcmax: float = 26.35
193 c_Jmax: float = 18.86
194 c_Gamma: float = 19.02
200 dH_Vcmax: float = 65.33
201 dH_Jmax: float = 46.36
202 dH_Gamma: float = 37.83
211 gm_at_25C: float = float(
'inf')
213 Topt_gm_C: float = -1.0
217 _vcmax_temp_response: Optional[PhotosyntheticTemperatureResponseParameters] = field(default=
None, init=
False)
218 _jmax_temp_response: Optional[PhotosyntheticTemperatureResponseParameters] = field(default=
None, init=
False)
219 _rd_temp_response: Optional[PhotosyntheticTemperatureResponseParameters] = field(default=
None, init=
False)
220 _alpha_temp_response: Optional[PhotosyntheticTemperatureResponseParameters] = field(default=
None, init=
False)
221 _theta_temp_response: Optional[PhotosyntheticTemperatureResponseParameters] = field(default=
None, init=
False)
224 """Validate parameter values after initialization."""
226 raise ValueError(
"Oxygen concentration must be positive")
228 raise ValueError(
"TPU_flag must be 0 or 1")
231 for param_name, value
in [
237 if not math.isfinite(value):
238 raise ValueError(f
"Temperature parameter {param_name} must be finite")
240 def setVcmax(self, vcmax_at_25c: float, dha: Optional[float] =
None,
241 topt: Optional[float] =
None, dhd: Optional[float] =
None) ->
None:
242 """Set Vcmax with temperature response (mimics C++ overloads)."""
256 self.
Vcmax = vcmax_at_25c
258 def setJmax(self, jmax_at_25c: float, dha: Optional[float] =
None,
259 topt: Optional[float] =
None, dhd: Optional[float] =
None) ->
None:
260 """Set Jmax with temperature response (mimics C++ overloads)."""
270 self.
Jmax = jmax_at_25c
272 def setRd(self, rd_at_25c: float, dha: Optional[float] =
None,
273 topt: Optional[float] =
None, dhd: Optional[float] =
None) ->
None:
274 """Set dark respiration with temperature response (mimics C++ overloads)."""
287 topt: Optional[float] =
None, dhd: Optional[float] =
None) ->
None:
288 """Set quantum efficiency with temperature response (mimics C++ overloads)."""
298 self.
alpha = alpha_at_25c
301 topt: Optional[float] =
None, dhd: Optional[float] =
None) ->
None:
302 """Set light response curvature with temperature response (mimics C++ overloads)."""
313 """Get Vcmax temperature response parameters."""
319 """Get Jmax temperature response parameters."""
325 """Get dark respiration temperature response parameters."""
331 """Get quantum efficiency temperature response parameters."""
337 """Get light response curvature temperature response parameters."""
343 """Convert to float array for C++ interface (22 floats; helios-core 1.3.72+).
345 Slots 0..17 are the legacy Farquhar fields (Vcmax/Jmax/alpha/Rd/O/TPU_flag plus
346 the 12 c_*/dH_* temperature constants). Slots 18..21 carry the mesophyll
347 conductance gm temperature response: (gm_at_25C, dHa, Topt_C, dHd) using the
348 -1 sentinel convention (dHa < 0 → constant gm with no temperature response,
349 Topt_C < 0 → monotonic Arrhenius, dHd < 0 → default deactivation energy).
350 Default ``gm_at_25C`` is ``+inf`` which reproduces the legacy ``Cc = Ci`` behaviour.
363 def from_array(cls, coefficients: List[float]) ->
'FarquharModelCoefficients':
364 """Create from float array (from C++ interface).
366 Accepts both the legacy 18-float layout (pre-1.3.72) and the 22-float layout
367 with mesophyll conductance gm in slots 18..21. When the array is 18 floats,
368 gm defaults to +infinity (legacy ``Cc = Ci`` behaviour).
370 if len(coefficients) < 18:
371 raise ValueError(
"Need at least 18 coefficients for Farquhar model")
373 gm_at_25C = coefficients[18]
if len(coefficients) > 18
else float(
'inf')
374 dHa_gm = coefficients[19]
if len(coefficients) > 19
else -1.0
375 Topt_gm_C = coefficients[20]
if len(coefficients) > 20
else -1.0
376 dHd_gm = coefficients[21]
if len(coefficients) > 21
else -1.0
379 Vcmax=coefficients[0], Jmax=coefficients[1], alpha=coefficients[2],
380 Rd=coefficients[3], O=coefficients[4], TPU_flag=int(coefficients[5]),
381 c_Vcmax=coefficients[6], dH_Vcmax=coefficients[7],
382 c_Jmax=coefficients[8], dH_Jmax=coefficients[9],
383 c_Rd=coefficients[10], dH_Rd=coefficients[11],
384 c_Kc=coefficients[12], dH_Kc=coefficients[13],
385 c_Ko=coefficients[14], dH_Ko=coefficients[15],
386 c_Gamma=coefficients[16], dH_Gamma=coefficients[17],
387 gm_at_25C=gm_at_25C, dHa_gm=dHa_gm, Topt_gm_C=Topt_gm_C, dHd_gm=dHd_gm,
393 Validate and normalize species name for photosynthesis library.
396 species: Species name (case insensitive, supports aliases)
399 Normalized species name
402 ValueError: If species is not recognized
405 raise ValueError(
"Species name cannot be empty")
408 if species
in PHOTOSYNTHESIS_SPECIES:
412 species_lower = species.lower()
413 if species_lower
in SPECIES_ALIASES:
414 return SPECIES_ALIASES[species_lower]
417 for known_species
in PHOTOSYNTHESIS_SPECIES:
418 if known_species.lower() == species_lower:
422 available_species = sorted(set(list(PHOTOSYNTHESIS_SPECIES) + list(SPECIES_ALIASES.keys())))
424 f
"Unknown species '{species}'. Available species and aliases:\n"
425 f
" {', '.join(available_species[:8])}\n"
426 f
" {', '.join(available_species[8:16])}\n"
427 f
" {', '.join(available_species[16:])}"
432 """Get list of available species in the photosynthesis library."""
433 return sorted(PHOTOSYNTHESIS_SPECIES.copy())
437 """Get dictionary of species aliases."""
438 return SPECIES_ALIASES.copy()
Empirical photosynthesis model coefficients.
float Topt
Optimum temperature for photosynthesis (K)
float Tmin
Minimum temperature for photosynthesis (K)
float Asat
Light-saturated photosynthetic rate (μmol/m²/s)
__post_init__(self)
Validate parameter values after initialization.
float q
Temperature response parameter (unitless)
'EmpiricalModelCoefficients' from_array(cls, List[float] coefficients)
Create from float array (from C++ interface).
float R
Respiration temperature coefficient (μmol·K^0.5/m²/s)
List[float] to_array(self)
Convert to float array for C++ interface.
float Tref
Reference temperature (K)
float ER
Respiration activation energy (1/K)
float Ci_ref
Reference CO2 concentration (μmol CO2/mol air)
float theta
Half-saturation light level (W/m²)
float kC
CO2 response coefficient (unitless)
Farquhar-von Caemmerer-Berry photosynthesis model coefficients.
List[float] to_array(self)
Convert to float array for C++ interface (22 floats; helios-core 1.3.72+).
None setVcmax(self, float vcmax_at_25c, Optional[float] dha=None, Optional[float] topt=None, Optional[float] dhd=None)
Set Vcmax with temperature response (mimics C++ overloads).
Optional _theta_temp_response
__post_init__(self)
Validate parameter values after initialization.
PhotosyntheticTemperatureResponseParameters getLightResponseCurvatureTempResponse(self)
Get light response curvature temperature response parameters.
Optional _vcmax_temp_response
None setQuantumEfficiency_alpha(self, float alpha_at_25c, Optional[float] dha=None, Optional[float] topt=None, Optional[float] dhd=None)
Set quantum efficiency with temperature response (mimics C++ overloads).
PhotosyntheticTemperatureResponseParameters getQuantumEfficiencyTempResponse(self)
Get quantum efficiency temperature response parameters.
Optional _rd_temp_response
PhotosyntheticTemperatureResponseParameters getVcmaxTempResponse(self)
Get Vcmax temperature response parameters.
Optional _alpha_temp_response
'FarquharModelCoefficients' from_array(cls, List[float] coefficients)
Create from float array (from C++ interface).
PhotosyntheticTemperatureResponseParameters getRdTempResponse(self)
Get dark respiration temperature response parameters.
Optional _jmax_temp_response
PhotosyntheticTemperatureResponseParameters getJmaxTempResponse(self)
Get Jmax temperature response parameters.
None setLightResponseCurvature_theta(self, float theta_at_25c, Optional[float] dha=None, Optional[float] topt=None, Optional[float] dhd=None)
Set light response curvature with temperature response (mimics C++ overloads).
None setRd(self, float rd_at_25c, Optional[float] dha=None, Optional[float] topt=None, Optional[float] dhd=None)
Set dark respiration with temperature response (mimics C++ overloads).
None setJmax(self, float jmax_at_25c, Optional[float] dha=None, Optional[float] topt=None, Optional[float] dhd=None)
Set Jmax with temperature response (mimics C++ overloads).
Temperature response parameters for photosynthetic processes.
float dHa
Activation energy (rate of increase parameter)
float dHd
Deactivation energy (rate of decrease parameter)
__post_init__(self)
Validate parameter values after initialization.
float value_at_25C
Value of the parameter at 25°C.
float Topt
Optimum temperature in Kelvin (10000K means no optimum)
List[str] get_available_species()
Get list of available species in the photosynthesis library.
str validate_species_name(str species)
Validate and normalize species name for photosynthesis library.
dict get_species_aliases()
Get dictionary of species aliases.