def slr_remove_dev(buildings, destroy_parcels, year, parcels, households, jobs): slr_demolish = buildings.local[buildings.parcel_id.isin (destroy_parcels.index)] orca.add_table("slr_demolish", slr_demolish) print "Demolishing %d buildings" % len(slr_demolish) households = households.to_frame() hh_unplaced = households[households["building_id"] == -1] jobs = jobs.to_frame() jobs_unplaced = jobs[jobs["building_id"] == -1] l1 = len(buildings) buildings = utils._remove_developed_buildings( buildings.to_frame(buildings.local_columns), slr_demolish, unplace_agents=["households", "jobs"]) households = orca.get_table("households") households = households.to_frame() hh_unplaced_slr = households[households["building_id"] == -1] hh_unplaced_slr = hh_unplaced_slr[~hh_unplaced_slr.index.isin (hh_unplaced.index)] orca.add_injectable("hh_unplaced_slr", hh_unplaced_slr) jobs = orca.get_table("jobs") jobs = jobs.to_frame() jobs_unplaced_slr = jobs[jobs["building_id"] == -1] jobs_unplaced_slr = jobs_unplaced_slr[~jobs_unplaced_slr.index.isin (jobs_unplaced.index)] orca.add_injectable("jobs_unplaced_slr", jobs_unplaced_slr) orca.add_table("buildings", buildings) buildings = orca.get_table("buildings") print "Demolished %d buildings" % (l1 - len(buildings))
def slr_remove_dev(buildings, destroy_parcels, year, parcels, households, jobs): slr_demolish = buildings.local[buildings.parcel_id.isin( destroy_parcels.index)] orca.add_table("slr_demolish", slr_demolish) print "Demolishing %d buildings" % len(slr_demolish) households = households.to_frame() hh_unplaced = households[households["building_id"] == -1] jobs = jobs.to_frame() jobs_unplaced = jobs[jobs["building_id"] == -1] l1 = len(buildings) buildings = utils._remove_developed_buildings( buildings.to_frame(buildings.local_columns), slr_demolish, unplace_agents=["households", "jobs"]) households = orca.get_table("households") households = households.to_frame() hh_unplaced_slr = households[households["building_id"] == -1] hh_unplaced_slr = hh_unplaced_slr[~hh_unplaced_slr.index.isin(hh_unplaced. index)] orca.add_injectable("hh_unplaced_slr", hh_unplaced_slr) jobs = orca.get_table("jobs") jobs = jobs.to_frame() jobs_unplaced_slr = jobs[jobs["building_id"] == -1] jobs_unplaced_slr = jobs_unplaced_slr[~jobs_unplaced_slr.index. isin(jobs_unplaced.index)] orca.add_injectable("jobs_unplaced_slr", jobs_unplaced_slr) orca.add_table("buildings", buildings) buildings = orca.get_table("buildings") print "Demolished %d buildings" % (l1 - len(buildings))
def scheduled_development_events(buildings, development_projects, demolish_events, summary, year, parcels, mapping, years_per_iter, parcels_geography, building_sqft_per_job, vmt_fee_categories, static_parcels): # first demolish demolish = demolish_events.to_frame().\ query("%d <= year_built < %d" % (year, year + years_per_iter)) print("Demolishing/building %d buildings" % len(demolish)) l1 = len(buildings) buildings = utils._remove_developed_buildings( buildings.to_frame(buildings.local_columns), demolish, unplace_agents=["households", "jobs"]) orca.add_injectable( 'static_parcels', np.append(static_parcels, demolish.loc[demolish.action == 'build', 'parcel_id'])) orca.add_table("buildings", buildings) buildings = orca.get_table("buildings") print("Demolished %d buildings" % (l1 - len(buildings))) print(" (this number is smaller when parcel has no existing buildings)") # then build dps = development_projects.to_frame().\ query("%d <= year_built < %d" % (year, year + years_per_iter)) if len(dps) == 0: return new_buildings = utils.scheduled_development_events( buildings, dps, remove_developed_buildings=False, unplace_agents=['households', 'jobs']) new_buildings["form"] = new_buildings.building_type.map( mapping['building_type_map']).str.lower() new_buildings["job_spaces"] = new_buildings.non_residential_sqft / \ new_buildings.building_type.fillna("OF").map(building_sqft_per_job) new_buildings["job_spaces"] = new_buildings.job_spaces.\ fillna(0).astype('int') new_buildings["geom_id"] = parcel_id_to_geom_id(new_buildings.parcel_id) new_buildings["SDEM"] = True new_buildings["subsidized"] = False new_buildings["zone_id"] = misc.reindex(parcels.zone_id, new_buildings.parcel_id) new_buildings["vmt_res_cat"] = misc.reindex(vmt_fee_categories.res_cat, new_buildings.zone_id) del new_buildings["zone_id"] new_buildings["pda"] = parcels_geography.pda_id.loc[ new_buildings.parcel_id].values new_buildings["juris_trich"] = parcels_geography.juris_trich.loc[ new_buildings.parcel_id].values summary.add_parcel_output(new_buildings)
def add_buildings(buildings, new_buildings, remove_developed_buildings=True): old_buildings = buildings.to_frame(buildings.local_columns) new_buildings = new_buildings[buildings.local_columns] if remove_developed_buildings: unplace_agents = ["households", "jobs"] old_buildings = \ _remove_developed_buildings(old_buildings, new_buildings, unplace_agents) all_buildings = dev.merge(old_buildings, new_buildings) orca.add_table("buildings", all_buildings)
def scheduled_development_events(buildings, development_projects, demolish_events, summary, year, parcels, settings, years_per_iter, parcels_geography, building_sqft_per_job, vmt_fee_categories): # first demolish demolish = demolish_events.to_frame().\ query("%d <= year_built < %d" % (year, year + years_per_iter)) print "Demolishing/building %d buildings" % len(demolish) l1 = len(buildings) buildings = utils._remove_developed_buildings( buildings.to_frame(buildings.local_columns), demolish, unplace_agents=["households", "jobs"]) orca.add_table("buildings", buildings) buildings = orca.get_table("buildings") print "Demolished %d buildings" % (l1 - len(buildings)) print " (this number is smaller when parcel has no existing buildings)" # then build dps = development_projects.to_frame().\ query("%d <= year_built < %d" % (year, year + years_per_iter)) if len(dps) == 0: return new_buildings = utils.scheduled_development_events( buildings, dps, remove_developed_buildings=False, unplace_agents=['households', 'jobs']) new_buildings["form"] = new_buildings.building_type.map( settings['building_type_map']).str.lower() new_buildings["job_spaces"] = new_buildings.non_residential_sqft / \ new_buildings.building_type.fillna("OF").map(building_sqft_per_job) new_buildings["job_spaces"] = new_buildings.job_spaces.\ fillna(0).astype('int') new_buildings["geom_id"] = parcel_id_to_geom_id(new_buildings.parcel_id) new_buildings["SDEM"] = True new_buildings["subsidized"] = False new_buildings["zone_id"] = misc.reindex( parcels.zone_id, new_buildings.parcel_id) new_buildings["vmt_res_cat"] = misc.reindex( vmt_fee_categories.res_cat, new_buildings.zone_id) del new_buildings["zone_id"] new_buildings["pda"] = parcels_geography.pda_id.loc[ new_buildings.parcel_id].values summary.add_parcel_output(new_buildings)
def add_buildings(buildings, new_buildings, remove_developed_buildings=True): old_buildings = buildings.to_frame(buildings.local_columns) new_buildings = new_buildings[buildings.local_columns] if remove_developed_buildings: unplace_agents = ["households", "jobs"] old_buildings = \ _remove_developed_buildings(old_buildings, new_buildings, unplace_agents) all_buildings = dev.merge(old_buildings, new_buildings) orca.add_table("buildings", all_buildings)
def earthquake_demolish(parcels, parcels_tract, tracts_earthquake, buildings, households, jobs, residential_units, year, earthquake): if year == 2035 and earthquake: # assign each parcel to a census tract # using the lookup table created with "parcel_tract_assignment.ipynb" census_tract = pd.Series(parcels_tract['census_tract'], parcels_tract.index) print "Number of parcels with census tracts is: %d" % len(census_tract) orca.add_column('parcels', 'tract', census_tract) # group parcels by their census tract parcels_tract['parcel_id'] = parcels_tract.index parcels_tract = parcels_tract.to_frame(columns=['parcel_id', 'census_tract']) parcels_tract = parcels_tract[['census_tract', 'parcel_id']] tract_parcels_grp = [] tracts = [] parcels_tract = sorted(parcels_tract.values, key=itemgetter(0)) for tract, parcels in itertools.groupby(parcels_tract, key=itemgetter(0)): tract_parcels_grp.append(list(parcels)) tracts.append(tract) print "Number of census tract groups is: %d" % len(tract_parcels_grp) # for the parcels in each tract, destroy X% of parcels in that tract tracts_earthquake = tracts_earthquake.to_frame() tracts_earthquake = tracts_earthquake.sort_values(by=['tract_ba']) tracts_earthquake = tracts_earthquake.reset_index(drop=True) buildings = buildings.to_frame() eq_buildings = [] existing_buildings = [] new_buildings = [] fire_buildings = [] for i in range(len(tracts)): grp = [x[1] for x in tract_parcels_grp[i]] buildings_i = buildings[buildings['parcel_id'].isin(grp)] # existing buildings # select the buildings with highest fragility co-efficient # (and random no.) based on census tract pct to be destroyed existing_pct = tracts_earthquake['prop_eq'][i] build_frag = buildings_i['eq_destroy'].sort_values(ascending=False) top_build_frag = build_frag[: int(round( len(build_frag) * existing_pct))] # add to a list of buildings to destroy buildings_top = top_build_frag.index existing_buildings.extend(buildings_top) eq_buildings.extend(buildings_top) # new buildings # translate MMI to a probability # in-model is also nice if probabilities associated with # new buildings change buildings_new = buildings_i[buildings_i['year_built'] > 2015] if len(buildings_new) > 0: mmi = int(round(tracts_earthquake['shaking'][i])) if mmi < 6: new_pct = 0 elif mmi == 7: new_pct = .002 elif mmi == 8: new_pct = .01 elif mmi == 9: new_pct = .05 # randomly select buildings to be destroyed based on # percentages new_no = int(round(len(buildings_new)*new_pct)) buildings_new_rand = np.random.choice(buildings_new.index, new_no, replace=False) # add to a list of buildings to destroy if len(buildings_new_rand) > 0: new_buildings.extend(buildings_new_rand) eq_buildings.extend(buildings_new_rand) # fire buildings # select buildings to be destroyed by fire by looking only at # remaining buildings fire_pct = tracts_earthquake['prop_fire'][i] buildings_i_remain = buildings_i[~buildings_i.index.isin (buildings_top)] if len(buildings_new) > 0: buildings_i_remain = buildings_i_remain[~buildings_i_remain. index.isin (buildings_new_rand)] # select buildings to be destroyed based on random number # and census tract pct fire_buildings_rand = buildings_i_remain['fire_destroy']. \ sort_values(ascending=False) top_fire_buildings = fire_buildings_rand[: int(round( len(fire_buildings_rand) * fire_pct))] # add to a list of buildings to destroy buildings_fire = top_fire_buildings.index fire_buildings.extend(buildings_fire) eq_buildings.extend(buildings_fire) print "Total number of buildings being destroyed is: %d" \ % len(eq_buildings) orca.add_injectable("eq_buildings", eq_buildings) orca.add_injectable("existing_buildings", existing_buildings) orca.add_injectable("new_buildings", new_buildings) orca.add_injectable("fire_buildings", fire_buildings) # remove buildings, unplace agents buildings = orca.get_table('buildings') eq_demolish = buildings.local[buildings.index.isin (eq_buildings)] orca.add_table("eq_demolish", eq_demolish) print "Demolishing %d buildings" % len(eq_demolish) households = households.to_frame() hh_unplaced = households[households["building_id"] == -1] jobs = jobs.to_frame() jobs_unplaced = jobs[jobs["building_id"] == -1] l1 = len(buildings) # currently destroying more buildings than it is being # passed- why? buildings = utils._remove_developed_buildings( buildings.to_frame(buildings.local_columns), eq_demolish, unplace_agents=["households", "jobs"]) households = orca.get_table("households") households = households.to_frame() hh_unplaced_eq = households[households["building_id"] == -1] hh_unplaced_eq = hh_unplaced_eq[~hh_unplaced_eq.index.isin (hh_unplaced.index)] orca.add_injectable("hh_unplaced_eq", hh_unplaced_eq) jobs = orca.get_table("jobs") jobs = jobs.to_frame() jobs_unplaced_eq = jobs[jobs["building_id"] == -1] jobs_unplaced_eq = jobs_unplaced_eq[~jobs_unplaced_eq.index.isin (jobs_unplaced.index)] orca.add_injectable("jobs_unplaced_eq", jobs_unplaced_eq) orca.add_table("buildings", buildings) buildings = orca.get_table("buildings") print "Demolished %d buildings" % (l1 - len(buildings))
def earthquake_demolish(parcels, parcels_tract, tracts_earthquake, buildings, households, jobs, residential_units, year, earthquake): if year == 2035 and earthquake: # assign each parcel to a census tract # using the lookup table created with "parcel_tract_assignment.ipynb" census_tract = pd.Series(parcels_tract['census_tract'], parcels_tract.index) print "Number of parcels with census tracts is: %d" % len(census_tract) orca.add_column('parcels', 'tract', census_tract) # group parcels by their census tract parcels_tract['parcel_id'] = parcels_tract.index parcels_tract = parcels_tract.to_frame( columns=['parcel_id', 'census_tract']) parcels_tract = parcels_tract[['census_tract', 'parcel_id']] tract_parcels_grp = [] tracts = [] parcels_tract = sorted(parcels_tract.values, key=itemgetter(0)) for tract, parcels in itertools.groupby(parcels_tract, key=itemgetter(0)): tract_parcels_grp.append(list(parcels)) tracts.append(tract) print "Number of census tract groups is: %d" % len(tract_parcels_grp) # for the parcels in each tract, destroy X% of parcels in that tract tracts_earthquake = tracts_earthquake.to_frame() tracts_earthquake = tracts_earthquake.sort_values(by=['tract_ba']) tracts_earthquake = tracts_earthquake.reset_index(drop=True) buildings = buildings.to_frame() eq_buildings = [] existing_buildings = [] new_buildings = [] fire_buildings = [] for i in range(len(tracts)): grp = [x[1] for x in tract_parcels_grp[i]] buildings_i = buildings[buildings['parcel_id'].isin(grp)] # existing buildings # select the buildings with highest fragility co-efficient # (and random no.) based on census tract pct to be destroyed existing_pct = tracts_earthquake['prop_eq'][i] build_frag = buildings_i['eq_destroy'].sort_values(ascending=False) top_build_frag = build_frag[:int( round(len(build_frag) * existing_pct))] # add to a list of buildings to destroy buildings_top = top_build_frag.index existing_buildings.extend(buildings_top) eq_buildings.extend(buildings_top) # new buildings # translate MMI to a probability # in-model is also nice if probabilities associated with # new buildings change buildings_new = buildings_i[buildings_i['year_built'] > 2015] if len(buildings_new) > 0: mmi = int(round(tracts_earthquake['shaking'][i])) if mmi < 6: new_pct = 0 elif mmi == 7: new_pct = .002 elif mmi == 8: new_pct = .01 elif mmi == 9: new_pct = .05 # randomly select buildings to be destroyed based on # percentages new_no = int(round(len(buildings_new) * new_pct)) buildings_new_rand = np.random.choice(buildings_new.index, new_no, replace=False) # add to a list of buildings to destroy if len(buildings_new_rand) > 0: new_buildings.extend(buildings_new_rand) eq_buildings.extend(buildings_new_rand) # fire buildings # select buildings to be destroyed by fire by looking only at # remaining buildings fire_pct = tracts_earthquake['prop_fire'][i] buildings_i_remain = buildings_i[~buildings_i.index. isin(buildings_top)] if len(buildings_new) > 0: buildings_i_remain = buildings_i_remain[ ~buildings_i_remain.index.isin(buildings_new_rand)] # select buildings to be destroyed based on random number # and census tract pct fire_buildings_rand = buildings_i_remain['fire_destroy']. \ sort_values(ascending=False) top_fire_buildings = fire_buildings_rand[:int( round(len(fire_buildings_rand) * fire_pct))] # add to a list of buildings to destroy buildings_fire = top_fire_buildings.index fire_buildings.extend(buildings_fire) eq_buildings.extend(buildings_fire) print "Total number of buildings being destroyed is: %d" \ % len(eq_buildings) orca.add_injectable("eq_buildings", eq_buildings) orca.add_injectable("existing_buildings", existing_buildings) orca.add_injectable("new_buildings", new_buildings) orca.add_injectable("fire_buildings", fire_buildings) # remove buildings, unplace agents buildings = orca.get_table('buildings') eq_demolish = buildings.local[buildings.index.isin(eq_buildings)] orca.add_table("eq_demolish", eq_demolish) print "Demolishing %d buildings" % len(eq_demolish) households = households.to_frame() hh_unplaced = households[households["building_id"] == -1] jobs = jobs.to_frame() jobs_unplaced = jobs[jobs["building_id"] == -1] l1 = len(buildings) # currently destroying more buildings than it is being # passed- why? buildings = utils._remove_developed_buildings( buildings.to_frame(buildings.local_columns), eq_demolish, unplace_agents=["households", "jobs"]) households = orca.get_table("households") households = households.to_frame() hh_unplaced_eq = households[households["building_id"] == -1] hh_unplaced_eq = hh_unplaced_eq[~hh_unplaced_eq.index.isin(hh_unplaced. index)] orca.add_injectable("hh_unplaced_eq", hh_unplaced_eq) jobs = orca.get_table("jobs") jobs = jobs.to_frame() jobs_unplaced_eq = jobs[jobs["building_id"] == -1] jobs_unplaced_eq = jobs_unplaced_eq[~jobs_unplaced_eq.index. isin(jobs_unplaced.index)] orca.add_injectable("jobs_unplaced_eq", jobs_unplaced_eq) orca.add_table("buildings", buildings) buildings = orca.get_table("buildings") print "Demolished %d buildings" % (l1 - len(buildings))
def run_developer(forms, agents, buildings,supply_fname, parcel_size, ave_unit_size, total_units, feasibility, max_dua_zoning, max_res_units, addl_units,year=None, target_vacancy=.1, use_max_res_units=False, form_to_btype_callback=None, add_more_columns_callback=None, max_parcel_size=2000000, residential=True, bldg_sqft_per_job=400.0, min_unit_size=400, remove_developed_buildings=True, unplace_agents=['households', 'jobs'], num_units_to_build=None, profit_to_prob_func=None): """ Run the developer model to pick and build buildings Parameters ---------- forms : string or list of strings Passed directly dev.pick agents : DataFrame Wrapper Used to compute the current demand for units/floorspace in the area buildings : DataFrame Wrapper Used to compute the current supply of units/floorspace in the area supply_fname : string Identifies the column in buildings which indicates the supply of units/floorspace parcel_size : Series Passed directly to dev.pick ave_unit_size : Series Passed directly to dev.pick - average residential unit size total_units : Series Passed directly to dev.pick - total current residential_units / job_spaces feasibility : DataFrame Wrapper The output from feasibility above (the table called 'feasibility') year : int The year of the simulation - will be assigned to 'year_built' on the new buildings target_vacancy : float The target vacancy rate - used to determine how much to build form_to_btype_callback : function Will be used to convert the 'forms' in the pro forma to 'building_type_id' in the larger model add_more_columns_callback : function Takes a dataframe and returns a dataframe - is used to make custom modifications to the new buildings that get added max_parcel_size : float Passed directly to dev.pick - max parcel size to consider min_unit_size : float Passed directly to dev.pick - min unit size that is valid residential : boolean Passed directly to dev.pick - switches between adding/computing residential_units and job_spaces bldg_sqft_per_job : float Passed directly to dev.pick - specified the multiplier between floor spaces and job spaces for this form (does not vary by parcel as ave_unit_size does) remove_redeveloped_buildings : optional, boolean (default True) Remove all buildings on the parcels which are being developed on unplace_agents : optional , list of strings (default ['households', 'jobs']) For all tables in the list, will look for field building_id and set it to -1 for buildings which are removed - only executed if remove_developed_buildings is true num_units_to_build: optional, int If num_units_to_build is passed, build this many units rather than computing it internally by using the length of agents adn the sum of the relevant supply columin - this trusts the caller to know how to compute this. profit_to_prob_func: func Passed directly to dev.pick Returns ------- Writes the result back to the buildings table and returns the new buildings with available debugging information on each new building """ # num_units_to_build = target_units_def() # ave_unit_size = target_avg_unit_size() dev = developer.Developer(feasibility.to_frame()) target_units = num_units_to_build or dev.\ compute_units_to_build(len(agents), buildings[supply_fname].sum(), target_vacancy) print "{:,} feasible buildings before running developer".format( len(dev.feasibility)) #df = dev.feasibility['residential'] df = dev.feasibility df['residential','max_profit_orig'] = df['residential','max_profit'] df['residential', 'max_profit'].loc[df['residential','max_profit_orig'] < 0] = .001 orca.add_table("feasibility", df) parcels = orca.get_table('parcels').to_frame() df = df['residential'] settings = orca.get_injectable('settings') df["parcel_size"] = parcel_size df["ave_unit_size"] = ave_unit_size df['current_units'] = total_units df['max_dua_zoning'] = max_dua_zoning df['max_res_units'] = max_res_units df['addl_units'] = addl_units df['zoning_id'] = parcels.zoning_id df['siteid'] = parcels.siteid df['zoning_schedule_id'] = parcels.zoning_schedule_id df['acres'] = parcels.parcel_acres df['land_cost_per_sqft'] = settings['default_land_cost'] df['cap_rate'] = settings['sqftproforma_config']['cap_rate'] df['building_efficiency'] = settings['sqftproforma_config']['building_efficiency'] df['min_size_per_unit'] = min_unit_size df['max_dua_from_zoning'] = df['max_dua_zoning'] df['development_type_id'] = parcels.development_type_id df = df[df.parcel_size < max_parcel_size] ''' df['units_from_max_dua_zoning'] = np.NaN df.loc[df['max_dua_from_zoning'] >= 0, 'units_from_max_dua_zoning'] = (df.max_dua_from_zoning * df.acres).round() df['units_from_max_res_zoning'] = df['max_res_units'] df['units_from_zoning'] = np.NaN # final units from zoning df.loc[(df['units_from_max_res_zoning'] >= 0) & (df['units_from_max_dua_zoning'].isnull()), 'units_from_zoning'] = df[ 'units_from_max_res_zoning'] df.loc[(df['units_from_max_res_zoning'].isnull()) & (df['units_from_max_dua_zoning'] >= 0), 'units_from_zoning'] = df[ 'units_from_max_dua_zoning'] df.loc[(df['units_from_max_res_zoning'].isnull()) & (df['units_from_max_dua_zoning'].isnull()), 'units_from_zoning'] = 0 df.loc[(df['units_from_max_res_zoning'] >= 0) & (df['units_from_max_dua_zoning'] >= 0), 'units_from_zoning'] = df[ ['units_from_max_res_zoning', 'units_from_max_dua_zoning']].min(axis=1) ''' ################################################################################################### # for schedule 2 ONLY df['units_from_min_unit_size'] = (df['residential_sqft'] / min_unit_size).round() # df.loc[(df['units_from_max_res_zoning'].isnull()), 'units_from_zoning'] = 0 # end for schedule 2 ONLY ####################################################################################################### df.loc[(df['siteid'] > 0), 'units_from_zoning'] = 0 df['final_units_constrained_by_size'] = df[['addl_units', 'units_from_min_unit_size']].min( axis=1) df['unit_size_from_final'] = df['residential_sqft'] / df['units_from_zoning'] df.loc[(df['unit_size_from_final'] < min_unit_size), 'unit_size_from_final'] = min_unit_size df['final_units_constrained_by_size'] = (df['residential_sqft'] / df['unit_size_from_final']).round() df['net_units'] = df.final_units_constrained_by_size df['roi'] = df['max_profit'] / df['total_cost'] df = df.reset_index(drop=False) df = df.set_index(['parcel_id']) unit_size_from_final = df.unit_size_from_final new_buildings = dev.pick(forms, target_units, parcel_size, unit_size_from_final, total_units, max_parcel_size=max_parcel_size, min_unit_size=min_unit_size, drop_after_build=False, residential=residential, bldg_sqft_per_job=bldg_sqft_per_job, profit_to_prob_func=profit_to_prob_func) orca.add_table("feasibility", dev.feasibility) if new_buildings is None: return if len(new_buildings) == 0: return new_buildings if year is not None: new_buildings["year_built"] = year if not isinstance(forms, list): # form gets set only if forms is a list new_buildings["form"] = forms if form_to_btype_callback is not None: new_buildings["building_type_id"] = new_buildings.\ apply(form_to_btype_callback, axis=1) new_buildings["stories"] = new_buildings.stories.apply(np.ceil) ret_buildings = new_buildings if add_more_columns_callback is not None: new_buildings = add_more_columns_callback(new_buildings) print "Adding {:,} buildings with {:,} {}".\ format(len(new_buildings), int(new_buildings['net_units'].sum()), supply_fname) print "{:,} feasible buildings after running developer".format( len(dev.feasibility)) old_buildings = buildings.to_frame(buildings.local_columns) new_buildings = new_buildings[buildings.local_columns] new_buildings['new_bldg'] = True new_buildings['sch_dev'] = False new_buildings['new_units'] = new_buildings['residential_units'] if remove_developed_buildings: old_buildings = \ utils._remove_developed_buildings(old_buildings, new_buildings, unplace_agents) all_buildings, new_index = dev.merge(old_buildings, new_buildings, return_index=True) ret_buildings.index = new_index orca.add_table("buildings", all_buildings) if "residential_units" in orca.list_tables() and residential: # need to add units to the units table as well old_units = orca.get_table("residential_units") old_units = old_units.to_frame(old_units.local_columns) new_units = pd.DataFrame({ "unit_residential_price": 0, "num_units": 1, "deed_restricted": 0, "unit_num": np.concatenate([np.arange(i) for i in \ new_buildings.residential_units.values]), "building_id": np.repeat(new_buildings.index.values, new_buildings.residential_units.\ astype('int32').values) }).sort(columns=["building_id", "unit_num"]).reset_index(drop=True) print "Adding {:,} units to the residential_units table".\ format(len(new_units)) all_units = dev.merge(old_units, new_units) all_units.index.name = "unit_id" orca.add_table("residential_units", all_units) return ret_buildings # pondered returning ret_buildings, new_units but users can get_table # the units if they want them - better to avoid breaking the api return ret_buildings
def scheduled_development_events(buildings, development_projects, demolish_events, summary, year, parcels, mapping, years_per_iter, parcels_geography, building_sqft_per_job, vmt_fee_categories, static_parcels, base_year): # first demolish # 6/3/20: current approach is to grab projects from the simulation year # and previous four years, however the base year is treated differently, # eg 2015 pulls 2015-2010 # this should be improved in the future so that the base year # also runs SDEM, eg 2015 pulls 2015-2014, while 2010 pulls 2010 projects if year == (base_year + years_per_iter): demolish = demolish_events.to_frame().\ query("%d <= year_built <= %d" % (year - years_per_iter, year)) else: demolish = demolish_events.to_frame().\ query("%d < year_built <= %d" % (year - years_per_iter, year)) print("Demolishing/building %d buildings" % len(demolish)) l1 = len(buildings) buildings = utils._remove_developed_buildings( buildings.to_frame(buildings.local_columns), demolish, unplace_agents=["households", "jobs"]) orca.add_injectable('static_parcels', np.append(static_parcels, demolish.loc[demolish.action == 'build', 'parcel_id'])) orca.add_table("buildings", buildings) buildings = orca.get_table("buildings") print("Demolished %d buildings" % (l1 - len(buildings))) print(" (this number is smaller when parcel has no existing buildings)") # then build # 6/3/20: current approach is to grab projects from the simulation year # and previous four years, however the base year is treated differently, # eg 2015 pulls 2015-2010 # this should be improved in the future so that the base year # also runs SDEM, eg 2015 pulls 2015-2014, while 2010 pulls 2010 projects if year == (base_year + years_per_iter): dps = development_projects.to_frame().\ query("%d <= year_built <= %d" % (year - years_per_iter, year)) else: dps = development_projects.to_frame().\ query("%d < year_built <= %d" % (year - years_per_iter, year)) if len(dps) == 0: return new_buildings = utils.scheduled_development_events( buildings, dps, remove_developed_buildings=False, unplace_agents=['households', 'jobs']) new_buildings["form"] = new_buildings.building_type.map( mapping['building_type_map']).str.lower() new_buildings["job_spaces"] = new_buildings.non_residential_sqft / \ new_buildings.building_type.fillna("OF").map(building_sqft_per_job) new_buildings["job_spaces"] = new_buildings.job_spaces.\ fillna(0).astype('int') new_buildings["geom_id"] = parcel_id_to_geom_id(new_buildings.parcel_id) new_buildings["SDEM"] = True new_buildings["subsidized"] = False new_buildings["zone_id"] = misc.reindex( parcels.zone_id, new_buildings.parcel_id) new_buildings["vmt_res_cat"] = misc.reindex( vmt_fee_categories.res_cat, new_buildings.zone_id) new_buildings["vmt_nonres_cat"] = misc.reindex( vmt_fee_categories.nonres_cat, new_buildings.zone_id) del new_buildings["zone_id"] # add PBA40 geographies new_buildings["pda_pba40"] = parcels_geography.pda_id_pba40.loc[ new_buildings.parcel_id].values # add Horizon geographies new_buildings["juris_trich"] = parcels_geography.juris_trich.loc[ new_buildings.parcel_id].values # add Draft Blueprint geographies new_buildings["pda_pba50"] = parcels_geography.pda_id_pba50.loc[ new_buildings.parcel_id].values new_buildings["tra_id"] = parcels_geography.tra_id.loc[ new_buildings.parcel_id].values new_buildings["ppa_id"] = parcels_geography.ppa_id.loc[ new_buildings.parcel_id].values new_buildings["sesit_id"] = parcels_geography.sesit_id.loc[ new_buildings.parcel_id].values new_buildings["coc_id"] = parcels_geography.coc_id.loc[ new_buildings.parcel_id].values new_buildings["juris_tra"] = parcels_geography.juris_tra.loc[ new_buildings.parcel_id].values new_buildings["juris_ppa"] = parcels_geography.juris_ppa.loc[ new_buildings.parcel_id].values new_buildings["juris_sesit"] = parcels_geography.juris_sesit.loc[ new_buildings.parcel_id].values new_buildings["juris_coc"] = parcels_geography.juris_coc.loc[ new_buildings.parcel_id].values summary.add_parcel_output(new_buildings)
def scheduled_development_events(buildings, development_projects, demolish_events, summary, year, parcels, settings, years_per_iter, parcels_geography, building_sqft_per_job, vmt_fee_categories): # first demolish demolish = demolish_events.to_frame().\ query("%d <= year_built < %d" % (year, year + years_per_iter)) print "Demolishing/building %d buildings" % len(demolish) l1 = len(buildings) buildings = utils._remove_developed_buildings( buildings.to_frame(buildings.local_columns), demolish, unplace_agents=["households", "jobs"]) orca.add_table("buildings", buildings) buildings = orca.get_table("buildings") print "Demolished %d buildings" % (l1 - len(buildings)) print " (this number is smaller when parcel has no existing buildings)" # then build dps = development_projects.to_frame().\ query("%d <= year_built < %d" % (year, year + years_per_iter)) if len(dps) == 0: return new_buildings = utils.scheduled_development_events( buildings, dps, remove_developed_buildings=False, unplace_agents=['households', 'jobs']) new_buildings["form"] = new_buildings.building_type.map( settings['building_type_map']).str.lower() new_buildings["job_spaces"] = new_buildings.nres_sqft / \ new_buildings.building_type.fillna("OF").map(building_sqft_per_job) new_buildings["job_spaces"] = new_buildings.job_spaces.\ fillna(0).astype('int') new_buildings["geom_id"] = parcel_id_to_geom_id(new_buildings.parcel_id) new_buildings["SDEM"] = True new_buildings["subsidized"] = False new_buildings["zone_id"] = misc.reindex( parcels.zone_id, new_buildings.parcel_id) new_buildings["vmt_res_cat"] = misc.reindex( vmt_fee_categories.res_cat, new_buildings.zone_id) del new_buildings["zone_id"] new_buildings["pda"] = parcels_geography.pda_id.loc[ new_buildings.parcel_id].values # Added to make topsheet work. Sketchy though, since only rows added in # this function's summary.add_parcel_output. Other functions that do this # will just have a NaN in this column. Consider changing. if 'total_sqft' not in new_buildings.columns: new_buildings['total_sqft'] = misc.reindex( parcels.total_sqft, new_buildings.PARCEL_ID) if 'superdistrict' not in new_buildings.columns: new_buildings['superdistrict'] = misc.reindex( parcels.superdistrict, new_buildings.PARCEL_ID) if 'juris' not in new_buildings.columns: new_buildings['juris'] = misc.reindex( parcels.juris, new_buildings.PARCEL_ID) summary.add_parcel_output(new_buildings)