BESS-JPL 1.15.0__py3-none-any.whl → 1.16.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.

Potentially problematic release.


This version of BESS-JPL might be problematic. Click here for more details.

BESS_JPL/BESS_JPL.py CHANGED
@@ -6,7 +6,7 @@ import numpy as np
6
6
  import rasters as rt
7
7
  from rasters import Raster, RasterGeometry
8
8
 
9
- from .check_distribution import check_distribution
9
+ from check_distribution import check_distribution
10
10
 
11
11
  from sun_angles import calculate_SZA_from_DOY_and_hour
12
12
  from solar_apparent_time import solar_day_of_year_for_area, solar_hour_of_day_for_area
@@ -1,6 +1,6 @@
1
1
  import numpy as np
2
2
 
3
- from .check_distribution import check_distribution
3
+ from check_distribution import check_distribution
4
4
 
5
5
 
6
6
  def canopy_shortwave_radiation(
@@ -12,25 +12,6 @@ from .soil_energy_balance import soil_energy_balance
12
12
 
13
13
  PASSES = 1
14
14
 
15
-
16
- def load_ball_berry_intercept_C3(self, geometry: RasterGeometry) -> Raster:
17
- filename = join(abspath(dirname(__file__)), "ball_berry_intercept_C3.tif")
18
- image = rt.Raster.open(filename, geometry=geometry, resampling=self.resampling)
19
-
20
- return image
21
-
22
- def load_ball_berry_slope_C3(self, geometry: RasterGeometry) -> Raster:
23
- filename = join(abspath(dirname(__file__)), "ball_berry_slope_C3.tif")
24
- image = rt.Raster.open(filename, geometry=geometry, resampling=self.resampling)
25
-
26
- return image
27
-
28
- def load_ball_berry_slope_C4(self, geometry: RasterGeometry) -> Raster:
29
- filename = join(abspath(dirname(__file__)), "ball_berry_slope_C4.tif")
30
- image = rt.Raster.open(filename, geometry=geometry, resampling=self.resampling)
31
-
32
- return image
33
-
34
15
  def carbon_water_fluxes(
35
16
  canopy_temperature_K: np.ndarray, # canopy temperature in Kelvin
36
17
  soil_temperature_K: np.ndarray, # soil temperature in Kelvin
@@ -3,8 +3,12 @@ from os.path import join, abspath, dirname
3
3
  import rasters as rt
4
4
  from rasters import Raster, RasterGeometry
5
5
 
6
+ import numpy as np
7
+
6
8
  def load_C4_fraction(geometry: RasterGeometry = None, resampling: str = "nearest") -> Raster:
7
9
  filename = join(abspath(dirname(__file__)), "C4_fraction.tif")
8
- image = Raster.open(filename, geometry=geometry, resampling=resampling)
10
+ image = Raster.open(filename, geometry=geometry, resampling=resampling, nodata=np.nan)
11
+ image = rt.clip(image, 0, 100)
12
+ # TODO: scale C4_fraction to be within 0 and 1?
9
13
 
10
14
  return image
@@ -3,8 +3,10 @@ from os.path import join, abspath, dirname
3
3
  import rasters as rt
4
4
  from rasters import Raster, RasterGeometry
5
5
 
6
+ import numpy as np
7
+
6
8
  def load_NDVI_maximum(geometry: RasterGeometry = None, resampling: str = "nearest") -> Raster:
7
9
  filename = join(abspath(dirname(__file__)), "NDVI_maximum.tif")
8
- image = Raster.open(filename, geometry=geometry, resampling=resampling)
10
+ image = Raster.open(filename, geometry=geometry, resampling=resampling, nodata=np.nan)
9
11
 
10
12
  return image
@@ -3,8 +3,10 @@ from os.path import join, abspath, dirname
3
3
  import rasters as rt
4
4
  from rasters import Raster, RasterGeometry
5
5
 
6
+ import numpy as np
7
+
6
8
  def load_NDVI_minimum(geometry: RasterGeometry = None, resampling: str = "nearest") -> Raster:
7
9
  filename = join(abspath(dirname(__file__)), "NDVI_minimum.tif")
8
- image = Raster.open(filename, geometry=geometry, resampling=resampling)
10
+ image = Raster.open(filename, geometry=geometry, resampling=resampling, nodata=np.nan)
9
11
 
10
12
  return image
@@ -5,6 +5,6 @@ from rasters import Raster, RasterGeometry
5
5
 
6
6
  def load_ball_berry_slope_C3(geometry: RasterGeometry = None, resampling: str = "nearest") -> Raster:
7
7
  filename = join(abspath(dirname(__file__)), "ball_berry_slope_C3.tif")
8
- image = Raster.open(filename, geometry=geometry, resampling="nearest")
8
+ image = Raster.open(filename, geometry=geometry, resampling=resampling)
9
9
 
10
10
  return image
@@ -5,6 +5,6 @@ from rasters import Raster, RasterGeometry
5
5
 
6
6
  def load_ball_berry_slope_C4(geometry: RasterGeometry = None, resampling: str = "nearest") -> Raster:
7
7
  filename = join(abspath(dirname(__file__)), "ball_berry_slope_C4.tif")
8
- image = Raster.open(filename, geometry=geometry, resampling="nearest")
8
+ image = Raster.open(filename, geometry=geometry, resampling=resampling)
9
9
 
10
10
  return image
BESS_JPL/load_kn.py CHANGED
@@ -5,6 +5,6 @@ from rasters import Raster, RasterGeometry
5
5
 
6
6
  def load_kn(geometry: RasterGeometry = None, resampling: str = "nearest") -> Raster:
7
7
  filename = join(abspath(dirname(__file__)), "kn.tif")
8
- image = Raster.open(filename, geometry=geometry, resampling="nearest")
8
+ image = Raster.open(filename, geometry=geometry, resampling=resampling)
9
9
 
10
10
  return image
@@ -3,8 +3,10 @@ from os.path import join, abspath, dirname
3
3
  import rasters as rt
4
4
  from rasters import Raster, RasterGeometry
5
5
 
6
+ import numpy as np
7
+
6
8
  def load_peakVCmax_C3(geometry: RasterGeometry = None, resampling: str = "nearest") -> Raster:
7
9
  filename = join(abspath(dirname(__file__)), "peakVCmax_C3.tif")
8
- image = Raster.open(filename, geometry=geometry, resampling="nearest")
10
+ image = Raster.open(filename, geometry=geometry, resampling=resampling, nodata=np.nan)
9
11
 
10
12
  return image
@@ -3,8 +3,10 @@ from os.path import join, abspath, dirname
3
3
  import rasters as rt
4
4
  from rasters import Raster, RasterGeometry
5
5
 
6
+ import numpy as np
7
+
6
8
  def load_peakVCmax_C4(geometry: RasterGeometry = None, resampling: str = "nearest") -> Raster:
7
9
  filename = join(abspath(dirname(__file__)), "peakVCmax_C4.tif")
8
- image = Raster.open(filename, geometry=geometry, resampling="nearest")
10
+ image = Raster.open(filename, geometry=geometry, resampling=resampling, nodata=np.nan)
9
11
 
10
12
  return image
BESS_JPL/model.py CHANGED
@@ -6,7 +6,7 @@ import numpy as np
6
6
  import rasters as rt
7
7
  from rasters import Raster, RasterGeometry
8
8
 
9
- from .check_distribution import check_distribution
9
+ from check_distribution import check_distribution
10
10
 
11
11
  from sun_angles import calculate_SZA_from_DOY_and_hour
12
12
  from solar_apparent_time import solar_day_of_year_for_area, solar_hour_of_day_for_area
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: BESS-JPL
3
- Version: 1.15.0
3
+ Version: 1.16.0
4
4
  Summary: Breathing Earth System Simulator (BESS) Gross Primary Production (GPP) and Evapotranspiration (ET) Model Python
5
5
  Author-email: Gregory Halverson <gregory.h.halverson@jpl.nasa.gov>
6
6
  Project-URL: Homepage, https://github.com/JPL-Evapotranspiration-Algorithms/BESS-JPL
@@ -9,6 +9,7 @@ Classifier: Operating System :: OS Independent
9
9
  Requires-Python: >=3.10
10
10
  Description-Content-Type: text/markdown
11
11
  License-File: LICENSE
12
+ Requires-Dist: check-distribution
12
13
  Requires-Dist: FLiESANN>=1.5.0
13
14
  Requires-Dist: gedi-canopy-height>=1.1.0
14
15
  Requires-Dist: GEOS5FP>=1.1.1
@@ -1,4 +1,4 @@
1
- BESS_JPL/BESS_JPL.py,sha256=-OieL_tZ04yhlv0z3_s9XmrEuAPueIvGON1d1Aj-F2M,1366
1
+ BESS_JPL/BESS_JPL.py,sha256=CTby93_HwhONe2NOlt-8DuqDH7jL9mAc3euuzbouANg,1365
2
2
  BESS_JPL/C3_photosynthesis.py,sha256=-ormDycaWttCOoYJdOoOV_zlM6n0nxkgXxj7fyH_mIs,2760
3
3
  BESS_JPL/C4_fraction.jpeg,sha256=ECaEYWA8MnNd5z0Yq3beeUCR93KtTDxM8MrH-YYon3Y,2746
4
4
  BESS_JPL/C4_fraction.tif,sha256=DFS-J08JCjnf0hi_T_dFridAegVTiU3FGyMBjS9yc1w,25446
@@ -19,27 +19,26 @@ BESS_JPL/ball_berry_slope_C4.tif,sha256=UedoUOnOjBxQ9pAaf5nXgDa8wvKOHVBD3sVToV12
19
19
  BESS_JPL/calculate_VCmax.py,sha256=DDZk7v-ME_UtupiPPvTsGqI55-3JUv6i_jDYQozcqzQ,1959
20
20
  BESS_JPL/canopy_energy_balance.py,sha256=k7uEm15iv7cG11grvb3hZSgZ45nLbPkeniWJFk7K9rE,6452
21
21
  BESS_JPL/canopy_longwave_radiation.py,sha256=TH5YaxyVgVP58moZ0aDGkMukJfcPQQgiYbuCHO6TxPc,3407
22
- BESS_JPL/canopy_shortwave_radiation.py,sha256=jkMK3iYq1WsebfQWLrESd5ZwZ31vW-EKRpyn92_IxJU,9768
22
+ BESS_JPL/canopy_shortwave_radiation.py,sha256=TzDGFFBVHcZ3s5v-R9pQYeW9PPvYDQ168VdoqtCXh4U,9767
23
23
  BESS_JPL/carbon_uptake_efficiency.jpeg,sha256=wz2cLk_4-DRdF71xR2c-cx1MsE0CH-EDWjs2pDJcRF0,704540
24
24
  BESS_JPL/carbon_uptake_efficiency.tif,sha256=Nnc8h2ImU6_sip0WzDh3q0BRoBe-CfCbwzDtYo5BSog,819269
25
- BESS_JPL/carbon_water_fluxes.py,sha256=qkCq_B-_0F9XQz9IDWQBaF-OpiDKIuZmhS7vyYKtYkI,13746
26
- BESS_JPL/check_distribution.py,sha256=T6lYN_vBCb1duoJ1BZ0XLRXttEI81S4BwK0DKb8KDeI,4508
25
+ BESS_JPL/carbon_water_fluxes.py,sha256=T1E1AHne3lYvkEoasqlM4oLxoSWLWmeJxy1BzrVdPUw,12987
27
26
  BESS_JPL/constants.py,sha256=tOYubq17dnLVKhtTI0CJUQAEeROE4KeSBpOVBqZprUU,131
28
27
  BESS_JPL/interpolate_C3_C4.py,sha256=adIyk03Yt6SJ_jFCUm6ivK9QpZYw10C3wJKpx1O56Pk,394
29
28
  BESS_JPL/kn.jpeg,sha256=wsI40jabT9_iPpQmOxd3GZzfAN7oZ2DubiARmULFUS0,854097
30
29
  BESS_JPL/kn.tif,sha256=nZAIAms7LRDVsadxa4z8yRqOudWu3AjJSm6l1T3ywuY,819988
31
- BESS_JPL/load_C4_fraction.py,sha256=X9GDGTruuCDVV0pnle5kZHrCeS1hftFAgfitvebdDug,364
32
- BESS_JPL/load_NDVI_maximum.py,sha256=cwVeFlJrBmtEHzP3Mc0P7XMgWFoONW_zQfGCLAfZdoY,366
33
- BESS_JPL/load_NDVI_minimum.py,sha256=lbaEMz1UWF0l3hT8yp5ZJoMwByyPYBYCuYKoxnn6Dhs,366
30
+ BESS_JPL/load_C4_fraction.py,sha256=Fn8CKMzpvRCenlaVe8or9NnGmNZ-L5l_vdUpbjwcNSw,486
31
+ BESS_JPL/load_NDVI_maximum.py,sha256=CADnbDULc5qW0oR7UgNN9pM0oplz7QMf8Ki09_fbj-o,401
32
+ BESS_JPL/load_NDVI_minimum.py,sha256=RZaLXKxJe2ViEvj76_l-YSLIMyjo54nP4oAe-NEvACs,401
34
33
  BESS_JPL/load_ball_berry_intercept_C3.py,sha256=6auXZHej127rhUCFXe7vdEg9C4CosFSHLTcdqKs06Ls,388
35
- BESS_JPL/load_ball_berry_slope_C3.py,sha256=6yNdyouDXgryMcCevyuDfVqQJc8XdL7Z2454F5Y9Nvw,379
36
- BESS_JPL/load_ball_berry_slope_C4.py,sha256=gbDO8f8DYgzoWYMGr8zS5vWjGNLky4DWnMTHyOGguDk,379
34
+ BESS_JPL/load_ball_berry_slope_C3.py,sha256=9nmbdkGnJ7UWXwktpkE8rL1LGA1vi71YZdzpme04P84,380
35
+ BESS_JPL/load_ball_berry_slope_C4.py,sha256=lsKwrkbChEm3sspUgAXjm86Q4VBirwFOZStiO9NuGx8,380
37
36
  BESS_JPL/load_carbon_uptake_efficiency.py,sha256=RbWxLbqHnxiHw7XHyFBuWRToc8hDjUR6EUUntiJfe0M,390
38
- BESS_JPL/load_kn.py,sha256=_IE7w_VfahubfqjvgE6F6HCO0SizcpMu104_7ZXOiaw,345
39
- BESS_JPL/load_peakVCmax_C3.py,sha256=ISaCyaN81F3CyYbYwUqvUfQ_vjn4_jCpt1_x_b4fY5o,365
40
- BESS_JPL/load_peakVCmax_C4.py,sha256=8vtjEiJKCqSK04DfTs8Zgn-rWwGucmeeLMzblLT1U-Y,365
37
+ BESS_JPL/load_kn.py,sha256=39RkQkkdmey0IPInziJI0kSiI8alRk5Hz42pzm-qihU,346
38
+ BESS_JPL/load_peakVCmax_C3.py,sha256=A-Wg4PjPgogfpRsAMo6ZNEXM7G3KbnF7ZRV3k_jTtEA,401
39
+ BESS_JPL/load_peakVCmax_C4.py,sha256=iVmJTitkMkB4AjfjanAi3yv1lWO4sSF6J7cjuRmaCwU,401
41
40
  BESS_JPL/meteorology.py,sha256=xIPQnIk9wGJPy8esJyxn35d6c_7UyiNuWTJXDnuSwf8,6995
42
- BESS_JPL/model.py,sha256=ioCuQXPO3tbhF-PXlCm1I7oo1Apno2FRjAANm0ShLG8,22811
41
+ BESS_JPL/model.py,sha256=0JNCOeflASxA6iy70ppFuCkATPDnBDza2cQrJtHLtRY,22810
43
42
  BESS_JPL/peakVCmax_C3.jpeg,sha256=nVvwLx8JyRhtm5lWRW93HLz0mInshEdOCJ1tAdcFqa8,1006133
44
43
  BESS_JPL/peakVCmax_C3.tif,sha256=ax6wCOPc_ovgJJl9YRjPWNY13OCGlzs2djXqwob_U7A,1583598
45
44
  BESS_JPL/peakVCmax_C4.jpeg,sha256=s7dhpcD573KW9Se4mejDeSzbSHqPtQY2EL6KJKt7ZIo,961497
@@ -47,8 +46,8 @@ BESS_JPL/peakVCmax_C4.tif,sha256=EST4_yy-HHYmazIv--RePL_bhLejMWql6hoV9EE38ok,155
47
46
  BESS_JPL/process_BESS_table.py,sha256=TYsDEZNELGdUc0xkB1MRQIDkVonNL5d49q7Zl1iaJvo,1472
48
47
  BESS_JPL/soil_energy_balance.py,sha256=5TKDVkKYJ8jhjuiwbRva_03fi_0gTM0IAKbSm4WhWnY,944
49
48
  BESS_JPL/version.txt,sha256=-Q2F9kDoBjnO1g1dZcNwbI4pu99GLJDvdHkxmPdU4JU,6
50
- bess_jpl-1.15.0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
51
- bess_jpl-1.15.0.dist-info/METADATA,sha256=N6XioN8Coziy-RjHi-pXGw_CRN4KWqhwyCzBpG7HPec,6313
52
- bess_jpl-1.15.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
53
- bess_jpl-1.15.0.dist-info/top_level.txt,sha256=GaKnzt-BBktYn1o-w4Qzh_jHxse4Y3ACOxZQrB2ufhc,9
54
- bess_jpl-1.15.0.dist-info/RECORD,,
49
+ bess_jpl-1.16.0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
50
+ bess_jpl-1.16.0.dist-info/METADATA,sha256=q1qsKhcEH3_yB_Xo3AHDQORDQyuXM0Y6tpqNPqNsivU,6347
51
+ bess_jpl-1.16.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
52
+ bess_jpl-1.16.0.dist-info/top_level.txt,sha256=GaKnzt-BBktYn1o-w4Qzh_jHxse4Y3ACOxZQrB2ufhc,9
53
+ bess_jpl-1.16.0.dist-info/RECORD,,
@@ -1,118 +0,0 @@
1
- """
2
- Replacement for check_distribution package to avoid pycksum dependency.
3
-
4
- This module provides data validation functionality that was previously
5
- provided by the check-distribution package, which depends on pycksum
6
- that doesn't compile on Python 3.12.
7
- """
8
-
9
- import logging
10
- from typing import Union, Optional
11
- from datetime import datetime
12
-
13
- # Try to import numpy, but make it optional
14
- try:
15
- import numpy as np
16
- HAS_NUMPY = True
17
- except ImportError:
18
- np = None
19
- HAS_NUMPY = False
20
-
21
-
22
- logger = logging.getLogger(__name__)
23
-
24
-
25
- def check_distribution(
26
- data: Union["np.ndarray", float, int, None],
27
- name: str,
28
- time_UTC: Optional[datetime] = None
29
- ) -> None:
30
- """
31
- Check and validate data distribution, logging warnings for invalid values.
32
-
33
- This function validates input data and logs information about the distribution,
34
- including warnings for NaN values, infinite values, and basic statistics.
35
-
36
- Args:
37
- data: The data to validate (numpy array, scalar, or None)
38
- name: Name of the variable for logging purposes
39
- time_UTC: Optional timestamp for logging context
40
-
41
- Returns:
42
- None
43
-
44
- Raises:
45
- Nothing - this function only logs warnings and information
46
- """
47
-
48
- # Create log prefix with time if provided
49
- time_prefix = f"[{time_UTC}] " if time_UTC else ""
50
-
51
- if data is None:
52
- logger.warning(f"{time_prefix}{name}: data is None")
53
- return
54
-
55
- # Handle numpy arrays or array-like objects
56
- if hasattr(data, 'shape') and hasattr(data, 'dtype'):
57
- # This is likely a numpy array or array-like object
58
-
59
- if hasattr(data, 'size') and data.size == 0:
60
- logger.warning(f"{time_prefix}{name}: array is empty")
61
- return
62
-
63
- if HAS_NUMPY:
64
- # Use numpy functions if available
65
- # Check for NaN values
66
- if np.any(np.isnan(data)):
67
- nan_count = np.sum(np.isnan(data))
68
- nan_percentage = (nan_count / data.size) * 100
69
- logger.warning(f"{time_prefix}{name}: contains {nan_count} NaN values ({nan_percentage:.1f}%)")
70
-
71
- # Check for infinite values
72
- if np.any(np.isinf(data)):
73
- inf_count = np.sum(np.isinf(data))
74
- inf_percentage = (inf_count / data.size) * 100
75
- logger.warning(f"{time_prefix}{name}: contains {inf_count} infinite values ({inf_percentage:.1f}%)")
76
-
77
- # Calculate statistics for finite values only
78
- finite_data = data[np.isfinite(data)]
79
- if len(finite_data) > 0:
80
- min_val = np.min(finite_data)
81
- max_val = np.max(finite_data)
82
- mean_val = np.mean(finite_data)
83
- std_val = np.std(finite_data)
84
-
85
- logger.debug(f"{time_prefix}{name}: shape={data.shape}, "
86
- f"min={min_val:.6f}, max={max_val:.6f}, "
87
- f"mean={mean_val:.6f}, std={std_val:.6f}")
88
- else:
89
- logger.warning(f"{time_prefix}{name}: no finite values found")
90
- else:
91
- # Fallback when numpy is not available
92
- logger.debug(f"{time_prefix}{name}: array-like data validated (numpy not available for detailed analysis)")
93
-
94
- else:
95
- # Handle scalar values
96
- try:
97
- # Convert to float to check for NaN/inf
98
- float_val = float(data)
99
-
100
- if HAS_NUMPY:
101
- if np.isnan(float_val):
102
- logger.warning(f"{time_prefix}{name}: scalar value is NaN")
103
- elif np.isinf(float_val):
104
- logger.warning(f"{time_prefix}{name}: scalar value is infinite")
105
- else:
106
- logger.debug(f"{time_prefix}{name}: scalar value = {float_val:.6f}")
107
- else:
108
- # Basic validation without numpy
109
- import math
110
- if math.isnan(float_val):
111
- logger.warning(f"{time_prefix}{name}: scalar value is NaN")
112
- elif math.isinf(float_val):
113
- logger.warning(f"{time_prefix}{name}: scalar value is infinite")
114
- else:
115
- logger.debug(f"{time_prefix}{name}: scalar value = {float_val:.6f}")
116
-
117
- except (ValueError, TypeError) as e:
118
- logger.warning(f"{time_prefix}{name}: cannot convert to float for validation: {e}")