Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

School location #40

Merged
merged 3 commits into from
Apr 10, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion activitysim/defaults/misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def data_dir():
return '.'


@sim.injectable(cache=True)
@sim.injectable()
def settings(configs_dir):
with open(os.path.join(configs_dir, "configs", "settings.yaml")) as f:
return yaml.load(f)
Expand Down
1 change: 1 addition & 0 deletions activitysim/defaults/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@
import non_mandatory_tour_frequency
import mandatory_scheduling
import non_mandatory_scheduling
import school_location
import workplace_location
import mode
3 changes: 0 additions & 3 deletions activitysim/defaults/models/auto_ownership.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@
with given characteristics owns
"""

# this is the max number of cars allowable in the auto ownership model
MAX_NUM_CARS = 5


@sim.injectable()
def auto_ownership_spec(configs_dir):
Expand Down
53 changes: 53 additions & 0 deletions activitysim/defaults/models/school_location.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import os
import pandas as pd
import urbansim.sim.simulation as sim
from activitysim import activitysim as asim


"""
The school location model predicts the zones in which various people will
go to school.
"""


@sim.table()
def school_location_spec(configs_dir):
f = os.path.join(configs_dir, 'configs', "school_location.csv")
return asim.read_model_spec(f).fillna(0)


@sim.model()
def school_location_simulate(set_random_seed,
persons_merged,
school_location_spec,
skims,
destination_size_terms):

choosers = persons_merged.to_frame()
alternatives = destination_size_terms.to_frame()
spec = school_location_spec.to_frame()

# set the keys for this lookup - in this case there is a TAZ in the choosers
# and a TAZ in the alternatives which get merged during interaction
skims.set_keys("TAZ", "TAZ_r")
# the skims will be available under the name "skims" for any @ expressions
locals_d = {"skims": skims}

choices_list = []
for school_type in ['university', 'highschool', 'gradeschool']:

locals_d['segment'] = school_type

choices, _ = asim.interaction_simulate(choosers[choosers["is_" +
school_type]],
alternatives,
spec[[school_type]],
skims=skims,
locals_d=locals_d)
choices_list.append(choices)

choices = pd.concat(choices_list)
choices = choices.reindex(persons_merged.index).fillna(-1).astype('int')

print "Describe of choices:\n", choices.describe()
sim.add_column("persons", "school_taz", choices)
5 changes: 3 additions & 2 deletions activitysim/defaults/models/workplace_location.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ def workplace_location_spec(configs_dir):
return asim.read_model_spec(f).fillna(0)


# FIXME there are three school models that go along with this one which have
# FIXME not been implemented yet
@sim.model()
def workplace_location_simulate(set_random_seed,
persons_merged,
Expand All @@ -25,6 +23,7 @@ def workplace_location_simulate(set_random_seed,
destination_size_terms):

choosers = persons_merged.to_frame()
choosers = choosers[choosers.employed_cat.isin(["full", "part"])]
alternatives = destination_size_terms.to_frame()

# set the keys for this lookup - in this case there is a TAZ in the choosers
Expand All @@ -39,5 +38,7 @@ def workplace_location_simulate(set_random_seed,
skims=skims,
locals_d=locals_d)

choices = choices.reindex(persons_merged.index).fillna(-1).astype('int')

print "Describe of choices:\n", choices.describe()
sim.add_column("persons", "workplace_taz", choices)
30 changes: 20 additions & 10 deletions activitysim/defaults/tables/persons.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,6 @@ def female(persons):
# count the number of mandatory tours for each person
@sim.column("persons")
def num_mand(persons):
# FIXME this is really because we ask for ALL columns in the persons data
# FIXME frame - urbansim actually only asks for the columns that are used by
# FIXME the model specs in play at that time
if "mandatory_tour_frequency" not in persons.columns:
return pd.Series(0, index=persons.index)

Expand Down Expand Up @@ -146,7 +143,7 @@ def student_is_employed(persons):
@sim.column("persons")
def nonstudent_to_school(persons):
return (persons.ptype_cat.isin(['full', 'part', 'nonwork', 'retired']) &
persons.student_cat.isin(['high', 'college']))
persons.student_cat.isin(['grade_or_high', 'college']))


@sim.column("persons")
Expand All @@ -162,14 +159,28 @@ def is_worker(persons):

@sim.column("persons")
def is_student(persons):
return persons.student_cat.isin(['high', 'college'])
return persons.student_cat.isin(['grade_or_high', 'college'])


@sim.column("persons")
def is_gradeschool(persons, settings):
return (persons.student_cat == "grade_or_high") & \
(persons.age <= settings['grade_school_max_age'])


@sim.column("persons")
def is_highschool(persons, settings):
return (persons.student_cat == "grade_or_high") & \
(persons.age > settings['grade_school_max_age'])


@sim.column("persons")
def is_university(persons):
return persons.student_cat == "university"


@sim.column("persons")
def workplace_taz(persons):
# FIXME this is really because we ask for ALL columns in the persons data
# FIXME frame - urbansim actually only asks for the columns that are used by
# FIXME the model specs in play at that time
return pd.Series(1, persons.index)


Expand All @@ -181,8 +192,7 @@ def home_taz(households, persons):

@sim.column("persons")
def school_taz(persons):
# FIXME need to fix this after getting school lcm working
return persons.workplace_taz
return pd.Series(1, persons.index)


# this use the distance skims to compute the raw distance to work from home
Expand Down
2 changes: 2 additions & 0 deletions activitysim/defaults/test/configs/settings.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ rural_threshold: 6

households_sample_size: 1000

grade_school_max_age: 14

county_map:
San Francisco: 1
San Mateo: 2
Expand Down
4 changes: 2 additions & 2 deletions example/configs/destination_choice_size_terms.csv
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ segment,TOTHH,RETEMPN,FPSEMPN,HEREMPN,OTHEMPN,AGREMPN,MWTEMPN,AGE0519,HSENROLL,C
"work, high",0,0.11,0.207,0.284,0.154,0.006,0.239,0,0,0,0
"work, veryhigh",0,0.093,0.27,0.241,0.146,0.004,0.246,0,0,0,0
university,0,0,0,0,0,0,0,0,0,0.592,0.408
"school, grade",0,0,0,0,0,0,0,1,0,0,0
"school, high",0,0,0,0,0,0,0,0,1,0,0
gradeschool,0,0,0,0,0,0,0,1,0,0,0
highschool,0,0,0,0,0,0,0,0,1,0,0
"escort, kids",0,0.225,0,0.144,0,0,0,0.465,0.166,0,0
"escort, no kids",0,0.225,0,0.144,0,0,0,0.465,0.166,0,0
shopping,0,1,0,0,0,0,0,0,0,0,0
Expand Down
9 changes: 9 additions & 0 deletions example/configs/school_location.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Description,Expression,university,highschool,gradeschool
"Distance, piecewise linear from 0 to 1 miles",@skims['DISTANCE'].clip(1),-3.2451,-0.9523,-1.6419
"Distance, piecewise linear from 1 to 2 miles","@(skims['DISTANCE']-1).clip(0,1)",-2.7011,-0.5700,-0.5700
"Distance, piecewise linear from 2 to 5 miles","@(skims['DISTANCE']-2).clip(0,3)",-0.5707,-0.5700,-0.5700
"Distance, piecewise linear from 5 to 15 miles","@(skims['DISTANCE']-5).clip(0,10)",-0.5002,-0.1930,-0.2031
"Distance, piecewise linear for 15+ miles",@(skims['DISTANCE']-15.0).clip(0),-0.0730,-0.1882,-0.0460
Mode choice logsum,mode_choice_logsums,0.5358,0.5358,0.5358
Size variable,@df[segment].apply(np.log1p),1.0000,1.0000,1.0000
No attractions,@df[segment]==0,-999.0000,-999.0000,-999.0000
6 changes: 4 additions & 2 deletions example/configs/settings.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ rural_threshold: 6

households_sample_size: 1000

grade_school_max_age: 14

county_map:
San Francisco: 1
San Mateo: 2
Expand All @@ -25,8 +27,8 @@ employment_map:
4: child

student_map:
1: high
2: college
1: grade_or_high
2: university
3: not

person_type_map:
Expand Down
81 changes: 71 additions & 10 deletions example/simulation.ipynb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"metadata": {
"name": "",
"signature": "sha256:880950d73f4f9e461598c60051b1f421518aa82880440b1f17bdf1ae89f0bc48"
"signature": "sha256:8dd6ed7b0367358850955b8044ce5cd4396e31fd6b83bd444987c950b7c3696a"
},
"nbformat": 3,
"nbformat_minor": 0,
Expand All @@ -22,6 +22,67 @@
"outputs": [],
"prompt_number": 1
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"sim.run([\"school_location_simulate\"])"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Running model 'school_location_simulate'\n",
"WARNING: Some columns have no variability:\n"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"['mode_choice_logsums']\n",
"WARNING: Some columns have no variability:\n"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"['mode_choice_logsums']\n",
"WARNING: Some columns have no variability:\n"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"['mode_choice_logsums']\n",
"Describe of choices:\n"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"count 2538.000000\n",
"mean 190.435776\n",
"std 389.915126\n",
"min -1.000000\n",
"25% -1.000000\n",
"50% -1.000000\n",
"75% 69.000000\n",
"max 1450.000000\n",
"Name: TAZ, dtype: float64\n",
"Time to execute model 'school_location_simulate': 18.74s\n",
"Total time to execute: 18.74s\n"
]
}
],
"prompt_number": 2
},
{
"cell_type": "code",
"collapsed": false,
Expand Down Expand Up @@ -51,17 +112,17 @@
"output_type": "stream",
"stream": "stdout",
"text": [
"count 2546.000000\n",
"mean 775.958759\n",
"std 425.999370\n",
"min 1.000000\n",
"25% 418.000000\n",
"50% 776.500000\n",
"75% 1168.000000\n",
"count 2538.000000\n",
"mean 332.508668\n",
"std 473.007494\n",
"min -1.000000\n",
"25% -1.000000\n",
"50% -1.000000\n",
"75% 651.000000\n",
"max 1452.000000\n",
"Name: TAZ, dtype: float64\n",
"Time to execute model 'workplace_location_simulate': 20.54s\n",
"Total time to execute: 20.54s\n"
"Time to execute model 'workplace_location_simulate': 10.24s\n",
"Total time to execute: 10.24s\n"
]
}
],
Expand Down