Skip to content

Fix gtfs creation from solution - #51

Merged
Hussein-Mahfouz merged 38 commits into
mainfrom
fix_gtfs_creation_from_solution
Mar 18, 2026
Merged

Fix gtfs creation from solution#51
Hussein-Mahfouz merged 38 commits into
mainfrom
fix_gtfs_creation_from_solution

Conversation

@Hussein-Mahfouz

@Hussein-Mahfouz Hussein-Mahfouz commented Feb 19, 2026

Copy link
Copy Markdown
Owner

This pull request introduces improvements to the GTFS route template extraction and trip generation logic. This affects the creation of GTFS feeds from PSO solutions. Misalignment between the PSO encoded representation of a PT schedule and the GTFS created from that representation means that MATSim simulations were not evaluating the actual PT solution provided by PSO.

Problem

The SolutionConverter was failing to generate bi-directional service in the output GTFS feeds.

  • Root Cause: In extract_route_templates, the logic looked for any valid trip within the time window for a given route_id. It would grab the first one it found (e.g., 'Outbound') and use that template for all generated trips for that route.
  • Consequence (Incomplete GTFS): The return direction (e.g., 'Inbound') was ignored. The resulting trips.txt only contained service for one direction.
  • Effect on Routing: Because stop_times.txt is generated directly from these templates, the file was missing all stop times for the return direction.

GTFS extraction and trip generation improvements:

  • Enhanced direction handling in extract_route_templates: Now detects and splits routes by direction_id or dominant trip_headsigns (if direction_id is missing, which it is for the Leeds BODS data I am using), applies splitting factors for multi-direction routes, and stores per-direction templates for each interval.
  • Updated trip generation logic to handle per-direction templates, apply splitting factors to headways (distribute bus frequency between the n directions, so as not to provide extra buses), and ensure unique trip IDs by including direction information. Metadata such as trip_headsign and shape_id is now properly propagated and fallback logic is improved.

Final thoughts

Decoding solutions to GTFS is proving to be a difficult problem, and there is still some discrepency between the fleet size per interval from the PSO results, and the fleet size per interval of the created GTFS. This PR has gone some way to reduce the discrepancy, but further improvements are possible. A next step could be to trace the steps in encoding and decoding and ensure that they are exactly the same

Update

Done in #57 , see this notebook: https://github.com/Hussein-Mahfouz/transit_opt/blob/ff7a0ca743fdd1a67b6c7bfe7dad46c027e7e5e4/notebooks/4_validate_gtfs_io.ipynb

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves fidelity between PSO-encoded PT schedules and the generated GTFS by making template extraction and trip generation direction-aware (including fallback direction inference when direction_id is missing), and extends the optimization pipeline with masking, DRT fleet cost scaling, and new sampling/export utilities.

Changes:

  • Update SolutionConverter GTFS template extraction + trip generation to handle per-direction templates and split headways across directions to avoid service inflation.
  • Add masked optimization support (fixed_intervals) and propagate a global drt_cost_factor into fleet constraints.
  • Extend initial population sampling with “service reduction” perturbations and add/expand tests around these behaviors.

Reviewed changes

Copilot reviewed 15 out of 16 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
src/transit_opt/gtfs/gtfs.py Direction-aware template extraction, splitting factor handling, and direction-preserving trip generation.
src/transit_opt/preprocessing/prepare_gtfs.py Route round-trip estimation updated to account for loop vs linear topology using direction/headsign signals.
src/transit_opt/optimisation/problems/transit_problem.py Masked optimization support (active vs fixed intervals), updated bounds handling, and DRT-aware constraint evaluation routing.
src/transit_opt/optimisation/problems/base.py Add DRT fleet scaling (drt_cost_factor) and fleet mode selection for per-interval constraints.
src/transit_opt/optimisation/runners/pso_runner.py Inject global drt_cost_factor, support fixed_intervals, and pass new sampling parameters into the population builder.
src/transit_opt/optimisation/utils/population_builder.py Add biased “service reduction” sampling that shifts PT headway indices upward (leaving DRT unchanged).
src/transit_opt/optimisation/config/config_manager.py Extend SamplingConfig schema for reductions (but currently not fully wired in).
src/transit_opt/gtfs/solution_manager.py Add fleet stats CSV export per solution (bus vs DRT, per interval).
src/transit_opt/optimisation/utils/solution_loader.py Minor import/style adjustments and updated default headways.
tests/test_gtfs.py Update tests for new template structure (interval → direction → template) and add direction logic test coverage.
tests/test_transit_problem.py Add masking tests and update formatting/imports.
tests/test_sampling.py Add service reduction sampling tests and update formatting/quoting.
tests/test_constraints.py Add DRT cost factor and PT/DRT fleet-mode tests; formatting cleanup.
configs/config_template.yaml Document new config knobs: fixed_intervals, global drt_cost_factor, and sampling reductions.
notebooks/3b_fix_directions.ipynb Investigation notebook documenting direction inference / splitting strategies.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment thread src/transit_opt/optimisation/problems/transit_problem.py Outdated
Comment thread src/transit_opt/gtfs/gtfs.py Outdated
Comment thread src/transit_opt/gtfs/gtfs.py Outdated
Comment thread src/transit_opt/optimisation/problems/transit_problem.py
Comment thread src/transit_opt/optimisation/config/config_manager.py
Comment thread src/transit_opt/optimisation/runners/pso_runner.py
Comment thread src/transit_opt/gtfs/solution_manager.py Outdated
Comment thread src/transit_opt/gtfs/solution_manager.py
Comment thread src/transit_opt/preprocessing/prepare_gtfs.py Outdated
Hussein-Mahfouz and others added 5 commits March 17, 2026 10:13
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@Hussein-Mahfouz
Hussein-Mahfouz merged commit b19d7fc into main Mar 18, 2026
3 checks passed
@Hussein-Mahfouz
Hussein-Mahfouz deleted the fix_gtfs_creation_from_solution branch March 18, 2026 21:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants