mirror of
https://github.com/TeachBooks/template.git
synced 2026-11-13 22:55:51 +00:00
started stripping down risk-and-reliability to create template
This commit is contained in:
parent
6697c0f5f8
commit
75ff95fa67
127 changed files with 54699 additions and 0 deletions
792
book/notebooks/flood-risk/Exercise_Flood_Risk_Render.ipynb
Normal file
792
book/notebooks/flood-risk/Exercise_Flood_Risk_Render.ipynb
Normal file
File diff suppressed because one or more lines are too long
BIN
book/notebooks/flood-risk/Prob_Cons.xlsx
Normal file
BIN
book/notebooks/flood-risk/Prob_Cons.xlsx
Normal file
Binary file not shown.
BIN
book/notebooks/flood-risk/exercise_flood_risk.zip
Normal file
BIN
book/notebooks/flood-risk/exercise_flood_risk.zip
Normal file
Binary file not shown.
BIN
book/notebooks/flood-risk/figures/flood-depth-12.PNG
Normal file
BIN
book/notebooks/flood-risk/figures/flood-depth-12.PNG
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 MiB |
BIN
book/notebooks/flood-risk/figures/map-dike-segments.PNG
Normal file
BIN
book/notebooks/flood-risk/figures/map-dike-segments.PNG
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 704 KiB |
163
book/notebooks/flood-risk/functions.py
Normal file
163
book/notebooks/flood-risk/functions.py
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
import pandas as pd
|
||||
|
||||
def find_scenarios_with_segment_i(segments_fixed, df):
|
||||
"""Given a list of segments, return set of dependent scenarios."""
|
||||
idx = []
|
||||
segments_fixed = set(segments_fixed)
|
||||
for i, row in enumerate(df['failed_segments'].values):
|
||||
segments_row = set([int(seg) for seg in row.split(",")])
|
||||
intersection = list(segments_fixed.intersection(segments_row))
|
||||
if len(intersection) > 0:
|
||||
idx.append(True)
|
||||
else:
|
||||
idx.append(False)
|
||||
segment_table = df.iloc[idx]
|
||||
return segment_table
|
||||
|
||||
def assemble_analysis_cases(df):
|
||||
"""From scenario dataframe collect damage and fatality information."""
|
||||
econ_damage_case_1 = df.iloc[:,3] # Unexpected, no evacuation
|
||||
econ_damage_case_2 = df.iloc[:,5] # Unexpected, unorganised evacuation
|
||||
econ_damage_case_3 = df.iloc[:,7] # Expected, unorganised evacuation
|
||||
econ_damage_case_4 = df.iloc[:,9] # Expected, organised evacuation
|
||||
|
||||
fatalities_case_1 = df.iloc[:,4]
|
||||
fatalities_case_2 = df.iloc[:,6]
|
||||
fatalities_case_3 = df.iloc[:,8]
|
||||
fatalities_case_4 = df.iloc[:,10]
|
||||
|
||||
scenario_prob = df.iloc[:,1] # scenario probability
|
||||
|
||||
cases = {'damage': [econ_damage_case_1, econ_damage_case_2, econ_damage_case_3, econ_damage_case_4],
|
||||
'fatality': [fatalities_case_1, fatalities_case_2, fatalities_case_3, fatalities_case_4]}
|
||||
return cases
|
||||
|
||||
def exceedance_prob(cases, scenario_prob):
|
||||
"""Compute exceedance probability."""
|
||||
case_1 = cases[0]
|
||||
case_2 = cases[1]
|
||||
case_3 = cases[2]
|
||||
case_4 = cases[3]
|
||||
|
||||
key = case_1.index
|
||||
|
||||
# Combine Evacuation Scenarios into new Dataframe
|
||||
scenarios = [pd.DataFrame({'Nr': key, 'N/D': case_1}),
|
||||
pd.DataFrame({'Nr': key, 'N/D': case_2}),
|
||||
pd.DataFrame({'Nr': key, 'N/D': case_3}),
|
||||
pd.DataFrame({'Nr': key, 'N/D': case_4})]
|
||||
|
||||
scen_combi = pd.concat(scenarios, ignore_index=True)
|
||||
|
||||
# Sort values by key ('Nr')
|
||||
scen_combi_sorted = scen_combi.sort_values(by=['Nr']) # useful if scen_combi_nodup.sort_values(by=['Nr']) in case of no duplicates
|
||||
# scen_combi_sorted = scen_combi.reset_index(drop=True) # Reset index starting from 0
|
||||
|
||||
# Create new Dataframe for scenario prob with corresponding key
|
||||
prob = pd.DataFrame({'Nr': key, 'scen_prob':scenario_prob})
|
||||
|
||||
# Join both Dataframes based on common key
|
||||
join_scen_prob = scen_combi_sorted.join(prob.set_index('Nr'), on='Nr')
|
||||
|
||||
# Determine Exceedance Probability
|
||||
sorted_N_D = scen_combi.sort_values(by=['N/D']) # Sort N/D based on ascending order
|
||||
complete_table = sorted_N_D.join(prob.set_index('Nr'), on='Nr')
|
||||
|
||||
N_D_prob_ordered = complete_table.iloc[:,2]
|
||||
|
||||
# N_D = join_scen_prob.dropna(axis=0).iloc[:,1].reset_index(drop=True) # N/D
|
||||
# N_D_prob = join_scen_prob.dropna(axis=0).iloc[:,2].reset_index(drop=True) # Corresponding scenario prob
|
||||
# print('N_D', N_D)
|
||||
# print('N_D_PROB', N_D_prob)
|
||||
# order = N_D.argsort() # Sort N/D based on ascending order
|
||||
|
||||
# N_D_prob_ordered = N_D_prob[order]
|
||||
N_D_prob_cs = np.cumsum(N_D_prob_ordered[::-1]) # Take cumulative sum of reversed order
|
||||
|
||||
exceed_prob = (1/4) * N_D_prob_cs[::-1] # Reverse result (1-FN(n)) and /4 as 4 evacuation scenarios are considered
|
||||
complete_table = complete_table.join(exceed_prob, lsuffix='_orignal', rsuffix='_new') # complete resulting table
|
||||
# N_D_ordered = N_D[order].reset_index(drop=True)
|
||||
N_D_ordered = complete_table.iloc[:,1]
|
||||
|
||||
return N_D_ordered, exceed_prob, complete_table
|
||||
|
||||
def sensitivity_analysis(cases, scenario_prob, idx_segment, N_D_ordered_original, exceed_prob_original, complete_table):
|
||||
"""Docstring incomplete."""
|
||||
case_1 = cases[0]
|
||||
case_2 = cases[1]
|
||||
case_3 = cases[2]
|
||||
case_4 = cases[3]
|
||||
|
||||
# Dropping segment(s)
|
||||
case_1_exc = case_1.drop(idx_segment, axis=0).reset_index(drop=True)
|
||||
case_2_exc = case_2.drop(idx_segment, axis=0).reset_index(drop=True)
|
||||
case_3_exc = case_3.drop(idx_segment, axis=0).reset_index(drop=True)
|
||||
case_4_exc = case_4.drop(idx_segment, axis=0).reset_index(drop=True)
|
||||
|
||||
scenario_prob_exc = scenario_prob.drop(idx_segment, axis=0).reset_index(drop=True)
|
||||
|
||||
# Determine new exceedance probability - Excluding segment(s)
|
||||
N_D_ordered_new, exceed_prob_new, complete_table_new = exceedance_prob([case_1_exc, case_2_exc, case_3_exc, case_4_exc], scenario_prob_exc)
|
||||
|
||||
# Plotting
|
||||
plot_curves(N_D_ordered_original, exceed_prob_original)
|
||||
plt.plot(N_D_ordered_new.dropna(axis=0), exceed_prob_new.dropna(axis=0), marker="o", linewidth=2, markersize=5, color= 'darkblue', label='Excluding segment(s)', zorder=10)
|
||||
|
||||
# Plot dropped points
|
||||
x_point = []
|
||||
y_point = []
|
||||
for i in range(len(idx_segment)):
|
||||
row_i = complete_table[complete_table['Nr']== (idx_segment[i] + 1)]
|
||||
for j in range(len(row_i)):
|
||||
x_point.append(row_i.iloc[j, 1])
|
||||
y_point.append(row_i.iloc[j, 3])
|
||||
plt.scatter(x_point, y_point, label='Dropped Points', s=45, color='darkred', zorder=15) # Plot the points corresponding to deleted segment
|
||||
plt.legend()
|
||||
plt.show()
|
||||
return N_D_ordered_new, exceed_prob_new, complete_table_new
|
||||
|
||||
def plot_curves(N_D, exceedance_prob):
|
||||
"""Plot FN or FD risk curve."""
|
||||
plt.figure(figsize=(10,6))
|
||||
set_TUDstyle()
|
||||
|
||||
# Plot FN/FD curve
|
||||
plt.plot(N_D, exceedance_prob, marker="o", linewidth=2, markersize=5, label='FN/D-curve',zorder=0)
|
||||
|
||||
# Add acceptable limit line
|
||||
ND = np.linspace(1,100000,100000) # fatalities
|
||||
alpha = 1
|
||||
C = 0.010
|
||||
limit_line = (C/ND**alpha)
|
||||
plt.plot(limit_line, linewidth=2, color='darkgreen', label='Acceptable Limit Line', zorder=5)
|
||||
|
||||
# Styling
|
||||
plt.yscale('log')
|
||||
plt.xscale('log')
|
||||
plt.grid(True, which="both", axis='x')
|
||||
plt.grid(True, which="major", axis='y')
|
||||
plt.title('FN/D-curve')
|
||||
plt.ylabel('Probability of Exceedance, $1-F_N(n)$')
|
||||
plt.xlabel('Economic damage [meuro] / Fatalities')
|
||||
plt.xlim(1,100000)
|
||||
plt.ylim(10**(-7),10**(-3))
|
||||
plt.legend()
|
||||
|
||||
def compute_benefit(table_old, table_new):
|
||||
"""Compute new and old consequences and net benefit."""
|
||||
old_consequences = np.sum(table_old["N/D"].values * table_old["scen_prob_new"].values)
|
||||
new_consequences = np.sum(table_new["N/D"].values * table_new["scen_prob_new"].values)
|
||||
benefit = old_consequences - new_consequences
|
||||
return old_consequences, new_consequences, benefit
|
||||
|
||||
def set_TUDstyle():
|
||||
TUcolor = {"cyan": "#00A6D6", "darkgreen": "#009B77", "purple": "#6F1D77",
|
||||
"darkred": "#A50034", "darkblue": "#0C2340",
|
||||
"orange": "#EC6842", "green": "#6CC24A",
|
||||
"lightcyan": "#00B8C8", "red": "#E03C31", "pink": "#EF60A3",
|
||||
"yellow": "#FFB81C", "blue": "#0076C2"}
|
||||
plt.rcParams.update({'axes.prop_cycle': plt.cycler(color=TUcolor.values()),
|
||||
'font.size': 16, "lines.linewidth": 4})
|
||||
return TUcolor
|
||||
Loading…
Add table
Add a link
Reference in a new issue