hspf 2.1.0__py3-none-any.whl → 2.1.1__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.
@@ -0,0 +1,545 @@
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
+
285
+ ts_name = 'PERO'
286
+ op_type = 'PERLND'
287
+ t_code = 4
288
+
289
+
290
+
291
+ pero = hbn.get_multiple_timeseries(op_type,t_code,ts_name).reset_index().rename(columns={'index': 'datetime'})
292
+ pero = pero.melt(id_vars = ['datetime'],var_name = 'operation_id', value_name = 'value')
293
+ pero['ts_name'] = ts_name
294
+ pero['t_code'] = t_code
295
+ pero['model_name'] = model_name
296
+
297
+
298
+ with duckdb.connect(db_path) as con:
299
+ warehouse.insert_model_run(con, model_name, run_id)
300
+
301
+
302
+
303
+
304
+
305
+
306
+
307
+
308
+
309
+
310
+
311
+
312
+
313
+ #%% Catchments
314
+ def build_catchments_table(model_name, uci):
315
+ df = pd.DataFrame({'catchment_id': uci.network.catchment_ids})
316
+ df['catchment_name'] = pd.NA
317
+ df['model_name'] = model_name
318
+ return df
319
+
320
+ catchments = []
321
+ for model_name, uci in ucis.items():
322
+ df = build_catchments_table(model_name, uci)
323
+ catchments.append(df)
324
+ catchments_df = pd.concat(catchments).reset_index(drop=True)
325
+ catchments_df['catchment_pk'] = catchments_df.index + 1
326
+
327
+
328
+ #%% Catchment Operations
329
+ catchment_operations = []
330
+ # for model_name, uci in ucis.items():
331
+ # dfs = []
332
+ # for reach_id in uci.network.get_node_type_ids('RCHRES'):
333
+ # df = uci.network.drainage(reach_id)
334
+ # df['catchment_id'] = reach_id
335
+ # dfs.append(df)
336
+ # df = pd.concat(dfs).reset_index(drop=True)
337
+ # df['model_name'] = model_name
338
+ # catchment_operations.append(df)
339
+ # catchment_operations_df = pd.concat(catchment_operations).reset_index(drop=True)
340
+ # catchment_operations_df.rename(columns = {
341
+ # 'source_type_id': 'source_operation_id',
342
+ # 'source_type': 'source_operation'}, inplace=True)
343
+
344
+ for model_name, uci in ucis.items():
345
+ df = uci.network.subwatersheds().reset_index()
346
+ df['model_name'] = model_name
347
+ df.rename(columns = {'TVOLNO': 'catchment_id',
348
+ 'SVOLNO': 'source_operation_id',
349
+ 'SVOL': 'source_operation',
350
+ 'MLNO': 'mlno',
351
+ 'AFACTR': 'area'}, inplace=True)
352
+ catchment_operations.append(df)
353
+ catchment_operations_df = pd.concat(catchment_operations).reset_index(drop=True)
354
+
355
+
356
+ #%% Join Model PKs
357
+ operations_df = operations_df.merge(models_df[['model_name','model_pk']], on='model_name', how='left')
358
+ catchments_df = catchments_df.merge(models_df[['model_name','model_pk']], on='model_name', how='left')
359
+ catchment_operations_df = catchment_operations_df.merge(models_df[['model_name','model_pk']], on='model_name', how='left')
360
+
361
+ #%% Join catchment pks
362
+ catchment_operations_df = catchment_operations_df.merge(
363
+ catchments_df[['model_pk','catchment_id','catchment_pk']],
364
+ on=['model_pk','catchment_id'],
365
+ how='left'
366
+ )
367
+
368
+ cathcment_operations_df = catchment_operations_df.merge(
369
+ operations_df[['model_pk','operation_id','operation_type','operation_pk']],
370
+ left_on=['model_pk','source_operation_id','source_operation'],
371
+ right_on=['model_pk','operation_id','operation_type'],
372
+ how='left'
373
+ ).rename(columns={'operation_pk': 'source_operation_pk'})
374
+
375
+ catchment_operations_df = catchment_operations_df.merge(
376
+ operations_df[['model_pk','operation_id','operation_type','operation_pk']],
377
+ left_on=['model_pk','target_operation_id','target_operation'],
378
+ right_on=['model_pk','operation_id','operation_type'],
379
+ how='left'
380
+ ).rename(columns={'operation_pk': 'target_operation_pk'})
381
+
382
+
383
+
384
+ #%% Properties, Flags, Parameters
385
+ # duplicate_tables = []
386
+ # for model_name, uci in ucis.items():
387
+ # for key, value in uci.uci.items():
388
+ # if key[0] in ['PERLND','RCHRES','IMPLND']:
389
+ # if key[2] > 0:
390
+ # duplicate_tables.append(key)
391
+
392
+
393
+ # Special Tables
394
+ '''
395
+ IMPLND QUAL-INPUT 0, 1, 2, 3, 4`: 0 = NH3+NH4, 1=NO3, 2 = ORTHO P, 3= BOD, 4 = F.COLIFORM
396
+ IMPLND QUAL-PROPS 0, 1, 2, 3, 4 : 0 = NH3+NH4, 1=NO3, 2 = ORTHO P, 3= BOD, 4 = F.COLIFORM
397
+ PERLND MON-ACCUM 0, 1, 2 : 0 = ?, 1= ?, 2 = ?
398
+ 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
399
+ PERLND MON-IFLW-CONC 0,1,2,3,4 : 0 = NH3+NH4, 1=NO3, 2 = ORTHO P, 3= BOD, 4 = F.COLIFORM
400
+ PERLND MON-POTFW 0,1 : 0 = ?, 1 = ?
401
+ PERLND MON-SQOLIM 0,1 : 0 = ?, 1 = ?
402
+ PERLND QUAL-INPUT 0,1,2,3,5 : 0 = NH3+NH4, 1=NO3, 2 = ORTHO P, 3= BOD, 4 = F.COLIFORM, 5= TSS
403
+ PERLND QUAL-PROPS 0,1,2,3,5 : 0 = NH3+NH4, 1=NO3, 2 = ORTHO P, 3= BOD, 4 = F.COLIFORM, 5= TSS
404
+ RCHRES SILT-CLAY-PM 0,1 : 0 = SILT, 1 = CLAY
405
+ '''
406
+ #props = parseTable.query('dtype == "C"').query('column != "OPNID"')
407
+
408
+
409
+
410
+ #%%
411
+ dfs = {key: pd.concat(value) for key, value in dfs.items()}
412
+
413
+ for row in props.iterrows():
414
+ if row['table2'] in uci.table_names(row['block']):
415
+ df_prop = uci.table(row['block'],row['table2'])[['OPNID',row['column']]]
416
+ df = df.rename(columns={row['column']: 'value'})
417
+ df['property_name'] = row['column']
418
+ df['model_name'] = model_name
419
+ properties.append(df)
420
+
421
+
422
+
423
+
424
+ #%% Parameters
425
+
426
+
427
+
428
+ #%% Flags
429
+
430
+
431
+
432
+ #%%
433
+
434
+
435
+
436
+
437
+
438
+
439
+
440
+ for model_name, uci in ucis.items():
441
+ extsources = uci.table('EXT SOURCES')
442
+ extsources['SVOL'] = extsources['SVOL'].str.upper().replace({'WDM': 'WDM1'})
443
+
444
+ files = uci.table('FILES')
445
+ files['FTYPE'] = files['FTYPE'].str.upper().replace({'WDM': 'WDM1'})
446
+
447
+ df = pd.merge(extsources,files,how='left',left_on = 'SVOL',right_on = 'FTYPE')
448
+ if 'EXT TARGETS' in uci.block_names():
449
+ extargets = uci.table('EXT TARGETS')
450
+ extargets['model_name'] = model_name
451
+ extargets['SVOL'] = extargets['SVOL'].str.upper().replace({'WDM': 'WDM1'})
452
+
453
+ df2 = pd.merge(extargets,files,how='left',left_on = 'SVOL',right_on = 'FTYPE')
454
+
455
+
456
+ catchment_operations.append(df)
457
+
458
+
459
+ # Properties
460
+ parseTable.query('dtype == "C"')
461
+
462
+
463
+ # Parameters
464
+ #%% PERLND Hydrology Parameters
465
+ # [Table-type PWAT-PARM1]
466
+ # Table-type PWAT-PARM2
467
+ # [Table-type PWAT-PARM3]
468
+ # Table-type PWAT-PARM4
469
+ # [Table-type PWAT-PARM5]
470
+ # [Table-type PWAT-PARM6]
471
+ # [Table-type PWAT-PARM7]
472
+
473
+
474
+ table_names = ['PWAT-PARM2','PWAT-PARM3','PWAT-PARM4','PWAT-PARM5']
475
+
476
+
477
+
478
+
479
+ dfs = []
480
+ for model_name, uci in ucis.items():
481
+ model_pk = Models.find(model_name)[0]
482
+ table_names = ['PWAT-PARM2','PWAT-PARM3','PWAT-PARM4','PWAT-PARM5']
483
+ params = [uci.table('PERLND',table_name) for table_name in table_names if table_name in uci.table_names('PERLND')]
484
+ merged_df = params[0]
485
+ for df in params[1:]:
486
+ merged_df = merged_df.join(df)
487
+ df = merged_df.stack().reset_index()
488
+ df.columns = ['OPNID','name','value']
489
+ df.insert(0,'OPERATION','PERLND')
490
+ df.insert(0,'model_pk',model_pk)
491
+ dfs.append(df)
492
+ params = pd.concat(dfs)
493
+ # Flags
494
+ flags = parseTable.query('dtype == "I"')
495
+
496
+
497
+
498
+
499
+ df[['TGRPN', 'TMEMN', 'TMEMSB1_y','TMEMSB2_y']].drop_duplicates().shape
500
+ df[['SGRPN', 'SMEMN', 'SMEMSB1','SMEMSB2']].drop_duplicates().shape
501
+
502
+ df[['TGRPN', 'TMEMN', 'TMEMSB1_y','TMEMSB2_y']].drop_duplicates()
503
+
504
+ for masslink in masslinks:
505
+ for mlno in masslink['MLNO'].unique():
506
+ if len(masslink.query(f'MLNO == "{mlno}"')['TVOL'].unique()) > 1:
507
+ print(f"{masslink['model_name'].iloc[0]} MASS-LINK{mlno} has multiple TVOL entries.")
508
+
509
+
510
+ for mlno in schematic['MLNO'].unique():
511
+ svol = schematic.query(f'MLNO == "{mlno}"')['SVOL'].unique()
512
+ tvol = schematic.query(f'MLNO == "{mlno}"')['TVOL'].unique()
513
+
514
+ df_targets = []
515
+ df_extsources = []
516
+ for model_name, uci in ucis.items():
517
+ files = uci.table('FILES')
518
+ files['FTYPE'] = files['FTYPE'].str.upper().replace({'WDM': 'WDM1'})
519
+ extsources = uci.table('EXT SOURCES')
520
+ extsources['SVOL'] = extsources['SVOL'].str.upper().replace({'WDM': 'WDM1'})
521
+ extsources['model_name'] = model_name
522
+ df_extsources.append(pd.merge(extsources,files,how='left',left_on = 'SVOL',right_on = 'FTYPE'))
523
+ if 'EXT TARGETS' in uci.block_names():
524
+ extargets = uci.table('EXT TARGETS')
525
+ extargets['model_name'] = model_name
526
+ extargets['TVOL'] = extargets['TVOL'].str.upper().replace({'WDM': 'WDM1'})
527
+ df = pd.merge(extargets,files,how='left',left_on = 'TVOL',right_on = 'FTYPE')
528
+ df_targets.append(df)
529
+
530
+ df_targets = pd.concat(df_targets,ignore_index=True)
531
+ df_extsources = pd.concat(df_extsources,ignore_index=True)
532
+
533
+
534
+ df_targets.rename(columns = {'TVOLNO': 'dsn',
535
+ 'SVOL': 'operation',
536
+ 'SVOLNO': 'operation_id'}, inplace=True)
537
+
538
+ df_extsources.rename(columns = {'SVOLNO': 'dsn',
539
+ 'TVOL': 'operation',
540
+ 'TVOLNO': 'operation_id'}, inplace=True)
541
+
542
+ df = pd.merge(df_targets,df_extsources,how='inner',left_on = ['FILENAME','dsn'],right_on = ['FILENAME','dsn'],suffixes=('_source','_target'))
543
+ df[['operation_source','operation_id','model_name_source','operation_target','TOPFST','model_name_target','FILENAME']].drop_duplicates()
544
+
545
+