Skip to content

Commit 78a1894

Browse files
Merge pull request #17 from gregory-halverson-jpl/main
using GEOS-5 FP numeric weather prediction for default parameters
2 parents 94f964a + 309fb2d commit 78a1894

File tree

5 files changed

+65
-8
lines changed

5 files changed

+65
-8
lines changed

FLiESANN/constants.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
DEFAULT_WORKING_DIRECTORY = "."
44
DEFAULT_FLIES_INTERMEDIATE = "FLiES_intermediate"
55

6+
GEOS5FP_DIRECTORY = "~/data/GEOS5FP_download"
7+
68
DEFAULT_MODEL_FILENAME = join(abspath(dirname(__file__)), "FLiESANN.h5")
79
SPLIT_ATYPES_CTYPES = True
810

FLiESANN/prepare_FLiES_ANN_inputs.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def prepare_FLiES_ANN_inputs(
2424
elevation_km_flat = np.array(elevation_km).flatten()
2525
SZA_flat = np.array(SZA).flatten()
2626

27-
inputs = pd.DataFrame({
27+
inputs_dict = {
2828
"ctype": ctype_flat,
2929
"atype": atype_flat,
3030
"COT": COT_flat,
@@ -34,7 +34,22 @@ def prepare_FLiES_ANN_inputs(
3434
"albedo": albedo_flat,
3535
"elevation_km": elevation_km_flat,
3636
"SZA": SZA_flat
37-
})
37+
}
38+
39+
# check all values in inputs_dict are numpy arrays and throw an exception if any are not
40+
41+
for key, value in inputs_dict.items():
42+
if not isinstance(value, np.ndarray):
43+
raise TypeError(f"input {key} is not a numpy array: {type(value)}")
44+
45+
# check the sizes of the input arrays and throw an exception if they mis-match
46+
47+
input_sizes = {key: np.array(value).size for key, value in inputs_dict.items()}
48+
49+
if len(set(input_sizes.values())) != 1:
50+
raise ValueError(f"FLiES input size mis-match: {input_sizes}")
51+
52+
inputs = pd.DataFrame(inputs_dict)
3853

3954
if split_atypes_ctypes:
4055
inputs["ctype0"] = np.float32(inputs.ctype == 0)

FLiESANN/process_FLiES_ANN.py

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
from typing import Union
22
from time import process_time
3-
3+
from datetime import datetime
44
import numpy as np
55
import rasters as rt
66
from rasters import Raster, RasterGeometry
77
from geos5fp import GEOS5FP
8+
from solar_apparent_time import solar_day_of_year_for_area, solar_hour_of_day_for_area
89
from sun_angles import calculate_SZA_from_DOY_and_hour
910
from koppengeiger import load_koppen_geiger
1011

@@ -14,8 +15,6 @@
1415
from .run_FLiES_ANN_inference import run_FLiES_ANN_inference
1516

1617
def process_FLiES_ANN(
17-
day_of_year: Union[Raster, np.ndarray],
18-
hour_of_day: Union[Raster, np.ndarray],
1918
albedo: Union[Raster, np.ndarray],
2019
COT: Union[Raster, np.ndarray] = None,
2120
AOT: Union[Raster, np.ndarray] = None,
@@ -25,8 +24,11 @@ def process_FLiES_ANN(
2524
SZA: Union[Raster, np.ndarray] = None,
2625
KG_climate: Union[Raster, np.ndarray] = None,
2726
geometry: RasterGeometry = None,
27+
time_UTC: datetime = None,
28+
day_of_year: Union[Raster, np.ndarray] = None,
29+
hour_of_day: Union[Raster, np.ndarray] = None,
2830
GEOS5FP_connection: GEOS5FP = None,
29-
GEOS5FP_directory: str = None,
31+
resampling: str = "cubic",
3032
ANN_model=None,
3133
model_filename=DEFAULT_MODEL_FILENAME,
3234
split_atypes_ctypes=SPLIT_ATYPES_CTYPES) -> dict:
@@ -82,6 +84,16 @@ def process_FLiES_ANN(
8284
if geometry is None and isinstance(albedo, Raster):
8385
geometry = albedo.geometry
8486

87+
if (day_of_year is None or hour_of_day is None) and time_UTC is not None and geometry is not None:
88+
day_of_year = solar_day_of_year_for_area(time_UTC=time_UTC, geometry=geometry)
89+
hour_of_day = solar_hour_of_day_for_area(time_UTC=time_UTC, geometry=geometry)
90+
91+
if time_UTC is None and day_of_year is None and hour_of_day is None:
92+
raise ValueError("no time given between time_UTC, day_of_year, and hour_of_day")
93+
94+
if GEOS5FP_connection is None:
95+
GEOS5FP_connection = GEOS5FP(working_directory=DEFAULT_WORKING_DIRECTORY, download_directory=GEOS5FP_DIRECTORY)
96+
8597
## FIXME need to fetch default values for parameters: COT, AOT, vapor_gccm, ozone_cm, elevation_km, SZA, KG_climate
8698

8799
if SZA is None and geometry is not None:
@@ -101,6 +113,34 @@ def process_FLiES_ANN(
101113
if KG_climate is None:
102114
raise ValueError("Koppen Geieger climate classification or geometry must be given")
103115

116+
if COT is None and geometry is not None and time_UTC is not None:
117+
COT = GEOS5FP_connection.COT(
118+
time_UTC=time_UTC,
119+
geometry=geometry,
120+
resampling=resampling
121+
)
122+
123+
if AOT is None and geometry is not None and time_UTC is not None:
124+
AOT = GEOS5FP_connection.AOT(
125+
time_UTC=time_UTC,
126+
geometry=geometry,
127+
resampling=resampling
128+
)
129+
130+
if vapor_gccm is None and geometry is not None and time_UTC is not None:
131+
vapor_gccm = GEOS5FP_connection.vapor_gccm(
132+
time_UTC=time_UTC,
133+
geometry=geometry,
134+
resampling=resampling
135+
)
136+
137+
if ozone_cm is None and geometry is not None and time_UTC is not None:
138+
ozone_cm = GEOS5FP_connection.ozone_cm(
139+
time_UTC=time_UTC,
140+
geometry=geometry,
141+
resampling=resampling
142+
)
143+
104144
# Preprocess COT and determine aerosol/cloud types
105145
COT = np.clip(COT, 0, None) # Ensure COT is non-negative
106146
COT = rt.where(COT < 0.001, 0, COT) # Set very small COT values to 0

FLiESANN/version.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.2.1
1+
1.3.0

pyproject.toml

Lines changed: 1 addition & 1 deletion
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.2.1"
6+
version = "1.3.0"
77
description = "Forest Light Environmental Simulator (FLiES) Radiative Transfer Model Artificial Neural Network (ANN) Implementation in Python"
88
readme = "README.md"
99
authors = [

0 commit comments

Comments
 (0)