Skip to content

Commit

Permalink
Develop (#366)
Browse files Browse the repository at this point in the history
* Provide more flexibility for defining mandatory schedule specifications.

* provide more flexibility for time periods.

* Improve consistency in slicing and fix code syntax issues.

* Consistency and code syntax.

* code syntax.

* code syntax fixes.

* syntax fix.

* Add necessary change to test script settings.

* Modify relevant section of the settings.yml for tests and examples.

* restore 'hours' as deprecated for backwards compatibility.

* Add default value for period_minutes for backwards compatibilitiy.

* create develop branch so we can merge features here before merging (releasing) to master

* provide more flexibility for time periods.

* Improve consistency in slicing and fix code syntax issues.

* Consistency and code syntax.

* code syntax fixes.

* Modify relevant section of the settings.yml for tests and examples.

* restore 'hours' as deprecated for backwards compatibility.

* Add default value for period_minutes for backwards compatibilitiy.

* Fix overflows

* Complete testing of the flexible time periods.

* pep8

* test some floats too.

* pep8

* start with csvs and write hdf5 outputs if desired  (#290)

* add h5_store option to write_tables

* keep csv files as the default

* read input tables from CSV

* update docs, drop scripts no longer needed, include example files in package

* formatting

Co-authored-by: Blake <brosenthalpdx@gmail.com>

* Update travis.yml

* Pandas 1.0 fixes

* Location and mode choice logsums (#298)

* optional logsums for location_choice and tour destination models

* mode choice logsums for trous and trips

* trip DEST_CHOICE_SAMPLE_TABLE_NAME

* update docs for writing logsums and also a couple small development page updates

* fix small py2 py 3 compatibility issue

* py2 py3 compatibility

Co-authored-by: Blake <brosenthalpdx@gmail.com>
Co-authored-by: Jeff Doyle <toliwaga@gmail.com>

* Deprecate Py2 and add CLI

* Tncs (#14)

* add tncs

* lognormal_for_df broadcasts duplicate indexes

* lognormal_for_df broadcasts duplicate indexes code

* correct lognormal calculations and add functions to calculation lognormal location and scale

* clean-up tnc wait time expressions

* set taxi, tnc wait time standard deviations to zero until we have better data

* add scaled option to random.lognormal_for_df

* add mobility-as-a-service modes to docs

* updated tnc mode constants

* rename maas to ridehail

Co-authored-by: Jeff Doyle <toliwaga@gmail.com>
Co-authored-by: Blake Rosenthal <blake.rosenthal@rsginc.com>

* write trip matrices (#311)

require newer pandas

add ability to save trips table to pipeline and begin to finish example

all time periods

fix trip scheduling bug

add support for odt skims as well

Co-authored-by: Ben Stabler <benstabler@yahoo.com>

Co-authored-by: Blake Rosenthal <blake.rosenthal@rsginc.com>

* small fixes for semcog deployment (#319)

* improved validation diagnostics in trip_purpose and various windows-related int32/int64 conversions

* pycodestyle

* deprecations in test code

* fix bug in handling of no viable trips case in choose_trip_destination

* add trace folder to example_mtc output folder

Co-authored-by: Jeffrey Doyle <jeff.doyle@rsginc.com>
Co-authored-by: Jeff Doyle <toliwaga@gmail.com>

* major work on phase 5 (#325)

* estimation through atwork_subtour_mode_choice

* Tnc updates and notebooks (#18)

* move other resources into folder since examples now part of package as well

* add shapefile

* clean up folder setup

* estimation notebooks for larch (#19)

* multiprocessing related logging and error checking

* trip_destination handle all trips fail

* skim caching with numpy memmap to speed skim loading

* better chunking in vectorize_tour_scheduling

* Cli (#22)

* use activitysim_resources

Fixed auto sufficiency conditions in tour_mode_choice.csv. (Issue #324)

* increment to version 0.9.5

* correct write trip matrices sampling expansion and add vehicle occupancy to the expression file

* updates to documentation for phase 5 work except multiple zone systems

* additional updates for estimation integration  (#328)

* estimation integration updates #327
* drop module no longer needed

* update license, fix univ coeff bug, update estimation example (#339)

* improve example setup for specifying input tables (#27)
* improve LICENSE (#30)
* correct univ coeff template lookup (#28)

* add license to package (#341)

* move notebooks to examples folder so they are installed and update docs as a result (#343)

* correct doc links

* Address Minor Issues Associated with ARC Update to Develop Branch (#342)

* publish v0.9.5 (#340)

* update docs, drop scripts no longer needed, include example files in package

* Pandas 1.0 fixes

* Location and mode choice logsums (#298)

* Tncs (#14)

* write trip matrices (#311)

* small fixes for semcog deployment (#319)

* improved validation diagnostics in trip_purpose and various windows-related int32/int64 conversions

* fix bug in handling of no viable trips case in choose_trip_destination

* major work on phase 5 (#325)

* estimation through atwork_subtour_mode_choice

* Tnc updates and notebooks (#18)

* move other resources into folder since examples now part of package as well

* add example zone shapefile

* estimation notebooks for larch (#19)

* multiprocessing related logging and error checking

* trip_destination handle all trips fail

* skim caching with numpy memmap to speed skim loading

* better chunking in vectorize_tour_scheduling

* Cli (#22)

* use activitysim_resources

Fixed auto sufficiency conditions in tour_mode_choice.csv. (Issue #324)

* correct write trip matrices sampling expansion and add vehicle occupancy to the expression file

* additional updates for estimation integration  (#328)

* improve LICENSE (#30)

* correct univ coeff template lookup (#28)

Co-authored-by: Clint Daniels <clint.daniels@wsp.com>
Co-authored-by: Blake <brosenthalpdx@gmail.com>
Co-authored-by: Blake Rosenthal <blake.rosenthal@rsginc.com>
Co-authored-by: Jeff Doyle <toliwaga@gmail.com>
Co-authored-by: Jeffrey Doyle <jeff.doyle@rsginc.com>
Co-authored-by: Jeffrey Newman <jeff@newman.me>

* Remove duplicate coefficient.

* move coefficient processing up

* Update joint_tour_destination.py

* Fix reference to joint tour destination.yaml

* Error check for COEFFICIENT files

* Add person_id to joint choosers.

* move notebooks to examples folder so they are installed and update docs as a result (#343)

* publish (#344)

* move notebooks to examples folder so they are installed and update docs as a result (#343)

* correct doc links

* Remove duplicate coefficient.

* move coefficient processing up

* Update joint_tour_destination.py

* Fix reference to joint tour destination.yaml

* Error check for COEFFICIENT files

* Add person_id to joint choosers.

* Remove duplicate coefficient.

* move coefficient processing up

* Update joint_tour_destination.py

* Fix reference to joint tour destination.yaml

* Error check for COEFFICIENT files

* Add person_id to joint choosers.

Co-authored-by: Ben Stabler <bstabler@users.noreply.github.com>
Co-authored-by: Blake <brosenthalpdx@gmail.com>
Co-authored-by: Blake Rosenthal <blake.rosenthal@rsginc.com>
Co-authored-by: Jeff Doyle <toliwaga@gmail.com>
Co-authored-by: Jeffrey Doyle <jeff.doyle@rsginc.com>
Co-authored-by: Jeffrey Newman <jeff@newman.me>
Co-authored-by: bstabler <benstabler@yahoo.com>

* fix #288 chunk joint_touyr_participation by chunk_id and update tests to catch such errors

* gitignore trivia

* Support for Multiple Zone Systems and Transit Virtual Path Building (#362)

* TransitVirtualPathBuilder first cut - get_tvpb_logsum computes logsums on demand

* tour_mode_choice logsums for 3-zone working for school and workplace location

* z3 running all models, but with hacked trip_mode_choice (no coefficient templates)

* z3 running all models

* passing tests

* pcodestyle passes

* refactored test teardown

* tvpb tracing

* tvpb tracing roughout

* build multizone test data before running test

* read_settings_file support include_settings

* read_settings_file support include_settings

* move constants to configs yaml and expressions from abm.util to core

* tvpb estimate_chunk_overhead

* adaptive chunking

* fixed bug in trip scheduling when no trips in leg after iteration

* 3 zone tap_tap uniquify

* tvpb TableCache

* tvpb TableCache - all fiiels

* 3 zone with feather cache

* tidy up notes around creating the marin example

* memmap skims

* memmap skims

* correct drive transit cost expression for miles/feet.  Still need to add some additional missing expressions now that everything appears to be working correctly.

* skim docstrings

* disable 3 zone tap_tap caching for traced taps

* initialize_los

* 3 zone mp plumbing untested

* THREE_ZONE tvpb multiprocessing tests and fixes

* THREE_ZONE tvpb multiprocessing tests and fixes

* reanme core tvpb and cache modules

* reanme core tvpb and cache modules

* util.iprod alias for np.prod with dtype int64

* THREE_ZONE cache initialization bug bixes

* multizone bug fixes

* bugs

* multiprocessing mjultizone tweaks

* tvpb cacha\e as array

* complain if apporting with more process than slice rows

* complain if apporting with more process than slice rows

* chunk initialize_tvpb

* shorter trace file names because windows

* refactor pathbuilder sans DYNAMIC

* fix tour_scheduling_calc_row_size

* fix multiprocess resume across mp step bug

* pycodestyle

* minor chunk cleanup

* allow MemMapSkimFactory multiprocessing

* consolidate mtc and multizone configs

* commit updated marin example config files

* some more marin example config updates

* add validation summaries script

* some additional marin example updates

* update example skim time period settings to align with tm1 (#360)

* update example settings to align with tm1

* correct home_is_rural coding since tm1 was incorrect

* corrected skim time periods go in network_los.yaml now

* travis depends on these scripts for testing

* improve logging and increase travis timeout

* #359 (#364)

* updates for CDAP person type mapping

* allow duplicate time labels

* fix a copy small items for #359

* test updates

* pycodestyle

* 3 zone test fix

Co-authored-by: Clint Daniels <clint.daniels@wsp.com>

* longer travis timeout and avoid file permissions between tests related to caching

* test-travis

* ls fix

* add timeout

* fix path

* put in both locations for now

* reduce household sample sizes for tests to avoid travis timeout

* not sure what's taking so long with the second and third tests.  It runs in 40 minutes with py 3.7 on my computer as well

* linux file paths

* cli test depends on py 3.7+

* add coveralls back

* test new architecture

* try build matrix

* setup environments

* correct matrix expansion

* correct duplicate key

* correct key

* correct env usage

* no need to specify architecture

* update inject settings for tests

* updated examples to use activitysim resources repo

* rename folder

* update survey test files so all example_manifest.yaml examples now running

* updated notebooks, default settings for examples, and updated rst files

* fix a couple typos

* add comments to travis script

* ARC Updates (#365)

Add parking_location_choice, trip_departure_choice, and trip_scheduling_choice models.

* add example_mtc_arc_extensions so arc extensions can be run and tested

* small doc update

* fix arc extensions example

Co-authored-by: Clint Daniels <clint.daniels@wsp.com>
Co-authored-by: Blake <brosenthalpdx@gmail.com>
Co-authored-by: Blake Rosenthal <blake.rosenthal@rsginc.com>
Co-authored-by: Jeff Doyle <toliwaga@gmail.com>
Co-authored-by: Jeffrey Doyle <jeff.doyle@rsginc.com>
Co-authored-by: Jeffrey Newman <jeff@newman.me>
  • Loading branch information
7 people authored Jan 12, 2021
1 parent 964ee00 commit 7af0868
Show file tree
Hide file tree
Showing 307 changed files with 55,876 additions and 10,686 deletions.
35 changes: 28 additions & 7 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,25 @@
os: linux
language: python
sudo: false

env:
global:
# GH_TOKEN ActivitySim/activitysim public_repo token
- secure: WZeCAmI08hBRgtVWUlerfizvSpOVlBxQDa/Z6HJiDUlIXdSAOIi7TAwnluOgs3lHbSqACegbLCU9CyIQa/ytwmmuwzltkSQN14EcnKea0bXyygd8DFdx4x8st8M3a4nh2svgp4BDM9PCu6T1XIZ1rYM46JsKzNk9X8GpWOVN498=
jobs:
# Add new TEST_SUITE jobs as needed via Travis build matrix expansion
- TEST_SUITE=activitysim/abm/models
- TEST_SUITE=activitysim/abm/test/test_misc.py
- TEST_SUITE=activitysim/abm/test/test_mp_pipeline.py
- TEST_SUITE=activitysim/abm/test/test_multi_zone.py
- TEST_SUITE=activitysim/abm/test/test_multi_zone_mp.py
- TEST_SUITE=activitysim/abm/test/test_pipeline.py
- TEST_SUITE=activitysim/cli
- TEST_SUITE=activitysim/core

python:
- '3.6'
- '3.7'
- '3.8'

install:
- wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh
- bash miniconda.sh -b -p $HOME/miniconda
Expand All @@ -17,9 +33,18 @@ install:
- conda install pytest pytest-cov coveralls pycodestyle
- pip install .
- pip freeze

script:
# build 2 and 3 zone test data twice since the Python test code on Linux sees these as different locations
- python activitysim/examples/example_multiple_zone/two_zone_example_data.py
- python activitysim/examples/example_multiple_zone/three_zone_example_data.py
- python /home/travis/miniconda/envs/test-environment/lib/python$TRAVIS_PYTHON_VERSION/site-packages/activitysim/examples/example_multiple_zone/two_zone_example_data.py
- python /home/travis/miniconda/envs/test-environment/lib/python$TRAVIS_PYTHON_VERSION/site-packages/activitysim/examples/example_multiple_zone/three_zone_example_data.py
# pycodestyle
- pycodestyle activitysim
- py.test --cov activitysim --cov-report term-missing
# run specific TEST_SUITE job on travis to avoid job max time
- travis_wait 50 py.test $TEST_SUITE --cov activitysim --cov-report term-missing --durations=0

after_success:
- coveralls
# Build docs
Expand All @@ -43,7 +68,3 @@ notifications:
on_success: never # default: change
on_failure: always # default: always
secure: Dpp+zBrnPGBHXrYWjwHy/bnHvhINfepSIiViwKfBZizBvTDvzSJfu6gCH+/lQ3squF3D4qTWwxB+LQ9V6KTYhuma8vQVisyneI6ARjUI/qgX6aJjuvmDDGPk6DVeDow7+aCLZ8VEHRhSjwy+dv0Ij0rxI6I94xPVwXUkk7ZjcK0=
env:
global:
# GH_TOKEN ActivitySim/activitysim public_repo token
- secure: WZeCAmI08hBRgtVWUlerfizvSpOVlBxQDa/Z6HJiDUlIXdSAOIi7TAwnluOgs3lHbSqACegbLCU9CyIQa/ytwmmuwzltkSQN14EcnKea0bXyygd8DFdx4x8st8M3a4nh2svgp4BDM9PCu6T1XIZ1rYM46JsKzNk9X8GpWOVN498=
2 changes: 1 addition & 1 deletion activitysim/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# ActivitySim
# See full license in LICENSE.txt.

__version__ = '0.9.5.2'
__version__ = '0.9.7'
__doc__ = 'Activity-Based Travel Modeling'
4 changes: 2 additions & 2 deletions activitysim/abm/misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def households_sample_size(settings, override_hh_ids):
if override_hh_ids is None:
return settings.get('households_sample_size', 0)
else:
return len(override_hh_ids)
return 0 if override_hh_ids is None else len(override_hh_ids)


@inject.injectable(cache=True)
Expand Down Expand Up @@ -79,7 +79,7 @@ def trace_od(settings):

@inject.injectable(cache=True)
def chunk_size(settings):
return int(settings.get('chunk_size', 0))
return int(settings.get('chunk_size', 0) or 0)


@inject.injectable(cache=True)
Expand Down
6 changes: 6 additions & 0 deletions activitysim/abm/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
from . import cdap
from . import free_parking
from . import initialize
from . import initialize_tours
from . import initialize_los
from . import joint_tour_composition
from . import joint_tour_destination
from . import joint_tour_frequency
Expand All @@ -20,11 +22,15 @@
from . import non_mandatory_destination
from . import non_mandatory_scheduling
from . import non_mandatory_tour_frequency
from . import parking_location_choice
from . import stop_frequency
from . import tour_mode_choice
from . import trip_destination
from . import trip_mode_choice
from . import trip_purpose
from . import trip_purpose_and_destination
from . import trip_scheduling
from . import trip_departure_choice
from . import trip_scheduling_choice
from . import trip_matrices
from . import summarize
185 changes: 99 additions & 86 deletions activitysim/abm/models/accessibility.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,95 +10,99 @@
from activitysim.core import config
from activitysim.core import inject
from activitysim.core import pipeline
from activitysim.core import mem

from activitysim.core import los
from activitysim.core.pathbuilder import TransitVirtualPathBuilder

logger = logging.getLogger(__name__)


class AccessibilitySkims(object):
"""
Wrapper for skim arrays to facilitate use of skims by accessibility model
Parameters
----------
skims : 2D array
omx: open omx file object
this is only used to load skims on demand that were not preloaded
length: int
number of zones in skim to return in skim matrix
in case the skims contain additional external zones that should be trimmed out so skim
array is correct shape to match (flattened) O-D tiled columns in the od dataframe
transpose: bool
whether to transpose the matrix before flattening. (i.e. act as a D-O instead of O-D skim)
"""

def __init__(self, skim_dict, orig_zones, dest_zones, transpose=False):

omx_shape = skim_dict.skim_info['omx_shape']
logger.info("init AccessibilitySkims with %d dest zones %d orig zones omx_shape %s" %
(len(dest_zones), len(orig_zones), omx_shape, ))

assert len(orig_zones) <= len(dest_zones)
assert np.isin(orig_zones, dest_zones).all()
assert len(np.unique(orig_zones)) == len(orig_zones)
assert len(np.unique(dest_zones)) == len(dest_zones)

self.skim_dict = skim_dict
self.transpose = transpose

if omx_shape[0] == len(orig_zones) and skim_dict.offset_mapper.offset_series is None:
# no slicing required because whatever the offset_int, the skim data aligns with zone list
self.map_data = False
else:

if omx_shape[0] == len(orig_zones):
logger.debug("AccessibilitySkims - applying offset_mapper")

skim_index = list(range(omx_shape[0]))
orig_map = skim_dict.offset_mapper.map(orig_zones)
dest_map = skim_dict.offset_mapper.map(dest_zones)

# (we might be sliced multiprocessing)
# assert np.isin(skim_index, orig_map).all()

if np.isin(skim_index, dest_map).all():
# not using the whole skim matrix
logger.info("%s skim zones not in dest_map: %s" %
((~dest_map).sum(), np.ix_(~dest_map)))

self.map_data = True
self.orig_map = orig_map
self.dest_map = dest_map

def __getitem__(self, key):
"""
accessor to return flattened skim array with specified key
flattened array will have length length*length and will match tiled OD df used by assign
this allows the skim array to be accessed from expressions as
skim['DISTANCE'] or skim[('SOVTOLL_TIME', 'MD')]
"""

data = self.skim_dict.get(key).data

if self.transpose:
data = data.transpose()

if self.map_data:

# slice skim to include only orig rows and dest columns
# 2-d boolean slicing in numpy is a bit tricky
# data = data[orig_map, dest_map] # <- WRONG!
# data = data[orig_map, :][:, dest_map] # <- RIGHT
# data = data[np.ix_(orig_map, dest_map)] # <- ALSO RIGHT

data = data[self.orig_map, :][:, self.dest_map]

return data.flatten()
# class AccessibilitySkims(object):
# """
# Wrapper for skim arrays to facilitate use of skims by accessibility model
#
# Parameters
# ----------
# skims : 2D array
# omx: open omx file object
# this is only used to load skims on demand that were not preloaded
# length: int
# number of zones in skim to return in skim matrix
# in case the skims contain additional external zones that should be trimmed out so skim
# array is correct shape to match (flattened) O-D tiled columns in the od dataframe
# transpose: bool
# whether to transpose the matrix before flattening. (i.e. act as a D-O instead of O-D skim)
# """
#
# def __init__(self, skim_dict, orig_zones, dest_zones, transpose=False):
#
# logger.info(f"init AccessibilitySkims with {len(dest_zones)} dest zones {len(orig_zones)} orig zones")
#
# assert len(orig_zones) <= len(dest_zones)
# assert np.isin(orig_zones, dest_zones).all()
# assert len(np.unique(orig_zones)) == len(orig_zones)
# assert len(np.unique(dest_zones)) == len(dest_zones)
#
# self.skim_dict = skim_dict
# self.transpose = transpose
#
# num_skim_zones = skim_dict.get_skim_info('omx_shape')[0]
# if num_skim_zones == len(orig_zones) and skim_dict.offset_mapper.offset_series is None:
# # no slicing required because whatever the offset_int, the skim data aligns with zone list
# self.map_data = False
# else:
#
# logger.debug("AccessibilitySkims - applying offset_mapper")
#
# skim_index = list(range(num_skim_zones))
# orig_map = skim_dict.offset_mapper.map(orig_zones)
# dest_map = skim_dict.offset_mapper.map(dest_zones)
#
# # (we might be sliced multiprocessing)
# # assert np.isin(skim_index, orig_map).all()
#
# out_of_bounds = ~np.isin(skim_index, dest_map)
# # if out_of_bounds.any():
# # print(f"{(out_of_bounds).sum()} skim zones not in dest_map")
# # print(f"dest_zones {dest_zones}")
# # print(f"dest_map {dest_map}")
# # print(f"skim_index {skim_index}")
# assert not out_of_bounds.any(), \
# f"AccessibilitySkims {(out_of_bounds).sum()} skim zones not in dest_map: {np.ix_(out_of_bounds)[0]}"
#
# self.map_data = True
# self.orig_map = orig_map
# self.dest_map = dest_map
#
# def __getitem__(self, key):
# """
# accessor to return flattened skim array with specified key
# flattened array will have length length*length and will match tiled OD df used by assign
#
# this allows the skim array to be accessed from expressions as
# skim['DISTANCE'] or skim[('SOVTOLL_TIME', 'MD')]
# """
#
# data = self.skim_dict.get(key).data
#
# if self.transpose:
# data = data.transpose()
#
# if self.map_data:
# # slice skim to include only orig rows and dest columns
# # 2-d boolean slicing in numpy is a bit tricky
# # data = data[orig_map, dest_map] # <- WRONG!
# # data = data[orig_map, :][:, dest_map] # <- RIGHT
# # data = data[np.ix_(orig_map, dest_map)] # <- ALSO RIGHT
#
# data = data[self.orig_map, :][:, self.dest_map]
#
# return data.flatten()


@inject.step()
def compute_accessibility(accessibility, skim_dict, land_use, trace_od):
def compute_accessibility(accessibility, network_los, land_use, trace_od):

"""
Compute accessibility for each zone in land use file using expressions from accessibility_spec
Expand Down Expand Up @@ -143,8 +147,8 @@ def compute_accessibility(accessibility, skim_dict, land_use, trace_od):
# create OD dataframe
od_df = pd.DataFrame(
data={
'orig': np.repeat(np.asanyarray(accessibility_df.index), dest_zone_count),
'dest': np.tile(np.asanyarray(land_use_df.index), orig_zone_count)
'orig': np.repeat(orig_zones, dest_zone_count),
'dest': np.tile(dest_zones, orig_zone_count)
}
)

Expand All @@ -160,9 +164,16 @@ def compute_accessibility(accessibility, skim_dict, land_use, trace_od):
locals_d = {
'log': np.log,
'exp': np.exp,
'skim_od': AccessibilitySkims(skim_dict, orig_zones, dest_zones),
'skim_do': AccessibilitySkims(skim_dict, orig_zones, dest_zones, transpose=True)
'network_los': network_los,
}

skim_dict = network_los.get_default_skim_dict()
locals_d['skim_od'] = skim_dict.wrap('orig', 'dest').set_df(od_df)
locals_d['skim_do'] = skim_dict.wrap('dest', 'orig').set_df(od_df)

if network_los.zone_system == los.THREE_ZONE:
locals_d['tvpb'] = TransitVirtualPathBuilder(network_los)

if constants is not None:
locals_d.update(constants)

Expand All @@ -174,13 +185,15 @@ def compute_accessibility(accessibility, skim_dict, land_use, trace_od):
data.shape = (orig_zone_count, dest_zone_count) # (o,d)
accessibility_df[column] = np.log(np.sum(data, axis=1) + 1)

logger.info("{trace_label} added {len(results.columns} columns")

# - write table to pipeline
pipeline.replace_table("accessibility", accessibility_df)

if trace_od:

if not trace_od_rows.any():
logger.warning("trace_od not found origin = %s, dest = %s" % (trace_orig, trace_dest))
logger.warning(f"trace_od not found origin = {trace_orig}, dest = {trace_dest}")
else:

# add OD columns to trace results
Expand Down
Loading

0 comments on commit 7af0868

Please sign in to comment.