This PR implements a simple market research framework (#17) based on residential or non-residential vacancy by zone. Lots of changes here.
Basic logic in this vacancy-based model
Before pro forma step: Add a print function to monitor the regional occupancy for residential and non-residential properties, optionally looking only at a subset of years.
During pro forma step: In parcels table that is passed to the pro forma lookup() method, add one column for each use, in which values are the expected occupancy for each parcel. The current placeholder callback function calculates this as the mean occupancy for either residential units or non-residential square footage in that zone.
During pro forma step: The lookup() method calculates profitability. Along with the latest changes to the developer model, we inject a couple of callbacks here: one to add a column to the DataFrame (weighted occupancy), and one to modify the revenue calculation. Specifically, we multiple weighted occupancy for each parcel by the revenue (so if occupancy is expected to be 80%, you only make 80% of revenue).
During developer step: The pick() method selects buildings for development. Along with latest changes to the developer model, we now inject a custom selection function to pick buildings. The one included here selects all buildings that have above a certain threshold of profitability (per sq ft).
Implementation details
Each of the regions now has a simulation script that runs the new workflow (see e.g. sd_example/Simulation_occupancy.py. The old script runs the old workflow.
Keep in mind that many of the changes are duplicated within the PR (e.g. there's a central version, then one for San Francisco, then one for San Diego). This is necessary just because of different injectable names in some cases.
1. Informational occupancy table
This is not important, but if you're interested see model step here, and the underlying functions here.
2. In lookup(), calculate occupancy
See model code interacting with pro forma model here, and default callback function here.
This PR implements a simple market research framework (#17) based on residential or non-residential vacancy by zone. Lots of changes here.
Basic logic in this vacancy-based model
lookup()
method, add one column for each use, in which values are the expected occupancy for each parcel. The current placeholder callback function calculates this as the mean occupancy for either residential units or non-residential square footage in that zone.lookup()
method calculates profitability. Along with the latest changes to the developer model, we inject a couple of callbacks here: one to add a column to the DataFrame (weighted occupancy), and one to modify the revenue calculation. Specifically, we multiple weighted occupancy for each parcel by the revenue (so if occupancy is expected to be 80%, you only make 80% of revenue).pick()
method selects buildings for development. Along with latest changes to the developer model, we now inject a custom selection function to pick buildings. The one included here selects all buildings that have above a certain threshold of profitability (per sq ft).Implementation details
sd_example/Simulation_occupancy.py
. The old script runs the old workflow.1. Informational occupancy table
This is not important, but if you're interested see model step here, and the underlying functions here.
2. In lookup(), calculate occupancy
See model code interacting with pro forma model here, and default callback function here.
3. Modifications to profit calculation
Callback functions are defined and passed here.
4. Modifications to building selection
Callback functions defined here.