0.1.33
Loading...
Searching...
No Matches
StomatalConductance.py
Go to the documentation of this file.
1"""
2High-level StomatalConductance interface for PyHelios.
3
4This module provides a user-friendly interface to the stomatal conductance modeling
5capabilities with graceful plugin handling and informative error messages.
6"""
7
8import logging
9import math
10from typing import List, Optional, Union, NamedTuple
11from contextlib import contextmanager
12
13from .plugins.registry import get_plugin_registry
14from .wrappers import UStomatalConductanceWrapper as stomatal_wrapper
15from .Context import Context, check_context_alive
16from .exceptions import HeliosError
17
18logger = logging.getLogger(__name__)
19
20
22 """Exception raised for StomatalConductance-specific errors."""
23 pass
24
25
26# Model Coefficient Classes for type safety and clarity
27class BWBCoefficients(NamedTuple):
28 """Ball-Woodrow-Berry model coefficients."""
29 gs0: float # mol/m²/s - minimum stomatal conductance
30 a1: float # dimensionless - sensitivity parameter
31
32
33class BBLCoefficients(NamedTuple):
34 """Ball-Berry-Leuning model coefficients."""
35 gs0: float # mol/m²/s - minimum stomatal conductance
36 a1: float # dimensionless - sensitivity parameter
37 D0: float # mmol/mol - VPD parameter
38
39
40class MOPTCoefficients(NamedTuple):
41 """Medlyn et al. optimality model coefficients."""
42 gs0: float # mol/m²/s - minimum stomatal conductance
43 g1: float # (kPa)^0.5 - marginal water use efficiency
44
45
46class BMFCoefficients(NamedTuple):
47 """Buckley-Mott-Farquhar model coefficients."""
48 Em: float # mmol/m²/s - maximum transpiration rate
49 i0: float # μmol/m²/s - minimum radiation
50 k: float # μmol/m²/s·mmol/mol - light response parameter
51 b: float # mmol/mol - humidity response parameter
52
53
54class BBCoefficients(NamedTuple):
55 """Bailey model coefficients."""
56 pi_0: float # MPa - turgor pressure at full closure
57 pi_m: float # MPa - turgor pressure at full opening
58 theta: float # μmol/m²/s - light saturation parameter
59 sigma: float # dimensionless - shape parameter
60 chi: float # mol/m²/s/MPa - hydraulic conductance parameter
61
62
64 """
65 High-level interface for stomatal conductance modeling and gas exchange calculations.
66
67 This class provides a user-friendly wrapper around the native Helios
68 stomatal conductance plugin with automatic plugin availability checking and
69 graceful error handling.
70
71 The stomatal conductance model implements five different stomatal response models:
72 - BWB: Ball, Woodrow, Berry (1987) - original model
73 - BBL: Ball, Berry, Leuning (1990, 1995) - includes VPD response
74 - MOPT: Medlyn et al. (2011) - optimality-based model
75 - BMF: Buckley, Mott, Farquhar - simplified mechanistic model
76 - BB: Bailey - hydraulic-based model
77
78 The plugin includes a species library with pre-calibrated coefficients for
79 common plant species (Almond, Apple, Avocado, Grape, Lemon, Olive, Walnut, etc.).
80
81 Both steady-state and dynamic (time-stepping) calculations are supported,
82 with configurable time constants for stomatal opening and closing dynamics.
83
84 System requirements:
85 - Cross-platform support (Windows, Linux, macOS)
86 - No GPU required
87 - No special dependencies
88 - Stomatal conductance plugin compiled into PyHelios
89
90 Example:
91 >>> with Context() as context:
92 ... # Add leaf geometry
93 ... leaf_uuid = context.addPatch(center=[0, 0, 1], size=[0.1, 0.1])
94 ...
95 ... with StomatalConductanceModel(context) as stomatal:
96 ... # Set model coefficients using species library
97 ... stomatal.setBMFCoefficientsFromLibrary("Almond")
98 ...
99 ... # Run steady-state calculation
100 ... stomatal.run()
101 ...
102 ... # Or run dynamic simulation with timestep
103 ... stomatal.run(dt=60.0) # 60 second timestep
104 ...
105 ... # Set custom BMF coefficients for specific leaves
106 ... bmf_coeffs = BMFCoefficients(Em=258.25, i0=38.65, k=232916.82, b=609.67)
107 ... stomatal.setBMFCoefficients(bmf_coeffs, uuids=[leaf_uuid])
108 """
109
110 def __init__(self, context: Context):
111 """
112 Initialize StomatalConductanceModel with graceful plugin handling.
113
114 Args:
115 context: Helios Context instance
116
117 Raises:
118 TypeError: If context is not a Context instance
119 StomatalConductanceModelError: If stomatal conductance plugin is not available
120 """
121 # Validate context type - use duck typing to handle import state issues during testing
122 if not (hasattr(context, '__class__') and
123 (isinstance(context, Context) or
124 context.__class__.__name__ == 'Context')):
125 raise TypeError(f"StomatalConductanceModel requires a Context instance, got {type(context).__name__}")
126
127 self.context = context
128 self.stomatal_model = None
129
130 # Check plugin availability using registry
131 registry = get_plugin_registry()
132
133 if not registry.is_plugin_available('stomatalconductance'):
134 # Get helpful information about the missing plugin
135 plugin_info = registry.get_plugin_capabilities()
136 available_plugins = registry.get_available_plugins()
137
138 error_msg = (
139 "StomatalConductanceModel requires the 'stomatalconductance' plugin which is not available.\n\n"
140 "The stomatal conductance plugin provides gas exchange calculations using five validated models:\n"
141 "- Ball-Woodrow-Berry (BWB) - classic stomatal response\n"
142 "- Ball-Berry-Leuning (BBL) - includes vapor pressure deficit\n"
143 "- Medlyn et al. optimality (MOPT) - optimal stomatal behavior\n"
144 "- Buckley-Mott-Farquhar (BMF) - mechanistic approach\n"
145 "- Bailey (BB) - hydraulic-based model\n\n"
146 "Features:\n"
147 "- Species library with pre-calibrated coefficients\n"
148 "- Dynamic time-stepping with configurable time constants\n"
149 "- No GPU or special dependencies required\n\n"
150 "To enable stomatal conductance modeling:\n"
151 "1. Build PyHelios with stomatal conductance plugin:\n"
152 " build_scripts/build_helios --plugins stomatalconductance\n"
153 "2. Or build with multiple plugins:\n"
154 " build_scripts/build_helios --plugins stomatalconductance,energybalance,photosynthesis\n"
155 f"\nCurrently available plugins: {available_plugins}"
156 )
157
158 # Suggest alternatives if available
159 alternatives = registry.suggest_alternatives('stomatalconductance')
160 if alternatives:
161 error_msg += f"\n\nAlternative plugins available: {alternatives}"
162 error_msg += "\nConsider using photosynthesis or energybalance for related plant physiology modeling."
163
164 raise StomatalConductanceModelError(error_msg)
165
166 # Plugin is available - create stomatal conductance model
167 try:
168 self.stomatal_model = stomatal_wrapper.createStomatalConductanceModel(context.getNativePtr())
169 if self.stomatal_model is None:
171 "Failed to create StomatalConductanceModel instance. "
172 "This may indicate a problem with the native library."
173 )
174 logger.info("StomatalConductanceModel created successfully")
175
176 except Exception as e:
177 raise StomatalConductanceModelError(f"Failed to initialize StomatalConductanceModel: {e}")
178
179 def _check_context_alive(self):
180 """Raise if the owning Context has been destroyed (see Context.check_context_alive)."""
181 check_context_alive(getattr(self, "context", None), "StomatalConductanceModel")
183 def __enter__(self):
184 """Context manager entry."""
185 return self
187 def __exit__(self, exc_type, exc_value, traceback):
188 """Context manager exit with proper cleanup."""
189 if self.stomatal_model is not None:
190 try:
191 stomatal_wrapper.destroyStomatalConductanceModel(self.stomatal_model)
192 logger.debug("StomatalConductanceModel destroyed successfully")
193 except Exception as e:
194 logger.warning(f"Error destroying StomatalConductanceModel: {e}")
195 finally:
196 self.stomatal_model = None
197
198 def __del__(self):
199 """Destructor to ensure C++ resources freed even without 'with' statement."""
200 if hasattr(self, 'stomatal_model') and self.stomatal_model is not None:
201 try:
202 stomatal_wrapper.destroyStomatalConductanceModel(self.stomatal_model)
203 self.stomatal_model = None
204 except Exception as e:
205 import warnings
206 warnings.warn(f"Error in StomatalConductanceModel.__del__: {e}")
207
208 def getNativePtr(self):
209 """Get the native pointer for advanced operations."""
210 return self.stomatal_model
212 def enableMessages(self) -> None:
213 """
214 Enable console output messages from the stomatal conductance model.
215
216 Raises:
217 StomatalConductanceModelError: If operation fails
218 """
220 try:
221 stomatal_wrapper.enableMessages(self.stomatal_model)
222 except Exception as e:
223 raise StomatalConductanceModelError(f"Failed to enable messages: {e}")
224
225 def disableMessages(self) -> None:
226 """
227 Disable console output messages from the stomatal conductance model.
228
229 Raises:
230 StomatalConductanceModelError: If operation fails
231 """
233 try:
234 stomatal_wrapper.disableMessages(self.stomatal_model)
235 except Exception as e:
236 raise StomatalConductanceModelError(f"Failed to disable messages: {e}")
237
238 def run(self, uuids: Optional[List[int]] = None, dt: Optional[float] = None) -> None:
239 """
240 Run the stomatal conductance model.
241
242 This method supports multiple execution modes:
243 - Steady state for all primitives: run()
244 - Dynamic with timestep for all primitives: run(dt=60.0)
245 - Steady state for specific primitives: run(uuids=[1, 2, 3])
246 - Dynamic with timestep for specific primitives: run(uuids=[1, 2, 3], dt=60.0)
247
248 Args:
249 uuids: Optional list of primitive UUIDs to process. If None, processes all primitives.
250 dt: Optional timestep in seconds for dynamic simulation. If None, runs steady-state.
251
252 Raises:
253 ValueError: If parameters are invalid
254 StomatalConductanceModelError: If calculation fails
255
256 Example:
257 >>> # Steady state for all primitives
258 >>> stomatal.run()
259
260 >>> # Dynamic simulation with 60-second timestep
261 >>> stomatal.run(dt=60.0)
262
263 >>> # Steady state for specific leaves
264 >>> stomatal.run(uuids=[leaf1_uuid, leaf2_uuid])
265
266 >>> # Dynamic simulation for specific leaves
267 >>> stomatal.run(uuids=[leaf1_uuid, leaf2_uuid], dt=30.0)
268 """
270 try:
271 if dt is not None and uuids is not None:
272 # Dynamic simulation for specific UUIDs
273 stomatal_wrapper.runForUUIDsDynamic(self.stomatal_model, uuids, dt)
274 elif dt is not None:
275 # Dynamic simulation for all primitives
276 stomatal_wrapper.runDynamic(self.stomatal_model, dt)
277 elif uuids is not None:
278 # Steady state for specific UUIDs
279 stomatal_wrapper.runForUUIDs(self.stomatal_model, uuids)
280 else:
281 # Steady state for all primitives
282 stomatal_wrapper.run(self.stomatal_model)
283
284 except Exception as e:
285 raise StomatalConductanceModelError(f"Failed to run stomatal conductance model: {e}")
286
287 # BWB Model Methods
288 def setBWBCoefficients(self, coeffs: BWBCoefficients, uuids: Optional[List[int]] = None) -> None:
289 """
290 Set Ball-Woodrow-Berry model coefficients.
291
292 Args:
293 coeffs: BWB model coefficients (gs0, a1)
294 uuids: Optional list of primitive UUIDs. If None, applies to all primitives.
295
296 Raises:
297 ValueError: If coefficients are invalid
298 StomatalConductanceModelError: If operation fails
299
300 Example:
301 >>> bwb_coeffs = BWBCoefficients(gs0=0.0733, a1=9.422)
302 >>> stomatal.setBWBCoefficients(bwb_coeffs)
303 """
304 if not isinstance(coeffs, BWBCoefficients):
305 raise ValueError("coeffs must be a BWBCoefficients instance")
306 if coeffs.gs0 < 0.0:
307 raise ValueError("gs0 must be non-negative")
308 if coeffs.a1 < 0.0:
309 raise ValueError("a1 must be non-negative")
310
312 try:
313 if uuids is not None:
314 stomatal_wrapper.setBWBCoefficientsForUUIDs(self.stomatal_model, coeffs.gs0, coeffs.a1, uuids)
315 else:
316 stomatal_wrapper.setBWBCoefficients(self.stomatal_model, coeffs.gs0, coeffs.a1)
317 except Exception as e:
318 raise StomatalConductanceModelError(f"Failed to set BWB coefficients: {e}")
319
320 # BBL Model Methods
321 def setBBLCoefficients(self, coeffs: BBLCoefficients, uuids: Optional[List[int]] = None) -> None:
322 """
323 Set Ball-Berry-Leuning model coefficients.
324
325 Args:
326 coeffs: BBL model coefficients (gs0, a1, D0)
327 uuids: Optional list of primitive UUIDs. If None, applies to all primitives.
328
329 Raises:
330 ValueError: If coefficients are invalid
331 StomatalConductanceModelError: If operation fails
332
333 Example:
334 >>> bbl_coeffs = BBLCoefficients(gs0=0.0743, a1=4.265, D0=14570.0)
335 >>> stomatal.setBBLCoefficients(bbl_coeffs)
336 """
337 if not isinstance(coeffs, BBLCoefficients):
338 raise ValueError("coeffs must be a BBLCoefficients instance")
339 if coeffs.gs0 < 0.0:
340 raise ValueError("gs0 must be non-negative")
341 if coeffs.a1 < 0.0:
342 raise ValueError("a1 must be non-negative")
343 if coeffs.D0 <= 0.0:
344 raise ValueError("D0 must be positive")
345
347 try:
348 if uuids is not None:
349 stomatal_wrapper.setBBLCoefficientsForUUIDs(self.stomatal_model, coeffs.gs0, coeffs.a1, coeffs.D0, uuids)
350 else:
351 stomatal_wrapper.setBBLCoefficients(self.stomatal_model, coeffs.gs0, coeffs.a1, coeffs.D0)
352 except Exception as e:
353 raise StomatalConductanceModelError(f"Failed to set BBL coefficients: {e}")
354
355 # MOPT Model Methods
356 def setMOPTCoefficients(self, coeffs: MOPTCoefficients, uuids: Optional[List[int]] = None) -> None:
357 """
358 Set Medlyn et al. optimality model coefficients.
359
360 Args:
361 coeffs: MOPT model coefficients (gs0, g1)
362 uuids: Optional list of primitive UUIDs. If None, applies to all primitives.
363
364 Raises:
365 ValueError: If coefficients are invalid
366 StomatalConductanceModelError: If operation fails
367
368 Example:
369 >>> mopt_coeffs = MOPTCoefficients(gs0=0.0825, g1=2.637)
370 >>> stomatal.setMOPTCoefficients(mopt_coeffs)
371 """
372 if not isinstance(coeffs, MOPTCoefficients):
373 raise ValueError("coeffs must be a MOPTCoefficients instance")
374 if coeffs.gs0 < 0.0:
375 raise ValueError("gs0 must be non-negative")
376 if coeffs.g1 <= 0.0:
377 raise ValueError("g1 must be positive")
378
380 try:
381 if uuids is not None:
382 stomatal_wrapper.setMOPTCoefficientsForUUIDs(self.stomatal_model, coeffs.gs0, coeffs.g1, uuids)
383 else:
384 stomatal_wrapper.setMOPTCoefficients(self.stomatal_model, coeffs.gs0, coeffs.g1)
385 except Exception as e:
386 raise StomatalConductanceModelError(f"Failed to set MOPT coefficients: {e}")
387
388 # BMF Model Methods
389 def setBMFCoefficients(self, coeffs: BMFCoefficients, uuids: Optional[List[int]] = None) -> None:
390 """
391 Set Buckley-Mott-Farquhar model coefficients.
392
393 Args:
394 coeffs: BMF model coefficients (Em, i0, k, b)
395 uuids: Optional list of primitive UUIDs. If None, applies to all primitives.
396
397 Raises:
398 ValueError: If coefficients are invalid
399 StomatalConductanceModelError: If operation fails
400
401 Example:
402 >>> bmf_coeffs = BMFCoefficients(Em=258.25, i0=38.65, k=232916.82, b=609.67)
403 >>> stomatal.setBMFCoefficients(bmf_coeffs)
404 """
405 if not isinstance(coeffs, BMFCoefficients):
406 raise ValueError("coeffs must be a BMFCoefficients instance")
407 if coeffs.Em <= 0.0:
408 raise ValueError("Em must be positive")
409 if coeffs.i0 < 0.0:
410 raise ValueError("i0 must be non-negative")
411 if coeffs.k <= 0.0:
412 raise ValueError("k must be positive")
413 if coeffs.b <= 0.0:
414 raise ValueError("b must be positive")
415
417 try:
418 if uuids is not None:
419 stomatal_wrapper.setBMFCoefficientsForUUIDs(self.stomatal_model, coeffs.Em, coeffs.i0, coeffs.k, coeffs.b, uuids)
420 else:
421 stomatal_wrapper.setBMFCoefficients(self.stomatal_model, coeffs.Em, coeffs.i0, coeffs.k, coeffs.b)
422 except Exception as e:
423 raise StomatalConductanceModelError(f"Failed to set BMF coefficients: {e}")
424
425 # BB Model Methods
426 def setBBCoefficients(self, coeffs: BBCoefficients, uuids: Optional[List[int]] = None) -> None:
427 """
428 Set Bailey model coefficients.
429
430 Args:
431 coeffs: BB model coefficients (pi_0, pi_m, theta, sigma, chi)
432 uuids: Optional list of primitive UUIDs. If None, applies to all primitives.
433
434 Raises:
435 ValueError: If coefficients are invalid
436 StomatalConductanceModelError: If operation fails
437
438 Example:
439 >>> bb_coeffs = BBCoefficients(pi_0=1.0, pi_m=1.67, theta=211.22, sigma=0.4408, chi=2.076)
440 >>> stomatal.setBBCoefficients(bb_coeffs)
441 """
442 if not isinstance(coeffs, BBCoefficients):
443 raise ValueError("coeffs must be a BBCoefficients instance")
444 if coeffs.pi_0 <= 0.0:
445 raise ValueError("pi_0 must be positive")
446 if coeffs.pi_m <= 0.0:
447 raise ValueError("pi_m must be positive")
448 if coeffs.theta <= 0.0:
449 raise ValueError("theta must be positive")
450 if coeffs.sigma <= 0.0:
451 raise ValueError("sigma must be positive")
452 if coeffs.chi <= 0.0:
453 raise ValueError("chi must be positive")
454
456 try:
457 if uuids is not None:
458 stomatal_wrapper.setBBCoefficientsForUUIDs(self.stomatal_model, coeffs.pi_0, coeffs.pi_m, coeffs.theta, coeffs.sigma, coeffs.chi, uuids)
459 else:
460 stomatal_wrapper.setBBCoefficients(self.stomatal_model, coeffs.pi_0, coeffs.pi_m, coeffs.theta, coeffs.sigma, coeffs.chi)
461 except Exception as e:
462 raise StomatalConductanceModelError(f"Failed to set BB coefficients: {e}")
463
464 # Species Library Methods
465 def setBMFCoefficientsFromLibrary(self, species: str, uuids: Optional[List[int]] = None) -> None:
466 """
467 Set BMF model coefficients using the built-in species library.
468
469 Args:
470 species: Species name from the library (e.g., "Almond", "Apple", "Grape", "Walnut")
471 uuids: Optional list of primitive UUIDs. If None, applies to all primitives.
472
473 Raises:
474 ValueError: If species name is invalid
475 StomatalConductanceModelError: If operation fails
476
477 Example:
478 >>> # Set coefficients for almond tree
479 >>> stomatal.setBMFCoefficientsFromLibrary("Almond")
480
481 >>> # Set coefficients for specific leaves only
482 >>> stomatal.setBMFCoefficientsFromLibrary("Grape", uuids=[leaf1_uuid, leaf2_uuid])
483 """
484 if not species:
485 raise ValueError("Species name cannot be empty")
486
487 # Common species available in the library
488 available_species = [
489 "Almond", "Apple", "Avocado", "Cherry", "Grape", "Lemon",
490 "Olive", "Orange", "Peach", "Pear", "Plum", "Walnut"
491 ]
492
494 try:
495 if uuids is not None:
496 stomatal_wrapper.setBMFCoefficientsFromLibraryForUUIDs(self.stomatal_model, species, uuids)
497 else:
498 stomatal_wrapper.setBMFCoefficientsFromLibrary(self.stomatal_model, species)
499 except Exception as e:
500 error_msg = f"Failed to set BMF coefficients from library for species '{species}': {e}"
501 if "species not found" in str(e).lower() or "invalid species" in str(e).lower():
502 error_msg += f"\nAvailable species: {', '.join(available_species)}"
503 raise StomatalConductanceModelError(error_msg)
504
505 # Dynamic Time Constants
506 def setDynamicTimeConstants(self, tau_open: float, tau_close: float, uuids: Optional[List[int]] = None) -> None:
507 """
508 Set time constants for dynamic stomatal opening and closing.
509
510 Args:
511 tau_open: Time constant (seconds) for stomatal opening
512 tau_close: Time constant (seconds) for stomatal closing
513 uuids: Optional list of primitive UUIDs. If None, applies to all primitives.
514
515 Raises:
516 ValueError: If time constants are invalid
517 StomatalConductanceModelError: If operation fails
518
519 Example:
520 >>> # Set time constants for all leaves
521 >>> stomatal.setDynamicTimeConstants(tau_open=120.0, tau_close=240.0)
522
523 >>> # Set different time constants for specific leaves
524 >>> stomatal.setDynamicTimeConstants(tau_open=60.0, tau_close=180.0, uuids=[leaf1_uuid])
525 """
526 # tau appears in the denominator of the forward Euler update, so zero gives a
527 # non-finite conductance and a negative value inverts the relaxation so that stomata
528 # diverge away from the steady-state value. Mirrors validateDynamicTimeConstants
529 # added in helios-core 1.3.80.
530 if not math.isfinite(tau_open) or tau_open <= 0.0:
531 raise ValueError("Opening time constant must be finite and positive")
532 if not math.isfinite(tau_close) or tau_close <= 0.0:
533 raise ValueError("Closing time constant must be finite and positive")
534
536 try:
537 if uuids is not None:
538 stomatal_wrapper.setDynamicTimeConstantsForUUIDs(self.stomatal_model, tau_open, tau_close, uuids)
539 else:
540 stomatal_wrapper.setDynamicTimeConstants(self.stomatal_model, tau_open, tau_close)
541 except Exception as e:
542 raise StomatalConductanceModelError(f"Failed to set dynamic time constants: {e}")
543
544 # Utility Methods
545 def optionalOutputPrimitiveData(self, label: str) -> None:
546 """
547 Add optional output primitive data to the Context.
548
549 Args:
550 label: Name of primitive data to output (e.g., "Ci", "gs", "E")
551
552 Raises:
553 ValueError: If label is invalid
554 StomatalConductanceModelError: If operation fails
555
556 Example:
557 >>> # Output stomatal conductance values
558 >>> stomatal.optionalOutputPrimitiveData("gs")
559
560 >>> # Output intercellular CO2 concentration
561 >>> stomatal.optionalOutputPrimitiveData("Ci")
562 """
563 if not label:
564 raise ValueError("Label cannot be empty")
565
567 try:
568 stomatal_wrapper.optionalOutputPrimitiveData(self.stomatal_model, label)
569 except Exception as e:
570 raise StomatalConductanceModelError(f"Failed to add optional output data '{label}': {e}")
571
572 def printDefaultValueReport(self, uuids: Optional[List[int]] = None) -> None:
573 """
574 Print a report detailing usage of default input values.
575
576 Args:
577 uuids: Optional list of primitive UUIDs. If None, reports on all primitives.
578
579 Raises:
580 StomatalConductanceModelError: If operation fails
581
582 Example:
583 >>> # Print report for all primitives
584 >>> stomatal.printDefaultValueReport()
585
586 >>> # Print report for specific leaves
587 >>> stomatal.printDefaultValueReport(uuids=[leaf1_uuid, leaf2_uuid])
588 """
590 try:
591 if uuids is not None:
592 stomatal_wrapper.printDefaultValueReportForUUIDs(self.stomatal_model, uuids)
593 else:
594 stomatal_wrapper.printDefaultValueReport(self.stomatal_model)
595 except Exception as e:
596 raise StomatalConductanceModelError(f"Failed to print default value report: {e}")
597
598 def is_available(self) -> bool:
599 """
600 Check if StomatalConductanceModel is available in current build.
601
602 Returns:
603 True if plugin is available, False otherwise
604 """
605 registry = get_plugin_registry()
606 return registry.is_plugin_available('stomatalconductance')
607
608
609# Convenience function
610def create_stomatal_conductance_model(context: Context) -> StomatalConductanceModel:
611 """
612 Create StomatalConductanceModel instance with context.
613
614 Args:
615 context: Helios Context
616
617 Returns:
618 StomatalConductanceModel instance
619 """
620 return StomatalConductanceModel(context)
Ball-Berry-Leuning model coefficients.
Buckley-Mott-Farquhar model coefficients.
Ball-Woodrow-Berry model coefficients.
Exception raised for StomatalConductance-specific errors.
High-level interface for stomatal conductance modeling and gas exchange calculations.
bool is_available(self)
Check if StomatalConductanceModel is available in current build.
__del__(self)
Destructor to ensure C++ resources freed even without 'with' statement.
None setBMFCoefficients(self, BMFCoefficients coeffs, Optional[List[int]] uuids=None)
Set Buckley-Mott-Farquhar model coefficients.
None setMOPTCoefficients(self, MOPTCoefficients coeffs, Optional[List[int]] uuids=None)
Set Medlyn et al.
None printDefaultValueReport(self, Optional[List[int]] uuids=None)
Print a report detailing usage of default input values.
None setDynamicTimeConstants(self, float tau_open, float tau_close, Optional[List[int]] uuids=None)
Set time constants for dynamic stomatal opening and closing.
None enableMessages(self)
Enable console output messages from the stomatal conductance model.
None setBBLCoefficients(self, BBLCoefficients coeffs, Optional[List[int]] uuids=None)
Set Ball-Berry-Leuning model coefficients.
__init__(self, Context context)
Initialize StomatalConductanceModel with graceful plugin handling.
None setBWBCoefficients(self, BWBCoefficients coeffs, Optional[List[int]] uuids=None)
Set Ball-Woodrow-Berry model coefficients.
__exit__(self, exc_type, exc_value, traceback)
Context manager exit with proper cleanup.
getNativePtr(self)
Get the native pointer for advanced operations.
_check_context_alive(self)
Raise if the owning Context has been destroyed (see Context.check_context_alive).
None run(self, Optional[List[int]] uuids=None, Optional[float] dt=None)
Run the stomatal conductance model.
None optionalOutputPrimitiveData(self, str label)
Add optional output primitive data to the Context.
None setBMFCoefficientsFromLibrary(self, str species, Optional[List[int]] uuids=None)
Set BMF model coefficients using the built-in species library.
None disableMessages(self)
Disable console output messages from the stomatal conductance model.
None setBBCoefficients(self, BBCoefficients coeffs, Optional[List[int]] uuids=None)
Set Bailey model coefficients.
Exception classes for PyHelios library.
Definition exceptions.py:10
StomatalConductanceModel create_stomatal_conductance_model(Context context)
Create StomatalConductanceModel instance with context.