Repository navigation
v2.2.0
opentop v2.2.0
Two major additions merge in this release: a package-wide refactor (originally scoped as v2.2) and a new OpenSky flight-replay CLI.
Breaking changes
MultiPhaseremoved — useCompleteFlightinstead; identical behavior for typical flight-envelope problems.trajectory()rejects unknown kwargs —TypeErrorinstead of silently ignoring. All options are now explicit keyword parameters.opentop.vis.maprenamed toopentop.vis.plot_map(the old name shadowedbuiltins.map).optimizer.solveris soft-deprecated — still works with aDeprecationWarning, will be removed in a future release. Useoptimizer.stats/optimizer.success/optimizer.objective_valueinstead.
New features
opentop replay CALLSIGNCLI command — fetches a real flight from OpenSky by callsign, pulls ERA5 meteo fromfastmeteo, builds a contrail interpolant if the objective needs one, runs a comparison optimization, and savesactual.parquet+optimized.parquet+trajectory.pngside-by-side. Flag mode or interactive wizard (runopentop replaywith no args). Requirespip install "opentop[replay]"for the optional dependencies.- Reusable Python API —
opentop.replay.fetch_flight,infer_aircraft,build_meteo_and_wind,build_contrail_interpolant,normalize_flight_for_vis— use from scripts/notebooks without the CLI. trajectory(..., result_object=True)returns aTrajectoryResultdataclass withdf,success,status,objective,iters,fuel,grid_cost,statsfields.vis.trajectory(df | [df1, df2])— accepts a list of DataFrames to overlay traces on the same axes with automatic legend.
Internal changes
base.pysplit into focused pure-function modules:_dynamics.py,_objectives.py,_trajectory.py,_options.py,_multi_start.py,_types.py.cli.pysplit into acli/package with one module per subcommand.- Full type annotations across the public API; pyright in
basicmode blocks CI. ruff format+ruff checkenforced via CI and pre-commit hooks;black,isort,flake8removed from dev deps.- New committed test fixtures: real EDDB→LEMD contrail interpolant (
contrail_4d.casadi) and OpenSky flight trace (flight_ryr880w_2023-01-05.parquet).
Correctness fixes (during the refactor)
Cruiseno longer double-initializesx_guesswheninitial_guess=is passed.Climbcolinearity constraint rewritten as cross-product form — no longer divides by zero on near-north-south routes.PolyWindrewritten withouteval()and now correctly applies the Ridge intercept (silently dropped before).- Hardcoded
3.14159replaced withnp.piin projection math. fuel_cost/grid_costno longer overcounted by one trailing segment.- User-input validation uses
ValueErrorinstead ofassert(strip-safe under-O).
See docs/superpowers/specs/2026-04-15-* for the full design history if you're reading the repo.