diff --git a/conveyal_update/README.md b/conveyal_update/README.md
index 418be1ab5..60723c5f1 100644
--- a/conveyal_update/README.md
+++ b/conveyal_update/README.md
@@ -11,7 +11,7 @@
* Set target date in `conveyal_vars.py`. Region boundaries are also set here, but these should remain static unless the decision is made to use entirely different regions in Conveyal. Target date should be a mid-week day.
* `evaluate_feeds.py` includes functions to check to see which feeds have service defined on the target date, and show feeds without any apparent service, including if that service is apparently captured in another feed. This helps check for potential coverage gaps, likely due to GTFS feed expirations and/or the [publishing future service issue](https://github.com/MobilityData/GTFS_Schedule_Best-Practices/issues/48). You may have to shift the target date around to find the best overall coverage, and/or manually edit important but missing feeds to define service if reasonable.
* `match_feeds_regions.py` matches feeds to Conveyal regions, based on if the feed contains _any_ stops within each region.
-* `download_data.py` downloads and zips original GTFS feeds, and additionally generates a shell script that can be used to download, crop, and filter OSM data for each region using Osmosis (not currently able to do so via hub, use other platform).
+* `download_data.py` downloads and zips original GTFS feeds, and additionally generates a shell script that can be used to download, crop, and filter OSM data for each region using Osmosis (not currently able to do so via hub, use other platform). Downloaded feeds are labelled `{row.gtfs_dataset_name.replace(" ", "_")}_{row.feed_key}_gtfs.zip`
## Workflow
diff --git a/conveyal_update/dev_conveyal_ids.ipynb b/conveyal_update/dev_conveyal_ids.ipynb
new file mode 100644
index 000000000..99debf2b4
--- /dev/null
+++ b/conveyal_update/dev_conveyal_ids.ipynb
@@ -0,0 +1,779 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 139,
+ "id": "bdbd0a4a-fb4a-4b8c-ab23-47b7c07f614e",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from siuba import *\n",
+ "import pandas as pd\n",
+ "import datetime as dt\n",
+ "\n",
+ "import download_data\n",
+ "import conveyal_vars\n",
+ "import json"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 16,
+ "id": "83b31583-0603-4118-a70b-4ed58da92455",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from calitp_data_analysis.tables import tbls"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "255a49f8-7acb-47af-ac70-989aa473a0a0",
+ "metadata": {},
+ "source": [
+ "# Matching our warehouse to Conveyal's feed ids..."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "deec5968-10aa-43bf-8e22-897f442e2b81",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "## can't query directly since Hub instance won't be authenticated...\n",
+ "\n",
+ "# bundle_url = 'https://analysis.conveyal.com/api/db/bundles'"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "f12d4d1d-53e6-43e4-b6ec-acbbb05bef95",
+ "metadata": {},
+ "source": [
+ "https://analysis.conveyal.com/api/db/bundles"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 178,
+ "id": "eed635ba-0133-4bef-93a8-ec248dad510e",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "conveyal_region_ids = {'central': '6354939b305024caa2c50d7d',\n",
+ " 'norcal': '6352a1d5e1a8e551137301aa',\n",
+ " 'socal': '635602532d6ff920d83ff32a',\n",
+ " 'mojave': '639387380ef4e9793d1e86d3'}"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 188,
+ "id": "fde8700f-1108-4d10-9cae-6d03b0c05b7d",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# must now specify region, bundle name manually to capture possible revisions\n",
+ "\n",
+ "def import_conveyal_bundle_data(path, bundle_name, region_id):\n",
+ " with open(path) as file:\n",
+ " bundles = json.load(file)\n",
+ " current_bundle = [bundle for bundle in bundles\n",
+ " if bundle['name'] == bundle_name and bundle['regionId'] == region_id][0]\n",
+ " feeds = [\n",
+ " {key:val for key, val in bundle_feed.items() if key != 'errors'}\n",
+ " for bundle_feed in current_bundle['feeds']\n",
+ " ]\n",
+ " return feeds"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 205,
+ "id": "f321f910-26dc-47cf-9e94-acf8b85e015e",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "# socal has revised bundle, will likely require manual handling\n",
+ "conveyal_socal = import_conveyal_bundle_data('./bundles.json', '2023-10-18a', conveyal_region_ids['socal'])\n",
+ "conveyal_norcal = import_conveyal_bundle_data('./bundles.json', '2023-10-18', conveyal_region_ids['norcal'])\n",
+ "conveyal_central = import_conveyal_bundle_data('./bundles.json', '2023-10-18', conveyal_region_ids['central'])\n",
+ "conveyal_mojave = import_conveyal_bundle_data('./bundles.json', '2023-10-18', conveyal_region_ids['mojave'])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "4aed3c88-4c64-428f-9e98-6843b7035ac9",
+ "metadata": {},
+ "source": [
+ "## Deriving start and end dates from one of our feeds?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 189,
+ "id": "b550cd42-fea0-4b0b-9287-5ad7738be136",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "regions_and_feeds = download_data.regions_and_feeds >> distinct(_.region, _.feed_key, _keep_all=True)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 190,
+ "id": "e90e0d5e-bbd7-4071-a0bc-66155efb6fc7",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "
\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " region \n",
+ " feed_key \n",
+ " gtfs_dataset_name \n",
+ " base64_url \n",
+ " date \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 \n",
+ " norcal \n",
+ " 7bd3d8c32eda4869c4d7f8bf2aec5bb0 \n",
+ " Flixbus Schedule \n",
+ " aHR0cDovL2d0ZnMuZ2lzLmZsaXgudGVjaC9ndGZzX2dlbm... \n",
+ " 2023-10-18 \n",
+ " \n",
+ " \n",
+ " 1 \n",
+ " central \n",
+ " 7bd3d8c32eda4869c4d7f8bf2aec5bb0 \n",
+ " Flixbus Schedule \n",
+ " aHR0cDovL2d0ZnMuZ2lzLmZsaXgudGVjaC9ndGZzX2dlbm... \n",
+ " 2023-10-18 \n",
+ " \n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " region feed_key gtfs_dataset_name \\\n",
+ "0 norcal 7bd3d8c32eda4869c4d7f8bf2aec5bb0 Flixbus Schedule \n",
+ "1 central 7bd3d8c32eda4869c4d7f8bf2aec5bb0 Flixbus Schedule \n",
+ "\n",
+ " base64_url date \n",
+ "0 aHR0cDovL2d0ZnMuZ2lzLmZsaXgudGVjaC9ndGZzX2dlbm... 2023-10-18 \n",
+ "1 aHR0cDovL2d0ZnMuZ2lzLmZsaXgudGVjaC9ndGZzX2dlbm... 2023-10-18 "
+ ]
+ },
+ "execution_count": 190,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "regions_and_feeds >> head(2)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 191,
+ "id": "f67cd8f9-a7da-40cd-82f1-96b8c157de19",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def get_region_feed_spans(regions_feeds_df: pd.DataFrame, region: str):\n",
+ " '''\n",
+ " using combined span of calendar and calendar_dates,\n",
+ " get each feed's first and last service date.\n",
+ " useful for matching with Conveyal bundle feed_ids\n",
+ " '''\n",
+ " \n",
+ " region_filtered = regions_feeds_df >> filter(_.region == region)\n",
+ " filter_feeds = filter(_.feed_key.isin(region_filtered.feed_key))\n",
+ " \n",
+ " dim_cd = (tbls.mart_gtfs.dim_calendar_dates()\n",
+ " >> select(_.feed_key, _.date)\n",
+ " >> filter_feeds\n",
+ " >> group_by(_.feed_key)\n",
+ " >> summarize(min_cd = _.date.min(), max_cd = _.date.max())\n",
+ " )\n",
+ "\n",
+ " dim_cal = (tbls.mart_gtfs.dim_calendar()\n",
+ " >> select(_.feed_key, _.start_date, _.end_date)\n",
+ " >> filter_feeds\n",
+ " >> group_by(_.feed_key)\n",
+ " >> summarize(min_cal = _.start_date.min(), max_cal = _.end_date.max())\n",
+ " )\n",
+ " \n",
+ " joined = (dim_cal\n",
+ " >> full_join(_, dim_cd, on = 'feed_key')\n",
+ " >> collect()\n",
+ " )\n",
+ " \n",
+ " joined = (joined >> collect()\n",
+ " >> inner_join(_, region_filtered, on = 'feed_key')\n",
+ " )\n",
+ " \n",
+ " # cross-fill na calendar and calendar_dates values (only one is required)\n",
+ " joined.min_cal = joined.min_cal.fillna(joined.min_cd)\n",
+ " joined.max_cal = joined.max_cal.fillna(joined.max_cd)\n",
+ " joined.min_cd = joined.min_cd.fillna(joined.min_cal)\n",
+ " joined.max_cd = joined.max_cd.fillna(joined.max_cal)\n",
+ "\n",
+ " joined['min_combined'] = joined[['min_cal', 'max_cal', 'max_cd', 'min_cd']].values.min(axis=1).astype(str)\n",
+ " joined['max_combined'] = joined[['min_cal', 'max_cal', 'max_cd', 'min_cd']].values.max(axis=1).astype(str)\n",
+ "\n",
+ " joined['span'] = joined['min_combined'] + '_' + joined['max_combined']\n",
+ " \n",
+ " joined = joined >> select(-_.min_cal, -_.max_cal, -_.min_cd,\n",
+ " -_.max_cd, -_.min_combined, -_.max_combined)\n",
+ " return joined"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 193,
+ "id": "ab4eb04b-7201-4d6f-a4f6-aab1a1484aee",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " feed_key \n",
+ " region \n",
+ " gtfs_dataset_name \n",
+ " base64_url \n",
+ " date \n",
+ " span \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 \n",
+ " f12e4782e7a1751f1c1e8dfb2a24861d \n",
+ " norcal \n",
+ " Siskiyou Schedule \n",
+ " aHR0cHM6Ly9kYXRhLnRyaWxsaXVtdHJhbnNpdC5jb20vZ3... \n",
+ " 2023-10-18 \n",
+ " 2023-02-13_2029-12-31 \n",
+ " \n",
+ " \n",
+ " 1 \n",
+ " 598ff5ab409c5158804e68abfc5698fa \n",
+ " norcal \n",
+ " Trinity Schedule \n",
+ " aHR0cHM6Ly9kYXRhLnRyaWxsaXVtdHJhbnNpdC5jb20vZ3... \n",
+ " 2023-10-18 \n",
+ " 2022-01-01_2023-12-31 \n",
+ " \n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " feed_key region gtfs_dataset_name \\\n",
+ "0 f12e4782e7a1751f1c1e8dfb2a24861d norcal Siskiyou Schedule \n",
+ "1 598ff5ab409c5158804e68abfc5698fa norcal Trinity Schedule \n",
+ "\n",
+ " base64_url date \\\n",
+ "0 aHR0cHM6Ly9kYXRhLnRyaWxsaXVtdHJhbnNpdC5jb20vZ3... 2023-10-18 \n",
+ "1 aHR0cHM6Ly9kYXRhLnRyaWxsaXVtdHJhbnNpdC5jb20vZ3... 2023-10-18 \n",
+ "\n",
+ " span \n",
+ "0 2023-02-13_2029-12-31 \n",
+ "1 2022-01-01_2023-12-31 "
+ ]
+ },
+ "execution_count": 193,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "feed_spans_norcal = get_region_feed_spans(regions_and_feeds, 'norcal')\n",
+ "feed_spans_norcal >> head(2)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 194,
+ "id": "120f309d-ec06-4018-833b-e9bc2d8f33e1",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def join_conveyal_by_span(conveyal_df: pd.DataFrame, feed_span_df: pd.DataFrame, exclude_feeds: list):\n",
+ " '''\n",
+ " exclude_feeds: list of feed_keys not used in conveyal upload\n",
+ " i.e. Lassen Flex, must remove to avoid duplicates\n",
+ " \n",
+ " it's possible to have a collision between two feeds that legitimately share\n",
+ " the same span, in that case implement a manual fix...\n",
+ " '''\n",
+ " conveyal_df['span'] = conveyal_df['serviceStart'] + '_' + conveyal_df['serviceEnd']\n",
+ " conveyal_joined = (conveyal_df\n",
+ " >> inner_join(_, feed_span_df, on = 'span')\n",
+ " >> filter(-_.feed_key.isin(exclude_feeds))\n",
+ " )\n",
+ " assert conveyal_joined.span.is_unique, 'more than one feed shares the same span!'\n",
+ " assert len(conveyal_joined) == len(conveyal_df), 'at least one feed failed to join!'\n",
+ " \n",
+ " return conveyal_joined"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 195,
+ "id": "e6c1a328-bef7-4486-a900-8555c793e883",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "exclude_feeds = ['c7cea554a5e958c1a6dae5d4f6ccdd6a' # lassen flex\n",
+ " ]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 196,
+ "id": "a18466b2-0216-4985-9d18-ffce32019d17",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "conveyal_df = pd.DataFrame(conveyal_norcal)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 197,
+ "id": "0fb5f1ec-0254-4fce-9563-439e6b6d2380",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "conveyal_joined = join_conveyal_by_span(conveyal_df, feed_spans_norcal, exclude_feeds)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 198,
+ "id": "6f15716b-459e-45e4-8a75-2880e0257f07",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " feedId \n",
+ " name \n",
+ " bundleScopedFeedId \n",
+ " serviceStart \n",
+ " serviceEnd \n",
+ " checksum \n",
+ " span \n",
+ " feed_key \n",
+ " region \n",
+ " gtfs_dataset_name \n",
+ " base64_url \n",
+ " date \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 \n",
+ " 6541351adad1a760f30e32c2 \n",
+ " Martz Trailways, Executive Transportation, Rou... \n",
+ " 6541351adad1a760f30e32c2_6541351adad1a760f30e32c1 \n",
+ " 2023-10-15 \n",
+ " 2024-10-14 \n",
+ " 3610834750 \n",
+ " 2023-10-15_2024-10-14 \n",
+ " b4970d6cc7e206d9e667796130394790 \n",
+ " norcal \n",
+ " Amtrak Schedule \n",
+ " aHR0cHM6Ly9jb250ZW50LmFtdHJhay5jb20vY29udGVudC... \n",
+ " 2023-10-18 \n",
+ " \n",
+ " \n",
+ " 1 \n",
+ " 65413534dad1a760f30e32c3 \n",
+ " B-Line: 2023-08-20 to 2024-01-20 \n",
+ " 65413534dad1a760f30e32c3_6541351adad1a760f30e32c1 \n",
+ " 2023-08-20 \n",
+ " 2024-01-20 \n",
+ " 1559914972 \n",
+ " 2023-08-20_2024-01-20 \n",
+ " 13bfca2933608e72d6dc9bce01ccb536 \n",
+ " norcal \n",
+ " B-Line Schedule \n",
+ " aHR0cDovL3d3dy5ibGluZXRyYW5zaXQuY29tL2RvY3VtZW... \n",
+ " 2023-10-18 \n",
+ " \n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " feedId \\\n",
+ "0 6541351adad1a760f30e32c2 \n",
+ "1 65413534dad1a760f30e32c3 \n",
+ "\n",
+ " name \\\n",
+ "0 Martz Trailways, Executive Transportation, Rou... \n",
+ "1 B-Line: 2023-08-20 to 2024-01-20 \n",
+ "\n",
+ " bundleScopedFeedId serviceStart serviceEnd \\\n",
+ "0 6541351adad1a760f30e32c2_6541351adad1a760f30e32c1 2023-10-15 2024-10-14 \n",
+ "1 65413534dad1a760f30e32c3_6541351adad1a760f30e32c1 2023-08-20 2024-01-20 \n",
+ "\n",
+ " checksum span feed_key \\\n",
+ "0 3610834750 2023-10-15_2024-10-14 b4970d6cc7e206d9e667796130394790 \n",
+ "1 1559914972 2023-08-20_2024-01-20 13bfca2933608e72d6dc9bce01ccb536 \n",
+ "\n",
+ " region gtfs_dataset_name \\\n",
+ "0 norcal Amtrak Schedule \n",
+ "1 norcal B-Line Schedule \n",
+ "\n",
+ " base64_url date \n",
+ "0 aHR0cHM6Ly9jb250ZW50LmFtdHJhay5jb20vY29udGVudC... 2023-10-18 \n",
+ "1 aHR0cDovL3d3dy5ibGluZXRyYW5zaXQuY29tL2RvY3VtZW... 2023-10-18 "
+ ]
+ },
+ "execution_count": 198,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "conveyal_joined >> head(2)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 199,
+ "id": "637c5bbc-b209-4559-af8f-19be04e60142",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "central_feed_spans = get_region_feed_spans(df, 'central')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 201,
+ "id": "2e7b878b-7b14-41e2-a83c-c73129d26b52",
+ "metadata": {},
+ "outputs": [
+ {
+ "ename": "AssertionError",
+ "evalue": "more than one feed shares the same span!",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[0;31mAssertionError\u001b[0m Traceback (most recent call last)",
+ "Cell \u001b[0;32mIn[201], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m central_conveyal_joined \u001b[38;5;241m=\u001b[39m \u001b[43mjoin_conveyal_by_span\u001b[49m\u001b[43m(\u001b[49m\u001b[43mpd\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mDataFrame\u001b[49m\u001b[43m(\u001b[49m\u001b[43mconveyal_central\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcentral_feed_spans\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mexclude_feeds\u001b[49m\u001b[43m)\u001b[49m\n",
+ "Cell \u001b[0;32mIn[194], line 14\u001b[0m, in \u001b[0;36mjoin_conveyal_by_span\u001b[0;34m(conveyal_df, feed_span_df, exclude_feeds)\u001b[0m\n\u001b[1;32m 9\u001b[0m conveyal_df[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mspan\u001b[39m\u001b[38;5;124m'\u001b[39m] \u001b[38;5;241m=\u001b[39m conveyal_df[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mserviceStart\u001b[39m\u001b[38;5;124m'\u001b[39m] \u001b[38;5;241m+\u001b[39m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124m_\u001b[39m\u001b[38;5;124m'\u001b[39m \u001b[38;5;241m+\u001b[39m conveyal_df[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mserviceEnd\u001b[39m\u001b[38;5;124m'\u001b[39m]\n\u001b[1;32m 10\u001b[0m conveyal_joined \u001b[38;5;241m=\u001b[39m (conveyal_df\n\u001b[1;32m 11\u001b[0m \u001b[38;5;241m>>\u001b[39m inner_join(_, feed_span_df, on \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mspan\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[1;32m 12\u001b[0m \u001b[38;5;241m>>\u001b[39m \u001b[38;5;28mfilter\u001b[39m(\u001b[38;5;241m-\u001b[39m_\u001b[38;5;241m.\u001b[39mfeed_key\u001b[38;5;241m.\u001b[39misin(exclude_feeds))\n\u001b[1;32m 13\u001b[0m )\n\u001b[0;32m---> 14\u001b[0m \u001b[38;5;28;01massert\u001b[39;00m conveyal_joined\u001b[38;5;241m.\u001b[39mspan\u001b[38;5;241m.\u001b[39mis_unique, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mmore than one feed shares the same span!\u001b[39m\u001b[38;5;124m'\u001b[39m\n\u001b[1;32m 15\u001b[0m \u001b[38;5;28;01massert\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(conveyal_joined) \u001b[38;5;241m==\u001b[39m \u001b[38;5;28mlen\u001b[39m(conveyal_df), \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mat least one feed failed to join!\u001b[39m\u001b[38;5;124m'\u001b[39m\n\u001b[1;32m 17\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m conveyal_joined\n",
+ "\u001b[0;31mAssertionError\u001b[0m: more than one feed shares the same span!"
+ ]
+ }
+ ],
+ "source": [
+ "central_conveyal_joined = join_conveyal_by_span(pd.DataFrame(conveyal_central), central_feed_spans, exclude_feeds)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 202,
+ "id": "c7e96d03-8665-4f8c-8d3d-321a114258d5",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "2020-06-17_2023-12-01 2\n",
+ "2023-09-30_2099-12-31 2\n",
+ "2023-09-10_2024-12-31 1\n",
+ "2023-01-27_2023-12-31 1\n",
+ "2020-05-26_2023-12-31 1\n",
+ " ..\n",
+ "2022-01-01_2024-01-01 1\n",
+ "2021-10-18_2023-12-31 1\n",
+ "2023-09-10_2024-01-13 1\n",
+ "2021-09-01_2024-09-01 1\n",
+ "2019-12-02_2024-02-01 1\n",
+ "Name: span, Length: 80, dtype: int64"
+ ]
+ },
+ "execution_count": 202,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "central_feed_spans.span.value_counts()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 203,
+ "id": "137cf8b1-ad35-48cc-b303-7726a9aaa3a7",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " feed_key \n",
+ " region \n",
+ " gtfs_dataset_name \n",
+ " base64_url \n",
+ " date \n",
+ " span \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " 21 \n",
+ " 78a93342ee0ba8aacd951e5a5637fe06 \n",
+ " central \n",
+ " Mission Bay Schedule \n",
+ " aHR0cHM6Ly9kYXRhLnRyaWxsaXVtdHJhbnNpdC5jb20vZ3... \n",
+ " 2023-10-18 \n",
+ " 2020-06-17_2023-12-01 \n",
+ " \n",
+ " \n",
+ " 46 \n",
+ " b2393e62001a4ceda7cc36d666c40bca \n",
+ " central \n",
+ " Bay Area 511 Mission Bay Schedule \n",
+ " aHR0cHM6Ly9hcGkuNTExLm9yZy90cmFuc2l0L2RhdGFmZW... \n",
+ " 2023-10-18 \n",
+ " 2020-06-17_2023-12-01 \n",
+ " \n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " feed_key region \\\n",
+ "21 78a93342ee0ba8aacd951e5a5637fe06 central \n",
+ "46 b2393e62001a4ceda7cc36d666c40bca central \n",
+ "\n",
+ " gtfs_dataset_name \\\n",
+ "21 Mission Bay Schedule \n",
+ "46 Bay Area 511 Mission Bay Schedule \n",
+ "\n",
+ " base64_url date \\\n",
+ "21 aHR0cHM6Ly9kYXRhLnRyaWxsaXVtdHJhbnNpdC5jb20vZ3... 2023-10-18 \n",
+ "46 aHR0cHM6Ly9hcGkuNTExLm9yZy90cmFuc2l0L2RhdGFmZW... 2023-10-18 \n",
+ "\n",
+ " span \n",
+ "21 2020-06-17_2023-12-01 \n",
+ "46 2020-06-17_2023-12-01 "
+ ]
+ },
+ "execution_count": 203,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# can drop one\n",
+ "central_feed_spans >> filter(_.span == '2020-06-17_2023-12-01')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 204,
+ "id": "770568fa-8044-4786-8a2b-4224e781256e",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " feed_key \n",
+ " region \n",
+ " gtfs_dataset_name \n",
+ " base64_url \n",
+ " date \n",
+ " span \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " 70 \n",
+ " ed7a212f2a38fd8734244030b40e4d07 \n",
+ " central \n",
+ " Bay Area 511 Union City Transit Schedule \n",
+ " aHR0cHM6Ly9hcGkuNTExLm9yZy90cmFuc2l0L2RhdGFmZW... \n",
+ " 2023-10-18 \n",
+ " 2023-09-30_2099-12-31 \n",
+ " \n",
+ " \n",
+ " 78 \n",
+ " 27b8abfcbdafb64f1bd516c4d065ab76 \n",
+ " central \n",
+ " Bay Area 511 Santa Rosa CityBus Schedule \n",
+ " aHR0cHM6Ly9hcGkuNTExLm9yZy90cmFuc2l0L2RhdGFmZW... \n",
+ " 2023-10-18 \n",
+ " 2023-09-30_2099-12-31 \n",
+ " \n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " feed_key region \\\n",
+ "70 ed7a212f2a38fd8734244030b40e4d07 central \n",
+ "78 27b8abfcbdafb64f1bd516c4d065ab76 central \n",
+ "\n",
+ " gtfs_dataset_name \\\n",
+ "70 Bay Area 511 Union City Transit Schedule \n",
+ "78 Bay Area 511 Santa Rosa CityBus Schedule \n",
+ "\n",
+ " base64_url date \\\n",
+ "70 aHR0cHM6Ly9hcGkuNTExLm9yZy90cmFuc2l0L2RhdGFmZW... 2023-10-18 \n",
+ "78 aHR0cHM6Ly9hcGkuNTExLm9yZy90cmFuc2l0L2RhdGFmZW... 2023-10-18 \n",
+ "\n",
+ " span \n",
+ "70 2023-09-30_2099-12-31 \n",
+ "78 2023-09-30_2099-12-31 "
+ ]
+ },
+ "execution_count": 204,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# uh-oh, need manual override\n",
+ "central_feed_spans >> filter(_.span == '2023-09-30_2099-12-31')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "e389be76-eb4d-44bf-9040-cc410d0af900",
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.9.13"
+ },
+ "widgets": {
+ "application/vnd.jupyter.widget-state+json": {
+ "state": {},
+ "version_major": 2,
+ "version_minor": 0
+ }
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/finding_transfers/Conveyal_Paths_Test.csv b/finding_transfers/Conveyal_Paths_Test.csv
deleted file mode 100644
index 0f6882307..000000000
--- a/finding_transfers/Conveyal_Paths_Test.csv
+++ /dev/null
@@ -1,221 +0,0 @@
-origin,destination,routes,boardStops,alightStops,rideTimes,accessTime,egressTime,transferTime,waitTimes,totalTime,nIterations
-Archives,Archives,,,,,,,0.0,,0.1,1200
-Archives,Curtis Park,533,7015,7019,9.0,1.1,17.6,0.0,1.9,29.6,1200
-Archives,Winco,533|013,7034|1096,7043|3089,20.0|21.0,0.3,1.4,2.5,1.7|4.5,51.4,410
-Archives,Winco,533|023,7034|1096,7043|1464,20.0|22.0,0.3,6.2,2.5,1.7|4.5,57.2,20
-Archives,Winco,507|026|082,7015|316|1666,7055|1551|3089,16.0|12.0|15.0,1.1,1.4,4.7,1.9|2.7|1.5,56.4,390
-Archives,Winco,533|023,7034|1096,7043|1464,20.0|21.0,0.3,6.2,2.5,1.7|4.5,56.2,40
-Archives,Winco,533|084,7034|9801,7049|1074,32.0|10.0,0.3,3.4,1.0,1.7|12.0,60.4,340
-Archives,Middle School,533|067,7015|2592,7022|2594,16.0|1.0,1.1,8.5,15.9,1.9|4.1,48.5,150
-Archives,Middle School,533|067,7015|2592,7022|2594,16.0|2.0,1.1,8.5,15.9,1.9|5.1,50.5,450
-Archives,Middle School,533,7015,7022,16.0,1.1,32.1,0.0,1.9,51.1,600
-Archives,High School,507|072,7015|377,7058|3794,23.0|19.0,1.1,3.5,1.1,1.9|6.9,56.5,600
-Archives,High School,507|072,7015|323,7062|2816,32.0|9.0,1.1,2.8,5.4,1.9|14.6,66.8,600
-Archives,Folsom,507,7015,7085,52.0,1.1,3.2,0.0,1.9,58.2,1200
-Archives,Sunrise Mall,533|001,7034|9801,7049|2807,32.0|30.0,0.3,7.8,1.0,1.7|4.0,76.8,20
-Archives,Sunrise Mall,507|021,7015|319,7062|2805,32.0|27.0,1.1,0.8,5.3,10.9|3.8,80.8,40
-Archives,Sunrise Mall,533|001,7034|9801,7049|2807,32.0|33.0,0.3,7.8,1.0,1.7|4.0,79.8,580
-Archives,Sunrise Mall,9_AM|B|021,53213|53043|1070,53043|53000|1200,36.0|10.0|15.0,4.5,3.7,0.8,1.5|10.0|3.2,84.7,80
-Archives,Sunrise Mall,507|021,7015|319,7062|2805,32.0|30.0,1.1,0.8,5.3,1.9|3.8,74.8,480
-Archives,Airport,507|04818ef1-576a-492b-9a18-e9fa6577ba3e,7034|80337645-0a8d-44f2-b37f-5ecf8209b17f,7036|641945e4-f72f-4a09-9110-35d862f24266,3.0|19.0,0.3,0.4,7.9,1.7|2.0,34.4,40
-Archives,Airport,142,526,1567,18.0,9.6,16.4,0.0,1.4,45.4,290
-Archives,Airport,04818ef1-576a-492b-9a18-e9fa6577ba3e,9f772657-d3b2-4fc6-8080-e9e986a01eb9,641945e4-f72f-4a09-9110-35d862f24266,20.1,12.2,0.4,0.0,1.6,34.4,210
-Archives,Airport,04818ef1-576a-492b-9a18-e9fa6577ba3e,9f772657-d3b2-4fc6-8080-e9e986a01eb9,641945e4-f72f-4a09-9110-35d862f24266,20.5,12.2,0.4,0.0,1.3,34.4,340
-Archives,Airport,04818ef1-576a-492b-9a18-e9fa6577ba3e,9f772657-d3b2-4fc6-8080-e9e986a01eb9,641945e4-f72f-4a09-9110-35d862f24266,22.1,12.2,0.4,0.0,1.6,36.4,300
-Archives,Airport,533|04818ef1-576a-492b-9a18-e9fa6577ba3e,7034|9f772657-d3b2-4fc6-8080-e9e986a01eb9,7037|641945e4-f72f-4a09-9110-35d862f24266,5.0|20.5,0.3,0.4,1.0,1.7|4.5,33.4,10
-Archives,Airport,533|04818ef1-576a-492b-9a18-e9fa6577ba3e,7034|9f772657-d3b2-4fc6-8080-e9e986a01eb9,7037|641945e4-f72f-4a09-9110-35d862f24266,5.0|20.1,0.3,0.4,1.0,1.7|4.8,33.4,10
-Curtis Park,Archives,051|507,1918|7014,326|7015,10.0|1.0,24.9,1.1,0.8,1.1|1.2,40.1,80
-Curtis Park,Archives,533,7030,7034,9.0,16.0,0.3,0.0,2.0,27.3,1120
-Curtis Park,Curtis Park,,,,,,,0.0,,0.0,1200
-Curtis Park,Winco,533|013,7030|1096,7043|3089,29.0|21.0,16.0,1.4,2.5,2.0|4.5,76.4,150
-Curtis Park,Winco,068|013,1818|1099,1099|3089,21.0|16.0,27.8,1.4,0.0,1.2|10.0,77.4,10
-Curtis Park,Winco,067|030|082,2623|1725|275,2638|275|3089,12.0|12.0|24.0,10.4,1.4,2.7,1.6|1.3|16.0,81.4,130
-Curtis Park,Winco,067|013,2623|1099,1099|3089,25.0|16.0,10.4,1.4,0.0,1.6|9.0,63.4,410
-Curtis Park,Winco,533|507|026|082,7030|7017|316|1666,7032|7055|1551|3089,6.0|11.0|12.0|15.0,16.0,1.4,6.5,2.0|5.3|2.7|1.5,79.4,50
-Curtis Park,Winco,533|084,7030|9801,7049|1074,41.0|10.0,16.0,3.4,1.0,2.0|12.0,85.4,450
-Curtis Park,Middle School,067,2573,2594,16.0,10.7,8.5,0.0,1.3,36.5,300
-Curtis Park,Middle School,067,2573,2594,17.0,10.7,8.5,0.0,1.3,37.5,900
-Curtis Park,High School,507|072,7050|377,7058|3794,16.0|19.0,39.2,3.5,1.1,1.8|6.9,87.5,280
-Curtis Park,High School,067|507|072,2623|7051|377,9812|7058|3794,8.0|14.0|19.0,10.4,3.5,1.8,1.6|1.3|6.9,66.5,840
-Curtis Park,High School,068|507|072,1818|7051|323,9812|7062|2816,5.0|23.0|9.0,27.8,2.8,6.2,1.2|1.3|14.6,90.8,10
-Curtis Park,High School,533|507|072,7030|7017|323,7032|7062|2816,6.0|27.0|9.0,16.0,2.8,7.2,2.0|5.3|14.6,89.8,70
-Curtis Park,Folsom,507,7050,7085,45.0,39.2,3.2,0.0,1.8,89.2,880
-Curtis Park,Folsom,067|507,2623|7051,9812|7085,8.0|43.0,10.4,3.2,15.7,1.6|1.3,83.2,60
-Curtis Park,Folsom,068|507,1818|7051,9812|7085,5.0|43.0,27.8,3.2,0.7,1.2|1.3,82.2,10
-Curtis Park,Folsom,533|507,7030|7017,7032|7085,6.0|47.0,16.0,3.2,1.8,2.0|5.3,81.2,250
-Curtis Park,Sunrise Mall,533|001,7030|9801,7049|2807,41.0|33.0,16.0,7.8,1.0,2.0|4.0,104.8,80
-Curtis Park,Sunrise Mall,067|507|021,2623|7051|319,9812|7062|2805,8.0|23.0|30.0,10.4,0.8,6.0,1.6|1.3|3.8,84.8,630
-Curtis Park,Sunrise Mall,507|021,7050|319,7062|2805,25.0|27.0,39.2,0.8,5.3,1.8|3.8,102.8,70
-Curtis Park,Sunrise Mall,067|507|021,2623|7051|319,9812|7062|2805,8.0|23.0|27.0,10.4,0.8,6.0,1.6|1.3|3.8,81.8,210
-Curtis Park,Sunrise Mall,507|021,7050|319,7062|2805,25.0|30.0,39.2,0.8,5.3,1.8|3.8,105.8,210
-Curtis Park,Airport,062|04818ef1-576a-492b-9a18-e9fa6577ba3e,2241|9f772657-d3b2-4fc6-8080-e9e986a01eb9,528|641945e4-f72f-4a09-9110-35d862f24266,15.0|20.5,16.8,0.4,6.0,1.2|4.5,64.4,150
-Curtis Park,Airport,533|04818ef1-576a-492b-9a18-e9fa6577ba3e,7030|9f772657-d3b2-4fc6-8080-e9e986a01eb9,7037|641945e4-f72f-4a09-9110-35d862f24266,14.0|20.1,16.0,0.4,16.0,2.0|4.8,73.4,210
-Curtis Park,Airport,533|142,7030|525,7032|1567,6.0|18.0,16.0,16.4,16.0,2.0|10.0,84.4,150
-Curtis Park,Airport,051|04818ef1-576a-492b-9a18-e9fa6577ba3e,1918|9f772657-d3b2-4fc6-8080-e9e986a01eb9,328|641945e4-f72f-4a09-9110-35d862f24266,11.0|20.5,24.9,0.4,10.0,1.1|4.5,72.4,60
-Curtis Park,Airport,533|04818ef1-576a-492b-9a18-e9fa6577ba3e,7030|9f772657-d3b2-4fc6-8080-e9e986a01eb9,7037|641945e4-f72f-4a09-9110-35d862f24266,14.0|20.5,16.0,0.4,1.0,2.0|4.5,58.4,400
-Curtis Park,Airport,533|04818ef1-576a-492b-9a18-e9fa6577ba3e,7030|9f772657-d3b2-4fc6-8080-e9e986a01eb9,7037|641945e4-f72f-4a09-9110-35d862f24266,14.0|22.1,16.0,0.4,1.0,2.0|11.9,67.4,10
-Curtis Park,Airport,062|142,2241|525,525|1567,13.0|18.0,16.8,16.4,0.0,1.2|10.0,75.4,90
-Curtis Park,Airport,067|038|142,2623|2633|525,2633|525|1567,7.0|11.0|18.0,10.4,16.4,0.0,1.6|2.0|5.0,71.4,40
-Curtis Park,Airport,062|04818ef1-576a-492b-9a18-e9fa6577ba3e,2241|9f772657-d3b2-4fc6-8080-e9e986a01eb9,528|641945e4-f72f-4a09-9110-35d862f24266,16.0|20.1,16.8,0.4,5.0,1.2|4.8,64.4,90
-Winco,Archives,082|507,1074|7076,288|7034,32.0|14.0,3.5,0.3,0.5,1.5|5.5,57.3,70
-Winco,Archives,013|533,1073|7007,9807|7015,23.0|18.0,3.0,1.1,1.2,2.0|8.8,57.1,510
-Winco,Archives,023|533,1380|7007,9807|7015,24.0|18.0,7.2,1.1,1.2,1.9|6.8,60.1,360
-Winco,Archives,084|533,3089|7000,9800|7015,15.0|31.0,1.4,1.1,3.8,1.6|6.2,60.1,260
-Winco,Curtis Park,023|067,1380|1099,1164|2573,15.0|24.0,7.2,10.6,14.0,1.9|3.0,75.6,180
-Winco,Curtis Park,023|067,1380|1099,1164|2573,15.0|26.0,7.2,10.6,14.0,1.9|2.0,76.6,180
-Winco,Curtis Park,013|067,1073|1099,1164|2573,13.0|26.0,3.0,10.6,2.0,2.0|2.0,58.6,180
-Winco,Curtis Park,082|507|533,1074|7076|7017,288|7032|7019,32.0|11.0|5.0,3.5,17.6,2.3,1.5|5.5|4.3,82.7,70
-Winco,Curtis Park,013|067,1073|1099,1164|2573,13.0|24.0,3.0,10.6,2.0,2.0|3.0,57.6,330
-Winco,Curtis Park,084|533,3089|7000,9800|7019,15.0|40.0,1.4,17.6,3.8,1.6|6.2,85.7,260
-Winco,Winco,,,,,,,0.0,,0.0,1200
-Winco,Middle School,013|067,1073|1099,1164|2594,13.0|40.0,3.0,8.5,2.0,2.0|3.0,71.5,330
-Winco,Middle School,013|067,1073|1099,1164|2594,13.0|43.0,3.0,8.5,2.0,2.0|2.0,73.5,180
-Winco,Middle School,023|067,1380|1099,1164|2594,15.0|43.0,7.2,8.5,14.0,1.9|2.0,91.5,180
-Winco,Middle School,023|067,1380|1099,1164|2594,15.0|40.0,7.2,8.5,14.0,1.9|3.0,89.5,180
-Winco,Middle School,082|081,1074|290,288|2313,32.0|26.0,3.5,21.3,1.4,1.5|10.6,96.3,330
-Winco,High School,084|072,1074|377,9817|3794,30.0|19.0,3.5,3.5,0.7,1.5|5.3,63.5,320
-Winco,High School,084|072,1074|377,9817|3794,29.0|19.0,3.5,3.5,0.7,1.5|5.3,62.5,880
-Winco,Folsom,084|507,1074|7058,9817|7085,30.0|29.0,3.5,3.2,1.6,1.5|11.4,80.2,320
-Winco,Folsom,084|507,1074|7058,9817|7085,29.0|29.0,3.5,3.2,1.6,1.5|11.4,79.2,880
-Winco,Sunrise Mall,023,1464,2807,34.0,6.3,7.8,0.0,1.8,49.8,870
-Winco,Sunrise Mall,082|001,3089|639,563|2807,21.0|20.0,1.4,7.8,2.1,1.6|1.9,55.8,90
-Winco,Sunrise Mall,082|001,3089|637,565|2807,21.0|24.0,1.4,7.8,1.4,1.6|2.7,59.8,240
-Winco,Airport,013|533|04818ef1-576a-492b-9a18-e9fa6577ba3e,1073|7007|80337645-0a8d-44f2-b37f-5ecf8209b17f,9807|7013|641945e4-f72f-4a09-9110-35d862f24266,23.0|15.0|18.0,3.0,0.4,36.2,2.0|8.8|4.0,110.4,100
-Winco,Airport,082|030|04818ef1-576a-492b-9a18-e9fa6577ba3e,1074|275|41b6f57e-6259-4313-91b2-1b79edd06eb3,275|281|641945e4-f72f-4a09-9110-35d862f24266,24.0|24.0|22.8,3.5,0.4,17.4,1.5|4.0|12.8,110.4,100
-Winco,Airport,082|030|142,1074|275|526,275|526|1567,24.0|20.0|18.0,3.5,16.4,16.6,1.5|4.0|2.4,106.4,140
-Winco,Airport,082|030|04818ef1-576a-492b-9a18-e9fa6577ba3e,1074|275|80337645-0a8d-44f2-b37f-5ecf8209b17f,275|5252|641945e4-f72f-4a09-9110-35d862f24266,24.0|22.0|18.0,3.5,0.4,18.0,1.5|4.0|4.0,95.4,330
-Winco,Airport,023|088|04818ef1-576a-492b-9a18-e9fa6577ba3e,1380|9807|41b6f57e-6259-4313-91b2-1b79edd06eb3,9807|414|641945e4-f72f-4a09-9110-35d862f24266,24.0|26.0|22.8,7.2,0.4,0.4,7.8|3.0|12.8,104.4,60
-Winco,Airport,023|533|142,1380|7007|526,9807|7011|1567,24.0|12.0|18.0,7.2,16.4,5.8,1.9|6.8|2.4,94.4,120
-Winco,Airport,023|533|04818ef1-576a-492b-9a18-e9fa6577ba3e,1380|7007|80337645-0a8d-44f2-b37f-5ecf8209b17f,9807|7013|641945e4-f72f-4a09-9110-35d862f24266,24.0|15.0|18.0,7.2,0.4,6.2,1.9|6.8|4.0,83.4,120
-Winco,Airport,023|533|04818ef1-576a-492b-9a18-e9fa6577ba3e,1380|7007|80337645-0a8d-44f2-b37f-5ecf8209b17f,9807|7013|641945e4-f72f-4a09-9110-35d862f24266,24.0|15.0|17.0,7.2,0.4,6.2,1.9|6.8|5.0,83.4,60
-Middle School,Archives,067|507,2600|7080,9812|7034,24.0|6.0,7.2,0.3,2.6,1.8|8.4,50.3,300
-Middle School,Archives,533,7027,7034,16.0,34.1,0.3,0.0,1.9,52.3,810
-Middle School,Archives,067|507,2600|7080,9812|7034,25.0|6.0,7.2,0.3,2.6,1.8|8.4,51.3,90
-Middle School,Curtis Park,067,2600,2623,16.0,7.2,10.4,0.0,1.8,35.4,840
-Middle School,Curtis Park,067,2600,2623,17.0,7.2,10.4,0.0,1.8,36.4,150
-Middle School,Curtis Park,533,7027,7030,7.0,34.1,15.9,0.0,1.9,58.9,210
-Middle School,Winco,533|084,7027|9801,7049|1074,48.0|10.0,34.1,3.4,1.0,1.9|12.0,110.4,40
-Middle School,Winco,533|084,7027|9801,7049|1074,48.0|11.0,34.1,3.4,1.0,1.9|10.0,109.4,20
-Middle School,Winco,067|081|026|013,2594|2372|316|1105,2031|290|1555|3089,3.0|25.0|15.0|9.0,8.6,1.4,5.2,1.4|4.3|12.9|2.5,88.4,20
-Middle School,Winco,067|081|082,2594|2372|288,2031|290|3089,3.0|25.0|35.0,8.6,1.4,4.0,1.4|4.3|8.6,91.4,40
-Middle School,Winco,081|026|013,2373|316|1105,290|1555|3089,24.0|15.0|9.0,21.8,1.4,2.5,1.2|12.9|2.5,90.4,10
-Middle School,Winco,081|082,2373|288,290|3089,24.0|35.0,21.8,1.4,1.4,1.2|8.6,93.4,360
-Middle School,Winco,067|081|026|013,2594|2372|316|1105,2031|290|1555|3089,3.0|28.0|15.0|9.0,8.6,1.4,5.2,1.4|1.4|12.9|2.5,88.4,40
-Middle School,Winco,067|013,2600|1099,1099|3089,41.0|16.0,7.2,1.4,0.0,1.8|9.0,76.4,670
-Middle School,Middle School,,,,,,,0.0,,0.0,1200
-Middle School,High School,067|081|507|072,2594|2372|7055|323,2031|290|7062|2816,3.0|25.0|16.0|9.0,8.6,2.8,11.0,1.4|4.3|6.1|14.6,101.8,60
-Middle School,High School,081|507|072,2373|7055|323,290|7062|2816,24.0|16.0|9.0,21.8,2.8,8.4,1.2|6.1|14.6,103.8,30
-Middle School,High School,067|081|507|072,2594|2372|7055|323,2031|290|7062|2816,3.0|28.0|16.0|9.0,8.6,2.8,11.0,1.4|1.4|6.1|14.6,101.8,40
-Middle School,High School,067|507|072,2600|7051|377,9812|7058|3794,24.0|14.0|19.0,7.2,3.5,1.8,1.8|1.3|6.9,79.5,920
-Middle School,High School,067|507|072,2600|7051|377,9812|7058|3794,25.0|14.0|19.0,7.2,3.5,1.8,1.8|1.3|6.9,80.5,150
-Middle School,Folsom,067|081|507,2594|2372|7055,2031|290|7085,3.0|25.0|36.0,8.6,3.2,5.6,1.4|4.3|6.1,93.2,60
-Middle School,Folsom,067|081|507,2594|2372|7055,2031|290|7085,3.0|28.0|36.0,8.6,3.2,5.6,1.4|1.4|6.1,93.2,40
-Middle School,Folsom,081|507,2373|7055,290|7085,24.0|36.0,21.8,3.2,2.9,1.2|6.1,95.2,750
-Middle School,Folsom,067|507,2600|7051,9812|7085,25.0|43.0,7.2,3.2,0.7,1.8|16.3,97.2,150
-Middle School,Folsom,067|507,2600|7051,9812|7085,24.0|43.0,7.2,3.2,0.7,17.8|16.3,112.2,80
-Middle School,Sunrise Mall,067|507|021,2600|7051|319,9812|7062|2805,24.0|23.0|30.0,7.2,0.8,6.0,1.8|1.3|3.8,97.8,460
-Middle School,Sunrise Mall,067|507|021,2600|7051|319,9812|7062|2805,25.0|23.0|30.0,7.2,0.8,6.0,1.8|1.3|3.8,98.8,150
-Middle School,Sunrise Mall,067|507|021,2600|7051|319,9812|7062|2805,24.0|23.0|27.0,7.2,0.8,6.0,1.8|1.3|3.8,94.8,360
-Middle School,Airport,067|038|04818ef1-576a-492b-9a18-e9fa6577ba3e,2600|2633|80337645-0a8d-44f2-b37f-5ecf8209b17f,2633|5252|641945e4-f72f-4a09-9110-35d862f24266,23.0|15.0|18.0,7.2,0.4,1.6,1.8|2.0|4.4,73.4,100
-Middle School,Airport,067|038|04818ef1-576a-492b-9a18-e9fa6577ba3e,2600|2633|80337645-0a8d-44f2-b37f-5ecf8209b17f,2633|5252|641945e4-f72f-4a09-9110-35d862f24266,24.0|15.0|17.0,7.2,0.4,1.6,1.8|2.0|5.4,74.4,90
-Middle School,Airport,067|038|142,2600|2633|525,2633|525|1567,23.0|11.0|18.0,7.2,16.4,0.0,1.8|2.0|5.0,84.4,250
-Middle School,Airport,533|04818ef1-576a-492b-9a18-e9fa6577ba3e,7027|9f772657-d3b2-4fc6-8080-e9e986a01eb9,7037|641945e4-f72f-4a09-9110-35d862f24266,21.0|20.5,34.1,0.4,16.0,1.9|4.5,98.4,560
-Middle School,Airport,533|142,7027|528,7036|1567,19.0|18.0,34.1,16.4,4.1,1.9|15.9,109.4,60
-Middle School,Airport,533|04818ef1-576a-492b-9a18-e9fa6577ba3e,7027|9f772657-d3b2-4fc6-8080-e9e986a01eb9,7037|641945e4-f72f-4a09-9110-35d862f24266,21.0|20.1,34.1,0.4,1.0,1.9|4.8,83.4,60
-High School,Archives,072|507,3794|7069,323|7034,10.0|30.0,3.5,0.3,0.7,1.5|8.3,54.3,1000
-High School,Archives,075|507,9928|7069,318|7034,5.0|30.0,23.9,0.3,1.3,1.1|4.8,66.3,30
-High School,Archives,072|507,2816|7073,377|7034,23.0|21.0,2.9,0.3,5.8,1.1|10.3,64.3,20
-High School,Archives,507,7069,7034,30.0,47.3,0.3,0.0,1.7,79.3,150
-High School,Curtis Park,075|507|067,9928|7069|9811,318|7080|2573,5.0|24.0|7.0,23.9,10.6,2.8,1.1|4.8|2.5,81.6,30
-High School,Curtis Park,072|507|067,2816|7073|9811,377|7080|2573,23.0|15.0|7.0,2.9,10.6,7.3,1.1|10.3|3.5,80.6,20
-High School,Curtis Park,507|533,7069|7017,7032|7019,27.0|5.0,47.3,17.6,1.8,1.7|4.3,104.7,150
-High School,Curtis Park,072|507|533,3794|7069|7017,323|7032|7019,10.0|27.0|5.0,3.5,17.6,2.5,1.5|8.3|4.3,79.7,1000
-High School,Winco,072|507|084,3794|7069|2757,323|7072|3089,10.0|7.0|23.0,3.5,1.4,1.3,1.5|8.3|1.5,57.4,120
-High School,Winco,507|084,7069|2757,7072|3089,7.0|23.0,47.3,1.4,0.5,3.7|1.5,84.4,30
-High School,Winco,072|084,2816|9817,377|3089,23.0|26.0,2.9,1.4,18.7,1.1|9.3,82.4,20
-High School,Winco,072|084,2816|9817,377|3089,19.0|26.0,2.9,1.4,0.7,1.1|9.3,60.4,1030
-High School,Middle School,507|081,7069|290,7076|2313,16.0|26.0,47.3,21.3,1.8,1.7|4.2,118.3,40
-High School,Middle School,072|507|081|067,3794|7069|290|2597,323|7076|2313|2600,10.0|16.0|26.0|2.0,3.5,7.2,8.1,1.5|8.3|5.2|6.5,94.2,250
-High School,Middle School,072|507|081,3794|7069|290,323|7076|2313,10.0|16.0|25.0,3.5,21.3,2.5,1.5|8.3|5.2,93.3,250
-High School,Middle School,072|507|081,3794|7069|290,323|7076|2313,10.0|16.0|26.0,3.5,21.3,2.5,1.5|8.3|4.2,93.3,500
-High School,Middle School,072|507|067,2816|7073|9811,377|7080|2594,23.0|15.0|24.0,2.9,8.5,7.3,1.1|10.3|3.5,95.5,20
-High School,Middle School,507|081|067,7069|290|2597,7076|2313|2600,16.0|26.0|2.0,47.3,7.2,7.3,1.7|5.2|6.5,119.2,10
-High School,Middle School,075|507|067,9928|7069|9811,318|7080|2594,5.0|24.0|23.0,23.9,8.5,2.8,1.1|4.8|2.5,95.5,30
-High School,High School,,,,,,,0.0,,0.0,1200
-High School,Folsom,507,7062,7085,20.0,49.5,3.2,0.0,1.5,74.2,440
-High School,Folsom,072|507,3794|7062,323|7085,10.0|20.0,3.5,3.2,5.4,1.5|11.6,55.2,760
-High School,Sunrise Mall,072|021,3794|319,323|2805,10.0|30.0,3.5,0.8,0.7,1.5|10.3,56.8,880
-High School,Sunrise Mall,021,319,2805,30.0,46.6,0.8,0.0,1.4,78.8,290
-High School,Sunrise Mall,021,319,2805,27.0,46.6,0.8,0.0,6.4,80.8,30
-High School,Airport,072|507|04818ef1-576a-492b-9a18-e9fa6577ba3e,3794|7069|3ae69214-3ea5-40d5-96cc-c2bc0caaf601,323|7091|641945e4-f72f-4a09-9110-35d862f24266,10.0|35.0|22.0,3.5,0.4,19.0,1.5|8.3|7.7,107.4,350
-High School,Airport,075|507|04818ef1-576a-492b-9a18-e9fa6577ba3e,9928|7069|3ae69214-3ea5-40d5-96cc-c2bc0caaf601,318|7091|641945e4-f72f-4a09-9110-35d862f24266,5.0|35.0|22.0,23.9,0.4,4.6,1.1|4.8|7.7,104.4,30
-High School,Airport,507|04818ef1-576a-492b-9a18-e9fa6577ba3e,7069|3ae69214-3ea5-40d5-96cc-c2bc0caaf601,7091|641945e4-f72f-4a09-9110-35d862f24266,35.0|22.0,47.3,0.4,3.3,1.7|7.7,117.4,60
-High School,Airport,072|507|142,3794|7069|528,323|7036|1567,10.0|33.0|18.0,3.5,16.4,4.8,1.5|8.3|7.9,103.4,170
-Folsom,Archives,507,7086,7034,50.0,0.2,0.3,0.0,1.8,52.3,1200
-Folsom,Curtis Park,507|533,7086|7017,7032|7019,47.0|5.0,0.2,17.6,1.8,1.8|4.3,77.7,1200
-Folsom,Winco,507|084,7086|2757,7072|3089,27.0|23.0,0.2,1.4,0.5,1.8|1.5,55.4,1200
-Folsom,Middle School,507|081|067,7086|290|2597,7076|2313|2600,36.0|26.0|2.0,0.2,7.2,7.3,1.8|5.2|6.5,92.2,280
-Folsom,Middle School,507|081,7086|290,7076|2313,36.0|25.0,0.2,21.3,1.8,1.8|5.2,91.3,290
-Folsom,Middle School,507|081,7086|290,7076|2313,36.0|26.0,0.2,21.3,1.8,1.8|4.2,91.3,580
-Folsom,High School,507|072,7086|323,7069|2816,20.0|9.0,0.2,2.8,0.7,1.8|27.3,61.8,590
-Folsom,High School,507|075,7086|318,7069|1432,20.0|4.0,0.2,23.2,1.3,1.8|9.8,60.2,610
-Folsom,Folsom,,,,,,,0.0,,0.0,1200
-Folsom,Sunrise Mall,507|021,7086|319,7069|2805,20.0|30.0,0.2,0.8,0.9,1.8|1.1,54.8,1190
-Folsom,Sunrise Mall,507|021,7086|319,7069|2805,20.0|27.0,0.2,0.8,0.9,30.8|1.1,80.8,10
-Folsom,Airport,507|142,7086|528,7036|1567,53.0|18.0,0.2,16.4,4.1,1.8|7.9,101.4,190
-Folsom,Airport,507|04818ef1-576a-492b-9a18-e9fa6577ba3e,7086|3ae69214-3ea5-40d5-96cc-c2bc0caaf601,7091|641945e4-f72f-4a09-9110-35d862f24266,55.0|22.0,0.2,0.4,3.3,1.8|7.7,90.4,450
-Sunrise Mall,Archives,001|533,1187|7000,9800|7015,28.0|31.0,8.6,1.1,3.8,1.5|1.2,75.1,60
-Sunrise Mall,Archives,001|533,1187|7000,9800|7015,30.0|31.0,8.6,1.1,3.8,1.5|1.2,77.1,1050
-Sunrise Mall,Archives,021|001|533,2805|1184|7000,1184|9800|7015,3.0|31.0|31.0,0.8,1.1,3.8,1.2|2.0|1.2,75.1,60
-Sunrise Mall,Archives,021|507,1200|7069,319|7034,32.0|30.0,3.8,0.3,0.9,1.3|8.1,76.3,30
-Sunrise Mall,Curtis Park,001|533,1187|7000,9800|7019,28.0|40.0,8.6,17.6,3.8,1.5|1.2,100.7,60
-Sunrise Mall,Curtis Park,001|533,1187|7000,9800|7019,30.0|40.0,8.6,17.6,3.8,1.5|1.2,102.7,1050
-Sunrise Mall,Curtis Park,021|001|533,2805|1184|7000,1184|9800|7019,3.0|31.0|40.0,0.8,17.6,3.8,1.2|2.0|1.2,100.7,60
-Sunrise Mall,Curtis Park,021|507|533,1200|7069|7017,319|7032|7019,32.0|27.0|5.0,3.8,17.6,2.6,1.3|8.1|4.3,101.7,30
-Sunrise Mall,Winco,001|082|013,1187|665|1131,563|1074|3089,21.0|20.0|0.0,8.6,1.4,1.6,1.5|2.8|1.6,58.4,40
-Sunrise Mall,Winco,001|082,1187|665,563|1074,21.0|20.0,8.6,3.4,1.2,1.5|2.8,58.4,80
-Sunrise Mall,Winco,023,1187,1380,35.0,8.6,7.0,0.0,1.5,52.0,1020
-Sunrise Mall,Winco,001|082,1187|665,563|1074,19.0|20.0,8.6,3.4,1.2,1.5|2.8,56.4,60
-Sunrise Mall,Middle School,021|507|081|067,1200|7069|290|2597,319|7076|2313|2600,32.0|16.0|26.0|2.0,3.8,7.2,8.2,1.3|8.1|5.2|6.5,116.2,40
-Sunrise Mall,Middle School,021|507|081,1200|7069|290,319|7076|2313,32.0|16.0|26.0,3.8,21.3,2.7,1.3|8.1|4.2,115.3,100
-Sunrise Mall,Middle School,021|507|081,1200|7069|290,319|7076|2313,35.0|16.0|25.0,3.8,21.3,2.7,1.3|4.2|5.2,114.3,60
-Sunrise Mall,High School,021|072,1200|323,319|2816,35.0|9.0,3.8,2.8,0.7,1.3|2.3,54.8,60
-Sunrise Mall,High School,021|072,1200|323,319|2816,32.0|9.0,3.8,2.8,0.7,1.3|6.3,55.8,1140
-Sunrise Mall,Folsom,021|507,1200|7062,319|7085,32.0|20.0,3.8,3.2,5.3,1.3|11.8,77.2,1140
-Sunrise Mall,Folsom,021|507,1200|7062,319|7085,35.0|20.0,3.8,3.2,5.3,1.3|7.8,76.2,60
-Sunrise Mall,Sunrise Mall,,,,,,,0.0,,0.0,1200
-Sunrise Mall,Airport,001|533|04818ef1-576a-492b-9a18-e9fa6577ba3e,1187|7000|80337645-0a8d-44f2-b37f-5ecf8209b17f,9800|7013|641945e4-f72f-4a09-9110-35d862f24266,30.0|28.0|18.0,8.6,0.4,23.8,1.5|1.2|4.0,115.4,500
-Sunrise Mall,Airport,001|533|142,1187|7000|526,9800|7011|1567,30.0|25.0|18.0,8.6,16.4,8.4,1.5|1.2|2.4,111.4,90
-Sunrise Mall,Airport,021|001|533|04818ef1-576a-492b-9a18-e9fa6577ba3e,2805|1184|7000|80337645-0a8d-44f2-b37f-5ecf8209b17f,1184|9800|7013|641945e4-f72f-4a09-9110-35d862f24266,3.0|31.0|28.0|18.0,0.8,0.4,8.8,1.2|2.0|1.2|4.0,98.4,20
-Sunrise Mall,Airport,021|507|04818ef1-576a-492b-9a18-e9fa6577ba3e,1200|7069|80337645-0a8d-44f2-b37f-5ecf8209b17f,319|7036|641945e4-f72f-4a09-9110-35d862f24266,32.0|33.0|18.0,3.8,0.4,13.9,1.3|8.1|4.0,114.4,10
-Airport,Archives,db09a072-c976-498b-8824-becced337484|507,641945e4-f72f-4a09-9110-35d862f24266|7090,41b6f57e-6259-4313-91b2-1b79edd06eb3|7015,15.8|5.0,0.4,1.1,4.4,1.6|1.8,30.1,280
-Airport,Archives,142,1568,417,18.0,0.2,12.7,0.0,1.8,32.7,190
-Airport,Archives,db09a072-c976-498b-8824-becced337484,641945e4-f72f-4a09-9110-35d862f24266,9f772657-d3b2-4fc6-8080-e9e986a01eb9,16.5,0.4,12.0,0.0,1.6,30.5,730
-Airport,Curtis Park,db09a072-c976-498b-8824-becced337484|533,641945e4-f72f-4a09-9110-35d862f24266|7011,9f772657-d3b2-4fc6-8080-e9e986a01eb9|7019,17.5|15.0,0.4,17.6,6.3,1.6|5.2,63.7,280
-Airport,Curtis Park,db09a072-c976-498b-8824-becced337484|533,641945e4-f72f-4a09-9110-35d862f24266|7011,9f772657-d3b2-4fc6-8080-e9e986a01eb9|7019,16.5|15.0,0.4,17.6,6.3,1.6|12.2,69.7,430
-Airport,Curtis Park,142|533,1568|7011,418|7019,19.0|15.0,0.2,17.6,4.5,1.8|9.5,67.7,170
-Airport,Curtis Park,142|030|067,1568|414|2650,414|1723|2573,16.0|12.0|12.0,0.2,10.6,2.3,1.8|2.0|1.7,58.6,20
-Airport,Curtis Park,db09a072-c976-498b-8824-becced337484|062,641945e4-f72f-4a09-9110-35d862f24266|414,41b6f57e-6259-4313-91b2-1b79edd06eb3|411,14.8|17.0,0.4,22.1,0.4,1.6|2.8,59.2,300
-Airport,Winco,db09a072-c976-498b-8824-becced337484|533|023,641945e4-f72f-4a09-9110-35d862f24266|7037|1096,9f772657-d3b2-4fc6-8080-e9e986a01eb9|7043|1464,16.5|15.0|22.0,0.4,6.2,3.5,1.6|6.5|4.5,76.2,430
-Airport,Winco,db09a072-c976-498b-8824-becced337484|088|013,641945e4-f72f-4a09-9110-35d862f24266|5252|5271,80337645-0a8d-44f2-b37f-5ecf8209b17f|5271|3089,20.0|22.0|24.0,0.4,1.4,1.6,1.6|5.4|3.0,79.4,280
-Airport,Winco,db09a072-c976-498b-8824-becced337484|533|084,641945e4-f72f-4a09-9110-35d862f24266|7037|9801,9f772657-d3b2-4fc6-8080-e9e986a01eb9|7049|1074,16.5|27.0|10.0,0.4,3.4,6.2,1.6|2.4|12.0,79.4,240
-Airport,Winco,142|533|084,1568|7037|9801,416|7049|1074,17.0|27.0|10.0,0.2,3.4,3.7,1.8|2.4|12.0,77.4,190
-Airport,Winco,db09a072-c976-498b-8824-becced337484|533|084,641945e4-f72f-4a09-9110-35d862f24266|7037|9801,9f772657-d3b2-4fc6-8080-e9e986a01eb9|7049|1074,16.5|27.0|11.0,0.4,3.4,2.0,23.6|6.5|10.0,100.4,60
-Airport,Middle School,142|030|067,1568|414|2650,414|1723|2594,16.0|12.0|29.0,0.2,8.5,2.3,1.8|2.0|1.7,73.5,20
-Airport,Middle School,db09a072-c976-498b-8824-becced337484|030|067,641945e4-f72f-4a09-9110-35d862f24266|414|2650,41b6f57e-6259-4313-91b2-1b79edd06eb3|1723|2594,14.8|12.0|29.0,0.4,8.5,5.4,1.6|2.0|1.7,75.5,240
-Airport,Middle School,142|533,1568|7011,418|7022,19.0|22.0,0.2,32.1,4.5,1.8|9.5,89.1,170
-Airport,Middle School,db09a072-c976-498b-8824-becced337484|533,641945e4-f72f-4a09-9110-35d862f24266|7011,9f772657-d3b2-4fc6-8080-e9e986a01eb9|7022,16.5|22.0,0.4,32.1,6.3,23.6|12.2,113.1,60
-Airport,Middle School,db09a072-c976-498b-8824-becced337484|038|067,641945e4-f72f-4a09-9110-35d862f24266|414|2651,41b6f57e-6259-4313-91b2-1b79edd06eb3|2651|2594,14.8|13.0|27.0,0.4,8.5,0.4,1.6|4.8|18.0,88.5,320
-Airport,Middle School,db09a072-c976-498b-8824-becced337484|533,641945e4-f72f-4a09-9110-35d862f24266|7011,9f772657-d3b2-4fc6-8080-e9e986a01eb9|7022,17.5|22.0,0.4,32.1,6.3,1.6|5.2,85.1,280
-Airport,High School,db09a072-c976-498b-8824-becced337484|507|072,641945e4-f72f-4a09-9110-35d862f24266|7090|377,41b6f57e-6259-4313-91b2-1b79edd06eb3|7058|3794,14.8|28.0|19.0,0.4,3.5,5.4,1.6|8.8|6.9,88.5,320
-Airport,High School,db09a072-c976-498b-8824-becced337484|507|072,641945e4-f72f-4a09-9110-35d862f24266|7090|323,41b6f57e-6259-4313-91b2-1b79edd06eb3|7062|2816,15.8|37.0|9.0,0.4,2.8,9.8,1.6|1.8|14.6,92.8,280
-Airport,High School,db09a072-c976-498b-8824-becced337484|507|072,641945e4-f72f-4a09-9110-35d862f24266|7090|323,41b6f57e-6259-4313-91b2-1b79edd06eb3|7062|2816,14.8|37.0|9.0,0.4,2.8,13.0,1.6|5.6|14.6,98.8,220
-Airport,High School,142|507|072,1568|7090|323,414|7062|2816,16.0|37.0|9.0,0.2,2.8,9.9,1.8|5.6|14.6,96.8,190
-Airport,Folsom,db09a072-c976-498b-8824-becced337484|507,641945e4-f72f-4a09-9110-35d862f24266|7090,41b6f57e-6259-4313-91b2-1b79edd06eb3|7085,14.8|57.0,0.4,3.2,22.6,1.6|5.6,105.2,450
-Airport,Folsom,db09a072-c976-498b-8824-becced337484|507,641945e4-f72f-4a09-9110-35d862f24266|7090,41b6f57e-6259-4313-91b2-1b79edd06eb3|7085,15.8|57.0,0.4,3.2,4.4,1.6|1.8,84.2,280
-Airport,Folsom,142|507,1568|7090,414|7085,16.0|57.0,0.2,3.2,4.4,1.8|5.6,88.2,190
-Airport,Sunrise Mall,db09a072-c976-498b-8824-becced337484|533|001,641945e4-f72f-4a09-9110-35d862f24266|7037|9801,9f772657-d3b2-4fc6-8080-e9e986a01eb9|7049|2807,17.5|27.0|33.0,0.4,7.8,2.0,1.6|14.5|4.0,107.8,130
-Airport,Sunrise Mall,db09a072-c976-498b-8824-becced337484|533|001,641945e4-f72f-4a09-9110-35d862f24266|7037|9801,9f772657-d3b2-4fc6-8080-e9e986a01eb9|7049|2807,16.5|27.0|33.0,0.4,7.8,6.2,1.6|2.4|4.0,98.8,220
-Airport,Sunrise Mall,142|533|001,1568|7037|9801,416|7049|2807,17.0|27.0|33.0,0.2,7.8,3.7,1.8|2.4|4.0,96.8,190
-Airport,Sunrise Mall,db09a072-c976-498b-8824-becced337484|Shuttle|B|021,641945e4-f72f-4a09-9110-35d862f24266|SAC|53043|1070,b3ee0b92-804a-46b7-932b-e924dcb3ca7c|RSV|53000|1200,14.6|30.0|10.0|15.0,0.4,3.7,9.1,1.6|3.7|5.4|2.2,95.7,250
-Airport,Airport,,,,,,,0.0,,0.1,1200
diff --git a/finding_transfers/test_process_conveyal.ipynb b/sb125_analyses/test_process_conveyal.ipynb
similarity index 100%
rename from finding_transfers/test_process_conveyal.ipynb
rename to sb125_analyses/test_process_conveyal.ipynb
diff --git a/sb125_analyses/test_raster.ipynb b/sb125_analyses/test_raster.ipynb
new file mode 100644
index 000000000..7dc753566
--- /dev/null
+++ b/sb125_analyses/test_raster.ipynb
@@ -0,0 +1,288 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "f5740745-9af6-40fb-8522-a9600bc2c2b4",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "os.environ[\"CALITP_BQ_MAX_BYTES\"] = str(1_000_000_000_000) ## 1TB?\n",
+ "\n",
+ "import pandas as pd\n",
+ "import geopandas as gpd\n",
+ "from siuba import *"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "44702b71-3434-4838-b74c-a3b5cb924c7e",
+ "metadata": {
+ "collapsed": true,
+ "jupyter": {
+ "outputs_hidden": true
+ },
+ "tags": []
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Collecting rasterio\n",
+ " Downloading rasterio-1.3.9-cp39-cp39-manylinux2014_x86_64.whl (20.6 MB)\n",
+ "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m20.6/20.6 MB\u001b[0m \u001b[31m39.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m00:01\u001b[0m00:01\u001b[0m\n",
+ "\u001b[?25hRequirement already satisfied: setuptools in /opt/conda/lib/python3.9/site-packages (from rasterio) (68.0.0)\n",
+ "Collecting affine\n",
+ " Downloading affine-2.4.0-py3-none-any.whl (15 kB)\n",
+ "Collecting snuggs>=1.4.1\n",
+ " Using cached snuggs-1.4.7-py3-none-any.whl (5.4 kB)\n",
+ "Requirement already satisfied: numpy in /opt/conda/lib/python3.9/site-packages (from rasterio) (1.23.5)\n",
+ "Requirement already satisfied: attrs in /opt/conda/lib/python3.9/site-packages (from rasterio) (21.4.0)\n",
+ "Requirement already satisfied: click>=4.0 in /opt/conda/lib/python3.9/site-packages (from rasterio) (8.1.6)\n",
+ "Requirement already satisfied: certifi in /opt/conda/lib/python3.9/site-packages (from rasterio) (2023.7.22)\n",
+ "Requirement already satisfied: cligj>=0.5 in /opt/conda/lib/python3.9/site-packages (from rasterio) (0.7.2)\n",
+ "Requirement already satisfied: click-plugins in /opt/conda/lib/python3.9/site-packages (from rasterio) (1.1.1)\n",
+ "Requirement already satisfied: pyparsing>=2.1.6 in /opt/conda/lib/python3.9/site-packages (from snuggs>=1.4.1->rasterio) (3.1.1)\n",
+ "Installing collected packages: snuggs, affine, rasterio\n",
+ "Successfully installed affine-2.4.0 rasterio-1.3.9 snuggs-1.4.7\n"
+ ]
+ }
+ ],
+ "source": [
+ "!pip install rasterio"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "611aecdb-7e2d-45d9-8d8c-4befc868ac2c",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import rasterio\n",
+ "import matplotlib.pyplot as plt\n",
+ "from shapely.geometry import Point"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "id": "f6a20a7a-d3e4-49f1-b493-73ea415f847f",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "pop = rasterio.open('./central_pop.tif')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "id": "4f0f034f-0d5d-455b-8375-42129df69309",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAAgkAAAG+CAYAAAAZRZeoAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8/fFQqAAAACXBIWXMAAA9hAAAPYQGoP6dpAABkTklEQVR4nO3de5QjZ3kn/q9UqiqVVLr01Iym1aPu9lw8HhN7wOBdE4P3Zx87IeCFxXvC2QWDweBsSBywk3DiQNhDTAzjXa7Jstk4xpgFnJ1dEm5LOCdmAYdDIGGOnQnGwNhz7e7p7tGMpnWpVqlu0u+PVpW7Z9TdUrfUun0/5/SxrS5JVep2v0+97/M+T6BWq9VAREREdIlgt0+AiIiIehODBCIiImqIQQIRERE1xCCBiIiIGmKQQERERA0xSCAiIqKGGCQQERFRQwwSiIiIqCEGCURERNQQgwQiIiJqqK+ChO9///t4/etfj7GxMQQCAXzta19r+TVqtRo+/vGPY//+/ZBlGbt27cJHPvKR9p8sERFRnwt1+wRasbi4iJe+9KV45zvfiX//7//9hl7jvvvuw5NPPomPf/zjuPbaa3Hx4kVcvHixzWdKRETU/wL92uApEAjgq1/9Kt74xjf6j5mmiT/6oz/C//pf/wv5fB7XXHMN/st/+S+4+eabAQA///nPcfDgQfz0pz/FVVdd1Z0TJyIi6hN9tdywnt/5nd/Bj370Ixw+fBg/+clP8KY3vQm/9mu/hhdeeAEA8H//7//Fnj178M1vfhO7d+/GFVdcgXvuuYczCURERA0MTJAwNTWFxx9/HF/+8pdx0003Ye/evXjf+96HV7/61Xj88ccBACdPnsSZM2fw5S9/GV/4whfw+c9/Hk8//TR+/dd/vctnT0RE1Hv6KidhLc8++yxc18X+/ftXPG6aJjRNAwBUq1WYpokvfOEL/nGPPfYYXvGKV+DYsWNcgiAiIlpmYIIEXdchCAKefvppCIKw4nuqqgIA0uk0QqHQikDi6quvBrA0E8EggYiI6EUDEyRcd911cF0X2WwWN910U8NjXvWqV8FxHJw4cQJ79+4FADz//PMAgMnJyS07VyIion7QV7sbdF3H8ePHASwFBZ/85Cdxyy23YNu2bZiYmMBb3/pW/MM//AM+8YlP4LrrrsP58+fxne98BwcPHsTtt9+OarWKf/Wv/hVUVcWnP/1pVKtV3HvvvYjH43jyySe7fHVERES9pa+ChKeeegq33HLLZY+//e1vx+c//3nYto2HHnoIX/jCF3D27Fls374dr3zlK/Hggw/i2muvBQDMzs7iPe95D5588klEo1G89rWvxSc+8Qls27Ztqy+HiIiop/VVkEBERERbZ2C2QBIREVF7MUggIiKihvpid0O1WsXs7CxisRgCgUC3T4eIiKhv1Wo1lEoljI2NIRhce66gL4KE2dlZjI+Pd/s0iIiIBsb09DQymcyax/RFkBCLxQAAY+D6CBER0WZUAczixbF1LX0RJHhLDEEwSCAiImqHZpbvOeYSERFRQwwSiIiIqCEGCURERNQQgwQiIiJqiEECERERNdQXuxuIWqWoKuLJJAzDQLlUgihJMHS926dFRNRXGCTQwHMsq9unQETUlxgk0EAydH3FzAEDBSKi1jEngYiIiBpikEBEREQNMUggIiKihhgkEBERUUMMEmjghSSp26dARNSXGCTQwHMsi4ECEdEGMEigocAtkERErWOQQERERA0xSCAiIqKGGCQQERFRQ5sKEh5++GEEAgHcf//9ax736U9/GldddRUURcH4+Dh+93d/F5VKZTNvTURERB224d4NR44cwSOPPIKDBw+uedxf/dVf4Q//8A/xuc99DjfeeCOef/55vOMd70AgEMAnP/nJjb49ERERddiGZhJ0Xcedd96JRx99FCMjI2se+8Mf/hCvetWr8Ja3vAVXXHEFfvVXfxVvfvOb8eMf/3hDJ0xERERbY0NBwr333ovbb78dt91227rH3njjjXj66af9oODkyZP41re+hde97nWrPsc0TRSLxRVfREREtLVaXm44fPgwnnnmGRw5cqSp49/ylrfgwoULePWrX41arQbHcfDud78bH/jAB1Z9zqFDh/Dggw+2emrURxRVXdHKudeFJKlhrQWvSBPrMBDRIGppJmF6ehr33XcfnnjiCYTD4aae89RTT+GjH/0o/vzP/xzPPPMMvvKVr+Bv//Zv8Sd/8ierPuf9738/CoWC/zU9Pd3KaVKPC0kS4skk4prW7VNZU0iSEJIkKKqKVDrt//vy6o0iKzkS0QAL1Gq1WrMHf+1rX8Mdd9wBQRD8x1zXRSAQQDAYhGmaK74HADfddBNe+cpX4mMf+5j/2Je+9CX8p//0n6DrOoLB9eOUYrGIRCKBDLhnc1DENQ3lUqmn78AVVYUoy7BNE/FkEgDguC4KuZx/3qvNMBAR9aoqgBkAhUIB8Xh8zWNbWm649dZb8eyzz6547O6778aBAwfwwAMPXBYgAEC5XL4sEPCOayE+oQFTzOW6fQpNsU0TtmWhmM8jEouhXCr5swcMFIho0LUUJMRiMVxzzTUrHotGo9A0zX/8rrvuwq5du3Do0CEAwOtf/3p88pOfxHXXXYcbbrgBx48fx3/+z/8Zr3/96xsGFUS9YnnOhBcE2Ja1YomBwQERDbIN10lYzdTU1IqZgw9+8IMIBAL44Ac/iLNnz2LHjh14/etfj4985CPtfmuijvICBNuyGBwQ0VBoKSehW5iTQERE1B6t5CT0/Zgb6kJ2eTfek7qPP3ciGjZ9HyRoqRS0dLrbp0FERDRw2p6TsNUMw+j2KRAREQ2kvg8SurHXnklrg6OVyo/8uRPRsOn75YZu/uHemclwnbrPibLc7VMgIupZfR8kdJNhGLy77HP9UtSJiKgbBiZI6MYdfblUgqKqW/6+REREW6HvcxI83bijd1hUp++xiyMR0eoGZiaBqFUhSUIqnYaWSnX7VGgNjWYJvQ6dRNRZDBJoaDmWBV3XUcznOeD0sEazPGzRTbQ1Bma5gWgjmLjYn9g/g2hrcCaBiHpao6UFBghEW4NBAhH1JC84ECUJkVis26dDNJS43EBEPcmbLXAsq+mqmETUXpxJICIiooYYJBDVsTAWEdFKDBK2ALfXNdZLn0tc07AjlWKgQES0DIOEDuulgbDX9FKGerlUgtlna99xTePvFxF1FIOEDmPp5v7gWBbOzcx09RxaHfDLpVKHzoSIaAmDBKIe4G31W4+iqlBUdUXPCc4mLH1+iqoirmndPhWigcIggaiHrDXghyQJoiwDAMYymRVbBIedt02SsytE7cUgYQvwTq89BvlzdCxrzVLDoXpBIVVVIcoyZru8NNKrGDARtReDhC0yyAPcVtFSqYGeTl5rgHMsC7ZpQq/fLXMwJKKtwIqLW0Bctn5MG2cYBmzT7PZpdI2h6321+4KI+h+DhC3AP+ztwY6NRERbi8sNHbY8E516n5clz58ZERGDhI6LxGJIpdNtf91BGsS2+lpWy2sISRK0VAq7xsb8JaKQJGFizx5oHfgZbkSjtslERJ3CIKHDyqUSQoLQ9oS7QcpvSGga4pq2ZSWRL122CEkStHQakVgMgiAgLMvYNTbmBw0AkJub25JzW49Yr6fAQIGItgJzEjrMtiwIwaD/h32QBvd26YUB2LYslEslfwdBStMgShIc18W5kycBrJzx6ObPUZRl2Pw9IqItwCChwxzLgmnb/kDYiUBBUdU199jT2px6gAAAuycnYdk2JFFEJBZDIZfzZxRikQiyuVxXC/bY69RTICJqJy43bIGF+kADdOYOlLsnNs/7ubjVKsqmCcM0/WBgLJOBIAiXHUtENOg4k7AFOjGIXzojwYGrPYRgcMU/AeB8NgtRlpGdm+uJz3mtc+CSFhG1E2cSBhC38G2MY1k4deYMsnNzKJsmRjTN7wlgm6afxNjtc1xNs02iiIiaxZmEPrXWYGHoOoOEDfI+u9kzZy77nixJiGtazxZ1YltyImo3ziT0oWYCAA4WG9fosxNlGYuGwS6DRDRUGCT0IU4pby2vfkOuR3IShhlnyIi2FoOEPuO1DKatY+h6zywxDPsgySCNaGsxSOhDLKQznLzExEaVKYc9eCCizmCQ0Gccy2rLXe1WlUAeJN0eiL276EZBIu+wiagTGCQMqX4owBSv93ToBYqqIrHGuYTqOx86HXwZus6AgIi2DLdADqhBKKrTK3kAntCyqouX8ko7b8Vn3is9JIho8HEmYUBx8GgvQ9eRy2bXPGarPvPl77PeEki3l0iIqL8xSBgQoVUS2tZ7DvWPS2cQWDyJiDqNQcIAEWW56WO9TPlQ/YvW1+0BeSPv3+1zJqL+xiBhQKy168ELBJbPNHg9CVLpNBKaxkChhymqyt0om8DfbaKNY5AwBNbaOrdQDyzWytyn7glJEuLJZEuzRPRiYLwzk+HvNtEmcHfDkFht2tm2rKUv09ziM6JmOJaFYj4PYGlL6FbtoOh3Xulyx3VR6LFdMkT9hEHCkGtXcSbqHK8zZSQWQ0LTUMjlGCiswquroSgKDMPgZ0W0SVxuINoCmy0K5dVhoObkslnOuhC1AYMEoi2gjYxAS6cBYMOVGUVZRkgQOPCtoZjLwTZN/zNi0iLR5nC5gWgL5BYWkNI0RBUFi4axoVkB2zSZO9IEb3mGwRTR5m1qJuHhhx9GIBDA/fffv+oxN998MwKBwGVft99++2bemqivlEsluNUqHNeFbVl+Yl0rRFlmB9AmMUAgao8NzyQcOXIEjzzyCA4ePLjmcV/5yldgLfsfNpfL4aUvfSne9KY3bfStifqSEAxC13XYpulvaWy20ZaiqpxFWIc3e8BZBKL22dBMgq7ruPPOO/Hoo49iZGRkzWO3bduG0dFR/+vb3/42IpEIgwQaOtlczl9mECVpKcegyRkFQ9fZAbIJzEEgaq8NBQn33nsvbr/9dtx2220tP/exxx7Df/yP/xHRaHTVY0zTRLFYXPFF1M+8raaOZSESiyGqKN0+pYHDfhZE7ddykHD48GE888wzOHToUMtv9uMf/xg//elPcc8996x53KFDh5BIJPyv8fHxlt+LqBeFJGlFgBCJxfy733i9PDbvhomoV7QUJExPT+O+++7DE088gXA43PKbPfbYY7j22mvxr//1v17zuPe///0oFAr+1/T0dMvvRRunqCoHqg4TgkFoIyN+AqP3eYtcTyeiHtJSkPD0008jm83i5S9/OUKhEEKhEP7+7/8ef/Znf4ZQKATXdVd97uLiIg4fPox3vetd676PLMuIx+MrvoZJSJL8PfXdspHse7pcXNOwM5O5rJiSJIpwq9UVOx1s07xs9wKDNSLqppZ2N9x666149tlnVzx2991348CBA3jggQcgCMKqz/3yl78M0zTx1re+dWNnOkQcy0JUUdCtYskb3aLXbxRVbXp3wUaEJAnayAiEYBCxSATlUgmiJGFEVeHWajBMcymBUZL8hMZLZxE4q0BE3dRSkBCLxXDNNdeseCwajULTNP/xu+66C7t27bosZ+Gxxx7DG9/4RmjsyNYUs4uDw/JqdYM8SHUyQNDSadiWhdzCAlRVheu6cCwLCU3D+UIBsihCCAaXKii6LiKx2GUFlgb98yei3tf2iotTU1MIBleuYhw7dgw/+MEP8OSTT7b77QZWLpvt6vtzcNocWZIwEovBchw4rgtBEKCl04gqCoRgEMXFxRUJjCFBWLHUwGUGIuoFgVqtVuv2SaynWCwikUggAzaboP4QkiRoqZS/BBcSBCiyDNd1sVAq+QGBN8twbmbmsuf3aqDW6WUaIuqsKoAZAIVCYd2cP465BIB3ru3mWBbOzczAdV3EIhFI9cReSRQRVZQVeQjA0sDr7SrZSPOnTgst24Vh16saEtHgY4MnAsDlhU4p5vPIZbNwLAs7MxnI9cFVliQkNM3fESTKsp/YKMoyRFlGMdf+1NXlg7soSWvOCDQqc8zuikTDhUECUQcoqro02NfvvIu5HM7NzPiBgiyKftKiHyjUj7UbVA0M1XdBbGaa33sNAIgnk36zKaBxkHhpYNDoe0Q02BgkELWRFxxMjI0hEYmgWq2iVKngvKLAqS89lOuNmoRgEKZlwTAMKIqy1PhplUBAlCREYrFNBQleyeKQJK1IjG11wO/lfAkiai/mJBBtkpdPsFy1WoXtuqjYNmzHAQBsTybhVqsICQKEYBBCMAjDMFAulfxBO55MNpzK9+74G+UrtDL17w3wm+lzwACBaHgwSKC+ENe0TSX0dbInQjyZxI5Uyk/qK5dKyOs6hEAA8UgEAJCMxeC6LoT69mDvn0o9iRFY6uMArKx26SUyRmIxhLydEsu+r6XTSKXTTV3b8uRD5hQQUTO43EB9oZjLbXhgC0kS9l95JdxqFflS6bLthq3wiiSJkoRCLgdRkiBLEvKFgn+MY1lwXRdurYZcqQQhGIRuGFAVBZZtQ1UUBINB2I6DSDgMpx4cAIBTz09YXlPBtG0s5HJQ6nUVvKUHL7HRXFYhc727fL8ENGcDiKgJDBKobzQzzb3aerlYvwvXEglEwmGYto3ZM2daev+QJCGzYwfE0NL/Ns/XZw1mZ2b88sqXDr6JSAQXikXEo1EIgQCCwSCEQAAV24ZhmnBcd+l7wSBK5TIMw8Do6Ojl5y/LMAwDkVgMsiTBdV3Yy2ZWRFn2tyau9zk1SowkImqEQQINlNUGv8VKBW61CkWWocjyUknkFhPwUum0/zreMoJjWUtLIYrib3UEAMMwUK1WoVsWwqLon4MkiigaBqRQyJ81cKtVCMHg0m4D04Rbrb543obh/7u4bDnD0PUXlw8EAbhkiWK1HQkMDoioFQwSaOA5loWzs7MrHmt0t76eWCSCUrkMXdchBIMol0pQVBW7d+3C+UJhRZtn2zSRKxb9AECRZVj1BEYhGITlOHBd19/ZcD6bhaHr0NJpP6nRO962LCiKAsMwYJumv8PBsSwUcrkVAz9zDYionRgk9DlFVTl93IRLtw7Oz8+3/JldyOcRj0Yhj4ysCDoqto2kqiIiyyibpr+MUa5UACwVTjLq2x7dahWmbcN1XRTzeX95wju/cqmE3Nyc/3MFloKBIl7cXrn8eHaNJKJOYpDQ57zugRwcWrORegOFXM7PH/il/ftRsW1UTBNCMAhREGDZNkKCgN379vm7F7yZBGApaHBcd6myoiz7uxnKpZK/ROCd1/Lz877nBQ2RWIyBIRFtCW6B7HMhQcCIpnGaeQs4loX5+XkAQDAYRFgUIYmi3/XUchyoioKoosByHAiCAEkUkawnGHo1ESbGx6GNjACAn1+w1oC/vPKhoeuXtZQmIuoUziT0uWI+79+RUmcpqorR0VG41SpOnD0LWZL8wkjeEkI8GkW1niBp2TYAoISlAMI2TewaG0NYFHEhn0dubm5D58EOjES0VRgk9DlD1zlobBFRlhFVFFSrVUxPTfmPe6WOI7EY7FgMMUVBXtdh1pcfSuUyFnI57EilEA2Hcb5Q2HCAQES0lRgkkE9RVcSTyRVb+ehFqqpCCARQNAwkNA07t22DW63iQj4PYGnpICyKiIbDyOs6XNeFWf8cRVmGFo8jLIqQRRE7M5lNFXUiItoKDBLIZ+h6U5X4Qk1W9+tFcU2DqqrIzs2tqFq4npAkQdd1yKKIfKEAbWQEiUgEbq3mJyZasRgWdB2LlQpK5fLS8wRhqXiTJKFsmsjrOsqVCoxl9Q+Wv0c/fqZENLgYJAwQbwA0G+yfb1Yzz+nHgUxRVexIpaDF46hWq4jUtxImEwnMzsyse01Ovd2zV1lREkUUymUEg0FYtg23WkW5UoFQr+woSxLi0SgAoLi4iFgkgrls9rKgxNvq6O1SISLqJdzdMEAURYEsioguaxpESyKxGJR6YOBVPhTqSYepdBpxTVv1uSFJQlzTMLFnD6KK4pdF9iojhuuvK0sSTMvyW0AXFxchCgKkUAgnTpzwA4T4st0oo6OjSGgabNPsy+CLiAYbZxIGSDGfh5xKQQgGEU8mmdC4TG5uDrm5OWjptN9NMRmLobi4uO6sy/jEBIRgENllswCu60KWJAjBIFRF8fsxAMD01BQcy4KWTkMKhZBd4/VzCwsrqigSEfUSBgkDxNB1zNY7AoqyPLBr3DszGQiCgIVcruXBdfmugnNNPsfrwuj1SxjLZF7MQ7Bt2KLo5ybEo1F4tRi9wORSy5ccirkctHSaQQIR9SQGCT2u1YHea+Jj6Lo/hd5scl4nzqcTivXdBFs1sHpllr06CYos+7sXIuGw3xWyGgjArdVafv1mt0P2wmdPRMOFOQk9bLUqis1WVyyXSlAUpW3VGBVVRaIHqjt2ozZESJIwOjoKIRiEYZrQdR3JehGrwuKif5zXkrrd4prGPBMi2nIMEnrUWtsMveI96w3WjmWtqHmw2cHd3sSuiX7nXbMkilBkGelUCmFRRDwSgRgKoWyasF0XQjCI8YkJTOzZA2ApsFLqZZk3w5sN6naARkTDhUFCj/KWDdb6/noUVcVYJuNn04v1wEJRVYxNTkJLp9t6ToOuWJ8xCNZbOauKArdWQyISQUxREAwG4VarkEQRUiiEsclJAEs7K5oJ6tazXo+H9TDAIKJWMSehR7WjYFEkFsOIqkIKhWAlEsgXCn6fh4gsIyLLCAnCQFdYVFS1bUsTubk5lEslv65BTlFQzOexd/duJCIRKJKE52dm/GWIiCwjMjaGs7OziMRifhGnbn3Wg/ozJqLOYZDQo9pR1CgkCKjYNnaOjGBB1yGFQiiVyxAEAZbjIF8oDPQ6tzflP9XG/AUv4CjmcijWH/vFsWPYf+WVEAUBgiBADIX8ZEZREPzATOcOBiLqMwwSBpg3YC3ouj8NHgmHl/69Poh5mfWDljkf1zR/m2I7ZxMacSwLumFgdNs27EgkEAwGUa0XWsrrOgpt3F3Siwbtd4eIXsQgoc81Wpbw/mi7rgvbcRAWRQDwywcDSwl4y2cRHMvyE+wGYc9+MZdDuVSClko11Y9iM0KSBEWWUTZNLNZ7MkiiCMu2/cJKy48dNAwQiAYXg4Q+t9ruBwBwXHcpMHBdxCKRpYQ7QcDU9DSE0dHLegUYut6WTPxe4VhWRzstLi+s5C0vKLKMcxcvQpYkyKIILZXyCz/ZQ574SUT9h0HCgPAaBS0fhLxp7pFYDGXThOu6WCiVYOg6Th0/3vB1vFkETiGvT5QkqIoCAFg0jKXZmVAI25NJWLYNqT6DE1UULAzp1lEi6m/cAjkgIrEYxjKZFdPZTr2uwdnZWVzI5xGW5abXxzcyoCmquiXT6ctrD4xNTnZtCt+2LASDQZy7eBFRRUFEllGtVmGYJkzbhmGaKFcqKC4uDsQSDhENH84kDIhCLgc7FkMkFltRhtmrbWBbFkKC0LG72ZAkbdl0ejyZhCAIMHQdC/X2zd24S3csC784dgwAMLFzJ2zXhW4YOJ/NAlgK3GzL8stI95JOJ3MS0WBgkDAgHMvycwwaLRV46/PtqL+w2vt3mlcQCli5nbDTiYlr8a47V1zaEJkvFPzBt5dzELr5mRFR/2CQMEC8cs1A40BheaLdajkJvUxLpfz2zIZhQEunIUuS34Cpm6ZOnrzssV4NEIDePjci6h3MSRgwy0snL1+r9xoESaEQTNvu1ultiuO6/vlnRkexc9s2yKI4kNsKN0pLp/3un+vxcjv4+RHRahgkDKhGd4q7xsYQi0QQkeWmBxKg9b39cU3rSEJhbm4OpXIZsihCFkWIggBFlge6amSrCvX6EM1gTgIRrYdBwgBbHiiUSyWUTRPVahWxSKSlgbXZrpMeUZIQi0T85lJA+4oI5bJZmLa9FCxIEtxqlevry7TahGuzTaOIaLAxJ2FIOJYFXdcREgQAaLlUcKreMbKZ9X/bsiAEg1BkGeroKGaAFTsuNsOxLMyeOYOdmQwEQcDcADenIiLqNgYJQ6SYy21qsI5FIusWWYprGhRFgWGaiCoKqtUqVFVFuVTadJvj5c/PZbMdraZIRERcbhharU7/m5YFwzShpVJrPrdcKqGYz6O4uAghEIBRr/S4mbwBRVWR0DR/6UJLpzE+MbHh1xsGTEYkonbgTAI1JTc3h7KqYnR0FEilkFtlmn958abMjh1+aeLI6GhL2y6X10SIJ5OQJQlSveVyuVRasyZEr/K2oC4aht99s1P65TMhot7GIGFIecmIl1ZoXIuh68gtLMA2zXUHIceyMHP+PGRJQnZubkMzCaIsQxsZQTwSAQC4tRpESUIxl0Nc02BbFhKa1vEBt12ceq6GlxdCRNTrGCQMMS2Vwo6REVxUVWTn5tYc+L0yvq3kNCwfvDdyZ6uqKtxqFWIohGg4DMu2UVQUIJ32X7tfAoSQJCGhaShXKsjVyzYTEfU65iQMqZAkoZjP42KxiFgkgv1XXgmtvoOhka3eU+9YFlzXhaooKBnGUsvrWg1SKIRovfNiPxElCdvrPSe4FEBE/YIzCUNsRyoFKRSCYZoYUVVsTyZRrreS7hW5QgEAkC+VIAgCkqqKhSaLBXXKRvIgDF3HhS1o9NTrORq9fn5EtBKDhCFmWhYUWYZjmpi/eBGGYXQtQNDSadj1JlXeIOJtcVw+sMx25exW2uggtxVLI70+APf6+RHRSgwShpRTb2HsuC6A7q7txzUN8hqtpgdtYOlUJ04ionZjkDDEDF3viaWFzRZ56jcMDoioXzBxkXrCzkxmy99zGAsONXvNrfTqIKLBtakg4eGHH0YgEMD999+/5nH5fB733nsv0uk0ZFnG/v378a1vfWszb019Jq5pUFR11e87rrvlg5IoSWvu6BhEzc5itNooiogG04aXG44cOYJHHnkEBw8eXPM4y7LwK7/yK0ilUvjrv/5r7Nq1C2fOnEEymdzoW1OfCUkSUpoGy3EwtcryRrlUwlgmg6mTJ7fsvLylFq8GxDBQVHXV3A8iokttKEjQdR133nknHn30UTz00ENrHvu5z30OFy9exA9/+EOI9RK9V1xxxUbelvqYIAgYCYdhZjIrdi2IkgRD12FbFswuDFy2ZUFLpbYkSIhrWtONrjoxmIckCaIss7U2ETVtQ8sN9957L26//Xbcdttt6x77jW98A7/8y7+Me++9Fzt37sQ111yDj370o3DrWfWNmKaJYrG44ov6V0LTEBZFuLUatETCX3ZYPgA6ltWVro7eLo+toKoqtFQKOzMZaOn0mssrnRrIN9uNk4iGS8szCYcPH8YzzzyDI0eONHX8yZMn8d3vfhd33nknvvWtb+H48eP47d/+bdi2jQ996EMNn3Po0CE8+OCDrZ4a9ajc3Bxsy0I6lUK+XgjJm+LvhWn+rTyHZL1JVbg+q7ba1tNODeRbFSCwaBLRYAjUarVaswdPT0/j+uuvx7e//W0/F+Hmm2/Gy172Mnz6059u+Jz9+/ejUqng1KlTEOqNbT75yU/iYx/7GOZW+QNpmiZM0/T/u1gsYnx8HBlwO0anLO+62O5pbkVVMaJpiNUbNQGAZduYnpoaqoFEqXfRFIJBbIvHMX/x4pblYHDQJiJPFcAMgEKhgHg8vuaxLc0kPP3008hms3j5y1/uP+a6Lr7//e/jM5/5DEzT9AMBTzqdhiiKKx6/+uqrMT8/D8uyIDWYcpVlGbIst3JqtAkhSYKWSkGu/yzM+hS8N+XdjsElqaqwbBuSKC71YahWN/2a/caud4EUBAGmZWHRMLp9SkREa2opSLj11lvx7LPPrnjs7rvvxoEDB/DAAw9cFiAAwKte9Sr81V/9FarVKoLBpXmA559/Hul0umGAQN3huC5gWdASCQjBIIpo39S0oetwq1XEIhHYrotoOIxwrQYzlepKHkK3OJYFt1qFIAio2PaWJRCy3gERbVRLQUIsFsM111yz4rFoNApN0/zH77rrLuzatQuHDh0CAPzWb/0WPvOZz+C+++7De97zHrzwwgv46Ec/ive+971tugTaLMeyUKhXPHRct+1dFkOShBMnTvitqRcrFX8mQUunX3zvIZgOP3X8OIAXdy9shWH4XImoM9q+xD81NbUi12B8fBx/93d/hyNHjuDgwYN473vfi/vuuw9/+Id/2O63pk3wiucUcjmYloXR0dG23YF6r+24LmzHgSAIKC4uwjAMyPWljkg9oW9YGLre94M3ZyiIBl9LiYvdUiwWkUgkmLi4RRRVRTyZhOO6bW/8pKXTiCoKTMtCLptFKp1GSBC2tIgStYe3lbUXdqgQUfNaSVzkmEuXMXQduWwWADA2OblmOeVWFXI55AsFnJuZgWNZ0HUdQjCIiT172vYevWBscnIpITSd9j/Ddn6OvWArtrBytoKouxgk0Jpc12372rm9fHtrLofi4mLL1RZ7ffCQRREJTcNILIZt8Th2jY2t+P7Enj2Ia1rPX0e3sJ02UW9gq2hawUuoEyUJtmUh14YWznFNgzYyglPHjzdsHNTqkoaiqti/Zw+K5TLm5+f9ICYSi0FVVcyeObPpc96sU8ePI16vDWHaNpKqCmlyEm616hdSMi0L5XpxKXqxlgNrOhD1DgYJtIJtWYjEYn5hpc02PwpJElRVhSSK0NLpNQOCtQaHS79XLJcRj0QQ37MHwWAQtutCCARguy4WeqRhU7lUghAMIhgMomya0GIxmI4DACjUEzebHQwHvTHT8hmVQb1Gon7EIGHIXDqNu3zw9b4nSpKfXBivd+tsddBVVBWiLCOlaZBEEYZprrlsoagqdo2NwXIc5AsFAEtLEY3YlgXTtlEsl+FWq0s1HgBkduxAZXERO1IpnK8fNz4xAUWWYZgm5ufn/etYazq7XXeyoiTBrVZxsViELIooCgLEUAiiICBfKsE2zabfqxeCnk7wrl/k8gJRT2KQMGTW+iPszSDYlgXUayUYhrFigGpmUBubnEQsEvGbeBmmCbdahaqqqzYYsi0LluNACoWgjYygXKmgXB84xjIZSKEQjj//vH8Ns2fOrLi7DkkSdtQLQcWjUSjj4xBDIcTCYVTqFR7jySTiySSK+Tx2jY1BEkXMzM/Drgcw3nm1c6AybRuyKCIeiaBYLkOLx1E2Tcje53yJQZxqX2uWwPtvb4lrEK+fqJ8xcXHILf+DrKoqRurr+t7dvPeHOyRJiGuaf8fXSEiS/ABBDIVQNk2U6nf7i4YBXddXrYfgWBbyhQIW6mv0sUgEY5kMREmCFApBEkXszGQwNjnpP2d5rQHHsjBz/jzOXbyI4uIiSuUyAKBQLvv/LksSHNeFKMuwHAfBYBDJRAKjo6MrzktLpzfyUTZk2TYAwK3VIIni0mdRqUAKhSA2GBAHcYAU631BIrHYmjs8Bnk5hahfcSaBACwN8Lquw3VdRMJhhOp35UK9lHa5Pj2+3rT3zpER2K6L4uIiIvXBOF8oNPXccqm0FJQIAgRBQCwSgaHrsOoFmLREAgDgZjLIZbOrJkDm8OIefm82Q0skoCoKFFlGvlTyg6BFw8DIshyM5a/TDgulEkbqAYjrujBtG6VyGclYDLvGxnD69OmBHxgNXW+4i2P5rMGgfwZE/YozCQRg6Y90MZfDuZkZFBcX/UHUchwc3LMHB/btW3eQT2gaUokEIrLsBxdSKASlvnTRTJ0Au16Z0XVdlMpl7MxkcPX4OCL1vIJgMAgtkVjKNVDVVbcQGrqO2TNn/N4QwWAQhmkuLUHUu1F653h2dtYvDd1OtmX5SwpCIOCfRyQcXnpMEDCWyWD3vn0rPptB2xbpXc+ldRVWCwwGrZ4EUT/jTAJdppDLQUullpoRBYP42ZkzfnGl1SiqiomdOxESBFSrVZi2jWz9jjyhaU1NJXu5BXJ9NkEKhRCudwMtlcsoVyqQ6tsH45EIlMlJ5AoFGIaxapIjABTzeQiCgJAgYNEwUK5UoKoq3GoVsiQhmkphtgONprzAC1hayjEtC9H67gbLtqHIMhRZRqlcbmrw7EcbCXi2qqcFEa2PQQI1ZBiGf8drNNHS2LYsRGQZwUAA0XAYOxIJ6LqOYi7X0vS9Y1lYyOWwI5Vael3HwfzCAoT6EsTU9DREWYaiKIhFIg07j152LZfcwXqtsb0ZD0WWG+YHtEsxl0Mxl0Nc02AKApKxGErlMoqLi4hHoy0XkupHrXy2gxQkEfU7LjfQZZx6kZ9yvVvjajsSPIqqIqFpkEIhlC3LT9ZT11gOWPccXBeCIGB7PI6KbeNCPg9gKRgp5nIwDAOnT5+GrutrJlM2ktA0PwDyZybqWz09cU3b0HmvJiRJ0EZGEItEEBZFRGQZ6e3bUVxcbHt/jF7SqHgWEfUPziRQQ6IkoZjPI55MIpVOQ9f1NYOFQi6HfyyVMDE+DgDYpqrYUU80zM7NNT1QhCQJoiwjJAiwbBvlegnnqKLAcV1EYjH/zhxYuktvNRCxLQvl+gyEtwxRrAchHkVRUG7z7IIkirBsGwu6jvPZLEbqgUhc09ZcLiEi6hYGCXQZRVX9Acz0Wjyb5qpT8l72uqHrmMtmUS6V4F5xBXaOjKBi25AnJjA9NXXZc70ENW8N2t8zb5rIFwrQRkZQrVZh2TYWDWMpEXBZ3wdPqwO5t1NDlOVVB2dBEJDQNJRLpbYUMhIlCTFFgS2KOHX2rL8EwroARNTLGCTQZWzLgmlZ2F6fgg/V77aN+kDdaFDzHvMG3dOnT2PnyAi2x+MolMsYn5jAqePH/eP96o71xEQAK8pBe9xaDeVKBYVcrm2D6Xqv420HbXUZYy22ZSFXLPrLN6udCxsbEVEvYZBAl/FyEqxoFACQLxT8gS0Si62bo+C9hmnbiCkKYuEwREHwp9VD9cI6Hu+OPhKLQZYkv7aBW62iUq9OmNC0tgcKa72Wd73tfL9Tx4+vu72PwQER9RImLlJDtmWhXKnAtCyo9YHNsSwoirJq1cRLTde3TaYSCajh8Ir6/MVc7rIOiOVSCQv1pETHdWFaFrK5HPKFAkKC4Fd/7KTld/KdGLCXV4kkIup1nEmghhzL8gsRaek0tFQKuWzWf6wZxXwe1q5dqNZqyGgaTMfx8wq8dX4vN0BRVURiMRRyOYiyDNuyEFKUFTkI3uOdtFUDOHMRiKgfcCaB1pWbm0Mxn0eqxZ4Ghq6jUC4jGAigaBiwHcefifAGSUPX/UDBa/Lj7V4o5vMrcha85MmQJPV9VT4GCETUDziTQE25tCBRM3ZmMoiFw3CqVViOg2q1ikg47HdqzC0sLNU8qDd+si3LDxa8AKLRe3rLHf3aEGj3vn3+tSuqOrBtoImo/3EmgdqiUfGhczMzOJPNwnFdBAMBJFUVQjAIt1qFW636PR0A+L0TbNNctZW0KMuIJ5NL7azrswpe/4Z+6nfg9YxQVBU7UimMTU721fkT0fDgTAK1RaN6A4qqIhaJICQIiMoyEgCK9dbNpm2vKPfs7ahYbduhU89lEOu9HVDfZeHlKHjtiHt5dkFLp5d6UogiyqUSEpqGeDQKsV7Yab2CVUREW41BArVs9759ODA+DkWSEAoG8ZXvfKfhwBaJxbBNVREMBGBYFsRQCMloFGo4jGK5DAArkhjX21HgHScvm7WIxGJQ6tUY5Xp9g16sXqioKkKCAFmS8LPnngOwtJtjMRpFUlWxLR5HLBJBXlFaSg71XptLFkTUCQwSqGljk5NL/9Q07Nm5Ey+dnETZNHGuUMDf//CHlx2fm5vD0VIJuycnEZFlXLVrF+RkEqbjQFUUBINBmMvaKTdzB+0dG49G/X+PhMMwbRshQUAykehIkBCSJKTSacyeObOh53t5FMu7TdqWBSEYhO26KC4uLnWovGRb6Hq0dBpyvZR1LwZHRNTfGCTQuvbt34+rx8cxtm0bqrUaTNtGvJ5P4FSr2LNzJ/5hlS19u+uBxXQ2i+lsFv/ftdciEYnAricyRhUFdiy2ai5CI67rouy6UBQFgiDAtG3o9TvpVgfZZkViMewcGdlwkLC8iZO3M2NE0+BWq7hYLMKtz4QUWlxqyM3NNb2d8tIy2AB3WRDR2hgk0LpikQj0SgXPz84iGAxiz86dCAaDmM7l8OMXXoCybJvipQzTxOjICHYmk3BcFz+bmUEsHMbOkRFckUohlUxiSpYxVy+8tN60eSQWQzIWw4V8HrZlIVlvIrV/chLZfL7jd9NaOr3pro3Lr9GrYLlrbAyW42zo9ZoZ6HdmMkjGYjBME7MzMwwOiKgpDBJoXcloFKPJJMKShMVKBbMXL0IIBqHFYhgdGcHMGuWSTx0/jnlVxd7du7EzmUQsHMbRn/8c+/fswYFMBoIgICLL/o6F9RRzOT95MaooUGQZU9PTSCWTUBWlYx0VbdPEuYWFy4o5eSWmtZERxCMRFMvlFT0q1rJ8i+fZ2dnLki5D9XLUmw1KdmYyiITDKJXL0FnxkYhawCCB1lWxLLjVKkqGgYXFRZQrFSSjUURkGYZp4ug6g6Kh6zhx6hTs8XFcyOdh6Dqe+8UvULFt/NLEBLbH45i9cGFFjYS1FOqBwq6xMb/Pw/NnziDVYBtmu6xWs2F8YgLxSAQAEJFlzF+8uOHXv1QkFltajlkj8GlmqcEwDBTrnzsRUStYJ4HWNb+wgEK5jHP5PCqWhUg4jEXTRMkw4FSruOnaa3HNtdeu+RqiLCOmKEvbF73HQiEUymVYjoPRbdsa5iU0qh/gFVoqlcsQBAHxerfK488/D2Dpznmr6g4UFxfh1moAgFKl0rbXVVQV6VRq3WTG5Z9XXNMwsWcPxiYnV9St8ApWERG1ikECrevU8eP4/tNPw7AsJKNRxBQFE9u343yxCGAp72DRMNYcmIu5HI7+9KdYqN8RO5aF4uIiqtWqv31xpD6whZYVSfLKMDcqmJTLZiEEg9gxMuLnJpRLJQiCgLFMpmGBJ09c09pSxKhcKsF2HNiui2q1uiII2gzbsjCXzSI3N7fUWEtVmypFPVKvTaH2edlqIuoNXG6gliSjUWixGBzXxWKlgpFoFLlSCdNTU021j15+zOzMzFKAIIrYkUxi58gITMuCLEmIRSIQgkHkCgU4rouQICBXT270RGIxuNUqAECRZX/tfXRkBBXbhuO6fmtqUZL8u2ktncZIk50s12PoOk6cOIG9e/cCWKqm2I7kRq9TpmdHKgUAmFpjRqBcKmFB13E+m+XMARG1BYMEasrE+DgS0ShM28Zz09M4c+4couEwfnLyZMvFfzxjmQyApYHVdhyIoRBefuWV0OuVGCu2jVgkgmwuh8KySoTeoC9Kkj+LUa7XY9ANA6VKBbbj+NsVHcuCVh9k7XplR++f7eBViXRdF6Ztd2wbphQKIa5p/qyJEAwit7Dgv79tWZg6ebIj701Ew4lBAjUlIssIBgKo1mqYu3gRx59/3h+sN2p2ZgYJTcPIjh2IyDJs14VVn7r3ZggkUYSqqisGXm9GwtB1FOpFjkLJJHKFwlJug+v6WyqBpaAiFolgbPv2pXLQ9V0UyUSiLYOqN5vgnVsneOfp11hQVYihEKKKgmr9s7Js2y9NzfLORNQOzEmgppRNE8FAAP/w3HN4/oUXACwNiJFYbMNtmx3LQm5uDhXbhu26kENLMWs0HIYYCkEMrR/DOpYFXdeRjMUQi0T8AOPSu3mv6JJbrUIIBmHa9obOea3zaGVQ3mguhKHryBcKCNYbZVVME5ZtIxgMIhaJILNjBzKjo36FRyKizeBMAjWlVC6jYtvQEgkkYzGIoRCq9W6OJzZZl+DYz3+Offv3IyzLGIlGIYkiEpEI5hYWoBuGX01xNcVcDqqq+lsyJVHEWCbjr80vn+0wTBP5QsHPVeiWzdzll0sl/OL4ceyenIQgCLBsG9VqFTYAIRCAKAhIadqKvhhERBvBIIGa5rguJlMp5EolCIEAVEVBNp9vy7S2t31x3/79iEUi2B6PLwUKFy5AVVV/Gn21egELuRzcZBKyJMGqJy3aloVQ/Xn5UgmyJPkBAtC/JYkTmoaoomBmfh7ayAiEYBDWspkRrxX3pYWfaLg1W76baDkGCdQUXdcxff48do+OolqtomzbmF9YwPTUVFvfx1sWqNZqCNerKp7PZtcd8AxdhyjLfvvp5Wvyiqr6OyMG4Y9kIZdDKJVaytWoVCDUW03LooiooiAsisjrOhKahsIa1TCBF3d6ZHM5NogaYF5lUGUDXUZpuDFIoKYoioJFw8BUNot4JIKKaSKqKNh/5ZV+6+N2yJdKGE+lULEsxCMRTKZSEILBpkodr5as10wVx37iWBZy2Sz27t0LMRTC1OwsREmCaVl+0ObUZ1HWu+5yqeTv9qDB5VgWbNPs2M4bGlwMEqgp3p14bm7ObxYUC4f9aoPtcm5mBpFwGFFFQaFcRnFxEaqiYGcms+4d0GoD4iAFCJ6EpmGbqqJUqUBRFL95kx2LtbScwpyF4cGfNW0EdzdQ07yM+XMzM5jLZjG/sIBqtYrd+/a19X3m5+cxd+ECpmZnkS8UMDM/j9Ft29asoDhsyqUSLuo6qtUqYpEILNuGqijIjI5i9759Kz4rRVWxs16TgoioFQwSaF2KqiKVTkOpd1kElnYU5BYWULFt7Egm2zqAG7oOWZKwe9cu7B0fh6IocGs1ZEZHoaXTbXuffmboOuayWciiCMtxUFxcfLH+g6peVpY5Eg53dTcHEfUnLjfQumzLgiyKgCjCqXddBJYChYuqioosY/euXRAnJ1E2TbjVKi7k85sqTSyLIrYnEqhYFka3bYMYCiEYDMKKxVAulTh1iqXP/5/rWzl/6cABuLUaKqaJcxcvrvjsDV1vun01EdFygVqtzYvKHVAsFpFIJJABpz66abVEOG8qW5YkpJJJ7Ewm4bguTmezOHHihN+gqJWBXUunsXfXLlSrVUTDYRTLZeR13c/mDwkCexQs41W/XJ6AOIi5GES0eVUAMwAKhQLi8fiax3ImgZq22qBzbmbGr7poWtZS0aVYDNvjcWDvXhimidFt23Bmfr7p7VfenfDBPXtQsSyE602gTMuCW6thJBqFaVkDt3Oh1WDKc2nFx52ZDBzX3XSjKSIP6ywMJ96YU1vYluXXKSguLqJYLkM3DIRFcWm5QBAgN2j3vJbc3Bx+duYMLuo63FoNcigEVVEQkWXo9RmF1IDlKLRrZiTXRG0JolYwQBhODBJoXc1kxjted0XTxPlsFnldh1gf1KvVKs4tLEAKhVoe1GVJQiIahRAIIFcqQTcMRGUZqUQCmR07EItE2r67YhAsbzWtqCrimuZ/ERE1i8sNtC6viuF6HMtCQtMQj0aXmg/ZNkRBgFutYqFUQlRRkG1x+nvRMFCtVqHXEyIN00QwGERYFAEs9ZSIRSIbnqYfdCFJwq6xMYRlGbbjwHVdlEulpVbbsswqi0S0JgYJtC6vSluzFfxCguCXCr6o63DrOyI20pa5XCrh+fpdcUiSMD4xgdkLFzC2fftSN0fLQkgQlpY6GCRcxrEslOtNrwDAchy/3oVd3zJJRLQaBgm0Lq/Eb6I+Vb1WMpyh6zB03Z/WjsgywrKM3aqKwgYaK3mv5z3P28pXzOf9Y6KKsqLTI63k1ttne7MvJuv3E1GTGCRQUxzLQm5uDqF68uF6A32x3jBIS6cxAkAUBBy46ipUq1XkCgXkslmIkrThu//lzxNGRzf0GsMil80iGYuhWC4DaH75qN8xG59o8xgkUEu8WYVmcwC8pQq3WkU8EkFa05CIRDCeSgEAnj9zBoqi+APXRtfIQ/XljUER1zQoigJBEDB75symXsuxLFzI5zESiy1VZxySPAQGCESbt6ndDQ8//DACgQDuv//+VY/5/Oc/j0AgsOIrHA5v5m2pB0Risaa2Mxq6Dtuy4FarAJYGc1VRAADT9dmEse3b8a9e8hJkNjgjMD01hUg47NdqGAR7x8eRrOcOtENubg5nZ2dxvt6oi4ioGRueSThy5AgeeeQRHDx4cN1j4/E4jh075v93IBDY6NtSD3AsC/FodNXWzKtZrFRwvlBAXteRzeWgjYzAtG3YrouKZUGrBx6t3gFGYjFktm+HW61iakCSF88tLMB13RW5F5vFxE4iatWGggRd13HnnXfi0UcfxUMPPbTu8YFAAKNcNx4o01NTTQ/mxVwOtmnCtixoqRQc14VtmhCCQcQiEYRFEYVyGUIggMiyVsfNsk0ThmVBi8ch7d+P06dP9/1U82aXGIiI2mFDyw333nsvbr/9dtx2221NHa/rOiYnJzE+Po5/9+/+HZ577rk1jzdNE8ViccUX9RaxxeqJXvW/XDaLcqmEXWNjEAQBF/J5nJqbg+04AIDM6GhTr7v8GG85o2ya2JFIYHxiosWrGU5jk5MDtURDRO3XcpBw+PBhPPPMMzh06FBTx1911VX43Oc+h69//ev40pe+hGq1ihtvvBEza2zBOnToEBKJhP81Pj7e6mlShxm63tLdutdbwHuO5TiYqwcM6e3bAcDv9KjVkxrXktA0f6cFAOSKReRLJZQqFWjxOAe/JkRkGSP1z5GIqJGWukBOT0/j+uuvx7e//W0/F+Hmm2/Gy172Mnz6059u6jVs28bVV1+NN7/5zfiTP/mThseYpglzWaGXYrGI8fFxdoEcUF5Nhf2TkwgGg7AdB6Zt49zFiyjkcn5g4XU6NHQdWjqNiZ07oYbDeH5mBsl6QyndMKAqCgrlMn5x7FjfLzu0i6KqiCeTrI9ARJ3rAvn0008jm83i5S9/uf+Y67r4/ve/j8985jMwTdOvtLcaURRx3XXX4fga/e1lWYYsy62cGvUZRVX9Do5eDsKsqiKzYwcmtm9H0TCQiERwMZnEsZ//HLv37cOedBoVy8IvpqaW2lInEgCA/ZkMZi5cwIViEYloFLbrQhQEaKkUctlsTwYKywOerWBbFpx65cu1rJU4ytLXRMOnpSDh1ltvxbPPPrvisbvvvhsHDhzAAw88sG6AACwFFc8++yxe97rXtXamNDBCknRZi+eQJEHXdcwLAqrVKkRBgO26iCkKrrr6aoRFEaFgEKZtA1jKc5m+cAG6YWDq5Ekoqor9e/bAdhxEZBnVahVj27dDliTMzsz0XKBwaWvnrXi/9dpGK6qKHakUFg3jsmN3ZjLQEgmcOnOGgQK1HQtf9a6WgoRYLIZrrrlmxWPRaBSapvmP33XXXdi1a5efs/DhD38Yr3zlK7Fv3z7k83l87GMfw5kzZ3DPPfe06RKo33lr4l4vgbyuIyzLEAIBjI6MIBhcWmSavnABp86cgW1ZiMRi+NmyBFhD17Gg6xjdtg0AEK3X4giLYsNBj1ZSVBUT4+OwbNsvgLVcjvUVqENCkrShXU20NdpecXFqasr/ow4ACwsL+I3f+A3Mz89jZGQEr3jFK/DDH/4QL3nJS9r91tRHGt012JaFRcMAFAVutQohGESuVIJbrSIZjUKRJOw4eBDFchmmbSOvqv5WwbHJSSwaBs7n89DicQQDAUiiiGAggPT27SiXSrwDXoOh6zhx4sS6d3MjmoYRTeMWTWoLb9mtXCpBS6f5/2kPailxsVuKxSISiQQTFwecN6OQ0DREFQVCMIhovTpjIhJBSBAQVxRc1HU/7+DU/Dyyc3PQUilMjo5CCATg1moY27YNtuOgYttwXBdnL1zA8eef7+bl9TVFVbF7ctL/75n5+YZ3fl4jMG/mhtPItB4v18X7/5+/L53XscRFok7y+kKUSyXIkgShvtMhlUggGAyiWC7Dsm1EwmFUKxWYto0xTUNEllEqlyEKAiKyDMtxsFipICQIkEIhXCyVEA2HEdc0TmlukKHrmJmfh6qqS625G2yb1NJpAPV24QwOqEnLu7xS72GQQD1leULfiKZBCAZhOg5sx0Fe1yGJIux6ln4wGETZNBGWZWyLx7Gg64hHIijUg4ltsRhmL15EXtexI5nExNgY5iRpYPITtnog9jp7Lt/l4DWiOjczg5F6rwlZkhASBOQLhYENyhgE0bDg7D31JEPXIYsiAGD+4kVUq1VEFQVhUUQiGkVMUWBaFmzHwUg9X0EUBDiui4vFIgrlMoKBAJLRKLR4HHIohIgs+4Wb+l1IkjA+MYGxZUsAW/W+9rLBsVwqIRIOIyRJEAQBbrWKWCQCVVEazjYMAgYINEwYJFDPyi0swK1WlxIRg0GERRFurYaLpRKCwSDEUAjheiBRrVYRDAahGwbKpom8ruOirsNxXciiCMOyUDZNVKvVgajGmNA0uNUqsl2eFXEsC6eOH0ckFoNhmnCrVVi2DcM0G+6SGAQMEGiYcLmBepbXGEoaH0e4vsxQrVYhiCIs28aORALnCwWYjgPdMAAAQjCIiCxDEkXEIxFMX7gAURCQKxbhuO7Seros930GdW5uDt2YyF+10JKiIB6NolIPFDzrFWe6tF4GEfUWziRQTzN0HXPZLBZ0HcXFRf9u1bAszOZysB0H5Xp9Bbda9ae7g8EgKpaFnckkZi9cwPlsFgu5HEzLWhrQ6qWgqT1y2Sxsx4EgCMgtLMC0bYyOjq655BCp5zAQUe/iTAL1PK/IkuO6Szse6v90azUIgQDE+uyAaVn+1siRaBRhSUKxXMbY9u0wDGNpD3Z9xsFe1huENs+xLJw4cQKRWAzlUgnFXG7dtftBSSAlGmQMEqinedXYHNfFQi4Hsd7Tw3YclMplbIvHYddLNQeDQX9qLFcqIVsoYHs8jlQigbyu+9n5g8L7bMqlUk9M2S/vw+H9NxH1Ny43UE9zLAuFXA4Lywaf3MIC8qUSQvVeIcFgENX6OrhQ7+8QkeWl3IRQCE61ingkgp2ZzEAkLXocy0IykeC0PRF1DIME6nmOZcHQddiWBds0oSgKBEGAIsuomCZsx1lqMe26yOv6Uv+B+k6G/OKi3/3QcV3sGhvzK7sNgqmTJwdqdoSIeguXG6hvOJYFUZIgSxKkUAj5UslvPJRKpxGRZb8T6bmLFwFgqahPOAwhGEQ8GoUkihC5z71nsR01UW9hkEB9xdB1nMdSZnwhl/MHe69egJZKIRIOY3syiQv5PHLZLM7Vj/H6CnAQ6l29/LNhESUaRgwSqO8Yun7ZYOL98T43MwNFVbEjlcJILAZ7WTKdY1nMqCciagGDBBo4hq5jtr40YfPOj1q02owBZxFoGDFIoIHksJIfEdGmcXcD0TKDtPOBNobBJdGLGCRQz2h2gO5ErQNFVf3ERu/1GTAQ9Q7+/9gdDBKo73Qqz0BLpVAulWBbFhRVhShJ7PFA1CM4w9MdzEmgvtOJPxa2ZSEWiSAZi6FULsN1XTiuiwILFRHREGOQQD2lW8V0HMtC2TSRVFWEBAGzZ85s+TkMMy2dhixJyM7N+btSeOdI1H0MEqhndHtQmD1zBm4mA8d1/fXPbp/TsJAlaWn2hsEBUU9hkEA9xbGsrg7QgiD4vR6A3q6y18vn1irO3BD1JiYuUk9KaFpXspmzc3Mol0orHhuUrOq4pmFnJtPt0yCiPsKZBOo5jmXBrldMvPROudN3z42mu3s1SGjlcwhJEvaOj8N2XRTz+Z7ukUBEvYMzCdSTvK2I3gAdqm9HTHRhS+IgTOmPT0ygbJpYNAxMjI9zaycRNYUzCdSTnHqtAk9C02Bb1mVLAbS+nZkM3GoV+fpnV65U+DkSUVMYJFBP8mYQDF2HoqqIKgrOl0pbOk0+KDscctksAECUJIiy7HfFJCJaD4ME6lleZUWvq+NWDtaKqmL35CQAIK/rfZ19731ujmUNZC7CIO3yIOo1zEmgntQL++UN00QiEkFSVaGl0109F7qcl6ci9mhiKdEgYJBAPW958qL3z+VfnSDKMsqVCgrlMiKyjO3JZEfehzYmJEmIxGIAMJCzI0S9gssN1NO8IECsDwrlUskfHDzeTghv5qEduQTFXA5lSUIxn8fuyUm4ywosDaNulctejWNZsE0Toiz7yw3NLjtweYKoeQwSqKd5U8m7xsYQlmVU6gGCW61CEkUYpgkAft3/dvIGknMXLw51o6eQJGGkvrukFwfXvXv3IiyKeO4Xv2jq+F68BqJexSCBetqOVAqqokBVFABAxTQRDYcBAIuVCmZnZgAsbZHUUikIgoCFXO6yu97lMxKt3BE7loVcm4OPfpSdm+upwVVRVexIpQAAiWgUtuN0+YyIBhODBOpppmUhHo1CNwzMzM8DALSRESiyjOPPP+8fl5ubQ0iS1iy2JPb4HXGv6sXPygseDdNEYXERYVFsWKHzUlxqIGoNgwTqablsFsV8fsXAvto+f8eyUMjlkNC0VWcLTAYIA2HRMJZ+lq6Lndu2wXbdphIZ+bMnag2DBOpprW6F9AKFS+8YI7EY0qkUxFAIhVyu5WUH6i3Ll4BkSUJEllHI5db8XRmU4lhEW4lBAg2c1QaBbfUyzy8/eBAz588zSBgQs2fOQFHVdQd/7/txTUO5VGKwQNQE1kmgoVDM5TC/sAAAiCkKdAYIA6WVgK+4yozD8l4hRLSEMwk0NObn55FbWIA2MgK7vnWSyGMvCxy0dBrlLe4VQtSLGCTQ0DB0HYaus8ERNeTNLuzMZBAJhxESBAYJNPS43EBDqZMlnYddpz/XTr5+SJIQCYchiSJikQiXIGjocSaBhlJC0zpWRXHY9+InNA0hQcC5eqGrduvUZxuSJIiSBCG4dO8kCALiySTiySSK+TxEWV7RTIpFtmgYMEigodSJP/Bjk5NIqios24ZbrSK3sDCUSxu5uTnENa0ng6W1tkGOT0ygXKnArVYBLAUJkXAYpm2/+HxBWHr+kPfyoOHBIIGoSd7U82rr1LNnziD5S7+EsCzDdhykNA22aQ7luna5VGqqAuJWimsaUvWKnGdnZ/3iS97A7wUD3kyC67owbRuu6yKeTEKWJJzPZofy50nDizkJNDQ2u5btJT6u5WfPPYe5Cxdg2TYEQViRMT9MHMvqucHUNk1YjoNYJIKJ8XHEo1HI9d+JSDiMWCSCSDgMoR40uNWqH0B4dqRSzGWhocIggYbGetX4ln9tRm5uDvPz8yiVyz11Jz3MQpKE0dHRpXLOto2wKCKpqitmESzbhiSKAJYChFPHjwMAxrZvX0pmDIUghUIYn5jAzkyGwQINBQYJRGh/Mpyh68jOzTE7fout9Xnn6sW08rqOU2fPolQuQ5FlyJLkLy0AgBgKIamq2Ld/P+LRKKrV6tKyQ7UKQRD8QMJLYuTPmAYZgwQaWqvdCbYrYOjFKfdBt9ryjmNZKOZyCAkCdiQSSCYSKJXLiMgytHjcX3YQQyEIgQBs14VbrUIUBCxWKpBFEUIwCLeesGgYhv9ew7qkRMOBiYs0lEKShEgsxhr+A2a9n2Uxn4csSXBcF1oiAWApUVGLx1GuV+EUQyHAcVCuVDA/Pw/bsjCWyUCRZQSDQSwaxoqtkPz9oUHGIIGGiqKqiCeTMAyjYYDAP/id4QVl3d4S6t31j2kabMdBXteRVFV/qcF2HIiCANt1MZ5K4bl8Ho5lYerkScQ1DYqiIJfN8veEhgaXG2io2JYFWZJWbfJDnTGWyfjbD3vBdDaLU2fPQggGkSsWEVy27REAREFAyTCwd/duaOk0gKXGUOdmZvh7Q0NlU0HCww8/jEAggPvvv7+p4w8fPoxAIIA3vvGNm3lbog3z7gpX+56HmevtlS8UUCqXu30a/s8/l82iXCrh7OwszmezKC4uIiyKCMsywqKIYDAIMRSC7TiIR6PYmclAS6f5e0FDZ8PLDUeOHMEjjzyCgwcPNnX86dOn8b73vQ833XTTRt+SqKO8KfFhLYDUScVcDsUOvK63s8C2rJbu8L1jvX8uxmIwLQuCIEAIBODWakhEItANA67rYsfICCqm2dFy00S9aEMzCbqu484778Sjjz6KkZGRdY93XRd33nknHnzwQezZs2fd403TRLFYXPFF1GlaKoWXXnklRFnu9qlQE0KShInxcUyMj2Msk9nwa2jpNEZiMSRjMSzkclisVCAKAkzbxmKlgrJpYmp2FmXT9HdBEA2LDQUJ9957L26//XbcdtttTR3/4Q9/GKlUCu9617uaOv7QoUNIJBL+1/j4+EZOk6glgiDAdBxkRkexe98+7n/vcY5l4cSJEzhx4gRmN3B37y0dFHI5lMpliKEQRjQNp0+fXrE0EotEkE6l4LouzmezDV9rbHISV119NcYmJzd2MUQ9quXlhsOHD+OZZ57BkSNHmjr+Bz/4AR577DEcPXq06fd4//vfj9/7vd/z/7tYLDJQoE1RVHXNJQRFVbEjkYAcCkFJJGBYFuKRCP7lJz/ZwrOkVm0miXD5c3PZLCLhMBbqCa2lchnZXA52fVukfcnyRCNCMIikqmJhnd81on7SUpAwPT2N++67D9/+9rcRDofXPb5UKuFtb3sbHn30UWzfvr3p95FlGTKnfKlN4pqGdCqFEydOrPlHXpYkLCwu4vzCAl4yOYl0MomFPXtWTXSkweFYFnILC/7g3mrewUJ9a6frugwQaKAEarVardmDv/a1r+GOO+7wG6AAS/9TBAIBBINBmKa54ntHjx7Fddddt+Kxar0NazAYxLFjx7B3795137dYLCKRSCAD7tmk1mnpNCZ27sTshQur/vHX0mlkduxAxbaxPR7H9nqHwH/8xS+YqDakWm113YutsYkaqQKYAVAoFBCPx9c8tqWZhFtvvRXPPvvsisfuvvtuHDhwAA888MCKYAAADhw4cNnxH/zgB1EqlfCnf/qnXEKgLVHI5XDCsqCq6qrLDiOxGNx6vLyg67hQLOJCPo/c3NxWny71iFYHfAYINIhaChJisRiuueaaFY9Fo1FomuY/ftddd2HXrl04dOgQwuHwZccnk0kAuOxxok7x6vYXczkoqoqQJCGhaSsCgLOzs9g1NgbLcXA+m+WU8ZDayGzAevkuRP2s7WWZp6am/OplRN12aTlg74/5pTMEhq7j+PPPb/n50UrdnLJvplBSo/NjgECDrKWchG5hTgKtJa5pDXsCeAGCKEkosAwzbUJIkqClUjAMo6P9J7R0mr+r1HGt5CRwzKW+FpIkpFMpTDQo0jU+MQFVVZGbm2vqj25Iklh2l1blNQVbS1zTVv09Wu93K65piEejKzpMEnUbgwTqe67rQlUU7KxX3QtJEsYmJ7EnnYYsius+3/vjzbu33rMzk+mJwM3La1nrdyQkSdg7Po4rrrgCiUuaWYUkCeMTE2sWW7JNE9NTU1y+6IBe+B3qV2wVTX3LW04olctwXBfReqAgCAJ2JBKYu3gR8/Pz677GpX/4uZWtd/RyW+ZLg0vHsvDsz3624jFPJBaDIsuIKgqyq/x+MTigXsQggfpaMZdDub5enC8UkEwkcD6bRbaemLjeAHPp93t1QBpWvfrzCEkSrrjiCgiCgKnpaX+AX+t8LdvGwjrLFdQZvfp71A8YJFDfWn4H591x2qbZVAldYOMzBpxpIMey4FarkETR/31bS7lUwulSib831HcYJFDfU1QVkVgMhVyupSlb/sGmzRCCQRj13g7rabSkFYnFUGbgQD2OQQL1PVGWm7qbaxf+UScAOH36NIDWfx+8pQpJFJFXVcyeOXPZ97VUCrl6x0n+vlE3cXcD9T1vW5r3x5SZzNQsb8viRjiW1XCGoJnnnT59GoZpIhaJXPb9hKb5jzNAoG5jkEB9z9uetvy/PVsVMCiquiXvQ+213rbGVoQkCWOZTFO/C45loVypYK4+W7BcIZeDW2+ER9RtXG6ggbZVd2I7UimcB7exDSsvQHBcd9Wlr0sTXlfrLupY1rpbd4m2CoMEojYwLQvxZJJBwpByLAvn18khaCVg5e8R9QoGCURtcG5mhrkQQ44DOw0i5iTQUOpEnwYmmdFaGERSP2KQQEOJAzoR0foYJNDQYqBAW4m/b9SPGCQQbQEtneY2SSLqOwwSiLZAZscO7Eilun0aVBeSpJaCtk7ksBD1AwYJRFtg/uJFSCFuJuoVrVbnbFRdsZcoqord+/Zxtorajn+1iLbAuZkZnOv2SdAKg7Rl0dB1mLa9pT1MaDgwSCAiGgCXNooiagcuNxAR9biQJGFnJtPt06AhxCCBiKgFnU5gbJQk6VgWivl8R9+XqBEGCURETYprGvZfeSXGJifb/tpaOu2/bqMkyUHKoaD+wZwEIqImaOk0oooCt1pFLBJBXNNWtChv1s56t8jc3Jz/3wAQCYcRj0SQVFVYto2FUgmF+uv38s4KGmycSSAiapLjurBsG67rQt3gdsNiPu8P/gBgGAZkSYIQDMJ2XciiiLAsQ5YkjE9MIKFp7Tp9opZxJoGoS3ZmMtASCZy7eNG/q6TeZVsWbMuCqyiQJQm6riMkSS3f5V+6bCBKEkzLghAMIlcoQBAEAMBCLocRTUNUUdD6fAVRezBIIOoSLZGAKAgMEHpEXNOgjYzArVYxdfKk/7iWTqOQy6FcKmF8YgIAMD8/39YcgWQsBiEYXPoSBLiuC3l0FOVK5bLz4NIDbSUGCURd8vwLL/APfo9QVBWp+rS+adsrvmfXqy2GJAlutQoAEGXZf3yzbMuCZdtQZNl/zHIcCMEgDMNAuVQCAEQVBdFMxg9g4poGUZIYZFJHMUgg6hIGCL3Dq1RYKpeRy2ZXfK+4LHlw+QxDuxRzOaiqinKlAsd1/fMpl0orfkcWDWPF80RJQjwaRVlVufOBOiZQq9Vq3T6J9RSLRSQSCWTATEsi6oyQJEGUpK4OuK3kOPTC+VJ/qgKYAVAoFBCPx9c8ljMJRDRUVhuIe6GJUyvv3wvnS4OPN+ZENDQUVUVC09gtkahJnEkgoqFh6Dqn54lawJkEIqJLdLo/w6XvpaXTiGtaR8o9E20GZxKIepSWTsO2rA2V/qXN2aq1/ok9e6DIMgzThLPJwISJjNQJnEkg6lHbk0lkRke7fRo9KT4geQWO6yIsihCCQcQiEciiCC2dbvl1FFXFWCaDifHxgfhcqHdwJoGoR81ls7BNs9un0ZNUVYWO/u+MaFoWKrYNt1qFZduIKsplxZyaYeg6FmMxmJbV958J9RYGCUQ9KCRJXGZYw+yZM217rY30X2iX3NwcCrkcIrEYAEAIBrGwwZ87Ky9SJzBIIKKh1u1aA86y6oq2aXImgHoKcxKIelC3By7aWt7PmwEC9RoGCUS0ZUKShHi9kRKt1K5tlyFJYvIitQ2DBCLaMuMTE9BGRrp9Gj1po7NHlwYXjmVBXNZRkmgzmJNARFumuLgIu952udGgqKhq21owD4tGnxWTXqldGCQQ0ZZZLwO/X9fkvbt5Bjc0aLjcQES0SWOZDLRUqtun4VNUdUtLS9PgYpBARLRJpmUhFol0fGBuJukzrmmYGB/HWCbDQIE2jcsNRESbdG5mBkVV7fhyw6W5Bo1yO5KJBIClwkxjmQwWDQOFXI5LIbQhnEkgImqDduVTtHL332jgF4JB/0tVFMSjUaQ20A+CCGCQQETUM+Ka5pdoXs9qNSfm5+eR13WUTROWbUMILv2Z19LpDTWPouHG5QYioh7RytZFr5zzpQxdh6HrUFQVC/XHuK2UNmpTMwkPP/wwAoEA7r///lWP+cpXvoLrr78eyWQS0WgUL3vZy/DFL35xM29LRERYe8ulFywYus4AgTZswzMJR44cwSOPPIKDBw+uedy2bdvwR3/0Rzhw4AAkScI3v/lN3H333UilUnjNa16z0bcnIiKiDtvQTIKu67jzzjvx6KOPYmSdEqs333wz7rjjDlx99dXYu3cv7rvvPhw8eBA/+MEPNnTCRDScFFXF7n37WupLwB4GRJuzoSDh3nvvxe23347bbrutpefVajV85zvfwbFjx/Bv/s2/WfU40zRRLBZXfBHRcDN0HW61ipEWGkT1awVHol7R8nLD4cOH8cwzz+DIkSNNP6dQKGDXrl0wTROCIODP//zP8Su/8iurHn/o0CE8+OCDrZ4aEQ24qZMnu30KREOlpZmE6elp3HfffXjiiScQDoebfl4sFsPRo0dx5MgRfOQjH8Hv/d7v4amnnlr1+Pe///0oFAr+1/T0dCunSUTU17hMQr0iUKvVas0e/LWvfQ133HEHBEHwH3NdF4FAAMFg0J8pWM8999yD6elp/N3f/V1T71ssFpFIJJABCzsQ0WALSRISmrZuM6z1xDWN3SCpoSqAGSzN8sfj8TWPbWm54dZbb8Wzzz674rG7774bBw4cwAMPPNBUgAAA1WoVpmm28tZEREPBsaxNBwgAGtZQIGpVS0FCLBbDNddcs+KxaDQKTdP8x++66y7s2rULhw4dArCUX3D99ddj7969ME0T3/rWt/DFL34R/+N//I82XQIREV2KtRGoHdpecXFqagrB4IuLAouLi/jt3/5tzMzMQFEUHDhwAF/60pfwH/7Df2j3WxMREVEbtZST0C3MSSAiImqPVnISOOYSERFRQwwSiIg6pJW2z5famclwKyR1HYMEIqIO2UzyoCxJTbeNJuoUtoomIupBrC5JvYAzCURERNQQgwQiIiJqiEECERERNcQggYiIiBpikEBEREQNMUggIiKihhgkEBERUUMMEoiIiKghBglERETUEIMEIiIiaohBAhERETXEIIGIiIgaYpBAREREDTFIICIiooYYJBAREVFDDBKIiIioIQYJRERE1BCDBCIiImqIQQIRERE1xCCBiIiIGmKQQERERA0xSCAiIqKGGCQQERFRQwwSiIiIqKFQt0+gGbVaDQBQ7fJ5EBER9TtvLPXG1rX0RZBQKpUAALNdPg8iIqJBUSqVkEgk1jwmUGsmlOiyarWK2dlZxGIxBAKBbp9ORxSLRYyPj2N6ehrxeLzbp7MlhvGageG87mG8ZoDXPUzX3U/XXKvVUCqVMDY2hmBw7ayDvphJCAaDyGQy3T6NLRGPx3v+F6zdhvGageG87mG8ZoDXPUz65ZrXm0HwMHGRiIiIGmKQQERERA0xSOgRsizjQx/6EGRZ7vapbJlhvGZgOK97GK8Z4HUP03UP6jX3ReIiERERbT3OJBAREVFDDBKIiIioIQYJRERE1BCDBCIiImqIQcIW+chHPoIbb7wRkUgEyWSyqef88R//MQ4cOIBoNIqRkRHcdttt+Kd/+if/+0899RQCgUDDryNHjnToSlrTiev2/O3f/i1uuOEGKIqCkZERvPGNb2zvyW9Qp675iiuuuOzn/PDDD3fgCjamkz9rADBNEy972csQCARw9OjR9p34JnTqmt/whjdgYmIC4XAY6XQab3vb2zA72zuF6Ttx3adPn8a73vUu7N69G4qiYO/evfjQhz4Ey7I6dBWt6dTPeiOvu5UYJGwRy7Lwpje9Cb/1W7/V9HP279+Pz3zmM3j22Wfxgx/8AFdccQV+9Vd/FefPnwcA3HjjjZibm1vxdc8992D37t24/vrrO3UpLenEdQPA3/zN3+Btb3sb7r77bvzLv/wL/uEf/gFvectbOnEJLevUNQPAhz/84RU/7/e85z3tPv0N6+R1A8Af/MEfYGxsrJ2nvGmduuZbbrkF/+f//B8cO3YMf/M3f4MTJ07g13/91ztxCRvSiev+xS9+gWq1ikceeQTPPfccPvWpT+Ev/uIv8IEPfKBTl9GSTv2sN/K6W6pGW+rxxx+vJRKJDT23UCjUANT+3//7fw2/b1lWbceOHbUPf/jDmzjDzmjnddu2Xdu1a1fts5/9bBvPsP3a/bOenJysfepTn2rPyXVQJ37Hv/Wtb9UOHDhQe+6552oAav/8z/+8+RNto07+f12r1Wpf//rXa4FAoGZZ1gbPsDM6fd3/9b/+19ru3bs3eHad0alr3szrdhJnEvqEZVn4y7/8SyQSCbz0pS9teMw3vvEN5HI53H333Vt8dp3T6LqfeeYZnD17FsFgENdddx3S6TRe+9rX4qc//WmXz7Y91vpZP/zww9A0Dddddx0+9rGPwXGcLp1l+6123efOncNv/MZv4Itf/CIikUgXz7D9mvn/+uLFi3jiiSdw4403QhTFLT7DzmjmugGgUChg27ZtW3hmndPsNfcaBgk97pvf/CZUVUU4HManPvUpfPvb38b27dsbHvvYY4/hNa95zUA0w1rruk+ePAlgab3vgx/8IL75zW9iZGQEN998My5evNjN096U9X7W733ve3H48GF873vfw2/+5m/iox/9KP7gD/6gi2fcHmtdd61Wwzve8Q68+93v7pkltHZo5v/rBx54ANFoFJqmYWpqCl//+te7dLbt08rfs+PHj+O//bf/ht/8zd/c4rNsr1auuSd1eyqjnz3wwAM1AGt+/fznP1/xnFanlHRdr73wwgu1H/3oR7V3vvOdtSuuuKJ27ty5y46bnp6uBYPB2l//9V9v9rLW1e3rfuKJJ2oAao888oh/fKVSqW3fvr32F3/xF225xkt1+5obeeyxx2qhUKhWqVQ2elnr6vZ1/+mf/mntVa96Vc1xnFqtVqudOnWq48sN3b5mz/nz52vHjh2rPfnkk7VXvepVtde97nW1arXajktsqFeuu1ar1WZmZmp79+6tvetd79rsZa2pl665V5cb+qJVdK/6/d//fbzjHe9Y85g9e/Zs6j2i0Sj27duHffv24ZWvfCWuvPJKPPbYY3j/+9+/4rjHH38cmqbhDW94w6berxndvu50Og0AeMlLXuIfL8sy9uzZg6mpqU2972q6fc2N3HDDDXAcB6dPn8ZVV121qfdeTbev+7vf/S5+9KMfXVYP//rrr8edd96J//k//+em3ruRbl+zZ/v27di+fTv279+Pq6++GuPj4/jHf/xH/PIv//Km3ns1vXLds7OzuOWWW3DjjTfiL//yLzf1fuvplWvuZQwSNmHHjh3YsWPHlr5ntVqFaZorHqvVanj88cdx1113bcmaZbev+xWveAVkWcaxY8fw6le/GgBg2zZOnz6NycnJjrx/t6+5kaNHjyIYDCKVSnXsHLp93X/2Z3+Ghx56yP/e7OwsXvOa1+B//+//jRtuuKEj79/ta17t+wDWPGazeuG6z549i1tuuQWveMUr8PjjjyMY7OyKeC9cc69jTsIWmZqawtGjRzE1NQXXdXH06FEcPXoUuq77xxw4cABf/epXAQCLi4v4wAc+gH/8x3/EmTNn8PTTT+Od73wnzp49ize96U0rXvu73/0uTp06hXvuuWdLr6kZnbjueDyOd7/73fjQhz6EJ598EseOHfO3D1362XRDJ675Rz/6ET796U/jX/7lX3Dy5Ek88cQT+N3f/V289a1vxcjISFeu81KduO6JiQlcc801/tf+/fsBAHv37u2J3JtOXPM//dM/4TOf+QyOHj2KM2fO4Lvf/S7e/OY3Y+/evR2bRWhVJ6777NmzuPnmmzExMYGPf/zjOH/+PObn5zE/P9+Va7xUp/6GN/O6XdXt9Y5h8fa3v73hetf3vvc9/xgAtccff7xWq9VqhmHU7rjjjtrY2FhNkqRaOp2uveENb6j9+Mc/vuy13/zmN9duvPHGLbqS1nTqui3Lqv3+7/9+LZVK1WKxWO22226r/fSnP93CK1tdJ6756aefrt1www21RCJRC4fDtauvvrr20Y9+tKP5CK3q5O+4ZytyElrRiWv+yU9+Urvllltq27Ztq8myXLviiitq7373u2szMzNbfHWr68R1P/7446vmBfSCTv1+N/O63cRW0URERNQQlxuIiIioIQYJRERE1BCDBCIiImqIQQIRERE1xCCBiIiIGmKQQERERA0xSCAiIqKGGCQQERFRQwwSiIiIesz3v/99vP71r8fY2BgCgQC+9rWvtfT8P/7jP0YgELjsKxqNtvQ6DBKIiIh6zOLiIl760pfiv//3/76h57/vfe/D3Nzciq+XvOQlLfe3YZBARETUY1772tfioYcewh133NHw+6Zp4n3vex927dqFaDSKG264AU899ZT/fVVVMTo66n+dO3cOP/vZz/Cud72rpfNgkEBERNRnfud3fgc/+tGPcPjwYfzkJz/Bm970Jvzar/0aXnjhhYbHf/azn8X+/ftx0003tfQ+DBKIiIj6yNTUFB5//HF8+ctfxk033YS9e/fife97H1796lfj8ccfv+z4SqWCJ554ouVZBAAIteOEiYiIaGs8++yzcF0X+/fvX/G4aZrQNO2y47/61a+iVCrh7W9/e8vvxSCBiIioj+i6DkEQ8PTTT0MQhBXfU1X1suM/+9nP4t/+23+LnTt3tvxeDBKIiIj6yHXXXQfXdZHNZtfNMTh16hS+973v4Rvf+MaG3otBAhERUY/RdR3Hjx/3//vUqVM4evQotm3bhv379+POO+/EXXfdhU984hO47rrrcP78eXznO9/BwYMHcfvtt/vP+9znPod0Oo3Xvva1GzqPQK1Wq236aoiIiKhtnnrqKdxyyy2XPf72t78dn//852HbNh566CF84QtfwNmzZ7F9+3a88pWvxIMPPohrr70WAFCtVjE5OYm77roLH/nIRzZ0HgwSiIiIqCFugSQiIqKGGCQQERFRQwwSiIiIqCEGCURERNQQgwQiIiJqiEECERERNcQggYiIiBpikEBEREQNMUggIiKihhgkEBERUUMMEoiIiKih/x99Ak8dKZd/XwAAAABJRU5ErkJggg==",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "from rasterio.plot import show\n",
+ "\n",
+ "fig, ax = plt.subplots()\n",
+ "\n",
+ "# transform rasterio plot to real world coords\n",
+ "extent = [pop.bounds[0], pop.bounds[2], pop.bounds[1], pop.bounds[3]]\n",
+ "ax = rasterio.plot.show(pop, extent=extent, ax=ax, cmap=\"pink\")\n",
+ "\n",
+ "# gdf.plot(ax=ax)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "id": "b1cd86f5-365d-417e-baa6-8003cc98f743",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "CRS.from_epsg(3857)"
+ ]
+ },
+ "execution_count": 9,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "pop.crs"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "id": "772e786c-8929-415f-8fe7-3c1e6844c774",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "(1,)"
+ ]
+ },
+ "execution_count": 10,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "pop.indexes"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "id": "89b79e2a-f29e-42ca-8aeb-48e1a0762ea1",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "band1 = pop.read(1)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 13,
+ "id": "23bb533c-3180-4ef7-81ad-9d64f3a5c076",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "1.0"
+ ]
+ },
+ "execution_count": 13,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "band1[pop.height // 3, pop.width // 2]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 17,
+ "id": "bc7be4ab-ba86-4921-9e53-193868cebe97",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "array([[0., 0., 0., ..., 0., 0., 0.],\n",
+ " [0., 0., 0., ..., 0., 0., 0.],\n",
+ " [0., 0., 0., ..., 0., 0., 0.],\n",
+ " ...,\n",
+ " [0., 0., 0., ..., 0., 0., 0.],\n",
+ " [0., 0., 0., ..., 0., 0., 0.],\n",
+ " [0., 0., 0., ..., 0., 0., 0.]], dtype=float32)"
+ ]
+ },
+ "execution_count": 17,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "band1"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "id": "013fd196-7987-4b2d-8e7f-f73c586e106c",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "BoundingBox(left=-13792603.131890344, bottom=4241337.82548786, right=-13030067.337717425, top=4841521.371583064)"
+ ]
+ },
+ "execution_count": 8,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "pop.bounds"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 18,
+ "id": "8f895208-c4bc-4519-b0a2-be03efcc6440",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "(1963, 2494)"
+ ]
+ },
+ "execution_count": 18,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "band1.shape"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "936279a3-fcb6-4f09-b8c2-453accbb79cb",
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.9.13"
+ },
+ "widgets": {
+ "application/vnd.jupyter.widget-state+json": {
+ "state": {},
+ "version_major": 2,
+ "version_minor": 0
+ }
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/sb125_analyses/vmt_transit_sketch/README.md b/sb125_analyses/vmt_transit_sketch/README.md
new file mode 100644
index 000000000..9a6373a84
--- /dev/null
+++ b/sb125_analyses/vmt_transit_sketch/README.md
@@ -0,0 +1,9 @@
+# Notebook Order
+
+Will script-ify at some point. Notebooks use local paths for now but source data also available in GCS.
+
+* read_process_data (includes vmt reduction/transit increase assumption)
+* stops_by_tract (join warehouse stops/feeds to tracts)
+* ntd
+* regional_summary (compare with ntd data at uza level)
+* analyze_visualize (maps, other quick exercises)
\ No newline at end of file
diff --git a/sb125_analyses/vmt_transit_sketch/_utils.py b/sb125_analyses/vmt_transit_sketch/_utils.py
new file mode 100644
index 000000000..1a5a7f181
--- /dev/null
+++ b/sb125_analyses/vmt_transit_sketch/_utils.py
@@ -0,0 +1,13 @@
+import pygris
+import geopandas as gpd
+from siuba import *
+from shared_utils.geography_utils import CA_NAD83Albers
+
+GCS_PATH = 'gs://calitp-analytics-data/data-analyses/sb125/vmt_transit_sketch/'
+
+def get_tract_geoms():
+ ca_tracts = pygris.tracts(state='CA', year=2020)
+ ca_tracts = ca_tracts >> select(_.GEOID, _.geometry)
+ ca_tracts = ca_tracts.to_crs(CA_NAD83Albers)
+
+ return ca_tracts
\ No newline at end of file
diff --git a/sb125_analyses/vmt_transit_sketch/analyze_visualize.ipynb b/sb125_analyses/vmt_transit_sketch/analyze_visualize.ipynb
new file mode 100644
index 000000000..9a017b84e
--- /dev/null
+++ b/sb125_analyses/vmt_transit_sketch/analyze_visualize.ipynb
@@ -0,0 +1,690 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "9e8158c2-a7f9-4b3c-a518-037132adf0c3",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import pandas as pd\n",
+ "import geopandas as gpd\n",
+ "from siuba import *"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "81cddca7-bea4-494d-b0cb-02508d52b380",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import zipfile"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "15475e21-db2a-4f64-a2bc-38f2b76b9a4f",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "# ! pip install pygris"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "682268e8-78fc-4609-afc5-294f3c650b5e",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import _utils\n",
+ "import importlib\n",
+ "importlib.reload(_utils)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "019d1eaf-c3a7-4b71-a0b9-f9b041a04280",
+ "metadata": {},
+ "source": [
+ "# \"What if VMT decreased by 25% per the CARB target, and all those trips were on (existing) transit instead?\"\n",
+ "\n",
+ "## VMT is a spatial phenomenon, our analysis should be spatial too\n",
+ "\n",
+ "* Start with \"big data\" weekday residential VMT per Census tract via Replica\n",
+ "* Per target, future VMT should be 25% less\n",
+ "* Assume tripmaking remains constant, and that transit entirely replaces that VMT\n",
+ " * optional: find tracts with no transit service, hold their VMT constant and redistribute missed target among remaining tracts (30% reduction instead of 25% perhaps?)\n",
+ " \n",
+ "## From reduced VMT to transit trips\n",
+ "\n",
+ "* Replica gives transit trip lengths but it may not be reliable (\"good for auto, less so for transit\")\n",
+ " * It's generally showing the median transit trip as longer than the median auto trip, which seems questionable\n",
+ " * We have plenty of good spatial data on transit service _provision_, but not ridership (generally agency-level only)\n",
+ " * May need to refer to research/default to a fixed \"median transit trip\" length based on population density\n",
+ "* Regardless, get a rough estimate by dividing reduced VMT in each tract by median transit trip distance, or median auto trip if transit data not available"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "7f72b03d-f2b6-48ab-a4d0-cc9c6841b6c7",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "gdf = gpd.read_parquet('outputs/new_trips_with_uza.parquet')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "949de2fb-46b5-4fdc-9982-6f2a2968748e",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# filtered test\n",
+ "gdf = gdf >> filter(_.NAME10.str.contains('Seaside'))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "345b6bfd-f569-442f-9641-4f5f5dd4c40c",
+ "metadata": {},
+ "source": [
+ "## Mapping..."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "b84ee354-9bc8-4808-b89e-39de27d24b71",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "# gdf.explore(column = 'total_mi_transit', scheme = 'NaturalBreaks')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "2bde07bb-30d9-48b7-86ae-1055c15c4aac",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "gdf.explore(column = 'total_mi_auto', scheme = 'NaturalBreaks')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "76a258eb-cd26-4d2e-8e0c-8ac50c5c1449",
+ "metadata": {},
+ "source": [
+ "## New transit trips"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bc798bcd-ac53-4240-9246-ab18723fa09f",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def map_per_capita(gdf):\n",
+ " gdf = gdf >> filter(_.total_pop != 0) # remove tracts where nobody lives\n",
+ " return gdf.explore(column = 'new_trips_per_capita', scheme = 'NaturalBreaks')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "50a3c08a-30c7-45c5-89d7-4b90c71c3d6b",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "map_per_capita(gdf)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "8fb69137-fb4e-4140-9600-1155712585fc",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "gdf.explore(column = 'projected_new_transit_trips', scheme = 'NaturalBreaks')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "718a534e-e8f5-4a2f-8698-f87c298d7ba0",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "gdf.projected_new_transit_trips.sum()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "6b708ffd-6d83-45e3-86c1-39d30ec2f5a8",
+ "metadata": {
+ "tags": []
+ },
+ "source": [
+ "## Next Steps\n",
+ "\n",
+ "* caveat: other strategies (land use, active modes...)\n",
+ "* caveat: induced travel\n",
+ "* stratify into \"good transit, not riding\", \"bad transit\"\n",
+ "* LODES o/d data? Replica? -> Conveyal transit o/d find that \"good transit but not riding it\"\n",
+ " * find what doesn't show up in aggregate accessibility...\n",
+ "* https://walker-data.com/pygris/"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "e269a698-e8bf-4af7-a53c-45265ca7e5ad",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import shared_utils"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "684770aa-d035-45d3-a3a4-ada6c51c2692",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "analysis_date = '2023-04-15'"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "b1424118-5e7c-4e00-9eee-1630d251cb14",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "feeds = shared_utils.gtfs_utils_v2.schedule_daily_feed_to_gtfs_dataset_name(selected_date=analysis_date)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "5f958167-a291-4aba-8566-111c5e713be9",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "mst = feeds >> filter(_.name.str.contains('Monterey'))\n",
+ "mst"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "d68764b0-476a-4af8-8560-b931a8afba51",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "stops = shared_utils.gtfs_utils_v2.get_stops(analysis_date, mst.feed_key)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "3bbf4ee7-7bd2-4ae2-968b-b17a5ef2514d",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "stops.columns"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "f07ef246-b92d-4e00-989b-b1800744a694",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "trips = shared_utils.gtfs_utils_v2.get_trips(analysis_date, mst.feed_key)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "2fd8b773-d935-4c13-8f9e-84a8cba153c9",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "trips.columns"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "8fe0c258-f084-4030-94e6-b0a44f5f5498",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "trips.route_short_name.unique()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "a6763fd7-c9cc-44e1-b7e9-8c8c919e3f91",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "ab_trips = trips >> filter(_.route_short_name.isin(['A', 'B']), _.direction_id == 0)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "f9151728-3f87-45b0-a799-eb2b126ea434",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "trips_20 = trips >> filter(_.route_short_name == '20', _.direction_id == 0)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "44c2f67b-74b7-4551-82b9-167f2744081b",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "st_20 = shared_utils.gtfs_utils_v2.get_stop_times(analysis_date, mst.feed_key, trip_df=trips_20)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "fc5f463c-b3c6-4f80-86d4-9835c650eebb",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "st_20 = st_20 >> distinct(_.stop_id, _.stop_sequence) >> collect()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "23f3a7b3-cd32-480f-ab1f-cc616c02e77a",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "st_20 = stops >> select(_.stop_id, _.geometry) >> inner_join(_, st_20, on='stop_id')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "53cb95cd-7e8c-455d-ab47-fe3968582541",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def trips_to_stops(trip_df, feed_list):\n",
+ " st = shared_utils.gtfs_utils_v2.get_stop_times(analysis_date, feed_list, trip_df=trip_df)\n",
+ " st = st >> distinct(_.stop_id, _.stop_sequence) >> collect()\n",
+ " st = stops >> select(_.stop_id, _.geometry) >> inner_join(_, st, on='stop_id')\n",
+ " return st"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "8b71bbe9-26d0-42ec-8b30-a7cfdee2236e",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "st_20 = trips_to_stops(trips_20)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "99b2afea-3280-422c-b3b7-6e1c5ff54b5d",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# SURF BRT area for joins...\n",
+ "st_20 = st_20 >> filter(_.stop_sequence <= 27)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "c3da388c-807d-424b-9e69-51588401ef2a",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# st_20.explore()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "0bfacea0-f958-4a65-90f3-2fec0ab04fd6",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "st_ab = trips_to_stops(ab_trips)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "25ab4e55-c0cf-4919-b9ef-41e665c9a136",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# st_ab.explore()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "27a834eb-34b0-46a4-9f0d-75534812a336",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "surf_corridor = pd.concat([st_20, st_ab])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "72671c73-1331-4888-a6e4-5a8cc3a34a16",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "surf_corridor.explore()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "1ca1517e-876d-49ae-82c1-973e02116745",
+ "metadata": {},
+ "source": [
+ "## Wilshire"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "d52788d4-e9f1-4ddc-9687-01dcfc957bde",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "feeds = shared_utils.gtfs_utils_v2.schedule_daily_feed_to_gtfs_dataset_name(selected_date=analysis_date)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "ed2d3a3a-3473-4174-91b7-56c4e6759e9d",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "metro = feeds >> filter(_.name.str.contains('LA Metro Bus'))\n",
+ "metro"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "030ebc15-6824-47a6-b781-11628b74d848",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "stops = shared_utils.gtfs_utils_v2.get_stops(analysis_date, metro.feed_key)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "c1e324d3-7891-40f2-bd7b-2389fa36ee26",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "trips = shared_utils.gtfs_utils_v2.get_trips(analysis_date, metro.feed_key)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "384bc785-79ed-4ca8-be5d-14a0480e98cf",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "trips.route_short_name.unique()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "1b6fde5e-1394-4350-b483-1c1e6ad1dabb",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "trips_720 = trips >> filter(_.route_short_name.isin(['720']), _.direction_id == 0)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "fed54ea9-8157-425a-889a-1069d77265ca",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "st_720 = trips_to_stops(trips_720, metro.feed_key)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "38b16a39-5d16-45bd-a9e4-71c22cacdb7f",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# only keep W of Wil/Wstn\n",
+ "st_720 = st_720 >> filter(_.stop_sequence <= 11)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "3e04bc76-99c8-4930-a754-fc4c2c0f3597",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "st_720.explore()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "c5d6a929-e7e4-4074-9467-2e7aaed57ddb",
+ "metadata": {},
+ "source": [
+ "## Sjoin and calculate"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "123fa697-8a27-4572-b144-66e0f9d6df25",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "gdf = gpd.read_parquet('outputs/new_trips_with_uza.parquet')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "a3551c17-c263-41b6-9f81-632afc134988",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "surf_corridor = surf_corridor.to_crs(shared_utils.geography_utils.CA_NAD83Albers)\n",
+ "st_720 = st_720.to_crs(shared_utils.geography_utils.CA_NAD83Albers)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "2e3caf3a-42b1-4520-be55-1f5c59655607",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# half-mile buffer stop areas, corridors should be broader...\n",
+ "surf_corridor.geometry = surf_corridor.buffer(804) \n",
+ "st_720.geometry = st_720.buffer(804)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "52860ef0-afdf-478a-98c8-6a2eed4d44f1",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "gdf = gdf >> select(-_.index_left, -_.index_right)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "1e6c6cbc-c388-43c3-8340-25d7b1519152",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "surf = gpd.sjoin(gdf, surf_corridor) >> distinct(_.GEOID, _keep_all=True)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "884d4536-874d-432b-8e0e-fbe71c9160fb",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "surf.explore(column = 'projected_new_transit_trips', scheme = 'NaturalBreaks')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "8821c382-1d27-4dd3-994b-6d73e9b384b1",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "wilshire = gpd.sjoin(gdf, st_720) >> distinct(_.GEOID, _keep_all=True)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "b6541ddd-66b0-4462-abc0-d9542bf1e082",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "wilshire.explore(column = 'projected_new_transit_trips', scheme = 'NaturalBreaks')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "4088fd65-a36c-4a54-a859-4bb954c5ce4c",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "surf.describe()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "a2169877-c50e-48f1-9729-7d37a7841e85",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "wilshire.describe()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "00959a08-aa6f-4a64-8f38-f90636a84d8a",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "surf.sum()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "481d4803-9e48-4cee-9fe9-181e3caa33f9",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "wilshire.sum()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "b693889c-093a-46b4-8160-1c58f5512551",
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.9.13"
+ },
+ "widgets": {
+ "application/vnd.jupyter.widget-state+json": {
+ "state": {},
+ "version_major": 2,
+ "version_minor": 0
+ }
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/sb125_analyses/vmt_transit_sketch/ntd.ipynb b/sb125_analyses/vmt_transit_sketch/ntd.ipynb
new file mode 100644
index 000000000..4944269f4
--- /dev/null
+++ b/sb125_analyses/vmt_transit_sketch/ntd.ipynb
@@ -0,0 +1,448 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "58257aa9-ddca-49c4-81fb-a764cf200207",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import pandas as pd\n",
+ "from siuba import *"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "790725e8-0a30-4fa6-b194-f67c5254189f",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import sys\n",
+ "sys.path.append('../../ntd/')\n",
+ "from update_vars import GCS_FILE_PATH, PUBLIC_FILENAME, YEAR, MONTH"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "4e894afc-083a-45b1-b6c5-b7cd27321a66",
+ "metadata": {},
+ "source": [
+ "## Read NTD using Tiffany's functions from `ntd/`"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "5b919f13-c18f-4e39-a92d-559b0fe64f5f",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "df = pd.read_parquet(\n",
+ " f\"{GCS_FILE_PATH}ca_monthly_ridership_{YEAR}_{MONTH}.parquet\"\n",
+ ").drop(\n",
+ " columns = [\"Mode\", \"TOS\"]\n",
+ ").rename(columns = {\"Mode_full\": \"Mode\", \"TOS_full\": \"TOS\"})"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "dba7857e-9853-421c-8400-22502b7d252d",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# find columns that are recent enough to plot\n",
+ "MIN_YEAR = 2018\n",
+ "\n",
+ "not_id_cols = [c for c in df.columns if \"/\" in c]\n",
+ "\n",
+ "recent_years = [\n",
+ " c for c in not_id_cols if int(c.split(\"/\")[1]) >= MIN_YEAR and \n",
+ " \"pct\" not in c\n",
+ "]\n",
+ "\n",
+ "upt_cols = [\n",
+ " c for c in recent_years if \"change\" not in c\n",
+ "]\n",
+ "\n",
+ "change_cols = [c for c in recent_years if \"change\" in c]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "0a0751e2-c696-4306-9c91-c8f0a65c6062",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def sum_by_group(df: pd.DataFrame, group_cols: list) -> pd.DataFrame:\n",
+ " \"\"\"\n",
+ " Since df is wide, use pivot_table() to sum up all\n",
+ " the columns that show UPT.\n",
+ " \"\"\"\n",
+ " grouped_df = df.pivot_table(\n",
+ " index = group_cols, \n",
+ " values = recent_years, \n",
+ " aggfunc=\"sum\"\n",
+ " ).reset_index().reindex(columns = group_cols + recent_years)\n",
+ " \n",
+ " return grouped_df\n",
+ "\n",
+ "def make_long(df: pd.DataFrame, group_cols: list, value_cols: list):\n",
+ " df_long = df[group_cols + value_cols].melt(\n",
+ " id_vars = group_cols, \n",
+ " value_vars = value_cols,\n",
+ " )\n",
+ " \n",
+ " df_long = df_long.assign(\n",
+ " variable = df_long.variable.str.replace(\"change_1yr_\", \"\")\n",
+ " )\n",
+ " \n",
+ " return df_long"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "9383fd25-bad7-44e7-ba45-59ca81572a49",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "agency_cols = [\"NTD ID\", \"Agency\", \"RTPA\"]\n",
+ "mode_cols = [\"Mode\", \"RTPA\"]\n",
+ "tos_cols = [\"TOS\", \"RTPA\"]\n",
+ "\n",
+ "by_agency = sum_by_group(df, agency_cols)\n",
+ "by_mode = sum_by_group(df, mode_cols)\n",
+ "by_tos = sum_by_group(df, tos_cols)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "0e57f73a-267d-4b99-92c2-bae890422111",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "by_agency.columns"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "6e155b61-0e74-4b11-aab7-50dc1985fbc3",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "sep_agency = by_agency[['NTD ID', 'Agency', 'RTPA', '9/2023']].rename(columns={'9/2023': 'upt_sep_2023'})"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "5defec1d-4ad7-40c4-bd18-4b423b6f5766",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "sep_agency >> head(3)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "da16ba16-4251-41ec-bc2c-05d56dec9b99",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from calitp_data_analysis.tables import tbls"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "e5eb26a3-c5c2-4dac-a333-3f7fc30a527e",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "ntd_organziations = (tbls.mart_transit_database.dim_organizations()\n",
+ " >> filter(_._is_current)\n",
+ " >> select(_.source_record_id, _.name, _.ntd_id)\n",
+ " >> collect()\n",
+ " )"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "3bc30f47-e89d-42a1-9036-492a86fccd3a",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "ntd_organziations = ntd_organziations >> inner_join(_, sep_agency, on = {'ntd_id': 'NTD ID'})"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "d937ab43-b631-4110-8351-4916e4fe3dc3",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "ntd_organziations >> head(3)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "2beb0ac9-7b96-4cac-a23f-ccbc1f5e85ac",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "service = pd.read_excel('./2022 Service.xlsx')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "970b138a-f0f3-4aa1-af61-85c51c571b17",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from calitp_data_analysis.sql import to_snakecase"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "74fc111a-a528-411c-aa6e-b2d23e50db51",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "service = to_snakecase(service)\n",
+ "service = service >> filter(_.time_period == 'Average Typical Weekday')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "ca379b13-e38c-406d-87da-e597eb82f8b6",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "service.columns"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "fd77a899-e835-40f5-8983-1e1f61d49f3c",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "service_grouped = service >> group_by('ntd_id') >> summarize(weekday_vrh = _.actual_vehicle_passenger_car_revenue_hours.sum(),\n",
+ " weekday_vrm = _.actual_vehicles_passenger_car_revenue_miles.sum())"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "94eb705e-8aeb-4f1d-bd0d-1b9730fb958f",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "service_grouped.dtypes"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "cf5a3101-9137-4ee2-b58d-f2e2638bc3cc",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "service_grouped.ntd_id = service_grouped.ntd_id.astype(str)\n",
+ "service_grouped.ntd_id = service_grouped.ntd_id.str.zfill(5)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "abdc16ec-e940-49a8-9c12-bb12b119745d",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "ntd_organziations['weekday_ridership'] = ntd_organziations.upt_sep_2023 // 21 # rough estimate"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "aa37246b-0181-427e-915e-8323cd810c59",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "with_service = ntd_organziations >> inner_join(_, service_grouped, on = 'ntd_id')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "ddcf9b25-b77c-4d56-af3b-51a5f370f833",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "with_service"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "1fd53ccf-7378-47d3-8d34-5723aed62202",
+ "metadata": {},
+ "source": [
+ "## add uza"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "51b89b92-c18c-4e73-9d9a-5c47bc9e74c4",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "info = pd.read_excel('2022 Agency Information.xlsx')\n",
+ "info = to_snakecase(info)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "e9afc41f-7bb1-487b-912e-e2ffc8dfdff8",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "info.columns"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "5dd8c457-d6e7-4673-96eb-5fbdd49009f3",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "info = info >> filter(_.state == 'CA') >> select(_.ntd_id, _.agency_name, _.primary_uza_uace_code,\n",
+ " _.uza_name)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "668cc6ad-29e8-42ec-ad6c-532f5a7f5be4",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "info"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "f56d8ef4-336c-4216-bfbc-caf4e0c31644",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "info.ntd_id = info.ntd_id.astype(str)\n",
+ "info.ntd_id = info.ntd_id.str.zfill(5)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "c9a53d84-6e4f-4e31-9b9b-d0e3c693f29c",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "with_info = with_service >> inner_join(_, info, on = 'ntd_id')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "99445321-3705-4e7f-b37d-a2f04d7aea03",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "uza_totals = with_info >> group_by(_.primary_uza_uace_code, _.uza_name) >> summarize(uza_ridership = _.weekday_ridership.sum())"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "c932c9de-ffe5-41e3-8e07-9de441897554",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "market_shares = (with_info >> inner_join(_, uza_totals, on = ['uza_name', 'primary_uza_uace_code'])\n",
+ " >> mutate(uza_share = _.weekday_ridership / _.uza_ridership)\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "508230aa-8a15-4db5-8697-a4acddf647c4",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "market_shares >> filter(_.uza_name.str.contains('Los Angeles')) >> arrange(-_.uza_share)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "742309f4-1f1a-458f-9edc-413f23b021d0",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "market_shares.to_parquet('intermediate/draft_ntd_market_shares.parquet')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "d6e7436e-0b8a-4673-8a90-b1fabb27b936",
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.9.13"
+ },
+ "widgets": {
+ "application/vnd.jupyter.widget-state+json": {
+ "state": {},
+ "version_major": 2,
+ "version_minor": 0
+ }
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/sb125_analyses/vmt_transit_sketch/read_process_data.ipynb b/sb125_analyses/vmt_transit_sketch/read_process_data.ipynb
new file mode 100644
index 000000000..c04a89e70
--- /dev/null
+++ b/sb125_analyses/vmt_transit_sketch/read_process_data.ipynb
@@ -0,0 +1,1097 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "9e8158c2-a7f9-4b3c-a518-037132adf0c3",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import pandas as pd\n",
+ "import geopandas as gpd\n",
+ "from siuba import *"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "81cddca7-bea4-494d-b0cb-02508d52b380",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import zipfile"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "b076a21f-5a53-4b75-b140-0e4947099e42",
+ "metadata": {
+ "tags": []
+ },
+ "source": [
+ "# Read and group Replica data"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "85a89737-f90d-488f-9310-ca83557e476c",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def read_group_replica(zip_path):\n",
+ " '''\n",
+ " zip_path: path to zip file containing a Replica trips export\n",
+ " '''\n",
+ " replica_filename = 'replica-mode_split_test-02_01_24-trips_dataset.csv'\n",
+ " with zipfile.ZipFile(zip_path) as z:\n",
+ " with z.open(replica_filename) as f:\n",
+ " df = pd.read_csv(f)\n",
+ " df = (df >> filter(_.primary_mode.isin(['private_auto', 'auto_passenger', 'on_demand_auto', 'public_transit']))\n",
+ " >> select(-_.origin_trct_2020, -_.activity_id)\n",
+ " )\n",
+ " df['is_auto'] = df.primary_mode.str.contains('auto')\n",
+ " grouped = (df >> group_by(_.origin_trct_fips_2020, _.is_auto)\n",
+ " >> summarize(n = _.shape[0], p50_distance = _.trip_distance_miles.quantile(.5),\n",
+ " p75_distance = _.trip_distance_miles.quantile(.75),\n",
+ " p90_distance = _.trip_distance_miles.quantile(.9),\n",
+ " total_miles = _.trip_distance_miles.sum(),\n",
+ " )\n",
+ " )\n",
+ " # parquet_path = f'./intermediate/{zip_path.split(\".zip\")[0]}.parquet'\n",
+ " # grouped.to_parquet(parquet_path)\n",
+ " # print(f'grouped data -> {parquet_path}')\n",
+ " return grouped"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "ec3470ac-5f0e-49a0-9000-f371f952bc74",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "zip_path = f'replica_raw/replica-la_north-trips_dataset.zip'"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "id": "868a0ae4-b076-4775-beba-fdc9ba764b27",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "replica_filename = 'replica-mode_split_test-02_01_24-trips_dataset.csv'"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "id": "b4c08637-9bbc-4727-af6d-14dc1c66b4a1",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "/tmp/ipykernel_472/3605967939.py:3: DtypeWarning: Columns (6,7,8) have mixed types. Specify dtype option on import or set low_memory=False.\n",
+ " df = pd.read_csv(f)\n"
+ ]
+ }
+ ],
+ "source": [
+ "with zipfile.ZipFile(zip_path) as z:\n",
+ " with z.open(replica_filename) as f:\n",
+ " df = pd.read_csv(f)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "id": "5875f7f5-2c1f-40f6-95fa-0a8d106b1e7a",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "miles_all = df.trip_distance_miles.sum()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 13,
+ "id": "01a823a1-de52-4d08-8b80-a024c1397f95",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "shorter = (df >> filter(_.trip_distance_miles < _.trip_distance_miles.quantile(.95))).trip_distance_miles.sum()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 14,
+ "id": "132b4a03-9f73-4978-8a35-ae5c130f7f73",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "0.5640656816072517"
+ ]
+ },
+ "execution_count": 14,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "shorter / miles_all"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "6c80cc92-a452-4d92-bf2f-d1f40a83442d",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# zip_path = 'replica-la_north-trips_dataset.zip'\n",
+ "\n",
+ "# replica_filename = 'replica-mode_split_test-02_01_24-trips_dataset.csv'\n",
+ "# with zipfile.ZipFile(zip_path) as z:\n",
+ "# with z.open(replica_filename) as f:\n",
+ "# df = pd.read_csv(f)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "id": "0b50f321-feee-4789-8f17-eee4f4a59f3f",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# df >> head(10)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "id": "dae2c9bb-5121-4966-85ed-111bd525c924",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "all_regions = ['central_a', 'central_b', 'north', 'la_north',\n",
+ " 'la_south', 'sandiego', 'socal_a', 'socal_b']"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "id": "9fb929ae-0c66-4dfb-9a0e-604bfedef078",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "central_a\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "/tmp/ipykernel_444/3995037246.py:8: DtypeWarning: Columns (6,7,8) have mixed types. Specify dtype option on import or set low_memory=False.\n",
+ " df = pd.read_csv(f)\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "central_b\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "/tmp/ipykernel_444/3995037246.py:8: DtypeWarning: Columns (6,7,8) have mixed types. Specify dtype option on import or set low_memory=False.\n",
+ " df = pd.read_csv(f)\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "north\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "/tmp/ipykernel_444/3995037246.py:8: DtypeWarning: Columns (6,7,8) have mixed types. Specify dtype option on import or set low_memory=False.\n",
+ " df = pd.read_csv(f)\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "la_north\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "/tmp/ipykernel_444/3995037246.py:8: DtypeWarning: Columns (6,7,8) have mixed types. Specify dtype option on import or set low_memory=False.\n",
+ " df = pd.read_csv(f)\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "la_south\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "/tmp/ipykernel_444/3995037246.py:8: DtypeWarning: Columns (6,7,8) have mixed types. Specify dtype option on import or set low_memory=False.\n",
+ " df = pd.read_csv(f)\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "sandiego\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "/tmp/ipykernel_444/3995037246.py:8: DtypeWarning: Columns (6,7,8) have mixed types. Specify dtype option on import or set low_memory=False.\n",
+ " df = pd.read_csv(f)\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "socal_a\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "/tmp/ipykernel_444/3995037246.py:8: DtypeWarning: Columns (6,7,8) have mixed types. Specify dtype option on import or set low_memory=False.\n",
+ " df = pd.read_csv(f)\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "socal_b\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "/tmp/ipykernel_444/3995037246.py:8: DtypeWarning: Columns (6,7,8) have mixed types. Specify dtype option on import or set low_memory=False.\n",
+ " df = pd.read_csv(f)\n"
+ ]
+ }
+ ],
+ "source": [
+ "grouped = pd.DataFrame()\n",
+ "for region in all_regions:\n",
+ " print(region)\n",
+ " df = read_group_replica(f'replica_raw/replica-{region}-trips_dataset.zip')\n",
+ " grouped = pd.concat([grouped, df])\n",
+ "\n",
+ "grouped.to_parquet('intermediate/replica_grouped.parquet')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "6e86832b-46f0-4977-96c2-7ca458dcfd89",
+ "metadata": {},
+ "source": [
+ "# Read back in grouped data\n",
+ "\n",
+ "* number of trips, median distance, and total miles travelled by auto yes/no and Census tract"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "id": "240ddd8f-6a36-44e1-a1c0-32e6f50c3cac",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# grouped = pd.DataFrame()\n",
+ "# for region in all_regions:\n",
+ "# grouped = pd.concat([grouped, pd.read_parquet(f'intermediate/replica-{region}-trips_dataset.parquet')])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 33,
+ "id": "7596b001-2c1c-488f-b089-c375c0ddff4f",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "replica_grouped = pd.read_parquet('intermediate/replica_grouped.parquet')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 34,
+ "id": "23b9ae5b-bd02-4978-b7d1-3e4b49de53b5",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "tracts_feeds = gpd.read_parquet('intermediate/feeds_tract_geo.parquet')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 35,
+ "id": "73088513-9710-4c9a-a205-d531c3807345",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "tracts_feeds.GEOID = tracts_feeds.GEOID.astype('int64')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 36,
+ "id": "61ce4f74-45e9-4c85-ad34-d2ac9c5cfc32",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "tracts_feeds = tracts_feeds >> distinct(_.GEOID, _.geometry)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 37,
+ "id": "06f007da-ad8d-4801-8595-85c5d44fe921",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def process_grouped_data(replica_df, tracts_feeds_df):\n",
+ " '''\n",
+ " replica_df: df from read_group_replica\n",
+ " tracts_feeds_df: gdf from stops_by_tract_agency\n",
+ " '''\n",
+ " replica_df.is_auto = replica_df.is_auto.map(lambda x: 'yes' if x else 'no')\n",
+ " \n",
+ " df2 = replica_df >> spread('is_auto', 'p50_distance') >> select(-_.n, -_.total_miles)\n",
+ " df2 = df2.rename(columns={'no': 'p50_mi_transit', 'yes': 'p50_mi_auto'})\n",
+ " \n",
+ " df3 = replica_df >> spread('is_auto', 'total_miles') >> select(-_.p50_distance, -_.n)\n",
+ " df3 = df3.rename(columns={'no': 'total_mi_transit', 'yes': 'total_mi_auto'})\n",
+ " \n",
+ " df2 = df2 >> inner_join(_, df3, on = 'origin_trct_fips_2020')\n",
+ " \n",
+ " df2 = (df2 >> group_by(_.origin_trct_fips_2020)\n",
+ " >> summarize(p50_mi_transit = _.p50_mi_transit.max(), p50_mi_auto = _.p50_mi_auto.max(),\n",
+ " total_mi_transit = _.total_mi_transit.max(),\n",
+ " total_mi_auto = _.total_mi_auto.max()\n",
+ " )\n",
+ " )\n",
+ " \n",
+ " df2['p50_transit_longer'] = df2['p50_mi_transit'] > df2['p50_mi_auto']\n",
+ " # df2['total_transit_higher'] = df2['total_mi_transit'] > df2['total_mi_auto'] # useless\n",
+ " tracts_with_stops = tracts_feeds_df.GEOID\n",
+ " df2['no_transit_replica'] = df2.total_mi_transit.isna()\n",
+ " df2['no_transit'] = ~df2.origin_trct_fips_2020.isin(tracts_with_stops)\n",
+ " df2['total_mi'] = df2.total_mi_transit + df2.total_mi_auto\n",
+ " no_transit = df2 >> group_by(_.no_transit) >> summarize(total_mi_auto = _.total_mi_auto.sum())\n",
+ " total_reduction = df2.total_mi_auto.sum() * .25 # CARB 25% VMT Decrease\n",
+ " \n",
+ " # rescaling after no transit tracts\n",
+ " actual_reduction = total_reduction / no_transit.iloc[0, 1]\n",
+ " print(actual_reduction)\n",
+ " df2.p50_mi_transit = df2.p50_mi_transit.fillna(df2.p50_mi_auto)\n",
+ " df2['new_transit_mi'] = df2.total_mi_auto * actual_reduction\n",
+ " df2['projected_new_transit_trips'] = df2.new_transit_mi // df2.p50_mi_transit\n",
+ " \n",
+ " return df2"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 38,
+ "id": "d661657b-cac7-4e9a-806d-48579c0516f9",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "0.2778337212327877\n"
+ ]
+ }
+ ],
+ "source": [
+ "df2 = process_grouped_data(replica_grouped, tracts_feeds)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 39,
+ "id": "50f04f86-6f13-4654-952e-58dc07a23faa",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " origin_trct_fips_2020 \n",
+ " p50_mi_transit \n",
+ " p50_mi_auto \n",
+ " total_mi_transit \n",
+ " total_mi_auto \n",
+ " p50_transit_longer \n",
+ " no_transit_replica \n",
+ " no_transit \n",
+ " total_mi \n",
+ " new_transit_mi \n",
+ " projected_new_transit_trips \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 \n",
+ " 6001400100 \n",
+ " 4.2 \n",
+ " 6.9 \n",
+ " 5185.3 \n",
+ " 165410.8 \n",
+ " False \n",
+ " False \n",
+ " False \n",
+ " 170596.1 \n",
+ " 45956.698096 \n",
+ " 10942.0 \n",
+ " \n",
+ " \n",
+ " 1 \n",
+ " 6001400200 \n",
+ " 4.1 \n",
+ " 3.4 \n",
+ " 3638.1 \n",
+ " 58763.4 \n",
+ " True \n",
+ " False \n",
+ " False \n",
+ " 62401.5 \n",
+ " 16326.454094 \n",
+ " 3982.0 \n",
+ " \n",
+ " \n",
+ " 2 \n",
+ " 6001400300 \n",
+ " 4.7 \n",
+ " 3.7 \n",
+ " 6130.7 \n",
+ " 122736.5 \n",
+ " True \n",
+ " False \n",
+ " False \n",
+ " 128867.2 \n",
+ " 34100.338526 \n",
+ " 7255.0 \n",
+ " \n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " origin_trct_fips_2020 p50_mi_transit p50_mi_auto total_mi_transit \\\n",
+ "0 6001400100 4.2 6.9 5185.3 \n",
+ "1 6001400200 4.1 3.4 3638.1 \n",
+ "2 6001400300 4.7 3.7 6130.7 \n",
+ "\n",
+ " total_mi_auto p50_transit_longer no_transit_replica no_transit \\\n",
+ "0 165410.8 False False False \n",
+ "1 58763.4 True False False \n",
+ "2 122736.5 True False False \n",
+ "\n",
+ " total_mi new_transit_mi projected_new_transit_trips \n",
+ "0 170596.1 45956.698096 10942.0 \n",
+ "1 62401.5 16326.454094 3982.0 \n",
+ "2 128867.2 34100.338526 7255.0 "
+ ]
+ },
+ "execution_count": 39,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "df2 >> head(3)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 40,
+ "id": "8169ca83-e540-48f4-af93-076a535f00c6",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " no_transit \n",
+ " total_mi_auto \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 \n",
+ " False \n",
+ " 1.162508e+09 \n",
+ " \n",
+ " \n",
+ " 1 \n",
+ " True \n",
+ " 1.294277e+08 \n",
+ " \n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " no_transit total_mi_auto\n",
+ "0 False 1.162508e+09\n",
+ "1 True 1.294277e+08"
+ ]
+ },
+ "execution_count": 40,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "no_transit = df2 >> group_by(_.no_transit) >> summarize(total_mi_auto = _.total_mi_auto.sum())\n",
+ "no_transit"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 41,
+ "id": "c7175031-a66c-4f90-8dca-193198b9d932",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'11.0 percent of VMT in tracts with no transit per GTFS Warehouse stops'"
+ ]
+ },
+ "execution_count": 41,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "no_transit_pct = no_transit.iloc[1, 1] / no_transit.iloc[0, 1]\n",
+ "f'{round(no_transit_pct*100, 0)} percent of VMT in tracts with no transit per GTFS Warehouse stops'"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 42,
+ "id": "6476da44-36ac-4604-89d5-76966eb9411d",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True 6571\n",
+ "False 2534\n",
+ "Name: p50_transit_longer, dtype: int64"
+ ]
+ },
+ "execution_count": 42,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "df2.p50_transit_longer.value_counts()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 43,
+ "id": "682268e8-78fc-4609-afc5-294f3c650b5e",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ ""
+ ]
+ },
+ "execution_count": 43,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "import _utils\n",
+ "import importlib\n",
+ "importlib.reload(_utils)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 44,
+ "id": "e83400ec-c295-40b3-91d6-3c3bd1ffb5f4",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Using FIPS code '06' for input 'CA'\n"
+ ]
+ }
+ ],
+ "source": [
+ "tract_geo = _utils.get_tract_geoms()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 45,
+ "id": "76766b3c-efc1-4ad7-9d47-3f465c616abf",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# tract_geo = gpd.read_file('./tl_2020_06_tract.zip') >> select(_.GEOID, _.geometry)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 46,
+ "id": "876be135-baf9-41bb-880f-22cf9df2c4a9",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "tract_geo.GEOID = tract_geo.GEOID.astype('int64')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 47,
+ "id": "03ecd820-d9e5-4c08-82ae-0929638e3af4",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "gdf = tract_geo >> inner_join(_, df2, on = {'GEOID': 'origin_trct_fips_2020'}) >> select(-_.origin_trct_fips_2020)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 48,
+ "id": "3a830524-3c8f-4915-8768-3062ddbf7db0",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "ca_uzas = gpd.read_parquet('intermediate/ca_uza.parquet')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 49,
+ "id": "d00b301f-ec03-4525-b415-53f9f65a77c2",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "uza_joined = gpd.sjoin(gdf, ca_uzas, how = 'left')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 50,
+ "id": "4cb23dd6-94b8-4b36-952b-054a06c04192",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# TODO to util, other source?\n",
+ "\n",
+ "census_pop = gpd.read_file('census_ntd/DECENNIALPL2020.P1_2024-02-01T163251.zip')\n",
+ "\n",
+ "tract_pop = census_pop[['GEO_ID', 'P1_001N']].iloc[2:,:]\n",
+ "\n",
+ "tract_pop.GEO_ID = tract_pop.GEO_ID.map(lambda x: x.split('US')[1])\n",
+ "\n",
+ "tract_pop.GEO_ID = tract_pop.GEO_ID.astype('int64')\n",
+ "\n",
+ "tract_pop = tract_pop >> select(_.total_pop == _.P1_001N, _.GEOID == _.GEO_ID)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 51,
+ "id": "31623fcf-efd7-4863-8f12-71a04ac45410",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "uza_joined = uza_joined >> inner_join(_, tract_pop, on = 'GEOID')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 52,
+ "id": "fb733ab6-007a-4747-91dd-ec40688a066f",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "uza_joined.total_pop = uza_joined.total_pop.astype('int64')\n",
+ "uza_joined['new_trips_per_capita'] = uza_joined.projected_new_transit_trips / uza_joined.total_pop"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 53,
+ "id": "addb6ac5-5f4d-41dc-9a7a-0d6644bb699c",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "uza_joined.to_parquet('outputs/new_trips_with_uza.parquet')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 34,
+ "id": "666ebaa0-7d29-4f56-a3fd-5ad7391b15c8",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# uza_joined = uza_joined >> filter(_.P1_001N != 0) # remove tracts where nobody lives"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "019d1eaf-c3a7-4b71-a0b9-f9b041a04280",
+ "metadata": {},
+ "source": [
+ "# \"What if VMT decreased by 25% per the CARB target, and all those trips were on (existing) transit instead?\"\n",
+ "\n",
+ "## VMT is a spatial phenomenon, our analysis should be spatial too\n",
+ "\n",
+ "* Start with \"big data\" weekday residential VMT per Census tract via Replica\n",
+ "* Per target, future VMT should be 25% less\n",
+ "* Assume tripmaking remains constant, and that transit entirely replaces that VMT\n",
+ " * optional: find tracts with no transit service, hold their VMT constant and redistribute missed target among remaining tracts (30% reduction instead of 25% perhaps?)\n",
+ " \n",
+ "## From reduced VMT to transit trips\n",
+ "\n",
+ "* Replica gives transit trip lengths but it may not be reliable (\"good for auto, less so for transit\")\n",
+ " * It's generally showing the median transit trip as longer than the median auto trip, which seems questionable\n",
+ " * We have plenty of good spatial data on transit service _provision_, but not ridership (generally agency-level only)\n",
+ " * May need to refer to research/default to a fixed \"median transit trip\" length based on population density\n",
+ "* Regardless, get a rough estimate by dividing reduced VMT in each tract by median transit trip distance\n",
+ "* Reality check using derived modeshare number?\n",
+ "\n",
+ "## Connecting our estimate to California's transit provider landscape\n",
+ "\n",
+ "* Proportionally assign new trips per census tract to transit operators\n",
+ " * ~By number of stops in tract? OK for bus but will dramatically undercount rail~\n",
+ " * By each operator's proportion of regional ridership (from NTD)? Will overcount in tracts on the edge of large operator service areas, but perhaps preferable\n",
+ "* Can then create operator-level estimates of increased ridership and service hour provision\n",
+ " * This is where we have the best estimates of existing ridership..."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "id": "2db21010-14d2-47d1-b8be-9fd270cca949",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import geopandas as gpd"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "345b6bfd-f569-442f-9641-4f5f5dd4c40c",
+ "metadata": {},
+ "source": [
+ "## Mapping..."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "b84ee354-9bc8-4808-b89e-39de27d24b71",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "gdf.explore(column = 'total_mi_transit', scheme = 'NaturalBreaks')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "2bde07bb-30d9-48b7-86ae-1055c15c4aac",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "gdf.explore(column = 'total_mi_auto', scheme = 'NaturalBreaks')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "0a9c55c5-b17e-4e4f-b0ec-198d2cd89b14",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "(gdf >> filter(_.no_transit)).explore()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "76a258eb-cd26-4d2e-8e0c-8ac50c5c1449",
+ "metadata": {},
+ "source": [
+ "## New transit trips"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "ea9768db-f59e-4d73-a21c-c903736b4421",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# gdf.explore(column = 'new_transit_mi', scheme = 'NaturalBreaks')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "a6d4647f-d6a3-4935-ab1f-613738ffecc5",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "gdf = gdf >> filter(_.new_trips_per_capita < _.new_trips_per_capita.quantile(.99))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "d560c555-ced9-43e5-bfb7-923a2c6a65ca",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "gdf.explore(column = 'new_trips_per_capita', scheme = 'Quantiles')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "8fb69137-fb4e-4140-9600-1155712585fc",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "gdf.explore(column = 'projected_new_transit_trips', scheme = 'NaturalBreaks')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 32,
+ "id": "718a534e-e8f5-4a2f-8698-f87c298d7ba0",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "17797968.0"
+ ]
+ },
+ "execution_count": 32,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "gdf.projected_new_transit_trips.sum()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "db1e79d4-2958-4483-bee9-7ea58ecd4406",
+ "metadata": {},
+ "source": [
+ "About 18 million new daily trips across LA/Orange/San Diego/Imperial Counties. For reference, LA Metro's daily ridership is around 1 million. Current regional transit modeshare is only about 5%..."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "6b708ffd-6d83-45e3-86c1-39d30ec2f5a8",
+ "metadata": {},
+ "source": [
+ "## Next Steps\n",
+ "\n",
+ "* caveat: other strategies (land use, active modes...)\n",
+ "* caveat: induced travel\n",
+ "* stratify into \"good transit, not riding\", \"bad transit\"\n",
+ "* LODES o/d data? Replica? -> Conveyal transit o/d find that \"good transit but not riding it\"\n",
+ " * find what doesn't show up in aggregate accessibility...\n",
+ "* https://walker-data.com/pygris/"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 99,
+ "id": "37b679d4-f8bd-4450-bf9f-50b68e8570b4",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from calitp_data_analysis import get_fs"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 100,
+ "id": "b0572b17-a9c2-4128-ab67-fa650c87fda0",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "fs = get_fs()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 102,
+ "id": "76539b31-f757-4703-9f7a-2eea60834d06",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'gs://calitp-analytics-data/data-analyses/sb125/vmt_transit_sketch/'"
+ ]
+ },
+ "execution_count": 102,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "_utils.GCS_PATH"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 111,
+ "id": "1518eea5-d2f1-4807-b392-4a4f2624439d",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "lpath = 'replica_raw/'"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 112,
+ "id": "e0048f15-f124-431d-9fae-35aa7ef3dd72",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[None, None, None, None, None, None, None, None, None, None]"
+ ]
+ },
+ "execution_count": 112,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "fs.put(lpath, _utils.GCS_PATH + lpath, recursive=True)"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.9.13"
+ },
+ "widgets": {
+ "application/vnd.jupyter.widget-state+json": {
+ "state": {},
+ "version_major": 2,
+ "version_minor": 0
+ }
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/sb125_analyses/vmt_transit_sketch/regional_summary.ipynb b/sb125_analyses/vmt_transit_sketch/regional_summary.ipynb
new file mode 100644
index 000000000..fa267572c
--- /dev/null
+++ b/sb125_analyses/vmt_transit_sketch/regional_summary.ipynb
@@ -0,0 +1,1809 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "a805b1ae-1091-4990-a0fe-096279f4a23d",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import pandas as pd\n",
+ "import geopandas as gpd\n",
+ "from siuba import *"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "36fd455f-9284-4ce8-9fce-d898f75081e7",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "results = gpd.read_parquet('outputs/new_trips_with_uza.parquet')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "f438eb7b-e94c-45d9-8e8d-9e47c615bd67",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " GEOID \n",
+ " geometry \n",
+ " p50_mi_transit \n",
+ " p50_mi_auto \n",
+ " total_mi_transit \n",
+ " total_mi_auto \n",
+ " p50_transit_longer \n",
+ " no_transit_replica \n",
+ " no_transit \n",
+ " total_mi \n",
+ " new_transit_mi \n",
+ " projected_new_transit_trips \n",
+ " index_right \n",
+ " UACE10 \n",
+ " NAME10 \n",
+ " total_pop \n",
+ " new_trips_per_capita \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 \n",
+ " 6029004402 \n",
+ " POLYGON ((59906.842 -270407.558, 59906.948 -27... \n",
+ " 42.2 \n",
+ " 1.7 \n",
+ " 84.4 \n",
+ " 148755.4 \n",
+ " True \n",
+ " False \n",
+ " False \n",
+ " 148839.8 \n",
+ " 41329.266335 \n",
+ " 979.0 \n",
+ " 2554.0 \n",
+ " 92161 \n",
+ " Wasco, CA \n",
+ " 4027 \n",
+ " 0.243109 \n",
+ " \n",
+ " \n",
+ " 1 \n",
+ " 6047000802 \n",
+ " POLYGON ((-52727.332 -74888.681, -52723.908 -7... \n",
+ " 4.0 \n",
+ " 4.0 \n",
+ " NaN \n",
+ " 90331.2 \n",
+ " False \n",
+ " True \n",
+ " False \n",
+ " NaN \n",
+ " 25097.053439 \n",
+ " 6274.0 \n",
+ " 8.0 \n",
+ " 56251 \n",
+ " Merced, CA \n",
+ " 4709 \n",
+ " 1.332342 \n",
+ " \n",
+ " \n",
+ " 2 \n",
+ " 6085501402 \n",
+ " POLYGON ((-165759.786 -73091.934, -165741.347 ... \n",
+ " 3.5 \n",
+ " 4.6 \n",
+ " 140.3 \n",
+ " 47341.1 \n",
+ " False \n",
+ " False \n",
+ " False \n",
+ " 47481.4 \n",
+ " 13152.953980 \n",
+ " 3757.0 \n",
+ " 1694.0 \n",
+ " 79039 \n",
+ " San Jose, CA \n",
+ " 2962 \n",
+ " 1.268400 \n",
+ " \n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " GEOID geometry \\\n",
+ "0 6029004402 POLYGON ((59906.842 -270407.558, 59906.948 -27... \n",
+ "1 6047000802 POLYGON ((-52727.332 -74888.681, -52723.908 -7... \n",
+ "2 6085501402 POLYGON ((-165759.786 -73091.934, -165741.347 ... \n",
+ "\n",
+ " p50_mi_transit p50_mi_auto total_mi_transit total_mi_auto \\\n",
+ "0 42.2 1.7 84.4 148755.4 \n",
+ "1 4.0 4.0 NaN 90331.2 \n",
+ "2 3.5 4.6 140.3 47341.1 \n",
+ "\n",
+ " p50_transit_longer no_transit_replica no_transit total_mi \\\n",
+ "0 True False False 148839.8 \n",
+ "1 False True False NaN \n",
+ "2 False False False 47481.4 \n",
+ "\n",
+ " new_transit_mi projected_new_transit_trips index_right UACE10 \\\n",
+ "0 41329.266335 979.0 2554.0 92161 \n",
+ "1 25097.053439 6274.0 8.0 56251 \n",
+ "2 13152.953980 3757.0 1694.0 79039 \n",
+ "\n",
+ " NAME10 total_pop new_trips_per_capita \n",
+ "0 Wasco, CA 4027 0.243109 \n",
+ "1 Merced, CA 4709 1.332342 \n",
+ "2 San Jose, CA 2962 1.268400 "
+ ]
+ },
+ "execution_count": 3,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "results >> head(3)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "2ded0fd4-bab1-4987-bc74-7bfa00d71c64",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "ntd_totals = pd.read_excel('census_ntd/2022 UZA Sums_0.xlsx')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "id": "5f6c3f50-f5d8-418d-86e1-5631cc916fdb",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " UACE CD \n",
+ " UZA Name \n",
+ " UZA Population \n",
+ " Total Vehicle Revenue Miles \n",
+ " Total Vehicle Revenue Hours \n",
+ " Total Passenger Miles Traveled \n",
+ " Total Unlinked Passenger Trips \n",
+ " Total Operating Expenses \n",
+ " Fixed Guideway Directional Route Miles \n",
+ " Fixed Guideway Vehicle Revenue Miles \n",
+ " Fixed Guideway Passenger Miles \n",
+ " Fixed Guideway Operating Expenses \n",
+ " Non-Fixed Guideway Vehicle Revenue Miles \n",
+ " Non-Fixed Guideway Passenger Miles \n",
+ " Non-Fixed Guideway Operating Expenses \n",
+ " Fixed Guideway Directional Route Miles >= 7 Years \n",
+ " Fixed Guideway Vehicle Revenue Miles >= 7 Years \n",
+ " High Intensity Bus Directional Route Miles >= 7 Years \n",
+ " High Intensity Bus Vehicle Revenue Miles >= 7 Years \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 \n",
+ " 1 \n",
+ " Alabama Non-UZA \n",
+ " NaN \n",
+ " 5191052 \n",
+ " 311767 \n",
+ " 1657944 \n",
+ " 847168 \n",
+ " 18285687 \n",
+ " 0.0 \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " 2032430 \n",
+ " 1657944 \n",
+ " 6989662 \n",
+ " 0.0 \n",
+ " 0 \n",
+ " 0.0 \n",
+ " 0 \n",
+ " \n",
+ " \n",
+ " 1 \n",
+ " 2 \n",
+ " Alaska Non-UZA \n",
+ " NaN \n",
+ " 3135019 \n",
+ " 181845 \n",
+ " 25208661 \n",
+ " 1103868 \n",
+ " 74591876 \n",
+ " 891.3 \n",
+ " 1032797 \n",
+ " 25208661 \n",
+ " 52590936 \n",
+ " 526779 \n",
+ " 0 \n",
+ " 3461538 \n",
+ " 891.3 \n",
+ " 1032797 \n",
+ " 0.0 \n",
+ " 0 \n",
+ " \n",
+ " \n",
+ " 2 \n",
+ " 4 \n",
+ " Arizona Non-UZA \n",
+ " NaN \n",
+ " 6917128 \n",
+ " 322764 \n",
+ " 13610232 \n",
+ " 1394405 \n",
+ " 24844073 \n",
+ " 0.0 \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " 5011277 \n",
+ " 13610232 \n",
+ " 16875708 \n",
+ " 0.0 \n",
+ " 0 \n",
+ " 0.0 \n",
+ " 0 \n",
+ " \n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " UACE CD UZA Name UZA Population Total Vehicle Revenue Miles \\\n",
+ "0 1 Alabama Non-UZA NaN 5191052 \n",
+ "1 2 Alaska Non-UZA NaN 3135019 \n",
+ "2 4 Arizona Non-UZA NaN 6917128 \n",
+ "\n",
+ " Total Vehicle Revenue Hours Total Passenger Miles Traveled \\\n",
+ "0 311767 1657944 \n",
+ "1 181845 25208661 \n",
+ "2 322764 13610232 \n",
+ "\n",
+ " Total Unlinked Passenger Trips Total Operating Expenses \\\n",
+ "0 847168 18285687 \n",
+ "1 1103868 74591876 \n",
+ "2 1394405 24844073 \n",
+ "\n",
+ " Fixed Guideway Directional Route Miles \\\n",
+ "0 0.0 \n",
+ "1 891.3 \n",
+ "2 0.0 \n",
+ "\n",
+ " Fixed Guideway Vehicle Revenue Miles Fixed Guideway Passenger Miles \\\n",
+ "0 0 0 \n",
+ "1 1032797 25208661 \n",
+ "2 0 0 \n",
+ "\n",
+ " Fixed Guideway Operating Expenses \\\n",
+ "0 0 \n",
+ "1 52590936 \n",
+ "2 0 \n",
+ "\n",
+ " Non-Fixed Guideway Vehicle Revenue Miles \\\n",
+ "0 2032430 \n",
+ "1 526779 \n",
+ "2 5011277 \n",
+ "\n",
+ " Non-Fixed Guideway Passenger Miles Non-Fixed Guideway Operating Expenses \\\n",
+ "0 1657944 6989662 \n",
+ "1 0 3461538 \n",
+ "2 13610232 16875708 \n",
+ "\n",
+ " Fixed Guideway Directional Route Miles >= 7 Years \\\n",
+ "0 0.0 \n",
+ "1 891.3 \n",
+ "2 0.0 \n",
+ "\n",
+ " Fixed Guideway Vehicle Revenue Miles >= 7 Years \\\n",
+ "0 0 \n",
+ "1 1032797 \n",
+ "2 0 \n",
+ "\n",
+ " High Intensity Bus Directional Route Miles >= 7 Years \\\n",
+ "0 0.0 \n",
+ "1 0.0 \n",
+ "2 0.0 \n",
+ "\n",
+ " High Intensity Bus Vehicle Revenue Miles >= 7 Years \n",
+ "0 0 \n",
+ "1 0 \n",
+ "2 0 "
+ ]
+ },
+ "execution_count": 5,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "ntd_totals >> head(3)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "id": "1d190fa0-ecd4-4ccf-83c0-9e7f7eedd9a1",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from calitp_data_analysis.sql import to_snakecase"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "id": "b1894bd2-2e2c-4068-a473-6ac9f3049df2",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "ntd_totals = to_snakecase(ntd_totals)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "id": "d51dddcd-fb96-4056-85bf-526e4b1e9f82",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "Index(['uace_cd', 'uza_name', 'uza_population', 'total_vehicle_revenue_miles',\n",
+ " 'total_vehicle_revenue_hours', 'total_passenger_miles_traveled',\n",
+ " 'total_unlinked_passenger_trips', 'total_operating_expenses',\n",
+ " 'fixed_guideway_directional_route_miles',\n",
+ " 'fixed_guideway_vehicle_revenue_miles',\n",
+ " 'fixed_guideway_passenger_miles', 'fixed_guideway_operating_expenses',\n",
+ " 'non_fixed_guideway_vehicle_revenue_miles',\n",
+ " 'non_fixed_guideway_passenger_miles',\n",
+ " 'non_fixed_guideway_operating_expenses',\n",
+ " 'fixed_guideway_directional_route_miles_>=_7_years',\n",
+ " 'fixed_guideway_vehicle_revenue_miles_>=_7_years',\n",
+ " 'high_intensity_bus_directional_route_miles_>=_7_years',\n",
+ " 'high_intensity_bus_vehicle_revenue_miles_>=_7_years'],\n",
+ " dtype='object')"
+ ]
+ },
+ "execution_count": 8,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "ntd_totals.columns"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "id": "495ad48f-eb76-4884-b05e-f563bfa47190",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "upt_df = ntd_totals >> select(_.uace_cd, _.uza_name, _.total_unlinked_passenger_trips, _.uza_population)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "id": "fb3bf7f0-21e9-4403-919c-cd4d2aad66c1",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " uace_cd \n",
+ " uza_name \n",
+ " total_unlinked_passenger_trips \n",
+ " uza_population \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 \n",
+ " 1 \n",
+ " Alabama Non-UZA \n",
+ " 847168 \n",
+ " NaN \n",
+ " \n",
+ " \n",
+ " 1 \n",
+ " 2 \n",
+ " Alaska Non-UZA \n",
+ " 1103868 \n",
+ " NaN \n",
+ " \n",
+ " \n",
+ " 2 \n",
+ " 4 \n",
+ " Arizona Non-UZA \n",
+ " 1394405 \n",
+ " NaN \n",
+ " \n",
+ " \n",
+ " 3 \n",
+ " 5 \n",
+ " Arkansas Non-UZA \n",
+ " 799801 \n",
+ " NaN \n",
+ " \n",
+ " \n",
+ " 4 \n",
+ " 6 \n",
+ " California Non-UZA \n",
+ " 7350357 \n",
+ " NaN \n",
+ " \n",
+ " \n",
+ " ... \n",
+ " ... \n",
+ " ... \n",
+ " ... \n",
+ " ... \n",
+ " \n",
+ " \n",
+ " 549 \n",
+ " 69517 \n",
+ " Pinehurst--Southern Pines, NC \n",
+ " 9046 \n",
+ " 50319.0 \n",
+ " \n",
+ " \n",
+ " 550 \n",
+ " 45262 \n",
+ " Kingston, NY \n",
+ " 161584 \n",
+ " 50254.0 \n",
+ " \n",
+ " \n",
+ " 551 \n",
+ " 27631 \n",
+ " Enid, OK \n",
+ " 38411 \n",
+ " 50194.0 \n",
+ " \n",
+ " \n",
+ " 552 \n",
+ " 15184 \n",
+ " Chambersburg, PA \n",
+ " 39130 \n",
+ " 50094.0 \n",
+ " \n",
+ " \n",
+ " 553 \n",
+ " 91405 \n",
+ " Walla Walla, WA--OR \n",
+ " 327185 \n",
+ " 50013.0 \n",
+ " \n",
+ " \n",
+ "
\n",
+ "
554 rows × 4 columns
\n",
+ "
"
+ ],
+ "text/plain": [
+ " uace_cd uza_name total_unlinked_passenger_trips \\\n",
+ "0 1 Alabama Non-UZA 847168 \n",
+ "1 2 Alaska Non-UZA 1103868 \n",
+ "2 4 Arizona Non-UZA 1394405 \n",
+ "3 5 Arkansas Non-UZA 799801 \n",
+ "4 6 California Non-UZA 7350357 \n",
+ ".. ... ... ... \n",
+ "549 69517 Pinehurst--Southern Pines, NC 9046 \n",
+ "550 45262 Kingston, NY 161584 \n",
+ "551 27631 Enid, OK 38411 \n",
+ "552 15184 Chambersburg, PA 39130 \n",
+ "553 91405 Walla Walla, WA--OR 327185 \n",
+ "\n",
+ " uza_population \n",
+ "0 NaN \n",
+ "1 NaN \n",
+ "2 NaN \n",
+ "3 NaN \n",
+ "4 NaN \n",
+ ".. ... \n",
+ "549 50319.0 \n",
+ "550 50254.0 \n",
+ "551 50194.0 \n",
+ "552 50094.0 \n",
+ "553 50013.0 \n",
+ "\n",
+ "[554 rows x 4 columns]"
+ ]
+ },
+ "execution_count": 10,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "upt_df"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "id": "9fa2e423-ba22-4d20-b525-4efdf42498f0",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "uace_cd int64\n",
+ "uza_name object\n",
+ "total_unlinked_passenger_trips int64\n",
+ "uza_population float64\n",
+ "dtype: object"
+ ]
+ },
+ "execution_count": 11,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "upt_df.dtypes"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "id": "083aa964-da4b-429e-aeec-6af92dbe5e03",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "results.UACE10 = results.UACE10.fillna(6).astype('int64') # 6 is CA non-UZA"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 13,
+ "id": "8a792091-ee81-4883-994d-37dd9678c39c",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "uza_grouped = (results >> group_by(_.UACE10, _.NAME10)\n",
+ " >> summarize(new_transit_mi_weekday = _.new_transit_mi.sum(),\n",
+ " new_transit_trips_weekday = _.projected_new_transit_trips.sum(),\n",
+ " num_tracts = _.shape[0]\n",
+ " )\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 14,
+ "id": "a90595b5-b857-4aa0-ab67-c0919890886b",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "df = (uza_grouped >> inner_join(_, upt_df, on = {'UACE10': 'uace_cd'})\n",
+ " >> mutate(current_weekday_trips = _.total_unlinked_passenger_trips / (365 - 104))\n",
+ " >> mutate(increase_ratio = _.new_transit_trips_weekday / _.current_weekday_trips,\n",
+ " new_trips_per_capita = _.new_transit_trips_weekday / _.uza_population,\n",
+ " )\n",
+ " >> arrange(-_.new_transit_trips_weekday)\n",
+ " ).round(2)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 15,
+ "id": "a51341ac-ecc5-496c-87f5-bad5cb0e6184",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "df.to_csv('vmt_to_transit_uza.csv', index = False)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 16,
+ "id": "a1f57c6f-33f0-41b4-a1ce-f87f338e0ce0",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "## What happens if you compare to 2019/08?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 17,
+ "id": "4ef75434-c9aa-474b-96e1-fc77128a0186",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " new_transit_mi_weekday \n",
+ " new_transit_trips_weekday \n",
+ " num_tracts \n",
+ " uza_name \n",
+ " total_unlinked_passenger_trips \n",
+ " uza_population \n",
+ " current_weekday_trips \n",
+ " increase_ratio \n",
+ " new_trips_per_capita \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " 17 \n",
+ " 1.015789e+08 \n",
+ " 13230200.0 \n",
+ " 2974 \n",
+ " Los Angeles--Long Beach--Anaheim, CA \n",
+ " 352876967 \n",
+ " 12237376.0 \n",
+ " 1352019.03 \n",
+ " 9.79 \n",
+ " 1.08 \n",
+ " \n",
+ " \n",
+ " 33 \n",
+ " 2.939732e+07 \n",
+ " 4005496.0 \n",
+ " 880 \n",
+ " San Francisco--Oakland, CA \n",
+ " 174947309 \n",
+ " 3515933.0 \n",
+ " 670296.20 \n",
+ " 5.98 \n",
+ " 1.14 \n",
+ " \n",
+ " \n",
+ " 32 \n",
+ " 2.951033e+07 \n",
+ " 3252737.0 \n",
+ " 714 \n",
+ " San Diego, CA \n",
+ " 63873516 \n",
+ " 3070300.0 \n",
+ " 244726.11 \n",
+ " 13.29 \n",
+ " 1.06 \n",
+ " \n",
+ " \n",
+ " 29 \n",
+ " 2.148795e+07 \n",
+ " 2516538.0 \n",
+ " 447 \n",
+ " Riverside--San Bernardino, CA \n",
+ " 7649513 \n",
+ " 2276703.0 \n",
+ " 29308.48 \n",
+ " 85.86 \n",
+ " 1.11 \n",
+ " \n",
+ " \n",
+ " 30 \n",
+ " 1.810016e+07 \n",
+ " 1985167.0 \n",
+ " 452 \n",
+ " Sacramento, CA \n",
+ " 11886782 \n",
+ " 1946618.0 \n",
+ " 45543.23 \n",
+ " 43.59 \n",
+ " 1.02 \n",
+ " \n",
+ " \n",
+ " 34 \n",
+ " 1.586511e+07 \n",
+ " 1741073.0 \n",
+ " 398 \n",
+ " San Jose, CA \n",
+ " 22102814 \n",
+ " 1837446.0 \n",
+ " 84685.11 \n",
+ " 20.56 \n",
+ " 0.95 \n",
+ " \n",
+ " \n",
+ " 10 \n",
+ " 6.356216e+06 \n",
+ " 1136586.0 \n",
+ " 166 \n",
+ " Fresno, CA \n",
+ " 7205414 \n",
+ " 717589.0 \n",
+ " 27606.95 \n",
+ " 41.17 \n",
+ " 1.58 \n",
+ " \n",
+ " \n",
+ " 24 \n",
+ " 3.502044e+06 \n",
+ " 883930.0 \n",
+ " 95 \n",
+ " Oxnard--San Buenaventura (Ventura), CA \n",
+ " 2795139 \n",
+ " 376117.0 \n",
+ " 10709.34 \n",
+ " 82.54 \n",
+ " 2.35 \n",
+ " \n",
+ " \n",
+ " 0 \n",
+ " 9.380291e+06 \n",
+ " 852281.0 \n",
+ " 200 \n",
+ " California Non-UZA \n",
+ " 7350357 \n",
+ " NaN \n",
+ " 28162.29 \n",
+ " 30.26 \n",
+ " NaN \n",
+ " \n",
+ " \n",
+ " 3 \n",
+ " 4.994286e+06 \n",
+ " 843937.0 \n",
+ " 156 \n",
+ " Bakersfield, CA \n",
+ " 3201508 \n",
+ " 570235.0 \n",
+ " 12266.31 \n",
+ " 68.80 \n",
+ " 1.48 \n",
+ " \n",
+ " \n",
+ " 43 \n",
+ " 4.068842e+06 \n",
+ " 824982.0 \n",
+ " 99 \n",
+ " Stockton, CA \n",
+ " 2276298 \n",
+ " 414847.0 \n",
+ " 8721.45 \n",
+ " 94.59 \n",
+ " 1.99 \n",
+ " \n",
+ " \n",
+ " 14 \n",
+ " 4.617474e+06 \n",
+ " 754544.0 \n",
+ " 105 \n",
+ " Indio--Palm Desert--Palm Springs, CA \n",
+ " 2087445 \n",
+ " 361075.0 \n",
+ " 7997.87 \n",
+ " 94.34 \n",
+ " 2.09 \n",
+ " \n",
+ " \n",
+ " 48 \n",
+ " 3.813196e+06 \n",
+ " 725369.0 \n",
+ " 79 \n",
+ " Victorville--Hesperia--Apple Valley, CA \n",
+ " 932423 \n",
+ " 355816.0 \n",
+ " 3572.50 \n",
+ " 203.04 \n",
+ " 2.04 \n",
+ " \n",
+ " \n",
+ " 40 \n",
+ " 3.330290e+06 \n",
+ " 681397.0 \n",
+ " 83 \n",
+ " Santa Rosa, CA \n",
+ " 1763224 \n",
+ " 297329.0 \n",
+ " 6755.65 \n",
+ " 100.86 \n",
+ " 2.29 \n",
+ " \n",
+ " \n",
+ " 36 \n",
+ " 2.307279e+06 \n",
+ " 638503.0 \n",
+ " 54 \n",
+ " Santa Barbara, CA \n",
+ " 4292799 \n",
+ " 202197.0 \n",
+ " 16447.51 \n",
+ " 38.82 \n",
+ " 3.16 \n",
+ " \n",
+ " \n",
+ " 49 \n",
+ " 2.463079e+06 \n",
+ " 632700.0 \n",
+ " 56 \n",
+ " Visalia, CA \n",
+ " 572862 \n",
+ " 160578.0 \n",
+ " 2194.87 \n",
+ " 288.26 \n",
+ " 3.94 \n",
+ " \n",
+ " \n",
+ " 22 \n",
+ " 3.438503e+06 \n",
+ " 613156.0 \n",
+ " 86 \n",
+ " Modesto, CA \n",
+ " 1638903 \n",
+ " 357301.0 \n",
+ " 6279.32 \n",
+ " 97.65 \n",
+ " 1.72 \n",
+ " \n",
+ " \n",
+ " 21 \n",
+ " 5.987486e+06 \n",
+ " 571394.0 \n",
+ " 124 \n",
+ " Mission Viejo--Lake Forest--Laguna Niguel, CA \n",
+ " 3027974 \n",
+ " 646843.0 \n",
+ " 11601.43 \n",
+ " 49.25 \n",
+ " 0.88 \n",
+ " \n",
+ " \n",
+ " 31 \n",
+ " 1.914888e+06 \n",
+ " 501002.0 \n",
+ " 46 \n",
+ " Salinas, CA \n",
+ " 706072 \n",
+ " 177532.0 \n",
+ " 2705.26 \n",
+ " 185.20 \n",
+ " 2.82 \n",
+ " \n",
+ " \n",
+ " 6 \n",
+ " 7.186704e+06 \n",
+ " 456303.0 \n",
+ " 151 \n",
+ " Concord--Walnut Creek, CA \n",
+ " 7508917 \n",
+ " 538583.0 \n",
+ " 28769.80 \n",
+ " 15.86 \n",
+ " 0.85 \n",
+ " \n",
+ " \n",
+ " 38 \n",
+ " 2.053463e+06 \n",
+ " 390836.0 \n",
+ " 50 \n",
+ " Santa Cruz, CA \n",
+ " 2019665 \n",
+ " 169038.0 \n",
+ " 7738.18 \n",
+ " 50.51 \n",
+ " 2.31 \n",
+ " \n",
+ " \n",
+ " 13 \n",
+ " 1.954984e+06 \n",
+ " 388747.0 \n",
+ " 48 \n",
+ " Hemet, CA \n",
+ " 466576 \n",
+ " 173194.0 \n",
+ " 1787.65 \n",
+ " 217.46 \n",
+ " 2.24 \n",
+ " \n",
+ " \n",
+ " 41 \n",
+ " 1.856838e+06 \n",
+ " 373048.0 \n",
+ " 40 \n",
+ " Seaside--Monterey--Pacific Grove, CA \n",
+ " 1002994 \n",
+ " 123495.0 \n",
+ " 3842.89 \n",
+ " 97.07 \n",
+ " 3.02 \n",
+ " \n",
+ " \n",
+ " 44 \n",
+ " 2.878925e+06 \n",
+ " 363132.0 \n",
+ " 59 \n",
+ " Thousand Oaks, CA \n",
+ " 209157 \n",
+ " 213986.0 \n",
+ " 801.37 \n",
+ " 453.14 \n",
+ " 1.70 \n",
+ " \n",
+ " \n",
+ " 39 \n",
+ " 1.319715e+06 \n",
+ " 361248.0 \n",
+ " 32 \n",
+ " Santa Maria, CA \n",
+ " 506498 \n",
+ " 143609.0 \n",
+ " 1940.61 \n",
+ " 186.15 \n",
+ " 2.52 \n",
+ " \n",
+ " \n",
+ " 20 \n",
+ " 1.467092e+06 \n",
+ " 345085.0 \n",
+ " 37 \n",
+ " Merced, CA \n",
+ " 351235 \n",
+ " 150052.0 \n",
+ " 1345.73 \n",
+ " 256.43 \n",
+ " 2.30 \n",
+ " \n",
+ " \n",
+ " 5 \n",
+ " 1.225752e+06 \n",
+ " 332072.0 \n",
+ " 27 \n",
+ " Chico, CA \n",
+ " 485301 \n",
+ " 111411.0 \n",
+ " 1859.39 \n",
+ " 178.59 \n",
+ " 2.98 \n",
+ " \n",
+ " \n",
+ " 7 \n",
+ " 7.742654e+05 \n",
+ " 320531.0 \n",
+ " 20 \n",
+ " Davis, CA \n",
+ " 2129760 \n",
+ " 77034.0 \n",
+ " 8160.00 \n",
+ " 39.28 \n",
+ " 4.16 \n",
+ " \n",
+ " \n",
+ " 27 \n",
+ " 1.523897e+06 \n",
+ " 303732.0 \n",
+ " 40 \n",
+ " Redding, CA \n",
+ " 246884 \n",
+ " 120602.0 \n",
+ " 945.92 \n",
+ " 321.10 \n",
+ " 2.52 \n",
+ " \n",
+ " \n",
+ " 37 \n",
+ " 3.197403e+06 \n",
+ " 284559.0 \n",
+ " 63 \n",
+ " Santa Clarita, CA \n",
+ " 2065119 \n",
+ " 278031.0 \n",
+ " 7912.33 \n",
+ " 35.96 \n",
+ " 1.02 \n",
+ " \n",
+ " \n",
+ " 35 \n",
+ " 1.257978e+06 \n",
+ " 283512.0 \n",
+ " 17 \n",
+ " San Luis Obispo, CA \n",
+ " 740931 \n",
+ " 56904.0 \n",
+ " 2838.82 \n",
+ " 99.87 \n",
+ " 4.98 \n",
+ " \n",
+ " \n",
+ " 52 \n",
+ " 1.349172e+06 \n",
+ " 282568.0 \n",
+ " 30 \n",
+ " Yuba City, CA \n",
+ " 438904 \n",
+ " 125706.0 \n",
+ " 1681.62 \n",
+ " 168.03 \n",
+ " 2.25 \n",
+ " \n",
+ " \n",
+ " 18 \n",
+ " 8.652113e+05 \n",
+ " 257937.0 \n",
+ " 20 \n",
+ " Madera, CA \n",
+ " 52164 \n",
+ " 81635.0 \n",
+ " 199.86 \n",
+ " 1290.58 \n",
+ " 3.16 \n",
+ " \n",
+ " \n",
+ " 42 \n",
+ " 1.351613e+06 \n",
+ " 230839.0 \n",
+ " 33 \n",
+ " Simi Valley, CA \n",
+ " 164630 \n",
+ " 127364.0 \n",
+ " 630.77 \n",
+ " 365.97 \n",
+ " 1.81 \n",
+ " \n",
+ " \n",
+ " 26 \n",
+ " 6.655831e+05 \n",
+ " 225769.0 \n",
+ " 19 \n",
+ " Porterville, CA \n",
+ " 182082 \n",
+ " 69862.0 \n",
+ " 697.63 \n",
+ " 323.62 \n",
+ " 3.23 \n",
+ " \n",
+ " \n",
+ " 16 \n",
+ " 4.978785e+05 \n",
+ " 217504.0 \n",
+ " 13 \n",
+ " Lompoc, CA \n",
+ " 144899 \n",
+ " 54287.0 \n",
+ " 555.17 \n",
+ " 391.78 \n",
+ " 4.01 \n",
+ " \n",
+ " \n",
+ " 12 \n",
+ " 1.128180e+06 \n",
+ " 204620.0 \n",
+ " 20 \n",
+ " Hanford, CA \n",
+ " 415547 \n",
+ " 66638.0 \n",
+ " 1592.13 \n",
+ " 128.52 \n",
+ " 3.07 \n",
+ " \n",
+ " \n",
+ " 46 \n",
+ " 1.244253e+06 \n",
+ " 185243.0 \n",
+ " 24 \n",
+ " Vacaville, CA \n",
+ " 261055 \n",
+ " 101027.0 \n",
+ " 1000.21 \n",
+ " 185.20 \n",
+ " 1.83 \n",
+ " \n",
+ " \n",
+ " 19 \n",
+ " 1.440176e+06 \n",
+ " 182203.0 \n",
+ " 24 \n",
+ " Manteca, CA \n",
+ " 247773 \n",
+ " 86674.0 \n",
+ " 949.32 \n",
+ " 191.93 \n",
+ " 2.10 \n",
+ " \n",
+ " \n",
+ " 9 \n",
+ " 1.510021e+06 \n",
+ " 181956.0 \n",
+ " 36 \n",
+ " Fairfield, CA \n",
+ " 371893 \n",
+ " 150122.0 \n",
+ " 1424.88 \n",
+ " 127.70 \n",
+ " 1.21 \n",
+ " \n",
+ " \n",
+ " 23 \n",
+ " 1.014432e+06 \n",
+ " 175937.0 \n",
+ " 28 \n",
+ " Napa, CA \n",
+ " 377272 \n",
+ " 84619.0 \n",
+ " 1445.49 \n",
+ " 121.71 \n",
+ " 2.08 \n",
+ " \n",
+ " \n",
+ " 45 \n",
+ " 1.098035e+06 \n",
+ " 172029.0 \n",
+ " 27 \n",
+ " Turlock, CA \n",
+ " 340324 \n",
+ " 79203.0 \n",
+ " 1303.92 \n",
+ " 131.93 \n",
+ " 2.17 \n",
+ " \n",
+ " \n",
+ " 50 \n",
+ " 8.553466e+05 \n",
+ " 167413.0 \n",
+ " 26 \n",
+ " Watsonville, CA \n",
+ " 1263457 \n",
+ " 68668.0 \n",
+ " 4840.83 \n",
+ " 34.58 \n",
+ " 2.44 \n",
+ " \n",
+ " \n",
+ " 8 \n",
+ " 1.170922e+06 \n",
+ " 162850.0 \n",
+ " 19 \n",
+ " El Paso de Robles (Paso Robles)--Atascadero, CA \n",
+ " 184534 \n",
+ " 67804.0 \n",
+ " 707.03 \n",
+ " 230.33 \n",
+ " 2.40 \n",
+ " \n",
+ " \n",
+ " 2 \n",
+ " 1.097684e+06 \n",
+ " 147963.0 \n",
+ " 16 \n",
+ " Arroyo Grande--Grover Beach--Pismo Beach, CA \n",
+ " 247369 \n",
+ " 50885.0 \n",
+ " 947.77 \n",
+ " 156.12 \n",
+ " 2.91 \n",
+ " \n",
+ " \n",
+ " 11 \n",
+ " 1.467065e+06 \n",
+ " 135790.0 \n",
+ " 26 \n",
+ " Gilroy--Morgan Hill, CA \n",
+ " 76517 \n",
+ " 114833.0 \n",
+ " 293.17 \n",
+ " 463.18 \n",
+ " 1.18 \n",
+ " \n",
+ " \n",
+ " 1 \n",
+ " 2.925885e+06 \n",
+ " 119287.0 \n",
+ " 62 \n",
+ " Antioch, CA \n",
+ " 3395022 \n",
+ " 326205.0 \n",
+ " 13007.75 \n",
+ " 9.17 \n",
+ " 0.37 \n",
+ " \n",
+ " \n",
+ " 47 \n",
+ " 1.715743e+06 \n",
+ " 99035.0 \n",
+ " 45 \n",
+ " Vallejo, CA \n",
+ " 582765 \n",
+ " 175132.0 \n",
+ " 2232.82 \n",
+ " 44.35 \n",
+ " 0.57 \n",
+ " \n",
+ " \n",
+ " 4 \n",
+ " 8.633931e+05 \n",
+ " 95216.0 \n",
+ " 18 \n",
+ " Camarillo, CA \n",
+ " 198858 \n",
+ " 76338.0 \n",
+ " 761.91 \n",
+ " 124.97 \n",
+ " 1.25 \n",
+ " \n",
+ " \n",
+ " 51 \n",
+ " 5.997722e+05 \n",
+ " 75208.0 \n",
+ " 15 \n",
+ " Woodland, CA \n",
+ " 196091 \n",
+ " 61133.0 \n",
+ " 751.31 \n",
+ " 100.10 \n",
+ " 1.23 \n",
+ " \n",
+ " \n",
+ " 15 \n",
+ " 8.076975e+05 \n",
+ " 73396.0 \n",
+ " 22 \n",
+ " Lodi, CA \n",
+ " 207778 \n",
+ " 73090.0 \n",
+ " 796.08 \n",
+ " 92.20 \n",
+ " 1.00 \n",
+ " \n",
+ " \n",
+ " 25 \n",
+ " 6.924392e+05 \n",
+ " 34302.0 \n",
+ " 16 \n",
+ " Petaluma, CA \n",
+ " 255372 \n",
+ " 65227.0 \n",
+ " 978.44 \n",
+ " 35.06 \n",
+ " 0.53 \n",
+ " \n",
+ " \n",
+ " 53 \n",
+ " 1.880209e+04 \n",
+ " 3032.0 \n",
+ " 1 \n",
+ " Yuma, AZ--CA \n",
+ " 1601570 \n",
+ " 135717.0 \n",
+ " 6136.28 \n",
+ " 0.49 \n",
+ " 0.02 \n",
+ " \n",
+ " \n",
+ " 28 \n",
+ " 5.827465e+04 \n",
+ " 2660.0 \n",
+ " 1 \n",
+ " Reno, NV--CA \n",
+ " 4316186 \n",
+ " 446529.0 \n",
+ " 16537.11 \n",
+ " 0.16 \n",
+ " 0.01 \n",
+ " \n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " new_transit_mi_weekday new_transit_trips_weekday num_tracts \\\n",
+ "17 1.015789e+08 13230200.0 2974 \n",
+ "33 2.939732e+07 4005496.0 880 \n",
+ "32 2.951033e+07 3252737.0 714 \n",
+ "29 2.148795e+07 2516538.0 447 \n",
+ "30 1.810016e+07 1985167.0 452 \n",
+ "34 1.586511e+07 1741073.0 398 \n",
+ "10 6.356216e+06 1136586.0 166 \n",
+ "24 3.502044e+06 883930.0 95 \n",
+ "0 9.380291e+06 852281.0 200 \n",
+ "3 4.994286e+06 843937.0 156 \n",
+ "43 4.068842e+06 824982.0 99 \n",
+ "14 4.617474e+06 754544.0 105 \n",
+ "48 3.813196e+06 725369.0 79 \n",
+ "40 3.330290e+06 681397.0 83 \n",
+ "36 2.307279e+06 638503.0 54 \n",
+ "49 2.463079e+06 632700.0 56 \n",
+ "22 3.438503e+06 613156.0 86 \n",
+ "21 5.987486e+06 571394.0 124 \n",
+ "31 1.914888e+06 501002.0 46 \n",
+ "6 7.186704e+06 456303.0 151 \n",
+ "38 2.053463e+06 390836.0 50 \n",
+ "13 1.954984e+06 388747.0 48 \n",
+ "41 1.856838e+06 373048.0 40 \n",
+ "44 2.878925e+06 363132.0 59 \n",
+ "39 1.319715e+06 361248.0 32 \n",
+ "20 1.467092e+06 345085.0 37 \n",
+ "5 1.225752e+06 332072.0 27 \n",
+ "7 7.742654e+05 320531.0 20 \n",
+ "27 1.523897e+06 303732.0 40 \n",
+ "37 3.197403e+06 284559.0 63 \n",
+ "35 1.257978e+06 283512.0 17 \n",
+ "52 1.349172e+06 282568.0 30 \n",
+ "18 8.652113e+05 257937.0 20 \n",
+ "42 1.351613e+06 230839.0 33 \n",
+ "26 6.655831e+05 225769.0 19 \n",
+ "16 4.978785e+05 217504.0 13 \n",
+ "12 1.128180e+06 204620.0 20 \n",
+ "46 1.244253e+06 185243.0 24 \n",
+ "19 1.440176e+06 182203.0 24 \n",
+ "9 1.510021e+06 181956.0 36 \n",
+ "23 1.014432e+06 175937.0 28 \n",
+ "45 1.098035e+06 172029.0 27 \n",
+ "50 8.553466e+05 167413.0 26 \n",
+ "8 1.170922e+06 162850.0 19 \n",
+ "2 1.097684e+06 147963.0 16 \n",
+ "11 1.467065e+06 135790.0 26 \n",
+ "1 2.925885e+06 119287.0 62 \n",
+ "47 1.715743e+06 99035.0 45 \n",
+ "4 8.633931e+05 95216.0 18 \n",
+ "51 5.997722e+05 75208.0 15 \n",
+ "15 8.076975e+05 73396.0 22 \n",
+ "25 6.924392e+05 34302.0 16 \n",
+ "53 1.880209e+04 3032.0 1 \n",
+ "28 5.827465e+04 2660.0 1 \n",
+ "\n",
+ " uza_name \\\n",
+ "17 Los Angeles--Long Beach--Anaheim, CA \n",
+ "33 San Francisco--Oakland, CA \n",
+ "32 San Diego, CA \n",
+ "29 Riverside--San Bernardino, CA \n",
+ "30 Sacramento, CA \n",
+ "34 San Jose, CA \n",
+ "10 Fresno, CA \n",
+ "24 Oxnard--San Buenaventura (Ventura), CA \n",
+ "0 California Non-UZA \n",
+ "3 Bakersfield, CA \n",
+ "43 Stockton, CA \n",
+ "14 Indio--Palm Desert--Palm Springs, CA \n",
+ "48 Victorville--Hesperia--Apple Valley, CA \n",
+ "40 Santa Rosa, CA \n",
+ "36 Santa Barbara, CA \n",
+ "49 Visalia, CA \n",
+ "22 Modesto, CA \n",
+ "21 Mission Viejo--Lake Forest--Laguna Niguel, CA \n",
+ "31 Salinas, CA \n",
+ "6 Concord--Walnut Creek, CA \n",
+ "38 Santa Cruz, CA \n",
+ "13 Hemet, CA \n",
+ "41 Seaside--Monterey--Pacific Grove, CA \n",
+ "44 Thousand Oaks, CA \n",
+ "39 Santa Maria, CA \n",
+ "20 Merced, CA \n",
+ "5 Chico, CA \n",
+ "7 Davis, CA \n",
+ "27 Redding, CA \n",
+ "37 Santa Clarita, CA \n",
+ "35 San Luis Obispo, CA \n",
+ "52 Yuba City, CA \n",
+ "18 Madera, CA \n",
+ "42 Simi Valley, CA \n",
+ "26 Porterville, CA \n",
+ "16 Lompoc, CA \n",
+ "12 Hanford, CA \n",
+ "46 Vacaville, CA \n",
+ "19 Manteca, CA \n",
+ "9 Fairfield, CA \n",
+ "23 Napa, CA \n",
+ "45 Turlock, CA \n",
+ "50 Watsonville, CA \n",
+ "8 El Paso de Robles (Paso Robles)--Atascadero, CA \n",
+ "2 Arroyo Grande--Grover Beach--Pismo Beach, CA \n",
+ "11 Gilroy--Morgan Hill, CA \n",
+ "1 Antioch, CA \n",
+ "47 Vallejo, CA \n",
+ "4 Camarillo, CA \n",
+ "51 Woodland, CA \n",
+ "15 Lodi, CA \n",
+ "25 Petaluma, CA \n",
+ "53 Yuma, AZ--CA \n",
+ "28 Reno, NV--CA \n",
+ "\n",
+ " total_unlinked_passenger_trips uza_population current_weekday_trips \\\n",
+ "17 352876967 12237376.0 1352019.03 \n",
+ "33 174947309 3515933.0 670296.20 \n",
+ "32 63873516 3070300.0 244726.11 \n",
+ "29 7649513 2276703.0 29308.48 \n",
+ "30 11886782 1946618.0 45543.23 \n",
+ "34 22102814 1837446.0 84685.11 \n",
+ "10 7205414 717589.0 27606.95 \n",
+ "24 2795139 376117.0 10709.34 \n",
+ "0 7350357 NaN 28162.29 \n",
+ "3 3201508 570235.0 12266.31 \n",
+ "43 2276298 414847.0 8721.45 \n",
+ "14 2087445 361075.0 7997.87 \n",
+ "48 932423 355816.0 3572.50 \n",
+ "40 1763224 297329.0 6755.65 \n",
+ "36 4292799 202197.0 16447.51 \n",
+ "49 572862 160578.0 2194.87 \n",
+ "22 1638903 357301.0 6279.32 \n",
+ "21 3027974 646843.0 11601.43 \n",
+ "31 706072 177532.0 2705.26 \n",
+ "6 7508917 538583.0 28769.80 \n",
+ "38 2019665 169038.0 7738.18 \n",
+ "13 466576 173194.0 1787.65 \n",
+ "41 1002994 123495.0 3842.89 \n",
+ "44 209157 213986.0 801.37 \n",
+ "39 506498 143609.0 1940.61 \n",
+ "20 351235 150052.0 1345.73 \n",
+ "5 485301 111411.0 1859.39 \n",
+ "7 2129760 77034.0 8160.00 \n",
+ "27 246884 120602.0 945.92 \n",
+ "37 2065119 278031.0 7912.33 \n",
+ "35 740931 56904.0 2838.82 \n",
+ "52 438904 125706.0 1681.62 \n",
+ "18 52164 81635.0 199.86 \n",
+ "42 164630 127364.0 630.77 \n",
+ "26 182082 69862.0 697.63 \n",
+ "16 144899 54287.0 555.17 \n",
+ "12 415547 66638.0 1592.13 \n",
+ "46 261055 101027.0 1000.21 \n",
+ "19 247773 86674.0 949.32 \n",
+ "9 371893 150122.0 1424.88 \n",
+ "23 377272 84619.0 1445.49 \n",
+ "45 340324 79203.0 1303.92 \n",
+ "50 1263457 68668.0 4840.83 \n",
+ "8 184534 67804.0 707.03 \n",
+ "2 247369 50885.0 947.77 \n",
+ "11 76517 114833.0 293.17 \n",
+ "1 3395022 326205.0 13007.75 \n",
+ "47 582765 175132.0 2232.82 \n",
+ "4 198858 76338.0 761.91 \n",
+ "51 196091 61133.0 751.31 \n",
+ "15 207778 73090.0 796.08 \n",
+ "25 255372 65227.0 978.44 \n",
+ "53 1601570 135717.0 6136.28 \n",
+ "28 4316186 446529.0 16537.11 \n",
+ "\n",
+ " increase_ratio new_trips_per_capita \n",
+ "17 9.79 1.08 \n",
+ "33 5.98 1.14 \n",
+ "32 13.29 1.06 \n",
+ "29 85.86 1.11 \n",
+ "30 43.59 1.02 \n",
+ "34 20.56 0.95 \n",
+ "10 41.17 1.58 \n",
+ "24 82.54 2.35 \n",
+ "0 30.26 NaN \n",
+ "3 68.80 1.48 \n",
+ "43 94.59 1.99 \n",
+ "14 94.34 2.09 \n",
+ "48 203.04 2.04 \n",
+ "40 100.86 2.29 \n",
+ "36 38.82 3.16 \n",
+ "49 288.26 3.94 \n",
+ "22 97.65 1.72 \n",
+ "21 49.25 0.88 \n",
+ "31 185.20 2.82 \n",
+ "6 15.86 0.85 \n",
+ "38 50.51 2.31 \n",
+ "13 217.46 2.24 \n",
+ "41 97.07 3.02 \n",
+ "44 453.14 1.70 \n",
+ "39 186.15 2.52 \n",
+ "20 256.43 2.30 \n",
+ "5 178.59 2.98 \n",
+ "7 39.28 4.16 \n",
+ "27 321.10 2.52 \n",
+ "37 35.96 1.02 \n",
+ "35 99.87 4.98 \n",
+ "52 168.03 2.25 \n",
+ "18 1290.58 3.16 \n",
+ "42 365.97 1.81 \n",
+ "26 323.62 3.23 \n",
+ "16 391.78 4.01 \n",
+ "12 128.52 3.07 \n",
+ "46 185.20 1.83 \n",
+ "19 191.93 2.10 \n",
+ "9 127.70 1.21 \n",
+ "23 121.71 2.08 \n",
+ "45 131.93 2.17 \n",
+ "50 34.58 2.44 \n",
+ "8 230.33 2.40 \n",
+ "2 156.12 2.91 \n",
+ "11 463.18 1.18 \n",
+ "1 9.17 0.37 \n",
+ "47 44.35 0.57 \n",
+ "4 124.97 1.25 \n",
+ "51 100.10 1.23 \n",
+ "15 92.20 1.00 \n",
+ "25 35.06 0.53 \n",
+ "53 0.49 0.02 \n",
+ "28 0.16 0.01 "
+ ]
+ },
+ "execution_count": 17,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "df >> select(-_.UACE10, -_.NAME10, -_.uace_cd)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "af8eca53-3024-4f48-8e6b-d79828152ada",
+ "metadata": {},
+ "source": [
+ "About 18 million new daily trips across LA/Orange/San Diego/Imperial Counties. For reference, LA Metro's daily ridership is around 1 million. Current regional transit modeshare is only about 5%..."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "9d0239a4-02e3-4a7e-8677-ed174ab3164f",
+ "metadata": {},
+ "source": [
+ "# Statewide"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 18,
+ "id": "089f91c8-fbfc-4211-afe0-f984f94558e4",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "/tmp/ipykernel_567/1703867807.py:1: FutureWarning: The default value of numeric_only in DataFrame.sum is deprecated. In a future version, it will default to False. In addition, specifying 'numeric_only=None' is deprecated. Select only valid columns or specify the value of numeric_only to silence this warning.\n",
+ " df.sum()\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ "UACE10 3281692\n",
+ "new_transit_mi_weekday 323248206.03\n",
+ "new_transit_trips_weekday 44026554.0\n",
+ "num_tracts 8339\n",
+ "uace_cd 3281692\n",
+ "uza_name Los Angeles--Long Beach--Anaheim, CASan Franci...\n",
+ "total_unlinked_passenger_trips 704442418\n",
+ "uza_population 34366472.0\n",
+ "current_weekday_trips 2699013.1\n",
+ "increase_ratio 8222.95\n",
+ "new_trips_per_capita 104.13\n",
+ "dtype: object"
+ ]
+ },
+ "execution_count": 18,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "df.sum()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 19,
+ "id": "d5f152db-7e45-4f3a-90d0-1edc289d10e5",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "/tmp/ipykernel_567/3999246341.py:1: FutureWarning: The default value of numeric_only in DataFrame.sum is deprecated. In a future version, it will default to False. In addition, specifying 'numeric_only=None' is deprecated. Select only valid columns or specify the value of numeric_only to silence this warning.\n",
+ " df.sum()['new_transit_trips_weekday'] / df.sum()['current_weekday_trips']\n",
+ "/tmp/ipykernel_567/3999246341.py:1: FutureWarning: The default value of numeric_only in DataFrame.sum is deprecated. In a future version, it will default to False. In addition, specifying 'numeric_only=None' is deprecated. Select only valid columns or specify the value of numeric_only to silence this warning.\n",
+ " df.sum()['new_transit_trips_weekday'] / df.sum()['current_weekday_trips']\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ "16.312093483355078"
+ ]
+ },
+ "execution_count": 19,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "df.sum()['new_transit_trips_weekday'] / df.sum()['current_weekday_trips']"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "01b348d2-fc58-4bcb-a1c9-f7ab073646ec",
+ "metadata": {},
+ "source": [
+ "# By MPO"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 20,
+ "id": "6543e8d9-201f-48c6-9d24-e6632a526638",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "mpo = gpd.read_file('census_ntd/mpos.geojson')\n",
+ "# trips_by_tract = gpd.read_parquet('outputs/')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 21,
+ "id": "4843dc50-2799-4d0e-a19d-ad5da78c97bb",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import shared_utils"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 22,
+ "id": "b24d3071-f427-4830-9070-708557046140",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "mpo = mpo[['MPO', 'LABEL_MPO', 'geometry']]\n",
+ "mpo = mpo.to_crs(shared_utils.geography_utils.CA_NAD83Albers)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 23,
+ "id": "791d5137-eeb3-42c3-a5d1-f7468ddb6252",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "results = results >> select(-_.index_right)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 24,
+ "id": "593a2a9c-084f-4b89-a9fb-c3d0da07be01",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "mpo_joined = gpd.sjoin(results, mpo, how = 'left')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 25,
+ "id": "2ae42e46-f59b-45c1-a0fc-a25b9c5c8cd4",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "## add population, per capita...\n",
+ "\n",
+ "df2 = (mpo_joined >> group_by(_.MPO, _.LABEL_MPO) \n",
+ " >> summarize(new_transit_mi_weekday = _.new_transit_mi.sum(),\n",
+ " new_transit_trips_weekday = _.projected_new_transit_trips.sum(),\n",
+ " num_tracts = _.shape[0],\n",
+ " population = _.total_pop.sum()\n",
+ " )\n",
+ " >> mutate(new_trips_per_capita = _.new_transit_trips_weekday / _.population)\n",
+ " >> mutate(new_transit_mi_pct = _.new_transit_mi_weekday / _.new_transit_mi_weekday.sum())\n",
+ " ).round(2) >> arrange(-_.new_transit_trips_weekday)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 26,
+ "id": "7226fca0-21bb-426b-9488-ba67ceeb4345",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "df2.to_csv('vmt_to_transit_mpo.csv', index = False)"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.9.13"
+ },
+ "widgets": {
+ "application/vnd.jupyter.widget-state+json": {
+ "state": {},
+ "version_major": 2,
+ "version_minor": 0
+ }
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/sb125_analyses/vmt_transit_sketch/replica_la_county.ipynb b/sb125_analyses/vmt_transit_sketch/replica_la_county.ipynb
new file mode 100644
index 000000000..2237e32a4
--- /dev/null
+++ b/sb125_analyses/vmt_transit_sketch/replica_la_county.ipynb
@@ -0,0 +1,169 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "1f8bcf0d-3662-4302-a1c2-5a45be405cfa",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import geopandas as gpd\n",
+ "import pandas as pd\n",
+ "from siuba import *\n",
+ "\n",
+ "from calitp_data_analysis import geography_utils"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "3544df1f-5942-4fe1-8a53-ada5dfa1e553",
+ "metadata": {},
+ "source": [
+ "# Custom Geographies to faciliate download"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "5f10e298-958f-46ad-876c-02b8f9a4d2fc",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "URL = \"https://opendata.arcgis.com/datasets/\" \"8713ced9b78a4abb97dc130a691a8695_0.geojson\"\n",
+ "\n",
+ "gdf = gpd.read_file(URL).to_crs(geography_utils.CA_StatePlane)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "id": "da33f24a-1074-49c9-85d5-dfd641e80cd7",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# exclude islands for now\n",
+ "gdf = gdf >> filter(_.ISLAND.isna())"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "id": "5625d1b2-80c2-47d6-925d-ebc99f4a2ddb",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# gdf.explore()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 15,
+ "id": "085d86ed-2046-42a1-805b-a1a7937e6c6f",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "la = gdf >> filter(_.COUNTY_NAME == 'Los Angeles')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 13,
+ "id": "3b22101a-53b4-4516-be76-045217bb5ce0",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "la_mask = gpd.read_file('./la_mask.geojson').to_crs(geography_utils.CA_StatePlane)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 19,
+ "id": "02356776-51da-41ab-8811-35bd9f689ee8",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "southbay = la.clip(la_mask)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 21,
+ "id": "31725fa3-a220-4b9f-83b1-a1b1874775d4",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "southbay['zone'] = 'la_southbay'\n",
+ "\n",
+ "southbay = southbay[['zone', 'geometry']]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 22,
+ "id": "12fcedb0-079d-4786-a9c3-5251b389787b",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "non_southbay = la.overlay(la_mask, how='difference')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 23,
+ "id": "3b002399-7999-46d0-9575-a27b193bcdbe",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "non_southbay['zone'] = 'la_other'\n",
+ "\n",
+ "non_southbay = non_southbay[['zone', 'geometry']]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 24,
+ "id": "76e015a6-b8fb-482a-8bf2-2c793741433e",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "pd.concat([southbay, non_southbay]).to_file('la.geojson')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "5334bb35-9395-4f0c-8f9d-5d2bbdba0131",
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.9.13"
+ },
+ "widgets": {
+ "application/vnd.jupyter.widget-state+json": {
+ "state": {},
+ "version_major": 2,
+ "version_minor": 0
+ }
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/sb125_analyses/vmt_transit_sketch/stops_by_tract_agency.ipynb b/sb125_analyses/vmt_transit_sketch/stops_by_tract_agency.ipynb
new file mode 100644
index 000000000..fa0086441
--- /dev/null
+++ b/sb125_analyses/vmt_transit_sketch/stops_by_tract_agency.ipynb
@@ -0,0 +1,679 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "id": "fb2a05d3-43f5-4f43-aeb8-c99154742cf3",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "os.environ[\"CALITP_BQ_MAX_BYTES\"] = str(800_000_000_000)\n",
+ "\n",
+ "from calitp_data_analysis.tables import tbls\n",
+ "\n",
+ "import pandas as pd\n",
+ "import geopandas as gpd\n",
+ "from siuba import *\n",
+ "\n",
+ "import shared_utils"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 17,
+ "id": "87cd3826-9ffa-4967-a7b9-f4e0a13f8fea",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "/opt/conda/lib/python3.9/site-packages/sqlalchemy_bigquery/_types.py:101: SAWarning: Did not recognize type 'GEOGRAPHY' of column 'pt_geom'\n",
+ " sqlalchemy.util.warn(\n"
+ ]
+ }
+ ],
+ "source": [
+ "stops = (tbls.mart_gtfs.fct_daily_scheduled_stops()\n",
+ " >> filter(_.service_date == '2023-09-13')\n",
+ " >> select(_.service_date, _.feed_key, _.stop_id,\n",
+ " _.pt_geom)\n",
+ " >> collect()\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 18,
+ "id": "bfedf45a-4432-48ce-93e4-e7bd9ca52c88",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "stops = gpd.GeoDataFrame(stops,\n",
+ " geometry=gpd.geoseries.from_wkt(stops['pt_geom'].to_numpy()),\n",
+ " crs='EPSG:4326') >> select(-_.pt_geom)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 19,
+ "id": "020d6db2-3db1-4236-bef3-b1d7cb6b5e76",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " service_date \n",
+ " feed_key \n",
+ " stop_id \n",
+ " geometry \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 \n",
+ " 2023-09-13 \n",
+ " b45b85ee42cd6a4311beab4aaf7e09d8 \n",
+ " 29340 \n",
+ " POINT (-120.46339 36.86854) \n",
+ " \n",
+ " \n",
+ " 1 \n",
+ " 2023-09-13 \n",
+ " b45b85ee42cd6a4311beab4aaf7e09d8 \n",
+ " 29343 \n",
+ " POINT (-120.45270 36.85343) \n",
+ " \n",
+ " \n",
+ " 2 \n",
+ " 2023-09-13 \n",
+ " b45b85ee42cd6a4311beab4aaf7e09d8 \n",
+ " 29344 \n",
+ " POINT (-120.45195 36.85275) \n",
+ " \n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " service_date feed_key stop_id \\\n",
+ "0 2023-09-13 b45b85ee42cd6a4311beab4aaf7e09d8 29340 \n",
+ "1 2023-09-13 b45b85ee42cd6a4311beab4aaf7e09d8 29343 \n",
+ "2 2023-09-13 b45b85ee42cd6a4311beab4aaf7e09d8 29344 \n",
+ "\n",
+ " geometry \n",
+ "0 POINT (-120.46339 36.86854) \n",
+ "1 POINT (-120.45270 36.85343) \n",
+ "2 POINT (-120.45195 36.85275) "
+ ]
+ },
+ "execution_count": 19,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "stops >> head(3)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "id": "01ea2314-0a85-4763-8d75-b88d58316dc7",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "(119150, 4)"
+ ]
+ },
+ "execution_count": 12,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "stops.shape"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 13,
+ "id": "44720400-e450-45aa-910e-8bbe35a4bea3",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# (stops >> head(1000) >> select(-_.service_date)).explore()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "0aeb9be7-4fec-4c1a-94f4-53ba0ffaf5cc",
+ "metadata": {
+ "collapsed": true,
+ "jupyter": {
+ "outputs_hidden": true
+ },
+ "tags": []
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Collecting pygris\n",
+ " Downloading pygris-0.1.6-py3-none-any.whl (55 kB)\n",
+ "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m55.7/55.7 kB\u001b[0m \u001b[31m873.6 kB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m \u001b[36m0:00:01\u001b[0m\n",
+ "\u001b[?25hRequirement already satisfied: requests in /opt/conda/lib/python3.9/site-packages (from pygris) (2.31.0)\n",
+ "Requirement already satisfied: shapely in /opt/conda/lib/python3.9/site-packages (from pygris) (2.0.1)\n",
+ "Requirement already satisfied: fiona in /opt/conda/lib/python3.9/site-packages (from pygris) (1.9.4.post1)\n",
+ "Requirement already satisfied: rtree in /opt/conda/lib/python3.9/site-packages (from pygris) (0.9.7)\n",
+ "Requirement already satisfied: pandas in /opt/conda/lib/python3.9/site-packages (from pygris) (1.5.3)\n",
+ "Requirement already satisfied: appdirs in /opt/conda/lib/python3.9/site-packages (from pygris) (1.4.4)\n",
+ "Requirement already satisfied: geopandas>=0.9 in /opt/conda/lib/python3.9/site-packages (from pygris) (0.14.0)\n",
+ "Requirement already satisfied: numpy in /opt/conda/lib/python3.9/site-packages (from pygris) (1.23.5)\n",
+ "Requirement already satisfied: pip in /opt/conda/lib/python3.9/site-packages (from pygris) (22.2.2)\n",
+ "Requirement already satisfied: packaging in /opt/conda/lib/python3.9/site-packages (from geopandas>=0.9->pygris) (23.1)\n",
+ "Requirement already satisfied: pyproj>=3.3.0 in /opt/conda/lib/python3.9/site-packages (from geopandas>=0.9->pygris) (3.6.0)\n",
+ "Requirement already satisfied: cligj>=0.5 in /opt/conda/lib/python3.9/site-packages (from fiona->pygris) (0.7.2)\n",
+ "Requirement already satisfied: click~=8.0 in /opt/conda/lib/python3.9/site-packages (from fiona->pygris) (8.1.6)\n",
+ "Requirement already satisfied: certifi in /opt/conda/lib/python3.9/site-packages (from fiona->pygris) (2023.7.22)\n",
+ "Requirement already satisfied: six in /opt/conda/lib/python3.9/site-packages (from fiona->pygris) (1.16.0)\n",
+ "Requirement already satisfied: attrs>=19.2.0 in /opt/conda/lib/python3.9/site-packages (from fiona->pygris) (21.4.0)\n",
+ "Requirement already satisfied: click-plugins>=1.0 in /opt/conda/lib/python3.9/site-packages (from fiona->pygris) (1.1.1)\n",
+ "Requirement already satisfied: importlib-metadata in /opt/conda/lib/python3.9/site-packages (from fiona->pygris) (6.8.0)\n",
+ "Requirement already satisfied: python-dateutil>=2.8.1 in /opt/conda/lib/python3.9/site-packages (from pandas->pygris) (2.8.2)\n",
+ "Requirement already satisfied: pytz>=2020.1 in /opt/conda/lib/python3.9/site-packages (from pandas->pygris) (2023.3)\n",
+ "Requirement already satisfied: urllib3<3,>=1.21.1 in /opt/conda/lib/python3.9/site-packages (from requests->pygris) (1.26.18)\n",
+ "Requirement already satisfied: idna<4,>=2.5 in /opt/conda/lib/python3.9/site-packages (from requests->pygris) (3.4)\n",
+ "Requirement already satisfied: charset-normalizer<4,>=2 in /opt/conda/lib/python3.9/site-packages (from requests->pygris) (3.2.0)\n",
+ "Requirement already satisfied: zipp>=0.5 in /opt/conda/lib/python3.9/site-packages (from importlib-metadata->fiona->pygris) (3.16.2)\n",
+ "Installing collected packages: pygris\n",
+ "Successfully installed pygris-0.1.6\n"
+ ]
+ }
+ ],
+ "source": [
+ "! pip install pygris"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "fd4da62d-b1ab-41fa-b778-0ac7afeda451",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import pygris"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "id": "9ea24b20-6069-4453-a30f-78a0d74f7a85",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Using the default year of 2021\n"
+ ]
+ }
+ ],
+ "source": [
+ "uza = pygris.urban_areas()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 31,
+ "id": "d03c436a-cb22-416c-acc7-c2dd70f838b6",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "ca_uza = uza >> filter(_.NAME10.str.contains('CA'))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 13,
+ "id": "541bfaa1-328e-45be-8bb8-5dfa6d84a098",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "ca_tracts = pygris.tracts(state='CA', year=2020)\n",
+ "\n",
+ "ca_tracts = ca_tracts >> select(_.GEOID, _.geometry)\n",
+ "\n",
+ "ca_tracts = ca_tracts.to_crs(shared_utils.geography_utils.CA_NAD83Albers)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 20,
+ "id": "0dad5f52-2b6d-4329-82ad-bfd4b88292b1",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "stops = stops.to_crs(shared_utils.geography_utils.CA_NAD83Albers)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 21,
+ "id": "4b060f23-b35d-49ee-a630-4e17537866d9",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " service_date \n",
+ " feed_key \n",
+ " stop_id \n",
+ " geometry \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 \n",
+ " 2023-09-13 \n",
+ " b45b85ee42cd6a4311beab4aaf7e09d8 \n",
+ " 29340 \n",
+ " POINT (-41252.686 -127493.402) \n",
+ " \n",
+ " \n",
+ " 1 \n",
+ " 2023-09-13 \n",
+ " b45b85ee42cd6a4311beab4aaf7e09d8 \n",
+ " 29343 \n",
+ " POINT (-40309.757 -129177.891) \n",
+ " \n",
+ " \n",
+ " 2 \n",
+ " 2023-09-13 \n",
+ " b45b85ee42cd6a4311beab4aaf7e09d8 \n",
+ " 29344 \n",
+ " POINT (-40242.891 -129253.681) \n",
+ " \n",
+ " \n",
+ " 3 \n",
+ " 2023-09-13 \n",
+ " b45b85ee42cd6a4311beab4aaf7e09d8 \n",
+ " 29347 \n",
+ " POINT (-34017.110 -140003.552) \n",
+ " \n",
+ " \n",
+ " 4 \n",
+ " 2023-09-13 \n",
+ " b45b85ee42cd6a4311beab4aaf7e09d8 \n",
+ " 29348 \n",
+ " POINT (-34004.854 -139993.376) \n",
+ " \n",
+ " \n",
+ " ... \n",
+ " ... \n",
+ " ... \n",
+ " ... \n",
+ " ... \n",
+ " \n",
+ " \n",
+ " 119145 \n",
+ " 2023-09-13 \n",
+ " 7519b1626b959b0fc517692b19431065 \n",
+ " 2611973 \n",
+ " POINT (-83917.665 72237.829) \n",
+ " \n",
+ " \n",
+ " 119146 \n",
+ " 2023-09-13 \n",
+ " 7519b1626b959b0fc517692b19431065 \n",
+ " 782799 \n",
+ " POINT (-92741.321 70695.418) \n",
+ " \n",
+ " \n",
+ " 119147 \n",
+ " 2023-09-13 \n",
+ " 7519b1626b959b0fc517692b19431065 \n",
+ " 782761 \n",
+ " POINT (-72120.851 76963.261) \n",
+ " \n",
+ " \n",
+ " 119148 \n",
+ " 2023-09-13 \n",
+ " 7519b1626b959b0fc517692b19431065 \n",
+ " 782795 \n",
+ " POINT (-86800.440 71821.263) \n",
+ " \n",
+ " \n",
+ " 119149 \n",
+ " 2023-09-13 \n",
+ " 7519b1626b959b0fc517692b19431065 \n",
+ " 782729 \n",
+ " POINT (-68556.244 79949.100) \n",
+ " \n",
+ " \n",
+ "
\n",
+ "
119150 rows × 4 columns
\n",
+ "
"
+ ],
+ "text/plain": [
+ " service_date feed_key stop_id \\\n",
+ "0 2023-09-13 b45b85ee42cd6a4311beab4aaf7e09d8 29340 \n",
+ "1 2023-09-13 b45b85ee42cd6a4311beab4aaf7e09d8 29343 \n",
+ "2 2023-09-13 b45b85ee42cd6a4311beab4aaf7e09d8 29344 \n",
+ "3 2023-09-13 b45b85ee42cd6a4311beab4aaf7e09d8 29347 \n",
+ "4 2023-09-13 b45b85ee42cd6a4311beab4aaf7e09d8 29348 \n",
+ "... ... ... ... \n",
+ "119145 2023-09-13 7519b1626b959b0fc517692b19431065 2611973 \n",
+ "119146 2023-09-13 7519b1626b959b0fc517692b19431065 782799 \n",
+ "119147 2023-09-13 7519b1626b959b0fc517692b19431065 782761 \n",
+ "119148 2023-09-13 7519b1626b959b0fc517692b19431065 782795 \n",
+ "119149 2023-09-13 7519b1626b959b0fc517692b19431065 782729 \n",
+ "\n",
+ " geometry \n",
+ "0 POINT (-41252.686 -127493.402) \n",
+ "1 POINT (-40309.757 -129177.891) \n",
+ "2 POINT (-40242.891 -129253.681) \n",
+ "3 POINT (-34017.110 -140003.552) \n",
+ "4 POINT (-34004.854 -139993.376) \n",
+ "... ... \n",
+ "119145 POINT (-83917.665 72237.829) \n",
+ "119146 POINT (-92741.321 70695.418) \n",
+ "119147 POINT (-72120.851 76963.261) \n",
+ "119148 POINT (-86800.440 71821.263) \n",
+ "119149 POINT (-68556.244 79949.100) \n",
+ "\n",
+ "[119150 rows x 4 columns]"
+ ]
+ },
+ "execution_count": 21,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "stops"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 23,
+ "id": "3c503592-c647-494c-8a93-5ed966401d1b",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "stops_in_tract = gpd.sjoin(ca_tracts, stops)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 24,
+ "id": "b4c8ec4e-fe36-42fe-9723-9787ba6ac167",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "tracts_and_feeds = stops_in_tract >> distinct(_.GEOID, _.geometry, _.feed_key)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 25,
+ "id": "f78ab658-cd50-45a1-8a0b-bdf5b19d22ca",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " GEOID \n",
+ " geometry \n",
+ " feed_key \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 \n",
+ " 06029004402 \n",
+ " POLYGON ((59906.842 -270407.558, 59906.948 -27... \n",
+ " 88fde0226aecc4b91a3900f52214f03b \n",
+ " \n",
+ " \n",
+ " 1 \n",
+ " 06029004402 \n",
+ " POLYGON ((59906.842 -270407.558, 59906.948 -27... \n",
+ " c13333e968e573c9decd68bc7fc2555d \n",
+ " \n",
+ " \n",
+ " 2 \n",
+ " 06047000802 \n",
+ " POLYGON ((-52727.332 -74888.681, -52723.908 -7... \n",
+ " 7a4bf0aaccd7aa130db46358ebdb5c26 \n",
+ " \n",
+ " \n",
+ " 3 \n",
+ " 06085501402 \n",
+ " POLYGON ((-165759.786 -73091.934, -165741.347 ... \n",
+ " 371141abbbf8d5e3a42694a3a3959747 \n",
+ " \n",
+ " \n",
+ " 4 \n",
+ " 06085501402 \n",
+ " POLYGON ((-165759.786 -73091.934, -165741.347 ... \n",
+ " eb9f5e395e946e3e6b8ed4b43c820e72 \n",
+ " \n",
+ " \n",
+ " ... \n",
+ " ... \n",
+ " ... \n",
+ " ... \n",
+ " \n",
+ " \n",
+ " 14807 \n",
+ " 06013338101 \n",
+ " POLYGON ((-180031.401 -5698.046, -179998.229 -... \n",
+ " fbf82b1f92575cb511fd97db46a0562a \n",
+ " \n",
+ " \n",
+ " 14808 \n",
+ " 06013338101 \n",
+ " POLYGON ((-180031.401 -5698.046, -179998.229 -... \n",
+ " a80da65523070e82301e8990873fd9c4 \n",
+ " \n",
+ " \n",
+ " 14809 \n",
+ " 06013338102 \n",
+ " POLYGON ((-180162.918 -6902.976, -180150.812 -... \n",
+ " fbf82b1f92575cb511fd97db46a0562a \n",
+ " \n",
+ " \n",
+ " 14810 \n",
+ " 06013338102 \n",
+ " POLYGON ((-180162.918 -6902.976, -180150.812 -... \n",
+ " a80da65523070e82301e8990873fd9c4 \n",
+ " \n",
+ " \n",
+ " 14811 \n",
+ " 06013338102 \n",
+ " POLYGON ((-180162.918 -6902.976, -180150.812 -... \n",
+ " eb9f5e395e946e3e6b8ed4b43c820e72 \n",
+ " \n",
+ " \n",
+ "
\n",
+ "
14812 rows × 3 columns
\n",
+ "
"
+ ],
+ "text/plain": [
+ " GEOID geometry \\\n",
+ "0 06029004402 POLYGON ((59906.842 -270407.558, 59906.948 -27... \n",
+ "1 06029004402 POLYGON ((59906.842 -270407.558, 59906.948 -27... \n",
+ "2 06047000802 POLYGON ((-52727.332 -74888.681, -52723.908 -7... \n",
+ "3 06085501402 POLYGON ((-165759.786 -73091.934, -165741.347 ... \n",
+ "4 06085501402 POLYGON ((-165759.786 -73091.934, -165741.347 ... \n",
+ "... ... ... \n",
+ "14807 06013338101 POLYGON ((-180031.401 -5698.046, -179998.229 -... \n",
+ "14808 06013338101 POLYGON ((-180031.401 -5698.046, -179998.229 -... \n",
+ "14809 06013338102 POLYGON ((-180162.918 -6902.976, -180150.812 -... \n",
+ "14810 06013338102 POLYGON ((-180162.918 -6902.976, -180150.812 -... \n",
+ "14811 06013338102 POLYGON ((-180162.918 -6902.976, -180150.812 -... \n",
+ "\n",
+ " feed_key \n",
+ "0 88fde0226aecc4b91a3900f52214f03b \n",
+ "1 c13333e968e573c9decd68bc7fc2555d \n",
+ "2 7a4bf0aaccd7aa130db46358ebdb5c26 \n",
+ "3 371141abbbf8d5e3a42694a3a3959747 \n",
+ "4 eb9f5e395e946e3e6b8ed4b43c820e72 \n",
+ "... ... \n",
+ "14807 fbf82b1f92575cb511fd97db46a0562a \n",
+ "14808 a80da65523070e82301e8990873fd9c4 \n",
+ "14809 fbf82b1f92575cb511fd97db46a0562a \n",
+ "14810 a80da65523070e82301e8990873fd9c4 \n",
+ "14811 eb9f5e395e946e3e6b8ed4b43c820e72 \n",
+ "\n",
+ "[14812 rows x 3 columns]"
+ ]
+ },
+ "execution_count": 25,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "tracts_and_feeds"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 28,
+ "id": "8b8ded78-3f6e-4418-b938-b32d1bc04b14",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# (tracts_and_feeds >> distinct(_.geometry)).explore()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 26,
+ "id": "a878d2ae-1c58-4e80-b094-c6348cc48a4a",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "tracts_and_feeds.to_parquet('intermediate/feeds_tract_geo.parquet')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 34,
+ "id": "fb0b7039-7b07-493e-b4f9-40a53114dd84",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "ca_uza = ca_uza >> select(_.UACE10, _.NAME10, _.geometry)\n",
+ "ca_uza = ca_uza.to_crs(shared_utils.geography_utils.CA_NAD83Albers)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 35,
+ "id": "9bfb62a2-8909-4df4-92a5-8dd52c2f9d74",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "ca_uza.to_parquet('intermediate/ca_uza.parquet')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "1c4982b2-c195-4acd-8877-9352f44568aa",
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.9.13"
+ },
+ "widgets": {
+ "application/vnd.jupyter.widget-state+json": {
+ "state": {},
+ "version_major": 2,
+ "version_minor": 0
+ }
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/sb125_analyses/vmt_transit_sketch/tract_factors.ipynb b/sb125_analyses/vmt_transit_sketch/tract_factors.ipynb
new file mode 100644
index 000000000..a134c14eb
--- /dev/null
+++ b/sb125_analyses/vmt_transit_sketch/tract_factors.ipynb
@@ -0,0 +1,733 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "f0ed1b30-854b-4622-8831-688b5007c850",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "os.environ[\"CALITP_BQ_MAX_BYTES\"] = str(800_000_000_000)\n",
+ "\n",
+ "from calitp_data_analysis.tables import tbls\n",
+ "\n",
+ "import pandas as pd\n",
+ "import geopandas as gpd\n",
+ "from siuba import *\n",
+ "\n",
+ "import shared_utils"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "1fce0724-f256-47ee-a597-57213e4fb5f7",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "shares = pd.read_parquet('intermediate/draft_ntd_market_shares.parquet')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "f54675ad-3e94-4ccf-a083-6b7a9ce9038c",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "tracts_and_feeds = gpd.read_parquet('intermediate/feeds_tract_geo.parquet')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "id": "8ed1014c-4e35-44e3-be23-2da62187d0ab",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "Index(['GEOID', 'geometry', 'feed_key'], dtype='object')"
+ ]
+ },
+ "execution_count": 9,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "tracts_and_feeds.columns"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 16,
+ "id": "3e72f814-d231-4a81-b051-fa86ddd5e0d4",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "dim_feeds = (tbls.mart_gtfs.dim_schedule_feeds() >> filter(_.key.isin(tracts_and_feeds.feed_key))\n",
+ " >> select(_.key, _.base64_url) >> rename(feed_key = _.key)\n",
+ " >> inner_join(_, tbls.mart_transit_database.dim_gtfs_datasets(), on = 'base64_url')\n",
+ " >> inner_join(_, tbls.mart_transit_database.dim_gtfs_service_data(), on = {'key': 'gtfs_dataset_key'})\n",
+ " >> select(_.feed_key, _.base64_url, \n",
+ " # >> collect()\n",
+ " )"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 17,
+ "id": "3f24be23-8112-49f9-a831-1b0d81f682c9",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "# Source: lazy query\n",
+ "# DB Conn: Engine(bigquery://cal-itp-data-infra/?maximum_bytes_billed=800000000000)\n",
+ "# Preview:\n",
+ " \n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " feed_key \n",
+ " base64_url \n",
+ " name \n",
+ " manual_check__link_to_dataset_on_website \n",
+ " manual_check__data_license \n",
+ " manual_check__authentication_acceptable \n",
+ " future_uri \n",
+ " uri \n",
+ " source_record_id \n",
+ " _is_current \n",
+ " ... \n",
+ " manual_check__grading_scheme_v1 \n",
+ " manual_check__localized_stop_tts \n",
+ " manual_check__stable_url \n",
+ " data_quality_pipeline \n",
+ " key \n",
+ " _valid_from \n",
+ " deprecated_date \n",
+ " type \n",
+ " backdated_regional_feed_type \n",
+ " regional_feed_type \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 \n",
+ " 0f6a1bef113617f84786d46d49303a4b \n",
+ " aHR0cHM6Ly9kYXRhLnRyaWxsaXVtdHJhbnNpdC5jb20vZ3... \n",
+ " Spirit Bus Schedule \n",
+ " No \n",
+ " Missing \n",
+ " Yes \n",
+ " None \n",
+ " https://data.trilliumtransit.com/gtfs/monterey... \n",
+ " recy14T38x2kl8n7K \n",
+ " False \n",
+ " ... \n",
+ " Unknown \n",
+ " Unknown \n",
+ " Yes - Vendor Website \n",
+ " True \n",
+ " 6d1d4573fa4905d7ad736e1bad59785d \n",
+ " 2023-03-15 00:00:00+00:00 \n",
+ " None \n",
+ " schedule \n",
+ " None \n",
+ " None \n",
+ " \n",
+ " \n",
+ " 1 \n",
+ " 0f6a1bef113617f84786d46d49303a4b \n",
+ " aHR0cHM6Ly9kYXRhLnRyaWxsaXVtdHJhbnNpdC5jb20vZ3... \n",
+ " Spirit Bus Schedule \n",
+ " Unknown \n",
+ " Unknown \n",
+ " Yes \n",
+ " None \n",
+ " https://data.trilliumtransit.com/gtfs/monterey... \n",
+ " recy14T38x2kl8n7K \n",
+ " False \n",
+ " ... \n",
+ " Unknown \n",
+ " Unknown \n",
+ " Yes \n",
+ " True \n",
+ " 61f86b62265214bf83b99574e156afd4 \n",
+ " 2022-10-26 00:00:00+00:00 \n",
+ " None \n",
+ " schedule \n",
+ " None \n",
+ " None \n",
+ " \n",
+ " \n",
+ " 2 \n",
+ " 0f6a1bef113617f84786d46d49303a4b \n",
+ " aHR0cHM6Ly9kYXRhLnRyaWxsaXVtdHJhbnNpdC5jb20vZ3... \n",
+ " Spirit Bus Schedule Historic \n",
+ " No \n",
+ " Missing \n",
+ " Yes \n",
+ " None \n",
+ " https://data.trilliumtransit.com/gtfs/monterey... \n",
+ " recy14T38x2kl8n7K \n",
+ " True \n",
+ " ... \n",
+ " Unknown \n",
+ " Unknown \n",
+ " Yes - Vendor Website \n",
+ " None \n",
+ " 8363a7be8f2519ea5d9c33abeaa153d9 \n",
+ " 2024-01-06 00:00:00+00:00 \n",
+ " 2024-01-05 \n",
+ " schedule \n",
+ " None \n",
+ " None \n",
+ " \n",
+ " \n",
+ " 3 \n",
+ " 0f6a1bef113617f84786d46d49303a4b \n",
+ " aHR0cHM6Ly9kYXRhLnRyaWxsaXVtdHJhbnNpdC5jb20vZ3... \n",
+ " Spirit Bus Schedule \n",
+ " Unknown \n",
+ " Unknown \n",
+ " Yes \n",
+ " None \n",
+ " https://data.trilliumtransit.com/gtfs/monterey... \n",
+ " recy14T38x2kl8n7K \n",
+ " False \n",
+ " ... \n",
+ " Unknown \n",
+ " Unknown \n",
+ " Yes - Vendor Website \n",
+ " True \n",
+ " ba500c92bfce3a73bee6262c4c7a6bea \n",
+ " 2022-11-22 00:00:00+00:00 \n",
+ " None \n",
+ " schedule \n",
+ " None \n",
+ " None \n",
+ " \n",
+ " \n",
+ " 4 \n",
+ " 294252b3b4b42fbb31a31ce184fcb3f5 \n",
+ " aHR0cHM6Ly9pcG9ydGFsLnNhY3J0LmNvbS9HVEZTL1NSVE... \n",
+ " Sacramento Schedule \n",
+ " Unknown \n",
+ " Unknown \n",
+ " Yes \n",
+ " None \n",
+ " https://iportal.sacrt.com/GTFS/SRTD/google_tra... \n",
+ " recbzZQUIdMmFvm1r \n",
+ " False \n",
+ " ... \n",
+ " Unknown \n",
+ " Unknown \n",
+ " Yes - Provider Website \n",
+ " True \n",
+ " ae1c2f25d0d162bf2a0e90527a8eecec \n",
+ " 2023-01-19 00:00:00+00:00 \n",
+ " None \n",
+ " schedule \n",
+ " None \n",
+ " None \n",
+ " \n",
+ " \n",
+ "
\n",
+ "
5 rows × 22 columns
\n",
+ "
# .. may have more rows
"
+ ],
+ "text/plain": [
+ "# Source: lazy query\n",
+ "# DB Conn: Engine(bigquery://cal-itp-data-infra/?maximum_bytes_billed=800000000000)\n",
+ "# Preview:\n",
+ " feed_key \\\n",
+ "0 0f6a1bef113617f84786d46d49303a4b \n",
+ "1 0f6a1bef113617f84786d46d49303a4b \n",
+ "2 0f6a1bef113617f84786d46d49303a4b \n",
+ "3 0f6a1bef113617f84786d46d49303a4b \n",
+ "4 294252b3b4b42fbb31a31ce184fcb3f5 \n",
+ "\n",
+ " base64_url \\\n",
+ "0 aHR0cHM6Ly9kYXRhLnRyaWxsaXVtdHJhbnNpdC5jb20vZ3... \n",
+ "1 aHR0cHM6Ly9kYXRhLnRyaWxsaXVtdHJhbnNpdC5jb20vZ3... \n",
+ "2 aHR0cHM6Ly9kYXRhLnRyaWxsaXVtdHJhbnNpdC5jb20vZ3... \n",
+ "3 aHR0cHM6Ly9kYXRhLnRyaWxsaXVtdHJhbnNpdC5jb20vZ3... \n",
+ "4 aHR0cHM6Ly9pcG9ydGFsLnNhY3J0LmNvbS9HVEZTL1NSVE... \n",
+ "\n",
+ " name manual_check__link_to_dataset_on_website \\\n",
+ "0 Spirit Bus Schedule No \n",
+ "1 Spirit Bus Schedule Unknown \n",
+ "2 Spirit Bus Schedule Historic No \n",
+ "3 Spirit Bus Schedule Unknown \n",
+ "4 Sacramento Schedule Unknown \n",
+ "\n",
+ " manual_check__data_license manual_check__authentication_acceptable \\\n",
+ "0 Missing Yes \n",
+ "1 Unknown Yes \n",
+ "2 Missing Yes \n",
+ "3 Unknown Yes \n",
+ "4 Unknown Yes \n",
+ "\n",
+ " future_uri uri \\\n",
+ "0 None https://data.trilliumtransit.com/gtfs/monterey... \n",
+ "1 None https://data.trilliumtransit.com/gtfs/monterey... \n",
+ "2 None https://data.trilliumtransit.com/gtfs/monterey... \n",
+ "3 None https://data.trilliumtransit.com/gtfs/monterey... \n",
+ "4 None https://iportal.sacrt.com/GTFS/SRTD/google_tra... \n",
+ "\n",
+ " source_record_id _is_current ... manual_check__grading_scheme_v1 \\\n",
+ "0 recy14T38x2kl8n7K False ... Unknown \n",
+ "1 recy14T38x2kl8n7K False ... Unknown \n",
+ "2 recy14T38x2kl8n7K True ... Unknown \n",
+ "3 recy14T38x2kl8n7K False ... Unknown \n",
+ "4 recbzZQUIdMmFvm1r False ... Unknown \n",
+ "\n",
+ " manual_check__localized_stop_tts manual_check__stable_url \\\n",
+ "0 Unknown Yes - Vendor Website \n",
+ "1 Unknown Yes \n",
+ "2 Unknown Yes - Vendor Website \n",
+ "3 Unknown Yes - Vendor Website \n",
+ "4 Unknown Yes - Provider Website \n",
+ "\n",
+ " data_quality_pipeline key \\\n",
+ "0 True 6d1d4573fa4905d7ad736e1bad59785d \n",
+ "1 True 61f86b62265214bf83b99574e156afd4 \n",
+ "2 None 8363a7be8f2519ea5d9c33abeaa153d9 \n",
+ "3 True ba500c92bfce3a73bee6262c4c7a6bea \n",
+ "4 True ae1c2f25d0d162bf2a0e90527a8eecec \n",
+ "\n",
+ " _valid_from deprecated_date type \\\n",
+ "0 2023-03-15 00:00:00+00:00 None schedule \n",
+ "1 2022-10-26 00:00:00+00:00 None schedule \n",
+ "2 2024-01-06 00:00:00+00:00 2024-01-05 schedule \n",
+ "3 2022-11-22 00:00:00+00:00 None schedule \n",
+ "4 2023-01-19 00:00:00+00:00 None schedule \n",
+ "\n",
+ " backdated_regional_feed_type regional_feed_type \n",
+ "0 None None \n",
+ "1 None None \n",
+ "2 None None \n",
+ "3 None None \n",
+ "4 None None \n",
+ "\n",
+ "[5 rows x 22 columns]\n",
+ "# .. may have more rows"
+ ]
+ },
+ "execution_count": 17,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "dim_feeds"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "id": "b9ef5c89-2a6a-4ba8-9afb-d2e2ab5c3e21",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "service_data = tbls.mart_transit_database.dim_gtfs_service_data() >> filter(_._is_current) >> collect()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "id": "36a316b7-5780-473f-9a5c-ec1f0d5c4499",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " key \n",
+ " name \n",
+ " source_record_id \n",
+ " service_key \n",
+ " gtfs_dataset_key \n",
+ " customer_facing \n",
+ " category \n",
+ " fares_v2_status \n",
+ " manual_check__fixed_route_completeness \n",
+ " manual_check__demand_response_completeness \n",
+ " _is_current \n",
+ " _valid_from \n",
+ " _valid_to \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 \n",
+ " 053b17e1360817ecf1b5a21e16126484 \n",
+ " MVGO – MVGO Alerts \n",
+ " recI99XuoZfQb7Lc4 \n",
+ " a844f7b4ebfcf2833e87260bf3447bed \n",
+ " 088fbeac48abfeda62a9398392675145 \n",
+ " False \n",
+ " None \n",
+ " [] \n",
+ " None \n",
+ " None \n",
+ " True \n",
+ " 2023-12-12 00:00:00+00:00 \n",
+ " 2098-12-31 23:59:59.999999+00:00 \n",
+ " \n",
+ " \n",
+ " 1 \n",
+ " b124745e67e5c8acd80fc80d1064fd04 \n",
+ " B-Line – B-Line Alerts \n",
+ " recHtX7WV7H5gZRwd \n",
+ " d584928c5feaa1accef0859f74a058f8 \n",
+ " 8cf9b2748fcc798dca5bdad2c3e2b28f \n",
+ " True \n",
+ " None \n",
+ " [] \n",
+ " None \n",
+ " None \n",
+ " True \n",
+ " 2023-10-26 00:00:00+00:00 \n",
+ " 2098-12-31 23:59:59.999999+00:00 \n",
+ " \n",
+ " \n",
+ " 2 \n",
+ " 2eeb353c5cd9fb78491e95e20c34c571 \n",
+ " FlixBus – Flixbus Schedule \n",
+ " recP2TyODJKLnKfoT \n",
+ " 9daae6a3c07fbed7638796e10def9b9d \n",
+ " a37760dde6b9fdcb76b82e57afab7274 \n",
+ " True \n",
+ " None \n",
+ " [] \n",
+ " None \n",
+ " None \n",
+ " True \n",
+ " 2023-05-18 00:00:00+00:00 \n",
+ " 2098-12-31 23:59:59.999999+00:00 \n",
+ " \n",
+ " \n",
+ " 3 \n",
+ " 3fac05fca33e1c0f7c947fc09c3a9cf4 \n",
+ " Glenn Ride – Glenn Schedule \n",
+ " recah4Ls5Sq2YOMhM \n",
+ " b35a15809e09aa7128945ead98b35bb6 \n",
+ " 72db364f3248e2eb7940bea6ccab1d72 \n",
+ " True \n",
+ " None \n",
+ " [] \n",
+ " None \n",
+ " None \n",
+ " True \n",
+ " 2023-06-13 00:00:00+00:00 \n",
+ " 2098-12-31 23:59:59.999999+00:00 \n",
+ " \n",
+ " \n",
+ " 4 \n",
+ " 3da3f1c40d682726f6004e7dd435599e \n",
+ " B-Line – B-Line Trip Updates \n",
+ " recOm2XjKnk1PdVdA \n",
+ " d584928c5feaa1accef0859f74a058f8 \n",
+ " 99c066f0726f0c9cf117d9754121ee18 \n",
+ " True \n",
+ " None \n",
+ " [] \n",
+ " None \n",
+ " None \n",
+ " True \n",
+ " 2023-10-26 00:00:00+00:00 \n",
+ " 2098-12-31 23:59:59.999999+00:00 \n",
+ " \n",
+ " \n",
+ " ... \n",
+ " ... \n",
+ " ... \n",
+ " ... \n",
+ " ... \n",
+ " ... \n",
+ " ... \n",
+ " ... \n",
+ " ... \n",
+ " ... \n",
+ " ... \n",
+ " ... \n",
+ " ... \n",
+ " ... \n",
+ " \n",
+ " \n",
+ " 844 \n",
+ " f69de35714542a5531fcd1db1c7493d6 \n",
+ " Angel Island-Tiburon Ferry – Bay Area 511 Ange... \n",
+ " recxXDglEfklpKMlM \n",
+ " 643839b344145322d3f98fb19af40557 \n",
+ " 538cd77b8319780a8bf412668f24440d \n",
+ " False \n",
+ " precursor \n",
+ " [] \n",
+ " Unknown \n",
+ " Unknown \n",
+ " True \n",
+ " 2023-10-25 00:00:00+00:00 \n",
+ " 2098-12-31 23:59:59.999999+00:00 \n",
+ " \n",
+ " \n",
+ " 845 \n",
+ " 570a2604a28cb0f80cb6cec2a9c1bd2d \n",
+ " Tahoe Truckee Area Regional Transportation – \"... \n",
+ " recmJSB9leIMYkoGP \n",
+ " e16b334aa0877fa87ff3441bbaad3e93 \n",
+ " 6fda78099793184fe08dd78945d188c0 \n",
+ " True \n",
+ " primary \n",
+ " [Vendor published, Fares v2 updates in progres... \n",
+ " Unknown \n",
+ " Unknown \n",
+ " True \n",
+ " 2023-10-25 00:00:00+00:00 \n",
+ " 2098-12-31 23:59:59.999999+00:00 \n",
+ " \n",
+ " \n",
+ " 846 \n",
+ " 0a39061670ba6d033e0b35d040dd21a2 \n",
+ " Fairfield and Suisun Transit – Bay Area 511 Fa... \n",
+ " recJqXfXgmFD5wA5X \n",
+ " 2621745b8b20cb8dbf4445049ad14bda \n",
+ " 0f5e1b251db53223200c5bfc365d33f2 \n",
+ " False \n",
+ " precursor \n",
+ " [] \n",
+ " Unknown \n",
+ " Unknown \n",
+ " True \n",
+ " 2023-10-26 00:00:00+00:00 \n",
+ " 2098-12-31 23:59:59.999999+00:00 \n",
+ " \n",
+ " \n",
+ " 847 \n",
+ " 235b09a3eabfe58660864a8426e14c54 \n",
+ " Antelope Valley Transportation Authority – Ant... \n",
+ " recCXo3GZl7eEYJDL \n",
+ " 8d62a5cec6fbb88a455322a60cf8dbef \n",
+ " e681c3a8dafa2c80e5b8e2cdd01f917a \n",
+ " True \n",
+ " primary \n",
+ " [] \n",
+ " Complete \n",
+ " Unknown \n",
+ " True \n",
+ " 2023-10-25 00:00:00+00:00 \n",
+ " 2098-12-31 23:59:59.999999+00:00 \n",
+ " \n",
+ " \n",
+ " 848 \n",
+ " 1f08852db785e207ef9ce9c456d48d71 \n",
+ " Sonoma-Marin Area Rail Transit – Bay Area 511 ... \n",
+ " recHO4NlaASWhISxE \n",
+ " 64c1a0b079d63559e2cc81e28e195372 \n",
+ " 0881af3822466784992a49f1cc57d38f \n",
+ " False \n",
+ " precursor \n",
+ " [] \n",
+ " Unknown \n",
+ " Unknown \n",
+ " True \n",
+ " 2023-10-26 00:00:00+00:00 \n",
+ " 2098-12-31 23:59:59.999999+00:00 \n",
+ " \n",
+ " \n",
+ "
\n",
+ "
849 rows × 13 columns
\n",
+ "
"
+ ],
+ "text/plain": [
+ " key \\\n",
+ "0 053b17e1360817ecf1b5a21e16126484 \n",
+ "1 b124745e67e5c8acd80fc80d1064fd04 \n",
+ "2 2eeb353c5cd9fb78491e95e20c34c571 \n",
+ "3 3fac05fca33e1c0f7c947fc09c3a9cf4 \n",
+ "4 3da3f1c40d682726f6004e7dd435599e \n",
+ ".. ... \n",
+ "844 f69de35714542a5531fcd1db1c7493d6 \n",
+ "845 570a2604a28cb0f80cb6cec2a9c1bd2d \n",
+ "846 0a39061670ba6d033e0b35d040dd21a2 \n",
+ "847 235b09a3eabfe58660864a8426e14c54 \n",
+ "848 1f08852db785e207ef9ce9c456d48d71 \n",
+ "\n",
+ " name source_record_id \\\n",
+ "0 MVGO – MVGO Alerts recI99XuoZfQb7Lc4 \n",
+ "1 B-Line – B-Line Alerts recHtX7WV7H5gZRwd \n",
+ "2 FlixBus – Flixbus Schedule recP2TyODJKLnKfoT \n",
+ "3 Glenn Ride – Glenn Schedule recah4Ls5Sq2YOMhM \n",
+ "4 B-Line – B-Line Trip Updates recOm2XjKnk1PdVdA \n",
+ ".. ... ... \n",
+ "844 Angel Island-Tiburon Ferry – Bay Area 511 Ange... recxXDglEfklpKMlM \n",
+ "845 Tahoe Truckee Area Regional Transportation – \"... recmJSB9leIMYkoGP \n",
+ "846 Fairfield and Suisun Transit – Bay Area 511 Fa... recJqXfXgmFD5wA5X \n",
+ "847 Antelope Valley Transportation Authority – Ant... recCXo3GZl7eEYJDL \n",
+ "848 Sonoma-Marin Area Rail Transit – Bay Area 511 ... recHO4NlaASWhISxE \n",
+ "\n",
+ " service_key gtfs_dataset_key \\\n",
+ "0 a844f7b4ebfcf2833e87260bf3447bed 088fbeac48abfeda62a9398392675145 \n",
+ "1 d584928c5feaa1accef0859f74a058f8 8cf9b2748fcc798dca5bdad2c3e2b28f \n",
+ "2 9daae6a3c07fbed7638796e10def9b9d a37760dde6b9fdcb76b82e57afab7274 \n",
+ "3 b35a15809e09aa7128945ead98b35bb6 72db364f3248e2eb7940bea6ccab1d72 \n",
+ "4 d584928c5feaa1accef0859f74a058f8 99c066f0726f0c9cf117d9754121ee18 \n",
+ ".. ... ... \n",
+ "844 643839b344145322d3f98fb19af40557 538cd77b8319780a8bf412668f24440d \n",
+ "845 e16b334aa0877fa87ff3441bbaad3e93 6fda78099793184fe08dd78945d188c0 \n",
+ "846 2621745b8b20cb8dbf4445049ad14bda 0f5e1b251db53223200c5bfc365d33f2 \n",
+ "847 8d62a5cec6fbb88a455322a60cf8dbef e681c3a8dafa2c80e5b8e2cdd01f917a \n",
+ "848 64c1a0b079d63559e2cc81e28e195372 0881af3822466784992a49f1cc57d38f \n",
+ "\n",
+ " customer_facing category \\\n",
+ "0 False None \n",
+ "1 True None \n",
+ "2 True None \n",
+ "3 True None \n",
+ "4 True None \n",
+ ".. ... ... \n",
+ "844 False precursor \n",
+ "845 True primary \n",
+ "846 False precursor \n",
+ "847 True primary \n",
+ "848 False precursor \n",
+ "\n",
+ " fares_v2_status \\\n",
+ "0 [] \n",
+ "1 [] \n",
+ "2 [] \n",
+ "3 [] \n",
+ "4 [] \n",
+ ".. ... \n",
+ "844 [] \n",
+ "845 [Vendor published, Fares v2 updates in progres... \n",
+ "846 [] \n",
+ "847 [] \n",
+ "848 [] \n",
+ "\n",
+ " manual_check__fixed_route_completeness \\\n",
+ "0 None \n",
+ "1 None \n",
+ "2 None \n",
+ "3 None \n",
+ "4 None \n",
+ ".. ... \n",
+ "844 Unknown \n",
+ "845 Unknown \n",
+ "846 Unknown \n",
+ "847 Complete \n",
+ "848 Unknown \n",
+ "\n",
+ " manual_check__demand_response_completeness _is_current \\\n",
+ "0 None True \n",
+ "1 None True \n",
+ "2 None True \n",
+ "3 None True \n",
+ "4 None True \n",
+ ".. ... ... \n",
+ "844 Unknown True \n",
+ "845 Unknown True \n",
+ "846 Unknown True \n",
+ "847 Unknown True \n",
+ "848 Unknown True \n",
+ "\n",
+ " _valid_from _valid_to \n",
+ "0 2023-12-12 00:00:00+00:00 2098-12-31 23:59:59.999999+00:00 \n",
+ "1 2023-10-26 00:00:00+00:00 2098-12-31 23:59:59.999999+00:00 \n",
+ "2 2023-05-18 00:00:00+00:00 2098-12-31 23:59:59.999999+00:00 \n",
+ "3 2023-06-13 00:00:00+00:00 2098-12-31 23:59:59.999999+00:00 \n",
+ "4 2023-10-26 00:00:00+00:00 2098-12-31 23:59:59.999999+00:00 \n",
+ ".. ... ... \n",
+ "844 2023-10-25 00:00:00+00:00 2098-12-31 23:59:59.999999+00:00 \n",
+ "845 2023-10-25 00:00:00+00:00 2098-12-31 23:59:59.999999+00:00 \n",
+ "846 2023-10-26 00:00:00+00:00 2098-12-31 23:59:59.999999+00:00 \n",
+ "847 2023-10-25 00:00:00+00:00 2098-12-31 23:59:59.999999+00:00 \n",
+ "848 2023-10-26 00:00:00+00:00 2098-12-31 23:59:59.999999+00:00 \n",
+ "\n",
+ "[849 rows x 13 columns]"
+ ]
+ },
+ "execution_count": 8,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "service_data >> inner_join(_, tracts_and_feeds, on = "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "3cfbe279-210b-4aaf-8d77-076ea08619c3",
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.9.13"
+ },
+ "widgets": {
+ "application/vnd.jupyter.widget-state+json": {
+ "state": {},
+ "version_major": 2,
+ "version_minor": 0
+ }
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}