PM-JPL 1.2.1__py3-none-any.whl → 1.7.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- PMJPL/ECOv002-cal-val-PM-JPL-inputs.csv +1048 -0
- PMJPL/ECOv002-cal-val-PM-JPL-outputs.csv +1048 -0
- PMJPL/ECOv002-static-tower-PM-JPL-inputs.csv +122 -0
- PMJPL/ECOv002_calval_PMJPL_inputs.py +19 -0
- PMJPL/ECOv002_static_tower_PMJPL_inputs.py +19 -0
- PMJPL/PMJPL.py +45 -378
- PMJPL/{parameters.py → PMJPL_parameter_from_IGBP.py} +22 -7
- PMJPL/VPD_factor.py +1 -1
- PMJPL/__init__.py +1 -6
- PMJPL/calculate_gamma.py +128 -0
- PMJPL/canopy_aerodynamic_resistance.py +151 -18
- PMJPL/canopy_conductance.py +71 -15
- PMJPL/closed_minimum_temperature.py +11 -0
- PMJPL/closed_vapor_pressure_deficit.py +11 -0
- PMJPL/constants.py +6 -1
- PMJPL/correctance_factor.py +56 -7
- PMJPL/generate_PMJPL_inputs.py +263 -0
- PMJPL/interception.py +1 -3
- PMJPL/leaf_conductance_to_evaporated_water.py +11 -0
- PMJPL/leaf_conductance_to_sensible_heat.py +58 -0
- PMJPL/maximum_boundary_layer_resistance.py +11 -0
- PMJPL/minimum_boundary_layer_resistance.py +11 -0
- PMJPL/{tmin_factor.py → minimum_temperature_factor.py} +2 -2
- PMJPL/mod16.csv +19 -0
- PMJPL/model.py +690 -0
- PMJPL/open_minimum_temperature.py +11 -0
- PMJPL/open_vapor_pressure_deficit.py +11 -0
- PMJPL/potential_soil_evaporation.py +2 -2
- PMJPL/potential_stomatal_conductance.py +11 -0
- PMJPL/process_PMJPL_table.py +208 -0
- PMJPL/process_daily_ET_table.py +40 -0
- PMJPL/transpiration.py +4 -4
- PMJPL/verify.py +77 -0
- PMJPL/version.py +4 -0
- PMJPL/wet_canopy_resistance.py +1 -0
- PMJPL/wet_soil_evaporation.py +4 -4
- {pm_jpl-1.2.1.dist-info → pm_jpl-1.7.0.dist-info}/METADATA +18 -21
- pm_jpl-1.7.0.dist-info/RECORD +42 -0
- {pm_jpl-1.2.1.dist-info → pm_jpl-1.7.0.dist-info}/WHEEL +1 -1
- PMJPL/MCD12C1/MCD12C1.py +0 -10
- PMJPL/MCD12C1/__init__.py +0 -1
- PMJPL/SEBAL/SEBAL.py +0 -45
- PMJPL/SEBAL/__init__.py +0 -1
- PMJPL/downscaling/__init__.py +0 -1
- PMJPL/downscaling/downscaling.py +0 -271
- PMJPL/downscaling/linear_downscale.py +0 -71
- PMJPL/evapotranspiration_conversion/__init__.py +0 -1
- PMJPL/evapotranspiration_conversion/evapotranspiration_conversion.py +0 -80
- PMJPL/fwet.py +0 -21
- PMJPL/meteorology_conversion/__init__.py +0 -1
- PMJPL/meteorology_conversion/meteorology_conversion.py +0 -123
- PMJPL/penman_monteith/__init__.py +0 -1
- PMJPL/penman_monteith/penman_monteith.py +0 -20
- PMJPL/priestley_taylor/__init__.py +0 -1
- PMJPL/priestley_taylor/priestley_taylor.py +0 -27
- PMJPL/santanello/__init__.py +0 -1
- PMJPL/santanello/santanello.py +0 -46
- PMJPL/soil_heat_flux/__init__.py +0 -1
- PMJPL/soil_heat_flux/soil_heat_flux.py +0 -62
- PMJPL/vegetation_conversion/__init__.py +0 -1
- PMJPL/vegetation_conversion/vegetation_conversion.py +0 -47
- PMJPL/verma_net_radiation/__init__.py +0 -1
- PMJPL/verma_net_radiation/verma_net_radiation.py +0 -108
- pm_jpl-1.2.1.dist-info/RECORD +0 -44
- {pm_jpl-1.2.1.dist-info → pm_jpl-1.7.0.dist-info}/licenses/LICENSE +0 -0
- {pm_jpl-1.2.1.dist-info → pm_jpl-1.7.0.dist-info}/top_level.txt +0 -0
PMJPL/__init__.py
CHANGED
PMJPL/calculate_gamma.py
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
from typing import Union
|
|
2
|
+
import numpy as np
|
|
3
|
+
|
|
4
|
+
from daylight_evapotranspiration import lambda_Jkg_from_Ta_C
|
|
5
|
+
|
|
6
|
+
from rasters import Raster
|
|
7
|
+
|
|
8
|
+
SPECIFIC_HEAT_CAPACITY_AIR = 1013 # J kg-1 K-1, Monteith & Unsworth (2001)
|
|
9
|
+
MOL_WEIGHT_WET_DRY_RATIO_AIR = 0.622
|
|
10
|
+
|
|
11
|
+
def calculate_gamma(
|
|
12
|
+
Ta_C: Union[Raster, np.ndarray],
|
|
13
|
+
Ps_Pa: Union[Raster, np.ndarray],
|
|
14
|
+
Cp_Jkg: Union[Raster, np.ndarray, float] = SPECIFIC_HEAT_CAPACITY_AIR,
|
|
15
|
+
RMW: Union[Raster, np.ndarray, float] = MOL_WEIGHT_WET_DRY_RATIO_AIR) -> Union[Raster, np.ndarray]:
|
|
16
|
+
"""
|
|
17
|
+
Calculate the psychrometric constant (gamma) for evapotranspiration modeling.
|
|
18
|
+
|
|
19
|
+
The psychrometric constant is a fundamental parameter in atmospheric physics that
|
|
20
|
+
quantifies the relationship between sensible and latent heat transfer in the atmosphere.
|
|
21
|
+
It is essential for the Penman-Monteith equation and other evapotranspiration models,
|
|
22
|
+
representing the ratio of specific heat of moist air to the latent heat of vaporization
|
|
23
|
+
multiplied by the ratio of molecular weights of water vapor to dry air.
|
|
24
|
+
|
|
25
|
+
Mathematical Formula:
|
|
26
|
+
γ = (Cp × P) / (λ × ε)
|
|
27
|
+
|
|
28
|
+
Where:
|
|
29
|
+
- γ = psychrometric constant (Pa K⁻¹)
|
|
30
|
+
- Cp = specific heat capacity of air at constant pressure (J kg⁻¹ K⁻¹)
|
|
31
|
+
- P = atmospheric pressure (Pa)
|
|
32
|
+
- λ = latent heat of vaporization of water (J kg⁻¹)
|
|
33
|
+
- ε = ratio of molecular weight of water vapor to dry air (≈ 0.622)
|
|
34
|
+
|
|
35
|
+
Physical Significance:
|
|
36
|
+
The psychrometric constant is temperature and pressure dependent, making it crucial
|
|
37
|
+
for accurate evapotranspiration calculations across diverse environmental conditions.
|
|
38
|
+
It accounts for:
|
|
39
|
+
- Temperature effects on latent heat of vaporization (Clausius-Clapeyron relation)
|
|
40
|
+
- Elevation effects through atmospheric pressure variations
|
|
41
|
+
- Energy partitioning between sensible and latent heat fluxes
|
|
42
|
+
|
|
43
|
+
This implementation is part of the MOD16 evapotranspiration algorithm used by
|
|
44
|
+
NASA's ECOSTRESS mission and is designed for processing high-resolution remote
|
|
45
|
+
sensing imagery.
|
|
46
|
+
|
|
47
|
+
Parameters
|
|
48
|
+
----------
|
|
49
|
+
Ta_C : Union[Raster, np.ndarray]
|
|
50
|
+
Air temperature in degrees Celsius. Used to calculate the temperature-dependent
|
|
51
|
+
latent heat of vaporization through the Clausius-Clapeyron equation.
|
|
52
|
+
|
|
53
|
+
Ps_Pa : Union[Raster, np.ndarray]
|
|
54
|
+
Surface atmospheric pressure in Pascals. Accounts for elevation effects on
|
|
55
|
+
evapotranspiration rates. Lower pressure at higher elevations reduces the
|
|
56
|
+
psychrometric constant.
|
|
57
|
+
|
|
58
|
+
Cp_Jkg : Union[Raster, np.ndarray, float], optional
|
|
59
|
+
Specific heat capacity of air at constant pressure in J kg⁻¹ K⁻¹.
|
|
60
|
+
Default: 1013 J kg⁻¹ K⁻¹ (Monteith & Unsworth, 2001).
|
|
61
|
+
This represents the amount of energy required to raise the temperature
|
|
62
|
+
of 1 kg of air by 1 K at constant pressure.
|
|
63
|
+
|
|
64
|
+
RMW : Union[Raster, np.ndarray, float], optional
|
|
65
|
+
Ratio of molecular weights of water vapor to dry air (dimensionless).
|
|
66
|
+
Default: 0.622 (18.016 g/mol ÷ 28.97 g/mol).
|
|
67
|
+
This constant accounts for the different molecular masses affecting
|
|
68
|
+
vapor pressure relationships.
|
|
69
|
+
|
|
70
|
+
Returns
|
|
71
|
+
-------
|
|
72
|
+
Union[Raster, np.ndarray]
|
|
73
|
+
Psychrometric constant in Pa K⁻¹. Values typically range from 60-70 Pa K⁻¹
|
|
74
|
+
at sea level and standard temperature, increasing with elevation and
|
|
75
|
+
decreasing with temperature.
|
|
76
|
+
|
|
77
|
+
Notes
|
|
78
|
+
-----
|
|
79
|
+
The psychrometric constant is used extensively in:
|
|
80
|
+
- Penman-Monteith equation for reference evapotranspiration
|
|
81
|
+
- Energy balance calculations for partitioning available energy
|
|
82
|
+
- Vapor pressure deficit relationships for atmospheric moisture demand
|
|
83
|
+
- Canopy conductance models for transpiration calculations
|
|
84
|
+
|
|
85
|
+
The temperature dependency through λ(T) is critical because:
|
|
86
|
+
- Higher temperatures decrease latent heat of vaporization
|
|
87
|
+
- This affects evapotranspiration rates and energy partitioning
|
|
88
|
+
- Accurate temperature relationships are essential for global applications
|
|
89
|
+
|
|
90
|
+
References
|
|
91
|
+
----------
|
|
92
|
+
.. [1] Monteith, J. L., & Unsworth, M. H. (2001). Principles of Environmental
|
|
93
|
+
Physics (3rd ed.). Academic Press.
|
|
94
|
+
.. [2] Mu, Q., Zhao, M., & Running, S. W. (2011). Improvements to a MODIS
|
|
95
|
+
global terrestrial evapotranspiration algorithm. Remote Sensing of
|
|
96
|
+
Environment, 115(8), 1781-1800. doi:10.1016/j.rse.2011.02.019
|
|
97
|
+
.. [3] Allen, R. G., Pereira, L. S., Raes, D., & Smith, M. (1998). Crop
|
|
98
|
+
evapotranspiration - Guidelines for computing crop water requirements.
|
|
99
|
+
FAO Irrigation and drainage paper 56.
|
|
100
|
+
.. [4] Penman, H. L. (1948). Natural evaporation from open water, bare soil
|
|
101
|
+
and grass. Proceedings of the Royal Society of London, 193(1032), 120-145.
|
|
102
|
+
|
|
103
|
+
Examples
|
|
104
|
+
--------
|
|
105
|
+
>>> import numpy as np
|
|
106
|
+
>>> from rasters import Raster
|
|
107
|
+
>>>
|
|
108
|
+
>>> # Calculate gamma for standard conditions
|
|
109
|
+
>>> Ta_C = np.array([20.0, 25.0, 30.0]) # Air temperature in Celsius
|
|
110
|
+
>>> Ps_Pa = np.array([101325, 101325, 101325]) # Sea level pressure
|
|
111
|
+
>>> gamma = calculate_gamma(Ta_C, Ps_Pa)
|
|
112
|
+
>>> print(f"Psychrometric constant: {gamma} Pa K⁻¹")
|
|
113
|
+
>>>
|
|
114
|
+
>>> # For high elevation (lower pressure)
|
|
115
|
+
>>> Ps_Pa_high = np.array([85000, 85000, 85000]) # ~1500m elevation
|
|
116
|
+
>>> gamma_high = calculate_gamma(Ta_C, Ps_Pa_high)
|
|
117
|
+
>>> print(f"High elevation gamma: {gamma_high} Pa K⁻¹")
|
|
118
|
+
|
|
119
|
+
See Also
|
|
120
|
+
--------
|
|
121
|
+
lambda_Jkg_from_Ta_C : Calculate latent heat of vaporization from temperature
|
|
122
|
+
delta_Pa_from_Ta_C : Calculate slope of saturation vapor pressure curve
|
|
123
|
+
"""
|
|
124
|
+
# calculate latent heat of vaporization (J kg-1)
|
|
125
|
+
lambda_Jkg = lambda_Jkg_from_Ta_C(Ta_C)
|
|
126
|
+
gamma = (Cp_Jkg * Ps_Pa) / (lambda_Jkg * RMW)
|
|
127
|
+
|
|
128
|
+
return gamma
|
|
@@ -3,28 +3,161 @@ import numpy as np
|
|
|
3
3
|
import rasters as rt
|
|
4
4
|
from rasters import Raster
|
|
5
5
|
|
|
6
|
-
def
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
def calculate_canopy_aerodynamic_resistance(
|
|
7
|
+
VPD_Pa: Union[Raster, np.ndarray],
|
|
8
|
+
VPD_open_Pa: Union[Raster, np.ndarray],
|
|
9
|
+
VPD_close_Pa: Union[Raster, np.ndarray],
|
|
10
|
+
RBL_max: Union[Raster, np.ndarray],
|
|
11
|
+
RBL_min: Union[Raster, np.ndarray]) -> Union[Raster, np.ndarray]:
|
|
12
12
|
"""
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
13
|
+
Calculate total canopy aerodynamic resistance based on vapor pressure deficit.
|
|
14
|
+
|
|
15
|
+
This function computes the total aerodynamic resistance to the canopy as a
|
|
16
|
+
function of vapor pressure deficit (VPD) and biome-specific boundary layer resistance
|
|
17
|
+
parameters. The resistance varies between minimum and maximum values based on stomatal
|
|
18
|
+
response to atmospheric moisture demand, implementing a key component of the MOD16
|
|
19
|
+
evapotranspiration algorithm.
|
|
20
|
+
|
|
21
|
+
**CRITICAL**: All VPD-related parameters must be in Pascals (Pa) to ensure correct
|
|
22
|
+
operation with MOD16 lookup table values. Using different pressure units will cause
|
|
23
|
+
incorrect stomatal response calculations.
|
|
24
|
+
|
|
25
|
+
The aerodynamic resistance represents the resistance to water vapor and heat transfer
|
|
26
|
+
from the canopy to the atmosphere through the boundary layer. This parameter is crucial
|
|
27
|
+
for accurately modeling transpiration rates and energy partitioning in vegetation.
|
|
28
|
+
|
|
29
|
+
Physical Mechanism:
|
|
30
|
+
- At low VPD (high atmospheric humidity): Stomata remain open, resistance is maximum
|
|
31
|
+
- At high VPD (low atmospheric humidity): Stomata close to conserve water, resistance is minimum
|
|
32
|
+
- Between thresholds: Linear interpolation models gradual stomatal response
|
|
33
|
+
|
|
34
|
+
Mathematical Implementation:
|
|
35
|
+
- VPD_Pa ≤ VPD_open_Pa: resistance = RBL_max (stomata fully open)
|
|
36
|
+
- VPD_Pa ≥ VPD_close_Pa: resistance = RBL_min (stomata mostly closed)
|
|
37
|
+
- VPD_open_Pa < VPD_Pa < VPD_close_Pa: resistance = RBL_min + (RBL_max - RBL_min) × (VPD_close_Pa - VPD_Pa) / (VPD_close_Pa - VPD_open_Pa)
|
|
38
|
+
|
|
39
|
+
This formulation captures the physiological response of plants to atmospheric dryness,
|
|
40
|
+
where stomata progressively close as VPD increases to prevent excessive water loss,
|
|
41
|
+
thereby increasing the resistance to water vapor transfer.
|
|
42
|
+
|
|
43
|
+
Parameters
|
|
44
|
+
----------
|
|
45
|
+
VPD_Pa : Union[Raster, np.ndarray]
|
|
46
|
+
Vapor pressure deficit in Pascals (Pa). **UNITS ARE CRITICAL** - must be in
|
|
47
|
+
Pascals to match MOD16 lookup table thresholds. Represents the difference
|
|
48
|
+
between saturated and actual vapor pressure, indicating atmospheric moisture
|
|
49
|
+
demand. Higher VPD values indicate drier atmospheric conditions that stress
|
|
50
|
+
vegetation. Typical range: 100-5000 Pa.
|
|
51
|
+
|
|
52
|
+
**Warning**: Using different units (e.g., kPa, hPa, or mb) will cause
|
|
53
|
+
incorrect results since direct numerical comparisons are made against
|
|
54
|
+
biome-specific thresholds defined in Pascals.
|
|
55
|
+
|
|
56
|
+
VPD_open_Pa : Union[Raster, np.ndarray]
|
|
57
|
+
VPD threshold in Pascals (Pa) below which stomata are completely open and
|
|
58
|
+
there is no water stress effect on transpiration. Biome-specific parameter
|
|
59
|
+
from MOD16 lookup table. Typical values: 650-1000 Pa.
|
|
60
|
+
**Must be in same units as VPD_Pa parameter.**
|
|
61
|
+
|
|
62
|
+
VPD_close_Pa : Union[Raster, np.ndarray]
|
|
63
|
+
VPD threshold in Pascals (Pa) above which stomata are almost completely
|
|
64
|
+
closed due to water stress. Biome-specific parameter from MOD16 lookup table.
|
|
65
|
+
Typical values: 2900-4500 Pa.
|
|
66
|
+
**Must be in same units as VPD_Pa parameter.**
|
|
67
|
+
|
|
68
|
+
RBL_max : Union[Raster, np.ndarray]
|
|
69
|
+
Maximum atmospheric boundary layer resistance in s m⁻¹. Applied when VPD is
|
|
70
|
+
low (favorable conditions) and stomata are fully open. Biome-specific parameter
|
|
71
|
+
representing maximum resistance to vapor transfer. Typical values: 45-100 s m⁻¹.
|
|
72
|
+
|
|
73
|
+
RBL_min : Union[Raster, np.ndarray]
|
|
74
|
+
Minimum atmospheric boundary layer resistance in s m⁻¹. Applied when VPD is
|
|
75
|
+
high (water stress conditions) and stomata are mostly closed. Biome-specific
|
|
76
|
+
parameter representing minimum resistance to vapor transfer.
|
|
77
|
+
Typical values: 20-70 s m⁻¹.
|
|
78
|
+
|
|
79
|
+
Returns
|
|
80
|
+
-------
|
|
81
|
+
Union[Raster, np.ndarray]
|
|
82
|
+
Total canopy aerodynamic resistance in s m⁻¹. Higher values indicate
|
|
83
|
+
greater resistance to water vapor and heat transfer from canopy to atmosphere.
|
|
84
|
+
Values range between RBL_min and RBL_max depending on VPD conditions.
|
|
85
|
+
|
|
86
|
+
Notes
|
|
87
|
+
-----
|
|
88
|
+
The function implements a three-piece piecewise linear function that models the
|
|
89
|
+
physiological response of vegetation to atmospheric water demand:
|
|
90
|
+
|
|
91
|
+
1. **Low VPD regime** (VPD_Pa ≤ VPD_open_Pa): Optimal conditions where stomata remain
|
|
92
|
+
fully open and resistance is at maximum, allowing efficient photosynthesis
|
|
93
|
+
with minimal water stress.
|
|
94
|
+
|
|
95
|
+
2. **High VPD regime** (VPD_Pa ≥ VPD_close_Pa): Severe water stress conditions where
|
|
96
|
+
stomata close to conserve water, reducing resistance to minimum values and
|
|
97
|
+
limiting transpiration.
|
|
98
|
+
|
|
99
|
+
3. **Intermediate VPD regime** (VPD_open_Pa < VPD_Pa < VPD_close_Pa): Transitional zone
|
|
100
|
+
where stomata gradually close as atmospheric demand increases, following a
|
|
101
|
+
linear relationship between the threshold values.
|
|
102
|
+
|
|
103
|
+
This formulation is essential for:
|
|
104
|
+
- Accurate transpiration modeling under varying atmospheric conditions
|
|
105
|
+
- Energy balance calculations in land surface models
|
|
106
|
+
- Water stress assessment in vegetation monitoring
|
|
107
|
+
- Climate impact studies on ecosystem water use
|
|
108
|
+
|
|
109
|
+
The biome-specific parameters (VPD_open_Pa, VPD_close_Pa, RBL_min, RBL_max) are derived
|
|
110
|
+
from the MOD16 lookup table based on IGBP land cover classifications, allowing
|
|
111
|
+
the model to account for different vegetation types' physiological responses.
|
|
112
|
+
|
|
113
|
+
References
|
|
114
|
+
----------
|
|
115
|
+
.. [1] Mu, Q., Zhao, M., & Running, S. W. (2011). Improvements to a MODIS
|
|
116
|
+
global terrestrial evapotranspiration algorithm. Remote Sensing of
|
|
117
|
+
Environment, 115(8), 1781-1800. doi:10.1016/j.rse.2011.02.019
|
|
118
|
+
.. [2] Mu, Q., Heinsch, F. A., Zhao, M., & Running, S. W. (2007). Development
|
|
119
|
+
of a global evapotranspiration algorithm based on MODIS and global
|
|
120
|
+
meteorology data. Remote Sensing of Environment, 111(4), 519-536.
|
|
121
|
+
.. [3] Monteith, J. L. (1995). A reinterpretation of stomatal responses to
|
|
122
|
+
humidity. Plant, Cell & Environment, 18(4), 357-364.
|
|
123
|
+
.. [4] Ball, J. T., Woodrow, I. E., & Berry, J. A. (1987). A model predicting
|
|
124
|
+
stomatal conductance and its contribution to the control of photosynthesis
|
|
125
|
+
under different environmental conditions. Progress in Photosynthesis
|
|
126
|
+
Research, 4, 221-224.
|
|
127
|
+
|
|
128
|
+
Examples
|
|
129
|
+
--------
|
|
130
|
+
>>> import numpy as np
|
|
131
|
+
>>> from rasters import Raster
|
|
132
|
+
>>>
|
|
133
|
+
>>> # Example for grassland (IGBP class 10)
|
|
134
|
+
>>> VPD_Pa = np.array([500, 1500, 3000, 5000]) # Pa
|
|
135
|
+
>>> VPD_open_Pa = np.array([650, 650, 650, 650]) # Pa (grassland threshold)
|
|
136
|
+
>>> VPD_close_Pa = np.array([4200, 4200, 4200, 4200]) # Pa (grassland threshold)
|
|
137
|
+
>>> RBL_max = np.array([50, 50, 50, 50]) # s/m (grassland maximum)
|
|
138
|
+
>>> RBL_min = np.array([20, 20, 20, 20]) # s/m (grassland minimum)
|
|
139
|
+
>>>
|
|
140
|
+
>>> rtotc = calculate_canopy_aerodynamic_resistance(VPD_Pa, VPD_open_Pa, VPD_close_Pa, RBL_max, RBL_min)
|
|
141
|
+
>>> print(f"Aerodynamic resistance: {rtotc} s/m")
|
|
142
|
+
>>> # Expected: [50, ~36, ~22, 20] - decreasing resistance with increasing VPD
|
|
143
|
+
>>>
|
|
144
|
+
>>> # Demonstrate VPD stress response
|
|
145
|
+
>>> VPD_stress = np.linspace(0, 5000, 100) # Full VPD range
|
|
146
|
+
>>> rtotc_response = calculate_canopy_aerodynamic_resistance(VPD_stress, 650, 4200, 50, 20)
|
|
147
|
+
>>> # Shows smooth transition from 50 to 20 s/m as VPD increases
|
|
148
|
+
|
|
149
|
+
See Also
|
|
150
|
+
--------
|
|
151
|
+
MOD16_parameter_from_IGBP : Retrieve biome-specific parameters from lookup table
|
|
152
|
+
calculate_rcorr : Calculate resistance correction factor
|
|
153
|
+
calculate_VPD_factor : Calculate VPD-based stress factor
|
|
21
154
|
"""
|
|
22
|
-
rtotc = rt.where(
|
|
23
|
-
rtotc = rt.where(
|
|
155
|
+
rtotc = rt.where(VPD_Pa <= VPD_open_Pa, RBL_max, np.nan)
|
|
156
|
+
rtotc = rt.where(VPD_Pa >= VPD_close_Pa, RBL_min, rtotc)
|
|
24
157
|
|
|
25
158
|
rtotc = rt.where(
|
|
26
|
-
|
|
27
|
-
|
|
159
|
+
np.logical_and(VPD_open_Pa < VPD_Pa, VPD_Pa < VPD_close_Pa),
|
|
160
|
+
RBL_min + (RBL_max - RBL_min) * (VPD_close_Pa - VPD_Pa) / (VPD_close_Pa - VPD_open_Pa),
|
|
28
161
|
rtotc
|
|
29
162
|
)
|
|
30
163
|
|
PMJPL/canopy_conductance.py
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import numpy as np
|
|
2
2
|
from typing import Union
|
|
3
|
-
|
|
3
|
+
|
|
4
4
|
import rasters as rt
|
|
5
5
|
from rasters import Raster
|
|
6
6
|
|
|
7
|
+
from .constants import MAX_RESISTANCE
|
|
8
|
+
|
|
7
9
|
def calculate_canopy_conductance(
|
|
8
10
|
LAI: Union[Raster, np.ndarray],
|
|
9
11
|
fwet: Union[Raster, np.ndarray],
|
|
@@ -11,26 +13,80 @@ def calculate_canopy_conductance(
|
|
|
11
13
|
gs1: Union[Raster, np.ndarray],
|
|
12
14
|
Gcu: Union[Raster, np.ndarray]) -> Union[Raster, np.ndarray]:
|
|
13
15
|
"""
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
:
|
|
16
|
+
Calculate canopy conductance (Cc) to transpired water vapor per unit leaf area index (LAI).
|
|
17
|
+
|
|
18
|
+
Canopy conductance (Cc) quantifies the ease with which water vapor moves from the leaf interior,
|
|
19
|
+
through stomata and cuticle, across the leaf boundary layer, and into the atmosphere. It is a key
|
|
20
|
+
control on plant transpiration and ecosystem water fluxes, and is the inverse of surface resistance (rs)
|
|
21
|
+
in the Penman-Monteith equation for evapotranspiration.
|
|
22
|
+
|
|
23
|
+
Physical Basis:
|
|
24
|
+
- Stomatal conductance (gs1): Rate of water vapor exit through stomata, regulated by plant physiology and environment.
|
|
25
|
+
- Cuticular conductance (Gcu): Water vapor loss through the leaf cuticle, important when stomata are closed.
|
|
26
|
+
- Leaf boundary layer conductance (gl_sh): Transfer of water vapor across the thin layer of still air adjacent to the leaf surface.
|
|
27
|
+
- LAI (Leaf Area Index): Total leaf area per unit ground area, scaling conductance to the canopy level.
|
|
28
|
+
- fwet (relative surface wetness): Fraction of leaf surface that is wet, reducing transpiration when wet.
|
|
29
|
+
|
|
30
|
+
Mathematical Structure:
|
|
31
|
+
Stomatal and cuticular conductances act in parallel, and their sum is in series with the leaf boundary layer conductance:
|
|
32
|
+
Cc = gl_sh * (gs1 + Gcu) / (gs1 + gl_sh + Gcu) * LAI * (1.0 - fwet)
|
|
33
|
+
- The parallel sum: (gs1 + Gcu)
|
|
34
|
+
- The series combination: gl_sh * (gs1 + Gcu) / (gs1 + gl_sh + Gcu)
|
|
35
|
+
- Scaled by LAI and reduced by the fraction of wet surface (1 - fwet)
|
|
36
|
+
- If LAI or (1 - fwet) is zero, conductance is set to zero (no transpiration)
|
|
37
|
+
- The result is clipped to a minimum value (1/MAX_RESISTANCE) to avoid extreme/unphysical values
|
|
38
|
+
|
|
39
|
+
Parameters:
|
|
40
|
+
LAI : Union[Raster, np.ndarray]
|
|
41
|
+
Leaf area index (dimensionless). Total leaf area per unit ground area.
|
|
42
|
+
fwet : Union[Raster, np.ndarray]
|
|
43
|
+
Relative surface wetness (dimensionless, 0-1). Fraction of leaf surface that is wet.
|
|
44
|
+
gl_sh : Union[Raster, np.ndarray]
|
|
45
|
+
Leaf boundary layer conductance (m s⁻¹ LAI⁻¹).
|
|
46
|
+
gs1 : Union[Raster, np.ndarray]
|
|
47
|
+
Stomatal conductance (m s⁻¹ LAI⁻¹).
|
|
48
|
+
Gcu : Union[Raster, np.ndarray]
|
|
49
|
+
Cuticular conductance (m s⁻¹ LAI⁻¹).
|
|
50
|
+
|
|
51
|
+
Returns:
|
|
52
|
+
Union[Raster, np.ndarray]
|
|
53
|
+
Canopy conductance (Cc) to water vapor in m s⁻¹. Higher values indicate greater ease of water vapor transfer.
|
|
54
|
+
|
|
55
|
+
Notes:
|
|
56
|
+
- Canopy conductance is the inverse of surface resistance (rs) in the Penman-Monteith equation.
|
|
57
|
+
- Integrates physiological (stomatal), anatomical (cuticular), and physical (boundary layer) controls on water flux.
|
|
58
|
+
- Sensitive to environmental stress (drought, humidity, leaf wetness).
|
|
59
|
+
- If LAI or (1 - fwet) is zero, Cc is set to zero (no transpiration).
|
|
60
|
+
- Clipped to a minimum value to avoid unphysical results.
|
|
61
|
+
|
|
62
|
+
References:
|
|
63
|
+
Thornton, P. E. (1998). A mechanistic approach to modeling photosynthesis at the leaf and canopy scale. Global Change Biology, 4(4), 389-404.
|
|
64
|
+
Running, S. W., & Kimball, J. S. (2005). Remote Sensing of Terrestrial Ecosystem Processes: A Review of MODIS Algorithms. Remote Sensing of Environment, 92(1), 1-19.
|
|
65
|
+
Monteith, J. L., & Unsworth, M. H. (2001). Principles of Environmental Physics (3rd ed.). Academic Press.
|
|
66
|
+
Jarvis, P. G., & McNaughton, K. G. (1986). Stomatal control of transpiration: Scaling up from leaf to region. Advances in Ecological Research, 15, 1-49.
|
|
67
|
+
|
|
68
|
+
Example:
|
|
69
|
+
>>> import numpy as np
|
|
70
|
+
>>> LAI = np.array([2.0, 3.0])
|
|
71
|
+
>>> fwet = np.array([0.1, 0.2])
|
|
72
|
+
>>> gl_sh = np.array([0.02, 0.03])
|
|
73
|
+
>>> gs1 = np.array([0.15, 0.12])
|
|
74
|
+
>>> Gcu = np.array([0.01, 0.01])
|
|
75
|
+
>>> Cc = calculate_canopy_conductance(LAI, fwet, gl_sh, gs1, Gcu)
|
|
76
|
+
>>> print(Cc)
|
|
26
77
|
"""
|
|
27
|
-
|
|
78
|
+
|
|
79
|
+
# Only compute conductance where there is leaf area and the surface is not fully wet
|
|
28
80
|
Cc = rt.where(
|
|
29
|
-
|
|
81
|
+
np.logical_and(LAI > 0.0, (1.0 - fwet) > 0.0),
|
|
82
|
+
# Series-parallel conductance: stomatal and cuticular conductances in parallel, in series with boundary layer
|
|
30
83
|
gl_sh * (gs1 + Gcu) / (gs1 + gl_sh + Gcu) * LAI * (1.0 - fwet),
|
|
84
|
+
# If no leaf area or surface is fully wet, set conductance to zero (no transpiration)
|
|
31
85
|
0.0
|
|
32
86
|
)
|
|
33
87
|
|
|
88
|
+
# Clip conductance to a minimum value to avoid unphysical/extreme results
|
|
34
89
|
Cc = rt.clip(Cc, 1.0 / MAX_RESISTANCE, None)
|
|
35
90
|
|
|
91
|
+
# Return canopy conductance (m s^-1)
|
|
36
92
|
return Cc
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
from .PMJPL_parameter_from_IGBP import PMJPL_parameter_from_IGBP
|
|
2
|
+
from rasters import Raster, RasterGeometry, VectorGeometry
|
|
3
|
+
from typing import Union
|
|
4
|
+
|
|
5
|
+
def closed_minimum_temperature(IGBP: Union[Raster, int], geometry=None, IGBP_upsampling_resolution_meters=None):
|
|
6
|
+
return PMJPL_parameter_from_IGBP(
|
|
7
|
+
variable="Tmin_closed",
|
|
8
|
+
IGBP=IGBP,
|
|
9
|
+
geometry=geometry,
|
|
10
|
+
IGBP_upsampling_resolution_meters=IGBP_upsampling_resolution_meters
|
|
11
|
+
)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
from .PMJPL_parameter_from_IGBP import PMJPL_parameter_from_IGBP
|
|
2
|
+
from rasters import Raster, RasterGeometry, VectorGeometry
|
|
3
|
+
from typing import Union
|
|
4
|
+
|
|
5
|
+
def closed_vapor_pressure_deficit(IGBP: Union[Raster, int], geometry=None, IGBP_upsampling_resolution_meters=None):
|
|
6
|
+
return PMJPL_parameter_from_IGBP(
|
|
7
|
+
variable="VPD_closed",
|
|
8
|
+
IGBP=IGBP,
|
|
9
|
+
geometry=geometry,
|
|
10
|
+
IGBP_upsampling_resolution_meters=IGBP_upsampling_resolution_meters
|
|
11
|
+
)
|
PMJPL/constants.py
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
from
|
|
1
|
+
from priestley_taylor import GAMMA_PA
|
|
2
|
+
|
|
3
|
+
UPSCALE_TO_DAILY = False
|
|
4
|
+
|
|
5
|
+
IGBP_PARAMETER_RESAMPLING = "cubic"
|
|
6
|
+
IGBP_UPSAMPLING_RESOLUTION_METERS = 5000
|
|
2
7
|
|
|
3
8
|
# TODO need to defend picking arbitrary maximum to avoid extreme values
|
|
4
9
|
MIN_RESISTANCE = 0.0
|
PMJPL/correctance_factor.py
CHANGED
|
@@ -3,15 +3,64 @@ import numpy as np
|
|
|
3
3
|
import rasters as rt
|
|
4
4
|
from rasters import Raster
|
|
5
5
|
|
|
6
|
-
def
|
|
6
|
+
def calculate_correctance_factor(
|
|
7
7
|
Ps_Pa: Union[Raster, np.ndarray],
|
|
8
8
|
Ta_K: Union[Raster, np.ndarray]) -> Union[Raster, np.ndarray]:
|
|
9
9
|
"""
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
Calculate the correction factor (rcorr) for stomatal and cuticular conductances
|
|
11
|
+
based on surface atmospheric pressure and air temperature.
|
|
12
|
+
|
|
13
|
+
This factor adjusts leaf conductance values from standard reference conditions
|
|
14
|
+
(sea level pressure, 20°C) to actual environmental conditions, accounting for
|
|
15
|
+
the effects of pressure and temperature on the diffusivity of water vapor in air.
|
|
16
|
+
|
|
17
|
+
Physical Basis
|
|
18
|
+
-------------
|
|
19
|
+
- Lower atmospheric pressure (e.g., high elevation) increases the diffusivity of gases, so conductance must be scaled up.
|
|
20
|
+
- Higher temperature increases molecular motion and the rate of diffusion, also requiring scaling.
|
|
21
|
+
- The correction factor ensures that modeled or measured conductances are physically consistent across different elevations and climates.
|
|
22
|
+
|
|
23
|
+
Mathematical Structure
|
|
24
|
+
---------------------
|
|
25
|
+
The formula is:
|
|
26
|
+
rcorr = 1 / ((101300 / Ps_Pa) * (Ta_K / 293.15) ** 1.75)
|
|
27
|
+
Where:
|
|
28
|
+
Ps_Pa : surface atmospheric pressure in Pascals
|
|
29
|
+
Ta_K : near-surface air temperature in Kelvin
|
|
30
|
+
101300: reference pressure (Pa, sea level)
|
|
31
|
+
293.15: reference temperature (K, 20°C)
|
|
32
|
+
1.75 : exponent for temperature dependence of water vapor diffusivity in air
|
|
33
|
+
|
|
34
|
+
Parameters
|
|
35
|
+
----------
|
|
36
|
+
Ps_Pa : Union[Raster, np.ndarray]
|
|
37
|
+
Surface atmospheric pressure in Pascals (Pa).
|
|
38
|
+
Ta_K : Union[Raster, np.ndarray]
|
|
39
|
+
Near-surface air temperature in Kelvin (K).
|
|
40
|
+
|
|
41
|
+
Returns
|
|
42
|
+
-------
|
|
43
|
+
Union[Raster, np.ndarray]
|
|
44
|
+
Correction factor (rcorr), dimensionless. Used to scale stomatal and cuticular conductances to local conditions.
|
|
45
|
+
|
|
46
|
+
Notes
|
|
47
|
+
-----
|
|
48
|
+
- Used in MOD16 and similar evapotranspiration models to adjust leaf conductance parameters for local meteorological conditions.
|
|
49
|
+
- Ensures physical consistency in remote sensing and land surface models across different elevations and climates.
|
|
50
|
+
- Based on the physical principles of gas diffusion (Fick's law) and empirical temperature/pressure dependence of water vapor diffusivity.
|
|
51
|
+
|
|
52
|
+
References
|
|
53
|
+
----------
|
|
54
|
+
Monteith, J. L., & Unsworth, M. H. (2001). Principles of Environmental Physics (3rd ed.). Academic Press.
|
|
55
|
+
Mu, Q., Zhao, M., & Running, S. W. (2011). Improvements to a MODIS global terrestrial evapotranspiration algorithm. Remote Sensing of Environment, 115(8), 1781-1800.
|
|
56
|
+
Jones, H. G. (2013). Plants and Microclimate: A Quantitative Approach to Environmental Plant Physiology (3rd ed.). Cambridge University Press.
|
|
57
|
+
Farquhar, G. D., & Sharkey, T. D. (1982). Stomatal conductance and photosynthesis. Annual Review of Plant Physiology, 33(1), 317-345.
|
|
58
|
+
|
|
59
|
+
Example
|
|
60
|
+
-------
|
|
61
|
+
>>> Ps_Pa = 90000.0 # Pa (high elevation)
|
|
62
|
+
>>> Ta_K = 303.15 # K (30°C)
|
|
63
|
+
>>> rcorr = calculate_correctance_factor(Ps_Pa, Ta_K)
|
|
64
|
+
>>> print(rcorr)
|
|
16
65
|
"""
|
|
17
66
|
return 1.0 / ((101300.0 / Ps_Pa) * (Ta_K / 293.15) ** 1.75)
|