Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
f9c164d
got through the first 40 variables or so in the tour freq spec
fscottfoti Feb 24, 2015
ddf4b16
finished up the rest of the rows of the mandatory tour generation model
fscottfoti Feb 24, 2015
8a311d9
comments, a few extra items on the todo list, and a few cosmetic chan…
fscottfoti Feb 24, 2015
12f4eeb
pep8 fixes
fscottfoti Feb 24, 2015
59d8484
adding csv formatted non mandatory tour config
fscottfoti Feb 25, 2015
a8fd8ca
add the alternatives too
fscottfoti Feb 25, 2015
d2fac8f
making the basic model for non mandatory tours
fscottfoti Feb 25, 2015
19e4fa2
the first 60 rows or so of the full time worker non mandatory tour ge…
fscottfoti Feb 25, 2015
fb365d7
got to row 114
fscottfoti Feb 25, 2015
a6c32a9
all but about 10 rows in non mandatory tours...
fscottfoti Feb 26, 2015
324c88f
spec is now complete
fscottfoti Feb 26, 2015
7d01e2c
now running non mandatory model for all segments
fscottfoti Feb 26, 2015
0cabf8f
adding a few notes to the readme
fscottfoti Feb 26, 2015
524deba
basic destination model working
fscottfoti Feb 26, 2015
767a9a2
a couple of small bugs and a couple of comments
fscottfoti Feb 26, 2015
df7fa25
adding small coment to TODO list
fscottfoti Feb 27, 2015
53bf27c
basic pipeline of tour departure and duration model
fscottfoti Mar 2, 2015
bb43936
have about half of the mandatory scheduling model implemented
fscottfoti Mar 2, 2015
522f35d
filling in basic skeleton of non-mandatory tour scheduling
fscottfoti Mar 3, 2015
d83e62e
experimental reorg splitting up large file into several smaller files
fscottfoti Mar 4, 2015
cc465da
major reorg of files
fscottfoti Mar 4, 2015
88e6f82
cleanup!
fscottfoti Mar 4, 2015
78af0a8
pep8
fscottfoti Mar 4, 2015
6ea98b0
added tests to the reorg
fscottfoti Mar 4, 2015
26135d3
install urbansim from master instead of through conda
fscottfoti Mar 4, 2015
687aed9
Update README.md
fscottfoti Mar 5, 2015
41caf35
some more cleanup
fscottfoti Mar 5, 2015
d0b3ee5
Merge branch 'file-reorg' of https://github.com/synthicity/activitysi…
fscottfoti Mar 5, 2015
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
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ install:
- >
conda create -q -c synthicity -n test-environment
python=$TRAVIS_PYTHON_VERSION
numpy pandas pip pytables pytest urbansim
numpy pandas pip pytables pytest
- source activate test-environment
- pip install https://github.com/synthicity/urbansim/archive/master.zip
- pip install openmatrix
- pip install pytest-cov coveralls pep8
- pip install .
Expand Down
29 changes: 20 additions & 9 deletions activitysim/activitysim.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,16 @@ def random_rows(df, n):

def read_model_spec(fname,
description_name="Description",
expression_name="Expression"):
expression_name="Expression",
stack=True):
"""
Read in the excel file and reformat for machines
"""
cfg = pd.read_csv(fname)
# don't need description and set the expression to the index
cfg = cfg.drop(description_name, axis=1).set_index(expression_name).stack()
cfg = cfg.drop(description_name, axis=1).set_index(expression_name)
if stack:
cfg = cfg.stack()
return cfg


Expand Down Expand Up @@ -87,13 +90,17 @@ def simple_simulate(choosers, alternatives, spec,
df[skim_join_name+"_r"])

# evaluate the expressions to build the final matrix
vars = {}
vars = []
for expr in exprs:
if expr[0][0] == "@":
if mult_by_alt_col:
expr = "({}) * df.{}".format(expr[0][1:], expr[1])
else:
expr = expr[0][1:]
if isinstance(expr, tuple):
expr = expr[0][1:]
else:
# it's already a string, but need to remove the "@"
expr = expr[1:]
try:
s = eval(expr)
except Exception as e:
Expand All @@ -103,21 +110,25 @@ def simple_simulate(choosers, alternatives, spec,
if mult_by_alt_col:
expr = "({}) * {}".format(*expr)
else:
expr = expr[0]
if isinstance(expr, tuple):
expr = expr[0]
else:
# it's already a string, which is fine
pass
try:
s = df.eval(expr)
except Exception as e:
print "Failed with DataFrame eval:\n%s" % expr
raise e
vars[expr] = s
vars[expr] = vars[expr].astype('float') # explicit cast
model_design = pd.DataFrame(vars, index=df.index)
vars.append((expr, s.astype('float')))
model_design = pd.DataFrame.from_items(vars)
model_design.index = df.index

df = random_rows(model_design, min(100000, len(model_design)))\
.describe().transpose()
df = df[df["std"] == 0]
if len(df):
print "WARNING: Describe of columns with no variability:\n", df
print "WARNING: Some columns have no variability:\n", df.index.values

positions = mnl.mnl_simulate(
model_design.as_matrix(),
Expand Down
4 changes: 4 additions & 0 deletions activitysim/defaults/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Definition of terms:

* CDAP: coordinated daily activity pattern
* TDD: tour departure and duration
4 changes: 4 additions & 0 deletions activitysim/defaults/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# ActivitySim
# Copyright (C) 2014-2015 Synthicity, LLC
# See full license in LICENSE.txt.

import misc
import tables
import models
87 changes: 0 additions & 87 deletions activitysim/defaults/datasources.py

This file was deleted.

69 changes: 69 additions & 0 deletions activitysim/defaults/misc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import urbansim.sim.simulation as sim
import warnings
import os
import yaml
import pandas as pd
import numpy as np


warnings.filterwarnings('ignore', category=pd.io.pytables.PerformanceWarning)
pd.options.mode.chained_assignment = None


@sim.injectable()
def configs_dir():
return '.'


@sim.injectable()
def data_dir():
return '.'


@sim.injectable(cache=True)
def settings(configs_dir):
with open(os.path.join(configs_dir, "configs", "settings.yaml")) as f:
return yaml.load(f)


@sim.injectable(cache=True)
def store(data_dir, settings):
return pd.HDFStore(os.path.join(data_dir, "data", settings["store"]),
mode='r')


# these are the alternatives for the workplace choice, among other things
@sim.table()
def zones():
# I grant this is a weird idiom but it helps to name the index
return pd.DataFrame({"TAZ": np.arange(1454)+1}).set_index("TAZ")


# this is a common merge so might as well define it once here and use it
@sim.table()
def households_merged(households, land_use, accessibility):
return sim.merge_tables(households.name, tables=[households,
land_use,
accessibility])


# another common merge for persons
@sim.table()
def persons_merged(persons, households, land_use, accessibility):
return sim.merge_tables(persons.name, tables=[persons,
households,
land_use,
accessibility])


@sim.table()
def mandatory_tours_merged(mandatory_tours, persons_merged):
return sim.merge_tables(mandatory_tours.name,
[mandatory_tours, persons_merged])


@sim.table()
def non_mandatory_tours_merged(non_mandatory_tours, persons_merged):
tours = non_mandatory_tours
return sim.merge_tables(tours.name, tables=[tours,
persons_merged])
11 changes: 11 additions & 0 deletions activitysim/defaults/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# ActivitySim
# Copyright (C) 2014-2015 Synthicity, LLC
# See full license in LICENSE.txt.

import auto_ownership
import destination
import mandatory_tour_frequency
import non_mandatory_tour_frequency
import mandatory_scheduling
import non_mandatory_scheduling
import workplace_location
42 changes: 42 additions & 0 deletions activitysim/defaults/models/auto_ownership.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import os
import urbansim.sim.simulation as sim
from activitysim import activitysim as asim

"""
Auto ownership is a standard model which predicts how many cars a household
with given characteristics owns
"""

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


@sim.table()
def auto_alts():
# alts can't be integers directly as they're used in expressions - they
# won't be evaluated correctly by DataFrame.eval unless they're strings
return asim.identity_matrix(["cars%d" % i for i in range(MAX_NUM_CARS)])


@sim.injectable()
def auto_ownership_spec(configs_dir):
f = os.path.join(configs_dir, 'configs', "auto_ownership.csv")
return asim.read_model_spec(f)


@sim.model()
def auto_ownership_simulate(households_merged,
auto_alts,
auto_ownership_spec):

choices, _ = asim.simple_simulate(households_merged.to_frame(),
auto_alts.to_frame(),
auto_ownership_spec,
mult_by_alt_col=True)

# map these back to integers - this is the actual number of cars chosen
car_map = {"cars%d" % i: i for i in range(MAX_NUM_CARS)}
choices = choices.map(car_map)

print "Choices:\n", choices.value_counts()
sim.add_column("households", "auto_ownership", choices)
74 changes: 74 additions & 0 deletions activitysim/defaults/models/destination.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import urbansim.sim.simulation as sim
from activitysim import activitysim as asim
import os
import pandas as pd

"""
Given the tour generation from the above, each tour needs to have a
destination, so in this case tours are the choosers (with the associated
person that's making the tour)
"""


@sim.table()
def destination_choice_size_terms(configs_dir):
f = os.path.join(configs_dir, 'configs',
'destination_choice_size_terms.csv')
return pd.read_csv(f)


@sim.table()
def destination_choice_spec(configs_dir):
f = os.path.join(configs_dir, 'configs',
'destination_choice_alternatives_sample.csv')
# FIXME not using all the variables yet
return asim.read_model_spec(f, stack=False).head(5)


@sim.model()
def destination_choice(non_mandatory_tours_merged,
zones,
distance_skim,
destination_choice_spec):

# choosers are tours - in a sense tours are choosing their destination
choosers = non_mandatory_tours_merged.to_frame()

# FIXME these models don't have size terms at the moment

# FIXME these models don't use stratified sampling - we're just making
# FIXME the choice with the sampling model

# all these tours are home based by definition so we use distance to the
# home as the relevant distance here
skims = {
"distance": distance_skim
}

choices_list = []
# segment by trip type and pick the right spec for each person type
for name, segment in choosers.groupby('tour_type'):

# FIXME - there are two options here escort with kids and without
if name == "escort":
continue

print "Running segment '%s' of size %d" % (name, len(segment))

choices, _ = \
asim.simple_simulate(segment,
zones.to_frame(),
destination_choice_spec[name],
skims,
skim_join_name="TAZ",
mult_by_alt_col=False,
sample_size=50)

choices_list.append(choices)

choices = pd.concat(choices_list)

print "Choices:\n", choices.describe()
# every trip now has a destination which is the index from the
# alternatives table - in this case it's the destination taz
sim.add_column("non_mandatory_tours", "destination", choices)
Loading