hspf 2.1.0__py3-none-any.whl → 2.1.2__py3-none-any.whl

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.
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1 @@
1
+ WDM WDM1 C:\Program Files (x86)\HSPEXP+\WinHSPFLt\hspfmsg.wdm
@@ -0,0 +1,625 @@
1
+
2
+ #%%
3
+ from hspf.parser.parsers import parseTable
4
+ from hspf import warehouse
5
+ import duckdb
6
+ import pandas as pd
7
+ from hspf.uci import UCI
8
+ from pathlib import Path
9
+ from pyhcal.repository import Repository
10
+
11
+ #%% Model information
12
+ '''
13
+ Model
14
+ Version (typically deliniated by end year)
15
+ Scenario
16
+ Run
17
+
18
+ We have a model for a Basin. Perodically the model is updated and altered enough to be considered a new version. Each version may have multiple scenarios (e.g., different management practices) and each scenario may have multiple runs (e.g., different time periods, different input data).
19
+
20
+
21
+ model: BigFork
22
+ version: BigFork_2000_2010
23
+ scenario: Base
24
+
25
+
26
+ run_name: Initial Run
27
+ run_id: 0
28
+ '''
29
+
30
+ ucis = {model_name: UCI(Repository(model_name).uci_file,False) for model_name in Repository.valid_models()}
31
+
32
+
33
+ #%% Table Builders
34
+
35
+ def build_model_table(model_name,uci,version_name=None, scenario_name=None):
36
+ scenario_name = pd.NA
37
+ start_year = int(uci.table('GLOBAL')['start_date'].str[0:4].values[0])
38
+ end_year = int(uci.table('GLOBAL')['end_date'].str[0:4].values[0])
39
+
40
+ if version_name is None:
41
+ version_name = f"{model_name}_{start_year}_{end_year}"
42
+
43
+ if scenario_name is None:
44
+ scenario_name = 'Basecase'
45
+
46
+ df_model = pd.DataFrame({
47
+ 'model_name': [model_name],
48
+ 'version_name': [version_name],
49
+ 'start_year': [start_year],
50
+ 'end_year': [end_year],
51
+ 'scenario_name': [scenario_name]
52
+ })
53
+
54
+ return df_model
55
+
56
+
57
+
58
+ def build_operations_table(model_name, uci):
59
+ df = uci.table('OPN SEQUENCE')[['OPERATION','SEGMENT']]
60
+ df = df.rename(columns={'SEGMENT': 'operation_id', 'OPERATION': 'operation_type'})
61
+ df['model_name'] = model_name
62
+ return df
63
+
64
+
65
+ def build_schematic_table(model_name, uci):
66
+ df = uci.table('SCHEMATIC')
67
+ df['model_name'] = model_name
68
+ return df
69
+
70
+ def build_masslink_table(model_name, uci):
71
+ dfs = []
72
+ for table_name in uci.table_names('MASS-LINK'):
73
+ mlno = table_name.split('MASS-LINK')[1]
74
+ masslink = uci.table('MASS-LINK',table_name)
75
+ masslink.insert(0,'MLNO',mlno)
76
+ masslink['model_name'] = model_name
77
+ dfs.append(masslink)
78
+ df = pd.concat(dfs).reset_index(drop=True)
79
+ return df
80
+
81
+
82
+ def build_extsources_table(model_name, uci):
83
+ extsource = uci.table('EXT SOURCES')
84
+ extsource['model_name'] = model_name
85
+ return extsource
86
+
87
+ def build_exttargets_table(model_name, uci):
88
+ if 'EXT TARGETS' in uci.block_names():
89
+ exttarget = uci.table('EXT TARGETS')
90
+ exttarget['model_name'] = model_name
91
+ else:
92
+ exttarget = pd.DataFrame()
93
+ return exttarget
94
+
95
+ def build_network_table(model_name, uci):
96
+ if 'NETWORK' in uci.block_names():
97
+ network = uci.table('NETWORK')
98
+ network['model_name'] = model_name
99
+ else:
100
+ network = pd.DataFrame()
101
+ return network
102
+
103
+ def build_ftables_table(model_name, uci):
104
+ dfs = []
105
+ if 'FTABLES' in uci.block_names():
106
+ for ftable_name in uci.table_names('FTABLES'):
107
+ ftable_num = int(ftable_name.split('FTABLE')[1])
108
+ ftable = uci.table('FTABLES',ftable_name)
109
+ ftable['reach_id'] = ftable_num
110
+ ftable['model_name'] = model_name
111
+ dfs.append(ftable)
112
+ if dfs:
113
+ df = pd.concat(dfs).reset_index(drop=True)
114
+ else:
115
+ df = pd.DataFrame()
116
+ return df
117
+
118
+
119
+ def build_parmeter_table(model_name, uci):
120
+ dfs = []
121
+ for key, value in uci.uci.items():
122
+ if key[0] in ['PERLND','RCHRES','IMPLND']:
123
+ table = uci.table(key[0],key[1],key[2]).reset_index()
124
+ table['model_name'] = model_name
125
+ table['operation_type'] = key[0]
126
+ table['table_name'] = key[1]
127
+ table['table_id'] = key[2]
128
+ table.rename(columns = {'OPNID': 'operation_id'}, inplace=True)
129
+ dfs.append(table.melt(id_vars = ['model_name','table_name','table_id','operation_type','operation_id']))
130
+ df = pd.concat(dfs).reset_index(drop=True)
131
+ return df
132
+
133
+ #%% Build Tables
134
+ models_df = pd.concat([build_model_table(model_name, uci) for model_name, uci in ucis.items()]).reset_index(drop=True)
135
+ operations_df = pd.concat([build_operations_table(model_name, uci) for model_name, uci in ucis.items()]).reset_index(drop=True)
136
+ masslinks_df = pd.concat([build_masslink_table(model_name, uci) for model_name, uci in ucis.items()]).reset_index(drop=True)
137
+ schematics_df = pd.concat([build_schematic_table(model_name, uci) for model_name, uci in ucis.items()]).reset_index(drop=True)
138
+ extsources_df = pd.concat([build_extsources_table(model_name, uci) for model_name, uci in ucis.items()]).reset_index(drop=True)
139
+ exttargets_df = pd.concat([build_exttargets_table(model_name, uci) for model_name, uci in ucis.items()]).reset_index(drop=True)
140
+ networks_df = pd.concat([build_network_table(model_name, uci) for model_name, uci in ucis.items()]).reset_index(drop=True)
141
+ ftables_df = pd.concat([build_ftables_table(model_name, uci) for model_name, uci in ucis.items()]).reset_index(drop=True)
142
+ df = pd.concat([build_parmeter_table(model_name, uci) for model_name, uci in ucis.items()]).reset_index(drop=True)
143
+ df = pd.merge(df,parseTable,left_on = ['operation_type','table_name','variable'],
144
+ right_on = ['block','table2','column'],how='left')[['model_name','operation_type','table_name','table_id','operation_id','variable','value','dtype']]
145
+ props = df.query('dtype == "C"')
146
+ flags = df.query('dtype == "I"')
147
+ params = df.query('dtype == "R"')
148
+
149
+ #%% Optionally Add PKs
150
+ models_df['model_pk'] = models_df.index + 1
151
+ operations_df['operation_pk'] = operations_df.index + 1
152
+ mlno_pks = {mlno: idx+1 for idx, mlno in enumerate(masslinks_df[['MLNO','model_name']].drop_duplicates().itertuples(index=False, name=None))}
153
+ masslinks_df['mlno_pk'] = masslinks_df[['MLNO','model_name']].apply(tuple, axis=1).map(mlno_pks)
154
+ # Schematics
155
+ schematics_df = schematics_df.merge(
156
+ operations_df[['model_name','operation_id','operation_type','operation_pk']],
157
+ left_on=['model_name','SVOLNO','SVOL'],
158
+ right_on=['model_name','operation_id','operation_type'],
159
+ how='left'
160
+ ).rename(columns={'operation_pk': 'source_operation_pk'})
161
+
162
+ schematics_df = schematics_df.merge(
163
+ operations_df[['model_name','operation_id','operation_type','operation_pk']],
164
+ left_on=['model_name','TVOL','TVOLNO'],
165
+ right_on=['model_name','operation_type','operation_id'],
166
+ how='left'
167
+ ).rename(columns={'operation_pk': 'target_operation_pk'})
168
+ #Join masslink pks
169
+ schematics_df = schematics_df.merge(
170
+ masslinks_df[['model_name','MLNO','mlno_pk']],
171
+ on=['model_name','MLNO'],
172
+ how='left'
173
+ )
174
+ #set operatin_pk dtyes to int
175
+ schematics_df['source_operation_pk'] = schematics_df['source_operation_pk'].astype('Int64')
176
+ schematics_df['target_operation_pk'] = schematics_df['target_operation_pk'].astype('Int64')
177
+ schematics_df[['source_operation_pk','target_operation_pk','AFACTR','MLNO','TMEMSB1','TMEMSB2']]
178
+ schematics_df['mlno_pk'] = schematics_df['mlno_pk'].astype('Int64')
179
+ #% Ext Sources
180
+ extsources_df = extsources_df.merge(
181
+ operations_df[['model_name','operation_id','operation_type','operation_pk']],
182
+ left_on=['model_name','TVOL','TOPFST'],
183
+ right_on=['model_name','operation_type','operation_id'],
184
+ how='left'
185
+ ).rename(columns={'operation_pk': 'target_operation_pk'})
186
+ #% Ext Targets
187
+ exttargets_df = exttargets_df.merge(
188
+ operations_df[['model_name','operation_id','operation_type','operation_pk']],
189
+ left_on=['model_name','SVOL','SVOLNO'],
190
+ right_on=['model_name','operation_type','operation_id'],
191
+ how='left'
192
+ ).rename(columns={'operation_pk': 'source_operation_pk'})
193
+ #% Network
194
+ networks_df = networks_df.merge(
195
+ operations_df[['model_name','operation_id','operation_type','operation_pk']],
196
+ left_on=['model_name','TOPFST','TVOL'],
197
+ right_on=['model_name','operation_id','operation_type'],
198
+ how='left'
199
+ ).rename(columns={'operation_pk': 'target_operation_pk'})
200
+ networks_df = networks_df.merge(
201
+ operations_df[['model_name','operation_id','operation_type','operation_pk']],
202
+ left_on=['model_name','SVOL','SVOLNO'],
203
+ right_on=['model_name','operation_type','operation_id'],
204
+ how='left'
205
+ ).rename(columns={'operation_pk': 'source_operation_pk'})
206
+ #% FTABLES
207
+ ftables_df = ftables_df.merge(
208
+ operations_df[['model_name','operation_id','operation_type','operation_pk']].query('operation_type == "RCHRES"'),
209
+ left_on=['model_name','reach_id'],
210
+ right_on=['model_name','operation_id'],
211
+ how='left'
212
+ )
213
+ #% Parameters, Flags, Properties
214
+ props = props.merge(models_df[['model_name','model_pk']], on='model_name', how='left')
215
+ props = props.merge(operations_df[['model_name','operation_id','operation_type','operation_pk']],
216
+ left_on=['model_name','operation_id','operation_type'],
217
+ right_on=['model_name','operation_id','operation_type'],
218
+ how='left')
219
+ flags = flags.merge(models_df[['model_name','model_pk']], on='model_name', how='left')
220
+ flags = flags.merge(operations_df[['model_name','operation_id','operation_type','operation_pk']],
221
+ left_on=['model_name','operation_id','operation_type'],
222
+ right_on=['model_name','operation_id','operation_type'],
223
+ how='left')
224
+ params = params.merge(models_df[['model_name','model_pk']], on='model_name', how='left')
225
+ params = params.merge(operations_df[['model_name','operation_id','operation_type','operation_pk']],
226
+ left_on=['model_name','operation_id','operation_type'],
227
+ right_on=['model_name','operation_id','operation_type'],
228
+ how='left')
229
+
230
+
231
+
232
+
233
+ #Dump all dataframes to warehouse
234
+ #%% Dump to Warehouse
235
+
236
+ db_path = 'c:/Users/mfratki/Documents/ucis.duckdb'
237
+ with duckdb.connect(db_path) as con:
238
+ warehouse.load_df_to_table(con, models_df, 'models')
239
+ warehouse.load_df_to_table(con, operations_df, 'operations')
240
+ warehouse.load_df_to_table(con, schematics_df, 'schematics')
241
+ warehouse.load_df_to_table(con, masslinks_df, 'masslinks')
242
+ warehouse.load_df_to_table(con, extsources_df, 'extsources')
243
+ warehouse.load_df_to_table(con, exttargets_df, 'exttargets')
244
+ warehouse.load_df_to_table(con, networks_df, 'networks')
245
+ warehouse.load_df_to_table(con, ftables_df, 'ftables')
246
+ warehouse.load_df_to_table(con, props, 'properties')
247
+ warehouse.load_df_to_table(con, flags, 'flags')
248
+ warehouse.load_df_to_table(con, params, 'parameters')
249
+
250
+
251
+
252
+ #%%
253
+
254
+ with duckdb.connect(db_path) as con:
255
+ warehouse.create_model_run_table(con)
256
+
257
+
258
+
259
+ model_name = 'BigFork'
260
+ run_id = 1
261
+
262
+ run_id = 47
263
+
264
+
265
+ hbn = cal.model.hbns
266
+ mapn = hbn.hbns[0].mapn
267
+
268
+ outputs = hbn.hbns[0].output_dictionary
269
+ dfs = []
270
+ for key,ts_names in outputs.items():
271
+ keys = key.split('_')
272
+ operation = keys[0]
273
+ activity = keys[1]
274
+ opnid = int(keys[2])
275
+ t_code = keys[3]
276
+ df = pd.DataFrame({'operation': operation,
277
+ 'activity': activity,
278
+ 'opnid': opnid,
279
+ 't_code': t_code,
280
+ 'ts_names': ts_names})
281
+ dfs.append(df)
282
+ output_df = pd.concat(dfs).reset_index(drop=True)
283
+
284
+ dfs = []
285
+ for key,data in hbn.hbns[0].data_frames.items():
286
+ keys = key.split('_')
287
+ operation = keys[0]
288
+ activity = keys[1]
289
+ opnid = int(keys[2])
290
+ t_code = keys[3]
291
+ data.reset_index(inplace=True)
292
+ data.rename(columns={'index': 'datetime'}, inplace=True)
293
+ data = data.melt(id_vars = ['datetime'],var_name = 'ts_name', value_name = 'value')
294
+ data['operation'] = operation
295
+ data['activity'] = activity
296
+ data['opnid'] = opnid
297
+ data['t_code'] = t_code
298
+ data['model_name'] = model_name
299
+ dfs.append(data)
300
+ output_df = pd.concat(dfs).reset_index(drop=True)
301
+
302
+
303
+
304
+ # Write to Parquet with DuckDB, including "t_code" as a partition
305
+ output_path = "model_outputs"
306
+
307
+ con = duckdb.connect(database=':memory:') # Temporary in-memory database
308
+ con.execute(f"""
309
+ COPY output_df
310
+ TO '{output_path}'
311
+ (FORMAT 'parquet', PARTITION_BY ('model_name','operation', 'opnid'))
312
+ """)
313
+
314
+ print(f"Data written to {output_path}")
315
+
316
+
317
+
318
+ ['PERO',
319
+ 'SURO',
320
+ 'IFWO',
321
+ 'AGWO']
322
+
323
+ for constituent in ['Q','TSS','TP','N','OP','BOD','TKN']:
324
+ t_cons = helpers.get_tcons(constituent,'RCHRES','lb')
325
+ df = hbn.get_rechres_data(constituent, units='lb', freq='daily').reset_index()
326
+
327
+
328
+ pero = hbn.get_multiple_timeseries(op_type,t_code,ts_name).reset_index().rename(columns={'index': 'datetime'})
329
+ pero = pero.melt(id_vars = ['datetime'],var_name = 'operation_id', value_name = 'value')
330
+ pero['ts_name'] = ts_name
331
+ pero['t_code'] = t_code
332
+ pero['model_name'] = model_name
333
+
334
+
335
+ db_path = 'c:/Users/mfratki/Documents/ucis.duckdb'
336
+ with duckdb.connect(db_path) as con:
337
+ warehouse.insert_model_run(con, model_name, run_id)
338
+
339
+ db_path = 'c:/Users/mfratki/Documents/ucis.duckdb'
340
+ with duckdb.connect(db_path) as conn:
341
+ conn.execute("CREATE SCHEMA if not exists reports")
342
+ conn.execute("CREATE TABLE if not exists reports.catchment_loading AS SELECT * FROM df")
343
+ conn.close()
344
+
345
+
346
+ # Average annual loading by catchment
347
+ db_path = 'c:/Users/mfratki/Documents/ucis.duckdb'
348
+ with duckdb.connect(db_path) as conn:
349
+ query = f"""
350
+ SELECT
351
+ model_name,
352
+ operation AS operation_type,
353
+ opnid AS operation_id,
354
+ t_code,
355
+ ts_name AS constituent,
356
+ AVG(value) * 365.25 AS annual_loading
357
+ FROM reports.catchment_loading
358
+ WHERE t_code = 'PERLND' AND constituent IN ('Q','TP','TSS','N','OP','BOD','TKN')
359
+ GROUP BY model_name, TVOLNO, constituent
360
+ """
361
+ annual_loadings = conn.execute(query).fetchdf()
362
+ conn.close()
363
+
364
+ hbn.hbns[0].data_frames.keys()
365
+
366
+
367
+
368
+ import duckdb
369
+ import pandas as pd
370
+
371
+
372
+ # Convert to DataFrame
373
+ df = pd.DataFrame(data)
374
+ df['datetime'] = pd.to_datetime(df['datetime']) # Ensure datetime column is formatted properly
375
+
376
+ # Write to Parquet with DuckDB, including "t_code" as a partition
377
+ output_path = "model_outputs"
378
+
379
+ con = duckdb.connect(database=':memory:') # Temporary in-memory database
380
+ con.execute(f"""
381
+ COPY df
382
+ TO '{output_path}'
383
+ (FORMAT 'parquet', PARTITION_BY ('operation_type', 'operation_id', 't_code'))
384
+ """)
385
+
386
+ print(f"Data written to {output_path}")
387
+
388
+
389
+
390
+
391
+
392
+
393
+ #%% Catchments
394
+ def build_catchments_table(model_name, uci):
395
+ df = pd.DataFrame({'catchment_id': uci.network.catchment_ids})
396
+ df['catchment_name'] = pd.NA
397
+ df['model_name'] = model_name
398
+ return df
399
+
400
+ catchments = []
401
+ for model_name, uci in ucis.items():
402
+ df = build_catchments_table(model_name, uci)
403
+ catchments.append(df)
404
+ catchments_df = pd.concat(catchments).reset_index(drop=True)
405
+ catchments_df['catchment_pk'] = catchments_df.index + 1
406
+
407
+
408
+ #%% Catchment Operations
409
+ catchment_operations = []
410
+ # for model_name, uci in ucis.items():
411
+ # dfs = []
412
+ # for reach_id in uci.network.get_node_type_ids('RCHRES'):
413
+ # df = uci.network.drainage(reach_id)
414
+ # df['catchment_id'] = reach_id
415
+ # dfs.append(df)
416
+ # df = pd.concat(dfs).reset_index(drop=True)
417
+ # df['model_name'] = model_name
418
+ # catchment_operations.append(df)
419
+ # catchment_operations_df = pd.concat(catchment_operations).reset_index(drop=True)
420
+ # catchment_operations_df.rename(columns = {
421
+ # 'source_type_id': 'source_operation_id',
422
+ # 'source_type': 'source_operation'}, inplace=True)
423
+
424
+ for model_name, uci in ucis.items():
425
+ df = uci.network.subwatersheds().reset_index()
426
+ df['model_name'] = model_name
427
+ df.rename(columns = {'TVOLNO': 'catchment_id',
428
+ 'SVOLNO': 'source_operation_id',
429
+ 'SVOL': 'source_operation',
430
+ 'MLNO': 'mlno',
431
+ 'AFACTR': 'area'}, inplace=True)
432
+ catchment_operations.append(df)
433
+ catchment_operations_df = pd.concat(catchment_operations).reset_index(drop=True)
434
+
435
+
436
+ #%% Join Model PKs
437
+ operations_df = operations_df.merge(models_df[['model_name','model_pk']], on='model_name', how='left')
438
+ catchments_df = catchments_df.merge(models_df[['model_name','model_pk']], on='model_name', how='left')
439
+ catchment_operations_df = catchment_operations_df.merge(models_df[['model_name','model_pk']], on='model_name', how='left')
440
+
441
+ #%% Join catchment pks
442
+ catchment_operations_df = catchment_operations_df.merge(
443
+ catchments_df[['model_pk','catchment_id','catchment_pk']],
444
+ on=['model_pk','catchment_id'],
445
+ how='left'
446
+ )
447
+
448
+ cathcment_operations_df = catchment_operations_df.merge(
449
+ operations_df[['model_pk','operation_id','operation_type','operation_pk']],
450
+ left_on=['model_pk','source_operation_id','source_operation'],
451
+ right_on=['model_pk','operation_id','operation_type'],
452
+ how='left'
453
+ ).rename(columns={'operation_pk': 'source_operation_pk'})
454
+
455
+ catchment_operations_df = catchment_operations_df.merge(
456
+ operations_df[['model_pk','operation_id','operation_type','operation_pk']],
457
+ left_on=['model_pk','target_operation_id','target_operation'],
458
+ right_on=['model_pk','operation_id','operation_type'],
459
+ how='left'
460
+ ).rename(columns={'operation_pk': 'target_operation_pk'})
461
+
462
+
463
+
464
+ #%% Properties, Flags, Parameters
465
+ # duplicate_tables = []
466
+ # for model_name, uci in ucis.items():
467
+ # for key, value in uci.uci.items():
468
+ # if key[0] in ['PERLND','RCHRES','IMPLND']:
469
+ # if key[2] > 0:
470
+ # duplicate_tables.append(key)
471
+
472
+
473
+ # Special Tables
474
+ '''
475
+ IMPLND QUAL-INPUT 0, 1, 2, 3, 4`: 0 = NH3+NH4, 1=NO3, 2 = ORTHO P, 3= BOD, 4 = F.COLIFORM
476
+ IMPLND QUAL-PROPS 0, 1, 2, 3, 4 : 0 = NH3+NH4, 1=NO3, 2 = ORTHO P, 3= BOD, 4 = F.COLIFORM
477
+ PERLND MON-ACCUM 0, 1, 2 : 0 = ?, 1= ?, 2 = ?
478
+ PERLND MON-GRND-CONC 0,1,2,3,4,5 : 0 = NH3+NH4, 1=NO3, 2 = ORTHO P, 3= BOD, 4 = F.COLIFORM, 5= TSS
479
+ PERLND MON-IFLW-CONC 0,1,2,3,4 : 0 = NH3+NH4, 1=NO3, 2 = ORTHO P, 3= BOD, 4 = F.COLIFORM
480
+ PERLND MON-POTFW 0,1 : 0 = ?, 1 = ?
481
+ PERLND MON-SQOLIM 0,1 : 0 = ?, 1 = ?
482
+ PERLND QUAL-INPUT 0,1,2,3,5 : 0 = NH3+NH4, 1=NO3, 2 = ORTHO P, 3= BOD, 4 = F.COLIFORM, 5= TSS
483
+ PERLND QUAL-PROPS 0,1,2,3,5 : 0 = NH3+NH4, 1=NO3, 2 = ORTHO P, 3= BOD, 4 = F.COLIFORM, 5= TSS
484
+ RCHRES SILT-CLAY-PM 0,1 : 0 = SILT, 1 = CLAY
485
+ '''
486
+ #props = parseTable.query('dtype == "C"').query('column != "OPNID"')
487
+
488
+
489
+
490
+ #%%
491
+ dfs = {key: pd.concat(value) for key, value in dfs.items()}
492
+
493
+ for row in props.iterrows():
494
+ if row['table2'] in uci.table_names(row['block']):
495
+ df_prop = uci.table(row['block'],row['table2'])[['OPNID',row['column']]]
496
+ df = df.rename(columns={row['column']: 'value'})
497
+ df['property_name'] = row['column']
498
+ df['model_name'] = model_name
499
+ properties.append(df)
500
+
501
+
502
+
503
+
504
+ #%% Parameters
505
+
506
+
507
+
508
+ #%% Flags
509
+
510
+
511
+
512
+ #%%
513
+
514
+
515
+
516
+
517
+
518
+
519
+
520
+ for model_name, uci in ucis.items():
521
+ extsources = uci.table('EXT SOURCES')
522
+ extsources['SVOL'] = extsources['SVOL'].str.upper().replace({'WDM': 'WDM1'})
523
+
524
+ files = uci.table('FILES')
525
+ files['FTYPE'] = files['FTYPE'].str.upper().replace({'WDM': 'WDM1'})
526
+
527
+ df = pd.merge(extsources,files,how='left',left_on = 'SVOL',right_on = 'FTYPE')
528
+ if 'EXT TARGETS' in uci.block_names():
529
+ extargets = uci.table('EXT TARGETS')
530
+ extargets['model_name'] = model_name
531
+ extargets['SVOL'] = extargets['SVOL'].str.upper().replace({'WDM': 'WDM1'})
532
+
533
+ df2 = pd.merge(extargets,files,how='left',left_on = 'SVOL',right_on = 'FTYPE')
534
+
535
+
536
+ catchment_operations.append(df)
537
+
538
+
539
+ # Properties
540
+ parseTable.query('dtype == "C"')
541
+
542
+
543
+ # Parameters
544
+ #%% PERLND Hydrology Parameters
545
+ # [Table-type PWAT-PARM1]
546
+ # Table-type PWAT-PARM2
547
+ # [Table-type PWAT-PARM3]
548
+ # Table-type PWAT-PARM4
549
+ # [Table-type PWAT-PARM5]
550
+ # [Table-type PWAT-PARM6]
551
+ # [Table-type PWAT-PARM7]
552
+
553
+
554
+ table_names = ['PWAT-PARM2','PWAT-PARM3','PWAT-PARM4','PWAT-PARM5']
555
+
556
+
557
+
558
+
559
+ dfs = []
560
+ for model_name, uci in ucis.items():
561
+ model_pk = Models.find(model_name)[0]
562
+ table_names = ['PWAT-PARM2','PWAT-PARM3','PWAT-PARM4','PWAT-PARM5']
563
+ params = [uci.table('PERLND',table_name) for table_name in table_names if table_name in uci.table_names('PERLND')]
564
+ merged_df = params[0]
565
+ for df in params[1:]:
566
+ merged_df = merged_df.join(df)
567
+ df = merged_df.stack().reset_index()
568
+ df.columns = ['OPNID','name','value']
569
+ df.insert(0,'OPERATION','PERLND')
570
+ df.insert(0,'model_pk',model_pk)
571
+ dfs.append(df)
572
+ params = pd.concat(dfs)
573
+ # Flags
574
+ flags = parseTable.query('dtype == "I"')
575
+
576
+
577
+
578
+
579
+ df[['TGRPN', 'TMEMN', 'TMEMSB1_y','TMEMSB2_y']].drop_duplicates().shape
580
+ df[['SGRPN', 'SMEMN', 'SMEMSB1','SMEMSB2']].drop_duplicates().shape
581
+
582
+ df[['TGRPN', 'TMEMN', 'TMEMSB1_y','TMEMSB2_y']].drop_duplicates()
583
+
584
+ for masslink in masslinks:
585
+ for mlno in masslink['MLNO'].unique():
586
+ if len(masslink.query(f'MLNO == "{mlno}"')['TVOL'].unique()) > 1:
587
+ print(f"{masslink['model_name'].iloc[0]} MASS-LINK{mlno} has multiple TVOL entries.")
588
+
589
+
590
+ for mlno in schematic['MLNO'].unique():
591
+ svol = schematic.query(f'MLNO == "{mlno}"')['SVOL'].unique()
592
+ tvol = schematic.query(f'MLNO == "{mlno}"')['TVOL'].unique()
593
+
594
+ df_targets = []
595
+ df_extsources = []
596
+ for model_name, uci in ucis.items():
597
+ files = uci.table('FILES')
598
+ files['FTYPE'] = files['FTYPE'].str.upper().replace({'WDM': 'WDM1'})
599
+ extsources = uci.table('EXT SOURCES')
600
+ extsources['SVOL'] = extsources['SVOL'].str.upper().replace({'WDM': 'WDM1'})
601
+ extsources['model_name'] = model_name
602
+ df_extsources.append(pd.merge(extsources,files,how='left',left_on = 'SVOL',right_on = 'FTYPE'))
603
+ if 'EXT TARGETS' in uci.block_names():
604
+ extargets = uci.table('EXT TARGETS')
605
+ extargets['model_name'] = model_name
606
+ extargets['TVOL'] = extargets['TVOL'].str.upper().replace({'WDM': 'WDM1'})
607
+ df = pd.merge(extargets,files,how='left',left_on = 'TVOL',right_on = 'FTYPE')
608
+ df_targets.append(df)
609
+
610
+ df_targets = pd.concat(df_targets,ignore_index=True)
611
+ df_extsources = pd.concat(df_extsources,ignore_index=True)
612
+
613
+
614
+ df_targets.rename(columns = {'TVOLNO': 'dsn',
615
+ 'SVOL': 'operation',
616
+ 'SVOLNO': 'operation_id'}, inplace=True)
617
+
618
+ df_extsources.rename(columns = {'SVOLNO': 'dsn',
619
+ 'TVOL': 'operation',
620
+ 'TVOLNO': 'operation_id'}, inplace=True)
621
+
622
+ df = pd.merge(df_targets,df_extsources,how='inner',left_on = ['FILENAME','dsn'],right_on = ['FILENAME','dsn'],suffixes=('_source','_target'))
623
+ df[['operation_source','operation_id','model_name_source','operation_target','TOPFST','model_name_target','FILENAME']].drop_duplicates()
624
+
625
+