BESS-JPL 1.9.2__tar.gz → 1.10.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 (73) hide show
  1. bess_jpl-1.10.0/BESS Sensitivity.ipynb +264 -0
  2. bess_jpl-1.10.0/BESS_JPL/BESS_JPL.py +44 -0
  3. bess_jpl-1.9.2/BESS_JPL/BESS_JPL.py → bess_jpl-1.10.0/BESS_JPL/model.py +1 -17
  4. bess_jpl-1.10.0/BESS_JPL/process_BESS_table.py +55 -0
  5. bess_jpl-1.10.0/BESS_JPL/version.txt +1 -0
  6. {bess_jpl-1.9.2 → bess_jpl-1.10.0/BESS_JPL.egg-info}/PKG-INFO +1 -1
  7. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/BESS_JPL.egg-info/SOURCES.txt +3 -0
  8. {bess_jpl-1.9.2/BESS_JPL.egg-info → bess_jpl-1.10.0}/PKG-INFO +1 -1
  9. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/Processing BESS with rasters.ipynb +83 -66
  10. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/pyproject.toml +1 -1
  11. bess_jpl-1.9.2/BESS_JPL/version.txt +0 -1
  12. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/.github/workflows/ci.yml +0 -0
  13. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/.github/workflows/python-publish.yml +0 -0
  14. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/.gitignore +0 -0
  15. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/BESS_JPL/C3_photosynthesis.py +0 -0
  16. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/BESS_JPL/C4_fraction.jpeg +0 -0
  17. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/BESS_JPL/C4_fraction.tif +0 -0
  18. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/BESS_JPL/C4_photosynthesis.py +0 -0
  19. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/BESS_JPL/FVC_from_NDVI.py +0 -0
  20. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/BESS_JPL/LAI_from_NDVI.py +0 -0
  21. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/BESS_JPL/NDVI_maximum.jpeg +0 -0
  22. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/BESS_JPL/NDVI_maximum.tif +0 -0
  23. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/BESS_JPL/NDVI_minimum.jpeg +0 -0
  24. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/BESS_JPL/NDVI_minimum.tif +0 -0
  25. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/BESS_JPL/__init__.py +0 -0
  26. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/BESS_JPL/ball_berry_intercept_C3.jpeg +0 -0
  27. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/BESS_JPL/ball_berry_intercept_C3.tif +0 -0
  28. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/BESS_JPL/ball_berry_slope_C3.jpeg +0 -0
  29. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/BESS_JPL/ball_berry_slope_C3.tif +0 -0
  30. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/BESS_JPL/ball_berry_slope_C4.jpeg +0 -0
  31. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/BESS_JPL/ball_berry_slope_C4.tif +0 -0
  32. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/BESS_JPL/calculate_VCmax.py +0 -0
  33. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/BESS_JPL/canopy_energy_balance.py +0 -0
  34. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/BESS_JPL/canopy_longwave_radiation.py +0 -0
  35. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/BESS_JPL/canopy_shortwave_radiation.py +0 -0
  36. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/BESS_JPL/carbon_uptake_efficiency.jpeg +0 -0
  37. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/BESS_JPL/carbon_uptake_efficiency.tif +0 -0
  38. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/BESS_JPL/carbon_water_fluxes.py +0 -0
  39. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/BESS_JPL/constants.py +0 -0
  40. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/BESS_JPL/interpolate_C3_C4.py +0 -0
  41. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/BESS_JPL/kn.jpeg +0 -0
  42. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/BESS_JPL/kn.tif +0 -0
  43. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/BESS_JPL/load_C4_fraction.py +0 -0
  44. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/BESS_JPL/load_NDVI_maximum.py +0 -0
  45. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/BESS_JPL/load_NDVI_minimum.py +0 -0
  46. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/BESS_JPL/load_ball_berry_intercept_C3.py +0 -0
  47. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/BESS_JPL/load_ball_berry_slope_C3.py +0 -0
  48. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/BESS_JPL/load_ball_berry_slope_C4.py +0 -0
  49. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/BESS_JPL/load_carbon_uptake_efficiency.py +0 -0
  50. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/BESS_JPL/load_kn.py +0 -0
  51. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/BESS_JPL/load_peakVCmax_C3.py +0 -0
  52. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/BESS_JPL/load_peakVCmax_C4.py +0 -0
  53. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/BESS_JPL/meteorology.py +0 -0
  54. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/BESS_JPL/peakVCmax_C3.jpeg +0 -0
  55. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/BESS_JPL/peakVCmax_C3.tif +0 -0
  56. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/BESS_JPL/peakVCmax_C4.jpeg +0 -0
  57. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/BESS_JPL/peakVCmax_C4.tif +0 -0
  58. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/BESS_JPL/soil_energy_balance.py +0 -0
  59. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/BESS_JPL.egg-info/dependency_links.txt +0 -0
  60. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/BESS_JPL.egg-info/requires.txt +0 -0
  61. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/BESS_JPL.egg-info/top_level.txt +0 -0
  62. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/C4 Fraction.ipynb +0 -0
  63. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/Dockerfile +0 -0
  64. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/LICENSE +0 -0
  65. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/Li_2023_RSE.pdf +0 -0
  66. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/MANIFEST.in +0 -0
  67. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/Processing BESS with rasters with default parameters.ipynb +0 -0
  68. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/README.md +0 -0
  69. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/makefile +0 -0
  70. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/processing_BESS_with_rasters_and_default_parameters.py +0 -0
  71. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/setup.cfg +0 -0
  72. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/tests/test_import_BESS_JPL.py +0 -0
  73. {bess_jpl-1.9.2 → bess_jpl-1.10.0}/tests/test_import_dependencies.py +0 -0
@@ -0,0 +1,264 @@
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": 1,
6
+ "metadata": {},
7
+ "outputs": [
8
+ {
9
+ "name": "stdout",
10
+ "output_type": "stream",
11
+ "text": [
12
+ "[2025-04-25 19:26:24 INFO] SRTM working directory: \u001b[34m/Users/gregoryhalverson/data/NASADEM\u001b[0m\n",
13
+ "[2025-04-25 19:26:24 INFO] SRTM download directory: \u001b[34m/Users/gregoryhalverson/data/NASADEM\u001b[0m\n"
14
+ ]
15
+ }
16
+ ],
17
+ "source": [
18
+ "import numpy as np\n",
19
+ "import pandas as pd\n",
20
+ "from pandas import DataFrame\n",
21
+ "from monte_carlo_sensitivity import perturbed_run, sensitivity_analysis\n",
22
+ "from BESS_JPL import BESS_JPL\n",
23
+ "# from BESS_JPL import process_BESS_table\n",
24
+ "import matplotlib.pyplot as plt\n",
25
+ "import seaborn as sns"
26
+ ]
27
+ },
28
+ {
29
+ "cell_type": "markdown",
30
+ "metadata": {},
31
+ "source": []
32
+ },
33
+ {
34
+ "cell_type": "code",
35
+ "execution_count": 2,
36
+ "metadata": {},
37
+ "outputs": [],
38
+ "source": [
39
+ "def process_BESS_table(input_df: DataFrame) -> DataFrame:\n",
40
+ " ST_C = np.array(input_df.ST_C).astype(np.float64)\n",
41
+ " NDVI = np.array(input_df.NDVI).astype(np.float64)\n",
42
+ "\n",
43
+ " NDVI = np.where(NDVI > 0.06, NDVI, np.nan).astype(np.float64)\n",
44
+ "\n",
45
+ " albedo = np.array(input_df.albedo).astype(np.float64)\n",
46
+ " \n",
47
+ " if \"Ta_C\" in input_df:\n",
48
+ " Ta_C = np.array(input_df.Ta_C).astype(np.float64)\n",
49
+ " elif \"Ta\" in input_df:\n",
50
+ " Ta_C = np.array(input_df.Ta).astype(np.float64)\n",
51
+ "\n",
52
+ " RH = np.array(input_df.RH).astype(np.float64)\n",
53
+ " Rn = np.array(input_df.Rn).astype(np.float64)\n",
54
+ " \n",
55
+ " results = BESS_JPL(\n",
56
+ " NDVI=NDVI,\n",
57
+ " Ta_C=Ta_C,\n",
58
+ " RH=RH,\n",
59
+ " Rn=Rn\n",
60
+ " )\n",
61
+ "\n",
62
+ " output_df = input_df.copy()\n",
63
+ "\n",
64
+ " for key, value in results.items():\n",
65
+ " output_df[key] = value\n",
66
+ "\n",
67
+ " return output_df\n"
68
+ ]
69
+ },
70
+ {
71
+ "cell_type": "code",
72
+ "execution_count": 3,
73
+ "metadata": {},
74
+ "outputs": [
75
+ {
76
+ "ename": "FileNotFoundError",
77
+ "evalue": "[Errno 2] No such file or directory: 'BESS_inputs_salton_sea.csv'",
78
+ "output_type": "error",
79
+ "traceback": [
80
+ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
81
+ "\u001b[0;31mFileNotFoundError\u001b[0m Traceback (most recent call last)",
82
+ "Cell \u001b[0;32mIn[3], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m input_df \u001b[38;5;241m=\u001b[39m \u001b[43mpd\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mread_csv\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mBESS_inputs_salton_sea.csv\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[1;32m 2\u001b[0m input_df \u001b[38;5;241m=\u001b[39m input_df[input_df\u001b[38;5;241m.\u001b[39mNDVI \u001b[38;5;241m>\u001b[39m \u001b[38;5;241m0.1\u001b[39m]\n\u001b[1;32m 3\u001b[0m input_df \u001b[38;5;241m=\u001b[39m input_df\u001b[38;5;241m.\u001b[39msample(\u001b[38;5;241m10000\u001b[39m)\n",
83
+ "File \u001b[0;32m/opt/homebrew/Caskroom/miniforge/base/envs/sensitivity/lib/python3.10/site-packages/pandas/io/parsers/readers.py:1026\u001b[0m, in \u001b[0;36mread_csv\u001b[0;34m(filepath_or_buffer, sep, delimiter, header, names, index_col, usecols, dtype, engine, converters, true_values, false_values, skipinitialspace, skiprows, skipfooter, nrows, na_values, keep_default_na, na_filter, verbose, skip_blank_lines, parse_dates, infer_datetime_format, keep_date_col, date_parser, date_format, dayfirst, cache_dates, iterator, chunksize, compression, thousands, decimal, lineterminator, quotechar, quoting, doublequote, escapechar, comment, encoding, encoding_errors, dialect, on_bad_lines, delim_whitespace, low_memory, memory_map, float_precision, storage_options, dtype_backend)\u001b[0m\n\u001b[1;32m 1013\u001b[0m kwds_defaults \u001b[38;5;241m=\u001b[39m _refine_defaults_read(\n\u001b[1;32m 1014\u001b[0m dialect,\n\u001b[1;32m 1015\u001b[0m delimiter,\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 1022\u001b[0m dtype_backend\u001b[38;5;241m=\u001b[39mdtype_backend,\n\u001b[1;32m 1023\u001b[0m )\n\u001b[1;32m 1024\u001b[0m kwds\u001b[38;5;241m.\u001b[39mupdate(kwds_defaults)\n\u001b[0;32m-> 1026\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43m_read\u001b[49m\u001b[43m(\u001b[49m\u001b[43mfilepath_or_buffer\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mkwds\u001b[49m\u001b[43m)\u001b[49m\n",
84
+ "File \u001b[0;32m/opt/homebrew/Caskroom/miniforge/base/envs/sensitivity/lib/python3.10/site-packages/pandas/io/parsers/readers.py:620\u001b[0m, in \u001b[0;36m_read\u001b[0;34m(filepath_or_buffer, kwds)\u001b[0m\n\u001b[1;32m 617\u001b[0m _validate_names(kwds\u001b[38;5;241m.\u001b[39mget(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mnames\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;28;01mNone\u001b[39;00m))\n\u001b[1;32m 619\u001b[0m \u001b[38;5;66;03m# Create the parser.\u001b[39;00m\n\u001b[0;32m--> 620\u001b[0m parser \u001b[38;5;241m=\u001b[39m \u001b[43mTextFileReader\u001b[49m\u001b[43m(\u001b[49m\u001b[43mfilepath_or_buffer\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwds\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 622\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m chunksize \u001b[38;5;129;01mor\u001b[39;00m iterator:\n\u001b[1;32m 623\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m parser\n",
85
+ "File \u001b[0;32m/opt/homebrew/Caskroom/miniforge/base/envs/sensitivity/lib/python3.10/site-packages/pandas/io/parsers/readers.py:1620\u001b[0m, in \u001b[0;36mTextFileReader.__init__\u001b[0;34m(self, f, engine, **kwds)\u001b[0m\n\u001b[1;32m 1617\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39moptions[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mhas_index_names\u001b[39m\u001b[38;5;124m\"\u001b[39m] \u001b[38;5;241m=\u001b[39m kwds[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mhas_index_names\u001b[39m\u001b[38;5;124m\"\u001b[39m]\n\u001b[1;32m 1619\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mhandles: IOHandles \u001b[38;5;241m|\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[0;32m-> 1620\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_engine \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_make_engine\u001b[49m\u001b[43m(\u001b[49m\u001b[43mf\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mengine\u001b[49m\u001b[43m)\u001b[49m\n",
86
+ "File \u001b[0;32m/opt/homebrew/Caskroom/miniforge/base/envs/sensitivity/lib/python3.10/site-packages/pandas/io/parsers/readers.py:1880\u001b[0m, in \u001b[0;36mTextFileReader._make_engine\u001b[0;34m(self, f, engine)\u001b[0m\n\u001b[1;32m 1878\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mb\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;129;01min\u001b[39;00m mode:\n\u001b[1;32m 1879\u001b[0m mode \u001b[38;5;241m+\u001b[39m\u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mb\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m-> 1880\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mhandles \u001b[38;5;241m=\u001b[39m \u001b[43mget_handle\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 1881\u001b[0m \u001b[43m \u001b[49m\u001b[43mf\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 1882\u001b[0m \u001b[43m \u001b[49m\u001b[43mmode\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 1883\u001b[0m \u001b[43m \u001b[49m\u001b[43mencoding\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43moptions\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mencoding\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 1884\u001b[0m \u001b[43m \u001b[49m\u001b[43mcompression\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43moptions\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mcompression\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 1885\u001b[0m \u001b[43m \u001b[49m\u001b[43mmemory_map\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43moptions\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mmemory_map\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 1886\u001b[0m \u001b[43m \u001b[49m\u001b[43mis_text\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mis_text\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 1887\u001b[0m \u001b[43m \u001b[49m\u001b[43merrors\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43moptions\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mencoding_errors\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mstrict\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 1888\u001b[0m \u001b[43m \u001b[49m\u001b[43mstorage_options\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43moptions\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mstorage_options\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 1889\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 1890\u001b[0m \u001b[38;5;28;01massert\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mhandles \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[1;32m 1891\u001b[0m f \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mhandles\u001b[38;5;241m.\u001b[39mhandle\n",
87
+ "File \u001b[0;32m/opt/homebrew/Caskroom/miniforge/base/envs/sensitivity/lib/python3.10/site-packages/pandas/io/common.py:873\u001b[0m, in \u001b[0;36mget_handle\u001b[0;34m(path_or_buf, mode, encoding, compression, memory_map, is_text, errors, storage_options)\u001b[0m\n\u001b[1;32m 868\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(handle, \u001b[38;5;28mstr\u001b[39m):\n\u001b[1;32m 869\u001b[0m \u001b[38;5;66;03m# Check whether the filename is to be opened in binary mode.\u001b[39;00m\n\u001b[1;32m 870\u001b[0m \u001b[38;5;66;03m# Binary mode does not support 'encoding' and 'newline'.\u001b[39;00m\n\u001b[1;32m 871\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m ioargs\u001b[38;5;241m.\u001b[39mencoding \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mb\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;129;01min\u001b[39;00m ioargs\u001b[38;5;241m.\u001b[39mmode:\n\u001b[1;32m 872\u001b[0m \u001b[38;5;66;03m# Encoding\u001b[39;00m\n\u001b[0;32m--> 873\u001b[0m handle \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mopen\u001b[39;49m\u001b[43m(\u001b[49m\n\u001b[1;32m 874\u001b[0m \u001b[43m \u001b[49m\u001b[43mhandle\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 875\u001b[0m \u001b[43m \u001b[49m\u001b[43mioargs\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmode\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 876\u001b[0m \u001b[43m \u001b[49m\u001b[43mencoding\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mioargs\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mencoding\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 877\u001b[0m \u001b[43m \u001b[49m\u001b[43merrors\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43merrors\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 878\u001b[0m \u001b[43m \u001b[49m\u001b[43mnewline\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 879\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 880\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 881\u001b[0m \u001b[38;5;66;03m# Binary mode\u001b[39;00m\n\u001b[1;32m 882\u001b[0m handle \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mopen\u001b[39m(handle, ioargs\u001b[38;5;241m.\u001b[39mmode)\n",
88
+ "\u001b[0;31mFileNotFoundError\u001b[0m: [Errno 2] No such file or directory: 'BESS_inputs_salton_sea.csv'"
89
+ ]
90
+ }
91
+ ],
92
+ "source": [
93
+ "input_df = pd.read_csv(\"BESS_inputs_salton_sea.csv\")\n",
94
+ "input_df = input_df[input_df.NDVI > 0.1]\n",
95
+ "input_df = input_df.sample(10000)\n",
96
+ "input_df"
97
+ ]
98
+ },
99
+ {
100
+ "cell_type": "code",
101
+ "execution_count": null,
102
+ "metadata": {},
103
+ "outputs": [],
104
+ "source": [
105
+ "input_variables = [\"ST_C\", \"NDVI\", \"albedo\", \"Ta_C\", \"RH\", \"VISdiff\", \"VISdir\", \"NIRdiff\", \"NIRdir\", \"UV\"]\n",
106
+ "output_variables = [\"GPP\", \"Rn\", \"LE\"]\n",
107
+ "\n",
108
+ "perturbation_df, sensitivity_metrics_df = sensitivity_analysis(\n",
109
+ " input_df=input_df,\n",
110
+ " input_variables=input_variables,\n",
111
+ " output_variables=output_variables,\n",
112
+ " forward_process=process_BESS_table\n",
113
+ ")\n",
114
+ "\n",
115
+ "sensitivity_metrics_df"
116
+ ]
117
+ },
118
+ {
119
+ "cell_type": "code",
120
+ "execution_count": null,
121
+ "metadata": {},
122
+ "outputs": [],
123
+ "source": [
124
+ "df = sensitivity_metrics_df\n",
125
+ "df = df[(df.output_variable == \"GPP\") & (df.metric == \"correlation\")]\n",
126
+ "df = df.dropna()\n",
127
+ "df"
128
+ ]
129
+ },
130
+ {
131
+ "cell_type": "code",
132
+ "execution_count": null,
133
+ "metadata": {},
134
+ "outputs": [],
135
+ "source": [
136
+ "df = sensitivity_metrics_df\n",
137
+ "df = df[(df.output_variable == \"GPP\") & (df.metric == \"correlation\")]\n",
138
+ "df = df.dropna()\n",
139
+ "ax = sns.barplot(x=df.input_variable, y=df.value)\n",
140
+ "ax.set_xticklabels([\"Surface\\nTemperature\", \"Albedo\", \"Air\\nTemperature\", \"Visible\\nDiffuse\\nRadiation\", \"Visible\\nDirect\\nRadiation\"])\n",
141
+ "plt.xlabel(\"Input Variable\")\n",
142
+ "plt.ylabel(\"Correlation of Input Perturbation to Output Perturbation\")\n",
143
+ "plt.title(\"BESS GPP Sensitivity\")"
144
+ ]
145
+ },
146
+ {
147
+ "cell_type": "code",
148
+ "execution_count": null,
149
+ "metadata": {},
150
+ "outputs": [],
151
+ "source": [
152
+ "df = sensitivity_metrics_df\n",
153
+ "df = df[(df.output_variable == \"GPP\") & (df.metric == \"r2\")]\n",
154
+ "df = df.dropna()\n",
155
+ "df = df[df.value>0]\n",
156
+ "df"
157
+ ]
158
+ },
159
+ {
160
+ "cell_type": "code",
161
+ "execution_count": null,
162
+ "metadata": {},
163
+ "outputs": [],
164
+ "source": [
165
+ "df = sensitivity_metrics_df\n",
166
+ "df = df[(df.output_variable == \"GPP\") & (df.metric == \"r2\")]\n",
167
+ "df = df.dropna()\n",
168
+ "df = df[df.value>0]\n",
169
+ "ax = sns.barplot(x=df.input_variable, y=df.value)\n",
170
+ "ax.set_xticklabels([\"Surface\\nTemperature\", \"Albedo\", \"Air\\nTemperature\", \"Visible\\nDiffuse\\nRadiation\", \"Visible\\nDirect\\nRadiation\"])\n",
171
+ "plt.xlabel(\"Input Variable\")\n",
172
+ "plt.ylabel(\"Coefficient of Determination\\nfrom Input Perturbation to Output Perturbation\")\n",
173
+ "plt.title(\"BESS GPP Sensitivity\")"
174
+ ]
175
+ },
176
+ {
177
+ "cell_type": "code",
178
+ "execution_count": null,
179
+ "metadata": {},
180
+ "outputs": [],
181
+ "source": [
182
+ "df = sensitivity_metrics_df\n",
183
+ "df = df[(df.output_variable == \"Rn\") & (df.metric == \"correlation\")]\n",
184
+ "df = df.dropna()\n",
185
+ "ax = sns.barplot(x=df.input_variable, y=df.value)\n",
186
+ "# ax.set_xticklabels([\"Surface\\nTemperature\", \"Albedo\", \"Air\\nTemperature\", \"Visible\\nDiffuse\\nRadiation\", \"Visible\\nDirect\\nRadiation\"])\n",
187
+ "plt.xlabel(\"Input Variable\")\n",
188
+ "plt.ylabel(\"Correlation of Input Perturbation to Output Perturbation\")\n",
189
+ "plt.title(\"BESS Net Radiation Sensitivity\")"
190
+ ]
191
+ },
192
+ {
193
+ "cell_type": "code",
194
+ "execution_count": null,
195
+ "metadata": {},
196
+ "outputs": [],
197
+ "source": [
198
+ "df = sensitivity_metrics_df\n",
199
+ "df = df[(df.output_variable == \"Rn\") & (df.metric == \"r2\")]\n",
200
+ "df = df.dropna()\n",
201
+ "df = df[df.value>0]\n",
202
+ "ax = sns.barplot(x=df.input_variable, y=df.value)\n",
203
+ "# ax.set_xticklabels([\"Surface\\nTemperature\", \"Albedo\", \"Air\\nTemperature\", \"Visible\\nDiffuse\\nRadiation\", \"Visible\\nDirect\\nRadiation\"])\n",
204
+ "plt.xlabel(\"Input Variable\")\n",
205
+ "plt.ylabel(\"Coefficient of Determination\\nfrom Input Perturbation to Output Perturbation\")\n",
206
+ "plt.title(\"BESS Net Radiation Sensitivity\")"
207
+ ]
208
+ },
209
+ {
210
+ "cell_type": "code",
211
+ "execution_count": null,
212
+ "metadata": {},
213
+ "outputs": [],
214
+ "source": [
215
+ "df = sensitivity_metrics_df\n",
216
+ "df = df[(df.output_variable == \"LE\") & (df.metric == \"correlation\")]\n",
217
+ "df = df.dropna()\n",
218
+ "ax = sns.barplot(x=df.input_variable, y=df.value)\n",
219
+ "# ax.set_xticklabels([\"Surface\\nTemperature\", \"Albedo\", \"Air\\nTemperature\", \"Visible\\nDiffuse\\nRadiation\", \"Visible\\nDirect\\nRadiation\"])\n",
220
+ "plt.xlabel(\"Input Variable\")\n",
221
+ "plt.ylabel(\"Correlation of Input Perturbation to Output Perturbation\")\n",
222
+ "plt.title(\"BESS Evapotranspiration Sensitivity\")"
223
+ ]
224
+ },
225
+ {
226
+ "cell_type": "code",
227
+ "execution_count": null,
228
+ "metadata": {},
229
+ "outputs": [],
230
+ "source": [
231
+ "df = sensitivity_metrics_df\n",
232
+ "df = df[(df.output_variable == \"LE\") & (df.metric == \"r2\")]\n",
233
+ "df = df.dropna()\n",
234
+ "df = df[df.value>0]\n",
235
+ "ax = sns.barplot(x=df.input_variable, y=df.value)\n",
236
+ "# ax.set_xticklabels([\"Surface\\nTemperature\", \"Albedo\", \"Air\\nTemperature\", \"Visible\\nDiffuse\\nRadiation\", \"Visible\\nDirect\\nRadiation\"])\n",
237
+ "plt.xlabel(\"Input Variable\")\n",
238
+ "plt.ylabel(\"Coefficient of Determination\\nfrom Input Perturbation to Output Perturbation\")\n",
239
+ "plt.title(\"BESS Evapotranspiration Sensitivity\")"
240
+ ]
241
+ }
242
+ ],
243
+ "metadata": {
244
+ "kernelspec": {
245
+ "display_name": "BESS-JPL",
246
+ "language": "python",
247
+ "name": "python3"
248
+ },
249
+ "language_info": {
250
+ "codemirror_mode": {
251
+ "name": "ipython",
252
+ "version": 3
253
+ },
254
+ "file_extension": ".py",
255
+ "mimetype": "text/x-python",
256
+ "name": "python",
257
+ "nbconvert_exporter": "python",
258
+ "pygments_lexer": "ipython3",
259
+ "version": "3.10.17"
260
+ }
261
+ },
262
+ "nbformat": 4,
263
+ "nbformat_minor": 2
264
+ }
@@ -0,0 +1,44 @@
1
+ from typing import Union
2
+ from datetime import datetime
3
+ import logging
4
+ import numpy as np
5
+
6
+ import rasters as rt
7
+ from rasters import Raster, RasterGeometry
8
+
9
+ from check_distribution import check_distribution
10
+
11
+ from sun_angles import calculate_SZA_from_DOY_and_hour
12
+ from solar_apparent_time import solar_day_of_year_for_area, solar_hour_of_day_for_area
13
+
14
+ from koppengeiger import load_koppen_geiger
15
+ from gedi_canopy_height import load_canopy_height
16
+ from FLiESANN import FLiESANN
17
+ from GEOS5FP import GEOS5FP
18
+ from MODISCI import MODISCI
19
+ from NASADEM import NASADEM
20
+
21
+ from .constants import *
22
+ from .C3_photosynthesis import *
23
+ from .C4_photosynthesis import *
24
+ from .canopy_energy_balance import *
25
+ from .canopy_longwave_radiation import *
26
+ from .canopy_shortwave_radiation import *
27
+ from .carbon_water_fluxes import *
28
+ from .FVC_from_NDVI import *
29
+ from .interpolate_C3_C4 import *
30
+ from .LAI_from_NDVI import *
31
+ from .load_C4_fraction import *
32
+ from .load_carbon_uptake_efficiency import *
33
+ from .load_kn import *
34
+ from .load_NDVI_minimum import *
35
+ from .load_NDVI_maximum import *
36
+ from .load_peakVCmax_C3 import *
37
+ from .load_peakVCmax_C4 import *
38
+ from .load_ball_berry_intercept_C3 import *
39
+ from .load_ball_berry_slope_C3 import *
40
+ from .load_ball_berry_slope_C4 import *
41
+ from .calculate_VCmax import *
42
+ from .meteorology import *
43
+ from .soil_energy_balance import *
44
+ from .model import *
@@ -166,34 +166,19 @@ def BESS_JPL(
166
166
 
167
167
  # Check for None values and size mismatches
168
168
  reference_size = None
169
- missing_radiative_transfer_variables = []
170
- need_radiative_transfer = False
171
-
172
169
  for name, var in variables_to_check.items():
173
- if var is None:
174
- logger.info(f"{name}: None")
175
- else:
176
- logger.info(f"{name}: {var.shape}")
177
-
178
170
  if var is None:
179
171
  logger.warning(f"Variable '{name}' is None.")
180
- missing_radiative_transfer_variables = missing_radiative_transfer_variables.append(name)
181
172
  else:
182
173
  # Get the size of the variable if it's a numpy array
183
174
  size = var.shape if isinstance(var, np.ndarray) else None
184
-
185
175
  if reference_size is None:
186
176
  reference_size = size # Set the first non-None size as the reference
187
177
  elif size != reference_size:
188
178
  logger.warning(f"Variable '{name}' has a different size: {size} (expected: {reference_size}).")
189
- missing_radiative_transfer_variables = missing_radiative_transfer_variables.append(name)
190
-
191
- if len(missing_radiative_transfer_variables) > 0:
192
- need_radiative_transfer = True
193
179
 
194
180
  # check if any of the FLiES outputs are not given
195
- if need_radiative_transfer:
196
- logger.info(f"running FLiES for missing variables: {', '.join(missing_radiative_transfer_variables)}")
181
+ if None in (Rg, VISdiff, VISdir, NIRdiff, NIRdir, UV, albedo_visible, albedo_NIR):
197
182
  # load cloud optical thickness if not provided
198
183
  if COT is None:
199
184
  COT = GEOS5FP_connection.COT(time_UTC=time_UTC, geometry=geometry, resampling=resampling)
@@ -529,7 +514,6 @@ def BESS_JPL(
529
514
  "Rn": Rn,
530
515
  "Rn_soil": Rn_soil,
531
516
  "Rn_canopy": Rn_canopy,
532
- "G": G,
533
517
  "LE": LE,
534
518
  "LE_soil": LE_soil,
535
519
  "LE_canopy": LE_canopy
@@ -0,0 +1,55 @@
1
+ import logging
2
+
3
+ import numpy as np
4
+ import rasters as rt
5
+ from dateutil import parser
6
+ from pandas import DataFrame
7
+
8
+ from .model import BESS_JPL
9
+
10
+ logger = logging.getLogger(__name__)
11
+
12
+ def process_BESS_table(input_df: DataFrame) -> DataFrame:
13
+ ST_C = np.array(input_df.ST_C).astype(np.float64)
14
+ NDVI = np.array(input_df.NDVI).astype(np.float64)
15
+
16
+ NDVI = np.where(NDVI > 0.06, NDVI, np.nan).astype(np.float64)
17
+
18
+ albedo = np.array(input_df.albedo).astype(np.float64)
19
+
20
+ if "Ta_C" in input_df:
21
+ Ta_C = np.array(input_df.Ta_C).astype(np.float64)
22
+ elif "Ta" in input_df:
23
+ Ta_C = np.array(input_df.Ta).astype(np.float64)
24
+
25
+ RH = np.array(input_df.RH).astype(np.float64)
26
+ # Rn = np.array(input_df.Rn).astype(np.float64)
27
+ # Topt = np.array(input_df.Topt).astype(np.float64)
28
+ # fAPARmax = np.array(input_df.fAPARmax).astype(np.float64)
29
+
30
+ # fAPARmax = np.where(fAPARmax == 0, np.nan, fAPARmax).astype(np.float64)
31
+
32
+ # if "G" in input_df:
33
+ # G = np.array(input_df.G).astype(np.float64)
34
+ # else:
35
+ # G = calculate_SEBAL_soil_heat_flux(
36
+ # Rn=Rn,
37
+ # ST_C=ST_C,
38
+ # NDVI=NDVI,
39
+ # albedo=albedo
40
+ # ).astype(np.float64)
41
+
42
+ results = BESS_JPL(
43
+ ST_C=ST_C,
44
+ albedo=albedo,
45
+ NDVI=NDVI,
46
+ Ta_C=Ta_C,
47
+ RH=RH
48
+ )
49
+
50
+ output_df = input_df.copy()
51
+
52
+ for key, value in results.items():
53
+ output_df[key] = value
54
+
55
+ return output_df
@@ -0,0 +1 @@
1
+ 1.10.0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: BESS-JPL
3
- Version: 1.9.2
3
+ Version: 1.10.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
@@ -1,4 +1,5 @@
1
1
  .gitignore
2
+ BESS Sensitivity.ipynb
2
3
  C4 Fraction.ipynb
3
4
  Dockerfile
4
5
  LICENSE
@@ -52,10 +53,12 @@ BESS_JPL/load_kn.py
52
53
  BESS_JPL/load_peakVCmax_C3.py
53
54
  BESS_JPL/load_peakVCmax_C4.py
54
55
  BESS_JPL/meteorology.py
56
+ BESS_JPL/model.py
55
57
  BESS_JPL/peakVCmax_C3.jpeg
56
58
  BESS_JPL/peakVCmax_C3.tif
57
59
  BESS_JPL/peakVCmax_C4.jpeg
58
60
  BESS_JPL/peakVCmax_C4.tif
61
+ BESS_JPL/process_BESS_table.py
59
62
  BESS_JPL/soil_energy_balance.py
60
63
  BESS_JPL/version.txt
61
64
  BESS_JPL.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: BESS-JPL
3
- Version: 1.9.2
3
+ Version: 1.10.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