py-ewr 2.3.6__py3-none-any.whl → 2.3.8__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.
- py_ewr/data_inputs.py +199 -98
- py_ewr/evaluate_EWRs.py +529 -1149
- py_ewr/model_metadata/EWR_Sitelist_FIRM_20250718.csv +255 -0
- py_ewr/model_metadata/SiteID_MDBA.csv +1 -1
- py_ewr/observed_handling.py +13 -13
- py_ewr/parameter_metadata/ewr_calc_config.json +3 -3
- py_ewr/parameter_metadata/objective_reference_NB_SA_WIM_NE_LACH_BIDG_MLD_ACT.csv +806 -0
- py_ewr/parameter_metadata/parameter_sheet.csv +3443 -3445
- py_ewr/parameter_metadata/parameter_sheet_NB_SA_WIM_NE_LACH_BIDG_MLD_ACT.csv +3127 -0
- py_ewr/parameter_metadata/parameter_sheet_NB_SA_WIM_NE_LACH_BIDG_MLD_ACT_added_act_env.csv +3188 -0
- py_ewr/scenario_handling.py +166 -42
- py_ewr/summarise_results.py +75 -87
- {py_ewr-2.3.6.dist-info → py_ewr-2.3.8.dist-info}/METADATA +90 -55
- py_ewr-2.3.8.dist-info/RECORD +21 -0
- {py_ewr-2.3.6.dist-info → py_ewr-2.3.8.dist-info}/WHEEL +1 -1
- py_ewr/parameter_metadata/ewr2obj.csv +0 -43331
- py_ewr/parameter_metadata/obj2target.csv +0 -7941
- py_ewr/parameter_metadata/obj2yrtarget.csv +0 -106
- py_ewr-2.3.6.dist-info/RECORD +0 -20
- {py_ewr-2.3.6.dist-info → py_ewr-2.3.8.dist-info/licenses}/LICENSE +0 -0
- {py_ewr-2.3.6.dist-info → py_ewr-2.3.8.dist-info}/top_level.txt +0 -0
py_ewr/evaluate_EWRs.py
CHANGED
|
@@ -20,228 +20,59 @@ warnings.simplefilter(action='ignore', category=pd.errors.PerformanceWarning)
|
|
|
20
20
|
|
|
21
21
|
#----------------------------------- Getting EWRs from the database ------------------------------#
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
'''Pass EWR details (planning unit, gauge, EWR, and EWR component) and the EWR table,
|
|
23
|
+
def component_pull(EWR_table: pd.DataFrame, gauge: str, pu: str, ewr: str, component: str, pu_ID: bool = True) -> str:
|
|
24
|
+
'''Pass ewr details (planning unit, gauge, ewr, and ewr component) and the ewr table,
|
|
26
25
|
this function will then pull the component from the table.
|
|
27
26
|
|
|
28
27
|
Args:
|
|
29
28
|
EWR_table (pd.DataFrame): Dataframe of EWRs
|
|
30
29
|
gauge (str): Gauge number
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
component (str):
|
|
30
|
+
pu (str): Planning Unit ID
|
|
31
|
+
ewr (str): ewr code
|
|
32
|
+
component (str): ewr parameter (data from which column in the ewr table)
|
|
34
33
|
|
|
35
34
|
Results:
|
|
36
|
-
str: value of requested parameter from the
|
|
35
|
+
str: value of requested parameter from the ewr table
|
|
37
36
|
|
|
38
37
|
'''
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
38
|
+
if pu_ID:
|
|
39
|
+
pu_idx = EWR_table['PlanningUnitID'] == pu
|
|
40
|
+
else:
|
|
41
|
+
pu_idx = EWR_table['PlanningUnitName'] == pu
|
|
42
|
+
|
|
43
|
+
gauge_idx = EWR_table['Gauge'] == gauge
|
|
44
|
+
ewr_idx = EWR_table['Code'] == ewr
|
|
44
45
|
|
|
45
|
-
|
|
46
|
-
|
|
46
|
+
value = EWR_table[(gauge_idx & ewr_idx & pu_idx)].loc[:, component].values[0]
|
|
47
|
+
return value
|
|
47
48
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
gauge (float): gauge number
|
|
51
|
-
ewr (str): ewr code
|
|
52
|
-
pu (str): planning unit code
|
|
53
|
-
|
|
54
|
-
Returns:
|
|
55
|
-
bool: second gauge code
|
|
56
|
-
"""
|
|
57
|
-
item = parameter_sheet[(parameter_sheet['Gauge']==gauge) & (parameter_sheet['Code']==ewr) & (parameter_sheet['PlanningUnitID']==pu)]
|
|
58
|
-
gauge_array = item['Multigauge'].to_list()
|
|
59
|
-
gauge_number = gauge_array[0] if gauge_array else ''
|
|
60
|
-
return gauge_number
|
|
61
|
-
|
|
62
|
-
def get_EWRs(PU: str, gauge: str, EWR: str, EWR_table: pd.DataFrame, components: list) -> dict:
|
|
63
|
-
'''Pulls the relevant EWR componenets for each EWR
|
|
49
|
+
def get_EWRs(pu: str, gauge: str, ewr: str, EWR_table: pd.DataFrame, components: list) -> dict:
|
|
50
|
+
'''Pulls the relevant ewr componenets for each ewr
|
|
64
51
|
|
|
65
52
|
Args:
|
|
66
|
-
|
|
53
|
+
pu (str): Planning unit ID
|
|
67
54
|
gauge (str): Gauge ID
|
|
68
|
-
|
|
69
|
-
EWR_table (pd.DataFrame):
|
|
70
|
-
components (list): List of parameters needing to be pulled from the
|
|
71
|
-
|
|
55
|
+
ewr (str): ewr code
|
|
56
|
+
EWR_table (pd.DataFrame): ewr dataset
|
|
57
|
+
components (list): List of parameters needing to be pulled from the ewr dataset
|
|
58
|
+
|
|
72
59
|
Results:
|
|
73
|
-
dict: The
|
|
74
|
-
|
|
60
|
+
dict: The ewr components and their values
|
|
61
|
+
|
|
75
62
|
'''
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
ewrs['start_month'] = int(start_date.split('.')[0])
|
|
87
|
-
else:
|
|
88
|
-
ewrs['start_day'] = None
|
|
89
|
-
ewrs['start_month'] = int(start_date)
|
|
90
|
-
if 'EM' in components:
|
|
91
|
-
end_date = str(component_pull(EWR_table, gauge, PU, EWR, 'EndMonth'))
|
|
92
|
-
if '.' in end_date:
|
|
93
|
-
ewrs['end_day'] = int(end_date.split('.')[1])
|
|
94
|
-
ewrs['end_month'] = int(end_date.split('.')[0])
|
|
95
|
-
else:
|
|
96
|
-
ewrs['end_day'] = None
|
|
97
|
-
ewrs['end_month'] =int(end_date)
|
|
98
|
-
if 'MINF' in components:
|
|
99
|
-
min_flow = int(component_pull(EWR_table, gauge, PU, EWR, 'FlowThresholdMin'))
|
|
100
|
-
ewrs['min_flow'] = int(min_flow)
|
|
101
|
-
if 'MAXF' in components:
|
|
102
|
-
max_flow = int(component_pull(EWR_table, gauge, PU, EWR, 'FlowThresholdMax'))
|
|
103
|
-
ewrs['max_flow'] = int(max_flow)
|
|
104
|
-
if 'MINL' in components:
|
|
105
|
-
min_level = float(component_pull(EWR_table, gauge, PU, EWR, 'LevelThresholdMin'))
|
|
106
|
-
ewrs['min_level'] = min_level
|
|
107
|
-
if 'MAXL' in components:
|
|
108
|
-
max_level = float(component_pull(EWR_table, gauge, PU, EWR, 'LevelThresholdMax'))
|
|
109
|
-
ewrs['max_level'] = max_level
|
|
110
|
-
if 'MINV' in components:
|
|
111
|
-
min_volume = int(component_pull(EWR_table, gauge, PU, EWR, 'VolumeThreshold'))
|
|
112
|
-
ewrs['min_volume'] = int(min_volume)
|
|
113
|
-
if 'DUR' in components:
|
|
114
|
-
duration = int(component_pull(EWR_table, gauge, PU, EWR, 'Duration'))
|
|
115
|
-
ewrs['duration'] = int(duration)
|
|
116
|
-
if 'GP' in components:
|
|
117
|
-
gap_tolerance = int(component_pull(EWR_table, gauge, PU, EWR, 'WithinEventGapTolerance'))
|
|
118
|
-
ewrs['gap_tolerance'] = gap_tolerance
|
|
119
|
-
if 'EPY' in components:
|
|
120
|
-
events_per_year = int(component_pull(EWR_table, gauge, PU, EWR, 'EventsPerYear'))
|
|
121
|
-
ewrs['events_per_year'] = events_per_year
|
|
122
|
-
if 'ME' in components:
|
|
123
|
-
min_event = int(component_pull(EWR_table, gauge, PU, EWR, 'MinSpell'))
|
|
124
|
-
ewrs['min_event'] = int(min_event)
|
|
125
|
-
if 'MD' in components:
|
|
126
|
-
max_drawdown = component_pull(EWR_table, gauge, PU, EWR, 'DrawdownRate')
|
|
127
|
-
if '%' in str(max_drawdown):
|
|
128
|
-
value_only = int(max_drawdown.replace('%', ''))
|
|
129
|
-
ewrs['drawdown_rate'] = str(int(value_only))+'%'
|
|
130
|
-
else:
|
|
131
|
-
ewrs['drawdown_rate'] = str(float(max_drawdown)) #TODO check this works
|
|
132
|
-
if max_drawdown == 0:
|
|
133
|
-
# Large value set to ensure that drawdown check is always passed in this case
|
|
134
|
-
ewrs['drawdown_rate'] = int(1000000)
|
|
135
|
-
if 'WPG' in components:
|
|
136
|
-
weirpool_gauge = component_pull(EWR_table, gauge, PU, EWR, 'WeirpoolGauge')
|
|
137
|
-
ewrs['weirpool_gauge'] =str(weirpool_gauge)
|
|
138
|
-
if 'MG' in components:
|
|
139
|
-
ewrs['second_gauge'] = get_second_multigauge(EWR_table, gauge, EWR, PU)
|
|
140
|
-
if 'TF' in components:
|
|
141
|
-
try:
|
|
142
|
-
ewrs['frequency'] = component_pull(EWR_table, gauge, PU, EWR, 'TargetFrequency')
|
|
143
|
-
except IndexError:
|
|
144
|
-
ewrs['frequency'] = None
|
|
145
|
-
if 'MIE' in components:
|
|
146
|
-
try:
|
|
147
|
-
ewrs['max_inter-event'] = float(component_pull(EWR_table, gauge, PU, EWR, 'MaxInter-event'))
|
|
148
|
-
except IndexError:
|
|
149
|
-
ewrs['max_inter-event'] = None
|
|
150
|
-
if 'AP' in components:
|
|
151
|
-
accumulation_period = component_pull(EWR_table, gauge, PU, EWR, 'AccumulationPeriod')
|
|
152
|
-
ewrs['accumulation_period'] = int(accumulation_period)
|
|
153
|
-
if 'FLV' in components:
|
|
154
|
-
flow_level_volume = component_pull(EWR_table, gauge, PU, EWR, 'FlowLevelVolume')
|
|
155
|
-
ewrs['flow_level_volume'] = flow_level_volume
|
|
156
|
-
if 'MAXD' in components:
|
|
157
|
-
max_duration = component_pull(EWR_table, gauge, PU, EWR, 'MaxSpell')
|
|
158
|
-
ewrs['max_duration'] = int(max_duration) if max_duration else 1_000_000
|
|
159
|
-
if 'TD' in components:
|
|
160
|
-
trigger_day = component_pull(EWR_table, gauge, PU, EWR, 'TriggerDay')
|
|
161
|
-
ewrs['trigger_day'] = int(trigger_day)
|
|
162
|
-
if 'TM' in components:
|
|
163
|
-
trigger_month = component_pull(EWR_table, gauge, PU, EWR, 'TriggerMonth')
|
|
164
|
-
ewrs['trigger_month'] = int(trigger_month)
|
|
165
|
-
if 'WDD' in components:
|
|
166
|
-
try: # The rate is represented in cm
|
|
167
|
-
drawdown_rate_week = component_pull(EWR_table, gauge, PU, EWR, 'DrawDownRateWeek')
|
|
168
|
-
ewrs['drawdown_rate_week'] = str(float(drawdown_rate_week)/100)#TODO check this works
|
|
169
|
-
except ValueError: # In this case set a large number
|
|
170
|
-
ewrs['drawdown_rate_week'] = int(1000000)
|
|
171
|
-
if 'ML' in components:
|
|
172
|
-
max_level = component_pull(EWR_table, gauge, PU, EWR, 'MaxLevelRise')
|
|
173
|
-
ewrs['max_level_raise'] = float(max_level)
|
|
174
|
-
if 'ABF' in components:
|
|
175
|
-
annual_barrage_flow = component_pull(EWR_table, gauge, PU, EWR, 'AnnualBarrageFlow')
|
|
176
|
-
ewrs['annual_barrage_flow'] = int(annual_barrage_flow)
|
|
177
|
-
if 'TYBF' in components:
|
|
178
|
-
three_years_barrage_flow = component_pull(EWR_table, gauge, PU, EWR, 'ThreeYearsBarrageFlow')
|
|
179
|
-
ewrs['three_years_barrage_flow'] = int(three_years_barrage_flow)
|
|
180
|
-
if 'HRWS' in components:
|
|
181
|
-
high_release_window_start = component_pull(EWR_table, gauge, PU, EWR, 'HighReleaseWindowStart')
|
|
182
|
-
ewrs['high_release_window_start'] = int(high_release_window_start)
|
|
183
|
-
if 'HRWE' in components:
|
|
184
|
-
high_release_window_end = component_pull(EWR_table, gauge, PU, EWR, 'HighReleaseWindowEnd')
|
|
185
|
-
ewrs['high_release_window_end'] = int(high_release_window_end)
|
|
186
|
-
if 'LRWS' in components:
|
|
187
|
-
low_release_window_start = component_pull(EWR_table, gauge, PU, EWR, 'LowReleaseWindowStart')
|
|
188
|
-
ewrs['low_release_window_start'] = int(low_release_window_start)
|
|
189
|
-
if 'LRWE' in components:
|
|
190
|
-
low_release_window_end = component_pull(EWR_table, gauge, PU, EWR, 'LowReleaseWindowEnd')
|
|
191
|
-
ewrs['low_release_window_end'] = int(low_release_window_end)
|
|
192
|
-
if 'PLWS' in components:
|
|
193
|
-
peak_level_window_start = component_pull(EWR_table, gauge, PU, EWR, 'PeakLevelWindowStart')
|
|
194
|
-
ewrs['peak_level_window_start'] = int(peak_level_window_start)
|
|
195
|
-
if 'PLWE' in components:
|
|
196
|
-
peak_level_window_end = component_pull(EWR_table, gauge, PU, EWR, 'PeakLevelWindowEnd')
|
|
197
|
-
ewrs['peak_level_window_end'] = int(peak_level_window_end)
|
|
198
|
-
if 'LLWS' in components:
|
|
199
|
-
low_level_window_start = component_pull(EWR_table, gauge, PU, EWR, 'LowLevelWindowStart')
|
|
200
|
-
ewrs['low_level_window_start'] = int(low_level_window_start)
|
|
201
|
-
if 'LLWE' in components:
|
|
202
|
-
low_level_window_end = component_pull(EWR_table, gauge, PU, EWR, 'LowLevelWindowEnd')
|
|
203
|
-
ewrs['low_level_window_end'] = int(low_level_window_end)
|
|
204
|
-
if 'NFS' in components:
|
|
205
|
-
non_flow_spell = component_pull(EWR_table, gauge, PU, EWR, 'NonFlowSpell')
|
|
206
|
-
ewrs['non_flow_spell'] = int(non_flow_spell)
|
|
207
|
-
if 'EDS' in components:
|
|
208
|
-
non_flow_spell = component_pull(EWR_table, gauge, PU, EWR, 'EggsDaysSpell')
|
|
209
|
-
ewrs['eggs_days_spell'] = int(non_flow_spell)
|
|
210
|
-
if 'LDS' in components:
|
|
211
|
-
non_flow_spell = component_pull(EWR_table, gauge, PU, EWR, 'LarvaeDaysSpell')
|
|
212
|
-
ewrs['larvae_days_spell'] = int(non_flow_spell)
|
|
213
|
-
if 'MLR' in components:
|
|
214
|
-
min_level_rise = component_pull(EWR_table, gauge, PU, EWR, 'MinLevelRise')
|
|
215
|
-
ewrs['min_level_rise'] = float(min_level_rise)
|
|
216
|
-
if 'RRM1' in components:
|
|
217
|
-
rate_of_rise_max1 = component_pull(EWR_table, gauge, PU, EWR, 'RateOfRiseMax1')
|
|
218
|
-
ewrs['rate_of_rise_max1'] = float(rate_of_rise_max1)
|
|
219
|
-
if 'RRM2' in components:
|
|
220
|
-
rate_of_rise_max1 = component_pull(EWR_table, gauge, PU, EWR, 'RateOfRiseMax2')
|
|
221
|
-
ewrs['rate_of_rise_max2'] = float(rate_of_rise_max1)
|
|
222
|
-
if 'RFM' in components:
|
|
223
|
-
rate_of_fall_min = component_pull(EWR_table, gauge, PU, EWR, 'RateOfFallMin')
|
|
224
|
-
ewrs['rate_of_fall_min'] = float(rate_of_fall_min)
|
|
225
|
-
if 'RRT1' in components:
|
|
226
|
-
rate_of_rise_threshold1 = component_pull(EWR_table, gauge, PU, EWR, 'RateOfRiseThreshold1')
|
|
227
|
-
ewrs['rate_of_rise_threshold1'] = float(rate_of_rise_threshold1)
|
|
228
|
-
if 'RRT2' in components:
|
|
229
|
-
rate_of_rise_threshold2 = component_pull(EWR_table, gauge, PU, EWR, 'RateOfRiseThreshold2')
|
|
230
|
-
ewrs['rate_of_rise_threshold2'] = float(rate_of_rise_threshold2)
|
|
231
|
-
if 'RRL' in components:
|
|
232
|
-
rate_of_rise_river_level = component_pull(EWR_table, gauge, PU, EWR, 'RateOfRiseRiverLevel')
|
|
233
|
-
ewrs['rate_of_rise_river_level'] = float(rate_of_rise_river_level)
|
|
234
|
-
if 'RFL' in components:
|
|
235
|
-
rate_of_fall_river_level = component_pull(EWR_table, gauge, PU, EWR, 'RateOfFallRiverLevel')
|
|
236
|
-
ewrs['rate_of_fall_river_level'] = float(rate_of_fall_river_level)
|
|
237
|
-
if 'CTFT' in components:
|
|
238
|
-
ctf_threshold = component_pull(EWR_table, gauge, PU, EWR, 'CtfThreshold')
|
|
239
|
-
ewrs['ctf_threshold'] = float(ctf_threshold)
|
|
240
|
-
|
|
241
|
-
return ewrs
|
|
63
|
+
|
|
64
|
+
components_map = data_inputs.get_components_map()
|
|
65
|
+
|
|
66
|
+
col_idx = ['PlanningUnitID'] + ['Gauge'] + ['Code'] + components
|
|
67
|
+
row_idx = (EWR_table['PlanningUnitID'] == pu) & (EWR_table['Gauge'] == gauge) & (EWR_table['Code'] == ewr)
|
|
68
|
+
|
|
69
|
+
ewr_dict = EWR_table.loc[row_idx, col_idx].to_dict(orient='records')[0] # convert the required part of the ewr table to a dictionary
|
|
70
|
+
ewr_dict = {components_map[key]: ewr_dict[key] for key in ewr_dict.keys()} # Rename dictionary to names required for the function calls
|
|
71
|
+
|
|
72
|
+
return ewr_dict
|
|
242
73
|
|
|
243
74
|
def is_multigauge(parameter_sheet: pd.DataFrame, gauge:float, ewr:str, pu:str) -> bool:
|
|
244
|
-
"""check in the parameter sheet if currently iterated
|
|
75
|
+
"""check in the parameter sheet if currently iterated ewr is a multigauge
|
|
245
76
|
|
|
246
77
|
Args:
|
|
247
78
|
parameter_sheet (pd.DataFrame): parameter sheet used in the calculation
|
|
@@ -253,15 +84,14 @@ def is_multigauge(parameter_sheet: pd.DataFrame, gauge:float, ewr:str, pu:str) -
|
|
|
253
84
|
bool: returns True if it is a multigauge and False if not
|
|
254
85
|
"""
|
|
255
86
|
item = parameter_sheet[(parameter_sheet['Gauge']==gauge) & (parameter_sheet['Code']==ewr) & (parameter_sheet['PlanningUnitID']==pu)]
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
return
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
return int(mg[0]) > 0
|
|
87
|
+
try:
|
|
88
|
+
mg = item['Multigauge'].values[0]
|
|
89
|
+
return bool(mg)
|
|
90
|
+
except IndexError:
|
|
91
|
+
raise IndexError(f"ewr: gauge={gauge}, code={ewr}, pu={pu} is not in the parameter sheet")
|
|
262
92
|
|
|
263
93
|
def is_weirpool_gauge(parameter_sheet: pd.DataFrame, gauge:float, ewr:str, pu:str) -> bool:
|
|
264
|
-
"""check in the parameter sheet if currently iterated
|
|
94
|
+
"""check in the parameter sheet if currently iterated ewr is a weirpool gauge
|
|
265
95
|
|
|
266
96
|
Args:
|
|
267
97
|
parameter_sheet (pd.DataFrame): parameter sheet used in the calculation
|
|
@@ -273,13 +103,11 @@ def is_weirpool_gauge(parameter_sheet: pd.DataFrame, gauge:float, ewr:str, pu:st
|
|
|
273
103
|
bool: returns True if it is a weirpool gauge and False if not
|
|
274
104
|
"""
|
|
275
105
|
item = parameter_sheet[(parameter_sheet['Gauge']==gauge) & (parameter_sheet['Code']==ewr) & (parameter_sheet['PlanningUnitID']==pu)]
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
return
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
else:
|
|
282
|
-
return True
|
|
106
|
+
try:
|
|
107
|
+
wp = item['WeirpoolGauge'].values[0]
|
|
108
|
+
return bool(wp)
|
|
109
|
+
except IndexError:
|
|
110
|
+
raise IndexError(f"ewr: gauge={gauge}, code={ewr}, pu={pu} is not in the parameter sheet")
|
|
283
111
|
|
|
284
112
|
def calculate_n_day_moving_average(df: pd.DataFrame, days: int) -> pd.DataFrame:
|
|
285
113
|
'''Calculates the n day moving average for a given gauges
|
|
@@ -307,13 +135,13 @@ def calculate_n_day_moving_average(df: pd.DataFrame, days: int) -> pd.DataFrame:
|
|
|
307
135
|
|
|
308
136
|
return result_df
|
|
309
137
|
|
|
310
|
-
#------------------------ Masking timeseries data to dates in
|
|
138
|
+
#------------------------ Masking timeseries data to dates in ewr requirement --------------------#
|
|
311
139
|
|
|
312
140
|
def mask_dates(EWR_info: dict, input_df: pd.DataFrame) -> set:
|
|
313
141
|
'''Distributes flow/level dataframe to functions for masking over dates
|
|
314
142
|
|
|
315
143
|
Args:
|
|
316
|
-
EWR_info (dict): The
|
|
144
|
+
EWR_info (dict): The ewr components and their values
|
|
317
145
|
input_df (pd.DataFrame): Flow/water level dataframe
|
|
318
146
|
|
|
319
147
|
Results:
|
|
@@ -350,7 +178,7 @@ def get_month_mask(start: int, end: int, input_df: pd.DataFrame) -> set:
|
|
|
350
178
|
|
|
351
179
|
if start > end:
|
|
352
180
|
month_mask = (input_df.index.month >= start) | (input_df.index.month <= end)
|
|
353
|
-
|
|
181
|
+
else:
|
|
354
182
|
month_mask = (input_df.index.month >= start) & (input_df.index.month <= end)
|
|
355
183
|
|
|
356
184
|
input_df_timeslice = input_df.loc[month_mask]
|
|
@@ -405,7 +233,7 @@ def wateryear_daily(input_df: pd.DataFrame, ewrs: dict) -> np.array:
|
|
|
405
233
|
|
|
406
234
|
Args:
|
|
407
235
|
input_df (pd.DataFrame): Flow/water level dataframe
|
|
408
|
-
ewrs (dict): The
|
|
236
|
+
ewrs (dict): The ewr components and their values
|
|
409
237
|
|
|
410
238
|
Results:
|
|
411
239
|
np.array: array containing the daily assignment of water year
|
|
@@ -460,391 +288,361 @@ def get_index_date(date_index:Any)-> datetime.date:
|
|
|
460
288
|
return date_index
|
|
461
289
|
# return date_index #TODO: should this break? i.e. we arent expecting other date formats
|
|
462
290
|
|
|
463
|
-
#-----------------------------------
|
|
291
|
+
#----------------------------------- ewr handling functions --------------------------------------#
|
|
464
292
|
|
|
465
|
-
def ctf_handle(
|
|
293
|
+
def ctf_handle(pu: str, gauge: str, ewr: str, EWR_table: pd.DataFrame, df_F: pd.DataFrame, PU_df: pd.DataFrame) -> tuple:
|
|
466
294
|
'''For handling Cease to flow type EWRs
|
|
467
295
|
|
|
468
296
|
Args:
|
|
469
|
-
|
|
297
|
+
pu (str): Planning unit ID
|
|
470
298
|
gauge (str): Gauge number
|
|
471
|
-
|
|
472
|
-
EWR_table (pd.DataFrame):
|
|
299
|
+
ewr (str): ewr code
|
|
300
|
+
EWR_table (pd.DataFrame): ewr dataset
|
|
473
301
|
df_F (pd.DataFrame): Daily flow data
|
|
474
|
-
PU_df (pd.DataFrame):
|
|
302
|
+
PU_df (pd.DataFrame): ewr results for the current planning unit iteration
|
|
475
303
|
|
|
476
304
|
Results:
|
|
477
|
-
tuple[pd.DataFrame, tuple[dict]]:
|
|
305
|
+
tuple[pd.DataFrame, tuple[dict]]: ewr results for the current planning unit iteration (updated); dictionary of ewr event information
|
|
478
306
|
|
|
479
307
|
'''
|
|
480
|
-
# Get information about
|
|
308
|
+
# Get information about ewr:
|
|
481
309
|
pull = data_inputs.get_EWR_components('cease to flow')
|
|
482
|
-
EWR_info = get_EWRs(
|
|
310
|
+
EWR_info = get_EWRs(pu, gauge, ewr, EWR_table, pull)
|
|
483
311
|
# Mask dates
|
|
484
312
|
masked_dates = mask_dates(EWR_info, df_F)
|
|
485
313
|
# Extract a daily timeseries for water years
|
|
486
314
|
water_years = wateryear_daily(df_F, EWR_info)
|
|
487
|
-
# Check flow data against
|
|
315
|
+
# Check flow data against ewr requirements and then perform analysis on the results:
|
|
488
316
|
if ((EWR_info['start_month'] == 7) and (EWR_info['end_month'] == 6)):
|
|
489
317
|
E, D = ctf_calc_anytime(EWR_info, df_F[gauge].values, water_years, df_F.index)
|
|
490
318
|
else:
|
|
491
319
|
E, D = ctf_calc(EWR_info, df_F[gauge].values, water_years, df_F.index, masked_dates)
|
|
492
|
-
PU_df = event_stats(df_F, PU_df, gauge,
|
|
320
|
+
PU_df = event_stats(df_F, PU_df, gauge, ewr, EWR_info, E, D, water_years)
|
|
493
321
|
return PU_df, tuple([E])
|
|
494
322
|
|
|
495
|
-
def lowflow_handle(
|
|
323
|
+
def lowflow_handle(pu: str, gauge: str, ewr: str, EWR_table: pd.DataFrame, df_F: pd.DataFrame, PU_df: pd.DataFrame) -> tuple:
|
|
496
324
|
'''For handling low flow type EWRs (Very low flows and baseflows)
|
|
497
325
|
|
|
498
326
|
Args:
|
|
499
|
-
|
|
327
|
+
pu (str): Planning unit ID
|
|
500
328
|
gauge (str): Gauge number
|
|
501
|
-
|
|
502
|
-
EWR_table (pd.DataFrame):
|
|
329
|
+
ewr (str): ewr code
|
|
330
|
+
EWR_table (pd.DataFrame): ewr dataset
|
|
503
331
|
df_F (pd.DataFrame): Daily flow data
|
|
504
|
-
PU_df (pd.DataFrame):
|
|
332
|
+
PU_df (pd.DataFrame): ewr results for the current planning unit iteration
|
|
505
333
|
|
|
506
334
|
Results:
|
|
507
|
-
tuple[pd.DataFrame, tuple[dict]]:
|
|
335
|
+
tuple[pd.DataFrame, tuple[dict]]: ewr results for the current planning unit iteration (updated); dictionary of ewr event information
|
|
508
336
|
|
|
509
337
|
'''
|
|
510
|
-
# Get information about
|
|
338
|
+
# Get information about ewr:
|
|
511
339
|
pull = data_inputs.get_EWR_components('low flow')
|
|
512
|
-
EWR_info = get_EWRs(
|
|
340
|
+
EWR_info = get_EWRs(pu, gauge, ewr, EWR_table, pull)
|
|
513
341
|
# Mask dates
|
|
514
342
|
masked_dates = mask_dates(EWR_info, df_F)
|
|
515
343
|
# Extract a daily timeseries for water years
|
|
516
344
|
water_years = wateryear_daily(df_F, EWR_info)
|
|
517
|
-
# Check flow data against
|
|
345
|
+
# Check flow data against ewr requirements and then perform analysis on the results:
|
|
518
346
|
E, D = lowflow_calc(EWR_info, df_F[gauge].values, water_years, df_F.index, masked_dates)
|
|
519
|
-
PU_df = event_stats(df_F, PU_df, gauge,
|
|
347
|
+
PU_df = event_stats(df_F, PU_df, gauge, ewr, EWR_info, E, D, water_years)
|
|
520
348
|
return PU_df, tuple([E])
|
|
521
349
|
|
|
522
|
-
def flow_handle(
|
|
350
|
+
def flow_handle(pu: str, gauge: str, ewr: str, EWR_table: pd.DataFrame, df_F: pd.DataFrame, PU_df: pd.DataFrame) -> tuple:
|
|
523
351
|
'''For handling non low flow based flow EWRs (freshes, bankfulls, overbanks)
|
|
524
352
|
|
|
525
353
|
Args:
|
|
526
|
-
|
|
354
|
+
pu (str): Planning unit ID
|
|
527
355
|
gauge (str): Gauge number
|
|
528
|
-
|
|
529
|
-
EWR_table (pd.DataFrame):
|
|
356
|
+
ewr (str): ewr code
|
|
357
|
+
EWR_table (pd.DataFrame): ewr dataset
|
|
530
358
|
df_F (pd.DataFrame): Daily flow data
|
|
531
|
-
PU_df (pd.DataFrame):
|
|
359
|
+
PU_df (pd.DataFrame): ewr results for the current planning unit iteration
|
|
532
360
|
|
|
533
361
|
Results:
|
|
534
|
-
tuple[pd.DataFrame, tuple[dict]]:
|
|
362
|
+
tuple[pd.DataFrame, tuple[dict]]: ewr results for the current planning unit iteration (updated); dictionary of ewr event information
|
|
535
363
|
|
|
536
364
|
'''
|
|
537
|
-
# Get information about
|
|
365
|
+
# Get information about ewr:
|
|
538
366
|
pull = data_inputs.get_EWR_components('flow')
|
|
539
|
-
EWR_info = get_EWRs(
|
|
367
|
+
EWR_info = get_EWRs(pu, gauge, ewr, EWR_table, pull)
|
|
540
368
|
# Mask dates
|
|
541
369
|
masked_dates = mask_dates(EWR_info, df_F)
|
|
542
370
|
# Extract a daily timeseries for water years
|
|
543
371
|
water_years = wateryear_daily(df_F, EWR_info)
|
|
544
|
-
# Check flow data against
|
|
372
|
+
# Check flow data against ewr requirements and then perform analysis on the results:
|
|
545
373
|
E, D = flow_calc(EWR_info, df_F[gauge].values, water_years, df_F.index, masked_dates)
|
|
546
|
-
PU_df = event_stats(df_F, PU_df, gauge,
|
|
374
|
+
PU_df = event_stats(df_F, PU_df, gauge, ewr, EWR_info, E, D, water_years)
|
|
547
375
|
return PU_df, tuple([E])
|
|
548
376
|
|
|
549
|
-
def flow_handle_anytime(
|
|
377
|
+
def flow_handle_anytime(pu: str, gauge: str, ewr: str, EWR_table: pd.DataFrame, df_F: pd.DataFrame, PU_df: pd.DataFrame) -> tuple:
|
|
550
378
|
'''For handling flow based flow EWRs (freshes, bankfulls, overbanks) to allow flows to continue to record
|
|
551
379
|
if it crosses water year boundaries.
|
|
552
380
|
|
|
553
381
|
Args:
|
|
554
|
-
|
|
382
|
+
pu (str): Planning unit ID
|
|
555
383
|
gauge (str): Gauge number
|
|
556
|
-
|
|
557
|
-
EWR_table (pd.DataFrame):
|
|
384
|
+
ewr (str): ewr code
|
|
385
|
+
EWR_table (pd.DataFrame): ewr dataset
|
|
558
386
|
df_F (pd.DataFrame): Daily flow data
|
|
559
|
-
PU_df (pd.DataFrame):
|
|
387
|
+
PU_df (pd.DataFrame): ewr results for the current planning unit iteration
|
|
560
388
|
|
|
561
389
|
|
|
562
390
|
Results:
|
|
563
|
-
tuple[pd.DataFrame, tuple[dict]]:
|
|
391
|
+
tuple[pd.DataFrame, tuple[dict]]: ewr results for the current planning unit iteration (updated); dictionary of ewr event information
|
|
564
392
|
|
|
565
393
|
'''
|
|
566
|
-
# Get information about
|
|
394
|
+
# Get information about ewr:
|
|
567
395
|
pull = data_inputs.get_EWR_components('flow')
|
|
568
|
-
EWR_info = get_EWRs(
|
|
396
|
+
EWR_info = get_EWRs(pu, gauge, ewr, EWR_table, pull)
|
|
569
397
|
# # Mask dates
|
|
570
398
|
masked_dates = mask_dates(EWR_info, df_F)
|
|
571
399
|
# Extract a daily timeseries for water years
|
|
572
400
|
water_years = wateryear_daily(df_F, EWR_info)
|
|
573
|
-
# Check flow data against
|
|
401
|
+
# Check flow data against ewr requirements and then perform analysis on the results
|
|
574
402
|
if ((EWR_info['start_month'] == 7) and (EWR_info['end_month'] == 6)):
|
|
575
403
|
E, D = flow_calc_anytime(EWR_info, df_F[gauge].values, water_years, df_F.index)
|
|
576
404
|
else:
|
|
577
405
|
E, D = flow_calc(EWR_info, df_F[gauge].values, water_years, df_F.index, masked_dates)
|
|
578
|
-
PU_df = event_stats(df_F, PU_df, gauge,
|
|
406
|
+
PU_df = event_stats(df_F, PU_df, gauge, ewr, EWR_info, E, D, water_years)
|
|
579
407
|
return PU_df, tuple([E])
|
|
580
408
|
|
|
581
|
-
def flow_handle_check_ctf(
|
|
409
|
+
def flow_handle_check_ctf(pu: str, gauge: str, ewr: str, EWR_table: pd.DataFrame, df_F: pd.DataFrame, PU_df: pd.DataFrame) -> tuple:
|
|
582
410
|
'''For handling non low flow based flow EWRs
|
|
583
411
|
|
|
584
412
|
Args:
|
|
585
|
-
|
|
413
|
+
pu (str): Planning unit ID
|
|
586
414
|
gauge (str): Gauge number
|
|
587
|
-
|
|
588
|
-
EWR_table (pd.DataFrame):
|
|
415
|
+
ewr (str): ewr code
|
|
416
|
+
EWR_table (pd.DataFrame): ewr dataset
|
|
589
417
|
df_F (pd.DataFrame): Daily flow data
|
|
590
|
-
PU_df (pd.DataFrame):
|
|
418
|
+
PU_df (pd.DataFrame): ewr results for the current planning unit iteration
|
|
591
419
|
|
|
592
420
|
Results:
|
|
593
|
-
tuple[pd.DataFrame, tuple[dict]]:
|
|
421
|
+
tuple[pd.DataFrame, tuple[dict]]: ewr results for the current planning unit iteration (updated); dictionary of ewr event information
|
|
594
422
|
|
|
595
423
|
'''
|
|
596
|
-
# Get information about
|
|
424
|
+
# Get information about ewr:
|
|
597
425
|
pull = data_inputs.get_EWR_components('flow-ctf')
|
|
598
|
-
EWR_info = get_EWRs(
|
|
426
|
+
EWR_info = get_EWRs(pu, gauge, ewr, EWR_table, pull)
|
|
599
427
|
# Mask dates
|
|
600
428
|
masked_dates = mask_dates(EWR_info, df_F)
|
|
601
429
|
# Extract a daily timeseries for water years
|
|
602
430
|
water_years = wateryear_daily(df_F, EWR_info)
|
|
603
|
-
# Check flow data against
|
|
431
|
+
# Check flow data against ewr requirements and then perform analysis on the results:
|
|
604
432
|
E, D = flow_calc_check_ctf(EWR_info, df_F[gauge].values, water_years, df_F.index, masked_dates)
|
|
605
|
-
PU_df = event_stats(df_F, PU_df, gauge,
|
|
433
|
+
PU_df = event_stats(df_F, PU_df, gauge, ewr, EWR_info, E, D, water_years)
|
|
606
434
|
return PU_df, tuple([E])
|
|
607
435
|
|
|
608
|
-
def cumulative_handle(
|
|
436
|
+
def cumulative_handle(pu: str, gauge: str, ewr: str, EWR_table: pd.DataFrame, df_F: pd.DataFrame, PU_df: pd.DataFrame):
|
|
609
437
|
'''For handling cumulative flow EWRs (some large freshes and overbanks, wetland flows).
|
|
610
438
|
|
|
611
439
|
Args:
|
|
612
|
-
|
|
440
|
+
pu (str): Planning unit ID
|
|
613
441
|
gauge (str): Gauge number
|
|
614
|
-
|
|
615
|
-
EWR_table (pd.DataFrame):
|
|
442
|
+
ewr (str): ewr code
|
|
443
|
+
EWR_table (pd.DataFrame): ewr dataset
|
|
616
444
|
df_F (pd.DataFrame): Daily flow data
|
|
617
|
-
PU_df (pd.DataFrame):
|
|
445
|
+
PU_df (pd.DataFrame): ewr results for the current planning unit iteration
|
|
618
446
|
|
|
619
447
|
Results:
|
|
620
|
-
tuple[pd.DataFrame, tuple[dict]]:
|
|
448
|
+
tuple[pd.DataFrame, tuple[dict]]: ewr results for the current planning unit iteration (updated); dictionary of ewr event information
|
|
621
449
|
|
|
622
450
|
'''
|
|
623
|
-
# Get information about
|
|
451
|
+
# Get information about ewr:
|
|
624
452
|
pull = data_inputs.get_EWR_components('cumulative')
|
|
625
|
-
EWR_info = get_EWRs(
|
|
453
|
+
EWR_info = get_EWRs(pu, gauge, ewr, EWR_table, pull)
|
|
626
454
|
# Mask dates:
|
|
627
455
|
masked_dates = mask_dates(EWR_info, df_F)
|
|
628
456
|
# Extract a daily timeseries for water years
|
|
629
457
|
water_years = wateryear_daily(df_F, EWR_info)
|
|
630
458
|
E, D = cumulative_calc(EWR_info, df_F[gauge].values, water_years, df_F.index, masked_dates)
|
|
631
|
-
PU_df = event_stats(df_F, PU_df, gauge,
|
|
459
|
+
PU_df = event_stats(df_F, PU_df, gauge, ewr, EWR_info, E, D, water_years)
|
|
632
460
|
|
|
633
461
|
return PU_df, tuple([E])
|
|
634
462
|
|
|
635
|
-
def cumulative_handle_qld(
|
|
463
|
+
def cumulative_handle_qld(pu: str, gauge: str, ewr: str, EWR_table: pd.DataFrame, df_F: pd.DataFrame, PU_df: pd.DataFrame):
|
|
636
464
|
'''For handling cumulative flow EWRs this to meet QLD requirements for bird breeding type 2.
|
|
637
465
|
|
|
638
466
|
Args:
|
|
639
|
-
|
|
467
|
+
pu (str): Planning unit ID
|
|
640
468
|
gauge (str): Gauge number
|
|
641
|
-
|
|
642
|
-
EWR_table (pd.DataFrame):
|
|
469
|
+
ewr (str): ewr code
|
|
470
|
+
EWR_table (pd.DataFrame): ewr dataset
|
|
643
471
|
df_F (pd.DataFrame): Daily flow data
|
|
644
|
-
PU_df (pd.DataFrame):
|
|
472
|
+
PU_df (pd.DataFrame): ewr results for the current planning unit iteration
|
|
645
473
|
|
|
646
474
|
Results:
|
|
647
|
-
tuple[pd.DataFrame, tuple[dict]]:
|
|
475
|
+
tuple[pd.DataFrame, tuple[dict]]: ewr results for the current planning unit iteration (updated); dictionary of ewr event information
|
|
648
476
|
|
|
649
477
|
'''
|
|
650
|
-
# Get information about
|
|
478
|
+
# Get information about ewr:
|
|
651
479
|
pull = data_inputs.get_EWR_components('cumulative')
|
|
652
|
-
EWR_info = get_EWRs(
|
|
480
|
+
EWR_info = get_EWRs(pu, gauge, ewr, EWR_table, pull)
|
|
653
481
|
# Mask dates:
|
|
654
482
|
masked_dates = mask_dates(EWR_info, df_F)
|
|
655
483
|
# Extract a daily timeseries for water years
|
|
656
484
|
water_years = wateryear_daily(df_F, EWR_info)
|
|
657
485
|
E, D = cumulative_calc_qld(EWR_info, df_F[gauge].values, water_years, df_F.index, masked_dates)
|
|
658
|
-
PU_df = event_stats(df_F, PU_df, gauge,
|
|
486
|
+
PU_df = event_stats(df_F, PU_df, gauge, ewr, EWR_info, E, D, water_years)
|
|
659
487
|
|
|
660
488
|
return PU_df, tuple([E])
|
|
661
489
|
|
|
662
|
-
def cumulative_handle_bbr(
|
|
490
|
+
def cumulative_handle_bbr(pu: str, gauge: str, ewr: str, EWR_table: pd.DataFrame, df_F: pd.DataFrame, df_L: pd.DataFrame, PU_df: pd.DataFrame):
|
|
663
491
|
'''For handling cumulative flow EWRs (for bird breeding ewr QLD).
|
|
664
492
|
|
|
665
493
|
Args:
|
|
666
|
-
|
|
494
|
+
pu (str): Planning unit ID
|
|
667
495
|
gauge (str): Gauge number
|
|
668
|
-
|
|
669
|
-
EWR_table (pd.DataFrame):
|
|
496
|
+
ewr (str): ewr code
|
|
497
|
+
EWR_table (pd.DataFrame): ewr dataset
|
|
670
498
|
df_F (pd.DataFrame): Daily flow data
|
|
671
499
|
df_L (pd.DataFrame): Daily water level data
|
|
672
|
-
PU_df (pd.DataFrame):
|
|
500
|
+
PU_df (pd.DataFrame): ewr results for the current planning unit iteration
|
|
673
501
|
|
|
674
502
|
Results:
|
|
675
|
-
tuple[pd.DataFrame, tuple[dict]]:
|
|
503
|
+
tuple[pd.DataFrame, tuple[dict]]: ewr results for the current planning unit iteration (updated); dictionary of ewr event information
|
|
676
504
|
|
|
677
505
|
'''
|
|
678
|
-
# Get information about
|
|
506
|
+
# Get information about ewr:
|
|
679
507
|
pull = data_inputs.get_EWR_components('cumulative_bbr')
|
|
680
|
-
EWR_info = get_EWRs(
|
|
508
|
+
EWR_info = get_EWRs(pu, gauge, ewr, EWR_table, pull)
|
|
681
509
|
# Mask dates:
|
|
682
510
|
masked_dates = mask_dates(EWR_info, df_F)
|
|
683
511
|
# If there is no level data loaded in, let user know and skip the analysis
|
|
684
512
|
try:
|
|
685
513
|
levels = df_L[EWR_info['weirpool_gauge']].values
|
|
686
514
|
except KeyError:
|
|
687
|
-
print(f'''Cannot evaluate this ewr for {gauge} {
|
|
515
|
+
print(f'''Cannot evaluate this ewr for {gauge} {ewr}, due to missing data. Specifically this ewr
|
|
688
516
|
also needs data for level gauge {EWR_info.get('weirpool_gauge', 'gauge data')}''')
|
|
689
517
|
return PU_df, None
|
|
690
518
|
# Extract a daily timeseries for water years
|
|
691
519
|
water_years = wateryear_daily(df_F, EWR_info)
|
|
692
520
|
E, D = cumulative_calc_bbr(EWR_info, df_F[gauge].values, levels, water_years, df_F.index, masked_dates)
|
|
693
|
-
PU_df = event_stats(df_F, PU_df, gauge,
|
|
521
|
+
PU_df = event_stats(df_F, PU_df, gauge, ewr, EWR_info, E, D, water_years)
|
|
694
522
|
|
|
695
523
|
return PU_df, tuple([E])
|
|
696
524
|
|
|
697
|
-
def water_stability_handle(
|
|
525
|
+
def water_stability_handle(pu: str, gauge: str, ewr: str, EWR_table: pd.DataFrame, df_F: pd.DataFrame, df_L: pd.DataFrame,
|
|
698
526
|
PU_df: pd.DataFrame):
|
|
699
527
|
'''For handling Fish Recruitment with water stability requirement (QLD).
|
|
700
528
|
|
|
701
529
|
Args:
|
|
702
|
-
|
|
530
|
+
pu (str): Planning unit ID
|
|
703
531
|
gauge (str): Gauge number
|
|
704
|
-
|
|
705
|
-
EWR_table (pd.DataFrame):
|
|
532
|
+
ewr (str): ewr code
|
|
533
|
+
EWR_table (pd.DataFrame): ewr dataset
|
|
706
534
|
df_F (pd.DataFrame): Daily flow data
|
|
707
535
|
df_L (pd.DataFrame): Daily water level data
|
|
708
|
-
PU_df (pd.DataFrame):
|
|
536
|
+
PU_df (pd.DataFrame): ewr results for the current planning unit iteration
|
|
709
537
|
|
|
710
538
|
Results:
|
|
711
|
-
tuple[pd.DataFrame, tuple[dict]]:
|
|
539
|
+
tuple[pd.DataFrame, tuple[dict]]: ewr results for the current planning unit iteration (updated); dictionary of ewr event information
|
|
712
540
|
|
|
713
541
|
'''
|
|
714
|
-
# Get information about
|
|
542
|
+
# Get information about ewr:
|
|
715
543
|
pull = data_inputs.get_EWR_components('water_stability')
|
|
716
|
-
EWR_info = get_EWRs(
|
|
544
|
+
EWR_info = get_EWRs(pu, gauge, ewr, EWR_table, pull)
|
|
717
545
|
# Mask dates:
|
|
718
546
|
masked_dates = mask_dates(EWR_info, df_F)
|
|
719
547
|
# If there is no level data loaded in, let user know and skip the analysis
|
|
720
548
|
try:
|
|
721
549
|
levels = df_L[EWR_info['weirpool_gauge']].values
|
|
722
550
|
except KeyError:
|
|
723
|
-
print(f'''Cannot evaluate this ewr for {gauge} {
|
|
551
|
+
print(f'''Cannot evaluate this ewr for {gauge} {ewr}, due to missing data. Specifically this ewr
|
|
724
552
|
also needs data for level gauge {EWR_info.get('weirpool_gauge', 'gauge data')}''')
|
|
725
553
|
return PU_df, None
|
|
726
554
|
# Extract a daily timeseries for water years
|
|
727
555
|
water_years = wateryear_daily(df_F, EWR_info)
|
|
728
556
|
E, D = water_stability_calc(EWR_info, df_F[gauge].values, levels, water_years, df_F.index, masked_dates)
|
|
729
|
-
PU_df = event_stats(df_F, PU_df, gauge,
|
|
557
|
+
PU_df = event_stats(df_F, PU_df, gauge, ewr, EWR_info, E, D, water_years)
|
|
730
558
|
|
|
731
559
|
return PU_df, tuple([E])
|
|
732
560
|
|
|
733
|
-
def water_stability_level_handle(
|
|
561
|
+
def water_stability_level_handle(pu: str, gauge: str, ewr: str, EWR_table: pd.DataFrame, df_L: pd.DataFrame, PU_df: pd.DataFrame):
|
|
734
562
|
'''For handling Fish Recruitment with water stability requirement (QLD).
|
|
735
563
|
|
|
736
564
|
Args:
|
|
737
|
-
|
|
565
|
+
pu (str): Planning unit ID
|
|
738
566
|
gauge (str): Gauge number
|
|
739
|
-
|
|
740
|
-
EWR_table (pd.DataFrame):
|
|
567
|
+
ewr (str): ewr code
|
|
568
|
+
EWR_table (pd.DataFrame): ewr dataset
|
|
741
569
|
df_F (pd.DataFrame): Daily flow data
|
|
742
570
|
df_L (pd.DataFrame): Daily water level data
|
|
743
|
-
PU_df (pd.DataFrame):
|
|
571
|
+
PU_df (pd.DataFrame): ewr results for the current planning unit iteration
|
|
744
572
|
|
|
745
573
|
Results:
|
|
746
|
-
tuple[pd.DataFrame, tuple[dict]]:
|
|
574
|
+
tuple[pd.DataFrame, tuple[dict]]: ewr results for the current planning unit iteration (updated); dictionary of ewr event information
|
|
747
575
|
|
|
748
576
|
'''
|
|
749
|
-
# Get information about
|
|
577
|
+
# Get information about ewr:
|
|
750
578
|
pull = data_inputs.get_EWR_components('water_stability_level')
|
|
751
|
-
EWR_info = get_EWRs(
|
|
579
|
+
EWR_info = get_EWRs(pu, gauge, ewr, EWR_table, pull)
|
|
752
580
|
# Mask dates:
|
|
753
581
|
masked_dates = mask_dates(EWR_info, df_L)
|
|
754
582
|
# If there is no level data loaded in, let user know and skip the analysis
|
|
755
583
|
try:
|
|
756
584
|
levels = df_L[EWR_info['weirpool_gauge']].values
|
|
757
585
|
except KeyError:
|
|
758
|
-
print(f'''Cannot evaluate this ewr for {gauge} {
|
|
586
|
+
print(f'''Cannot evaluate this ewr for {gauge} {ewr}, due to missing data. Specifically this ewr
|
|
759
587
|
also needs data for level gauge {EWR_info.get('weirpool_gauge', 'gauge data')}''')
|
|
760
588
|
return PU_df, None
|
|
761
589
|
# Extract a daily timeseries for water years
|
|
762
590
|
water_years = wateryear_daily(df_L, EWR_info)
|
|
763
591
|
E, D = water_stability_level_calc(EWR_info, levels, water_years, df_L.index, masked_dates)
|
|
764
|
-
PU_df = event_stats(df_L, PU_df, gauge,
|
|
592
|
+
PU_df = event_stats(df_L, PU_df, gauge, ewr, EWR_info, E, D, water_years)
|
|
765
593
|
|
|
766
594
|
return PU_df, tuple([E])
|
|
767
595
|
|
|
768
|
-
def level_handle(
|
|
596
|
+
def level_handle(pu: str, gauge: str, ewr: str, EWR_table: pd.DataFrame, df_L: pd.DataFrame, PU_df: pd.DataFrame) -> tuple:
|
|
769
597
|
'''For handling level type EWRs (low, mid, high and very high level lake fills).
|
|
770
598
|
|
|
771
599
|
Args:
|
|
772
|
-
|
|
600
|
+
pu (str): Planning unit ID
|
|
773
601
|
gauge (str): Gauge number
|
|
774
|
-
|
|
775
|
-
EWR_table (pd.DataFrame):
|
|
602
|
+
ewr (str): ewr code
|
|
603
|
+
EWR_table (pd.DataFrame): ewr dataset
|
|
776
604
|
df_L (pd.DataFrame): Daily water level data
|
|
777
|
-
PU_df (pd.DataFrame):
|
|
605
|
+
PU_df (pd.DataFrame): ewr results for the current planning unit iteration
|
|
778
606
|
|
|
779
607
|
Results:
|
|
780
|
-
tuple[pd.DataFrame, tuple[dict]]:
|
|
608
|
+
tuple[pd.DataFrame, tuple[dict]]: ewr results for the current planning unit iteration (updated); dictionary of ewr event information
|
|
781
609
|
|
|
782
610
|
'''
|
|
783
|
-
# Get information about
|
|
611
|
+
# Get information about ewr:
|
|
784
612
|
pull = data_inputs.get_EWR_components('level')
|
|
785
|
-
EWR_info = get_EWRs(
|
|
613
|
+
EWR_info = get_EWRs(pu, gauge, ewr, EWR_table, pull)
|
|
786
614
|
# Mask dates:
|
|
787
615
|
masked_dates = mask_dates(EWR_info, df_L)
|
|
788
616
|
# Extract a daily timeseries for water years
|
|
789
617
|
water_years = wateryear_daily(df_L, EWR_info)
|
|
790
618
|
E, D = lake_calc(EWR_info, df_L[gauge].values, water_years, df_L.index, masked_dates)
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
PU_df = event_stats(df_L, PU_df, gauge, EWR, EWR_info, E, D, water_years)
|
|
794
|
-
return PU_df, tuple([E])
|
|
795
|
-
|
|
796
|
-
def level_change_handle(PU: str, gauge: str, EWR: str, EWR_table: pd.DataFrame, df_L: pd.DataFrame, PU_df: pd.DataFrame) -> tuple:
|
|
797
|
-
'''For handling level type EWRs (low, mid, high and very high level lake fills).
|
|
798
|
-
|
|
799
|
-
Args:
|
|
800
|
-
PU (str): Planning unit ID
|
|
801
|
-
gauge (str): Gauge number
|
|
802
|
-
EWR (str): EWR code
|
|
803
|
-
EWR_table (pd.DataFrame): EWR dataset
|
|
804
|
-
df_L (pd.DataFrame): Daily water level data
|
|
805
|
-
PU_df (pd.DataFrame): EWR results for the current planning unit iteration
|
|
806
|
-
|
|
807
|
-
Results:
|
|
808
|
-
tuple[pd.DataFrame, tuple[dict]]: EWR results for the current planning unit iteration (updated); dictionary of EWR event information
|
|
809
|
-
|
|
810
|
-
'''
|
|
811
|
-
# Get information about EWR:
|
|
812
|
-
pull = data_inputs.get_EWR_components('level')
|
|
813
|
-
EWR_info = get_EWRs(PU, gauge, EWR, EWR_table, pull)
|
|
814
|
-
# Mask dates:
|
|
815
|
-
masked_dates = mask_dates(EWR_info, df_L)
|
|
816
|
-
# Extract a daily timeseries for water years
|
|
817
|
-
water_years = wateryear_daily(df_L, EWR_info)
|
|
818
|
-
E, D = level_change_calc(EWR_info, df_L[gauge].values, water_years, df_L.index, masked_dates)
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
PU_df = event_stats(df_L, PU_df, gauge, EWR, EWR_info, E, D, water_years)
|
|
619
|
+
PU_df = event_stats(df_L, PU_df, gauge, ewr, EWR_info, E, D, water_years)
|
|
822
620
|
return PU_df, tuple([E])
|
|
823
621
|
|
|
824
|
-
def weirpool_handle(
|
|
622
|
+
def weirpool_handle(pu: str, gauge: str, ewr: str, EWR_table: pd.DataFrame, df_F: pd.DataFrame, df_L: pd.DataFrame, PU_df: pd.DataFrame) -> tuple:
|
|
825
623
|
'''For handling weirpool type EWRs.
|
|
826
624
|
|
|
827
625
|
Args:
|
|
828
|
-
|
|
626
|
+
pu (str): Planning unit ID
|
|
829
627
|
gauge (str): Gauge number
|
|
830
|
-
|
|
831
|
-
EWR_table (pd.DataFrame):
|
|
628
|
+
ewr (str): ewr code
|
|
629
|
+
EWR_table (pd.DataFrame): ewr dataset
|
|
832
630
|
df_F (pd.DataFrame): Daily flow data
|
|
833
631
|
df_L (pd.DataFrame): Daily water level data
|
|
834
|
-
PU_df (pd.DataFrame):
|
|
632
|
+
PU_df (pd.DataFrame): ewr results for the current planning unit iteration
|
|
835
633
|
|
|
836
634
|
Results:
|
|
837
|
-
tuple[pd.DataFrame, tuple[dict]]:
|
|
635
|
+
tuple[pd.DataFrame, tuple[dict]]: ewr results for the current planning unit iteration (updated); dictionary of ewr event information
|
|
838
636
|
|
|
839
637
|
'''
|
|
840
638
|
|
|
841
|
-
# Get information about
|
|
842
|
-
weirpool_type = data_inputs.weirpool_type(
|
|
639
|
+
# Get information about ewr (changes depending on the weirpool type):
|
|
640
|
+
weirpool_type = data_inputs.weirpool_type(ewr)
|
|
843
641
|
if weirpool_type == 'raising':
|
|
844
642
|
pull = data_inputs.get_EWR_components('weirpool-raising')
|
|
845
643
|
elif weirpool_type == 'falling':
|
|
846
644
|
pull = data_inputs.get_EWR_components('weirpool-falling')
|
|
847
|
-
EWR_info = get_EWRs(
|
|
645
|
+
EWR_info = get_EWRs(pu, gauge, ewr, EWR_table, pull)
|
|
848
646
|
# Mask dates for both the flow and level dataframes:
|
|
849
647
|
masked_dates = mask_dates(EWR_info, df_F)
|
|
850
648
|
# Extract a daily timeseries for water years:
|
|
@@ -854,37 +652,37 @@ def weirpool_handle(PU: str, gauge: str, EWR: str, EWR_table: pd.DataFrame, df_F
|
|
|
854
652
|
levels = df_L[EWR_info['weirpool_gauge']].values
|
|
855
653
|
|
|
856
654
|
except KeyError:
|
|
857
|
-
print(f'''Cannot evaluate this ewr for {gauge} {
|
|
655
|
+
print(f'''Cannot evaluate this ewr for {gauge} {ewr}, due to missing data. Specifically this ewr
|
|
858
656
|
also needs data for level gauge {EWR_info.get('weirpool_gauge', 'no wp gauge')}''')
|
|
859
657
|
return PU_df, None
|
|
860
|
-
# Check flow and level data against
|
|
658
|
+
# Check flow and level data against ewr requirements and then perform analysis on the results:
|
|
861
659
|
E, D = weirpool_calc(EWR_info, df_F[gauge].values, levels, water_years, weirpool_type, df_F.index, masked_dates)
|
|
862
|
-
PU_df = event_stats(df_F, PU_df, gauge,
|
|
660
|
+
PU_df = event_stats(df_F, PU_df, gauge, ewr, EWR_info, E, D, water_years)
|
|
863
661
|
return PU_df, tuple([E])
|
|
864
662
|
|
|
865
|
-
def nest_handle(
|
|
663
|
+
def nest_handle(pu: str, gauge: str, ewr: str, EWR_table: pd.DataFrame, df_F: pd.DataFrame, df_L: pd.DataFrame, PU_df: pd.DataFrame) -> tuple:
|
|
866
664
|
'''For handling nest style EWRs.
|
|
867
665
|
|
|
868
666
|
Args:
|
|
869
|
-
|
|
667
|
+
pu (str): Planning unit ID
|
|
870
668
|
gauge (str): Gauge number
|
|
871
|
-
|
|
872
|
-
EWR_table (pd.DataFrame):
|
|
669
|
+
ewr (str): ewr code
|
|
670
|
+
EWR_table (pd.DataFrame): ewr dataset
|
|
873
671
|
df_F (pd.DataFrame): Daily flow data
|
|
874
672
|
df_L (pd.DataFrame): Daily water level data
|
|
875
|
-
PU_df (pd.DataFrame):
|
|
673
|
+
PU_df (pd.DataFrame): ewr results for the current planning unit iteration
|
|
876
674
|
|
|
877
675
|
Results:
|
|
878
|
-
tuple[pd.DataFrame, tuple[dict]]:
|
|
676
|
+
tuple[pd.DataFrame, tuple[dict]]: ewr results for the current planning unit iteration (updated); dictionary of ewr event information
|
|
879
677
|
|
|
880
678
|
'''
|
|
881
|
-
# Get information about
|
|
882
|
-
requires_weirpool_gauge = is_weirpool_gauge(EWR_table, gauge,
|
|
679
|
+
# Get information about ewr (changes depending on if theres a weirpool level gauge in the ewr)
|
|
680
|
+
requires_weirpool_gauge = is_weirpool_gauge(EWR_table, gauge, ewr, pu)
|
|
883
681
|
if requires_weirpool_gauge:
|
|
884
682
|
pull = data_inputs.get_EWR_components('nest-level')
|
|
885
683
|
else:
|
|
886
684
|
pull = data_inputs.get_EWR_components('nest-percent')
|
|
887
|
-
EWR_info = get_EWRs(
|
|
685
|
+
EWR_info = get_EWRs(pu, gauge, ewr, EWR_table, pull)
|
|
888
686
|
masked_dates = mask_dates(EWR_info, df_F)
|
|
889
687
|
# Extract a daily timeseries for water years:
|
|
890
688
|
water_years = wateryear_daily(df_F, EWR_info)
|
|
@@ -904,37 +702,37 @@ def nest_handle(PU: str, gauge: str, EWR: str, EWR_table: pd.DataFrame, df_F: pd
|
|
|
904
702
|
# If its a nest with a weirpool requirement, do not analyses without the level data:
|
|
905
703
|
levels = df_L[EWR_info['weirpool_gauge']].values
|
|
906
704
|
except KeyError:
|
|
907
|
-
print(f'''Cannot evaluate this ewr for {gauge} {
|
|
705
|
+
print(f'''Cannot evaluate this ewr for {gauge} {ewr}, due to missing data. Specifically this ewr
|
|
908
706
|
also needs data for level gauge {EWR_info.get('weirpool_gauge', 'no wp gauge')}''')
|
|
909
707
|
return PU_df, None
|
|
910
708
|
# handle any error in missing values in parameter sheet
|
|
911
709
|
try:
|
|
912
710
|
E, D = nest_calc_weirpool(EWR_info, df_F[gauge].values, levels, water_years, df_F.index, masked_dates)
|
|
913
711
|
except KeyError:
|
|
914
|
-
log.info(f'''Cannot evaluate this ewr for {gauge} {
|
|
712
|
+
log.info(f'''Cannot evaluate this ewr for {gauge} {ewr}, due to missing parameter data. Specifically this ewr
|
|
915
713
|
also needs data for level threshold min or level threshold max''')
|
|
916
714
|
return PU_df, None
|
|
917
|
-
PU_df = event_stats(df_F, PU_df, gauge,
|
|
715
|
+
PU_df = event_stats(df_F, PU_df, gauge, ewr, EWR_info, E, D, water_years)
|
|
918
716
|
return PU_df, tuple([E])
|
|
919
717
|
|
|
920
|
-
def flow_handle_multi(
|
|
718
|
+
def flow_handle_multi(pu: str, gauge: str, ewr: str, EWR_table: pd.DataFrame, df_F: pd.DataFrame, PU_df: pd.DataFrame) -> tuple:
|
|
921
719
|
'''For handling flow EWRs where flow needs to be combined at two gauges
|
|
922
720
|
|
|
923
721
|
Args:
|
|
924
|
-
|
|
722
|
+
pu (str): Planning unit ID
|
|
925
723
|
gauge (str): Gauge number
|
|
926
|
-
|
|
927
|
-
EWR_table (pd.DataFrame):
|
|
724
|
+
ewr (str): ewr code
|
|
725
|
+
EWR_table (pd.DataFrame): ewr dataset
|
|
928
726
|
df_F (pd.DataFrame): Daily flow data
|
|
929
|
-
PU_df (pd.DataFrame):
|
|
727
|
+
PU_df (pd.DataFrame): ewr results for the current planning unit iteration
|
|
930
728
|
|
|
931
729
|
Results:
|
|
932
|
-
tuple[pd.DataFrame, tuple[dict]]:
|
|
730
|
+
tuple[pd.DataFrame, tuple[dict]]: ewr results for the current planning unit iteration (updated); dictionary of ewr event information
|
|
933
731
|
|
|
934
732
|
'''
|
|
935
|
-
# Get information about the
|
|
733
|
+
# Get information about the ewr:
|
|
936
734
|
pull = data_inputs.get_EWR_components('multi-gauge-flow')
|
|
937
|
-
EWR_info = get_EWRs(
|
|
735
|
+
EWR_info = get_EWRs(pu, gauge, ewr, EWR_table, pull)
|
|
938
736
|
# Mask the dates:
|
|
939
737
|
masked_dates = mask_dates(EWR_info, df_F)
|
|
940
738
|
# Extract a daily timeseries for water years:
|
|
@@ -945,34 +743,34 @@ def flow_handle_multi(PU: str, gauge: str, EWR: str, EWR_table: pd.DataFrame, df
|
|
|
945
743
|
flows2 = df_F[EWR_info['second_gauge']].values
|
|
946
744
|
flows = flows1 + flows2
|
|
947
745
|
except KeyError:
|
|
948
|
-
print(f'''This {
|
|
949
|
-
The
|
|
746
|
+
print(f'''This {ewr} at the gauge {gauge} sums the flows at two gauges ({gauge} and {EWR_info['second_gauge']}.
|
|
747
|
+
The ewr tool has not been able to find the flow data for {EWR_info["second_gauge"]} so it will only evaluate EWRs against the
|
|
950
748
|
flow at the gauge {gauge}. If you are running a model scenario through please disregard this message - most hydrology models have already
|
|
951
749
|
summed flows at these two gauges.''')
|
|
952
750
|
flows = flows1
|
|
953
751
|
|
|
954
752
|
E, D = flow_calc(EWR_info, flows, water_years, df_F.index, masked_dates)
|
|
955
|
-
PU_df = event_stats(df_F, PU_df, gauge,
|
|
753
|
+
PU_df = event_stats(df_F, PU_df, gauge, ewr, EWR_info, E, D, water_years)
|
|
956
754
|
return PU_df, tuple([E])
|
|
957
755
|
|
|
958
|
-
def lowflow_handle_multi(
|
|
756
|
+
def lowflow_handle_multi(pu: str, gauge: str, ewr: str, EWR_table: pd.DataFrame, df_F: pd.DataFrame, PU_df: pd.DataFrame) -> tuple:
|
|
959
757
|
'''For handling low flow EWRs where flow needs to be combined at two gauges.
|
|
960
758
|
|
|
961
759
|
Args:
|
|
962
|
-
|
|
760
|
+
pu (str): Planning unit ID
|
|
963
761
|
gauge (str): Gauge number
|
|
964
|
-
|
|
965
|
-
EWR_table (pd.DataFrame):
|
|
762
|
+
ewr (str): ewr code
|
|
763
|
+
EWR_table (pd.DataFrame): ewr dataset
|
|
966
764
|
df_F (pd.DataFrame): Daily flow data
|
|
967
|
-
PU_df (pd.DataFrame):
|
|
765
|
+
PU_df (pd.DataFrame): ewr results for the current planning unit iteration
|
|
968
766
|
|
|
969
767
|
Results:
|
|
970
|
-
tuple[pd.DataFrame, tuple[dict]]:
|
|
768
|
+
tuple[pd.DataFrame, tuple[dict]]: ewr results for the current planning unit iteration (updated); dictionary of ewr event information
|
|
971
769
|
|
|
972
770
|
'''
|
|
973
|
-
# Get information about the
|
|
771
|
+
# Get information about the ewr:
|
|
974
772
|
pull = data_inputs.get_EWR_components('multi-gauge-low flow')
|
|
975
|
-
EWR_info = get_EWRs(
|
|
773
|
+
EWR_info = get_EWRs(pu, gauge, ewr, EWR_table, pull)
|
|
976
774
|
# Mask dates:
|
|
977
775
|
masked_dates = mask_dates(EWR_info, df_F)
|
|
978
776
|
# Extract a daily timeseries for water years
|
|
@@ -983,34 +781,34 @@ def lowflow_handle_multi(PU: str, gauge: str, EWR: str, EWR_table: pd.DataFrame,
|
|
|
983
781
|
flows2 = df_F[EWR_info['second_gauge']].values
|
|
984
782
|
flows = flows1 + flows2
|
|
985
783
|
except KeyError:
|
|
986
|
-
print(f'''This {
|
|
987
|
-
The
|
|
784
|
+
print(f'''This {ewr} at the gauge {gauge} sums the flows at two gauges ({gauge} and {EWR_info['second_gauge']}.
|
|
785
|
+
The ewr tool has not been able to find the flow data for {EWR_info["second_gauge"]} so it will only evaluate EWRs against the
|
|
988
786
|
flow at the gauge {gauge}. If you are running a model scenario through please disregard this message - most hydrology models have already
|
|
989
787
|
summed flows at these two gauges.''')
|
|
990
788
|
flows = flows1
|
|
991
|
-
# Check flow data against
|
|
789
|
+
# Check flow data against ewr requirements and then perform analysis on the results:
|
|
992
790
|
E, D = lowflow_calc(EWR_info, flows, water_years, df_F.index, masked_dates)
|
|
993
|
-
PU_df = event_stats(df_F, PU_df, gauge,
|
|
791
|
+
PU_df = event_stats(df_F, PU_df, gauge, ewr, EWR_info, E, D, water_years)
|
|
994
792
|
return PU_df, tuple([E])
|
|
995
793
|
|
|
996
|
-
def ctf_handle_multi(
|
|
794
|
+
def ctf_handle_multi(pu: str, gauge: str, ewr: str, EWR_table: pd.DataFrame, df_F: pd.DataFrame, PU_df: pd.DataFrame) -> tuple:
|
|
997
795
|
'''For handling cease to flow EWRs where flow needs to be combined at two gauges
|
|
998
796
|
|
|
999
797
|
Args:
|
|
1000
|
-
|
|
798
|
+
pu (str): Planning unit ID
|
|
1001
799
|
gauge (str): Gauge number
|
|
1002
|
-
|
|
1003
|
-
EWR_table (pd.DataFrame):
|
|
800
|
+
ewr (str): ewr code
|
|
801
|
+
EWR_table (pd.DataFrame): ewr dataset
|
|
1004
802
|
df_F (pd.DataFrame): Daily flow data
|
|
1005
|
-
PU_df (pd.DataFrame):
|
|
803
|
+
PU_df (pd.DataFrame): ewr results for the current planning unit iteration
|
|
1006
804
|
|
|
1007
805
|
Results:
|
|
1008
|
-
tuple[pd.DataFrame, tuple[dict]]:
|
|
806
|
+
tuple[pd.DataFrame, tuple[dict]]: ewr results for the current planning unit iteration (updated); dictionary of ewr event information
|
|
1009
807
|
|
|
1010
808
|
'''
|
|
1011
|
-
# Get information about the
|
|
809
|
+
# Get information about the ewr:
|
|
1012
810
|
pull = data_inputs.get_EWR_components('multi-gauge-cease to flow')
|
|
1013
|
-
EWR_info = get_EWRs(
|
|
811
|
+
EWR_info = get_EWRs(pu, gauge, ewr, EWR_table, pull)
|
|
1014
812
|
# Mask dates:
|
|
1015
813
|
masked_dates = mask_dates(EWR_info, df_F)
|
|
1016
814
|
# Extract a daily timeseries for water years
|
|
@@ -1021,37 +819,37 @@ def ctf_handle_multi(PU: str, gauge: str, EWR: str, EWR_table: pd.DataFrame, df_
|
|
|
1021
819
|
flows2 = df_F[EWR_info['second_gauge']].values
|
|
1022
820
|
flows = flows1 + flows2
|
|
1023
821
|
except KeyError:
|
|
1024
|
-
print(f'''This {
|
|
1025
|
-
The
|
|
822
|
+
print(f'''This {ewr} at the gauge {gauge} sums the flows at two gauges ({gauge} and {EWR_info['second_gauge']}.
|
|
823
|
+
The ewr tool has not been able to find the flow data for {EWR_info["second_gauge"]} so it will only evaluate EWRs against the
|
|
1026
824
|
flow at the gauge {gauge}. If you are running a model scenario through please disregard this message - most hydrology models have already
|
|
1027
825
|
summed flows at these two gauges.''')
|
|
1028
826
|
flows = flows1
|
|
1029
|
-
# Check flow data against
|
|
827
|
+
# Check flow data against ewr requirements and then perform analysis on the results:
|
|
1030
828
|
if ((EWR_info['start_month'] == 7) and (EWR_info['end_month'] == 6)):
|
|
1031
829
|
E, D = ctf_calc_anytime(EWR_info, df_F[gauge].values, water_years, df_F.index)
|
|
1032
830
|
else:
|
|
1033
831
|
E, D = ctf_calc(EWR_info, df_F[gauge].values, water_years, df_F.index, masked_dates)
|
|
1034
|
-
PU_df = event_stats(df_F, PU_df, gauge,
|
|
832
|
+
PU_df = event_stats(df_F, PU_df, gauge, ewr, EWR_info, E, D, water_years)
|
|
1035
833
|
return PU_df, tuple([E])
|
|
1036
834
|
|
|
1037
|
-
def cumulative_handle_multi(
|
|
835
|
+
def cumulative_handle_multi(pu: str, gauge: str, ewr: str, EWR_table: pd.DataFrame, df_F: pd.DataFrame, PU_df: pd.DataFrame) -> tuple:
|
|
1038
836
|
'''For handling cumulative volume EWRs where flow needs to be combined at two gauges.
|
|
1039
837
|
|
|
1040
838
|
Args:
|
|
1041
|
-
|
|
839
|
+
pu (str): Planning unit ID
|
|
1042
840
|
gauge (str): Gauge number
|
|
1043
|
-
|
|
1044
|
-
EWR_table (pd.DataFrame):
|
|
841
|
+
ewr (str): ewr code
|
|
842
|
+
EWR_table (pd.DataFrame): ewr dataset
|
|
1045
843
|
df_F (pd.DataFrame): Daily flow data
|
|
1046
|
-
PU_df (pd.DataFrame):
|
|
844
|
+
PU_df (pd.DataFrame): ewr results for the current planning unit iteration
|
|
1047
845
|
|
|
1048
846
|
Results:
|
|
1049
|
-
tuple[pd.DataFrame, tuple[dict]]:
|
|
847
|
+
tuple[pd.DataFrame, tuple[dict]]: ewr results for the current planning unit iteration (updated); dictionary of ewr event information
|
|
1050
848
|
|
|
1051
849
|
'''
|
|
1052
|
-
# Get information about the
|
|
850
|
+
# Get information about the ewr:
|
|
1053
851
|
pull = data_inputs.get_EWR_components('multi-gauge-cumulative')
|
|
1054
|
-
EWR_info = get_EWRs(
|
|
852
|
+
EWR_info = get_EWRs(pu, gauge, ewr, EWR_table, pull)
|
|
1055
853
|
# Mask dates:
|
|
1056
854
|
masked_dates = mask_dates(EWR_info, df_F)
|
|
1057
855
|
# Extract a daily timeseries for water years
|
|
@@ -1062,58 +860,58 @@ def cumulative_handle_multi(PU: str, gauge: str, EWR: str, EWR_table: pd.DataFra
|
|
|
1062
860
|
flows2 = df_F[EWR_info['second_gauge']].values
|
|
1063
861
|
flows = flows1 + flows2
|
|
1064
862
|
except KeyError:
|
|
1065
|
-
print(f'''This {
|
|
1066
|
-
The
|
|
863
|
+
print(f'''This {ewr} at the gauge {gauge} sums the flows at two gauges ({gauge} and {EWR_info['second_gauge']}.
|
|
864
|
+
The ewr tool has not been able to find the flow data for {EWR_info["second_gauge"]} so it will only evaluate EWRs against the
|
|
1067
865
|
flow at the gauge {gauge}. If you are running a model scenario through please disregard this message - most hydrology models have already
|
|
1068
866
|
summed flows at these two gauges.''')
|
|
1069
867
|
flows = flows1
|
|
1070
868
|
E, D = cumulative_calc(EWR_info, flows, water_years, df_F.index, masked_dates)
|
|
1071
|
-
PU_df = event_stats(df_F, PU_df, gauge,
|
|
869
|
+
PU_df = event_stats(df_F, PU_df, gauge, ewr, EWR_info, E, D, water_years)
|
|
1072
870
|
return PU_df, tuple([E])
|
|
1073
871
|
|
|
1074
872
|
|
|
1075
|
-
def flow_handle_sa(
|
|
873
|
+
def flow_handle_sa(pu: str, gauge: str, ewr: str, EWR_table: pd.DataFrame, df_F: pd.DataFrame, PU_df: pd.DataFrame) -> tuple:
|
|
1076
874
|
'''For handling SA IC(in channel) and FP (flood plain) type EWRs.
|
|
1077
875
|
It checks Flow thresholds, and check for Flow raise and fall.
|
|
1078
876
|
|
|
1079
877
|
Args:
|
|
1080
|
-
|
|
878
|
+
pu (str): Planning unit ID
|
|
1081
879
|
gauge (str): Gauge number
|
|
1082
|
-
|
|
1083
|
-
EWR_table (pd.DataFrame):
|
|
880
|
+
ewr (str): ewr code
|
|
881
|
+
EWR_table (pd.DataFrame): ewr dataset
|
|
1084
882
|
df_F (pd.DataFrame): Daily flow data
|
|
1085
883
|
df_L (pd.DataFrame): Daily water level data
|
|
1086
|
-
PU_df (pd.DataFrame):
|
|
884
|
+
PU_df (pd.DataFrame): ewr results for the current planning unit iteration
|
|
1087
885
|
|
|
1088
886
|
Results:
|
|
1089
|
-
tuple[pd.DataFrame, tuple[dict]]:
|
|
887
|
+
tuple[pd.DataFrame, tuple[dict]]: ewr results for the current planning unit iteration (updated); dictionary of ewr event information
|
|
1090
888
|
|
|
1091
889
|
'''
|
|
1092
890
|
|
|
1093
891
|
pull = data_inputs.get_EWR_components('flood-plains')
|
|
1094
|
-
EWR_info = get_EWRs(
|
|
892
|
+
EWR_info = get_EWRs(pu, gauge, ewr, EWR_table, pull)
|
|
1095
893
|
# Mask dates for both the flow and level dataframes:
|
|
1096
894
|
masked_dates = mask_dates(EWR_info, df_F)
|
|
1097
895
|
# Extract a daily timeseries for water years:
|
|
1098
896
|
water_years = wateryear_daily(df_F, EWR_info)
|
|
1099
897
|
|
|
1100
898
|
E, D = flow_calc_sa(EWR_info, df_F[gauge].values, water_years, df_F.index, masked_dates)
|
|
1101
|
-
PU_df = event_stats(df_F, PU_df, gauge,
|
|
899
|
+
PU_df = event_stats(df_F, PU_df, gauge, ewr, EWR_info, E, D, water_years)
|
|
1102
900
|
return PU_df, tuple([E])
|
|
1103
901
|
|
|
1104
|
-
def barrage_flow_handle(
|
|
902
|
+
def barrage_flow_handle(pu: str, gauge: str, ewr: str, EWR_table: pd.DataFrame, df_F: pd.DataFrame, PU_df: pd.DataFrame) -> tuple:
|
|
1105
903
|
"""handle function to calculate barrage flow type EWRs
|
|
1106
904
|
|
|
1107
905
|
Args:
|
|
1108
|
-
|
|
906
|
+
pu (str): Planning unit ID
|
|
1109
907
|
gauge (str): Gauge number
|
|
1110
|
-
|
|
1111
|
-
EWR_table (pd.DataFrame):
|
|
908
|
+
ewr (str): ewr code
|
|
909
|
+
EWR_table (pd.DataFrame): ewr dataset
|
|
1112
910
|
df_F (pd.DataFrame): Daily flow data
|
|
1113
|
-
PU_df (pd.DataFrame):
|
|
911
|
+
PU_df (pd.DataFrame): ewr results for the current planning unit iteration
|
|
1114
912
|
|
|
1115
913
|
Returns:
|
|
1116
|
-
tuple[pd.DataFrame, tuple[dict]]:
|
|
914
|
+
tuple[pd.DataFrame, tuple[dict]]: ewr results for the current planning unit iteration (updated); dictionary of ewr event information
|
|
1117
915
|
"""
|
|
1118
916
|
barrage_flow_gauges = data_inputs.get_barrage_flow_gauges()
|
|
1119
917
|
all_required_gauges = barrage_flow_gauges.get(gauge)
|
|
@@ -1122,7 +920,7 @@ def barrage_flow_handle(PU: str, gauge: str, EWR: str, EWR_table: pd.DataFrame,
|
|
|
1122
920
|
# check if current gauge is the main barrage gauge
|
|
1123
921
|
if all_required_gauges_in_df_F:
|
|
1124
922
|
pull = data_inputs.get_EWR_components('barrage-flow')
|
|
1125
|
-
EWR_info = get_EWRs(
|
|
923
|
+
EWR_info = get_EWRs(pu, gauge, ewr, EWR_table, pull)
|
|
1126
924
|
# Mask dates for both the flow and level dataframes:
|
|
1127
925
|
# Extract a daily timeseries for water years:
|
|
1128
926
|
water_years = wateryear_daily(df_F, EWR_info)
|
|
@@ -1130,25 +928,25 @@ def barrage_flow_handle(PU: str, gauge: str, EWR: str, EWR_table: pd.DataFrame,
|
|
|
1130
928
|
df = df_F.copy(deep=True)
|
|
1131
929
|
df['combined_flow'] = df[all_required_gauges].sum(axis=1)
|
|
1132
930
|
E, D = barrage_flow_calc(EWR_info, df['combined_flow'], water_years, df_F.index)
|
|
1133
|
-
PU_df = event_stats(df_F, PU_df, gauge,
|
|
931
|
+
PU_df = event_stats(df_F, PU_df, gauge, ewr, EWR_info, E, D, water_years)
|
|
1134
932
|
return PU_df, tuple([E])
|
|
1135
933
|
else:
|
|
1136
934
|
print(f'Missing data for barrage gauges {" ".join(all_required_gauges)}')
|
|
1137
935
|
return PU_df, None
|
|
1138
936
|
|
|
1139
|
-
def barrage_level_handle(
|
|
937
|
+
def barrage_level_handle(pu: str, gauge: str, ewr: str, EWR_table: pd.DataFrame, df_L: pd.DataFrame, PU_df: pd.DataFrame) -> tuple:
|
|
1140
938
|
"""handle function to calculate barrage level type EWRs
|
|
1141
939
|
|
|
1142
940
|
Args:
|
|
1143
|
-
|
|
941
|
+
pu (str): Planning unit ID
|
|
1144
942
|
gauge (str): Gauge number
|
|
1145
|
-
|
|
1146
|
-
EWR_table (pd.DataFrame):
|
|
943
|
+
ewr (str): ewr code
|
|
944
|
+
EWR_table (pd.DataFrame): ewr dataset
|
|
1147
945
|
df_L (pd.DataFrame): Daily level data
|
|
1148
|
-
PU_df (pd.DataFrame):
|
|
946
|
+
PU_df (pd.DataFrame): ewr results for the current planning unit iteration
|
|
1149
947
|
|
|
1150
948
|
Returns:
|
|
1151
|
-
tuple[pd.DataFrame, tuple[dict]]:
|
|
949
|
+
tuple[pd.DataFrame, tuple[dict]]: ewr results for the current planning unit iteration (updated); dictionary of ewr event information
|
|
1152
950
|
"""
|
|
1153
951
|
barrage_level_gauges = data_inputs.get_barrage_level_gauges()
|
|
1154
952
|
all_required_gauges = barrage_level_gauges.get(gauge)
|
|
@@ -1160,7 +958,7 @@ def barrage_level_handle(PU: str, gauge: str, EWR: str, EWR_table: pd.DataFrame,
|
|
|
1160
958
|
# directly subset and use all_required_gauges_in_df_L as the new list.
|
|
1161
959
|
if all_required_gauges_in_df_L:
|
|
1162
960
|
pull = data_inputs.get_EWR_components('barrage-level')
|
|
1163
|
-
EWR_info = get_EWRs(
|
|
961
|
+
EWR_info = get_EWRs(pu, gauge, ewr, EWR_table, pull)
|
|
1164
962
|
masked_dates = mask_dates(EWR_info, df_L)
|
|
1165
963
|
# Extract a daily timeseries for water years:
|
|
1166
964
|
water_years = wateryear_daily(df_L, EWR_info)
|
|
@@ -1175,71 +973,53 @@ def barrage_level_handle(PU: str, gauge: str, EWR: str, EWR_table: pd.DataFrame,
|
|
|
1175
973
|
if cllmm_type == 'd':
|
|
1176
974
|
E, D = coorong_level_calc(EWR_info, df_5_day_averages['mean'], water_years, df_L.index, masked_dates)
|
|
1177
975
|
|
|
1178
|
-
PU_df = event_stats(df_L, PU_df, gauge,
|
|
976
|
+
PU_df = event_stats(df_L, PU_df, gauge, ewr, EWR_info, E, D, water_years)
|
|
1179
977
|
return PU_df, tuple([E])
|
|
1180
978
|
|
|
1181
979
|
else:
|
|
1182
980
|
print(f'skipping calculation because gauge {" ".join(all_required_gauges)} is not the main barrage level gauge ') #TODO: improve error message
|
|
1183
981
|
return PU_df, None
|
|
1184
982
|
|
|
1185
|
-
def rise_and_fall_handle(
|
|
983
|
+
def rise_and_fall_handle(pu: str, gauge: str, ewr: str, EWR_table: pd.DataFrame, df_F: pd.DataFrame, df_L: pd.DataFrame, PU_df: pd.DataFrame) -> tuple:
|
|
1186
984
|
"""For handling rise and fall EWRs of type FLOW and LEVEL.
|
|
1187
985
|
|
|
1188
986
|
Args:
|
|
1189
|
-
|
|
987
|
+
pu (str): Planning unit ID
|
|
1190
988
|
gauge (str): Gauge number
|
|
1191
|
-
|
|
1192
|
-
EWR_table (pd.DataFrame):
|
|
989
|
+
ewr (str): ewr code
|
|
990
|
+
EWR_table (pd.DataFrame): ewr dataset
|
|
1193
991
|
df_F (pd.DataFrame): Daily flow data
|
|
1194
992
|
df_L (pd.DataFrame): Daily level data
|
|
1195
|
-
PU_df (pd.DataFrame):
|
|
993
|
+
PU_df (pd.DataFrame): ewr results for the current planning unit iteration
|
|
1196
994
|
|
|
1197
995
|
Returns:
|
|
1198
|
-
tuple[pd.DataFrame, tuple[dict]]: EWRS results for the current planning unit iteration (updated); dictionary of
|
|
996
|
+
tuple[pd.DataFrame, tuple[dict]]: EWRS results for the current planning unit iteration (updated); dictionary of ewr event information
|
|
1199
997
|
"""
|
|
1200
998
|
|
|
1201
|
-
# Get information about
|
|
999
|
+
# Get information about ewr:
|
|
1202
1000
|
pull = data_inputs.get_EWR_components('rise_fall')
|
|
1203
|
-
EWR_info = get_EWRs(
|
|
1001
|
+
EWR_info = get_EWRs(pu, gauge, ewr, EWR_table, pull)
|
|
1204
1002
|
# Mask dates:
|
|
1205
1003
|
masked_dates = mask_dates(EWR_info, df_F)
|
|
1206
1004
|
# If there is no level data loaded in, let user know and skip the analysis
|
|
1207
1005
|
# Extract a daily timeseries for water years
|
|
1208
1006
|
water_years = wateryear_daily(df_F, EWR_info)
|
|
1209
1007
|
|
|
1210
|
-
if 'RRF' in
|
|
1008
|
+
if 'RRF' in ewr:
|
|
1211
1009
|
E, D = rate_rise_flow_calc(EWR_info, df_F[gauge].values, water_years, df_F.index, masked_dates)
|
|
1212
|
-
if 'RFF' in
|
|
1010
|
+
if 'RFF' in ewr:
|
|
1213
1011
|
E, D = rate_fall_flow_calc(EWR_info, df_F[gauge].values, water_years, df_F.index, masked_dates)
|
|
1214
|
-
if 'RRL' in
|
|
1012
|
+
if 'RRL' in ewr:
|
|
1215
1013
|
E, D = rate_rise_level_calc(EWR_info, df_L[gauge].values, water_years, df_F.index, masked_dates)
|
|
1216
|
-
if 'RFL' in
|
|
1014
|
+
if 'RFL' in ewr:
|
|
1217
1015
|
E, D = rate_fall_level_calc(EWR_info, df_L[gauge].values, water_years, df_F.index, masked_dates)
|
|
1218
1016
|
|
|
1219
|
-
PU_df = event_stats(df_F, PU_df, gauge,
|
|
1017
|
+
PU_df = event_stats(df_F, PU_df, gauge, ewr, EWR_info, E, D, water_years)
|
|
1220
1018
|
|
|
1221
1019
|
return PU_df, tuple([E])
|
|
1222
1020
|
|
|
1223
1021
|
|
|
1224
1022
|
#---------------------------------------- Checking EWRs ------------------------------------------#
|
|
1225
|
-
|
|
1226
|
-
def which_water_year_no_event(iteration: int, total_event: int, water_years: np.array) -> int:
|
|
1227
|
-
'''Finding which water year the event gap was finished in - the start of the event that broke the gap
|
|
1228
|
-
|
|
1229
|
-
Args:
|
|
1230
|
-
iteration (int): current iteration in the timeseries
|
|
1231
|
-
total_event (int): total length of the current event
|
|
1232
|
-
water_years (np.array): daily array of water year values
|
|
1233
|
-
|
|
1234
|
-
Results:
|
|
1235
|
-
int: water year assigned for the event gap
|
|
1236
|
-
|
|
1237
|
-
'''
|
|
1238
|
-
|
|
1239
|
-
start_event = water_years[iteration-total_event]
|
|
1240
|
-
|
|
1241
|
-
return start_event
|
|
1242
|
-
|
|
1243
1023
|
|
|
1244
1024
|
def which_water_year(iteration: int, total_event: int, water_years: np.array) -> int:
|
|
1245
1025
|
'''Finding which water year the majority of the event fell in. If equal, defaults to latter
|
|
@@ -1284,8 +1064,7 @@ def water_year_touches(start_date:date, end_date:date)->List[int]:
|
|
|
1284
1064
|
"""
|
|
1285
1065
|
start_wy = water_year(start_date)
|
|
1286
1066
|
end_wy = water_year(end_date)
|
|
1287
|
-
|
|
1288
|
-
return [start_wy + i for i in range(span + 1)]
|
|
1067
|
+
return [wy for wy in range(start_wy, end_wy + 1)]
|
|
1289
1068
|
|
|
1290
1069
|
def return_event_info(event:list)-> tuple:
|
|
1291
1070
|
"""given an event return information about an event
|
|
@@ -1349,7 +1128,7 @@ def years_lengths(event_info: tuple)-> list:
|
|
|
1349
1128
|
|
|
1350
1129
|
def which_year_lake_event(event_info: tuple, min_duration: int)-> int:
|
|
1351
1130
|
"""given a event info and a event min duration it returns the
|
|
1352
|
-
year the event has to be recorded according to the lake level
|
|
1131
|
+
year the event has to be recorded according to the lake level ewr rule
|
|
1353
1132
|
|
|
1354
1133
|
If not at year boundary the event will be recorded.
|
|
1355
1134
|
|
|
@@ -1386,13 +1165,13 @@ def achieved_min_volume(event: List[tuple], EWR_info: Dict)-> bool:
|
|
|
1386
1165
|
|
|
1387
1166
|
def flow_check(EWR_info: dict, iteration: int, flow: float, event: list, all_events: dict, gap_track: int,
|
|
1388
1167
|
water_years: np.array, total_event: int, flow_date: date) -> tuple:
|
|
1389
|
-
'''Checks daily flow against
|
|
1168
|
+
'''Checks daily flow against ewr threshold. Builds on event lists and no event counters.
|
|
1390
1169
|
At the end of the event, if it was long enough, the event is saved against the relevant
|
|
1391
1170
|
water year in the event dictionary. All event gaps are saved against the relevant water
|
|
1392
1171
|
year in the no event dictionary
|
|
1393
1172
|
|
|
1394
1173
|
Args:
|
|
1395
|
-
EWR_info (dict): dictionary with the parameter info of the
|
|
1174
|
+
EWR_info (dict): dictionary with the parameter info of the ewr being calculated
|
|
1396
1175
|
iteration (int): current iteration
|
|
1397
1176
|
flow (float): current flow
|
|
1398
1177
|
event (list): current event state
|
|
@@ -1426,54 +1205,6 @@ def flow_check(EWR_info: dict, iteration: int, flow: float, event: list, all_eve
|
|
|
1426
1205
|
|
|
1427
1206
|
return event, all_events, gap_track, total_event
|
|
1428
1207
|
|
|
1429
|
-
def level_change_check(EWR_info: dict, iteration: int, levels: list, event: list, all_events: dict, gap_track: int,
|
|
1430
|
-
water_years: np.array, total_event: int, level_date: date) -> tuple:
|
|
1431
|
-
'''Checks daily levels and evaluate level change in the last n days.
|
|
1432
|
-
if the change os equals or greater the event accrue and is saved against the relevant
|
|
1433
|
-
water year in the event dictionary when the change is below.
|
|
1434
|
-
|
|
1435
|
-
Args:
|
|
1436
|
-
EWR_info (dict): dictionary with the parameter info of the EWR being calculated
|
|
1437
|
-
iteration (int): current iteration
|
|
1438
|
-
levels (list): levels for the current gauge
|
|
1439
|
-
event (list): current event state
|
|
1440
|
-
all_events (dict): current all events state
|
|
1441
|
-
gap_track (int): current gap_track state
|
|
1442
|
-
water_years (np.array): list of water year for every flow iteration
|
|
1443
|
-
total_event (int): current total event state
|
|
1444
|
-
level_date (date): current level date
|
|
1445
|
-
|
|
1446
|
-
Returns:
|
|
1447
|
-
tuple: the current state of the event, all_events, gap_track, total_event
|
|
1448
|
-
|
|
1449
|
-
'''
|
|
1450
|
-
period = EWR_info['min_event']
|
|
1451
|
-
season_start = date(level_date.year, EWR_info['start_month'], 1)
|
|
1452
|
-
start_day = get_index_date(level_date) - timedelta(days=period-1)
|
|
1453
|
-
meet_level_change_condition = evaluate_level_change(EWR_info, levels, iteration, period=period)
|
|
1454
|
-
if meet_level_change_condition and start_day >= season_start:
|
|
1455
|
-
if len(event) > 0:
|
|
1456
|
-
threshold_level = (get_index_date(level_date), levels[iteration])
|
|
1457
|
-
event.append(threshold_level)
|
|
1458
|
-
if len(event) == 0:
|
|
1459
|
-
levels_to_append = levels[iteration-(period-1):iteration+1]
|
|
1460
|
-
start_of_event = [ (start_day + timedelta(days=i), l) for i, l in zip(range(period), levels_to_append)]
|
|
1461
|
-
event.extend(start_of_event)
|
|
1462
|
-
total_event += 1
|
|
1463
|
-
gap_track = EWR_info['gap_tolerance'] # reset the gapTolerance after threshold is reached
|
|
1464
|
-
else:
|
|
1465
|
-
if gap_track > 0:
|
|
1466
|
-
gap_track = gap_track - 1
|
|
1467
|
-
total_event += 1
|
|
1468
|
-
else:
|
|
1469
|
-
if len(event) > 0:
|
|
1470
|
-
all_events[water_years[iteration]].append(event)
|
|
1471
|
-
total_event = 0
|
|
1472
|
-
|
|
1473
|
-
event = []
|
|
1474
|
-
|
|
1475
|
-
return event, all_events, gap_track, total_event
|
|
1476
|
-
|
|
1477
1208
|
def get_flows_in_between_dry_spells(flows:list, iteration:int, ctf_state:dict)-> list:
|
|
1478
1209
|
"""get flows in between dry spells from the ctf_state dictionary
|
|
1479
1210
|
|
|
@@ -1514,6 +1245,26 @@ def get_full_failed_event(flows:list, iteration:int, ctf_state:dict)->list:
|
|
|
1514
1245
|
|
|
1515
1246
|
return event
|
|
1516
1247
|
|
|
1248
|
+
def get_full_failed_event_single(flows:list, iteration:int, ctf_state:dict)->list:
|
|
1249
|
+
"""get full failed event inclusive of dry spells from the ctf_state dictionary
|
|
1250
|
+
|
|
1251
|
+
Args:
|
|
1252
|
+
flows (list): current flows
|
|
1253
|
+
iteration (int): current iteration
|
|
1254
|
+
ctf_state (dict): state_of_ctf_events
|
|
1255
|
+
|
|
1256
|
+
Returns:
|
|
1257
|
+
event: failed event inclusive of dry spells
|
|
1258
|
+
"""
|
|
1259
|
+
|
|
1260
|
+
first_day_first_event = ctf_state['events'][-1][0][0]
|
|
1261
|
+
last_day_second_event = ctf_state['events'][-1][-1][0]
|
|
1262
|
+
distance_iteration = (last_day_second_event - first_day_first_event).days + 1
|
|
1263
|
+
full_failed_event_flows = flows[iteration - (distance_iteration) : iteration]
|
|
1264
|
+
event = [ (first_day_first_event + timedelta(days=i), f) for i, f in zip(range(distance_iteration), full_failed_event_flows)]
|
|
1265
|
+
|
|
1266
|
+
return event
|
|
1267
|
+
|
|
1517
1268
|
def get_threshold_events(EWR_info:dict, flows:list)->list:
|
|
1518
1269
|
"""get events that meed a threshold flow and return a list of events
|
|
1519
1270
|
|
|
@@ -1538,8 +1289,37 @@ def get_threshold_events(EWR_info:dict, flows:list)->list:
|
|
|
1538
1289
|
events.append(current_sublist)
|
|
1539
1290
|
return events
|
|
1540
1291
|
|
|
1292
|
+
def process_checks_once_ctf_period_over(EWR_info: dict, iteration: int, flows: List, water_years: np.array, all_events: dict, ctf_state: dict) -> tuple:
|
|
1293
|
+
'''
|
|
1294
|
+
Each time a cease to flow period is finished these are the checks that are made. It also gets called on the end of the time series to check if we end in an event.
|
|
1295
|
+
'''
|
|
1296
|
+
ctf_state['in_event'] = False
|
|
1297
|
+
|
|
1298
|
+
if len(ctf_state['events'][-1]) >= (2 * EWR_info["non_flow_spell"]):
|
|
1299
|
+
full_failed_event = get_full_failed_event_single(flows, iteration, ctf_state)
|
|
1300
|
+
# records the failed event inclusive of dry spells in the all event year dictionary
|
|
1301
|
+
all_events[water_years[iteration]].append(full_failed_event)
|
|
1302
|
+
|
|
1303
|
+
if len(ctf_state['events'][-1]) < EWR_info["non_flow_spell"]:
|
|
1304
|
+
ctf_state['events'].pop()
|
|
1305
|
+
|
|
1306
|
+
if len(ctf_state['events']) == 2:
|
|
1307
|
+
flows_in_between_dry_spells = get_flows_in_between_dry_spells(flows, iteration, ctf_state)
|
|
1308
|
+
events_in_between_dry_spells = get_threshold_events(EWR_info, flows_in_between_dry_spells)
|
|
1309
|
+
at_least_one_dispersal_opportunity = any([len(event) >= EWR_info['min_event'] for event in events_in_between_dry_spells])
|
|
1310
|
+
if at_least_one_dispersal_opportunity:
|
|
1311
|
+
ctf_state['events'].pop(0)
|
|
1312
|
+
if not at_least_one_dispersal_opportunity:
|
|
1313
|
+
full_failed_event = get_full_failed_event(flows, iteration, ctf_state)
|
|
1314
|
+
# records the failed event inclusive of dry spells in the all event year dictionary
|
|
1315
|
+
all_events[water_years[iteration]].append(full_failed_event)
|
|
1316
|
+
ctf_state['events'].pop(0)
|
|
1317
|
+
|
|
1318
|
+
return all_events, ctf_state
|
|
1319
|
+
|
|
1320
|
+
|
|
1541
1321
|
def flow_check_ctf(EWR_info: dict, iteration: int, flows: List, all_events: dict, water_years: np.array, flow_date: date, ctf_state: dict) -> tuple:
|
|
1542
|
-
'''Checks daily flow against
|
|
1322
|
+
'''Checks daily flow against ewr threshold and records dry spells
|
|
1543
1323
|
in the ctf_state dictionary in the events key.
|
|
1544
1324
|
When there are 2 events in the events key it evaluates if there is at least 1 phase 2 event
|
|
1545
1325
|
(i.e. event that allow Fish Dispersal) in between the dry spells. If there is no phase 2 event i.e.
|
|
@@ -1547,7 +1327,7 @@ def flow_check_ctf(EWR_info: dict, iteration: int, flows: List, all_events: dic
|
|
|
1547
1327
|
It records in the all_events dictionary from the beginning of the first dry spell to the end of the second dry spell
|
|
1548
1328
|
|
|
1549
1329
|
Args:
|
|
1550
|
-
EWR_info (dict): dictionary with the parameter info of the
|
|
1330
|
+
EWR_info (dict): dictionary with the parameter info of the ewr being calculated
|
|
1551
1331
|
iteration (int): current iteration
|
|
1552
1332
|
flow (float): current flow
|
|
1553
1333
|
event (list): current event state
|
|
@@ -1559,7 +1339,6 @@ def flow_check_ctf(EWR_info: dict, iteration: int, flows: List, all_events: dic
|
|
|
1559
1339
|
tuple: all_events, ctf_state
|
|
1560
1340
|
|
|
1561
1341
|
'''
|
|
1562
|
-
period = EWR_info["non_flow_spell"]
|
|
1563
1342
|
flow = flows[iteration]
|
|
1564
1343
|
if flow <= EWR_info["ctf_threshold"]:
|
|
1565
1344
|
threshold_flow = (get_index_date(flow_date), flow)
|
|
@@ -1570,38 +1349,24 @@ def flow_check_ctf(EWR_info: dict, iteration: int, flows: List, all_events: dic
|
|
|
1570
1349
|
new_event.append(threshold_flow)
|
|
1571
1350
|
ctf_state['events'].append(new_event)
|
|
1572
1351
|
ctf_state['in_event'] = True
|
|
1573
|
-
|
|
1574
|
-
if flow > 1:
|
|
1352
|
+
else:
|
|
1575
1353
|
if ctf_state['in_event']:
|
|
1576
|
-
ctf_state
|
|
1577
|
-
if len(ctf_state['events'][-1]) < period:
|
|
1578
|
-
ctf_state['events'].pop()
|
|
1579
|
-
if len(ctf_state['events']) == 2:
|
|
1580
|
-
flows_in_between_dry_spells = get_flows_in_between_dry_spells(flows, iteration, ctf_state)
|
|
1581
|
-
events_in_between_dry_spells = get_threshold_events(EWR_info, flows_in_between_dry_spells)
|
|
1582
|
-
at_least_one_dispersal_opportunity = any([len(event) >= EWR_info['min_event'] for event in events_in_between_dry_spells])
|
|
1583
|
-
if at_least_one_dispersal_opportunity:
|
|
1584
|
-
ctf_state['events'].pop(0)
|
|
1585
|
-
if not at_least_one_dispersal_opportunity:
|
|
1586
|
-
full_failed_event = get_full_failed_event(flows, iteration, ctf_state)
|
|
1587
|
-
# records the failed event inclusive of dry spells in the all event year dictionary
|
|
1588
|
-
all_events[water_years[iteration]].append(full_failed_event)
|
|
1589
|
-
ctf_state['events'].pop(0)
|
|
1354
|
+
all_events, ctf_state = process_checks_once_ctf_period_over(EWR_info, iteration, flows, water_years, all_events, ctf_state)
|
|
1590
1355
|
|
|
1591
1356
|
return all_events, ctf_state
|
|
1592
1357
|
|
|
1593
1358
|
def level_check(EWR_info: dict, iteration: int, level:float, level_change:float,
|
|
1594
1359
|
event: list, all_events: dict, gap_track: int,
|
|
1595
1360
|
water_years: np.array, total_event: int, level_date: date)-> tuple:
|
|
1596
|
-
"""Checks daily level against
|
|
1361
|
+
"""Checks daily level against ewr threshold. Builds on event lists and no event counters.
|
|
1597
1362
|
At the end of the event, if it was long enough, the event is saved against the relevant
|
|
1598
1363
|
water year in the event dictionary. All event gaps are saved against the relevant water
|
|
1599
1364
|
year in the no event dictionary
|
|
1600
|
-
NOTE: this
|
|
1365
|
+
NOTE: this ewr is a slight variation of the level_check_ltwp as it records the event in a different year depending on
|
|
1601
1366
|
the rules in the function which_year_lake_event
|
|
1602
1367
|
|
|
1603
1368
|
Args:
|
|
1604
|
-
EWR_info (dict): dictionary with the parameter info of the
|
|
1369
|
+
EWR_info (dict): dictionary with the parameter info of the ewr being calculated
|
|
1605
1370
|
iteration (int): current iteration
|
|
1606
1371
|
level (float): current level
|
|
1607
1372
|
level_change (float): level change in meters from previous day to current day
|
|
@@ -1644,13 +1409,13 @@ def nest_flow_check(EWR_info: dict, iteration: int, flow: float, event: list, al
|
|
|
1644
1409
|
gap_track: int, water_years: list, total_event: int,
|
|
1645
1410
|
flow_date: date, flow_percent_change: float, iteration_no_event: int)-> tuple:
|
|
1646
1411
|
|
|
1647
|
-
"""Checks daily flows against
|
|
1412
|
+
"""Checks daily flows against ewr threshold. Builds on event lists and no_event counters.
|
|
1648
1413
|
At the end of the event, if it was long enough, the event is saved against the relevant
|
|
1649
1414
|
water year in the event dictionary. All event gaps are saved against the relevant water
|
|
1650
1415
|
year in the no event dictionary.
|
|
1651
1416
|
|
|
1652
1417
|
Args:
|
|
1653
|
-
EWR_info (dict): dictionary with the parameter info of the
|
|
1418
|
+
EWR_info (dict): dictionary with the parameter info of the ewr being calculated
|
|
1654
1419
|
iteration (int): current iteration
|
|
1655
1420
|
flow (float): current flow
|
|
1656
1421
|
event (list): current event state
|
|
@@ -1687,12 +1452,12 @@ def nest_flow_check(EWR_info: dict, iteration: int, flow: float, event: list, al
|
|
|
1687
1452
|
|
|
1688
1453
|
|
|
1689
1454
|
def lowflow_check(EWR_info: dict, iteration: int, flow: float, event: list, all_events: dict, water_years: np.array, flow_date: date) -> tuple:
|
|
1690
|
-
'''Checks daily flow against the
|
|
1455
|
+
'''Checks daily flow against the ewr threshold. Saves all events to the relevant water year
|
|
1691
1456
|
in the event tracking dictionary. Saves all event gaps to the relevant water year in the
|
|
1692
1457
|
no event dictionary.
|
|
1693
1458
|
|
|
1694
1459
|
Args:
|
|
1695
|
-
EWR_info (dict): dictionary with the parameter info of the
|
|
1460
|
+
EWR_info (dict): dictionary with the parameter info of the ewr being calculated
|
|
1696
1461
|
iteration (int): current iteration
|
|
1697
1462
|
flow (float): current flow
|
|
1698
1463
|
event (list): current event state
|
|
@@ -1717,12 +1482,12 @@ def lowflow_check(EWR_info: dict, iteration: int, flow: float, event: list, all_
|
|
|
1717
1482
|
return event, all_events
|
|
1718
1483
|
|
|
1719
1484
|
def ctf_check(EWR_info: dict, iteration: int, flow: float, event: list, all_events: dict, water_years: np.array, flow_date: date) -> tuple:
|
|
1720
|
-
'''Checks daily flow against the cease to flow
|
|
1485
|
+
'''Checks daily flow against the cease to flow ewr threshold. Saves all events to the relevant
|
|
1721
1486
|
water year in the event tracking dictionary. Saves all no events to the relevant water year
|
|
1722
1487
|
in the no event dictionary.
|
|
1723
1488
|
|
|
1724
1489
|
Args:
|
|
1725
|
-
EWR_info (dict): dictionary with the parameter info of the
|
|
1490
|
+
EWR_info (dict): dictionary with the parameter info of the ewr being calculated
|
|
1726
1491
|
iteration (int): current iteration
|
|
1727
1492
|
flow (float): current flow
|
|
1728
1493
|
event (list): current event state
|
|
@@ -1745,10 +1510,6 @@ def ctf_check(EWR_info: dict, iteration: int, flow: float, event: list, all_even
|
|
|
1745
1510
|
|
|
1746
1511
|
return event, all_events
|
|
1747
1512
|
|
|
1748
|
-
def date_check(date, masked_dates):
|
|
1749
|
-
'''Pass in a date, if the date is within the range of accepted dates, return True, else False'''
|
|
1750
|
-
return True if date in masked_dates else False
|
|
1751
|
-
|
|
1752
1513
|
def check_roller_reset_points(roller:int, flow_date:date, EWR_info:Dict):
|
|
1753
1514
|
"""given a date check if roller needs reset to 0
|
|
1754
1515
|
It happens either at the start of a water year or the start of a window check
|
|
@@ -1757,7 +1518,7 @@ def check_roller_reset_points(roller:int, flow_date:date, EWR_info:Dict):
|
|
|
1757
1518
|
Args:
|
|
1758
1519
|
roller (int): how many days to look back on the volume checker window
|
|
1759
1520
|
flow_date (date): date of the current flow
|
|
1760
|
-
EWR_info (Dict): dictionary with the parameter info of the
|
|
1521
|
+
EWR_info (Dict): dictionary with the parameter info of the ewr being calculated
|
|
1761
1522
|
|
|
1762
1523
|
Returns:
|
|
1763
1524
|
(int): roller value either the same or a reset value
|
|
@@ -1772,7 +1533,7 @@ def volume_check(EWR_info:Dict, iteration:int, flow:int, event:List, all_events:
|
|
|
1772
1533
|
It looks back in a window of the size of the Accumulation period in(Days)
|
|
1773
1534
|
|
|
1774
1535
|
Args:
|
|
1775
|
-
EWR_info (Dict): dictionary with the parameter info of the
|
|
1536
|
+
EWR_info (Dict): dictionary with the parameter info of the ewr being calculated
|
|
1776
1537
|
iteration (int): current iteration
|
|
1777
1538
|
flow (int): current flow
|
|
1778
1539
|
event (List[float]): current event state
|
|
@@ -1782,7 +1543,7 @@ def volume_check(EWR_info:Dict, iteration:int, flow:int, event:List, all_events:
|
|
|
1782
1543
|
total_event (int): current total event state
|
|
1783
1544
|
flow_date (date): current flow date
|
|
1784
1545
|
roller (int): current roller state
|
|
1785
|
-
max_roller (int): current
|
|
1546
|
+
max_roller (int): current ewr max roller window
|
|
1786
1547
|
flows (List): current list of all flows being iterated
|
|
1787
1548
|
|
|
1788
1549
|
Returns:
|
|
@@ -1819,7 +1580,7 @@ def volume_check_qld(EWR_info:Dict, iteration:int, event:List, all_events:Dict,
|
|
|
1819
1580
|
This is the QLD version of the volume check
|
|
1820
1581
|
|
|
1821
1582
|
Args:
|
|
1822
|
-
EWR_info (Dict): dictionary with the parameter info of the
|
|
1583
|
+
EWR_info (Dict): dictionary with the parameter info of the ewr being calculated
|
|
1823
1584
|
iteration (int): current iteration
|
|
1824
1585
|
event (List): current event state
|
|
1825
1586
|
all_events (Dict): current all events state
|
|
@@ -1827,7 +1588,7 @@ def volume_check_qld(EWR_info:Dict, iteration:int, event:List, all_events:Dict,
|
|
|
1827
1588
|
total_event (int): current total event state
|
|
1828
1589
|
flow_date (date): current flow date
|
|
1829
1590
|
roller (int): current roller state
|
|
1830
|
-
max_roller (int): current
|
|
1591
|
+
max_roller (int): current ewr max roller window
|
|
1831
1592
|
flows (List): current list of all flows being iterated
|
|
1832
1593
|
|
|
1833
1594
|
Returns:
|
|
@@ -1858,7 +1619,7 @@ def volume_level_check_bbr(EWR_info:Dict, iteration:int, flow:float, event:List,
|
|
|
1858
1619
|
It looks back in a window of the size of the Accumulation period in(Days)
|
|
1859
1620
|
|
|
1860
1621
|
Args:
|
|
1861
|
-
EWR_info (Dict): dictionary with the parameter info of the
|
|
1622
|
+
EWR_info (Dict): dictionary with the parameter info of the ewr being calculated
|
|
1862
1623
|
iteration (int): current iteration
|
|
1863
1624
|
flow (int): current flow
|
|
1864
1625
|
event (List[float]): current event state
|
|
@@ -1868,7 +1629,7 @@ def volume_level_check_bbr(EWR_info:Dict, iteration:int, flow:float, event:List,
|
|
|
1868
1629
|
total_event (int): current total event state
|
|
1869
1630
|
flow_date (date): current flow date
|
|
1870
1631
|
roller (int): current roller state
|
|
1871
|
-
max_roller (int): current
|
|
1632
|
+
max_roller (int): current ewr max roller window
|
|
1872
1633
|
flows (List): current list of all flows being iterated
|
|
1873
1634
|
levels (List): current list of all levels being iterated
|
|
1874
1635
|
|
|
@@ -1952,7 +1713,7 @@ def water_stability_check(EWR_info:Dict, iteration:int, flows:List, all_events:D
|
|
|
1952
1713
|
if there is an opportunity record the event otherwise go to next day
|
|
1953
1714
|
|
|
1954
1715
|
Args:
|
|
1955
|
-
EWR_info (Dict): dictionary with the parameter info of the
|
|
1716
|
+
EWR_info (Dict): dictionary with the parameter info of the ewr being calculated
|
|
1956
1717
|
iteration (int): current iteration
|
|
1957
1718
|
flow (int): current flow
|
|
1958
1719
|
event (List[float]): current event state
|
|
@@ -1991,7 +1752,7 @@ def water_stability_level_check(EWR_info:Dict, iteration:int, all_events:Dict, w
|
|
|
1991
1752
|
if there is an opportunity record the event otherwise go to next day
|
|
1992
1753
|
|
|
1993
1754
|
Args:
|
|
1994
|
-
EWR_info (Dict): dictionary with the parameter info of the
|
|
1755
|
+
EWR_info (Dict): dictionary with the parameter info of the ewr being calculated
|
|
1995
1756
|
iteration (int): current iteration
|
|
1996
1757
|
event (List[float]): current event state
|
|
1997
1758
|
all_events (Dict): current all events state
|
|
@@ -2025,7 +1786,7 @@ def weirpool_check(EWR_info: dict, iteration: int, flow: float, level: float, ev
|
|
|
2025
1786
|
"""Check weirpool flow and level if meet condition and update state of the events
|
|
2026
1787
|
|
|
2027
1788
|
Args:
|
|
2028
|
-
EWR_info (dict): dictionary with the parameter info of the
|
|
1789
|
+
EWR_info (dict): dictionary with the parameter info of the ewr being calculated
|
|
2029
1790
|
iteration (int): current iteration
|
|
2030
1791
|
flow (float): current flow
|
|
2031
1792
|
level (float): current level
|
|
@@ -2066,7 +1827,7 @@ def nest_weirpool_check(EWR_info: dict, iteration: int, flow: float, level: floa
|
|
|
2066
1827
|
"""Check weirpool flow and level if meet condition and update state of the events
|
|
2067
1828
|
|
|
2068
1829
|
Args:
|
|
2069
|
-
EWR_info (Dict): dictionary with the parameter info of the
|
|
1830
|
+
EWR_info (Dict): dictionary with the parameter info of the ewr being calculated
|
|
2070
1831
|
iteration (int): current iteration
|
|
2071
1832
|
flow (float): current flow
|
|
2072
1833
|
level (float): current level
|
|
@@ -2101,45 +1862,6 @@ def nest_weirpool_check(EWR_info: dict, iteration: int, flow: float, level: floa
|
|
|
2101
1862
|
|
|
2102
1863
|
return event, all_events, gap_track, total_event
|
|
2103
1864
|
|
|
2104
|
-
def flow_level_check(EWR_info: dict, iteration: int, flow: float, level: float, event: list, all_events: dict, gap_track: int,
|
|
2105
|
-
water_years: list, total_event: int, flow_date: date, level_change: float, levels:list) -> tuple:
|
|
2106
|
-
"""Check weirpool flow and level if meet condition and update state of the events
|
|
2107
|
-
|
|
2108
|
-
Args:
|
|
2109
|
-
EWR_info (dict): dictionary with the parameter info of the EWR being calculated
|
|
2110
|
-
iteration (int): current iteration
|
|
2111
|
-
flow (float): current flow
|
|
2112
|
-
level (float): current level
|
|
2113
|
-
event (list): current event state
|
|
2114
|
-
all_events (dict): current all events state
|
|
2115
|
-
gap_track (int): current gap_track state
|
|
2116
|
-
water_years (list): list of water year for every flow iteration
|
|
2117
|
-
total_event (int): current total event state
|
|
2118
|
-
flow_date (date): current flow date
|
|
2119
|
-
weirpool_type (str): type of weirpool ewr raising of falling
|
|
2120
|
-
level_change (float): level change in meters
|
|
2121
|
-
|
|
2122
|
-
Returns:
|
|
2123
|
-
tuple: after the check return the current state of the event, all_events, gap_track, total_event
|
|
2124
|
-
"""
|
|
2125
|
-
if flow >= EWR_info['min_flow'] and check_weekly_level_change(levels, EWR_info, iteration, len(event)) and level > 0:
|
|
2126
|
-
threshold_flow = (get_index_date(flow_date), flow)
|
|
2127
|
-
event.append(threshold_flow)
|
|
2128
|
-
total_event += 1
|
|
2129
|
-
gap_track = EWR_info['gap_tolerance']
|
|
2130
|
-
|
|
2131
|
-
else:
|
|
2132
|
-
if gap_track > 0:
|
|
2133
|
-
gap_track = gap_track - 1
|
|
2134
|
-
total_event += 1
|
|
2135
|
-
else:
|
|
2136
|
-
if len(event) > 0:
|
|
2137
|
-
all_events[water_years[iteration]].append(event)
|
|
2138
|
-
total_event = 0
|
|
2139
|
-
event = []
|
|
2140
|
-
|
|
2141
|
-
return event, all_events, gap_track, total_event
|
|
2142
|
-
|
|
2143
1865
|
def flow_check_rise_fall(EWR_info: dict, iteration: int, flow: float, event: list, all_events: dict, gap_track: int,
|
|
2144
1866
|
water_years: list, total_event: int, flow_date: date, flows: list) -> tuple:
|
|
2145
1867
|
""" Check if current flow meets the treshold and manages the recording of events based on
|
|
@@ -2153,7 +1875,7 @@ def flow_check_rise_fall(EWR_info: dict, iteration: int, flow: float, event: lis
|
|
|
2153
1875
|
has fallen below the target minimum discharge metric
|
|
2154
1876
|
|
|
2155
1877
|
Args:
|
|
2156
|
-
EWR_info (dict): dictionary with the parameter info of the
|
|
1878
|
+
EWR_info (dict): dictionary with the parameter info of the ewr being calculated
|
|
2157
1879
|
iteration (int): current iteration
|
|
2158
1880
|
flow (float): current flow
|
|
2159
1881
|
event (list): current event state
|
|
@@ -2196,58 +1918,6 @@ def flow_check_rise_fall(EWR_info: dict, iteration: int, flow: float, event: lis
|
|
|
2196
1918
|
|
|
2197
1919
|
return event, all_events, gap_track, total_event
|
|
2198
1920
|
|
|
2199
|
-
|
|
2200
|
-
def flow_check_rise_fall_stepped(EWR_info: dict, iteration: int, flow: float, event: list, all_events: dict, gap_track: int,
|
|
2201
|
-
water_years: list, total_event: int, flow_date: date, flows: list) -> tuple:
|
|
2202
|
-
""" Check if current flow meets the treshold and manages the recording of events based on
|
|
2203
|
-
previous 30 days flow rise to validade event.
|
|
2204
|
-
Also check at the end of the event if leading 30 days after the evend fall of flow validates the event
|
|
2205
|
-
|
|
2206
|
-
Args:
|
|
2207
|
-
EWR_info (dict): dictionary with the parameter info of the EWR being calculated
|
|
2208
|
-
iteration (int): current iteration
|
|
2209
|
-
flow (float): current flow
|
|
2210
|
-
event (list): current event state
|
|
2211
|
-
all_events (dict): current all events state
|
|
2212
|
-
gap_track (int): current gap_track state
|
|
2213
|
-
water_years (list): list of water year for every flow iteration
|
|
2214
|
-
total_event (int): current total event state
|
|
2215
|
-
flow_date (date): current flow date
|
|
2216
|
-
flows (list): flows of the iteration
|
|
2217
|
-
|
|
2218
|
-
Returns:
|
|
2219
|
-
tuple: after the check return the current state of the event, all_events, gap_track, total_event
|
|
2220
|
-
"""
|
|
2221
|
-
|
|
2222
|
-
# if there is not an event hapening then check condition
|
|
2223
|
-
if total_event == 0:
|
|
2224
|
-
meet_condition_previous_30_days = check_period_flow_change_stepped(flows, EWR_info, iteration, "backwards", 3)
|
|
2225
|
-
|
|
2226
|
-
# if there is an event hapening then the condition is always true and only need to check flow threshold
|
|
2227
|
-
if total_event > 0:
|
|
2228
|
-
meet_condition_previous_30_days = True
|
|
2229
|
-
|
|
2230
|
-
if flow >= EWR_info['min_flow'] and meet_condition_previous_30_days:
|
|
2231
|
-
threshold_flow = (get_index_date(flow_date), flow)
|
|
2232
|
-
event.append(threshold_flow)
|
|
2233
|
-
total_event += 1
|
|
2234
|
-
gap_track = EWR_info['gap_tolerance']
|
|
2235
|
-
|
|
2236
|
-
else:
|
|
2237
|
-
if gap_track > 0:
|
|
2238
|
-
gap_track = gap_track - 1
|
|
2239
|
-
total_event += 1
|
|
2240
|
-
else:
|
|
2241
|
-
if len(event) > 0:
|
|
2242
|
-
meet_condition_next_30_days = check_period_flow_change(flows, EWR_info, iteration, "forwards", 3)
|
|
2243
|
-
if meet_condition_next_30_days:
|
|
2244
|
-
all_events[water_years[iteration]].append(event)
|
|
2245
|
-
total_event = 0
|
|
2246
|
-
event = []
|
|
2247
|
-
|
|
2248
|
-
return event, all_events, gap_track, total_event
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
1921
|
def rate_rise_flow_check(EWR_info: dict, iteration: int, event: list, all_events: dict, gap_track: int,
|
|
2252
1922
|
water_years: list, total_event: int, flow_date: date, flows: list)-> tuple:
|
|
2253
1923
|
|
|
@@ -2346,25 +2016,6 @@ def rate_fall_level_check(EWR_info: dict, iteration: int, event: list, all_event
|
|
|
2346
2016
|
|
|
2347
2017
|
return event, all_events, gap_track, total_event
|
|
2348
2018
|
|
|
2349
|
-
def is_leap_year(year:int)-> bool:
|
|
2350
|
-
""" check if the year is a leap year
|
|
2351
|
-
A leap year occurs once every four years, except for years that are divisible
|
|
2352
|
-
by 100 but not divisible by 400.
|
|
2353
|
-
For example, 1900 was not a leap year because it is divisible by 100
|
|
2354
|
-
but not divisible by 400. However, 1904 was a leap year because it is divisible by 4
|
|
2355
|
-
and not divisible by 100, or it is divisible by 400.
|
|
2356
|
-
|
|
2357
|
-
Args:
|
|
2358
|
-
year (int): year to check
|
|
2359
|
-
|
|
2360
|
-
Returns:
|
|
2361
|
-
bool: True if the year is a leap year
|
|
2362
|
-
"""
|
|
2363
|
-
if year % 4 == 0 and (year % 100 != 0 or year % 400 == 0):
|
|
2364
|
-
return True
|
|
2365
|
-
else:
|
|
2366
|
-
return False
|
|
2367
|
-
|
|
2368
2019
|
def get_water_year(month: int, year:int) -> int:
|
|
2369
2020
|
"""Get the water year for the given date
|
|
2370
2021
|
if month is 1st half then get current year
|
|
@@ -2404,7 +2055,7 @@ def filter_timing_window_non_std(flows: pd.Series, flow_date: date, start_month:
|
|
|
2404
2055
|
|
|
2405
2056
|
Args:
|
|
2406
2057
|
flows (pd.Series): series of flows
|
|
2407
|
-
EWR_info (dict): dictionary with the parameter info of the
|
|
2058
|
+
EWR_info (dict): dictionary with the parameter info of the ewr being calculated
|
|
2408
2059
|
flow_date (date): current flow date
|
|
2409
2060
|
|
|
2410
2061
|
Returns:
|
|
@@ -2424,7 +2075,7 @@ def filter_last_year_flows(flows: pd.Series, flow_date: date) -> pd.Series:
|
|
|
2424
2075
|
|
|
2425
2076
|
Args:
|
|
2426
2077
|
flows (pd.Series): series of flows
|
|
2427
|
-
EWR_info (dict): dictionary with the parameter info of the
|
|
2078
|
+
EWR_info (dict): dictionary with the parameter info of the ewr being calculated
|
|
2428
2079
|
flow_date (date): current flow date
|
|
2429
2080
|
|
|
2430
2081
|
Returns:
|
|
@@ -2478,7 +2129,7 @@ def filter_last_three_years_flows(flows: pd.Series, flow_date: date) -> pd.Serie
|
|
|
2478
2129
|
|
|
2479
2130
|
Args:
|
|
2480
2131
|
flows (pd.Series): series of flows
|
|
2481
|
-
EWR_info (dict): dictionary with the parameter info of the
|
|
2132
|
+
EWR_info (dict): dictionary with the parameter info of the ewr being calculated
|
|
2482
2133
|
flow_date (date): current flow date
|
|
2483
2134
|
|
|
2484
2135
|
Returns:
|
|
@@ -2492,17 +2143,17 @@ def filter_last_three_years_flows(flows: pd.Series, flow_date: date) -> pd.Serie
|
|
|
2492
2143
|
return flows[last_three_years_mask]
|
|
2493
2144
|
|
|
2494
2145
|
def what_cllmm_type(EWR_info: dict) -> str:
|
|
2495
|
-
"""Determine the CLLMM type based on the
|
|
2146
|
+
"""Determine the CLLMM type based on the ewr code.
|
|
2496
2147
|
|
|
2497
2148
|
Args:
|
|
2498
|
-
EWR_info (dict): dictionary with the parameter info of the
|
|
2149
|
+
EWR_info (dict): dictionary with the parameter info of the ewr being calculated
|
|
2499
2150
|
|
|
2500
2151
|
Returns:
|
|
2501
|
-
str: 'a' if the
|
|
2152
|
+
str: 'a' if the ewr code contains '_a', 'b' otherwise
|
|
2502
2153
|
"""
|
|
2503
|
-
|
|
2154
|
+
ewr = EWR_info['Code']
|
|
2504
2155
|
|
|
2505
|
-
return
|
|
2156
|
+
return ewr.split('_')[0][-1]
|
|
2506
2157
|
|
|
2507
2158
|
|
|
2508
2159
|
def barrage_flow_check(EWR_info: dict, flows: pd.Series, event: list, all_events: dict, flow_date: date) -> tuple:
|
|
@@ -2510,7 +2161,7 @@ def barrage_flow_check(EWR_info: dict, flows: pd.Series, event: list, all_events
|
|
|
2510
2161
|
then save the results in the events list and all events dictionary
|
|
2511
2162
|
|
|
2512
2163
|
Args:
|
|
2513
|
-
EWR_info (dict): dictionary with the parameter info of the
|
|
2164
|
+
EWR_info (dict): dictionary with the parameter info of the ewr being calculated
|
|
2514
2165
|
flows (pd.Series): series of flows
|
|
2515
2166
|
event (list): current event state
|
|
2516
2167
|
all_events (dict): current all events state
|
|
@@ -2524,7 +2175,7 @@ def barrage_flow_check(EWR_info: dict, flows: pd.Series, event: list, all_events
|
|
|
2524
2175
|
if cllmm_type == 'a':
|
|
2525
2176
|
last_year_flows = filter_last_year_flows(flows, flow_date)
|
|
2526
2177
|
|
|
2527
|
-
if 'S' in EWR_info['
|
|
2178
|
+
if 'S' in EWR_info['Code']:
|
|
2528
2179
|
if last_year_flows.sum() >= EWR_info['annual_barrage_flow']:
|
|
2529
2180
|
threshold_flow = (get_index_date(flow_date), last_year_flows.sum())
|
|
2530
2181
|
event.append(threshold_flow)
|
|
@@ -2533,13 +2184,13 @@ def barrage_flow_check(EWR_info: dict, flows: pd.Series, event: list, all_events
|
|
|
2533
2184
|
start_date_peak = EWR_info['high_release_window_start']
|
|
2534
2185
|
end_date_peak = EWR_info['high_release_window_end']
|
|
2535
2186
|
high_release_window_flows = filter_timing_window_std(flows, flow_date, start_date_peak, end_date_peak)
|
|
2536
|
-
if start_date_peak < 7 and end_date_peak
|
|
2187
|
+
if start_date_peak < 7 and end_date_peak >= 7:
|
|
2537
2188
|
high_release_window_flows = filter_timing_window_non_std(flows, flow_date, start_date_peak, end_date_peak)
|
|
2538
2189
|
|
|
2539
2190
|
start_date_min = EWR_info['low_release_window_start']
|
|
2540
2191
|
end_date_min = EWR_info['low_release_window_end']
|
|
2541
2192
|
low_release_window_flows = filter_timing_window_std(flows, flow_date, start_date_min, end_date_min)
|
|
2542
|
-
if start_date_min < 7 and end_date_min
|
|
2193
|
+
if start_date_min < 7 and end_date_min >= 7:
|
|
2543
2194
|
low_release_window_flows = filter_timing_window_non_std(flows, flow_date, start_date_min, end_date_min)
|
|
2544
2195
|
|
|
2545
2196
|
if last_year_flows.sum() >= EWR_info['annual_barrage_flow'] and high_release_window_flows.sum() > low_release_window_flows.sum():
|
|
@@ -2563,7 +2214,7 @@ def coorong_check(EWR_info: dict, levels: pd.Series, event: list, all_events: di
|
|
|
2563
2214
|
"""check if current level meet the minimal level requirement for coorong levels.
|
|
2564
2215
|
|
|
2565
2216
|
Args:
|
|
2566
|
-
EWR_info (dict): dictionary with the parameter info of the
|
|
2217
|
+
EWR_info (dict): dictionary with the parameter info of the ewr being calculated
|
|
2567
2218
|
levels (pd.Series): series of levels
|
|
2568
2219
|
event (list): current event state
|
|
2569
2220
|
all_events (dict): current all events state
|
|
@@ -2597,7 +2248,7 @@ def lower_lakes_level_check(EWR_info: dict, levels: pd.Series, event: list, all_
|
|
|
2597
2248
|
If both conditions are met event is counted.
|
|
2598
2249
|
|
|
2599
2250
|
Args:
|
|
2600
|
-
EWR_info (dict): dictionary with the parameter info of the
|
|
2251
|
+
EWR_info (dict): dictionary with the parameter info of the ewr being calculated
|
|
2601
2252
|
levels (pd.Series): series of levels
|
|
2602
2253
|
event (list): current event state
|
|
2603
2254
|
all_events (dict): current all events state
|
|
@@ -2666,7 +2317,7 @@ def check_wp_level(weirpool_type: str, level: float, EWR_info: dict)-> bool:
|
|
|
2666
2317
|
Args:
|
|
2667
2318
|
weirpool_type (str): type of weirpool either 'raising' or 'falling'
|
|
2668
2319
|
level (float): current level
|
|
2669
|
-
EWR_info (dict):
|
|
2320
|
+
EWR_info (dict): ewr parameters
|
|
2670
2321
|
|
|
2671
2322
|
Returns:
|
|
2672
2323
|
bool: if meet requirements True else False
|
|
@@ -2679,30 +2330,13 @@ def check_draw_down(level_change: float, EWR_info: dict) -> bool:
|
|
|
2679
2330
|
|
|
2680
2331
|
Args:
|
|
2681
2332
|
level_change (float): change in meters
|
|
2682
|
-
EWR_info (dict):
|
|
2333
|
+
EWR_info (dict): ewr parameters
|
|
2683
2334
|
|
|
2684
2335
|
Returns:
|
|
2685
2336
|
bool: if pass test returns True and fail return False
|
|
2686
2337
|
"""
|
|
2687
2338
|
return level_change <= float(EWR_info['drawdown_rate']) if float(EWR_info['drawdown_rate']) else True
|
|
2688
2339
|
|
|
2689
|
-
def check_daily_level_change(level_change: float, EWR_info: dict) -> bool:
|
|
2690
|
-
""" check if the daily level changes has breached the min and max boundaries
|
|
2691
|
-
if not returns True if yes then False
|
|
2692
|
-
|
|
2693
|
-
Args:
|
|
2694
|
-
level_change (float): change in meters
|
|
2695
|
-
EWR_info (dict): EWR parameters
|
|
2696
|
-
|
|
2697
|
-
Returns:
|
|
2698
|
-
bool: if pass test returns True and fail return False
|
|
2699
|
-
"""
|
|
2700
|
-
if level_change < 0:
|
|
2701
|
-
return level_change*-1 <= float(EWR_info['drawdown_rate'])
|
|
2702
|
-
else:
|
|
2703
|
-
return level_change <= float(EWR_info['max_level_raise'])
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
2340
|
def check_water_stability_flow(flows: List, iteration:int, EWR_info:Dict)-> bool:
|
|
2707
2341
|
"""Check if water flows for in the next n days if is within water flow
|
|
2708
2342
|
range for eggs and larvae stability
|
|
@@ -2744,7 +2378,7 @@ def is_egg_phase_stable(levels:list, EWR_info: dict )-> bool:
|
|
|
2744
2378
|
"""Evaluate if water stability for egg is stable
|
|
2745
2379
|
It calculated the difference between the max level in the period
|
|
2746
2380
|
and the minimum and then evaluate if the difference is
|
|
2747
|
-
less than the '
|
|
2381
|
+
less than the 'max_level_change' parameter
|
|
2748
2382
|
True otherwise returns false
|
|
2749
2383
|
|
|
2750
2384
|
Args:
|
|
@@ -2757,12 +2391,12 @@ def is_egg_phase_stable(levels:list, EWR_info: dict )-> bool:
|
|
|
2757
2391
|
max_level_in_period = max(levels)
|
|
2758
2392
|
min_level_in_period = min(levels)
|
|
2759
2393
|
max_level_change = max_level_in_period - min_level_in_period
|
|
2760
|
-
return max_level_change <= EWR_info["
|
|
2394
|
+
return max_level_change <= EWR_info["max_level_change"]
|
|
2761
2395
|
|
|
2762
2396
|
def is_larva_phase_stable(levels:list, EWR_info: dict )-> bool:
|
|
2763
2397
|
"""Evaluate if water stability for larva is stable
|
|
2764
2398
|
If calculated the max daily change is less than
|
|
2765
|
-
the '
|
|
2399
|
+
the 'max_level_change' parameter then return
|
|
2766
2400
|
True otherwise returns false
|
|
2767
2401
|
|
|
2768
2402
|
Args:
|
|
@@ -2774,7 +2408,7 @@ def is_larva_phase_stable(levels:list, EWR_info: dict )-> bool:
|
|
|
2774
2408
|
"""
|
|
2775
2409
|
daily_changes = [ abs(levels[i] - levels[i-1]) for i in range(1, len(levels))]
|
|
2776
2410
|
max_daily_change = max(daily_changes) if daily_changes else 0
|
|
2777
|
-
return max_daily_change <= EWR_info["
|
|
2411
|
+
return max_daily_change <= EWR_info["max_level_change"]
|
|
2778
2412
|
|
|
2779
2413
|
|
|
2780
2414
|
def check_water_stability_level(levels: List, iteration:int, EWR_info:Dict)-> bool:
|
|
@@ -2805,44 +2439,6 @@ def check_water_stability_level(levels: List, iteration:int, EWR_info:Dict)-> bo
|
|
|
2805
2439
|
is_larva_level_stable = is_larva_phase_stable(larva_levels_to_check, EWR_info )
|
|
2806
2440
|
|
|
2807
2441
|
return all([is_egg_level_stable, is_larva_level_stable])
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
def check_weekly_level_change(levels: list, EWR_info: dict, iteration: int, event_length: int) -> bool:
|
|
2811
|
-
"""Check if the level change from 7 days ago to today is within the maximum allowed in a week
|
|
2812
|
-
for raise and fall.
|
|
2813
|
-
|
|
2814
|
-
Args:
|
|
2815
|
-
levels (float): Level time series values
|
|
2816
|
-
EWR_info (dict): EWR parameters
|
|
2817
|
-
|
|
2818
|
-
Returns:
|
|
2819
|
-
bool: if pass test returns True and fail return False
|
|
2820
|
-
"""
|
|
2821
|
-
level_drop_week_max = float(EWR_info["drawdown_rate"])*7
|
|
2822
|
-
level_raise_week_max = float(EWR_info["max_level_raise"])*7
|
|
2823
|
-
|
|
2824
|
-
if event_length < 7 :
|
|
2825
|
-
current_weekly_change = levels[iteration] - levels[iteration + 1 - event_length]
|
|
2826
|
-
else:
|
|
2827
|
-
current_weekly_change = levels[iteration] - levels[iteration - 6 ]
|
|
2828
|
-
return (current_weekly_change >= level_drop_week_max*-1) if current_weekly_change < 0 else (current_weekly_change <= level_raise_week_max)
|
|
2829
|
-
|
|
2830
|
-
def evaluate_level_change(EWR_info:dict, levels:list, iteration:int, period:int = 7) -> bool:
|
|
2831
|
-
"""Evaluate if in the last period days the level has changes per requirement
|
|
2832
|
-
|
|
2833
|
-
Args:
|
|
2834
|
-
EWR_info (dict): EWR parameters
|
|
2835
|
-
levels (list): Level time series values
|
|
2836
|
-
iteration (int): current iteration
|
|
2837
|
-
period (int, optional): lookback period. Defaults to 7.
|
|
2838
|
-
|
|
2839
|
-
Returns:
|
|
2840
|
-
bool: True is level change is within the parameters and False otherwise
|
|
2841
|
-
"""
|
|
2842
|
-
level_change = levels[iteration] - levels[iteration - (period - 1) ]
|
|
2843
|
-
|
|
2844
|
-
return False if len(levels[:iteration+1]) < period else ( level_change > EWR_info['min_level_rise'])
|
|
2845
|
-
|
|
2846
2442
|
|
|
2847
2443
|
def calculate_change(values:List)-> List:
|
|
2848
2444
|
"""Calcualte the change in values for items from a list
|
|
@@ -2936,7 +2532,7 @@ def check_period_flow_change(flows: list, EWR_info: dict, iteration: int, mode:
|
|
|
2936
2532
|
|
|
2937
2533
|
Args:
|
|
2938
2534
|
flows (list): Flow time series values
|
|
2939
|
-
EWR_info (dict):
|
|
2535
|
+
EWR_info (dict):ewr parameters
|
|
2940
2536
|
iteration (int): current iteration
|
|
2941
2537
|
mode (str): mode to look for flow change. Can be backwards to check before start an event or forwards
|
|
2942
2538
|
to check after an event ends.
|
|
@@ -2946,10 +2542,9 @@ def check_period_flow_change(flows: list, EWR_info: dict, iteration: int, mode:
|
|
|
2946
2542
|
bool: Return True is meet condition and False if don't
|
|
2947
2543
|
"""
|
|
2948
2544
|
|
|
2949
|
-
max_raise = float(EWR_info["
|
|
2545
|
+
max_raise = float(EWR_info["max_level_change"])
|
|
2950
2546
|
max_fall = float(EWR_info['drawdown_rate'])
|
|
2951
2547
|
|
|
2952
|
-
|
|
2953
2548
|
if mode == "backwards":
|
|
2954
2549
|
last_30_days_flows = flows[iteration - 29:iteration + 1]
|
|
2955
2550
|
last_30_days_flows_change = calculate_change(last_30_days_flows)
|
|
@@ -2973,7 +2568,7 @@ def check_period_flow_change_stepped(flows: list, EWR_info: dict, iteration: int
|
|
|
2973
2568
|
|
|
2974
2569
|
Args:
|
|
2975
2570
|
flows (list): Flow time series values
|
|
2976
|
-
EWR_info (dict):
|
|
2571
|
+
EWR_info (dict):ewr parameters
|
|
2977
2572
|
iteration (int): current iteration
|
|
2978
2573
|
mode (str): mode to look for flow change. Can be backwards to check before start an event or forwards
|
|
2979
2574
|
to check after an event ends.
|
|
@@ -3003,28 +2598,6 @@ def check_period_flow_change_stepped(flows: list, EWR_info: dict, iteration: int
|
|
|
3003
2598
|
next_30_days_flows_change = calculate_change_previous_day(next_30_days_flows)
|
|
3004
2599
|
return min(next_30_days_flows_change) >= EWR_info['rate_of_fall_stage']
|
|
3005
2600
|
|
|
3006
|
-
def check_cease_flow_period(flows: list, iteration: int, period:int) -> bool:
|
|
3007
|
-
"""Check if the there is a period of "period" days ending 90 days (hydrological constraint)
|
|
3008
|
-
before the start of the flow event.
|
|
3009
|
-
This to allow a ramp up period for the flow event.
|
|
3010
|
-
e.g. Need to have a CTF ie flows <= 1 lasting the period (e.g 365 days) 90 days imediate beore the start
|
|
3011
|
-
of the flow thresfold event.
|
|
3012
|
-
Rationale from QLD EWR: followign a non-flow spell of 365 days (1 year)
|
|
3013
|
-
Args:
|
|
3014
|
-
flows (list): Flow time series values
|
|
3015
|
-
iteration (int): current iteration
|
|
3016
|
-
period (int): period of the minimum duration of the cease to flow in days
|
|
3017
|
-
|
|
3018
|
-
Returns:
|
|
3019
|
-
bool: Return True if meet condition and False if not
|
|
3020
|
-
"""
|
|
3021
|
-
|
|
3022
|
-
hydrological_constraint_days = 90
|
|
3023
|
-
end_of_ctf_period = iteration - hydrological_constraint_days
|
|
3024
|
-
beginning_of_ctf_period = end_of_ctf_period - period
|
|
3025
|
-
|
|
3026
|
-
return max(flows[beginning_of_ctf_period:end_of_ctf_period]) <= 1 if end_of_ctf_period >= period else False
|
|
3027
|
-
|
|
3028
2601
|
def check_weekly_drawdown(levels: list, EWR_info: dict, iteration: int, event_length: int) -> bool:
|
|
3029
2602
|
"""Check if the level change from 7 days ago to today changed more than the maximum allowed in a week.
|
|
3030
2603
|
It will return True if the drawdown is within the allowed drawdown_rate_week in cm/week and False if it is above.
|
|
@@ -3034,7 +2607,7 @@ def check_weekly_drawdown(levels: list, EWR_info: dict, iteration: int, event_le
|
|
|
3034
2607
|
|
|
3035
2608
|
Args:
|
|
3036
2609
|
levels (float): Level time series values
|
|
3037
|
-
EWR_info (dict):
|
|
2610
|
+
EWR_info (dict): ewr parameters
|
|
3038
2611
|
iteration (int): current iteration
|
|
3039
2612
|
event_legth (int): current event length
|
|
3040
2613
|
|
|
@@ -3072,7 +2645,7 @@ def check_nest_percent_drawdown(flow_percent_change: float, EWR_info: dict, flow
|
|
|
3072
2645
|
|
|
3073
2646
|
Args:
|
|
3074
2647
|
flow_percent_change (float): flow percent change
|
|
3075
|
-
EWR_info (Dict):
|
|
2648
|
+
EWR_info (Dict): ewr parameters
|
|
3076
2649
|
flow (float): current flow
|
|
3077
2650
|
|
|
3078
2651
|
Returns:
|
|
@@ -3143,7 +2716,7 @@ def last_year_peak_within_window(last_year_peak: float, levels: pd.Series, EWR_
|
|
|
3143
2716
|
|
|
3144
2717
|
Args:
|
|
3145
2718
|
last_year_peak_date (date): date of the last year peak
|
|
3146
|
-
EWR_info (Dict):
|
|
2719
|
+
EWR_info (Dict): ewr parameters
|
|
3147
2720
|
|
|
3148
2721
|
Returns:
|
|
3149
2722
|
bool: True if it is within the window otherwise False
|
|
@@ -3166,7 +2739,7 @@ def last_year_low_within_window(last_year_low: float, levels: pd.Series, EWR_in
|
|
|
3166
2739
|
|
|
3167
2740
|
Args:
|
|
3168
2741
|
last_year_peak_date (date): date of the last year peak
|
|
3169
|
-
EWR_info (Dict):
|
|
2742
|
+
EWR_info (Dict): ewr parameters
|
|
3170
2743
|
|
|
3171
2744
|
Returns:
|
|
3172
2745
|
bool: True if it is within the window otherwise False
|
|
@@ -3187,10 +2760,10 @@ def last_year_low_within_window(last_year_low: float, levels: pd.Series, EWR_in
|
|
|
3187
2760
|
|
|
3188
2761
|
|
|
3189
2762
|
def calc_nest_cut_date(EWR_info: dict, iteration: int, dates: list) -> date:
|
|
3190
|
-
"""Calculates the last date (date of the month) the nest
|
|
2763
|
+
"""Calculates the last date (date of the month) the nest ewr event is valid
|
|
3191
2764
|
|
|
3192
2765
|
Args:
|
|
3193
|
-
EWR_info (Dict):
|
|
2766
|
+
EWR_info (Dict): ewr parameters
|
|
3194
2767
|
iteration (int): current iteration
|
|
3195
2768
|
dates (List): time series dates
|
|
3196
2769
|
|
|
@@ -3208,7 +2781,7 @@ def lowflow_calc(EWR_info: dict, flows: np.array, water_years: np.array, dates:
|
|
|
3208
2781
|
each water year.
|
|
3209
2782
|
|
|
3210
2783
|
Args:
|
|
3211
|
-
EWR_info (dict): dictionary with the parameter info of the
|
|
2784
|
+
EWR_info (dict): dictionary with the parameter info of the ewr being calculated
|
|
3212
2785
|
flows (np.array): array of daily flows
|
|
3213
2786
|
water_years (np.array): array of daily water year values
|
|
3214
2787
|
dates (np.array): array of dates
|
|
@@ -3249,7 +2822,7 @@ def ctf_calc_anytime(EWR_info: dict, flows: np.array, water_years: np.array, dat
|
|
|
3249
2822
|
water year.
|
|
3250
2823
|
|
|
3251
2824
|
Args:
|
|
3252
|
-
EWR_info (dict): dictionary with the parameter info of the
|
|
2825
|
+
EWR_info (dict): dictionary with the parameter info of the ewr being calculated
|
|
3253
2826
|
flows (np.array): array of daily flows
|
|
3254
2827
|
water_years (np.array): array of daily water year values
|
|
3255
2828
|
dates (np.array): array of dates
|
|
@@ -3286,7 +2859,7 @@ def ctf_calc(EWR_info: dict, flows: np.array, water_years: np.array, dates: np.a
|
|
|
3286
2859
|
water year.
|
|
3287
2860
|
|
|
3288
2861
|
Args:
|
|
3289
|
-
EWR_info (dict): dictionary with the parameter info of the
|
|
2862
|
+
EWR_info (dict): dictionary with the parameter info of the ewr being calculated
|
|
3290
2863
|
flows (np.array): array of daily flows
|
|
3291
2864
|
water_years (np.array): array of daily water year values
|
|
3292
2865
|
dates (np.array): array of dates
|
|
@@ -3326,7 +2899,7 @@ def flow_calc(EWR_info: dict, flows: np.array, water_years: np.array, dates: np.
|
|
|
3326
2899
|
therefore reset at the end of each water year.
|
|
3327
2900
|
|
|
3328
2901
|
Args:
|
|
3329
|
-
EWR_info (dict): dictionary with the parameter info of the
|
|
2902
|
+
EWR_info (dict): dictionary with the parameter info of the ewr being calculated
|
|
3330
2903
|
flows (np.array): array of daily flows
|
|
3331
2904
|
water_years (np.array): array of daily water year values
|
|
3332
2905
|
dates (np.array): array of dates
|
|
@@ -3366,59 +2939,13 @@ def flow_calc(EWR_info: dict, flows: np.array, water_years: np.array, dates: np.
|
|
|
3366
2939
|
|
|
3367
2940
|
return all_events, durations
|
|
3368
2941
|
|
|
3369
|
-
|
|
3370
|
-
def level_change_calc(EWR_info: dict, levels: np.array, water_years: np.array, dates: np.array, masked_dates: set) -> tuple:
|
|
3371
|
-
'''For calculating level change EWRs with a time constraint within their requirements. Events are
|
|
3372
|
-
therefore reset at the end of each water year.
|
|
3373
|
-
|
|
3374
|
-
Args:
|
|
3375
|
-
EWR_info (dict): dictionary with the parameter info of the EWR being calculated
|
|
3376
|
-
flows (np.array): array of daily flows
|
|
3377
|
-
water_years (np.array): array of daily water year values
|
|
3378
|
-
dates (np.array): array of dates
|
|
3379
|
-
masked_dates (set): Dates within required date range
|
|
3380
|
-
|
|
3381
|
-
Results:
|
|
3382
|
-
tuple[dict, dict, list, list]: dictionaries of all events and event gaps in timeseries. Lists of annual required durations
|
|
3383
|
-
|
|
3384
|
-
'''
|
|
3385
|
-
# Declare variables:
|
|
3386
|
-
event = []
|
|
3387
|
-
total_event = 0
|
|
3388
|
-
all_events = construct_event_dict(water_years)
|
|
3389
|
-
durations = []
|
|
3390
|
-
gap_track = 0
|
|
3391
|
-
# Iterate over flow timeseries, sending to the flow_check function each iteration:
|
|
3392
|
-
for i, level in enumerate(levels[:-1]):
|
|
3393
|
-
if dates[i] in masked_dates:
|
|
3394
|
-
flow_date = dates[i]
|
|
3395
|
-
event, all_events, gap_track, total_event = level_change_check(EWR_info, i, levels, event, all_events, gap_track, water_years, total_event, flow_date)
|
|
3396
|
-
# At the end of each water year, save any ongoing events and event gaps to the dictionaries, and reset the list and counter
|
|
3397
|
-
if water_years[i] != water_years[i+1]:
|
|
3398
|
-
if len(event) > 0:
|
|
3399
|
-
all_events[water_years[i]].append(event)
|
|
3400
|
-
total_event = 0
|
|
3401
|
-
event = []
|
|
3402
|
-
durations.append(EWR_info['duration'])
|
|
3403
|
-
|
|
3404
|
-
# Check final iteration in the flow timeseries, saving any ongoing events/event gaps to their spots in the dictionaries:
|
|
3405
|
-
if dates[-1] in masked_dates:
|
|
3406
|
-
level_date = dates[-1]
|
|
3407
|
-
event, all_events, gap_track, total_event = level_change_check(EWR_info, -1, levels, event, all_events, gap_track, water_years, total_event, flow_date)
|
|
3408
|
-
if len(event) > 0:
|
|
3409
|
-
all_events[water_years[-1]].append(event)
|
|
3410
|
-
total_event = 0
|
|
3411
|
-
durations.append(EWR_info['duration'])
|
|
3412
|
-
|
|
3413
|
-
return all_events, durations
|
|
3414
|
-
|
|
3415
2942
|
def flow_calc_check_ctf(EWR_info: dict, flows: np.array, water_years: np.array, dates: np.array, masked_dates: set) -> tuple:
|
|
3416
2943
|
'''For calculating flow EWRs with a time constraint within their requirements. Events are
|
|
3417
2944
|
therefore reset at the end of each water year. Also check at the begining of any event that in the last
|
|
3418
2945
|
n days there was a period of ctf
|
|
3419
2946
|
|
|
3420
2947
|
Args:
|
|
3421
|
-
EWR_info (dict): dictionary with the parameter info of the
|
|
2948
|
+
EWR_info (dict): dictionary with the parameter info of the ewr being calculated
|
|
3422
2949
|
flows (np.array): array of daily flows
|
|
3423
2950
|
water_years (np.array): array of daily water year values
|
|
3424
2951
|
dates (np.array): array of dates
|
|
@@ -3443,7 +2970,9 @@ def flow_calc_check_ctf(EWR_info: dict, flows: np.array, water_years: np.array,
|
|
|
3443
2970
|
# Check final iteration in the flow timeseries, saving any ongoing events/event gaps to their spots in the dictionaries:
|
|
3444
2971
|
if dates[-1] in masked_dates:
|
|
3445
2972
|
flow_date = dates[-1]
|
|
3446
|
-
|
|
2973
|
+
if ctf_state['in_event']:
|
|
2974
|
+
all_events, ctf_state = process_checks_once_ctf_period_over(EWR_info, -1, flows, water_years, all_events, ctf_state)
|
|
2975
|
+
|
|
3447
2976
|
durations.append(EWR_info['duration'])
|
|
3448
2977
|
|
|
3449
2978
|
return all_events, durations
|
|
@@ -3453,7 +2982,7 @@ def flow_calc_anytime(EWR_info: dict, flows: np.array, water_years: np.array, da
|
|
|
3453
2982
|
water year boundaries will be saved to the water year where the majority of event days were.
|
|
3454
2983
|
|
|
3455
2984
|
Args:
|
|
3456
|
-
EWR_info (dict): dictionary with the parameter info of the
|
|
2985
|
+
EWR_info (dict): dictionary with the parameter info of the ewr being calculated
|
|
3457
2986
|
flows (np.array): array of daily flows
|
|
3458
2987
|
water_years (np.array): array of daily water year values
|
|
3459
2988
|
dates (np.array): array of dates
|
|
@@ -3486,18 +3015,18 @@ def flow_calc_anytime(EWR_info: dict, flows: np.array, water_years: np.array, da
|
|
|
3486
3015
|
|
|
3487
3016
|
|
|
3488
3017
|
def lake_calc(EWR_info: dict, levels: np.array, water_years: np.array, dates: np.array, masked_dates: set)-> tuple:
|
|
3489
|
-
"""For calculating lake level
|
|
3018
|
+
"""For calculating lake level ewr with or without time constraint (anytime).
|
|
3490
3019
|
At the end of each water year save ongoing event, however not resetting the event list.
|
|
3491
3020
|
Let the level_check_ltwp_alt record the event when it finishes and reset the event list.
|
|
3492
|
-
NOTE: this
|
|
3021
|
+
NOTE: this ewr is a slight variation of the lake_calc_ltwp as it records the event in a different year depending on
|
|
3493
3022
|
the rules in the function which_year_lake_event
|
|
3494
3023
|
|
|
3495
3024
|
Args:
|
|
3496
|
-
EWR_info (dict): dictionary with the parameter info of the
|
|
3497
|
-
levels (np.array): List with all the levels for the current calculated
|
|
3498
|
-
water_years (np.array): List of the water year of each day of the current calculated
|
|
3499
|
-
dates (np.array): List of the dates of the current calculated
|
|
3500
|
-
masked_dates (set): List of the dates that the
|
|
3025
|
+
EWR_info (dict): dictionary with the parameter info of the ewr being calculated
|
|
3026
|
+
levels (np.array): List with all the levels for the current calculated ewr
|
|
3027
|
+
water_years (np.array): List of the water year of each day of the current calculated ewr
|
|
3028
|
+
dates (np.array): List of the dates of the current calculated ewr
|
|
3029
|
+
masked_dates (set): List of the dates that the ewr needs to be calculated i.e. the time window.
|
|
3501
3030
|
|
|
3502
3031
|
Returns:
|
|
3503
3032
|
tuple: final output with the calculation of volume all_events, durations
|
|
@@ -3539,16 +3068,16 @@ def lake_calc(EWR_info: dict, levels: np.array, water_years: np.array, dates: np
|
|
|
3539
3068
|
return all_events, durations
|
|
3540
3069
|
|
|
3541
3070
|
def cumulative_calc(EWR_info: dict, flows: np.array, water_years: np.array, dates: np.array, masked_dates: set)-> tuple:
|
|
3542
|
-
""" Calculate and manage state of the Volume
|
|
3071
|
+
""" Calculate and manage state of the Volume ewr calculations. It delegates to volume_check function
|
|
3543
3072
|
the record of events when they not end at the end of a water year, otherwise it resets the event at year boundary
|
|
3544
3073
|
adopting the hybrid method
|
|
3545
3074
|
|
|
3546
3075
|
Args:
|
|
3547
|
-
EWR_info (dict): dictionary with the parameter info of the
|
|
3548
|
-
flows (np.array): List with all the flows for the current calculated
|
|
3549
|
-
water_years (np.array): List of the water year of each day of the current calculated
|
|
3550
|
-
dates (np.array): List of the dates of the current calculated
|
|
3551
|
-
masked_dates (set): List of the dates that the
|
|
3076
|
+
EWR_info (dict): dictionary with the parameter info of the ewr being calculated
|
|
3077
|
+
flows (np.array): List with all the flows for the current calculated ewr
|
|
3078
|
+
water_years (np.array): List of the water year of each day of the current calculated ewr
|
|
3079
|
+
dates (np.array): List of the dates of the current calculated ewr
|
|
3080
|
+
masked_dates (set): List of the dates that the ewr needs to be calculated i.e. the time window.
|
|
3552
3081
|
|
|
3553
3082
|
Returns:
|
|
3554
3083
|
tuple: final output with the calculation of volume all_events, durations
|
|
@@ -3589,16 +3118,16 @@ def cumulative_calc(EWR_info: dict, flows: np.array, water_years: np.array, date
|
|
|
3589
3118
|
return all_events, durations
|
|
3590
3119
|
|
|
3591
3120
|
def cumulative_calc_qld(EWR_info: dict, flows: np.array, water_years: np.array, dates: np.array, masked_dates: set)-> tuple:
|
|
3592
|
-
""" Calculate and manage state of the Volume
|
|
3121
|
+
""" Calculate and manage state of the Volume ewr calculations. It delegates to volume_check function
|
|
3593
3122
|
the record of events when they not end at the end of a water year.
|
|
3594
3123
|
This version does not reset event at year boundary, it accumulates the event until volume drops below threshold.
|
|
3595
3124
|
|
|
3596
3125
|
Args:
|
|
3597
|
-
EWR_info (dict): dictionary with the parameter info of the
|
|
3598
|
-
flows (np.array): List with all the flows for the current calculated
|
|
3599
|
-
water_years (np.array): List of the water year of each day of the current calculated
|
|
3600
|
-
dates (np.array): List of the dates of the current calculated
|
|
3601
|
-
masked_dates (set): List of the dates that the
|
|
3126
|
+
EWR_info (dict): dictionary with the parameter info of the ewr being calculated
|
|
3127
|
+
flows (np.array): List with all the flows for the current calculated ewr
|
|
3128
|
+
water_years (np.array): List of the water year of each day of the current calculated ewr
|
|
3129
|
+
dates (np.array): List of the dates of the current calculated ewr
|
|
3130
|
+
masked_dates (set): List of the dates that the ewr needs to be calculated i.e. the time window.
|
|
3602
3131
|
|
|
3603
3132
|
Returns:
|
|
3604
3133
|
tuple: final output with the calculation of volume all_events, durations
|
|
@@ -3632,17 +3161,17 @@ def cumulative_calc_qld(EWR_info: dict, flows: np.array, water_years: np.array,
|
|
|
3632
3161
|
return all_events, durations
|
|
3633
3162
|
|
|
3634
3163
|
def cumulative_calc_bbr(EWR_info: dict, flows: np.array, levels: np.array, water_years: np.array, dates: np.array, masked_dates: set)-> tuple:
|
|
3635
|
-
""" Calculate and manage state of the Volume
|
|
3164
|
+
""" Calculate and manage state of the Volume ewr calculations. It delegates to volume_check function
|
|
3636
3165
|
the record of events when they not end at the end of a water year, otherwise it resets the event at year boundary
|
|
3637
3166
|
adopting the hybrid method
|
|
3638
3167
|
|
|
3639
3168
|
Args:
|
|
3640
|
-
EWR_info (dict): dictionary with the parameter info of the
|
|
3641
|
-
flows (np.array): List with all the flows for the current calculated
|
|
3642
|
-
levels (np.array): List with all the levels for the current calculated
|
|
3643
|
-
water_years (np.array): List of the water year of each day of the current calculated
|
|
3644
|
-
dates (np.array): List of the dates of the current calculated
|
|
3645
|
-
masked_dates (set): List of the dates that the
|
|
3169
|
+
EWR_info (dict): dictionary with the parameter info of the ewr being calculated
|
|
3170
|
+
flows (np.array): List with all the flows for the current calculated ewr
|
|
3171
|
+
levels (np.array): List with all the levels for the current calculated ewr
|
|
3172
|
+
water_years (np.array): List of the water year of each day of the current calculated ewr
|
|
3173
|
+
dates (np.array): List of the dates of the current calculated ewr
|
|
3174
|
+
masked_dates (set): List of the dates that the ewr needs to be calculated i.e. the time window.
|
|
3646
3175
|
|
|
3647
3176
|
Returns:
|
|
3648
3177
|
tuple: final output with the calculation of volume all_events, durations
|
|
@@ -3679,12 +3208,12 @@ def water_stability_calc(EWR_info: dict, flows: np.array, levels: np.array, wate
|
|
|
3679
3208
|
if within season it will look forward if there is an opportunity given the egg and larvae phases are met
|
|
3680
3209
|
|
|
3681
3210
|
Args:
|
|
3682
|
-
EWR_info (dict): dictionary with the parameter info of the
|
|
3683
|
-
flows (np.array): List with all the flows for the current calculated
|
|
3684
|
-
levels (np.array): List with all the levels for the current calculated
|
|
3685
|
-
water_years (np.array): List of the water year of each day of the current calculated
|
|
3686
|
-
dates (np.array): List of the dates of the current calculated
|
|
3687
|
-
masked_dates (set): List of the dates that the
|
|
3211
|
+
EWR_info (dict): dictionary with the parameter info of the ewr being calculated
|
|
3212
|
+
flows (np.array): List with all the flows for the current calculated ewr
|
|
3213
|
+
levels (np.array): List with all the levels for the current calculated ewr
|
|
3214
|
+
water_years (np.array): List of the water year of each day of the current calculated ewr
|
|
3215
|
+
dates (np.array): List of the dates of the current calculated ewr
|
|
3216
|
+
masked_dates (set): List of the dates that the ewr needs to be calculated i.e. the time window.
|
|
3688
3217
|
|
|
3689
3218
|
Returns:
|
|
3690
3219
|
tuple: final output with the calculation of volume all_events, durations
|
|
@@ -3708,12 +3237,12 @@ def water_stability_level_calc(EWR_info: dict, levels: np.array, water_years: np
|
|
|
3708
3237
|
if within season it will look forward if there is an opportunity given the egg and larvae phases are met
|
|
3709
3238
|
|
|
3710
3239
|
Args:
|
|
3711
|
-
EWR_info (dict): dictionary with the parameter info of the
|
|
3712
|
-
flows (np.array): List with all the flows for the current calculated
|
|
3713
|
-
levels (np.array): List with all the levels for the current calculated
|
|
3714
|
-
water_years (np.array): List of the water year of each day of the current calculated
|
|
3715
|
-
dates (np.array): List of the dates of the current calculated
|
|
3716
|
-
masked_dates (set): List of the dates that the
|
|
3240
|
+
EWR_info (dict): dictionary with the parameter info of the ewr being calculated
|
|
3241
|
+
flows (np.array): List with all the flows for the current calculated ewr
|
|
3242
|
+
levels (np.array): List with all the levels for the current calculated ewr
|
|
3243
|
+
water_years (np.array): List of the water year of each day of the current calculated ewr
|
|
3244
|
+
dates (np.array): List of the dates of the current calculated ewr
|
|
3245
|
+
masked_dates (set): List of the dates that the ewr needs to be calculated i.e. the time window.
|
|
3717
3246
|
|
|
3718
3247
|
Returns:
|
|
3719
3248
|
tuple: final output with the calculation of volume all_events, durations
|
|
@@ -3743,12 +3272,12 @@ def nest_calc_weirpool(EWR_info: dict, flows: list, levels: list, water_years: l
|
|
|
3743
3272
|
- To start and end an event the event needs to be in a time window (masked dates).
|
|
3744
3273
|
|
|
3745
3274
|
Args:
|
|
3746
|
-
EWR_info (Dict): dictionary with the parameter info of the
|
|
3747
|
-
flows (List): List with all the flows measurements for the current calculated
|
|
3748
|
-
levels (List): List with all the levels measurements for the current calculated
|
|
3749
|
-
water_years (List): List of the water year of each day of the current calculated
|
|
3750
|
-
dates (List): List of the dates of the current calculated
|
|
3751
|
-
masked_dates (List): List of the dates that the
|
|
3275
|
+
EWR_info (Dict): dictionary with the parameter info of the ewr being calculated
|
|
3276
|
+
flows (List): List with all the flows measurements for the current calculated ewr
|
|
3277
|
+
levels (List): List with all the levels measurements for the current calculated ewr
|
|
3278
|
+
water_years (List): List of the water year of each day of the current calculated ewr
|
|
3279
|
+
dates (List): List of the dates of the current calculated ewr
|
|
3280
|
+
masked_dates (List): List of the dates that the ewr needs to be calculated i.e. the time window.
|
|
3752
3281
|
weirpool_type (str, optional): type of weirpool either 'raising' or 'falling'. Defaults to "raising".
|
|
3753
3282
|
|
|
3754
3283
|
Returns:
|
|
@@ -3795,9 +3324,9 @@ def nest_calc_weirpool(EWR_info: dict, flows: list, levels: list, water_years: l
|
|
|
3795
3324
|
|
|
3796
3325
|
|
|
3797
3326
|
def nest_calc_percent_trigger(EWR_info:Dict, flows:List, water_years:List, dates:List)->tuple:
|
|
3798
|
-
"""Do the calculation of the nesting
|
|
3327
|
+
"""Do the calculation of the nesting ewr with trigger and % drawdown
|
|
3799
3328
|
To start and event it needs to be in a trigger window
|
|
3800
|
-
To sustain the
|
|
3329
|
+
To sustain the ewr needs to
|
|
3801
3330
|
- Be above the flow (min threshold)
|
|
3802
3331
|
- Does not fall more than the % in a day if between the min and max flow i.e If it is above max flow threshold, percent drawn
|
|
3803
3332
|
down rate does not matter
|
|
@@ -3809,11 +3338,11 @@ def nest_calc_percent_trigger(EWR_info:Dict, flows:List, water_years:List, dates
|
|
|
3809
3338
|
|
|
3810
3339
|
|
|
3811
3340
|
Args:
|
|
3812
|
-
EWR_info (Dict): dictionary with the parameter info of the
|
|
3813
|
-
flows (List): List with all the flows measurements for the current calculated
|
|
3814
|
-
water_years (List): List of the water year of each day of the current calculated
|
|
3815
|
-
dates (List): List of the dates of the current calculated
|
|
3816
|
-
masked_dates (List): List of the dates that the
|
|
3341
|
+
EWR_info (Dict): dictionary with the parameter info of the ewr being calculated
|
|
3342
|
+
flows (List): List with all the flows measurements for the current calculated ewr
|
|
3343
|
+
water_years (List): List of the water year of each day of the current calculated ewr
|
|
3344
|
+
dates (List): List of the dates of the current calculated ewr
|
|
3345
|
+
masked_dates (List): List of the dates that the ewr needs to be calculated i.e. the time window.
|
|
3817
3346
|
|
|
3818
3347
|
Returns:
|
|
3819
3348
|
tuple: final output with the calculation of volume all_events, durations
|
|
@@ -3900,17 +3429,17 @@ def nest_calc_percent_trigger(EWR_info:Dict, flows:List, water_years:List, dates
|
|
|
3900
3429
|
|
|
3901
3430
|
def weirpool_calc(EWR_info: Dict, flows: List, levels: List, water_years: List, weirpool_type: str,
|
|
3902
3431
|
dates:List, masked_dates:List)-> tuple:
|
|
3903
|
-
""" Iterates each yearly flows to manage calculation of weirpool
|
|
3432
|
+
""" Iterates each yearly flows to manage calculation of weirpool ewr. It delegates to weirpool_check function
|
|
3904
3433
|
the record of events which will check the flow and level threshold as all as drawdown of event
|
|
3905
3434
|
|
|
3906
3435
|
Args:
|
|
3907
|
-
EWR_info (Dict): dictionary with the parameter info of the
|
|
3908
|
-
flows (List): List with all the flows measurements for the current calculated
|
|
3909
|
-
levels (List): List with all the levels measurements for the current calculated
|
|
3910
|
-
water_years (List): List of the water year of each day of the current calculated
|
|
3436
|
+
EWR_info (Dict): dictionary with the parameter info of the ewr being calculated
|
|
3437
|
+
flows (List): List with all the flows measurements for the current calculated ewr
|
|
3438
|
+
levels (List): List with all the levels measurements for the current calculated ewr
|
|
3439
|
+
water_years (List): List of the water year of each day of the current calculated ewr
|
|
3911
3440
|
weirpool_type (str): type of weirpool either 'raising' or 'falling'
|
|
3912
|
-
dates (List): List of the dates of the current calculated
|
|
3913
|
-
masked_dates (List): List of the dates that the
|
|
3441
|
+
dates (List): List of the dates of the current calculated ewr
|
|
3442
|
+
masked_dates (List): List of the dates that the ewr needs to be calculated i.e. the time window.
|
|
3914
3443
|
|
|
3915
3444
|
Returns:
|
|
3916
3445
|
tuple: final output with the calculation of volume all_events, durations
|
|
@@ -3952,68 +3481,17 @@ def weirpool_calc(EWR_info: Dict, flows: List, levels: List, water_years: List,
|
|
|
3952
3481
|
|
|
3953
3482
|
return all_events, durations
|
|
3954
3483
|
|
|
3955
|
-
def flow_level_calc(EWR_info: Dict, flows: List, levels: List, water_years: List,
|
|
3956
|
-
dates:List, masked_dates:List)-> tuple:
|
|
3957
|
-
""" Iterates each yearly flows to manage calculation of flow and level raise and fall. It delegates to flow_level_check function
|
|
3958
|
-
the record of events which will check the flow and level changes against the EWR requirements.
|
|
3959
|
-
Args:
|
|
3960
|
-
EWR_info (Dict): dictionary with the parameter info of the EWR being calculated
|
|
3961
|
-
flows (List): List with all the flows measurements for the current calculated EWR
|
|
3962
|
-
levels (List): List with all the levels measurements for the current calculated EWR
|
|
3963
|
-
water_years (List): List of the water year of each day of the current calculated EWR
|
|
3964
|
-
dates (List): List of the dates of the current calculated EWR
|
|
3965
|
-
masked_dates (List): List of the dates that the EWR needs to be calculated i.e. the time window.
|
|
3966
|
-
Returns:
|
|
3967
|
-
tuple: final output with the calculation of volume all_events, durations
|
|
3968
|
-
"""
|
|
3969
|
-
# Declare variables:
|
|
3970
|
-
event = []
|
|
3971
|
-
total_event = 0
|
|
3972
|
-
all_events = construct_event_dict(water_years)
|
|
3973
|
-
durations = []
|
|
3974
|
-
gap_track = 0
|
|
3975
|
-
# Iterate over flow timeseries, sending to the weirpool_check function each iteration:
|
|
3976
|
-
for i, flow in enumerate(flows[:-1]):
|
|
3977
|
-
if dates[i] in masked_dates:
|
|
3978
|
-
flow_date = dates[i]
|
|
3979
|
-
level_change = levels[i-1]-levels[i] if i > 0 else 0
|
|
3980
|
-
event, all_events, gap_track, total_event = flow_level_check(EWR_info, i, flow, levels[i], event,
|
|
3981
|
-
all_events, gap_track,
|
|
3982
|
-
water_years, total_event, flow_date, level_change, levels)
|
|
3983
|
-
# At the end of each water year, save any ongoing events and event gaps to the dictionaries, and reset the list and counter
|
|
3984
|
-
if water_years[i] != water_years[i+1]:
|
|
3985
|
-
if len(event) > 0:
|
|
3986
|
-
all_events[water_years[i]].append(event)
|
|
3987
|
-
total_event = 0
|
|
3988
|
-
event = []
|
|
3989
|
-
durations.append(EWR_info['duration'])
|
|
3990
|
-
|
|
3991
|
-
# Check final iteration in the flow timeseries, saving any ongoing events/event gaps to their spots in the dictionaries:
|
|
3992
|
-
if dates[-1] in masked_dates:
|
|
3993
|
-
flow_date = dates[-1]
|
|
3994
|
-
level_change = levels[-2]-levels[-1] if i > 0 else 0
|
|
3995
|
-
event, all_events, gap_track, total_event = flow_level_check(EWR_info, -1, flows[-1], levels[-1], event,
|
|
3996
|
-
all_events, gap_track,
|
|
3997
|
-
water_years, total_event, flow_date, level_change, levels)
|
|
3998
|
-
if len(event) > 0:
|
|
3999
|
-
all_events[water_years[-1]].append(event)
|
|
4000
|
-
total_event = 0
|
|
4001
|
-
|
|
4002
|
-
durations.append(EWR_info['duration'])
|
|
4003
|
-
|
|
4004
|
-
return all_events, durations
|
|
4005
|
-
|
|
4006
3484
|
def flow_calc_sa(EWR_info: Dict, flows: List, water_years: List,
|
|
4007
3485
|
dates:List, masked_dates:List)-> tuple:
|
|
4008
3486
|
""" Iterates each flows to manage calculation of flow and flows raise and fall. It delegates to flow_check_rise_fall function
|
|
4009
|
-
the record of events which will check the flow changes against the
|
|
3487
|
+
the record of events which will check the flow changes against the ewr requirements.
|
|
4010
3488
|
|
|
4011
3489
|
Args:
|
|
4012
|
-
EWR_info (Dict): dictionary with the parameter info of the
|
|
4013
|
-
flows (List): List with all the flows measurements for the current calculated
|
|
4014
|
-
water_years (List): List of the water year of each day of the current calculated
|
|
4015
|
-
dates (List): List of the dates of the current calculated
|
|
4016
|
-
masked_dates (List): List of the dates that the
|
|
3490
|
+
EWR_info (Dict): dictionary with the parameter info of the ewr being calculated
|
|
3491
|
+
flows (List): List with all the flows measurements for the current calculated ewr
|
|
3492
|
+
water_years (List): List of the water year of each day of the current calculated ewr
|
|
3493
|
+
dates (List): List of the dates of the current calculated ewr
|
|
3494
|
+
masked_dates (List): List of the dates that the ewr needs to be calculated i.e. the time window.
|
|
4017
3495
|
|
|
4018
3496
|
Returns:
|
|
4019
3497
|
tuple: final output with the calculation of volume all_events, durations
|
|
@@ -4061,11 +3539,11 @@ def rate_rise_flow_calc(EWR_info: Dict, flows: List, water_years: List,
|
|
|
4061
3539
|
""" Iterates each flows to manage identify events that meet the rate of flow rise requirements
|
|
4062
3540
|
|
|
4063
3541
|
Args:
|
|
4064
|
-
EWR_info (Dict): dictionary with the parameter info of the
|
|
4065
|
-
flows (List): List with all the flows measurements for the current calculated
|
|
4066
|
-
water_years (List): List of the water year of each day of the current calculated
|
|
4067
|
-
dates (List): List of the dates of the current calculated
|
|
4068
|
-
masked_dates (List): List of the dates that the
|
|
3542
|
+
EWR_info (Dict): dictionary with the parameter info of the ewr being calculated
|
|
3543
|
+
flows (List): List with all the flows measurements for the current calculated ewr
|
|
3544
|
+
water_years (List): List of the water year of each day of the current calculated ewr
|
|
3545
|
+
dates (List): List of the dates of the current calculated ewr
|
|
3546
|
+
masked_dates (List): List of the dates that the ewr needs to be calculated i.e. the time window.
|
|
4069
3547
|
|
|
4070
3548
|
Returns:
|
|
4071
3549
|
tuple: final output with the calculation of volume all_events, durations
|
|
@@ -4101,11 +3579,11 @@ def rate_fall_flow_calc(EWR_info: Dict, flows: List, water_years: List,
|
|
|
4101
3579
|
""" Iterates each flows to manage identify events that meet the rate of fall requirements
|
|
4102
3580
|
|
|
4103
3581
|
Args:
|
|
4104
|
-
EWR_info (Dict): dictionary with the parameter info of the
|
|
4105
|
-
flows (List): List with all the flows measurements for the current calculated
|
|
4106
|
-
water_years (List): List of the water year of each day of the current calculated
|
|
4107
|
-
dates (List): List of the dates of the current calculated
|
|
4108
|
-
masked_dates (List): List of the dates that the
|
|
3582
|
+
EWR_info (Dict): dictionary with the parameter info of the ewr being calculated
|
|
3583
|
+
flows (List): List with all the flows measurements for the current calculated ewr
|
|
3584
|
+
water_years (List): List of the water year of each day of the current calculated ewr
|
|
3585
|
+
dates (List): List of the dates of the current calculated ewr
|
|
3586
|
+
masked_dates (List): List of the dates that the ewr needs to be calculated i.e. the time window.
|
|
4109
3587
|
|
|
4110
3588
|
Returns:
|
|
4111
3589
|
tuple: final output with the calculation of volume all_events, durations
|
|
@@ -4144,11 +3622,11 @@ def rate_rise_level_calc(EWR_info: Dict, levels: List, water_years: List,
|
|
|
4144
3622
|
""" Iterates each flows to manage identify events that meet the rate of fall requirements
|
|
4145
3623
|
|
|
4146
3624
|
Args:
|
|
4147
|
-
EWR_info (Dict): dictionary with the parameter info of the
|
|
4148
|
-
levels (List): List with all the levels for the current calculated
|
|
4149
|
-
water_years (List): List of the water year of each day of the current calculated
|
|
4150
|
-
dates (List): List of the dates of the current calculated
|
|
4151
|
-
masked_dates (List): List of the dates that the
|
|
3625
|
+
EWR_info (Dict): dictionary with the parameter info of the ewr being calculated
|
|
3626
|
+
levels (List): List with all the levels for the current calculated ewr
|
|
3627
|
+
water_years (List): List of the water year of each day of the current calculated ewr
|
|
3628
|
+
dates (List): List of the dates of the current calculated ewr
|
|
3629
|
+
masked_dates (List): List of the dates that the ewr needs to be calculated i.e. the time window.
|
|
4152
3630
|
|
|
4153
3631
|
Returns:
|
|
4154
3632
|
tuple: final output with the calculation of volume all_events, durations
|
|
@@ -4185,11 +3663,11 @@ def rate_fall_level_calc(EWR_info: Dict, levels: List, water_years: List,
|
|
|
4185
3663
|
""" Iterates each flows to manage identify events that meet the rate of fall requirements
|
|
4186
3664
|
|
|
4187
3665
|
Args:
|
|
4188
|
-
EWR_info (Dict): dictionary with the parameter info of the
|
|
4189
|
-
levels (List): List with all the levels for the current calculated
|
|
4190
|
-
water_years (List): List of the water year of each day of the current calculated
|
|
4191
|
-
dates (List): List of the dates of the current calculated
|
|
4192
|
-
masked_dates (List): List of the dates that the
|
|
3666
|
+
EWR_info (Dict): dictionary with the parameter info of the ewr being calculated
|
|
3667
|
+
levels (List): List with all the levels for the current calculated ewr
|
|
3668
|
+
water_years (List): List of the water year of each day of the current calculated ewr
|
|
3669
|
+
dates (List): List of the dates of the current calculated ewr
|
|
3670
|
+
masked_dates (List): List of the dates that the ewr needs to be calculated i.e. the time window.
|
|
4193
3671
|
|
|
4194
3672
|
Returns:
|
|
4195
3673
|
tuple: final output with the calculation of volume all_events, durations
|
|
@@ -4229,10 +3707,10 @@ def barrage_flow_calc(EWR_info: Dict, flows: pd.Series, water_years: List, dates
|
|
|
4229
3707
|
as well as the seasonal flow threshold
|
|
4230
3708
|
|
|
4231
3709
|
Args:
|
|
4232
|
-
EWR_info (Dict): dictionary with the parameter info of the
|
|
4233
|
-
flows (List): List with all the flows measurements for the current calculated
|
|
4234
|
-
water_years (List): List of the water year of each day of the current calculated
|
|
4235
|
-
dates (List): List of the dates of the current calculated
|
|
3710
|
+
EWR_info (Dict): dictionary with the parameter info of the ewr being calculated
|
|
3711
|
+
flows (List): List with all the flows measurements for the current calculated ewr
|
|
3712
|
+
water_years (List): List of the water year of each day of the current calculated ewr
|
|
3713
|
+
dates (List): List of the dates of the current calculated ewr
|
|
4236
3714
|
|
|
4237
3715
|
Returns:
|
|
4238
3716
|
tuple: final output with the calculation of volume all_events, durations
|
|
@@ -4260,11 +3738,11 @@ def coorong_level_calc(EWR_info: Dict, levels: pd.Series, water_years: List, dat
|
|
|
4260
3738
|
"""iterate level data for barrage combined levels are with in minimum levels
|
|
4261
3739
|
|
|
4262
3740
|
Args:
|
|
4263
|
-
EWR_info (Dict): dictionary with the parameter info of the
|
|
4264
|
-
levels (List): List with all the levels measurements for the current calculated
|
|
4265
|
-
water_years (List): List of the water year of each day of the current calculated
|
|
4266
|
-
dates (List): List of the dates of the current calculated
|
|
4267
|
-
masked_dates (List): List of the dates that the
|
|
3741
|
+
EWR_info (Dict): dictionary with the parameter info of the ewr being calculated
|
|
3742
|
+
levels (List): List with all the levels measurements for the current calculated ewr
|
|
3743
|
+
water_years (List): List of the water year of each day of the current calculated ewr
|
|
3744
|
+
dates (List): List of the dates of the current calculated ewr
|
|
3745
|
+
masked_dates (List): List of the dates that the ewr needs to be calculated i.e. the time window.
|
|
4268
3746
|
|
|
4269
3747
|
Returns:
|
|
4270
3748
|
tuple: final output with the calculation of volume all_events, durations
|
|
@@ -4298,11 +3776,11 @@ def lower_lakes_level_calc(EWR_info: Dict, levels: pd.Series, water_years: List,
|
|
|
4298
3776
|
if barrage level is at the required minimum as well as the seasonal peak levels threshold
|
|
4299
3777
|
|
|
4300
3778
|
Args:
|
|
4301
|
-
EWR_info (Dict): dictionary with the parameter info of the
|
|
4302
|
-
levels (List): List with all the levels measurements for the current calculated
|
|
4303
|
-
water_years (List): List of the water year of each day of the current calculated
|
|
4304
|
-
dates (List): List of the dates of the current calculated
|
|
4305
|
-
masked_dates (List): List of the dates that the
|
|
3779
|
+
EWR_info (Dict): dictionary with the parameter info of the ewr being calculated
|
|
3780
|
+
levels (List): List with all the levels measurements for the current calculated ewr
|
|
3781
|
+
water_years (List): List of the water year of each day of the current calculated ewr
|
|
3782
|
+
dates (List): List of the dates of the current calculated ewr
|
|
3783
|
+
masked_dates (List): List of the dates that the ewr needs to be calculated i.e. the time window.
|
|
4306
3784
|
|
|
4307
3785
|
Returns:
|
|
4308
3786
|
tuple: final output with the calculation of volume all_events, durations
|
|
@@ -4326,15 +3804,15 @@ def lower_lakes_level_calc(EWR_info: Dict, levels: pd.Series, water_years: List,
|
|
|
4326
3804
|
durations.append(EWR_info['duration'])
|
|
4327
3805
|
return all_events, durations
|
|
4328
3806
|
|
|
4329
|
-
#------------------------------------ Stats on
|
|
3807
|
+
#------------------------------------ Stats on ewr events ----------------------------------------#
|
|
4330
3808
|
|
|
4331
3809
|
def filter_min_events(EWR_info:Dict, events:Dict)-> Dict:
|
|
4332
3810
|
"""Given an events dictionary, filter out all events that are
|
|
4333
3811
|
below min_event as they should not contribute to total duration.
|
|
4334
3812
|
|
|
4335
3813
|
Args:
|
|
4336
|
-
EWR_info (Dict):
|
|
4337
|
-
events (Dict):
|
|
3814
|
+
EWR_info (Dict): ewr parameters
|
|
3815
|
+
events (Dict): ewr calculation events dictionary
|
|
4338
3816
|
|
|
4339
3817
|
Returns:
|
|
4340
3818
|
Dict: events dictionary with only events that is above minimum
|
|
@@ -4349,7 +3827,7 @@ def get_event_years(EWR_info:Dict, events:Dict, unique_water_years:set, duration
|
|
|
4349
3827
|
'''Returns a list of years with events (represented by a 1), and years without events (0)
|
|
4350
3828
|
|
|
4351
3829
|
Args:
|
|
4352
|
-
EWR_info (Dict):
|
|
3830
|
+
EWR_info (Dict): ewr parameters
|
|
4353
3831
|
events (Dict): Dictionary with water years as keys, and a list of event lists for values.
|
|
4354
3832
|
unique_water_years (set): Set of unique water years in timeseries
|
|
4355
3833
|
durations (List): List of durations - 1 value per year
|
|
@@ -4376,13 +3854,13 @@ def get_achievements(EWR_info:Dict, events:Dict, unique_water_years:set, duratio
|
|
|
4376
3854
|
'''Returns a list of number of events per year.
|
|
4377
3855
|
|
|
4378
3856
|
Args:
|
|
4379
|
-
EWR_info (Dict):
|
|
3857
|
+
EWR_info (Dict): ewr parameters
|
|
4380
3858
|
events (Dict): Dictionary with water years as keys, and a list of event lists for values.
|
|
4381
3859
|
unique_water_years (set): Set of unique water years in timeseries
|
|
4382
3860
|
durations (List): List of durations - 1 value per year
|
|
4383
3861
|
|
|
4384
3862
|
Results:
|
|
4385
|
-
list: A list of years with the number of times the
|
|
3863
|
+
list: A list of years with the number of times the ewr requirements were achieved
|
|
4386
3864
|
'''
|
|
4387
3865
|
events_filtered = filter_min_events(EWR_info, events)
|
|
4388
3866
|
num_events = []
|
|
@@ -4416,9 +3894,12 @@ def get_achievements_connecting_events(events: Dict, unique_water_years:set)->Li
|
|
|
4416
3894
|
else:
|
|
4417
3895
|
for i in range(len(events_info)-1):
|
|
4418
3896
|
start_first, _, length, _ = events_info[i]
|
|
4419
|
-
|
|
4420
|
-
|
|
4421
|
-
|
|
3897
|
+
achievement_met = 0
|
|
3898
|
+
for j in range(i+1, len(events_info)):
|
|
3899
|
+
start_second, _, _, _ = events_info[j]
|
|
3900
|
+
gap = (start_second - start_first).days
|
|
3901
|
+
achievement_met += bool(gap >= 27 and gap <= 90 or length >= 90)
|
|
3902
|
+
achievement_count += bool(achievement_met)
|
|
4422
3903
|
achievements_per_years.append(achievement_count)
|
|
4423
3904
|
return achievements_per_years
|
|
4424
3905
|
|
|
@@ -4426,7 +3907,7 @@ def get_number_events(EWR_info:Dict, events:Dict, unique_water_years:set, durati
|
|
|
4426
3907
|
'''Returns a list of number of events per year
|
|
4427
3908
|
|
|
4428
3909
|
Args:
|
|
4429
|
-
EWR_info (Dict):
|
|
3910
|
+
EWR_info (Dict): ewr parameters
|
|
4430
3911
|
events (Dict): Dictionary with water years as keys, and a list of event lists for values.
|
|
4431
3912
|
unique_water_years (set): Set of unique water years in timeseries
|
|
4432
3913
|
durations (List): List of durations - 1 value per year
|
|
@@ -4616,80 +4097,6 @@ def get_event_years_max_rolling_days(events:Dict , unique_water_years:List[int])
|
|
|
4616
4097
|
log.error(e)
|
|
4617
4098
|
return [1 if (max_rolling > 0) else 0 for max_rolling in max_consecutive_days]
|
|
4618
4099
|
|
|
4619
|
-
|
|
4620
|
-
def get_min_gap(events:List[List])->int:
|
|
4621
|
-
"""Retunt the min gap in between events list if there are more than 1 event in the list
|
|
4622
|
-
|
|
4623
|
-
Args:
|
|
4624
|
-
events (List[List]): List of events
|
|
4625
|
-
|
|
4626
|
-
Returns:
|
|
4627
|
-
int: min gap if there is more than 1 event otherwise return 0
|
|
4628
|
-
"""
|
|
4629
|
-
|
|
4630
|
-
|
|
4631
|
-
events_info = [return_event_info(event) for event in events]
|
|
4632
|
-
gaps = []
|
|
4633
|
-
|
|
4634
|
-
if len(events_info) > 1:
|
|
4635
|
-
for i in range(len(events_info)-1):
|
|
4636
|
-
current_event = events_info[i]
|
|
4637
|
-
next_event = events_info[i+1]
|
|
4638
|
-
_, current_event_end, _, _ = current_event
|
|
4639
|
-
next_event_start, _, _, _ = next_event
|
|
4640
|
-
gap = (next_event_start - current_event_end).days
|
|
4641
|
-
gaps.append(gap)
|
|
4642
|
-
return min(gaps)
|
|
4643
|
-
else:
|
|
4644
|
-
return 0
|
|
4645
|
-
|
|
4646
|
-
def get_max_gap(events:List[List])->int:
|
|
4647
|
-
"""Retunt the max gap in between events list if there are more than 1 event in the list
|
|
4648
|
-
|
|
4649
|
-
Args:
|
|
4650
|
-
events (List[List]): List of events
|
|
4651
|
-
|
|
4652
|
-
Returns:
|
|
4653
|
-
int: max gap if there is more than 1 event otherwise return 0
|
|
4654
|
-
"""
|
|
4655
|
-
|
|
4656
|
-
|
|
4657
|
-
events_info = [return_event_info(event) for event in events]
|
|
4658
|
-
gaps = []
|
|
4659
|
-
|
|
4660
|
-
if len(events_info) > 1:
|
|
4661
|
-
for i in range(len(events_info)-1):
|
|
4662
|
-
current_event = events_info[i]
|
|
4663
|
-
next_event = events_info[i+1]
|
|
4664
|
-
_, current_event_end, _, _ = current_event
|
|
4665
|
-
next_event_start, _, _, _ = next_event
|
|
4666
|
-
gap = (next_event_start - current_event_end).days
|
|
4667
|
-
gaps.append(gap)
|
|
4668
|
-
return max(gaps)
|
|
4669
|
-
else:
|
|
4670
|
-
return 0
|
|
4671
|
-
|
|
4672
|
-
def get_max_event_length(events:List[List])->int:
|
|
4673
|
-
"""Retunt the max legth of events list
|
|
4674
|
-
|
|
4675
|
-
Args:
|
|
4676
|
-
events (List[List]): List of events
|
|
4677
|
-
|
|
4678
|
-
Returns:
|
|
4679
|
-
int: max gap if there is more than 1 event otherwise return 0
|
|
4680
|
-
"""
|
|
4681
|
-
events_info = [return_event_info(event) for event in events]
|
|
4682
|
-
lengths = []
|
|
4683
|
-
|
|
4684
|
-
if events_info:
|
|
4685
|
-
for info in events_info:
|
|
4686
|
-
_, _, length, _ = info
|
|
4687
|
-
lengths.append(length)
|
|
4688
|
-
return max(lengths)
|
|
4689
|
-
else:
|
|
4690
|
-
return 0
|
|
4691
|
-
|
|
4692
|
-
|
|
4693
4100
|
def get_event_years_connecting_events(events:Dict , unique_water_years:List[int])->List:
|
|
4694
4101
|
"""Return a list of years with events (represented by a 1), where the 2 connecting events
|
|
4695
4102
|
meet the condition to be between 27 and 90 (3 months) days
|
|
@@ -4763,17 +4170,6 @@ def get_all_events(yearly_events:dict)-> List:
|
|
|
4763
4170
|
"""
|
|
4764
4171
|
return [len(yearly_events[year]) for year in sorted(yearly_events.keys())]
|
|
4765
4172
|
|
|
4766
|
-
def get_all_event_days(yearly_events:dict)-> List:
|
|
4767
|
-
"""count the events in a collection of years
|
|
4768
|
-
|
|
4769
|
-
Args:
|
|
4770
|
-
yearly_events (dict): ewr yearly events dictionary of lists of lists
|
|
4771
|
-
|
|
4772
|
-
Returns:
|
|
4773
|
-
List: total event days count per year in order
|
|
4774
|
-
"""
|
|
4775
|
-
return [len(list(chain(*yearly_events[year]))) for year in sorted(yearly_events.keys())]
|
|
4776
|
-
|
|
4777
4173
|
def get_achieved_event_days(EWR_info:Dict, yearly_events:dict)-> List:
|
|
4778
4174
|
"""count the events days in a collection of years. Filter events below min_event
|
|
4779
4175
|
|
|
@@ -4830,15 +4226,15 @@ def get_total_series_days(water_years:List) -> pd.Series:
|
|
|
4830
4226
|
|
|
4831
4227
|
return intoSeries
|
|
4832
4228
|
|
|
4833
|
-
def event_stats(df:pd.DataFrame, PU_df:pd.DataFrame, gauge:str,
|
|
4229
|
+
def event_stats(df:pd.DataFrame, PU_df:pd.DataFrame, gauge:str, ewr:str, EWR_info:Dict, events:Dict, durations:List, water_years:List) -> pd.DataFrame:
|
|
4834
4230
|
''' Produces statistics based on the event dictionaries and event gap dictionaries.
|
|
4835
4231
|
|
|
4836
4232
|
Args:
|
|
4837
4233
|
df (pd.DataFrame): Raw flow/level dataframe
|
|
4838
4234
|
PU_df (pd.DataFrame): Dataframe with the results from the EWRs in the current planning unit
|
|
4839
4235
|
gauge (str): current iteration gauge string
|
|
4840
|
-
|
|
4841
|
-
EWR_info (Dict): Parameter information for current
|
|
4236
|
+
ewr (str): current iteration ewr string
|
|
4237
|
+
EWR_info (Dict): Parameter information for current ewr
|
|
4842
4238
|
events (Dict): Detailed event information events
|
|
4843
4239
|
durations (List): List of annual required durations
|
|
4844
4240
|
water_years (List): Daily water year values
|
|
@@ -4855,80 +4251,80 @@ def event_stats(df:pd.DataFrame, PU_df:pd.DataFrame, gauge:str, EWR:str, EWR_inf
|
|
|
4855
4251
|
## reset the no_events to keep functionality but switched off
|
|
4856
4252
|
no_events = construct_event_dict(water_years)
|
|
4857
4253
|
|
|
4858
|
-
if EWR_info['
|
|
4254
|
+
if EWR_info['Code'] in ['rANA']:
|
|
4859
4255
|
years_with_events = get_event_years_connecting_events(events, unique_water_years)
|
|
4860
4256
|
|
|
4861
|
-
if EWR_info['
|
|
4257
|
+
if EWR_info['Code'] in ['CF1_c','CF1_C']:
|
|
4862
4258
|
years_with_events = get_event_years_max_rolling_days(events, unique_water_years)
|
|
4863
4259
|
|
|
4864
4260
|
if EWR_info['flow_level_volume'] == 'V':
|
|
4865
4261
|
years_with_events = get_event_years_volume_achieved(events, unique_water_years)
|
|
4866
4262
|
|
|
4867
|
-
YWE = pd.Series(name = str(
|
|
4263
|
+
YWE = pd.Series(name = str(ewr + '_eventYears'), data = years_with_events, index = unique_water_years)
|
|
4868
4264
|
# PU_df = pd.concat([PU_df, YWE], axis = 1)
|
|
4869
4265
|
# Number of event achievements:
|
|
4870
4266
|
num_event_achievements = get_achievements(EWR_info, events, unique_water_years, durations)
|
|
4871
4267
|
|
|
4872
|
-
if EWR_info['
|
|
4268
|
+
if EWR_info['Code'] in ['rANA']:
|
|
4873
4269
|
num_event_achievements = get_achievements_connecting_events(events, unique_water_years)
|
|
4874
4270
|
|
|
4875
|
-
NEA = pd.Series(name = str(
|
|
4271
|
+
NEA = pd.Series(name = str(ewr + '_numAchieved'), data= num_event_achievements, index = unique_water_years)
|
|
4876
4272
|
# PU_df = pd.concat([PU_df, NEA], axis = 1)
|
|
4877
4273
|
# Total number of events THIS ONE IS ONLY ACHIEVED due to Filter Applied
|
|
4878
4274
|
num_events = get_number_events(EWR_info, events, unique_water_years, durations)
|
|
4879
|
-
NE = pd.Series(name = str(
|
|
4275
|
+
NE = pd.Series(name = str(ewr + '_numEvents'), data= num_events, index = unique_water_years)
|
|
4880
4276
|
# PU_df = pd.concat([PU_df, NE], axis = 1)
|
|
4881
4277
|
# Total number of events THIS ONE IS ALL EVENTS
|
|
4882
4278
|
num_events_all = get_all_events(events)
|
|
4883
|
-
NEALL = pd.Series(name = str(
|
|
4279
|
+
NEALL = pd.Series(name = str(ewr + '_numEventsAll'), data= num_events_all, index = unique_water_years)
|
|
4884
4280
|
# PU_df = pd.concat([PU_df, NEALL], axis = 1)
|
|
4885
4281
|
# Max inter event period
|
|
4886
4282
|
max_inter_period = get_max_inter_event_days(no_events, unique_water_years)
|
|
4887
|
-
MIP = pd.Series(name = str(
|
|
4283
|
+
MIP = pd.Series(name = str(ewr + '_maxInterEventDays'), data= max_inter_period, index = unique_water_years)
|
|
4888
4284
|
# PU_df = pd.concat([PU_df, MIP], axis = 1)
|
|
4889
4285
|
# Max inter event period achieved
|
|
4890
4286
|
max_inter_period_achieved = get_event_max_inter_event_achieved(EWR_info, no_events, unique_water_years)
|
|
4891
|
-
MIPA = pd.Series(name = str(
|
|
4287
|
+
MIPA = pd.Series(name = str(ewr + '_maxInterEventDaysAchieved'), data= max_inter_period_achieved, index = unique_water_years)
|
|
4892
4288
|
# PU_df = pd.concat([PU_df, MIPA], axis = 1)
|
|
4893
4289
|
# Average length of events
|
|
4894
4290
|
av_length = get_average_event_length(events, unique_water_years)
|
|
4895
|
-
AL = pd.Series(name = str(
|
|
4291
|
+
AL = pd.Series(name = str(ewr + '_eventLength'), data = av_length, index = unique_water_years)
|
|
4896
4292
|
# PU_df = pd.concat([PU_df, AL], axis = 1)
|
|
4897
4293
|
# Average length of events ONLY the ACHIEVED
|
|
4898
4294
|
av_length_achieved = get_average_event_length_achieved(EWR_info, events)
|
|
4899
|
-
ALA = pd.Series(name = str(
|
|
4295
|
+
ALA = pd.Series(name = str(ewr + '_eventLengthAchieved' ), data = av_length_achieved, index = unique_water_years)
|
|
4900
4296
|
# PU_df = pd.concat([PU_df, ALA], axis = 1)
|
|
4901
4297
|
# Total event days
|
|
4902
4298
|
total_days = get_total_days(events, unique_water_years)
|
|
4903
|
-
TD_A = pd.Series(name = str(
|
|
4299
|
+
TD_A = pd.Series(name = str(ewr + '_totalEventDays'), data = total_days, index = unique_water_years)
|
|
4904
4300
|
# PU_df = pd.concat([PU_df, TD], axis = 1)
|
|
4905
4301
|
# Total event days ACHIEVED
|
|
4906
4302
|
total_days_achieved = get_achieved_event_days(EWR_info, events)
|
|
4907
|
-
TDA = pd.Series(name = str(
|
|
4303
|
+
TDA = pd.Series(name = str(ewr + '_totalEventDaysAchieved'), data = total_days_achieved, index = unique_water_years)
|
|
4908
4304
|
# PU_df = pd.concat([PU_df, TDA], axis = 1)
|
|
4909
4305
|
# Max event days
|
|
4910
4306
|
max_days = get_max_event_days(events, unique_water_years)
|
|
4911
|
-
MD = pd.Series(name = str(
|
|
4307
|
+
MD = pd.Series(name = str(ewr + '_maxEventDays'), data = max_days, index = unique_water_years)
|
|
4912
4308
|
# PU_df = pd.concat([PU_df, MD], axis = 1)
|
|
4913
4309
|
# Max rolling consecutive event days
|
|
4914
4310
|
try:
|
|
4915
4311
|
max_consecutive_days = get_max_consecutive_event_days(events, unique_water_years)
|
|
4916
|
-
MR = pd.Series(name = str(
|
|
4312
|
+
MR = pd.Series(name = str(ewr + '_maxRollingEvents'), data = max_consecutive_days, index = unique_water_years)
|
|
4917
4313
|
# PU_df = pd.concat([PU_df, MR], axis = 1)
|
|
4918
4314
|
except Exception as e:
|
|
4919
4315
|
max_consecutive_days = [0]*len(unique_water_years)
|
|
4920
|
-
MR = pd.Series(name = str(
|
|
4316
|
+
MR = pd.Series(name = str(ewr + '_maxRollingEvents'), data = max_consecutive_days, index = unique_water_years)
|
|
4921
4317
|
# PU_df = pd.concat([PU_df, MR], axis = 1)
|
|
4922
4318
|
log.error(e)
|
|
4923
4319
|
# Max rolling duration achieved
|
|
4924
4320
|
achieved_max_rolling_duration = get_max_rolling_duration_achievement(durations, max_consecutive_days)
|
|
4925
|
-
MRA = pd.Series(name = str(
|
|
4321
|
+
MRA = pd.Series(name = str(ewr + '_maxRollingAchievement'), data = achieved_max_rolling_duration, index = unique_water_years)
|
|
4926
4322
|
# PU_df = pd.concat([PU_df, MRA], axis = 1)
|
|
4927
4323
|
# Append information around available and missing data:
|
|
4928
4324
|
yearly_gap = get_data_gap(df, water_years, gauge)
|
|
4929
4325
|
total_days = get_total_series_days(water_years)
|
|
4930
|
-
YG = pd.Series(name = str(
|
|
4931
|
-
TD_B = pd.Series(name = str(
|
|
4326
|
+
YG = pd.Series(name = str(ewr + '_missingDays'), data = yearly_gap, index = unique_water_years)
|
|
4327
|
+
TD_B = pd.Series(name = str(ewr + '_totalPossibleDays'), data = total_days, index = unique_water_years)
|
|
4932
4328
|
# PU_df = pd.concat([PU_df, YG], axis = 1)
|
|
4933
4329
|
# PU_df = pd.concat([PU_df, TD], axis = 1)
|
|
4934
4330
|
PU_df = pd.concat(
|
|
@@ -4960,11 +4356,11 @@ def merge_weirpool_with_freshes(wp_freshes:List, PU_df:pd.DataFrame)-> pd.DataFr
|
|
|
4960
4356
|
"""Perform the post processing of WP2 and WP3 with equivalent freshes
|
|
4961
4357
|
|
|
4962
4358
|
Args:
|
|
4963
|
-
wp_freshes (List): freshed that need to be proceed to produced merged
|
|
4359
|
+
wp_freshes (List): freshed that need to be proceed to produced merged ewr
|
|
4964
4360
|
PU_df (pd.DataFrame): Dataframe with all the statistics so for this calculation run
|
|
4965
4361
|
|
|
4966
4362
|
Returns:
|
|
4967
|
-
pd.DataFrame: Return Dataframe with the statistics of the merged
|
|
4363
|
+
pd.DataFrame: Return Dataframe with the statistics of the merged ewr
|
|
4968
4364
|
"""
|
|
4969
4365
|
|
|
4970
4366
|
weirpool_pair = {'SF-WP':'WP3',
|
|
@@ -5033,7 +4429,6 @@ HANDLING_FUNCTIONS = {
|
|
|
5033
4429
|
'water_stability_level_handle' : water_stability_level_handle,
|
|
5034
4430
|
'flow_handle_anytime': flow_handle_anytime,
|
|
5035
4431
|
'cumulative_handle_qld': cumulative_handle_qld,
|
|
5036
|
-
'level_change_handle': level_change_handle,
|
|
5037
4432
|
'rise_and_fall_handle' : rise_and_fall_handle
|
|
5038
4433
|
}
|
|
5039
4434
|
|
|
@@ -5053,21 +4448,6 @@ def get_gauge_calc_type(multigauge:bool)-> str:
|
|
|
5053
4448
|
else:
|
|
5054
4449
|
return 'single'
|
|
5055
4450
|
|
|
5056
|
-
def get_ewr_prefix(ewr_code:str, prefixes:list)-> str:
|
|
5057
|
-
"""Get the EWR prefix by identifying the prefix in the EWR code
|
|
5058
|
-
|
|
5059
|
-
Args:
|
|
5060
|
-
ewr_code (str): EWR code
|
|
5061
|
-
prefixes (list): list of prefixes
|
|
5062
|
-
|
|
5063
|
-
Returns:
|
|
5064
|
-
str: EWR prefix
|
|
5065
|
-
"""
|
|
5066
|
-
for prefix in prefixes:
|
|
5067
|
-
if prefix in ewr_code:
|
|
5068
|
-
return prefix
|
|
5069
|
-
return 'unknown'
|
|
5070
|
-
|
|
5071
4451
|
def get_handle_function(function_name: str) -> object:
|
|
5072
4452
|
"""return handling function
|
|
5073
4453
|
|
|
@@ -5110,41 +4490,41 @@ def find_function(ewr_key:str, new_config_file:dict) -> str:
|
|
|
5110
4490
|
#---------------------------- Sorting and distributing to handling functions ---------------------#
|
|
5111
4491
|
|
|
5112
4492
|
def calc_sorter(df_F:pd.DataFrame, df_L:pd.DataFrame, gauge:str, EWR_table:pd.DataFrame, calc_config: dict) -> tuple:
|
|
5113
|
-
'''Sends to handling functions to get calculated depending on the type of
|
|
4493
|
+
'''Sends to handling functions to get calculated depending on the type of ewr
|
|
5114
4494
|
|
|
5115
4495
|
Args:
|
|
5116
4496
|
df_F (pd.DataFrame): Dataframe with the daily flows
|
|
5117
4497
|
df_L (pd.DataFrame): Dataframe with the daily levels
|
|
5118
4498
|
gauge (str): gauge string of current iteration
|
|
5119
|
-
EWR_table (pd.DataFrame): Dataframe of
|
|
4499
|
+
EWR_table (pd.DataFrame): Dataframe of ewr parameters
|
|
5120
4500
|
|
|
5121
4501
|
Results:
|
|
5122
4502
|
tuple[dict, dict]: annual results summary and detailed event information
|
|
5123
4503
|
|
|
5124
4504
|
'''
|
|
5125
|
-
# Get
|
|
4505
|
+
# Get ewr tables:
|
|
5126
4506
|
PU_items = EWR_table.groupby(['PlanningUnitID', 'PlanningUnitName']).size().reset_index().drop([0], axis=1)
|
|
5127
|
-
# Extract relevant sections of the
|
|
4507
|
+
# Extract relevant sections of the ewr table:
|
|
5128
4508
|
gauge_table = EWR_table[EWR_table['Gauge'] == gauge]
|
|
5129
4509
|
# save the planning unit dataframes to this dictionary:
|
|
5130
4510
|
location_results = {}
|
|
5131
4511
|
location_events = {}
|
|
5132
|
-
for
|
|
5133
|
-
PU_table = gauge_table[gauge_table['PlanningUnitID'] ==
|
|
4512
|
+
for pu in set(gauge_table['PlanningUnitID']):
|
|
4513
|
+
PU_table = gauge_table[gauge_table['PlanningUnitID'] == pu]
|
|
5134
4514
|
EWR_categories = PU_table['FlowLevelVolume'].values
|
|
5135
4515
|
EWR_codes = PU_table['Code']
|
|
5136
4516
|
PU_df = pd.DataFrame()
|
|
5137
4517
|
PU_events = {}
|
|
5138
4518
|
|
|
5139
|
-
for i,
|
|
4519
|
+
for i, ewr in enumerate(EWR_codes):
|
|
5140
4520
|
events = {}
|
|
5141
4521
|
|
|
5142
|
-
MULTIGAUGE = is_multigauge(EWR_table, gauge,
|
|
4522
|
+
MULTIGAUGE = is_multigauge(EWR_table, gauge, ewr, pu)
|
|
5143
4523
|
|
|
5144
4524
|
# Save dict with function arguments value
|
|
5145
|
-
all_args = {"
|
|
4525
|
+
all_args = {"pu": pu,
|
|
5146
4526
|
"gauge": gauge,
|
|
5147
|
-
"
|
|
4527
|
+
"ewr": ewr,
|
|
5148
4528
|
"EWR_table": EWR_table,
|
|
5149
4529
|
"df_F": df_F,
|
|
5150
4530
|
"df_L": df_L,
|
|
@@ -5153,7 +4533,7 @@ def calc_sorter(df_F:pd.DataFrame, df_L:pd.DataFrame, gauge:str, EWR_table:pd.Da
|
|
|
5153
4533
|
|
|
5154
4534
|
cat = EWR_categories[i]
|
|
5155
4535
|
gauge_calc_type = get_gauge_calc_type(MULTIGAUGE)
|
|
5156
|
-
ewr_key = f'{
|
|
4536
|
+
ewr_key = f'{ewr}-{gauge_calc_type}-{cat}'
|
|
5157
4537
|
function_name = find_function(ewr_key, calc_config)
|
|
5158
4538
|
if function_name == 'unknown':
|
|
5159
4539
|
log.warning(f"skipping calculation due to ewr key {ewr_key} not in the configuration configuration files")
|
|
@@ -5167,13 +4547,13 @@ def calc_sorter(df_F:pd.DataFrame, df_L:pd.DataFrame, gauge:str, EWR_table:pd.Da
|
|
|
5167
4547
|
|
|
5168
4548
|
PU_df, events = handle_function(**kwargs)
|
|
5169
4549
|
if events != {}:
|
|
5170
|
-
PU_events[str(
|
|
4550
|
+
PU_events[str(ewr)]=events
|
|
5171
4551
|
|
|
5172
4552
|
# wp_freshes = [ewr for ewr in EWR_codes.to_list() if ewr in ["SF-WP","LF2-WP"]]
|
|
5173
4553
|
# if wp_freshes:
|
|
5174
4554
|
# PU_df = merge_weirpool_with_freshes(wp_freshes, PU_df)
|
|
5175
4555
|
|
|
5176
|
-
PU_name = PU_items['PlanningUnitName'].loc[PU_items[PU_items['PlanningUnitID'] ==
|
|
4556
|
+
PU_name = PU_items['PlanningUnitName'].loc[PU_items[PU_items['PlanningUnitID'] == pu].index[0]]
|
|
5177
4557
|
|
|
5178
4558
|
location_results[PU_name] = PU_df
|
|
5179
4559
|
location_events[PU_name] = PU_events
|