diff --git a/.github/workflows/build_pipeline.yml b/.github/workflows/build_pipeline.yml deleted file mode 100644 index 30562847..00000000 --- a/.github/workflows/build_pipeline.yml +++ /dev/null @@ -1,86 +0,0 @@ -name: CI - -on: [push] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-python@v1 - with: - python-version: 3.11 - - uses: actions/cache@v1 - with: - path: ~/.cache/pip - key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} - restore-keys: | - ${{ runner.os }}-pip- - - name: Install dependencies - run: | - export ACCEPT_EULA=Y - sudo apt-get update - python -m pip install --upgrade pip - sudo apt-get install -y python3-pip libgdal-dev locales - sudo apt-get install -y libspatialindex-dev - sudo apt-get install -y coinor-cbc - export CPLUS_INCLUDE_PATH=/usr/include/gdal - export C_INCLUDE_PATH=/usr/include/gdal - sudo apt-get install ca-certificates - export CURL_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt - pip install GDAL==3.4.1 - pip install -e '.[dev]' - - - name: Install jupyter kernel - run: python -m ipykernel install --user --name genet - - - name: Unit tests - run: pytest - - - name: Configure AWS credentials - uses: aws-actions/configure-aws-credentials@v1 - with: - aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} - aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - aws-region: eu-west-1 - - name: Push zip to S3 - env: - AWS_S3_CODE_BUCKET: ${{ secrets.AWS_S3_CODE_BUCKET }} - run: | - echo $GITHUB_REPOSITORY - echo $GITHUB_SHA - echo $GITHUB_SHA > release - if test "$GITHUB_REF" = "refs/heads/main"; then - echo "Branch is main - no need to make a release name..." - else - echo "Making a release name for non-main branch..." - branch=`echo $GITHUB_REF | awk -F '/' '{print $3}'` - release_name=`echo $GITHUB_ACTOR-$branch` - echo "Release name: $release_name" - echo $release_name > release_name - fi - zip -r app.zip . - repo_slug=`echo $GITHUB_REPOSITORY | awk -F '/' '{print $2}'` - echo $repo_slug - aws s3 cp app.zip "s3://$AWS_S3_CODE_BUCKET/$repo_slug.zip" - - name: Send build success notification - if: success() - uses: rtCamp/action-slack-notify@v2.2.0 - env: - SLACK_MESSAGE: ${{ github.repository }} build ${{ github.run_number }} launched by ${{ github.actor }} has succeeded - SLACK_TITLE: Build Success - SLACK_CHANNEL: city-modelling-feeds - SLACK_USERNAME: GitHub Build Bot - SLACK_ICON: https://slack-files2.s3-us-west-2.amazonaws.com/avatars/2017-12-19/288981919427_f45f04edd92902a96859_512.png - SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} - - name: Send build failure notification - if: failure() - uses: rtCamp/action-slack-notify@v2.2.0 - env: - SLACK_COLOR: '#FF0000' - SLACK_MESSAGE: ${{ github.repository }} build ${{ github.run_number }} launched by ${{ github.actor }} has failed - SLACK_TITLE: Build Failure! - SLACK_CHANNEL: city-modelling-feeds - SLACK_USERNAME: GitHub Build Bot - SLACK_ICON: https://slack-files2.s3-us-west-2.amazonaws.com/avatars/2017-12-19/288981919427_f45f04edd92902a96859_512.png - SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} diff --git a/.github/workflows/commit-ci.yml b/.github/workflows/commit-ci.yml new file mode 100644 index 00000000..f87bca3a --- /dev/null +++ b/.github/workflows/commit-ci.yml @@ -0,0 +1,32 @@ +name: Minimal CI + +on: + push: + branches: + - "**" + paths-ignore: + - README.md + - CHANGELOG.md + - LICENSE + - CONTRIBUTING.md + - docs/** + - mkdocs.yml + +jobs: + test: + uses: arup-group/actions-city-modelling-lab/.github/workflows/python-install-lint-test.yml@main + with: + os: ubuntu-latest + py3version: "11" + notebook_kernel: genet + lint: false + additional_mamba_args: coin-or-cbc + + aws-upload: + needs: test + if: needs.test.result == 'success' + uses: arup-group/actions-city-modelling-lab/.github/workflows/aws-upload.yml@main + secrets: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + AWS_S3_CODE_BUCKET: ${{ secrets.AWS_S3_CODE_BUCKET }} \ No newline at end of file diff --git a/.github/workflows/daily-scheduled-ci.yml b/.github/workflows/daily-scheduled-ci.yml index 911cd6e6..179a7935 100644 --- a/.github/workflows/daily-scheduled-ci.yml +++ b/.github/workflows/daily-scheduled-ci.yml @@ -1,69 +1,36 @@ -name: Daily GeNet CI Build +name: Daily CI on: schedule: - - cron: '37 14 * * 1-5' + - cron: '37 14 * * 1-5' # checks on the 37th minute of the 14th hour every weekday jobs: - build: + get-date: runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v3 - - - uses: actions/setup-python@v1 - with: - python-version: 3.11 - - - uses: actions/cache@v1 - with: - path: ~/.cache/pip - key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} - restore-keys: | - ${{ runner.os }}-pip- - - - name: Install dependencies - run: | - export ACCEPT_EULA=Y - sudo apt-get update - python -m pip install --upgrade pip - sudo apt-get install -y python3-pip libgdal-dev locales - sudo apt-get install -y libspatialindex-dev - sudo apt-get install -y coinor-cbc - export CPLUS_INCLUDE_PATH=/usr/include/gdal - export C_INCLUDE_PATH=/usr/include/gdal - sudo apt-get install ca-certificates - export CURL_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt - pip install GDAL==3.4.1 - pip install -e '.[dev]' - - - name: Install jupyter kernel - run: python -m ipykernel install --user --name genet - - - name: Run tests - run: pytest - - - name: Send build success notification - if: success() - uses: rtCamp/action-slack-notify@v2.2.0 - env: - SLACK_MESSAGE: ${{ github.repository }} Daily scheduled CI Build ${{ github.run_number }} has succeeded - SLACK_TITLE: Daily Scheduled CI Build Success - SLACK_CHANNEL: city-modelling-feeds - SLACK_USERNAME: GitHub Build Bot - SLACK_ICON: https://slack-files2.s3-us-west-2.amazonaws.com/avatars/2017-12-19/288981919427_f45f04edd92902a96859_512.png - SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} - - - name: Send build failure notification - if: failure() - uses: rtCamp/action-slack-notify@v2.2.0 - env: - SLACK_COLOR: '#FF0000' - SLACK_LINK_NAMES: true - SLACK_MESSAGE: ' ${{ github.repository }} Daily scheduled CI Build ${{ github.run_number }} has failed' - SLACK_TITLE: Daily Scheduled CI Build Failure! - SLACK_CHANNEL: city-modelling-feeds - SLACK_USERNAME: GitHub Build Bot - SLACK_ICON: https://slack-files2.s3-us-west-2.amazonaws.com/avatars/2017-12-19/288981919427_f45f04edd92902a96859_512.png - SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} + - name: Add date to github output env + run: echo "DATE=$(date +'%Y-%m-%d')" >> $GITHUB_OUTPUT + + test: + needs: get-date + uses: arup-group/actions-city-modelling-lab/.github/workflows/python-install-lint-test.yml@main + with: + os: ubuntu-latest + py3version: "11" + notebook_kernel: genet + pytest_args: '--no-cov' # ignore coverage + cache_mamba_env: false + lint: false + mamba_env_name: daily-ci + additional_mamba_args: coin-or-cbc + + slack-notify-ci: + needs: test + if: always() + uses: arup-group/actions-city-modelling-lab/.github/workflows/slack-notify.yml@main + secrets: + SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} + with: + result: needs.test.result + channel: genet-feed + message: Daily CI action \ No newline at end of file diff --git a/.github/workflows/pr-ci.yml b/.github/workflows/pr-ci.yml new file mode 100644 index 00000000..fe54113e --- /dev/null +++ b/.github/workflows/pr-ci.yml @@ -0,0 +1,48 @@ +name: Pull Request CI + +on: + pull_request: + branches: + - main + paths-ignore: + - README.md + - CHANGELOG.md + - LICENSE + - CONTRIBUTING.md + - docs/** + - mkdocs.yml + +jobs: + test: + strategy: + matrix: + os: [windows-latest, ubuntu-latest, macos-latest] + py3version: ["9", "11"] + include: + - os: windows-latest + add_args: "" + - os: ubuntu-latest + add_args: coin-or-cbc + - os: macos-latest + add_args: coin-or-cbc + fail-fast: false + uses: arup-group/actions-city-modelling-lab/.github/workflows/python-install-lint-test.yml@main + with: + os: ${{ matrix.os }} + py3version: ${{ matrix.py3version }} + notebook_kernel: genet + lint: false + pytest_args: '--no-cov' # ignore coverage + upload_to_codecov: false + additional_mamba_args: ${{ matrix.add_args }} + + test-coverage: + uses: arup-group/actions-city-modelling-lab/.github/workflows/python-install-lint-test.yml@main + with: + os: ubuntu-latest + py3version: "11" + notebook_kernel: genet + lint: false + pytest_args: 'tests/' # ignore example notebooks + upload_to_codecov: true + additional_mamba_args: coin-or-cbc diff --git a/Dockerfile b/Dockerfile index 113996ab..0ba4ff60 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,13 +1,11 @@ -FROM python:3.11.4-bullseye +FROM mambaorg/micromamba:1.5.3-bullseye-slim -RUN apt-get update && \ -apt-get upgrade -y && \ -apt-get -y install gcc git libgdal-dev libgeos-dev libspatialindex-dev curl coinor-cbc cmake && \ -rm -rf /var/lib/apt/lists/* +COPY --chown=$MAMBA_USER:$MAMBA_USER . ./src -RUN python -m pip install --no-cache-dir --compile --upgrade pip +RUN micromamba install -y -n base -c conda-forge -c city-modelling-lab python=3.11 "proj>=9.3" pip coin-or-cbc --file src/requirements/base.txt && \ + micromamba clean --all --yes +ARG MAMBA_DOCKERFILE_ACTIVATE=1 -COPY . ./src - -RUN pip3 install --no-cache-dir --compile -e ./src && pip cache purge +RUN pip install --no-deps ./src +ENTRYPOINT ["/usr/local/bin/_entrypoint.sh"] \ No newline at end of file diff --git a/README.md b/README.md index bf5bfb77..2ac6b5ac 100644 --- a/README.md +++ b/README.md @@ -10,18 +10,12 @@ + [Building the image](#build-the-image) + [Running GeNet from the container](#running-a-container-with-a-pre-baked-script) * [Installation as a Python Package](#installation-as-a-python-package) - + [Native dependencies](#native-dependencies) + + [Installing a development environment](#installing-a-development-environment) + [A note on the mathematical solver](#a-note-on-the-mathematical-solver) - + [Installing the native dependencies](#installing-the-native-dependencies) - + [Install dev prereqs](#install-dev-prereqs) - + [Install Python dependencies](#install-python-dependencies) - + [Install GeNet in to the virtual environment](#install-genet-in-to-the-virtual-environment) - + [Install Kepler dependencies](#install-kepler-dependencies) - [Developing GeNet](#developing-genet) * [Unit tests](#unit-tests) * [Code coverage report](#generate-a-unit-test-code-coverage-report) * [Linting](#lint-the-python-code) - * [Smoke testing Jupyter notebooks](#smoke-test-the-jupyter-notebooks) ## Overview @@ -114,85 +108,59 @@ as part of your command: Note, if you reference data inside your script, or pass them as arguments to the script, they need to reference the aliased path inside the container, here: `/mnt/`, rather than the path `/local/path/`. -### Installation as a Python Package / CLI +### Installation as a Python Package -You can in your base installation of python or a virtual environment. You can use GeNet's CLI to run pre-baked modifications or checks on networks. -You can also write your own python scripts, importing genet as a package, use IPython shell or Jupyter Notebook to load -up a network, inspect or change it and save it out to file. Check out the -[wiki pages](https://github.com/arup-group/genet/wiki/Functionality-and-Usage-Guide) and -[example jupyter notebooks](https://github.com/arup-group/genet/tree/master/notebooks) -for usage examples. - -**Note:** if you plan only to _use_ GeNet rather than make code changes to it, you can avoid having to perform any -local installation by using [GeNet's Docker image](#using-docker). If you are going to make code changes or use GeNet's -CLI locally, follow the steps below: - -#### Native dependencies -GeNet uses some Python libraries that rely on underlying native libraries for things like geospatial calculations and -linear programming solvers. Before you install GeNet's Python dependencies, you must first install these native -libraries. +You can also write your own python scripts, importing genet as a package, use IPython shell or Jupyter Notebook to load up a network, inspect or change it and save it out to file. +Check out the [wiki pages](https://github.com/arup-group/genet/wiki/Functionality-and-Usage-Guide) and [example jupyter notebooks](https://github.com/arup-group/genet/tree/master/notebooks) for usage examples. + +**Note:** if you plan only to _use_ GeNet rather than make code changes to it, you can ignore the rest of this section and instead use [GeNet's Docker image](#using-docker). +If you are going to make code changes or use GeNet's CLI locally, follow the steps below to [install a development environment](#installing-a-development-environment). + +### Installing a development environment + +To create a development environment for genet, with all libraries required for development and quality assurance installed, it is easiest to install genet using the [mamba](https://mamba.readthedocs.io/en/latest/index.html) package manager, as follows: + +1. Install mamba with the [Mambaforge](https://github.com/conda-forge/miniforge#mambaforge) executable for your operating system. +2. Open the command line (or the "miniforge prompt" in Windows). +3. Download (a.k.a., clone) the genet repository: `git clone git@github.com:arup-group/genet.git` +4. Change into the `genet` directory: `cd genet` +5. Create the genet mamba environment: `mamba create -n genet -c conda-forge -c city-modelling-lab --file requirements/base.txt --file requirements/dev.txt` +6. Activate the genet mamba environment: `mamba activate genet` +7. Install the genet package into the environment, in editable mode and ignoring dependencies (we have dealt with those when creating the mamba environment): `pip install --no-deps -e .` +8. Create a jupyter kernel linked to the environment to enable example notebook testing: `ipython kernel install --user --name=genet` + +All together: +``` shell +git clone git@github.com:arup-group/genet.git +cd genet +mamba create -n genet -c conda-forge -c city-modelling-lab --file requirements/base.txt --file requirements/dev.txt +mamba activate genet +pip install --no-deps -e . +ipython kernel install --user --name=genet +``` #### A note on the mathematical solver + **Note**: The default CBC solver is pre-installed inside [GeNet's Docker image](#using-docker), which can save you some installation effort -To use methods which snap public transit to the graph, GeNet uses a mathematical solver. If you won't be using such -functionality, you do not need to install this solver. +To use methods which snap public transit to the graph, GeNet uses a mathematical solver. +If you won't be using such functionality, you do not need to install this solver. Methods default to [CBC](https://projects.coin-or.org/Cbc), an open source solver. +You can install this solver (`coin-or-cbc`) along with your other requirements when creating the environment: `mamba create -n genet -c conda-forge -c city-modelling-lab coin-or-cbc --file requirements/base.txt --file requirements/dev.txt`, +or install it after the fact `mamba install -n genet coin-or-cbc` + Another good open source choice is [GLPK](https://www.gnu.org/software/glpk/). The solver you use needs to support MILP - mixed integer linear programming. -#### Installing the native dependencies -The commands for installing the necessary native libraries vary according to the operating system you are using, for -example: - -| OS | Commands | -|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -|Mac OS | `brew install boost`
`brew install spatialindex`
`brew install gdal --HEAD`
`brew install gdal`
`brew tap coin-or-tools/coinor`
`brew install coin-or-tools/coinor/cbc`
`brew install cbc` | -|Ubuntu | `sudo apt install libspatialindex-dev`
`sudo apt install libgdal-dev`
`sudo apt install coinor-cbc` | - -#### Install dev prereqs -(Use equivalent linux or Windows package management as appropriate for your environment) - - brew install python3.11 - brew install virtualenv - -#### Install Python dependencies -Create and activate a Python virtual environment - - virtualenv -p python3.11 venv - source venv/bin/activate - -#### Install GeNet in to the virtual environment -Finally, install `GeNet`'s Python dependencies - - pip install -e . - -After installation, you should be able to successfully run the help command to see all possible commands: - - genet --help - -To inspect a specific command, run e.g.: - - genet simplify-network --help - -#### Install Kepler dependencies - -Please follow [kepler's installation instructions](https://docs.kepler.gl/docs/keplergl-jupyter#install) to be able to -use the visualisation methods. To see the maps in a jupyter notebook, make sure you enable widgets. -``` -jupyter nbextension enable --py widgetsnbextension -``` - ## Developing GeNet -We welcome community contributions to GeNet; please see our [guide to contributing](CONTRIBUTING.md) and our -[community code of conduct](CODE_OF_CONDUCT.md). If you are making changes to the codebase, you should use the tools -described below to verify that the code still works. All of the following commands assume you are in the project's root -directory. +We welcome community contributions to GeNet; please see our [guide to contributing](CONTRIBUTING.md) and our [community code of conduct](CODE_OF_CONDUCT.md). +If you are making changes to the codebase, you should use the tools described below to verify that the code still works. +All of the following commands assume you are in the project's root directory. -### tests +### Tests To run unit tests within genet python environment (including testing example notebooks): pytest diff --git a/examples/4_3_using_network_routing.ipynb b/examples/4_3_using_network_routing.ipynb index f30239cb..43fdd5c7 100644 --- a/examples/4_3_using_network_routing.ipynb +++ b/examples/4_3_using_network_routing.ipynb @@ -25,12 +25,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Graph info: Name: \n", - "Type: MultiDiGraph\n", - "Number of nodes: 1662\n", - "Number of edges: 3166\n", - "Average in degree: 1.9049\n", - "Average out degree: 1.9049 \n", + "Graph info: MultiDiGraph with 1662 nodes and 3166 edges \n", "Schedule info: Schedule:\n", "Number of services: 9\n", "Number of routes: 68\n", @@ -40,6 +35,7 @@ ], "source": [ "import os\n", + "import shutil\n", "\n", "from genet import read_matsim\n", "\n", @@ -267,9 +263,9 @@ "name": "stderr", "output_type": "stream", "text": [ - "2022-07-14 15:40:37,681 - Checking `linkRefId`s of the Route: `VJ375a660d47a2aa570aa20a8568012da8497ffecf` are present in the graph\n", - "2022-07-14 15:40:37,685 - Rerouting Route `VJ375a660d47a2aa570aa20a8568012da8497ffecf`\n", - "2022-07-14 15:40:37,784 - Changed Route attributes for 1 routes\n" + "2023-12-08 13:44:17,450 - Checking `linkRefId`s of the Route: `VJ375a660d47a2aa570aa20a8568012da8497ffecf` are present in the graph\n", + "2023-12-08 13:44:17,451 - Rerouting Route `VJ375a660d47a2aa570aa20a8568012da8497ffecf`\n", + "2023-12-08 13:44:17,492 - Changed Route attributes for 1 routes\n" ] } ], @@ -298,26 +294,29 @@ "name": "stderr", "output_type": "stream", "text": [ - "2022-07-14 15:40:40,387 - Routing Service 20274 with modes = {'bus'}\n", - "2022-07-14 15:40:40,429 - Building Maximum Stable Set for PT graph with 8 stops and 6 edges\n", - "2022-07-14 15:40:40,896 - Passing problem to solver\n", - "2022-07-14 15:40:40,898 - Initializing ordered Set vertices with a fundamentally unordered data source (type: set). This WILL potentially lead to nondeterministic behavior in Pyomo\n", - "2022-07-14 15:40:40,915 - Passing problem to solver\n", - "2022-07-14 15:40:41,597 - Stop ID changes detected for Routes: {'VJ375a660d47a2aa570aa20a8568012da8497ffecf', 'VJ6c64ab7b477e201cae950efde5bd0cb4e2e8888e', 'VJ812fad65e7fa418645b57b446f00cba573f2cdaf'}\n", - "2022-07-14 15:40:41,601 - Changed Route attributes for 3 routes\n", - "2022-07-14 15:40:41,608 - Changed Link attributes for 41 links\n" + "2023-12-08 13:44:18,258 - Routing Service 20274 with modes = {'bus'}\n", + "2023-12-08 13:44:18,274 - Building Maximum Stable Set for PT graph with 8 stops and 6 edges\n", + "2023-12-08 13:44:18,338 - Passing problem to solver\n", + "2023-12-08 13:44:18,339 - Initializing ordered Set vertices with a fundamentally unordered data source (type: set). This WILL potentially lead to nondeterministic behavior in Pyomo\n", + "2023-12-08 13:44:18,343 - Passing problem to solver\n", + "2023-12-08 13:44:18,838 - Stop ID changes detected for Routes: {'VJ6c64ab7b477e201cae950efde5bd0cb4e2e8888e', 'VJ812fad65e7fa418645b57b446f00cba573f2cdaf', 'VJ375a660d47a2aa570aa20a8568012da8497ffecf'}\n", + "2023-12-08 13:44:18,841 - Changed Route attributes for 3 routes\n", + "2023-12-08 13:44:18,845 - Changed Link attributes for 41 links\n" ] } ], "source": [ - "n.route_service(\"20274\", additional_modes={\"car\"})" + "if shutil.which(\"cbc\"):\n", + " n.route_service(\"20274\", additional_modes={\"car\"})\n", + "else:\n", + " print(\"Cannot route service without a solver installed\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "If you are creating a `Network` and want to snap and route the entire `Schedule`, or a larger number of services, the method `route_schedule` is advised. Bear in mind though that it will struggle with large networks and big and complicated schedules. Similar parameters apply to this method as the one abov" + "If you are creating a `Network` and want to snap and route the entire `Schedule`, or a larger number of services, the method `route_schedule` is advised. Bear in mind though that it will struggle with large networks and big and complicated schedules. Similar parameters apply to this method as the one above, and a solver is needed to undertake the routing." ] }, { @@ -334,32 +333,35 @@ "name": "stderr", "output_type": "stream", "text": [ - "2022-07-14 15:40:41,615 - Building Spatial Tree\n", - "2022-07-14 15:40:43,833 - Extracting Modal SubTree for modes: {'bus'}\n", - "2022-07-14 15:40:43,882 - Routing Service 15660 with modes = {'bus'}\n", - "2022-07-14 15:40:43,884 - Building Maximum Stable Set for PT graph with 5 stops and 3 edges\n", - "2022-07-14 15:40:44,283 - This Maximum Stable Set Problem is partially viable.\n", - "2022-07-14 15:40:44,284 - Maximum Stable Set problem to snap the PT graph to the network is partially viable, meaning not all stops have found a link to snap to within the distance_threshold.Partial snapping is ON, this problem will proceed to the solver.\n", - "2022-07-14 15:40:44,285 - Passing problem to solver\n", - "2022-07-14 15:40:44,286 - Initializing ordered Set vertices with a fundamentally unordered data source (type: set). This WILL potentially lead to nondeterministic behavior in Pyomo\n", - "2022-07-14 15:40:44,288 - Passing problem to solver\n", - "2022-07-14 15:40:44,383 - Successfully snapped 4 stops to network links.\n", - "2022-07-14 15:40:44,408 - Routing Service 20274 with modes = {'bus'}\n", - "2022-07-14 15:40:44,410 - Building Maximum Stable Set for PT graph with 8 stops and 6 edges\n", - "2022-07-14 15:40:44,673 - Passing problem to solver\n", - "2022-07-14 15:40:44,674 - Initializing ordered Set vertices with a fundamentally unordered data source (type: set). This WILL potentially lead to nondeterministic behavior in Pyomo\n", - "2022-07-14 15:40:44,677 - Passing problem to solver\n", - "2022-07-14 15:40:44,790 - Stop ID changes detected for Routes: {'VJ375a660d47a2aa570aa20a8568012da8497ffecf', 'VJ6c64ab7b477e201cae950efde5bd0cb4e2e8888e', 'VJ812fad65e7fa418645b57b446f00cba573f2cdaf', 'VJ3716910ec59c370d9f5c69137df7276b68cf0a08', 'VJ1cf651142378958b52229bfe1fa552e49136e60e', 'VJf2e0de4f5dad68cb03064e6064e372dde52cc678'}\n", - "2022-07-14 15:40:44,804 - Changed Route attributes for 6 routes\n", - "2022-07-14 15:40:44,813 - Added 1 nodes\n", - "2022-07-14 15:40:45,325 - Generated 0 link ids.\n", - "2022-07-14 15:40:45,341 - Added 2 links\n", - "2022-07-14 15:40:45,364 - Changed Link attributes for 53 links\n" + "2023-12-08 13:44:18,854 - Building Spatial Tree\n", + "2023-12-08 13:44:19,530 - Extracting Modal SubTree for modes: {'bus'}\n", + "2023-12-08 13:44:19,544 - Routing Service 20274 with modes = {'bus'}\n", + "2023-12-08 13:44:19,545 - Building Maximum Stable Set for PT graph with 8 stops and 6 edges\n", + "2023-12-08 13:44:19,589 - Passing problem to solver\n", + "2023-12-08 13:44:19,590 - Initializing ordered Set vertices with a fundamentally unordered data source (type: set). This WILL potentially lead to nondeterministic behavior in Pyomo\n", + "2023-12-08 13:44:19,592 - Passing problem to solver\n", + "2023-12-08 13:44:19,696 - Routing Service 15660 with modes = {'bus'}\n", + "2023-12-08 13:44:19,698 - Building Maximum Stable Set for PT graph with 5 stops and 3 edges\n", + "2023-12-08 13:44:19,753 - This Maximum Stable Set Problem is partially viable.\n", + "2023-12-08 13:44:19,754 - Maximum Stable Set problem to snap the PT graph to the network is partially viable, meaning not all stops have found a link to snap to within the distance_threshold.Partial snapping is ON, this problem will proceed to the solver.\n", + "2023-12-08 13:44:19,754 - Passing problem to solver\n", + "2023-12-08 13:44:19,755 - Initializing ordered Set vertices with a fundamentally unordered data source (type: set). This WILL potentially lead to nondeterministic behavior in Pyomo\n", + "2023-12-08 13:44:19,756 - Passing problem to solver\n", + "2023-12-08 13:44:19,821 - Successfully snapped 4 stops to network links.\n", + "2023-12-08 13:44:19,830 - Stop ID changes detected for Routes: {'VJf2e0de4f5dad68cb03064e6064e372dde52cc678', 'VJ6c64ab7b477e201cae950efde5bd0cb4e2e8888e', 'VJ812fad65e7fa418645b57b446f00cba573f2cdaf', 'VJ375a660d47a2aa570aa20a8568012da8497ffecf', 'VJ3716910ec59c370d9f5c69137df7276b68cf0a08', 'VJ1cf651142378958b52229bfe1fa552e49136e60e'}\n", + "2023-12-08 13:44:19,834 - Changed Route attributes for 6 routes\n", + "2023-12-08 13:44:19,838 - Added 1 nodes\n", + "2023-12-08 13:44:19,900 - Generated 0 link ids.\n", + "2023-12-08 13:44:19,903 - Added 2 links\n", + "2023-12-08 13:44:19,907 - Changed Link attributes for 53 links\n" ] } ], "source": [ - "unsnapped_service_ids = n.route_schedule(services=[\"20274\", \"15660\"])" + "if shutil.which(\"cbc\"):\n", + " unsnapped_service_ids = n.route_schedule(services=[\"20274\", \"15660\"])\n", + "else:\n", + " print(\"Cannot route schedule without a solver installed\")" ] }, { @@ -383,11 +385,11 @@ "name": "stderr", "output_type": "stream", "text": [ - "2022-07-14 15:40:45,436 - Added 0 nodes\n", - "2022-07-14 15:40:45,858 - Generated 0 link ids.\n", - "2022-07-14 15:40:45,866 - Added 8 links\n", - "2022-07-14 15:40:45,869 - Changed Stop attributes for 10 stops\n", - "2022-07-14 15:40:45,874 - Changed Route attributes for 2 routes\n" + "2023-12-08 13:44:19,925 - Added 0 nodes\n", + "2023-12-08 13:44:19,969 - Generated 0 link ids.\n", + "2023-12-08 13:44:19,973 - Added 8 links\n", + "2023-12-08 13:44:19,975 - Changed Stop attributes for 10 stops\n", + "2023-12-08 13:44:19,977 - Changed Route attributes for 2 routes\n" ] } ], @@ -481,13 +483,20 @@ "source": [ "list(n.schedule[\"17732\"].routes())[0].route" ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { "kernelspec": { - "display_name": "genet", + "display_name": "genet-new", "language": "python", - "name": "genet" + "name": "python3" }, "language_info": { "codemirror_mode": { @@ -499,7 +508,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.7" + "version": "3.11.6" }, "latex_envs": { "LaTeX_envs_menu_present": true, diff --git a/examples/5_2_modifying_network_pt_schedule.ipynb b/examples/5_2_modifying_network_pt_schedule.ipynb index 0c0697ac..3a3c9c90 100644 --- a/examples/5_2_modifying_network_pt_schedule.ipynb +++ b/examples/5_2_modifying_network_pt_schedule.ipynb @@ -23,12 +23,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Graph info: Name: \n", - "Type: MultiDiGraph\n", - "Number of nodes: 1662\n", - "Number of edges: 3166\n", - "Average in degree: 1.9049\n", - "Average out degree: 1.9049 \n", + "Graph info: MultiDiGraph with 1662 nodes and 3166 edges \n", "Schedule info: Schedule:\n", "Number of services: 9\n", "Number of routes: 68\n", @@ -39,6 +34,7 @@ "source": [ "# read example network\n", "import os\n", + "import shutil\n", "\n", "from genet import Route, Service, Stop, read_matsim\n", "\n", @@ -222,7 +218,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "2022-07-14 15:49:53,678 - Added Services with IDs `['new_service']` and Routes: [['new_route']]\n" + "2023-12-08 13:44:17,452 - Added Services with IDs `['new_service']` and Routes: [['new_route']]\n" ] } ], @@ -244,10 +240,10 @@ "name": "stderr", "output_type": "stream", "text": [ - "2022-07-14 15:49:54,010 - Route with ID `new_route` for Service 20274 within already exists in the Schedule. This Route will be reindexed to `20274_4`\n", - "2022-07-14 15:49:54,016 - Reindexed Route from new_route to 20274_4\n", - "2022-07-14 15:49:54,018 - Added Routes with IDs ['20274_4'], to Services `['20274']` within the Schedule\n", - "/Users/kasia.kozlowska/PycharmProjects/ABM/genet/genet/schedule_elements.py:1384: UserWarning: DataFrame columns are not unique, some columns will be omitted.\n", + "2023-12-08 13:44:17,570 - Route with ID `new_route` for Service 20274 within already exists in the Schedule. This Route will be reindexed to `20274_4`\n", + "2023-12-08 13:44:17,573 - Reindexed Route from new_route to 20274_4\n", + "2023-12-08 13:44:17,575 - Added Routes with IDs ['20274_4'], to Services `['20274']` within the Schedule\n", + "/Users/bryn.pickering/Repos/arup-group/genet/genet/schedule_elements.py:1803: UserWarning: DataFrame columns are not unique, some columns will be omitted.\n", " self.vehicles = {**df.T.to_dict(), **self.vehicles}\n" ] } @@ -380,7 +376,9 @@ "name": "stderr", "output_type": "stream", "text": [ - "2022-07-14 15:49:54,284 - Added Routes with IDs ['another_new_route'], to Services `['20274']` within the Schedule\n" + "2023-12-08 13:44:17,731 - Added Routes with IDs ['another_new_route'], to Services `['20274']` within the Schedule\n", + "/Users/bryn.pickering/Repos/arup-group/genet/genet/schedule_elements.py:1803: UserWarning: DataFrame columns are not unique, some columns will be omitted.\n", + " self.vehicles = {**df.T.to_dict(), **self.vehicles}\n" ] } ], @@ -448,7 +446,9 @@ "name": "stderr", "output_type": "stream", "text": [ - "2022-07-14 15:49:54,612 - Added Routes with IDs ['another_new_route_2'], to Services `['20274']` within the Schedule\n" + "2023-12-08 13:44:17,959 - Added Routes with IDs ['another_new_route_2'], to Services `['20274']` within the Schedule\n", + "/Users/bryn.pickering/Repos/arup-group/genet/genet/schedule_elements.py:1803: UserWarning: DataFrame columns are not unique, some columns will be omitted.\n", + " self.vehicles = {**df.T.to_dict(), **self.vehicles}\n" ] } ], @@ -494,8 +494,10 @@ "name": "stderr", "output_type": "stream", "text": [ - "2022-07-14 15:49:54,944 - The following stops will inherit the data currently stored under those Stop IDs in the Schedule: ['490000235X.link:834', '490010689KB.link:981'].\n", - "2022-07-14 15:49:54,946 - Added Routes with IDs ['another_new_route_3'], to Services `['20274']` within the Schedule\n" + "2023-12-08 13:44:18,133 - The following stops will inherit the data currently stored under those Stop IDs in the Schedule: ['490000235X.link:834', '490010689KB.link:981'].\n", + "2023-12-08 13:44:18,135 - Added Routes with IDs ['another_new_route_3'], to Services `['20274']` within the Schedule\n", + "/Users/bryn.pickering/Repos/arup-group/genet/genet/schedule_elements.py:1803: UserWarning: DataFrame columns are not unique, some columns will be omitted.\n", + " self.vehicles = {**df.T.to_dict(), **self.vehicles}\n" ] } ], @@ -546,7 +548,7 @@ { "data": { "text/plain": [ - "13293" + "1566" ] }, "execution_count": 16, @@ -567,7 +569,16 @@ "start_time": "2022-07-14T14:49:55.186816Z" } }, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/bryn.pickering/Repos/arup-group/genet/genet/schedule_elements.py:1803: UserWarning: DataFrame columns are not unique, some columns will be omitted.\n", + " self.vehicles = {**df.T.to_dict(), **self.vehicles}\n" + ] + } + ], "source": [ "n.schedule.generate_vehicles()" ] @@ -586,8 +597,8 @@ "name": "stderr", "output_type": "stream", "text": [ - "2022-07-14 15:49:55,588 - The following vehicle types are missing from the `vehicle_types` attribute: {'bus'}\n", - "2022-07-14 15:49:55,589 - Vehicles affected by missing vehicle types: {'fun_bus_1': {'type': 'bus'}, 'fun_bus_2': {'type': 'bus'}, 'some_bus_2': {'type': 'bus'}}\n" + "2023-12-08 13:44:18,335 - The following vehicle types are missing from the `vehicle_types` attribute: {'bus'}\n", + "2023-12-08 13:44:18,337 - Vehicles affected by missing vehicle types: {'fun_bus_1': {'type': 'bus'}, 'fun_bus_2': {'type': 'bus'}, 'some_bus_2': {'type': 'bus'}}\n" ] }, { @@ -618,7 +629,7 @@ { "data": { "text/plain": [ - "13293" + "1566" ] }, "execution_count": 19, @@ -674,7 +685,7 @@ " \n", " \n", " 0\n", - " 2022-07-14 15:49:53\n", + " 2023-12-08 13:44:17\n", " add\n", " service\n", " None\n", @@ -685,7 +696,7 @@ " \n", " \n", " 1\n", - " 2022-07-14 15:49:54\n", + " 2023-12-08 13:44:17\n", " add\n", " route\n", " None\n", @@ -696,7 +707,7 @@ " \n", " \n", " 2\n", - " 2022-07-14 15:49:54\n", + " 2023-12-08 13:44:17\n", " add\n", " route\n", " None\n", @@ -707,7 +718,7 @@ " \n", " \n", " 3\n", - " 2022-07-14 15:49:54\n", + " 2023-12-08 13:44:17\n", " add\n", " route\n", " None\n", @@ -718,7 +729,7 @@ " \n", " \n", " 4\n", - " 2022-07-14 15:49:54\n", + " 2023-12-08 13:44:18\n", " add\n", " route\n", " None\n", @@ -733,11 +744,11 @@ ], "text/plain": [ " timestamp change_event object_type old_id new_id \\\n", - "0 2022-07-14 15:49:53 add service None new_service \n", - "1 2022-07-14 15:49:54 add route None 20274_4 \n", - "2 2022-07-14 15:49:54 add route None another_new_route \n", - "3 2022-07-14 15:49:54 add route None another_new_route_2 \n", - "4 2022-07-14 15:49:54 add route None another_new_route_3 \n", + "0 2023-12-08 13:44:17 add service None new_service \n", + "1 2023-12-08 13:44:17 add route None 20274_4 \n", + "2 2023-12-08 13:44:17 add route None another_new_route \n", + "3 2023-12-08 13:44:17 add route None another_new_route_2 \n", + "4 2023-12-08 13:44:18 add route None another_new_route_3 \n", "\n", " old_attributes new_attributes \\\n", "0 None {'id': 'new_service', 'name': 'N55'} \n", @@ -852,25 +863,28 @@ "name": "stderr", "output_type": "stream", "text": [ - "2022-07-14 15:49:57,865 - Routing Service new_service with modes = {'bus'}\n", - "2022-07-14 15:49:57,899 - Building Maximum Stable Set for PT graph with 4 stops and 3 edges\n", - "2022-07-14 15:49:58,036 - This Maximum Stable Set Problem is partially viable.\n", - "2022-07-14 15:49:58,037 - Maximum Stable Set problem to snap the PT graph to the network is partially viable, meaning not all stops have found a link to snap to within the distance_threshold.Partial snapping is ON, this problem will proceed to the solver.\n", - "2022-07-14 15:49:58,038 - Passing problem to solver\n", - "2022-07-14 15:49:58,041 - Initializing ordered Set vertices with a fundamentally unordered data source (type: set). This WILL potentially lead to nondeterministic behavior in Pyomo\n", - "2022-07-14 15:49:58,047 - Passing problem to solver\n", - "2022-07-14 15:49:58,374 - Successfully snapped 3 stops to network links.\n", - "2022-07-14 15:49:58,390 - Stop ID changes detected for Routes: {'new_route'}\n", - "2022-07-14 15:49:58,394 - Changed Route attributes for 1 routes\n", - "2022-07-14 15:49:58,399 - Added 1 nodes\n", - "2022-07-14 15:49:58,505 - Generated 0 link ids.\n", - "2022-07-14 15:49:58,510 - Added 2 links\n", - "2022-07-14 15:49:58,513 - Changed Link attributes for 4 links\n" + "2023-12-08 13:44:19,064 - Routing Service new_service with modes = {'bus'}\n", + "2023-12-08 13:44:19,077 - Building Maximum Stable Set for PT graph with 4 stops and 3 edges\n", + "2023-12-08 13:44:19,121 - This Maximum Stable Set Problem is partially viable.\n", + "2023-12-08 13:44:19,124 - Maximum Stable Set problem to snap the PT graph to the network is partially viable, meaning not all stops have found a link to snap to within the distance_threshold.Partial snapping is ON, this problem will proceed to the solver.\n", + "2023-12-08 13:44:19,125 - Passing problem to solver\n", + "2023-12-08 13:44:19,128 - Initializing ordered Set vertices with a fundamentally unordered data source (type: set). This WILL potentially lead to nondeterministic behavior in Pyomo\n", + "2023-12-08 13:44:19,132 - Passing problem to solver\n", + "2023-12-08 13:44:19,208 - Successfully snapped 3 stops to network links.\n", + "2023-12-08 13:44:19,217 - Stop ID changes detected for Routes: {'new_route'}\n", + "2023-12-08 13:44:19,218 - Changed Route attributes for 1 routes\n", + "2023-12-08 13:44:19,222 - Added 1 nodes\n", + "2023-12-08 13:44:19,266 - Generated 0 link ids.\n", + "2023-12-08 13:44:19,269 - Added 2 links\n", + "2023-12-08 13:44:19,270 - Changed Link attributes for 4 links\n" ] } ], "source": [ - "n.route_service(\"new_service\")" + "if shutil.which(\"cbc\"):\n", + " n.route_service(\"new_service\")\n", + "else:\n", + " print(\"Cannot route service without a solver installed\")" ] }, { @@ -952,7 +966,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "2022-07-14 15:49:58,565 - Reindexed Service from new_service to more_appropriate_id\n" + "2023-12-08 13:44:19,290 - Reindexed Service from new_service to more_appropriate_id\n" ] } ], @@ -974,7 +988,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "2022-07-14 15:49:58,583 - Reindexed Route from new_route to more_appropriate_route_id\n" + "2023-12-08 13:44:19,297 - Reindexed Route from new_route to more_appropriate_route_id\n" ] } ], @@ -1026,7 +1040,7 @@ " \n", " \n", " 3\n", - " 2022-07-14 15:49:54\n", + " 2023-12-08 13:44:17\n", " add\n", " route\n", " None\n", @@ -1037,7 +1051,7 @@ " \n", " \n", " 4\n", - " 2022-07-14 15:49:54\n", + " 2023-12-08 13:44:18\n", " add\n", " route\n", " None\n", @@ -1048,7 +1062,7 @@ " \n", " \n", " 5\n", - " 2022-07-14 15:49:58\n", + " 2023-12-08 13:44:19\n", " modify\n", " route\n", " new_route\n", @@ -1059,7 +1073,7 @@ " \n", " \n", " 6\n", - " 2022-07-14 15:49:58\n", + " 2023-12-08 13:44:19\n", " modify\n", " service\n", " new_service\n", @@ -1070,7 +1084,7 @@ " \n", " \n", " 7\n", - " 2022-07-14 15:49:58\n", + " 2023-12-08 13:44:19\n", " modify\n", " route\n", " new_route\n", @@ -1085,11 +1099,11 @@ ], "text/plain": [ " timestamp change_event object_type old_id \\\n", - "3 2022-07-14 15:49:54 add route None \n", - "4 2022-07-14 15:49:54 add route None \n", - "5 2022-07-14 15:49:58 modify route new_route \n", - "6 2022-07-14 15:49:58 modify service new_service \n", - "7 2022-07-14 15:49:58 modify route new_route \n", + "3 2023-12-08 13:44:17 add route None \n", + "4 2023-12-08 13:44:18 add route None \n", + "5 2023-12-08 13:44:19 modify route new_route \n", + "6 2023-12-08 13:44:19 modify service new_service \n", + "7 2023-12-08 13:44:19 modify route new_route \n", "\n", " new_id \\\n", "3 another_new_route_2 \n", @@ -1150,9 +1164,9 @@ "name": "stderr", "output_type": "stream", "text": [ - "/Users/kasia.kozlowska/PycharmProjects/ABM/genet/genet/schedule_elements.py:1384: UserWarning: DataFrame columns are not unique, some columns will be omitted.\n", + "/Users/bryn.pickering/Repos/arup-group/genet/genet/schedule_elements.py:1803: UserWarning: DataFrame columns are not unique, some columns will be omitted.\n", " self.vehicles = {**df.T.to_dict(), **self.vehicles}\n", - "2022-07-14 15:49:58,899 - Removed Services with IDs `more_appropriate_id`, and Routes: {'more_appropriate_route_id'}\n" + "2023-12-08 13:44:19,404 - Removed Services with IDs `more_appropriate_id`, and Routes: {'more_appropriate_route_id'}\n" ] } ], @@ -1174,9 +1188,17 @@ "name": "stderr", "output_type": "stream", "text": [ - "2022-07-14 15:49:59,144 - Removed Routes with IDs ['another_new_route_2'], to Services `20274`.\n", - "2022-07-14 15:49:59,467 - Removed Routes with IDs ['another_new_route'], to Services `20274`.\n", - "2022-07-14 15:49:59,892 - Removed Routes with IDs ['another_new_route_3'], to Services `20274`.\n" + "/Users/bryn.pickering/Repos/arup-group/genet/genet/schedule_elements.py:1803: UserWarning: DataFrame columns are not unique, some columns will be omitted.\n", + " self.vehicles = {**df.T.to_dict(), **self.vehicles}\n", + "2023-12-08 13:44:19,507 - Removed Routes with IDs ['another_new_route_2'], to Services `20274`.\n", + "2023-12-08 13:44:19,603 - Removed Routes with IDs ['another_new_route_3'], to Services `20274`.\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2023-12-08 13:44:19,700 - Removed Routes with IDs ['another_new_route'], to Services `20274`.\n" ] } ], @@ -1229,7 +1251,7 @@ " \n", " \n", " 7\n", - " 2022-07-14 15:49:58\n", + " 2023-12-08 13:44:19\n", " modify\n", " route\n", " new_route\n", @@ -1240,7 +1262,7 @@ " \n", " \n", " 8\n", - " 2022-07-14 15:49:58\n", + " 2023-12-08 13:44:19\n", " remove\n", " service\n", " more_appropriate_id\n", @@ -1251,7 +1273,7 @@ " \n", " \n", " 9\n", - " 2022-07-14 15:49:58\n", + " 2023-12-08 13:44:19\n", " remove\n", " route\n", " another_new_route_2\n", @@ -1262,10 +1284,10 @@ " \n", " \n", " 10\n", - " 2022-07-14 15:49:59\n", + " 2023-12-08 13:44:19\n", " remove\n", " route\n", - " another_new_route\n", + " another_new_route_3\n", " None\n", " {'route_short_name': 'N55', 'mode': 'bus', 'ar...\n", " None\n", @@ -1273,10 +1295,10 @@ " \n", " \n", " 11\n", - " 2022-07-14 15:49:59\n", + " 2023-12-08 13:44:19\n", " remove\n", " route\n", - " another_new_route_3\n", + " another_new_route\n", " None\n", " {'route_short_name': 'N55', 'mode': 'bus', 'ar...\n", " None\n", @@ -1288,11 +1310,11 @@ ], "text/plain": [ " timestamp change_event object_type old_id \\\n", - "7 2022-07-14 15:49:58 modify route new_route \n", - "8 2022-07-14 15:49:58 remove service more_appropriate_id \n", - "9 2022-07-14 15:49:58 remove route another_new_route_2 \n", - "10 2022-07-14 15:49:59 remove route another_new_route \n", - "11 2022-07-14 15:49:59 remove route another_new_route_3 \n", + "7 2023-12-08 13:44:19 modify route new_route \n", + "8 2023-12-08 13:44:19 remove service more_appropriate_id \n", + "9 2023-12-08 13:44:19 remove route another_new_route_2 \n", + "10 2023-12-08 13:44:19 remove route another_new_route_3 \n", + "11 2023-12-08 13:44:19 remove route another_new_route \n", "\n", " new_id \\\n", "7 more_appropriate_route_id \n", @@ -1353,7 +1375,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "2022-07-14 15:49:59,946 - Removed Stops with indices `['new_stop']`.Routes affected: {'20274_4'}. Services affected: {'20274'}.\n" + "2023-12-08 13:44:19,715 - Removed Stops with indices `['new_stop']`.Routes affected: {'20274_4'}. Services affected: {'20274'}.\n" ] } ], @@ -1382,7 +1404,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "2022-07-14 15:49:59,978 - Removed Stops with indices `['9400ZZLUWRR2', 'new_stop.link:3154', '490000235W1', '9400ZZLUESQ1', '9400ZZLUESQ2', '9400ZZLUGDG1', '9400ZZLUTCR1', '490000235X.link:artificial_link===from:490000235X===to:490000235X', '490015196N', '9400ZZLUWRR1', '9400ZZLUWRR4', '9400ZZLUOXC1', '9400ZZLUGPS2', '9400ZZLUOXC3', '9400ZZLURGP1', '490000235N', '9400ZZLURGP2', '9400ZZLUOXC4', '490000091E', '490000173RD', '9400ZZLUWRR3', '9400ZZLUTCR4', '490000356NE', '490010198W', '490015196R', '490019675D', '490000252R', '490000252S', 'other_new_stop.link:3154', '9400ZZLUOXC2', '490000173RF', '9400ZZLUOXC5', '490000091F', '490011126K', '9400ZZLUOXC6', '9400ZZLUTCR3', '490013600C']`.Routes affected: set(). Services affected: set().\n" + "2023-12-08 13:44:19,721 - Removed Stops with indices `['490000252R', '9400ZZLUTCR3', 'new_stop.link:3154', '490015196N', '9400ZZLUOXC6', '9400ZZLUGDG1', '9400ZZLUOXC1', '490000235W1', '490000235X.link:artificial_link===from:490000235X===to:490000235X', '490010198W', '490000252S', '9400ZZLUESQ2', '490000091F', '9400ZZLURGP1', '9400ZZLUWRR3', '9400ZZLUWRR1', '490000173RF', '9400ZZLUTCR4', '490000235N', '490015196R', '9400ZZLUOXC3', '9400ZZLURGP2', '9400ZZLUWRR2', '490000356NE', '9400ZZLUOXC5', '490011126K', '9400ZZLUTCR1', 'other_new_stop.link:3154', '9400ZZLUOXC4', '490000173RD', '9400ZZLUGPS2', '490013600C', '9400ZZLUWRR4', '490019675D', '490000091E', '9400ZZLUESQ1', '9400ZZLUOXC2']`.Routes affected: set(). Services affected: set().\n" ] } ], @@ -1436,24 +1458,24 @@ " \n", " \n", " \n", - " 14134\n", - " 98\n", - " \n", - " \n", " 20274\n", " N55\n", " \n", " \n", - " 18853\n", - " N8\n", + " 18915\n", + " N5\n", " \n", " \n", - " 15234\n", - " 134\n", + " 14134\n", + " 98\n", " \n", " \n", - " 17732\n", - " N20\n", + " 15660\n", + " 113\n", + " \n", + " \n", + " 18853\n", + " N8\n", " \n", " \n", "\n", @@ -1461,11 +1483,11 @@ ], "text/plain": [ " name\n", - "14134 98\n", "20274 N55\n", - "18853 N8\n", - "15234 134\n", - "17732 N20" + "18915 N5\n", + "14134 98\n", + "15660 113\n", + "18853 N8" ] }, "execution_count": 34, @@ -1521,24 +1543,24 @@ " \n", " \n", " \n", - " 14134\n", - " Service_98\n", - " \n", - " \n", " 20274\n", " Service_N55\n", " \n", " \n", - " 18853\n", - " Service_N8\n", + " 18915\n", + " Service_N5\n", " \n", " \n", - " 15234\n", - " Service_134\n", + " 14134\n", + " Service_98\n", + " \n", + " \n", + " 15660\n", + " Service_113\n", " \n", " \n", - " 17732\n", - " Service_N20\n", + " 18853\n", + " Service_N8\n", " \n", " \n", "\n", @@ -1546,11 +1568,11 @@ ], "text/plain": [ " name\n", - "14134 Service_98\n", "20274 Service_N55\n", - "18853 Service_N8\n", - "15234 Service_134\n", - "17732 Service_N20" + "18915 Service_N5\n", + "14134 Service_98\n", + "15660 Service_113\n", + "18853 Service_N8" ] }, "execution_count": 35, @@ -1584,7 +1606,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "2022-07-14 15:50:00,085 - Changed Service attributes for 9 services\n" + "2023-12-08 13:44:19,740 - Changed Service attributes for 9 services\n" ] } ], @@ -1636,18 +1658,18 @@ " \n", " \n", " 54\n", - " 2022-07-14 15:50:00\n", + " 2023-12-08 13:44:19\n", " modify\n", " service\n", - " 17732\n", - " 17732\n", - " {'id': '17732', 'name': 'N20'}\n", - " {'id': '17732', 'name': 'Service_N20'}\n", - " [(change, name, (N20, Service_N20))]\n", + " 18853\n", + " 18853\n", + " {'id': '18853', 'name': 'N8'}\n", + " {'id': '18853', 'name': 'Service_N8'}\n", + " [(change, name, (N8, Service_N8))]\n", " \n", " \n", " 55\n", - " 2022-07-14 15:50:00\n", + " 2023-12-08 13:44:19\n", " modify\n", " service\n", " 12430\n", @@ -1658,29 +1680,29 @@ " \n", " \n", " 56\n", - " 2022-07-14 15:50:00\n", + " 2023-12-08 13:44:19\n", " modify\n", " service\n", - " 15660\n", - " 15660\n", - " {'id': '15660', 'name': '113'}\n", - " {'id': '15660', 'name': 'Service_113'}\n", - " [(change, name, (113, Service_113))]\n", + " 15234\n", + " 15234\n", + " {'id': '15234', 'name': '134'}\n", + " {'id': '15234', 'name': 'Service_134'}\n", + " [(change, name, (134, Service_134))]\n", " \n", " \n", " 57\n", - " 2022-07-14 15:50:00\n", + " 2023-12-08 13:44:19\n", " modify\n", " service\n", - " 18915\n", - " 18915\n", - " {'id': '18915', 'name': 'N5'}\n", - " {'id': '18915', 'name': 'Service_N5'}\n", - " [(change, name, (N5, Service_N5))]\n", + " 17732\n", + " 17732\n", + " {'id': '17732', 'name': 'N20'}\n", + " {'id': '17732', 'name': 'Service_N20'}\n", + " [(change, name, (N20, Service_N20))]\n", " \n", " \n", " 58\n", - " 2022-07-14 15:50:00\n", + " 2023-12-08 13:44:19\n", " modify\n", " service\n", " 14073\n", @@ -1695,24 +1717,24 @@ ], "text/plain": [ " timestamp change_event object_type old_id new_id \\\n", - "54 2022-07-14 15:50:00 modify service 17732 17732 \n", - "55 2022-07-14 15:50:00 modify service 12430 12430 \n", - "56 2022-07-14 15:50:00 modify service 15660 15660 \n", - "57 2022-07-14 15:50:00 modify service 18915 18915 \n", - "58 2022-07-14 15:50:00 modify service 14073 14073 \n", + "54 2023-12-08 13:44:19 modify service 18853 18853 \n", + "55 2023-12-08 13:44:19 modify service 12430 12430 \n", + "56 2023-12-08 13:44:19 modify service 15234 15234 \n", + "57 2023-12-08 13:44:19 modify service 17732 17732 \n", + "58 2023-12-08 13:44:19 modify service 14073 14073 \n", "\n", " old_attributes new_attributes \\\n", - "54 {'id': '17732', 'name': 'N20'} {'id': '17732', 'name': 'Service_N20'} \n", + "54 {'id': '18853', 'name': 'N8'} {'id': '18853', 'name': 'Service_N8'} \n", "55 {'id': '12430', 'name': '205'} {'id': '12430', 'name': 'Service_205'} \n", - "56 {'id': '15660', 'name': '113'} {'id': '15660', 'name': 'Service_113'} \n", - "57 {'id': '18915', 'name': 'N5'} {'id': '18915', 'name': 'Service_N5'} \n", + "56 {'id': '15234', 'name': '134'} {'id': '15234', 'name': 'Service_134'} \n", + "57 {'id': '17732', 'name': 'N20'} {'id': '17732', 'name': 'Service_N20'} \n", "58 {'id': '14073', 'name': '94'} {'id': '14073', 'name': 'Service_94'} \n", "\n", " diff \n", - "54 [(change, name, (N20, Service_N20))] \n", + "54 [(change, name, (N8, Service_N8))] \n", "55 [(change, name, (205, Service_205))] \n", - "56 [(change, name, (113, Service_113))] \n", - "57 [(change, name, (N5, Service_N5))] \n", + "56 [(change, name, (134, Service_134))] \n", + "57 [(change, name, (N20, Service_N20))] \n", "58 [(change, name, (94, Service_94))] " ] }, @@ -1746,7 +1768,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "2022-07-14 15:50:00,132 - Changed Route attributes for 1 routes\n" + "2023-12-08 13:44:19,754 - Changed Route attributes for 1 routes\n" ] } ], @@ -1775,7 +1797,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "2022-07-14 15:50:00,148 - Changed Stop attributes for 1 stops\n" + "2023-12-08 13:44:19,759 - Changed Stop attributes for 1 stops\n" ] } ], @@ -1827,29 +1849,29 @@ " \n", " \n", " 56\n", - " 2022-07-14 15:50:00\n", + " 2023-12-08 13:44:19\n", " modify\n", " service\n", - " 15660\n", - " 15660\n", - " {'id': '15660', 'name': '113'}\n", - " {'id': '15660', 'name': 'Service_113'}\n", - " [(change, name, (113, Service_113))]\n", + " 15234\n", + " 15234\n", + " {'id': '15234', 'name': '134'}\n", + " {'id': '15234', 'name': 'Service_134'}\n", + " [(change, name, (134, Service_134))]\n", " \n", " \n", " 57\n", - " 2022-07-14 15:50:00\n", + " 2023-12-08 13:44:19\n", " modify\n", " service\n", - " 18915\n", - " 18915\n", - " {'id': '18915', 'name': 'N5'}\n", - " {'id': '18915', 'name': 'Service_N5'}\n", - " [(change, name, (N5, Service_N5))]\n", + " 17732\n", + " 17732\n", + " {'id': '17732', 'name': 'N20'}\n", + " {'id': '17732', 'name': 'Service_N20'}\n", + " [(change, name, (N20, Service_N20))]\n", " \n", " \n", " 58\n", - " 2022-07-14 15:50:00\n", + " 2023-12-08 13:44:19\n", " modify\n", " service\n", " 14073\n", @@ -1860,7 +1882,7 @@ " \n", " \n", " 59\n", - " 2022-07-14 15:50:00\n", + " 2023-12-08 13:44:19\n", " modify\n", " route\n", " VJ375a660d47a2aa570aa20a8568012da8497ffecf\n", @@ -1871,13 +1893,13 @@ " \n", " \n", " 60\n", - " 2022-07-14 15:50:00\n", + " 2023-12-08 13:44:19\n", " modify\n", " stop\n", " 490000235YB.link:574\n", " 490000235YB.link:574\n", - " {'services': {'20274', '18853', '14134'}, 'rou...\n", - " {'services': {'20274', '18853', '14134'}, 'rou...\n", + " {'services': {'18853', '14134', '20274'}, 'rou...\n", + " {'services': {'18853', '14134', '20274'}, 'rou...\n", " [(add, , [('new_attribute', 'hello!')])]\n", " \n", " \n", @@ -1886,43 +1908,43 @@ ], "text/plain": [ " timestamp change_event object_type \\\n", - "56 2022-07-14 15:50:00 modify service \n", - "57 2022-07-14 15:50:00 modify service \n", - "58 2022-07-14 15:50:00 modify service \n", - "59 2022-07-14 15:50:00 modify route \n", - "60 2022-07-14 15:50:00 modify stop \n", + "56 2023-12-08 13:44:19 modify service \n", + "57 2023-12-08 13:44:19 modify service \n", + "58 2023-12-08 13:44:19 modify service \n", + "59 2023-12-08 13:44:19 modify route \n", + "60 2023-12-08 13:44:19 modify stop \n", "\n", " old_id \\\n", - "56 15660 \n", - "57 18915 \n", + "56 15234 \n", + "57 17732 \n", "58 14073 \n", "59 VJ375a660d47a2aa570aa20a8568012da8497ffecf \n", "60 490000235YB.link:574 \n", "\n", " new_id \\\n", - "56 15660 \n", - "57 18915 \n", + "56 15234 \n", + "57 17732 \n", "58 14073 \n", "59 VJ375a660d47a2aa570aa20a8568012da8497ffecf \n", "60 490000235YB.link:574 \n", "\n", " old_attributes \\\n", - "56 {'id': '15660', 'name': '113'} \n", - "57 {'id': '18915', 'name': 'N5'} \n", + "56 {'id': '15234', 'name': '134'} \n", + "57 {'id': '17732', 'name': 'N20'} \n", "58 {'id': '14073', 'name': '94'} \n", "59 {'route_short_name': 'N55', 'mode': 'bus', 'ar... \n", - "60 {'services': {'20274', '18853', '14134'}, 'rou... \n", + "60 {'services': {'18853', '14134', '20274'}, 'rou... \n", "\n", " new_attributes \\\n", - "56 {'id': '15660', 'name': 'Service_113'} \n", - "57 {'id': '18915', 'name': 'Service_N5'} \n", + "56 {'id': '15234', 'name': 'Service_134'} \n", + "57 {'id': '17732', 'name': 'Service_N20'} \n", "58 {'id': '14073', 'name': 'Service_94'} \n", "59 {'route_short_name': 'N55', 'mode': 'piggyback... \n", - "60 {'services': {'20274', '18853', '14134'}, 'rou... \n", + "60 {'services': {'18853', '14134', '20274'}, 'rou... \n", "\n", " diff \n", - "56 [(change, name, (113, Service_113))] \n", - "57 [(change, name, (N5, Service_N5))] \n", + "56 [(change, name, (134, Service_134))] \n", + "57 [(change, name, (N20, Service_N20))] \n", "58 [(change, name, (94, Service_94))] \n", "59 [(change, mode, (bus, piggyback)), (add, , [('... \n", "60 [(add, , [('new_attribute', 'hello!')])] " @@ -1992,8 +2014,8 @@ " \n", " \n", " mode\n", - " service_id\n", " route_id\n", + " service_id\n", " trip_id\n", " trip_departure_time\n", " vehicle_id\n", @@ -2003,73 +2025,73 @@ " \n", " 0\n", " bus\n", - " 18853\n", - " VJ8cacca9a6722c497c413005568182ecf4d50b160\n", - " VJ2e4c6d83aa4dfd4b71ae27a9568cd3a4d0598f6d_05:...\n", - " 2021-01-01 05:25:00\n", - " veh_2205_bus\n", + " VJ0cb60de3ed229c1413abac506e770b6ab8a7c49a\n", + " 17732\n", + " VJ0b0180c7b6bcef5834ec857e9b5a94254803694f_03:...\n", + " 2021-01-01 03:48:00\n", + " veh_2160_bus\n", " \n", " \n", " 1\n", " bus\n", - " 18853\n", - " VJ8cacca9a6722c497c413005568182ecf4d50b160\n", - " VJ4fef3d3f34855f68dab603441550f4e487b0b9b7_03:...\n", - " 2021-01-01 03:45:00\n", - " veh_2206_bus\n", + " VJ0cb60de3ed229c1413abac506e770b6ab8a7c49a\n", + " 17732\n", + " VJ0cb60de3ed229c1413abac506e770b6ab8a7c49a_03:...\n", + " 2021-01-01 03:18:00\n", + " veh_2161_bus\n", " \n", " \n", " 2\n", " bus\n", - " 18853\n", - " VJ8cacca9a6722c497c413005568182ecf4d50b160\n", - " VJ8cacca9a6722c497c413005568182ecf4d50b160_05:...\n", - " 2021-01-01 05:05:00\n", - " veh_2207_bus\n", + " VJ0cb60de3ed229c1413abac506e770b6ab8a7c49a\n", + " 17732\n", + " VJ5e32459fcb7ab3481a1bab1b2c106f592a67d8ff_04:...\n", + " 2021-01-01 04:43:00\n", + " veh_2162_bus\n", " \n", " \n", " 3\n", " bus\n", - " 18853\n", - " VJ8cacca9a6722c497c413005568182ecf4d50b160\n", - " VJ99c16d764175d7337e6a4eb4e96b9f86d229c48f_03:...\n", - " 2021-01-01 03:25:00\n", - " veh_2208_bus\n", + " VJ0cb60de3ed229c1413abac506e770b6ab8a7c49a\n", + " 17732\n", + " VJ691d8b8a2b60e4f943babbea813c047824d60e6e_02:...\n", + " 2021-01-01 02:28:00\n", + " veh_2163_bus\n", " \n", " \n", " 4\n", " bus\n", - " 18853\n", - " VJ8cacca9a6722c497c413005568182ecf4d50b160\n", - " VJb539a6d218dff4d1beedc043251816c61261a18b_04:...\n", - " 2021-01-01 04:05:00\n", - " veh_2209_bus\n", + " VJ0cb60de3ed229c1413abac506e770b6ab8a7c49a\n", + " 17732\n", + " VJ9b62613eaaadfb63206602708def459f48c9d7e5_01:...\n", + " 2021-01-01 01:58:00\n", + " veh_2164_bus\n", " \n", " \n", "\n", "" ], "text/plain": [ - " mode service_id route_id \\\n", - "0 bus 18853 VJ8cacca9a6722c497c413005568182ecf4d50b160 \n", - "1 bus 18853 VJ8cacca9a6722c497c413005568182ecf4d50b160 \n", - "2 bus 18853 VJ8cacca9a6722c497c413005568182ecf4d50b160 \n", - "3 bus 18853 VJ8cacca9a6722c497c413005568182ecf4d50b160 \n", - "4 bus 18853 VJ8cacca9a6722c497c413005568182ecf4d50b160 \n", + " mode route_id service_id \\\n", + "0 bus VJ0cb60de3ed229c1413abac506e770b6ab8a7c49a 17732 \n", + "1 bus VJ0cb60de3ed229c1413abac506e770b6ab8a7c49a 17732 \n", + "2 bus VJ0cb60de3ed229c1413abac506e770b6ab8a7c49a 17732 \n", + "3 bus VJ0cb60de3ed229c1413abac506e770b6ab8a7c49a 17732 \n", + "4 bus VJ0cb60de3ed229c1413abac506e770b6ab8a7c49a 17732 \n", "\n", " trip_id trip_departure_time \\\n", - "0 VJ2e4c6d83aa4dfd4b71ae27a9568cd3a4d0598f6d_05:... 2021-01-01 05:25:00 \n", - "1 VJ4fef3d3f34855f68dab603441550f4e487b0b9b7_03:... 2021-01-01 03:45:00 \n", - "2 VJ8cacca9a6722c497c413005568182ecf4d50b160_05:... 2021-01-01 05:05:00 \n", - "3 VJ99c16d764175d7337e6a4eb4e96b9f86d229c48f_03:... 2021-01-01 03:25:00 \n", - "4 VJb539a6d218dff4d1beedc043251816c61261a18b_04:... 2021-01-01 04:05:00 \n", + "0 VJ0b0180c7b6bcef5834ec857e9b5a94254803694f_03:... 2021-01-01 03:48:00 \n", + "1 VJ0cb60de3ed229c1413abac506e770b6ab8a7c49a_03:... 2021-01-01 03:18:00 \n", + "2 VJ5e32459fcb7ab3481a1bab1b2c106f592a67d8ff_04:... 2021-01-01 04:43:00 \n", + "3 VJ691d8b8a2b60e4f943babbea813c047824d60e6e_02:... 2021-01-01 02:28:00 \n", + "4 VJ9b62613eaaadfb63206602708def459f48c9d7e5_01:... 2021-01-01 01:58:00 \n", "\n", " vehicle_id \n", - "0 veh_2205_bus \n", - "1 veh_2206_bus \n", - "2 veh_2207_bus \n", - "3 veh_2208_bus \n", - "4 veh_2209_bus " + "0 veh_2160_bus \n", + "1 veh_2161_bus \n", + "2 veh_2162_bus \n", + "3 veh_2163_bus \n", + "4 veh_2164_bus " ] }, "execution_count": 42, @@ -2120,8 +2142,8 @@ " \n", " \n", " mode\n", - " service_id\n", " route_id\n", + " service_id\n", " trip_id\n", " trip_departure_time\n", " vehicle_id\n", @@ -2131,66 +2153,66 @@ " \n", " 0\n", " bus\n", - " 18853\n", - " VJ8cacca9a6722c497c413005568182ecf4d50b160\n", + " VJ0cb60de3ed229c1413abac506e770b6ab8a7c49a\n", + " 17732\n", " trip_0\n", - " 2021-01-01 05:25:00\n", - " veh_2205_bus\n", + " 2021-01-01 03:48:00\n", + " veh_2160_bus\n", " \n", " \n", " 1\n", " bus\n", - " 18853\n", - " VJ8cacca9a6722c497c413005568182ecf4d50b160\n", + " VJ0cb60de3ed229c1413abac506e770b6ab8a7c49a\n", + " 17732\n", " trip_1\n", - " 2021-01-01 03:45:00\n", - " veh_2206_bus\n", + " 2021-01-01 03:18:00\n", + " veh_2161_bus\n", " \n", " \n", " 2\n", " bus\n", - " 18853\n", - " VJ8cacca9a6722c497c413005568182ecf4d50b160\n", + " VJ0cb60de3ed229c1413abac506e770b6ab8a7c49a\n", + " 17732\n", " trip_2\n", - " 2021-01-01 05:05:00\n", - " veh_2207_bus\n", + " 2021-01-01 04:43:00\n", + " veh_2162_bus\n", " \n", " \n", " 3\n", " bus\n", - " 18853\n", - " VJ8cacca9a6722c497c413005568182ecf4d50b160\n", + " VJ0cb60de3ed229c1413abac506e770b6ab8a7c49a\n", + " 17732\n", " trip_3\n", - " 2021-01-01 03:25:00\n", - " veh_2208_bus\n", + " 2021-01-01 02:28:00\n", + " veh_2163_bus\n", " \n", " \n", " 4\n", " bus\n", - " 18853\n", - " VJ8cacca9a6722c497c413005568182ecf4d50b160\n", + " VJ0cb60de3ed229c1413abac506e770b6ab8a7c49a\n", + " 17732\n", " trip_4\n", - " 2021-01-01 04:05:00\n", - " veh_2209_bus\n", + " 2021-01-01 01:58:00\n", + " veh_2164_bus\n", " \n", " \n", "\n", "" ], "text/plain": [ - " mode service_id route_id trip_id \\\n", - "0 bus 18853 VJ8cacca9a6722c497c413005568182ecf4d50b160 trip_0 \n", - "1 bus 18853 VJ8cacca9a6722c497c413005568182ecf4d50b160 trip_1 \n", - "2 bus 18853 VJ8cacca9a6722c497c413005568182ecf4d50b160 trip_2 \n", - "3 bus 18853 VJ8cacca9a6722c497c413005568182ecf4d50b160 trip_3 \n", - "4 bus 18853 VJ8cacca9a6722c497c413005568182ecf4d50b160 trip_4 \n", + " mode route_id service_id trip_id \\\n", + "0 bus VJ0cb60de3ed229c1413abac506e770b6ab8a7c49a 17732 trip_0 \n", + "1 bus VJ0cb60de3ed229c1413abac506e770b6ab8a7c49a 17732 trip_1 \n", + "2 bus VJ0cb60de3ed229c1413abac506e770b6ab8a7c49a 17732 trip_2 \n", + "3 bus VJ0cb60de3ed229c1413abac506e770b6ab8a7c49a 17732 trip_3 \n", + "4 bus VJ0cb60de3ed229c1413abac506e770b6ab8a7c49a 17732 trip_4 \n", "\n", " trip_departure_time vehicle_id \n", - "0 2021-01-01 05:25:00 veh_2205_bus \n", - "1 2021-01-01 03:45:00 veh_2206_bus \n", - "2 2021-01-01 05:05:00 veh_2207_bus \n", - "3 2021-01-01 03:25:00 veh_2208_bus \n", - "4 2021-01-01 04:05:00 veh_2209_bus " + "0 2021-01-01 03:48:00 veh_2160_bus \n", + "1 2021-01-01 03:18:00 veh_2161_bus \n", + "2 2021-01-01 04:43:00 veh_2162_bus \n", + "3 2021-01-01 02:28:00 veh_2163_bus \n", + "4 2021-01-01 01:58:00 veh_2164_bus " ] }, "execution_count": 43, @@ -2226,7 +2248,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "2022-07-14 15:50:00,520 - Changed Route attributes for 69 routes\n" + "2023-12-08 13:44:19,838 - Changed Route attributes for 69 routes\n" ] }, { @@ -2255,24 +2277,24 @@ " \n", " \n", " \n", - " VJ8cacca9a6722c497c413005568182ecf4d50b160\n", + " VJ0cb60de3ed229c1413abac506e770b6ab8a7c49a\n", " [trip_0, trip_1, trip_2, trip_3, trip_4, trip_...\n", " \n", " \n", - " VJ2aba67e3ed98f2ed5f5966c1ac394cbf6d1943d7\n", - " [trip_8, trip_9, trip_10, trip_11, trip_12, tr...\n", + " VJ5b511605b1e07428c2e0a7d676d301c6c40dcca6\n", + " [trip_12, trip_13, trip_14, trip_15, trip_16, ...\n", " \n", " \n", - " VJ1a8cc306354fdc322d739ae644eb73444341d08d\n", - " [trip_78, trip_79, trip_80, trip_81, trip_82, ...\n", + " VJ4e2b897edf0e7b8a8e3b5516ab43ce56f72c5cff\n", + " [trip_26, trip_27, trip_28, trip_29, trip_30, ...\n", " \n", " \n", - " VJ5b511605b1e07428c2e0a7d676d301c6c40dcca6\n", - " [trip_94, trip_95, trip_96, trip_97, trip_98, ...\n", + " VJd78967364a302cf232c5139d40622dcb6c238c9e\n", + " [trip_45, trip_46]\n", " \n", " \n", - " VJe18efadf172576fea7989ec1f233f26854c0f66a\n", - " [trip_108, trip_109, trip_110, trip_111, trip_...\n", + " VJ256e98df611ff48afe737ddc81cbcde82e4e81c8\n", + " [trip_47]\n", " \n", " \n", "\n", @@ -2280,11 +2302,11 @@ ], "text/plain": [ " trips::trip_id\n", - "VJ8cacca9a6722c497c413005568182ecf4d50b160 [trip_0, trip_1, trip_2, trip_3, trip_4, trip_...\n", - "VJ2aba67e3ed98f2ed5f5966c1ac394cbf6d1943d7 [trip_8, trip_9, trip_10, trip_11, trip_12, tr...\n", - "VJ1a8cc306354fdc322d739ae644eb73444341d08d [trip_78, trip_79, trip_80, trip_81, trip_82, ...\n", - "VJ5b511605b1e07428c2e0a7d676d301c6c40dcca6 [trip_94, trip_95, trip_96, trip_97, trip_98, ...\n", - "VJe18efadf172576fea7989ec1f233f26854c0f66a [trip_108, trip_109, trip_110, trip_111, trip_..." + "VJ0cb60de3ed229c1413abac506e770b6ab8a7c49a [trip_0, trip_1, trip_2, trip_3, trip_4, trip_...\n", + "VJ5b511605b1e07428c2e0a7d676d301c6c40dcca6 [trip_12, trip_13, trip_14, trip_15, trip_16, ...\n", + "VJ4e2b897edf0e7b8a8e3b5516ab43ce56f72c5cff [trip_26, trip_27, trip_28, trip_29, trip_30, ...\n", + "VJd78967364a302cf232c5139d40622dcb6c238c9e [trip_45, trip_46]\n", + "VJ256e98df611ff48afe737ddc81cbcde82e4e81c8 [trip_47]" ] }, "execution_count": 44, @@ -2319,7 +2341,7 @@ { "data": { "text/plain": [ - "{'trip_id': ['trip_1358', 'trip_1359'],\n", + "{'trip_id': ['trip_203', 'trip_204'],\n", " 'trip_departure_time': ['07:51:00', '22:50:00'],\n", " 'vehicle_id': ['veh_887_bus', 'veh_888_bus']}" ] @@ -2349,7 +2371,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "2022-07-14 15:50:00,583 - Changed Route attributes for 1 routes\n" + "2023-12-08 13:44:19,863 - Changed Route attributes for 1 routes\n" ] } ], @@ -2430,7 +2452,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "2022-07-14 15:50:00,627 - Changed Stop attributes for 85 stops\n" + "2023-12-08 13:44:19,894 - Changed Stop attributes for 85 stops\n" ] } ], @@ -2489,25 +2511,25 @@ " \n", " \n", " 214\n", - " 2022-07-14 15:50:00\n", + " 2023-12-08 13:44:19\n", " modify\n", " stop\n", - " 490002124ZZ\n", - " 490002124ZZ\n", - " {'id': '490002124ZZ', 'x': 529737.7933655808, ...\n", - " {'id': '490002124ZZ', 'x': 529737.7933655808, ...\n", - " [(add, , [('geometry', <shapely.geometry.point...\n", + " 490000235YB\n", + " 490000235YB\n", + " {'id': '490000235YB', 'x': 529570.7813227688, ...\n", + " {'id': '490000235YB', 'x': 529570.7813227688, ...\n", + " [(add, , [('geometry', <POINT (529570.781 1813...\n", " \n", " \n", " 215\n", - " 2022-07-14 15:50:00\n", + " 2023-12-08 13:44:19\n", " modify\n", " stop\n", " other_new_stop\n", " other_new_stop\n", " {'services': {'20274'}, 'routes': {'20274_4'},...\n", " {'services': {'20274'}, 'routes': {'20274_4'},...\n", - " [(add, , [('geometry', <shapely.geometry.point...\n", + " [(add, , [('geometry', <POINT (529502 181302)>...\n", " \n", " \n", "\n", @@ -2515,20 +2537,20 @@ ], "text/plain": [ " timestamp change_event object_type old_id \\\n", - "214 2022-07-14 15:50:00 modify stop 490002124ZZ \n", - "215 2022-07-14 15:50:00 modify stop other_new_stop \n", + "214 2023-12-08 13:44:19 modify stop 490000235YB \n", + "215 2023-12-08 13:44:19 modify stop other_new_stop \n", "\n", " new_id old_attributes \\\n", - "214 490002124ZZ {'id': '490002124ZZ', 'x': 529737.7933655808, ... \n", + "214 490000235YB {'id': '490000235YB', 'x': 529570.7813227688, ... \n", "215 other_new_stop {'services': {'20274'}, 'routes': {'20274_4'},... \n", "\n", " new_attributes \\\n", - "214 {'id': '490002124ZZ', 'x': 529737.7933655808, ... \n", + "214 {'id': '490000235YB', 'x': 529570.7813227688, ... \n", "215 {'services': {'20274'}, 'routes': {'20274_4'},... \n", "\n", " diff \n", - "214 [(add, , [('geometry', ... " ] }, "execution_count": 49, @@ -2597,21 +2619,21 @@ " Wardour Street (Stop OM)\n", " 529477.750156\n", " 181314.437043\n", - " POINT (529477.7501560802 181314.4370430721)\n", + " POINT (529477.7501560802 181314.43704307207)\n", " \n", " \n", " 490010689KB.link:981\n", " Great Titchfield Street Oxford Circus Station...\n", " 529166.734973\n", " 181256.336723\n", - " POINT (529166.7349732723 181256.3367228433)\n", + " POINT (529166.7349732723 181256.33672284335)\n", " \n", " \n", - " 490010689OJ.link:1787\n", - " Great Titchfield Street Oxford Circus Station...\n", - " 529227.773057\n", - " 181280.477507\n", - " POINT (529227.7730568129 181280.4775071898)\n", + " 490000235V.link:3140\n", + " Tottenham Court Road Station (Stop V)\n", + " 529716.723832\n", + " 181371.384818\n", + " POINT (529716.7238324936 181371.3848181052)\n", " \n", " \n", "\n", @@ -2623,21 +2645,21 @@ "490000235YB.link:574 Oxford Street Soho Street (Stop YB) \n", "490014214HE.link:3154 Wardour Street (Stop OM) \n", "490010689KB.link:981 Great Titchfield Street Oxford Circus Station... \n", - "490010689OJ.link:1787 Great Titchfield Street Oxford Circus Station... \n", + "490000235V.link:3140 Tottenham Court Road Station (Stop V) \n", "\n", " x y \\\n", "490000235X.link:834 529981.795880 181412.097576 \n", "490000235YB.link:574 529570.781323 181336.281593 \n", "490014214HE.link:3154 529477.750156 181314.437043 \n", "490010689KB.link:981 529166.734973 181256.336723 \n", - "490010689OJ.link:1787 529227.773057 181280.477507 \n", + "490000235V.link:3140 529716.723832 181371.384818 \n", "\n", - " geometry \n", - "490000235X.link:834 POINT (529981.7958802709 181412.0975758662) \n", - "490000235YB.link:574 POINT (529570.7813227688 181336.2815925331) \n", - "490014214HE.link:3154 POINT (529477.7501560802 181314.4370430721) \n", - "490010689KB.link:981 POINT (529166.7349732723 181256.3367228433) \n", - "490010689OJ.link:1787 POINT (529227.7730568129 181280.4775071898) " + " geometry \n", + "490000235X.link:834 POINT (529981.7958802709 181412.0975758662) \n", + "490000235YB.link:574 POINT (529570.7813227688 181336.2815925331) \n", + "490014214HE.link:3154 POINT (529477.7501560802 181314.43704307207) \n", + "490010689KB.link:981 POINT (529166.7349732723 181256.33672284335) \n", + "490000235V.link:3140 POINT (529716.7238324936 181371.3848181052) " ] }, "execution_count": 50, @@ -2662,7 +2684,7 @@ { "data": { "text/plain": [ - "" + "" ] }, "execution_count": 51, @@ -2671,14 +2693,12 @@ }, { "data": { - "image/png": "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", + "image/png": "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rFiBmpoaqecjMTERGo0GaWlpOH36NP76179i+fLlyMjIkHo15s6dC6VSifT0dFRWViI/Px8bNmzA0qVLO7zlQURERD3Q3WkhlqmeDz7mz58vhBCioaFBpKenC7VaLQYNGiTGjBkjNm7caDVNc9WqVXaPsWPHDinm5MmTIjExUYSEhIiAgADx1FNPicLCQqtzuXTpkkhJSREqlUqEhISIRYsWWU0RFUKIr7/+WkyZMkUolUoRFhYmVq9e7fCUUSE4bZSIiHyLu77XZEKwbGRnjEYjgoKCYDAYpJ4PIiIib+Wu7zWuEENEREROY0JBRERETmNCQURERE5jQkFEREROY0JBRERETmNCQURERE5jQkFEREROY0JBRERETmNCQURERE5jQkFEREROY0JBRERETmNCQURERE5jQkFEREROY0JBRERETmNCQURERE5jQkFEREROY0JBRERETmNCQURERE5jQkFEREROY0JBRERETmNCQURERE5jQkFEREROY0JBRERETmNCQURERE5jQkFEREROY0JBRERETmNCQURERE5jQkFEREROY0JBRERETmNCQURERE5jQkFEREROY0JBRERETmNCQURERE5jQkFEREROY0JBRERETmNCQURERE5jQkFEREROY0JBRERETmNCQURERE5jQkFEREROY0JBRERETut2QlFSUoLU1FSo1WrIZDJ88sknVvtbWlqwaNEihIeHQ6VSYdy4cdiyZYtVzLZt2zB16lQEBgZCJpPh+vXrdt9r3759mDx5MlQqFUJDQ/H8889b7a+rq0Nqair8/f0RGhqKxYsXo7293SqmoqIC8fHxUKlUGDlyJNauXQshRHebTURERJ0Y0N0XtLa2YsKECXjllVcwZ84cm/1LlixBcXEx9uzZg8jISBQVFSEzMxNqtRqzZ88GANy8eRPJyclITk5GVlaW3ff5+OOPkZGRgQ0bNuCnP/0phBCoqKiQ9t+9excpKSkYOnQojh07hmvXrmH+/PkQQiAvLw8AYDQaMX36dCQkJODkyZOorq5Geno6/P39sWzZsu42nYiIiDoinABA5OfnW217/PHHxdq1a622TZw4Ubz55ps2ry8uLhYARHNzs9V2k8kkRo4cKf70pz91+N6FhYVCLpeL+vp6adv7778vlEqlMBgMQgghNm/eLIKCgsTt27elmJycHKFWq4XZ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", "text/plain": [ - "
" + "
" ] }, - "metadata": { - "needs_background": "light" - }, + "metadata": {}, "output_type": "display_data" } ], @@ -2706,13 +2726,13 @@ " 'y': 181336.2815925331,\n", " 'epsg': 'epsg:27700',\n", " 'name': 'Oxford Street Soho Street (Stop YB)',\n", - " 'lat': 51.51609803324077,\n", + " 'lat': 51.51609803324078,\n", " 'lon': -0.13404398709291904,\n", " 's2_id': 5221390696959560815,\n", " 'linkRefId': '574',\n", " 'isBlocking': 'false',\n", " 'new_attribute': 'hello!',\n", - " 'geometry': }" + " 'geometry': }" ] }, "execution_count": 52, @@ -2745,7 +2765,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "2022-07-14 15:50:00,895 - `route_trips_to_dataframe` method is deprecated and will be replaced by `trips_to_dataframe`in later versions.\n" + "2023-12-08 13:44:20,294 - `route_trips_to_dataframe` method is deprecated and will be replaced by `trips_to_dataframe`in later versions.\n" ] }, { @@ -2778,7 +2798,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "2022-07-14 15:50:00,959 - Changed Route attributes for 69 routes\n" + "2023-12-08 13:44:20,387 - Changed Route attributes for 69 routes\n" ] } ], @@ -2808,7 +2828,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "2022-07-14 15:50:00,965 - `route_trips_to_dataframe` method is deprecated and will be replaced by `trips_to_dataframe`in later versions.\n" + "2023-12-08 13:44:20,395 - `route_trips_to_dataframe` method is deprecated and will be replaced by `trips_to_dataframe`in later versions.\n" ] }, { @@ -2873,41 +2893,41 @@ " \n", " \n", " \n", + " 20274\n", + " Service_N55\n", + " Brand_new_nameService_N55\n", + " \n", + " \n", + " 18915\n", + " Service_N5\n", + " Brand_new_nameService_N5\n", + " \n", + " \n", " 14134\n", " Service_98\n", " Brand_new_nameService_98\n", " \n", " \n", - " 20274\n", - " Service_N55\n", - " Brand_new_nameService_N55\n", + " 15660\n", + " Service_113\n", + " Brand_new_nameService_113\n", " \n", " \n", " 18853\n", " Service_N8\n", " Brand_new_nameService_N8\n", " \n", - " \n", - " 15234\n", - " Service_134\n", - " Brand_new_nameService_134\n", - " \n", - " \n", - " 17732\n", - " Service_N20\n", - " Brand_new_nameService_N20\n", - " \n", " \n", "\n", "" ], "text/plain": [ " name new_name\n", - "14134 Service_98 Brand_new_nameService_98\n", "20274 Service_N55 Brand_new_nameService_N55\n", - "18853 Service_N8 Brand_new_nameService_N8\n", - "15234 Service_134 Brand_new_nameService_134\n", - "17732 Service_N20 Brand_new_nameService_N20" + "18915 Service_N5 Brand_new_nameService_N5\n", + "14134 Service_98 Brand_new_nameService_98\n", + "15660 Service_113 Brand_new_nameService_113\n", + "18853 Service_N8 Brand_new_nameService_N8" ] }, "execution_count": 56, @@ -2933,14 +2953,14 @@ { "data": { "text/plain": [ - "{'Service_98': 'Brand_new_nameService_98',\n", - " 'Service_N55': 'Brand_new_nameService_N55',\n", + "{'Service_N55': 'Brand_new_nameService_N55',\n", + " 'Service_N5': 'Brand_new_nameService_N5',\n", + " 'Service_98': 'Brand_new_nameService_98',\n", + " 'Service_113': 'Brand_new_nameService_113',\n", " 'Service_N8': 'Brand_new_nameService_N8',\n", + " 'Service_205': 'Brand_new_nameService_205',\n", " 'Service_134': 'Brand_new_nameService_134',\n", " 'Service_N20': 'Brand_new_nameService_N20',\n", - " 'Service_205': 'Brand_new_nameService_205',\n", - " 'Service_113': 'Brand_new_nameService_113',\n", - " 'Service_N5': 'Brand_new_nameService_N5',\n", " 'Service_94': 'Brand_new_nameService_94'}" ] }, @@ -2975,7 +2995,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "2022-07-14 15:50:01,017 - Changed Service attributes for 9 services\n" + "2023-12-08 13:44:20,431 - Changed Service attributes for 9 services\n" ] } ], @@ -3027,18 +3047,18 @@ " \n", " \n", " 289\n", - " 2022-07-14 15:50:01\n", + " 2023-12-08 13:44:20\n", " modify\n", " service\n", - " 17732\n", - " 17732\n", - " {'id': '17732', 'name': 'Service_N20'}\n", - " {'id': '17732', 'name': 'Brand_new_nameService...\n", - " [(change, name, (Service_N20, Brand_new_nameSe...\n", + " 18853\n", + " 18853\n", + " {'id': '18853', 'name': 'Service_N8'}\n", + " {'id': '18853', 'name': 'Brand_new_nameService...\n", + " [(change, name, (Service_N8, Brand_new_nameSer...\n", " \n", " \n", " 290\n", - " 2022-07-14 15:50:01\n", + " 2023-12-08 13:44:20\n", " modify\n", " service\n", " 12430\n", @@ -3049,29 +3069,29 @@ " \n", " \n", " 291\n", - " 2022-07-14 15:50:01\n", + " 2023-12-08 13:44:20\n", " modify\n", " service\n", - " 15660\n", - " 15660\n", - " {'id': '15660', 'name': 'Service_113'}\n", - " {'id': '15660', 'name': 'Brand_new_nameService...\n", - " [(change, name, (Service_113, Brand_new_nameSe...\n", + " 15234\n", + " 15234\n", + " {'id': '15234', 'name': 'Service_134'}\n", + " {'id': '15234', 'name': 'Brand_new_nameService...\n", + " [(change, name, (Service_134, Brand_new_nameSe...\n", " \n", " \n", " 292\n", - " 2022-07-14 15:50:01\n", + " 2023-12-08 13:44:20\n", " modify\n", " service\n", - " 18915\n", - " 18915\n", - " {'id': '18915', 'name': 'Service_N5'}\n", - " {'id': '18915', 'name': 'Brand_new_nameService...\n", - " [(change, name, (Service_N5, Brand_new_nameSer...\n", + " 17732\n", + " 17732\n", + " {'id': '17732', 'name': 'Service_N20'}\n", + " {'id': '17732', 'name': 'Brand_new_nameService...\n", + " [(change, name, (Service_N20, Brand_new_nameSe...\n", " \n", " \n", " 293\n", - " 2022-07-14 15:50:01\n", + " 2023-12-08 13:44:20\n", " modify\n", " service\n", " 14073\n", @@ -3086,31 +3106,31 @@ ], "text/plain": [ " timestamp change_event object_type old_id new_id \\\n", - "289 2022-07-14 15:50:01 modify service 17732 17732 \n", - "290 2022-07-14 15:50:01 modify service 12430 12430 \n", - "291 2022-07-14 15:50:01 modify service 15660 15660 \n", - "292 2022-07-14 15:50:01 modify service 18915 18915 \n", - "293 2022-07-14 15:50:01 modify service 14073 14073 \n", + "289 2023-12-08 13:44:20 modify service 18853 18853 \n", + "290 2023-12-08 13:44:20 modify service 12430 12430 \n", + "291 2023-12-08 13:44:20 modify service 15234 15234 \n", + "292 2023-12-08 13:44:20 modify service 17732 17732 \n", + "293 2023-12-08 13:44:20 modify service 14073 14073 \n", "\n", " old_attributes \\\n", - "289 {'id': '17732', 'name': 'Service_N20'} \n", + "289 {'id': '18853', 'name': 'Service_N8'} \n", "290 {'id': '12430', 'name': 'Service_205'} \n", - "291 {'id': '15660', 'name': 'Service_113'} \n", - "292 {'id': '18915', 'name': 'Service_N5'} \n", + "291 {'id': '15234', 'name': 'Service_134'} \n", + "292 {'id': '17732', 'name': 'Service_N20'} \n", "293 {'id': '14073', 'name': 'Service_94'} \n", "\n", " new_attributes \\\n", - "289 {'id': '17732', 'name': 'Brand_new_nameService... \n", + "289 {'id': '18853', 'name': 'Brand_new_nameService... \n", "290 {'id': '12430', 'name': 'Brand_new_nameService... \n", - "291 {'id': '15660', 'name': 'Brand_new_nameService... \n", - "292 {'id': '18915', 'name': 'Brand_new_nameService... \n", + "291 {'id': '15234', 'name': 'Brand_new_nameService... \n", + "292 {'id': '17732', 'name': 'Brand_new_nameService... \n", "293 {'id': '14073', 'name': 'Brand_new_nameService... \n", "\n", " diff \n", - "289 [(change, name, (Service_N20, Brand_new_nameSe... \n", + "289 [(change, name, (Service_N8, Brand_new_nameSer... \n", "290 [(change, name, (Service_205, Brand_new_nameSe... \n", - "291 [(change, name, (Service_113, Brand_new_nameSe... \n", - "292 [(change, name, (Service_N5, Brand_new_nameSer... \n", + "291 [(change, name, (Service_134, Brand_new_nameSe... \n", + "292 [(change, name, (Service_N20, Brand_new_nameSe... \n", "293 [(change, name, (Service_94, Brand_new_nameSer... " ] }, @@ -3232,16 +3252,16 @@ "name": "stderr", "output_type": "stream", "text": [ - "2022-07-14 15:50:01,252 - The following vehicle types are missing from the `vehicle_types` attribute: {'piggyback'}\n", - "2022-07-14 15:50:01,252 - Vehicles affected by missing vehicle types: {'veh_2331_bus': {'type': 'piggyback'}, 'veh_2333_bus': {'type': 'piggyback'}, 'veh_2335_bus': {'type': 'piggyback'}, 'veh_2337_bus': {'type': 'piggyback'}, 'veh_2339_bus': {'type': 'piggyback'}}\n", - "2022-07-14 15:50:01,387 - Removed Services with IDs `20274`, and Routes: {'VJ375a660d47a2aa570aa20a8568012da8497ffecf', '20274_4', 'VJ812fad65e7fa418645b57b446f00cba573f2cdaf', 'VJ6c64ab7b477e201cae950efde5bd0cb4e2e8888e'}\n", - "2022-07-14 15:50:01,594 - Removed Services with IDs `18853`, and Routes: {'VJfc4917783c2ca3227789fa7c532c9adf47702095', 'VJ8cacca9a6722c497c413005568182ecf4d50b160', 'VJf3e316e5e605bb512147dee2a989be5a82ef1b5f'}\n", - "2022-07-14 15:50:01,718 - Removed Services with IDs `17732`, and Routes: {'VJ85c23573d670bab5485618b0c5fddff3314efc89', 'VJ0cb60de3ed229c1413abac506e770b6ab8a7c49a'}\n", - "2022-07-14 15:50:01,824 - Removed Services with IDs `12430`, and Routes: {'VJef7f20c3a9bf1419f6401e1e9131fe2c634bcb9a', 'VJ0f3c08222de16c2e278be0a1bf0f9ea47370774e', 'VJ95b4c534d7c903d76ec0340025aa88b81dba3ce4', 'VJ06cd41dcd58d947097df4a8f33234ef423210154', 'VJ948e8caa0f08b9c6bf6330927893942c474b5100', 'VJ15419796737689e742962a625abcf3fd5b3d58b1', 'VJf8e38a73359b6cf743d8e35ee64ef1f7b7914daa', 'VJ8f9aea7491080b0137d3092706f53dc11f7dba45', 'VJ235c8fca539cf931b3c673f9b056606384aff950', 'VJ06420fdab0dfe5c8e7f2f9504df05cf6289cd7d3', 'VJeae6e634f8479e0b6712780d5728f0afca964e64', 'VJeb72539d69ddf8e29f1adf74d43953def196ae41'}\n", - "2022-07-14 15:50:01,917 - Removed Services with IDs `15660`, and Routes: {'VJ1cf651142378958b52229bfe1fa552e49136e60e', 'VJf2e0de4f5dad68cb03064e6064e372dde52cc678', 'VJ3716910ec59c370d9f5c69137df7276b68cf0a08'}\n", - "2022-07-14 15:50:02,003 - Removed Services with IDs `18915`, and Routes: {'VJ8a4b1ca7dfd0a130abd1de9f55f3b756617dd4ca', 'VJ887921c00645929c5402ac46592e57c368ea63a1', 'VJ0d304b95d39f4bce48e6ff26ddd73a9c06f17f4f', 'VJb08f8a2de01a4ef99d3b7fefd9022117ac307531', 'VJ520ec0c0ca58a849349fa614b5cf9270ac5c93da'}\n", - "2022-07-14 15:50:02,084 - Removed Services with IDs `14073`, and Routes: {'VJe8cffad09738ff7b9698b333e3247918d5c45358', 'VJea6046f64f85febf1854290fb8f76e921e3ac96b', 'VJd132b905afc6c0e8e8a994142e301ca5c0f70e22', 'VJe6ba07ef9f19ae40517261ad626bf34dd656491a', 'VJdbc280077e505b4f8d66586ca51751a125cb4ef0', 'VJaa5ee0daec7529d7668c81fe7fac0c4ff545daea', 'VJf6055fdf9ef0dd6d0500b6c11adcfdd4d10655dc', 'VJe18efadf172576fea7989ec1f233f26854c0f66a', 'VJfc35884fc4f11dc408a209c19f56f3b60f634daf', 'VJb4309b7a9598539ab9942ea1bcadc60a91b978ba', 'VJd9dbeefeca6d74ef2594a17514ebc08ee2d503b2', 'VJ6cf76a4c03cca468cb6954db7f7aad5ae189df13', 'VJ93d8207ae8540b4ff59d47c9ee1ec5689084522d', 'VJ24fe211d801738b556a39f815256d7f6bc544ec5', 'VJc8cdbd902dadeebeeb4dbd7332b564ee2e4b00ce'}\n", - "2022-07-14 15:50:02,087 - Removed Stops with indices `['other_new_stop', '490000173JB.link:1663']`.Routes affected: set(). Services affected: set().\n" + "2023-12-08 13:44:20,655 - The following vehicle types are missing from the `vehicle_types` attribute: {'piggyback'}\n", + "2023-12-08 13:44:20,658 - Vehicles affected by missing vehicle types: {'veh_2331_bus': {'type': 'piggyback'}, 'veh_2333_bus': {'type': 'piggyback'}, 'veh_2335_bus': {'type': 'piggyback'}, 'veh_2337_bus': {'type': 'piggyback'}, 'veh_2339_bus': {'type': 'piggyback'}}\n", + "2023-12-08 13:44:20,713 - Removed Services with IDs `20274`, and Routes: {'VJ6c64ab7b477e201cae950efde5bd0cb4e2e8888e', '20274_4', 'VJ812fad65e7fa418645b57b446f00cba573f2cdaf', 'VJ375a660d47a2aa570aa20a8568012da8497ffecf'}\n", + "2023-12-08 13:44:20,774 - Removed Services with IDs `18915`, and Routes: {'VJ887921c00645929c5402ac46592e57c368ea63a1', 'VJ8a4b1ca7dfd0a130abd1de9f55f3b756617dd4ca', 'VJ520ec0c0ca58a849349fa614b5cf9270ac5c93da', 'VJ0d304b95d39f4bce48e6ff26ddd73a9c06f17f4f', 'VJb08f8a2de01a4ef99d3b7fefd9022117ac307531'}\n", + "2023-12-08 13:44:20,831 - Removed Services with IDs `15660`, and Routes: {'VJ3716910ec59c370d9f5c69137df7276b68cf0a08', 'VJf2e0de4f5dad68cb03064e6064e372dde52cc678', 'VJ1cf651142378958b52229bfe1fa552e49136e60e'}\n", + "2023-12-08 13:44:20,895 - Removed Services with IDs `18853`, and Routes: {'VJ8cacca9a6722c497c413005568182ecf4d50b160', 'VJfc4917783c2ca3227789fa7c532c9adf47702095', 'VJf3e316e5e605bb512147dee2a989be5a82ef1b5f'}\n", + "2023-12-08 13:44:20,935 - Removed Services with IDs `12430`, and Routes: {'VJf8e38a73359b6cf743d8e35ee64ef1f7b7914daa', 'VJ15419796737689e742962a625abcf3fd5b3d58b1', 'VJ0f3c08222de16c2e278be0a1bf0f9ea47370774e', 'VJ8f9aea7491080b0137d3092706f53dc11f7dba45', 'VJef7f20c3a9bf1419f6401e1e9131fe2c634bcb9a', 'VJ95b4c534d7c903d76ec0340025aa88b81dba3ce4', 'VJ06420fdab0dfe5c8e7f2f9504df05cf6289cd7d3', 'VJeb72539d69ddf8e29f1adf74d43953def196ae41', 'VJ948e8caa0f08b9c6bf6330927893942c474b5100', 'VJeae6e634f8479e0b6712780d5728f0afca964e64', 'VJ06cd41dcd58d947097df4a8f33234ef423210154', 'VJ235c8fca539cf931b3c673f9b056606384aff950'}\n", + "2023-12-08 13:44:20,977 - Removed Services with IDs `17732`, and Routes: {'VJ0cb60de3ed229c1413abac506e770b6ab8a7c49a', 'VJ85c23573d670bab5485618b0c5fddff3314efc89'}\n", + "2023-12-08 13:44:21,006 - Removed Services with IDs `14073`, and Routes: {'VJ6cf76a4c03cca468cb6954db7f7aad5ae189df13', 'VJaa5ee0daec7529d7668c81fe7fac0c4ff545daea', 'VJe18efadf172576fea7989ec1f233f26854c0f66a', 'VJfc35884fc4f11dc408a209c19f56f3b60f634daf', 'VJe8cffad09738ff7b9698b333e3247918d5c45358', 'VJb4309b7a9598539ab9942ea1bcadc60a91b978ba', 'VJ24fe211d801738b556a39f815256d7f6bc544ec5', 'VJdbc280077e505b4f8d66586ca51751a125cb4ef0', 'VJc8cdbd902dadeebeeb4dbd7332b564ee2e4b00ce', 'VJd9dbeefeca6d74ef2594a17514ebc08ee2d503b2', 'VJea6046f64f85febf1854290fb8f76e921e3ac96b', 'VJd132b905afc6c0e8e8a994142e301ca5c0f70e22', 'VJe6ba07ef9f19ae40517261ad626bf34dd656491a', 'VJ93d8207ae8540b4ff59d47c9ee1ec5689084522d', 'VJf6055fdf9ef0dd6d0500b6c11adcfdd4d10655dc'}\n", + "2023-12-08 13:44:21,007 - Removed Stops with indices `['490000173JB.link:1663', 'other_new_stop']`.Routes affected: set(). Services affected: set().\n" ] } ], @@ -3312,41 +3332,36 @@ "name": "stderr", "output_type": "stream", "text": [ - "2022-07-14 15:50:03,479 - Subsetting a Network will likely result in a disconnected network graph. A cleaner will be ran that will remove links to make the resulting Network strongly connected for modes: car, walk, bike.\n", - "2022-07-14 15:50:03,543 - Schedule will be subsetted using given services: ['12430']. Links pertaining to their network routes will also be retained.\n", - "2022-07-14 15:50:03,720 - The following vehicle types are missing from the `vehicle_types` attribute: {'piggyback'}\n", - "2022-07-14 15:50:03,721 - Vehicles affected by missing vehicle types: {'veh_2331_bus': {'type': 'piggyback'}, 'veh_2333_bus': {'type': 'piggyback'}, 'veh_2335_bus': {'type': 'piggyback'}, 'veh_2337_bus': {'type': 'piggyback'}, 'veh_2339_bus': {'type': 'piggyback'}}\n", - "2022-07-14 15:50:03,834 - Removed Services with IDs `14134`, and Routes: {'VJb93a17a405fe502c5b3a2d6544105b0311da9fe2', 'VJ323d02e117552af1565f2ff1273a612655c829c4', 'VJ5909ba51575a9459eb0013fbd31c8205455ca2fd', 'VJ2aba67e3ed98f2ed5f5966c1ac394cbf6d1943d7', 'VJ26095b8f9f9db92ca2e53d4c086a7dcd82a13be9', 'VJ2c87b2a59184888f3175b55bde7b02d024ea8607', 'VJ4e2b897edf0e7b8a8e3b5516ab43ce56f72c5cff', 'VJf9a22035ae6f25bb420df833474943ad76065c89', 'VJd78967364a302cf232c5139d40622dcb6c238c9e', 'VJ12ba6089dfb2733e29c415a1a0015fef30fd5305', 'VJdb0c128567fcbcc063d554ae1c95851cee41b909', 'VJdf3936da1a51eb33db594ef99738802c14b19995', 'VJa7f37392e276aeac26c7e73bbc05e6a71af38dba', 'VJ4c6fa387b0d4be94a6c3679b94790b183e2558ca', 'VJ256e98df611ff48afe737ddc81cbcde82e4e81c8', 'VJ4e311a625836374adf4cfaa841224840dbeb7619'}\n", - "2022-07-14 15:50:03,941 - Removed Services with IDs `20274`, and Routes: {'VJ375a660d47a2aa570aa20a8568012da8497ffecf', '20274_4', 'VJ812fad65e7fa418645b57b446f00cba573f2cdaf', 'VJ6c64ab7b477e201cae950efde5bd0cb4e2e8888e'}\n", - "2022-07-14 15:50:04,136 - Removed Services with IDs `18853`, and Routes: {'VJfc4917783c2ca3227789fa7c532c9adf47702095', 'VJ8cacca9a6722c497c413005568182ecf4d50b160', 'VJf3e316e5e605bb512147dee2a989be5a82ef1b5f'}\n", - "2022-07-14 15:50:04,215 - Removed Services with IDs `15234`, and Routes: {'VJd4cbfb092a104ac6a3164a86e9765f68734fdfcf', 'VJ28a8a6a4ab02807a4fdfd199e5c2ca0622d34d0c', 'VJ8ccf92aa0f351b2e31f1a078b968dff4c2505c02', 'VJ1a8cc306354fdc322d739ae644eb73444341d08d', 'VJ5b511605b1e07428c2e0a7d676d301c6c40dcca6', 'VJ3d50b96792ae8495dbe5a5e372849a60c48b2279', 'VJ9b58a59e3d74941586a5bca7726a8aa624da67fc', 'VJbf9d4fdb976223e6a026c0c669ed290418abefee', 'VJ652c769bc42361cc0308dff59a1fdcf0949bdade'}\n", - "2022-07-14 15:50:04,303 - Removed Services with IDs `17732`, and Routes: {'VJ85c23573d670bab5485618b0c5fddff3314efc89', 'VJ0cb60de3ed229c1413abac506e770b6ab8a7c49a'}\n", - "2022-07-14 15:50:04,367 - Removed Services with IDs `15660`, and Routes: {'VJ1cf651142378958b52229bfe1fa552e49136e60e', 'VJf2e0de4f5dad68cb03064e6064e372dde52cc678', 'VJ3716910ec59c370d9f5c69137df7276b68cf0a08'}\n", - "2022-07-14 15:50:04,428 - Removed Services with IDs `18915`, and Routes: {'VJ8a4b1ca7dfd0a130abd1de9f55f3b756617dd4ca', 'VJ887921c00645929c5402ac46592e57c368ea63a1', 'VJ0d304b95d39f4bce48e6ff26ddd73a9c06f17f4f', 'VJb08f8a2de01a4ef99d3b7fefd9022117ac307531', 'VJ520ec0c0ca58a849349fa614b5cf9270ac5c93da'}\n", - "2022-07-14 15:50:04,460 - Removed Services with IDs `14073`, and Routes: {'VJe8cffad09738ff7b9698b333e3247918d5c45358', 'VJea6046f64f85febf1854290fb8f76e921e3ac96b', 'VJd132b905afc6c0e8e8a994142e301ca5c0f70e22', 'VJe6ba07ef9f19ae40517261ad626bf34dd656491a', 'VJdbc280077e505b4f8d66586ca51751a125cb4ef0', 'VJaa5ee0daec7529d7668c81fe7fac0c4ff545daea', 'VJf6055fdf9ef0dd6d0500b6c11adcfdd4d10655dc', 'VJe18efadf172576fea7989ec1f233f26854c0f66a', 'VJfc35884fc4f11dc408a209c19f56f3b60f634daf', 'VJb4309b7a9598539ab9942ea1bcadc60a91b978ba', 'VJd9dbeefeca6d74ef2594a17514ebc08ee2d503b2', 'VJ6cf76a4c03cca468cb6954db7f7aad5ae189df13', 'VJ93d8207ae8540b4ff59d47c9ee1ec5689084522d', 'VJ24fe211d801738b556a39f815256d7f6bc544ec5', 'VJc8cdbd902dadeebeeb4dbd7332b564ee2e4b00ce'}\n", - "2022-07-14 15:50:04,462 - Removed Stops with indices `['other_new_stop', '490000173JB.link:1663']`.Routes affected: set(). Services affected: set().\n", - "2022-07-14 15:50:04,486 - Param: strongly_connected_modes is defaulting to `{'car', 'walk', 'bike'}` You can change this behaviour by passing the parameter.\n", - "2022-07-14 15:50:04,495 - The graph for mode car is not strongly connected. The largest 1 connected components will be extracted.\n", - "2022-07-14 15:50:04,509 - Extracting largest connected components resulted in mode: car being deleted from 82 edges\n", - "/Users/kasia.kozlowska/PycharmProjects/ABM/genet/genet/core.py:595: UserWarning: Boolean Series key will be reindexed to match DataFrame index.\n", - " df = df.loc[links & set(df.index)][df['modes'].apply(lambda x: bool(mode & x))]\n", - "2022-07-14 15:50:04,531 - Changed Link attributes for 82 links\n", - "2022-07-14 15:50:04,537 - Removed 56 links\n", - "2022-07-14 15:50:04,540 - The graph for modes: walk does not have any connected components. This method returns True because if the graph is empty for this mode there is no reason to fail this check.\n", - "2022-07-14 15:50:04,544 - The graph for modes: bike does not have any connected components. This method returns True because if the graph is empty for this mode there is no reason to fail this check.\n", - "2022-07-14 15:50:04,548 - Subsetted Network is ready - do not forget to validate and visualise your subset!\n" + "2023-12-08 13:44:21,462 - Subsetting a Network will likely result in a disconnected network graph. A cleaner will be ran that will remove links to make the resulting Network strongly connected for modes: car, walk, bike.\n", + "2023-12-08 13:44:21,512 - Schedule will be subsetted using given services: ['12430']. Links pertaining to their network routes will also be retained.\n", + "2023-12-08 13:44:21,599 - The following vehicle types are missing from the `vehicle_types` attribute: {'piggyback'}\n", + "2023-12-08 13:44:21,599 - Vehicles affected by missing vehicle types: {'veh_2331_bus': {'type': 'piggyback'}, 'veh_2333_bus': {'type': 'piggyback'}, 'veh_2335_bus': {'type': 'piggyback'}, 'veh_2337_bus': {'type': 'piggyback'}, 'veh_2339_bus': {'type': 'piggyback'}}\n", + "2023-12-08 13:44:21,658 - Removed Services with IDs `20274`, and Routes: {'VJ6c64ab7b477e201cae950efde5bd0cb4e2e8888e', '20274_4', 'VJ812fad65e7fa418645b57b446f00cba573f2cdaf', 'VJ375a660d47a2aa570aa20a8568012da8497ffecf'}\n", + "2023-12-08 13:44:21,789 - Removed Services with IDs `18915`, and Routes: {'VJ887921c00645929c5402ac46592e57c368ea63a1', 'VJ8a4b1ca7dfd0a130abd1de9f55f3b756617dd4ca', 'VJ520ec0c0ca58a849349fa614b5cf9270ac5c93da', 'VJ0d304b95d39f4bce48e6ff26ddd73a9c06f17f4f', 'VJb08f8a2de01a4ef99d3b7fefd9022117ac307531'}\n", + "2023-12-08 13:44:21,834 - Removed Services with IDs `14134`, and Routes: {'VJ4e2b897edf0e7b8a8e3b5516ab43ce56f72c5cff', 'VJd78967364a302cf232c5139d40622dcb6c238c9e', 'VJ256e98df611ff48afe737ddc81cbcde82e4e81c8', 'VJ4e311a625836374adf4cfaa841224840dbeb7619', 'VJ2c87b2a59184888f3175b55bde7b02d024ea8607', 'VJ26095b8f9f9db92ca2e53d4c086a7dcd82a13be9', 'VJdb0c128567fcbcc063d554ae1c95851cee41b909', 'VJ5909ba51575a9459eb0013fbd31c8205455ca2fd', 'VJa7f37392e276aeac26c7e73bbc05e6a71af38dba', 'VJb93a17a405fe502c5b3a2d6544105b0311da9fe2', 'VJ2aba67e3ed98f2ed5f5966c1ac394cbf6d1943d7', 'VJ12ba6089dfb2733e29c415a1a0015fef30fd5305', 'VJ4c6fa387b0d4be94a6c3679b94790b183e2558ca', 'VJdf3936da1a51eb33db594ef99738802c14b19995', 'VJf9a22035ae6f25bb420df833474943ad76065c89', 'VJ323d02e117552af1565f2ff1273a612655c829c4'}\n", + "2023-12-08 13:44:21,875 - Removed Services with IDs `15660`, and Routes: {'VJ3716910ec59c370d9f5c69137df7276b68cf0a08', 'VJf2e0de4f5dad68cb03064e6064e372dde52cc678', 'VJ1cf651142378958b52229bfe1fa552e49136e60e'}\n", + "2023-12-08 13:44:21,912 - Removed Services with IDs `18853`, and Routes: {'VJ8cacca9a6722c497c413005568182ecf4d50b160', 'VJfc4917783c2ca3227789fa7c532c9adf47702095', 'VJf3e316e5e605bb512147dee2a989be5a82ef1b5f'}\n", + "2023-12-08 13:44:21,938 - Removed Services with IDs `15234`, and Routes: {'VJ5b511605b1e07428c2e0a7d676d301c6c40dcca6', 'VJ28a8a6a4ab02807a4fdfd199e5c2ca0622d34d0c', 'VJ3d50b96792ae8495dbe5a5e372849a60c48b2279', 'VJd4cbfb092a104ac6a3164a86e9765f68734fdfcf', 'VJ652c769bc42361cc0308dff59a1fdcf0949bdade', 'VJ8ccf92aa0f351b2e31f1a078b968dff4c2505c02', 'VJ1a8cc306354fdc322d739ae644eb73444341d08d', 'VJ9b58a59e3d74941586a5bca7726a8aa624da67fc', 'VJbf9d4fdb976223e6a026c0c669ed290418abefee'}\n", + "2023-12-08 13:44:21,963 - Removed Services with IDs `17732`, and Routes: {'VJ0cb60de3ed229c1413abac506e770b6ab8a7c49a', 'VJ85c23573d670bab5485618b0c5fddff3314efc89'}\n", + "2023-12-08 13:44:21,979 - Removed Services with IDs `14073`, and Routes: {'VJ6cf76a4c03cca468cb6954db7f7aad5ae189df13', 'VJaa5ee0daec7529d7668c81fe7fac0c4ff545daea', 'VJe18efadf172576fea7989ec1f233f26854c0f66a', 'VJfc35884fc4f11dc408a209c19f56f3b60f634daf', 'VJe8cffad09738ff7b9698b333e3247918d5c45358', 'VJb4309b7a9598539ab9942ea1bcadc60a91b978ba', 'VJ24fe211d801738b556a39f815256d7f6bc544ec5', 'VJdbc280077e505b4f8d66586ca51751a125cb4ef0', 'VJc8cdbd902dadeebeeb4dbd7332b564ee2e4b00ce', 'VJd9dbeefeca6d74ef2594a17514ebc08ee2d503b2', 'VJea6046f64f85febf1854290fb8f76e921e3ac96b', 'VJd132b905afc6c0e8e8a994142e301ca5c0f70e22', 'VJe6ba07ef9f19ae40517261ad626bf34dd656491a', 'VJ93d8207ae8540b4ff59d47c9ee1ec5689084522d', 'VJf6055fdf9ef0dd6d0500b6c11adcfdd4d10655dc'}\n", + "2023-12-08 13:44:21,981 - Removed Stops with indices `['490000173JB.link:1663', 'other_new_stop']`.Routes affected: set(). Services affected: set().\n", + "2023-12-08 13:44:21,990 - Param: strongly_connected_modes is defaulting to `{'car', 'walk', 'bike'}` You can change this behaviour by passing the parameter.\n", + "2023-12-08 13:44:21,995 - The graph for mode car is not strongly connected. The largest 1 connected components will be extracted.\n", + "2023-12-08 13:44:22,000 - Extracting largest connected components resulted in mode: car being deleted from 82 edges\n", + "/Users/bryn.pickering/Repos/arup-group/genet/genet/core.py:674: UserWarning: Boolean Series key will be reindexed to match DataFrame index.\n", + " df = df.loc[df.index.intersection(links)][df[\"modes\"].apply(lambda x: bool(mode & x))]\n", + "2023-12-08 13:44:22,033 - Changed Link attributes for 82 links\n", + "2023-12-08 13:44:22,036 - Removed 56 links\n", + "2023-12-08 13:44:22,037 - The graph for modes: walk does not have any connected components. This method returns True because if the graph is empty for this mode there is no reason to fail this check.\n", + "2023-12-08 13:44:22,038 - The graph for modes: bike does not have any connected components. This method returns True because if the graph is empty for this mode there is no reason to fail this check.\n", + "2023-12-08 13:44:22,039 - Subsetted Network is ready - do not forget to validate and visualise your subset!\n" ] }, { "data": { "text/plain": [ - "