BESS-JPL 1.14.0__tar.gz → 1.15.0__tar.gz

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.

Files changed (74) hide show
  1. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL/BESS_JPL.py +1 -1
  2. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL/canopy_shortwave_radiation.py +1 -1
  3. bess_jpl-1.15.0/BESS_JPL/check_distribution.py +118 -0
  4. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL/model.py +8 -3
  5. bess_jpl-1.15.0/BESS_JPL/version.txt +1 -0
  6. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL.egg-info/PKG-INFO +2 -3
  7. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL.egg-info/SOURCES.txt +1 -0
  8. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL.egg-info/requires.txt +1 -2
  9. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/PKG-INFO +2 -3
  10. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/pyproject.toml +2 -3
  11. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/tests/test_import_dependencies.py +0 -1
  12. bess_jpl-1.14.0/BESS_JPL/version.txt +0 -1
  13. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/.github/workflows/ci.yml +0 -0
  14. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/.github/workflows/python-publish.yml +0 -0
  15. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/.gitignore +0 -0
  16. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS Sensitivity.ipynb +0 -0
  17. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL/C3_photosynthesis.py +0 -0
  18. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL/C4_fraction.jpeg +0 -0
  19. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL/C4_fraction.tif +0 -0
  20. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL/C4_photosynthesis.py +0 -0
  21. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL/FVC_from_NDVI.py +0 -0
  22. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL/LAI_from_NDVI.py +0 -0
  23. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL/NDVI_maximum.jpeg +0 -0
  24. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL/NDVI_maximum.tif +0 -0
  25. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL/NDVI_minimum.jpeg +0 -0
  26. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL/NDVI_minimum.tif +0 -0
  27. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL/__init__.py +0 -0
  28. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL/ball_berry_intercept_C3.jpeg +0 -0
  29. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL/ball_berry_intercept_C3.tif +0 -0
  30. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL/ball_berry_slope_C3.jpeg +0 -0
  31. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL/ball_berry_slope_C3.tif +0 -0
  32. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL/ball_berry_slope_C4.jpeg +0 -0
  33. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL/ball_berry_slope_C4.tif +0 -0
  34. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL/calculate_VCmax.py +0 -0
  35. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL/canopy_energy_balance.py +0 -0
  36. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL/canopy_longwave_radiation.py +0 -0
  37. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL/carbon_uptake_efficiency.jpeg +0 -0
  38. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL/carbon_uptake_efficiency.tif +0 -0
  39. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL/carbon_water_fluxes.py +0 -0
  40. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL/constants.py +0 -0
  41. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL/interpolate_C3_C4.py +0 -0
  42. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL/kn.jpeg +0 -0
  43. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL/kn.tif +0 -0
  44. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL/load_C4_fraction.py +0 -0
  45. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL/load_NDVI_maximum.py +0 -0
  46. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL/load_NDVI_minimum.py +0 -0
  47. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL/load_ball_berry_intercept_C3.py +0 -0
  48. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL/load_ball_berry_slope_C3.py +0 -0
  49. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL/load_ball_berry_slope_C4.py +0 -0
  50. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL/load_carbon_uptake_efficiency.py +0 -0
  51. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL/load_kn.py +0 -0
  52. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL/load_peakVCmax_C3.py +0 -0
  53. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL/load_peakVCmax_C4.py +0 -0
  54. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL/meteorology.py +0 -0
  55. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL/peakVCmax_C3.jpeg +0 -0
  56. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL/peakVCmax_C3.tif +0 -0
  57. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL/peakVCmax_C4.jpeg +0 -0
  58. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL/peakVCmax_C4.tif +0 -0
  59. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL/process_BESS_table.py +0 -0
  60. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL/soil_energy_balance.py +0 -0
  61. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL.egg-info/dependency_links.txt +0 -0
  62. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/BESS_JPL.egg-info/top_level.txt +0 -0
  63. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/C4 Fraction.ipynb +0 -0
  64. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/Dockerfile +0 -0
  65. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/LICENSE +0 -0
  66. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/Li_2023_RSE.pdf +0 -0
  67. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/MANIFEST.in +0 -0
  68. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/Processing BESS with rasters with default parameters.ipynb +0 -0
  69. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/Processing BESS with rasters.ipynb +0 -0
  70. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/README.md +0 -0
  71. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/makefile +0 -0
  72. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/processing_BESS_with_rasters_and_default_parameters.py +0 -0
  73. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/setup.cfg +0 -0
  74. {bess_jpl-1.14.0 → bess_jpl-1.15.0}/tests/test_import_BESS_JPL.py +0 -0
@@ -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(
@@ -0,0 +1,118 @@
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}")
@@ -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
@@ -16,7 +16,7 @@ from gedi_canopy_height import load_canopy_height, GEDI_DOWNLOAD_DIRECTORY
16
16
  from FLiESANN import FLiESANN
17
17
  from GEOS5FP import GEOS5FP
18
18
  from MODISCI import MODISCI
19
- from NASADEM import NASADEM
19
+ from NASADEM import NASADEMConnection
20
20
 
21
21
  from .constants import *
22
22
  from .C3_photosynthesis import *
@@ -88,6 +88,7 @@ def BESS_JPL(
88
88
  peakVCmax_C4: np.ndarray = None, # peak maximum carboxylation rate for C4 plants
89
89
  CI: Union[Raster, np.ndarray] = None,
90
90
  MODISCI_connection: MODISCI = None,
91
+ NASADEM_connection: NASADEMConnection = None,
91
92
  resampling: str = RESAMPLING,
92
93
  GEDI_download_directory: str = GEDI_DOWNLOAD_DIRECTORY): # clumping index
93
94
  if geometry is None and isinstance(ST_C, Raster):
@@ -104,7 +105,11 @@ def BESS_JPL(
104
105
  raise ValueError("no time given between time_UTC, day_of_year, and hour_of_day")
105
106
 
106
107
  if elevation_km is None and geometry is not None:
107
- elevation_km = NASADEM.elevation_km(geometry=geometry)
108
+ if NASADEM_connection is None:
109
+ from NASADEM import NASADEMConnection
110
+ NASADEM_connection = NASADEMConnection()
111
+
112
+ elevation_km = NASADEM_connection.elevation_km(geometry=geometry)
108
113
 
109
114
  # load air temperature in Celsius if not provided
110
115
  if Ta_C is None:
@@ -0,0 +1 @@
1
+ 1.15.0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: BESS-JPL
3
- Version: 1.14.0
3
+ Version: 1.15.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,13 +9,12 @@ 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
13
12
  Requires-Dist: FLiESANN>=1.5.0
14
13
  Requires-Dist: gedi-canopy-height>=1.1.0
15
14
  Requires-Dist: GEOS5FP>=1.1.1
16
15
  Requires-Dist: koppengeiger>=1.0.4
17
16
  Requires-Dist: MODISCI>=1.3.0
18
- Requires-Dist: NASADEM
17
+ Requires-Dist: NASADEM>=1.3.0
19
18
  Requires-Dist: numpy
20
19
  Requires-Dist: rasters
21
20
  Requires-Dist: solar-apparent-time>=1.3.2
@@ -38,6 +38,7 @@ BESS_JPL/canopy_shortwave_radiation.py
38
38
  BESS_JPL/carbon_uptake_efficiency.jpeg
39
39
  BESS_JPL/carbon_uptake_efficiency.tif
40
40
  BESS_JPL/carbon_water_fluxes.py
41
+ BESS_JPL/check_distribution.py
41
42
  BESS_JPL/constants.py
42
43
  BESS_JPL/interpolate_C3_C4.py
43
44
  BESS_JPL/kn.jpeg
@@ -1,10 +1,9 @@
1
- check-distribution
2
1
  FLiESANN>=1.5.0
3
2
  gedi-canopy-height>=1.1.0
4
3
  GEOS5FP>=1.1.1
5
4
  koppengeiger>=1.0.4
6
5
  MODISCI>=1.3.0
7
- NASADEM
6
+ NASADEM>=1.3.0
8
7
  numpy
9
8
  rasters
10
9
  solar-apparent-time>=1.3.2
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: BESS-JPL
3
- Version: 1.14.0
3
+ Version: 1.15.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,13 +9,12 @@ 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
13
12
  Requires-Dist: FLiESANN>=1.5.0
14
13
  Requires-Dist: gedi-canopy-height>=1.1.0
15
14
  Requires-Dist: GEOS5FP>=1.1.1
16
15
  Requires-Dist: koppengeiger>=1.0.4
17
16
  Requires-Dist: MODISCI>=1.3.0
18
- Requires-Dist: NASADEM
17
+ Requires-Dist: NASADEM>=1.3.0
19
18
  Requires-Dist: numpy
20
19
  Requires-Dist: rasters
21
20
  Requires-Dist: solar-apparent-time>=1.3.2
@@ -3,7 +3,7 @@ requires = ["setuptools>=60", "setuptools-scm>=8.0", "wheel"]
3
3
 
4
4
  [project]
5
5
  name = "BESS-JPL"
6
- version = "1.14.0"
6
+ version = "1.15.0"
7
7
  description = "Breathing Earth System Simulator (BESS) Gross Primary Production (GPP) and Evapotranspiration (ET) Model Python"
8
8
  readme = "README.md"
9
9
  authors = [
@@ -14,13 +14,12 @@ classifiers = [
14
14
  "Operating System :: OS Independent",
15
15
  ]
16
16
  dependencies = [
17
- "check-distribution",
18
17
  "FLiESANN>=1.5.0",
19
18
  "gedi-canopy-height>=1.1.0",
20
19
  "GEOS5FP>=1.1.1",
21
20
  "koppengeiger>=1.0.4",
22
21
  "MODISCI>=1.3.0",
23
- "NASADEM",
22
+ "NASADEM>=1.3.0",
24
23
  "numpy",
25
24
  "rasters",
26
25
  "solar-apparent-time>=1.3.2"
@@ -2,7 +2,6 @@ import pytest
2
2
 
3
3
  # List of dependencies
4
4
  dependencies = [
5
- "check_distribution",
6
5
  "FLiESANN",
7
6
  "gedi_canopy_height",
8
7
  "GEOS5FP",
@@ -1 +0,0 @@
1
- 1.14.0
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes