diff --git a/.gitattributes b/.gitattributes
index deda00c72..0df48f948 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,7 +1,4 @@
 portfolio/**/*.ipynb filter=lfs diff=lfs merge=lfs -text
-portfolio/ntd_monthly_ridership/**/*.ipynb filter=lfs diff=lfs merge=lfs -text
-portfolio/dla/district_*/*.ipynb filter=lfs diff=lfs merge=lfs -text
-portfolio/parallel_corridors/district_*/*.ipynb filter=lfs diff=lfs merge=lfs -text
-portfolio/district_digest/district_*/*.ipynb filter=lfs diff=lfs merge=lfs -text
+portfolio/**/**/*.ipynb filter=lfs diff=lfs merge=lfs -text
 “portfolio/**/**/*.ipynb” filter=lfs diff=lfs merge=lfs -text
 “portfolio/**/*.ipynb” filter=lfs diff=lfs merge=lfs -text
diff --git a/Makefile b/Makefile
index 54f786995..a2af445cd 100644
--- a/Makefile
+++ b/Makefile
@@ -6,8 +6,9 @@ build_portfolio_site:
 	#need git rm because otherwise, just local removal, but git change is untracked
 	#git rm portfolio/$(site)/ -rf
 	python portfolio/portfolio.py clean $(site)
+	python portfolio/portfolio.py build $(site) 
 	gcloud auth login --login-config=iac/login.json && gcloud config set project cal-itp-data-infra
-	python portfolio/portfolio.py build $(site) --deploy 
+	python portfolio/portfolio.py build $(site) --no-execute-papermill --deploy
 	git add portfolio/sites/$(site).yml     
 	#make production_portfolio
 
diff --git a/_shared_utils/requirements.txt b/_shared_utils/requirements.txt
index 6ac6c4ccf..2b706a34b 100644
--- a/_shared_utils/requirements.txt
+++ b/_shared_utils/requirements.txt
@@ -3,6 +3,8 @@ altair-transform==0.2.0
 great_tables==0.16.1
 omegaconf==2.3.0 # better yaml configuration
 polars==1.22.0
+pytest (>=8.4.1, <9.0.0)
 quarto-cli==1.6.40
 quarto==0.1.0
-pytest (>=8.4.1, <9.0.0)
+vegafusion==2.0.2
+vl-convert-python>=1.6.0
diff --git a/portfolio/portfolio.py b/portfolio/portfolio.py
index e5005d5b2..e01369c85 100644
--- a/portfolio/portfolio.py
+++ b/portfolio/portfolio.py
@@ -65,7 +65,7 @@ def parameterize_filename(i: int, old_path: Path, params: Dict) -> Path:
 
 
 class Chapter(BaseModel):
-    caption: Optional[Any]
+    caption: Optional[Any] = None
     notebook: Optional[Path] = None
     params: Dict = {}
     sections: List[Dict] = []
@@ -215,7 +215,7 @@ class Site(BaseModel):
     output_dir: Path
     name: str
     title: str
-    directory: Path
+    directory: Path 
     readme: Optional[Path] = "README.md"
     notebook: Optional[Path] = None
     parts: List[Part]
@@ -226,14 +226,14 @@ def __init__(self, **data):
 
         for part in self.parts:
             part.site = self
-
-    @validator('readme', pre=True, always=True)
+    
+    @validator('readme', pre=True, always=True, check_fields=False)
     def default_readme(cls, v, *, values, **kwargs):
         if "./" in v: 
             return Path(v)
         else:
             return (values['directory'] / Path("README.md")) or (values['directory'] / Path(v))
-
+    
     @property
     def slug(self) -> str:
         return slugify(self.title)
diff --git a/portfolio/requirements.txt b/portfolio/requirements.txt
index 50300ba82..67ceef25a 100644
--- a/portfolio/requirements.txt
+++ b/portfolio/requirements.txt
@@ -1,10 +1,10 @@
-papermill~=2.4
-nbformat~=5.8
-typer~=0.9
-jupyter-book==1.0.0
+#papermill~=2.4
+#nbformat~=5.8
+#typer~=0.9
+jupyter-book>=1.0.0
 python-slugify==6.1.1
 pyaml==21.10.1
-humanize~=4.6
-pydantic~=1.9
+#humanize~=4.6
+#pydantic>=2.0
 calitp_data_analysis
-axe-selenium-python
+axe-selenium-python
\ No newline at end of file
diff --git a/portfolio/rt_trip_updates_stop_metrics/README.md b/portfolio/rt_trip_updates_stop_metrics/README.md
index 71653d77f..10e4e7c42 100644
--- a/portfolio/rt_trip_updates_stop_metrics/README.md
+++ b/portfolio/rt_trip_updates_stop_metrics/README.md
@@ -1,7 +1,92 @@
 # README
 
+One of the most common transit user behaviors is to consult an app (Google Maps, Apple Maps, NextBus, etc) to find out when the bus or train is going to arrive.
+
+That widely desired piece of information is powered by GTFS Real-Time Trip Updates, specifically the [Stop Time Updates](https://gtfs.org/documentation/realtime/reference/#message-stoptimeupdate) specification.
+
 GTFS Real Time trip updates performance metrics, specifically the stop time update messages. 
 Accurate and reliable information should be provided to transit users for journey planning. These performance metrics provide insights into:
+
 * availability and completeness of RT - is there information available for users?
 * prediction inconsistency - how much are predictions changing from minute to minute as the bus approaches time of arrival?
 * prediction reliability and accuracy - are these predictions accurate (when compared to our estimated actual time of arrival)?
+
+
+## Reliable Prediction Accuracy
+
+The prediction is considered **accurate** if it falls within the bounds of this equation: `-60ln(Time to Prediction+1.3) < Prediction Error < 60ln(Time to Prediction+1.5)`.
+
+As the bus approaches each stop, the software is making predictions for when the bus should arrive. When the bus is 30 min away from arrival, there is a more generous buffer for accuracy; this buffer tightens as the bus is nearing the stop.
+
+| Minutes Until Bus Arives | Accurate Within Bounds          |
+|--------------------------|---------------------------------|
+| 0 min                    | -0.26 min early - 0.41 min late |
+| 10 min                   | -2.42 min early - 2.44 min late |
+| 30 min                   | -3.44 min early - 3.45 min late |
+
+* Positive values = arrival came **after** the prediction. 
+   * actual_arrival = 8:05 am
+   * predicted arrival = 8:00 am
+   * actual_arrival - predicted_arrival = +5 seconds
+   * follow the prediction, you will catch the bus
+* Negative values = arrival came **before** the prediction.
+   * actual_arrival = 8:05 am
+   * predicted arrival = 8:10 am
+   * actual_arrival - predicted_arrival = -5 seconds
+   * follow the prediction, you will **miss** the bus...this is very bad!
+   * we want fewer of these kinds of predictions, and would much rather wait for the bus than to miss it
+
+## Availability and Completeness of Predictions
+
+* This metric is the easiest to achieve. For starters, having information is better than no information.
+* For each instance of scheduled stop arrival, there is complete information if there are at least 2 predictions each minute.
+* For the 30 minute period before the bus arrives at each stop, each minute is an observation that goes into this calculation (up to 30 observations).
+* This ensures that we have fairly equal number of observations for each stop and can compare across stops.
+   * We want to avoid having 30 minutes of predictions for the 1st stop and 60 minutes of predictions for the last stop and comparing metrics that have different denominators.
+   
+## Prediction Inconsistency
+
+* This metric (also called jitter or wobble) captures another aspect of transit user experience. Any change in prediction is counted, so this metric **only has positive values**, but smaller positive values are better.
+   * If the prediction is changing from minute to minute, a large spread would show up.
+   * If the prediction is fairly consistent, we would see small spread.
+* There is [research](https://www.sciencedirect.com/science/article/abs/pii/S0965856416303494) around how transit users perceive wait time, and that users perceive longer wait times than what is actually experienced. Decreasing the perceived wait time by providing real-time information has positive benefits for user experience. 
+
+## Master Services Agreement
+Exhibit H definitions (pg 53 on pdf)
+
+| **Item** | **Report Metric** | **Definition** | **Implementation Notes** |
+|---|---|---|---|
+| 3. Availability of
Acceptable StopTimeUpdate
Messages | pct_tu_complete_minutes, 
n_tu_complete_minutes,
n_tu_minutes_available | Percent of time riders have up-to-date prediction information available, calculated as the percent of one-minute time bins for a given trip and stop during a Trip Time Span where there are two (2) or greater GTFS-RT StopTimeUpdate arrival predictions per minute. | Each minute for the 30 minute period 
before **each** stop's 
arrival for equal comparison across stops |
+| 9. Experienced Wait 
Time Delay | prediction_error_label, 
avg_prediction_error_minutes | The amount of time a transit rider perceives they have waited after seeing the real-time information in their Journey Planning Application and the arrival of the next vehicle arrives at their stop. This is calculated as the time interval between the next trip to arrive at a stop for a given route_id/shape_id/stop_id combination and the next predicted arrival time from a StopTimeUpdate message for that route_id/shape_id/stop_id combination as sampled for each minute of the day that the route_id/shape_id/stop_id combination is in service. | Use a simpler derived version with average
prediction error.
Current aggregation does not support 
route aggregation yet. |
+| 23. Measurement Time Windows |  | A series of 30 consecutive time windows, each starting one (1) minute apart and lasting two (2) minutes. | Each minute for the 30 minute period 
before **each** stop's 
arrival for equal comparison across stops |
+| 27. Prediction Error | avg_prediction_error_minutes | Actual Trip Stop Arrival Time minus the Predicted Trip Stop Arrival Time in seconds. Note that while Prediction Error is not the final metric in this case, it is useful to retain this value into the future and in archival storage in the event that
the definition of the frontier defined in Reliable Accuracy is changed in the future based on a specific agency’s needs |  |
+| 28. Prediction
Inconsistency | avg_prediction_spread_minutes | How much the prediction changes in the last thirty (30) minutes before a vehicle arrives at a stop, calculated for a given trip and stop as the average Predicted Trip Stop Arrival Spread of all Measurement Time Windows where a given window has a StopTimeUpdate message for the trip and stop with a timestamp in that window. |  |
+| 29. Prediction Reliability | pct_tu_accurate_minutes, 
n_tu_accurate_minutes,
n_tu_minutes_available,
pct_tu_predictions_early/ontime/late,
n_predictions,
n_predictions_early/ontime/late | The percent of time transit riders are looking at a reliably good prediction – understanding that the closer a vehicle is
to a stop, the better the prediction should be, calculated as the percent of minutes for each stop for each trip where predictions have Reliable Accuracy, starting sixty (60) minutes before the first scheduled stop for the trip. | Each minute for the 30 minute period 
before **each** stop's 
arrival for equal comparison across stops |
+| 32. Reliable Accuracy | pct_tu_accurate_minutes, 
n_tu_accurate_minutes,
n_tu_minutes_available,
pct_tu_predictions_early/ontime/late,
n_predictions,
n_predictions_early/ontime/late | A prediction has reliable accuracy if:
-60ln(Time to Prediction+1.3) < Prediction Error < 60ln(Time
to Prediction+1.5). |  |
+| 39. Time to Prediction |  | The current time until the Predicted Trip Stop Arrival Time in minutes |  |
+| 43. Trip Start Time  |  | Time of the first scheduled stop arrival of the trip per the GTFS Schedule for trips with ScheduleRelationship =
SCHEDULED or CANCELED or the first predicted arrival time for other ScheduleRelationship values. |  |
+| 44. Trip Time Span |  | Time in minutes from the Trip Start Time to the arrival time
at the stop being measured | Each minute for the 30 minute period 
before **each** stop's 
arrival for equal comparison across stops |
+
+## References
+* Caltrans GTFS RT Master Service Agreement Contract
+   * Swiftly provides a prediction accuracy exponential equation
+* Professor Gregory Newmark's paper: [Assessing GTFS Accuracy](https://transweb.sjsu.edu/sites/default/files/2017-Newmark-Public-Transit-Statistical-Analysis.pdf)
+    * This project is a work in progress for productionizing and implementing all the ideas presented in this paper.
+    * This paper provides the basis of policy and planning interpretations around the various metrics.
+    * We replicate as many of the visualizations and tables as possible.
+* Yingling Fan, Andrew Guthrie, David Levinson's paper on [Waiting time perceptions at transit stops and stations](https://www.sciencedirect.com/science/article/abs/pii/S0965856416303494)
+
+### Data Models and Data Processing Scripts
+1. Big Query SQL models (upstream to downstream SQL)
+   * 2 week [sample](https://dbt-docs.dds.dot.ca.gov/index.html#!/model/model.calitp_warehouse.fct_stop_time_updates_sample)
+   * [actual arrivals](https://dbt-docs.dds.dot.ca.gov/index.html#!/model/model.calitp_warehouse.int_gtfs_rt__trip_updates_trip_stop_day_map_grouping)
+   * [daily stop time metrics](https://dbt-docs.dds.dot.ca.gov/index.html#!/model/model.calitp_warehouse.fct_stop_time_metrics) 
+   * [daily stop metrics](https://dbt-docs.dds.dot.ca.gov/index.html#!/model/model.calitp_warehouse.fct_trip_updates_stop_metrics) --> desired future aggregation: move to this stop on a June 2025 weekday instead of this stop on June 1, 2025
+   * [GitHub issue](https://github.com/cal-itp/data-infra/issues/4101)
+
+
+2. Python scripts
+   * [report notebook](https://github.com/cal-itp/data-analyses/blob/main/rt_predictions/rt_trip_updates_report.ipynb)
+   * [Makefile](https://github.com/cal-itp/data-analyses/blob/main/rt_predictions/Makefile)
+   * [download warehouse tables](https://github.com/cal-itp/data-analyses/blob/main/rt_predictions/download_warehouse_tables.py)
+   * [prep data](https://github.com/cal-itp/data-analyses/blob/main/rt_predictions/prep_data.py)
\ No newline at end of file
diff --git a/portfolio/rt_trip_updates_stop_metrics/_toc.yml b/portfolio/rt_trip_updates_stop_metrics/_toc.yml
index 0d2f44a2e..e0ab0af6a 100644
--- a/portfolio/rt_trip_updates_stop_metrics/_toc.yml
+++ b/portfolio/rt_trip_updates_stop_metrics/_toc.yml
@@ -26,7 +26,6 @@ parts:
     -   file: name_bay-area-511-union-city-transit-schedule/00__rt_trip_updates_report__name_bay-area-511-union-city-transit-schedule.ipynb
     -   file: name_bay-area-511-vine-transit-schedule/00__rt_trip_updates_report__name_bay-area-511-vine-transit-schedule.ipynb
     -   file: name_beach-cities-gmv-schedule/00__rt_trip_updates_report__name_beach-cities-gmv-schedule.ipynb
-    -   file: name_beaumont-pass-schedule/00__rt_trip_updates_report__name_beaumont-pass-schedule.ipynb
     -   file: name_beaumont-transit-schedule/00__rt_trip_updates_report__name_beaumont-transit-schedule.ipynb
     -   file: name_big-blue-bus-swiftly-schedule/00__rt_trip_updates_report__name_big-blue-bus-swiftly-schedule.ipynb
     -   file: name_bruinbus-schedule/00__rt_trip_updates_report__name_bruinbus-schedule.ipynb
@@ -37,7 +36,6 @@ parts:
     -   file: name_eastern-sierra-schedule/00__rt_trip_updates_report__name_eastern-sierra-schedule.ipynb
     -   file: name_fairfield-schedule/00__rt_trip_updates_report__name_fairfield-schedule.ipynb
     -   file: name_fresno-schedule/00__rt_trip_updates_report__name_fresno-schedule.ipynb
-    -   file: name_historic-tuolumne-schedule/00__rt_trip_updates_report__name_historic-tuolumne-schedule.ipynb
     -   file: name_humboldt-schedule/00__rt_trip_updates_report__name_humboldt-schedule.ipynb
     -   file: name_irvine-connect-schedule/00__rt_trip_updates_report__name_irvine-connect-schedule.ipynb
     -   file: name_kern-schedule/00__rt_trip_updates_report__name_kern-schedule.ipynb
@@ -49,7 +47,6 @@ parts:
     -   file: name_madera-county-connection-schedule/00__rt_trip_updates_report__name_madera-county-connection-schedule.ipynb
     -   file: name_marin-gmv-schedule/00__rt_trip_updates_report__name_marin-gmv-schedule.ipynb
     -   file: name_marin-optibus-schedule/00__rt_trip_updates_report__name_marin-optibus-schedule.ipynb
-    -   file: name_marin-schedule/00__rt_trip_updates_report__name_marin-schedule.ipynb
     -   file: name_mendocino-schedule/00__rt_trip_updates_report__name_mendocino-schedule.ipynb
     -   file: name_merced-gmv-schedule/00__rt_trip_updates_report__name_merced-gmv-schedule.ipynb
     -   file: name_monterey-salinas-schedule/00__rt_trip_updates_report__name_monterey-salinas-schedule.ipynb
@@ -57,12 +54,10 @@ parts:
     -   file: name_nevada-county-schedule/00__rt_trip_updates_report__name_nevada-county-schedule.ipynb
     -   file: name_north-county-schedule/00__rt_trip_updates_report__name_north-county-schedule.ipynb
     -   file: name_octa-schedule/00__rt_trip_updates_report__name_octa-schedule.ipynb
-    -   file: name_ojai-schedule/00__rt_trip_updates_report__name_ojai-schedule.ipynb
     -   file: name_petaluma-gmv-schedule/00__rt_trip_updates_report__name_petaluma-gmv-schedule.ipynb
     -   file: name_presidigo-schedule/00__rt_trip_updates_report__name_presidigo-schedule.ipynb
     -   file: name_redding-schedule/00__rt_trip_updates_report__name_redding-schedule.ipynb
     -   file: name_redwood-coast-schedule/00__rt_trip_updates_report__name_redwood-coast-schedule.ipynb
-    -   file: name_redwood-coast-schedulel/00__rt_trip_updates_report__name_redwood-coast-schedulel.ipynb
     -   file: name_roseville-transit-gmv-schedule/00__rt_trip_updates_report__name_roseville-transit-gmv-schedule.ipynb
     -   file: name_scvta-schedule/00__rt_trip_updates_report__name_scvta-schedule.ipynb
     -   file: name_smart-schedule/00__rt_trip_updates_report__name_smart-schedule.ipynb
@@ -75,7 +70,6 @@ parts:
     -   file: name_torrance-schedule/00__rt_trip_updates_report__name_torrance-schedule.ipynb
     -   file: name_tri-valley-wheels-schedule/00__rt_trip_updates_report__name_tri-valley-wheels-schedule.ipynb
     -   file: name_tuolumne-remix-schedule/00__rt_trip_updates_report__name_tuolumne-remix-schedule.ipynb
-    -   file: name_tuolumne-schedule/00__rt_trip_updates_report__name_tuolumne-schedule.ipynb
     -   file: name_turlock-schedule/00__rt_trip_updates_report__name_turlock-schedule.ipynb
     -   file: name_union-city-gmv-schedule/00__rt_trip_updates_report__name_union-city-gmv-schedule.ipynb
     -   file: name_vctc-gmv-schedule/00__rt_trip_updates_report__name_vctc-gmv-schedule.ipynb
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_ac-transit-schedule/00__rt_trip_updates_report__name_ac-transit-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_ac-transit-schedule/00__rt_trip_updates_report__name_ac-transit-schedule.ipynb
index d1c928b1a..d90b03e65 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_ac-transit-schedule/00__rt_trip_updates_report__name_ac-transit-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_ac-transit-schedule/00__rt_trip_updates_report__name_ac-transit-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:5c7e0259fecd5e1b610e5291986c332ab5d1e81303250c92df42fd4209de632e
-size 12153344
+oid sha256:cf3603548a7147f1769b25044eaed8afe664175594e53bd15b1f404645c3f52f
+size 8979358
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_anaheim-resort-schedule-v2/00__rt_trip_updates_report__name_anaheim-resort-schedule-v2.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_anaheim-resort-schedule-v2/00__rt_trip_updates_report__name_anaheim-resort-schedule-v2.ipynb
index 024abbfd8..b8ed34033 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_anaheim-resort-schedule-v2/00__rt_trip_updates_report__name_anaheim-resort-schedule-v2.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_anaheim-resort-schedule-v2/00__rt_trip_updates_report__name_anaheim-resort-schedule-v2.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:e9e5a723b01f3349cf8dc1e3ce8ecc08a9a04092358bba362d7ca1e3c6260cda
-size 784349
+oid sha256:bb361bb0ce44d32ad3467f38000bb6d785d773a582f585403dc3a37ce953f202
+size 832792
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_anaheim-resort-schedule/00__rt_trip_updates_report__name_anaheim-resort-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_anaheim-resort-schedule/00__rt_trip_updates_report__name_anaheim-resort-schedule.ipynb
index 734f1fcfd..b00718faf 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_anaheim-resort-schedule/00__rt_trip_updates_report__name_anaheim-resort-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_anaheim-resort-schedule/00__rt_trip_updates_report__name_anaheim-resort-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:b90234c0f6137f9b6a0466b7d75e901f624794dc1162ae5ffda9283d4313ce5b
-size 938515
+oid sha256:3e23229f0ff0c3728251c739bf1f0f22600ccb5b2de46a794ac548a95ef694d0
+size 825971
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_banning-pass-schedule/00__rt_trip_updates_report__name_banning-pass-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_banning-pass-schedule/00__rt_trip_updates_report__name_banning-pass-schedule.ipynb
index a5fc307ae..d216bcb4a 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_banning-pass-schedule/00__rt_trip_updates_report__name_banning-pass-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_banning-pass-schedule/00__rt_trip_updates_report__name_banning-pass-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:b468188bc78e1f98f805d38e5a88eabb09baca11d003bdbdf3e3f34e18363dbb
-size 418096
+oid sha256:c47830e212e2cc7d261d3b39b0f7b69f8a4e8f7b181092e223ecf66d4f544478
+size 825356
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_basin-transit-gmv-schedule/00__rt_trip_updates_report__name_basin-transit-gmv-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_basin-transit-gmv-schedule/00__rt_trip_updates_report__name_basin-transit-gmv-schedule.ipynb
index 798407b49..412e6a6cb 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_basin-transit-gmv-schedule/00__rt_trip_updates_report__name_basin-transit-gmv-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_basin-transit-gmv-schedule/00__rt_trip_updates_report__name_basin-transit-gmv-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:abba3b429db88313e773789450c6765818c1dd65370f21b5b34d7e30b8d111bc
-size 957524
+oid sha256:c87fe4d1694c6c5f56b5dc105a7d1554979e1b26436354b3c6b8089885fe73a3
+size 1247056
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-ac-transit-schedule/00__rt_trip_updates_report__name_bay-area-511-ac-transit-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-ac-transit-schedule/00__rt_trip_updates_report__name_bay-area-511-ac-transit-schedule.ipynb
index ef87184da..4527220ff 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-ac-transit-schedule/00__rt_trip_updates_report__name_bay-area-511-ac-transit-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-ac-transit-schedule/00__rt_trip_updates_report__name_bay-area-511-ac-transit-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:c02d71e1e8e3e03554069d28bb793d49a59c2734624dca0f3d5f58564e3fc198
-size 9299910
+oid sha256:25b55e06ff3c3689b228de4ddd157cf904a8dfe659653673dc66734421ed8cad
+size 8707500
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-ace-schedule/00__rt_trip_updates_report__name_bay-area-511-ace-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-ace-schedule/00__rt_trip_updates_report__name_bay-area-511-ace-schedule.ipynb
index 40a4e8795..a616c3e96 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-ace-schedule/00__rt_trip_updates_report__name_bay-area-511-ace-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-ace-schedule/00__rt_trip_updates_report__name_bay-area-511-ace-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:a84e399e2b790f5ab38d37c5bc7e4bb643dbf9c600a562ef6709139b610a8619
-size 305995
+oid sha256:ba03a892378aecc0f2dc1aae6cd7126bd02dae797dc35618f90bfc105816abff
+size 563891
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-capitol-corridor-schedule/00__rt_trip_updates_report__name_bay-area-511-capitol-corridor-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-capitol-corridor-schedule/00__rt_trip_updates_report__name_bay-area-511-capitol-corridor-schedule.ipynb
index c0f5be0f5..837b8b71e 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-capitol-corridor-schedule/00__rt_trip_updates_report__name_bay-area-511-capitol-corridor-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-capitol-corridor-schedule/00__rt_trip_updates_report__name_bay-area-511-capitol-corridor-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:a75f616c8560e533f1660c03ca2a4858a3e72d7f3597b81473e2730a108bce29
-size 385452
+oid sha256:fa4e538e2fc83a4727408bdbb79b0b9de97e6a8fb738f373e8cbbfc6c38d6efb
+size 808710
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-county-connection-schedule/00__rt_trip_updates_report__name_bay-area-511-county-connection-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-county-connection-schedule/00__rt_trip_updates_report__name_bay-area-511-county-connection-schedule.ipynb
index fb931c503..0103ffd25 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-county-connection-schedule/00__rt_trip_updates_report__name_bay-area-511-county-connection-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-county-connection-schedule/00__rt_trip_updates_report__name_bay-area-511-county-connection-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:e57a77ed8ba2971b5aa81da153ee086f63b3311c28dc4c1eacdb2407db591c4c
-size 2721322
+oid sha256:ee883b84599e37e01f2ed1d226be7a6de50be25fb3de79948c9a23568941236d
+size 2682577
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-fairfield-and-suisun-transit-schedule/00__rt_trip_updates_report__name_bay-area-511-fairfield-and-suisun-transit-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-fairfield-and-suisun-transit-schedule/00__rt_trip_updates_report__name_bay-area-511-fairfield-and-suisun-transit-schedule.ipynb
index 2775e03d5..c88073062 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-fairfield-and-suisun-transit-schedule/00__rt_trip_updates_report__name_bay-area-511-fairfield-and-suisun-transit-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-fairfield-and-suisun-transit-schedule/00__rt_trip_updates_report__name_bay-area-511-fairfield-and-suisun-transit-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:21ace3307a528ce580d204ce5fa4bbb82305e77a9c5859b65277b750efe4d6d0
-size 520922
+oid sha256:60759327c53fbf0a858723299217b44b9b24d14e88154ed644656938272bb00c
+size 879920
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-golden-gate-transit-schedule/00__rt_trip_updates_report__name_bay-area-511-golden-gate-transit-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-golden-gate-transit-schedule/00__rt_trip_updates_report__name_bay-area-511-golden-gate-transit-schedule.ipynb
index 8fdee1eb2..2c357120d 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-golden-gate-transit-schedule/00__rt_trip_updates_report__name_bay-area-511-golden-gate-transit-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-golden-gate-transit-schedule/00__rt_trip_updates_report__name_bay-area-511-golden-gate-transit-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:d82ec278f2982dbd5657daf817dbab6c092bf58cb098611dd2bb5e662211e32d
-size 1587364
+oid sha256:bed9cb1de4e2e6e7fd07b8448d5e5a4029f0e36714a1244c9fcb8f2c67ec1083
+size 1411636
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-marin-schedule/00__rt_trip_updates_report__name_bay-area-511-marin-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-marin-schedule/00__rt_trip_updates_report__name_bay-area-511-marin-schedule.ipynb
index 0b58d5dcd..b6ee33581 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-marin-schedule/00__rt_trip_updates_report__name_bay-area-511-marin-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-marin-schedule/00__rt_trip_updates_report__name_bay-area-511-marin-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:0fb4b18b6de54c551bbe834f1fa0e69e4621b96246a4a4f5b551d0a09106b12e
-size 1898559
+oid sha256:294be3462f7fbd8499280eef072204f0ad003093bbc655b164661b950420522b
+size 1702019
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-petaluma-schedule/00__rt_trip_updates_report__name_bay-area-511-petaluma-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-petaluma-schedule/00__rt_trip_updates_report__name_bay-area-511-petaluma-schedule.ipynb
index c76701521..4b79cc5a0 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-petaluma-schedule/00__rt_trip_updates_report__name_bay-area-511-petaluma-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-petaluma-schedule/00__rt_trip_updates_report__name_bay-area-511-petaluma-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:24b1070f5096ab983c45150907890689bf2067cb6b63b1849139d35067ef0243
-size 716319
+oid sha256:26a28e3c60cd8913b6b905a1db840eb725830f012b531b713ae6ada8a09f3877
+size 1142398
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-presidigo-schedule/00__rt_trip_updates_report__name_bay-area-511-presidigo-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-presidigo-schedule/00__rt_trip_updates_report__name_bay-area-511-presidigo-schedule.ipynb
index 1ecf9f60a..c652836b2 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-presidigo-schedule/00__rt_trip_updates_report__name_bay-area-511-presidigo-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-presidigo-schedule/00__rt_trip_updates_report__name_bay-area-511-presidigo-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:1e235f97b2a50052d162de3a6d5c434e53f26fa81579bafb3cfca664fd78d467
-size 438069
+oid sha256:69d30b00add0c98da0a806ca8d65cb52919860ca4d36e3caeb4106dda9966062
+size 863802
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-samtrans-schedule/00__rt_trip_updates_report__name_bay-area-511-samtrans-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-samtrans-schedule/00__rt_trip_updates_report__name_bay-area-511-samtrans-schedule.ipynb
index f66a6fd42..787d69b83 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-samtrans-schedule/00__rt_trip_updates_report__name_bay-area-511-samtrans-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-samtrans-schedule/00__rt_trip_updates_report__name_bay-area-511-samtrans-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:d85ff9825f2fbd1efb000eca2f7381c3caccb0300a7f8b8bbb4c7a44277609ac
-size 3934838
+oid sha256:5b4a0d5559d97edc7d23dabd8bb17a0493ffa6e6d1833cc8af99513dc0f0f525
+size 4455614
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-san-francisco-bay-ferry-schedule/00__rt_trip_updates_report__name_bay-area-511-san-francisco-bay-ferry-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-san-francisco-bay-ferry-schedule/00__rt_trip_updates_report__name_bay-area-511-san-francisco-bay-ferry-schedule.ipynb
index c14010110..73f42d6fd 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-san-francisco-bay-ferry-schedule/00__rt_trip_updates_report__name_bay-area-511-san-francisco-bay-ferry-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-san-francisco-bay-ferry-schedule/00__rt_trip_updates_report__name_bay-area-511-san-francisco-bay-ferry-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:72204bc6ce54e5831b787e6dfe513e527f1a0178a660959a890e7894c1bdf904
-size 362166
+oid sha256:9ffa0199afe76b8ca9fe41ac67427d8cadcb7b792993da22e294c234c9008737
+size 262472
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-santa-clara-transit-schedule/00__rt_trip_updates_report__name_bay-area-511-santa-clara-transit-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-santa-clara-transit-schedule/00__rt_trip_updates_report__name_bay-area-511-santa-clara-transit-schedule.ipynb
index 1638f667c..f5b6f00c2 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-santa-clara-transit-schedule/00__rt_trip_updates_report__name_bay-area-511-santa-clara-transit-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-santa-clara-transit-schedule/00__rt_trip_updates_report__name_bay-area-511-santa-clara-transit-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:2bf2153194ebe26a8a7af324b661c1976cfe3c498abe57c22a8814b0ca927e72
-size 8583638
+oid sha256:a3dda13289465259f68a74d2125ba7e9e24e27742e112869b760974f002327e1
+size 6812677
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-santa-rosa-citybus-schedule/00__rt_trip_updates_report__name_bay-area-511-santa-rosa-citybus-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-santa-rosa-citybus-schedule/00__rt_trip_updates_report__name_bay-area-511-santa-rosa-citybus-schedule.ipynb
index cd23e2336..f0cbe1bb8 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-santa-rosa-citybus-schedule/00__rt_trip_updates_report__name_bay-area-511-santa-rosa-citybus-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-santa-rosa-citybus-schedule/00__rt_trip_updates_report__name_bay-area-511-santa-rosa-citybus-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:c47ddb347df5a254bd701c014ce859af4f7fcf54fd8ec02bfbdecb0de904c017
-size 1668155
+oid sha256:be034de3eb018ba71ec580e138a9c9d348fa60e23799cb05ed8ae743b8743573
+size 1791663
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-sonoma-marin-area-rail-transit-schedule/00__rt_trip_updates_report__name_bay-area-511-sonoma-marin-area-rail-transit-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-sonoma-marin-area-rail-transit-schedule/00__rt_trip_updates_report__name_bay-area-511-sonoma-marin-area-rail-transit-schedule.ipynb
index 3f22f509b..41f623edc 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-sonoma-marin-area-rail-transit-schedule/00__rt_trip_updates_report__name_bay-area-511-sonoma-marin-area-rail-transit-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-sonoma-marin-area-rail-transit-schedule/00__rt_trip_updates_report__name_bay-area-511-sonoma-marin-area-rail-transit-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:759eda8eb9ae92388568b864aa948e879f77d86e3dfe442be2c599fee757854c
-size 390807
+oid sha256:cf7d1452ea3ec4ff63ba6592316f0840d686cd82b4bd4c43f4bfb75ebf900ced
+size 835625
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-tri-delta-schedule/00__rt_trip_updates_report__name_bay-area-511-tri-delta-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-tri-delta-schedule/00__rt_trip_updates_report__name_bay-area-511-tri-delta-schedule.ipynb
index b76bde9cb..65f7c44d9 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-tri-delta-schedule/00__rt_trip_updates_report__name_bay-area-511-tri-delta-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-tri-delta-schedule/00__rt_trip_updates_report__name_bay-area-511-tri-delta-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:bafe7655b7311b2756045fff9aac2c3c770674e7700dea5555afe36b9aeb17f5
-size 318756
+oid sha256:5b8b00977146596bf8e6f6d4df57dff1414a36ffcc5d9b9307c7fbe5498ac188
+size 514859
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-tri-valley-wheels-schedule/00__rt_trip_updates_report__name_bay-area-511-tri-valley-wheels-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-tri-valley-wheels-schedule/00__rt_trip_updates_report__name_bay-area-511-tri-valley-wheels-schedule.ipynb
index d27d993f1..668b95c55 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-tri-valley-wheels-schedule/00__rt_trip_updates_report__name_bay-area-511-tri-valley-wheels-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-tri-valley-wheels-schedule/00__rt_trip_updates_report__name_bay-area-511-tri-valley-wheels-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:078fdbb6d940cc028aaa17a6f00483124e32b8705dd91d4bfeebb98a13ecf478
-size 1986568
+oid sha256:fd030fbb28ae13f4dc4172b843a315126aed21d3e6dba46933e35aabdea185ab
+size 1728180
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-union-city-transit-schedule/00__rt_trip_updates_report__name_bay-area-511-union-city-transit-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-union-city-transit-schedule/00__rt_trip_updates_report__name_bay-area-511-union-city-transit-schedule.ipynb
index f4e47428d..12cf62890 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-union-city-transit-schedule/00__rt_trip_updates_report__name_bay-area-511-union-city-transit-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-union-city-transit-schedule/00__rt_trip_updates_report__name_bay-area-511-union-city-transit-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:26f498c4aff63e76251dead69cb769d21581598548eafa8ed15a3f4ee75dc556
-size 892876
+oid sha256:ba82df7d7abb01fe5cf877d76d383e38323682a2665412f7e67b6b4da512e4bb
+size 1159146
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-vine-transit-schedule/00__rt_trip_updates_report__name_bay-area-511-vine-transit-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-vine-transit-schedule/00__rt_trip_updates_report__name_bay-area-511-vine-transit-schedule.ipynb
index 1f1969cf6..15df7b78d 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-vine-transit-schedule/00__rt_trip_updates_report__name_bay-area-511-vine-transit-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_bay-area-511-vine-transit-schedule/00__rt_trip_updates_report__name_bay-area-511-vine-transit-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:196c0e9efee08ca5fb5c3f9d7b4dc9bc3504ce6349b5034b2319c7a4a5d3125b
-size 1119084
+oid sha256:9f1ec9af9064445653467a32fa239227b818781155d551c2a7bbed7bc1b72512
+size 1226820
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_beach-cities-gmv-schedule/00__rt_trip_updates_report__name_beach-cities-gmv-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_beach-cities-gmv-schedule/00__rt_trip_updates_report__name_beach-cities-gmv-schedule.ipynb
index c4d7157bf..d4d525d64 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_beach-cities-gmv-schedule/00__rt_trip_updates_report__name_beach-cities-gmv-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_beach-cities-gmv-schedule/00__rt_trip_updates_report__name_beach-cities-gmv-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:7750a2d020a14b91501e77d1c523fb6e3e2fbe32e5106894b5b6586ab4e874aa
-size 1344847
+oid sha256:2f6ea293033255a4ae869a96d3c1ba6fb13ab7aff3d4408057f272336e1cdd48
+size 1318426
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_beaumont-pass-schedule/00__rt_trip_updates_report__name_beaumont-pass-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_beaumont-pass-schedule/00__rt_trip_updates_report__name_beaumont-pass-schedule.ipynb
deleted file mode 100644
index 6a36b0cea..000000000
--- a/portfolio/rt_trip_updates_stop_metrics/name_beaumont-pass-schedule/00__rt_trip_updates_report__name_beaumont-pass-schedule.ipynb
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:dd4c42b53c18a916eb6c059bab10786600c6236ddc8544e63f6926457020a28a
-size 543124
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_beaumont-transit-schedule/00__rt_trip_updates_report__name_beaumont-transit-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_beaumont-transit-schedule/00__rt_trip_updates_report__name_beaumont-transit-schedule.ipynb
index 24630478e..07e8f130f 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_beaumont-transit-schedule/00__rt_trip_updates_report__name_beaumont-transit-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_beaumont-transit-schedule/00__rt_trip_updates_report__name_beaumont-transit-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:808c0de4ab478a2436b5793133e594ae5d922277c672ce84ff15f7876336aff9
-size 494545
+oid sha256:55bfbdf3daad9d666ac732fb9f76dc022a10bc660d9b01c08cac298dda6153b8
+size 933302
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_big-blue-bus-swiftly-schedule/00__rt_trip_updates_report__name_big-blue-bus-swiftly-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_big-blue-bus-swiftly-schedule/00__rt_trip_updates_report__name_big-blue-bus-swiftly-schedule.ipynb
index 221363665..9c10aaf77 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_big-blue-bus-swiftly-schedule/00__rt_trip_updates_report__name_big-blue-bus-swiftly-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_big-blue-bus-swiftly-schedule/00__rt_trip_updates_report__name_big-blue-bus-swiftly-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:79fe1402cc5fb5e80792d775d31cad4f0ed949bcd2ada2a3c533ebb4f414d1f4
-size 1034168
+oid sha256:1883aabe778794d7d38cd5d372c017ffb98fab64522e531426267df3bcedb6f8
+size 2001724
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_bruinbus-schedule/00__rt_trip_updates_report__name_bruinbus-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_bruinbus-schedule/00__rt_trip_updates_report__name_bruinbus-schedule.ipynb
index 72dafb5dc..b753058aa 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_bruinbus-schedule/00__rt_trip_updates_report__name_bruinbus-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_bruinbus-schedule/00__rt_trip_updates_report__name_bruinbus-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:5966b0289823c91a60b0e457ef327c6d128a704ad2502b6994bbde5756c304b8
-size 242270
+oid sha256:a859b199686799b8b440d50bdda004eff8d27fc39ce86bd58e908299804b1cfe
+size 387477
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_burbank-schedule/00__rt_trip_updates_report__name_burbank-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_burbank-schedule/00__rt_trip_updates_report__name_burbank-schedule.ipynb
index b488d1796..3bb8d53e7 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_burbank-schedule/00__rt_trip_updates_report__name_burbank-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_burbank-schedule/00__rt_trip_updates_report__name_burbank-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:de2aa8480d1152afc09fefea194e1a7aead76a1336c22063524809581d4a527b
-size 365712
+oid sha256:b8fcdb434bd41a70fcffad078e6e45f685ce0020f26d774ae0a39124e9d6c186
+size 704948
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_commerce-schedule/00__rt_trip_updates_report__name_commerce-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_commerce-schedule/00__rt_trip_updates_report__name_commerce-schedule.ipynb
index bb6fa3fcf..d6b7e014a 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_commerce-schedule/00__rt_trip_updates_report__name_commerce-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_commerce-schedule/00__rt_trip_updates_report__name_commerce-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:c51a6fc063de9a597ee478596c0ce3ddb957bf71e659c5cf6fa141c7f57dee0f
-size 1166541
+oid sha256:75f11a2ee4f00a87ed2cc93cfecda1027103470048a751120e9df72726bbd702
+size 1381127
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_county-connection-schedule/00__rt_trip_updates_report__name_county-connection-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_county-connection-schedule/00__rt_trip_updates_report__name_county-connection-schedule.ipynb
index e81f4a5f3..4f1e1df90 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_county-connection-schedule/00__rt_trip_updates_report__name_county-connection-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_county-connection-schedule/00__rt_trip_updates_report__name_county-connection-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:ef211f0420ced52b69a26027366d37aec27f26ee86ce4036cdc405ebe9da25cf
-size 4531856
+oid sha256:ce0b6f8ba6e279c55b427099bcadc1a002fcae1e5d48b71a4b97b01a20f799bc
+size 2800328
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_desert-roadrunner-gmv-schedule/00__rt_trip_updates_report__name_desert-roadrunner-gmv-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_desert-roadrunner-gmv-schedule/00__rt_trip_updates_report__name_desert-roadrunner-gmv-schedule.ipynb
index 4a8bb811b..59ecc7970 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_desert-roadrunner-gmv-schedule/00__rt_trip_updates_report__name_desert-roadrunner-gmv-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_desert-roadrunner-gmv-schedule/00__rt_trip_updates_report__name_desert-roadrunner-gmv-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:9d6721b525ac12d9dcf2927bb8e27d6fa2d7347a371aba4f117fbc7f2840344d
-size 357697
+oid sha256:7757dea4cb0001bf01181d55075c785c8037d84663908643b3bed9fdbde345c5
+size 717643
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_eastern-sierra-schedule/00__rt_trip_updates_report__name_eastern-sierra-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_eastern-sierra-schedule/00__rt_trip_updates_report__name_eastern-sierra-schedule.ipynb
index de2c09d80..c6567463e 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_eastern-sierra-schedule/00__rt_trip_updates_report__name_eastern-sierra-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_eastern-sierra-schedule/00__rt_trip_updates_report__name_eastern-sierra-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:4e214fea3d7df8250d249c652d572075eacaa9cbd990d0e17e5976c71bdb0911
-size 1138832
+oid sha256:57b1e198a5c1961066b698aa89502c1bd63eb13d934ad338af8c0ad598817a29
+size 1111967
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_fairfield-schedule/00__rt_trip_updates_report__name_fairfield-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_fairfield-schedule/00__rt_trip_updates_report__name_fairfield-schedule.ipynb
index 96b437f4e..020908f14 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_fairfield-schedule/00__rt_trip_updates_report__name_fairfield-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_fairfield-schedule/00__rt_trip_updates_report__name_fairfield-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:b6dc14be43187ddaa7889c73fd3012a614eaf7d7f4c0d3d683b49cf2b545bbab
-size 522093
+oid sha256:336c40e338d74c36598ad3a4b3806f317735a8f8f928070747b1789555bd2a23
+size 898258
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_fresno-schedule/00__rt_trip_updates_report__name_fresno-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_fresno-schedule/00__rt_trip_updates_report__name_fresno-schedule.ipynb
index fb11302ce..311f5095f 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_fresno-schedule/00__rt_trip_updates_report__name_fresno-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_fresno-schedule/00__rt_trip_updates_report__name_fresno-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:c5645f49542ad4910d921845141d6b4d5f9c74161610bb4a26ad9a04927a4551
-size 3709091
+oid sha256:555e28bae0805ed8b5cdb2debacb5850bbc363666e4a567b1582cd25e41d1c13
+size 4281763
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_historic-tuolumne-schedule/00__rt_trip_updates_report__name_historic-tuolumne-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_historic-tuolumne-schedule/00__rt_trip_updates_report__name_historic-tuolumne-schedule.ipynb
deleted file mode 100644
index c02f41b00..000000000
--- a/portfolio/rt_trip_updates_stop_metrics/name_historic-tuolumne-schedule/00__rt_trip_updates_report__name_historic-tuolumne-schedule.ipynb
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:92ac91e279df92679aa23787b15ec35fbd3ba7a0283289b023d83126b8c4fbac
-size 407503
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_humboldt-schedule/00__rt_trip_updates_report__name_humboldt-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_humboldt-schedule/00__rt_trip_updates_report__name_humboldt-schedule.ipynb
index a8b76f478..320ae24f1 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_humboldt-schedule/00__rt_trip_updates_report__name_humboldt-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_humboldt-schedule/00__rt_trip_updates_report__name_humboldt-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:e7f2230dbfce86c695c3646385458bd9f43a39bf379f64c9dd791e0bf707855c
-size 1171492
+oid sha256:3fe1a1139176f027b2370e2248397e9be5314d00cbc073051e1297e3db786ec2
+size 1223182
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_irvine-connect-schedule/00__rt_trip_updates_report__name_irvine-connect-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_irvine-connect-schedule/00__rt_trip_updates_report__name_irvine-connect-schedule.ipynb
index f78397b2e..9ec30ed1f 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_irvine-connect-schedule/00__rt_trip_updates_report__name_irvine-connect-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_irvine-connect-schedule/00__rt_trip_updates_report__name_irvine-connect-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:985b049907902e42f6aa47ca356a52820bf2155a2d7d6d273be0a9990f589562
-size 836870
+oid sha256:5dc380189871a080b3cb29df01006eff39f90d4ce568938f69fbfdeebb3e8f41
+size 945693
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_kern-schedule/00__rt_trip_updates_report__name_kern-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_kern-schedule/00__rt_trip_updates_report__name_kern-schedule.ipynb
index 8487f2430..0594f4026 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_kern-schedule/00__rt_trip_updates_report__name_kern-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_kern-schedule/00__rt_trip_updates_report__name_kern-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:73409d6db5044cc343ba19b938caf2fbc2ed5b79c3c4a7f2f1ec6a27cf0bda9a
-size 976301
+oid sha256:455f03c75c1725fa2b500d9506e89ddebe0aae2c4feee2fde0f4d8ac1ab7b38d
+size 1217561
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_la-dot-schedule/00__rt_trip_updates_report__name_la-dot-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_la-dot-schedule/00__rt_trip_updates_report__name_la-dot-schedule.ipynb
index 42bf4e34c..c53fadddb 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_la-dot-schedule/00__rt_trip_updates_report__name_la-dot-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_la-dot-schedule/00__rt_trip_updates_report__name_la-dot-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:311ecc359add60ce5beac51ce2ab68f34f011123c4fd173bc217ffa337f1024a
-size 22592281
+oid sha256:4be3d4e61ccec17462de42389326fa7fa43d64cda4ff248278b03cc1626818a7
+size 7289130
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_la-metro-bus-schedule/00__rt_trip_updates_report__name_la-metro-bus-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_la-metro-bus-schedule/00__rt_trip_updates_report__name_la-metro-bus-schedule.ipynb
index 74b7239d4..c33b5ada2 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_la-metro-bus-schedule/00__rt_trip_updates_report__name_la-metro-bus-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_la-metro-bus-schedule/00__rt_trip_updates_report__name_la-metro-bus-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:fd3bcb00b6f5a29f28748db209cb2fb92f10dbc6036563a73895e85dfb6612cf
-size 39934594
+oid sha256:05981ef49f93bcef7d91553c17f0cff8813f23561e4bbda4db6c94a848e14c34
+size 29112983
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_la-metro-rail-schedule/00__rt_trip_updates_report__name_la-metro-rail-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_la-metro-rail-schedule/00__rt_trip_updates_report__name_la-metro-rail-schedule.ipynb
index 225fdf4e7..6c4fa6e52 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_la-metro-rail-schedule/00__rt_trip_updates_report__name_la-metro-rail-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_la-metro-rail-schedule/00__rt_trip_updates_report__name_la-metro-rail-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:fa2a4e2a68a3987f05d93d7f2bf34c3ecb5f67e783442381e07e8e8fd4499cf3
-size 1025223
+oid sha256:5cc00464b45a617baeac97ea213efbac3b388c725b9627d653799d02426e25e7
+size 1039111
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_lake-schedule/00__rt_trip_updates_report__name_lake-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_lake-schedule/00__rt_trip_updates_report__name_lake-schedule.ipynb
index d708b7a99..815af2e76 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_lake-schedule/00__rt_trip_updates_report__name_lake-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_lake-schedule/00__rt_trip_updates_report__name_lake-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:9778031831019cd537ec2ab791d7cd7c66a1c694f514a939f77e34c544db8df8
-size 1139276
+oid sha256:85cfcf81935c7bf5eb52f9780daafa95734b72c9325bd767423cbbfb263c3cea
+size 1210492
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_lawndale-beat-gmv-schedule/00__rt_trip_updates_report__name_lawndale-beat-gmv-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_lawndale-beat-gmv-schedule/00__rt_trip_updates_report__name_lawndale-beat-gmv-schedule.ipynb
index 719bd1560..bc2893cb5 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_lawndale-beat-gmv-schedule/00__rt_trip_updates_report__name_lawndale-beat-gmv-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_lawndale-beat-gmv-schedule/00__rt_trip_updates_report__name_lawndale-beat-gmv-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:932bef5d06cf34cf8bc062f12e194bf05109878e56ae874c7aa7985320a0c1a1
-size 331295
+oid sha256:d9622c02a6dd2cf09269415b5fad4cc1b9e515519923d7532321febb63f4e8fd
+size 636153
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_madera-county-connection-schedule/00__rt_trip_updates_report__name_madera-county-connection-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_madera-county-connection-schedule/00__rt_trip_updates_report__name_madera-county-connection-schedule.ipynb
index a02505a4f..ee4eceb1b 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_madera-county-connection-schedule/00__rt_trip_updates_report__name_madera-county-connection-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_madera-county-connection-schedule/00__rt_trip_updates_report__name_madera-county-connection-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:bbde60533bc99d864961f536b4fbb0ad2fe2193e347345b2bf9c4b455f50dcd1
-size 368769
+oid sha256:4447fded56d8ea95b035029aab02b318fb338bbef91ce121cbff8ebfe24864d7
+size 677101
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_marin-gmv-schedule/00__rt_trip_updates_report__name_marin-gmv-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_marin-gmv-schedule/00__rt_trip_updates_report__name_marin-gmv-schedule.ipynb
index 617e5b366..02699df00 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_marin-gmv-schedule/00__rt_trip_updates_report__name_marin-gmv-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_marin-gmv-schedule/00__rt_trip_updates_report__name_marin-gmv-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:5ca39a37dcc50baac41eca979944a348b5c174d4981aafc3eac0519cb0661059
-size 2655238
+oid sha256:dd386cc5407b06a38cca82468dc289766080ae463628a131c77a9e7c5f365607
+size 2084597
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_marin-optibus-schedule/00__rt_trip_updates_report__name_marin-optibus-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_marin-optibus-schedule/00__rt_trip_updates_report__name_marin-optibus-schedule.ipynb
index f5af34d07..7328e9552 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_marin-optibus-schedule/00__rt_trip_updates_report__name_marin-optibus-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_marin-optibus-schedule/00__rt_trip_updates_report__name_marin-optibus-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:4f329e5fde1799859c516978b74206398888652d68ac95a43e7f99e4ea7ead72
-size 1385223
+oid sha256:ea7e60d8f3fbd984035454c01c49b19f7a2beef8924c01c066c95c3bf6ce0d86
+size 1727605
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_marin-schedule/00__rt_trip_updates_report__name_marin-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_marin-schedule/00__rt_trip_updates_report__name_marin-schedule.ipynb
deleted file mode 100644
index d6523c3a7..000000000
--- a/portfolio/rt_trip_updates_stop_metrics/name_marin-schedule/00__rt_trip_updates_report__name_marin-schedule.ipynb
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:dcebc7c0a4f3a0724be25513bc6a5488a49f5fc142bbca8e83e0cb8666f881a8
-size 1385187
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_mendocino-schedule/00__rt_trip_updates_report__name_mendocino-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_mendocino-schedule/00__rt_trip_updates_report__name_mendocino-schedule.ipynb
index 931d7014c..f4cdf7dc1 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_mendocino-schedule/00__rt_trip_updates_report__name_mendocino-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_mendocino-schedule/00__rt_trip_updates_report__name_mendocino-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:1dfb4c4049e0eb0a53004061d9951c981e80b01d243a7e3996bbd5dec95f95de
-size 775813
+oid sha256:a793e4b19bfba9d12b0d67d7eaea33af0ff17dea9bb17c32680ccd3f61b9cfbe
+size 1145540
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_merced-gmv-schedule/00__rt_trip_updates_report__name_merced-gmv-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_merced-gmv-schedule/00__rt_trip_updates_report__name_merced-gmv-schedule.ipynb
index 6887ddead..08379ef63 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_merced-gmv-schedule/00__rt_trip_updates_report__name_merced-gmv-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_merced-gmv-schedule/00__rt_trip_updates_report__name_merced-gmv-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:12d5d739bda552b34827b9e2dd05d23fdf218f843a9157cf8247c8f544c199bf
-size 1999331
+oid sha256:72f82a55026a1bd3b5f6302b8c168e2cdccb6a1aa09d2c35efaeb2f89ba44ff5
+size 1696760
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_monterey-salinas-schedule/00__rt_trip_updates_report__name_monterey-salinas-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_monterey-salinas-schedule/00__rt_trip_updates_report__name_monterey-salinas-schedule.ipynb
index 59edbe0df..7f73618f9 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_monterey-salinas-schedule/00__rt_trip_updates_report__name_monterey-salinas-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_monterey-salinas-schedule/00__rt_trip_updates_report__name_monterey-salinas-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:d6171f272705258e7b174302be2380e73dee380a2135b6c3f29f51a2f1ac7819
-size 2569140
+oid sha256:fdef237f04fd1d24f2ff137a491ce5ef9e2f3c76a7c45ac71d2801a554f8cbd0
+size 518670
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_mountain-transit-gmv-schedule/00__rt_trip_updates_report__name_mountain-transit-gmv-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_mountain-transit-gmv-schedule/00__rt_trip_updates_report__name_mountain-transit-gmv-schedule.ipynb
index c6f67d4fc..27f6e6fe1 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_mountain-transit-gmv-schedule/00__rt_trip_updates_report__name_mountain-transit-gmv-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_mountain-transit-gmv-schedule/00__rt_trip_updates_report__name_mountain-transit-gmv-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:24399889febd9d7a506e40ed198f9d372fe2f9bbdb7ace2dff18a6a5c141c194
-size 1082122
+oid sha256:9b8eec0c6eed8ce13d8412c601c33a088f16fba7c79b1ebe96f466092cba768e
+size 1145154
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_nevada-county-schedule/00__rt_trip_updates_report__name_nevada-county-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_nevada-county-schedule/00__rt_trip_updates_report__name_nevada-county-schedule.ipynb
index 892d960c7..7d199dd5d 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_nevada-county-schedule/00__rt_trip_updates_report__name_nevada-county-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_nevada-county-schedule/00__rt_trip_updates_report__name_nevada-county-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:41416da2e3fe4d6f01d4fd4c840fb55be29471d49b0f09c27741848b7ec6d504
-size 708653
+oid sha256:ddf6be25c0d308fb5b886449e82ce5ffa73a3e173c73594bd4104f3890dbd540
+size 1011860
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_north-county-schedule/00__rt_trip_updates_report__name_north-county-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_north-county-schedule/00__rt_trip_updates_report__name_north-county-schedule.ipynb
index 89c76de62..d537dd838 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_north-county-schedule/00__rt_trip_updates_report__name_north-county-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_north-county-schedule/00__rt_trip_updates_report__name_north-county-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:4783db7d01d09f02e5543bed7b8a22d0f60b897c3a63d76ab26a11005c5d2c2e
-size 6065579
+oid sha256:ace389647f31fbfa941699ff0e5f134652f3b342db45868d532e422017434046
+size 3892538
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_octa-schedule/00__rt_trip_updates_report__name_octa-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_octa-schedule/00__rt_trip_updates_report__name_octa-schedule.ipynb
index 20a5219f5..7a56a4f3d 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_octa-schedule/00__rt_trip_updates_report__name_octa-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_octa-schedule/00__rt_trip_updates_report__name_octa-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:3154e047cbca0878051aac346ebca0f888fcddecc85e212b30f71c9523492e56
-size 9063001
+oid sha256:76a86d158f6f24aaecd4f0ee577037061909f10e96fa39e639674c036c7d01ba
+size 9357915
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_ojai-schedule/00__rt_trip_updates_report__name_ojai-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_ojai-schedule/00__rt_trip_updates_report__name_ojai-schedule.ipynb
deleted file mode 100644
index 6c3e70d79..000000000
--- a/portfolio/rt_trip_updates_stop_metrics/name_ojai-schedule/00__rt_trip_updates_report__name_ojai-schedule.ipynb
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:d6d3970cf83d6d6f292f7d7631a9f7949ffdb4b8fdda7df910236fd2471af0ed
-size 4317110
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_petaluma-gmv-schedule/00__rt_trip_updates_report__name_petaluma-gmv-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_petaluma-gmv-schedule/00__rt_trip_updates_report__name_petaluma-gmv-schedule.ipynb
index a22bf32dc..10bafd6de 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_petaluma-gmv-schedule/00__rt_trip_updates_report__name_petaluma-gmv-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_petaluma-gmv-schedule/00__rt_trip_updates_report__name_petaluma-gmv-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:228836296bc119d42208011f8e4fc1c0019a0e41a30ab6f1324137d80f621c14
-size 951719
+oid sha256:3330524d8cd64e4ae7e3cedf8ba764b88375424ce952f9fcb736f4a7d13505e1
+size 1152368
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_presidigo-schedule/00__rt_trip_updates_report__name_presidigo-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_presidigo-schedule/00__rt_trip_updates_report__name_presidigo-schedule.ipynb
index 27b6afb45..5ebcb1ae4 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_presidigo-schedule/00__rt_trip_updates_report__name_presidigo-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_presidigo-schedule/00__rt_trip_updates_report__name_presidigo-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:317bd7602db536a8c8aa3dc4531dfd26eea0f3aaed2fb0d900242d7419be198f
-size 547286
+oid sha256:039dc0019cd392c52a0a202488b82d6832ac591fb0613a827fab5404ac7b75f7
+size 854800
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_redding-schedule/00__rt_trip_updates_report__name_redding-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_redding-schedule/00__rt_trip_updates_report__name_redding-schedule.ipynb
index 52a8cf956..83c1423fd 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_redding-schedule/00__rt_trip_updates_report__name_redding-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_redding-schedule/00__rt_trip_updates_report__name_redding-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:c5e9a780227956879511c77952996d0526684a747ede0c9bf2b156b86b761371
-size 912953
+oid sha256:fe9e0503f8dbe903fd21a98f33d97729675ca4bd88c00e5c2a322f3016292b50
+size 1348331
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_redwood-coast-schedule/00__rt_trip_updates_report__name_redwood-coast-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_redwood-coast-schedule/00__rt_trip_updates_report__name_redwood-coast-schedule.ipynb
index 484b9d1a9..cbe661ac4 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_redwood-coast-schedule/00__rt_trip_updates_report__name_redwood-coast-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_redwood-coast-schedule/00__rt_trip_updates_report__name_redwood-coast-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:fff9ee2bcac9db04373aaa82cc9b791c27146ea8d193d39cdb004af3743c6d2b
-size 747791
+oid sha256:f7620c04f3348954880cabe4fb061718880ebfa2e7dd68bd43dab93078d0849c
+size 936334
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_redwood-coast-schedulel/00__rt_trip_updates_report__name_redwood-coast-schedulel.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_redwood-coast-schedulel/00__rt_trip_updates_report__name_redwood-coast-schedulel.ipynb
deleted file mode 100644
index 979e47441..000000000
--- a/portfolio/rt_trip_updates_stop_metrics/name_redwood-coast-schedulel/00__rt_trip_updates_report__name_redwood-coast-schedulel.ipynb
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:e2ac8020f5ff7f3664084e2a09c3b7fc461efb0b1c798c1e9c6b936ca64e83ca
-size 548930
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_roseville-transit-gmv-schedule/00__rt_trip_updates_report__name_roseville-transit-gmv-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_roseville-transit-gmv-schedule/00__rt_trip_updates_report__name_roseville-transit-gmv-schedule.ipynb
index 66fa1ff55..2daade094 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_roseville-transit-gmv-schedule/00__rt_trip_updates_report__name_roseville-transit-gmv-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_roseville-transit-gmv-schedule/00__rt_trip_updates_report__name_roseville-transit-gmv-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:1d744de70f38c380d4495d59cb13dae9eee5f7b90429703ba8ec72f7753f3bc5
-size 300513
+oid sha256:74b82f05dab094824ab8816d4b1613bd2f47963013c11be44759eb8662ffe5af
+size 512997
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_san-francisco-bay-ferry-schedule/00__rt_trip_updates_report__name_san-francisco-bay-ferry-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_san-francisco-bay-ferry-schedule/00__rt_trip_updates_report__name_san-francisco-bay-ferry-schedule.ipynb
index 6f67423f8..4548f82f1 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_san-francisco-bay-ferry-schedule/00__rt_trip_updates_report__name_san-francisco-bay-ferry-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_san-francisco-bay-ferry-schedule/00__rt_trip_updates_report__name_san-francisco-bay-ferry-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:7f2c3705ca249f8e2f70052d46b9ef3de441e26a40fcd95b2466f99f521cf3bf
-size 362318
+oid sha256:b98991b8e1ed1d333e6c5f3f020d1c0ba8efea3f788fbf1d976b6e9d569087de
+size 262407
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_san-joaquin-schedule/00__rt_trip_updates_report__name_san-joaquin-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_san-joaquin-schedule/00__rt_trip_updates_report__name_san-joaquin-schedule.ipynb
index cb2399059..84ef0b694 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_san-joaquin-schedule/00__rt_trip_updates_report__name_san-joaquin-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_san-joaquin-schedule/00__rt_trip_updates_report__name_san-joaquin-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:79e79bad189fe18b1e842c75d447571cdcbd57c4f025077f9576c72649324944
-size 1663293
+oid sha256:a713162b1799048ff9498f63658652bf6d666b80d3c968274139fad362612b65
+size 2120055
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_santa-rosa-citybus-gmv-schedule/00__rt_trip_updates_report__name_santa-rosa-citybus-gmv-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_santa-rosa-citybus-gmv-schedule/00__rt_trip_updates_report__name_santa-rosa-citybus-gmv-schedule.ipynb
index be933c6c0..695970ee3 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_santa-rosa-citybus-gmv-schedule/00__rt_trip_updates_report__name_santa-rosa-citybus-gmv-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_santa-rosa-citybus-gmv-schedule/00__rt_trip_updates_report__name_santa-rosa-citybus-gmv-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:31b8d3e6142da2b24799c525f5cbadea3ee9558882b9d8b92570ebee8407c85c
-size 1209119
+oid sha256:65cb7865620a64ebabdc480354f1b9f3e4bc52ac68f51d4db7a2074fce3a1562
+size 1812375
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_scvta-schedule/00__rt_trip_updates_report__name_scvta-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_scvta-schedule/00__rt_trip_updates_report__name_scvta-schedule.ipynb
index f6f54bd74..620081b76 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_scvta-schedule/00__rt_trip_updates_report__name_scvta-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_scvta-schedule/00__rt_trip_updates_report__name_scvta-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:9bb9aabf4cb000a0e613ff41aedac1d9dfb678c78df938b851e1b81b43e97d8e
-size 9533431
+oid sha256:863fd5ba04a0da68e2dff43343f7bb95f51457373bb7c783c0367d9c2546b452
+size 6805912
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_smart-schedule/00__rt_trip_updates_report__name_smart-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_smart-schedule/00__rt_trip_updates_report__name_smart-schedule.ipynb
index 3495ee9ef..28f4efd16 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_smart-schedule/00__rt_trip_updates_report__name_smart-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_smart-schedule/00__rt_trip_updates_report__name_smart-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:309cc03b07ff3a3f12f8ca65983272796e070a91c4e3f37cb330a6cbd0bcee35
-size 385625
+oid sha256:50d50df82cfb869f7c19d6bf5cb3e146739b39dbe94ff2f85d23d64ff6eba727
+size 849004
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_tahoe-transportation-district-gmv-schedule/00__rt_trip_updates_report__name_tahoe-transportation-district-gmv-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_tahoe-transportation-district-gmv-schedule/00__rt_trip_updates_report__name_tahoe-transportation-district-gmv-schedule.ipynb
index c9cc8a36c..625e84ba9 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_tahoe-transportation-district-gmv-schedule/00__rt_trip_updates_report__name_tahoe-transportation-district-gmv-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_tahoe-transportation-district-gmv-schedule/00__rt_trip_updates_report__name_tahoe-transportation-district-gmv-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:8688639957c27a0aac76cdd199691bb198f154d0d54f37db673d61b516627fa7
-size 686772
+oid sha256:efb0d284929716e18a892b1c391226ac82b1d9d2ae4463ee0dbd5e7004ab3f64
+size 1082678
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_tcrta-tripshot-schedule/00__rt_trip_updates_report__name_tcrta-tripshot-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_tcrta-tripshot-schedule/00__rt_trip_updates_report__name_tcrta-tripshot-schedule.ipynb
index e3842c5a4..4d4b3d1c4 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_tcrta-tripshot-schedule/00__rt_trip_updates_report__name_tcrta-tripshot-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_tcrta-tripshot-schedule/00__rt_trip_updates_report__name_tcrta-tripshot-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:59849f6f5f5b0818f2a167b88c68b9799686567b565ce940862dfcb09c2df268
-size 734861
+oid sha256:fdf72f59b6689741492c219af73a60483c93f5c7506f249e3a2c9df020ee3700
+size 1099107
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_tehama-schedule/00__rt_trip_updates_report__name_tehama-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_tehama-schedule/00__rt_trip_updates_report__name_tehama-schedule.ipynb
index 293465b07..af1d8f8df 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_tehama-schedule/00__rt_trip_updates_report__name_tehama-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_tehama-schedule/00__rt_trip_updates_report__name_tehama-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:17065e13be5da561d40c1f042a7e46e3b3a287976a7ad34c568b4a2c307b4152
-size 550478
+oid sha256:f97a885fe5077f0db1cb50ec267ac79dd74e71345c2c3e34419c99279f1b9044
+size 825343
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_torrance-schedule/00__rt_trip_updates_report__name_torrance-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_torrance-schedule/00__rt_trip_updates_report__name_torrance-schedule.ipynb
index b84ddd974..f4739ffe7 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_torrance-schedule/00__rt_trip_updates_report__name_torrance-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_torrance-schedule/00__rt_trip_updates_report__name_torrance-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:61fe378eaad06f4c0105483acb0e0fb9010622a1fe994a8e0ef7fb71ec39286d
-size 1109480
+oid sha256:06d4f597a7efb392b10128a64465c6f3dce776a85b5482a76d2368b588109a6b
+size 2004179
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_tri-valley-wheels-schedule/00__rt_trip_updates_report__name_tri-valley-wheels-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_tri-valley-wheels-schedule/00__rt_trip_updates_report__name_tri-valley-wheels-schedule.ipynb
index 8e3805273..df1340a49 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_tri-valley-wheels-schedule/00__rt_trip_updates_report__name_tri-valley-wheels-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_tri-valley-wheels-schedule/00__rt_trip_updates_report__name_tri-valley-wheels-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:5769d4c8428dcb3fdd442654fdf1123eb66c0baa74087cfdb4d9308d878ab449
-size 1462586
+oid sha256:28531238935f4e173313ddbbddd18261842fa0aa2d434919b5073804b985ba65
+size 1743456
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_tuolumne-remix-schedule/00__rt_trip_updates_report__name_tuolumne-remix-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_tuolumne-remix-schedule/00__rt_trip_updates_report__name_tuolumne-remix-schedule.ipynb
index 0fa183e1d..3383d2a92 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_tuolumne-remix-schedule/00__rt_trip_updates_report__name_tuolumne-remix-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_tuolumne-remix-schedule/00__rt_trip_updates_report__name_tuolumne-remix-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:41a6832c681f9dd510eaf84354a0de2e40a5455b84a08e348d95c1b15884bdb5
-size 425563
+oid sha256:cc8ccf99f97c51bf78ec17b98651b9e4df1efc942959d082e80301170f1a092e
+size 742614
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_tuolumne-schedule/00__rt_trip_updates_report__name_tuolumne-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_tuolumne-schedule/00__rt_trip_updates_report__name_tuolumne-schedule.ipynb
deleted file mode 100644
index fecf69a15..000000000
--- a/portfolio/rt_trip_updates_stop_metrics/name_tuolumne-schedule/00__rt_trip_updates_report__name_tuolumne-schedule.ipynb
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:0fffbc224ae7706ee8e736d085253e31423c1d78f70c390ddcb1ef2d7eb58b7c
-size 407462
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_turlock-schedule/00__rt_trip_updates_report__name_turlock-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_turlock-schedule/00__rt_trip_updates_report__name_turlock-schedule.ipynb
index 77106fdd9..a168be7d1 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_turlock-schedule/00__rt_trip_updates_report__name_turlock-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_turlock-schedule/00__rt_trip_updates_report__name_turlock-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:7c325ac5bbf5c3f607f8e23b6fc95a992e56a43a09792dbef47a00d16237864c
-size 491812
+oid sha256:4bad0c28edd36e82ef9549afdaa24d628aec0a3970ba677cee6dac456efe3fa5
+size 896702
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_union-city-gmv-schedule/00__rt_trip_updates_report__name_union-city-gmv-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_union-city-gmv-schedule/00__rt_trip_updates_report__name_union-city-gmv-schedule.ipynb
index b21a1548b..4eefd3626 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_union-city-gmv-schedule/00__rt_trip_updates_report__name_union-city-gmv-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_union-city-gmv-schedule/00__rt_trip_updates_report__name_union-city-gmv-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:46047f84fa630404cfd34a257c0ea20efa1c459a1fb1869f70311b82b7c4dda3
-size 1138986
+oid sha256:aceb8b805479932afe58595dad87bd994b40b13459c9de7270a204493a0b10ba
+size 1164778
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_vctc-gmv-schedule/00__rt_trip_updates_report__name_vctc-gmv-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_vctc-gmv-schedule/00__rt_trip_updates_report__name_vctc-gmv-schedule.ipynb
index c70ebbf7d..6d6cef4c9 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_vctc-gmv-schedule/00__rt_trip_updates_report__name_vctc-gmv-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_vctc-gmv-schedule/00__rt_trip_updates_report__name_vctc-gmv-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:7c15c50bdb7d3c5f7d8e2116101ac49e8fcf721c77d77d62d4a40ec8b28f612b
-size 8543213
+oid sha256:9803d76f05556cb9ea359b008161cc02fad8aa4606d65d6f987ce1a120f25387
+size 3591435
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_victor-valley-gmv-schedule/00__rt_trip_updates_report__name_victor-valley-gmv-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_victor-valley-gmv-schedule/00__rt_trip_updates_report__name_victor-valley-gmv-schedule.ipynb
index b80396042..2decb2673 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_victor-valley-gmv-schedule/00__rt_trip_updates_report__name_victor-valley-gmv-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_victor-valley-gmv-schedule/00__rt_trip_updates_report__name_victor-valley-gmv-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:9adec0527950270c2cf06c8b9a59a720c1b3d5ad4ab96514dad0a5945e73d848
-size 5619382
+oid sha256:b517f8da6c2c70df732cfc3ff39a3e54cb1d8a60ea42cb5708e9dfef75932ac3
+size 3216158
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_vine-gmv-schedule/00__rt_trip_updates_report__name_vine-gmv-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_vine-gmv-schedule/00__rt_trip_updates_report__name_vine-gmv-schedule.ipynb
index 42a15dd14..fe4c430b3 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_vine-gmv-schedule/00__rt_trip_updates_report__name_vine-gmv-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_vine-gmv-schedule/00__rt_trip_updates_report__name_vine-gmv-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:e4b885b8f978df8693a441ccafa1710d5dbaa097f86c03d8068fa6628802fd94
-size 1434437
+oid sha256:282098f0766cca63f6cfb35d4720c45ea587e19b77e3c021b6c1c153036c862d
+size 1430721
diff --git a/portfolio/rt_trip_updates_stop_metrics/name_visalia-schedule/00__rt_trip_updates_report__name_visalia-schedule.ipynb b/portfolio/rt_trip_updates_stop_metrics/name_visalia-schedule/00__rt_trip_updates_report__name_visalia-schedule.ipynb
index 23831b868..06c898647 100644
--- a/portfolio/rt_trip_updates_stop_metrics/name_visalia-schedule/00__rt_trip_updates_report__name_visalia-schedule.ipynb
+++ b/portfolio/rt_trip_updates_stop_metrics/name_visalia-schedule/00__rt_trip_updates_report__name_visalia-schedule.ipynb
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:56d39f9c808be0e042c988eeb86c83bdeaf78b369a93b953c0ba0b86ddd7c5e4
-size 1649921
+oid sha256:dff990f0c0213ca40a560618f2d0467a32aee11987b7ff199ea5e25d3e218853
+size 1908088
diff --git a/portfolio/sites/rt_trip_updates_stop_metrics.yml b/portfolio/sites/rt_trip_updates_stop_metrics.yml
index 3ce5e18d7..0c2c69c58 100644
--- a/portfolio/sites/rt_trip_updates_stop_metrics.yml
+++ b/portfolio/sites/rt_trip_updates_stop_metrics.yml
@@ -51,8 +51,6 @@ parts:
       name: Bay Area 511 Vine Transit Schedule
   - params:
       name: Beach Cities GMV Schedule
-  - params:
-      name: Beaumont Pass Schedule
   - params:
       name: Beaumont Transit Schedule
   - params:
@@ -73,8 +71,6 @@ parts:
       name: Fairfield Schedule
   - params:
       name: Fresno Schedule
-  - params:
-      name: Historic Tuolumne Schedule
   - params:
       name: Humboldt Schedule
   - params:
@@ -97,8 +93,6 @@ parts:
       name: Marin GMV Schedule
   - params:
       name: Marin Optibus Schedule
-  - params:
-      name: Marin Schedule
   - params:
       name: Mendocino Schedule
   - params:
@@ -113,8 +107,6 @@ parts:
       name: North County Schedule
   - params:
       name: OCTA Schedule
-  - params:
-      name: Ojai Schedule
   - params:
       name: Petaluma GMV Schedule
   - params:
@@ -123,8 +115,6 @@ parts:
       name: Redding Schedule
   - params:
       name: Redwood Coast Schedule
-  - params:
-      name: Redwood Coast Schedulel
   - params:
       name: Roseville Transit GMV Schedule
   - params:
@@ -149,8 +139,6 @@ parts:
       name: Tri-Valley Wheels Schedule
   - params:
       name: Tuolumne Remix Schedule
-  - params:
-      name: Tuolumne Schedule
   - params:
       name: Turlock Schedule
   - params:
diff --git a/rt_predictions/07_stop_prediction_error_exploration.ipynb b/rt_predictions/07_stop_prediction_error_exploration.ipynb
new file mode 100644
index 000000000..d8cc3c311
--- /dev/null
+++ b/rt_predictions/07_stop_prediction_error_exploration.ipynb
@@ -0,0 +1,1461 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "id": "45c2f6d0-52f7-456d-8c10-725e2c3fab0b",
+   "metadata": {},
+   "source": [
+    "# Daily Stop Grain Exploration\n",
+    "\n",
+    "1. Make sure that `avg_prediction_error_sec` matches up with how a prediction is categorized as `early/on_time/late`, and make sure those seconds have the right signs.\n",
+    "1. Make sure that `early/on_time/late` metrics make sense with `pct_accuracy`\n",
+    "1. Deeper dive into the \"accuracy\" exponential curve. See if we can use this as \"expected wait time\" metric."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "id": "d2c0f29f-b019-41d3-9a45-499ecb76344b",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "import altair as alt\n",
+    "import pandas as pd\n",
+    "\n",
+    "import prep_data\n",
+    "from rt_msa_utils import PREDICTIONS_GCS, RT_MSA_DICT\n",
+    "\n",
+    "alt.data_transformers.enable(\"vegafusion\")\n",
+    "\n",
+    "DOWNLOAD_DICT = RT_MSA_DICT.rt_trip_updates_downloads"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "4998a876-dc95-4f49-90d7-123b78e2a3a5",
+   "metadata": {},
+   "source": [
+    "## Daily Stop Grain\n",
+    "### Avg prediction error seconds is positive for bus arriving after prediction says (prediction is **earlier** than actual)\n",
+    "* yes, the sign direction is correct\n",
+    "* we will want to remove outliers, maybe anything above a certain threshold of minutes (here, it's 1% or less for outliers)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "id": "7cbc169a-0bb0-4254-82e5-1c33008c19a9",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "key                                      object\n",
+       "stop_key                                 object\n",
+       "base64_url                               object\n",
+       "service_date                     datetime64[ns]\n",
+       "stop_id                                  object\n",
+       "schedule_feed_key                        object\n",
+       "avg_prediction_error_sec                float64\n",
+       "n_tu_accurate_minutes                     Int64\n",
+       "n_tu_complete_minutes                     Int64\n",
+       "n_tu_minutes_available                    Int64\n",
+       "avg_prediction_spread_minutes           float64\n",
+       "n_predictions                             Int64\n",
+       "n_predictions_early                       Int64\n",
+       "n_predictions_ontime                      Int64\n",
+       "n_predictions_late                        Int64\n",
+       "n_tu_trips                                Int64\n",
+       "dtype: object"
+      ]
+     },
+     "execution_count": 2,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "FILE = RT_MSA_DICT.rt_trip_updates_downloads.daily_stop_grain\n",
+    "\n",
+    "daily_df = pd.read_parquet(\n",
+    "    f\"{PREDICTIONS_GCS}{FILE}.parquet\"\n",
+    ")\n",
+    "\n",
+    "daily_df.dtypes"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "id": "85f40f62-808e-4a6b-96e6-981b232fcbf9",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "
\n",
+       "\n",
+       "
\n",
+       "  \n",
+       "    \n",
+       "      | \n",
+       " | avg_prediction_error_sec\n",
+       " | pct_tu_predictions_early\n",
+       " | pct_tu_predictions_ontime\n",
+       " | pct_tu_predictions_late\n",
+       " | 
\n",
+       "  \n",
+       "  \n",
+       "    \n",
+       "      | count\n",
+       " | 926463.000000\n",
+       " | 942162.0\n",
+       " | 942162.0\n",
+       " | 942162.0\n",
+       " | 
\n",
+       "    \n",
+       "      | mean\n",
+       " | 49.187435\n",
+       " | 0.631339\n",
+       " | 0.03902\n",
+       " | 0.302079\n",
+       " | 
\n",
+       "    \n",
+       "      | std\n",
+       " | 123.158659\n",
+       " | 0.197401\n",
+       " | 0.107054\n",
+       " | 0.161343\n",
+       " | 
\n",
+       "    \n",
+       "      | min\n",
+       " | -22509.692308\n",
+       " | 0.0\n",
+       " | 0.0\n",
+       " | 0.0\n",
+       " | 
\n",
+       "    \n",
+       "      | 1%\n",
+       " | -185.920227\n",
+       " | 0.0\n",
+       " | 0.0\n",
+       " | 0.0\n",
+       " | 
\n",
+       "    \n",
+       "      | 5%\n",
+       " | -46.243339\n",
+       " | 0.25\n",
+       " | 0.0\n",
+       " | 0.05\n",
+       " | 
\n",
+       "    \n",
+       "      | 10%\n",
+       " | -15.833333\n",
+       " | 0.39\n",
+       " | 0.0\n",
+       " | 0.11\n",
+       " | 
\n",
+       "    \n",
+       "      | 25%\n",
+       " | 21.045454\n",
+       " | 0.53\n",
+       " | 0.01\n",
+       " | 0.19\n",
+       " | 
\n",
+       "    \n",
+       "      | 50%\n",
+       " | 55.886665\n",
+       " | 0.67\n",
+       " | 0.01\n",
+       " | 0.29\n",
+       " | 
\n",
+       "    \n",
+       "      | 75%\n",
+       " | 85.399978\n",
+       " | 0.77\n",
+       " | 0.02\n",
+       " | 0.4\n",
+       " | 
\n",
+       "    \n",
+       "      | 90%\n",
+       " | 115.561361\n",
+       " | 0.84\n",
+       " | 0.06\n",
+       " | 0.51\n",
+       " | 
\n",
+       "    \n",
+       "      | 95%\n",
+       " | 138.694220\n",
+       " | 0.88\n",
+       " | 0.18\n",
+       " | 0.58\n",
+       " | 
\n",
+       "    \n",
+       "      | 99%\n",
+       " | 214.427955\n",
+       " | 0.96\n",
+       " | 0.51\n",
+       " | 0.75\n",
+       " | 
\n",
+       "    \n",
+       "      | max\n",
+       " | 1513.930476\n",
+       " | 1.0\n",
+       " | 1.0\n",
+       " | 1.0\n",
+       " | 
\n",
+       "  \n",
+       "
\n",
+       "
\n",
+       "\n",
+       "
\n",
+       "  \n",
+       "    \n",
+       "      | \n",
+       " | avg_prediction_error_sec\n",
+       " | pct_tu_predictions_early\n",
+       " | pct_tu_predictions_ontime\n",
+       " | pct_tu_predictions_late\n",
+       " | 
\n",
+       "  \n",
+       "  \n",
+       "    \n",
+       "      | count\n",
+       " | 914559.000000\n",
+       " | 914559.0\n",
+       " | 914559.0\n",
+       " | 914559.0\n",
+       " | 
\n",
+       "    \n",
+       "      | mean\n",
+       " | 51.468511\n",
+       " | 0.643398\n",
+       " | 0.039625\n",
+       " | 0.306053\n",
+       " | 
\n",
+       "    \n",
+       "      | std\n",
+       " | 56.734082\n",
+       " | 0.178116\n",
+       " | 0.108301\n",
+       " | 0.154067\n",
+       " | 
\n",
+       "    \n",
+       "      | min\n",
+       " | -250.000000\n",
+       " | 0.0\n",
+       " | 0.0\n",
+       " | 0.0\n",
+       " | 
\n",
+       "    \n",
+       "      | 1%\n",
+       " | -130.567398\n",
+       " | 0.01\n",
+       " | 0.0\n",
+       " | 0.0\n",
+       " | 
\n",
+       "    \n",
+       "      | 5%\n",
+       " | -40.838048\n",
+       " | 0.32\n",
+       " | 0.0\n",
+       " | 0.08\n",
+       " | 
\n",
+       "    \n",
+       "      | 10%\n",
+       " | -13.808901\n",
+       " | 0.41\n",
+       " | 0.0\n",
+       " | 0.12\n",
+       " | 
\n",
+       "    \n",
+       "      | 25%\n",
+       " | 21.653752\n",
+       " | 0.54\n",
+       " | 0.01\n",
+       " | 0.2\n",
+       " | 
\n",
+       "    \n",
+       "      | 50%\n",
+       " | 55.896078\n",
+       " | 0.67\n",
+       " | 0.01\n",
+       " | 0.29\n",
+       " | 
\n",
+       "    \n",
+       "      | 75%\n",
+       " | 84.969749\n",
+       " | 0.77\n",
+       " | 0.02\n",
+       " | 0.4\n",
+       " | 
\n",
+       "    \n",
+       "      | 90%\n",
+       " | 113.993045\n",
+       " | 0.84\n",
+       " | 0.06\n",
+       " | 0.51\n",
+       " | 
\n",
+       "    \n",
+       "      | 95%\n",
+       " | 134.891708\n",
+       " | 0.88\n",
+       " | 0.18\n",
+       " | 0.57\n",
+       " | 
\n",
+       "    \n",
+       "      | 99%\n",
+       " | 186.113821\n",
+       " | 0.96\n",
+       " | 0.53\n",
+       " | 0.72\n",
+       " | 
\n",
+       "    \n",
+       "      | max\n",
+       " | 249.989072\n",
+       " | 1.0\n",
+       " | 1.0\n",
+       " | 1.0\n",
+       " | 
\n",
+       "  \n",
+       "
\n",
+       "
"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "daily_df2[(daily_df2.pct_tu_predictions_late >= 0.5)].avg_prediction_error_sec.hist(bins=100)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "id": "70a6b694-3676-40a3-97f8-28c04d1754b4",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       ""
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    },
+    {
+     "data": {
+      "image/png": "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o8rKSr+63bt36/7771dkZKTi4uKUm5tba1tr165Vr169FBkZqb59+2r9+vWB2o1m4aWXXtK9996rqKioa37o5JEjR5SamqqoqChFR0drxowZunTpkl/Npk2bNGjQINlsNvXs2VMFBQVNP/lmLi8vTz169FBkZKSSkpK0Y8eOYE+pWdmyZYsefvhhdenSRSEhIfrggw/81huGoezsbHXu3FmtWrVScnKy/va3v/nVnDhxQuPHj5fdblf79u01adIknT17NoB7cfNbsGCBfvSjH6lt27aKjo7WmDFjdPDgQb+aixcvKj09XZ06dVKbNm00duzYWh+CW5/3kZaKkNPCHDhwQNXV1Xr99de1b98+LVmyRPn5+frlL39p1ni9XqWkpKh79+4qLS3Vyy+/rJycHL3xxhtmzdatW/Xkk09q0qRJ2rVrl8aMGaMxY8Zo7969wditm1JlZaUef/xxTZ069arrq6qqlJqaqsrKSm3dulVvv/22CgoKlJ2dbdYcOnRIqampGj58uMrKyjRt2jQ9++yzKioqCtRuNDurV69WZmam5syZo88++0z9+/eX0+nU8ePHgz21ZuPcuXPq37+/8vLyrro+NzdXv/3tb5Wfn6/t27erdevWcjqdunjxolkzfvx47du3Ty6XS+vWrdOWLVv03HPPBWoXmoXNmzcrPT1d27Ztk8vlks/nU0pKis6dO2fWTJ8+XR9++KHWrl2rzZs36+jRo3rsscfM9fV5H2nRDLR4ubm5Rnx8vLn86quvGh06dDAqKirMsRdeeMG4++67zeX//M//NFJTU/22k5SUZPzsZz9r+gk3MytXrjTatWtXa3z9+vVGaGio4fF4zLHXXnvNsNvtZu9nzpxp3HPPPX6PGzdunOF0Opt0zs3ZkCFDjPT0dHO5qqrK6NKli7FgwYIgzqr5kmS8//775nJ1dbURGxtrvPzyy+bYqVOnDJvNZvzud78zDMMw9u/fb0gyPv30U7PmT3/6kxESEmL885//DNjcm5vjx48bkozNmzcbhnG5r+Hh4cbatWvNms8//9yQZLjdbsMw6vc+0pJxJAc6ffq0OnbsaC673W498MADioiIMMecTqcOHjyokydPmjXJycl+23E6nXK73YGZtAW43W717dvX78MrnU6nvF6v9u3bZ9bQ5/qrrKxUaWmpX89CQ0OVnJxMzxrJoUOH5PF4/Hrcrl07JSUlmT12u91q3769Bg8ebNYkJycrNDRU27dvD/icm4vTp09Lkvl+XFpaKp/P59frXr16qVu3bn69vt77SEtGyGnhvvjiC73yyiv62c9+Zo55PJ5anxpds+zxeOqsqVmP6/shffZ6vbpw4UJgJtqM/Otf/1JVVRWvzSZU08e6euzxeBQdHe23/pZbblHHjh3573AN1dXVmjZtmn784x+rT58+ki73MSIiotY1fd/v9fXeR1oyQo5FzJo1SyEhIXX+HDhwwO8x//znPzVq1Cg9/vjjmjx5cpBm3rzcSJ8B4HrS09O1d+9evffee8GeiqU06++uwnd+8Ytf6Omnn66z5vbbbzf/fvToUQ0fPlz33nuv3wXFkhQbG1vr6v2a5djY2DpratZbVUP7XJfY2Nhad/3Ut892u12tWrWq56xbjltvvVVhYWEt8rUZKDV9LC8vV+fOnc3x8vJyDRgwwKz5/oXely5d0okTJ/jvcBUZGRnmxdldu3Y1x2NjY1VZWalTp075Hc258vVcn/eRlowjORZx2223qVevXnX+1Fxj889//lPDhg1TYmKiVq5cqdBQ/5eBw+HQli1b5PP5zDGXy6W7775bHTp0MGtKSkr8HudyueRwOJp4T4OrIX2+HofDoT179vj9Y+ByuWS325WQkGDWtMQ+36iIiAglJib69ay6ulolJSX0rJHEx8crNjbWr8der1fbt283e+xwOHTq1CmVlpaaNRs3blR1dbWSkpICPueblWEYysjI0Pvvv6+NGzcqPj7eb31iYqLCw8P9en3w4EEdOXLEr9fXex9p0YJ95TMC6+uvvzZ69uxpjBgxwvj666+NY8eOmT81Tp06ZcTExBgTJkww9u7da7z33ntGVFSU8frrr5s1f/nLX4xbbrnF+M1vfmN8/vnnxpw5c4zw8HBjz549wditm9I//vEPY9euXcbcuXONNm3aGLt27TJ27dplnDlzxjAMw7h06ZLRp08fIyUlxSgrKzM2bNhg3HbbbUZWVpa5jb///e9GVFSUMWPGDOPzzz838vLyjLCwMGPDhg3B2q2b3nvvvWfYbDajoKDA2L9/v/Hcc88Z7du397v7BHU7c+aM+XqVZCxevNjYtWuX8Y9//MMwDMNYuHCh0b59e+OPf/yjsXv3buORRx4x4uPjjQsXLpjbGDVqlDFw4EBj+/btxieffGLceeedxpNPPhmsXbopTZ061WjXrp2xadMmv/fi8+fPmzVTpkwxunXrZmzcuNHYuXOn4XA4DIfDYa6vz/tIS0bIaWFWrlxpSLrqz5X++te/Gvfdd59hs9mM//f//p+xcOHCWttas2aNcddddxkRERHGPffcYxQWFgZqN5qFtLS0q/b5448/NmsOHz5sjB492mjVqpVx6623Gr/4xS8Mn8/nt52PP/7YGDBggBEREWHcfvvtxsqVKwO7I83QK6+8YnTr1s2IiIgwhgwZYmzbti3YU2pWPv7446u+dtPS0gzDuHwb+YsvvmjExMQYNpvNGDFihHHw4EG/bXz77bfGk08+abRp08aw2+3GxIkTzYCPy671Xnzl7/iFCxeM//qv/zI6dOhgREVFGY8++qjf/5QaRv3eR1qqEMMwjAAeOAIAAAgIrskBAACWRMgBAACWRMgBAACWRMgBAACWRMgBAACWRMgBAACWRMgBAACWRMgBAACWRMgBAACWRMgBAACWRMgBAACWRMgBAACW9P8D8TGWzAuEsEUAAAAASUVORK5CYII=",
+      "text/plain": [
+       ""
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "daily_df2[(daily_df2.pct_tu_predictions_early >= 0.5)].avg_prediction_error_sec.hist(bins=100)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "id": "b313b745-f542-4cda-8a00-c45a762f12df",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "\n",
+       "
\n",
+       "  \n",
+       "    \n",
+       "      | \n",
+       " | pct_tu_accurate_minutes\n",
+       " | pct_tu_predictions_ontime\n",
+       " | 
\n",
+       "  \n",
+       "  \n",
+       "    \n",
+       "      | count\n",
+       " | 942162.0\n",
+       " | 942162.0\n",
+       " | 
\n",
+       "    \n",
+       "      | mean\n",
+       " | 0.749586\n",
+       " | 0.03902\n",
+       " | 
\n",
+       "    \n",
+       "      | std\n",
+       " | 0.172775\n",
+       " | 0.107054\n",
+       " | 
\n",
+       "    \n",
+       "      | min\n",
+       " | 0.0\n",
+       " | 0.0\n",
+       " | 
\n",
+       "    \n",
+       "      | 1%\n",
+       " | 0.0\n",
+       " | 0.0\n",
+       " | 
\n",
+       "    \n",
+       "      | 5%\n",
+       " | 0.41\n",
+       " | 0.0\n",
+       " | 
\n",
+       "    \n",
+       "      | 10%\n",
+       " | 0.56\n",
+       " | 0.0\n",
+       " | 
\n",
+       "    \n",
+       "      | 25%\n",
+       " | 0.7\n",
+       " | 0.01\n",
+       " | 
\n",
+       "    \n",
+       "      | 50%\n",
+       " | 0.79\n",
+       " | 0.01\n",
+       " | 
\n",
+       "    \n",
+       "      | 75%\n",
+       " | 0.85\n",
+       " | 0.02\n",
+       " | 
\n",
+       "    \n",
+       "      | 90%\n",
+       " | 0.91\n",
+       " | 0.06\n",
+       " | 
\n",
+       "    \n",
+       "      | 95%\n",
+       " | 0.94\n",
+       " | 0.18\n",
+       " | 
\n",
+       "    \n",
+       "      | 99%\n",
+       " | 1.0\n",
+       " | 0.51\n",
+       " | 
\n",
+       "    \n",
+       "      | max\n",
+       " | 1.0\n",
+       " | 1.0\n",
+       " | 
\n",
+       "  \n",
+       "
\n",
+       "
\n",
+       "\n",
+       "
\n",
+       "  \n",
+       "    \n",
+       "      | \n",
+       " | pct_tu_accurate_minutes\n",
+       " | pct_tu_predictions_ontime\n",
+       " | 
\n",
+       "  \n",
+       "  \n",
+       "    \n",
+       "      | count\n",
+       " | 914559.0\n",
+       " | 914559.0\n",
+       " | 
\n",
+       "    \n",
+       "      | mean\n",
+       " | 0.767459\n",
+       " | 0.039625\n",
+       " | 
\n",
+       "    \n",
+       "      | std\n",
+       " | 0.135172\n",
+       " | 0.108301\n",
+       " | 
\n",
+       "    \n",
+       "      | min\n",
+       " | 0.0\n",
+       " | 0.0\n",
+       " | 
\n",
+       "    \n",
+       "      | 1%\n",
+       " | 0.33\n",
+       " | 0.0\n",
+       " | 
\n",
+       "    \n",
+       "      | 5%\n",
+       " | 0.5\n",
+       " | 0.0\n",
+       " | 
\n",
+       "    \n",
+       "      | 10%\n",
+       " | 0.59\n",
+       " | 0.0\n",
+       " | 
\n",
+       "    \n",
+       "      | 25%\n",
+       " | 0.71\n",
+       " | 0.01\n",
+       " | 
\n",
+       "    \n",
+       "      | 50%\n",
+       " | 0.79\n",
+       " | 0.01\n",
+       " | 
\n",
+       "    \n",
+       "      | 75%\n",
+       " | 0.86\n",
+       " | 0.02\n",
+       " | 
\n",
+       "    \n",
+       "      | 90%\n",
+       " | 0.91\n",
+       " | 0.06\n",
+       " | 
\n",
+       "    \n",
+       "      | 95%\n",
+       " | 0.94\n",
+       " | 0.18\n",
+       " | 
\n",
+       "    \n",
+       "      | 99%\n",
+       " | 1.0\n",
+       " | 0.53\n",
+       " | 
\n",
+       "    \n",
+       "      | max\n",
+       " | 1.0\n",
+       " | 1.0\n",
+       " | 
\n",
+       "  \n",
+       "
\n",
+       "
\n",
+       "\n",
+       "
\n",
+       "  \n",
+       "    \n",
+       "      | \n",
+       " | avg_prediction_error_sec\n",
+       " | pct_tu_predictions_early\n",
+       " | pct_tu_predictions_ontime\n",
+       " | pct_tu_predictions_late\n",
+       " | 
\n",
+       "  \n",
+       "  \n",
+       "    \n",
+       "      | count\n",
+       " | 1.742386e+06\n",
+       " | 1.764792e+06\n",
+       " | 1.764792e+06\n",
+       " | 1.764792e+06\n",
+       " | 
\n",
+       "    \n",
+       "      | mean\n",
+       " | 4.732094e+01\n",
+       " | 6.312258e-01\n",
+       " | 3.748932e-02\n",
+       " | 3.073510e-01\n",
+       " | 
\n",
+       "    \n",
+       "      | std\n",
+       " | 1.203496e+02\n",
+       " | 1.711195e-01\n",
+       " | 9.187022e-02\n",
+       " | 1.366724e-01\n",
+       " | 
\n",
+       "    \n",
+       "      | min\n",
+       " | -2.097112e+04\n",
+       " | 0.000000e+00\n",
+       " | 0.000000e+00\n",
+       " | 0.000000e+00\n",
+       " | 
\n",
+       "    \n",
+       "      | 1%\n",
+       " | -1.613084e+02\n",
+       " | 0.000000e+00\n",
+       " | 0.000000e+00\n",
+       " | 0.000000e+00\n",
+       " | 
\n",
+       "    \n",
+       "      | 5%\n",
+       " | -3.716826e+01\n",
+       " | 3.000000e-01\n",
+       " | 0.000000e+00\n",
+       " | 1.000000e-01\n",
+       " | 
\n",
+       "    \n",
+       "      | 10%\n",
+       " | -7.003360e+00\n",
+       " | 4.200000e-01\n",
+       " | 1.000000e-02\n",
+       " | 1.500000e-01\n",
+       " | 
\n",
+       "    \n",
+       "      | 25%\n",
+       " | 2.773828e+01\n",
+       " | 5.600000e-01\n",
+       " | 1.000000e-02\n",
+       " | 2.200000e-01\n",
+       " | 
\n",
+       "    \n",
+       "      | 50%\n",
+       " | 5.419504e+01\n",
+       " | 6.700000e-01\n",
+       " | 1.000000e-02\n",
+       " | 3.000000e-01\n",
+       " | 
\n",
+       "    \n",
+       "      | 75%\n",
+       " | 7.792475e+01\n",
+       " | 7.400000e-01\n",
+       " | 2.000000e-02\n",
+       " | 3.800000e-01\n",
+       " | 
\n",
+       "    \n",
+       "      | 90%\n",
+       " | 1.014436e+02\n",
+       " | 8.000000e-01\n",
+       " | 6.000000e-02\n",
+       " | 4.800000e-01\n",
+       " | 
\n",
+       "    \n",
+       "      | 95%\n",
+       " | 1.198483e+02\n",
+       " | 8.400000e-01\n",
+       " | 1.900000e-01\n",
+       " | 5.400000e-01\n",
+       " | 
\n",
+       "    \n",
+       "      | 99%\n",
+       " | 1.726551e+02\n",
+       " | 9.000000e-01\n",
+       " | 4.100000e-01\n",
+       " | 7.100000e-01\n",
+       " | 
\n",
+       "    \n",
+       "      | max\n",
+       " | 1.188624e+03\n",
+       " | 1.000000e+00\n",
+       " | 1.000000e+00\n",
+       " | 1.000000e+00\n",
+       " | 
\n",
+       "  \n",
+       "
\n",
+       "
\n",
+       "\n",
+       "
\n",
+       "  \n",
+       "    \n",
+       "      | \n",
+       " | avg_prediction_error_sec\n",
+       " | pct_tu_predictions_early\n",
+       " | pct_tu_predictions_ontime\n",
+       " | pct_tu_predictions_late\n",
+       " | 
\n",
+       "  \n",
+       "  \n",
+       "    \n",
+       "      | count\n",
+       " | 1.727213e+06\n",
+       " | 1.727213e+06\n",
+       " | 1.727213e+06\n",
+       " | 1.727213e+06\n",
+       " | 
\n",
+       "    \n",
+       "      | mean\n",
+       " | 4.989460e+01\n",
+       " | 6.410566e-01\n",
+       " | 3.796528e-02\n",
+       " | 3.096397e-01\n",
+       " | 
\n",
+       "    \n",
+       "      | std\n",
+       " | 4.924638e+01\n",
+       " | 1.533830e-01\n",
+       " | 9.267598e-02\n",
+       " | 1.289014e-01\n",
+       " | 
\n",
+       "    \n",
+       "      | min\n",
+       " | -2.499416e+02\n",
+       " | 0.000000e+00\n",
+       " | 0.000000e+00\n",
+       " | 0.000000e+00\n",
+       " | 
\n",
+       "    \n",
+       "      | 1%\n",
+       " | -1.184392e+02\n",
+       " | 1.100000e-01\n",
+       " | 0.000000e+00\n",
+       " | 2.000000e-02\n",
+       " | 
\n",
+       "    \n",
+       "      | 5%\n",
+       " | -3.224838e+01\n",
+       " | 3.500000e-01\n",
+       " | 0.000000e+00\n",
+       " | 1.200000e-01\n",
+       " | 
\n",
+       "    \n",
+       "      | 10%\n",
+       " | -5.213724e+00\n",
+       " | 4.500000e-01\n",
+       " | 1.000000e-02\n",
+       " | 1.600000e-01\n",
+       " | 
\n",
+       "    \n",
+       "      | 25%\n",
+       " | 2.826944e+01\n",
+       " | 5.700000e-01\n",
+       " | 1.000000e-02\n",
+       " | 2.200000e-01\n",
+       " | 
\n",
+       "    \n",
+       "      | 50%\n",
+       " | 5.430531e+01\n",
+       " | 6.700000e-01\n",
+       " | 1.000000e-02\n",
+       " | 3.000000e-01\n",
+       " | 
\n",
+       "    \n",
+       "      | 75%\n",
+       " | 7.781720e+01\n",
+       " | 7.400000e-01\n",
+       " | 2.000000e-02\n",
+       " | 3.800000e-01\n",
+       " | 
\n",
+       "    \n",
+       "      | 90%\n",
+       " | 1.008661e+02\n",
+       " | 8.000000e-01\n",
+       " | 6.000000e-02\n",
+       " | 4.800000e-01\n",
+       " | 
\n",
+       "    \n",
+       "      | 95%\n",
+       " | 1.183707e+02\n",
+       " | 8.400000e-01\n",
+       " | 1.900000e-01\n",
+       " | 5.300000e-01\n",
+       " | 
\n",
+       "    \n",
+       "      | 99%\n",
+       " | 1.612898e+02\n",
+       " | 9.000000e-01\n",
+       " | 4.200000e-01\n",
+       " | 6.700000e-01\n",
+       " | 
\n",
+       "    \n",
+       "      | max\n",
+       " | 2.496432e+02\n",
+       " | 1.000000e+00\n",
+       " | 1.000000e+00\n",
+       " | 1.000000e+00\n",
+       " | 
\n",
+       "  \n",
+       "
\n",
+       "
"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "daytype_df2[(daytype_df2.pct_tu_predictions_late >= 0.5)].avg_prediction_error_sec.hist(bins=100)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "id": "60bf3b84-460e-4d6e-93ef-4bc7ad583e2e",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       ""
+      ]
+     },
+     "execution_count": 14,
+     "metadata": {},
+     "output_type": "execute_result"
+    },
+    {
+     "data": {
+      "image/png": "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8ePtffzrX/+yoqKirDFjxlh79uyxFi9ebIWFhVnFxcWNdVhN3ptvvmk5HA5r6dKl1u7du62RI0dasbGxflfV4MKOHz9uP18lWXPnzrW2bdtmff7555ZlWdbMmTOt2NhY629/+5v16aefWvfee6+VkpJifffdd/Y+Bg4caF1//fVWaWmp9cEHH1jXXHONNXTo0MY6pCbpiSeesGJiYqz333/f7/X45MmTds3jjz9uXXXVVdb69eutjz76yEpLS7PS0tLs7fV5HTEZQQh+lixZYkk678/ZPvnkE+vWW2+1HA6HdcUVV1gzZ86ss6+33nrLuvbaa62IiAirR48eVlFRUbAOo9nIzs4+b6/fe+89u+bAgQPWL3/5S6t169bWZZddZv3+97+3fD6f337ee+89q0+fPlZERIT1s5/9zFqyZElwD6QZWrhwoXXVVVdZERERVv/+/a3Nmzc39pSalffee++8z93s7GzLsr6/hH7ixIlWQkKC5XA4rAEDBlj79u3z28c333xjDR061Grbtq0VHR1tDR8+3P5HAL73Q6/HZ/+Of/fdd9aTTz5pxcXFWVFRUdZ9993n949Xy6rf64ipQizLsoK4AAUAANBkcI4QAAAwFkEIAAAYiyAEAACMRRACAADGIggBAABjEYQAAICxCEIAAMBYBCEAAGAsghAAADAWQQgAABiLIAQAAIxFEAIAAMb6/4r6DpsrfxqKAAAAAElFTkSuQmCC",
+      "text/plain": [
+       ""
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "daytype_df2[(daytype_df2.pct_tu_predictions_early >= 0.5)].avg_prediction_error_sec.hist(bins=100)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "id": "db0b4421-3ddf-4384-ba06-a00348929c3b",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "\n",
+       "
\n",
+       "  \n",
+       "    \n",
+       "      | \n",
+       " | pct_tu_accurate_minutes\n",
+       " | pct_tu_predictions_ontime\n",
+       " | 
\n",
+       "  \n",
+       "  \n",
+       "    \n",
+       "      | count\n",
+       " | 1.727213e+06\n",
+       " | 1.727213e+06\n",
+       " | 
\n",
+       "    \n",
+       "      | mean\n",
+       " | 7.699415e-01\n",
+       " | 3.796528e-02\n",
+       " | 
\n",
+       "    \n",
+       "      | std\n",
+       " | 1.205612e-01\n",
+       " | 9.267598e-02\n",
+       " | 
\n",
+       "    \n",
+       "      | min\n",
+       " | 0.000000e+00\n",
+       " | 0.000000e+00\n",
+       " | 
\n",
+       "    \n",
+       "      | 1%\n",
+       " | 3.500000e-01\n",
+       " | 0.000000e+00\n",
+       " | 
\n",
+       "    \n",
+       "      | 5%\n",
+       " | 5.300000e-01\n",
+       " | 0.000000e+00\n",
+       " | 
\n",
+       "    \n",
+       "      | 10%\n",
+       " | 6.300000e-01\n",
+       " | 1.000000e-02\n",
+       " | 
\n",
+       "    \n",
+       "      | 25%\n",
+       " | 7.300000e-01\n",
+       " | 1.000000e-02\n",
+       " | 
\n",
+       "    \n",
+       "      | 50%\n",
+       " | 7.900000e-01\n",
+       " | 1.000000e-02\n",
+       " | 
\n",
+       "    \n",
+       "      | 75%\n",
+       " | 8.500000e-01\n",
+       " | 2.000000e-02\n",
+       " | 
\n",
+       "    \n",
+       "      | 90%\n",
+       " | 8.900000e-01\n",
+       " | 6.000000e-02\n",
+       " | 
\n",
+       "    \n",
+       "      | 95%\n",
+       " | 9.100000e-01\n",
+       " | 1.900000e-01\n",
+       " | 
\n",
+       "    \n",
+       "      | 99%\n",
+       " | 9.700000e-01\n",
+       " | 4.200000e-01\n",
+       " | 
\n",
+       "    \n",
+       "      | max\n",
+       " | 1.000000e+00\n",
+       " | 1.000000e+00\n",
+       " | 
\n",
+       "  \n",
+       "
\n",
+       "
\n",
+       "\n",
+       "
\n",
+       "  \n",
+       "    \n",
+       "      | \n",
+       " | key\n",
+       " | stop_key\n",
+       " | base64_url\n",
+       " | service_date\n",
+       " | stop_id\n",
+       " | schedule_feed_key\n",
+       " | avg_prediction_error_sec\n",
+       " | n_tu_accurate_minutes\n",
+       " | n_tu_complete_minutes\n",
+       " | n_tu_minutes_available\n",
+       " | ...\n",
+       " | n_predictions_early\n",
+       " | n_predictions_ontime\n",
+       " | n_predictions_late\n",
+       " | n_tu_trips\n",
+       " | pct_tu_predictions_early\n",
+       " | pct_tu_predictions_ontime\n",
+       " | pct_tu_predictions_late\n",
+       " | pct_tu_accurate_minutes\n",
+       " | pct_tu_predictions_early_ontime\n",
+       " | prediction_error_category\n",
+       " | 
\n",
+       "  \n",
+       "  \n",
+       "    \n",
+       "      | 0\n",
+       " | 5fd1b1a829400b57519951e7e5409643\n",
+       " | 3b95038c8989c9dcd4871c11fb7081be\n",
+       " | aHR0cHM6Ly9hcGkuZ29zd2lmdC5seS9yZWFsLXRpbWUvbG...\n",
+       " | 2025-06-08\n",
+       " | 7373\n",
+       " | 8d9623a1823a27925b7e2f00e44fc5bb\n",
+       " | 39.183454\n",
+       " | 7113\n",
+       " | 9123\n",
+       " | 9234\n",
+       " | ...\n",
+       " | 17070\n",
+       " | 315\n",
+       " | 9951\n",
+       " | 90\n",
+       " | 0.62\n",
+       " | 0.01\n",
+       " | 0.36\n",
+       " | 0.77\n",
+       " | 0.63\n",
+       " | ontime\n",
+       " | 
\n",
+       "    \n",
+       "      | 1\n",
+       " | eb6c24f24772649fe54ae88566015a8d\n",
+       " | fff2473a01ee0e1f7f3913e16bba795f\n",
+       " | aHR0cHM6Ly9hcGkuZ29zd2lmdC5seS9yZWFsLXRpbWUvbG...\n",
+       " | 2025-06-08\n",
+       " | 1222\n",
+       " | 8d9623a1823a27925b7e2f00e44fc5bb\n",
+       " | 48.851525\n",
+       " | 9192\n",
+       " | 10191\n",
+       " | 10302\n",
+       " | ...\n",
+       " | 21303\n",
+       " | 546\n",
+       " | 8709\n",
+       " | 106\n",
+       " | 0.7\n",
+       " | 0.02\n",
+       " | 0.28\n",
+       " | 0.89\n",
+       " | 0.72\n",
+       " | ontime\n",
+       " | 
\n",
+       "    \n",
+       "      | 2\n",
+       " | e763549740cb2e9dcd92e223cded777c\n",
+       " | 4ed1b3a7ad8900a527682cf50cd17862\n",
+       " | aHR0cHM6Ly9hcGkuZ29zd2lmdC5seS9yZWFsLXRpbWUvbG...\n",
+       " | 2025-06-08\n",
+       " | 11909\n",
+       " | 8d9623a1823a27925b7e2f00e44fc5bb\n",
+       " | 58.596248\n",
+       " | 6633\n",
+       " | 7812\n",
+       " | 7935\n",
+       " | ...\n",
+       " | 16893\n",
+       " | 405\n",
+       " | 6153\n",
+       " | 85\n",
+       " | 0.72\n",
+       " | 0.02\n",
+       " | 0.26\n",
+       " | 0.84\n",
+       " | 0.74\n",
+       " | ontime\n",
+       " | 
\n",
+       "    \n",
+       "      | 3\n",
+       " | 3250d0d32752750f0c689e96fa3fed8c\n",
+       " | a0fb4a11017f532098331c399fd31ca0\n",
+       " | aHR0cHM6Ly9hcGkuZ29zd2lmdC5seS9yZWFsLXRpbWUvbG...\n",
+       " | 2025-06-08\n",
+       " | 176170\n",
+       " | 8d9623a1823a27925b7e2f00e44fc5bb\n",
+       " | 60.681358\n",
+       " | 4689\n",
+       " | 5961\n",
+       " | 6048\n",
+       " | ...\n",
+       " | 12420\n",
+       " | 411\n",
+       " | 5049\n",
+       " | 63\n",
+       " | 0.69\n",
+       " | 0.02\n",
+       " | 0.28\n",
+       " | 0.78\n",
+       " | 0.71\n",
+       " | little_early\n",
+       " | 
\n",
+       "    \n",
+       "      | 4\n",
+       " | 321d084fe34caf6494c5853b3edfe837\n",
+       " | 20de800adb403d08b883ff758ad00abf\n",
+       " | aHR0cHM6Ly9hcGkuZ29zd2lmdC5seS9yZWFsLXRpbWUvbG...\n",
+       " | 2025-06-08\n",
+       " | 6372\n",
+       " | 8d9623a1823a27925b7e2f00e44fc5bb\n",
+       " | 61.335705\n",
+       " | 2865\n",
+       " | 3123\n",
+       " | 3159\n",
+       " | ...\n",
+       " | 7293\n",
+       " | 120\n",
+       " | 1947\n",
+       " | 33\n",
+       " | 0.78\n",
+       " | 0.01\n",
+       " | 0.21\n",
+       " | 0.91\n",
+       " | 0.79\n",
+       " | little_early\n",
+       " | 
\n",
+       "    \n",
+       "      | ...\n",
+       " | ...\n",
+       " | ...\n",
+       " | ...\n",
+       " | ...\n",
+       " | ...\n",
+       " | ...\n",
+       " | ...\n",
+       " | ...\n",
+       " | ...\n",
+       " | ...\n",
+       " | ...\n",
+       " | ...\n",
+       " | ...\n",
+       " | ...\n",
+       " | ...\n",
+       " | ...\n",
+       " | ...\n",
+       " | ...\n",
+       " | ...\n",
+       " | ...\n",
+       " | ...\n",
+       " | 
\n",
+       "    \n",
+       "      | 914554\n",
+       " | 04e2b18da6d6c95c32c99aedfa470214\n",
+       " | 53394a01951ad335893e06a1e9991654\n",
+       " | aHR0cHM6Ly9hcGkuNTExLm9yZy90cmFuc2l0L3RyaXB1cG...\n",
+       " | 2025-06-13\n",
+       " | 57776\n",
+       " | 80b17fbe1735c5f7c348eda4fb45b99a\n",
+       " | 60.053590\n",
+       " | 10659\n",
+       " | 13230\n",
+       " | 13368\n",
+       " | ...\n",
+       " | 27147\n",
+       " | 177\n",
+       " | 12309\n",
+       " | 136\n",
+       " | 0.68\n",
+       " | 0.0\n",
+       " | 0.31\n",
+       " | 0.8\n",
+       " | 0.68\n",
+       " | little_early\n",
+       " | 
\n",
+       "    \n",
+       "      | 914555\n",
+       " | 08b8fa793a58da149152da63126706a1\n",
+       " | 9dd642a1d82e6702aec1f789aeccbde9\n",
+       " | aHR0cHM6Ly9hcGkuNTExLm9yZy90cmFuc2l0L3RyaXB1cG...\n",
+       " | 2025-06-13\n",
+       " | 83745\n",
+       " | 80b17fbe1735c5f7c348eda4fb45b99a\n",
+       " | 79.291473\n",
+       " | 9468\n",
+       " | 13230\n",
+       " | 13416\n",
+       " | ...\n",
+       " | 28023\n",
+       " | 135\n",
+       " | 11604\n",
+       " | 136\n",
+       " | 0.7\n",
+       " | 0.0\n",
+       " | 0.29\n",
+       " | 0.71\n",
+       " | 0.70\n",
+       " | little_early\n",
+       " | 
\n",
+       "    \n",
+       "      | 914556\n",
+       " | 1ff00e9ade83e1bbd7403872ece6a21e\n",
+       " | adbf64adc0d0af82d94a67a78a0eab74\n",
+       " | aHR0cHM6Ly9hcGkuNTExLm9yZy90cmFuc2l0L3RyaXB1cG...\n",
+       " | 2025-06-13\n",
+       " | 52271\n",
+       " | 80b17fbe1735c5f7c348eda4fb45b99a\n",
+       " | 93.003835\n",
+       " | 10665\n",
+       " | 13590\n",
+       " | 13746\n",
+       " | ...\n",
+       " | 32853\n",
+       " | 261\n",
+       " | 7644\n",
+       " | 140\n",
+       " | 0.81\n",
+       " | 0.01\n",
+       " | 0.19\n",
+       " | 0.78\n",
+       " | 0.82\n",
+       " | little_early\n",
+       " | 
\n",
+       "    \n",
+       "      | 914557\n",
+       " | d6e1160ae86140b1cbb6a3de3ea288ee\n",
+       " | ffd7ba875d6c61a8f7b55755fd752311\n",
+       " | aHR0cHM6Ly9hcGkuNTExLm9yZy90cmFuc2l0L3RyaXB1cG...\n",
+       " | 2025-06-13\n",
+       " | 61957\n",
+       " | 80b17fbe1735c5f7c348eda4fb45b99a\n",
+       " | 36.926193\n",
+       " | 6786\n",
+       " | 13935\n",
+       " | 14130\n",
+       " | ...\n",
+       " | 14415\n",
+       " | 324\n",
+       " | 10059\n",
+       " | 144\n",
+       " | 0.34\n",
+       " | 0.01\n",
+       " | 0.24\n",
+       " | 0.48\n",
+       " | 0.35\n",
+       " | ontime\n",
+       " | 
\n",
+       "    \n",
+       "      | 914558\n",
+       " | 6c5d2004f4e703c0b33e3544a628592d\n",
+       " | e42f71ce37e5350d0920167ab248f522\n",
+       " | aHR0cHM6Ly9hcGkuNTExLm9yZy90cmFuc2l0L3RyaXB1cG...\n",
+       " | 2025-06-13\n",
+       " | 55777\n",
+       " | 80b17fbe1735c5f7c348eda4fb45b99a\n",
+       " | 56.467242\n",
+       " | 11499\n",
+       " | 14889\n",
+       " | 15081\n",
+       " | ...\n",
+       " | 30264\n",
+       " | 462\n",
+       " | 13944\n",
+       " | 155\n",
+       " | 0.68\n",
+       " | 0.01\n",
+       " | 0.31\n",
+       " | 0.76\n",
+       " | 0.69\n",
+       " | ontime\n",
+       " | 
\n",
+       "  \n",
+       "
\n",
+       "
914559 rows × 22 columns
\n",
+       "
Acceptable StopTimeUpdate
Messages | pct_tu_complete_minutes, 
n_tu_complete_minutes,
n_tu_minutes_available | Percent of time riders have up-to-date prediction information available, calculated as the percent of one-minute time bins for a given trip and stop during a Trip Time Span where there are two (2) or greater GTFS-RT StopTimeUpdate arrival predictions per minute. | Each minute for the 30 minute period 
before **each** stop's 
arrival for equal comparison across stops |
+| 9. Experienced Wait 
Time Delay | prediction_error_label, 
avg_prediction_error_minutes | The amount of time a transit rider perceives they have waited after seeing the real-time information in their Journey Planning Application and the arrival of the next vehicle arrives at their stop. This is calculated as the time interval between the next trip to arrive at a stop for a given route_id/shape_id/stop_id combination and the next predicted arrival time from a StopTimeUpdate message for that route_id/shape_id/stop_id combination as sampled for each minute of the day that the route_id/shape_id/stop_id combination is in service. | Use a simpler derived version with average
prediction error.
Current aggregation does not support 
route aggregation yet. |
+| 23. Measurement Time Windows |  | A series of 30 consecutive time windows, each starting one (1) minute apart and lasting two (2) minutes. | Each minute for the 30 minute period 
before **each** stop's 
arrival for equal comparison across stops |
+| 27. Prediction Error | avg_prediction_error_minutes | Actual Trip Stop Arrival Time minus the Predicted Trip Stop Arrival Time in seconds. Note that while Prediction Error is not the final metric in this case, it is useful to retain this value into the future and in archival storage in the event that
the definition of the frontier defined in Reliable Accuracy is changed in the future based on a specific agency’s needs |  |
+| 28. Prediction
Inconsistency | avg_prediction_spread_minutes | How much the prediction changes in the last thirty (30) minutes before a vehicle arrives at a stop, calculated for a given trip and stop as the average Predicted Trip Stop Arrival Spread of all Measurement Time Windows where a given window has a StopTimeUpdate message for the trip and stop with a timestamp in that window. |  |
+| 29. Prediction Reliability | pct_tu_accurate_minutes, 
n_tu_accurate_minutes,
n_tu_minutes_available,
pct_tu_predictions_early/ontime/late,
n_predictions,
n_predictions_early/ontime/late | The percent of time transit riders are looking at a reliably good prediction – understanding that the closer a vehicle is
to a stop, the better the prediction should be, calculated as the percent of minutes for each stop for each trip where predictions have Reliable Accuracy, starting sixty (60) minutes before the first scheduled stop for the trip. | Each minute for the 30 minute period 
before **each** stop's 
arrival for equal comparison across stops |
+| 32. Reliable Accuracy | pct_tu_accurate_minutes, 
n_tu_accurate_minutes,
n_tu_minutes_available,
pct_tu_predictions_early/ontime/late,
n_predictions,
n_predictions_early/ontime/late | A prediction has reliable accuracy if:
-60ln(Time to Prediction+1.3) < Prediction Error < 60ln(Time
to Prediction+1.5). |  |
+| 39. Time to Prediction |  | The current time until the Predicted Trip Stop Arrival Time in minutes |  |
+| 43. Trip Start Time  |  | Time of the first scheduled stop arrival of the trip per the GTFS Schedule for trips with ScheduleRelationship =
SCHEDULED or CANCELED or the first predicted arrival time for other ScheduleRelationship values. |  |
+| 44. Trip Time Span |  | Time in minutes from the Trip Start Time to the arrival time
at the stop being measured | Each minute for the 30 minute period 
before **each** stop's 
arrival for equal comparison across stops |
+
+## References
+* Caltrans GTFS RT Master Service Agreement Contract
+   * Swiftly provides a prediction accuracy exponential equation
+* Professor Gregory Newmark's paper: [Assessing GTFS Accuracy](https://transweb.sjsu.edu/sites/default/files/2017-Newmark-Public-Transit-Statistical-Analysis.pdf)
+    * This project is a work in progress for productionizing and implementing all the ideas presented in this paper.
+    * This paper provides the basis of policy and planning interpretations around the various metrics.
+    * We replicate as many of the visualizations and tables as possible.
+* Yingling Fan, Andrew Guthrie, David Levinson's paper on [Waiting time perceptions at transit stops and stations](https://www.sciencedirect.com/science/article/abs/pii/S0965856416303494)
+
+### Data Models and Data Processing Scripts
+1. Big Query SQL models (upstream to downstream SQL)
+   * 2 week [sample](https://dbt-docs.dds.dot.ca.gov/index.html#!/model/model.calitp_warehouse.fct_stop_time_updates_sample)
+   * [actual arrivals](https://dbt-docs.dds.dot.ca.gov/index.html#!/model/model.calitp_warehouse.int_gtfs_rt__trip_updates_trip_stop_day_map_grouping)
+   * [daily stop time metrics](https://dbt-docs.dds.dot.ca.gov/index.html#!/model/model.calitp_warehouse.fct_stop_time_metrics) 
+   * [daily stop metrics](https://dbt-docs.dds.dot.ca.gov/index.html#!/model/model.calitp_warehouse.fct_trip_updates_stop_metrics) --> desired future aggregation: move to this stop on a June 2025 weekday instead of this stop on June 1, 2025
+   * [GitHub issue](https://github.com/cal-itp/data-infra/issues/4101)
+
+
+2. Python scripts
+   * [report notebook](https://github.com/cal-itp/data-analyses/blob/main/rt_predictions/rt_trip_updates_report.ipynb)
+   * [Makefile](https://github.com/cal-itp/data-analyses/blob/main/rt_predictions/Makefile)
+   * [download warehouse tables](https://github.com/cal-itp/data-analyses/blob/main/rt_predictions/download_warehouse_tables.py)
+   * [prep data](https://github.com/cal-itp/data-analyses/blob/main/rt_predictions/prep_data.py)
\ No newline at end of file
diff --git a/rt_predictions/chart_utils.py b/rt_predictions/chart_utils.py
index 2654e8df0..32ddd96a5 100644
--- a/rt_predictions/chart_utils.py
+++ b/rt_predictions/chart_utils.py
@@ -1,278 +1,221 @@
 """
-(1a) daily time-series stop df
-* % completeness, % accuracy - 2D histogram?
-scatterplot is similar, but this groups them
-* avg_prediction_error_minutes
-layered histogram or several histograms by day_of_week
-* avg_prediction_spread_minutes
-layered histogram or several histograms by day_of_week
-* n_predictions in the 30 min interval
-
-(1b) aggregated day_type stop df
-* % completeness, % accuracy by day_type - 2D histogram?
-* avg_prediction_error_minutes
-* avg_prediction_spread_minutes
-* daily_predictions_per_stop
-* can we put the above all in a table, pivoted wide so it's weekday/sat/sun?
-
-would be nice to merge in trip grain, and trip grain has a column
-for an array of stop_ids, so when we aggregate to route-direction,
-we can unpack the stops for that and grab it from the stop grain
-
-(2a)
-(2b)
+Chart and map functions for report.
 """
 import altair as alt
-import folium
 import geopandas as gpd
 import pandas as pd
 
-def make_layered_histogram(
+TRI_COLORS = ["#ccbb44","#5b8efd","#dd217d"]
+FOUR_COLORS = ["#dd217d","#fcb40e","#ccbb44","#5b8efd"]
+FOUR_COLORS2 = ["#ee6677","#66ccee","#ccbb44","#4477aa",]
+FULL_CATEGORICAL_COLORS = ["#5b8efd", "#765fec", "#fcb40e", "#fc5c04", "#dd217d", "#ccbb44"]
+
+
+def histogram_line_chart_by_date(
     df: pd.DataFrame, 
-    plot_col:str,
-    step_size: float
-):
+    metric_column: str,
+    legend_color_column: str
+) -> alt.Chart:
     """
-    Might be useful for distributions of the metrics by day_type
-    https://altair-viz.github.io/gallery/layered_histogram.html
+    Distill the results from a histogram (deciles binned) for each day 
+    into 1 chart.
+    Line chart works better; can't get bar chart to unstack and still select 
+    a date for a legend.
     
-    Make a symmetrical distribution, centered on 0.
-    Find the larger of min and max and use that as bounds.
+    Purpose of chart is to show daily differences in distribution, so that we are
+    comfortable with moving towards a day_type aggregation (weekday/Sat/Sun summary).
     """
-    vertical_line = alt.Chart(
-        pd.DataFrame({'line_x': [0]})).mark_rule(
-        color='red'
-    ).encode(
-        x=alt.X('line_x:Q', title="")
-    )
-    
-    chart = (
-        alt.Chart(df)
-        .mark_bar(
-            opacity=0.3,
-            binSpacing=0
-    ).encode(
-        alt.X(f'{plot_col}:Q', bin=alt.Bin(step=step_size), 
-             #scale=alt.Scale(domain=[bounds * -1, bounds])
-             ),
-        alt.Y('count()', stack=None),
-        alt.Color(
-            'weekday_weekend:N',
-            scale=alt.Scale(
-                range=["#ccbb44","#5b8efd","#dd217d"]) # tri_color color_palette
-            )
-        )
+    selection = alt.selection_point(fields=[legend_color_column], bind='legend')
+      
+    subset_df = df[df.metric==metric_column]
+    
+    if "Weekday" in subset_df[legend_color_column].unique():
+        sort_order = ["Weekday", "Saturday", "Sunday"]
+    else:
+        sort_order = sorted(subset_df[legend_color_column].unique().tolist())
+        
+    chart= (
+        alt.Chart(subset_df)
+        .mark_line(point={"size": 15, "filled": True})
+        .encode(
+            alt.X('decile_bin'),
+            alt.Y('counts:Q'),
+            alt.Color(
+                f'{legend_color_column}:N', 
+                sort = sort_order,
+                scale=alt.Scale(range=FULL_CATEGORICAL_COLORS + TRI_COLORS + FOUR_COLORS + FOUR_COLORS2),
+                
+            ),
+            opacity=alt.when(selection).then(alt.value(1)).otherwise(alt.value(0.2)),
+            strokeWidth=alt.when(selection).then(alt.value(2)).otherwise(alt.value(1)),
+            tooltip = ["decile_bin", "counts", "metric"]
+        ).add_params(
+            selection
+        ).properties(
+            title = f"{metric_column.replace('pct_tu', '%').replace('_', ' ')}",
+            width = 220, height = 170
+        ).interactive()
     )
     
-    return chart + vertical_line
+    return chart
 
 
-def counts_for_2d_histogram(
-    df: pd.DataFrame
-) -> pd.DataFrame:
-    """
-    Group by the combinations of the 2 percent columns.
-    Otherwise, each stop is overlaying the other, and we can't actually see.
+def boxplot_by_date(
+    df: pd.DataFrame, 
+    y_col: str
+) -> alt.Chart:
     """
-    df2 = (
-        df
-        .groupby(["pct_complete_minutes", "pct_accurate_minutes", "weekday_weekend"])
-        .agg({"stop_id": "count"})
-        .reset_index()
-        .rename(columns = {"stop_id": "n_stops"})
-    )
-    
-    return df2
+    Get a boxplot for each day to look at distribution avg_prediction_error_minutes
+    and avg_prediction_spread_minutes.
+    These are more suited to see how "early" or "late" an operator's predictions are.
+    If it's centered at 0, that's very on-time/accurate!
     
-def make_2d_histogram(
-    df: pd.DataFrame,
-    title: str = "",
-):
-    """
-    https://altair-viz.github.io/gallery/histogram_scatterplot.html
-    prefer this one: https://altair-viz.github.io/gallery/histogram_heatmap.html
+    Couldn't get alt.datum to work from this:
+    https://altair-viz.github.io/user_guide/encodings/index.html#datum-and-value
     """
-    aggregated_df = counts_for_2d_histogram(df)
+    df = df.assign(horiz_line = 0)
     
     chart = (
-        alt.Chart(aggregated_df)
-        .mark_rect()
+        alt.Chart(df)
+        .mark_boxplot()
         .encode(
-            x = alt.X(
-                "pct_complete_minutes:Q", 
-                bin=alt.Bin(maxbins=20), 
-                title = "% complete"
-            ),
-            y = alt.Y(
-                "pct_accurate_minutes:Q", 
-                bin=alt.Bin(maxbins=20), 
-                title = "% accurate"
-            ),
+            x=alt.X('service_date:T', axis=alt.Axis(format="%b %e")),
+            y=f'{y_col}:Q',
             color=alt.Color(
-                'sum(n_stops):Q', 
-                scale=alt.Scale(scheme="greenblue")
-                #range=["#ccbb44","#5b8efd","#dd217d"] # color_palette
-            ), 
-            #size='sum(n_stops)',
-            tooltip=["weekday_weekend", "n_stops",
-                     "pct_complete_minutes", "pct_accurate_minutes"]
-        ).properties(title=title).interactive()
+                "day_type:N", 
+                scale=alt.Scale(
+                    domain=["Weekday", "Saturday", "Sunday"], 
+                    range=FULL_CATEGORICAL_COLORS)
+            ),
+        )
+    )
+
+    #rule = alt.Chart(df).mark_rule(strokeDash=[2, 2]).encode(
+    #    y=alt.datum(0)
+    #)
+    rule = alt.Chart(df).mark_rule(
+        color='black', strokeWidth=1, strokeDash=[2, 2]
+    ).encode(
+        y='horiz_line'
     )
+
+    combined = (chart + rule).properties(
+        title=f"{y_col.replace('_', ' ').title()}"
+    )   
     
-    return chart
-        
-def make_boxplot_by_day_type(
+    return combined
+ 
+    
+def bar_chart_by_date(
     df: pd.DataFrame, 
-    plot_col: str,
-    title: str
+    legend_color_column: str,
+    is_stacked: bool
 ) -> alt.Chart:
-    """
-    """
-    boxplot = (
-        alt.Chart(
-            df[["weekday_weekend", "service_date", "stop_id", "stop_name", plot_col]]
-        ).mark_boxplot(size=4, opacity=0.7)
+    selection = alt.selection_point(fields=[legend_color_column], bind='legend')
+
+    chart = (
+        alt.Chart(df)
+        .mark_bar(size=20)
         .encode(
-            x="service_date:T",
-            y=f"{plot_col}:Q",
+            x=alt.X("service_date:T", axis=alt.Axis(format='%b %e')),
+            y=alt.Y("count()"),
             color=alt.Color(
-                'weekday_weekend:N', 
-                scale = alt.Scale(range=["#ccbb44","#5b8efd","#dd217d"])
+                f"{legend_color_column}:N", 
+                sort = ["5+ min early", "3-5 min early", "1-3 min early",
+                       "1 min early to 1 min late", 
+                        "1-3 min late", "5+ min late",
+                       "unknown"],
+                scale = alt.Scale(range = FULL_CATEGORICAL_COLORS),   
             ),
-            tooltip=["stop_id", "stop_name", plot_col]
-        ).interactive().properties(title = title)
-    )
-
-    return boxplot
-   
-    
-def test_jitter(plot_col):
-    plot_col = "avg_prediction_error_minutes"
-
-    subset_gdf = gdf1[["weekday_weekend", "service_date", "stop_id", "stop_name", plot_col]]
-
-    jitter = alt.Chart(subset_gdf).mark_circle(size=8).encode(
-        x="service_date:T",
-        y=f"{plot_col}:Q",
-        xOffset="jitter:Q",
-        yOffset="jitter:Q",
-        color=alt.Color('weekday_weekend:N', legend=None)
-    ).transform_calculate(
-        # Generate Gaussian jitter with a Box-Muller transform
-        #jitter="sqrt(-2*log(random()))*cos(2*PI*random())"
-        jitter='random()'
+            opacity=alt.when(selection).then(alt.value(1)).otherwise(alt.value(0.2)),
+            tooltip = ["service_date", legend_color_column, "count()"],
+            ).add_params(
+                selection
+        ).properties(
+            title = f"{legend_color_column.replace('_', ' ').replace('label', '').title()}",
+            width = 350, height = 300
+        ).interactive()
     )
 
-    return jitter
+    if is_stacked:
+        chart = chart.encode(
+            y=alt.Y("count()", stack="normalize")
+        )
 
-def stop_map_of_metric(
-    gdf: gpd.GeoDataFrame,
-    plot_col: str
-):
-    subset_gdf = gdf[["stop_id", "stop_name", "weekday_weekend", plot_col, "geometry"]]
     
-    weekday_df = subset_gdf[subset_gdf.weekday_weekend=="Weekday"] 
-    sat_df = subset_gdf[subset_gdf.weekday_weekend=="Saturday"] 
-    sun_df = subset_gdf[subset_gdf.weekday_weekend=="Sunday"]
+    return chart
     
-    m = weekday_df.explore(
+
+def plot_basic_map(gdf: gpd.GeoDataFrame, plot_col: str, colorscale: str):
+    """
+    Function for map arguments.
+    """
+    m = gdf.explore(
         plot_col,
-        tiles = "CartoDB Positron",
-        name="Weekday"
+        tiles = "CartoDB Positron", 
+        cmap = colorscale, 
+        legend=True,
+        legend_kwds = {
+            "caption": f"{plot_col.replace('pct_tu', '%').replace('_', ' ').title()}"
+        }
     )
-    
-    if len(sat_df) > 0:
-        m = sat_df.explore(plot_col, m=m, name="Saturday", legend=False)
-    
-    if len(sun_df) > 0:
-        m = sun_df.explore(plot_col, m=m, name="Sunday", legend=False)
-    
-    folium.LayerControl().add_to(m)
-    
+
     return m
 
-def manual_quartiles(
-    df: pd.DataFrame
-) -> pd.DataFrame:
-    """
-    For percents, start with 0.25, 0.5, 0.75.
-    For other metrics, divide into 4 groups?
-    """
-    pct_scale_cols = ["pct_accurate_minutes", "pct_complete_minutes"]
-    other_metric_cols = ["avg_prediction_error_sec", "avg_prediction_spread_minutes", "avg_predictions_per_trip"]
 
-    for c in pct_scale_cols:
-        df[f"{c}_categorized"] = pd.qcut(df[c], q=[0, 0.25, 0.5, 0.75, 1], labels=['< 25%', '25-50%', '50-75%', '> 75%'])
+def make_map(gdf: gpd.GeoDataFrame, plot_col: str):
+    """
+    Make map for metric.
+    The map gets cluttered with the tooltip, 
+    so keep only a small set of columns.
+    """    
+    keep_cols = [
+        "month", "year", "day_type", 
+        "stop_id", "stop_name",
+        "pct_tu_predictions_early", "pct_tu_predictions_ontime", "pct_tu_predictions_late",
+        "avg_prediction_error_minutes", "avg_prediction_spread_minutes",
+        "prediction_error_label", "n_predictions",
+        "geometry"
+    ]
+    categorical_cols = ["prediction_error_label"]
+    
+    if plot_col in categorical_cols:
+        colorscale = FULL_CATEGORICAL_COLORS
+    else:
+        colorscale = "viridis"
+    
+    subset_weekday_gdf = gdf[
+        gdf.day_type == "Weekday"
+    ][keep_cols].dropna(subset="geometry")
+    
+    subset_weekend_gdf = gdf[
+        gdf.day_type != "Weekday"
+    ][keep_cols].dropna(subset="geometry")
+    
+    # try to plot weekday where we can
+    if len(subset_weekday_gdf) > 0:
+        
+        m = plot_basic_map(subset_weekday_gdf, plot_col, colorscale)
     
-    for c in other_metric_cols:
-        df[f"{c}_categorized"] = pd.qcut(df[c], q=4)
-
-    return df
+    # if there are no weekday rows, then let's plot weekend 
+    elif len(subset_weekday_gdf) == 0 and len(subset_weekend_gdf) > 0:
         
+        print(f"Weekday map could not be plotted. Plot weekend map.")
+        m = plot_basic_map(subset_weekend_gdf, plot_col, colorscale)
     
-def make_bar_chart(df: pd.DataFrame, plot_col: str): 
-    """
-    Put a daily chart, x=service_date, y=metric,
-    see if we can merge in the avg for the day_type
-    """
-    chart = (
-        alt.Chart(df)
-        .mark_bar()
-        .encode(
-            x=alt.X(
-                "yearmonthdate(service_date):O", 
-                title="Date", 
-                axis=alt.Axis(labelAngle=-45)
-            ),
-            y=alt.Y(plot_col),
-            column=alt.Column("day_type:N")
-        )
-    )
-
-    return chart
-
-#make_layered_histogram(df, "avg_prediction_spread_minutes")
-#make_layered_histogram(df, "avg_prediction_error_sec")
-#make_layered_histogram(df, "pct_accurate_minutes")
-#make_layered_histogram(df, "n_predictions") # this covers the period that's 30 minutes before arrival
-
+    else: 
+        m = "No map could be plotted. Debug error related to schedule + RT data."
+    
+    return m 
 
-def base_facet_line_chart(
-    df: pd.DataFrame,
-    y_col: str,
-    facet_col: str,
-    ruler_col: str
-) -> alt.Chart:
 
-    # Create the ruler chart
-    ruler = (
-            alt.Chart(df)
-            .mark_rule(color="red", strokeDash=[10, 7])
-            .encode(y=f"{ruler_col}:Q")
-        )
-
-    chart = (
-            alt.Chart(df)
-            .mark_line()
-            .encode(
-                x=alt.X(
-                    "stop_name:O",
-                    title="Stop",
-                    order = "stop_sequence",
-                    axis=alt.Axis(labelAngle=-45),
-                ),
-            )
-        )
-    # Add ruler plus main chart
-    chart = (chart + ruler).properties(width=200, height=250)
-    chart = chart.facet(
-            column=alt.Column("{facet_col}:N"),
-        ).properties(
-            #title={
-            #    "text": [title],
-            #    "subtitle": [subtitle],
-            #}
-        )
-    
-    return chart
+'''
+Double check that we have different values for each date
 
+daily_df2[daily_df2.metric=="pct_tu_accurate_minutes"].groupby(
+    ["decile_bin"]
+).agg({
+    "service_date": lambda x: list(x),
+    "counts": lambda x: list(x)}
+).reset_index()
+'''
\ No newline at end of file
diff --git a/rt_predictions/deploy_portfolio_yaml.py b/rt_predictions/deploy_portfolio_yaml.py
new file mode 100644
index 000000000..2f286a77c
--- /dev/null
+++ b/rt_predictions/deploy_portfolio_yaml.py
@@ -0,0 +1,73 @@
+"""
+Create the yamls for parameterized reports.
+
+Since these yamls do not use sections, we can
+generate them similarly using Makefile commands.
+
+Try out typer to make CLI a little easier to use, since 
+this only takes 1 argument with 2 possible values.
+Base it off of this tutorial:
+https://typer.tiangolo.com/tutorial/options/required/
+"""
+import pandas as pd
+import typer
+
+from pathlib import Path
+
+from shared_utils import portfolio_utils
+from rt_msa_utils import PREDICTIONS_GCS, RT_MSA_DICT
+
+RT_TRIP_UPDATES_STOP_YAML = Path("../portfolio/sites/rt_trip_updates_stop_metrics.yml")
+RT_TRIP_UPDATES_ROUTE_YAML = Path("../portfolio/sites/rt_trip_updates_route_metrics.yml")
+
+app = typer.Typer()
+
+excluded_operators = [
+    "Bay Area 511 Regional Schedule"
+]
+
+@app.command()
+def overwrite_yaml(
+    name: str = typer.Argument(default="rt_msa")
+):
+    """
+    Create yamls for portfolio.
+    """
+    if name == "rt_msa_stops":
+        FILE = RT_MSA_DICT.rt_schedule_models.weekday_stop_grain
+    
+        df = pd.read_parquet(
+            f"{PREDICTIONS_GCS}{FILE}.parquet",
+            columns = ["schedule_name"],
+            filters = [[ ("schedule_name", "not in", excluded_operators)]]
+        ).drop_duplicates().dropna(
+            subset="schedule_name" 
+            # there shouldn't be occurrences of this, but there are, so check why
+        ).rename(columns = {"schedule_name": "name"})
+        
+        portfolio_utils.create_portfolio_yaml_chapters_no_sections(
+          RT_TRIP_UPDATES_STOP_YAML, 
+          chapter_name = "name",
+          chapter_values = sorted(list(df.name))
+        )  
+        
+    elif name == "rt_msa_trips":
+        FILE = RT_MSA_DICT.rt_trip_updates_models.weekday_route_direction_grain
+    
+        df = pd.read_parquet(
+            f"{PREDICTIONS_GCS}{FILE}.parquet",
+            columns = ["name"],
+            filters = [[("name", "notin", excluded_operators)]]
+        ).drop_duplicates()
+
+        portfolio_utils.create_portfolio_yaml_chapters_no_sections(
+          RT_TRIP_UPDATES_ROUTE_YAML, 
+          chapter_name = "name",
+          chapter_values = sorted(list(df.name))
+        )  
+      
+    return
+
+
+if __name__ == "__main__":
+    app()
diff --git a/rt_predictions/download_warehouse_tables.py b/rt_predictions/download_warehouse_tables.py
new file mode 100644
index 000000000..461c3dff7
--- /dev/null
+++ b/rt_predictions/download_warehouse_tables.py
@@ -0,0 +1,214 @@
+"""
+Download sample tables (2 weeks worth) that were created.
+Benchmark times, get intuitive feel for how much we 
+can comfortably work with.
+
+Exploratory work around aggregations, make sure metrics make sense.
+Visualize these.
+Go back to tables and tweak data models.
+"""
+import datetime
+import geopandas as gpd
+import pandas as pd
+import google.auth
+import shapely
+import sys
+
+from loguru import logger
+
+import warehouse_utils 
+from rt_msa_utils import PREDICTIONS_GCS
+credentials, project = google.auth.default()
+
+'''
+from functools import cache
+from calitp_data_analysis import get_fs
+from calitp_data_analysis.gcs_geopandas import GCSGeoPandas
+gcsgp = GCSGeoPandas()
+
+@cache
+def gcs_geopandas():
+    return GCSGeoPandas()
+'''
+PRODUCTION_PROJECT = "cal-itp-data-infra"
+STAGING_PROJECT = "cal-itp-data-infra-staging"
+PRODUCTION_MART_GTFS = "mart_gtfs"
+TIFFANY_MART = "tiffany_mart_gtfs"
+
+def download_daily_metrics(
+    table_name: str,
+    start_date: str,
+    end_date: str,
+) -> pd.DataFrame:
+    """
+    Download daily stop or trip metrics.
+    """
+    t0 = datetime.datetime.now()
+    
+    if table_name == "fct_trip_updates_stop_metrics":
+        sql_query = f"""
+            SELECT 
+                * EXCEPT(prediction_error_by_minute_array, minutes_until_arrival_array) 
+            FROM `{PRODUCTION_PROJECT}.{PRODUCTION_MART_GTFS}.{table_name}`
+        """
+    else:
+        sql_query = warehouse_utils.basic_sql_query(
+            PRODUCTION_PROJECT, PRODUCTION_MART_GTFS, table_name
+        )     
+    
+    where_condition = warehouse_utils.add_sql_date_filter("service_date", start_date, end_date)
+    
+    df = warehouse_utils.download_table_with_date(
+        f"{sql_query} {where_condition}",
+        date_col = "service_date"
+    )
+    
+    df.to_parquet(
+        f"{PREDICTIONS_GCS}{table_name}_{start_date}_{end_date}.parquet",
+        engine = "pyarrow"
+    )
+    
+    t1 = datetime.datetime.now()
+    logger.info(f"download {table_name}: {start_date}-{end_date}: {t1 - t0}")
+
+    return
+
+
+def download_staging_table(
+    project_name: str = STAGING_PROJECT,
+    dataset_name = TIFFANY_MART,
+    table_name: str = "",
+    date_col: str = "",
+    start_date: str = "",
+    end_date: str = "",
+    get_df: bool = False
+) -> pd.DataFrame:
+    """
+    Download staging table
+    """
+    t0 = datetime.datetime.now()
+    
+    sql_query = warehouse_utils.basic_sql_query(project_name, dataset_name, table_name)
+    where_condition = warehouse_utils.add_sql_date_filter(date_col, start_date, end_date)
+    
+    df = warehouse_utils.download_table_with_date(
+        f"{sql_query} {where_condition}",
+        date_col = date_col
+    )
+    
+    if get_df:
+        return df
+    else:
+        df.to_parquet(
+            f"{PREDICTIONS_GCS}{table_name}_{start_date}_{end_date}.parquet"
+        )  
+        t1 = datetime.datetime.now()
+        logger.info(f"download {table_name}: {start_date}-{end_date}: {t1 - t0}")
+
+        return
+
+def download_staging_table_with_geom(
+    project_name: str = STAGING_PROJECT,
+    dataset_name = TIFFANY_MART,
+    table_name: str = "",
+    date_col: str = "",
+    start_date: str = "",
+    end_date: str = "",
+    geom_col: str = "",
+    geom_type: str = ""
+):
+    """
+    Download table with geom, save out as gdf
+    """
+    t0 = datetime.datetime.now()
+    
+    sql_query = warehouse_utils.basic_sql_query(project_name, dataset_name, table_name)
+    where_condition = warehouse_utils.add_sql_date_filter(date_col, start_date, end_date)
+    
+    gdf = warehouse_utils.download_table_with_date_geom(
+        f"{sql_query} {where_condition}",
+        date_col = date_col,
+        geom_col = geom_col,
+        geom_type = geom_type
+    )
+       
+    warehouse_utils.geoparquet_gcs_export(
+        gdf,
+        f"{PREDICTIONS_GCS}",
+        table_name
+    )
+    
+    t1 = datetime.datetime.now()
+    logger.info(f"download {table_name}: {start_date}-{end_date}: {t1 - t0}")
+    return
+
+def download_staging_table_no_dates(
+    project_name: str = STAGING_PROJECT,
+    dataset_name = TIFFANY_MART,
+    table_name: str = "",
+):
+    """
+    These are staging tables in tiffany_mart_gtfs that don't have a service_date column.
+    """
+    t0 = datetime.datetime.now()
+
+    sql_query = warehouse_utils.basic_sql_query(project_name, dataset_name, table_name)
+    
+    df = warehouse_utils.download_table_no_date(
+        sql_query
+    )
+
+    df.to_parquet(
+        f"{PREDICTIONS_GCS}{table_name}.parquet"
+    )  
+    
+    t1 = datetime.datetime.now()
+    logger.info(f"download {table_name}: {t1 - t0}")
+    
+    return
+        
+    
+if __name__ == "__main__":
+    
+    LOG_FILE = "./logs/download_warehouse.log"
+    logger.add(LOG_FILE, retention="2 months")
+    logger.add(sys.stderr, 
+               format="{time:YYYY-MM-DD at HH:mm:ss} | {level} | {message}", 
+               level="INFO")
+
+    
+    ## (1) Download the production ready tables
+    for t in ["fct_trip_updates_stop_metrics", "fct_trip_updates_trip_metrics"]:
+        download_daily_metrics(
+            table_name = t,
+            start_date = "2025-06-01",
+            end_date = "2025-06-15",
+        )
+    
+
+    ## (2) Download aggregations on trip metrics
+    for t in [
+        "test_schedule_rt_trip_metrics", 
+        "test_schedule_rt_route_direction_metrics",
+        "test_schedule_rt_route_metrics",
+        "crosswalk_stop_times_route_dir",
+    ]:
+        download_staging_table_no_dates(
+            project_name = STAGING_PROJECT,
+            dataset_name = TIFFANY_MART,
+            table_name = t,
+        )
+    
+    
+    ## (3) Download aggregations on stop metrics    
+    download_staging_table_with_geom(
+        project_name = STAGING_PROJECT,
+        dataset_name = TIFFANY_MART,
+        table_name = "test_monthly_schedule_rt_stop_metrics",
+        date_col = "month_first_day",
+        start_date = "2025-06-01",
+        end_date = "2025-06-01",
+        geom_col = "pt_geom",
+        geom_type = "point"
+    )
+    
\ No newline at end of file
diff --git a/rt_predictions/prep_data.py b/rt_predictions/prep_data.py
new file mode 100644
index 000000000..8ce8cd17f
--- /dev/null
+++ b/rt_predictions/prep_data.py
@@ -0,0 +1,369 @@
+"""
+Data prep related to removing outliers, adding new columns, rounding values,
+renaming columns. 
+Minimal data processing, move as much into dbt models, but
+what shouldn't be done there should be handled here.
+"""
+import datetime
+import geopandas as gpd
+import pandas as pd
+import google.auth
+import sys
+
+from loguru import logger
+
+from rt_msa_utils import PREDICTIONS_GCS, RT_MSA_DICT
+
+credentials, project = google.auth.default()
+
+PREDICTION_CATEGORIES = ["early", "ontime", "late"]
+
+MIN_ERROR_SEC = -250
+MAX_ERROR_SEC = 250
+MIN_ERROR_SEC_5MIN = -60 * 5
+MAX_ERROR_SEC_5MIN = 60 * 5
+
+PREDICTION_ERROR_COLS = [
+    "avg_prediction_error_sec", 
+    "pct_tu_predictions_early", "pct_tu_predictions_ontime", "pct_tu_predictions_late"
+]
+
+ACCURACY_COLS = [
+    "pct_tu_accurate_minutes", "pct_tu_predictions_ontime"
+]
+
+# Drop a bunch of stuff for data wrangling we want to do for analysis or exploration
+PERCENTILE_LIST = [0.01, 0.05, 0.1, 0.25, 0.5, 0.75, 0.9, 0.95, 0.99]
+
+def drop_outliers(
+    df: pd.DataFrame,
+    min_cutoff: int,
+    max_cutoff: int
+) -> pd.DataFrame:
+    """
+    Drop outliers based on avg_prediction_error_sec for now.
+    Use 250 seconds on either end, this is roughly 1% of either tail.
+    In the future, we might expand to other columns.
+    """
+    return df[
+        (df.avg_prediction_error_sec >= min_cutoff) & 
+        (df.avg_prediction_error_sec <= max_cutoff)
+    ].reset_index(drop=True)
+    
+    
+def round_columns(df: pd.DataFrame) -> pd.DataFrame:
+    """
+    Rounding numeric columns, convert seconds to minutes for charts.
+    TODO: added rounding to dbt models, those have been rounded to 2 decimal places, we
+    want 3 decimal places
+    """
+    df = df.assign(
+        avg_prediction_error_minutes = df.avg_prediction_error_sec.divide(
+            60).round(3),
+        avg_prediction_spread_minutes = df.avg_prediction_spread_minutes.round(2),
+    ) 
+    return df
+
+
+def calculate_percents(df: pd.DataFrame):
+    """
+    Calculate percents for the daily stop df.
+    In the aggregated one, these will be pre-calculated in dbt model.
+    """
+    df = df.assign(
+        pct_tu_predictions_early = df.n_predictions_early.divide(
+            df.n_predictions).round(3),
+        pct_tu_predictions_ontime = df.n_predictions_ontime.divide(
+            df.n_predictions).round(3),       
+        pct_tu_predictions_late = df.n_predictions_late.divide(
+            df.n_predictions).round(3),
+        pct_tu_accurate_minutes = df.n_tu_accurate_minutes.divide(
+            df.n_tu_minutes_available).round(3),
+        pct_tu_complete_minutes = df.n_tu_complete_minutes.divide(
+            df.n_tu_minutes_available).round(3),
+        avg_predictions_per_trip = df.n_predictions.divide(
+            df.n_tu_trips).round(3),
+    ) 
+
+    return df
+
+
+def prediction_count_sanity_check(df: pd.DataFrame) -> pd.DataFrame:
+    """
+    Noticed that there are some rows where predictions (when aggregated 
+    to stop) do not line up to 100%.
+    Why? 
+    - Does this have to do with losing stop_sequence (stop_time grain -> stop grain)?
+    - Are these all on-time ones that fall between/exactly on "actual" arrival and departure?
+    - small % of these, need to go back to dbt models to check
+    """ 
+    pct_cols = [
+        f"pct_tu_predictions_{i}" for i in PREDICTION_CATEGORIES
+    ]
+    count_cols = [f"n_predictions_{i}" for i in PREDICTION_CATEGORIES]
+    
+    df = df.assign(
+        n_predictions2 = df[count_cols].sum(axis=1),
+        pct_predictions2 = df[pct_cols].sum(axis=1)
+    )
+    
+    return df
+
+
+def remove_rows_where_needing_investigation(df: pd.DataFrame) -> pd.DataFrame:
+    """
+    Perhaps some are due to rounding of rounding to 1 decimal place.
+    Allow those to be pretty close to be included.
+    
+    Otherwise, for now, let's remove the ones where counts 
+    do not fall within the boundaries of rounding errors.
+    """
+    df2 = df[
+        (df.pct_predictions2 >= 0.98) & 
+        (df.pct_predictions2 <= 1.02 )
+    ].reset_index(drop=True).drop(
+        columns = ["pct_predictions2", "n_predictions2"]
+    )
+
+    return df2
+
+
+def pct_rows_need_investigation(df: pd.DataFrame):
+    """
+    Quick descriptive to understand how many rows are off, 
+    even after accounting for rounding errors.
+    """
+    denominator = len(df)
+    numerator = len(df[(df.pct_predictions2 >= 0.98) & (df.pct_predictions2 <= 1.02 )])
+
+    # account for rounding error
+    print(numerator/denominator)
+    return
+
+
+def categorize_day_type(df: pd.DataFrame) -> pd.DataFrame:
+    """
+    This is already done for aggregated dfs.
+    Add this so we can color altair charts more easily.
+    """
+    category_dict = {
+        **{k: "Weekday" for k in ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"]},
+        **{k: k for k in ["Saturday", "Sunday"]},
+    }
+    
+    df = df.assign(
+        day_type = df.service_date.dt.day_name().map(category_dict)
+    )
+    
+    return df
+
+def import_stop_df(
+    is_daily: bool,
+    filters: tuple,
+) -> gpd.GeoDataFrame:
+    """
+    """
+    if is_daily:
+        subset_operators = pd.read_parquet(
+            f"{PREDICTIONS_GCS}{RT_MSA_DICT.rt_schedule_models.weekday_stop_grain}.parquet",
+            columns = ["tu_base64_url", "schedule_name"],
+            filters = filters
+        ).drop_duplicates().rename(
+            columns = {"tu_base64_url": "base64_url"}
+        )
+            
+        df = pd.read_parquet(
+            f"{PREDICTIONS_GCS}{RT_MSA_DICT.rt_trip_updates_downloads.daily_stop_grain}.parquet",
+            filters = [[("base64_url", "in", subset_operators.base64_url.tolist())]]
+        ).merge(
+            subset_operators,
+            on = "base64_url",
+            how = "inner"
+        ).pipe(
+            calculate_percents
+        ).pipe(
+            round_columns
+        ).pipe(
+            prediction_count_sanity_check
+        ).pipe(
+            drop_outliers,
+            MIN_ERROR_SEC, MAX_ERROR_SEC
+        ).pipe(
+            remove_rows_where_needing_investigation
+        ).pipe(
+            categorize_day_type
+        ).pipe(
+            categorize_prediction_error, 
+            "avg_prediction_error_minutes"
+        )
+
+
+    else:
+        df = gpd.read_parquet(
+            f"{PREDICTIONS_GCS}{RT_MSA_DICT.rt_schedule_models.weekday_stop_grain}.parquet",
+            filters = filters,
+            storage_options={"token": credentials.token}
+        ).pipe(
+            round_columns
+        ).pipe(
+            prediction_count_sanity_check
+        ).pipe(
+            drop_outliers,
+            MIN_ERROR_SEC_5MIN, MAX_ERROR_SEC_5MIN 
+            # use 5 minute cutoffs, this is also < 1% on either tail
+        ).pipe(
+            remove_rows_where_needing_investigation
+        ).pipe(
+            categorize_prediction_error,
+            "avg_prediction_error_minutes"
+        )
+    
+    return df
+
+
+def daily_binned_counts_by_deciles(
+    df: pd.DataFrame, 
+    percentile_columns: list
+):
+    """
+    Create side-by-side chart that will show distributions (deciles) for 
+    pct_tu_predictions_early/ontime/late (compare daily vs daytype aggregation).
+    Might need to pre-aggregate or the notebook will not produce portfolio for
+    larger operators (4 sec timeout for autosave).
+    """
+    bins = pd.IntervalIndex.from_tuples([
+        (0, 0.1), (0.101, 0.2), (0.201, 0.3),
+        (0.301, 0.4), (0.401, 0.5), (0.501, 0.6),
+        (0.601, 0.7), (0.701, 0.8), (0.801, 0.9), (0.901, 1.0)
+    ])
+        
+    for c in percentile_columns:
+        # For a column, categorize it into a decile
+        df[f"{c}_bin"] = pd.cut(df[c], bins)
+        
+    return df
+
+
+def summary_counts_by_bins(
+    df: pd.DataFrame, 
+    group_cols: list,
+    percentile_columns: list
+):
+    """
+    Get daily counts for each decile bin.
+    These will be concatenated into a long df so that the altair line chart
+    can share the same x-axis (decile bins) and legend can select a 
+    particular service_date to highlight.
+    
+    df coming in looks like:
+        stop1  decile1
+        stop2  decile1
+        stop3  decile2
+    
+    post aggregation df:
+        decile1  2 stops  metric1
+        decile2  1 stop   metric1
+    """
+    summary_dfs = []
+    
+    for col in percentile_columns:
+    
+        binned_column = f"{col}_bin"
+
+        df2 = (
+            df
+            .groupby(group_cols + [binned_column])
+            .agg({"stop_key": "count"})
+            .reset_index()
+            .rename(columns = {
+                binned_column: "decile_bin",
+                "stop_key": "counts"
+            })
+        )
+
+        df2 = df2.assign(
+            metric = col
+        )
+        
+        summary_dfs.append(df2)
+    
+    
+    # Concatenate and create a long df, where each row is service_date-operator-decile-metric.
+    # day1-operator-1st_decile-pct_early, day1-operator-1st_decile-pct_ontime      
+    summary_df = pd.concat(
+        summary_dfs,
+        axis=0, ignore_index=True
+    ).astype(
+        {"decile_bin": "str"}
+    )
+
+    return summary_df    
+
+
+def categorize_prediction_error(
+    df: pd.DataFrame, 
+    prediction_error_col: str
+) -> pd.DataFrame:
+    """
+    Using exponential equation to determine accuracy means it is
+    fairly assertive.
+    However, we can convert that to minutes and get a better understanding
+    of how far out operators are doing.
+    """
+    UPPER = 5  # 5 minutes
+    MIDDLE = 3 
+    LOWER = 1
+    
+    PREDICTION_ERROR_LABELS = {
+        "very_early": "5+ min early", 
+        "early": "3-5 min early",
+        "little_early": "1-3 min early",
+        "ontime": "1 min early to 1 min late", 
+        "little_late": "1-3 min late", 
+        "late": "3-5 min late",
+        "very_late": "5+ min late",
+        "unknown": "unknown"
+    }
+    
+    df["prediction_error_category"] = df.apply(
+        lambda x: set_error_cutoffs(
+            x[prediction_error_col], UPPER, MIDDLE, LOWER), 
+        axis=1
+    )
+    df["prediction_error_label"] = df.prediction_error_category.map(PREDICTION_ERROR_LABELS) 
+    
+    return df
+
+
+def set_error_cutoffs(
+    prediction_error: float,
+    upper_cutoff: int,
+    middle_cutoff: int,
+    lower_cutoff: int,
+) -> str:
+    """
+    early (positive values) mean prediction is earlier than actual arrival
+    bus comes after prediction (which means you will catch bus)
+    highest end, > 5 minutes
+    second highest: 3.01 minutes to 5.0 minutes
+    second lowest: -3.01 minutes (late) to -5.0 minutes (late)
+    lowest end < -5 minutes (late)
+    """
+    if prediction_error > upper_cutoff:
+        return "very_early"
+    elif (prediction_error <= upper_cutoff) and (prediction_error > middle_cutoff):
+        return "early"
+    elif (prediction_error <= middle_cutoff) and (prediction_error > lower_cutoff):
+        return "little_early"
+    elif (prediction_error <= lower_cutoff) and (prediction_error >= -1 * lower_cutoff):
+        return "ontime"
+    elif (prediction_error < -1 * lower_cutoff) and (prediction_error >= -1 * middle_cutoff):
+        return "little_late"
+    elif (prediction_error < -1 * middle_cutoff) and (prediction_error >= -1 * upper_cutoff):
+        return "late"
+    elif (prediction_error < -1 * upper_cutoff):
+        return "very_late"
+    else:
+        return "unknown"
+    
+
diff --git a/rt_predictions/rt_msa_catalog.yml b/rt_predictions/rt_msa_catalog.yml
new file mode 100644
index 000000000..759dd7876
--- /dev/null
+++ b/rt_predictions/rt_msa_catalog.yml
@@ -0,0 +1,21 @@
+# GTFS RT MSA catalog
+gcs_paths:
+  GCS: gs://calitp-analytics-data/data-analyses/
+  PREDICTIONS_GCS: ${.GCS}rt_predictions/
+
+# Existing dbt models or tweaks to existing dbt models
+rt_trip_updates_downloads:
+  dir: ${gcs_paths.PREDICTIONS_GCS}
+  daily_trip_grain: "fct_trip_updates_trip_metrics_2025-06-01_2025-06-15"
+  daily_stop_grain: "fct_trip_updates_stop_metrics_2025-06-01_2025-06-15"
+  daily_schedule_rt_trip_grain: "test_schedule_rt_trip_metrics"
+
+  
+# Stage future dbt models that are aggregations or joins across quartet 
+rt_schedule_models:
+  dir: ${gcs_paths.PREDICTIONS_GCS}
+  weekday_route_direction_grain: "test_schedule_rt_route_direction_metrics"
+  weekday_route_grain: "test_schedule_rt_route_metrics"
+  weekday_stop_grain: "test_monthly_schedule_rt_stop_metrics"
+  crosswalk_stops_route_dir: "crosswalk_stop_times_route_dir"
+  crosswalk_stops_route_dir2: "crosswalk_stop_times_route_dir2_2025-06-01_2025-06-01"
\ No newline at end of file
diff --git a/rt_predictions/rt_msa_utils.py b/rt_predictions/rt_msa_utils.py
new file mode 100644
index 000000000..f86172808
--- /dev/null
+++ b/rt_predictions/rt_msa_utils.py
@@ -0,0 +1,14 @@
+from omegaconf import OmegaConf
+from pathlib import Path
+
+PREDICTIONS_GCS = "gs://calitp-analytics-data/data-analyses/rt_predictions/"
+
+def get_catalog(catalog_name = "rt_msa_catalog") -> Path:
+    """
+    Grab GTFS RT MSA catalog (uses OmegaConf yaml parser).
+    """
+    catalog_path = Path.cwd().joinpath(f"{catalog_name}.yml")
+    
+    return OmegaConf.load(catalog_path)
+
+RT_MSA_DICT = get_catalog("rt_msa_catalog")
\ No newline at end of file
diff --git a/rt_predictions/rt_trip_updates_report.ipynb b/rt_predictions/rt_trip_updates_report.ipynb
index e59df0423..ad0a0b4c1 100644
--- a/rt_predictions/rt_trip_updates_report.ipynb
+++ b/rt_predictions/rt_trip_updates_report.ipynb
@@ -3,7 +3,7 @@
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "df299e42-ab1c-428e-b292-443a15bf08c2",
+   "id": "827cc662-3fca-4d05-926d-aa21224a8034",
    "metadata": {
     "tags": []
    },
@@ -15,13 +15,12 @@
     "warnings.filterwarnings(\"ignore\")\n",
     "\n",
     "import altair as alt\n",
-    "import geopandas as gpd\n",
     "import pandas as pd\n",
     "\n",
     "import calitp_data_analysis.magics\n",
     "from great_tables import GT\n",
     "\n",
-    "import viz_stop_metrics\n",
+    "import prep_data\n",
     "import chart_utils\n",
     "\n",
     "alt.data_transformers.enable(\"vegafusion\")"
@@ -30,7 +29,7 @@
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "6ddc53c0-44ac-4894-a13f-92f93e69f444",
+   "id": "b898ae0b-54d3-4909-bfcc-b9bee2615217",
    "metadata": {
     "tags": [
      "parameters"
@@ -45,368 +44,555 @@
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "39c971f8-0d82-4eb0-a718-7672e3afa25e",
-   "metadata": {
-    "tags": []
-   },
+   "id": "ceb3c1ed-8c30-4cc0-8883-4d3634087eff",
+   "metadata": {},
    "outputs": [],
    "source": [
     "%%capture_parameters\n",
     "name"
    ]
   },
+  {
+   "cell_type": "markdown",
+   "id": "625a3901-75f8-4cf8-b694-9e37d669a38e",
+   "metadata": {},
+   "source": [
+    "# {name} \n",
+    "\n",
+    "One of the most common transit user behaviors is to consult an app (Google Maps, Apple Maps, NextBus, etc) to find out when the bus or train is going to arrive.\n",
+    "\n",
+    "That widely desired piece of information is powered by GTFS Real-Time Trip Updates, specifically the [Stop Time Updates](https://gtfs.org/documentation/realtime/reference/#message-stoptimeupdate) specification. The underlying data produced here is huge. Imagine every instance a bus arrives at a stop in California. Multiply that by 30 for the 30 minutes before the bus arrives, and that's the dataset we're working to distill into usable performance metrics for all transit operators.\n",
+    "\n",
+    "Generally, we want better transit user experience. Specifically, the performance metrics we can derive from GTFS RT Trip Updates distills into the following objectives:\n",
+    "1. Increase prediction reliability and accuracy\n",
+    "2. Increase the availability and completeness of GTFS RT\n",
+    "3. Decrease the inconsistency and fluctuations of predictions "
+   ]
+  },
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "7dd9d12f-b63e-481b-b937-a16d33a757a6",
+   "id": "e6ba44e0-16e8-45a8-8c8d-789170560709",
    "metadata": {
     "tags": []
    },
    "outputs": [],
    "source": [
-    "gdf1 = viz_stop_metrics.import_stop_df(\n",
-    "    is_daily = True, filters = [[(\"name\", \"==\", name)]]\n",
+    "daily_df = prep_data.import_stop_df(\n",
+    "    is_daily = True,\n",
+    "    filters = [[(\"schedule_name\", \"==\", name)]]\n",
+    ")\n",
+    "\n",
+    "daytype_df = prep_data.import_stop_df(\n",
+    "    is_daily = False, \n",
+    "    filters = [[(\"schedule_name\", \"==\", name)]]\n",
     ")"
    ]
   },
   {
-   "cell_type": "markdown",
-   "id": "52bf3b76-d29f-4956-a010-29d297f5e638",
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "10560041-a5a7-4dca-a8c9-f41d8cad60be",
    "metadata": {
     "tags": []
    },
+   "outputs": [],
    "source": [
-    "# {name} \n",
-    "## Time-Series\n",
-    "### Availability and Reliability of Acceptable StopTimeUpdate Messages\n",
+    "# Create aggregated binned dataset \n",
+    "# replicate what altair does with count() for histogram\n",
+    "# do this to avoid the autosave timeout that seems to happen after 4 seconds\n",
+    "percentile_columns = [\n",
+    "    \"pct_tu_predictions_early\", \n",
+    "    \"pct_tu_predictions_ontime\", \n",
+    "    \"pct_tu_predictions_late\",\n",
+    "    \"pct_tu_accurate_minutes\", \n",
+    "    \"pct_tu_complete_minutes\"\n",
+    "]\n",
+    "\n",
+    "daily_df2 = prep_data.daily_binned_counts_by_deciles(\n",
+    "    daily_df, percentile_columns\n",
+    ").pipe(\n",
+    "    prep_data.summary_counts_by_bins,\n",
+    "    group_cols = [\"service_date\", \"base64_url\"],\n",
+    "    percentile_columns = percentile_columns\n",
+    ").astype({\"service_date\": \"str\"}) # make date string for altair legend\n",
+    "\n",
+    "daytype_df2 = prep_data.daily_binned_counts_by_deciles(\n",
+    "    daytype_df, percentile_columns\n",
+    ").pipe(\n",
+    "    prep_data.summary_counts_by_bins,\n",
+    "    group_cols = [\"year\", \"month\", \"month_first_day\", \n",
+    "                  \"day_type\", \"schedule_base64_url\", \"tu_base64_url\"],\n",
+    "    percentile_columns = percentile_columns\n",
+    ")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "0e692c06-d072-437d-a685-68ec0a1c4aa8",
+   "metadata": {},
+   "source": [
+    "## Reliable Prediction Accuracy\n",
+    "\n",
+    "We can measure progress on this large objective with several metrics:\n",
+    "\n",
+    "* Share of predictions that are early / on-time / late\n",
+    "* Prediction error (difference between `predicted_arrival` and `actual_arrival`)\n",
+    "* Share predictions that are accurate (prediction error categorized as boolean of accurate or not depending an exponential equation)\n",
+    "   * The prediction is accurate if  it falls within the bounds of `-60ln(Time to Prediction+1.3) < Prediction Error < 60ln(Time\n",
+    "to Prediction+1.5)`, the further out before arrival, the more generous the buffer. \n",
+    "* Time period: 30 minutes before the arrival at stop \n",
+    "\n",
+    "### Percent Predictions Early / On-Time / Late \n",
+    "\n",
+    "* column used `pct_tu_predictions_early`, `pct_tu_predictions_ontime`, `pct_tu_predictions_late`\n",
+    "* For transit users, **higher proportions of `% predictions early / on-time` mean you are more likely to catch the bus** if you follow the prediction exactly.\n",
+    "* **Goal:** increase the share of early / on-time predictions and lower share of late predictions.We would rather have transit users follow the predictions and wait for the bus."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "f4b04152-49e6-43fb-816f-16af078c7081",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "chart_list = [\n",
+    "    chart_utils.histogram_line_chart_by_date(\n",
+    "        daily_df2, \n",
+    "        metric_column = f\"pct_tu_predictions_{c}\",\n",
+    "        legend_color_column = \"service_date\"\n",
+    "    ) for c in [\"early\", \"ontime\", \"late\"]\n",
+    "]\n",
     "\n",
-    "* 2+ trip updates with stop arrival information in each minute interval\n",
-    "* higher accuracy (prediction is accurate if it falls within the bounds of `-60ln(Time to Prediction+1.3) < Prediction Error < 60ln(Time\n",
-    "to Prediction+1.5)`, the further out before arrival, the more generous the buffer.\n",
-    "* Time period: 30 minutes before the arrival at stop"
+    "combined_percent_daily_chart = alt.hconcat(*chart_list).resolve_scale(y='shared')\n",
+    "combined_percent_daily_chart"
    ]
   },
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "5df2251d-d688-4134-8ee9-8aaad5470895",
+   "id": "733a524b-3c1b-41d0-be52-c57366b675bf",
    "metadata": {
     "tags": []
    },
    "outputs": [],
    "source": [
-    "stop_grouping_cols = [\"name\", \"weekday_weekend\", \"stop_id\"]\n",
-    "plot_cols = [\n",
-    "    \"pct_accurate_minutes\", \"pct_complete_minutes\"\n",
+    "chart_list = [\n",
+    "    chart_utils.histogram_line_chart_by_date(\n",
+    "        daytype_df2, \n",
+    "        metric_column = f\"pct_tu_predictions_{c}\",\n",
+    "        legend_color_column = \"day_type\"\n",
+    "    ) for c in [\"early\", \"ontime\", \"late\"]\n",
     "]\n",
     "\n",
-    "d = \"Weekday\"\n",
-    "chart = chart_utils.make_2d_histogram(\n",
-    "    gdf1[gdf1.weekday_weekend==d][stop_grouping_cols + plot_cols],\n",
-    "    title = f\"% complete and accurate predictions for {d} trips by stop\"\n",
-    ")\n",
+    "combined_percent_daytype_chart = alt.hconcat(*chart_list).resolve_scale(y='shared')\n",
+    "combined_percent_daytype_chart"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "f6561568-885a-4c38-afa2-4f8fb1034d53",
+   "metadata": {},
+   "source": [
+    "### High Share of Late Predictions for Weekday Stops Map\n",
     "\n",
-    "chart"
+    "If weekday stops can't be plotted, weekend stops will be used. "
    ]
   },
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "a5cf6291-6dd0-4fba-b559-571c89960726",
-   "metadata": {
-    "tags": []
-   },
+   "id": "ccb6e80b-e4f3-481c-ba89-ecffc2685c07",
+   "metadata": {},
    "outputs": [],
    "source": [
-    "d = \"Saturday\"\n",
-    "chart = chart_utils.make_2d_histogram(\n",
-    "    gdf1[gdf1.weekday_weekend==d][stop_grouping_cols + plot_cols],\n",
-    "    title = f\"% complete and accurate predictions for {d} trips by stop\"\n",
+    "# These stops have lots of late predictions (that's the type of error we want to avoid)\n",
+    "m = chart_utils.make_map(\n",
+    "    daytype_df[daytype_df.pct_tu_predictions_late > 0.25], \n",
+    "    \"pct_tu_predictions_late\"\n",
     ")\n",
-    "\n",
-    "chart"
+    "m"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "ce1f2ce9-e4e6-4cda-ac55-a250787e9d61",
+   "metadata": {},
+   "source": [
+    "### Average Prediction Error \n",
+    "* column used `avg_prediction_error_minutes`\n",
+    "* For transit users, **negative values for `avg_prediction_error` mean you miss the bus** if you follow the prediction exactly.\n",
+    "* **Goal 1:** minimize occurrences of negative prediction errors.We would rather have transit users follow the predictions and wait for the bus.\n",
+    "* **Goal 2:** tighten the range of prediction errors and have the range move closer to zero for shorter expected wait times. \n",
+    "   * Large positive prediction error values mean users are expected to wait longer by following the prediction. \n",
+    "   * By tightening the box and centering it on zero, users experience both more reliable predictions and shorter wait times. "
    ]
   },
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "0ae063b7-2fc7-4bd8-b639-5f2be4c703be",
+   "id": "81ffc91c-a010-42f4-a3eb-8981e0a7440a",
    "metadata": {
     "tags": []
    },
    "outputs": [],
    "source": [
-    "d = \"Sunday\"\n",
-    "chart = chart_utils.make_2d_histogram(\n",
-    "    gdf1[gdf1.weekday_weekend==d][stop_grouping_cols + plot_cols],\n",
-    "    title = f\"% complete and accurate predictions for {d} trips by stop\"\n",
-    ")\n",
-    "\n",
-    "chart"
+    "chart_utils.boxplot_by_date(daily_df, \"avg_prediction_error_minutes\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "2e16d67d-f49f-4f44-a313-26a86af7743d",
+   "metadata": {
+    "tags": []
+   },
+   "source": [
+    "### % of minutes with accurate predictions\n",
+    "* column used: `pct_accurate_minutes`\n",
+    "* For transit users, **a higher proportion of `% accurate minutes` means you are getting reliable predictions for longer stretches of time before the bus arrives**.\n",
+    "* **Goal:** increase the share of accurate minutes.\n",
+    "* Note: this metric does depend on the exponential curve, which means that anything outside this fairly assertive curve means low performance on this metric."
    ]
   },
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "6cc5c3b6-2d45-4a3b-984d-037d2892c595",
+   "id": "456fe18d-5620-4af1-877f-9c1f83efb7be",
    "metadata": {
     "tags": []
    },
    "outputs": [],
    "source": [
-    "metric_cols = [\n",
-    "    \"avg_prediction_spread_minutes\",\n",
-    "    \"avg_prediction_error_minutes\",\n",
-    "    \"pct_accurate_minutes\",\n",
-    "    \"pct_complete_minutes\",\n",
-    "    \"avg_predictions_per_trip\",\n",
-    "]"
+    "chart_utils.histogram_line_chart_by_date(\n",
+    "    daily_df2, \n",
+    "    metric_column = \"pct_tu_accurate_minutes\",\n",
+    "    legend_color_column = \"service_date\"\n",
+    ") "
    ]
   },
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "40eee46e-1b52-45f4-8c93-71f23a7e9984",
+   "id": "551dd8f8-2778-417b-bccd-7ce49a319322",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "chart_utils.histogram_line_chart_by_date(\n",
+    "    daytype_df2, \n",
+    "    metric_column = \"pct_tu_accurate_minutes\",\n",
+    "    legend_color_column = \"day_type\"\n",
+    ") "
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "5a4572b3-d2f3-4efc-90ef-ced018bf3587",
+   "metadata": {},
+   "source": [
+    "## Availability of Acceptable StopTimeUpdate Messages  \n",
+    "### % of minutes with available predictions \n",
+    "* column used: `pct_tu_complete_minutes`\n",
+    "* This metric is the easiest to achieve. For starters, having information is better than no information.\n",
+    "* For transit users, **a higher proportion of `% complete minutes` means you are getting predictions for longer stretches of time before the bus arrives**.\n",
+    "* **Goal:** increase the share of complete minutes.\n",
+    "* Note: Newmark paper shows that among four CA operators, this metric is fairly easy to reach and operators can even reach up to 90% completeness."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "3113197e-d9ca-4ec7-8728-0cbd831410c5",
    "metadata": {
     "tags": []
    },
    "outputs": [],
    "source": [
-    "def format_table(df, title):\n",
-    "    table = (\n",
-    "        GT(df.describe().reset_index())\n",
-    "         .fmt_percent(\n",
-    "             columns=[\"pct_accurate_minutes\", \"pct_complete_minutes\"], \n",
-    "             decimals=1\n",
-    "         ).fmt_number(\n",
-    "             columns = [\n",
-    "                 \"avg_prediction_spread_minutes\", \n",
-    "                 \"avg_prediction_error_minutes\", \n",
-    "                 \"avg_predictions_per_trip\"\n",
-    "             ], decimals=2)\n",
-    "        .cols_label(\n",
-    "            avg_prediction_error_minutes = \"Prediction Error (minutes)\",\n",
-    "            avg_prediction_spread_minutes = \"Prediction Spread / Wobble (minutes)\",\n",
-    "            pct_accurate_minutes = \"% Minutes with Accurate Prediction\",\n",
-    "            pct_complete_minutes = \"% Minutes with Trip Updates\",\n",
-    "            avg_predictions_per_trip = \"# Predictions in 30 Minutes Before Arrival\",\n",
-    "        )\n",
-    "        .tab_options(table_font_size=\"12px\")\n",
-    "        .tab_header(title = title)\n",
-    "    )\n",
-    "    \n",
-    "    return table"
+    "chart_utils.histogram_line_chart_by_date(\n",
+    "    daily_df2, \n",
+    "    metric_column = \"pct_tu_complete_minutes\",\n",
+    "    legend_color_column = \"service_date\"\n",
+    ") "
    ]
   },
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "f8480f6e-fb7a-4546-8ef5-721d60f52606",
+   "id": "2f29d438-c0d7-4a82-affc-421702265f07",
    "metadata": {
     "tags": []
    },
    "outputs": [],
    "source": [
-    "d = \"Weekday\"\n",
-    "format_table(\n",
-    "    gdf1[gdf1.weekday_weekend==d][metric_cols], f\"{d} Descriptives\"\n",
-    ")"
+    "chart_utils.histogram_line_chart_by_date(\n",
+    "    daytype_df2, \n",
+    "    metric_column = \"pct_tu_complete_minutes\",\n",
+    "    legend_color_column = \"day_type\"\n",
+    ") "
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "46b28310-643a-49ab-a54e-89da1523694b",
+   "metadata": {},
+   "source": [
+    "## Simpler Expected Wait Time \n",
+    "* column used: `avg_prediction_error_minutes`, `prediction_error_label`\n",
+    "* For transit users, **shorter wait times (lower positive values) without missing the bus (few negative values)** result in more pleasant transit journeys.\n",
+    "* **Goal:** decrease expected wait time and decrease late predictions.\n",
+    "* This metric attempts a more generous approach towards determining accuracy, by categorizing `avg_prediction_error_minutes` with the 1-3 min, 3-5 min, and 5+ min thresholds.\n",
+    "   * ontime is between 1 min early to 1 min late"
    ]
   },
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "0ece2e2f-4e8b-48c8-94cc-e256edc5a4f1",
+   "id": "f5d21dfa-98f9-4096-92bc-82d7517d100f",
    "metadata": {
     "tags": []
    },
    "outputs": [],
    "source": [
-    "d = \"Saturday\"\n",
-    "format_table(\n",
-    "    gdf1[gdf1.weekday_weekend==d][metric_cols], f\"{d} Descriptives\"\n",
+    "chart_utils.bar_chart_by_date(\n",
+    "    daily_df, \"prediction_error_label\", \n",
+    "    is_stacked=False\n",
     ")"
    ]
   },
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "b32bf05a-2a50-4263-9305-4cac7c720a09",
+   "id": "90ac6f09-f494-43c3-976d-deb2ddb6d145",
    "metadata": {
     "tags": []
    },
    "outputs": [],
    "source": [
-    "d = \"Sunday\"\n",
-    "format_table(\n",
-    "    gdf1[gdf1.weekday_weekend==d][metric_cols], f\"{d} Descriptives\"\n",
+    "chart_utils.bar_chart_by_date(\n",
+    "    daily_df, \"prediction_error_label\", \n",
+    "    is_stacked=True\n",
     ")"
    ]
   },
   {
    "cell_type": "markdown",
-   "id": "1123ea17-9610-4335-b6e7-014a844aebe9",
+   "id": "822e608e-4a0e-460b-8831-6b2d31fbb648",
    "metadata": {},
    "source": [
-    "### Prediction Accuracy \n",
-    "\n",
-    "* Find how \"accurate\" the prediction is, based on whether it falls within the bounds of `-60ln(Time to Prediction+1.3) < Prediction Error < 60ln(Time\n",
-    "to Prediction+1.5)`, the further out before arrival, the more generous the buffer.\n",
-    "* In contrast to the `True/False` of whether a prediction is deemed accurate or not, this metric finds the \"error\" in minutes.### Weekday Descriptives\n",
-    "* Positive values = arrival came **after** the prediction. \n",
-    "* Time period: 30 minutes before the arrival at stop"
+    "### Prediction Error for Weekday Stops Map"
    ]
   },
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "14dc22a6-1834-47d7-b89f-8b670b3f31bf",
-   "metadata": {
-    "tags": []
-   },
+   "id": "e276cfcf-cecc-42f8-96cc-832f5ee5d527",
+   "metadata": {},
    "outputs": [],
    "source": [
-    "plot_col = \"avg_prediction_error_minutes\"\n",
-    "\n",
-    "boxplot = chart_utils.make_boxplot_by_day_type(\n",
-    "    gdf1, plot_col, \"Avg Prediction Error (minutes)\")\n",
-    "\n",
-    "boxplot"
+    "chart_utils.make_map(daytype_df, \"prediction_error_label\")"
    ]
   },
   {
    "cell_type": "markdown",
-   "id": "083e4039-4644-433b-9d9f-fe7191f35050",
+   "id": "11b3a832-b531-48d2-868a-c91906b33876",
    "metadata": {},
    "source": [
-    "### Availability of StopTimeUpdate Messages  \n",
+    "## Prediction Inconsistency \n",
     "\n",
-    "* How many predictions are we getting for each stop (per trip, to normalize) in the 30 minute period before arrival?\n",
-    "* Similar to the `True/False` whether there were at least 2 predictions per minute, this gets the counts (3 predictions per minute, for 30 minutes, yields 90 predictions).\n",
-    "* Time period: 30 minutes before the arrival at stop"
+    "* column used: `avg_prediction_spread_minutes`\n",
+    "* This metric wants to **distinguish between consistent but inaccurate and inconsistent but accurate** prediction patterns.\n",
+    "   * Consistent predictions contribute to low user trust in the information generally.\n",
+    "   * Inconsistent but accurate predictions fluctuate, making it difficult for trip planning ahead of time. However, the up-to-date information can alleviate the discomfort. [Research](https://www.sciencedirect.com/science/article/abs/pii/S0965856416303494) has shown that waiting time is negatively perceived, but having real-time information communicated reduces that perceived waiting time.  \n",
+    "* For transit users, **less inconsistency (lower positive values)** mean fewer fluctuations in predictions.\n",
+    "* **Goal:** Tighten the box with values closer to zero."
    ]
   },
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "e3254f92-e8d7-46bb-9be6-03248a8f4283",
+   "id": "6e321226-07b9-4041-8402-4d501e96df98",
    "metadata": {
     "tags": []
    },
    "outputs": [],
    "source": [
-    "plot_col = \"avg_predictions_per_trip\"\n",
-    "# in the 30 minute period before arrival\n",
-    "\n",
-    "boxplot = chart_utils.make_boxplot_by_day_type(\n",
-    "    gdf1, plot_col, f\"# Predictions 30 min before Arrival\")\n",
-    "\n",
-    "boxplot"
+    "chart_utils.boxplot_by_date(daily_df, \"avg_prediction_spread_minutes\")"
    ]
   },
   {
    "cell_type": "markdown",
-   "id": "c6da2140-c819-4619-a098-fbde87cdf9d7",
+   "id": "aeb6a835-1ba8-4a7e-9729-258f7612b868",
    "metadata": {},
    "source": [
-    "## Aggregated Stops by Day Type \n",
+    "## Descriptives Table with Detailed Percentiles\n",
     "\n",
-    "Maps show the metrics by only **weekday** so far."
+    "Take a look at percentiles for the metrics we have, so we can be comfortable moving towards a day type aggregation (weekday/Sat/Sunday) in the future."
    ]
   },
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "9bea753c-d402-4585-9c45-f6b3d52a7d91",
-   "metadata": {},
+   "id": "6cc5c3b6-2d45-4a3b-984d-037d2892c595",
+   "metadata": {
+    "tags": []
+   },
    "outputs": [],
    "source": [
-    "#del gdf1\n",
-    "gdf2 = viz_stop_metrics.import_stop_df(\n",
-    "    is_daily = False, filters = [[(\"name\", \"==\", name)]]\n",
-    ")"
+    "metric_cols = [\n",
+    "    \"avg_prediction_error_minutes\",\n",
+    "    \"pct_tu_accurate_minutes\",\n",
+    "    \"pct_tu_predictions_early\",\n",
+    "    \"pct_tu_predictions_ontime\", \n",
+    "    \"pct_tu_predictions_late\",\n",
+    "    \"n_predictions\",\n",
+    "    \"avg_prediction_spread_minutes\",\n",
+    "    \"pct_tu_complete_minutes\",\n",
+    "]"
    ]
   },
   {
-   "cell_type": "markdown",
-   "id": "5de8c0f0-515c-49de-9703-95e1a09ae2b5",
-   "metadata": {},
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "40eee46e-1b52-45f4-8c93-71f23a7e9984",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
    "source": [
-    "### Prediction Inconsistency (Wobble)\n",
-    "* If the prediction is changing from minute to minute, a large spread would show up.\n",
-    "* If the prediction is fairly consistent, we would see small spread.\n",
-    "* It is possible for the predicted stop arrival to be **consistent, yet inaccurate** or **inconsistent, yet fairly accurate as it approaches the stop**.\n",
-    "* These touch on different transit user experiences.\n",
-    "  * Inconsistent predictions are difficult for trip planning in real-time, though keeping customers up-to-date with reliable stop arrivals can alleviate the experience.\n",
-    "  * Consistently inaccurate predictions are difficult to plan around and can result in low trust."
+    "def format_table(\n",
+    "    df: pd.DataFrame, title: str\n",
+    ") -> GT:\n",
+    "    \"\"\"\n",
+    "    Quickly format table of descriptives\n",
+    "    \"\"\"\n",
+    "    table = (\n",
+    "        GT(df)\n",
+    "         .fmt_percent(\n",
+    "             columns=[\"pct_tu_accurate_minutes\", \"pct_tu_complete_minutes\",\n",
+    "                      \"pct_tu_predictions_early\", \"pct_tu_predictions_ontime\",\n",
+    "                      \"pct_tu_predictions_late\"\n",
+    "                     ], \n",
+    "             decimals=1\n",
+    "         ).fmt_number(\n",
+    "             columns = [\n",
+    "                 \"avg_prediction_spread_minutes\", \n",
+    "                 \"avg_prediction_error_minutes\", \n",
+    "             ], decimals=2\n",
+    "        ).fmt_number(\n",
+    "             columns = [\"n_predictions\"], \n",
+    "             decimals=0,\n",
+    "         )\n",
+    "        .cols_label(\n",
+    "            avg_prediction_error_minutes = \"Prediction Error (minutes)\",\n",
+    "            avg_prediction_spread_minutes = \"Prediction Spread / Wobble (minutes)\",\n",
+    "            pct_tu_accurate_minutes = \"% Minutes with Accurate Prediction\",\n",
+    "            pct_tu_complete_minutes = \"% Minutes with Trip Updates\",\n",
+    "            pct_tu_predictions_early = \"% Early Predictions\",\n",
+    "            pct_tu_predictions_ontime = \"% OnTime Predictions\",\n",
+    "            pct_tu_predictions_late = \"% Late Predictions\",\n",
+    "            n_predictions = \"Total Predictions\",\n",
+    "        )\n",
+    "        .tab_options(table_font_size=\"12px\")\n",
+    "        .tab_header(title = title)\n",
+    "\n",
+    "    )\n",
+    " \n",
+    "    return table"
    ]
   },
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "d62267f5-1b1a-4641-917c-7f2dc6826a41",
-   "metadata": {},
+   "id": "f8480f6e-fb7a-4546-8ef5-721d60f52606",
+   "metadata": {
+    "tags": []
+   },
    "outputs": [],
    "source": [
-    "stop_grouping_cols = [\"name\", \"weekday_weekend\", \"stop_id\", \"stop_name\"]\n",
-    "\n",
-    "plot_col = \"avg_prediction_error_minutes\"\n",
-    "\n",
-    "chart_utils.make_layered_histogram(\n",
-    "    gdf2[stop_grouping_cols + [plot_col]],\n",
-    "    plot_col,\n",
-    "    step_size=0.25 # 15 sec\n",
-    ").properties(\n",
-    "    title = \"Avg Prediction Error (minutes)\",\n",
+    "# get all the percentiles, except counts, because we need to format separately\n",
+    "format_table(\n",
+    "    daytype_df[\n",
+    "        daytype_df.day_type==\"Weekday\"\n",
+    "    ][metric_cols].describe(\n",
+    "        prep_data.PERCENTILE_LIST\n",
+    "    ).drop(index=\"count\").reset_index(), \n",
+    "    \"Weekday Descriptives\"\n",
     ")"
    ]
   },
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "c49367da-b726-42c1-bbb4-85a4ebb58a0e",
+   "id": "e417acd8-0a10-4b42-8a38-bb90242341be",
    "metadata": {
     "tags": []
    },
    "outputs": [],
    "source": [
-    "plot_col = \"pct_accurate_minutes\"\n",
-    "\n",
-    "chart_utils.make_layered_histogram(\n",
-    "    gdf2[stop_grouping_cols + [plot_col]],\n",
-    "    plot_col,\n",
-    "    step_size=0.05 \n",
-    ").properties(\n",
-    "    title = \"% Accurate Predictions\",\n",
-    ")"
+    "# format the counts row by making it all numbers\n",
+    "format_table(\n",
+    "    daytype_df[\n",
+    "        daytype_df.day_type==\"Weekday\"\n",
+    "    ][metric_cols].describe().head(1), \n",
+    "    \"\"\n",
+    ").fmt_number(decimals=0)"
    ]
   },
   {
    "cell_type": "markdown",
-   "id": "34a3cb6a-ffa7-495e-ac9b-73712277e60d",
+   "id": "30dc58b8-dbf0-46c4-9b2a-19762f034568",
    "metadata": {},
    "source": [
-    "### Accurate Predictions"
+    "## Priority Stops\n",
+    "\n",
+    "These are the weekday stops identified with either:\n",
+    "* over 25% of predictions late\n",
+    "* average prediction error of 3 minutes early *or* late\n",
+    "\n",
+    "It will be possible for operators to not have any stops that meet this threshold."
    ]
   },
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "3d75ec29-f7ee-437e-9177-0998a8cac27a",
-   "metadata": {
-    "tags": []
-   },
+   "id": "eecec474-626c-417c-bd2f-1a414a2a926a",
+   "metadata": {},
    "outputs": [],
    "source": [
-    "plot_col = \"pct_accurate_minutes\"\n",
-    "m = chart_utils.stop_map_of_metric(gdf2[gdf2.weekday_weekend==\"Weekday\"], plot_col)\n",
-    "m"
+    "keep_cols = [\n",
+    "    \"month\", \"year\", \"day_type\", \n",
+    "    \"stop_id\", \"stop_name\",\n",
+    "    \"pct_tu_predictions_early\", \"pct_tu_predictions_ontime\", \"pct_tu_predictions_late\",\n",
+    "    \"avg_prediction_error_minutes\", \"avg_prediction_spread_minutes\",\n",
+    "    \"prediction_error_label\", \"n_predictions\",\n",
+    "    \"geometry\"\n",
+    "]\n",
+    "\n",
+    "priority_df = daytype_df[\n",
+    "    (daytype_df.day_type == \"Weekday\") & ( \n",
+    "        (daytype_df.pct_tu_predictions_late > 0.25) & \n",
+    "        (daytype_df.avg_prediction_error_minutes.abs() > 3) \n",
+    "    )\n",
+    "][keep_cols]\n",
+    "\n",
+    "if len(priority_df) > 0:\n",
+    "\n",
+    "    m = chart_utils.plot_basic_map(\n",
+    "        priority_df, \n",
+    "        plot_col = \"prediction_error_label\", \n",
+    "        colorscale = chart_utils.FULL_CATEGORICAL_COLORS\n",
+    "    )\n",
+    "    \n",
+    "else:\n",
+    "    m = \"No stops fit this criteria, and that's a good thing!\"\n",
+    "\n",
+    "display(m)"
    ]
   },
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "9eefa43c-097f-4fde-aa79-c6e5f1fb2cff",
+   "id": "bafe6fe3-b98a-48c1-b9bb-6b2d433d1328",
    "metadata": {},
    "outputs": [],
    "source": []