def calc_winter_highflow_POR(matrix, exceedance_percent): exceedance_object = {} exceedance_value = {} current_flow_object = {} freq = {} duration = {} timing = {} magnitude = {} average_annual_flow = np.nanmedian(matrix) for i in exceedance_percent: exceedance_value[i] = np.nanpercentile(matrix, 100 - i) exceedance_object[i] = [] current_flow_object[i] = None freq[i] = 0 duration[i] = [] timing[i] = [] magnitude[i] = [] for column_number, flow_column in enumerate(matrix[0]): for row_number, flow_row in enumerate(matrix[:, column_number]): for percent in exceedance_percent: if flow_row < exceedance_value[percent] and current_flow_object[ percent] or row_number == len( matrix[:, column_number] ) - 1 and current_flow_object[percent]: """End of a object if it falls below threshold, or end of column""" current_flow_object[percent].end_date = row_number + 1 duration[percent].append( current_flow_object[percent].duration) magnitude[percent].append( max(current_flow_object[percent].flow) / average_annual_flow) current_flow_object[percent] = None elif flow_row >= exceedance_value[percent]: if not current_flow_object[percent]: """Begining of a object""" exceedance_object[percent].append( FlowExceedance(row_number + 1, None, 1, percent)) current_flow_object[percent] = exceedance_object[ percent][-1] current_flow_object[percent].add_flow(flow_row) timing[percent].append(row_number + 1) freq[percent] = freq[percent] + 1 else: """Continue of a object""" current_flow_object[percent].add_flow(flow_row) current_flow_object[ percent].duration = current_flow_object[ percent].duration + 1 return timing, duration, freq, magnitude
def calc_winter_highflow_annual(matrix, exceedance_percent, winter_params = def_winter_params): params = set_user_params(winter_params, def_winter_params) max_zero_allowed_per_year, max_nan_allowed_per_year = params.values() """Get peak percentiles calculated from each year's peak flow values""" peak_flows = [] peak_percentiles = [2,5,10,20,50] # for peak flow metrics high_percentiles = [2,5,10,20] # for high flow metrics peak_exceedance_values = [] highflow_exceedance_values = [] for column_number, _ in enumerate(matrix[0]): flow_data = matrix[:, column_number] peak_flows.append(np.nanmax(flow_data)) for percentile in peak_percentiles: peak_exceedance_values.append(np.nanpercentile(peak_flows, 100 - percentile)) """Add high flow percentiles and peak flow exceedance vals together for final list of exceedance values""" highflow_exceedance_values = [] for i in high_percentiles: highflow_exceedance_values.append(np.nanpercentile(matrix, 100 - i)) exceedance_values = peak_exceedance_values + highflow_exceedance_values # five peak exceedance vals plus four high flow exceedance vals exceedance_value = {} freq = {} duration = {} timing = {} magnitude = {} peak_magnitude = {} for i, value in enumerate(exceedance_values): exceedance_value[i] = value freq[i] = [] duration[i] = [] timing[i] = [] magnitude[i] = [] peak_magnitude[i] = [] for column_number, flow_column in enumerate(matrix[0]): if np.isnan(matrix[:, column_number]).sum() > max_nan_allowed_per_year or np.count_nonzero(matrix[:, column_number] == 0) > max_zero_allowed_per_year: for i, value in enumerate(exceedance_values): freq[i].append(None) duration[i].append(None) timing[i].append(None) magnitude[i].append(None) peak_magnitude[i].append(None) continue exceedance_object = {} exceedance_duration = {} current_flow_object = {} peak_flow = {} """Init current flow object""" for i, value in enumerate(exceedance_values): exceedance_object[i] = [] exceedance_duration[i] = [] current_flow_object[i] = None peak_flow[i] = [] """Loop through each flow value for the year to check if they pass exceedance threshold""" for row_number, flow_row in enumerate(matrix[:, column_number]): for i, value in enumerate(exceedance_values): if bool(flow_row < exceedance_value[i] and current_flow_object[i]) or bool(row_number == len(matrix[:, column_number]) - 1 and current_flow_object[i]): """End of an object if it falls below threshold, or end of column""" current_flow_object[i].end_date = row_number + 1 current_flow_object[i].get_max_magnitude() exceedance_duration[i].append(current_flow_object[i].duration) peak_flow[i] = np.nanmax(flow_row) current_flow_object[i] = None elif flow_row >= exceedance_value[i]: if not current_flow_object[i]: """Beginning of an object""" exceedance_object[i].append( FlowExceedance(row_number, None, 1, i)) current_flow_object[i] = exceedance_object[i][-1] current_flow_object[i].add_flow(flow_row) else: """Continuing an object""" current_flow_object[i].add_flow(flow_row) current_flow_object[i].duration = current_flow_object[i].duration + 1 for i, value in enumerate(exceedance_values): freq[i].append(None if len(exceedance_object[i])==0 else len(exceedance_object[i])) duration[i].append( None if np.nansum(exceedance_duration[i])==0 else np.nansum(exceedance_duration[i]) if not np.isnan(np.nansum(exceedance_duration[i])) else None) timing[i].append(median_of_time(exceedance_object[i])) magnitude[i].append(exceedance_value[i]) _timing = {2: timing[0], 5: timing[1], 10: timing[2], 20: timing[3], 50: timing[4], 12: timing[5], 15: timing[6], 110: timing[7], 120: timing[8],} _duration = {2: duration[0], 5: duration[1], 10: duration[2], 20: duration[3], 50: duration[4], 12: duration[5], 15: duration[6], 110: duration[7], 120: duration[8],} _freq = {2: freq[0], 5: freq[1], 10: freq[2], 20: freq[3], 50: freq[4], 12: freq[5], 15: freq[6], 110: freq[7], 120: freq[8],} _magnitude = {2: magnitude[0], 5: magnitude[1], 10: magnitude[2], 20: magnitude[3], 50: magnitude[4], 12: magnitude[5], 15: magnitude[6], 110: magnitude[7], 120: magnitude[8],} return _timing, _duration, _freq, _magnitude
def calc_winter_highflow_annual(matrix, exceedance_percent, winter_params=def_winter_params): max_nan_allowed_per_year = winter_params['max_nan_allowed_per_year'] max_zero_allowed_per_year = winter_params['max_zero_allowed_per_year'] exceedance_value = {} freq = {} duration = {} timing = {} magnitude = {} for i in exceedance_percent: exceedance_value[i] = np.nanpercentile(matrix, 100 - i) freq[i] = [] duration[i] = [] timing[i] = [] magnitude[i] = [] for column_number, flow_column in enumerate(matrix[0]): if np.isnan(matrix[:, column_number]).sum() > max_nan_allowed_per_year or np.count_nonzero(matrix[:, column_number] == 0) > max_zero_allowed_per_year: for percent in exceedance_percent: freq[percent].append(None) duration[percent].append(None) timing[percent].append(None) magnitude[percent].append(None) continue exceedance_object = {} exceedance_duration = {} current_flow_object = {} """Init current flow object""" for percent in exceedance_percent: exceedance_object[percent] = [] exceedance_duration[percent] = [] current_flow_object[percent] = None """Loop through each flow value for the year to check if they pass exceedance threshold""" for row_number, flow_row in enumerate(matrix[:, column_number]): for percent in exceedance_percent: if bool(flow_row < exceedance_value[percent] and current_flow_object[percent]) or bool(row_number == len(matrix[:, column_number]) - 1 and current_flow_object[percent]): """End of an object if it falls below threshold, or end of column""" current_flow_object[percent].end_date = row_number + 1 current_flow_object[percent].get_max_magnitude() exceedance_duration[percent].append( current_flow_object[percent].duration) current_flow_object[percent] = None elif flow_row >= exceedance_value[percent]: if not current_flow_object[percent]: """Beginning of an object""" exceedance_object[percent].append( FlowExceedance(row_number, None, 1, percent)) current_flow_object[percent] = exceedance_object[percent][-1] current_flow_object[percent].add_flow(flow_row) else: """Continuing an object""" current_flow_object[percent].add_flow(flow_row) current_flow_object[percent].duration = current_flow_object[percent].duration + 1 for percent in exceedance_percent: freq[percent].append(len(exceedance_object[percent])) duration[percent].append( np.nanmedian(exceedance_duration[percent]) if not np.isnan(np.nanmedian(exceedance_duration[percent])) else None) timing[percent].append(median_of_time(exceedance_object[percent])) magnitude[percent].append(exceedance_value[percent]) return timing, duration, freq, magnitude