Skip to content

Commit 6defd1e

Browse files
authored
Merge pull request UDST#105 from BayAreaMetro/hazards_strategies
Hazards strategies
2 parents ba34046 + 537126e commit 6defd1e

8 files changed

+239567
-61206
lines changed

baus/datasources.py

+15-1
Original file line numberDiff line numberDiff line change
@@ -788,14 +788,28 @@ def zones(store):
788788
return store['zones'].sort_index()
789789

790790

791-
# SLR inundation levels for parcels
791+
# SLR inundation levels for parcels, with full, partial, or no mitigation
792792
@orca.table(cache=True)
793793
def slr_parcel_inundation():
794794
return pd.read_csv(
795795
os.path.join(misc.data_dir(), "slr_parcel_inundation.csv"),
796796
index_col='parcel_id')
797797

798798

799+
@orca.table(cache=True)
800+
def slr_parcel_inundation_mf():
801+
return pd.read_csv(
802+
os.path.join(misc.data_dir(), "slr_parcel_inundation_mf.csv"),
803+
index_col='parcel_id')
804+
805+
806+
@orca.table(cache=True)
807+
def slr_parcel_inundation_mp():
808+
return pd.read_csv(
809+
os.path.join(misc.data_dir(), "slr_parcel_inundation_mp.csv"),
810+
index_col='parcel_id')
811+
812+
799813
# SLR progression by year, for "futures" C, B, R
800814
@orca.table(cache=True)
801815
def slr_progression_C():

baus/earthquake.py

+26-2
Original file line numberDiff line numberDiff line change
@@ -255,8 +255,8 @@ def earthquake_demolish(parcels, parcels_tract, tracts_earthquake, buildings,
255255
return
256256

257257
if year == 2035:
258-
# assign each parcel to a census tract
259-
# using the lookup table created with "parcel_tract_assignment.ipynb"
258+
# assign each parcel to a census tract using the lookup table
259+
# created with scripts/parcel_tract_assignment.py
260260
census_tract = pd.Series(parcels_tract['census_tract'],
261261
parcels_tract.index)
262262
print "Number of parcels with census tracts is: %d" % len(census_tract)
@@ -286,6 +286,7 @@ def earthquake_demolish(parcels, parcels_tract, tracts_earthquake, buildings,
286286
existing_buildings = []
287287
new_buildings = []
288288
fire_buildings = []
289+
retrofit_bldgs_tot = pd.DataFrame()
289290

290291
for i in range(len(tracts)):
291292
grp = [x[1] for x in tract_parcels_grp[i]]
@@ -298,6 +299,29 @@ def earthquake_demolish(parcels, parcels_tract, tracts_earthquake, buildings,
298299
build_frag = buildings_i['eq_destroy'].sort_values(ascending=False)
299300
top_build_frag = build_frag[: int(round(
300301
len(build_frag) * existing_pct))]
302+
# in "strategies" scenarios, exclude some existing buildings
303+
# from destruction due to retrofit
304+
if scenario in settings["eq_scenarios"]["mitigation"]:
305+
retrofit_codes = ['DU01G1N', 'DU01G2N', 'MF01G1N', 'MF01G2N',
306+
'MF25G1N', 'MF25G2N', 'MF25G3N', 'MF25G4N',
307+
'SF01G1N', 'SF2PG1N']
308+
top_build_frag_bldgs = buildings[buildings.index.isin
309+
(top_build_frag.index)]
310+
retrofit_bldgs = top_build_frag_bldgs[top_build_frag_bldgs.
311+
earthquake_code.isin
312+
(retrofit_codes)]
313+
retro_no = round(float(len(retrofit_bldgs))/2)
314+
retrofit_set = np.random.choice(retrofit_bldgs.index,
315+
retro_no, replace=False)
316+
# update top_build_frag to remove retrofit buildings
317+
top_build_frag = top_build_frag[~top_build_frag.index.isin
318+
(retrofit_set)]
319+
# add table of retrofit buildings that weren't destroyed
320+
retrofit_bldgs_set = buildings[buildings.index.isin
321+
(retrofit_set)]
322+
retrofit_bldgs_tot = retrofit_bldgs_tot. \
323+
append(retrofit_bldgs_set)
324+
orca.add_table("retrofit_bldgs_tot", retrofit_bldgs_tot)
301325
# add to a list of buildings to destroy
302326
buildings_top = top_build_frag.index
303327
existing_buildings.extend(buildings_top)

baus/slr.py

+18-6
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,34 @@
1212

1313
@orca.step()
1414
def slr_inundate(scenario, parcels, slr_progression_C, slr_progression_R,
15-
slr_progression_B, year, slr_parcel_inundation, settings):
15+
slr_progression_B, slr_parcel_inundation,
16+
slr_parcel_inundation_mf, slr_parcel_inundation_mp,
17+
year, settings):
1618

1719
if scenario not in settings["slr_scenarios"]["enable_in"]:
1820
return
1921

20-
if scenario in settings["slr_scenarios"]["rtff"]:
22+
if scenario in settings["slr_scenarios"]["rtff_prog"]:
2123
slr_progression = slr_progression_R.to_frame()
22-
elif scenario in settings["slr_scenarios"]["cag"]:
24+
elif scenario in settings["slr_scenarios"]["cag_prog"]:
2325
slr_progression = slr_progression_C.to_frame()
24-
elif scenario in settings["slr_scenarios"]["bttf"]:
26+
elif scenario in settings["slr_scenarios"]["bttf_prog"]:
2527
slr_progression = slr_progression_B.to_frame()
26-
2728
orca.add_table("slr_progression", slr_progression)
29+
2830
inundation_yr = slr_progression.query('year==@year')['inundated'].item()
2931
print "Inundation in model year is %d inches" % inundation_yr
30-
slr_parcel_inundation = slr_parcel_inundation.to_frame()
32+
33+
if scenario in settings["slr_scenarios"]["mitigation_full"]:
34+
slr_parcel_inundation = slr_parcel_inundation_mf.to_frame()
35+
orca.add_injectable("slr_mitigation", 'full mitigation')
36+
elif scenario in settings["slr_scenarios"]["mitigation_partial"]:
37+
slr_parcel_inundation = slr_parcel_inundation_mp.to_frame()
38+
orca.add_injectable("slr_mitigation", 'partial mitigation')
39+
else:
40+
slr_parcel_inundation = slr_parcel_inundation.to_frame()
41+
orca.add_injectable("slr_mitigation", 'none')
42+
3143
destroy_parcels = slr_parcel_inundation.\
3244
query('inundation<=@inundation_yr').astype('bool')
3345
orca.add_table('destroy_parcels', destroy_parcels)

baus/summaries.py

+106-53
Original file line numberDiff line numberDiff line change
@@ -22,20 +22,30 @@ def write(s):
2222
f.write(s + "\n")
2323

2424
# sea level rise
25+
# level
2526
if scenario in settings["slr_scenarios"]["enable_in"]:
2627
slr_progression = orca.get_table("slr_progression")
2728
slr = slr_progression['inundated'].max()
2829
write("Sea level rise in this scenario is %d inches" % slr)
2930
else:
3031
write("There is no sea level rise in this scenario")
32+
# mitigation
33+
slr_mitigation = orca.get_injectable("slr_mitigation")
34+
write("Sea level rise mitigation is %s" % slr_mitigation)
3135

3236
write("")
3337

3438
# earthquake
39+
# activation
3540
if scenario in settings["eq_scenarios"]["enable_in"]:
3641
write("Earthquake is activated")
3742
else:
3843
write("Earthquake is not activated")
44+
# mitigation
45+
if scenario in settings["eq_scenarios"]["mitigation"]:
46+
write("Earthquake retrofit policies are applied")
47+
else:
48+
write("Earthquake retrofit policies are not applied")
3949

4050
write("")
4151

@@ -47,7 +57,6 @@ def write(s):
4757
write("Household control file used: %s" % hh_fname)
4858
emp_fname = orca.get_injectable("employment_control_file")
4959
write("Employment file used: %s" % emp_fname)
50-
# these injectables are not storing ...
5160
reg_fname = orca.get_injectable("reg_control_file")
5261
write("Regional control file used is: %s" % reg_fname)
5362
reg_dem_fname = orca.get_injectable("reg_dem_control_file")
@@ -80,7 +89,6 @@ def write(s):
8089
else:
8190
write("No 2030 non-mandatory accessibility file is set")
8291
# segmentation
83-
# this injectable is also not storing ...
8492
acc_seg_fname_2010 = orca.get_injectable("acc_seg_file_2010")
8593
write("2010 accessibility segmentation file used: %s"
8694
% acc_seg_fname_2010)
@@ -1633,60 +1641,81 @@ def hazards_slr_summary(run_number, year, scenario, households, jobs, parcels,
16331641
if scenario not in settings["slr_scenarios"]["enable_in"]:
16341642
return
16351643

1636-
f = open(os.path.join("runs", "run%d_hazards_slr_%d.log" %
1637-
(run_number, year)), "w")
1644+
destroy_parcels = orca.get_table("destroy_parcels")
1645+
if len(destroy_parcels) > 0:
16381646

1639-
def write(s):
1640-
# print s
1641-
f.write(s + "\n\n")
1647+
def write(s):
1648+
# print s
1649+
f.write(s + "\n\n")
16421650

1643-
destroy_parcels = orca.get_table("destroy_parcels")
1644-
slr_demolish = orca.get_table("slr_demolish")
1645-
n = len(destroy_parcels)
1646-
write("Number of impacted parcels = %d" % n)
1647-
n = slr_demolish['residential_units'].sum()
1648-
write("Number of impacted residential units = %d" % n)
1649-
n = slr_demolish['building_sqft'].sum()
1650-
write("Number of impacted building sqft = %d" % n)
1651-
1652-
# income quartile counts
1653-
hh_unplaced_slr = orca.get_injectable("hh_unplaced_slr")
1654-
1655-
write("Number of impacted households by type")
1656-
1657-
hh_summary = pd.DataFrame(index=[0])
1658-
hh_summary['hhincq1'] = \
1659-
(hh_unplaced_slr["base_income_quartile"] == 1).sum()
1660-
hh_summary['hhincq2'] = \
1661-
(hh_unplaced_slr["base_income_quartile"] == 2).sum()
1662-
hh_summary['hhincq3'] = \
1663-
(hh_unplaced_slr["base_income_quartile"] == 3).sum()
1664-
hh_summary['hhincq4'] = \
1665-
(hh_unplaced_slr["base_income_quartile"] == 4).sum()
1666-
hh_summary.to_string(f, index=False)
1651+
f = open(os.path.join("runs", "run%d_hazards_slr_%d.log" %
1652+
(run_number, year)), "w")
16671653

1668-
write("")
1669-
jobs_unplaced_slr = orca.get_injectable("jobs_unplaced_slr")
1670-
# employees by sector
1654+
n = len(destroy_parcels)
1655+
write("Number of impacted parcels = %d" % n)
1656+
1657+
try:
1658+
slr_demolish_cum = orca.get_table("slr_demolish_cum").to_frame()
1659+
except:
1660+
slr_demolish_cum = pd.DataFrame()
1661+
slr_demolish = orca.get_table("slr_demolish").to_frame()
1662+
slr_demolish_cum = slr_demolish.append(slr_demolish_cum)
1663+
orca.add_table("slr_demolish_cum", slr_demolish_cum)
16711664

1672-
write("Number of impacted jobs by sector")
1665+
n = slr_demolish_cum['residential_units'].sum()
1666+
write("Number of impacted residential units = %d" % n)
1667+
n = slr_demolish_cum['building_sqft'].sum()
1668+
write("Number of impacted building sqft = %d" % n)
16731669

1674-
jobs_summary = pd.DataFrame(index=[0])
1675-
jobs_summary['agrempn'] = (jobs_unplaced_slr["empsix"] == 'AGREMPN').sum()
1676-
jobs_summary['mwtempn'] = (jobs_unplaced_slr["empsix"] == 'MWTEMPN').sum()
1677-
jobs_summary['retempn'] = (jobs_unplaced_slr["empsix"] == 'RETEMPN').sum()
1678-
jobs_summary['fpsempn'] = (jobs_unplaced_slr["empsix"] == 'FPSEMPN').sum()
1679-
jobs_summary['herempn'] = (jobs_unplaced_slr["empsix"] == 'HEREMPN').sum()
1680-
jobs_summary['othempn'] = (jobs_unplaced_slr["empsix"] == 'OTHEMPN').sum()
1681-
jobs_summary.to_string(f, index=False)
1670+
# income quartile counts
1671+
try:
1672+
hh_unplaced_slr_cum = \
1673+
orca.get_table("hh_unplaced_slr_cum").to_frame()
1674+
except:
1675+
hh_unplaced_slr_cum = pd.DataFrame()
1676+
hh_unplaced_slr = orca.get_injectable("hh_unplaced_slr")
1677+
hh_unplaced_slr_cum = hh_unplaced_slr.append(hh_unplaced_slr_cum)
1678+
orca.add_table("hh_unplaced_slr_cum", hh_unplaced_slr_cum)
16821679

1683-
f.close()
1680+
write("Number of impacted households by type")
1681+
hs = pd.DataFrame(index=[0])
1682+
hs['hhincq1'] = \
1683+
(hh_unplaced_slr_cum["base_income_quartile"] == 1).sum()
1684+
hs['hhincq2'] = \
1685+
(hh_unplaced_slr_cum["base_income_quartile"] == 2).sum()
1686+
hs['hhincq3'] = \
1687+
(hh_unplaced_slr_cum["base_income_quartile"] == 3).sum()
1688+
hs['hhincq4'] = \
1689+
(hh_unplaced_slr_cum["base_income_quartile"] == 4).sum()
1690+
hs.to_string(f, index=False)
1691+
1692+
write("")
1693+
1694+
# employees by sector
1695+
try:
1696+
jobs_unplaced_slr_cum = \
1697+
orca.get_table("jobs_unplaced_slr_cum").to_frame()
1698+
except:
1699+
jobs_unplaced_slr_cum = pd.DataFrame()
1700+
jobs_unplaced_slr = orca.get_injectable("jobs_unplaced_slr")
1701+
jobs_unplaced_slr_cum = jobs_unplaced_slr.append(jobs_unplaced_slr_cum)
1702+
orca.add_table("jobs_unplaced_slr_cum", jobs_unplaced_slr_cum)
1703+
1704+
write("Number of impacted jobs by sector")
1705+
js = pd.DataFrame(index=[0])
1706+
js['agrempn'] = (jobs_unplaced_slr_cum["empsix"] == 'AGREMPN').sum()
1707+
js['mwtempn'] = (jobs_unplaced_slr_cum["empsix"] == 'MWTEMPN').sum()
1708+
js['retempn'] = (jobs_unplaced_slr_cum["empsix"] == 'RETEMPN').sum()
1709+
js['fpsempn'] = (jobs_unplaced_slr_cum["empsix"] == 'FPSEMPN').sum()
1710+
js['herempn'] = (jobs_unplaced_slr_cum["empsix"] == 'HEREMPN').sum()
1711+
js['othempn'] = (jobs_unplaced_slr_cum["empsix"] == 'OTHEMPN').sum()
1712+
js.to_string(f, index=False)
1713+
1714+
f.close()
16841715

1685-
slr_demolish = slr_demolish.to_frame()
1686-
slr_demolish = slr_demolish[['parcel_id']]
1687-
slr_demolish.to_csv(os.path.join("runs",
1688-
"run%d_hazards_slr_buildings_%d.csv"
1689-
% (run_number, year)))
1716+
slr_demolish.to_csv(os.path.join("runs",
1717+
"run%d_hazards_slr_buildings_%d.csv"
1718+
% (run_number, year)))
16901719

16911720

16921721
@orca.step()
@@ -1780,29 +1809,53 @@ def write(s):
17801809

17811810
f.close()
17821811

1812+
# print out demolished buildings
17831813
eq_demolish = eq_demolish.to_frame()
17841814
eq_demolish_taz = misc.reindex(parcels.zone_id,
17851815
eq_demolish.parcel_id)
17861816
eq_demolish['taz'] = eq_demolish_taz
1817+
eq_demolish['count'] = 1
17871818
eq_demolish = eq_demolish.drop(['parcel_id', 'year_built',
17881819
'redfin_sale_year'], axis=1)
17891820
eq_demolish = eq_demolish.groupby(['taz']).sum()
17901821
eq_demolish.to_csv(os.path.join("runs",
17911822
"run%d_hazards_eq_demolish_buildings_%d.csv"
17921823
% (run_number, year)))
17931824

1825+
# print out retrofit buildings that were saved
1826+
if scenario in settings["eq_scenarios"]["mitigation"]:
1827+
retrofit_bldgs_tot = orca.get_table("retrofit_bldgs_tot")
1828+
retrofit_bldgs_tot = retrofit_bldgs_tot.to_frame()
1829+
retrofit_bldgs_tot_taz = misc.reindex(parcels.zone_id,
1830+
retrofit_bldgs_tot.parcel_id)
1831+
retrofit_bldgs_tot['taz'] = retrofit_bldgs_tot_taz
1832+
retrofit_bldgs_tot['count'] = 1
1833+
retrofit_bldgs_tot = retrofit_bldgs_tot[[
1834+
'taz', 'residential_units', 'residential_sqft',
1835+
'non_residential_sqft', 'building_sqft', 'stories',
1836+
'redfin_sale_price', 'non_residential_rent',
1837+
'deed_restricted_units', 'residential_price', 'count']]
1838+
retrofit_bldgs_tot = retrofit_bldgs_tot.groupby(['taz']).sum()
1839+
retrofit_bldgs_tot.\
1840+
to_csv(os.path.join(
1841+
"runs", "run%d_hazards_eq_retrofit_buildings_%d.csv"
1842+
% (run_number, year)))
1843+
1844+
# print out buildings in 2030, 2035, and 2050 so Horizon team can compare
1845+
# building inventory by TAZ
17941846
if year in [2030, 2035, 2050] and scenario in \
17951847
settings["eq_scenarios"]["enable_in"]:
17961848
buildings = buildings.to_frame()
17971849
buildings_taz = misc.reindex(parcels.zone_id,
17981850
buildings.parcel_id)
17991851
buildings['taz'] = buildings_taz
1800-
buildings = buildings[['taz', 'residential_units', 'residential_sqft',
1801-
'non_residential_sqft', 'building_sqft',
1802-
'stories', 'redfin_sale_price',
1852+
buildings['count'] = 1
1853+
buildings = buildings[['taz', 'count', 'residential_units',
1854+
'residential_sqft', 'non_residential_sqft',
1855+
'building_sqft', 'stories', 'redfin_sale_price',
18031856
'non_residential_rent', 'deed_restricted_units',
18041857
'residential_price']]
18051858
buildings = buildings.groupby(['taz']).sum()
18061859
buildings.to_csv(os.path.join("runs",
1807-
"run%d_hazards_eq_buildings_%d.csv"
1860+
"run%d_hazards_eq_buildings_list_%d.csv"
18081861
% (run_number, year)))

configs/settings.yaml

+8-4
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,16 @@
1717
# scenarios for hazards models
1818
slr_scenarios:
1919
enable_in: ["1", "2", "5", "11", "12", "15"]
20-
rtff: ["2", "7", "12"]
21-
cag: ["1", "6", "11"]
22-
bttf: ["5", "10", "15"]
20+
rtff_prog: ["2", "7", "12"]
21+
cag_prog: ["1", "6", "11"]
22+
bttf_prog: ["5", "10", "15"]
23+
mitigation_full: ["11", "15"]
24+
mitigation_partial: ["12"]
2325
eq_scenarios:
2426
enable_in: ["1", "2", "5", "11", "12", "15"]
25-
27+
mitigation: ["11", "15"]
28+
# rtff is not mitigated
29+
2630

2731
# these are the tables the get auto-merged to buildings/parcels in the hedonic and lcms
2832
aggregation_tables:

0 commit comments

Comments
 (0)