Run parameter sweeps and Monte Carlo dispersions over GMAT missions in parallel from Python.
Project description
gmat-sweep
Run parameter sweeps and Monte Carlo dispersions over GMAT missions in parallel from Python.
What this is
A parallel orchestrator on top of gmat-run's
single-run primitive. Point gmat-sweep at a working .script and either a parameter
grid, an explicit run table, or a perturbation distribution, and it fans the run set
across subprocess workers, aggregates each run's ReportFile (and any EphemerisFile,
ContactLocator, or solver-iteration outputs) into multi-indexed pandas DataFrames, and
writes a JSON Lines manifest alongside the results so any sweep is reproducible
bit-for-bit. Killed sweeps reload from the manifest and re-run only the missing or
failed runs.
A per-run postprocess hook runs arbitrary Python after each GMAT step; the files it
writes are tracked in the manifest and aggregated back through lazy_extra_outputs
beside the GMAT reports — so a downstream consumer pins gmat-sweep rather than
bolting its own postprocessing onto a finished sweep.
The four entry points cover the common shapes:
sweep(grid=...)— full-factorial grid over one or more dotted-path fields.sweep(samples=DataFrame)— explicit-row sweep where you pre-build the run set (Halton, Sobol, custom design).monte_carlo(perturb=...)— stochastic dispersion with named distributions and a deterministic seed contract.latin_hypercube(perturb=...)— stratified sampling for variance reduction at smalln.
What this is not
- Not a single-run runner — that's
gmat-run; everygmat-sweepworker calls into it. - Not a way to build GMAT missions from scratch in Python — see
gmatpyplus. - Not a
.scripttext generator — seepygmat. - Not an optimiser. Gradient-, Bayesian-, and population-based optimisation
(CasADi, pagmo2, scikit-optimize) is a different problem;
gmat-sweepmay serve as the parallel evaluator inside one, but it ships no optimiser of its own. - Not a workflow engine.
gmat-sweepruns homogeneous parametric sweeps of one mission; Snakemake / Nextflow / Hamilton manage DAGs of heterogeneous tasks. A workflow engine can schedule agmat-sweepstep; the converse is not interesting.
Requirements
- Python 3.10, 3.11, or 3.12.
gmat-run≥ 0.6 — installed as a transitive dependency from PyPI.gmat-sweepnever importsgmatpydirectly; the import happens inside each worker subprocess on first call.- A local GMAT install.
gmat-sweepdoes not ship GMAT binaries; it relies ongmat-run's install discovery, which honours$GMAT_ROOTor finds a build under a conventional path. Download GMAT from the SourceForge release page — seegmat-run's install guide for the unpack-and-discover steps.
Supported GMAT versions
| GMAT release | Status | CI |
|---|---|---|
| R2026a | Primary development target | Exercised on every PR (Ubuntu + Windows + macOS, Python 3.10/3.11/3.12) |
| R2025a | Supported | Exercised on every PR (Ubuntu + Windows + macOS, Python 3.10/3.11/3.12) |
R2023a and R2024a were never released by the upstream GMAT project; R2025a and R2026a are the only releases supported.
Installation
pip install gmat-sweep
The [examples] extra pulls in matplotlib for the example notebooks:
pip install gmat-sweep[examples]
Quick start
from gmat_sweep import LocalJoblibPool, sweep
df = sweep(
"mission.script",
grid={"Sat.SMA": [7000, 7100, 7200]},
backend=LocalJoblibPool(max_workers=8),
)
print(df)
That call runs mission.script three times — once per Sat.SMA value — each in a fresh
subprocess, and returns a (run_id, time)-MultiIndexed pandas.DataFrame containing
the rows from every run's ReportFile plus a __status column flagging
ok / failed / skipped. A single failed run lands as a failed row with the captured
GMAT stderr in the manifest — never as a silent zero-row DataFrame and never as an
unhandled exception that aborts the whole sweep.
For a stochastic dispersion, swap sweep
for monte_carlo and pass a
perturb mapping of named distributions:
from gmat_sweep import LocalJoblibPool, monte_carlo
df = monte_carlo(
"mission.script",
n=1000,
perturb={"Sat.SMA": ("normal", 7100.0, 50.0)},
backend=LocalJoblibPool(max_workers=8),
seed=42,
)
Returns the same DataFrame shape as sweep(). Per-run sub-seeds derive from seed via
numpy.random.SeedSequence.spawn, so the draw is bit-reproducible and a resumed sweep
samples the same values for any given run_id. See the
Monte Carlo guide for the full
determinism contract and latin_hypercube
for the stratified-sampling variant.
By default the per-run Parquet files and the manifest land in a temporary directory
whose lifetime is tied to the returned DataFrame. Pass out=Path(...) to keep them —
that's also what enables resuming a killed sweep
via Sweep.from_manifest(...).resume() or gmat-sweep resume <manifest>.
For multi-host sweeps, swap the local pool for DaskPool or RayPool — same
sweep() / monte_carlo() / latin_hypercube() call shape, different backend=:
from gmat_sweep import sweep
from gmat_sweep.backends import DaskPool
with DaskPool(n_workers=8) as pool:
df = sweep(
"mission.script",
grid={"Sat.SMA": [7000, 7100, 7200]},
backend=pool,
)
DaskPool and RayPool ship behind pip install gmat-sweep[dask] /
gmat-sweep[ray]. See the backends page
for the full set of pool patterns and the
cluster recipes for
Slurm / Kubernetes / Ray autoscaling wiring.
A gmat-sweep console script is also installed for shell-script and CI use:
gmat-sweep run --grid Sat.SMA=7000:7200:3 --workers 8 --out ./sweep mission.script
gmat-sweep run --grid Sat.SMA=7000:7200:3 --backend dask --workers 8 --out ./sweep mission.script
gmat-sweep monte-carlo --n 1000 --perturb 'Sat.SMA=normal:7100:50' --seed 42 --out ./mc mission.script
gmat-sweep resume --script mission.script --workers 8 ./mc/manifest.jsonl
gmat-sweep show ./sweep/manifest.jsonl
gmat-sweep archive --out ./sweep.zip ./sweep/manifest.jsonl
See the CLI reference in the docs for every subcommand and the full mini-grammar.
Outputs
Every sweep emits two artefacts:
- The returned DataFrame —
(run_id, time)-MultiIndexed, one column perReportFilechannel plus the__statuscolumn. Built lazily from per-run Parquet files via pyarrow's dataset API, so a 10,000-run sweep does not have to fit in memory at once. - A JSON Lines manifest (
manifest.jsonl) — append-only, fsync'd after every entry. Records the canonical script SHA-256, software-version fingerprint, full parameter spec, and per-run status, timing, output paths, and captured stderr. ACtrl-Cmid-sweep leaves the manifest in a parseable state. See the manifest schema for the full contract.
Documentation
Full docs at https://astro-tools.github.io/gmat-sweep/, including a getting-started guide, a ten-minute evaluation recipe against a bundled mission script, the parameter spec reference, the manifest schema, the supported-version matrix, the FAQ, and the API reference.
Runnable example notebooks:
- Single-axis SMA scan —
fifty runs across
np.linspace(7000, 8000, 50)ofSat.SMA, parallel-dispatched and overlaid on a single altitude-vs-time plot. - Two-axis epoch × time-of-flight grid —
cartesian product over
Sat.Epochand a script-levelVariable TOF, contoured by per-run miss distance. - Surviving a kill —
launch a sweep, send
SIGINTmid-run, walk through inspecting the partial manifest withgmat-sweep show, then complete the sweep withSweep.from_manifest(...).resume(). - Monte Carlo dispersion — 1000-run Monte Carlo around a nominal injection burn over a four-axis perturbation cube, with arrival-miss histogram and a 3-σ covariance ellipse.
- Latin hypercube vs Monte Carlo — 64-run Latin hypercube alongside a 64-run plain Monte Carlo on the same perturbation, pair-plotting the unit-cube samples to make the stratification visible.
- Dask cluster recipe —
100-run
Sat.SMAgrid dispatched through adistributed.LocalClusterwithDaskPool, same flow as a realdask.distributedcluster. - Ray autoscaling recipe —
100-run Monte Carlo dispatched through
RayPoolagainst a localray.init(), same task model as a real autoscaling Ray cluster. - Sobol sensitivity —
Saltelli design via
sobol_sample, run throughsweep(samples=...), reduced to first/total-order Sobol indices viasobol_analyzewith 95 % bootstrap CIs. - Archive bundle —
pack a finished sweep into a self-describing
.zipviaSweep.archive(), inspect the layout, and re-aggregate the per-run DataFrame from the unzipped tree. - Extending a Monte Carlo —
anchor a 100-run
monte_carlo, append 200 more viamonte_carlo_extend(n=200), and assert that the original 100run_ids are preserved bit-for-bit. - Solver convergence —
sweep a LEO→GEO Hohmann transfer targeted by a
DifferentialCorrector, aggregate the per-run iteration history withlazy_solver_runs, and show aMaximumIterations-capped run stayingstatus="ok"whilelazy_solver_convergencereports it unconverged. - Downstream-consumer pipeline —
a per-run postprocess hook that writes derived metrics,
lazy_extra_outputsaggregation beside the GMATReportFile, a killed sweep resumed against a separate output tree, and a sensitivity variant reusing the same pipeline.
Citation
If you use gmat-sweep in academic work, please cite it using the
metadata in CITATION.cff. GitHub renders this as the
"Cite this repository" sidebar on the project page, and reference
managers read the file directly.
A joint JOSS paper covering gmat-run and gmat-sweep as one
toolchain is in preparation. The Markdown source lives under
joss/; a draft-pdf CI workflow compiles it to a PDF on
every push that touches that directory.
Development
To work on gmat-sweep itself:
git clone https://github.com/astro-tools/gmat-sweep.git
cd gmat-sweep
uv sync --all-groups
See CONTRIBUTING.md for the full branch / PR / test workflow.
Licence
MIT. See LICENSE.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file gmat_sweep-0.6.0.tar.gz.
File metadata
- Download URL: gmat_sweep-0.6.0.tar.gz
- Upload date:
- Size: 1.6 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
681fd1149d3b5eb9472a163e01b6a85cd1589b12d5285e40c9833fb8c48ba37c
|
|
| MD5 |
6e99eb062e55f33cc33bf3ea9a8881b0
|
|
| BLAKE2b-256 |
120c26b5592dbc384f20c4f4e8eadd40898a39aff24a4ad03459346a96ae8c94
|
Provenance
The following attestation bundles were made for gmat_sweep-0.6.0.tar.gz:
Publisher:
release.yml on astro-tools/gmat-sweep
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gmat_sweep-0.6.0.tar.gz -
Subject digest:
681fd1149d3b5eb9472a163e01b6a85cd1589b12d5285e40c9833fb8c48ba37c - Sigstore transparency entry: 1610878022
- Sigstore integration time:
-
Permalink:
astro-tools/gmat-sweep@597c839016a9ad0f6430fcef5eb8263302fa6291 -
Branch / Tag:
refs/tags/v0.6.0 - Owner: https://github.com/astro-tools
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@597c839016a9ad0f6430fcef5eb8263302fa6291 -
Trigger Event:
push
-
Statement type:
File details
Details for the file gmat_sweep-0.6.0-py3-none-any.whl.
File metadata
- Download URL: gmat_sweep-0.6.0-py3-none-any.whl
- Upload date:
- Size: 145.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7ab0b4814499e3107b688108803aae14f711ebb2b82702bc2fe1c153e6628776
|
|
| MD5 |
7552505684a431ce772809a14aa01312
|
|
| BLAKE2b-256 |
7b8685ae554c2da5c2122ccfbb3d98b41f0dd6b7155bad6b6b808c57055f88e6
|
Provenance
The following attestation bundles were made for gmat_sweep-0.6.0-py3-none-any.whl:
Publisher:
release.yml on astro-tools/gmat-sweep
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gmat_sweep-0.6.0-py3-none-any.whl -
Subject digest:
7ab0b4814499e3107b688108803aae14f711ebb2b82702bc2fe1c153e6628776 - Sigstore transparency entry: 1610878103
- Sigstore integration time:
-
Permalink:
astro-tools/gmat-sweep@597c839016a9ad0f6430fcef5eb8263302fa6291 -
Branch / Tag:
refs/tags/v0.6.0 - Owner: https://github.com/astro-tools
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@597c839016a9ad0f6430fcef5eb8263302fa6291 -
Trigger Event:
push
-
Statement type: