Skip to content

Commit 69297ec

Browse files
Merge pull request #18 from gregory-halverson-jpl/main
making `FLiESANN` main entry-point, using `NASADEM` package for elevation
2 parents 78a1894 + 3113d1a commit 69297ec

10 files changed

+219
-8673
lines changed
Binary file not shown.
Binary file not shown.

FLiESANN/FLiESANN.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@
44
from .determine_ctype import determine_ctype
55
from .prepare_FLiES_ANN_inputs import prepare_FLiES_ANN_inputs
66
from .run_FLiES_ANN_inference import run_FLiES_ANN_inference
7-
from .process_FLiES_ANN import process_FLiES_ANN
7+
from .process_FLiES_ANN import FLiESANN
88
from .generate_FLiES_inputs_table import generate_FLiES_inputs_table
99
from .process_FLiES_table import process_FLiES_table

FLiESANN/process_FLiES_ANN.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,14 @@
88
from solar_apparent_time import solar_day_of_year_for_area, solar_hour_of_day_for_area
99
from sun_angles import calculate_SZA_from_DOY_and_hour
1010
from koppengeiger import load_koppen_geiger
11+
from NASADEM import NASADEM, NASADEMConnection
1112

1213
from .constants import *
1314
from .determine_atype import determine_atype
1415
from .determine_ctype import determine_ctype
1516
from .run_FLiES_ANN_inference import run_FLiES_ANN_inference
1617

17-
def process_FLiES_ANN(
18+
def FLiESANN(
1819
albedo: Union[Raster, np.ndarray],
1920
COT: Union[Raster, np.ndarray] = None,
2021
AOT: Union[Raster, np.ndarray] = None,
@@ -28,6 +29,7 @@ def process_FLiES_ANN(
2829
day_of_year: Union[Raster, np.ndarray] = None,
2930
hour_of_day: Union[Raster, np.ndarray] = None,
3031
GEOS5FP_connection: GEOS5FP = None,
32+
NASADEM_connection: NASADEMConnection = NASADEM,
3133
resampling: str = "cubic",
3234
ANN_model=None,
3335
model_filename=DEFAULT_MODEL_FILENAME,
@@ -141,6 +143,9 @@ def process_FLiES_ANN(
141143
resampling=resampling
142144
)
143145

146+
if elevation_km is None and geometry is not None:
147+
elevation_km = NASADEM.elevation_km(geometry=geometry)
148+
144149
# Preprocess COT and determine aerosol/cloud types
145150
COT = np.clip(COT, 0, None) # Ensure COT is non-negative
146151
COT = rt.where(COT < 0.001, 0, COT) # Set very small COT values to 0
@@ -224,4 +229,6 @@ def process_FLiES_ANN(
224229
for key in results.keys():
225230
results[key] = rt.Raster(results[key], geometry=geometry)
226231

227-
return results
232+
return results
233+
234+
FLiESANN = FLiESANN

FLiESANN/process_FLiES_table.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import pandas as pd
22

3-
from .process_FLiES_ANN import process_FLiES_ANN
3+
from .process_FLiES_ANN import FLiESANN
44

55
def process_FLiES_table(FLiES_inputs_df: pd.DataFrame) -> pd.DataFrame:
6-
FLiES_results = process_FLiES_ANN(
6+
FLiES_results = FLiESANN(
77
day_of_year=FLiES_inputs_df.doy,
88
albedo=FLiES_inputs_df.albedo,
99
COT=FLiES_inputs_df.COT,

FLiESANN/version.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.3.0
1+
1.4.0
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"# Running FLiES for an ECOSTRESS Scene\n",
8+
"\n",
9+
"This is an example of running the artificial neural network emulator of the Forest Light Environmental Simulator (FLiES) corresponding to an ECOsystem Spaceborne Thermal Radiometer Experiment on Space Station (ECOSTRESS) scene."
10+
]
11+
},
12+
{
13+
"cell_type": "code",
14+
"execution_count": null,
15+
"metadata": {},
16+
"outputs": [],
17+
"source": [
18+
"from os.path import join\n",
19+
"from datetime import datetime, date, time\n",
20+
"from dateutil import parser\n",
21+
"import rasters as rt\n",
22+
"from geos5fp import GEOS5FP\n",
23+
"from koppengeiger import load_koppen_geiger\n",
24+
"from solar_apparent_time import UTC_to_solar\n",
25+
"import sun_angles\n",
26+
"from FLiESANN import process_FLiES_ANN\n",
27+
"from matplotlib.colors import LinearSegmentedColormap\n",
28+
"import logging\n",
29+
"logging.disable(logging.CRITICAL)"
30+
]
31+
},
32+
{
33+
"cell_type": "markdown",
34+
"metadata": {},
35+
"source": [
36+
"Here's an example ECOSTRESS albedo scene."
37+
]
38+
},
39+
{
40+
"cell_type": "code",
41+
"execution_count": null,
42+
"metadata": {},
43+
"outputs": [],
44+
"source": [
45+
"albedo_filename = \"ECOv002_L2T_STARS_11SPS_20240728_0712_01_albedo.tif\"\n",
46+
"albedo_cmap = LinearSegmentedColormap.from_list(name=\"albedo\", colors=[\"black\", \"white\"])\n",
47+
"albedo = rt.Raster.open(albedo_filename, cmap=albedo_cmap)\n",
48+
"albedo"
49+
]
50+
},
51+
{
52+
"cell_type": "markdown",
53+
"metadata": {},
54+
"source": [
55+
"Let's get the acquisition time of the scene."
56+
]
57+
},
58+
{
59+
"cell_type": "code",
60+
"execution_count": null,
61+
"metadata": {},
62+
"outputs": [],
63+
"source": [
64+
"time_UTC = parser.parse(albedo_filename.split(\"_\")[6])\n",
65+
"longitude = albedo.geometry.centroid_latlon.x\n",
66+
"latitude = albedo.geometry.centroid_latlon.y\n",
67+
"time_solar = UTC_to_solar(time_UTC, longitude)\n",
68+
"doy_solar = time_solar.timetuple().tm_yday\n",
69+
"hour_of_day_solar = time_solar.hour + time_solar.minute / 60 + time_solar.second / 3600\n",
70+
"print(f\"{time_UTC:%Y-%m-%d %H:%M:%S} UTC\")\n",
71+
"print(f\"{time_solar:%Y-%m-%d %H:%M:%S} solar apparent time at longitude {longitude}\")\n",
72+
"print(f\"day of year {doy_solar} at longitude {longitude}\")\n",
73+
"print(f\"hour of day {hour_of_day_solar} at longitude {longitude}\")\n"
74+
]
75+
},
76+
{
77+
"cell_type": "code",
78+
"execution_count": null,
79+
"metadata": {},
80+
"outputs": [],
81+
"source": [
82+
"geometry = albedo.geometry\n",
83+
"geometry"
84+
]
85+
},
86+
{
87+
"cell_type": "code",
88+
"execution_count": null,
89+
"metadata": {},
90+
"outputs": [],
91+
"source": [
92+
"FLiES_results = process_FLiES_ANN(\n",
93+
" geometry=geometry,\n",
94+
" time_UTC=time_UTC,\n",
95+
" albedo=albedo\n",
96+
")"
97+
]
98+
},
99+
{
100+
"cell_type": "code",
101+
"execution_count": null,
102+
"metadata": {},
103+
"outputs": [],
104+
"source": [
105+
"Rg = FLiES_results[\"Rg\"]\n",
106+
"Rg.cmap = \"bwr\"\n",
107+
"Rg"
108+
]
109+
},
110+
{
111+
"cell_type": "code",
112+
"execution_count": null,
113+
"metadata": {},
114+
"outputs": [],
115+
"source": []
116+
}
117+
],
118+
"metadata": {
119+
"kernelspec": {
120+
"display_name": "FLiESANN",
121+
"language": "python",
122+
"name": "python3"
123+
},
124+
"language_info": {
125+
"codemirror_mode": {
126+
"name": "ipython",
127+
"version": 3
128+
},
129+
"file_extension": ".py",
130+
"mimetype": "text/x-python",
131+
"name": "python",
132+
"nbconvert_exporter": "python",
133+
"pygments_lexer": "ipython3",
134+
"version": "3.10.16"
135+
}
136+
},
137+
"nbformat": 4,
138+
"nbformat_minor": 2
139+
}

Processing FLiES with a raster.ipynb

Lines changed: 0 additions & 8665 deletions
This file was deleted.
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# %% [markdown]
2+
# # Running FLiES for an ECOSTRESS Scene
3+
#
4+
# This is an example of running the artificial neural network emulator of the Forest Light Environmental Simulator (FLiES) corresponding to an ECOsystem Spaceborne Thermal Radiometer Experiment on Space Station (ECOSTRESS) scene.
5+
6+
# %%
7+
from os.path import join
8+
from datetime import datetime, date, time
9+
from dateutil import parser
10+
import rasters as rt
11+
from geos5fp import GEOS5FP
12+
from koppengeiger import load_koppen_geiger
13+
from solar_apparent_time import UTC_to_solar
14+
import sun_angles
15+
from FLiESANN import FLiESANN
16+
from matplotlib.colors import LinearSegmentedColormap
17+
import logging
18+
logging.disable(logging.CRITICAL)
19+
20+
# %% [markdown]
21+
# Here's an example ECOSTRESS albedo scene.
22+
23+
# %%
24+
albedo_filename = "ECOv002_L2T_STARS_11SPS_20240728_0712_01_albedo.tif"
25+
albedo_cmap = LinearSegmentedColormap.from_list(name="albedo", colors=["black", "white"])
26+
albedo = rt.Raster.open(albedo_filename, cmap=albedo_cmap)
27+
albedo
28+
29+
# %% [markdown]
30+
# Let's get the acquisition time of the scene.
31+
32+
# %%
33+
time_UTC = parser.parse(albedo_filename.split("_")[6])
34+
longitude = albedo.geometry.centroid_latlon.x
35+
latitude = albedo.geometry.centroid_latlon.y
36+
time_solar = UTC_to_solar(time_UTC, longitude)
37+
doy_solar = time_solar.timetuple().tm_yday
38+
hour_of_day_solar = time_solar.hour + time_solar.minute / 60 + time_solar.second / 3600
39+
print(f"{time_UTC:%Y-%m-%d %H:%M:%S} UTC")
40+
print(f"{time_solar:%Y-%m-%d %H:%M:%S} solar apparent time at longitude {longitude}")
41+
print(f"day of year {doy_solar} at longitude {longitude}")
42+
print(f"hour of day {hour_of_day_solar} at longitude {longitude}")
43+
44+
45+
# %%
46+
geometry = albedo.geometry
47+
geometry
48+
49+
# %%
50+
FLiES_results = FLiESANN(
51+
geometry=geometry,
52+
time_UTC=time_UTC,
53+
albedo=albedo
54+
)
55+
56+
# %%
57+
Rg = FLiES_results["Rg"]
58+
Rg.cmap = "bwr"
59+
Rg
60+
61+
# %%
62+
63+
64+

pyproject.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ requires = ["setuptools>=60", "setuptools-scm>=8.0", "wheel"]
33

44
[project]
55
name = "FLiESANN"
6-
version = "1.3.0"
6+
version = "1.4.0"
77
description = "Forest Light Environmental Simulator (FLiES) Radiative Transfer Model Artificial Neural Network (ANN) Implementation in Python"
88
readme = "README.md"
99
authors = [
@@ -17,6 +17,8 @@ dependencies = [
1717
"geos5fp",
1818
"keras==2.15",
1919
"koppengeiger",
20+
"MCD12C1-2019-v006",
21+
"NASADEM>=1.1.1",
2022
"netCDF4",
2123
"numpy<2",
2224
"pandas",
@@ -32,7 +34,6 @@ requires-python = ">=3.10"
3234
[project.optional-dependencies]
3335
dev = [
3436
"build",
35-
"MCD12C1-2019-v006",
3637
"pytest>=6.0",
3738
"pytest-cov",
3839
"jupyter",

0 commit comments

Comments
 (0)