예제 #1
0
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))
예제 #2
0
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))
예제 #3
0
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)
예제 #4
0
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)
예제 #5
0
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)
예제 #6
0
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))
예제 #8
0
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))
예제 #9
0
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
예제 #10
0
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)
예제 #11
0
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)