├── .nojekyll
├── syspy
├── __init__.py
├── io
│ ├── __init__.py
│ ├── pandasdbf
│ │ ├── __init__.py
│ │ ├── exceltodbf_qc.py
│ │ └── pandasdbf.py
│ ├── pandasshp
│ │ ├── __init__.py
│ │ ├── Thumbs.db
│ │ └── gis_resources
│ │ │ └── projections
│ │ │ ├── epsg4326.prj
│ │ │ ├── epsg32614.prj
│ │ │ └── epsg2154.prj
│ └── geojson_utils.py
├── operations
│ ├── __init__.py
│ └── rollingstock_model.py
├── pycube
│ ├── __init__.py
│ ├── project.py
│ ├── network.py
│ ├── dijkstra.py
│ └── application.py
├── surveys
│ ├── __init__.py
│ ├── array_example.py
│ └── discrete_choice.py
├── syspy_utils
│ ├── __init__.py
│ ├── test.py
│ ├── gis_resources
│ │ └── projections
│ │ │ ├── epsg4326.prj
│ │ │ ├── epsg32614.prj
│ │ │ └── epsg2154.prj
│ ├── assignment.py
│ ├── daycount.py
│ ├── documentation_jupyter.py
│ ├── pandas_utils.py
│ ├── mca_utils.py
│ └── gtfs_utils.py
├── clients
│ ├── linedraft_client
│ │ └── __init__.py
│ └── __init__.py
├── distribution
│ ├── description.txt
│ └── __init__.py
├── routing
│ ├── __init__.py
│ ├── frequency
│ │ └── __init__.py
│ ├── timetable
│ │ ├── __init__.py
│ │ └── csa.py
│ └── networkx_wrapper.py
├── skims
│ └── __init__.py
├── spatial
│ ├── __init__.py
│ ├── graph
│ │ └── __init__.py
│ ├── utils.py
│ └── geometry_smoothing.py
├── assignment
│ └── __init__.py
├── transitfeed
│ ├── __init__.py
│ └── feed_links.py
├── .vscode
│ └── .ropeproject
│ │ └── objectdb
├── paths.py
├── logit
│ ├── multinomial_logit.py
│ └── nested_logit.py
├── renumber
│ └── renumber.py
└── graph
│ └── nearest_path.py
├── quetzal
├── io
│ ├── __init__.py
│ ├── gtfs_reader
│ │ ├── __init__.py
│ │ └── patterns.py
│ ├── md.py
│ ├── cube
│ │ └── cube.py
│ ├── EMMEporter.py
│ └── hdf_io.py
├── analysis
│ ├── __init__.py
│ ├── on_demand.py
│ └── cost_benefit_analysis.py
├── engine
│ ├── __init__.py
│ ├── combinatorial_pathfinder.py
│ ├── subprocesses
│ │ ├── filepaths.py
│ │ └── subprocess_path_and_duration_from_graph_json.py
│ ├── msa_trackers
│ │ ├── tracker.py
│ │ └── test_tracker.py
│ ├── parallelization.py
│ ├── screenlines.py
│ ├── park_and_ride_pathfinder.py
│ ├── optimal_strategy.py
│ ├── vdf.py
│ ├── elevation.py
│ └── graph_utils.py
├── launcher
│ ├── __init__.py
│ └── launcher_utils.py
├── model
│ ├── __init__.py
│ └── docmodel.py
├── .python-version
├── __init__.py
├── index.txt
└── description.txt
├── tests
├── .gitignore
├── readme.txt
├── __init__.py
├── data
│ └── jsons
│ │ ├── jsons.json
│ │ ├── nodes.geojson
│ │ ├── centroids.geojson
│ │ ├── checkpoint_nodes.geojson
│ │ └── loaded_nodes.geojson
└── old_test_engine_od_volume_from_zones.py
├── _config.yml
├── docs
├── quetzal_icon.ico
├── build
│ ├── objects.inv
│ ├── _static
│ │ ├── file.png
│ │ ├── minus.png
│ │ ├── plus.png
│ │ └── css
│ │ │ └── badge_only.css
│ ├── .doctrees
│ │ ├── index.doctree
│ │ ├── LICENSE.doctree
│ │ ├── quetzal.doctree
│ │ ├── environment.pickle
│ │ ├── quetzal.io.doctree
│ │ ├── quetzal.engine.doctree
│ │ ├── quetzal.model.doctree
│ │ ├── quetzal.analysis.doctree
│ │ ├── quetzal.io.export.doctree
│ │ ├── quetzal.io.display.doctree
│ │ ├── quetzal.io.importer.doctree
│ │ ├── quetzal.model.model.doctree
│ │ ├── quetzal.engine.engine.doctree
│ │ ├── quetzal.model.docmodel.doctree
│ │ ├── quetzal.analysis.analysis.doctree
│ │ ├── quetzal.engine.pathfinder.doctree
│ │ ├── quetzal.io.export_utils.doctree
│ │ ├── quetzal.io.gtfs_importer.doctree
│ │ ├── quetzal.model.cubemodel.doctree
│ │ ├── quetzal.model.stepmodel.doctree
│ │ ├── quetzal.analysis.on_demand.doctree
│ │ ├── quetzal.engine.add_network.doctree
│ │ ├── quetzal.engine.connectivity.doctree
│ │ ├── quetzal.engine.screenlines.doctree
│ │ ├── quetzal.model.analysismodel.doctree
│ │ ├── quetzal.model.integritymodel.doctree
│ │ ├── quetzal.model.preparationmodel.doctree
│ │ ├── quetzal.model.transportmodel.doctree
│ │ ├── quetzal.engine.linearsolver_utils.doctree
│ │ └── quetzal.analysis.cost_benefit_analysis.doctree
│ └── .buildinfo
├── source
│ ├── _images
│ │ ├── Thumbs.db
│ │ ├── paris.png
│ │ ├── paris.pgw
│ │ └── favicon_package_v0.16
│ │ │ ├── favicon.ico
│ │ │ ├── favicon-16x16.png
│ │ │ ├── favicon-32x32.png
│ │ │ ├── mstile-150x150.png
│ │ │ ├── apple-touch-icon.png
│ │ │ ├── android-chrome-192x192.png
│ │ │ ├── android-chrome-512x512.png
│ │ │ ├── browserconfig.xml
│ │ │ └── site.webmanifest
│ ├── nstatic
│ │ ├── Thumbs.db
│ │ └── gtfs_mexico.png
│ ├── _build
│ │ ├── html
│ │ │ ├── objects.inv
│ │ │ ├── _static
│ │ │ │ ├── up.png
│ │ │ │ ├── Thumbs.db
│ │ │ │ ├── down.png
│ │ │ │ ├── file.png
│ │ │ │ ├── minus.png
│ │ │ │ ├── plus.png
│ │ │ │ ├── comment.png
│ │ │ │ ├── up-pressed.png
│ │ │ │ ├── ajax-loader.gif
│ │ │ │ ├── comment-close.png
│ │ │ │ ├── down-pressed.png
│ │ │ │ ├── comment-bright.png
│ │ │ │ ├── fonts
│ │ │ │ │ ├── Lato-Bold.ttf
│ │ │ │ │ ├── Lato-Regular.ttf
│ │ │ │ │ ├── Inconsolata-Bold.ttf
│ │ │ │ │ ├── RobotoSlab-Bold.ttf
│ │ │ │ │ ├── Inconsolata-Regular.ttf
│ │ │ │ │ ├── RobotoSlab-Regular.ttf
│ │ │ │ │ ├── fontawesome-webfont.eot
│ │ │ │ │ ├── fontawesome-webfont.ttf
│ │ │ │ │ └── fontawesome-webfont.woff
│ │ │ │ └── css
│ │ │ │ │ └── badge_only.css
│ │ │ ├── _sources
│ │ │ │ ├── quetzal.io.display.txt
│ │ │ │ ├── quetzal.io.export.txt
│ │ │ │ ├── quetzal.io.importer.txt
│ │ │ │ ├── quetzal.model.model.txt
│ │ │ │ ├── quetzal.engine.engine.txt
│ │ │ │ ├── quetzal.io.export_utils.txt
│ │ │ │ ├── quetzal.model.cubemodel.txt
│ │ │ │ ├── quetzal.model.docmodel.txt
│ │ │ │ ├── quetzal.model.stepmodel.txt
│ │ │ │ ├── quetzal.io.gtfs_importer.txt
│ │ │ │ ├── quetzal.analysis.analysis.txt
│ │ │ │ ├── quetzal.engine.pathfinder.txt
│ │ │ │ ├── quetzal.analysis.on_demand.txt
│ │ │ │ ├── quetzal.engine.add_network.txt
│ │ │ │ ├── quetzal.engine.screenlines.txt
│ │ │ │ ├── quetzal.analysis.txt
│ │ │ │ ├── quetzal.engine.connectivity.txt
│ │ │ │ ├── quetzal.model.analysismodel.txt
│ │ │ │ ├── quetzal.model.integritymodel.txt
│ │ │ │ ├── quetzal.model.transportmodel.txt
│ │ │ │ ├── quetzal.model.preparationmodel.txt
│ │ │ │ ├── quetzal.engine.linearsolver_utils.txt
│ │ │ │ ├── quetzal.analysis.cost_benefit_analysis.txt
│ │ │ │ ├── quetzal.txt
│ │ │ │ ├── quetzal.io.txt
│ │ │ │ ├── index.txt
│ │ │ │ ├── quetzal.engine.txt
│ │ │ │ └── quetzal.model.txt
│ │ │ ├── .buildinfo
│ │ │ └── searchindex.js
│ │ └── doctrees
│ │ │ ├── index.doctree
│ │ │ ├── quetzal.doctree
│ │ │ ├── environment.pickle
│ │ │ ├── quetzal.io.doctree
│ │ │ ├── quetzal.model.doctree
│ │ │ ├── quetzal.engine.doctree
│ │ │ ├── quetzal.analysis.doctree
│ │ │ ├── quetzal.io.display.doctree
│ │ │ ├── quetzal.io.export.doctree
│ │ │ ├── quetzal.io.importer.doctree
│ │ │ ├── quetzal.model.model.doctree
│ │ │ ├── quetzal.engine.engine.doctree
│ │ │ ├── quetzal.io.export_utils.doctree
│ │ │ ├── quetzal.model.cubemodel.doctree
│ │ │ ├── quetzal.model.docmodel.doctree
│ │ │ ├── quetzal.model.stepmodel.doctree
│ │ │ ├── quetzal.analysis.analysis.doctree
│ │ │ ├── quetzal.engine.pathfinder.doctree
│ │ │ ├── quetzal.io.gtfs_importer.doctree
│ │ │ ├── quetzal.analysis.on_demand.doctree
│ │ │ ├── quetzal.engine.add_network.doctree
│ │ │ ├── quetzal.engine.connectivity.doctree
│ │ │ ├── quetzal.engine.screenlines.doctree
│ │ │ ├── quetzal.model.analysismodel.doctree
│ │ │ ├── quetzal.model.integritymodel.doctree
│ │ │ ├── quetzal.model.transportmodel.doctree
│ │ │ ├── quetzal.model.preparationmodel.doctree
│ │ │ ├── quetzal.engine.linearsolver_utils.doctree
│ │ │ └── quetzal.analysis.cost_benefit_analysis.doctree
│ ├── quetzal.io.osm.rst
│ ├── quetzal.io.road.rst
│ ├── quetzal.io.excel.rst
│ ├── quetzal.io.export.rst
│ ├── quetzal.io.hdf_io.rst
│ ├── quetzal.engine.csa.rst
│ ├── quetzal.io.display.rst
│ ├── quetzal.io.importer.rst
│ ├── quetzal.model.model.rst
│ ├── quetzal.engine.engine.rst
│ ├── quetzal.model.docmodel.rst
│ ├── quetzal.io.export_utils.rst
│ ├── quetzal.model.cubemodel.rst
│ ├── quetzal.model.plotmodel.rst
│ ├── quetzal.model.stepmodel.rst
│ ├── quetzal.engine.msa_utils.rst
│ ├── quetzal.io.gtfs_importer.rst
│ ├── quetzal.analysis.analysis.rst
│ ├── quetzal.engine.gps_tracks.rst
│ ├── quetzal.engine.graph_utils.rst
│ ├── quetzal.engine.pathfinder.rst
│ ├── quetzal.model.optimalmodel.rst
│ ├── quetzal.model.summarymodel.rst
│ ├── quetzal.analysis.on_demand.rst
│ ├── quetzal.engine.add_network.rst
│ ├── quetzal.engine.connectivity.rst
│ ├── quetzal.engine.nested_logit.rst
│ ├── quetzal.engine.screenlines.rst
│ ├── quetzal.model.analysismodel.rst
│ ├── quetzal.model.parkridemodel.rst
│ ├── quetzal.model.integritymodel.rst
│ ├── quetzal.model.transportmodel.rst
│ ├── quetzal.analysis.accessibility.rst
│ ├── quetzal.engine.parallelization.rst
│ ├── quetzal.engine.optimal_strategy.rst
│ ├── quetzal.engine.pathfinder_utils.rst
│ ├── quetzal.engine.road_pathfinder.rst
│ ├── quetzal.io.gtfs_reader.importer.rst
│ ├── quetzal.io.gtfs_reader.patterns.rst
│ ├── quetzal.io.gtfs_reader.services.rst
│ ├── quetzal.launcher.launcher_utils.rst
│ ├── quetzal.model.preparationmodel.rst
│ ├── quetzal.model.timeexpandedmodel.rst
│ ├── quetzal.io.gtfs_reader.filtering.rst
│ ├── quetzal.engine.linearsolver_utils.rst
│ ├── quetzal.engine.optimization_utils.rst
│ ├── quetzal.io.gtfs_reader.directions.rst
│ ├── quetzal.io.gtfs_reader.feed_gtfsk.rst
│ ├── quetzal.model.connectionscanmodel.rst
│ ├── quetzal.engine.time_expanded_utils.rst
│ ├── quetzal.io.gtfs_reader.frequencies.rst
│ ├── quetzal.io.gtfs_reader.gtfs_importer.rst
│ ├── quetzal.analysis.cost_benefit_analysis.rst
│ ├── quetzal.engine.add_network_mapmatching.rst
│ ├── quetzal.engine.combinatorial_pathfinder.rst
│ ├── quetzal.engine.park_and_ride_pathfinder.rst
│ ├── quetzal.launcher.rst
│ ├── quetzal.rst
│ ├── quetzal.analysis.rst
│ ├── quetzal.io.rst
│ ├── quetzal.engine.rst
│ ├── quetzal.io.gtfs_reader.rst
│ └── quetzal.model.rst
├── index.html
└── makedoc.py
├── .vscode
├── .ropeproject
│ ├── objectdb
│ └── config.py
└── settings.json
├── index.html
├── ruff.toml
├── api
└── ML_MatrixRoadCaster
│ ├── Dockerfile.dockerignore
│ ├── Dockerfile
│ ├── requirements.txt
│ ├── README.md
│ ├── update-lambda.sh
│ ├── update-lambda-dev.sh
│ └── s3_utils.py
├── desktop.ini
├── .gitignore
├── setup.cfg
├── requirements_win.txt
├── windows-install.bat
├── pyproject.toml
└── README.md
/.nojekyll:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/syspy/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/quetzal/io/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/syspy/io/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/quetzal/analysis/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/quetzal/engine/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/quetzal/launcher/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/quetzal/model/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/syspy/operations/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/syspy/pycube/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/syspy/surveys/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/.gitignore:
--------------------------------------------------------------------------------
1 | out/*
2 |
--------------------------------------------------------------------------------
/syspy/syspy_utils/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-minimal
--------------------------------------------------------------------------------
/quetzal/io/gtfs_reader/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/quetzal/.python-version:
--------------------------------------------------------------------------------
1 | quetzal_env
2 |
--------------------------------------------------------------------------------
/quetzal/engine/combinatorial_pathfinder.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/quetzal/engine/subprocesses/filepaths.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/syspy/clients/linedraft_client/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/syspy/distribution/description.txt:
--------------------------------------------------------------------------------
1 | tralalala
2 |
--------------------------------------------------------------------------------
/syspy/io/pandasdbf/__init__.py:
--------------------------------------------------------------------------------
1 | from . import *
--------------------------------------------------------------------------------
/syspy/clients/__init__.py:
--------------------------------------------------------------------------------
1 | __author__ = 'qchasserieau'
2 |
--------------------------------------------------------------------------------
/syspy/routing/__init__.py:
--------------------------------------------------------------------------------
1 | __author__ = 'qchasserieau'
2 |
--------------------------------------------------------------------------------
/syspy/skims/__init__.py:
--------------------------------------------------------------------------------
1 | __author__ = 'qchasserieau'
2 |
--------------------------------------------------------------------------------
/syspy/spatial/__init__.py:
--------------------------------------------------------------------------------
1 | __author__ = 'qchasserieau'
2 |
--------------------------------------------------------------------------------
/syspy/assignment/__init__.py:
--------------------------------------------------------------------------------
1 | __author__ = 'qchasserieau'
2 |
--------------------------------------------------------------------------------
/syspy/distribution/__init__.py:
--------------------------------------------------------------------------------
1 | __author__ = 'qchasserieau'
2 |
--------------------------------------------------------------------------------
/syspy/io/pandasshp/__init__.py:
--------------------------------------------------------------------------------
1 | __author__ = 'qchasserieau'
2 |
--------------------------------------------------------------------------------
/syspy/syspy_utils/test.py:
--------------------------------------------------------------------------------
1 | def sum():
2 | print('vroom')
3 |
--------------------------------------------------------------------------------
/syspy/transitfeed/__init__.py:
--------------------------------------------------------------------------------
1 | __author__ = 'qchasserieau'
2 |
--------------------------------------------------------------------------------
/syspy/routing/frequency/__init__.py:
--------------------------------------------------------------------------------
1 | __author__ = 'qchasserieau'
2 |
--------------------------------------------------------------------------------
/syspy/routing/timetable/__init__.py:
--------------------------------------------------------------------------------
1 | __author__ = 'qchasserieau'
2 |
--------------------------------------------------------------------------------
/tests/readme.txt:
--------------------------------------------------------------------------------
1 | to_run tests:
2 | python -m pytest syspy/tests/
3 |
--------------------------------------------------------------------------------
/docs/quetzal_icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/quetzal_icon.ico
--------------------------------------------------------------------------------
/docs/build/objects.inv:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/build/objects.inv
--------------------------------------------------------------------------------
/.vscode/.ropeproject/objectdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/.vscode/.ropeproject/objectdb
--------------------------------------------------------------------------------
/docs/build/_static/file.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/build/_static/file.png
--------------------------------------------------------------------------------
/docs/build/_static/minus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/build/_static/minus.png
--------------------------------------------------------------------------------
/docs/build/_static/plus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/build/_static/plus.png
--------------------------------------------------------------------------------
/docs/source/_images/Thumbs.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_images/Thumbs.db
--------------------------------------------------------------------------------
/docs/source/_images/paris.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_images/paris.png
--------------------------------------------------------------------------------
/docs/source/nstatic/Thumbs.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/nstatic/Thumbs.db
--------------------------------------------------------------------------------
/syspy/io/pandasshp/Thumbs.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/syspy/io/pandasshp/Thumbs.db
--------------------------------------------------------------------------------
/docs/build/.doctrees/index.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/build/.doctrees/index.doctree
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/docs/build/.doctrees/LICENSE.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/build/.doctrees/LICENSE.doctree
--------------------------------------------------------------------------------
/docs/build/.doctrees/quetzal.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/build/.doctrees/quetzal.doctree
--------------------------------------------------------------------------------
/docs/source/_build/html/objects.inv:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/html/objects.inv
--------------------------------------------------------------------------------
/docs/source/nstatic/gtfs_mexico.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/nstatic/gtfs_mexico.png
--------------------------------------------------------------------------------
/syspy/.vscode/.ropeproject/objectdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/syspy/.vscode/.ropeproject/objectdb
--------------------------------------------------------------------------------
/docs/build/.doctrees/environment.pickle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/build/.doctrees/environment.pickle
--------------------------------------------------------------------------------
/docs/build/.doctrees/quetzal.io.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/build/.doctrees/quetzal.io.doctree
--------------------------------------------------------------------------------
/docs/source/_build/html/_static/up.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/html/_static/up.png
--------------------------------------------------------------------------------
/docs/index.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/docs/source/_build/doctrees/index.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/doctrees/index.doctree
--------------------------------------------------------------------------------
/docs/source/_build/html/_static/Thumbs.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/html/_static/Thumbs.db
--------------------------------------------------------------------------------
/docs/source/_build/html/_static/down.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/html/_static/down.png
--------------------------------------------------------------------------------
/docs/source/_build/html/_static/file.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/html/_static/file.png
--------------------------------------------------------------------------------
/docs/source/_build/html/_static/minus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/html/_static/minus.png
--------------------------------------------------------------------------------
/docs/source/_build/html/_static/plus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/html/_static/plus.png
--------------------------------------------------------------------------------
/docs/build/.doctrees/quetzal.engine.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/build/.doctrees/quetzal.engine.doctree
--------------------------------------------------------------------------------
/docs/build/.doctrees/quetzal.model.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/build/.doctrees/quetzal.model.doctree
--------------------------------------------------------------------------------
/docs/source/_build/doctrees/quetzal.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/doctrees/quetzal.doctree
--------------------------------------------------------------------------------
/docs/source/_build/html/_static/comment.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/html/_static/comment.png
--------------------------------------------------------------------------------
/docs/build/.doctrees/quetzal.analysis.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/build/.doctrees/quetzal.analysis.doctree
--------------------------------------------------------------------------------
/docs/build/.doctrees/quetzal.io.export.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/build/.doctrees/quetzal.io.export.doctree
--------------------------------------------------------------------------------
/docs/source/_build/doctrees/environment.pickle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/doctrees/environment.pickle
--------------------------------------------------------------------------------
/docs/source/_build/doctrees/quetzal.io.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/doctrees/quetzal.io.doctree
--------------------------------------------------------------------------------
/docs/source/_build/html/_static/up-pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/html/_static/up-pressed.png
--------------------------------------------------------------------------------
/docs/build/.doctrees/quetzal.io.display.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/build/.doctrees/quetzal.io.display.doctree
--------------------------------------------------------------------------------
/docs/build/.doctrees/quetzal.io.importer.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/build/.doctrees/quetzal.io.importer.doctree
--------------------------------------------------------------------------------
/docs/build/.doctrees/quetzal.model.model.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/build/.doctrees/quetzal.model.model.doctree
--------------------------------------------------------------------------------
/docs/source/_build/doctrees/quetzal.model.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/doctrees/quetzal.model.doctree
--------------------------------------------------------------------------------
/docs/source/_build/html/_static/ajax-loader.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/html/_static/ajax-loader.gif
--------------------------------------------------------------------------------
/docs/source/_build/html/_static/comment-close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/html/_static/comment-close.png
--------------------------------------------------------------------------------
/docs/source/_build/html/_static/down-pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/html/_static/down-pressed.png
--------------------------------------------------------------------------------
/docs/source/_images/paris.pgw:
--------------------------------------------------------------------------------
1 | 10.65141178318930315
2 | 0
3 | 0
4 | -10.65141178318930315
5 | 644592.60360589157789946
6 | 6867101.39765243511646986
7 |
--------------------------------------------------------------------------------
/syspy/paths.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | r_path = os.path.dirname(os.path.realpath(__file__))
4 | gis_resources = r_path + r'/io/pandasshp/gis_resources/'
5 |
--------------------------------------------------------------------------------
/docs/build/.doctrees/quetzal.engine.engine.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/build/.doctrees/quetzal.engine.engine.doctree
--------------------------------------------------------------------------------
/docs/build/.doctrees/quetzal.model.docmodel.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/build/.doctrees/quetzal.model.docmodel.doctree
--------------------------------------------------------------------------------
/docs/source/_build/doctrees/quetzal.engine.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/doctrees/quetzal.engine.doctree
--------------------------------------------------------------------------------
/docs/source/_build/html/_static/comment-bright.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/html/_static/comment-bright.png
--------------------------------------------------------------------------------
/docs/source/_build/html/_static/fonts/Lato-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/html/_static/fonts/Lato-Bold.ttf
--------------------------------------------------------------------------------
/docs/build/.doctrees/quetzal.analysis.analysis.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/build/.doctrees/quetzal.analysis.analysis.doctree
--------------------------------------------------------------------------------
/docs/build/.doctrees/quetzal.engine.pathfinder.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/build/.doctrees/quetzal.engine.pathfinder.doctree
--------------------------------------------------------------------------------
/docs/build/.doctrees/quetzal.io.export_utils.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/build/.doctrees/quetzal.io.export_utils.doctree
--------------------------------------------------------------------------------
/docs/build/.doctrees/quetzal.io.gtfs_importer.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/build/.doctrees/quetzal.io.gtfs_importer.doctree
--------------------------------------------------------------------------------
/docs/build/.doctrees/quetzal.model.cubemodel.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/build/.doctrees/quetzal.model.cubemodel.doctree
--------------------------------------------------------------------------------
/docs/build/.doctrees/quetzal.model.stepmodel.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/build/.doctrees/quetzal.model.stepmodel.doctree
--------------------------------------------------------------------------------
/docs/source/_build/doctrees/quetzal.analysis.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/doctrees/quetzal.analysis.doctree
--------------------------------------------------------------------------------
/docs/source/_build/doctrees/quetzal.io.display.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/doctrees/quetzal.io.display.doctree
--------------------------------------------------------------------------------
/docs/source/_build/doctrees/quetzal.io.export.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/doctrees/quetzal.io.export.doctree
--------------------------------------------------------------------------------
/docs/source/_build/html/_static/fonts/Lato-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/html/_static/fonts/Lato-Regular.ttf
--------------------------------------------------------------------------------
/docs/source/_images/favicon_package_v0.16/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_images/favicon_package_v0.16/favicon.ico
--------------------------------------------------------------------------------
/docs/build/.doctrees/quetzal.analysis.on_demand.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/build/.doctrees/quetzal.analysis.on_demand.doctree
--------------------------------------------------------------------------------
/docs/build/.doctrees/quetzal.engine.add_network.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/build/.doctrees/quetzal.engine.add_network.doctree
--------------------------------------------------------------------------------
/docs/build/.doctrees/quetzal.engine.connectivity.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/build/.doctrees/quetzal.engine.connectivity.doctree
--------------------------------------------------------------------------------
/docs/build/.doctrees/quetzal.engine.screenlines.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/build/.doctrees/quetzal.engine.screenlines.doctree
--------------------------------------------------------------------------------
/docs/build/.doctrees/quetzal.model.analysismodel.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/build/.doctrees/quetzal.model.analysismodel.doctree
--------------------------------------------------------------------------------
/docs/source/_build/doctrees/quetzal.io.importer.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/doctrees/quetzal.io.importer.doctree
--------------------------------------------------------------------------------
/docs/source/_build/doctrees/quetzal.model.model.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/doctrees/quetzal.model.model.doctree
--------------------------------------------------------------------------------
/ruff.toml:
--------------------------------------------------------------------------------
1 | line-length = 120
2 |
3 | [format]
4 | quote-style = "single"
5 | indent-style = "space"
6 | docstring-code-format = true
7 | skip-magic-trailing-comma = true
--------------------------------------------------------------------------------
/docs/build/.doctrees/quetzal.model.integritymodel.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/build/.doctrees/quetzal.model.integritymodel.doctree
--------------------------------------------------------------------------------
/docs/build/.doctrees/quetzal.model.preparationmodel.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/build/.doctrees/quetzal.model.preparationmodel.doctree
--------------------------------------------------------------------------------
/docs/build/.doctrees/quetzal.model.transportmodel.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/build/.doctrees/quetzal.model.transportmodel.doctree
--------------------------------------------------------------------------------
/docs/source/_build/doctrees/quetzal.engine.engine.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/doctrees/quetzal.engine.engine.doctree
--------------------------------------------------------------------------------
/docs/source/_build/doctrees/quetzal.io.export_utils.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/doctrees/quetzal.io.export_utils.doctree
--------------------------------------------------------------------------------
/docs/source/_build/doctrees/quetzal.model.cubemodel.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/doctrees/quetzal.model.cubemodel.doctree
--------------------------------------------------------------------------------
/docs/source/_build/doctrees/quetzal.model.docmodel.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/doctrees/quetzal.model.docmodel.doctree
--------------------------------------------------------------------------------
/docs/source/_build/doctrees/quetzal.model.stepmodel.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/doctrees/quetzal.model.stepmodel.doctree
--------------------------------------------------------------------------------
/docs/source/_build/html/_static/fonts/Inconsolata-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/html/_static/fonts/Inconsolata-Bold.ttf
--------------------------------------------------------------------------------
/docs/source/_build/html/_static/fonts/RobotoSlab-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/html/_static/fonts/RobotoSlab-Bold.ttf
--------------------------------------------------------------------------------
/docs/source/_images/favicon_package_v0.16/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_images/favicon_package_v0.16/favicon-16x16.png
--------------------------------------------------------------------------------
/docs/source/_images/favicon_package_v0.16/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_images/favicon_package_v0.16/favicon-32x32.png
--------------------------------------------------------------------------------
/api/ML_MatrixRoadCaster/Dockerfile.dockerignore:
--------------------------------------------------------------------------------
1 | __pycache__
2 | *.ipynb_checkpoints
3 | *.python-version
4 | *.md
5 | *.env
6 | api/ML_MatrixRoadCaster/notebook
7 | syspy/surveys
--------------------------------------------------------------------------------
/docs/source/_build/doctrees/quetzal.analysis.analysis.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/doctrees/quetzal.analysis.analysis.doctree
--------------------------------------------------------------------------------
/docs/source/_build/doctrees/quetzal.engine.pathfinder.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/doctrees/quetzal.engine.pathfinder.doctree
--------------------------------------------------------------------------------
/docs/source/_build/doctrees/quetzal.io.gtfs_importer.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/doctrees/quetzal.io.gtfs_importer.doctree
--------------------------------------------------------------------------------
/docs/source/_build/html/_static/fonts/Inconsolata-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/html/_static/fonts/Inconsolata-Regular.ttf
--------------------------------------------------------------------------------
/docs/source/_build/html/_static/fonts/RobotoSlab-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/html/_static/fonts/RobotoSlab-Regular.ttf
--------------------------------------------------------------------------------
/docs/source/_build/html/_static/fonts/fontawesome-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/html/_static/fonts/fontawesome-webfont.eot
--------------------------------------------------------------------------------
/docs/source/_build/html/_static/fonts/fontawesome-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/html/_static/fonts/fontawesome-webfont.ttf
--------------------------------------------------------------------------------
/docs/source/_images/favicon_package_v0.16/mstile-150x150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_images/favicon_package_v0.16/mstile-150x150.png
--------------------------------------------------------------------------------
/docs/build/.doctrees/quetzal.engine.linearsolver_utils.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/build/.doctrees/quetzal.engine.linearsolver_utils.doctree
--------------------------------------------------------------------------------
/docs/source/_build/doctrees/quetzal.analysis.on_demand.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/doctrees/quetzal.analysis.on_demand.doctree
--------------------------------------------------------------------------------
/docs/source/_build/doctrees/quetzal.engine.add_network.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/doctrees/quetzal.engine.add_network.doctree
--------------------------------------------------------------------------------
/docs/source/_build/doctrees/quetzal.engine.connectivity.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/doctrees/quetzal.engine.connectivity.doctree
--------------------------------------------------------------------------------
/docs/source/_build/doctrees/quetzal.engine.screenlines.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/doctrees/quetzal.engine.screenlines.doctree
--------------------------------------------------------------------------------
/docs/source/_build/doctrees/quetzal.model.analysismodel.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/doctrees/quetzal.model.analysismodel.doctree
--------------------------------------------------------------------------------
/docs/source/_build/doctrees/quetzal.model.integritymodel.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/doctrees/quetzal.model.integritymodel.doctree
--------------------------------------------------------------------------------
/docs/source/_build/doctrees/quetzal.model.transportmodel.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/doctrees/quetzal.model.transportmodel.doctree
--------------------------------------------------------------------------------
/docs/source/_build/html/_static/fonts/fontawesome-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/html/_static/fonts/fontawesome-webfont.woff
--------------------------------------------------------------------------------
/docs/source/_images/favicon_package_v0.16/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_images/favicon_package_v0.16/apple-touch-icon.png
--------------------------------------------------------------------------------
/docs/source/_build/doctrees/quetzal.model.preparationmodel.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/doctrees/quetzal.model.preparationmodel.doctree
--------------------------------------------------------------------------------
/docs/source/quetzal.io.osm.rst:
--------------------------------------------------------------------------------
1 | quetzal.io.osm module
2 | =====================
3 |
4 | .. automodule:: quetzal.io.osm
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/build/.doctrees/quetzal.analysis.cost_benefit_analysis.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/build/.doctrees/quetzal.analysis.cost_benefit_analysis.doctree
--------------------------------------------------------------------------------
/docs/source/_build/doctrees/quetzal.engine.linearsolver_utils.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/doctrees/quetzal.engine.linearsolver_utils.doctree
--------------------------------------------------------------------------------
/docs/source/_images/favicon_package_v0.16/android-chrome-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_images/favicon_package_v0.16/android-chrome-192x192.png
--------------------------------------------------------------------------------
/docs/source/_images/favicon_package_v0.16/android-chrome-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_images/favicon_package_v0.16/android-chrome-512x512.png
--------------------------------------------------------------------------------
/docs/source/quetzal.io.road.rst:
--------------------------------------------------------------------------------
1 | quetzal.io.road module
2 | ======================
3 |
4 | .. automodule:: quetzal.io.road
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/quetzal.io.excel.rst:
--------------------------------------------------------------------------------
1 | quetzal.io.excel module
2 | =======================
3 |
4 | .. automodule:: quetzal.io.excel
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/desktop.ini:
--------------------------------------------------------------------------------
1 | [.ShellClassInfo]
2 | IconResource=C:\Users\qchasserieau\OneDrive - SystraGroup\Images\favicon_package_v0.16 (2)\favicon.ico,0
3 | [ViewState]
4 | Mode=
5 | Vid=
6 | FolderType=Generic
7 |
--------------------------------------------------------------------------------
/docs/source/_build/doctrees/quetzal.analysis.cost_benefit_analysis.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/systragroup/quetzal/HEAD/docs/source/_build/doctrees/quetzal.analysis.cost_benefit_analysis.doctree
--------------------------------------------------------------------------------
/docs/source/quetzal.io.export.rst:
--------------------------------------------------------------------------------
1 | quetzal.io.export module
2 | ========================
3 |
4 | .. automodule:: quetzal.io.export
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/quetzal.io.hdf_io.rst:
--------------------------------------------------------------------------------
1 | quetzal.io.hdf\_io module
2 | =========================
3 |
4 | .. automodule:: quetzal.io.hdf_io
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/syspy/io/pandasshp/gis_resources/projections/epsg4326.prj:
--------------------------------------------------------------------------------
1 | GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]
--------------------------------------------------------------------------------
/syspy/syspy_utils/gis_resources/projections/epsg4326.prj:
--------------------------------------------------------------------------------
1 | GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]
--------------------------------------------------------------------------------
/docs/source/quetzal.engine.csa.rst:
--------------------------------------------------------------------------------
1 | quetzal.engine.csa module
2 | =========================
3 |
4 | .. automodule:: quetzal.engine.csa
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/quetzal.io.display.rst:
--------------------------------------------------------------------------------
1 | quetzal.io.display module
2 | =========================
3 |
4 | .. automodule:: quetzal.io.display
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/quetzal.io.importer.rst:
--------------------------------------------------------------------------------
1 | quetzal.io.importer module
2 | ==========================
3 |
4 | .. automodule:: quetzal.io.importer
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/quetzal.model.model.rst:
--------------------------------------------------------------------------------
1 | quetzal.model.model module
2 | ==========================
3 |
4 | .. automodule:: quetzal.model.model
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/quetzal/__init__.py:
--------------------------------------------------------------------------------
1 | import warnings
2 | import sys
3 | if sys.version_info.major != 3 or sys.version_info.minor < 12:
4 | warnings.warn(f'Quetzal was updated to python 3.12. Please refer to README to update.')
--------------------------------------------------------------------------------
/docs/source/quetzal.engine.engine.rst:
--------------------------------------------------------------------------------
1 | quetzal.engine.engine module
2 | ============================
3 |
4 | .. automodule:: quetzal.engine.engine
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/quetzal.model.docmodel.rst:
--------------------------------------------------------------------------------
1 | quetzal.model.docmodel module
2 | =============================
3 |
4 | .. automodule:: quetzal.model.docmodel
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/_build/html/_sources/quetzal.io.display.txt:
--------------------------------------------------------------------------------
1 | quetzal.io.display module
2 | =========================
3 |
4 | .. automodule:: quetzal.io.display
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/_build/html/_sources/quetzal.io.export.txt:
--------------------------------------------------------------------------------
1 | quetzal.io.export module
2 | ========================
3 |
4 | .. automodule:: quetzal.io.export
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/quetzal.io.export_utils.rst:
--------------------------------------------------------------------------------
1 | quetzal.io.export_utils module
2 | ==============================
3 |
4 | .. automodule:: quetzal.io.export_utils
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/quetzal.model.cubemodel.rst:
--------------------------------------------------------------------------------
1 | quetzal.model.cubemodel module
2 | ==============================
3 |
4 | .. automodule:: quetzal.model.cubemodel
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/quetzal.model.plotmodel.rst:
--------------------------------------------------------------------------------
1 | quetzal.model.plotmodel module
2 | ==============================
3 |
4 | .. automodule:: quetzal.model.plotmodel
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/quetzal.model.stepmodel.rst:
--------------------------------------------------------------------------------
1 | quetzal.model.stepmodel module
2 | ==============================
3 |
4 | .. automodule:: quetzal.model.stepmodel
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/_build/html/_sources/quetzal.io.importer.txt:
--------------------------------------------------------------------------------
1 | quetzal.io.importer module
2 | ==========================
3 |
4 | .. automodule:: quetzal.io.importer
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/_build/html/_sources/quetzal.model.model.txt:
--------------------------------------------------------------------------------
1 | quetzal.model.model module
2 | ==========================
3 |
4 | .. automodule:: quetzal.model.model
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/quetzal.engine.msa_utils.rst:
--------------------------------------------------------------------------------
1 | quetzal.engine.msa\_utils module
2 | ================================
3 |
4 | .. automodule:: quetzal.engine.msa_utils
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/quetzal.io.gtfs_importer.rst:
--------------------------------------------------------------------------------
1 | quetzal.io.gtfs_importer module
2 | ===============================
3 |
4 | .. automodule:: quetzal.io.gtfs_importer
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/quetzal.analysis.analysis.rst:
--------------------------------------------------------------------------------
1 | quetzal.analysis.analysis module
2 | ================================
3 |
4 | .. automodule:: quetzal.analysis.analysis
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/quetzal.engine.gps_tracks.rst:
--------------------------------------------------------------------------------
1 | quetzal.engine.gps\_tracks module
2 | =================================
3 |
4 | .. automodule:: quetzal.engine.gps_tracks
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/quetzal.engine.graph_utils.rst:
--------------------------------------------------------------------------------
1 | quetzal.engine.graph\_utils module
2 | ==================================
3 |
4 | .. automodule:: quetzal.engine.graph_utils
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/quetzal.engine.pathfinder.rst:
--------------------------------------------------------------------------------
1 | quetzal.engine.pathfinder module
2 | ================================
3 |
4 | .. automodule:: quetzal.engine.pathfinder
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/quetzal.model.optimalmodel.rst:
--------------------------------------------------------------------------------
1 | quetzal.model.optimalmodel module
2 | =================================
3 |
4 | .. automodule:: quetzal.model.optimalmodel
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/quetzal.model.summarymodel.rst:
--------------------------------------------------------------------------------
1 | quetzal.model.summarymodel module
2 | =================================
3 |
4 | .. automodule:: quetzal.model.summarymodel
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/_build/html/_sources/quetzal.engine.engine.txt:
--------------------------------------------------------------------------------
1 | quetzal.engine.engine module
2 | ============================
3 |
4 | .. automodule:: quetzal.engine.engine
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/quetzal.analysis.on_demand.rst:
--------------------------------------------------------------------------------
1 | quetzal.analysis.on_demand module
2 | =================================
3 |
4 | .. automodule:: quetzal.analysis.on_demand
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/quetzal.engine.add_network.rst:
--------------------------------------------------------------------------------
1 | quetzal.engine.add_network module
2 | =================================
3 |
4 | .. automodule:: quetzal.engine.add_network
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/quetzal.engine.connectivity.rst:
--------------------------------------------------------------------------------
1 | quetzal.engine.connectivity module
2 | ==================================
3 |
4 | .. automodule:: quetzal.engine.connectivity
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/quetzal.engine.nested_logit.rst:
--------------------------------------------------------------------------------
1 | quetzal.engine.nested\_logit module
2 | ===================================
3 |
4 | .. automodule:: quetzal.engine.nested_logit
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/quetzal.engine.screenlines.rst:
--------------------------------------------------------------------------------
1 | quetzal.engine.screenlines module
2 | =================================
3 |
4 | .. automodule:: quetzal.engine.screenlines
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/quetzal.model.analysismodel.rst:
--------------------------------------------------------------------------------
1 | quetzal.model.analysismodel module
2 | ==================================
3 |
4 | .. automodule:: quetzal.model.analysismodel
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/quetzal.model.parkridemodel.rst:
--------------------------------------------------------------------------------
1 | quetzal.model.parkridemodel module
2 | ==================================
3 |
4 | .. automodule:: quetzal.model.parkridemodel
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/_build/html/_sources/quetzal.io.export_utils.txt:
--------------------------------------------------------------------------------
1 | quetzal.io.export_utils module
2 | ==============================
3 |
4 | .. automodule:: quetzal.io.export_utils
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/_build/html/_sources/quetzal.model.cubemodel.txt:
--------------------------------------------------------------------------------
1 | quetzal.model.cubemodel module
2 | ==============================
3 |
4 | .. automodule:: quetzal.model.cubemodel
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/_build/html/_sources/quetzal.model.docmodel.txt:
--------------------------------------------------------------------------------
1 | quetzal.model.docmodel module
2 | =============================
3 |
4 | .. automodule:: quetzal.model.docmodel
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/_build/html/_sources/quetzal.model.stepmodel.txt:
--------------------------------------------------------------------------------
1 | quetzal.model.stepmodel module
2 | ==============================
3 |
4 | .. automodule:: quetzal.model.stepmodel
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/quetzal.model.integritymodel.rst:
--------------------------------------------------------------------------------
1 | quetzal.model.integritymodel module
2 | ===================================
3 |
4 | .. automodule:: quetzal.model.integritymodel
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/quetzal.model.transportmodel.rst:
--------------------------------------------------------------------------------
1 | quetzal.model.transportmodel module
2 | ===================================
3 |
4 | .. automodule:: quetzal.model.transportmodel
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/_build/html/_sources/quetzal.io.gtfs_importer.txt:
--------------------------------------------------------------------------------
1 | quetzal.io.gtfs_importer module
2 | ===============================
3 |
4 | .. automodule:: quetzal.io.gtfs_importer
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/quetzal.analysis.accessibility.rst:
--------------------------------------------------------------------------------
1 | quetzal.analysis.accessibility module
2 | =====================================
3 |
4 | .. automodule:: quetzal.analysis.accessibility
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/quetzal.engine.parallelization.rst:
--------------------------------------------------------------------------------
1 | quetzal.engine.parallelization module
2 | =====================================
3 |
4 | .. automodule:: quetzal.engine.parallelization
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/_build/html/_sources/quetzal.analysis.analysis.txt:
--------------------------------------------------------------------------------
1 | quetzal.analysis.analysis module
2 | ================================
3 |
4 | .. automodule:: quetzal.analysis.analysis
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/_build/html/_sources/quetzal.engine.pathfinder.txt:
--------------------------------------------------------------------------------
1 | quetzal.engine.pathfinder module
2 | ================================
3 |
4 | .. automodule:: quetzal.engine.pathfinder
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/quetzal.engine.optimal_strategy.rst:
--------------------------------------------------------------------------------
1 | quetzal.engine.optimal\_strategy module
2 | =======================================
3 |
4 | .. automodule:: quetzal.engine.optimal_strategy
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/quetzal.engine.pathfinder_utils.rst:
--------------------------------------------------------------------------------
1 | quetzal.engine.pathfinder\_utils module
2 | =======================================
3 |
4 | .. automodule:: quetzal.engine.pathfinder_utils
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/quetzal.engine.road_pathfinder.rst:
--------------------------------------------------------------------------------
1 | quetzal.engine.road\_pathfinder module
2 | ======================================
3 |
4 | .. automodule:: quetzal.engine.road_pathfinder
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/quetzal.io.gtfs_reader.importer.rst:
--------------------------------------------------------------------------------
1 | quetzal.io.gtfs\_reader.importer module
2 | =======================================
3 |
4 | .. automodule:: quetzal.io.gtfs_reader.importer
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/quetzal.io.gtfs_reader.patterns.rst:
--------------------------------------------------------------------------------
1 | quetzal.io.gtfs\_reader.patterns module
2 | =======================================
3 |
4 | .. automodule:: quetzal.io.gtfs_reader.patterns
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/quetzal.io.gtfs_reader.services.rst:
--------------------------------------------------------------------------------
1 | quetzal.io.gtfs\_reader.services module
2 | =======================================
3 |
4 | .. automodule:: quetzal.io.gtfs_reader.services
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/quetzal.launcher.launcher_utils.rst:
--------------------------------------------------------------------------------
1 | quetzal.launcher.launcher\_utils module
2 | =======================================
3 |
4 | .. automodule:: quetzal.launcher.launcher_utils
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/quetzal.model.preparationmodel.rst:
--------------------------------------------------------------------------------
1 | quetzal.model.preparationmodel module
2 | =====================================
3 |
4 | .. automodule:: quetzal.model.preparationmodel
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/quetzal.model.timeexpandedmodel.rst:
--------------------------------------------------------------------------------
1 | quetzal.model.timeexpandedmodel module
2 | ======================================
3 |
4 | .. automodule:: quetzal.model.timeexpandedmodel
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/_build/html/_sources/quetzal.analysis.on_demand.txt:
--------------------------------------------------------------------------------
1 | quetzal.analysis.on_demand module
2 | =================================
3 |
4 | .. automodule:: quetzal.analysis.on_demand
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/_build/html/_sources/quetzal.engine.add_network.txt:
--------------------------------------------------------------------------------
1 | quetzal.engine.add_network module
2 | =================================
3 |
4 | .. automodule:: quetzal.engine.add_network
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/_build/html/_sources/quetzal.engine.screenlines.txt:
--------------------------------------------------------------------------------
1 | quetzal.engine.screenlines module
2 | =================================
3 |
4 | .. automodule:: quetzal.engine.screenlines
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/quetzal.io.gtfs_reader.filtering.rst:
--------------------------------------------------------------------------------
1 | quetzal.io.gtfs\_reader.filtering module
2 | ========================================
3 |
4 | .. automodule:: quetzal.io.gtfs_reader.filtering
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/build/.buildinfo:
--------------------------------------------------------------------------------
1 | # Sphinx build info version 1
2 | # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
3 | config: 60f528c778e046ba175bf6b491097794
4 | tags: 645f666f9bcd5a90fca523b33c5a78b7
5 |
--------------------------------------------------------------------------------
/docs/source/_build/html/_sources/quetzal.analysis.txt:
--------------------------------------------------------------------------------
1 | quetzal.analysis package
2 | ========================
3 |
4 |
5 |
6 | .. toctree::
7 |
8 | quetzal.analysis.analysis
9 | quetzal.analysis.cost_benefit_analysis
10 | quetzal.analysis.on_demand
--------------------------------------------------------------------------------
/docs/source/_build/html/_sources/quetzal.engine.connectivity.txt:
--------------------------------------------------------------------------------
1 | quetzal.engine.connectivity module
2 | ==================================
3 |
4 | .. automodule:: quetzal.engine.connectivity
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/_build/html/_sources/quetzal.model.analysismodel.txt:
--------------------------------------------------------------------------------
1 | quetzal.model.analysismodel module
2 | ==================================
3 |
4 | .. automodule:: quetzal.model.analysismodel
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/_build/html/_sources/quetzal.model.integritymodel.txt:
--------------------------------------------------------------------------------
1 | quetzal.model.integritymodel module
2 | ===================================
3 |
4 | .. automodule:: quetzal.model.integritymodel
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/_build/html/_sources/quetzal.model.transportmodel.txt:
--------------------------------------------------------------------------------
1 | quetzal.model.transportmodel module
2 | ===================================
3 |
4 | .. automodule:: quetzal.model.transportmodel
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/quetzal.engine.linearsolver_utils.rst:
--------------------------------------------------------------------------------
1 | quetzal.engine.linearsolver_utils module
2 | ========================================
3 |
4 | .. automodule:: quetzal.engine.linearsolver_utils
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/quetzal.engine.optimization_utils.rst:
--------------------------------------------------------------------------------
1 | quetzal.engine.optimization\_utils module
2 | =========================================
3 |
4 | .. automodule:: quetzal.engine.optimization_utils
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/quetzal.io.gtfs_reader.directions.rst:
--------------------------------------------------------------------------------
1 | quetzal.io.gtfs\_reader.directions module
2 | =========================================
3 |
4 | .. automodule:: quetzal.io.gtfs_reader.directions
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/quetzal.io.gtfs_reader.feed_gtfsk.rst:
--------------------------------------------------------------------------------
1 | quetzal.io.gtfs\_reader.feed\_gtfsk module
2 | ==========================================
3 |
4 | .. automodule:: quetzal.io.gtfs_reader.feed_gtfsk
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/quetzal.model.connectionscanmodel.rst:
--------------------------------------------------------------------------------
1 | quetzal.model.connectionscanmodel module
2 | ========================================
3 |
4 | .. automodule:: quetzal.model.connectionscanmodel
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/quetzal.engine.time_expanded_utils.rst:
--------------------------------------------------------------------------------
1 | quetzal.engine.time\_expanded\_utils module
2 | ===========================================
3 |
4 | .. automodule:: quetzal.engine.time_expanded_utils
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/quetzal.io.gtfs_reader.frequencies.rst:
--------------------------------------------------------------------------------
1 | quetzal.io.gtfs\_reader.frequencies module
2 | ==========================================
3 |
4 | .. automodule:: quetzal.io.gtfs_reader.frequencies
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/syspy/spatial/graph/__init__.py:
--------------------------------------------------------------------------------
1 | # module level doc-string
2 | __doc__ = """
3 | This module provides tools for network processing.
4 | It processes geometries more than abstract graphs.
5 | network contains the tools
6 | graphbuilder contains the wrapper
7 | """
8 |
--------------------------------------------------------------------------------
/docs/source/_build/html/_sources/quetzal.model.preparationmodel.txt:
--------------------------------------------------------------------------------
1 | quetzal.model.preparationmodel module
2 | =====================================
3 |
4 | .. automodule:: quetzal.model.preparationmodel
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/_build/html/.buildinfo:
--------------------------------------------------------------------------------
1 | # Sphinx build info version 1
2 | # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
3 | config: d3e45443eb1522752c325181ab085454
4 | tags: 645f666f9bcd5a90fca523b33c5a78b7
5 |
--------------------------------------------------------------------------------
/docs/source/quetzal.io.gtfs_reader.gtfs_importer.rst:
--------------------------------------------------------------------------------
1 | quetzal.io.gtfs\_reader.gtfs\_importer module
2 | =============================================
3 |
4 | .. automodule:: quetzal.io.gtfs_reader.gtfs_importer
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/_build/html/_sources/quetzal.engine.linearsolver_utils.txt:
--------------------------------------------------------------------------------
1 | quetzal.engine.linearsolver_utils module
2 | ========================================
3 |
4 | .. automodule:: quetzal.engine.linearsolver_utils
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/quetzal.analysis.cost_benefit_analysis.rst:
--------------------------------------------------------------------------------
1 | quetzal.analysis.cost_benefit_analysis module
2 | =============================================
3 |
4 | .. automodule:: quetzal.analysis.cost_benefit_analysis
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/quetzal.engine.add_network_mapmatching.rst:
--------------------------------------------------------------------------------
1 | quetzal.engine.add\_network\_mapmatching module
2 | ===============================================
3 |
4 | .. automodule:: quetzal.engine.add_network_mapmatching
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/quetzal.engine.combinatorial_pathfinder.rst:
--------------------------------------------------------------------------------
1 | quetzal.engine.combinatorial\_pathfinder module
2 | ===============================================
3 |
4 | .. automodule:: quetzal.engine.combinatorial_pathfinder
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/quetzal.engine.park_and_ride_pathfinder.rst:
--------------------------------------------------------------------------------
1 | quetzal.engine.park\_and\_ride\_pathfinder module
2 | =================================================
3 |
4 | .. automodule:: quetzal.engine.park_and_ride_pathfinder
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/_build/html/_sources/quetzal.analysis.cost_benefit_analysis.txt:
--------------------------------------------------------------------------------
1 | quetzal.analysis.cost_benefit_analysis module
2 | =============================================
3 |
4 | .. automodule:: quetzal.analysis.cost_benefit_analysis
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/quetzal/index.txt:
--------------------------------------------------------------------------------
1 | quetzal package
2 | =====================
3 |
4 | .. include:: ../syspy/quetzal/description.txt
5 |
6 | Subpackages
7 | -----------
8 |
9 | .. toctree::
10 | :maxdepth: 1
11 |
12 | quetzal.analysis
13 | quetzal.engine
14 | quetzal.io
15 | quetzal.stories
16 |
--------------------------------------------------------------------------------
/docs/source/_images/favicon_package_v0.16/browserconfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | #da532c
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/api/ML_MatrixRoadCaster/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM public.ecr.aws/lambda/python:3.12
2 | COPY api/ML_MatrixRoadCaster/requirements.txt ./requirements.txt
3 | RUN pip install -r ./requirements.txt
4 |
5 | COPY api/ML_MatrixRoadCaster/ ./
6 | #COPY quetzal/engine/road_model.py ./road_model.py
7 | COPY quetzal ./quetzal
8 | COPY syspy ./syspy
9 |
10 | CMD ["main.handler"]
--------------------------------------------------------------------------------
/docs/source/quetzal.launcher.rst:
--------------------------------------------------------------------------------
1 | quetzal.launcher package
2 | ========================
3 |
4 | Submodules
5 | ----------
6 |
7 | .. toctree::
8 | :maxdepth: 4
9 |
10 | quetzal.launcher.launcher_utils
11 |
12 | Module contents
13 | ---------------
14 |
15 | .. automodule:: quetzal.launcher
16 | :members:
17 | :undoc-members:
18 | :show-inheritance:
19 |
--------------------------------------------------------------------------------
/docs/source/quetzal.rst:
--------------------------------------------------------------------------------
1 | quetzal package
2 | ===============
3 |
4 | Subpackages
5 | -----------
6 |
7 | .. toctree::
8 |
9 | quetzal.analysis
10 | quetzal.engine
11 | quetzal.io
12 | quetzal.model
13 |
14 | Module contents
15 | ---------------
16 |
17 | .. automodule:: quetzal
18 | :members:
19 | :undoc-members:
20 | :show-inheritance:
21 |
--------------------------------------------------------------------------------
/docs/source/_build/html/_sources/quetzal.txt:
--------------------------------------------------------------------------------
1 | quetzal package
2 | ===============
3 |
4 | Subpackages
5 | -----------
6 |
7 | .. toctree::
8 |
9 | quetzal.analysis
10 | quetzal.engine
11 | quetzal.io
12 | quetzal.model
13 |
14 | Module contents
15 | ---------------
16 |
17 | .. automodule:: quetzal
18 | :members:
19 | :undoc-members:
20 | :show-inheritance:
21 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | **__pycache__**
2 | *.pyc
3 | doc/
4 | **.cache**
5 | **.ipynb_checkpoints
6 | quetzal/tests/data/out/
7 | tests/data/out/
8 | .eggs/
9 | *.egg-info/
10 | .venv/
11 | .idea/
12 | .python-version
13 | .vscode/
14 |
15 | build/
16 | *.env
17 | !docker/templates/.env
18 |
19 | # Local .terraform directories
20 | **/.terraform/*
21 | docker/infra/.terraform/*
22 | *.tfstate
23 | *.tfstate.*
24 |
25 |
--------------------------------------------------------------------------------
/docs/makedoc.py:
--------------------------------------------------------------------------------
1 | import os
2 | import sys
3 |
4 | sys.path.insert(0, os.path.abspath('../..'))
5 |
6 | os.system('rmdir /s /q build')
7 | project_options = '-H quetzal -A Systra'
8 | make_options = '-o source ../quetzal -s rst'
9 | make_options_1 = '--full --separate'
10 |
11 | os.system(f'sphinx-apidoc {make_options} {make_options_1} {project_options}')
12 | os.system('sphinx-build -b html source build')
13 |
--------------------------------------------------------------------------------
/docs/source/quetzal.analysis.rst:
--------------------------------------------------------------------------------
1 | quetzal.analysis package
2 | ========================
3 |
4 | Submodules
5 | ----------
6 |
7 | .. toctree::
8 |
9 | quetzal.analysis.analysis
10 | quetzal.analysis.cost_benefit_analysis
11 | quetzal.analysis.on_demand
12 |
13 | Module contents
14 | ---------------
15 |
16 | .. automodule:: quetzal.analysis
17 | :members:
18 | :undoc-members:
19 | :show-inheritance:
20 |
--------------------------------------------------------------------------------
/docs/source/quetzal.io.rst:
--------------------------------------------------------------------------------
1 | quetzal.io package
2 | ==================
3 |
4 | Submodules
5 | ----------
6 |
7 | .. toctree::
8 |
9 | quetzal.io.display
10 | quetzal.io.export
11 | quetzal.io.export_utils
12 | quetzal.io.gtfs_importer
13 | quetzal.io.importer
14 |
15 | Module contents
16 | ---------------
17 |
18 | .. automodule:: quetzal.io
19 | :members:
20 | :undoc-members:
21 | :show-inheritance:
22 |
--------------------------------------------------------------------------------
/syspy/io/pandasshp/gis_resources/projections/epsg32614.prj:
--------------------------------------------------------------------------------
1 | PROJCS["WGS_1984_UTM_Zone_14N",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-99],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["Meter",1]]
--------------------------------------------------------------------------------
/syspy/syspy_utils/gis_resources/projections/epsg32614.prj:
--------------------------------------------------------------------------------
1 | PROJCS["WGS_1984_UTM_Zone_14N",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-99],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["Meter",1]]
--------------------------------------------------------------------------------
/docs/source/_build/html/_sources/quetzal.io.txt:
--------------------------------------------------------------------------------
1 | quetzal.io package
2 | ==================
3 |
4 | Submodules
5 | ----------
6 |
7 | .. toctree::
8 |
9 | quetzal.io.display
10 | quetzal.io.export
11 | quetzal.io.export_utils
12 | quetzal.io.gtfs_importer
13 | quetzal.io.importer
14 |
15 | Module contents
16 | ---------------
17 |
18 | .. automodule:: quetzal.io
19 | :members:
20 | :undoc-members:
21 | :show-inheritance:
22 |
--------------------------------------------------------------------------------
/quetzal/engine/subprocesses/subprocess_path_and_duration_from_graph_json.py:
--------------------------------------------------------------------------------
1 | import json
2 | import sys
3 | from pathlib import Path
4 |
5 | from quetzal.engine.pathfinder import path_and_duration_from_graph_json
6 |
7 | path = Path(__file__)
8 | libdir = str(path.parent.parent.parent.parent)
9 | print(libdir)
10 |
11 | sys.path.insert(0, libdir)
12 |
13 | io_string = sys.argv[1]
14 | kwargs = json.loads(io_string)
15 | path_and_duration_from_graph_json(**kwargs)
16 |
--------------------------------------------------------------------------------
/syspy/syspy_utils/gis_resources/projections/epsg2154.prj:
--------------------------------------------------------------------------------
1 | PROJCS["RGF93_Lambert_93",GEOGCS["GCS_RGF93",DATUM["D_RGF_1993",SPHEROID["GRS_1980",6378137,298.257222101]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["standard_parallel_1",49],PARAMETER["standard_parallel_2",44],PARAMETER["latitude_of_origin",46.5],PARAMETER["central_meridian",3],PARAMETER["false_easting",700000],PARAMETER["false_northing",6600000],UNIT["Meter",1]]
--------------------------------------------------------------------------------
/syspy/io/pandasshp/gis_resources/projections/epsg2154.prj:
--------------------------------------------------------------------------------
1 | PROJCS["RGF93_Lambert_93",GEOGCS["GCS_RGF93",DATUM["D_RGF_1993",SPHEROID["GRS_1980",6378137,298.257222101]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["standard_parallel_1",49],PARAMETER["standard_parallel_2",44],PARAMETER["latitude_of_origin",46.5],PARAMETER["central_meridian",3],PARAMETER["false_easting",700000],PARAMETER["false_northing",6600000],UNIT["Meter",1]]
--------------------------------------------------------------------------------
/docs/source/_build/html/_sources/index.txt:
--------------------------------------------------------------------------------
1 | Quetzal Overview
2 | ================
3 | quetzal is a Python package providing flexible models for transport planning and traffic forecasting.
4 |
5 | Packages
6 | ========
7 |
8 | .. toctree::
9 | :maxdepth: 1
10 |
11 | quetzal.engine
12 | quetzal.model
13 | quetzal.io
14 | quetzal.analysis
15 |
16 | Indices and tables
17 | ==================
18 |
19 | * :ref:`genindex`
20 | * :ref:`modindex`
21 | * :ref:`search`
22 |
23 |
--------------------------------------------------------------------------------
/tests/__init__.py:
--------------------------------------------------------------------------------
1 | from unittest import TestCase
2 |
3 |
4 | class MyTest(TestCase):
5 | # basedir = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) + '\\data'
6 | # uri = ':memory:'
7 | # #uri = os.path.join(basedir, 'app.db')
8 | # SQLALCHEMY_DATABASE_URI = "sqlite:///" + uri
9 | # TESTING = True
10 |
11 | def setUp(self):
12 | pass
13 |
14 | def tearDown(self):
15 | pass
16 | # db.session.remove()
17 | # db.drop_all()
18 |
--------------------------------------------------------------------------------
/setup.cfg:
--------------------------------------------------------------------------------
1 | [bdist_wheel]
2 | # If set to 1, this flag says that the code is written to work on both Python 2
3 | # and Python 3. If at all possible, it is good practice to do this. If you
4 | # cannot, you will need to generate wheels for each Python version that you
5 | # support.
6 | universal=0
7 |
8 | # alieas created for automated testing at setup
9 | # http://doc.pytest.org/en/latest/goodpractices.html#integrating-with-setuptools-python-setup-py-test-pytest-runner
10 | [aliases]
11 | test=pytest
12 |
--------------------------------------------------------------------------------
/docs/source/quetzal.engine.rst:
--------------------------------------------------------------------------------
1 | quetzal.engine package
2 | ======================
3 |
4 | Submodules
5 | ----------
6 |
7 | .. toctree::
8 |
9 | quetzal.engine.add_network
10 | quetzal.engine.connectivity
11 | quetzal.engine.engine
12 | quetzal.engine.linearsolver_utils
13 | quetzal.engine.pathfinder
14 | quetzal.engine.screenlines
15 |
16 | Module contents
17 | ---------------
18 |
19 | .. automodule:: quetzal.engine
20 | :members:
21 | :undoc-members:
22 | :show-inheritance:
23 |
--------------------------------------------------------------------------------
/docs/source/_build/html/_sources/quetzal.engine.txt:
--------------------------------------------------------------------------------
1 | quetzal.engine package
2 | ======================
3 |
4 | Submodules
5 | ----------
6 |
7 | .. toctree::
8 |
9 | quetzal.engine.add_network
10 | quetzal.engine.connectivity
11 | quetzal.engine.engine
12 | quetzal.engine.linearsolver_utils
13 | quetzal.engine.pathfinder
14 | quetzal.engine.screenlines
15 |
16 | Module contents
17 | ---------------
18 |
19 | .. automodule:: quetzal.engine
20 | :members:
21 | :undoc-members:
22 | :show-inheritance:
23 |
--------------------------------------------------------------------------------
/docs/source/_images/favicon_package_v0.16/site.webmanifest:
--------------------------------------------------------------------------------
1 | {
2 | "name": "",
3 | "short_name": "",
4 | "icons": [
5 | {
6 | "src": "/android-chrome-192x192.png",
7 | "sizes": "192x192",
8 | "type": "image/png"
9 | },
10 | {
11 | "src": "/android-chrome-512x512.png",
12 | "sizes": "512x512",
13 | "type": "image/png"
14 | }
15 | ],
16 | "theme_color": "#ffffff",
17 | "background_color": "#ffffff",
18 | "display": "standalone"
19 | }
20 |
--------------------------------------------------------------------------------
/docs/source/_build/html/_sources/quetzal.model.txt:
--------------------------------------------------------------------------------
1 | quetzal.model package
2 | =====================
3 |
4 | Submodules
5 | ----------
6 |
7 | .. toctree::
8 |
9 | quetzal.model.analysismodel
10 | quetzal.model.cubemodel
11 | quetzal.model.docmodel
12 | quetzal.model.integritymodel
13 | quetzal.model.model
14 | quetzal.model.preparationmodel
15 | quetzal.model.stepmodel
16 | quetzal.model.transportmodel
17 |
18 | Module contents
19 | ---------------
20 |
21 | .. automodule:: quetzal.model
22 | :members:
23 | :undoc-members:
24 | :show-inheritance:
25 |
--------------------------------------------------------------------------------
/syspy/logit/multinomial_logit.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 |
3 |
4 | def nest_probabilities(utilities, phi=1):
5 | exponential_df = np.exp(np.multiply(utilities, 1 / phi))
6 | exponential_s = exponential_df.T.sum()
7 | probability_df = exponential_df.apply(lambda s: s / exponential_s)
8 | return probability_df.T
9 |
10 |
11 | def nest_utility(utilities, phi=1):
12 | exponential_df = np.exp(np.multiply(utilities, 1 / phi))
13 | exponential_s = exponential_df.T.sum()
14 | emu = np.log(exponential_s)
15 | composite_utility = phi * emu
16 | return composite_utility
17 |
--------------------------------------------------------------------------------
/syspy/routing/networkx_wrapper.py:
--------------------------------------------------------------------------------
1 | import networkx as nx
2 | from tqdm import tqdm
3 |
4 |
5 | def pairwise_function(single_source_function, sources, targets, **kwargs):
6 | resp_dict = {}
7 | for source in tqdm(sources):
8 | try:
9 | to_all_targets = single_source_function(source=source, **kwargs)
10 | filtered = {
11 | key: value for key, value in to_all_targets.items()
12 | if key in targets
13 | }
14 | resp_dict[source] = filtered
15 | except KeyError:
16 | print(source)
17 | return resp_dict
18 |
--------------------------------------------------------------------------------
/api/ML_MatrixRoadCaster/requirements.txt:
--------------------------------------------------------------------------------
1 | boto3==1.34.131
2 | fiona==1.9.6
3 | fqdn==1.5.1
4 | fastapi==0.111.0
5 | geopy==2.4.1
6 | gtfs-kit==6.1.0
7 | httptools==0.6.1
8 | ipywidgets==8.1.3
9 | isoduration==20.11.0
10 | jsonpointer==3.0.0
11 | networkx==3.3
12 | notebook==6.5.7
13 | numba==0.60.0
14 | openmatrix==0.3.5.0
15 | openpyxl==3.1.5
16 | python-dotenv==1.0.1
17 | rasterio==1.3.10
18 | s3fs==2024.6.1
19 | scikit-learn==1.5.1
20 | seaborn==0.13.2
21 | tqdm==4.66.4
22 | uri-template==1.3.0
23 | uvloop==0.19.0
24 | watchfiles==0.22.0
25 | webcolors==24.6.0
26 | websockets==12.0
27 | xlrd==2.0.1
28 | zstandard==0.23.0
29 |
--------------------------------------------------------------------------------
/requirements_win.txt:
--------------------------------------------------------------------------------
1 | boto3==1.34.144
2 | fastapi==0.111.1
3 | fiona==1.9.6
4 | fqdn==1.5.1
5 | geopy==2.4.1
6 | gevent==24.2.1
7 | gtfs-kit==6.1.0
8 | httptools==0.6.1
9 | ipywidgets==8.1.3
10 | isoduration==20.11.0
11 | jsonpointer==3.0.0
12 | networkx==3.3
13 | notebook==6.5.7
14 | numba==0.60.0
15 | openmatrix==0.3.5.0
16 | openpyxl==3.1.5
17 | orjson==3.10.6
18 | pip-chill==1.0.3
19 | python-dotenv==1.0.1
20 | rasterio==1.3.10
21 | s3fs==0.4.2
22 | scikit-learn==1.5.1
23 | seaborn==0.13.2
24 | tqdm==4.66.4
25 | ujson==5.10.0
26 | uri-template==1.3.0
27 | watchfiles==0.22.0
28 | webcolors==24.6.0
29 | websockets==12.0
30 | xlrd==2.0.1
31 | zstandard==0.23.0
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 |
3 | // "python.pythonPath": "${workspaceFolder}/.venv/bin/python3.8",
4 | "python.pythonPath": "${QUETZAL_ENV}/python.exe",
5 | "python.venvPath": "${QUETZAL_ENV}",
6 | "python.jediEnabled": true,
7 | "python.workspaceSymbols.tagFilePath": "${workspaceFolder}/.vscode/tags",
8 | "python.workspaceSymbols.enabled": true,
9 | "python.linting.pylintEnabled": false,
10 | "python.linting.flake8Enabled": true,
11 | "python.linting.mypyArgs": [
12 | "--ignore-missing-imports",
13 | "--follow-imports=silent",
14 | "--disable=W503"
15 | ],
16 | "python.linting.enabled": true,
17 | }
--------------------------------------------------------------------------------
/docs/source/quetzal.io.gtfs_reader.rst:
--------------------------------------------------------------------------------
1 | quetzal.io.gtfs\_reader package
2 | ===============================
3 |
4 | Submodules
5 | ----------
6 |
7 | .. toctree::
8 | :maxdepth: 4
9 |
10 | quetzal.io.gtfs_reader.directions
11 | quetzal.io.gtfs_reader.feed_gtfsk
12 | quetzal.io.gtfs_reader.filtering
13 | quetzal.io.gtfs_reader.frequencies
14 | quetzal.io.gtfs_reader.gtfs_importer
15 | quetzal.io.gtfs_reader.importer
16 | quetzal.io.gtfs_reader.patterns
17 | quetzal.io.gtfs_reader.services
18 |
19 | Module contents
20 | ---------------
21 |
22 | .. automodule:: quetzal.io.gtfs_reader
23 | :members:
24 | :undoc-members:
25 | :show-inheritance:
26 |
--------------------------------------------------------------------------------
/docs/source/quetzal.model.rst:
--------------------------------------------------------------------------------
1 | quetzal.model package
2 | =====================
3 |
4 | Submodules
5 | ----------
6 |
7 | .. toctree::
8 |
9 | quetzal.model.analysismodel
10 | quetzal.model.cubemodel
11 | quetzal.model.docmodel
12 | quetzal.model.integritymodel
13 | quetzal.model.model
14 | quetzal.model.preparationmodel
15 | quetzal.model.stepmodel
16 | quetzal.model.transportmodel
17 | quetzal.model.connectionscanmodel
18 | quetzal.model.timeexpandedmodel
19 | quetzal.model.parkridemodel
20 |
21 | Module contents
22 | ---------------
23 |
24 | .. automodule:: quetzal.model
25 | :members:
26 | :undoc-members:
27 | :show-inheritance:
28 |
--------------------------------------------------------------------------------
/quetzal/engine/msa_trackers/tracker.py:
--------------------------------------------------------------------------------
1 | import abc
2 | from typing import List
3 |
4 |
5 | # abstract class to create trackers
6 | class Tracker(abc.ABC):
7 | @abc.abstractmethod
8 | def __init__(self, track_links_list: List):
9 | pass
10 |
11 | @abc.abstractmethod
12 | def init(self, links_sparse_index, links_to_sparse):
13 | pass
14 |
15 | @abc.abstractmethod
16 | def __call__(self) -> bool:
17 | pass
18 |
19 | @abc.abstractmethod
20 | def assign(self, ab_volumes, odv, pred, seg, it):
21 | pass
22 |
23 | @abc.abstractmethod
24 | def add_weights(self, phi, beta, relgap, it):
25 | pass
26 |
27 | @abc.abstractmethod
28 | def merge(self):
29 | pass
30 |
--------------------------------------------------------------------------------
/windows-install.bat:
--------------------------------------------------------------------------------
1 | @echo on
2 | cd "%~dp0"
3 |
4 | call set SSL_NO_VERIFY=1
5 | call conda config --set ssl_verify false
6 |
7 | SET /P env_name=enter an environment name (default = quetzal_env):
8 | IF NOT DEFINED env_name SET "env_name=quetzal_env"
9 |
10 | if not "X%CONDA_DEFAULT_ENV%" == "X%env_name%" (
11 | conda info -e | findstr %env_name% > NUL
12 | if errorlevel 1 (
13 | call conda create -n %env_name% -y python=3.12
14 | timeout 3 /nobreak > NUL
15 | )
16 | call activate %env_name%
17 | )
18 |
19 | @echo on
20 | echo Installing...
21 | call python -m pip install -e . -r requirements_win.txt --trusted-host pypi.org --trusted-host files.pythonhosted.org
22 |
23 | call python -m ipykernel install --user --name=%env_name%
24 |
25 | echo Done!
26 | @pause
--------------------------------------------------------------------------------
/quetzal/description.txt:
--------------------------------------------------------------------------------
1 | Quetzal est une librairie python développée au sein de SYSTRA permettant
2 | la réalisation intégrale d’un modèle multimodal à 4 étapes, l’analyse des
3 | lignes de désir, la génération automatique d’indicateurs d’offre
4 | et de demande (fréquentation des lignes et des stations,
5 | report modal au niveau du zonage du modèle, comparaison des temps VP et TC)
6 | ainsi que la réalisation d’une analyse coût-bénéfice. Cette librairie Python,
7 | compatible avec nos outils Linedraft et ITSIM,
8 | est également adossé à un logiciel libre de SIG pour la visualisation
9 | des différents indicateurs.
10 |
11 |
12 | .. figure:: ./pictures/quetzal/graphviz.png
13 | :width: 100%
14 | :alt: alternate text
15 | :figclass: align-center
16 |
17 | quetzal
18 |
--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------
1 | [tool.poetry]
2 | name = "quetzal"
3 | version = "1.0.0"
4 | description = "modeling library for transport planning"
5 | authors = ["Quentin Chasserieau = nodes if nodes else True
13 | bool_links = row['pt_path'] >= links if links else True
14 | return bool_nodes & bool_links
15 |
16 |
17 | def checkpoint_demand(
18 | od_stack,
19 | link_checkpoints,
20 | node_checkpoints,
21 | volume_columns=['volume'],
22 | suffixe=''
23 | ):
24 | df = od_stack.copy()
25 | df['select_bool'] = df.apply(
26 | lambda r: select(r, link_checkpoints, node_checkpoints),
27 | axis=1
28 | )
29 | for column in volume_columns:
30 | df[column + suffixe] = df[column] * df['select_bool']
31 | return df
32 |
--------------------------------------------------------------------------------
/tests/data/jsons/jsons.json:
--------------------------------------------------------------------------------
1 | {"index":{"0":"broken_sequences","1":"circular_lines","2":"debug","3":"parameters","4":"walk_on_road"},"json":{"0":"[\"AAMV_bis\"]","1":"[\"AAMV\"]","2":"true","3":"{\"step_distribution\": {\"args\": [], \"kwargs\": {}}, \"step_ntlegs\": {\"args\": [], \"kwargs\": {\"n_ntlegs\": 5, \"short_leg_speed\": 2, \"long_leg_speed\": 10, \"threshold\": 1000, \"max_ntleg_length\": 100000}}, \"step_footpaths\": {\"args\": [], \"kwargs\": {\"speed\": 1}}, \"step_pathfinder\": {\"args\": [], \"kwargs\": {}}, \"step_assignment\": {\"args\": [], \"kwargs\": {\"volume_column\": \"volume_pt\", \"boardings\": true, \"alightings\": true, \"transfers\": true}}, \"checkpoints\": {\"args\": [], \"kwargs\": {\"link_checkpoints\": [], \"node_checkpoints\": [\"BULLFROG\"], \"volume_column\": \"volume_pt\"}}, \"to_hdf\": {\"args\": [\"..\/..\/quetzal\/inputs\/sample-feed\/hdf\/quetzal.hdf\"], \"kwargs\": {}}, \"to_json\": {\"args\": [\"..\/..\/quetzal\/inputs\/sample-feed\/jsons\"], \"kwargs\": {}}}","4":"false"}}
--------------------------------------------------------------------------------
/quetzal/io/md.py:
--------------------------------------------------------------------------------
1 | class MDFILE():
2 | def __init__(self):
3 | self.content=''''''
4 | def __repr__(self):
5 | return self.content
6 |
7 | def newline(self, n:int=1):
8 | self.content += n*'\n'
9 |
10 | def add_text(self, string:str):
11 | self.newline()
12 | self.content += string
13 |
14 | def add_header(self, string:str, level:int=1):
15 | self.newline()
16 | formated_string = level*'#' + ' '+ string
17 | self.content += formated_string
18 |
19 | def add_image(self, path:str, text:str='alt text'):
20 | self.newline(2)
21 | self.content += f''
22 |
23 | def load(self, file_path:str='sample.md'):
24 | with open(file_path, 'r') as mdfile:
25 | self.content = mdfile.read()
26 |
27 | def write(self, file_path:str='sample.md'):
28 | # Write the string to the markdown file
29 | with open(file_path, 'w') as mdfile:
30 | mdfile.write(self.content)
--------------------------------------------------------------------------------
/syspy/io/geojson_utils.py:
--------------------------------------------------------------------------------
1 | import json
2 | import os
3 |
4 | import geopandas as gpd
5 |
6 | default_crs_string = "urn:ogc:def:crs:EPSG::2154"
7 | default_prj_file = "../syspy_utils/gis_resources/epsg2154.prj"
8 |
9 |
10 | def set_geojson_crs(file, crs_string=default_crs_string, encoding='utf-8'):
11 | with open(file, 'r', encoding=encoding) as infile:
12 | data = json.load(infile)
13 | infile.close()
14 | with open(file, 'w', encoding=encoding) as outfile:
15 | data['crs'] = {"type": "name", "properties": {"name": crs_string}}
16 | json.dump(data, outfile)
17 |
18 |
19 | def set_shp_crs(file, prj_file=default_prj_file):
20 | file_without_extension = file.split('.shp')[0]
21 | copyfile(prj_file, file_without_extension + r'.prj')
22 |
23 |
24 | def gdf_to_geojson(gdf, filename, crs_string=default_crs_string, encoding='utf-8'):
25 | try:
26 | os.remove(filename)
27 | except OSError:
28 | pass
29 | gdf.to_file(filename, driver='GeoJSON', encoding=encoding)
30 | set_geojson_crs(filename, crs_string, encoding=encoding)
31 |
--------------------------------------------------------------------------------
/quetzal/io/cube/cube.py:
--------------------------------------------------------------------------------
1 | def head_string(links, trip_id):
2 | return 'LINE NAME="%s", ONEWAY=T, ' % trip_id
3 |
4 |
5 | def stop_and_node_string(links, trip_id):
6 | line = links.loc[links['trip_id'] == trip_id]
7 |
8 | dicts = []
9 | for nodes in list(line['road_node_list']):
10 | dicts.append({'nodes': nodes[1:-1], 'stop': nodes[-1]})
11 |
12 | s = 'N=%s' % (str(line['road_a'].iloc[0]))
13 | for chunk in dicts:
14 | for node in chunk['nodes']:
15 | s += ', ' + '-' + str(node)
16 | s += ', ' + str(chunk['stop'])
17 | return s
18 |
19 |
20 | def lin_string(links, trip_id, custom_head=head_string):
21 | return custom_head(links, trip_id) + stop_and_node_string(links, trip_id)
22 |
23 |
24 | class cubeModel():
25 | def __init__(self):
26 | pass
27 |
28 |
29 | def to_lin(self, path_or_buf):
30 | lines = set(self.links['trip_id'])
31 | lin = ''
32 | for trip_id in lines:
33 | lin += lin_string(self.links, trip_id)
34 | lin += ' \n'
35 |
36 | with open(path_or_buf, 'w') as file:
37 | file.write(lin)
38 |
--------------------------------------------------------------------------------
/api/ML_MatrixRoadCaster/README.md:
--------------------------------------------------------------------------------
1 |
2 | # quetzal
3 | ## Copyright
4 | (c) SYSTRA
5 | ## License
6 | [CeCILL-B](LICENSE.md)
7 | ## Deploy
8 | ```bash
9 | ./update-lambda.sh
10 | ```
11 | ## TEST
12 |
13 | 1) create a test.env file at the root of this folder (with the DockerFile)
14 | ```bash
15 | AWS_ACCESS_KEY_ID=[your access key]
16 | AWS_SECRET_ACCESS_KEY=[your secret key]
17 | AWS_REGION=ca-central
18 | BUCKET_NAME=quetzal-api-bucket
19 | AWS_LAMBDA_FUNCTION_MEMORY_SIZE=3000
20 | ```
21 | 2) Buld the Docker from quetzal root directory (not this one)
22 | ```bash
23 | docker build -f api/ML_MatrixRoadCaster/Dockerfile -t ml_matrixroadcaster:latest .
24 | ```
25 | 3) run the docker with the environment variable
26 | ```bash
27 | docker run -p 9000:8080 --env-file 'api/ML_MatrixRoadCaster/test.env' ml_matrixroadcaster
28 | ```
29 | 4) from another terminal window:
30 | ```bash
31 | curl -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{"callID":"test"}'
32 | ```
33 | CallId correspond to a folder on the s3 Bucket matrixroadcaster. you need to add road_links.geojson and road_nodes.geojson first. if there is no here_OD.csv. the here api will be call and you need to provide your apikey il the XPOST payload (ex: {"callID":"test","hereApiKey":"THIS-IS-AN-API-KEY"})
--------------------------------------------------------------------------------
/syspy/syspy_utils/assignment.py:
--------------------------------------------------------------------------------
1 | __author__ = 'qchasserieau'
2 |
3 | import itertools
4 |
5 | import pandas as pd
6 |
7 |
8 | def nested_list(volume_array, paths):
9 | return [[volume_array[i]] * len(paths[i]) for i in range(len(volume_array))]
10 |
11 |
12 | def assign(volume_array, paths):
13 | nested_row_indices = [[i] * len(paths[i]) for i in range(len(volume_array))]
14 | row_indices = list(itertools.chain.from_iterable(nested_row_indices))
15 | column_indices = list(itertools.chain.from_iterable(paths))
16 | nested_volumes = nested_list(volume_array, paths)
17 | volumes = list(itertools.chain.from_iterable(nested_volumes))
18 | try:
19 | test = volumes[0][0] # volumes_array is an ndarray
20 | sparse = pd.concat(
21 | (
22 | pd.DataFrame(
23 | {
24 | 'od': row_indices,
25 | 'link': column_indices
26 | }
27 | ),
28 | pd.DataFrame(volumes)
29 | ),
30 | axis=1
31 | )
32 | except IndexError: # volume_array is actually a 1d vector
33 | sparse = (pd.DataFrame({'od': row_indices, 'link': column_indices, 'volume': volumes}))
34 | return sparse.drop('od', axis=1).groupby('link').sum()
35 |
--------------------------------------------------------------------------------
/quetzal/engine/parallelization.py:
--------------------------------------------------------------------------------
1 | from concurrent.futures import ProcessPoolExecutor
2 |
3 | from tqdm import tqdm
4 |
5 |
6 | def map_kwargs(func, iterables=[], show_progress=False, **kwargs):
7 | return [
8 | func(arg, **kwargs)
9 | for arg in (tqdm(iterables) if show_progress else iterables)
10 | ]
11 |
12 |
13 | def parallel_map_kwargs(func, iterables, workers=1, **kwargs):
14 | if workers == 1:
15 | return map_kwargs(func, iterables, **kwargs)
16 |
17 | chunk_size = len(iterables) // workers
18 | if len(iterables) % workers > 0:
19 | chunk_size += 1
20 |
21 | results = []
22 | with ProcessPoolExecutor(max_workers=workers) as executor:
23 | for i in range(workers):
24 | results.append(
25 | executor.submit(
26 | map_kwargs,
27 | func,
28 | iterables[i * chunk_size:(i + 1) * chunk_size],
29 | **kwargs
30 | )
31 | )
32 |
33 | to_return = []
34 | for i in range(len(results)):
35 | r = results.pop(0)
36 | try:
37 | to_return += r.result()
38 | except TypeError: # 'NoneType' object is not subscriptable
39 | print('error')
40 | pass
41 | del r
42 | return to_return
43 |
--------------------------------------------------------------------------------
/syspy/syspy_utils/daycount.py:
--------------------------------------------------------------------------------
1 | def count_by_weekday(start_date, end_date):
2 | """
3 | returns a list of length 7 with the number of occurrences of each day over a given period
4 |
5 | :param start_date: first day of the period
6 | :type start_date: datetime.datetime
7 | :param end_date: first day after the period
8 | :type end_date: datetime.datetime
9 | :return: inner_count_by_weekday
10 | :rtype: list
11 | """
12 | delta = end_date - start_date
13 | inner_count_by_weekday = [delta.days // 7] * 7
14 |
15 | for i in range(delta.days % 7):
16 | inner_count_by_weekday[(start_date.weekday() + i) % 7] += 1
17 | return inner_count_by_weekday
18 |
19 |
20 | def count_from_mask(start_date, end_date, mask=(1, 1, 1, 1, 1, 1, 1)):
21 | """
22 | returns the number of days in a period that are consistent with the provided mask
23 |
24 | :param start_date: first day of the period
25 | :type start_date: datetime.datetime
26 | :param end_date: first day after the period
27 | :type end_date: datetime.datetime
28 | :param mask: boolean list of length 7 that states wich weekday should be taken into account
29 | :type mask: list
30 | :return: count
31 | :rtype: int
32 | """
33 | inner_count_by_weekday = count_by_weekday(start_date, end_date)
34 | count = 0
35 | for i in range(7):
36 | count += mask[i] * inner_count_by_weekday[i]
37 | return count
38 |
--------------------------------------------------------------------------------
/syspy/spatial/utils.py:
--------------------------------------------------------------------------------
1 | import math
2 | def haversine(coord1: object, coord2: object)->float:
3 | # Coordinates in decimal degrees (e.g. 2.89078, 12.79797)
4 | lat1, lon1 = coord1
5 | lat2, lon2 = coord2
6 |
7 | R = 6371000 # radius of Earth in meters
8 | phi_1 = math.radians(lat1)
9 | phi_2 = math.radians(lat2)
10 |
11 | delta_phi = math.radians(lat2 - lat1)
12 | delta_lambda = math.radians(lon2 - lon1)
13 |
14 | a = math.sin(delta_phi / 2.0) ** 2 + math.cos(phi_1) * math.cos(phi_2) * math.sin(delta_lambda / 2.0) ** 2
15 |
16 | c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
17 |
18 | meters = R * c # output distance in meters
19 |
20 | return meters
21 |
22 | def get_acf_distance(x:list,reverse:bool=False)->list:
23 | # return dist in meters between 2 points in CRS 4326 (degs)
24 | # inputs : [(lat,lon), (lat,lon)]. or [(y,x),(y,x)]
25 | # if reverse : [(lon,lat), (lon,lat)]. or [(x,y),(x,y)]
26 | # ex: df['geometry'].apply(lambda x: get_acf_distance([x.coords[0],x.coords[-1]],True))
27 | if reverse:
28 | return haversine(x[0][::-1],x[1][::-1])
29 | else:
30 | return haversine(x[0],x[1])
31 |
32 |
33 | def get_epsg(lat: float, lon: float) -> int:
34 | '''
35 | lat, lon or y, x
36 | return EPSG in meter for a given (lat,lon)
37 | lat is north south
38 | lon is est west
39 | '''
40 | return int(32700 - round((45 + lat) / 90, 0) * 100 + round((183 + lon) / 6, 0))
--------------------------------------------------------------------------------
/syspy/io/pandasdbf/exceltodbf_qc.py:
--------------------------------------------------------------------------------
1 | import os.path
2 |
3 | import xlrd
4 | from syspy.io.pandasdbf import dbf_qc as dbf
5 |
6 | _encoding = 'cp850'
7 |
8 |
9 | def convert_value(value, encoding=_encoding):
10 | if isinstance(value, str):
11 | return value.encode(_encoding, 'replace')
12 | elif isinstance(value, float) and value % 1 == 0:
13 | return int(value)
14 | else:
15 | return value
16 |
17 |
18 | class exceltodbf:
19 | def __init__(self, infile, outfile, encoding=_encoding):
20 | import tkinter as Tkinter
21 | self.infile = infile
22 | self.wb = xlrd.open_workbook(infile)
23 | self.sheet_names = self.wb.sheet_names()
24 | self.mainWin = Tkinter.Tk()
25 | self.selectedSheet = Tkinter.StringVar(self.mainWin)
26 | self.selectedSheet.set(self.sheet_names[0])
27 | self.encoding = encoding
28 | self.convert(outfile)
29 |
30 | def convert(self, outfile, event=None):
31 | if os.path.isfile(outfile):
32 | os.remove(outfile)
33 |
34 | sheet = self.wb.sheet_by_name(self.selectedSheet.get())
35 | fieldnames = [str(sheet.cell_value(0, col)) for col in range(sheet.ncols)]
36 | data = [[convert_value(sheet.cell_value(row, col), self.encoding) for col in range(sheet.ncols)] for row in range(1, sheet.nrows)]
37 | dbf.dbfwriter(outfile, fieldnames, data)
38 | self.exit()
39 |
40 | def exit(self):
41 | self.mainWin.destroy()
42 |
--------------------------------------------------------------------------------
/quetzal/engine/screenlines.py:
--------------------------------------------------------------------------------
1 | import pandas as pd
2 | from syspy.spatial import spatial
3 | from syspy.spatial.geometries import b_crosses_a_to_the_left
4 |
5 |
6 | def direct(row):
7 | direct = b_crosses_a_to_the_left(
8 | row['geometry_screen'],
9 | row['geometry_link']
10 | )
11 | return direct
12 |
13 |
14 | def intersection_flows(screens, links, flow_column, **nearest_geometry_kwargs):
15 | screens = screens[['geometry']].copy()
16 | links = links[['geometry', flow_column]].copy()
17 |
18 | cross = spatial.nearest_geometry(screens, links, **nearest_geometry_kwargs)
19 | cross = cross[cross['actual_distance'] == 0].copy()
20 |
21 | cross = pd.merge(cross, screens, left_on='ix_one', right_index=True)
22 | cross = pd.merge(cross, links, left_on='ix_many',
23 | right_index=True, suffixes=['_screen', '_link'])
24 |
25 | cross['direct'] = cross.apply(direct, axis=1)
26 | cross = cross.loc[cross['direct'] is True]
27 | cross.rename(columns={'ix_one': 'screen', 'ix_many': 'link'}, inplace=True)
28 | return cross[['screen', 'link', flow_column]]
29 |
30 |
31 | def intersection_flow(screens, links, flow_column, **kwargs):
32 | flows = intersection_flows(screens, links, flow_column, **kwargs)
33 | flow = pd.merge(
34 | flows.groupby('screen')[[flow_column]].sum(),
35 | screens[[flow_column]],
36 | left_index=True,
37 | right_index=True,
38 | suffixes=['_link', '_screen']
39 | )
40 | flow['screen'] = flow.index
41 | return flow
42 |
--------------------------------------------------------------------------------
/api/ML_MatrixRoadCaster/update-lambda.sh:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | declare AWS_ECR_REPO_NAME=quetzal-matrixroadcaster-api
5 | declare AWS_LAMBDA_FUNCTION_NAME=quetzal-matrixroadcaster-api
6 | declare FOLDER_NAME=ML_MatrixRoadCaster
7 | declare QUETZAL_ROOT=../..
8 |
9 |
10 | # Prompt user for a tag
11 | last_tag=$(aws ecr describe-images --repository-name $AWS_ECR_REPO_NAME \
12 | --query 'sort_by(imageDetails,& imagePushedAt)[-1].imageTags[0]')
13 |
14 | echo "Enter a docker TAG (last: $last_tag)":
15 | read TAG
16 |
17 | cd $QUETZAL_ROOT
18 | # Build docker image
19 | docker build -f api/$FOLDER_NAME/Dockerfile -t $AWS_ECR_REPO_NAME:$TAG .
20 |
21 | # Connect to AWS ECR
22 | aws_account=$(aws sts get-caller-identity | jq '.Account' | sed 's/"//g')
23 | aws_region=$(aws configure get region)
24 |
25 | aws ecr get-login-password --region $aws_region | docker login --username AWS --password-stdin \
26 | $aws_account.dkr.ecr.$aws_region.amazonaws.com
27 |
28 | #Tag docker
29 | docker tag $AWS_ECR_REPO_NAME:$TAG $aws_account.dkr.ecr.$aws_region.amazonaws.com/$AWS_ECR_REPO_NAME:$TAG
30 |
31 | #Push docker to aws
32 | docker push $aws_account.dkr.ecr.$aws_region.amazonaws.com/$AWS_ECR_REPO_NAME:$TAG
33 |
34 | #update Lambda
35 | aws lambda update-function-code --region $aws_region --function-name $AWS_LAMBDA_FUNCTION_NAME \
36 | --image-uri $aws_account.dkr.ecr.$aws_region.amazonaws.com/$AWS_LAMBDA_FUNCTION_NAME:$TAG > /dev/null
37 |
38 | echo "updating lambda function ..."
39 |
40 | aws lambda wait function-updated --region $aws_region --function-name $AWS_LAMBDA_FUNCTION_NAME
41 |
42 | echo "success"
--------------------------------------------------------------------------------
/api/ML_MatrixRoadCaster/update-lambda-dev.sh:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | declare AWS_ECR_REPO_NAME=quetzal-matrixroadcaster-api-dev
5 | declare AWS_LAMBDA_FUNCTION_NAME=quetzal-matrixroadcaster-api-dev
6 | declare FOLDER_NAME=ML_MatrixRoadCaster
7 | declare QUETZAL_ROOT=../..
8 |
9 |
10 | # Prompt user for a tag
11 | last_tag=$(aws ecr describe-images --repository-name $AWS_ECR_REPO_NAME \
12 | --query 'sort_by(imageDetails,& imagePushedAt)[-1].imageTags[0]')
13 |
14 | echo "Enter a docker TAG (last: $last_tag)":
15 | read TAG
16 |
17 | cd $QUETZAL_ROOT
18 | # Build docker image
19 | docker build -f api/$FOLDER_NAME/Dockerfile -t $AWS_ECR_REPO_NAME:$TAG .
20 |
21 | # Connect to AWS ECR
22 | aws_account=$(aws sts get-caller-identity | jq '.Account' | sed 's/"//g')
23 | aws_region=$(aws configure get region)
24 |
25 | aws ecr get-login-password --region $aws_region | docker login --username AWS --password-stdin \
26 | $aws_account.dkr.ecr.$aws_region.amazonaws.com
27 |
28 | #Tag docker
29 | docker tag $AWS_ECR_REPO_NAME:$TAG $aws_account.dkr.ecr.$aws_region.amazonaws.com/$AWS_ECR_REPO_NAME:$TAG
30 |
31 | #Push docker to aws
32 | docker push $aws_account.dkr.ecr.$aws_region.amazonaws.com/$AWS_ECR_REPO_NAME:$TAG
33 |
34 | #update Lambda
35 | aws lambda update-function-code --region $aws_region --function-name $AWS_LAMBDA_FUNCTION_NAME \
36 | --image-uri $aws_account.dkr.ecr.$aws_region.amazonaws.com/$AWS_LAMBDA_FUNCTION_NAME:$TAG > /dev/null
37 |
38 | echo "updating lambda function ..."
39 |
40 | aws lambda wait function-updated --region $aws_region --function-name $AWS_LAMBDA_FUNCTION_NAME
41 |
42 | echo "success"
--------------------------------------------------------------------------------
/quetzal/engine/msa_trackers/test_tracker.py:
--------------------------------------------------------------------------------
1 | from typing import List, Dict, Union
2 | from quetzal.engine.msa_trackers.tracker import Tracker
3 | from collections import namedtuple
4 |
5 | # need to name the class the same as the namedTuple name for pickle.
6 | TrackedAssign = namedtuple('TrackedAssign', 'ab_volumes odv pred seg it')
7 | TrackedWeight = namedtuple('TrackedWeight', 'iteration phi beta relgap')
8 |
9 |
10 | class TestTracker(Tracker):
11 | def __init__(self, track_links_list: List[str] = []):
12 | self.track_links_list = track_links_list
13 | self.weights = []
14 | self.tracked_mat: List[TrackedAssign] = []
15 |
16 | def init(
17 | self,
18 | links_sparse_index: Union[List[int], List[tuple[int, int]]],
19 | links_to_sparse: Union[Dict[str, int], Dict[str, tuple[int, int]]],
20 | ):
21 | self.links_sparse_index = links_sparse_index
22 | self.links_to_sparse = links_to_sparse
23 | self.sparse_links_list = [*map(links_to_sparse.get, self.track_links_list)]
24 | self.sparse_to_links = {v: k for k, v in links_to_sparse.items()}
25 |
26 | def __call__(self) -> bool: # when calling the instance. check if we track links or no.
27 | return True
28 |
29 | def assign(self, ab_volumes, odv, pred, seg, it):
30 | # just save everything.
31 | self.tracked_mat.append(TrackedAssign(ab_volumes, odv, pred, seg, it))
32 |
33 | def add_weights(self, phi, beta, relgap, it):
34 | self.weights.append(TrackedWeight(iteration=it, phi=phi, beta=beta, relgap=relgap))
35 |
36 | def merge(self):
37 | pass
38 |
--------------------------------------------------------------------------------
/quetzal/engine/park_and_ride_pathfinder.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import pandas as pd
3 | from quetzal.engine import engine
4 | from quetzal.engine.pathfinder_utils import path_and_duration_from_graph
5 |
6 |
7 | class ParkRidePathFinder:
8 | def __init__(self, model, walk_on_road=False):
9 | self.zones = model.zones.copy()
10 | self.links = engine.graph_links(model.links.copy())
11 | self.road_links = model.road_links
12 | self.pr_nodes = set(model.nodes.loc[model.nodes['parking_spots'].astype(bool)].index)
13 | self.road_to_transit = model.road_to_transit.loc[
14 | model.road_to_transit['b'].isin(self.pr_nodes)]
15 | self.zone_to_road = model.zone_to_road.loc[
16 | model.zone_to_road['direction'] == 'access']
17 | self.transit_to_zone = model.zone_to_transit.loc[
18 | model.zone_to_transit['direction'] != 'access']
19 | self.footpaths = model.footpaths
20 |
21 | def build_graph(self, **kwargs):
22 | self.nx_graph = engine.multimodal_graph(
23 | self.links,
24 | ntlegs=pd.concat([self.zone_to_road, self.transit_to_zone]),
25 | footpaths=pd.concat([self.footpaths, self.road_to_transit, self.road_links]),
26 | pole_set=set(self.zones.index),
27 | **kwargs
28 | )
29 |
30 | def find_best_path(self, cutoff=np.inf, od_set=None, **kwargs):
31 | self.build_graph(**kwargs)
32 | pr_los = path_and_duration_from_graph(
33 | self.nx_graph,
34 | pole_set=set(self.zones.index),
35 | cutoff=cutoff,
36 | od_set=od_set
37 | )
38 |
39 | pr_los['pathfinder_session'] = 'park_and_ride'
40 | pr_los['path'] = [tuple(p) for p in pr_los['path']]
41 | self.paths = pr_los
42 |
--------------------------------------------------------------------------------
/quetzal/launcher/launcher_utils.py:
--------------------------------------------------------------------------------
1 | import os
2 | import time
3 | from subprocess import PIPE, Popen
4 |
5 | import pandas as pd
6 |
7 |
8 | def parallel_call_notebook(
9 | notebook,
10 | arg_list,
11 | stdout_path='log/out.txt',
12 | stderr_path='log/err.txt',
13 | workers=4,
14 | sleep=1,
15 | leave=False,
16 | errout_suffix=False
17 | ):
18 | os.system('jupyter nbconvert --to python %s' % notebook)
19 | file = notebook.replace('.ipynb', '.py')
20 | popens = {}
21 |
22 | for i in range(len(arg_list)):
23 | arg = arg_list[i]
24 | suffix = arg if errout_suffix else ''
25 | suffix += '_' + notebook.split('.')[0]
26 | mode = 'w' if errout_suffix else 'a+'
27 | print(i, arg)
28 | with open(stdout_path.replace('.txt', '_' + suffix + '.txt'), mode) as stdout:
29 | with open(stderr_path.replace('.txt', '_' + suffix + '.txt'), mode) as stderr:
30 | popens[i] = Popen(
31 | ['python', file, arg],
32 | stdout=stdout,
33 | stderr=stderr
34 | )
35 | if (i + 1) % workers == 0 or (i + 1) == len(arg_list):
36 | # print('waiting')
37 | popens[i].wait()
38 | time.sleep(sleep)
39 | if not leave:
40 | os.remove(file)
41 | for i in range(len(arg_list)):
42 | arg = arg_list[i]
43 | suffix = arg if errout_suffix else ''
44 | suffix += '_' + notebook.split('.')[0]
45 | mode = 'r'
46 | with open(stderr_path.replace('.txt', '_' + suffix + '.txt'), mode) as stderr:
47 | content = stderr.read()
48 | if 'Error' in content and "end_of_notebook" not in content:
49 | print("subprocess **{} {}** terminated with an error.".format(i, arg))
50 |
--------------------------------------------------------------------------------
/tests/old_test_engine_od_volume_from_zones.py:
--------------------------------------------------------------------------------
1 | import sys
2 | from unittest import TestCase, skipIf
3 | from unittest.mock import ANY, patch
4 |
5 | import numpy as np
6 | import pandas as pd
7 | from quetzal.engine.engine import od_volume_from_zones
8 |
9 | sys.path.append(r'../syspy')
10 |
11 |
12 | origin_power = np.power
13 |
14 |
15 | @patch('numpy.power')
16 | @patch('syspy.distribution.distribution.CalcDoublyConstrained', autospec=True)
17 | @patch('syspy.skims.skims.euclidean', autospec=True)
18 | @skipIf(True, 'want to skip')
19 | class Test(TestCase):
20 | def test_zones_only_intrazonal(self, skims_euclidean, distribution_CalcDoublyConstrained, spy_power):
21 | spy_power.side_effect = origin_power
22 | values = [[1, 2, 3], [1, 2, 4]]
23 | zones = pd.DataFrame(values, columns=['emission', 'attraction', 'geometry'])
24 | values = [[0.0, 0.0, 0.0], [1.0, 0.0, 157249.38127194397], [0.0, 1.0, 157249.38127194397], [1.0, 1.0, 0.0]]
25 | euclidean_df = pd.DataFrame(values, columns=['origin', 'destination', 'euclidean_distance'])
26 | skims_euclidean.return_value = euclidean_df
27 |
28 | values = [[0.9, 0.1], [0.1, 0.9]]
29 | volume_array = np.array(values)
30 | distribution_CalcDoublyConstrained.return_value = volume_array
31 |
32 | result = od_volume_from_zones(zones)
33 |
34 | expected = pd.DataFrame(
35 | [[0, 0, 0.9], [0, 1, 0.1], [1, 0, 0.1], [1, 1, 0.9]], columns=['origin', 'destination', 'volume']
36 | )
37 |
38 | pd.testing.assert_frame_equal(result, expected)
39 | skims_euclidean.assert_called_once_with(zones, intrazonal=False)
40 | distribution_CalcDoublyConstrained.assert_called_once_with(
41 | zones['emission'].values, zones['attraction'].values, ANY
42 | )
43 | spy_power.assert_called_once_with(ANY, -2)
44 |
--------------------------------------------------------------------------------
/syspy/syspy_utils/documentation_jupyter.py:
--------------------------------------------------------------------------------
1 | __author__ = 'qchasserieau'
2 |
3 | import itertools
4 | import json
5 | import os
6 |
7 |
8 | def list_files(path, patterns):
9 | file_list = [os.path.join(path, file) for file in os.listdir(path) if file.split('.')[-1].lower() in patterns]
10 | subdirectories = [os.path.join(path, dir) for dir in os.listdir(path) if os.path.isdir(os.path.join(path, dir))]
11 | file_list += list(itertools.chain(*[list_files(subdirectory, patterns) for subdirectory in subdirectories]))
12 | return file_list
13 |
14 |
15 | def makedoc(folder=os.getcwd(), doc_file=os.getcwd() + r'/doc.ipynb', old=None):
16 | """
17 | creates a .ipynb that gather all the documentation written in the firt cells of the notebooks of a given folder
18 |
19 | :param folder: the folder that contains the notebooks
20 | :type input_matrix: str
21 | :param doc_file: the file where the markdown cell of documentation will be included in 2nd position
22 | :type doc_file: str
23 | :param old: the classical folder name for old scripts that we do not want to include in the doc.
24 | :type old: str or None
25 |
26 | :return: None
27 | """
28 | files = [f.replace(folder, '') for f in list_files(folder, ['ipynb']) if 'checkpoint' not in f]
29 | text = ''
30 |
31 | for file in files:
32 | if old is None or old not in file:
33 | with open(folder + file, 'r', encoding='utf-8') as n:
34 | j = json.loads(n.read())
35 |
36 | text += '#### ' + file.replace('.ipynb', '') + '\n'
37 | try:
38 | if j['cells'][0]['cell_type'] == 'markdown':
39 | text += ''.join(j['cells'][0]['source'])
40 | text += '\n'
41 | else:
42 | text += '\n'
43 | except IndexError:
44 | print(j, file)
45 |
46 | with open(doc_file, 'r', encoding='utf-8') as d:
47 | jd = json.loads(d.read())
48 | jd['cells'][1]['source'] = text
49 |
50 | with open(doc_file, 'w', encoding='utf-8') as d:
51 | d.write(json.dumps(jd))
52 |
--------------------------------------------------------------------------------
/tests/data/jsons/nodes.geojson:
--------------------------------------------------------------------------------
1 | {
2 | "type": "FeatureCollection",
3 | "features": [
4 | { "type": "Feature", "properties": { "index": "FUR_CREEK_RES", "stop_name": "Furnace Creek Resort (Demo)", "stop_lat": 36.425288, "stop_lon": -117.133162 }, "geometry": { "type": "Point", "coordinates": [ -117.133162, 36.425288 ] } },
5 | { "type": "Feature", "properties": { "index": "BEATTY_AIRPORT", "stop_name": "Nye County Airport (Demo)", "stop_lat": 36.868446, "stop_lon": -116.784582 }, "geometry": { "type": "Point", "coordinates": [ -116.784582, 36.868446 ] } },
6 | { "type": "Feature", "properties": { "index": "BULLFROG", "stop_name": "Bullfrog (Demo)", "stop_lat": 36.88108, "stop_lon": -116.81797 }, "geometry": { "type": "Point", "coordinates": [ -116.81797, 36.88108 ] } },
7 | { "type": "Feature", "properties": { "index": "STAGECOACH", "stop_name": "Stagecoach Hotel & Casino (Demo)", "stop_lat": 36.915682, "stop_lon": -116.751677 }, "geometry": { "type": "Point", "coordinates": [ -116.751677, 36.915682 ] } },
8 | { "type": "Feature", "properties": { "index": "NADAV", "stop_name": "North Ave \/ D Ave N (Demo)", "stop_lat": 36.914893, "stop_lon": -116.76821 }, "geometry": { "type": "Point", "coordinates": [ -116.76821, 36.914893 ] } },
9 | { "type": "Feature", "properties": { "index": "NANAA", "stop_name": "North Ave \/ N A Ave (Demo)", "stop_lat": 36.914944, "stop_lon": -116.761472 }, "geometry": { "type": "Point", "coordinates": [ -116.761472, 36.914944 ] } },
10 | { "type": "Feature", "properties": { "index": "DADAN", "stop_name": "Doing Ave \/ D Ave N (Demo)", "stop_lat": 36.909489, "stop_lon": -116.768242 }, "geometry": { "type": "Point", "coordinates": [ -116.768242, 36.909489 ] } },
11 | { "type": "Feature", "properties": { "index": "EMSI", "stop_name": "E Main St \/ S Irving St (Demo)", "stop_lat": 36.905697, "stop_lon": -116.76218 }, "geometry": { "type": "Point", "coordinates": [ -116.76218, 36.905697 ] } },
12 | { "type": "Feature", "properties": { "index": "AMV", "stop_name": "Amargosa Valley (Demo)", "stop_lat": 36.641496, "stop_lon": -116.40094 }, "geometry": { "type": "Point", "coordinates": [ -116.40094, 36.641496 ] } }
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/quetzal/analysis/cost_benefit_analysis.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import pandas as pd
3 |
4 |
5 | def od_weighted_time_delta(reference_od, scenario_od):
6 | columns = [
7 | 'origin', 'destination', 'volume',
8 | 'volume_pt', 'volume_car', 'volume_walk',
9 | 'duration_car', 'duration_pt'
10 | ]
11 |
12 | ref = reference_od[columns].set_index(['origin', 'destination'])
13 | scen = scenario_od[columns].set_index(['origin', 'destination'])
14 |
15 | constant_pt = np.minimum(ref['volume_pt'], scen['volume_pt'])
16 | constant_car = np.minimum(ref['volume_car'], scen['volume_car'])
17 |
18 | duration_car_to_pt = scen['duration_pt'] - ref['duration_car']
19 | duration_pt_to_car = scen['duration_car'] - ref['duration_pt']
20 | volume_car_to_pt = np.maximum(ref['volume_car'] - scen['volume_car'], 0)
21 | volume_pt_to_car = np.maximum(scen['volume_car'] - ref['volume_car'], 0)
22 |
23 | delta = scen - ref
24 |
25 | weighted_time_delta = pd.DataFrame(
26 | {
27 | 'time_constant_pt': constant_pt * delta['duration_pt'],
28 | 'time_constant_car': constant_car * delta['duration_car'],
29 | 'time_car_to_pt': volume_car_to_pt * duration_car_to_pt,
30 | 'time_pt_to_car': volume_pt_to_car * duration_pt_to_car,
31 | 'volume_pt_to_car': volume_pt_to_car,
32 | 'volume_car_to_pt': volume_car_to_pt,
33 | 'duration_pt_to_car': duration_pt_to_car,
34 | 'duration_car_to_pt': duration_car_to_pt,
35 | 'volume_constant_pt': constant_pt,
36 | 'volume_constant_car': constant_car,
37 | 'duration_car': delta['duration_car'],
38 | 'duration_pt': delta['duration_pt']
39 | }
40 | )
41 | ordered_columns = [
42 | 'volume_constant_pt', 'duration_pt', 'time_constant_pt',
43 | 'volume_constant_car', 'duration_car', 'time_constant_car',
44 | 'volume_car_to_pt', 'duration_car_to_pt', 'time_car_to_pt',
45 | 'volume_pt_to_car', 'duration_pt_to_car', 'time_pt_to_car'
46 | ]
47 | return weighted_time_delta[ordered_columns]
48 |
--------------------------------------------------------------------------------
/syspy/operations/rollingstock_model.py:
--------------------------------------------------------------------------------
1 | import pandas as pd
2 |
3 |
4 | def distribute_load(load, total_capacity_aw2, seating_capacity):
5 | standing_capacity_aw2 = total_capacity_aw2 - seating_capacity
6 | seating = min(load, seating_capacity)
7 | standing = load - seating
8 | standing_density = standing / standing_capacity_aw2 * 4
9 | return pd.Series({'seating': seating, 'standing_density': standing_density})
10 |
11 |
12 | def get_dwell_time(boardings, alightings, door_time, pax_flow_per_sec, min_dwell_time):
13 | pax_time = (boardings + alightings) / pax_flow_per_sec
14 | return max(pax_time + door_time, min_dwell_time)
15 |
16 |
17 | def compute_capacity(n_seats, aw2_capacity, target_density):
18 | """
19 | Compute RS capacity for target density
20 | """
21 | return (aw2_capacity - n_seats) * target_density / 4 + n_seats
22 |
23 |
24 | class RollingStockUnit():
25 | def __init__(
26 | self, length, weight, max_speed,
27 | n_doors, door_width, door_time, pax_flow,
28 | seats, capacity
29 | ):
30 | self.length, self.weight, self.max_speed = length, weight, max_speed
31 | self.n_doors, self.door_width, self.door_time = n_doors, door_width, door_time
32 | self.pax_flow = pax_flow
33 | self.seats, self.capacity = seats, capacity
34 |
35 | def distribute_load(self, load):
36 | return distribute_load(load, self.capacity, self.seats)
37 |
38 | def get_dwell_time(self, boardings_per_headway, alightings_per_headway, min_dwell_time):
39 | flow = self.n_doors * self.door_width * self.pax_flow
40 | return get_dwell_time(
41 | boardings_per_headway, alightings_per_headway,
42 | self.door_time, flow, min_dwell_time
43 | )
44 |
45 | def compute_capacity(self, target_density):
46 | return compute_capacity(self.seats, self.capacity, target_density)
47 |
48 |
49 | class RollingStock(RollingStockUnit):
50 | def __init__(self, RSUnit, n_units):
51 | super().__init__(**RSUnit.__dict__)
52 | self.n_units = n_units
53 | self.length *= n_units
54 | self.weight *= n_units
55 | self.n_doors *= n_units
56 | self.seats *= n_units
57 | self.capacity *= n_units
58 |
--------------------------------------------------------------------------------
/tests/data/jsons/centroids.geojson:
--------------------------------------------------------------------------------
1 | {
2 | "type": "FeatureCollection",
3 | "features": [
4 | { "type": "Feature", "properties": { "index": "zone_0", "emp": 1, "pop": 1, "emission": 1, "attraction": 1.0, "emission_rate": 0.5, "weight": 2.0 }, "geometry": { "type": "Point", "coordinates": [ -117.008219410085161, 36.520732061318995 ] } },
5 | { "type": "Feature", "properties": { "index": "zone_1", "emp": 1, "pop": 1, "emission": 1, "attraction": 1.0, "emission_rate": 0.5, "weight": 2.0 }, "geometry": { "type": "Point", "coordinates": [ -116.502414125023435, 36.609377818527889 ] } },
6 | { "type": "Feature", "properties": { "index": "zone_2", "emp": 1, "pop": 1, "emission": 1, "attraction": 1.0, "emission_rate": 0.5, "weight": 2.0 }, "geometry": { "type": "Point", "coordinates": [ -116.606318578467878, 36.900788120245544 ] } },
7 | { "type": "Feature", "properties": { "index": "zone_3", "emp": 1, "pop": 1, "emission": 1, "attraction": 1.0, "emission_rate": 0.5, "weight": 2.0 }, "geometry": { "type": "Point", "coordinates": [ -116.991899369597547, 36.833465595595513 ] } },
8 | { "type": "Feature", "properties": { "index": "zone_4", "emp": 1, "pop": 1, "emission": 1, "attraction": 1.0, "emission_rate": 0.5, "weight": 2.0 }, "geometry": { "type": "Point", "coordinates": [ -116.754424779437059, 36.694477962421857 ] } },
9 | { "type": "Feature", "properties": { "index": "zone_5", "emp": 1, "pop": 1, "emission": 1, "attraction": 1.0, "emission_rate": 0.5, "weight": 2.0 }, "geometry": { "type": "Point", "coordinates": [ -116.782658429892734, 36.90350702201232 ] } },
10 | { "type": "Feature", "properties": { "index": "zone_6", "emp": 1, "pop": 1, "emission": 1, "attraction": 1.0, "emission_rate": 0.5, "weight": 2.0 }, "geometry": { "type": "Point", "coordinates": [ -116.739823711156845, 36.878430187917687 ] } },
11 | { "type": "Feature", "properties": { "index": "zone_7", "emp": 1, "pop": 1, "emission": 1, "attraction": 1.0, "emission_rate": 0.5, "weight": 2.0 }, "geometry": { "type": "Point", "coordinates": [ -116.761680016038881, 36.939212979303335 ] } },
12 | { "type": "Feature", "properties": { "index": "zone_8", "emp": 1, "pop": 1, "emission": 1, "attraction": 1.0, "emission_rate": 0.5, "weight": 2.0 }, "geometry": { "type": "Point", "coordinates": [ -116.795984409301923, 36.947733090457625 ] } }
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/syspy/surveys/array_example.py:
--------------------------------------------------------------------------------
1 | import json
2 | import os
3 |
4 | import pandas as pd
5 |
6 |
7 | def build_json():
8 | with open('orthogonal_arrays.txt') as file:
9 | text = file.read()
10 | chunks = text[1:].split('\n\n\n')
11 |
12 | arrays = []
13 |
14 | for chunk in chunks:
15 |
16 | name = chunk.split('\n')[0]
17 |
18 | lines = chunk.split('\n')[1:]
19 | lines = [line.replace(' ', '') for line in lines if line]
20 | array = [[int(char) for char in line] for line in lines]
21 |
22 | exponents = name.split('n')[0]
23 | runs = int(name.split('n=')[-1])
24 |
25 | array_dict = {
26 | 'array': json.dumps(array),
27 | 'runs': runs
28 | }
29 | exp_dict = {}
30 |
31 | for exp_group in exponents.split(' '):
32 | try:
33 | key, exp = exp_group.split('^')
34 | exp_dict[int(key)] = int(exp)
35 | except ValueError: # ValueError
36 | pass
37 | array_dict.update(exp_dict)
38 | array_dict['exponents'] = exp_dict
39 | arrays.append(array_dict)
40 |
41 | base = pd.DataFrame([pd.Series(array) for array in arrays]).fillna(0)
42 | int_columns = sorted([c for c in base.columns if type(c) is int])
43 | string_columns = [c for c in base.columns if type(c) is str]
44 | base[int_columns] = base[int_columns].astype(int)
45 |
46 | base = base[string_columns + int_columns]
47 |
48 | base.sort_values(['runs'] + int_columns, inplace=True)
49 | base.reset_index(inplace=True, drop=True)
50 | base['len'] = base['array'].apply(lambda s: len(json.loads(s)))
51 | base['error'] = (base['len'] - base['runs'])
52 |
53 | with open('orthogonal_arrays.json', 'w') as file:
54 | file.write(base.to_json(orient='records'))
55 |
56 |
57 | def try_int(s):
58 | try:
59 | return int(s)
60 | except ValueError:
61 | return s
62 |
63 |
64 | def main():
65 | dir_path = os.path.dirname(os.path.realpath(__file__))
66 | global base
67 | with open(dir_path + r'/orthogonal_arrays.json', 'r') as file:
68 | base = pd.read_json(file.read())
69 |
70 | base['exponents'] = base['exponents'].apply(
71 | lambda d: {int(k): v for k, v in d.items()}
72 | )
73 | base.columns = [try_int(c) for c in base.columns]
74 |
75 |
76 | main()
77 |
--------------------------------------------------------------------------------
/api/ML_MatrixRoadCaster/s3_utils.py:
--------------------------------------------------------------------------------
1 | import os
2 | from io import BytesIO, StringIO
3 | import json
4 | import numpy as np
5 | import pandas as pd
6 | import geopandas as gpd
7 | import boto3
8 |
9 | class NpEncoder(json.JSONEncoder):
10 | def default(self, obj):
11 | if isinstance(obj, np.integer):
12 | return int(obj)
13 | if isinstance(obj, np.floating):
14 | return float(obj)
15 | if isinstance(obj, np.ndarray):
16 | return obj.tolist()
17 | if isinstance(obj, np.nan):
18 | return None
19 | return super(NpEncoder, self).default(obj)
20 |
21 |
22 | class DataBase:
23 | def __init__(self):
24 | print('init db')
25 | self.BUCKET = os.environ['BUCKET_NAME']
26 | self.s3_resource = boto3.resource('s3')
27 | self.s3 = boto3.client('s3')
28 |
29 | def read_geojson(self, uuid, name):
30 | path = uuid + '/' + name
31 | result = self.s3.get_object(Bucket=self.BUCKET, Key=path)
32 | dict = json.load(result["Body"])
33 | return gpd.read_file(json.dumps(dict))
34 |
35 |
36 |
37 | def read_csv(self, uuid, name):
38 | path = uuid + '/' + name
39 | obj = self.s3.get_object(Bucket=self.BUCKET, Key=path)
40 | return pd.read_csv(BytesIO(obj['Body'].read()))
41 |
42 | def save_csv(self, uuid, name, payload):
43 | '''
44 | parameters
45 | ----------
46 | payload: pandas df to send to s3 as csv.
47 | name: name of the file (with .csv at the end)
48 | returns
49 | ----------
50 | '''
51 | csv_buffer = StringIO()
52 | payload.to_csv(csv_buffer)
53 |
54 | filename = uuid + '/' + name
55 | self.s3_resource.Object(self.BUCKET, filename).put(Body=csv_buffer.getvalue())
56 |
57 | def save_image(self, uuid, name, img_buffer):
58 | '''
59 | parameters
60 | ----------
61 | payload: pandas df to send to s3 as csv.
62 | name: name of the file (with .csv at the end)
63 | returns
64 | ----------
65 | '''
66 | img_buffer.seek(0)
67 | bucket = self.s3_resource.Bucket(self.BUCKET)
68 | filename = uuid + '/' + name
69 | bucket.put_object(Body=img_buffer, ContentType='image/png', Key=filename)
70 |
71 |
--------------------------------------------------------------------------------
/quetzal/engine/optimal_strategy.py:
--------------------------------------------------------------------------------
1 | import bisect
2 | import heapq
3 |
4 |
5 | def find_optimal_strategy(edges, destination, inf=1e9):
6 | zero = 1 / inf
7 |
8 | # set of all nodes
9 | nodes = set.union(*[{i, j} for ix, i, j, f, c in edges])
10 |
11 | # create index in order to access edges by j
12 | j_edges = {node: [] for node in nodes}
13 | for e in edges:
14 | ix, i, j, f, c = e
15 | j_edges[j].append(e)
16 |
17 | # initialization
18 | j = r = destination
19 | u = {r: 0} # node distance
20 | f = {node: zero for node in nodes}
21 | strategy = list()
22 |
23 | edge_data = {ix: (i, j, fa, ca) for ix, i, j, fa, ca in edges}
24 | heap = [(u[j] + ca, ix) for ix, i, j, fa, ca in j_edges[destination]]
25 | heapq.heapify(heap)
26 | seen = set()
27 |
28 | def get_next_link():
29 | # get first tuple of (distance, ix) tuples
30 | # if ix has not been visited yet
31 | while True:
32 | try:
33 | ix = heapq.heappop(heap)[1]
34 | if ix not in seen:
35 | seen.add(ix)
36 | return ix
37 | except IndexError:
38 | return
39 |
40 | while(len(heap)):
41 | ix = get_next_link()
42 | if ix is None:
43 | break
44 | i, j, fa, ca = edge_data[ix]
45 |
46 | # Update node label
47 | if u.get(i, inf) >= u[j] + ca:
48 | u[i] = (f[i] * u.get(i, inf) + fa * (u[j] + ca)) / (f[i] + fa)
49 | f[i] = f[i] + fa
50 | strategy.append(ix)
51 | for ixa, i, j, fa, ca in j_edges[i]:
52 | heapq.heappush(heap, (u[j] + ca, ixa))
53 | return strategy, u, f
54 |
55 |
56 | def assign_optimal_strategy(sources, edges, u, f):
57 | distance = {
58 | (ix, i, j, fa, ca): u[j] + ca
59 | for ix, i, j, fa, ca in edges
60 | }
61 |
62 | nodes = set.union(*[{i, j} for ix, i, j, f, c in edges])
63 |
64 | node_v = {node: 0 for node in nodes}
65 | node_v.update(sources)
66 | edge_v = {}
67 |
68 | # do for every link a in A, in decreasing order of u[j] + ca
69 | relevant = list(distance.items())
70 | relevant.sort(key=lambda x: x[1])
71 |
72 | while len(relevant):
73 | ix, i, j, fa, ca = relevant.pop()[0]
74 | if node_v[i] > 0:
75 | edge_v[ix] = (fa / f[i]) * node_v[i]
76 | node_v[j] = node_v[j] + edge_v[ix]
77 | return node_v, edge_v
78 |
--------------------------------------------------------------------------------
/syspy/syspy_utils/pandas_utils.py:
--------------------------------------------------------------------------------
1 | import copy
2 | import pandas as pd
3 |
4 |
5 | def df_explode(df, column_to_explode):
6 | """
7 | Take a column with iterable elements, and flatten the iterable to one element
8 | per observation in the output table.
9 | Slow and therefore not adapted to huge df.
10 |
11 | :param df: A dataframe to explod
12 | :type df: pandas.DataFrame
13 | :param column_to_explode:
14 | :type column_to_explode: str
15 | :return: An exploded data frame
16 | :rtype: pandas.DataFrame
17 | """
18 | # Create a list of new observations
19 | new_observations = list()
20 |
21 | # Iterate through existing observations
22 | for row in df.to_dict(orient='records'):
23 | # Take out the exploding iterable
24 | explode_values = row[column_to_explode]
25 | del row[column_to_explode]
26 | # Create a new observation for every entry in the exploding iterable & add all of the other columns
27 | for explode_value in explode_values:
28 | # Deep copy existing observation
29 | new_observation = copy.deepcopy(row)
30 | # Add one (newly flattened) value from exploding iterable
31 | new_observation[column_to_explode] = explode_value
32 | # Add to the list of new observations
33 | new_observations.append(new_observation)
34 | # Create a DataFrame
35 | return_df = pd.DataFrame(new_observations)
36 | # Return
37 | return return_df
38 |
39 |
40 | def groupby_weighted_average(df, groupby, columns, weight):
41 | """
42 | perform a weighted average on specified columns
43 | during a groupby operation
44 |
45 | :param df: A dataframe to group
46 | :type df: pandas.DataFrame
47 | :param groupby: column(s) to groupby
48 | :type groupby: str or list
49 | :param columns: column(s) to average
50 | :type columns: str or list
51 | :param weight: column to use as weight
52 | :type weight: str
53 | :return: A grouped dataframe with averaged columns
54 | :rtype: pandas.DataFrame
55 | """
56 | if not isinstance(columns, list):
57 | columns = [columns]
58 | new_columns = [(c, weight) for c in columns]
59 | df[new_columns] = pd.concat([df[c] * df[weight] for c in columns], axis=1)
60 | grouped = df.groupby(groupby)[new_columns].sum().div(df.groupby(groupby)[weight].sum(), axis=0)
61 | grouped = grouped.rename(columns={(c, w): c for c, w in grouped.columns})
62 | return grouped
63 |
--------------------------------------------------------------------------------
/syspy/syspy_utils/mca_utils.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import pandas as pd
3 |
4 |
5 | def classification(values, classes, ascending=True, bins=None, round_bins=None):
6 | """
7 | Return the array of classes of the values, for the given classes
8 | Inputs:
9 | values: np.array of values to classify
10 | classes: ordered list of classe names
11 | ascending: bool
12 | bins: boundaries of each classes. Automatically computed with equal width if None
13 | round_bins: integer to round the inner boundaries. Not rounded if None
14 |
15 | Outputs:
16 | tuple (np.array of the classes of the values, np.array of bins bounds)
17 |
18 | Example:
19 |
20 | x = np.array([1,2,10])
21 | classes = [1,2,3]
22 | classification(x,classes)
23 | ----
24 | (array([1, 1, 3]), array([ 1. , 4. , 7. , 10.1]))
25 | """
26 | n_classes = len(classes)
27 | if bins is None:
28 | bins = n_classes
29 |
30 | # Create bins
31 | _, bins_bounds = np.histogram(values, bins=bins)
32 | # Force max value in interval
33 | bins_bounds[-1] = bins_bounds[-1] * 1.01
34 |
35 | # Round bins: all but first and last
36 | if round_bins is not None:
37 | temp = np.round(bins_bounds[1:-1], round_bins)
38 | temp = np.append(np.array([bins_bounds[0], bins_bounds[-1]]), temp)
39 | bins_bounds = np.sort(temp)
40 |
41 | # Get values index
42 | if ascending:
43 | index = np.digitize(values, bins_bounds)
44 | # print('index:', index)
45 | return np.array([classes[i - 1] for i in index]), bins_bounds
46 | else:
47 | index = np.digitize(values, bins_bounds)
48 | # print('index:', index)
49 | return np.array([classes[n_classes - i] for i in index]), bins_bounds
50 |
51 |
52 | def basic_scoring(x, classes=[1, 2, 3, 4, 5], methods={}):
53 | """
54 | To apply to a dataframe to get a basic ascending scoring from 1 to 5 with equal intervals.
55 | """
56 | classes, bounds = classification(x, classes)
57 | result_dict = {x.index[i]: classes[i] for i in range(len(classes))}
58 | result_dict.update({'bounds': bounds})
59 | return pd.Series(result_dict)
60 |
61 |
62 | def background_colormap(val):
63 | """
64 | Basic 1 to 5 background colormap for nice dataframe printing or excel export purposes.
65 |
66 | Example:
67 | df.style.applymap(background_colormap)
68 | """
69 | color = ['#FB676D', '#FBA977', '#FEE987', '#B1D584', '#62C073']
70 | return 'background-color: %s' % color[val - 1]
71 |
--------------------------------------------------------------------------------
/quetzal/engine/vdf.py:
--------------------------------------------------------------------------------
1 | from numba import jit
2 | import numpy as np
3 |
4 |
5 | # vdf and vdfd (derivative)
6 |
7 | # Eval strings
8 |
9 | free_flow = 'time'
10 |
11 | default_bpr = 'time * (1 + {alpha} * (flow/capacity)**{beta})'.format(alpha=0.15, beta=4)
12 |
13 | # Python functions
14 |
15 |
16 | def limit_factory(expression: str, limit: float = None):
17 | # add a limit time*limit to an expression function.
18 | # if limit is None. use limit column. else: its a constant (df[time_col] * limit)
19 | def wrapped(df, flow_col, time_col):
20 | expr = expression.replace('flow', flow_col).replace('time', time_col)
21 | res = df.eval(expr)
22 | if limit == None:
23 | return res.clip(upper=df[time_col] * df['limit'])
24 | else:
25 | return res.clip(upper=df[time_col] * limit)
26 |
27 | return wrapped
28 |
29 |
30 | limited_bpr = limit_factory(default_bpr)
31 |
32 |
33 | # Numba functions
34 |
35 |
36 | @jit(nopython=True)
37 | def jit_limited_bpr(mat):
38 | # columns in mat : 'alpha','beta','limit','flow','time','penalty','capacity'
39 | # der return the first derivative (for the find beta...)
40 | jam_time = []
41 | for i in range(mat.shape[0]):
42 | alpha = mat[i, 0]
43 | beta = mat[i, 1]
44 | limit = mat[i, 2]
45 | V = mat[i, 3]
46 | t0 = mat[i, 4]
47 | penalty = mat[i, 5]
48 | Q = mat[i, 6]
49 | res = t0 * (1 + alpha * np.power(V / Q, beta))
50 | if res > t0 * limit: # we plateau the curve at limit.
51 | jam_time.append(t0 * limit + penalty)
52 | else:
53 | jam_time.append(res + penalty)
54 | return jam_time
55 |
56 |
57 | @jit(nopython=True)
58 | def jit_default_bpr(mat):
59 | # columns in mat : 'alpha','beta','limit','flow','time','penalty','capacity'
60 | # der return the first derivative (for the find beta...)
61 | jam_time = []
62 | for i in range(mat.shape[0]):
63 | alpha = mat[i, 0]
64 | beta = mat[i, 1]
65 | V = mat[i, 3]
66 | t0 = mat[i, 4]
67 | penalty = mat[i, 5]
68 | Q = mat[i, 6]
69 | V0 = mat[i, 7]
70 | V += V0
71 | res = t0 * (1 + alpha * np.power(V / Q, beta))
72 | jam_time.append(res + penalty)
73 | return jam_time
74 |
75 |
76 | @jit(nopython=True)
77 | def jit_free_flow(mat):
78 | # columns in mat : 'alpha','beta','limit','flow','time','penalty','capacity'
79 | # der return the derivative (for the find beta...)
80 | t0 = mat[:, 4]
81 | penalty = mat[:, 5]
82 | return t0 + penalty
83 |
84 | # columns in mat : 'alpha','beta','limit','flow','time','penalty','capacity'
85 | # der return the derivative (for the find beta...)
86 | t0 = mat[:, 4]
87 | return t0 * 0
88 |
--------------------------------------------------------------------------------
/tests/data/jsons/checkpoint_nodes.geojson:
--------------------------------------------------------------------------------
1 | {
2 | "type": "FeatureCollection",
3 | "features": [
4 | { "type": "Feature", "properties": { "index": "FUR_CREEK_RES", "stop_name": "Furnace Creek Resort (Demo)", "stop_desc": 0.0, "stop_lat": 36.425288, "stop_lon": -117.133162, "zone_id": 0.0, "stop_url": 0.0, "volume_pt": 1.846307147203984 }, "geometry": { "type": "Point", "coordinates": [ -117.133162, 36.425288 ] } },
5 | { "type": "Feature", "properties": { "index": "BEATTY_AIRPORT", "stop_name": "Nye County Airport (Demo)", "stop_desc": 0.0, "stop_lat": 36.868446, "stop_lon": -116.784582, "zone_id": 0.0, "stop_url": 0.0, "volume_pt": 0.7469955008400182 }, "geometry": { "type": "Point", "coordinates": [ -116.784582, 36.868446 ] } },
6 | { "type": "Feature", "properties": { "index": "BULLFROG", "stop_name": "Bullfrog (Demo)", "stop_desc": 0.0, "stop_lat": 36.88108, "stop_lon": -116.81797, "zone_id": 0.0, "stop_url": 0.0, "volume_pt": 2.1976134094415394 }, "geometry": { "type": "Point", "coordinates": [ -116.81797, 36.88108 ] } },
7 | { "type": "Feature", "properties": { "index": "STAGECOACH", "stop_name": "Stagecoach Hotel & Casino (Demo)", "stop_desc": 0.0, "stop_lat": 36.915682, "stop_lon": -116.751677, "zone_id": 0.0, "stop_url": 0.0, "volume_pt": 0.15367788940941798 }, "geometry": { "type": "Point", "coordinates": [ -116.751677, 36.915682 ] } },
8 | { "type": "Feature", "properties": { "index": "NADAV", "stop_name": "North Ave \/ D Ave N (Demo)", "stop_desc": 0.0, "stop_lat": 36.914893, "stop_lon": -116.76821, "zone_id": 0.0, "stop_url": 0.0, "volume_pt": 0.0 }, "geometry": { "type": "Point", "coordinates": [ -116.76821, 36.914893 ] } },
9 | { "type": "Feature", "properties": { "index": "NANAA", "stop_name": "North Ave \/ N A Ave (Demo)", "stop_desc": 0.0, "stop_lat": 36.914944, "stop_lon": -116.761472, "zone_id": 0.0, "stop_url": 0.0, "volume_pt": 0.0 }, "geometry": { "type": "Point", "coordinates": [ -116.761472, 36.914944 ] } },
10 | { "type": "Feature", "properties": { "index": "DADAN", "stop_name": "Doing Ave \/ D Ave N (Demo)", "stop_desc": 0.0, "stop_lat": 36.909489, "stop_lon": -116.768242, "zone_id": 0.0, "stop_url": 0.0, "volume_pt": 0.0 }, "geometry": { "type": "Point", "coordinates": [ -116.768242, 36.909489 ] } },
11 | { "type": "Feature", "properties": { "index": "EMSI", "stop_name": "E Main St \/ S Irving St (Demo)", "stop_desc": 0.0, "stop_lat": 36.905697, "stop_lon": -116.76218, "zone_id": 0.0, "stop_url": 0.0, "volume_pt": 0.0 }, "geometry": { "type": "Point", "coordinates": [ -116.76218, 36.905697 ] } },
12 | { "type": "Feature", "properties": { "index": "AMV", "stop_name": "Amargosa Valley (Demo)", "stop_desc": 0.0, "stop_lat": 36.641496, "stop_lon": -116.40094, "zone_id": 0.0, "stop_url": 0.0, "volume_pt": 0.0 }, "geometry": { "type": "Point", "coordinates": [ -116.40094, 36.641496 ] } }
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/syspy/syspy_utils/gtfs_utils.py:
--------------------------------------------------------------------------------
1 | """
2 | This modules provides tools for manipulating gtfs files
3 |
4 | example::
5 |
6 | """
7 |
8 | __author__ = 'mjoly'
9 |
10 | import json
11 |
12 | import pandas as pd
13 |
14 |
15 | def get_patterns(gtfs_dir, direction=True, by_route=True):
16 | stop_times = pd.read_csv(gtfs_dir + 'stop_times.txt')
17 | trips = pd.read_csv(gtfs_dir + 'trips.txt').set_index('trip_id')
18 |
19 | trips_to_patterns = stop_times[['trip_id', 'stop_id']].groupby('trip_id').aggregate(lambda x: (tuple(x)))
20 | trips_to_patterns.rename(columns={'stop_id': 'geo_pattern_links'}, inplace=True)
21 |
22 | trips_to_patterns['reversed_geo_pattern_links'] = trips_to_patterns.apply(lambda r: tuple(reversed(r['geo_pattern_links'])), axis=1)
23 | trips_to_patterns['route_id'] = trips['route_id']
24 |
25 | def pattern_choice(r):
26 | if r['geo_pattern_links'] < r['reversed_geo_pattern_links']:
27 | return r['geo_pattern_links']
28 | else:
29 | return r['reversed_geo_pattern_links']
30 |
31 | if not direction:
32 | trips_to_patterns['chosen_geo_pattern_links'] = trips_to_patterns.apply(lambda r: pattern_choice(r), axis=1)
33 | trips_to_patterns['direction'] = 0
34 | else:
35 | trips_to_patterns['chosen_geo_pattern_links'] = trips_to_patterns['geo_pattern_links']
36 | trips_to_patterns['direction'] = trips_to_patterns.apply(lambda r: 1 + 1 * (r['geo_pattern_links'] < r['reversed_geo_pattern_links']), axis=1)
37 | trips_direction = trips_to_patterns.copy()
38 |
39 | if by_route:
40 | patterns = trips_to_patterns.groupby(['chosen_geo_pattern_links', 'route_id', 'direction']).count().reset_index()
41 | patterns = patterns[['chosen_geo_pattern_links', 'direction', 'route_id']]
42 | patterns.reset_index(inplace=True)
43 | patterns.rename(columns={'index': 'pattern_id'}, inplace=True)
44 | trips_to_patterns = trips_to_patterns.reset_index().merge(patterns, on=['chosen_geo_pattern_links', 'direction', 'route_id'])[['pattern_id', 'trip_id']]
45 | else:
46 | patterns = trips_to_patterns.groupby(['chosen_geo_pattern_links', 'direction']).count().reset_index()
47 | patterns = patterns[['chosen_geo_pattern_links', 'direction']]
48 | patterns.reset_index(inplace=True)
49 | patterns.rename(columns={'index': 'pattern_id'}, inplace=True)
50 | trips_to_patterns = trips_to_patterns.reset_index().merge(patterns, on=['chosen_geo_pattern_links', 'direction'])[['pattern_id', 'trip_id']]
51 |
52 | trips_to_patterns.set_index('trip_id', inplace=True)
53 | patterns.rename(columns={'chosen_geo_pattern_links': 'geo_pattern_links'}, inplace=True)
54 | patterns.set_index('pattern_id', inplace=True)
55 | return trips_to_patterns, patterns, trips_direction
56 |
--------------------------------------------------------------------------------
/quetzal/model/docmodel.py:
--------------------------------------------------------------------------------
1 | import networkx as nx
2 |
3 |
4 | def io_from_doc(doc):
5 | try:
6 | if 'deprecated!' in doc:
7 | return [], []
8 | except TypeError: # argument of type 'NoneType' is not iterable
9 | return [], []
10 |
11 | doc = doc.replace(' ', ' ') # espace insécable
12 |
13 | try:
14 | requirements = doc.split('* requires: ')[1].split('\n')[0]
15 | requirements = [r.strip() for r in requirements.split(',')]
16 | except IndexError:
17 | requirements = []
18 | try:
19 | products = doc.split('* builds: ')[1].split('\n')[0]
20 | products = [r.strip() for r in products.split(',')]
21 | except IndexError:
22 | products = []
23 | return requirements, products
24 |
25 |
26 | def contain_pattern(s, patterns):
27 | for p in patterns:
28 | if p in s:
29 | return True
30 | return False
31 |
32 |
33 | class DocModel:
34 | def __init__(self):
35 | pass
36 |
37 | def io_from_method(self, name):
38 | method = self.__getattribute__(name)
39 | doc = method.__doc__
40 | return io_from_doc(doc)
41 |
42 | def edges_from_method(self, name):
43 | inputs, outputs = self.io_from_method(name)
44 | return [(i, name) for i in inputs] + [(name, o) for o in outputs]
45 |
46 | def dot(self, patterns, header=None):
47 |
48 | header = """
49 | ratio = fill;
50 | node [style=filled, fontname = "calibri", fontsize=24, color="#C8D2B3"];
51 | edge[ fontname = "calibri", fontsize=24];
52 | ranksep = "0.5";
53 | rankdir="HR";
54 | """ if header is None else header
55 |
56 | methods = [m for m in dir(self) if contain_pattern(m, patterns)]
57 | edges = []
58 | for method in methods:
59 | edges += self.edges_from_method(method)
60 |
61 | g = nx.DiGraph()
62 | g.add_edges_from(edges)
63 |
64 | # colors
65 | color = "#AACDDA"
66 | input_color = "#EEC880"
67 | output_color = "#C8D2B3"
68 |
69 | reversed_g = g.reverse()
70 |
71 | for node in list(g.nodes):
72 | if not bool(list(g.predecessors(node))):
73 | g.nodes[node]['color'] = input_color
74 | elif not bool(list(reversed_g.predecessors(node))):
75 | g.nodes[node]['color'] = output_color
76 | else:
77 | g.nodes[node]['color'] = color
78 |
79 | for method in methods:
80 | try:
81 | g.nodes[method]['color'] = '#E89196'
82 | g.nodes[method]['shape'] = 'rectangle'
83 | except KeyError:
84 | pass
85 |
86 | dot = nx.nx_pydot.to_pydot(g)
87 |
88 | return dot.to_string().replace('{', '{' + header)
89 |
--------------------------------------------------------------------------------
/syspy/routing/timetable/csa.py:
--------------------------------------------------------------------------------
1 | __author__ = 'qchasserieau'
2 |
3 | from IPython.display import display
4 | from IPython.html.widgets import FloatProgress
5 | from syspy.syspy_utils import syscolors
6 |
7 |
8 | def csa(_links, start, infinity=999999, connection_time=False, origins=False):
9 | links = _links.copy()
10 | origin_set = set(links['origin']).intersection(set(origins)) if origins else set(links['origin'])
11 | stop_set = set(links['origin']).union(set(links['destination']))
12 |
13 | progress = FloatProgress(min=0, max=len(origin_set), width=975,
14 | height=10, color=syscolors.rainbow_shades[1], margin=5)
15 | progress.value = 1
16 | display(progress)
17 |
18 | links['reachable'] = False
19 | csa_connections = links.to_dict(orient='records')
20 |
21 | earliest_arrival_time_dict = {}
22 | earliest_arrival_link_dict = {}
23 | reachable_connections_dict = {}
24 | reachable_trips_dict = {}
25 |
26 | connection_time = connection_time if connection_time else {s: 0 for s in stop_set}
27 |
28 | print(len(origin_set))
29 | for origin in list(origin_set):
30 | progress.value += 1
31 |
32 | reachable_connections = {l: 0 for l in list(links['index'])}
33 | reachable_trips = {t: 0 for t in list(links['trip_id'])}
34 |
35 | earliest_arrival_time = {s: infinity for s in stop_set}
36 | earliest_arrival_time[origin] = start
37 | earliest_arrival_link = {}
38 |
39 | def is_reachable(label):
40 | r = reachable_trips[label['trip_id']] or \
41 | earliest_arrival_time[label['origin']] + connection_time[label['destination']] \
42 | <= label['departure_time']
43 | return r
44 |
45 | def scan(label):
46 | reachable = is_reachable(label)
47 | reachable_trips[label['trip_id']], reachable_connections[label['index']] = reachable, reachable
48 |
49 | if reachable:
50 | if earliest_arrival_time[label['destination']] > label['arrival_time']:
51 | earliest_arrival_time[label['destination']] = label['arrival_time']
52 | earliest_arrival_link[label['destination']] = label['index']
53 |
54 | for connection in csa_connections:
55 | scan(connection)
56 |
57 | earliest_arrival_time_dict[origin] = earliest_arrival_time
58 | earliest_arrival_link_dict[origin] = earliest_arrival_link
59 | reachable_connections_dict[origin] = reachable_connections
60 | reachable_trips_dict[origin] = reachable_trips
61 |
62 | return{'earliest_arrival_time_dict': earliest_arrival_time_dict,
63 | 'earliest_arrival_link_dict': earliest_arrival_link_dict,
64 | 'reachable_connections_dict': reachable_connections_dict,
65 | 'reachable_trips_dict': reachable_trips}
66 |
--------------------------------------------------------------------------------
/syspy/transitfeed/feed_links.py:
--------------------------------------------------------------------------------
1 | __author__ = 'qchasserieau'
2 |
3 | import pandas as pd
4 |
5 |
6 | def link_from_stop_times(
7 | stop_times,
8 | max_shortcut=False,
9 | stop_id='stop_id',
10 | trip_id='trip_id',
11 | in_sequence='stop_sequence',
12 | out_sequence='link_sequence',
13 | stop_id_origin=False,
14 | stop_id_destination=False,
15 | keep_origin_columns=[],
16 | keep_destination_columns=[]
17 | ):
18 | """
19 | From a set of trips, represented as a table of events (stop time for
20 | example), returns a table of links between these events, given two trips:
21 | a-b-c-d and f-g-h. we should return : ab, bc, cd, fg and gh.
22 |
23 | :param stop_times: DataFrame
24 | :param max_shortcut:
25 | :param stop_id:
26 | :param in_sequence:
27 | :param out_sequence:
28 | :param stop_id_origin:
29 | :param stop_id_destination:
30 | :param keep_origin_columns:
31 | :param keep_destination_columns:
32 | :return:
33 | """
34 | origins = stop_times[[stop_id, trip_id,
35 | in_sequence] + keep_origin_columns].copy()
36 | destinations = stop_times[[stop_id, trip_id,
37 | in_sequence] + keep_destination_columns].copy()
38 | links = []
39 |
40 | max_sequence = stop_times[in_sequence].max()
41 | assert max_sequence
42 | max_shortcut = max_shortcut if max_shortcut and max_shortcut < max_sequence else max_sequence
43 | for i in range(int(max_shortcut)):
44 | origins['next'] = origins[in_sequence] + 1 + i
45 | links.append(pd.merge(origins, destinations,
46 | left_on=[trip_id, 'next'],
47 | right_on=[trip_id, in_sequence],
48 | suffixes=['_origin', '_destination']
49 | ))
50 | stop_id_origin = stop_id_origin if stop_id_origin else stop_id + '_origin'
51 | stop_id_destination = stop_id_destination if stop_id_destination else stop_id + '_destination'
52 |
53 | assert len(links), 'no link to concatenate'
54 | concat = pd.concat(links).rename(
55 | columns={
56 | in_sequence + '_origin': out_sequence,
57 | stop_id + '_origin': stop_id_origin,
58 | stop_id + '_destination': stop_id_destination
59 | }
60 | ).drop([in_sequence + '_destination', 'next'], axis=1)
61 | return concat
62 |
63 |
64 | def clean_sequences(df, sequence='stop_sequence', group_id='trip_id'):
65 | """ Clean the sequence column, drop the index"""
66 | df = df.sort_values([group_id, sequence]).reset_index(drop=True)
67 | sequence_series = df.groupby(group_id).count()[sequence].sort_index()
68 | all_sequences = []
69 | for group_sequences in list(sequence_series):
70 | for seq in range(group_sequences):
71 | all_sequences.append(seq + 1)
72 | df[sequence] = pd.Series(all_sequences)
73 | return df
74 |
--------------------------------------------------------------------------------
/syspy/spatial/geometry_smoothing.py:
--------------------------------------------------------------------------------
1 | # Adapted and simplified from https://github.com/GeographicaGS/GeoSmoothing
2 |
3 | import numpy as np
4 | from scipy.interpolate import splev, splprep
5 | from shapely.geometry import LineString, Polygon
6 |
7 |
8 | class Splines():
9 | def compSplineKnots(self, x, y, s, k, nest=-1):
10 | """
11 | Computed with Scipy splprep. Find the B-spline representation of
12 | an N-dimensional curve.
13 | Spline parameters:
14 | :s - smoothness parameter
15 | :k - spline order
16 | :nest - estimate of number of knots needed (-1 = maximal)
17 | """
18 |
19 | tck_u, fp, ier, msg = splprep([x, y], s=s, k=k, nest=nest, full_output=1)
20 |
21 | if ier > 0:
22 | print("{}. ier={}".format(msg, ier))
23 | return(tck_u, fp)
24 |
25 | def compSplineEv(self, x, tck, zoom=10):
26 | """
27 | Computed with Scipy splev. Given the knots and coefficients of
28 | a B-spline representation, evaluate the value of the smoothing
29 | polynomial and its derivatives
30 | Parameters:
31 | :tck - A tuple (t,c,k) containing the vector of knots,
32 | the B-spline coefficients, and the degree of the spline.
33 | """
34 | n_coords = len(x)
35 | n_len = n_coords * zoom
36 | x_ip, y_ip = splev(np.linspace(0, 1, n_len), tck)
37 |
38 | return(x_ip, y_ip)
39 |
40 |
41 | class GeoSmoothing():
42 | def __init__(self, spl_smpar=0, spl_order=2, verbose=True):
43 | """
44 | spl_smpar: smoothness parameter
45 | spl_order: spline order
46 | """
47 | self.spl_smpar = spl_smpar
48 | self.spl_order = spl_order
49 | self.verbose = verbose
50 |
51 | def get_coordinates(self, geom):
52 | """
53 | Getting x,y coordinates from geometry...
54 | """
55 | if isinstance(geom, LineString):
56 | x = np.array(geom.coords.xy[0])
57 | y = np.array(geom.coords.xy[1])
58 |
59 | elif isinstance(geom, Polygon):
60 | x = np.array(geom.exterior.coords.xy[0])
61 | y = np.array(geom.exterior.coords.xy[1])
62 | return(x, y)
63 |
64 | def geom_from_coords(self, coords_ip, geom):
65 | """
66 | """
67 | if isinstance(geom, LineString):
68 | geom_ip = LineString(coords_ip.T)
69 |
70 | elif isinstance(geom, Polygon):
71 | geom_ip = Polygon(coords_ip.T)
72 | return geom_ip
73 |
74 | def smooth_geom(self, geom):
75 | """
76 | Run smoothing geometries
77 | """
78 | x, y = self.get_coordinates(geom)
79 |
80 | spl = Splines()
81 |
82 | tck_u, fp = spl.compSplineKnots(x, y, self.spl_smpar, self.spl_order)
83 | x_ip, y_ip = spl.compSplineEv(x, tck_u[0])
84 |
85 | coords_ip = np.array([x_ip, y_ip])
86 | return self.geom_from_coords(coords_ip, geom)
87 |
--------------------------------------------------------------------------------
/quetzal/engine/elevation.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import os
3 | from osgeo import gdal
4 | from pathlib import Path
5 | import rasterio
6 | import scipy
7 | from hashlib import sha1
8 |
9 |
10 | def _query_raster_nearest(nodes, filepath, band=1):
11 | """
12 | Query a raster for values at coordinates in a DataFrame's x/y columns.
13 | Parameters
14 | ----------
15 | nodes : pandas.DataFrame
16 | DataFrame indexed by node ID and with two columns: x and y
17 | filepath : string or pathlib.Path
18 | path to the raster file or VRT to query
19 | band : int
20 | which raster band to query
21 | Returns
22 | -------
23 | nodes_values : zip
24 | zipped node IDs and corresponding raster values
25 | """
26 | # must open raster file here: cannot pickle it to pass in multiprocessing
27 | with rasterio.open(filepath) as raster:
28 | values = np.array(tuple(raster.sample(nodes.values, band)), dtype=float).squeeze()
29 | values[values == raster.nodata] = np.nan
30 | return zip(nodes.index, values)
31 |
32 |
33 | def _query_raster_interp(nodes, filepath, band=1, method='linear'):
34 |
35 | with rasterio.open(filepath) as src:
36 | band1 = src.read(band)
37 | height = band1.shape[0]
38 | width = band1.shape[1]
39 | cols, rows = np.meshgrid(np.arange(width), np.arange(height))
40 | xs, ys = rasterio.transform.xy(src.transform, rows, cols)
41 |
42 | lons= np.array(xs)
43 | lats = np.array(ys)
44 | f = scipy.interpolate.interp2d(
45 | lons[0, :],
46 | lats[:, 0],
47 | band1,
48 | kind=method
49 | )
50 |
51 | values = [f(r[0], r[1])[0] for r in nodes.values]
52 | # values = nodes.apply(lambda r: f(r.x, r.y)[0], 1)
53 |
54 | return list(zip(nodes.index, values))
55 |
56 |
57 | def query_raster(nodes, filepath, band=1, method='nearest'):
58 | """
59 | Query a raster for values at coordinates in a DataFrame's x/y columns.
60 | Parameters
61 | ----------
62 | nodes : pandas.DataFrame
63 | DataFrame indexed by node ID and with two columns: x and y
64 | filepath : string or pathlib.Path
65 | path to the raster file or VRT to query
66 | band : int
67 | which raster band to query
68 | Returns
69 | -------
70 | nodes_values : zip
71 | zipped node IDs and corresponding raster values
72 | """
73 | if method=='nearest':
74 | return _query_raster_nearest(nodes, filepath, band)
75 | else:
76 | return _query_raster_interp(nodes, filepath, band, method)
77 |
78 |
79 | def merge_rasters_virtually(filepath):
80 |
81 | if not isinstance(filepath, (str, Path)):
82 | filepaths = [str(p) for p in filepath]
83 | sha = sha1(str(filepaths).encode("utf-8")).hexdigest()
84 | filepath = os.path.join(os.path.dirname(filepaths[0]), f".osmnx_{sha}.vrt")
85 | gdal.BuildVRT(filepath, filepaths).FlushCache()
86 |
87 | return filepath
--------------------------------------------------------------------------------
/syspy/pycube/project.py:
--------------------------------------------------------------------------------
1 | import itertools
2 | import os
3 |
4 | from syspy.pycube.application import Application
5 |
6 |
7 | def multiple_replace(text, word_dict):
8 | for key in word_dict:
9 | text = text.replace(key, word_dict[key])
10 | return text
11 |
12 |
13 | def list_files(path, patterns):
14 | files = [os.path.join(path, file) for file in os.listdir(path) if file.split('.')[-1].lower() in patterns]
15 | subdirectories = [os.path.join(path, dir) for dir in os.listdir(path) if os.path.isdir(os.path.join(path, dir))]
16 | files += list(itertools.chain(*[list_files(subdirectory, patterns) for subdirectory in subdirectories]))
17 | return files
18 |
19 |
20 | def list_apps(path):
21 | apps = [os.path.join(path, app) for app in os.listdir(path) if (app.endswith('.app') or app.endswith('.APP'))]
22 | subdirectories = [os.path.join(path, dir) for dir in os.listdir(path) if os.path.isdir(os.path.join(path, dir))]
23 | apps += list(itertools.chain(*[list_apps(subdirectory) for subdirectory in subdirectories]))
24 | return apps
25 |
26 |
27 | def replace_in_file(filename, old, new):
28 | with open(filename, 'r') as file:
29 | soup = file.read()
30 | count = soup.count(old)
31 | with open(filename, 'w') as file:
32 | file.write(soup.replace(old, new))
33 | return count
34 |
35 |
36 | class Project:
37 | """
38 | Object for processing text, scripts an apps in a cube project, based on top of pycube.application.
39 | """
40 | def __init__(self, catalog_dir):
41 | self.catalog_dir = catalog_dir
42 | self.apps = [Application(app_file) for app_file in list_apps(self.catalog_dir)]
43 | self.cube_generated_text_like_files = list_files(
44 | self.catalog_dir, patterns=['app', 'txt', 's', 'vpr', 'cpl', 'py'])
45 |
46 | def change_catalog_dir(self, old_dir, new_dir='default'):
47 |
48 | """
49 | :param old_dir: current path to the catalog directory as written in the scripts and apps
50 | :type old_dir: str
51 | :param new_dir: new path to the catalog directory to be written in the scripts and apps
52 | :type new_dir: str
53 | :return: None
54 | """
55 | _new_dir = self.catalog_dir if new_dir == 'default' else new_dir
56 | occurrences = 0
57 | for filename in self.cube_generated_text_like_files:
58 | occurrences += replace_in_file(filename, old_dir, _new_dir)
59 |
60 | print(str(occurrences) + ' replacement have been performed ')
61 |
62 | def replace(self, old_string, new_string):
63 |
64 | """
65 | :param old_string: string to replace
66 | :type old_dir: str
67 | :param new_string: new string
68 | :type new_dir: str
69 | :return: None
70 | """
71 | occurrences = 0
72 | for filename in self.cube_generated_text_like_files:
73 | occurrences += replace_in_file(filename, old_string, new_string)
74 |
75 | print(str(occurrences) + ' change(s)')
76 |
--------------------------------------------------------------------------------
/syspy/renumber/renumber.py:
--------------------------------------------------------------------------------
1 | __author__ = 'qchasserieau'
2 |
3 | import pandas as pd
4 | import shapely
5 | from syspy.spatial import spatial
6 |
7 |
8 | def _join_geometry(link_row, one, many):
9 | return shapely.geometry.LineString(
10 | [one['geometry'].loc[link_row['ix_one']], many['geometry'].loc[link_row['ix_many']]])
11 |
12 |
13 | def add_geometry_coordinates(df, columns=['x_geometry', 'y_geometry']):
14 | df[columns[0]] = df['geometry'].apply(lambda g: g.coords[0][0])
15 | df[columns[1]] = df['geometry'].apply(lambda g: g.coords[0][1])
16 | return df
17 |
18 |
19 | def renumber(
20 | zones,
21 | volume,
22 | n_clusters=10,
23 | cluster_column=None,
24 | volume_columns=['volume']
25 | ):
26 | clusters, cluster_series = spatial.zone_clusters(
27 | zones,
28 | n_clusters=n_clusters,
29 | cluster_column=cluster_column
30 | )
31 | grouped = renumber_volume(
32 | volume,
33 | cluster_series,
34 | volume_columns=volume_columns
35 | )
36 | return clusters, grouped, cluster_series
37 |
38 |
39 | def renumber_quetzal(
40 | zones,
41 | volume,
42 | od_stack,
43 | n_clusters=10,
44 | cluster_column=None,
45 | volume_columns=['volume'],
46 | volume_od_columns=['volume_pt'],
47 | distance_columns=['euclidean_distance']
48 | ):
49 | clusters, cluster_series = spatial.zone_clusters(
50 | zones,
51 | n_clusters=n_clusters,
52 | cluster_column=cluster_column
53 | )
54 | grouped = renumber_volume(
55 | volume,
56 | cluster_series,
57 | volume_columns=volume_columns
58 | )
59 | od_stack_grouped = renumber_od_stack(
60 | od_stack,
61 | cluster_series,
62 | volume_od_columns,
63 | distance_columns)
64 | return clusters, grouped, cluster_series, od_stack_grouped
65 |
66 |
67 | def renumber_volume(volume, cluster_series, volume_columns):
68 | proto = pd.merge(volume, pd.DataFrame(cluster_series), left_on='origin', right_index=True)
69 | proto = pd.merge(proto, pd.DataFrame(cluster_series), left_on='destination',
70 | right_index=True, suffixes=['_origin', '_destination'])
71 | grouped = proto.groupby(['cluster_origin', 'cluster_destination'])[volume_columns].sum()
72 | grouped.index.names = ['origin', 'destination']
73 | grouped.reset_index(inplace=True)
74 | return grouped
75 |
76 |
77 | def renumber_od_stack(od_stack, cluster_series, volume_columns, distance_columns):
78 | proto = pd.merge(od_stack, pd.DataFrame(cluster_series), left_on='origin', right_index=True)
79 | proto = pd.merge(proto, pd.DataFrame(cluster_series), left_on='destination',
80 | right_index=True, suffixes=['_origin', '_destination'])
81 | f = {v: 'sum' for v in volume_columns}
82 | f.update({d: 'mean' for d in distance_columns})
83 | grouped = proto.groupby(['cluster_origin', 'cluster_destination']).agg(f)
84 | grouped.index.names = ['origin', 'destination']
85 | grouped = pd.DataFrame(grouped)
86 | grouped.reset_index(inplace=True)
87 | return grouped
88 |
--------------------------------------------------------------------------------
/docs/build/_static/css/badge_only.css:
--------------------------------------------------------------------------------
1 | .fa:before{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}
--------------------------------------------------------------------------------
/syspy/pycube/network.py:
--------------------------------------------------------------------------------
1 | __author__ = 'qchasserieau'
2 |
3 | import pandas as pd
4 | import shapely
5 | from IPython.display import display
6 | from IPython.html.widgets import FloatProgress
7 | from syspy.spatial import spatial
8 | from syspy.syspy_utils import syscolors
9 |
10 |
11 | def zone_stops(zones, nodes, stop_list, leg_type='contains'):
12 |
13 | if leg_type == 'contains':
14 | progress = FloatProgress(
15 | min=0, max=len(list(zones.iterrows())), width=975, height=10, color=syscolors.rainbow_shades[1], margin=5)
16 | progress.value = 0
17 | display(progress)
18 | zone_stops = {}
19 | for zone_id, zone in zones.iterrows():
20 | zone_stops[zone_id] = []
21 | for stop_id, stop in nodes.loc[stop_list].iterrows():
22 | if zone['geometry'].contains(stop['geometry']):
23 | zone_stops[zone_id].append(stop_id)
24 | progress.value += 1
25 |
26 | if leg_type == 'nearest':
27 | centroids = zones.copy()
28 | centroids['geometry'] = zones['geometry'].apply(lambda g: g.centroid)
29 | stops = nodes.loc[stop_list]
30 |
31 | links_a = spatial.nearest(stops, centroids).rename(columns={'ix_many': 'zone', 'ix_one': 'stop'})
32 | links_b = spatial.nearest(centroids, stops).rename(columns={'ix_one': 'zone', 'ix_many': 'stop'})
33 | links = pd.concat([links_a, links_b]).drop_duplicates()
34 | zone_stops = dict(links.groupby('zone')['stop'].agg(lambda s: list(s)))
35 | return zone_stops
36 |
37 |
38 | def nontransitleg_geometries(nontransitleg_list, zones, nodes):
39 | df_a = pd.DataFrame(nontransitleg_list, columns=['a', 'b'])
40 |
41 | def geometry(row):
42 | return shapely.geometry.LineString(
43 | [nodes.loc[row['a'], 'geometry'], zones.loc[row['b'], 'geometry'].centroid]
44 | )
45 |
46 | df_a['geometry'] = df_a.apply(geometry, axis=1)
47 | df_b = df_a.rename(columns={'a': 'b', 'b': 'a'})
48 | return pd.concat([df_a, df_b])
49 |
50 |
51 | def nontransitleg_list(zone_stops):
52 | nontransitlegs = []
53 | for zone in zone_stops.keys():
54 | for stop in zone_stops[zone]:
55 | nontransitlegs.append((stop, zone))
56 |
57 | return list(set(nontransitlegs))
58 |
59 |
60 | def nontransitlegs(zones, nodes, stop_list, leg_type='contains'):
61 | _zone_stops = zone_stops(zones, nodes, stop_list, leg_type)
62 | _list = nontransitleg_list(_zone_stops)
63 | return nontransitleg_geometries(_list, zones, nodes)
64 |
65 |
66 | def reindex_nodes(links, nodes, start_from=0, reindex_node=None):
67 | if reindex_node is None:
68 | nodes = nodes.copy()
69 | links = links.copy()
70 |
71 | index = nodes.index
72 | rename_dict = {}
73 | current = start_from
74 | for n in index:
75 | rename_dict[n] = str(current)
76 | current += 1
77 |
78 | def reindex_node(node):
79 | return rename_dict[node]
80 |
81 | nodes.index = [reindex_node(n) for n in nodes.index]
82 | links['a'] = links['a'].apply(reindex_node)
83 | links['b'] = links['b'].apply(reindex_node)
84 | return links, nodes
85 |
--------------------------------------------------------------------------------
/quetzal/io/EMMEporter.py:
--------------------------------------------------------------------------------
1 | import geopandas as gpd
2 | import pandas as pd
3 | import json
4 | from syspy.spatial.geometries import line_list_to_polyline
5 |
6 | def shorter_links(links,original_links = False, add_dict = {} ):
7 | '''
8 | script to shorten the links of Emme that are keeping on the node to have Quetzal links with only alighting or boardings
9 | if original_links == True, we keep the emme links in liste in the new table'
10 | Geometric_node_columns is the field that permit to filter geometric nodes that have buged pickup_type using other columns
11 | you will need to pass a list of two columns, first boarding then alighting
12 |
13 | '''
14 | crs = links.crs
15 | links = links.copy()
16 | # Safeguard: Ensure key columns are present
17 | required_cols = ['pickup_type', 'drop_off_type', 'a', 'b','geometry','trip_id','link_sequence','length','speed','time']
18 | missing_cols = [col for col in required_cols if col not in links.columns]
19 | if missing_cols:
20 | raise ValueError(f"Missing columns: {missing_cols}")
21 | links = links.sort_values(['trip_id', 'link_sequence'])
22 | first_last = links.reset_index().groupby('trip_id')['index'].agg(['first', 'last'])
23 | links['stop'] = True
24 | links['next_pickup'] = links['pickup_type'].shift(-1).fillna(0).astype(int)
25 | links['prev_drop_off'] = links['drop_off_type'].shift(+1).fillna(0).astype(int)
26 | links.loc[(links['pickup_type'] != 0) & (links['prev_drop_off'] != 0), 'stop'] = False
27 | #if the one before is false it means that you can
28 | links.loc[first_last['first'], 'stop'] = True
29 | #links.loc[first_last['last'],'stop'] = True
30 | links['cumsum'] = links['stop'].cumsum()
31 | links = links.drop(columns=['next_pickup', 'prev_drop_off'])
32 | #Aggregate of links and columns
33 | #ajouter dans parametre agg_dict() update mon agg_dict()
34 | agg_dict = {col: 'first' for col in links.columns}
35 | del agg_dict['cumsum']
36 | del agg_dict['stop']
37 | del agg_dict['speed']
38 | agg_dict['a'] = 'first'
39 | agg_dict['b'] = 'last'
40 | agg_dict['geometry'] = line_list_to_polyline
41 | agg_dict['road_link_list'] = lambda x: sum(x, [])
42 | agg_dict['time'] = sum
43 | agg_dict['length'] = sum
44 | agg_dict['drop_off_type'] = 'last'
45 | agg_dict.update(add_dict)
46 | if original_links is True:
47 | links['original_links'] = [*zip(links['a'], links['b'])]
48 | agg_dict['original_links'] = list
49 | if 'selectLink' in links.columns:
50 | agg_dict['selectLink'] = lambda x: 'yes' if 'yes' in set(x) else None
51 | for col in links.columns:
52 | print(col, ' --> ', agg_dict.get(col, '! not agg !'))
53 | links = links.reset_index().groupby('cumsum').agg(agg_dict)
54 | links['speed'] = 3.6 * links['length'] / links['time']
55 | # fix link_sequence
56 | lengths_sequence = links.groupby('trip_id')['a'].agg(len).values
57 | link_sequence = [i + 1 for l in lengths_sequence for i in range(l)]
58 | links['link_sequence'] = link_sequence
59 | links.index = 'link_' + links.index.astype(str)
60 | links.index.name = 'index'
61 | links = gpd.GeoDataFrame(links)
62 | links = links.set_crs(crs)
63 |
64 | return(links)
--------------------------------------------------------------------------------
/syspy/surveys/discrete_choice.py:
--------------------------------------------------------------------------------
1 | import json
2 |
3 | import numpy as np
4 | import pandas as pd
5 | from syspy.surveys.array_example import base
6 |
7 |
8 | def get_array(array_class, verbose=False):
9 | selected = base.copy()
10 | for level, factors in array_class.items():
11 | selected = selected .loc[
12 | selected[level] >= factors
13 | ].copy()
14 |
15 | first = selected.iloc[0]
16 | exponents = first['exponents']
17 | df = pd.DataFrame(json.loads(first['array']))
18 | df.columns = get_index(exponents)
19 |
20 | array_classes = selected.loc[
21 | selected['runs'] == first['runs'],
22 | 'exponents'
23 | ]
24 | if verbose:
25 | print('required array class:')
26 | print(array_class)
27 | print('available array classes (using first one): ')
28 | print(array_classes)
29 | return df[get_index(array_class)]
30 |
31 |
32 | def build_array(array_class, *args, **kwargs):
33 | try:
34 | return get_array(array_class, *args, **kwargs)
35 | except ValueError:
36 | i = 2
37 | m = max(array_class.keys())
38 | pop = array_class.pop(m)
39 | l = []
40 | for key in [int(m / i), i]:
41 | base = 0
42 | if key in array_class.keys():
43 | base = array_class[key]
44 | array_class[key] = base + 1
45 | l.append('%ie%i' % (key, base))
46 |
47 | oa = get_array(array_class)
48 | oa['%ie%i' % (m, 0)] = oa[l[0]] + oa[l[1]] * int(m / i)
49 | return oa.drop(l, axis=1)
50 |
51 |
52 | def get_index(exponents):
53 | index = []
54 | for level, factors in exponents.items():
55 | for i in range(factors):
56 | c = str(level) + 'e' + str(i)
57 | index.append(c)
58 | return sorted(index)
59 |
60 |
61 | def get_selection(array_class):
62 | selected = base.copy()
63 | for level, factors in array_class.items():
64 | selected = selected .loc[
65 | selected[level] >= factors
66 | ].copy()
67 | return selected
68 |
69 |
70 | def get_array_class(factors):
71 | array_class = {}
72 | join = {}
73 |
74 | for factor, levels in factors.items():
75 | key = len(levels)
76 | if key in array_class:
77 | array_class[key] += 1
78 | else:
79 | array_class[key] = 1
80 |
81 | factor_index = array_class[key] - 1
82 | join[str(key) + 'e' + str(factor_index)] = factor
83 | return array_class, join
84 |
85 |
86 | def orthogonal_array(factors, *args, **kwargs):
87 | array_class, match = get_array_class(factors)
88 |
89 | df = build_array(array_class, *args, **kwargs)
90 |
91 | df.columns = [match[c] for c in df.columns]
92 |
93 | for factor, factor_list in factors.items():
94 | df[factor] = df[factor].apply(lambda v: factor_list[v])
95 |
96 | columns = list(set(df.columns))
97 | identity = pd.DataFrame(
98 | np.identity(len(columns)),
99 | columns=columns,
100 | index=columns
101 | )
102 | delta_corr = df.corr() - identity
103 | assert delta_corr.max().max() < 1e-9
104 | return df
105 |
--------------------------------------------------------------------------------
/quetzal/io/hdf_io.py:
--------------------------------------------------------------------------------
1 | import importlib
2 | import pickle
3 | import uuid
4 | import zlib
5 | import zstandard
6 | import os
7 |
8 | import pandas as pd
9 | from tqdm import tqdm
10 |
11 |
12 | class PickleProtocol:
13 | def __init__(self, level):
14 | self.previous = pickle.HIGHEST_PROTOCOL
15 | self.level = level
16 |
17 | def __enter__(self):
18 | importlib.reload(pickle)
19 | pickle.HIGHEST_PROTOCOL = self.level
20 |
21 | def __exit__(self, *exc):
22 | importlib.reload(pickle)
23 | pickle.HIGHEST_PROTOCOL = self.previous
24 |
25 |
26 | def pickle_protocol(level):
27 | return PickleProtocol(level)
28 |
29 |
30 | def write_hdf_to_buffer(frames, level=4, complevel=None):
31 | with pickle_protocol(level):
32 | with pd.HDFStore(
33 | 'quetzal-%s.h5' % str(uuid.uuid4()),
34 | mode='a',
35 | driver='H5FD_CORE',
36 | driver_core_backing_store=0,
37 | complevel=complevel,
38 | ) as out:
39 | iterator = tqdm(frames.items())
40 | for key, df in iterator:
41 | iterator.desc = key
42 | out[key] = df
43 | return out._handle.get_file_image()
44 |
45 |
46 | def to_zippedpickle(frame, filepath, pickle_protocol_level=4, complevel=-1):
47 | with pickle_protocol(pickle_protocol_level):
48 | buffer = pickle.dumps(frame)
49 | smallbuffer = zstandard.ZstdCompressor(level=complevel).compress(buffer)
50 | with open(filepath, 'wb') as file:
51 | file.write(smallbuffer)
52 |
53 |
54 | def read_zippedpickle(filename):
55 | with open(filename, 'rb') as file:
56 | buffer = file.read()
57 | decompressor = zstandard.ZstdDecompressor()
58 | bigbuffer = decompressor.decompress(buffer)
59 | return pickle.loads(bigbuffer)
60 |
61 |
62 | def frame_to_zip(frame, filepath, level=4, complevel=None):
63 | with pickle_protocol(level):
64 | with pd.HDFStore(
65 | 'quetzal-%s.h5' % str(uuid.uuid4()),
66 | mode='a',
67 | driver='H5FD_CORE',
68 | driver_core_backing_store=0,
69 | complevel=complevel,
70 | ) as out:
71 | out['frame'] = frame
72 | buffer = out._handle.get_file_image()
73 | smallbuffer = zlib.compress(buffer)
74 | with open(filepath, 'wb') as file:
75 | file.write(smallbuffer)
76 |
77 |
78 | def zip_to_frame(filepath):
79 | with open(filepath, 'rb') as file:
80 | data = file.read()
81 | bigbyte = zlib.decompress(data)
82 |
83 | with pd.HDFStore(
84 | 'quetzal-%s.h5' % str(uuid.uuid4()),
85 | mode='r',
86 | driver='H5FD_CORE',
87 | driver_core_backing_store=0,
88 | driver_core_image=bigbyte,
89 | ) as store:
90 | return store['frame']
91 |
92 |
93 | def get_folder_size(folder):
94 | # return MB
95 | total_size = sum(
96 | os.path.getsize(os.path.join(dirpath, filename))
97 | for dirpath, _, filenames in os.walk(folder)
98 | for filename in filenames
99 | )
100 | return total_size / (1024 * 1024) # Convert bytes to MB
101 |
--------------------------------------------------------------------------------
/docs/source/_build/html/_static/css/badge_only.css:
--------------------------------------------------------------------------------
1 | .fa:before{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-weight:normal;font-style:normal;src:url("../font/fontawesome_webfont.eot");src:url("../font/fontawesome_webfont.eot?#iefix") format("embedded-opentype"),url("../font/fontawesome_webfont.woff") format("woff"),url("../font/fontawesome_webfont.ttf") format("truetype"),url("../font/fontawesome_webfont.svg#FontAwesome") format("svg")}.fa:before{display:inline-block;font-family:FontAwesome;font-style:normal;font-weight:normal;line-height:1;text-decoration:inherit}a .fa{display:inline-block;text-decoration:inherit}li .fa{display:inline-block}li .fa-large:before,li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-0.8em}ul.fas li .fa{width:0.8em}ul.fas li .fa-large:before,ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before{content:""}.icon-book:before{content:""}.fa-caret-down:before{content:""}.icon-caret-down:before{content:""}.fa-caret-up:before{content:""}.icon-caret-up:before{content:""}.fa-caret-left:before{content:""}.icon-caret-left:before{content:""}.fa-caret-right:before{content:""}.icon-caret-right:before{content:""}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;border-top:solid 10px #343131;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;z-index:400}.rst-versions a{color:#2980B9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27AE60;*zoom:1}.rst-versions .rst-current-version:before,.rst-versions .rst-current-version:after{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book{float:left}.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#E74C3C;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#F1C40F;color:#000}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:gray;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:solid 1px #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px}.rst-versions.rst-badge .icon-book{float:none}.rst-versions.rst-badge .fa-book{float:none}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book{float:left}.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge .rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width: 768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}img{width:100%;height:auto}}
2 | /*# sourceMappingURL=badge_only.css.map */
3 |
--------------------------------------------------------------------------------
/quetzal/engine/graph_utils.py:
--------------------------------------------------------------------------------
1 | def build_neighbors(edges):
2 | neighbors = {}
3 | for a, b, w in edges:
4 | try:
5 | neighbors[a].add(b)
6 | except KeyError:
7 | neighbors[a] = {b}
8 | try:
9 | neighbors[b].add(a)
10 | except KeyError:
11 | neighbors[b] = {a}
12 | return neighbors
13 |
14 | def vertex_indexed_weights(edges):
15 | ab_dict = {a: dict() for a, b, w in edges}
16 | ba_dict = {b: dict() for a, b, w in edges}
17 |
18 | for a, b, w in edges:
19 | try:
20 | ab_dict[a][b] = w
21 | except KeyError:
22 | ab_dict[a] = {b: w}
23 | try:
24 | ba_dict[b][a] = w
25 | except KeyError:
26 | ba_dict[b] = {a: w}
27 | return ab_dict, ba_dict
28 |
29 | def combine_edges(edges, keep=set()):
30 |
31 | neighbors = build_neighbors(edges)
32 |
33 | # find nodes of degree two
34 | degree_two_or_less = {k for k, n in neighbors.items() if len(n) <= 2}
35 | to_combine = degree_two_or_less - keep
36 |
37 | ab_dict, ba_dict = vertex_indexed_weights(edges)
38 | new_edges = set()
39 | shortcuts = {}
40 |
41 | to_combine = {
42 | n for n in to_combine
43 | if n in ab_dict and n in ba_dict
44 | } # dead_ends can not be combined
45 |
46 | def pop_node(node, ab_dict, ba_dict, new_edges, shortcuts):
47 |
48 |
49 | ab = ab_dict.pop(node)
50 | ba = ba_dict.pop(node)
51 |
52 | for p, w_left in ba.items(): # predecessors
53 | ab_dict[p].pop(node)
54 |
55 | for s, w_right in ab.items(): # successors
56 | ba_dict[s].pop(node)
57 |
58 | for p, w_left in ba.items():
59 |
60 | if p != s:
61 | time = w_left + w_right
62 | try:
63 | former_time = ab_dict[p][s]
64 | if time < former_time:
65 | ab_dict[p][s] = time
66 | ba_dict[s][p] = time
67 | new_edges.add((p, s))
68 | left = shortcuts.get((p, node), [p, node])
69 | right = shortcuts.get((node, s), [node, s])
70 | shortcuts[(p, s)] = left + right[1:]
71 |
72 | except KeyError: # the edge does not exist
73 | ab_dict[p][s] = time
74 | ba_dict[s][p] = time
75 | new_edges.add((p, s))
76 | left = shortcuts.get((p, node), [p, node])
77 | right = shortcuts.get((node, s), [node, s])
78 | shortcuts[(p, s)] = left + right[1:]
79 |
80 | for node in to_combine:
81 | pop_node(node, ab_dict, ba_dict, new_edges, shortcuts)
82 |
83 | e = []
84 | for a, ss in ab_dict.items():
85 | for b, w in ss.items():
86 | e.append([a, b, w])
87 |
88 | combined_edges = {(a, b) for a, b, w in e}
89 | shortcuts = {k: v for k, v in shortcuts.items() if k in combined_edges}
90 | new_edges = new_edges.intersection(combined_edges)
91 |
92 | return e, shortcuts
93 |
94 | def expand_path(p, shortcuts):
95 | path = [p[0]]
96 | for e in list(zip(p[:-1], p[1:])): # edge_path
97 | path += shortcuts.get(e, e)[1:]
98 | return path
99 |
--------------------------------------------------------------------------------
/tests/data/jsons/loaded_nodes.geojson:
--------------------------------------------------------------------------------
1 | {
2 | "type": "FeatureCollection",
3 | "features": [
4 | { "type": "Feature", "properties": { "index": "FUR_CREEK_RES", "stop_name": "Furnace Creek Resort (Demo)", "stop_desc": 0.0, "stop_lat": 36.425288, "stop_lon": -117.133162, "zone_id": 0.0, "stop_url": 0.0, "volume_pt": 1.846307147203984, "boardings": 0.8463171119253321, "alightings": 0.99999003527865182, "transfers": 0.0 }, "geometry": { "type": "Point", "coordinates": [ -117.133162, 36.425288 ] } },
5 | { "type": "Feature", "properties": { "index": "BEATTY_AIRPORT", "stop_name": "Nye County Airport (Demo)", "stop_desc": 0.0, "stop_lat": 36.868446, "stop_lon": -116.784582, "zone_id": 0.0, "stop_url": 0.0, "volume_pt": 2.0048428268202225, "boardings": 0.45033581134181183, "alightings": 0.45033757890762455, "transfers": 0.15367788940941798 }, "geometry": { "type": "Point", "coordinates": [ -116.784582, 36.868446 ] } },
6 | { "type": "Feature", "properties": { "index": "BULLFROG", "stop_name": "Bullfrog (Demo)", "stop_desc": 0.0, "stop_lat": 36.88108, "stop_lon": -116.81797, "zone_id": 0.0, "stop_url": 0.0, "volume_pt": 2.1976134094415394, "boardings": 1.2966497247768585, "alightings": 1.296652923267144, "transfers": 0.7469955008400182 }, "geometry": { "type": "Point", "coordinates": [ -116.81797, 36.88108 ] } },
7 | { "type": "Feature", "properties": { "index": "STAGECOACH", "stop_name": "Stagecoach Hotel & Casino (Demo)", "stop_desc": 0.0, "stop_lat": 36.915682, "stop_lon": -116.751677, "zone_id": 0.0, "stop_url": 0.0, "volume_pt": 1.0075274578207731, "boardings": 0.15367788940941798, "alightings": 0.0, "transfers": 0.0 }, "geometry": { "type": "Point", "coordinates": [ -116.751677, 36.915682 ] } },
8 | { "type": "Feature", "properties": { "index": "NADAV", "stop_name": "North Ave \/ D Ave N (Demo)", "stop_desc": 0.0, "stop_lat": 36.914893, "stop_lon": -116.76821, "zone_id": 0.0, "stop_url": 0.0, "volume_pt": 1.7595200009064602, "boardings": 0.0, "alightings": 0.0, "transfers": 0.0 }, "geometry": { "type": "Point", "coordinates": [ -116.76821, 36.914893 ] } },
9 | { "type": "Feature", "properties": { "index": "NANAA", "stop_name": "North Ave \/ N A Ave (Demo)", "stop_desc": 0.0, "stop_lat": 36.914944, "stop_lon": -116.761472, "zone_id": 0.0, "stop_url": 0.0, "volume_pt": 0.093939911307376153, "boardings": 0.0, "alightings": 0.0, "transfers": 0.0 }, "geometry": { "type": "Point", "coordinates": [ -116.761472, 36.914944 ] } },
10 | { "type": "Feature", "properties": { "index": "DADAN", "stop_name": "Doing Ave \/ D Ave N (Demo)", "stop_desc": 0.0, "stop_lat": 36.909489, "stop_lon": -116.768242, "zone_id": 0.0, "stop_url": 0.0, "volume_pt": 0.94810650699354992, "boardings": 0.0, "alightings": 0.0, "transfers": 0.0 }, "geometry": { "type": "Point", "coordinates": [ -116.768242, 36.909489 ] } },
11 | { "type": "Feature", "properties": { "index": "EMSI", "stop_name": "E Main St \/ S Irving St (Demo)", "stop_desc": 0.0, "stop_lat": 36.905697, "stop_lon": -116.76218, "zone_id": 0.0, "stop_url": 0.0, "volume_pt": 1.8891232754361238, "boardings": 0.0, "alightings": 0.0, "transfers": 0.0 }, "geometry": { "type": "Point", "coordinates": [ -116.76218, 36.905697 ] } },
12 | { "type": "Feature", "properties": { "index": "AMV", "stop_name": "Amargosa Valley (Demo)", "stop_desc": 0.0, "stop_lat": 36.641496, "stop_lon": -116.40094, "zone_id": 0.0, "stop_url": 0.0, "volume_pt": 0.0, "boardings": 0.0, "alightings": 0.0, "transfers": 0.0 }, "geometry": { "type": "Point", "coordinates": [ -116.40094, 36.641496 ] } }
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | # quetzal
3 | ## What is it?
4 | **quetzal** is a Python package providing flexible models for transport planning and traffic forecasting.
5 | ## Copyright
6 | (c) SYSTRA
7 | ## License
8 | [CeCILL-B](LICENSE.md)
9 | ## Documentation
10 | The official documentation is hosted on https://systragroup.github.io/quetzal
11 | ## Backward compatibility
12 | In order to improve the ergonomics, the code may be re-factored and a few method calls may be re-designed. As a consequence, the backward compatibility of the library is not guaranteed. Therefore, the version of quetzal used for a project should be specified in its requirements.
13 |
14 | # Installation from sources
15 | ## For Linux
16 | One should choose between
17 | - Poetry (recommended)
18 | - Virtualenv
19 | - Anaconda
20 |
21 | ### poetry
22 | 1) May need to set the default (or local) python version in the project
23 | ```bash
24 | pyenv local 3.12
25 | ```
26 | 2) install dependancies (this will create a new virtualenv)
27 | ```bash
28 | poetry install
29 | ```
30 | 3) activate the env
31 | ```bash
32 | poetry shell
33 | ```
34 | 4) add the env to ipykernel (to use in jupyter)
35 | ```bash
36 | python -m ipykernel install --user --name=quetzal_env
37 | ```
38 |
39 | ### Virtualenv
40 | Virtual environment: `virtualenv .venv -p python3.12; source .venv/bin/activate` or any equivalent command.
41 |
42 | ```bash
43 | pip install -e .
44 | ```
45 |
46 | #### Anaconda
47 | In order to use python notebook, Anaconda 3 + Python 3.12 must be installed.
48 | Then create + activate quetzal environment:
49 | ```bash
50 | conda init
51 | conda create -n quetzal_env -y python=3.12
52 | conda activate quetzal_env
53 | pip install -e . -r requirements_win.txt
54 | python -m ipykernel install --user --name=quetzal_env
55 | ```
56 |
57 |
58 |
59 | ## For Windows
60 | `Anaconda 3 + Python 3.12` is supposed to be installed
61 | #### PIP and Anaconda (recommended)
62 | To create quetzal_env automatically and install quetzal, open anaconda prompt and
63 | run windows-install batch file
64 | ```bash
65 | (base) C:users\you\path\to\quetzal> windows-install.bat
66 | ```
67 | press enter to accept default environment name or enter a custom name
68 | #### If you are facing SSL issues
69 | ```bash
70 | (base) pip config set global.trusted-host "pypi.org files.pythonhosted.org"
71 | (base) C:users\you\path\to\quetzal> windows-install.bat
72 | ```
73 | security warning: the host is added to pip.ini
74 |
75 | #### If you are facing DLL or dependencies issues
76 | Anaconda and Pip do not get along well, your Anaconda install may have been corrupted at some point.
77 | - Remove your envs
78 | - Uninstall Anaconda
79 | - Delete your Python and Anaconda folders (users\you\Anaconda3, users\you\Appdata\Roaming\Python, ...etc)
80 | - Install Anaconda
81 |
82 |
83 | ## migration to 3.12
84 | * pandas append was remove:
85 | ```python
86 | # before
87 | sm.volumes = sm.volumes.append(vol)
88 | #now
89 | sm.volumes = pd.concat([sm.volumes, vol])
90 | #or
91 | sm.volumes = pd.concat([sm.volumes, pd.DataFrame(vol)])
92 | ```
93 | filtering index with set was remove:
94 | ```python
95 | # before
96 | sm.volumes = sm.volumes.loc[od_set]
97 | #now
98 | sm.volumes = sm.volumes.loc[list(od_set)]
99 | ```
100 |
101 | * shapely
102 | ```python
103 | # before
104 | hull = zones.unary_union.convex_hull
105 | # now
106 | hull = zones.union_all().convex_hull
107 | ```
108 | * scikitlearn
109 | ```python
110 | # add n_init='auto'
111 | KMeans(n_clusters=num_zones,random_state=0,n_init='auto')
112 | ```
113 |
--------------------------------------------------------------------------------
/syspy/graph/nearest_path.py:
--------------------------------------------------------------------------------
1 | import itertools
2 |
3 | import networkx as nx
4 | from networkx import NetworkXNoPath
5 |
6 |
7 | def find_road_node_options(node_path, nearest_neighbors):
8 | df = nearest_neighbors.loc[nearest_neighbors['ix_one'].isin(node_path)].copy()
9 | df.sort_values('rank', inplace=True)
10 |
11 | options = {}
12 | for node_index in range(len(node_path)):
13 | node = node_path[node_index]
14 | road_nodes = set(df[df['ix_one'] == node]['ix_many'])
15 | tuples = [(node, road_node) for road_node in road_nodes]
16 | options[node] = tuples
17 | return options
18 |
19 |
20 | def build_shortcut_ghaph(
21 | node_path,
22 | road_node_options,
23 | road_graph,
24 | penalties=None
25 | ):
26 | if True:
27 | indexed_road_node_options = {}
28 | indexed_node_path = []
29 | for node_index in range(len(node_path)):
30 | node = node_path[node_index]
31 | key = (node_index, node)
32 | value = [(node_index,) + option for option in road_node_options[node]]
33 | indexed_road_node_options[key] = value
34 | indexed_node_path.append(key)
35 | road_node_options = indexed_road_node_options
36 | node_path = indexed_node_path
37 |
38 | node_tuples = [
39 | (node_path[i], node_path[i + 1])
40 | for i in range(len(node_path) - 1)
41 | ]
42 |
43 | # Build the shortcut graph
44 | edges = []
45 |
46 | for tuple_index in range(len(node_tuples)):
47 | origin, destination = node_tuples[tuple_index]
48 | product = list(
49 | itertools.product(
50 | road_node_options[origin],
51 | road_node_options[destination]
52 | )
53 | )
54 |
55 | edges += [p + (tuple_index,) for p in product]
56 |
57 | def penalty(node_road_node_tuple):
58 | if True:
59 | node_road_node_tuple = node_road_node_tuple[1:]
60 |
61 | if penalties:
62 | return penalties[node_road_node_tuple]
63 | else:
64 | return 0
65 |
66 | weighted_edges = []
67 | for edge_index in range(len(edges)):
68 | origin, destination, tuple_index = edges[edge_index]
69 | road_origin = origin[-1]
70 | road_destination = destination[-1]
71 | try:
72 | length, path = nx.bidirectional_dijkstra(
73 | road_graph,
74 | road_origin,
75 | road_destination
76 | )
77 | except NetworkXNoPath:
78 | length, path = float('inf'), ['wrong']
79 |
80 | length += penalty(origin) + penalty(destination)
81 |
82 | weighted_edge = (
83 | origin,
84 | destination,
85 | length
86 | )
87 | weighted_edges.append(weighted_edge)
88 |
89 | origin_options = road_node_options[node_path[0]]
90 | destination_options = road_node_options[node_path[-1]]
91 |
92 | assert origin_options and destination_options
93 | o_edges = [['origin', o, penalty(o)] for o in origin_options]
94 | d_edges = [[o, 'destination', penalty(o)]for o in destination_options]
95 |
96 | shortcut_graph = nx.DiGraph()
97 | shortcut_graph.add_weighted_edges_from(
98 | weighted_edges + o_edges + d_edges
99 | )
100 | return shortcut_graph
101 |
102 |
103 | def find_road_node_path(shortcut_graph):
104 | tuple_path = nx.dijkstra_path(shortcut_graph, 'origin', 'destination')[1:-1]
105 | return [t[-1] for t in tuple_path]
106 |
--------------------------------------------------------------------------------
/syspy/pycube/dijkstra.py:
--------------------------------------------------------------------------------
1 | __author__ = 'qchasserieau'
2 |
3 | import networkx as nx
4 |
5 |
6 | class DijkstraMonkey:
7 | """
8 | nx.DiGraph based object. Runs Dijkstra algorithm to infer the extensive sequence of nodes from a partial
9 | sequence. Add intermediate nodes to a .LIN to fit a detailed network.
10 |
11 | example:
12 | ::
13 | df_edges =links[['a', 'b', 'length']]
14 | edges = [tuple(df_edges.ix[i]) for i in df_edges.index] # edges is a list of tuples (a, b, length)
15 | edsger = pycube.lin.DijkstraMonkey(edges)
16 | edsger.make_lin(data_path + 'monterrey_2045_edited.lin', data_path + 'monterrey_2045_edited_dijkstra.lin')
17 | """
18 | def __init__(self, edges):
19 | self.g = nx.DiGraph()
20 | self.g.add_weighted_edges_from(edges)
21 |
22 | def _to_insert(path):
23 | """ returns a string containing all the intermediates nodes of a path in .lin format """
24 | return ''.join(['N=-' + str(int(path[i])) + ', ' for i in range(1, len(path) - 1)])
25 | _to_insert = staticmethod(_to_insert)
26 |
27 | def _path_from_pair(self, pair):
28 | _pair = [int(i.replace('-', '')) for i in pair]
29 | """ tries to return the shortest path between to points of a pair"""
30 | try:
31 | path = nx.dijkstra_path(self.g, _pair[0], _pair[1])
32 | except Exception:
33 | print('fail at ' + str(pair))
34 | path = []
35 |
36 | return path
37 |
38 | def _line_with_intermediate_nodes(self, line):
39 | """ returns a string string with all the intermediates nodes from a .lin line string"""
40 | sequence = line.split('N=')
41 | pairs = [[sequence[i].split(',')[0], sequence[i + 1].split(',')[0]] for i in range(1, len(sequence) - 1)]
42 | paths = [self._path_from_pair(pair) for pair in pairs]
43 |
44 | k = 2
45 | for i in range(0, len(pairs)):
46 | if len(self._to_insert(paths[i])):
47 | sequence.insert(i + k, self._to_insert(paths[i]))
48 | k += 1
49 | return 'N='.join(sequence).replace('N=N', 'N')
50 |
51 | def make_lin(self, from_lin_file, to_lin_file, sep=None):
52 | """
53 | make a .lin file from another using dijkstra algorithm to add intermediates nodes
54 |
55 | :param from_lin_file: the lin to process
56 | :param to_lin_file: the path to the lin to save
57 | :param sep: the string that separates the lines in the file ex: 'LINE NAME'
58 | :return: None
59 | """
60 | # lecture du .LIN d'origine
61 | with open(from_lin_file, 'r') as f:
62 | lines = f.readlines()
63 |
64 | if sep:
65 | with open(from_lin_file, 'r') as f:
66 | lines = _to_n_equal(f.read()).split(sep)
67 |
68 | # construction de la liste des lignes du nouveau .LIN à partir de celle de l'ancien
69 | lines_with_intermediate_nodes = [self._line_with_intermediate_nodes(line) for line in lines]
70 |
71 | # écriture du nouveau .LIN
72 | with open(to_lin_file, 'w') as f:
73 | f.write(''.join(lines_with_intermediate_nodes))
74 | if sep:
75 | with open(to_lin_file, 'w') as f:
76 | f.write(sep.join(lines_with_intermediate_nodes))
77 |
78 |
79 | def _to_n_equal(l):
80 | return ','.join([_chunk_to_n_equal(c) for c in l.split(',')])
81 |
82 |
83 | def _chunk_to_n_equal(c):
84 | return 'N=' + c if _represents_int(c) else c
85 |
86 |
87 | def _represents_int(s):
88 | try:
89 | int(s)
90 | return True
91 | except ValueError:
92 | return False
93 |
--------------------------------------------------------------------------------
/quetzal/io/gtfs_reader/patterns.py:
--------------------------------------------------------------------------------
1 | import gtfs_kit as gk
2 | import numpy as np
3 | import pandas as pd
4 | from syspy.spatial import spatial
5 |
6 |
7 | def build_stop_clusters(
8 | stops, distance_threshold=150, col='cluster_id', use_parent_station=False
9 | ):
10 | """
11 | Apply agglomerative clustering algorithm to stops.
12 | Add a column cluster_id with the cluster id.
13 | If use_parent_station = True: clustering based on parent stations when known
14 | """
15 | # TODO: do not work for big feeds --> suggest to use KMeans in this case
16 | gdf = gk.stops.geometrize_stops_0(stops, use_utm=True)
17 | temp = gdf.copy()
18 | if use_parent_station:
19 | if 'parent_station' not in gdf.columns:
20 | gdf['parent_station'] = np.nan
21 | gdf['dissolve'] = gdf.apply(
22 | lambda x: x['parent_station'] if isinstance(x['parent_station'], str) else x['stop_id'],
23 | 1
24 | )
25 | temp = gdf.dissolve('dissolve', as_index=False)
26 | temp.geometry = temp.geometry.centroid
27 |
28 | temp[col] = spatial.agglomerative_clustering(
29 | temp, distance_threshold=distance_threshold
30 | )
31 |
32 | if use_parent_station:
33 | temp = gdf.merge(temp[['dissolve', col]], on='dissolve', how='left')
34 | temp.drop('dissolve', 1, inplace=True)
35 | return gk.stops.ungeometrize_stops_0(temp)
36 |
37 |
38 | def build_patterns(
39 | feed, group=['route_id'], on='stop_id'
40 | ):
41 | """
42 | """
43 | trip_footprints = get_trip_footprints(feed, on=on)
44 | patterns = get_patterns(feed.trips, trip_footprints, group=group)
45 | feed.trips = feed.trips.merge(
46 | patterns[['trip_id', 'pattern_id']], on='trip_id'
47 | )
48 |
49 |
50 | def get_trip_stop_list(stop_times, stops=None, on='stop_id'):
51 | trip_stops = stop_times.copy()
52 | if on != 'stop_id':
53 | s_to_c = stops.set_index('stop_id')[on].reset_index()
54 | trip_stops = trip_stops.merge(s_to_c)
55 | trip_stops = trip_stops.sort_values(['trip_id', 'stop_sequence']).groupby('trip_id').agg(
56 | {on: lambda x: list(x)}
57 | ).rename(columns={on: 'stops'})
58 |
59 | return trip_stops
60 |
61 |
62 | def get_trip_footprints(feed, on='stop_id'):
63 | """
64 | Build each trip's footprint.
65 | The footprint is a String that will be used to derive the trip
66 | patterns: it must allow to identify trips that will be grouped
67 | and to distinguish trips that will not. Here we use the ordered
68 | list of stops or clusters to build each trip footprint.
69 | """
70 | trip_stops = get_trip_stop_list(feed.stop_times, feed.stops, on=on)
71 | trip_footprints = trip_stops.rename(columns={'stops': 'footprint'})
72 | trip_footprints['footprint'] = trip_footprints['footprint'].map(str)
73 | return trip_footprints
74 |
75 |
76 | def get_patterns(trips, trip_footprints, group=['route_id']): # we can add direction, it can also be on route_short_name, …
77 | patterns = trip_footprints.copy()
78 | patterns = patterns.merge(
79 | trips.set_index('trip_id')[group],
80 | left_index=True,
81 | right_index=True
82 | )
83 | pattern_n = patterns.drop_duplicates().set_index(['footprint'] + group).groupby(
84 | group,
85 | as_index=False
86 | ).cumcount()
87 | pattern_n.name = 'pattern_num'
88 | patterns = patterns.reset_index().merge(
89 | pattern_n,
90 | on=['footprint'] + group
91 | )
92 | patterns['pattern_id'] = patterns[group + ['pattern_num']].apply(
93 | lambda x: '_'.join(x.map(str)), 1
94 | )
95 | return patterns
96 |
--------------------------------------------------------------------------------
/.vscode/.ropeproject/config.py:
--------------------------------------------------------------------------------
1 | # The default ``config.py``
2 |
3 |
4 | def set_prefs(prefs):
5 | """This function is called before opening the project"""
6 |
7 | # Specify which files and folders to ignore in the project.
8 | # Changes to ignored resources are not added to the history and
9 | # VCSs. Also they are not returned in `Project.get_files()`.
10 | # Note that ``?`` and ``*`` match all characters but slashes.
11 | # '*.pyc': matches 'test.pyc' and 'pkg/test.pyc'
12 | # 'mod*.pyc': matches 'test/mod1.pyc' but not 'mod/1.pyc'
13 | # '.svn': matches 'pkg/.svn' and all of its children
14 | # 'build/*.o': matches 'build/lib.o' but not 'build/sub/lib.o'
15 | # 'build//*.o': matches 'build/lib.o' and 'build/sub/lib.o'
16 | prefs['ignored_resources'] = ['*.pyc', '*~', '.ropeproject',
17 | '.hg', '.svn', '_svn', '.git',
18 | '__pycache__']
19 |
20 | # Specifies which files should be considered python files. It is
21 | # useful when you have scripts inside your project. Only files
22 | # ending with ``.py`` are considered to be python files by
23 | # default.
24 | # prefs['python_files'] = ['*.py']
25 |
26 | # Custom source folders: By default rope searches the project
27 | # for finding source folders (folders that should be searched
28 | # for finding modules). You can add paths to that list. Note
29 | # that rope guesses project source folders correctly most of the
30 | # time; use this if you have any problems.
31 | # The folders should be relative to project root and use '/' for
32 | # separating folders regardless of the platform rope is running on.
33 | # 'src/my_source_folder' for instance.
34 | # prefs.add('source_folders', 'src')
35 |
36 | # You can extend python path for looking up modules
37 | # prefs.add('python_path', '~/python/')
38 |
39 | # Should rope save object information or not.
40 | prefs['save_objectdb'] = True
41 | prefs['compress_objectdb'] = False
42 |
43 | # If `True`, rope analyzes each module when it is being saved.
44 | prefs['automatic_soa'] = True
45 | # The depth of calls to follow in static object analysis
46 | prefs['soa_followed_calls'] = 0
47 |
48 | # If `False` when running modules or unit tests "dynamic object
49 | # analysis" is turned off. This makes them much faster.
50 | prefs['perform_doa'] = True
51 |
52 | # Rope can check the validity of its object DB when running.
53 | prefs['validate_objectdb'] = True
54 |
55 | # How many undos to hold?
56 | prefs['max_history_items'] = 32
57 |
58 | # Shows whether to save history across sessions.
59 | prefs['save_history'] = True
60 | prefs['compress_history'] = False
61 |
62 | # Set the number spaces used for indenting. According to
63 | # :PEP:`8`, it is best to use 4 spaces. Since most of rope's
64 | # unit-tests use 4 spaces it is more reliable, too.
65 | prefs['indent_size'] = 4
66 |
67 | # Builtin and c-extension modules that are allowed to be imported
68 | # and inspected by rope.
69 | prefs['extension_modules'] = []
70 |
71 | # Add all standard c-extensions to extension_modules list.
72 | prefs['import_dynload_stdmods'] = True
73 |
74 | # If `True` modules with syntax errors are considered to be empty.
75 | # The default value is `False`; When `False` syntax errors raise
76 | # `rope.base.exceptions.ModuleSyntaxError` exception.
77 | prefs['ignore_syntax_errors'] = False
78 |
79 | # If `True`, rope ignores unresolvable imports. Otherwise, they
80 | # appear in the importing namespace.
81 | prefs['ignore_bad_imports'] = False
82 |
83 |
84 | def project_opened(project):
85 | """This function is called after opening the project"""
86 | # Do whatever you like here!
87 |
--------------------------------------------------------------------------------
/syspy/pycube/application.py:
--------------------------------------------------------------------------------
1 | import copy
2 | import os
3 | import shutil
4 |
5 |
6 | class File:
7 | def __init__(self, soup):
8 | self.soup = soup
9 | self.soup_chunks = soup.split('\n')
10 |
11 | def __repr__(self):
12 | self.makesoup()
13 | return(self.soup)
14 |
15 | def makesoup(self):
16 | self.soup = '\n'.join([chunk for chunk in self.soup_chunks])
17 |
18 |
19 | class Preface:
20 | def __init__(self, soup):
21 | self.soup = soup
22 | self.soup_chunks = soup.split('\n')
23 |
24 | def __repr__(self):
25 | self.makesoup()
26 | return(self.soup)
27 |
28 | def makesoup(self):
29 | self.soup = '\n'.join([chunk for chunk in self.soup_chunks])
30 |
31 |
32 | class Program:
33 |
34 | def __init__(self, soup):
35 | self.soup = soup
36 | self.parse()
37 |
38 | def parse(self):
39 | self.preface = Preface(self.soup.split('#')[0])
40 | self.infiles = [File('#INFIL' + chunk) for chunk in self.soup.split('#OUTFIL')[0].split('#INFIL')[1:]]
41 | self.outfiles = [File('#OUTFIL' + chunk) for chunk in self.soup.split('#OUTFIL')[1:]]
42 | self.files = self.infiles + self.outfiles
43 |
44 | def __repr__(self):
45 | self.makesoup()
46 | return self.soup
47 |
48 | def makesoup(self):
49 | self.soup = str(self.preface) + ''.join([str(file) for file in self.files])
50 |
51 |
52 | class Application:
53 |
54 | '''
55 | Contient toutes les informations caractéristiques d'une application
56 | '''
57 |
58 | def __init__(self, file_name, copy=False):
59 | self.file_name = file_name
60 | self.duplicata = file_name.split('.')[0] + '_duplicata_deleteme.' + file_name.split('.')[1]
61 | if copy:
62 | if not os.path.isfile(self.duplicata):
63 | shutil.copyfile(file_name, self.duplicata)
64 | print('copy')
65 | self.file = open(self.file_name, 'r')
66 | self.soup = self.file.read()
67 | self.file.close()
68 | self.eatsoup()
69 |
70 | def makesoup(self):
71 | self.soup = str(self.preface) + ''.join(['#PROGRAM' + str(program) for program in self.programs])
72 |
73 | def eatsoup(self):
74 | self.preface = Preface(self.soup.split('#PROGRAM')[0])
75 | self.programs = [Program(chunk) for chunk in self.soup.split('#PROGRAM')][1:]
76 |
77 | def __repr__(self):
78 | self.makesoup()
79 | return self.soup
80 |
81 | def dump(self):
82 | self.makesoup()
83 | self.file = open(self.file_name, 'w')
84 | self.file.write(self.soup)
85 | self.file.close()
86 |
87 | def addprogram(self, program):
88 | prog = copy.deepcopy(program)
89 | prog_id = len(self.programs)
90 | prog.preface.soup_chunks[0] = str(prog_id) # on indique un id du programme qui suit ceux existants
91 | prog.preface.soup_chunks[3] = str(0) # on fixe la priorité à 0
92 | prog.makesoup()
93 | self.programs.append(prog.soup)
94 |
95 | def addprograms(self, app):
96 | for program in app.programs:
97 | if 'addprograms' in program.preface.soup_chunks[12]:
98 | self.addprogram(program)
99 |
100 | def sortprograms(self):
101 | priority_zero_id = len(self.programs)
102 | for program in self.programs:
103 | if program.preface.soup_chunks[3]: # si la priorité du programme est non nulle, on l'utilise pour numéroter le programme.
104 | program.preface.soup_chunks[0] = program.preface.soup_chunks[3]
105 | else:
106 | priority_zero_id += 1
107 | program.preface.soup_chunks[0] = priority_zero_id
108 | self.makesoup()
109 |
--------------------------------------------------------------------------------
/syspy/io/pandasdbf/pandasdbf.py:
--------------------------------------------------------------------------------
1 | __author__ = 'qchasserieau'
2 |
3 | import os
4 | import pandas as pd
5 | from syspy.io.pandasdbf import exceltodbf_qc
6 |
7 |
8 | def read_dbf(path, encoding='utf-8'):
9 | """
10 | read a .dbf file, temporary write it as a csv and return a pandas.core.frame.DataFrame object.
11 |
12 | :param path: The complete path to the .dbf to read
13 | :type path: str
14 | :param encoding: The codec to use when decoding text-based records
15 | :type encoding: str
16 | :return: a pandas.DataFrame corresponding to the .dbf file
17 | :rtype: pandas.core.frame.DataFrame
18 |
19 | .. warnings:: not all encodings are handled by this function
20 | """
21 | from simpledbf import Dbf5
22 | dbf_instance = Dbf5(path, codec=encoding)
23 | csv_name = path[:-4] + '_from_dbf' + '.csv'
24 |
25 | # clear the folder from the temporary csv if necessary
26 | if os.path.isfile(csv_name):
27 | os.remove(csv_name)
28 |
29 | dbf_instance.to_csv(csv_name)
30 | df = pd.read_csv(csv_name, sep=',', encoding='Latin-1', na_values='None')
31 | os.remove(csv_name)
32 | return df
33 |
34 |
35 | def write_dbf(df, path, pre_process=True, encoding='cp850'):
36 |
37 | """
38 | write a .dbf from a pandas.core.frame.DataFrame object
39 |
40 | :param df: the DataFrame to write as a dbf
41 | :param path: The complete path to the .dbf to write
42 | :param pre_process: pre-process df with convert_stringy_things_to_string if True
43 |
44 | :type df: pandas.core.frame.DataFrame
45 | :type path: str
46 | :type pre_process: bool
47 |
48 | :return: None
49 | :rtype: NoneType
50 |
51 | .. warnings:: the length of the .dbf file cannot exceed 1 000 000 lines
52 | """
53 |
54 | inner_df = convert_stringy_things_to_string(df.copy())if pre_process else df.copy()
55 | xlsx_name = path.split('.')[0] + '_from_df' + '.xlsx' # temporary file name
56 | inner_df.to_excel(xlsx_name, index=False) # write index as a regular column.
57 | exceltodbf_qc.exceltodbf(xlsx_name, path, encoding=encoding)
58 | os.remove(xlsx_name)
59 |
60 |
61 | def normalize(frame):
62 | df = frame.copy().astype(float)
63 | for column in df.columns:
64 | weight = df[column].interpolate().sum()
65 | df[column] = df[column].interpolate() / weight
66 | return df
67 |
68 |
69 | def convert_bytes_to_string(df, debug=False, encoding='utf-8'):
70 | """
71 | returns a pandas.core.frame.DataFrame where all bytes columns are converted to string
72 |
73 | :param df: the DataFrame to convert
74 | :type df: pandas.core.frame.DataFrame
75 | :return: inner_df
76 | :rtype: pandas.core.frame.DataFrame
77 | """
78 | inner_df = df.copy()
79 | bytes_columns = [column for column in inner_df.columns if type(inner_df[column].iloc[0]) in {bytes, str}]
80 | if debug:
81 | print('bytes_columns converted to string:' + str(bytes_columns))
82 | for column in bytes_columns:
83 | try:
84 | inner_df[column] = inner_df[column].apply(to_str, args={encoding})
85 | except AttributeError:
86 | print('fail: column:', column)
87 | pass
88 | return inner_df
89 |
90 |
91 | def to_str(bor, encoding):
92 | if type(bor) == str:
93 | return bor
94 | else:
95 | return bor.decode(encoding=encoding, errors='strict')
96 |
97 |
98 | def convert_stringy_things_to_string(df, debug=False):
99 | """
100 | returns a pandas.core.frame.DataFrame where all bytes columns are converted to string
101 |
102 | :param df: the DataFrame to convert
103 | :type df: pandas.core.frame.DataFrame
104 | :return: inner_df
105 | :rtype: pandas.core.frame.DataFrame
106 | """
107 | inner_df = convert_bytes_to_string(df).copy()
108 | stringy_columns = [column for column in inner_df.columns if type(inner_df[column].iloc[0]) == str]
109 | if debug:
110 | print('stringy_columns converted to string:' + str(stringy_columns))
111 | inner_df[stringy_columns] = inner_df[stringy_columns].astype(str)
112 | return inner_df
113 |
114 |
115 | def clean_dbf(path):
116 | write_dbf(read_dbf(path), path, pre_process=True)
117 |
--------------------------------------------------------------------------------