Skip to content

Commit befffe1

Browse files
committedApr 20, 2025
SCH-832 mulitple schism studies
1 parent 915c00f commit befffe1

File tree

2 files changed

+75
-16
lines changed

2 files changed

+75
-16
lines changed
 

‎pydelmod/schismstudy.py

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import schimpy
55
import pandas as pd
66
import schimpy.station as station
7+
from schimpy import param as schimpyparam
78
import schimpy.schism_yaml as schism_yaml
89
import schimpy.batch_metrics as schism_metrics
910
import cartopy.crs as ccrs
@@ -12,6 +13,7 @@
1213
import geopandas as gpd
1314
import param
1415
import diskcache
16+
import datetime
1517

1618
# use logging
1719
import logging
@@ -105,27 +107,40 @@ class SchismStudy(param.Parameterized):
105107
def __init__(
106108
self,
107109
base_dir=".",
110+
output_dir="outputs",
111+
param_nml_file="param.nml",
108112
flux_xsect_file="flow_station_xsects.yaml",
109113
station_in_file="station.in",
110114
flux_out="flux.out",
111-
reftime="2020-01-01",
115+
reftime=None,
112116
**kwargs,
113117
):
114118
self.base_dir = pathlib.Path(base_dir)
119+
self.param_nml_file = self.interpret_file_relative_to(
120+
self.base_dir, pathlib.Path(param_nml_file)
121+
)
122+
self.output_dir = self.interpret_file_relative_to(
123+
self.base_dir, pathlib.Path(output_dir)
124+
)
115125
try:
116126
self.cache = diskcache.Cache(self.base_dir / ".cache-schismstudy")
117127
except:
118128
logger.warning("Could not create cache. Using temporary cache.")
119129
self.cache = diskcache.Cache()
120-
self.reftime = pd.Timestamp(reftime)
130+
if not reftime:
131+
nml = schimpyparam.read_params(self.param_nml_file)
132+
self.reftime = nml.run_start
133+
self.endtime = nml.run_start + datetime.timedelta(days=nml["rnday"])
134+
else:
135+
self.reftime = pd.Timestamp(reftime)
121136
self.flux_xsect_file = self.interpret_file_relative_to(
122137
self.base_dir, pathlib.Path(flux_xsect_file)
123138
)
124139
self.station_in_file = self.interpret_file_relative_to(
125140
self.base_dir, pathlib.Path(station_in_file)
126141
)
127142
self.flux_out = self.interpret_file_relative_to(
128-
self.base_dir, pathlib.Path(flux_out)
143+
self.output_dir, pathlib.Path(flux_out)
129144
)
130145
super().__init__(**kwargs)
131146
stations = read_station_in(self.station_in_file)
@@ -160,10 +175,10 @@ def __init__(
160175

161176
def interpret_file_relative_to(self, base_dir, fpath):
162177
full_path = base_dir / fpath
163-
if full_path.exists():
164-
return full_path
165-
else:
166-
return fpath
178+
if not full_path.exists():
179+
logger.warning(f"File {full_path} does not exist. Using {fpath} instead.")
180+
full_path = fpath
181+
return full_path
167182

168183
def get_unit_for_variable(self, var):
169184
if var in ["elev"]:
@@ -191,7 +206,9 @@ def get_catalog(self):
191206
s = self.stations_gdf.copy()
192207
s["variable"] = var
193208
s["unit"] = self.get_unit_for_variable(var)
194-
s["filename"] = str(self.base_dir / station.staout_name(var))
209+
s["filename"] = self.interpret_file_relative_to(
210+
self.output_dir, station.staout_name(var)
211+
)
195212
s.drop(columns=["id", "subloc", "x", "y", "z"], inplace=True)
196213
s.rename(columns={"station_id": "id"}, inplace=True)
197214
var_stations.append(s)
@@ -252,7 +269,9 @@ def get_flux(self):
252269
@lru_cache(maxsize=32)
253270
def get_staout(self, variable, fpath=None):
254271
if fpath is None:
255-
fpath = str(self.base_dir / station.staout_name(variable))
272+
fpath = self.interpret_file_relative_to(
273+
self.output_dir, station.staout_name(variable)
274+
)
256275
if fpath in self.cache:
257276
logger.info(f"Using cached staout from disk: {fpath}")
258277
return self.cache[fpath]

‎pydelmod/schismui.py

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ def __init__(self, *studies, datastore=None, time_range=None, **kwargs):
2121
This is merged with the data catalog to get the station locations.
2222
"""
2323
self.studies = studies
24-
self.study_dir_map = {str(s.base_dir): s for s in self.studies}
24+
self.study_dir_map = {str(s.output_dir): s for s in self.studies}
2525
self.datastore = datastore
2626
self.catalog = self._merge_catalogs(self.studies, self.datastore)
2727
self.catalog["filename"] = self.catalog["filename"].astype(str)
@@ -195,18 +195,47 @@ def get_map_marker_columns(self):
195195
"--station_in_file", default="station.in", help="Path to the station.in file"
196196
)
197197
@click.option("--flux_out", default="flux.out", help="Path to the flux.out file")
198-
@click.option("--reftime", default="2020-01-01", help="Reference time")
198+
@click.option("--reftime", default=None, help="Reference time")
199199
@click.option("--yaml_file", default=None, help="Path to the yaml file")
200200
def show_schism_output_ui(
201201
schism_dir=".",
202202
flux_xsect_file="flow_station_xsects.yaml",
203203
station_in_file="station.in",
204204
flux_out="flux.out",
205-
reftime="2020-01-01",
205+
reftime=None,
206206
repo_dir="screened",
207207
inventory_file="inventory_datasets.csv",
208208
yaml_file=None,
209209
):
210+
"""
211+
Shows Data UI for SCHISM output files.
212+
213+
This function creates a Data UI for SCHISM output files, allowing users to visualize and analyze the data.
214+
It can handle multiple studies and datasets, and provides options for customizing the display.
215+
The function can be run from the command line or imported as a module.
216+
217+
If a YAML file is provided, it will be used to create multiple studies.
218+
Otherwise, a single study will be created using the provided parameters.
219+
220+
Example YAML file::
221+
222+
.. code-block:: yaml
223+
\b
224+
schism_studies:
225+
- label: Study1
226+
base_dir: "study1_directory"
227+
flux_xsect_file: "study1_flow_station_xsects.yaml"
228+
station_in_file: "study1_station.in"
229+
output_dir: "outputs"
230+
param_nml_file: "param.nml"
231+
flux_out: "study1_flux.out"
232+
reftime: "2020-01-01"
233+
- label: Study2
234+
base_dir: "study2_directory"
235+
datastore:
236+
repo_dir: /repo/continuous/screened
237+
inventory_file: "inventory_datasets.csv"
238+
"""
210239
if yaml_file:
211240
# Load the YAML file and create multiple studies
212241
with open(yaml_file, "r") as file:
@@ -217,15 +246,21 @@ def show_schism_output_ui(
217246
studies.append(
218247
schismstudy.SchismStudy(
219248
base_dir=study_config["base_dir"],
249+
output_dir=study_config.get("output_dir", "outputs"),
250+
param_nml_file=study_config.get("param_nml_file", "param.nml"),
220251
flux_xsect_file=study_config.get(
221252
"flux_xsect_file", "flow_station_xsects.yaml"
222253
),
223254
station_in_file=study_config.get("station_in_file", "station.in"),
224255
flux_out=study_config.get("flux_out", "flux.out"),
225-
reftime=study_config.get("reftime", "2020-01-01"),
256+
reftime=reftime,
226257
**study_config.get("additional_parameters", {}),
227258
)
228259
)
260+
261+
datastore_config = yaml_data.get("datastore", {})
262+
repo_dir = datastore_config.get("repo_dir", repo_dir)
263+
inventory_file = datastore_config.get("inventory_file", inventory_file)
229264
else:
230265
# Create a single study if no YAML file is provided
231266
studies = [
@@ -238,12 +273,17 @@ def show_schism_output_ui(
238273
)
239274
]
240275

276+
# study.reftime to study.endtime is the range of a single study
277+
# Initialize the union range
278+
union_start = min(study.reftime for study in studies)
279+
union_end = max(study.endtime for study in studies)
280+
281+
# Create the union range as a single variable
282+
time_range = (union_start, union_end)
283+
241284
# Create the datastore
242285
ds = datastore.StationDatastore(repo_dir=repo_dir, inventory_file=inventory_file)
243286

244-
# Define the time range
245-
time_range = (pd.Timestamp(reftime), pd.Timestamp(reftime) + pd.Timedelta(days=250))
246-
247287
# Create the UI
248288
ui = DataUI(
249289
SchismOutputUIDataManager(

0 commit comments

Comments
 (0)
Failed to load comments.