hspf 2.0.2__tar.gz → 2.1.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.
- {hspf-2.0.2 → hspf-2.1.0}/PKG-INFO +1 -1
- {hspf-2.0.2 → hspf-2.1.0}/pyproject.toml +1 -1
- hspf-2.1.0/src/hspf/bin/WinHSPFLt/WinHspfLt.exe +0 -0
- {hspf-2.0.2 → hspf-2.1.0}/src/hspf/hbn.py +10 -35
- {hspf-2.0.2 → hspf-2.1.0}/src/hspf/hspfModel.py +32 -12
- {hspf-2.0.2 → hspf-2.1.0}/src/hspf/parser/graph.py +153 -332
- {hspf-2.0.2 → hspf-2.1.0}/src/hspf/parser/parsers.py +29 -3
- {hspf-2.0.2 → hspf-2.1.0}/src/hspf/reports.py +1 -0
- {hspf-2.0.2 → hspf-2.1.0}/src/hspf/uci.py +93 -9
- hspf-2.1.0/tests/__init__.py +0 -0
- hspf-2.1.0/tests/data/Clearwater.tpl +19727 -0
- hspf-2.1.0/tests/data/Clearwater.uci +16857 -0
- hspf-2.1.0/tests/test_graph.py +86 -0
- hspf-2.1.0/tests/test_uci.py +11 -0
- {hspf-2.0.2 → hspf-2.1.0}/.gitattributes +0 -0
- {hspf-2.0.2 → hspf-2.1.0}/.gitignore +0 -0
- {hspf-2.0.2 → hspf-2.1.0}/MANIFEST.in +0 -0
- {hspf-2.0.2 → hspf-2.1.0}/src/hspf/__init__.py +0 -0
- {hspf-2.0.2 → hspf-2.1.0}/src/hspf/data/ParseTable.csv +0 -0
- {hspf-2.0.2 → hspf-2.1.0}/src/hspf/data/Timeseries Catalog/IMPLND/IQUAL.txt +0 -0
- {hspf-2.0.2 → hspf-2.1.0}/src/hspf/data/Timeseries Catalog/IMPLND/IWATER.txt +0 -0
- {hspf-2.0.2 → hspf-2.1.0}/src/hspf/data/Timeseries Catalog/IMPLND/IWTGAS.txt +0 -0
- {hspf-2.0.2 → hspf-2.1.0}/src/hspf/data/Timeseries Catalog/IMPLND/SOLIDS.txt +0 -0
- {hspf-2.0.2 → hspf-2.1.0}/src/hspf/data/Timeseries Catalog/PERLND/MSTLAY.txt +0 -0
- {hspf-2.0.2 → hspf-2.1.0}/src/hspf/data/Timeseries Catalog/PERLND/PQUAL.txt +0 -0
- {hspf-2.0.2 → hspf-2.1.0}/src/hspf/data/Timeseries Catalog/PERLND/PSTEMP.txt +0 -0
- {hspf-2.0.2 → hspf-2.1.0}/src/hspf/data/Timeseries Catalog/PERLND/PWATER.txt +0 -0
- {hspf-2.0.2 → hspf-2.1.0}/src/hspf/data/Timeseries Catalog/PERLND/PWATGAS.txt +0 -0
- {hspf-2.0.2 → hspf-2.1.0}/src/hspf/data/Timeseries Catalog/PERLND/SEDMNT.txt +0 -0
- {hspf-2.0.2 → hspf-2.1.0}/src/hspf/data/Timeseries Catalog/PERLND/SNOW.txt +0 -0
- {hspf-2.0.2 → hspf-2.1.0}/src/hspf/data/Timeseries Catalog/RCHRES/CONS.txt +0 -0
- {hspf-2.0.2 → hspf-2.1.0}/src/hspf/data/Timeseries Catalog/RCHRES/GQUAL.txt +0 -0
- {hspf-2.0.2 → hspf-2.1.0}/src/hspf/data/Timeseries Catalog/RCHRES/HTRCH.txt +0 -0
- {hspf-2.0.2 → hspf-2.1.0}/src/hspf/data/Timeseries Catalog/RCHRES/HYDR.txt +0 -0
- {hspf-2.0.2 → hspf-2.1.0}/src/hspf/data/Timeseries Catalog/RCHRES/NUTRX.txt +0 -0
- {hspf-2.0.2 → hspf-2.1.0}/src/hspf/data/Timeseries Catalog/RCHRES/OXRX.txt +0 -0
- {hspf-2.0.2 → hspf-2.1.0}/src/hspf/data/Timeseries Catalog/RCHRES/PLANK.txt +0 -0
- {hspf-2.0.2 → hspf-2.1.0}/src/hspf/data/Timeseries Catalog/RCHRES/SEDTRN.txt +0 -0
- {hspf-2.0.2 → hspf-2.1.0}/src/hspf/helpers.py +0 -0
- {hspf-2.0.2 → hspf-2.1.0}/src/hspf/parser/__init__.py +0 -0
- {hspf-2.0.2 → hspf-2.1.0}/src/hspf/wdm.py +0 -0
- {hspf-2.0.2 → hspf-2.1.0}/src/hspf/wdmReader.py +0 -0
|
Binary file
|
|
@@ -176,6 +176,12 @@ class hbnInterface:
|
|
|
176
176
|
def get_multiple_timeseries(self,t_opn,t_code,t_con,opnids = None,activity = None,axis = 1):
|
|
177
177
|
return pd.concat([hbn.get_multiple_timeseries(t_opn,t_code,t_con,opnids,activity) for hbn in self.hbns],axis = 1)
|
|
178
178
|
|
|
179
|
+
def get_perlnd_constituent(self,constituent,perlnd_ids = None,time_step = 5):
|
|
180
|
+
return get_simulated_perlnd_constituent(self,constituent,time_step)
|
|
181
|
+
|
|
182
|
+
def get_implnd_constituent(self,constituent,implnd_ids = None,time_step = 5):
|
|
183
|
+
return get_simulated_implnd_constituent(self,constituent,time_step)
|
|
184
|
+
|
|
179
185
|
def get_reach_constituent(self,constituent,reach_ids,time_step,unit = None):
|
|
180
186
|
if constituent == 'Q':
|
|
181
187
|
df = get_simulated_flow(self,time_step,reach_ids,unit = unit)
|
|
@@ -209,48 +215,17 @@ class hbnInterface:
|
|
|
209
215
|
|
|
210
216
|
return df
|
|
211
217
|
|
|
212
|
-
|
|
218
|
+
|
|
213
219
|
def get_rchres_data(self,constituent,reach_ids,units = 'mg/l',t_code = 'daily'):
|
|
214
220
|
'''
|
|
215
221
|
Convience function for accessing the hbn time series associated with our current
|
|
216
222
|
calibration method. Assumes you are summing across all dataframes.
|
|
217
|
-
|
|
218
|
-
Parameters
|
|
219
|
-
----------
|
|
220
|
-
hbn : TYPE
|
|
221
|
-
DESCRIPTION.
|
|
222
|
-
nutrient_id : TYPE
|
|
223
|
-
DESCRIPTION.
|
|
224
|
-
reach_ids : TYPE
|
|
225
|
-
DESCRIPTION.
|
|
226
|
-
flux : TYPE, optional
|
|
227
|
-
DESCRIPTION. The default is None.
|
|
228
|
-
|
|
229
|
-
Returns
|
|
230
|
-
-------
|
|
231
|
-
df : TYPE
|
|
232
|
-
DESCRIPTION.
|
|
233
|
-
|
|
234
|
-
'''
|
|
235
|
-
|
|
236
|
-
|
|
223
|
+
'''
|
|
237
224
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
df = pd.concat([self.get_multiple_timeseries(t_opn = 'RCHRES',
|
|
243
|
-
t_code =t_code,
|
|
244
|
-
t_con = t_con,
|
|
245
|
-
opnids = reach_ids)
|
|
246
|
-
for t_con in t_cons],axis = 1).sum(1).to_frame()
|
|
247
|
-
|
|
248
|
-
if (constituent == 'Q') & (units == 'cfs'):
|
|
249
|
-
df = df/CF2CFS[t_code]*43560 #Acrfeet/invl to cubic feet/s
|
|
250
|
-
|
|
225
|
+
df = pd.concat([self.get_reach_constituent(constituent,[reach_id],t_code,units) for reach_id in reach_ids], axis = 1)
|
|
226
|
+
df.columns = reach_ids
|
|
251
227
|
df.attrs['unit'] = units
|
|
252
228
|
df.attrs['constituent'] = constituent
|
|
253
|
-
df.attrs['reach_ids'] = reach_ids
|
|
254
229
|
return df
|
|
255
230
|
|
|
256
231
|
|
|
@@ -30,7 +30,7 @@ class hspfModel():
|
|
|
30
30
|
|
|
31
31
|
# Imposed structures of an hspf model:
|
|
32
32
|
# 1. all model files are located in the same directory as the uci file.
|
|
33
|
-
def __init__(self,uci_file:str):
|
|
33
|
+
def __init__(self,uci_file:str,run_model:bool = False):
|
|
34
34
|
#wdm_files:list = None,
|
|
35
35
|
#hbn_files:str = None):
|
|
36
36
|
# Inputs
|
|
@@ -39,7 +39,7 @@ class hspfModel():
|
|
|
39
39
|
self.wdm_paths = []
|
|
40
40
|
self.uci_file = Path(uci_file).resolve()
|
|
41
41
|
# Validate and load binary data
|
|
42
|
-
self.validate_uci()
|
|
42
|
+
self.validate_uci(run_model = run_model)
|
|
43
43
|
|
|
44
44
|
|
|
45
45
|
self.hbns = hbn.hbnInterface(self.hbn_paths)
|
|
@@ -51,8 +51,28 @@ class hspfModel():
|
|
|
51
51
|
# Compositions
|
|
52
52
|
self.reports = Reports(self.uci,self.hbns,self.wdms)
|
|
53
53
|
|
|
54
|
+
|
|
55
|
+
def validate_wdms(self):
|
|
56
|
+
# Ensure wdm files exist and the folders for the other file types exist relative
|
|
57
|
+
# to the uci path
|
|
58
|
+
|
|
59
|
+
for index, row in self.uci.table('FILES',drop_comments = False).iterrows():
|
|
60
|
+
file_path = self.uci_file.parent.joinpath(Path(row['FILENAME']))
|
|
61
|
+
if file_path.suffix.lower() == '.wdm':
|
|
62
|
+
assert file_path.exists(),'File Specified in the UCI does not exist:' + file_path.as_posix()
|
|
63
|
+
self.wdm_paths.append(file_path)
|
|
54
64
|
|
|
55
|
-
def
|
|
65
|
+
def validate_pltgens(self):
|
|
66
|
+
raise NotImplementedError()
|
|
67
|
+
|
|
68
|
+
def validate_folders(self):
|
|
69
|
+
for index, row in self.uci.table('FILES',drop_comments = False).iterrows():
|
|
70
|
+
file_path = self.uci_file.parent.joinpath(Path(row['FILENAME']))
|
|
71
|
+
assert file_path.parent.exists(),'File folder Specified in the UCI does not exist: ' + file_path.as_posix()
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def validate_uci(self,run_model:bool = False):
|
|
56
76
|
# Ensure wdm files exist and the folders for the other file types exist relative
|
|
57
77
|
# to the uci path
|
|
58
78
|
|
|
@@ -63,15 +83,15 @@ class hspfModel():
|
|
|
63
83
|
self.wdm_paths.append(file_path)
|
|
64
84
|
elif file_path.suffix.lower() == '.hbn':
|
|
65
85
|
assert file_path.parent.exists(),'File folder Specified in the UCI does not exist: ' + file_path.as_posix()
|
|
66
|
-
|
|
67
|
-
if file_path.exists():
|
|
68
|
-
#self.hbns[file_path.name.split('.')[0]] = hbn.hbnClass(file_path)
|
|
69
|
-
self.hbn_paths.append(file_path)
|
|
70
|
-
else:
|
|
71
|
-
self.run_model()
|
|
86
|
+
self.hbn_paths.append(file_path)
|
|
72
87
|
else:
|
|
73
88
|
assert file_path.parent.exists(),'File folder Specified in the UCI does not exist: ' + file_path.as_posix()
|
|
74
89
|
|
|
90
|
+
if (all(file_path.exists() for file_path in self.hbn_paths)) & (run_model == False):
|
|
91
|
+
pass
|
|
92
|
+
else:
|
|
93
|
+
self.run_model()
|
|
94
|
+
|
|
75
95
|
def run_model(self,new_uci_file = None):
|
|
76
96
|
|
|
77
97
|
if new_uci_file is None:
|
|
@@ -80,14 +100,14 @@ class hspfModel():
|
|
|
80
100
|
# new_uci_file = self.model_path.joinpath(uci_name)
|
|
81
101
|
# self.uci.write(new_uci_file)
|
|
82
102
|
subprocess.run([self.winHSPF,self.uci_file.as_posix()]) #, stdout=subprocess.PIPE, creationflags=0x08000000)
|
|
83
|
-
self.load_uci(new_uci_file)
|
|
103
|
+
self.load_uci(new_uci_file,run_model = False)
|
|
84
104
|
|
|
85
105
|
def load_hbn(self,hbn_name):
|
|
86
106
|
self.hbns[hbn_name] = hbn.hbnClass(self.uci_file.parent.joinpath(hbn_name).as_posix())
|
|
87
107
|
|
|
88
|
-
def load_uci(self,uci_file):
|
|
108
|
+
def load_uci(self,uci_file,run_model:bool = False):
|
|
89
109
|
self.uci = UCI(uci_file)
|
|
90
|
-
self.validate_uci()
|
|
110
|
+
self.validate_uci(run_model = run_model)
|
|
91
111
|
|
|
92
112
|
def convert_wdms(self):
|
|
93
113
|
for wdm_file in self.wdm_paths:
|