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.
Files changed (66) hide show
  1. PMJPL/ECOv002-cal-val-PM-JPL-inputs.csv +1048 -0
  2. PMJPL/ECOv002-cal-val-PM-JPL-outputs.csv +1048 -0
  3. PMJPL/ECOv002-static-tower-PM-JPL-inputs.csv +122 -0
  4. PMJPL/ECOv002_calval_PMJPL_inputs.py +19 -0
  5. PMJPL/ECOv002_static_tower_PMJPL_inputs.py +19 -0
  6. PMJPL/PMJPL.py +45 -378
  7. PMJPL/{parameters.py → PMJPL_parameter_from_IGBP.py} +22 -7
  8. PMJPL/VPD_factor.py +1 -1
  9. PMJPL/__init__.py +1 -6
  10. PMJPL/calculate_gamma.py +128 -0
  11. PMJPL/canopy_aerodynamic_resistance.py +151 -18
  12. PMJPL/canopy_conductance.py +71 -15
  13. PMJPL/closed_minimum_temperature.py +11 -0
  14. PMJPL/closed_vapor_pressure_deficit.py +11 -0
  15. PMJPL/constants.py +6 -1
  16. PMJPL/correctance_factor.py +56 -7
  17. PMJPL/generate_PMJPL_inputs.py +263 -0
  18. PMJPL/interception.py +1 -3
  19. PMJPL/leaf_conductance_to_evaporated_water.py +11 -0
  20. PMJPL/leaf_conductance_to_sensible_heat.py +58 -0
  21. PMJPL/maximum_boundary_layer_resistance.py +11 -0
  22. PMJPL/minimum_boundary_layer_resistance.py +11 -0
  23. PMJPL/{tmin_factor.py → minimum_temperature_factor.py} +2 -2
  24. PMJPL/mod16.csv +19 -0
  25. PMJPL/model.py +690 -0
  26. PMJPL/open_minimum_temperature.py +11 -0
  27. PMJPL/open_vapor_pressure_deficit.py +11 -0
  28. PMJPL/potential_soil_evaporation.py +2 -2
  29. PMJPL/potential_stomatal_conductance.py +11 -0
  30. PMJPL/process_PMJPL_table.py +208 -0
  31. PMJPL/process_daily_ET_table.py +40 -0
  32. PMJPL/transpiration.py +4 -4
  33. PMJPL/verify.py +77 -0
  34. PMJPL/version.py +4 -0
  35. PMJPL/wet_canopy_resistance.py +1 -0
  36. PMJPL/wet_soil_evaporation.py +4 -4
  37. {pm_jpl-1.2.1.dist-info → pm_jpl-1.7.0.dist-info}/METADATA +18 -21
  38. pm_jpl-1.7.0.dist-info/RECORD +42 -0
  39. {pm_jpl-1.2.1.dist-info → pm_jpl-1.7.0.dist-info}/WHEEL +1 -1
  40. PMJPL/MCD12C1/MCD12C1.py +0 -10
  41. PMJPL/MCD12C1/__init__.py +0 -1
  42. PMJPL/SEBAL/SEBAL.py +0 -45
  43. PMJPL/SEBAL/__init__.py +0 -1
  44. PMJPL/downscaling/__init__.py +0 -1
  45. PMJPL/downscaling/downscaling.py +0 -271
  46. PMJPL/downscaling/linear_downscale.py +0 -71
  47. PMJPL/evapotranspiration_conversion/__init__.py +0 -1
  48. PMJPL/evapotranspiration_conversion/evapotranspiration_conversion.py +0 -80
  49. PMJPL/fwet.py +0 -21
  50. PMJPL/meteorology_conversion/__init__.py +0 -1
  51. PMJPL/meteorology_conversion/meteorology_conversion.py +0 -123
  52. PMJPL/penman_monteith/__init__.py +0 -1
  53. PMJPL/penman_monteith/penman_monteith.py +0 -20
  54. PMJPL/priestley_taylor/__init__.py +0 -1
  55. PMJPL/priestley_taylor/priestley_taylor.py +0 -27
  56. PMJPL/santanello/__init__.py +0 -1
  57. PMJPL/santanello/santanello.py +0 -46
  58. PMJPL/soil_heat_flux/__init__.py +0 -1
  59. PMJPL/soil_heat_flux/soil_heat_flux.py +0 -62
  60. PMJPL/vegetation_conversion/__init__.py +0 -1
  61. PMJPL/vegetation_conversion/vegetation_conversion.py +0 -47
  62. PMJPL/verma_net_radiation/__init__.py +0 -1
  63. PMJPL/verma_net_radiation/verma_net_radiation.py +0 -108
  64. pm_jpl-1.2.1.dist-info/RECORD +0 -44
  65. {pm_jpl-1.2.1.dist-info → pm_jpl-1.7.0.dist-info}/licenses/LICENSE +0 -0
  66. {pm_jpl-1.2.1.dist-info → pm_jpl-1.7.0.dist-info}/top_level.txt +0 -0
@@ -1,62 +0,0 @@
1
- from typing import Union
2
- import numpy as np
3
-
4
- import rasters as rt
5
- from rasters import Raster
6
-
7
- from ..santanello import calculate_soil_heat_flux as santanello_G
8
- from ..SEBAL import calculate_soil_heat_flux as SEBAL_G
9
-
10
- DEFAULT_G_METHOD = "santanello"
11
-
12
- def calculate_soil_heat_flux(
13
- seconds_of_day: Union[Raster, np.ndarray] = None,
14
- ST_C: Union[Raster, np.ndarray] = None,
15
- NDVI: Union[Raster, np.ndarray] = None,
16
- albedo: Union[Raster, np.ndarray] = None,
17
- Rn: Union[Raster, np.ndarray] = None,
18
- SM: Union[Raster, np.ndarray] = None,
19
- method: str = DEFAULT_G_METHOD) -> Union[Raster, np.ndarray]:
20
- """
21
- The method estimates soil heat flux (G) as a function of time of day, net radiation (Rn), soil moisture (SM),
22
- surface temperature (ST_C), Normalized Difference Vegetation Index (NDVI), and albedo. The method used for
23
- calculation can be specified.
24
-
25
- Parameters:
26
- seconds_of_day (np.ndarray): Time in seconds of the day since midnight.
27
- ST_C (np.ndarray): Surface temperature in Celsius.
28
- NDVI (np.ndarray): Normalized Difference Vegetation Index.
29
- albedo (np.ndarray): Albedo of the surface.
30
- Rn (np.ndarray): Net radiation in W/m^2.
31
- SM (np.ndarray): Soil moisture in m^3/m^3.
32
- method (str, optional): Method to be used for calculation. Defaults to "santanello".
33
-
34
- Returns:
35
- G (np.ndarray): Soil heat flux in W/m^2.
36
- """
37
-
38
- # FIXME make sure G doesn't drop to extreme negative values
39
-
40
- if method == "santanello":
41
- G = santanello_G(
42
- seconds_of_day=seconds_of_day,
43
- Rn=Rn,
44
- SM=SM
45
- )
46
- elif method == "SEBAL":
47
- G = SEBAL_G(
48
- Rn=Rn,
49
- ST_C=ST_C,
50
- NDVI=NDVI,
51
- albedo=albedo
52
- )
53
- elif method == "MOD16":
54
- G = (-0.276 * NDVI + 0.35) * Rn
55
- elif method == "PTJPL":
56
- G = rt.clip(Rn * (0.05 + (1 - rt.clip(NDVI, 0, 1)) * 0.265), 0, 0.35 * Rn)
57
- else:
58
- raise ValueError(f"invalid soil heat flux method: {method}")
59
-
60
- G = rt.clip(G, 0, None)
61
-
62
- return G
@@ -1 +0,0 @@
1
- from .vegetation_conversion import *
@@ -1,47 +0,0 @@
1
- from typing import Union
2
- import numpy as np
3
- import rasters as rt
4
- from rasters import Raster
5
-
6
- KPAR = 0.5
7
- MIN_FIPAR = 0.0
8
- MAX_FIPAR = 1.0
9
- MIN_LAI = 0.0
10
- MAX_LAI = 10.0
11
-
12
- def FVC_from_NDVI(NDVI: Union[Raster, np.ndarray]) -> Union[Raster, np.ndarray]:
13
- """
14
- Convert Normalized Difference Vegetation Index (NDVI) to Fractional Vegetation Cover (FVC).
15
-
16
- Parameters:
17
- NDVI (Union[Raster, np.ndarray]): Input NDVI data.
18
-
19
- Returns:
20
- Union[Raster, np.ndarray]: Converted FVC data.
21
- """
22
- NDVIv = 0.52 # +- 0.03
23
- NDVIs = 0.04 # +- 0.03
24
- FVC = rt.clip((NDVI - NDVIs) / (NDVIv - NDVIs), 0.0, 1.0)
25
-
26
- return FVC
27
-
28
- def LAI_from_NDVI(
29
- NDVI: Union[Raster, np.ndarray],
30
- min_fIPAR: float = MIN_FIPAR,
31
- max_fIPAR: float = MAX_FIPAR,
32
- min_LAI: float = MIN_LAI,
33
- max_LAI: float = MAX_LAI) -> Union[Raster, np.ndarray]:
34
- """
35
- Convert Normalized Difference Vegetation Index (NDVI) to Leaf Area Index (LAI).
36
-
37
- Parameters:
38
- NDVI (Union[Raster, np.ndarray]): Input NDVI data.
39
-
40
- Returns:
41
- Union[Raster, np.ndarray]: Converted LAI data.
42
- """
43
- fIPAR = rt.clip(NDVI - 0.05, min_fIPAR, max_fIPAR)
44
- fIPAR = np.where(fIPAR == 0, np.nan, fIPAR)
45
- LAI = rt.clip(-np.log(1 - fIPAR) * (1 / KPAR), min_LAI, max_LAI)
46
-
47
- return LAI
@@ -1 +0,0 @@
1
- from .verma_net_radiation import *
@@ -1,108 +0,0 @@
1
- from typing import Union, Dict
2
- import warnings
3
- import numpy as np
4
- from sun_angles import daylight_from_SHA
5
- from sun_angles import sunrise_from_SHA
6
- from sun_angles import SHA_deg_from_DOY_lat
7
- from rasters import Raster
8
-
9
- STEFAN_BOLTZMAN_CONSTANT = 5.67036713e-8 # SI units watts per square meter per kelvin to the fourth
10
-
11
-
12
- def process_verma_net_radiation(
13
- SWin: np.ndarray,
14
- albedo: np.ndarray,
15
- ST_C: np.ndarray,
16
- emissivity: np.ndarray,
17
- Ta_C: np.ndarray,
18
- RH: np.ndarray,
19
- cloud_mask: np.ndarray = None) -> Dict:
20
- results = {}
21
-
22
- # Convert surface temperature from Celsius to Kelvin
23
- ST_K = ST_C + 273.15
24
-
25
- # Convert air temperature from Celsius to Kelvin
26
- Ta_K = Ta_C + 273.15
27
-
28
- # Calculate water vapor pressure in Pascals using air temperature and relative humidity
29
- Ea_Pa = (RH * 0.6113 * (10 ** (7.5 * (Ta_K - 273.15) / (Ta_K - 35.85)))) * 1000
30
-
31
- # constrain albedo between 0 and 1
32
- albedo = np.clip(albedo, 0, 1)
33
-
34
- # calculate outgoing shortwave from incoming shortwave and albedo
35
- SWout = np.clip(SWin * albedo, 0, None)
36
- results["SWout"] = SWout
37
-
38
- # calculate instantaneous net radiation from components
39
- SWnet = np.clip(SWin - SWout, 0, None)
40
-
41
- # calculate atmospheric emissivity
42
- eta1 = 0.465 * Ea_Pa / Ta_K
43
- # atmospheric_emissivity = (1 - (1 + eta1) * np.exp(-(1.2 + 3 * eta1) ** 0.5))
44
- eta2 = -(1.2 + 3 * eta1) ** 0.5
45
- eta2 = eta2.astype(float)
46
- eta3 = np.exp(eta2)
47
- atmospheric_emissivity = np.where(eta2 != 0, (1 - (1 + eta1) * eta3), np.nan)
48
-
49
- if cloud_mask is None:
50
- # calculate incoming longwave for clear sky
51
- LWin = atmospheric_emissivity * STEFAN_BOLTZMAN_CONSTANT * Ta_K ** 4
52
- else:
53
- # calculate incoming longwave for clear sky and cloudy
54
- LWin = np.where(
55
- ~cloud_mask,
56
- atmospheric_emissivity * STEFAN_BOLTZMAN_CONSTANT * Ta_K ** 4,
57
- STEFAN_BOLTZMAN_CONSTANT * Ta_K ** 4
58
- )
59
-
60
- results["LWin"] = LWin
61
-
62
- # constrain emissivity between 0 and 1
63
- emissivity = np.clip(emissivity, 0, 1)
64
-
65
- # calculate outgoing longwave from land surface temperature and emissivity
66
- LWout = emissivity * STEFAN_BOLTZMAN_CONSTANT * ST_K ** 4
67
- results["LWout"] = LWout
68
-
69
- # LWnet = np.clip(LWin - LWout, 0, None)
70
- LWnet = np.clip(LWin - LWout, 0, None)
71
-
72
- # constrain negative values of instantaneous net radiation
73
- Rn = np.clip(SWnet + LWnet, 0, None)
74
- results["Rn"] = Rn
75
-
76
- return results
77
-
78
- def daily_Rn_integration_verma(
79
- Rn: Union[Raster, np.ndarray],
80
- hour_of_day: Union[Raster, np.ndarray],
81
- DOY: Union[Raster, np.ndarray] = None,
82
- lat: Union[Raster, np.ndarray] = None,
83
- sunrise_hour: Union[Raster, np.ndarray] = None,
84
- daylight_hours: Union[Raster, np.ndarray] = None) -> Raster:
85
- """
86
- calculate daily net radiation using solar parameters
87
- this is the average rate of energy transfer from sunrise to sunset
88
- in watts per square meter
89
- watts are joules per second
90
- to get the total amount of energy transferred, factor seconds out of joules
91
- the number of seconds for which this average is representative is (daylight_hours * 3600)
92
- documented in verma et al, bisht et al, and lagouARDe et al
93
- :param Rn:
94
- :param hour_of_day:
95
- :param sunrise_hour:
96
- :param daylight_hours:
97
- :return:
98
- """
99
- if daylight_hours is None or sunrise_hour is None and DOY is not None and lat is not None:
100
- sha_deg = SHA_deg_from_DOY_lat(DOY=DOY, latitude=lat)
101
- daylight_hours = daylight_from_SHA(sha_deg)
102
- sunrise_hour = sunrise_from_SHA(sha_deg)
103
-
104
- with warnings.catch_warnings():
105
- warnings.filterwarnings("ignore")
106
- Rn_daily = 1.6 * Rn / (np.pi * np.sin(np.pi * (hour_of_day - sunrise_hour) / (daylight_hours)))
107
-
108
- return Rn_daily
@@ -1,44 +0,0 @@
1
- PMJPL/PMJPL.py,sha256=QXhLgqeOiLCFjtYHr_01hUfusVL_iOqeK_PXANeKdsU,12819
2
- PMJPL/VPD_factor.py,sha256=mEi3qXClc07QT2wlfCgzaFkERbm_D8JqWKmB86pJMVk,970
3
- PMJPL/__init__.py,sha256=rqFqtI2rLgIxSN3i2J8wZVoT2EpHYgVizfZt8ctwqsc,213
4
- PMJPL/canopy_aerodynamic_resistance.py,sha256=ejcmjGNimv2aja6WFRC_2D_48YD2fVHE3ndWHbGbxfM,1217
5
- PMJPL/canopy_conductance.py,sha256=1e2KwFGiRrXMJvG0iHwP3cpQ68HFB44eQ0CXsv1mQ-A,1367
6
- PMJPL/constants.py,sha256=Az7hftY_CIibJdvRdQcDisRdKqJYm8khktakCcNZtXU,787
7
- PMJPL/correctance_factor.py,sha256=V93rZcv5DM3LfujhEK8mRgJ-GHk868hDbTmcg8VoOAo,582
8
- PMJPL/fwet.py,sha256=-5GEGC1ohKBzsuYGLNiCaVe10DQLm82rsZTZGVxb4WY,616
9
- PMJPL/interception.py,sha256=lJ_kAa_Xkr21iWcVtSmLoNPfHEzCuiFSVRxB4-NUs9k,1689
10
- PMJPL/parameters.py,sha256=hiMXIafFkS4rqDQVvPhCFuiLc-WXTwlRyS-eIK9vQuk,1973
11
- PMJPL/potential_soil_evaporation.py,sha256=Xq-cvOqOa9W1FFHMmPKGtZs18tiDRUDOQ86-8rONO_Y,1823
12
- PMJPL/soil_moisture_constraint.py,sha256=URUGsE1_p2P1dVQ8qKRcKb93hahYWtAmYqoassRu-PI,667
13
- PMJPL/tmin_factor.py,sha256=BqSPM3Y8eB2fekSxUf9dzmAT_5UPNz0eY_wWnlvn1Xg,1595
14
- PMJPL/transpiration.py,sha256=8wxCsXURWabn8ARUDnekG3-igdygtlX9SgLrQu_RMaA,1980
15
- PMJPL/wet_canopy_resistance.py,sha256=q1RBq6SePklb-XLmv3zPbLX5rxtZ4uxvEecB9faJlyE,792
16
- PMJPL/wet_soil_evaporation.py,sha256=1lZ0qokBffZTCKuuh0M3jYtR2nbJyVLe15gFzXRlBU0,1416
17
- PMJPL/MCD12C1/MCD12C1.py,sha256=2zq6QW9SJGnADwbExZ7JvAaUcBrHeBSDiRS46RrumAY,378
18
- PMJPL/MCD12C1/__init__.py,sha256=4_gn1pQK9nuh7ZuUTFpaFhT6ypSvsIxBwIpOYmw5Vfg,23
19
- PMJPL/SEBAL/SEBAL.py,sha256=IBKKYbZzk0WOND6eRVdgTyqnsLriwOFECGBKIf0nOFk,1688
20
- PMJPL/SEBAL/__init__.py,sha256=IK_eHynpUb_XvECuLOfE0h3Js-4vdeXqCEe9y5oeKWw,21
21
- PMJPL/downscaling/__init__.py,sha256=xvhP4rHzx-nK_R6HSarJ-WF1bMPXYZGvvr8Hk84-q40,27
22
- PMJPL/downscaling/downscaling.py,sha256=VuhFbK92llJbtkOtJpah_51sM5ctFJ9oNUaH4aaNO7g,8447
23
- PMJPL/downscaling/linear_downscale.py,sha256=Yi0d2rb1XVSlBJoL2Arq9RtU5FH1RJ98MHLngJIYUjM,2466
24
- PMJPL/evapotranspiration_conversion/__init__.py,sha256=21wYXP8FJT63MpUTbHu0wGntyFFeiGDRneGMKCNAu8Q,45
25
- PMJPL/evapotranspiration_conversion/evapotranspiration_conversion.py,sha256=kwxLb_Vli_Tfal4lWBHMkEMmpCV7Kha_0wgqk8HjlXs,2754
26
- PMJPL/meteorology_conversion/__init__.py,sha256=dLF40imqJCC_l8_QMetbsj1YzkXZuFt9tQ2fsd7Wcdw,38
27
- PMJPL/meteorology_conversion/meteorology_conversion.py,sha256=8vzx71FLLNhR5v6EQBL8OSgAmupQcgdLX2c9tL9TPxA,4202
28
- PMJPL/penman_monteith/__init__.py,sha256=vcfkNo6BLDCfSF9HZFDvRMAKCx49F9idN7iNTKQCpcA,31
29
- PMJPL/penman_monteith/penman_monteith.py,sha256=2rSFP9_DBz1vMSbVyBQGhW-VXXb5XT8a7ls8sCstfXU,819
30
- PMJPL/priestley_taylor/__init__.py,sha256=E0SiG_DNAsMz_8A3342UPwbDyrMOgd35AZ-plaJar5s,32
31
- PMJPL/priestley_taylor/priestley_taylor.py,sha256=Rj168jfWHSBhGeUkDs6ePrVsHhFbmUujzQaA8z0fCXE,1126
32
- PMJPL/santanello/__init__.py,sha256=HXZS1p3sp4mDJCXkdq___ZIJ9etu7-B8yauJcFvQFgQ,26
33
- PMJPL/santanello/santanello.py,sha256=lvgskYrirQz0t1m4XNSj8hLzrESS-oVZzMvAnVPyt3g,1521
34
- PMJPL/soil_heat_flux/__init__.py,sha256=bES8bWQhwRLmyJPsaFB190yiuz2mHyJM1X8Q1KbwwEE,30
35
- PMJPL/soil_heat_flux/soil_heat_flux.py,sha256=wg5h6FmIxGFYDFRyQ_0D3GaL5PIiYonuz8u4o8MPaKw,2092
36
- PMJPL/vegetation_conversion/__init__.py,sha256=8gnz0yK_euCV0TtVGDrSGaVfx4g0EJCG2J68ppuA5oc,37
37
- PMJPL/vegetation_conversion/vegetation_conversion.py,sha256=-K3FLV6pXkpxtRxQvimqqkXAgkn9mUUlHQ8FIscq1Zg,1306
38
- PMJPL/verma_net_radiation/__init__.py,sha256=5TzlqNWajiVxbQdUqjWuu17oBrTmjIeaF40nQPnVzWo,35
39
- PMJPL/verma_net_radiation/verma_net_radiation.py,sha256=Y4OxcuBXTY6IZzZ6cXjxp2xTyeSAfYQ_itws0PcSc-I,3869
40
- pm_jpl-1.2.1.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
41
- pm_jpl-1.2.1.dist-info/METADATA,sha256=RxFlP8a66o37oND4TnqyInBGyVzslenurjZy-zZvz2w,4260
42
- pm_jpl-1.2.1.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
43
- pm_jpl-1.2.1.dist-info/top_level.txt,sha256=YaAFwdYHUxfUW08hiuFquUEdDGrsYn1duuMMjJKh0Ws,6
44
- pm_jpl-1.2.1.dist-info/RECORD,,