1515from . import datastore , schismstudy
1616from vtools .functions .filter import cosine_lanczos
1717from . import calibplot
18+ from .dvue .utils import interpret_file_relative_to
1819
1920# from .calibplot import tsplot, scatterplot, calculate_metrics, regression_line_plots
2021
3435}
3536
3637
37- def interpret_file_relative_to (base_dir , fpath ):
38- full_path = base_dir / fpath
39- if full_path .exists ():
40- return str (full_path )
41- else :
42- return str (fpath )
43-
44-
4538def replace_with_paths_relative_to (base_dir , params ):
4639 params = params .copy ()
47- params ["output_dir" ] = [
48- interpret_file_relative_to (base_dir , file ) for file in params ["outputs_dir" ]
49- ]
40+
41+ def _to_list (v ):
42+ return [v ] if isinstance (v , (str , pathlib .Path )) else v
43+
44+ # Normalize possibly singular entries to lists before path interpretation
45+ params ["outputs_dir" ] = _to_list (params .get ("outputs_dir" , []))
5046 params ["stations_csv" ] = interpret_file_relative_to (
5147 base_dir , params ["stations_csv" ]
5248 )
@@ -55,17 +51,17 @@ def replace_with_paths_relative_to(base_dir, params):
5551 ]
5652 if "station_input" in params :
5753 params ["station_input" ] = [
58- interpret_file_relative_to (base_dir , file )
59- for file in params ["station_input" ]
54+ interpret_file_relative_to (base_dir , f )
55+ for f in _to_list ( params ["station_input" ])
6056 ]
61- params ["obs_links_csv" ] = interpret_file_relative_to (
62- base_dir , params ["obs_links_csv" ]
63- )
6457 if "flow_station_input" in params :
6558 params ["flow_station_input" ] = [
66- interpret_file_relative_to (base_dir , file )
67- for file in params ["flow_station_input" ]
59+ interpret_file_relative_to (base_dir , f )
60+ for f in _to_list ( params ["flow_station_input" ])
6861 ]
62+ params ["obs_links_csv" ] = interpret_file_relative_to (
63+ base_dir , params ["obs_links_csv" ]
64+ )
6965 return params
7066
7167
@@ -95,7 +91,9 @@ def __init__(self, config_file, base_dir=None, **kwargs):
9591 config ["station_input" ] = ["station.in" ]
9692 if "flow_station_input" not in config :
9793 config ["flow_station_input" ] = ["fluxflag.prop" ]
98- config = replace_with_paths_relative_to (base_dir , config )
94+ config = replace_with_paths_relative_to (
95+ base_dir , config
96+ ) # no replacement needed as schismstudy does it
9997 self .config = config
10098 # load studies and datastore
10199 self .reftime = pd .Timestamp (self .config ["time_basis" ])
@@ -109,17 +107,49 @@ def __init__(self, config_file, base_dir=None, **kwargs):
109107 )
110108 self .labels = self .config ["labels" ]
111109 self .studies = {}
112- for schism_dir , flux_xsect_file , station_inf_file , label in zip (
113- self .config ["output_dir" ],
114- self .config ["flow_station_input" ],
115- self .config ["station_input" ],
116- self .labels [1 :],
117- ):
110+
111+ def _ensure_list (v ):
112+ return [v ] if isinstance (v , (str , pathlib .Path )) else v
113+
114+ # Normalize to lists (may be a single string/path or already a list)
115+ outputs_dir_list = _ensure_list (self .config .get ("outputs_dir" , []))
116+ station_input_list = _ensure_list (self .config .get ("station_input" , []))
117+ flow_station_input_list = _ensure_list (
118+ self .config .get ("flow_station_input" , [])
119+ )
120+
121+ if len (outputs_dir_list ) == 0 :
122+ raise ValueError ("outputs_dir is empty in config." )
123+ if len (station_input_list ) == 0 :
124+ raise ValueError ("station_input is empty in config." )
125+ if len (flow_station_input_list ) == 0 :
126+ raise ValueError ("flow_station_input is empty in config." )
127+
128+ for idx , label in enumerate (self .labels [1 :]): # skip first label (Obs)
129+ # Select matching (or last) entries for each list
130+ if idx < len (outputs_dir_list ):
131+ chosen_output_dir = outputs_dir_list [idx ]
132+ else :
133+ chosen_output_dir = outputs_dir_list [- 1 ]
134+
135+ if idx < len (station_input_list ):
136+ chosen_station_input = station_input_list [idx ]
137+ else :
138+ chosen_station_input = station_input_list [- 1 ]
139+
140+ if idx < len (flow_station_input_list ):
141+ chosen_flow_station_input = flow_station_input_list [idx ]
142+ else :
143+ chosen_flow_station_input = flow_station_input_list [- 1 ]
144+
118145 study = schismstudy .SchismStudy (
119- base_dir = schism_dir ,
120- flux_xsect_file = flux_xsect_file ,
146+ study_name = label ,
147+ base_dir = str (base_dir ),
148+ output_dir = str (chosen_output_dir ),
149+ param_nml_file = "param.nml" ,
150+ flux_xsect_file = str (chosen_flow_station_input ),
121151 flux_out = "flux.out" ,
122- station_in_file = station_inf_file ,
152+ station_in_file = str ( chosen_station_input ) ,
123153 reftime = self .reftime ,
124154 )
125155 self .studies [label ] = study
@@ -207,9 +237,19 @@ def get_data_for_id_var(self, id, variable):
207237 df .columns = [study_name ]
208238 dfs .append (df )
209239 dparam = self .get_datastore_param_name (variable )
240+ idsplit = id .split ("_" )
241+ try :
242+ if len (idsplit ) > 1 and variable not in ["flow" , "elev" ]:
243+ id_col = "full_id"
244+ else :
245+ id_col = "station_id"
246+ except Exception :
247+ id_col = "station_id"
248+ if variable in ["flow" , "elev" ] and len (idsplit ) > 1 :
249+ id = idsplit [0 ]
210250 try :
211251 rd = self .dcat [
212- self .dcat .eval (f'(full_id =="{ id } ") & (param=="{ dparam } ")' )
252+ self .dcat .eval (f'({ id_col } =="{ id } ") & (param=="{ dparam } ")' )
213253 ].iloc [0 ]
214254 except IndexError :
215255 print ("No data found for" , id , variable )
0 commit comments