Example #1
0
def price_vars(net):
    nodes2 = networks.from_yaml(net, "price_vars.yaml")
    nodes2 = nodes2.fillna(0)
    print nodes2.describe()
    nodes = sim.get_table('nodes')
    nodes = nodes.to_frame().join(nodes2)
    sim.add_table("nodes", nodes)
Example #2
0
def price_vars(net):
    nodes2 = networks.from_yaml(net, "price_vars.yaml")
    nodes2 = nodes2.fillna(0)
    print nodes2.describe()
    nodes = sim.get_table('nodes')
    nodes = nodes.to_frame().join(nodes2)
    sim.add_table("nodes", nodes)
Example #3
0
def simple_transition(tbl, rate, location_fname):
    """
    Run a simple growth rate transition model on the table passed in

    Parameters
    ----------
    tbl : DataFrameWrapper
        Table to be transitioned
    rate : float
        Growth rate
    location_fname : str
        The field name in the resulting dataframe to set to -1 (to unplace
        new agents)

    Returns
    -------
    Nothing
    """
    transition = GrowthRateTransition(rate)
    df = tbl.to_frame(tbl.local_columns)

    print "%d agents before transition" % len(df.index)
    df, added, copied, removed = transition.transition(df, None)
    print "%d agents after transition" % len(df.index)

    df.loc[added, location_fname] = -1
    sim.add_table(tbl.name, df)
Example #4
0
def simple_transition(tbl, rate, location_fname):
    """
    Run a simple growth rate transition model on the table passed in

    Parameters
    ----------
    tbl : DataFrameWrapper
        Table to be transitioned
    rate : float
        Growth rate
    location_fname : str
        The field name in the resulting dataframe to set to -1 (to unplace
        new agents)

    Returns
    -------
    Nothing
    """
    transition = GrowthRateTransition(rate)
    df = tbl.to_frame(tbl.local_columns)

    print "%d agents before transition" % len(df.index)
    df, added, copied, removed = transition.transition(df, None)
    print "%d agents after transition" % len(df.index)

    df.loc[added, location_fname] = -1
    sim.add_table(tbl.name, df)
Example #5
0
def households_transition(households, annual_household_control_totals, year):
    ct = annual_household_control_totals.to_frame()
    tran = transition.TabularTotalsTransition(ct, 'total_number_of_households')
    model = transition.TransitionModel(tran)
    hh = households.to_frame(households.local_columns + ['activity_id', 'luz_id'])
    new, added_hh_idx, empty_dict = \
        model.transition(hh, year,)
    new.loc[added_hh_idx, "building_id"] = -1
    sim.add_table("households", new)
Example #6
0
def simple_transition(tbl, rate, location_fname):
    transition = GrowthRateTransition(rate)
    df = tbl.to_frame(tbl.local_columns)

    print "%d agents before transition" % len(df.index)
    df, added, copied, removed = transition.transition(df, None)
    print "%d agents after transition" % len(df.index)

    df.loc[added, location_fname] = -1
    sim.add_table(tbl.name, df)
Example #7
0
def simple_transition(tbl, rate, location_fname):
    transition = GrowthRateTransition(rate)
    df = tbl.to_frame(tbl.local_columns)

    print "%d agents before transition" % len(df.index)
    df, added, copied, removed = transition.transition(df, None)
    print "%d agents after transition" % len(df.index)

    df.loc[added, location_fname] = -1
    sim.add_table(tbl.name, df)
Example #8
0
def households_transition(households, annual_household_control_totals, year):
    ct = annual_household_control_totals.to_frame()
    tran = transition.TabularTotalsTransition(ct, 'total_number_of_households')
    model = transition.TransitionModel(tran)
    hh = households.to_frame(households.local_columns +
                             ['activity_id', 'luz_id'])
    new, added_hh_idx, empty_dict = \
        model.transition(hh, year,)
    new.loc[added_hh_idx, "building_id"] = -1
    sim.add_table("households", new)
Example #9
0
def build_networks(parcels):
    st = pd.HDFStore(os.path.join(misc.data_dir(), "osm_sandag.h5"), "r")
    nodes, edges = st.nodes, st.edges
    net = pdna.Network(nodes["x"], nodes["y"], edges["from"], edges["to"],
                       edges[["weight"]])
    net.precompute(3000)
    sim.add_injectable("net", net)

    p = parcels.to_frame(parcels.local_columns)
    p['node_id'] = net.get_node_ids(p['x'], p['y'])
    sim.add_table("parcels", p)
Example #10
0
def build_networks(parcels):
    st = pd.HDFStore(os.path.join(misc.data_dir(), "osm_sandag.h5"), "r")
    nodes, edges = st.nodes, st.edges
    net = pdna.Network(nodes["x"], nodes["y"], edges["from"], edges["to"],
                       edges[["weight"]])
    net.precompute(3000)
    sim.add_injectable("net", net)
    
    p = parcels.to_frame(parcels.local_columns)
    p['node_id'] = net.get_node_ids(p['x'], p['y'])
    sim.add_table("parcels", p)
Example #11
0
def run_feasibility(parcels,
                    parcel_price_callback,
                    parcel_use_allowed_callback,
                    residential_to_yearly=True):
    """
    Execute development feasibility on all parcels

    Parameters
    ----------
    parcels : DataFrame Wrapper
        The data frame wrapper for the parcel data
    parcel_price_callback : function
        A callback which takes each use of the pro forma and returns a series
        with index as parcel_id and value as yearly_rent
    parcel_use_allowed_callback : function
        A callback which takes each form of the pro forma and returns a series
        with index as parcel_id and value and boolean whether the form
        is allowed on the parcel
    residential_to_yearly : boolean (default true)
        Whether to use the cap rate to convert the residential price from total
        sales price per sqft to rent per sqft

    Returns
    -------
    Adds a table called feasibility to the sim object (returns nothing)
    """
    pf = sqftproforma.SqFtProForma()

    df = parcels.to_frame()

    # add prices for each use
    for use in pf.config.uses:
        df[use] = parcel_price_callback(use)

    # convert from cost to yearly rent
    if residential_to_yearly:
        df["residential"] *= pf.config.cap_rate

    print "Describe of the yearly rent by use"
    print df[pf.config.uses].describe()

    d = {}
    for form in pf.config.forms:
        print "Computing feasibility for form %s" % form
        d[form] = pf.lookup(form, df[parcel_use_allowed_callback(form)])

    far_predictions = pd.concat(d.values(), keys=d.keys(), axis=1)

    sim.add_table("feasibility", far_predictions)
Example #12
0
def scheduled_development_events(buildings):
    year = get_year()
    sched_dev = pd.read_csv("./data/scheduled_development_events.csv")
    sched_dev = sched_dev[sched_dev.year_built==year]
    sched_dev['residential_sqft'] = sched_dev.sqft_per_unit*sched_dev.residential_units
    sched_dev['job_spaces'] = sched_dev.non_residential_sqft/400
    if len(sched_dev) > 0:
        max_bid = buildings.index.values.max()
        idx = np.arange(max_bid + 1,max_bid+len(sched_dev)+1)
        sched_dev['building_id'] = idx
        sched_dev = sched_dev.set_index('building_id')
        from urbansim.developer.developer import Developer
        merge = Developer(pd.DataFrame({})).merge
        b = buildings.to_frame(buildings.local_columns)
        all_buildings = merge(b,sched_dev[b.columns])
        sim.add_table("buildings", all_buildings)
Example #13
0
def run_feasibility(parcels, parcel_price_callback,
                    parcel_use_allowed_callback, residential_to_yearly=True):
    """
    Execute development feasibility on all parcels

    Parameters
    ----------
    parcels : DataFrame Wrapper
        The data frame wrapper for the parcel data
    parcel_price_callback : function
        A callback which takes each use of the pro forma and returns a series
        with index as parcel_id and value as yearly_rent
    parcel_use_allowed_callback : function
        A callback which takes each form of the pro forma and returns a series
        with index as parcel_id and value and boolean whether the form
        is allowed on the parcel
    residential_to_yearly : boolean (default true)
        Whether to use the cap rate to convert the residential price from total
        sales price per sqft to rent per sqft

    Returns
    -------
    Adds a table called feasibility to the sim object (returns nothing)
    """
    pf = sqftproforma.SqFtProForma()

    df = parcels.to_frame()

    # add prices for each use
    for use in pf.config.uses:
        df[use] = parcel_price_callback(use)

    # convert from cost to yearly rent
    if residential_to_yearly:
        df["residential"] *= pf.config.cap_rate

    print "Describe of the yearly rent by use"
    print df[pf.config.uses].describe()

    d = {}
    for form in pf.config.forms:
        print "Computing feasibility for form %s" % form
        d[form] = pf.lookup(form, df[parcel_use_allowed_callback(form)])

    far_predictions = pd.concat(d.values(), keys=d.keys(), axis=1)

    sim.add_table("feasibility", far_predictions)
Example #14
0
def scheduled_development_events(buildings):
    year = get_year()
    sched_dev = pd.read_csv("./data/scheduled_development_events.csv")
    sched_dev = sched_dev[sched_dev.year_built == year]
    sched_dev[
        'residential_sqft'] = sched_dev.sqft_per_unit * sched_dev.residential_units
    sched_dev['job_spaces'] = sched_dev.non_residential_sqft / 400
    if len(sched_dev) > 0:
        max_bid = buildings.index.values.max()
        idx = np.arange(max_bid + 1, max_bid + len(sched_dev) + 1)
        sched_dev['building_id'] = idx
        sched_dev = sched_dev.set_index('building_id')
        from urbansim.developer.developer import Developer
        merge = Developer(pd.DataFrame({})).merge
        b = buildings.to_frame(buildings.local_columns)
        all_buildings = merge(b, sched_dev[b.columns])
        sim.add_table("buildings", all_buildings)
Example #15
0
def full_transition(agents, agent_controls, year, settings, location_fname):
    """
    Run a transition model based on control totals specified in the usual
    UrbanSim way

    Parameters
    ----------
    agents : DataFrameWrapper
        Table to be transitioned
    agent_controls : DataFrameWrapper
        Table of control totals
    year : int
        The year, which will index into the controls
    settings : dict
        Contains the configuration for the transition model - is specified
        down to the yaml level with a "total_column" which specifies the
        control total and an "add_columns" param which specified which
        columns to add when calling to_frame (should be a list of the columns
        needed to do the transition
    location_fname : str
        The field name in the resulting dataframe to set to -1 (to unplace
        new agents)

    Returns
    -------
    Nothing
    """
    ct = agent_controls.to_frame()
    hh = agents.to_frame(agents.local_columns +
                         settings['add_columns'])
    print "Total agents before transition: {}".format(len(hh))
    tran = transition.TabularTotalsTransition(ct, settings['total_column'])
    model = transition.TransitionModel(tran)
    new, added_hh_idx, new_linked = model.transition(hh, year)
    new.loc[added_hh_idx, location_fname] = -1
    print "Total agents after transition: {}".format(len(new))
    sim.add_table(agents.name, new)
Example #16
0
def full_transition(agents, agent_controls, year, settings, location_fname):
    """
    Run a transition model based on control totals specified in the usual
    UrbanSim way

    Parameters
    ----------
    agents : DataFrameWrapper
        Table to be transitioned
    agent_controls : DataFrameWrapper
        Table of control totals
    year : int
        The year, which will index into the controls
    settings : dict
        Contains the configuration for the transition model - is specified
        down to the yaml level with a "total_column" which specifies the
        control total and an "add_columns" param which specified which
        columns to add when calling to_frame (should be a list of the columns
        needed to do the transition
    location_fname : str
        The field name in the resulting dataframe to set to -1 (to unplace
        new agents)

    Returns
    -------
    Nothing
    """
    ct = agent_controls.to_frame()
    hh = agents.to_frame(agents.local_columns + settings['add_columns'])
    print "Total agents before transition: {}".format(len(hh))
    tran = transition.TabularTotalsTransition(ct, settings['total_column'])
    model = transition.TransitionModel(tran)
    new, added_hh_idx, new_linked = model.transition(hh, year)
    new.loc[added_hh_idx, location_fname] = -1
    print "Total agents after transition: {}".format(len(new))
    sim.add_table(agents.name, new)
Example #17
0
def run_developer(forms, agents, buildings, supply_fname, parcel_size,
                  ave_unit_size, total_units, feasibility, year=None,
                  target_vacancy=.1, 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']):
    """
    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

    Returns
    -------
    Writes the result back to the buildings table and returns the new
    buildings with available debugging information on each new building
    """

    dev = developer.Developer(feasibility.to_frame())

    target_units = dev.\
        compute_units_to_build(len(agents),
                               buildings[supply_fname].sum(),
                               target_vacancy)

    print "{:,} feasible buildings before running developer".format(
          len(dev.feasibility))

    new_buildings = dev.pick(forms,
                             target_units,
                             parcel_size,
                             ave_unit_size,
                             total_units,
                             max_parcel_size=max_parcel_size,
                             min_unit_size=min_unit_size,
                             drop_after_build=True,
                             residential=residential,
                             bldg_sqft_per_job=bldg_sqft_per_job)

    sim.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[supply_fname].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]

    if remove_developed_buildings:
        redev_buildings = old_buildings.parcel_id.isin(new_buildings.parcel_id)
        l = len(old_buildings)
        drop_buildings = old_buildings[redev_buildings]
        old_buildings = old_buildings[np.logical_not(redev_buildings)]
        l2 = len(old_buildings)
        if l2-l > 0:
            print "Dropped {} buildings because they were redeveloped".\
                format(l2-l)

        for tbl in unplace_agents:
            agents = sim.get_table(tbl)
            agents = agents.to_frame(agents.local_columns)
            displaced_agents = agents.building_id.isin(drop_buildings.index)
            print "Unplaced {} before: {}".format(tbl, len(agents.query(
                                                  "building_id == -1")))
            agents.building_id[displaced_agents] = -1
            print "Unplaced {} after: {}".format(tbl, len(agents.query(
                                                 "building_id == -1")))
            sim.add_table(tbl, agents)

    all_buildings = dev.merge(old_buildings, new_buildings)

    sim.add_table("buildings", all_buildings)

    return ret_buildings
Example #18
0
def run_feasibility(parcels, parcel_price_callback,
                    parcel_use_allowed_callback, residential_to_yearly=True,
                    parcel_filter=None, only_built=True, forms_to_test=None,
                    config=None, pass_through=[]):
    """
    Execute development feasibility on all parcels

    Parameters
    ----------
    parcels : DataFrame Wrapper
        The data frame wrapper for the parcel data
    parcel_price_callback : function
        A callback which takes each use of the pro forma and returns a series
        with index as parcel_id and value as yearly_rent
    parcel_use_allowed_callback : function
        A callback which takes each form of the pro forma and returns a series
        with index as parcel_id and value and boolean whether the form
        is allowed on the parcel
    residential_to_yearly : boolean (default true)
        Whether to use the cap rate to convert the residential price from total
        sales price per sqft to rent per sqft
    parcel_filter : string
        A filter to apply to the parcels data frame to remove parcels from
        consideration - is typically used to remove parcels with buildings
        older than a certain date for historical preservation, but is
        generally useful
    only_built : boolean
        Only return those buildings that are profitable - only those buildings
        that "will be built"
    forms_to_test : list of strings (optional)
        Pass the list of the names of forms to test for feasibility - if set to
        None will use all the forms available in ProFormaConfig
    config : SqFtProFormaConfig configuration object.  Optional.  Defaults to
        None
    pass_through : list of strings
        Will be passed to the feasibility lookup function - is used to pass
        variables from the parcel dataframe to the output dataframe, usually
        for debugging

    Returns
    -------
    Adds a table called feasibility to the sim object (returns nothing)
    """

    pf = sqftproforma.SqFtProForma(config) if config \
        else sqftproforma.SqFtProForma()

    df = parcels.to_frame()

    if parcel_filter:
        df = df.query(parcel_filter)

    # add prices for each use
    for use in pf.config.uses:
        # assume we can get the 80th percentile price for new development
        df[use] = parcel_price_callback(use)

    # convert from cost to yearly rent
    if residential_to_yearly:
        df["residential"] *= pf.config.cap_rate

    print "Describe of the yearly rent by use"
    print df[pf.config.uses].describe()

    d = {}
    forms = forms_to_test or pf.config.forms
    for form in forms:
        print "Computing feasibility for form %s" % form
        allowed = parcel_use_allowed_callback(form).loc[df.index]
        d[form] = pf.lookup(form, df[allowed], only_built=only_built,
                            pass_through=pass_through)
        if residential_to_yearly and "residential" in pass_through:
            d[form]["residential"] /= pf.config.cap_rate

    far_predictions = pd.concat(d.values(), keys=d.keys(), axis=1)

    sim.add_table("feasibility", far_predictions)
Example #19
0
def neighborhood_vars(net):
    nodes = networks.from_yaml(net, "neighborhood_vars.yaml")
    nodes = nodes.fillna(0)
    print nodes.describe()
    sim.add_table("nodes", nodes)
Example #20
0
# Use codes were classified manually because the assessor classifications
# are meant for property tax purposes. These classifications should be
# reviewed and revised.
res_codes = {'single': [str(i) for i in range(11, 17)] + ['19'],
             'multi': ['10', '17', '18', '61', '88'] +
                      [str(i) for i in range(20, 30)],
             'mixed': ['48', '89']}
exempt_codes = []


## Register input tables.


tf = TableFrame(staging.parcels_cnc_pt)
sim.add_table('parcels_in', tf, copy_col=False)


## Register intermediate table and columns.

# The purpose of this intermediate table is to compute certain fields,
# like non_residential_sqft and residential_units, before grouping together
# records with the same parc_py_id. Thus, single-family condominium units
# would each be assumed to have one residential unit, and this count would
# be summed when grouping later.


@sim.table()
def parcels_in2(parcels_in):
    return pd.DataFrame(index=parcels_in.index)
Example #21
0
def run_developer(forms, agents, buildings, supply_fname, parcel_size,
                  ave_unit_size, total_units, feasibility, year=None,
                  target_vacancy=.1, form_to_btype_callback=None,
                  add_more_columns_callback=None, max_parcel_size=200000,
                  residential=True, bldg_sqft_per_job=400.0):
    """
    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
    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)

    Returns
    -------
    Writes the result back to the buildings table (returns nothing)
    """

    dev = developer.Developer(feasibility.to_frame())

    target_units = dev.\
        compute_units_to_build(len(agents),
                               buildings[supply_fname].sum(),
                               target_vacancy)

    print "{:,} feasible buildings before running developer".format(
          len(dev.feasibility))

    new_buildings = dev.pick(forms,
                             target_units,
                             parcel_size,
                             ave_unit_size,
                             total_units,
                             max_parcel_size=max_parcel_size,
                             drop_after_build=True,
                             residential=residential,
                             bldg_sqft_per_job=bldg_sqft_per_job)

    sim.add_table("feasibility", dev.feasibility)

    if new_buildings is None:
        return

    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["form"].\
            apply(form_to_btype_callback)

    new_buildings["stories"] = new_buildings.stories.apply(np.ceil)

    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[supply_fname].sum()),
               supply_fname)

    print "{:,} feasible buildings after running developer".format(
          len(dev.feasibility))

    all_buildings = dev.merge(buildings.to_frame(buildings.local_columns),
                              new_buildings[buildings.local_columns])

    sim.add_table("buildings", all_buildings)
Example #22
0
def residential_developer(parcels):
    feas = sim.get_table('feasibility').to_frame()

    year = get_year()

    targets = residential_space_targets()

    print "{:,} feasible buildings before running developer".format(len(feas))

    # LUZ overrides, if applicable
    p = sim.get_table('parcels').to_frame(columns=[
        'luz_id', 'total_residential_units', 'total_sfd_du', 'total_sfa_du',
        'total_mfr_du'
    ])
    feas['luz_id'] = p.luz_id
    overrides = pd.read_csv('./data/overrides/luz_overrides.csv')
    overrides = overrides[overrides.year == year]
    controlled_luzes = np.unique(overrides.luz_id)

    if len(overrides) > 0:

        #Record existing LUZ values
        existing_du = p.groupby('luz_id').total_residential_units.sum()
        existing_sfd_du = p.groupby('luz_id').total_sfd_du.sum()
        existing_sfa_du = p.groupby('luz_id').total_sfa_du.sum()
        existing_mfr_du = p.groupby('luz_id').total_mfr_du.sum()
        existing_df = pd.DataFrame({
            'existing_du': existing_du,
            19: existing_sfd_du,
            20: existing_sfa_du,
            21: existing_mfr_du
        }).fillna(0)
        mini_feases = []
        for luz in controlled_luzes:
            overrides_subset = overrides[overrides.luz_id == luz]
            for devtype in np.unique(overrides_subset.development_type_id):
                target = overrides_subset.target[
                    overrides_subset.development_type_id == devtype].values[0]
                print 'LUZ %s has a DU override target for development type %s of %s.' % (
                    luz, devtype, target)
                existing_du = existing_df[devtype][existing_df.index ==
                                                   luz].values[0]
                print '    There are %s existing units of this type in this LUZ' % existing_du
                difference = target - existing_du
                if difference > 0:
                    feas_subset = feas[feas.luz_id == luz]
                    if len(feas_subset) > 0:
                        if devtype == 19: residential_form = 'sf_detached'
                        if devtype == 20: residential_form = 'sf_attached'
                        if devtype == 21: residential_form = 'mf_residential'
                        feasible_units = feas_subset[
                            residential_form].net_units.sum()
                        if feasible_units > 0:
                            if difference > feasible_units:
                                reallocate = difference - feasible_units
                                print '    Moving %s units to the uncontrolled bucket because only part of the target difference was feasible' % reallocate
                                targets[residential_form] = targets[
                                    residential_form] + reallocate
                            dev_luz = developer.Developer(feas_subset)
                            run_developer(dev_luz,
                                          residential_form,
                                          difference,
                                          year,
                                          build=True)
                            #Store the unbuilt feasible parcels and add back into feasibility later
                            mini_feases.append(dev_luz.feasibility)
                        else:
                            print '    No profitable projects'

    #Uncontrolled LUZs
    print 'Running Developer for uncontrolled LUZs'
    feas = feas[~feas.luz_id.isin(controlled_luzes)]
    dev = developer.Developer(feas)
    for residential_form in [
            'mf_residential',
            'sf_attached',
            'sf_detached',
    ]:
        if residential_form in targets.keys():
            target = targets[residential_form]
            run_developer(dev, residential_form, target, year, build=True)

    #Remaining feasible parcels back to feas after running controlled LUZs so that nonres can be built on these parcels if multiple forms allowed and not already built on
    if len(overrides) > 0:
        feas_list = mini_feases.append(dev.feasibility)
        feas = pd.concat(mini_feases)
        sim.add_table("feasibility", feas)
    else:
        sim.add_table("feasibility", dev.feasibility)

    b = sim.get_table('buildings')
    b = b.to_frame(b.local_columns)
    b_sim = b[(b.note == 'simulated') * (b.year_built == year)]
    print 'Simulated DU: %s' % b_sim.residential_units.sum()
    print 'Target DU: %s' % (targets['sf_detached'] +
                             targets['mf_residential'] + targets['sf_attached']
                             )  #Note:  includes negative when target is lower.
Example #23
0
def residential_developer(parcels):
    feas = sim.get_table('feasibility').to_frame()
    
    year = get_year()
              
    targets = residential_space_targets()
    
    print "{:,} feasible buildings before running developer".format(
          len(feas))
          
    # LUZ overrides, if applicable
    p = sim.get_table('parcels').to_frame(columns = ['luz_id', 'total_residential_units', 'total_sfd_du', 'total_sfa_du', 'total_mfr_du'])
    feas['luz_id'] = p.luz_id
    overrides = pd.read_csv('./data/overrides/luz_overrides.csv')
    overrides = overrides[overrides.year == year]
    controlled_luzes = np.unique(overrides.luz_id)
    
    if len(overrides) > 0:
        
        #Record existing LUZ values
        existing_du = p.groupby('luz_id').total_residential_units.sum()
        existing_sfd_du = p.groupby('luz_id').total_sfd_du.sum()
        existing_sfa_du = p.groupby('luz_id').total_sfa_du.sum()
        existing_mfr_du = p.groupby('luz_id').total_mfr_du.sum()
        existing_df = pd.DataFrame({'existing_du':existing_du,
                           19:existing_sfd_du,
                           20:existing_sfa_du,
                           21:existing_mfr_du}).fillna(0)   
        mini_feases = []
        for luz in controlled_luzes:
            overrides_subset = overrides[overrides.luz_id == luz]
            for devtype in np.unique(overrides_subset.development_type_id):
                target = overrides_subset.target[overrides_subset.development_type_id == devtype].values[0]
                print 'LUZ %s has a DU override target for development type %s of %s.' % (luz, devtype, target)
                existing_du = existing_df[devtype][existing_df.index == luz].values[0]
                print '    There are %s existing units of this type in this LUZ' % existing_du
                difference = target - existing_du
                if difference > 0:
                    feas_subset = feas[feas.luz_id == luz]
                    if len(feas_subset) > 0:
                        if devtype == 19:  residential_form = 'sf_detached'
                        if devtype == 20:  residential_form = 'sf_attached'
                        if devtype == 21:  residential_form = 'mf_residential'
                        feasible_units = feas_subset[residential_form].net_units.sum()
                        if feasible_units > 0:
                            if difference > feasible_units:
                                reallocate = difference - feasible_units
                                print '    Moving %s units to the uncontrolled bucket because only part of the target difference was feasible' % reallocate
                                targets[residential_form] = targets[residential_form] + reallocate
                            dev_luz = developer.Developer(feas_subset)
                            run_developer(dev_luz, residential_form, difference, year, build = True)
                            #Store the unbuilt feasible parcels and add back into feasibility later
                            mini_feases.append(dev_luz.feasibility)
                        else:
                            print '    No profitable projects'
    
    #Uncontrolled LUZs
    print 'Running Developer for uncontrolled LUZs'
    feas = feas[~feas.luz_id.isin(controlled_luzes)]
    dev = developer.Developer(feas)
    for residential_form in ['mf_residential', 'sf_attached', 'sf_detached', ]:
        if residential_form in targets.keys():
            target = targets[residential_form]
            run_developer(dev, residential_form, target, year, build = True)

    #Remaining feasible parcels back to feas after running controlled LUZs so that nonres can be built on these parcels if multiple forms allowed and not already built on
    if len(overrides) > 0:
        feas_list = mini_feases.append(dev.feasibility)
        feas = pd.concat(mini_feases)
        sim.add_table("feasibility", feas)
    else:
        sim.add_table("feasibility", dev.feasibility)
    
    b = sim.get_table('buildings')
    b = b.to_frame(b.local_columns)
    b_sim = b[(b.note == 'simulated') * (b.year_built == year)]
    print 'Simulated DU: %s' % b_sim.residential_units.sum()
    print 'Target DU: %s' % (targets['sf_detached'] + targets['mf_residential'] + targets['sf_attached']) #Note:  includes negative when target is lower.
Example #24
0
def run_developer(forms, agents, buildings, buildings_all, supply_fname, parcel_size,
                  ave_unit_size, total_units, feasibility, year=None,
                  target_vacancy=.1, form_to_btype_callback=None,
                  add_more_columns_callback=None, max_parcel_size=34647265,
                  residential=True, bldg_sqft_per_job=400.0,
                  min_unit_size=400, remove_developed_buildings=True,
                  unplace_agents=['households', 'jobs']):
    """
    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
    buildings_all:
        Buildings for the entire region, used to write back to buildings table
    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

    Returns
    -------
    Writes the result back to the buildings table and returns the new
    buildings with available debugging information on each new building
    """

    dev = developer.Developer(feasibility.to_frame())
    #dev = WFRCDeveloper.WFRCDeveloper(feasibility.to_frame())

    target_units = dev.\
        compute_units_to_build(len(agents),
                               buildings[supply_fname].sum(),
                               target_vacancy)

    print "{:,} feasible buildings before running developer".format(
          len(dev.feasibility))

    new_buildings = dev.pick(forms,
                             target_units,
                             parcel_size,
                             ave_unit_size,
                             total_units,
                             max_parcel_size=max_parcel_size,
                             min_unit_size=min_unit_size,
                             drop_after_build=True,
                             residential=residential,
                             bldg_sqft_per_job=bldg_sqft_per_job)

    sim.add_table("feasibility", dev.feasibility)
    year = sim.get_injectable('year')
    if new_buildings is None:
        return

    if len(new_buildings) == 0:
        return new_buildings
    
    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)
    new_buildings["note"] = "simulated"
    
    ret_buildings = new_buildings
    if add_more_columns_callback is not None:
        new_buildings = add_more_columns_callback(new_buildings)
        
    if year is not None:
        new_buildings["year_built"] = year
    
    print "Adding {:,} buildings with {:,} {}".\
        format(len(new_buildings),
               int(new_buildings[supply_fname].sum()),
               supply_fname)

    print "{:,} feasible buildings after running developer".format(
          len(dev.feasibility))

    old_buildings = buildings.to_frame(buildings.local_columns)
    old_buildings_all = buildings_all.to_frame(buildings.local_columns)
    new_buildings = new_buildings[buildings.local_columns]
    
    if remove_developed_buildings:
        redev_buildings = old_buildings.parcel_id.isin(new_buildings.parcel_id)
        redev_buildings_all = old_buildings_all.parcel_id.isin(new_buildings.parcel_id)
        l = len(old_buildings)
        drop_buildings = old_buildings[redev_buildings]
        drop_buildings_all = old_buildings_all[redev_buildings_all]
        old_buildings = old_buildings[np.logical_not(redev_buildings)]
        old_buildings_all = old_buildings_all[np.logical_not(redev_buildings_all)]
        l2 = len(old_buildings)
        print "before dropped l:" + str(l)
        print "after dropped l2: " + str(l2)
        #print redev_buildings
        #print drop_buildings
        if l2-l > 0:
            print "Dropped {} buildings because they were redeveloped".\
                format(l2-l)

        for tbl in unplace_agents:
            agents = sim.get_table(tbl)
            agents = agents.to_frame(agents.local_columns)
            #displaced_agents = agents.building_id.isin(drop_buildings.index)
            displaced_agents = agents.building_id.isin(drop_buildings_all.index)
            print "Unplaced {} before: {}".format(tbl, len(agents.query(
                                                  "building_id == -1")))
            agents.building_id[displaced_agents] = -1
            print "Unplaced {} after: {}".format(tbl, len(agents.query(
                                                 "building_id == -1")))
            sim.add_table(tbl, agents)
    
    all_buildings = dev.merge(old_buildings_all, new_buildings)
    
    sim.add_table("buildings", all_buildings)

    return ret_buildings
Example #25
0
def run_developer(dev, residential_form, target, year, build = False):
    old_buildings = sim.get_table('buildings').to_frame(sim.get_table('buildings').local_columns)
    parcels = sim.get_table('parcels')
    print 'Residential unit target for %s is %s.' % (residential_form, target)
    if target > 0:
        print residential_form
        drop_after_build = True if build else False
        new_buildings = dev.pick(residential_form,
                                 target,
                                 parcels.parcel_size,
                                 parcels.ave_sqft_per_unit,
                                 parcels.total_residential_units,
                                 max_parcel_size=2000000,
                                 min_unit_size=400,
                                 drop_after_build=True,
                                 residential=True,
                                 bldg_sqft_per_job=400.0)
        if build:
            print 'Constructed %s %s buildings, totaling %s new residential_units' % (len(new_buildings), residential_form, new_buildings.residential_units.sum())
            overshoot = new_buildings.residential_units.sum() - target
            print 'Overshot target by %s units' % (overshoot)
            print 'Biggest development has %s units' % new_buildings.residential_units.max()
            if overshoot > 1:
                to_remove = new_buildings[['parcel_id', 'residential_units']].copy()
                to_remove = to_remove[to_remove.residential_units < 4].set_index('parcel_id')
                to_remove = to_remove.sort('residential_units')
                to_remove['du_cumsum'] = to_remove.residential_units.cumsum()
                idx_to_remove = np.searchsorted(to_remove.du_cumsum, overshoot)
                parcel_ids_to_remove = to_remove.index.values[:(idx_to_remove[0] + 1)]
                print 'Removing %s units to match target' % to_remove.residential_units.values[:(idx_to_remove[0] + 1)].sum()
                new_buildings = new_buildings[~new_buildings.parcel_id.isin(parcel_ids_to_remove)]
            new_buildings["year_built"] = year
            new_buildings["stories"] = new_buildings.stories.apply(np.ceil)
            if residential_form == 'sf_detached':
                new_buildings['development_type_id'] = 19
            elif residential_form == 'sf_attached':
                new_buildings['development_type_id'] = 20
            elif residential_form == 'mf_residential':
                new_buildings['development_type_id'] = 21
            new_buildings['improvement_value'] = 0
            new_buildings['note'] = 'simulated'
            new_buildings['res_price_per_sqft'] = 0.0
            new_buildings['nonres_rent_per_sqft'] = 0.0
            new_buildings = new_buildings[old_buildings.columns]
            
            # Remove redeveloped buildings
            redev_buildings = old_buildings.parcel_id.isin(new_buildings.parcel_id)
            l = len(old_buildings)
            drop_buildings = old_buildings[redev_buildings]
            old_buildings = old_buildings[np.logical_not(redev_buildings)]
            l2 = len(old_buildings)
            if l2-l > 0:
                print "Dropped {} buildings because they were redeveloped".\
                    format(l2-l)

            for tbl in ['households', 'jobs']:
                agents = sim.get_table(tbl)
                agents = agents.to_frame(agents.local_columns)
                displaced_agents = agents.building_id.isin(drop_buildings.index)
                print "Unplaced {} before: {}".format(tbl, len(agents.query(
                                                      "building_id == -1")))
                agents.building_id[displaced_agents] = -1
                print "Unplaced {} after: {}".format(tbl, len(agents.query(
                                                     "building_id == -1")))
                sim.add_table(tbl, agents)
            
            # Update buildings table
            all_buildings = dev.merge(old_buildings, new_buildings)
            sim.add_table("buildings", all_buildings)
        
        else:
            return new_buildings.residential_units.sum()
Example #26
0
def run_feasibility(parcels, parcel_price_callback,
                    parcel_use_allowed_callback, residential_to_yearly=True,
                    parcel_filter=None, only_built=True, forms_to_test=None,
                    config=None, pass_through=[]):
    """
    Execute development feasibility on all parcels

    Parameters
    ----------
    parcels : DataFrame Wrapper
        The data frame wrapper for the parcel data
    parcel_price_callback : function
        A callback which takes each use of the pro forma and returns a series
        with index as parcel_id and value as yearly_rent
    parcel_use_allowed_callback : function
        A callback which takes each form of the pro forma and returns a series
        with index as parcel_id and value and boolean whether the form
        is allowed on the parcel
    residential_to_yearly : boolean (default true)
        Whether to use the cap rate to convert the residential price from total
        sales price per sqft to rent per sqft
    parcel_filter : string
        A filter to apply to the parcels data frame to remove parcels from
        consideration - is typically used to remove parcels with buildings
        older than a certain date for historical preservation, but is
        generally useful
    only_built : boolean
        Only return those buildings that are profitable - only those buildings
        that "will be built"
    forms_to_test : list of strings (optional)
        Pass the list of the names of forms to test for feasibility - if set to
        None will use all the forms available in ProFormaConfig
    config : SqFtProFormaConfig configuration object.  Optional.  Defaults to
        None
    pass_through : list of strings
        Will be passed to the feasibility lookup function - is used to pass
        variables from the parcel dataframe to the output dataframe, usually
        for debugging

    Returns
    -------
    Adds a table called feasibility to the sim object (returns nothing)
    """

    pf = sqftproforma.SqFtProForma(config) if config \
        else sqftproforma.SqFtProForma()

    df = parcels.to_frame()

    if parcel_filter:
        df = df.query(parcel_filter)
    #print df.loc[765403]
    #df.to_csv("select_parcels.csv")
    # add prices for each use
    for use in pf.config.uses:
        # assume we can get the 80th percentile price for new development
        df[use] = parcel_price_callback(use)

    # convert from cost to yearly rent
    if residential_to_yearly:
        df["residential"] *= pf.config.cap_rate

    print "Describe of the yearly rent by use"
    print df[pf.config.uses].describe()

    d = {}
    forms = forms_to_test or pf.config.forms
    for form in forms:
        print "Computing feasibility for form %s" % form
        allowed = parcel_use_allowed_callback(form).loc[df.index]       
        #allowed.to_csv(str(form) + "allow.csv")
        #df[allowed].to_csv(str(form) + "allow.csv")
        d[form] = pf.lookup(form, df[allowed], only_built=only_built,
                            pass_through=pass_through)
        #d[form].to_csv(str(form) + "dform.csv")
        if residential_to_yearly and "residential" in pass_through:
            d[form]["residential"] /= pf.config.cap_rate

    far_predictions = pd.concat(d.values(), keys=d.keys(), axis=1)
    far_predictions['residential'].to_csv("residential_far_prediction.csv")
    far_predictions['retail'].to_csv("retail_far_prediction.csv")
    far_predictions['office'].to_csv("office_far_prediction.csv")
    #far_predictions.to_csv("far_prediction.csv")
    far_predictions['residential'].max_profit = far_predictions['residential'].max_profit / np.power(far_predictions['residential'].max_profit_far*far_predictions['residential'].shape_area,1)
    far_predictions['industrial'].max_profit = far_predictions['industrial'].max_profit / np.power(far_predictions['industrial'].max_profit_far*far_predictions['industrial'].shape_area,1)
    far_predictions['retail'].max_profit = far_predictions['retail'].max_profit / np.power(far_predictions['retail'].max_profit_far*far_predictions['retail'].shape_area,1)
    far_predictions['office'].max_profit = far_predictions['office'].max_profit / np.power(far_predictions['office'].max_profit_far*far_predictions['office'].shape_area,1)
    #far_predictions['residential'].max_profit = np.divide(far_predictions['residential'].max_profit,far_predictions['residential'].max_dua)
    #far_predictions['residential'].max_profit[far_predictions['residential'].max_profit==-np.inf] = np.nan

    sim.add_table("feasibility", far_predictions)
Example #27
0
def feasibility(parcels, settings,
                parcel_sales_price_sqft_func,
                parcel_is_allowed_func):
    # Fee table preprocessing
    fee_schedule = sim.get_table('fee_schedule').to_frame()
    parcel_fee_schedule = sim.get_table('parcel_fee_schedule').to_frame()
    parcels = sim.get_table('parcels').to_frame(columns = ['zoning_id','development_type_id'])
    fee_schedule = fee_schedule.groupby(['fee_schedule_id', 'development_type_id']).development_fee_per_unit_space_initial.mean().reset_index()

    parcel_use_allowed_callback = sim.get_injectable('parcel_is_allowed_func')

    def run_proforma_lookup(parcels, fees, pf, use, form, residential_to_yearly, parcel_filter = None):
        if parcel_filter:
            parcels = parcels.query(parcel_filter)
        # add prices for each use (rents).  Apply fees
        parcels[use] = misc.reindex(sim.get_table('nodes')[use], sim.get_table('parcels').node_id) - fees
        
        #Calibration shifters
        calibration_shifters = pd.read_csv('.\\data\\calibration\\msa_shifters.csv').set_index('msa_id').to_dict()
        
        if use == 'residential':
            shifter_name = 'res_price_shifter'
        else:
            shifter_name = 'nonres_price_shifter'
        parcels[shifter_name] = 1.0
        shifters = calibration_shifters[shifter_name]
        for msa_id in shifters.keys():
            shift = shifters[msa_id]
            parcels[shifter_name][parcels.msa_id == msa_id] = shift
            
        parcels[use] = parcels[use] * parcels[shifter_name]
        
        #LUZ shifter
        if use == 'residential':
            target_luz = pd.read_csv('.\\data\\calibration\\target_luz.csv').values.flatten()
            luz_shifter = pd.read_csv('.\\data\\calibration\\luz_du_shifter.csv').values[0][0]
            parcels[use][parcels.luz_id.isin(target_luz)] = parcels[use][parcels.luz_id.isin(target_luz)] * luz_shifter
            
        # convert from cost to yearly rent
        if residential_to_yearly:
            parcels[use] *= pf.config.cap_rate
            
        # Price minimum if hedonic predicts outlier
        parcels[use][parcels[use] <= .5] = .5
        parcels[use][parcels[use].isnull()] = .5

        print "Describe of the yearly rent by use"
        print parcels[use].describe()
        allowed = parcel_use_allowed_callback(form).loc[parcels.index]
        feasibility = pf.lookup(form, parcels[allowed], only_built=True,
                                    pass_through=[])
                                    
        if use == 'residential':
            def iter_feasibility(feasibility, price_scaling_factor):
                if price_scaling_factor > 3.0:
                    return feasibility
                # Get targets
                target_units = residential_space_targets()[form]
                #Calculate number of profitable units
                d = {}
                d[form] = feasibility
                feas = pd.concat(d.values(), keys=d.keys(), axis=1)
                dev = developer.Developer(feas)
                profitable_units = run_developer(dev, form, target_units, get_year(), build = False)

                print 'Feasibility given current prices/zonining indicates %s profitable units and target of %s' % (profitable_units, target_units)
                
                if profitable_units < target_units:
                    price_scaling_factor += .1
                    print 'Scaling prices up by factor of %s' % price_scaling_factor
                    parcels[use] = parcels[use] * price_scaling_factor
                    feasibility = pf.lookup(form, parcels[allowed], only_built=True,
                                        pass_through=[])
                                        
                    return iter_feasibility(feasibility, price_scaling_factor)
                else:
                    price_scaling_factor += .1
                    parcels[use] = parcels[use] * price_scaling_factor
                    feasibility = pf.lookup(form, parcels[allowed], only_built=True,
                                        pass_through=[])
                    return feasibility
            feasibility = iter_feasibility(feasibility, 1.0)
            
        elif use != 'residential':
            def iter_feasibility(feasibility, price_scaling_factor):
                if price_scaling_factor > 3.0:
                    return feasibility
                # Get targets
                targets = non_residential_space_targets()
                target_units = targets[form]/400
                #Calculate number of profitable units
                feasibility['current_units'] = parcels.total_job_spaces
                feasibility["parcel_size"] = parcels.parcel_size
                feasibility = feasibility[feasibility.parcel_size < 200000]
                feasibility['job_spaces'] = np.round(feasibility.non_residential_sqft / 400.0)
                feasibility['net_units'] = feasibility.job_spaces - feasibility.current_units
                feasibility.net_units = feasibility.net_units.fillna(0)
                profitable_units = int(feasibility.net_units.sum())
                print 'Feasibility given current prices/zonining indicates %s profitable units and target of %s' % (profitable_units, target_units)
                
                if profitable_units < target_units:
                    price_scaling_factor += .1
                    print 'Scaling prices up by factor of %s' % price_scaling_factor
                    parcels[use] = parcels[use] * price_scaling_factor
                    feasibility = pf.lookup(form, parcels[allowed], only_built=True,
                                        pass_through=[])
                                        
                    return iter_feasibility(feasibility, price_scaling_factor)
                else:
                    return feasibility
            feasibility = iter_feasibility(feasibility, 1.0)

        print len(feasibility)
        return feasibility

    def residential_proforma(form, devtype_id, parking_rate):
        print form
        use = 'residential'
        parcels = sim.get_table('parcels').to_frame()
        
        residential_to_yearly = True
        parcel_filter = settings['feasibility']['parcel_filter']
        #parcel_filter = None
        pfc = sqftproforma.SqFtProFormaConfig()
        pfc.forms = {form: {use : 1.0}}
        pfc.uses = [use]
        pfc.residential_uses = [True]
        pfc.parking_rates = {use : parking_rate}
        pfc.costs = {use : [170.0, 190.0, 210.0, 240.0]}

        #Fees
        fee_schedule_devtype = fee_schedule[fee_schedule.development_type_id == devtype_id]
        parcel_fee_schedule_devtype = pd.merge(parcel_fee_schedule, fee_schedule_devtype, left_on = 'fee_schedule_id', right_on = 'fee_schedule_id')
        parcel_fee_schedule_devtype['development_fee_per_unit'] = parcel_fee_schedule_devtype.development_fee_per_unit_space_initial*parcel_fee_schedule_devtype.portion
        parcel_fees_processed = parcel_fee_schedule_devtype.groupby('parcel_id').development_fee_per_unit.sum()
        fees = pd.Series(data = parcel_fees_processed, index = parcels.index).fillna(0)

        pf = sqftproforma.SqFtProForma(pfc)
        
        return run_proforma_lookup(parcels, fees, pf, use, form, residential_to_yearly, parcel_filter = parcel_filter)

    def nonresidential_proforma(form, devtype_id, use, parking_rate):
        print form
        parcels = sim.get_table('parcels').to_frame()
        
        residential_to_yearly = False
        parcel_filter = settings['feasibility']['parcel_filter']
        #parcel_filter = None
        pfc = sqftproforma.SqFtProFormaConfig()
        pfc.forms = {form: {use : 1.0}}
        pfc.uses = [use]
        pfc.residential_uses = [False]
        pfc.parking_rates = {use : parking_rate}
        if use == 'retail':
            pfc.costs = {use : [160.0, 175.0, 200.0, 230.0]}
        elif use == 'industrial':
            pfc.costs = {use : [140.0, 175.0, 200.0, 230.0]}
        else: #office
            pfc.costs = {use : [160.0, 175.0, 200.0, 230.0]}

        #Fees
        fee_schedule_devtype = fee_schedule[fee_schedule.development_type_id == devtype_id]
        parcel_fee_schedule_devtype = pd.merge(parcel_fee_schedule, fee_schedule_devtype, left_on = 'fee_schedule_id', right_on = 'fee_schedule_id')
        parcel_fee_schedule_devtype['development_fee_per_unit'] = parcel_fee_schedule_devtype.development_fee_per_unit_space_initial*parcel_fee_schedule_devtype.portion
        parcel_fees_processed = parcel_fee_schedule_devtype.groupby('parcel_id').development_fee_per_unit.sum()
        fees = pd.Series(data = parcel_fees_processed, index = parcels.index).fillna(0)
        
        pf = sqftproforma.SqFtProForma(pfc)
        fees = fees*pf.config.cap_rate

        return run_proforma_lookup(parcels, fees, pf, use, form, residential_to_yearly, parcel_filter = parcel_filter)

    d = {}

    ##SF DETACHED proforma (devtype 19)
    form = 'sf_detached'
    devtype_id = 19
    d[form] = residential_proforma(form, devtype_id, parking_rate = 1.0)

    ##SF ATTACHED proforma (devtype 20)
    form = 'sf_attached'
    devtype_id = 20
    d[form] = residential_proforma(form, devtype_id, parking_rate = 1.0)

    ##MF_RESIDENTIAL proforma (devtype 21)
    form = 'mf_residential'
    devtype_id = 21
    d[form] = residential_proforma(form, devtype_id, parking_rate = 1.0)

    ##OFFICE (devtype 4)
    form = 'office'
    devtype_id = 4
    d[form] = nonresidential_proforma(form, devtype_id, form, parking_rate = 1.0)

    ##RETAIL (devtype 5)
    form = 'retail'
    devtype_id = 5
    d[form] = nonresidential_proforma(form, devtype_id, form, parking_rate = 2.0)

    ##LIGHT INDUSTRIAL (devtype 2)
    form = 'light_industrial'
    devtype_id = 2
    d[form] = nonresidential_proforma(form, devtype_id, 'industrial', parking_rate = .6)

    ##HEAVY INDUSTRIAL (devtype 3)
    form = 'heavy_industrial'
    devtype_id = 3
    d[form] = nonresidential_proforma(form, devtype_id, 'industrial', parking_rate = .6)

    far_predictions = pd.concat(d.values(), keys=d.keys(), axis=1)
    sim.add_table("feasibility", far_predictions)
Example #28
0
def feasibility(parcels, settings, parcel_sales_price_sqft_func,
                parcel_is_allowed_func):
    # Fee table preprocessing
    fee_schedule = sim.get_table('fee_schedule').to_frame()
    parcel_fee_schedule = sim.get_table('parcel_fee_schedule').to_frame()
    parcels = sim.get_table('parcels').to_frame(
        columns=['zoning_id', 'development_type_id'])
    fee_schedule = fee_schedule.groupby([
        'fee_schedule_id', 'development_type_id'
    ]).development_fee_per_unit_space_initial.mean().reset_index()

    parcel_use_allowed_callback = sim.get_injectable('parcel_is_allowed_func')

    def run_proforma_lookup(parcels,
                            fees,
                            pf,
                            use,
                            form,
                            residential_to_yearly,
                            parcel_filter=None):
        if parcel_filter:
            parcels = parcels.query(parcel_filter)
        # add prices for each use (rents).  Apply fees
        parcels[use] = misc.reindex(
            sim.get_table('nodes')[use],
            sim.get_table('parcels').node_id) - fees

        #Calibration shifters
        calibration_shifters = pd.read_csv(
            '.\\data\\calibration\\msa_shifters.csv').set_index(
                'msa_id').to_dict()

        if use == 'residential':
            shifter_name = 'res_price_shifter'
        else:
            shifter_name = 'nonres_price_shifter'
        parcels[shifter_name] = 1.0
        shifters = calibration_shifters[shifter_name]
        for msa_id in shifters.keys():
            shift = shifters[msa_id]
            parcels[shifter_name][parcels.msa_id == msa_id] = shift

        parcels[use] = parcels[use] * parcels[shifter_name]

        #LUZ shifter
        if use == 'residential':
            target_luz = pd.read_csv(
                '.\\data\\calibration\\target_luz.csv').values.flatten()
            luz_shifter = pd.read_csv(
                '.\\data\\calibration\\luz_du_shifter.csv').values[0][0]
            parcels[use][parcels.luz_id.isin(target_luz)] = parcels[use][
                parcels.luz_id.isin(target_luz)] * luz_shifter

        # convert from cost to yearly rent
        if residential_to_yearly:
            parcels[use] *= pf.config.cap_rate

        # Price minimum if hedonic predicts outlier
        parcels[use][parcels[use] <= .5] = .5
        parcels[use][parcels[use].isnull()] = .5

        print "Describe of the yearly rent by use"
        print parcels[use].describe()
        allowed = parcel_use_allowed_callback(form).loc[parcels.index]
        feasibility = pf.lookup(form,
                                parcels[allowed],
                                only_built=True,
                                pass_through=[])

        if use == 'residential':

            def iter_feasibility(feasibility, price_scaling_factor):
                if price_scaling_factor > 3.0:
                    return feasibility
                # Get targets
                target_units = residential_space_targets()[form]
                #Calculate number of profitable units
                d = {}
                d[form] = feasibility
                feas = pd.concat(d.values(), keys=d.keys(), axis=1)
                dev = developer.Developer(feas)
                profitable_units = run_developer(dev,
                                                 form,
                                                 target_units,
                                                 get_year(),
                                                 build=False)

                print 'Feasibility given current prices/zonining indicates %s profitable units and target of %s' % (
                    profitable_units, target_units)

                if profitable_units < target_units:
                    price_scaling_factor += .1
                    print 'Scaling prices up by factor of %s' % price_scaling_factor
                    parcels[use] = parcels[use] * price_scaling_factor
                    feasibility = pf.lookup(form,
                                            parcels[allowed],
                                            only_built=True,
                                            pass_through=[])

                    return iter_feasibility(feasibility, price_scaling_factor)
                else:
                    price_scaling_factor += .1
                    parcels[use] = parcels[use] * price_scaling_factor
                    feasibility = pf.lookup(form,
                                            parcels[allowed],
                                            only_built=True,
                                            pass_through=[])
                    return feasibility

            feasibility = iter_feasibility(feasibility, 1.0)

        elif use != 'residential':

            def iter_feasibility(feasibility, price_scaling_factor):
                if price_scaling_factor > 3.0:
                    return feasibility
                # Get targets
                targets = non_residential_space_targets()
                target_units = targets[form] / 400
                #Calculate number of profitable units
                feasibility['current_units'] = parcels.total_job_spaces
                feasibility["parcel_size"] = parcels.parcel_size
                feasibility = feasibility[feasibility.parcel_size < 200000]
                feasibility['job_spaces'] = np.round(
                    feasibility.non_residential_sqft / 400.0)
                feasibility[
                    'net_units'] = feasibility.job_spaces - feasibility.current_units
                feasibility.net_units = feasibility.net_units.fillna(0)
                profitable_units = int(feasibility.net_units.sum())
                print 'Feasibility given current prices/zonining indicates %s profitable units and target of %s' % (
                    profitable_units, target_units)

                if profitable_units < target_units:
                    price_scaling_factor += .1
                    print 'Scaling prices up by factor of %s' % price_scaling_factor
                    parcels[use] = parcels[use] * price_scaling_factor
                    feasibility = pf.lookup(form,
                                            parcels[allowed],
                                            only_built=True,
                                            pass_through=[])

                    return iter_feasibility(feasibility, price_scaling_factor)
                else:
                    return feasibility

            feasibility = iter_feasibility(feasibility, 1.0)

        print len(feasibility)
        return feasibility

    def residential_proforma(form, devtype_id, parking_rate):
        print form
        use = 'residential'
        parcels = sim.get_table('parcels').to_frame()

        residential_to_yearly = True
        parcel_filter = settings['feasibility']['parcel_filter']
        #parcel_filter = None
        pfc = sqftproforma.SqFtProFormaConfig()
        pfc.forms = {form: {use: 1.0}}
        pfc.uses = [use]
        pfc.residential_uses = [True]
        pfc.parking_rates = {use: parking_rate}
        pfc.costs = {use: [170.0, 190.0, 210.0, 240.0]}

        #Fees
        fee_schedule_devtype = fee_schedule[fee_schedule.development_type_id ==
                                            devtype_id]
        parcel_fee_schedule_devtype = pd.merge(parcel_fee_schedule,
                                               fee_schedule_devtype,
                                               left_on='fee_schedule_id',
                                               right_on='fee_schedule_id')
        parcel_fee_schedule_devtype[
            'development_fee_per_unit'] = parcel_fee_schedule_devtype.development_fee_per_unit_space_initial * parcel_fee_schedule_devtype.portion
        parcel_fees_processed = parcel_fee_schedule_devtype.groupby(
            'parcel_id').development_fee_per_unit.sum()
        fees = pd.Series(data=parcel_fees_processed,
                         index=parcels.index).fillna(0)

        pf = sqftproforma.SqFtProForma(pfc)

        return run_proforma_lookup(parcels,
                                   fees,
                                   pf,
                                   use,
                                   form,
                                   residential_to_yearly,
                                   parcel_filter=parcel_filter)

    def nonresidential_proforma(form, devtype_id, use, parking_rate):
        print form
        parcels = sim.get_table('parcels').to_frame()

        residential_to_yearly = False
        parcel_filter = settings['feasibility']['parcel_filter']
        #parcel_filter = None
        pfc = sqftproforma.SqFtProFormaConfig()
        pfc.forms = {form: {use: 1.0}}
        pfc.uses = [use]
        pfc.residential_uses = [False]
        pfc.parking_rates = {use: parking_rate}
        if use == 'retail':
            pfc.costs = {use: [160.0, 175.0, 200.0, 230.0]}
        elif use == 'industrial':
            pfc.costs = {use: [140.0, 175.0, 200.0, 230.0]}
        else:  #office
            pfc.costs = {use: [160.0, 175.0, 200.0, 230.0]}

        #Fees
        fee_schedule_devtype = fee_schedule[fee_schedule.development_type_id ==
                                            devtype_id]
        parcel_fee_schedule_devtype = pd.merge(parcel_fee_schedule,
                                               fee_schedule_devtype,
                                               left_on='fee_schedule_id',
                                               right_on='fee_schedule_id')
        parcel_fee_schedule_devtype[
            'development_fee_per_unit'] = parcel_fee_schedule_devtype.development_fee_per_unit_space_initial * parcel_fee_schedule_devtype.portion
        parcel_fees_processed = parcel_fee_schedule_devtype.groupby(
            'parcel_id').development_fee_per_unit.sum()
        fees = pd.Series(data=parcel_fees_processed,
                         index=parcels.index).fillna(0)

        pf = sqftproforma.SqFtProForma(pfc)
        fees = fees * pf.config.cap_rate

        return run_proforma_lookup(parcels,
                                   fees,
                                   pf,
                                   use,
                                   form,
                                   residential_to_yearly,
                                   parcel_filter=parcel_filter)

    d = {}

    ##SF DETACHED proforma (devtype 19)
    form = 'sf_detached'
    devtype_id = 19
    d[form] = residential_proforma(form, devtype_id, parking_rate=1.0)

    ##SF ATTACHED proforma (devtype 20)
    form = 'sf_attached'
    devtype_id = 20
    d[form] = residential_proforma(form, devtype_id, parking_rate=1.0)

    ##MF_RESIDENTIAL proforma (devtype 21)
    form = 'mf_residential'
    devtype_id = 21
    d[form] = residential_proforma(form, devtype_id, parking_rate=1.0)

    ##OFFICE (devtype 4)
    form = 'office'
    devtype_id = 4
    d[form] = nonresidential_proforma(form, devtype_id, form, parking_rate=1.0)

    ##RETAIL (devtype 5)
    form = 'retail'
    devtype_id = 5
    d[form] = nonresidential_proforma(form, devtype_id, form, parking_rate=2.0)

    ##LIGHT INDUSTRIAL (devtype 2)
    form = 'light_industrial'
    devtype_id = 2
    d[form] = nonresidential_proforma(form,
                                      devtype_id,
                                      'industrial',
                                      parking_rate=.6)

    ##HEAVY INDUSTRIAL (devtype 3)
    form = 'heavy_industrial'
    devtype_id = 3
    d[form] = nonresidential_proforma(form,
                                      devtype_id,
                                      'industrial',
                                      parking_rate=.6)

    far_predictions = pd.concat(d.values(), keys=d.keys(), axis=1)
    sim.add_table("feasibility", far_predictions)
Example #29
0
def run_developer(forms,
                  agents,
                  buildings,
                  supply_fname,
                  parcel_size,
                  ave_unit_size,
                  total_units,
                  feasibility,
                  year=None,
                  target_vacancy=.1,
                  form_to_btype_callback=None,
                  add_more_columns_callback=None,
                  max_parcel_size=200000,
                  residential=True,
                  bldg_sqft_per_job=400.0):
    """
    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
    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)

    Returns
    -------
    Writes the result back to the buildings table (returns nothing)
    """

    dev = developer.Developer(feasibility.to_frame())

    target_units = dev.\
        compute_units_to_build(len(agents),
                               buildings[supply_fname].sum(),
                               target_vacancy)

    print "{:,} feasible buildings before running developer".format(
        len(dev.feasibility))

    new_buildings = dev.pick(forms,
                             target_units,
                             parcel_size,
                             ave_unit_size,
                             total_units,
                             max_parcel_size=max_parcel_size,
                             drop_after_build=True,
                             residential=residential,
                             bldg_sqft_per_job=bldg_sqft_per_job)

    sim.add_table("feasibility", dev.feasibility)

    if new_buildings is None:
        return

    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["form"].\
            apply(form_to_btype_callback)

    new_buildings["stories"] = new_buildings.stories.apply(np.ceil)

    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[supply_fname].sum()),
               supply_fname)

    print "{:,} feasible buildings after running developer".format(
        len(dev.feasibility))

    all_buildings = dev.merge(buildings.to_frame(buildings.local_columns),
                              new_buildings[buildings.local_columns])

    sim.add_table("buildings", all_buildings)
Example #30
0
def non_residential_developer(parcels):
    feas = sim.get_table('feasibility').to_frame()
    dev = developer.Developer(feas)
    
    print "{:,} feasible buildings before running developer".format(
              len(dev.feasibility))
    
    year = get_year()
    
    targets = non_residential_space_targets()
           
    for non_residential_form in ['heavy_industrial', 'light_industrial', 'retail', 'office']:
        if non_residential_form in targets.keys():
            old_buildings = sim.get_table('buildings').to_frame(sim.get_table('buildings').local_columns)

            target = targets[non_residential_form]
            target = target/400
            print 'Job space target for %s is %s.' % (non_residential_form, target)
            
            if target > 0:
                new_buildings = dev.pick(non_residential_form,
                                         target,
                                         parcels.parcel_size,
                                         parcels.ave_sqft_per_unit,
                                         parcels.total_job_spaces,
                                         max_parcel_size=2000000,
                                         min_unit_size=0,
                                         drop_after_build=True,
                                         residential=False,
                                         bldg_sqft_per_job=400.0)
                
                print 'Constructed %s %s buildings, totaling %s new job spaces.' % (len(new_buildings), non_residential_form, new_buildings.non_residential_sqft.sum()/400)
                
                new_buildings["year_built"] = year
                new_buildings["stories"] = new_buildings.stories.apply(np.ceil)
                if non_residential_form == 'light_industrial':
                    new_buildings['development_type_id'] = 2
                elif non_residential_form == 'heavy_industrial':
                    new_buildings['development_type_id'] = 3
                elif non_residential_form == 'office':
                    new_buildings['development_type_id'] = 4
                elif non_residential_form == 'retail':
                    new_buildings['development_type_id'] = 5
                new_buildings['improvement_value'] = 0
                new_buildings['note'] = 'simulated'
                new_buildings['res_price_per_sqft'] = 0.0
                new_buildings['nonres_rent_per_sqft'] = 0.0
                new_buildings = new_buildings[old_buildings.columns]
                
                # Remove redeveloped buildings
                redev_buildings = old_buildings.parcel_id.isin(new_buildings.parcel_id)
                l = len(old_buildings)
                drop_buildings = old_buildings[redev_buildings]
                old_buildings = old_buildings[np.logical_not(redev_buildings)]
                l2 = len(old_buildings)
                if l2-l > 0:
                    print "Dropped {} buildings because they were redeveloped".\
                        format(l2-l)

                for tbl in ['households', 'jobs']:
                    agents = sim.get_table(tbl)
                    agents = agents.to_frame(agents.local_columns)
                    displaced_agents = agents.building_id.isin(drop_buildings.index)
                    print "Unplaced {} before: {}".format(tbl, len(agents.query(
                                                          "building_id == -1")))
                    agents.building_id[displaced_agents] = -1
                    print "Unplaced {} after: {}".format(tbl, len(agents.query(
                                                         "building_id == -1")))
                    sim.add_table(tbl, agents)
                    
                # Update buildings table
                all_buildings = dev.merge(old_buildings, new_buildings)
                sim.add_table("buildings", all_buildings)
                
    sim.add_table("feasibility", dev.feasibility)
Example #31
0
def non_residential_developer(parcels):
    feas = sim.get_table('feasibility').to_frame()
    dev = developer.Developer(feas)

    print "{:,} feasible buildings before running developer".format(
        len(dev.feasibility))

    year = get_year()

    targets = non_residential_space_targets()

    for non_residential_form in [
            'heavy_industrial', 'light_industrial', 'retail', 'office'
    ]:
        if non_residential_form in targets.keys():
            old_buildings = sim.get_table('buildings').to_frame(
                sim.get_table('buildings').local_columns)

            target = targets[non_residential_form]
            target = target / 400
            print 'Job space target for %s is %s.' % (non_residential_form,
                                                      target)

            if target > 0:
                new_buildings = dev.pick(non_residential_form,
                                         target,
                                         parcels.parcel_size,
                                         parcels.ave_sqft_per_unit,
                                         parcels.total_job_spaces,
                                         max_parcel_size=2000000,
                                         min_unit_size=0,
                                         drop_after_build=True,
                                         residential=False,
                                         bldg_sqft_per_job=400.0)

                print 'Constructed %s %s buildings, totaling %s new job spaces.' % (
                    len(new_buildings), non_residential_form,
                    new_buildings.non_residential_sqft.sum() / 400)

                new_buildings["year_built"] = year
                new_buildings["stories"] = new_buildings.stories.apply(np.ceil)
                if non_residential_form == 'light_industrial':
                    new_buildings['development_type_id'] = 2
                elif non_residential_form == 'heavy_industrial':
                    new_buildings['development_type_id'] = 3
                elif non_residential_form == 'office':
                    new_buildings['development_type_id'] = 4
                elif non_residential_form == 'retail':
                    new_buildings['development_type_id'] = 5
                new_buildings['improvement_value'] = 0
                new_buildings['note'] = 'simulated'
                new_buildings['res_price_per_sqft'] = 0.0
                new_buildings['nonres_rent_per_sqft'] = 0.0
                new_buildings = new_buildings[old_buildings.columns]

                # Remove redeveloped buildings
                redev_buildings = old_buildings.parcel_id.isin(
                    new_buildings.parcel_id)
                l = len(old_buildings)
                drop_buildings = old_buildings[redev_buildings]
                old_buildings = old_buildings[np.logical_not(redev_buildings)]
                l2 = len(old_buildings)
                if l2 - l > 0:
                    print "Dropped {} buildings because they were redeveloped".\
                        format(l2-l)

                for tbl in ['households', 'jobs']:
                    agents = sim.get_table(tbl)
                    agents = agents.to_frame(agents.local_columns)
                    displaced_agents = agents.building_id.isin(
                        drop_buildings.index)
                    print "Unplaced {} before: {}".format(
                        tbl, len(agents.query("building_id == -1")))
                    agents.building_id[displaced_agents] = -1
                    print "Unplaced {} after: {}".format(
                        tbl, len(agents.query("building_id == -1")))
                    sim.add_table(tbl, agents)

                # Update buildings table
                all_buildings = dev.merge(old_buildings, new_buildings)
                sim.add_table("buildings", all_buildings)

    sim.add_table("feasibility", dev.feasibility)
Example #32
0
def run_developer(dev, residential_form, target, year, build=False):
    old_buildings = sim.get_table('buildings').to_frame(
        sim.get_table('buildings').local_columns)
    parcels = sim.get_table('parcels')
    print 'Residential unit target for %s is %s.' % (residential_form, target)
    if target > 0:
        print residential_form
        drop_after_build = True if build else False
        new_buildings = dev.pick(residential_form,
                                 target,
                                 parcels.parcel_size,
                                 parcels.ave_sqft_per_unit,
                                 parcels.total_residential_units,
                                 max_parcel_size=2000000,
                                 min_unit_size=400,
                                 drop_after_build=True,
                                 residential=True,
                                 bldg_sqft_per_job=400.0)
        if build:
            print 'Constructed %s %s buildings, totaling %s new residential_units' % (
                len(new_buildings), residential_form,
                new_buildings.residential_units.sum())
            overshoot = new_buildings.residential_units.sum() - target
            print 'Overshot target by %s units' % (overshoot)
            print 'Biggest development has %s units' % new_buildings.residential_units.max(
            )
            if overshoot > 1:
                to_remove = new_buildings[['parcel_id',
                                           'residential_units']].copy()
                to_remove = to_remove[
                    to_remove.residential_units < 4].set_index('parcel_id')
                to_remove = to_remove.sort('residential_units')
                to_remove['du_cumsum'] = to_remove.residential_units.cumsum()
                idx_to_remove = np.searchsorted(to_remove.du_cumsum, overshoot)
                parcel_ids_to_remove = to_remove.index.values[:(
                    idx_to_remove[0] + 1)]
                print 'Removing %s units to match target' % to_remove.residential_units.values[:(
                    idx_to_remove[0] + 1)].sum()
                new_buildings = new_buildings[~new_buildings.parcel_id.
                                              isin(parcel_ids_to_remove)]
            new_buildings["year_built"] = year
            new_buildings["stories"] = new_buildings.stories.apply(np.ceil)
            if residential_form == 'sf_detached':
                new_buildings['development_type_id'] = 19
            elif residential_form == 'sf_attached':
                new_buildings['development_type_id'] = 20
            elif residential_form == 'mf_residential':
                new_buildings['development_type_id'] = 21
            new_buildings['improvement_value'] = 0
            new_buildings['note'] = 'simulated'
            new_buildings['res_price_per_sqft'] = 0.0
            new_buildings['nonres_rent_per_sqft'] = 0.0
            new_buildings = new_buildings[old_buildings.columns]

            # Remove redeveloped buildings
            redev_buildings = old_buildings.parcel_id.isin(
                new_buildings.parcel_id)
            l = len(old_buildings)
            drop_buildings = old_buildings[redev_buildings]
            old_buildings = old_buildings[np.logical_not(redev_buildings)]
            l2 = len(old_buildings)
            if l2 - l > 0:
                print "Dropped {} buildings because they were redeveloped".\
                    format(l2-l)

            for tbl in ['households', 'jobs']:
                agents = sim.get_table(tbl)
                agents = agents.to_frame(agents.local_columns)
                displaced_agents = agents.building_id.isin(
                    drop_buildings.index)
                print "Unplaced {} before: {}".format(
                    tbl, len(agents.query("building_id == -1")))
                agents.building_id[displaced_agents] = -1
                print "Unplaced {} after: {}".format(
                    tbl, len(agents.query("building_id == -1")))
                sim.add_table(tbl, agents)

            # Update buildings table
            all_buildings = dev.merge(old_buildings, new_buildings)
            sim.add_table("buildings", all_buildings)

        else:
            return new_buildings.residential_units.sum()
Example #33
0
# Use codes were classified manually because the assessor classifications
# are meant for property tax purposes. These classifications should be
# reviewed and revised.
res_codes = {
    'single': ['01', '51', '52', '53'],
    'multi':
    [string.zfill(i, 2) for i in range(2, 6) + range(7, 10) + range(89, 99)],
    'mixed': []
}
exempt_codes = []

## Register input tables.

tf = TableFrame(staging.parcels_smt, index_col='apn')
sim.add_table('parcels_in', tf, copy_col=False)


@sim.table(cache=True)
def roll():
    mdb = loader.get_path(
        'built/parcel/2010/smt/Property Characteristics/ASSESSOR_ROLL.mdb')
    csv = os.path.splitext(mdb)[0] + '.csv'

    if not os.path.exists(csv):
        with open(csv, 'w') as f:
            # Export of MS Access database requires mdbtools.
            subprocess.check_call(['mdb-export', mdb, '2009_ROLL'], stdout=f)

    df = pd.read_csv(csv, dtype={'APN': str}, low_memory=False)
Example #34
0
def neighborhood_vars(net):
    nodes = networks.from_yaml(net, "neighborhood_vars.yaml")
    nodes = nodes.fillna(0)
    print nodes.describe()
    sim.add_table("nodes", nodes)