-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
remove run_events.trip_service_id from spec and trim examples #2
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -171,28 +171,30 @@ weekday,10000,30,BLOCK-A,deadhead ,,stop-1,12:00:00,garage,12:10:00 | |
|
||
## Distinct Crew and Trip schedule scenarios | ||
|
||
The below examples identify how to use the distinct `trip_service_id` feature of `run_events.txt` to model instances in which crew schedules may be decoupled from trips, forming a many:1 relationship of runs and trips. | ||
These examples show situations where the crew schedules in `run_events.txt` use different service IDs than the trips they work on, as is allowed by [the spec](/docs/spec/#service_id-crew-schedules-and-trip-schedules). Most agencies will not need to model a situation like this. | ||
|
||
In all these cases, the trips and service IDs in the public GTFS file are not modified. New service IDs are created in the calendar supplement files, and runs that operate on those dates are described in `run_events.txt`. | ||
|
||
### Extra staffing for a special event | ||
|
||
Due to a baseball game, an additional ticket collector will be assigned to supplement the existing crew on train 101, serving the ballpark. | ||
|
||
#### `run_events.txt` | ||
#### `calendar.txt` | ||
|
||
_Note that the `run_id` of 1 maps to the combination of `(service_id, trip_service_id)`, meaning other runs with the same `run_id` of `1` can be in effect at the same time provided they existin other combinations of `(service_id, trip_service_id)`._ | ||
```csv | ||
service_id,monday,tuesday,wednesday,thursday,friday,saturday,sunday,start_date,end_date | ||
weekday,1,1,1,1,1,0,0,20240101,20241231 | ||
``` | ||
|
||
#### `trips.txt` | ||
|
||
```csv | ||
service_id,trip_service_id,run_id,event_sequence,event_type,trip_id,start_location,start_time,end_location,end_time | ||
gameday,weekday,1,1,signup,,main_terminal,14:00:00,main_terminal,14:15:00 | ||
gameday,weekday,1,2,collector,train_101,main_terminal,14:45:00,ballpark,15:30:00 | ||
gameday,weekday,1,3,work_as_directed,train_101,ballpark,15:30:00,main_terminal,22:00:00 | ||
gameday,weekday,1,4,signoff,,main_terminal,22:00:00,main_terminal,22:15:00 | ||
route_id,service_id,trip_id,block_id | ||
route,weekday,101,BLOCK-A | ||
``` | ||
|
||
#### `calendar_dates_supplement.txt` | ||
|
||
The added position can be added on the applicable gamedays via `calendar_dates_supplement.txt`. | ||
|
||
```csv | ||
service_id,date,exception_type | ||
gameday,20240820,1 | ||
|
@@ -201,134 +203,41 @@ gameday,20240827,1 | |
gameday,20240903,1 | ||
``` | ||
|
||
### Different runs mapping to the same set of trips | ||
|
||
Consider a bus network between West City, Eastland, and Northingdon. Route 1 runs between West City and Eastland via Northingdon, whereas Route 2 runs directly between the two cities. | ||
|
||
To improve on-time performance, the driver working the 10:45am Route 1 departure and the driver of the 11am Route 2 departure will exchange these trips effective September 2024. | ||
|
||
#### `trips.txt` | ||
|
||
```csv | ||
route_id,service_id,trip_id,trip_headsign,direction_id | ||
1,weekday,10001,Eastland via Northingdon,1 | ||
2,weekday,20001,Eastland,1 | ||
1,weekday,10002,West City via Northingdon,0 | ||
2,weekday,20002,West City,0 | ||
``` | ||
|
||
#### `calendar.txt` | ||
|
||
Assume these trips run daily on weekdays in the defined date range. | ||
|
||
```csv | ||
service_id,monday,tuesday,wednesday,thursday,friday,saturday,sunday,start_date,end_date | ||
weekday,1,1,1,1,1,0,0,20240101,20241231 | ||
``` | ||
|
||
#### `run_events.txt` | ||
|
||
The current runs can be modeled with service_id `current`, and mapped to the existing `weekday` trips. The future runs can be modeled with service_id `future`, also mapped to the existing `weekday` trips. The service_id `weekday` is already defined in `calendar.txt`, but neither `current` nor `future` are. | ||
|
||
```csv | ||
service_id ,trip_service_id ,run_id ,event_sequence ,block_id ,event_type ,trip_id ,start_location ,start_time ,end_location ,end_time | ||
current ,weekday ,1 ,10 ,A ,report , ,garage ,08:00:00 ,garage ,08:20:00 | ||
current ,weekday ,1 ,20 ,A ,drive ,10001 ,westcity ,09:00:00 ,eastland ,10:30:00 | ||
current ,weekday ,1 ,30 ,A ,drive ,10002 ,eastland ,10:45:00 ,westcity ,12:15:00 | ||
current ,weekday ,1 ,40 ,A ,signoff , ,garage ,12:45:00 ,garage ,13:00:00 | ||
|
||
current ,weekday ,2 ,10 ,B ,report , ,garage ,08:00:00 ,garage ,08:20:00 | ||
current ,weekday ,2 ,20 ,B ,drive ,20001 ,westcity ,09:00:00 ,eastland ,10:00:00 | ||
current ,weekday ,2 ,30 ,B ,drive ,20002 ,eastland ,11:00:00 ,westcity ,12:00:00 | ||
current ,weekday ,2 ,40 ,B ,signoff , ,garage ,12:30:00 ,garage ,12:45:00 | ||
|
||
future ,weekday ,1 ,10 ,A ,report , ,garage ,08:00:00 ,garage ,08:20:00 | ||
future ,weekday ,1 ,20 ,A ,drive ,10001 ,westcity ,09:00:00 ,eastland ,10:30:00 | ||
future ,weekday ,1 ,30 ,A ,drive ,20002 ,eastland ,11:00:00 ,westcity ,12:00:00 | ||
future ,weekday ,1 ,40 ,A ,signoff , ,garage ,12:30:00 ,garage ,12:45:00 | ||
|
||
future ,weekday ,2 ,10 ,B ,report , ,garage ,08:00:00 ,garage ,08:20:00 | ||
future ,weekday ,2 ,20 ,B ,drive ,20001 ,westcity ,09:00:00 ,eastland ,10:00:00 | ||
future ,weekday ,2 ,30 ,B ,drive ,10002 ,eastland ,10:45:00 ,westcity ,12:15:00 | ||
future ,weekday ,2 ,40 ,B ,signoff , ,garage ,12:45:00 ,garage ,13:00:00 | ||
service_id,run_id,event_sequence,block_id,job_type,event_type,trip_id,start_location,start_time,end_location,end_time | ||
weekday,1,1, ,collector,sign-in , ,main_terminal,14:00:00,main_terminal,14:15:00 | ||
weekday,1,2,BLOCK-A,collector,collector ,101,main_terminal,14:45:00,ballpark ,15:30:00 | ||
gameday,2,1, ,collector,sign-in , ,main_terminal,14:00:00,main_terminal,14:15:00 | ||
jeffkessler-keolis marked this conversation as resolved.
Show resolved
Hide resolved
|
||
gameday,2,2,BLOCK-A,collector,extra collector,101,main_terminal,14:45:00,ballpark ,15:30:00 | ||
``` | ||
|
||
#### `calendar_supplement.txt` | ||
### Trip worked by different runs on different dates | ||
|
||
To detail the presence of the new `service_id`s and assign them to their applicable days of the week, the runs can be added to the calendar via `calendar_supplement.txt`: | ||
|
||
```csv | ||
service_id,monday,tuesday,wednesday,thursday,friday,saturday,sunday,start_date,end_date | ||
current,1,1,1,1,1,0,0,20240101,20240831 | ||
future ,1,1,1,1,1,0,0,20240901,20241231 | ||
``` | ||
|
||
### Variations of runs by day of the week | ||
|
||
Consider a commuter train line that operates three daily round-trips: two morning inbound trains from the suburbs to the city, two evening return trips from the city to the suburbs, plus one reverse-peak trip for day-trippers to the outlying village and back. | ||
|
||
Every day, the same six trips are operated from the public perspective, with the crew of the earlier morning inbound rush-hour trip always working the earlier evening outbound rush-hour trip (trains 102 and 101, respectively), and the other crew working the later of the two (trains 104 and 103, respectively). To more evenly distribute fatigue and rest, the midday round-trip (trains 191 and 192) is split between the early and late crews by day-of-week, and switching halfway through the year. Whichever crew works the midday trip takes their break in the suburban village, whereas the other crew takes their break in the city. | ||
Consider a bus network between West City, Eastland, and Northingdon. Route 1 runs between West City and Eastland via Northingdon, whereas Route 2 runs directly between the two cities. | ||
|
||
#### `trips.txt` | ||
To lengthen a short layover and improve on-time performance, the driver working the 10:45am Route 1 departure and the driver of the 11am Route 2 departure will exchange these trips effective September 2024. | ||
|
||
Rather than listing these trips as varying by day-of-week in a public-facing schedule, these can indeed be maintained as a single service_id in `trips.txt`. | ||
The public-facing schedule will not change. The trips remain on the service `weekday`. The runs are scheduled on new services `summer` and `fall`, which together cover all of the dates in `weekday`. | ||
|
||
```csv | ||
route_id,service_id,trip_id,trip_headsign,direction_id,trip_short_name | ||
commuter_line,spring_train_schedule,spring-city_train_102,City ,1,102 | ||
commuter_line,spring_train_schedule,spring-city_train_104,City ,1,104 | ||
commuter_line,spring_train_schedule,spring-city_train_191,Suburbs,0,191 | ||
commuter_line,spring_train_schedule,spring-city_train_192,City ,1,192 | ||
commuter_line,spring_train_schedule,spring-city_train_101,Suburbs,0,101 | ||
commuter_line,spring_train_schedule,spring-city_train_103,Suburbs,0,103 | ||
``` | ||
![Diagram showing four trips on two runs, with the assignments rearranged in the fall.](different-runs-same-trips.png) | ||
|
||
#### `calendar.txt` | ||
|
||
Assume these trips run daily on weekdays in the defined date range. | ||
|
||
```csv | ||
service_id,monday,tuesday,wednesday,thursday,friday,saturday,sunday,start_date,end_date | ||
spring_train_schedule,1,1,1,1,1,0,0,20240101,20241231 | ||
weekday,1,1,1,1,1,0,0,20240601,20241231 | ||
``` | ||
|
||
#### `run_events.txt` | ||
|
||
The individual runs can be broken into two run-based service_ids: `spring_train_latelong` represents the days where the late job works the midday trip (and has its break in the village), whereas `spring_train_earlylong` represents the days where the early job works the midday trip. | ||
|
||
Note that in all circumstances, the trips all reference those with `service_id` matching `spring_train_schedule`; there are not any trips defined under `service_id` `spring_train_latelong` nor `spring_train_earlylong`. | ||
#### `trips.txt` | ||
|
||
```csv | ||
service_id,trip_service_id,run_id,event_sequence,block_id,event_type,trip_id,start_location,start_time,end_location,end_time | ||
|
||
spring_train_latelong ,spring_train_schedule,early_job,10,BLOCK-A,sign-in , ,yard ,06:00:00,yard ,06:15:00 | ||
spring_train_latelong ,spring_train_schedule,early_job,20,BLOCK-A,conductor,spring-city_train_102,village,06:30:00,city ,07:30:00 | ||
spring_train_latelong ,spring_train_schedule,early_job,30,BLOCK-A,release , ,city ,07:45:00,city ,16:00:00 | ||
spring_train_latelong ,spring_train_schedule,early_job,40,BLOCK-A,conductor,spring-city_train_101,city ,16:30:00,village,17:30:00 | ||
spring_train_latelong ,spring_train_schedule,early_job,50,BLOCK-A,sign-off , ,yard ,17:30:00,yard ,17:45:00 | ||
|
||
spring_train_latelong ,spring_train_schedule,later_job,10,BLOCK-B,sign-in , ,yard ,07:00:00,yard ,07:15:00 | ||
spring_train_latelong ,spring_train_schedule,later_job,20,BLOCK-B,conductor,spring-city_train_104,village,07:30:00,city ,08:30:00 | ||
spring_train_latelong ,spring_train_schedule,later_job,30,BLOCK-B,conductor,spring-city_train_191,city ,09:00:00,village,10:00:00 | ||
spring_train_latelong ,spring_train_schedule,later_job,40,BLOCK-B,break , ,village,10:00:00,village,15:00:00 | ||
spring_train_latelong ,spring_train_schedule,later_job,50,BLOCK-B,conductor,spring-city_train_190,village,15:00:00,city ,16:00:00 | ||
spring_train_latelong ,spring_train_schedule,later_job,60,BLOCK-B,conductor,spring-city_train_103,city ,17:30:00,village,18:30:00 | ||
spring_train_latelong ,spring_train_schedule,later_job,70,BLOCK-B,sign-off , ,yard ,18:30:00,yard ,18:45:00 | ||
|
||
spring_train_earlylong,spring_train_schedule,early_job,10,BLOCK-A,sign-in , ,yard ,06:00:00,yard ,06:15:00 | ||
spring_train_earlylong,spring_train_schedule,early_job,20,BLOCK-A,conductor,spring-city_train_102,village,06:30:00,city ,07:30:00 | ||
spring_train_earlylong,spring_train_schedule,early_job,30,BLOCK-A,conductor,spring-city_train_191,city ,09:00:00,village,10:00:00 | ||
spring_train_earlylong,spring_train_schedule,early_job,40,BLOCK-A,break , ,village,10:00:00,village,15:00:00 | ||
spring_train_earlylong,spring_train_schedule,early_job,50,BLOCK-A,conductor,spring-city_train_190,village,15:00:00,city ,16:00:00 | ||
spring_train_earlylong,spring_train_schedule,early_job,60,BLOCK-A,conductor,spring-city_train_101,city ,16:30:00,village,17:30:00 | ||
spring_train_earlylong,spring_train_schedule,early_job,70,BLOCK-A,sign-off , ,yard ,17:30:00,yard ,17:45:00 | ||
|
||
spring_train_earlylong,spring_train_schedule,later_job,10,BLOCK-B,sign-in , ,yard ,07:00:00,yard ,07:15:00 | ||
spring_train_earlylong,spring_train_schedule,later_job,20,BLOCK-B,conductor,spring-city_train_104,village,07:30:00,city ,08:30:00 | ||
spring_train_earlylong,spring_train_schedule,later_job,30,BLOCK-B,release , ,city ,08:45:00,city ,17:00:00 | ||
spring_train_earlylong,spring_train_schedule,later_job,40,BLOCK-B,conductor,spring-city_train_103,city ,17:30:00,village,18:30:00 | ||
spring_train_earlylong,spring_train_schedule,later_job,50,BLOCK-B,sign-off , ,yard ,18:30:00,yard ,18:45:00 | ||
|
||
route_id,service_id,trip_id,trip_headsign,direction_id | ||
1,weekday,101,Eastland via Northingdon,1 | ||
2,weekday,201,Eastland,1 | ||
1,weekday,102,West City via Northingdon,0 | ||
2,weekday,202,West City,0 | ||
``` | ||
|
||
#### `calendar_supplement.txt` | ||
|
@@ -337,100 +246,27 @@ To detail the presence of the new `service_id`s and assign them to their applica | |
|
||
```csv | ||
service_id,monday,tuesday,wednesday,thursday,friday,saturday,sunday,start_date,end_date | ||
spring_train_latelong ,1,0,1,0,1,0,0,20240101,20240630 | ||
spring_train_earlylong,0,1,0,1,0,0,0,20240101,20240630 | ||
spring_train_earlylong,1,0,1,0,1,0,0,20240701,20241231 | ||
spring_train_latelong ,0,1,0,1,0,0,0,20240701,20241231 | ||
``` | ||
|
||
### Jobs of entirely nonrevenue operations | ||
|
||
A special track inspection train is being operated on a particular day, supported by an extra crew position. | ||
|
||
_Note: The deadhead trips themselves could be defined in their own new `service_id` even without definining corresponding run data in `run_events.txt` using the `calendar_supplement.txt` or `calendar_dates_supplement.txt` files._ | ||
|
||
#### `trips_supplement.txt` | ||
|
||
```csv | ||
route_id,service_id,trip_id,TODS_trip_type,direction_id | ||
line1,inspection_train,inspection_line1_ob,deadhead,0 | ||
line1,inspection_train,inspection_line1_ib,deadhead,1 | ||
line1,inspection_train,inspection_line2_ob,deadhead,0 | ||
line1,inspection_train,inspection_line2_ib,deadhead,1 | ||
line1,inspection_train,inspection_line3_ob,deadhead,0 | ||
line1,inspection_train,inspection_line3_ib,deadhead,1 | ||
``` | ||
|
||
#### `stop_times_supplement.txt` | ||
|
||
```csv | ||
trip_id,arrival_time,stop_id | ||
inspection_line1_ob,downtown,08:00:00 | ||
inspection_line1_ob,anytown,09:00:00 | ||
inspection_line1_ib,anytown,09:15:00 | ||
inspection_line1_ib,downtown,10:15:00 | ||
inspection_line2_ob,downtown,11:00:00 | ||
inspection_line2_ob,busyville,12:30:00 | ||
inspection_line2_ib,busyville,13:00:00 | ||
inspection_line2_ib,downtown,14:30:00 | ||
inspection_line3_ob,downtown,15:00:00 | ||
inspection_line3_ob,centerton,15:45:00 | ||
inspection_line3_ib,centerton,16:00:00 | ||
inspection_line3_ib,downtown,16:45:00 | ||
``` | ||
|
||
#### `calendar_dates_supplement.txt` | ||
|
||
```csv | ||
service_id,date,exception_type | ||
inspection_train,20240901 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I do like the idea of including this as an example, because I think this is a big use case for the distinct TODS-specific modeling of non-public trips. That said, we could certainly cut this down to two trips of two stop_times each to simplify things. But open to cutting if the rest of the working group believes it to not be worthwhile. |
||
summer,1,1,1,1,1,0,0,20240601,20240831 | ||
fall ,1,1,1,1,1,0,0,20240901,20241231 | ||
``` | ||
|
||
#### `run_events.txt` | ||
|
||
Here a run can be defined alongside entirely deadhead trips added via `trips_supplement.txt` using the same `service_id` defined and assigned in `calendar_dates_supplement.txt`. | ||
The current runs can be modeled with service_id `summer`, and mapped to the existing `weekday` trips. The future runs can be modeled with service_id `fall`, also mapped to the existing `weekday` trips. The service_id `weekday` is already defined in `calendar.txt`, but neither `summer` nor `fall` are. | ||
|
||
```csv | ||
service_id,run_id,event_sequence,event_type,trip_id,start_location,start_time,end_location,end_time | ||
inspection_train ,1 ,1 ,signup , ,main_terminal ,07:15:00 ,main_terminal ,07:45:00 | ||
inspection_train ,1 ,2 ,operator ,inspection_line1_ob ,downtown ,08:00:00 ,anytown ,09:00:00 | ||
inspection_train ,1 ,3 ,operator ,inspection_line1_ib ,anytown ,09:15:00 ,downtown ,10:15:00 | ||
inspection_train ,1 ,4 ,operator ,inspection_line2_ob ,downtown ,11:00:00 ,busyville ,12:30:00 | ||
inspection_train ,1 ,5 ,operator ,inspection_line2_ib ,busyville ,13:00:00 ,downtown ,14:30:00 | ||
inspection_train ,1 ,6 ,operator ,inspection_line3_ob ,downtown ,15:00:00 ,centerton ,15:45:00 | ||
inspection_train ,1 ,7 ,operator ,inspection_line3_ib ,centerton ,16:00:00 ,downtown ,16:45:00 | ||
gameday ,1 ,8 ,signoff , ,main_terminal ,17:00:00 ,main_terminal ,17:30:00 | ||
service_id ,run_id ,event_sequence ,block_id ,event_type ,trip_id ,start_location ,start_time ,end_location ,end_time | ||
summer ,1 ,20 ,A ,drive ,101 ,westcity ,09:00:00 ,eastland ,10:30:00 | ||
summer ,1 ,30 ,A ,drive ,102 ,eastland ,10:45:00 ,westcity ,12:15:00 | ||
|
||
``` | ||
|
||
### Activating a storm schedule | ||
summer ,2 ,20 ,B ,drive ,201 ,westcity ,09:00:00 ,eastland ,10:00:00 | ||
summer ,2 ,30 ,B ,drive ,202 ,eastland ,11:00:00 ,westcity ,12:00:00 | ||
|
||
Assume a public GTFS file includes a set of trips with service_id `storm_schedule`, with no normal assignment in the calendar. | ||
fall ,1 ,20 ,A ,drive ,101 ,westcity ,09:00:00 ,eastland ,10:30:00 | ||
fall ,1 ,30 ,A ,drive ,202 ,eastland ,11:00:00 ,westcity ,12:00:00 | ||
|
||
#### `calendar.txt` | ||
|
||
```csv | ||
service_id,monday,tuesday,wednesday,thursday,friday,saturday,sunday,start_date,end_date | ||
normal,1,1,1,1,1,0,0,20240101,20241231 | ||
storm_schedule,0,0,0,0,0,0,0,20240101,20241231 | ||
fall ,2 ,20 ,B ,drive ,201 ,westcity ,09:00:00 ,eastland ,10:00:00 | ||
fall ,2 ,30 ,B ,drive ,102 ,eastland ,10:45:00 ,westcity ,12:15:00 | ||
``` | ||
|
||
#### `calendar_dates.txt` | ||
|
||
This storm schedule could be activated whenever inclement weather is encountered by updating `calendar_dates.txt` to include: | ||
|
||
```csv | ||
service_id,date,exception_type | ||
normal,20240901,2 | ||
storm_schedule,20240901,1 | ||
``` | ||
|
||
#### `calendar_dates_supplement.txt` | ||
|
||
While waiting for the GTFS data to propagate through one's system, this could also be reflected in the TODS `calendar_dates_supplement.txt` file to activate the change in any operational systems, alongside any runs associated with the `storm_schedule` service_id. | ||
|
||
```csv | ||
service_id,date,exception_type | ||
normal,20240901,2 | ||
storm_schedule,20240901,1 | ||
``` | ||
(In this example, block IDs are listed in `run_events.txt` but not `trips.txt` because the blocks would also change with the schedule change.) |
skyqrose marked this conversation as resolved.
Show resolved
Hide resolved
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See comment below, but I think this is an important note to reiterate; perhaps this should be moved below, though?
The key thing I want to avoid is a consumer thinking the feed is broken because there are two versions of
run_id
=1
, each of which have differentservice_id
values, though.