Skip to content

Commit 5be6514

Browse files
v4.5.14.3 Implement denylist for flow-based CatFIM (#1413)
1 parent 267dd22 commit 5be6514

File tree

5 files changed

+134
-80
lines changed

5 files changed

+134
-80
lines changed

docs/CHANGELOG.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,22 @@
11
All notable changes to this project will be documented in this file.
22
We follow the [Semantic Versioning 2.0.0](http://semver.org/) format.
33

4+
## v4.5.14.3 - 2025-01-31 - [PR#1413](https://github.com/NOAA-OWP/inundation-mapping/pull/1413)
5+
6+
Implements a denylist for flow-based CatFIM (that uses the same conventions as the existing denylist functionality used in stage-based CatFIM. Adds CMUG1 to the denylist for flow-based CatFIM.
7+
8+
### Additions
9+
- `tools/catfim/ahps_restricted_sites.csv`: Renamed from `stage_based_ahps_restricted_sites.csv`. Added an additional column, `catfim_type`, that specifies whether a site should be restricted for flow-based CatFIM (`flow`), stage-based CatFIM (`stage`), or both (`both`).
10+
11+
### Changes
12+
- `tools/catfim/generate_categorical_fim.py`: Update the `load_restricted_sites()` function to handle restricted sites for both flow- and stage-based CatFIM.
13+
- `tools/catfim/generate_categorical_fim_flows.py`: Add restricted sites filtration to flow-based CatFIM processing.
14+
15+
### Removals
16+
- `tools/catfim/stage_based_ahps_restricted_sites.csv`: Renamed to `ahps_restricted_sites.csv`
17+
18+
<br/><br/>
19+
420
## v4.5.14.2 - 2025-01-24 - [PR#1178](https://github.com/NOAA-OWP/inundation-mapping/pull/1178)
521

622
### Summary
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
nws_lid,restricted_reason,catfim_type
2+
# RULES: Ensure that the top line has no comments above the header line above:
3+
# -- Careful not to add commas other then the one after the lid ID.
4+
# -- Don't allow for any duplicate LID values in this list please.
5+
#
6+
# Comment lines can be added as any independent line in this csv.
7+
#
8+
AABDB,Test Site,stage
9+
ADLG1,Stage thresholds seem to be based on sea level and not channel thalweg,stage
10+
AUGG1,Stage thresholds seem to be based on sea level and not channel thalweg,stage
11+
BAXG1,Stage thresholds seem to be based on sea level and not channel thalweg,stage
12+
BRKTS,Test Site,stage
13+
CNNN6,Pool elevation thresholds. Disabled at request of MARFC,stage
14+
DMBT2,Test Site,stage
15+
DMSF1,Tidal Gauge,stage
16+
DVNIA,Test Site,both
17+
GVDA1,bad data in API,stage
18+
HFMW4,gage relocated. check again later for review,stage
19+
HLZU1,bad data in API,stage
20+
HNXCA,Test Site,stage
21+
HRAG1,Stage thresholds seem to be based on sea level and not channel thalweg,stage
22+
HUSKR,Test Site,stage
23+
HZT00,Test Site,stage
24+
HZT02,Test Site,stage
25+
ILMNA,Test Site,stage
26+
JTEST,Test Site,stage
27+
JYNT2,Test Site,stage
28+
KLNQ9,Outside U.S.,both
29+
LAMF1,Stage thresholds seem to be based on sea level and not channel thalweg.,stage
30+
MCVA3,historical gauge,both
31+
NVRN6,Pool elevation thresholds. Disabled at request of MARFC.,stage
32+
PEPN6,Pool elevation thresholds. Disabled at request of MARFC.,stage
33+
PRXQ9,Outside U.S.,both
34+
ONDN6,Inundation issues,stage
35+
QUTG1,Stage thresholds seem to be based on sea level and not channel thalweg,stage
36+
RCYF1,Out of Service,both
37+
RWBW3, historical gauge,stage
38+
SMSV2,point not in AHPS,both
39+
STNG1,Stage thresholds seem to be based on sea level and not channel thalweg,stage
40+
TESM8,Test Site,stage
41+
TEST,Test Site,stage
42+
TEST1,Test Site,stage
43+
TEST11,Test Site,stage
44+
TEST2,Test Site,stage
45+
TEST3,Test Site,stage
46+
TEST4,Test Site,stage
47+
TEST9,Test Site,stage
48+
TESTA,Test Site,stage
49+
TESTB,Test Site,stage
50+
TESTC,Test Site,stage
51+
TESTPT1,Test Site,stage
52+
TETM8,Test Site,stage
53+
TS2W3,Test Site,stage
54+
TS3W3,Test Site,stage
55+
TS4W3,Test Site,stage
56+
TSTMO,Test Site,stage
57+
TSTN6,Test Site,stage
58+
TSTSP,Test Site,stage
59+
TSTUP,Test Site,stage
60+
TTARX,Test Site,both
61+
VEFNV,Test Site,both
62+
WBYA1,Out of Service,both
63+
WLSA1, bad data in API,stage
64+
WUNTS, not a real gauge,both
65+
XXXN3,Test Site,stage
66+
YDAQ9,Outside U.S.,both
67+
YLKA2,Discontinued Gage,stage
68+
YWRQ9,Outside U.S.,both
69+
ZZZT2,Test Site,stage
70+
CMUG1,Out of Service,both

tools/catfim/generate_categorical_fim.py

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -247,13 +247,13 @@ def process_generate_categorical_fim(
247247
# STAGE-BASED
248248
if is_stage_based:
249249
# Generate Stage-Based CatFIM mapping
250-
# does flows and inundation (mapping)
250+
# does flows and inundation (mapping)
251251

252252
catfim_sites_file_path = os.path.join(output_mapping_dir, 'stage_based_catfim_sites.gpkg')
253253

254254
if step_num <= 1:
255255

256-
df_restricted_sites = load_restricted_sites()
256+
df_restricted_sites = load_restricted_sites(is_stage_based)
257257

258258
generate_stage_based_categorical_fim(
259259
output_catfim_dir,
@@ -300,6 +300,9 @@ def process_generate_categorical_fim(
300300
job_flows = job_number_huc * job_number_inundate
301301

302302
if step_num <= 1:
303+
304+
df_restricted_sites = load_restricted_sites(is_stage_based)
305+
303306
generate_flows(
304307
output_catfim_dir,
305308
nwm_us_search,
@@ -310,6 +313,7 @@ def process_generate_categorical_fim(
310313
valid_ahps_hucs,
311314
nwm_metafile,
312315
FLOG.LOG_FILE_PATH,
316+
df_restricted_sites,
313317
)
314318
end = time.time()
315319
elapsed_time = (end - start) / 60
@@ -1167,23 +1171,31 @@ def __calc_stage_intervals(non_rec_stage_values_df, past_major_interval_cap, huc
11671171
return interval_recs
11681172

11691173

1170-
def load_restricted_sites():
1174+
def load_restricted_sites(is_stage_based):
11711175
"""
1172-
At this point, only stage based uses this. But a arg of "catfim_type (stage or flow) or something
1173-
can be added later.
1176+
Previously, only stage based used this. It is now being used by stage-based and flow-based (1/24/25)
1177+
1178+
The 'catfim_type' column can have three different values: 'stage', 'flow', and 'both'. This determines
1179+
whether the site should be filtered out for stage-based CatFIM, flow-based CatFIM, or both of them.
11741180
11751181
Returns: a dataframe for the restricted lid and the reason why:
1176-
"nws_lid", "restricted_reason"
1182+
'nws_lid', 'restricted_reason', 'catfim_type'
11771183
"""
11781184

1179-
file_name = "stage_based_ahps_restricted_sites.csv"
1185+
file_name = "ahps_restricted_sites.csv"
11801186
current_script_folder = os.path.dirname(__file__)
11811187
file_path = os.path.join(current_script_folder, file_name)
11821188

11831189
df_restricted_sites = pd.read_csv(file_path, dtype=str)
11841190

11851191
df_restricted_sites['nws_lid'].fillna("", inplace=True)
11861192
df_restricted_sites['restricted_reason'].fillna("", inplace=True)
1193+
df_restricted_sites['catfim_type'].fillna("", inplace=True)
1194+
1195+
# remove extra empty spaces on either side of all cellls
1196+
df_restricted_sites['nws_lid'] = df_restricted_sites['nws_lid'].str.strip()
1197+
df_restricted_sites['restricted_reason'] = df_restricted_sites['restricted_reason'].str.strip()
1198+
df_restricted_sites['catfim_type'] = df_restricted_sites['catfim_type'].str.strip()
11871199

11881200
# Need to drop the comment lines before doing any more processing
11891201
df_restricted_sites.drop(
@@ -1195,11 +1207,13 @@ def load_restricted_sites():
11951207
# There are enough conditions and a low number of rows that it is easier to
11961208
# test / change them via a for loop
11971209
indexs_for_recs_to_be_removed_from_list = []
1210+
1211+
# Clean up dataframe
11981212
for ind, row in df_restricted_sites.iterrows():
11991213
nws_lid = row['nws_lid']
12001214
restricted_reason = row['restricted_reason']
12011215

1202-
if len(nws_lid) != 5: # could be just a blank row in the
1216+
if len(nws_lid) != 5: # Invalid row, could be just a blank row in the file
12031217
FLOG.warning(
12041218
f"From the ahps_restricted_sites list, an invalid nws_lid value of '{nws_lid}'"
12051219
" and has dropped from processing"
@@ -1213,14 +1227,22 @@ def load_restricted_sites():
12131227
df_restricted_sites.at[ind, 'restricted_reason'] = restricted_reason
12141228
FLOG.warning(f"{restricted_reason}. Lid is '{nws_lid}'")
12151229
continue
1216-
# end for
1230+
# end loop
12171231

1218-
# Invalid records (not dropping, just completely invalid recs from the csv)
1232+
# Invalid records in CSV (not dropping, just completely invalid recs from the csv)
12191233
# Could be just blank rows from the csv
12201234
if len(indexs_for_recs_to_be_removed_from_list) > 0:
12211235
df_restricted_sites = df_restricted_sites.drop(indexs_for_recs_to_be_removed_from_list).reset_index()
12221236

1223-
# print(df_restricted_sites.head(10))
1237+
# Filter df_restricted_sites by CatFIM type
1238+
if is_stage_based == True: # Keep rows where 'catfim_type' is either 'stage' or 'both'
1239+
df_restricted_sites = df_restricted_sites[df_restricted_sites['catfim_type'].isin(['stage', 'both'])]
1240+
1241+
else: # Keep rows where 'catfim_type' is either 'flow' or 'both'
1242+
df_restricted_sites = df_restricted_sites[df_restricted_sites['catfim_type'].isin(['flow', 'both'])]
1243+
1244+
# Remove catfim_type column
1245+
df_restricted_sites.drop('catfim_type', axis=1, inplace=True)
12241246

12251247
return df_restricted_sites
12261248

@@ -1526,6 +1548,7 @@ def generate_stage_based_categorical_fim(
15261548
lst_hucs,
15271549
nwm_metafile,
15281550
str(FLOG.LOG_FILE_PATH),
1551+
df_restricted_sites,
15291552
)
15301553
)
15311554

tools/catfim/generate_categorical_fim_flows.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ def generate_flows_for_huc(
6666
nwm_flows_df,
6767
parent_log_output_file,
6868
child_log_file_prefix,
69+
df_restricted_sites,
6970
):
7071

7172
try:
@@ -127,6 +128,17 @@ def generate_flows_for_huc(
127128
# Convert lid to lower case
128129
lid = lid.lower()
129130

131+
# Check whether LID is in the restricted sites list
132+
found_restrict_lid = df_restricted_sites.loc[df_restricted_sites['nws_lid'] == lid.upper()]
133+
134+
# Assume only one rec for now, fix later
135+
if len(found_restrict_lid) > 0:
136+
reason = found_restrict_lid.iloc[0, found_restrict_lid.columns.get_loc("restricted_reason")]
137+
msg = ':' + reason
138+
all_messages.append(lid + msg)
139+
MP_LOG.warning(huc_lid_id + msg)
140+
continue
141+
130142
# TODO: Jun 17, 2024 - This gets recalled for every huc but only uses the nws_list.
131143
# Move this somewhere outside the huc list so it doesn't need to be called over and over again
132144

@@ -363,6 +375,7 @@ def generate_flows(
363375
lst_hucs,
364376
nwm_metafile,
365377
log_output_file,
378+
df_restricted_sites,
366379
):
367380

368381
# TODO; Most docstrings like this are now very outdated and need updating
@@ -509,6 +522,7 @@ def generate_flows(
509522
nwm_flows_region_df,
510523
log_output_file,
511524
child_log_file_prefix,
525+
df_restricted_sites,
512526
)
513527
# end ProcessPoolExecutor
514528

tools/catfim/stage_based_ahps_restricted_sites.csv

Lines changed: 0 additions & 69 deletions
This file was deleted.

0 commit comments

Comments
 (0)