Huseyin Kaya commited on
Commit
6c19e9c
·
unverified ·
2 Parent(s): 15fdf80a8ae93a

Merge pull request #113 from TomorrowsCities/feature_multi_class_flood

Browse files
tomorrowcities/backend/engine.py CHANGED
@@ -117,10 +117,10 @@ def compute_road_infra(buildings, household, individual,
117
  flooded_roads = (non_bridges) & (gdf_edges['im'] > road_water_height_threshold)
118
  flooded_culverts = (culverts) & (gdf_edges['im'] > culvert_water_height_threshold)
119
 
120
- gdf_edges.loc[flooded_roads, 'ds'] = 1
121
  gdf_edges.loc[flooded_roads, 'is_damaged'] = True
122
 
123
- gdf_edges.loc[flooded_culverts, 'ds'] = 1
124
  gdf_edges.loc[flooded_culverts, 'is_damaged'] = True
125
  elif hazard == 'earthquake':
126
  fragility = fragility.rename(columns={"med_slight": "med_ds1",
@@ -242,6 +242,7 @@ def compute_power_infra(buildings, household, nodes,edges,intensity,fragility,ha
242
  threshold_flood, threshold_flood_distance, preserve_edge_directions,
243
  earthquake_intensity_unit = 'm/s2',
244
  ):
 
245
  earthquake_intensity_normalization_factor = 1
246
  if earthquake_intensity_unit == 'm/s2':
247
  earthquake_intensity_normalization_factor = 9.81
@@ -355,8 +356,8 @@ def compute_power_infra(buildings, household, nodes,edges,intensity,fragility,ha
355
  flood_mapping = interp1d(x,y,axis=1,kind='linear',bounds_error=False, fill_value=(0,1))
356
  # TODO: find another way for vectorized interpolate
357
  gdf_nodes['fl_prob'] = np.diag(flood_mapping(xnew))
358
- gdf_nodes['ds'] = 0
359
- gdf_nodes.loc[gdf_nodes['fl_prob'] > threshold_flood,'ds'] = 1
360
 
361
  # All Nodes
362
  all_nodes = set(gdf_nodes['node_id'])
@@ -439,13 +440,13 @@ def compute_power_infra(buildings, household, nodes,edges,intensity,fragility,ha
439
  gdf_buildings['has_power'], household_w_node_id['has_power'],hospitals['has_power']
440
 
441
  def compute(gdf_landuse, gdf_buildings, df_household, df_individual,gdf_intensity, df_hazard, hazard_type, policies=[],
442
- threshold_flood = 0.2, threshold_flood_distance = 10,
443
  earthquake_intensity_unit = 'm/s2',
444
  cdf_median_increase_in_percent = 0.20,
445
  flood_depth_reduction = 0.20,
446
  damage_curve_suppress_factor = 0.9,
447
  ):
448
-
449
  print('cdf_median_increase_in_percent',cdf_median_increase_in_percent)
450
  print('flood_depth_reduction', flood_depth_reduction)
451
  print('policies', policies)
@@ -778,9 +779,9 @@ def compute(gdf_landuse, gdf_buildings, df_household, df_individual,gdf_intensit
778
  flood_mapping = interp1d(x,y,axis=1,kind='linear',bounds_error=False, fill_value=(0,1))
779
  # TODO: find another way for vectorized interpolate
780
  bld_flood['fl_prob'] = np.diag(flood_mapping(xnew))
781
- bld_flood['fl_ds'] = 0
782
- flooded_buildings = bld_flood['fl_prob'] > threshold_flood
783
- bld_flood.loc[flooded_buildings, 'fl_ds'] = 1
784
 
785
  casualty_rates = np.array([[0,0,0,0.000976715,0.0105355,0.052184493,0.160744982,0.373769339,0.743830881]])
786
  y_casualty = np.repeat(casualty_rates, len(bld_flood),axis=0)
@@ -844,13 +845,12 @@ def generate_metrics(t, t_full, hazard_type, population_displacement_consensus):
844
  HAZARD_FLOOD = "flood"
845
  HAZARD_DEBRIS = "debris"
846
 
847
- if hazard_type == HAZARD_EARTHQUAKE:
848
  # Effect of policies on thresholds
849
  # First get the global threshold
850
  thresholds = {f'metric{id}': DS_SLIGHT for id in range(8)}
851
  else:
852
- # Default thresholds for flood and debris
853
- # For flood, there are only two states: 0 or 1.
854
  # So threshold is set to 0.
855
  thresholds = {f'metric{id}': DS_NO for id in range(8)}
856
 
 
117
  flooded_roads = (non_bridges) & (gdf_edges['im'] > road_water_height_threshold)
118
  flooded_culverts = (culverts) & (gdf_edges['im'] > culvert_water_height_threshold)
119
 
120
+ gdf_edges.loc[flooded_roads, 'ds'] = DS_COMPLETE
121
  gdf_edges.loc[flooded_roads, 'is_damaged'] = True
122
 
123
+ gdf_edges.loc[flooded_culverts, 'ds'] = DS_COMPLETE
124
  gdf_edges.loc[flooded_culverts, 'is_damaged'] = True
125
  elif hazard == 'earthquake':
126
  fragility = fragility.rename(columns={"med_slight": "med_ds1",
 
242
  threshold_flood, threshold_flood_distance, preserve_edge_directions,
243
  earthquake_intensity_unit = 'm/s2',
244
  ):
245
+ print('threshold_flood', threshold_flood)
246
  earthquake_intensity_normalization_factor = 1
247
  if earthquake_intensity_unit == 'm/s2':
248
  earthquake_intensity_normalization_factor = 9.81
 
356
  flood_mapping = interp1d(x,y,axis=1,kind='linear',bounds_error=False, fill_value=(0,1))
357
  # TODO: find another way for vectorized interpolate
358
  gdf_nodes['fl_prob'] = np.diag(flood_mapping(xnew))
359
+ ds2_threshold, ds3_threshold, ds4_threshold = threshold_flood
360
+ gdf_nodes['ds'] = gdf_nodes['fl_prob'].map(lambda x: DS_COMPLETE if x > ds4_threshold else DS_EXTENSIVE if x > ds3_threshold else DS_MODERATE if x > ds2_threshold else DS_SLIGHT if x > 0 else DS_NO )
361
 
362
  # All Nodes
363
  all_nodes = set(gdf_nodes['node_id'])
 
440
  gdf_buildings['has_power'], household_w_node_id['has_power'],hospitals['has_power']
441
 
442
  def compute(gdf_landuse, gdf_buildings, df_household, df_individual,gdf_intensity, df_hazard, hazard_type, policies=[],
443
+ threshold_flood = [0.05, 0.2, 0.5], threshold_flood_distance = 10,
444
  earthquake_intensity_unit = 'm/s2',
445
  cdf_median_increase_in_percent = 0.20,
446
  flood_depth_reduction = 0.20,
447
  damage_curve_suppress_factor = 0.9,
448
  ):
449
+ print('threshold_flood', threshold_flood)
450
  print('cdf_median_increase_in_percent',cdf_median_increase_in_percent)
451
  print('flood_depth_reduction', flood_depth_reduction)
452
  print('policies', policies)
 
779
  flood_mapping = interp1d(x,y,axis=1,kind='linear',bounds_error=False, fill_value=(0,1))
780
  # TODO: find another way for vectorized interpolate
781
  bld_flood['fl_prob'] = np.diag(flood_mapping(xnew))
782
+ ds2_threshold, ds3_threshold, ds4_threshold = threshold_flood
783
+ bld_flood['fl_ds'] = bld_flood['fl_prob'].map(lambda x: DS_COLLAPSED if x > ds4_threshold else DS_EXTENSIZE if x > ds3_threshold else DS_MODERATE if x > ds2_threshold else DS_SLIGHT if x > 0 else DS_NO )
784
+ flooded_buildings = bld_flood['fl_ds'] > DS_SLIGHT
785
 
786
  casualty_rates = np.array([[0,0,0,0.000976715,0.0105355,0.052184493,0.160744982,0.373769339,0.743830881]])
787
  y_casualty = np.repeat(casualty_rates, len(bld_flood),axis=0)
 
845
  HAZARD_FLOOD = "flood"
846
  HAZARD_DEBRIS = "debris"
847
 
848
+ if hazard_type == HAZARD_EARTHQUAKE or hazard_type == HAZARD_FLOOD:
849
  # Effect of policies on thresholds
850
  # First get the global threshold
851
  thresholds = {f'metric{id}': DS_SLIGHT for id in range(8)}
852
  else:
853
+ # For debris, there are only two states: 0 or 1.
 
854
  # So threshold is set to 0.
855
  thresholds = {f'metric{id}': DS_NO for id in range(8)}
856
 
tomorrowcities/pages/engine.py CHANGED
@@ -23,7 +23,7 @@ import pickle
23
  import datetime
24
  from . import storage, user, session_storage, store_in_session_storage, read_from_session_storage
25
  from .settings import landslide_max_trials
26
- from .settings import threshold_flood, threshold_flood_distance, threshold_road_water_height, threshold_culvert_water_height, preserve_edge_directions,\
27
  population_displacement_consensus
28
  from ..backend.engine import compute, compute_power_infra, compute_road_infra, calculate_metrics, generate_exposure, \
29
  create_tally, generate_metrics
@@ -1357,6 +1357,7 @@ def ExecutePanel():
1357
  fragility = layers.value['layers']['power fragility']['data'].value
1358
  hazard = layers.value['hazard'].value
1359
  earthquake_intensity_unit = layers.value['earthquake_intensity_unit'].value
 
1360
 
1361
  if layers.value['hazard'].value == 'landslide':
1362
  fragility = layers.value['layers']['landslide fragility']['data'].value
@@ -1373,7 +1374,7 @@ def ExecutePanel():
1373
  edges,
1374
  intensity,
1375
  fragility,
1376
- hazard, threshold_flood.value, threshold_flood_distance.value,
1377
  preserve_edge_directions.value,
1378
  earthquake_intensity_unit=earthquake_intensity_unit,
1379
  )
@@ -1400,7 +1401,7 @@ def ExecutePanel():
1400
  flood_depth_reduction = layers.value['flood_depth_reduction'].value
1401
  cdf_median_increase_in_percent = layers.value['cdf_median_increase_in_percent'].value
1402
  damage_curve_suppress_factor = layers.value['damage_curve_suppress_factor'].value
1403
-
1404
 
1405
  policies = [p['id'] for _, p in layers.value['policies'].items() if f"{p['description']} ({p['label']})" in layers.value['selected_policies'].value]
1406
 
@@ -1424,7 +1425,7 @@ def ExecutePanel():
1424
  fragility[['expstr','susceptibility',trigger_level]].rename(columns={trigger_level:'collapse_probability'}),
1425
  layers.value['hazard'].value,
1426
  policies=policies,
1427
- threshold_flood = threshold_flood.value,
1428
  threshold_flood_distance = threshold_flood_distance.value,
1429
  earthquake_intensity_unit=earthquake_intensity_unit,
1430
  cdf_median_increase_in_percent=cdf_median_increase_in_percent,
@@ -1442,7 +1443,7 @@ def ExecutePanel():
1442
  intensity,
1443
  fragility if layers.value['hazard'].value == "earthquake" else vulnerability,
1444
  layers.value['hazard'].value, policies=policies,
1445
- threshold_flood = threshold_flood.value,
1446
  threshold_flood_distance = threshold_flood_distance.value,
1447
  earthquake_intensity_unit=earthquake_intensity_unit,
1448
  cdf_median_increase_in_percent=cdf_median_increase_in_percent,
 
23
  import datetime
24
  from . import storage, user, session_storage, store_in_session_storage, read_from_session_storage
25
  from .settings import landslide_max_trials
26
+ from .settings import threshold_flood_ds2, threshold_flood_ds3, threshold_flood_ds4, threshold_flood_distance, threshold_road_water_height, threshold_culvert_water_height, preserve_edge_directions,\
27
  population_displacement_consensus
28
  from ..backend.engine import compute, compute_power_infra, compute_road_infra, calculate_metrics, generate_exposure, \
29
  create_tally, generate_metrics
 
1357
  fragility = layers.value['layers']['power fragility']['data'].value
1358
  hazard = layers.value['hazard'].value
1359
  earthquake_intensity_unit = layers.value['earthquake_intensity_unit'].value
1360
+ threshold_flood = [threshold_flood_ds2.value, threshold_flood_ds3.value, threshold_flood_ds4.value]
1361
 
1362
  if layers.value['hazard'].value == 'landslide':
1363
  fragility = layers.value['layers']['landslide fragility']['data'].value
 
1374
  edges,
1375
  intensity,
1376
  fragility,
1377
+ hazard, threshold_flood, threshold_flood_distance.value,
1378
  preserve_edge_directions.value,
1379
  earthquake_intensity_unit=earthquake_intensity_unit,
1380
  )
 
1401
  flood_depth_reduction = layers.value['flood_depth_reduction'].value
1402
  cdf_median_increase_in_percent = layers.value['cdf_median_increase_in_percent'].value
1403
  damage_curve_suppress_factor = layers.value['damage_curve_suppress_factor'].value
1404
+ threshold_flood = [threshold_flood_ds2.value, threshold_flood_ds3.value, threshold_flood_ds4.value]
1405
 
1406
  policies = [p['id'] for _, p in layers.value['policies'].items() if f"{p['description']} ({p['label']})" in layers.value['selected_policies'].value]
1407
 
 
1425
  fragility[['expstr','susceptibility',trigger_level]].rename(columns={trigger_level:'collapse_probability'}),
1426
  layers.value['hazard'].value,
1427
  policies=policies,
1428
+ threshold_flood = threshold_flood,
1429
  threshold_flood_distance = threshold_flood_distance.value,
1430
  earthquake_intensity_unit=earthquake_intensity_unit,
1431
  cdf_median_increase_in_percent=cdf_median_increase_in_percent,
 
1443
  intensity,
1444
  fragility if layers.value['hazard'].value == "earthquake" else vulnerability,
1445
  layers.value['hazard'].value, policies=policies,
1446
+ threshold_flood = threshold_flood,
1447
  threshold_flood_distance = threshold_flood_distance.value,
1448
  earthquake_intensity_unit=earthquake_intensity_unit,
1449
  cdf_median_increase_in_percent=cdf_median_increase_in_percent,
tomorrowcities/pages/settings.py CHANGED
@@ -6,7 +6,10 @@ import os
6
  from . import user, config
7
 
8
  landslide_max_trials = solara.reactive(5)
9
- threshold_flood = solara.reactive(0.2)
 
 
 
10
  threshold_flood_distance = solara.reactive(10)
11
  threshold_road_water_height = solara.reactive(0.3)
12
  threshold_culvert_water_height = solara.reactive(1.5)
@@ -31,7 +34,9 @@ def Page(name: Optional[str] = None, page: int = 0, page_size=100):
31
  If the relative damage obtained from the vulnerability curve is beyond
32
  the flood threshold, the structure is assumed to flooded.
33
  After resetting the value, please execute the simulation again to see its effect.''')
34
- solara.SliderFloat(label='Flood Threshold (relative damage)', value=threshold_flood, min=0,max=1, step=0.1)
 
 
35
  solara.Markdown(md_text='''
36
  If the distance from a structure to the nearest flood intensity measure
37
  is greater than Flood Distance, then the structure is assumed to be
 
6
  from . import user, config
7
 
8
  landslide_max_trials = solara.reactive(5)
9
+ threshold_flood_ds2 = solara.reactive(0.05)
10
+ threshold_flood_ds3 = solara.reactive(0.20)
11
+ threshold_flood_ds4 = solara.reactive(0.50)
12
+
13
  threshold_flood_distance = solara.reactive(10)
14
  threshold_road_water_height = solara.reactive(0.3)
15
  threshold_culvert_water_height = solara.reactive(1.5)
 
34
  If the relative damage obtained from the vulnerability curve is beyond
35
  the flood threshold, the structure is assumed to flooded.
36
  After resetting the value, please execute the simulation again to see its effect.''')
37
+ solara.SliderFloat(label='Flood Threshold for DS2', value=threshold_flood_ds2, min=0.05,max=1, step=0.05)
38
+ solara.SliderFloat(label='Flood Threshold for DS3', value=threshold_flood_ds3, min=0.05,max=1, step=0.05)
39
+ solara.SliderFloat(label='Flood Threshold for DS4', value=threshold_flood_ds4, min=0.05,max=1, step=0.05)
40
  solara.Markdown(md_text='''
41
  If the distance from a structure to the nearest flood intensity measure
42
  is greater than Flood Distance, then the structure is assumed to be