def run(self): dataset_pool = SessionConfiguration().get_dataset_pool() current_year = SimulationState().get_current_time() building_set = dataset_pool.get_dataset('building') parcel_set = dataset_pool.get_dataset('parcel') proposal_set = dataset_pool.get_dataset('proposed_development_event') parcels = proposal_set.get_attribute('parcel_id') amount = proposal_set.get_attribute('amount') year = proposal_set.get_attribute('year') proposal_in_current_year = (year==current_year) building_type_id = proposal_set.get_attribute('building_type_id') proposed_sf_units = amount * (building_type_id == 1)*proposal_in_current_year proposed_townhome_units = amount * (building_type_id == 2)*proposal_in_current_year proposed_mf_units = amount * (building_type_id == 3)*proposal_in_current_year proposal_zone = proposal_in_current_year * proposal_set.compute_variables('_proposal_zone = proposed_development_event.disaggregate(parcel.zone_id)') parcel_zone = parcel_set.get_attribute('zone_id') zone_ids = unique(parcel_zone) in_zone = None for zone_id in zone_ids: # proposals_in_zone = where(proposal_zone==zone_id)[0] # logger.log_status("proposals_in_zone %s: %s" % (zone_id,proposals_in_zone.size)) # if proposals_in_zone.size > 0: # logger.log_status("sf units in zone %s: %s" % (zone_id,proposed_sf_units[proposals_in_zone].sum())) # logger.log_status("townhome units in zone %s: %s" % (zone_id,proposed_townhome_units[proposals_in_zone].sum())) # logger.log_status("mf units in zone %s: %s" % (zone_id,proposed_mf_units[proposals_in_zone].sum())) ######Need to come back and look at the treatment of proposed projects. But this won't affect calibration/validation, so proceed for now. if in_zone is not None: building_set.delete_computed_attributes() parcel_set.delete_computed_attributes() in_zone = building_set.compute_variables('_in_zone = building.disaggregate(parcel.zone_id)==%s'% (zone_id)) idx_in_zone = where(in_zone)[0] max_building_id = (building_set.get_attribute('building_id')).max() attribs = building_set.get_known_attribute_names() table_data={} for name in attribs: table_data["%s"%(name)]=building_set.get_attribute("%s" %(name))[idx_in_zone] storage = StorageFactory().get_storage('dict_storage') table_name = 'buildings_zone' storage.write_table( table_name=table_name, table_data=table_data ) buildings_zone = BuildingDataset(in_storage=storage, in_table_name=table_name) if buildings_zone.size() > 0: dptm = RealEstateTransitionModel(target_vancy_dataset=dataset_pool.get_dataset('target_vacancy')) results, index = dptm.run(realestate_dataset = buildings_zone, year = current_year, occupied_spaces_variable = 'occupied_spaces', total_spaces_variable = 'total_spaces', target_attribute_name = 'target_vacancy_rate', sample_from_dataset = dataset_pool.get_dataset('building'), dataset_pool=dataset_pool, append_to_realestate_dataset = False, reset_attribute_value={'parcel_id':-1}, sample_filter="(building.building_type_id==1)*(building.year_built>1989) + (building.building_type_id==3)*(building.year_built>1979) + (building.building_type_id==2)*(building.year_built>1989)+ (building.building_type_id>3)*(building.building_type_id<12)" ) #This is where, now that we know the demand for sqft, I'd want to insert the appropriate amount of permitted/proposed projects. if results is not None: results.modify_attribute('year_built', array(index.size*[current_year])) attribs2 = results.get_known_attribute_names() table_data2={} for name in attribs2: if name in attribs: table_data2["%s"%(name)]=results.get_attribute("%s" %(name)) building_set.add_elements(data=table_data2, require_all_attributes=False, change_ids_if_not_unique=True) index_new_sf_units = where(logical_and(building_set['building_id']>max_building_id, building_set['building_type_id']==1))[0] index_new_mf_units = where(logical_and(building_set['building_id']>max_building_id, (building_set['building_type_id']==2)+(building_set['building_type_id']==3)))[0] index_new_industrial_units = where(logical_and(building_set['building_id']>max_building_id, (building_set['building_type_id']==6)+(building_set['building_type_id']==7)))[0] index_new_commercial_units = where(logical_and(building_set['building_id']>max_building_id, (building_set['building_type_id']==9)+(building_set['building_type_id']==8)))[0] if index_new_sf_units.size > 0: for building in index_new_sf_units: has_available_sf_capacity = parcel_set.compute_variables('_has_available_sf_capacity = (parcel.zone_id==%s) * parcel.disaggregate(zoning.allow_sf==1) * (((safe_array_divide(parcel.parcel_sqft,parcel.disaggregate(zoning.min_lot_size)).round().astype(int32)) - (parcel.number_of_agents(building)))>0)'%(zone_id)) idx_has_available_sf_capacity = where(has_available_sf_capacity)[0] if idx_has_available_sf_capacity.size < 1: logger.log_status("No more single-family capacity remaining in this zone") break parcel_ids_available_sf_capacity=(parcel_set.get_attribute('parcel_id'))[idx_has_available_sf_capacity] shuffle(parcel_ids_available_sf_capacity) parcel_id_to_assign = parcel_ids_available_sf_capacity[:1] building_set.modify_attribute('parcel_id', parcel_id_to_assign, building) if index_new_commercial_units.size > 0: for building in index_new_commercial_units: available_commercial_capacity = parcel_set.compute_variables('_available_commercial_capacity = (parcel.zone_id==%s) * parcel.disaggregate(zoning.allow_comm==1) * clip_to_zero((((parcel.parcel_sqft)*parcel.disaggregate(zoning.max_far)).round().astype(int32)-(parcel.aggregate(1000*building.residential_units))) - (parcel.aggregate(building.non_residential_sqft)))'%(zone_id)) ####update the capacity calcs to account for sqft per unit of hotel/resort units building_sqft = building_set['non_residential_sqft'][building] idx_building_would_fit = where(available_commercial_capacity>=building_sqft)[0] if idx_building_would_fit.size < 1: logger.log_status("No more commercial capacity remaining in this zone") break parcel_ids_with_enough_capacity = (parcel_set.get_attribute('parcel_id'))[idx_building_would_fit] shuffle(parcel_ids_with_enough_capacity) #replace with code involving random/uniform/cumprob/searchsorted etc... I think it would be faster parcel_id_to_assign = parcel_ids_with_enough_capacity[:1] building_set.modify_attribute('parcel_id', parcel_id_to_assign, building) if index_new_industrial_units.size > 0: for building in index_new_industrial_units: available_industrial_capacity = parcel_set.compute_variables('_available_industrial_capacity = (parcel.zone_id==%s) * parcel.disaggregate(zoning.allow_indust==1) * clip_to_zero((((parcel.parcel_sqft)*parcel.disaggregate(zoning.max_far)).round().astype(int32)-(parcel.aggregate(1000*building.residential_units))) - (parcel.aggregate(building.non_residential_sqft)))'%(zone_id)) building_sqft = building_set['non_residential_sqft'][building] idx_building_would_fit = where(available_industrial_capacity>=building_sqft)[0] if idx_building_would_fit.size < 1: logger.log_status("No more industrial capacity remaining in this zone") break parcel_ids_with_enough_capacity = (parcel_set.get_attribute('parcel_id'))[idx_building_would_fit] shuffle(parcel_ids_with_enough_capacity) parcel_id_to_assign = parcel_ids_with_enough_capacity[:1] building_set.modify_attribute('parcel_id', parcel_id_to_assign, building) if index_new_mf_units.size > 0: for building in index_new_mf_units: available_mf_capacity = parcel_set.compute_variables('_available_mf_capacity = (parcel.zone_id==%s) * parcel.disaggregate(zoning.allow_mf==1) * clip_to_zero(((((parcel.parcel_sqft)*parcel.disaggregate(zoning.max_far)).round().astype(int32)) - (parcel.aggregate(building.non_residential_sqft)))/1000 - (parcel.aggregate(building.residential_units)))'%(zone_id)) building_resunits = building_set['residential_units'][building] idx_building_would_fit = where(available_mf_capacity>=building_resunits)[0] if idx_building_would_fit.size < 1: logger.log_status("No more multifamily capacity remaining in this zone") break parcel_ids_with_enough_capacity = (parcel_set.get_attribute('parcel_id'))[idx_building_would_fit] shuffle(parcel_ids_with_enough_capacity) parcel_id_to_assign = parcel_ids_with_enough_capacity[:1] building_set.modify_attribute('parcel_id', parcel_id_to_assign, building) index_unplaced_buildings = where(logical_and(building_set['building_id']>max_building_id, building_set['parcel_id']<=0))[0] logger.log_status("Number of unplaced buildings to be removed from zone%s: %s" % (zone_id,index_unplaced_buildings.size)) building_set.remove_elements(index_unplaced_buildings)
def run(self): dataset_pool = SessionConfiguration().get_dataset_pool() submarket_set = dataset_pool.get_dataset('submarket') building_set = dataset_pool.get_dataset('building') parcel_set = dataset_pool.get_dataset('parcel') current_year = SimulationState().get_current_time() dptm = RealEstateTransitionModel(target_vancy_dataset=dataset_pool.get_dataset('target_vacancy')) results, index = dptm.run(realestate_dataset = dataset_pool.get_dataset('building'), year = current_year, occupied_spaces_variable = 'occupied_spaces', total_spaces_variable = 'total_spaces', target_attribute_name = 'target_vacancy_rate', sample_from_dataset = dataset_pool.get_dataset('building'), dataset_pool=dataset_pool, append_to_realestate_dataset = True, reset_attribute_value={'parcel_id':-1}, sample_filter="(building.building_type_id==1)*(building.year_built>1989) + (building.building_type_id==3)*(building.year_built>1979) + (building.building_type_id==2)*(building.year_built>1989)+ (building.building_type_id>3)*(building.building_type_id<12)" #year_built = 2001, #table_name = 'buildings', #dataset_name = 'building', #id_name = 'building_id' ) #resources=self.compute_resources) logger.log_status("results: %s" % (results)) logger.log_status("index: %s" % (index)) logger.log_status("results_size: %s" % (results.size())) logger.log_status("index_size: %s" % (index.size)) number_of_new_residential_units = results.get_attribute('residential_units')[index].sum() logger.log_status("number_of_new_residential_units: %s" % (number_of_new_residential_units)) new_nonres_sqft = (results.get_attribute('non_residential_sqft') * (results.get_attribute('building_type_id')>3))[index].sum() logger.log_status("new_nonres_sqft: %s" % (new_nonres_sqft)) logger.log_status("building_set: %s" % (building_set)) logger.log_status("building_set_size: %s" % (building_set.size())) number_of_new_residential_units = building_set.get_attribute('residential_units')[index].sum() logger.log_status("number_of_new_residential_units: %s" % (number_of_new_residential_units)) new_nonres_sqft = (building_set.get_attribute('non_residential_sqft') * (building_set.get_attribute('building_type_id')>3))[index].sum() logger.log_status("new_nonres_sqft: %s" % (new_nonres_sqft)) new_sf_units = (building_set.get_attribute('residential_units') * (building_set.get_attribute('building_type_id')==1))[index].sum() new_townhome_units = (building_set.get_attribute('residential_units') * (building_set.get_attribute('building_type_id')==2))[index].sum() new_apartment_units = (building_set.get_attribute('residential_units') * (building_set.get_attribute('building_type_id')==3))[index].sum() new_hotel_sqft = (building_set.get_attribute('non_residential_sqft') * (building_set.get_attribute('building_type_id')==4))[index].sum() new_resort_sqft = (building_set.get_attribute('non_residential_sqft') * (building_set.get_attribute('building_type_id')==5))[index].sum() new_industrial_sqft = (building_set.get_attribute('non_residential_sqft') * (building_set.get_attribute('building_type_id')==6))[index].sum() new_warehouse_sqft = (building_set.get_attribute('non_residential_sqft') * (building_set.get_attribute('building_type_id')==7))[index].sum() new_office_sqft = (building_set.get_attribute('non_residential_sqft') * (building_set.get_attribute('building_type_id')==8))[index].sum() new_retail_sqft = (building_set.get_attribute('non_residential_sqft') * (building_set.get_attribute('building_type_id')==9))[index].sum() new_community_sqft = (building_set.get_attribute('non_residential_sqft') * (building_set.get_attribute('building_type_id')==10))[index].sum() new_other_sqft = (building_set.get_attribute('non_residential_sqft') * (building_set.get_attribute('building_type_id')==11))[index].sum() logger.log_status("new_sf_units: %s" % (new_sf_units)) logger.log_status("new_townhome_units: %s" % (new_townhome_units)) logger.log_status("new_apartment_units: %s" % (new_apartment_units)) logger.log_status("new_hotel_sqft: %s" % (new_hotel_sqft)) logger.log_status("new_resort_sqft: %s" % (new_resort_sqft)) logger.log_status("new_industrial_sqft: %s" % (new_industrial_sqft)) logger.log_status("new_warehouse_sqft: %s" % (new_warehouse_sqft)) logger.log_status("new_office_sqft: %s" % (new_office_sqft)) logger.log_status("new_retail_sqft: %s" % (new_retail_sqft)) logger.log_status("new_community_sqft: %s" % (new_community_sqft)) logger.log_status("new_other_sqft: %s" % (new_other_sqft)) #This is where, now that we know the demand for sqft, I'd want to insert the appropriate amount of permitted/proposed projects. building_set.modify_attribute('year_built', array(index.size*[current_year]), index) minimum_new_building_id = (building_set.get_attribute('building_id'))[index].min() max_old_building_id = minimum_new_building_id - 1 logger.log_status("minimum_new_building_id: %s" % (minimum_new_building_id)) index_new_sf_units = where(logical_and(building_set['building_id']>max_old_building_id, building_set['building_type_id']==1))[0] logger.log_status("index_new_sf_units_size: %s" % (index_new_sf_units.size)) logger.log_status("index_new_sf_units number resunits: %s" % ((building_set['residential_units'])[index_new_sf_units].sum())) #Ok, so come up with a random list of eligible parcel_id's of length index_new_sf_units, then assign these parcel_id's to this index of buildings has_available_sf_capacity = parcel_set.compute_variables('_has_available_sf_capacity = parcel.disaggregate(zoning.allow_sf==1) * (((safe_array_divide(parcel.parcel_sqft,parcel.disaggregate(zoning.min_lot_size)).round().astype(int32)) - (parcel.number_of_agents(building)))>0)') idx_has_available_sf_capacity = where(has_available_sf_capacity)[0] parcel_ids_available_sf_capacity=(parcel_set.get_attribute('parcel_id'))[idx_has_available_sf_capacity] logger.log_status("idx_has_available_sf_capacity: %s" % (idx_has_available_sf_capacity)) logger.log_status("idx_has_available_sf_capacity_size: %s" % (idx_has_available_sf_capacity.size)) logger.log_status("parcel_ids_available_sf_capacity: %s" % (parcel_ids_available_sf_capacity)) logger.log_status("parcel_ids_available_sf_capacity_size: %s" % (parcel_ids_available_sf_capacity.size)) shuffle(parcel_ids_available_sf_capacity) parcel_ids_to_assign = parcel_ids_available_sf_capacity[:index_new_sf_units.size] logger.log_status("parcel_ids_to_assign: %s" % (parcel_ids_to_assign)) logger.log_status("parcel_ids_to_assign_size: %s" % (parcel_ids_to_assign.size)) building_set.modify_attribute('parcel_id', parcel_ids_to_assign, index_new_sf_units) #remember at the end of this program to delete all buildings with parcel_id of -1. These buildings should not be placed because zoning is maxed out (e.g. sf detached will prolly be maxed after 10 yr...) #index_new_townhome_units = where(logical_and(building_set['building_id']>max_old_building_id, building_set['building_type_id']==2))[0] #index_new_apartment_units = where(logical_and(building_set['building_id']>max_old_building_id, building_set['building_type_id']==3))[0] index_new_mf_units = where(logical_and(building_set['building_id']>max_old_building_id, (building_set['building_type_id']==2)+(building_set['building_type_id']==3)))[0] index_new_hotel_units = where(logical_and(building_set['building_id']>max_old_building_id, building_set['building_type_id']==4))[0] index_new_resort_units = where(logical_and(building_set['building_id']>max_old_building_id, building_set['building_type_id']==5))[0] #index_new_industrial_units = where(logical_and(building_set['building_id']>max_old_building_id, building_set['building_type_id']==6))[0] #index_new_warehouse_units = where(logical_and(building_set['building_id']>max_old_building_id, building_set['building_type_id']==7))[0] index_new_industrial_units = where(logical_and(building_set['building_id']>max_old_building_id, (building_set['building_type_id']==6)+(building_set['building_type_id']==7)))[0] #index_new_office_units = where(logical_and(building_set['building_id']>max_old_building_id, building_set['building_type_id']==8))[0] #index_new_retail_units = where(logical_and(building_set['building_id']>max_old_building_id, building_set['building_type_id']==9))[0] index_new_commercial_units = where(logical_and(building_set['building_id']>max_old_building_id, (building_set['building_type_id']==9)+(building_set['building_type_id']==8)))[0] index_new_community_units = where(logical_and(building_set['building_id']>max_old_building_id, building_set['building_type_id']==10))[0] index_new_other_units = where(logical_and(building_set['building_id']>max_old_building_id, building_set['building_type_id']==11))[0] #logger.log_status("index_new_townhome_units_size: %s" % (index_new_townhome_units.size)) #logger.log_status("index_new_apartment_units: %s" % (index_new_apartment_units.size)) logger.log_status("index_new_mf_units: %s" % (index_new_mf_units.size)) logger.log_status("index_new_hotel_units: %s" % (index_new_hotel_units.size)) logger.log_status("index_new_resort_units: %s" % (index_new_resort_units.size)) #logger.log_status("index_new_warehouse_units: %s" % (index_new_warehouse_units.size)) logger.log_status("index_new_industrial_units: %s" % (index_new_industrial_units.size)) #logger.log_status("index_new_office_units: %s" % (index_new_office_units.size)) #logger.log_status("index_new_retail_units: %s" % (index_new_retail_units.size)) logger.log_status("index_new_commercial_units: %s" % (index_new_commercial_units.size)) logger.log_status("index_new_community_units: %s" % (index_new_community_units.size)) logger.log_status("index_new_other_units: %s" % (index_new_other_units.size)) #logger.log_status("index_new_townhome_units number resunits: %s" % ((building_set['residential_units'])[index_new_townhome_units].sum())) #logger.log_status("index_new_apartment_units number resunits: %s" % ((building_set['residential_units'])[index_new_apartment_units].sum())) logger.log_status("index_new_mf_units number resunits: %s" % ((building_set['residential_units'])[index_new_mf_units].sum())) logger.log_status("index_new_hotel_units nonres_sqft: %s" % ((building_set['non_residential_sqft'])[index_new_hotel_units].sum())) logger.log_status("index_new_resort_units nonres_sqft: %s" % ((building_set['non_residential_sqft'])[index_new_resort_units].sum())) #logger.log_status("index_new_industrial_units nonres_sqft: %s" % ((building_set['non_residential_sqft'])[index_new_industrial_units].sum())) #logger.log_status("index_new_warehouse_units nonres_sqft: %s" % ((building_set['non_residential_sqft'])[index_new_warehouse_units].sum())) logger.log_status("index_new_industrial_units nonres_sqft: %s" % ((building_set['non_residential_sqft'])[index_new_industrial_units].sum())) #logger.log_status("index_new_office_units nonres_sqft: %s" % ((building_set['non_residential_sqft'])[index_new_office_units].sum())) #logger.log_status("index_new_retail_units nonres_sqft: %s" % ((building_set['non_residential_sqft'])[index_new_retail_units].sum())) logger.log_status("index_new_commercial_units nonres_sqft: %s" % ((building_set['non_residential_sqft'])[index_new_commercial_units].sum())) logger.log_status("index_new_community_units nonres_sqft: %s" % ((building_set['non_residential_sqft'])[index_new_community_units].sum())) logger.log_status("index_new_other_units nonres_sqft: %s" % ((building_set['non_residential_sqft'])[index_new_other_units].sum())) #Ok, so come up with a random list of eligible parcel_id's of length index_new_sf_units, then assign these parcel_id's to this index of buildings #available_commercial_capacity = parcel_set.compute_variables('_available_commercial_capacity = parcel.disaggregate(zoning.allow_comm==1) * clip_to_zero((((parcel.parcel_sqft)*parcel.disaggregate(zoning.max_far)).round().astype(int32)-(parcel.aggregate(1000*building.residential_units))) - (parcel.aggregate(building.non_residential_sqft)))') for building in index_new_commercial_units: available_commercial_capacity = parcel_set.compute_variables('_available_commercial_capacity = parcel.disaggregate(zoning.allow_comm==1) * clip_to_zero((((parcel.parcel_sqft)*parcel.disaggregate(zoning.max_far)).round().astype(int32)-(parcel.aggregate(1000*building.residential_units))) - (parcel.aggregate(building.non_residential_sqft)))') logger.log_status("available_commercial_capacity: %s" % (available_commercial_capacity)) building_sqft = building_set['non_residential_sqft'][building] logger.log_status("building_sqft: %s" % (building_sqft)) idx_building_would_fit = where(available_commercial_capacity>=building_sqft)[0] logger.log_status("idx_building_would_fit: %s" % (idx_building_would_fit)) parcel_ids_with_enough_capacity = (parcel_set.get_attribute('parcel_id'))[idx_building_would_fit] logger.log_status("parcel_ids_with_enough_capacity: %s" % (parcel_ids_with_enough_capacity)) shuffle(parcel_ids_with_enough_capacity) #replace with code involving random/uniform/cumprob/searchsorted etc... I think it would be faster logger.log_status("parcel_ids_with_enough_capacity: %s" % (parcel_ids_with_enough_capacity)) parcel_id_to_assign = parcel_ids_with_enough_capacity[:1] logger.log_status("parcel_id_to_assign: %s" % (parcel_id_to_assign)) building_set.modify_attribute('parcel_id', parcel_id_to_assign, building) for building in index_new_industrial_units: available_industrial_capacity = parcel_set.compute_variables('_available_industrial_capacity = parcel.disaggregate(zoning.allow_indust==1) * clip_to_zero((((parcel.parcel_sqft)*parcel.disaggregate(zoning.max_far)).round().astype(int32)-(parcel.aggregate(1000*building.residential_units))) - (parcel.aggregate(building.non_residential_sqft)))') logger.log_status("available_industrial_capacity: %s" % (available_industrial_capacity)) building_sqft = building_set['non_residential_sqft'][building] logger.log_status("building_sqft: %s" % (building_sqft)) idx_building_would_fit = where(available_industrial_capacity>=building_sqft)[0] logger.log_status("idx_building_would_fit: %s" % (idx_building_would_fit)) parcel_ids_with_enough_capacity = (parcel_set.get_attribute('parcel_id'))[idx_building_would_fit] logger.log_status("parcel_ids_with_enough_capacity: %s" % (parcel_ids_with_enough_capacity)) shuffle(parcel_ids_with_enough_capacity) #replace with code involving random/uniform/cumprob/searchsorted etc... I think it would be faster logger.log_status("parcel_ids_with_enough_capacity: %s" % (parcel_ids_with_enough_capacity)) parcel_id_to_assign = parcel_ids_with_enough_capacity[:1] logger.log_status("parcel_id_to_assign: %s" % (parcel_id_to_assign)) building_set.modify_attribute('parcel_id', parcel_id_to_assign, building) for building in index_new_mf_units: available_mf_capacity = parcel_set.compute_variables('_available_mf_capacity = parcel.disaggregate(zoning.allow_mf==1) * clip_to_zero(((((parcel.parcel_sqft)*parcel.disaggregate(zoning.max_far)).round().astype(int32)) - (parcel.aggregate(building.non_residential_sqft)))/1000 - (parcel.aggregate(building.residential_units)))') logger.log_status("available_mf_capacity: %s" % (available_mf_capacity)) building_resunits = building_set['residential_units'][building] logger.log_status("building_resunits: %s" % (building_resunits)) idx_building_would_fit = where(available_mf_capacity>=building_resunits)[0] logger.log_status("idx_building_would_fit: %s" % (idx_building_would_fit)) parcel_ids_with_enough_capacity = (parcel_set.get_attribute('parcel_id'))[idx_building_would_fit] logger.log_status("parcel_ids_with_enough_capacity: %s" % (parcel_ids_with_enough_capacity)) shuffle(parcel_ids_with_enough_capacity) #replace with code involving random/uniform/cumprob/searchsorted etc... I think it would be faster logger.log_status("parcel_ids_with_enough_capacity: %s" % (parcel_ids_with_enough_capacity)) parcel_id_to_assign = parcel_ids_with_enough_capacity[:1] logger.log_status("parcel_id_to_assign: %s" % (parcel_id_to_assign)) building_set.modify_attribute('parcel_id', parcel_id_to_assign, building)