Skip to main content

Groundtrack

Contributors Forks Stargazers Issues MIT License LinkedIn Documentation DOI CI codecov


Logo

Groundtrack

Seismic waveform pipeline for atmospheric re-entry events using orbital ground tracks and seismic station data.

Quick Start » · Report Bug · Request Feature

Table of Contents
  1. About The Project
  2. Built With
  3. Getting Started
  4. Usage
  5. Roadmap
  6. Contributing
  7. License
  8. Contact
  9. Acknowledgments

About The Project

Groundtrack is a Python library developed for discovering and analyzing seismic signals that are produced when an object re-enters the atmosphere. When space debris or a spacecraft re-enters the atmosphere at hypersonic speeds, it generates sonic booms that then couple into the ground and are recorded by seismic stations. Groundtrack automates the full pipeline from orbital data to the processed waveforms, while allowing each piece of the pipeline to be easily configured/called if the user wishes:

  1. Fetches TLE elements from Space-Track using a user-provided NORAD ID
  2. Propagates the ground track over a user-defined analysis window
  3. Tiles the track into spatial boxes, automatically skips boxes that are entirely over open ocean, and queries FDSN providers for nearby seismic stations in the remaining boxes
  4. Downloads waveform data for stations within a configurable distance from the ground track
  5. Applies instrument response removal and bandpass filtering
  6. Provides optional visualization tools for validating output

The library was developed at Johns Hopkins University as independent research in collaboration with Dr. Benjamin Fernando (Department of Earth and Planetary Sciences), building on the methodology established in his work on seismic detection of the 2024 Shenzhou-15 re-entry. The pipeline was first validated in multiple proof-of-concept Jupyter notebooks replicating published detection results before being migrated into this library format.

(back to top)

Built With

  • Python
  • NumPy
  • ObsPy
  • pandas
  • Space-Track
  • Skyfield
  • global-land-mask

Optional Features

Groundtrack includes built-in plotting utilities for analyzing re-entry events:

  • Ground track + download boxes visualization
  • Station distribution maps
  • Raw vs. processed waveform comparisons

Install with plotting support:

pip install groundtrack[plotting]
  • matplotlib
  • cartopy

(back to top)

Getting Started

Prerequisites

  • Python 3.10+
  • A free Space-Track account for TLE and TIP message access

Installation

Install from PyPI:

pip install groundtrack

With optional plotting support:

pip install groundtrack[plotting]

Credentials

Groundtrack requires Space-Track credentials to fetch orbital data. Create a .env file in your project root:

SPACETRACK_USER=your_email@example.com
SPACETRACK_PASS=your_password

Add .env to your .gitignore to avoid accidentally committing credentials:

echo ".env" >> .gitignore

Or pass them directly to run_pipeline():

results = run_pipeline(
    ...,
    username="your_email@example.com",
    password="your_password",
)

(back to top)

Usage

Minimal Example

from groundtrack import run_pipeline

results = run_pipeline(
    norad_id=56873,
    start="2024-04-02T08:40:00Z",
    end="2024-04-02T09:00:00Z",
    cache_dir="data/cache",
    output_dir="data/outputs",
    event_name="shenzhou15_reentry",
)

With Processing and Custom Parameters

results = run_pipeline(
    norad_id=56873,
    start="2024-04-02T08:40:00Z",
    end="2024-04-02T09:00:00Z",
    cache_dir="data/cache",
    output_dir="data/outputs",
    event_name="shenzhou15_reentry",
    corridor_km=100.0,          # station inclusion threshold
    chunk_km=300.0,             # along-track box size
    max_workers=3,              # boxes downloaded concurrently (1 = sequential)
    apply_processing=True,      # remove instrument response + bandpass
    freqmin=1.0,                # bandpass lower corner (Hz)
    freqmax=20.0,               # bandpass upper corner (Hz)
)

Choosing Data Providers

By default (providers="auto") the library picks providers per box from a built-in map of where each FDSN archive actually holds stations. A corridor over Italy queries INGV, ORFEUS and GEOFON; one over Texas queries TEXNET. Selection is offline and deterministic for a given release, so it adds no latency and reproduces exactly.

# Auto (default) - region-selected, plus EarthScope everywhere
run_pipeline(..., providers="auto")

# Explicit - exactly these, in this order, no region filtering
run_pipeline(..., providers=("SCEDC", "NCEDC", "EARTHSCOPE"))

# Auto plus one more, always queried regardless of region
run_pipeline(..., extra_providers=("RASPISHAKE",))

Providers are ordered by how many stations they hold inside each box, with EarthScope last, because a regional archive usually has fresher metadata for its own network. extra_providers rank last of all. Each box's manifest records providers_queried and providers_skipped_by_region, so a box that found nothing can be told apart from a box where the relevant provider was never asked.

Supported with providers="auto" (26 archives). EARTHSCOPE is queried for every box; the rest are selected by region:

EARTHSCOPE (always) IESDMC Taiwan NIEP Romania
AUSPASS Australia IGN Spain NOA Greece
BGR Germany INGV Italy NRCAN Canada
BGS United Kingdom IPGP France, overseas ORFEUS Europe (ODC)
EPOSFR France KAGSR Kamchatka * SCEDC S. California
ETH Switzerland KNMI Netherlands TEXNET Texas
GEOFON Germany, global KOERI Turkey UIB-NORSAR Norway
GEONET New Zealand LMU Germany USP Brazil *
ICGC Catalonia NCEDC N. California

* KAGSR and USP publish station metadata but serve no waveforms. They are still queried, since knowing instruments exist near a corridor is a real result, but nothing depends on them for data.

Region labels say where an archive is based, not where its coverage stops: GEOFON holds instruments across Africa, Asia and Antarctica, and SCEDC reaches well beyond Southern California. The selection map is measured from real holdings rather than drawn from these labels.

Not selected automatically, but available by name: RASPISHAKE (citizen science), IRISPH5 (nodal), USGS/EMSC/ISC (event catalogues only), and EIDA (a router). IRIS, EARTHSCOPE+USGS, GFZ, ODC and RESIF are alternative names for archives already listed.

Querying Raspberry Shake

Adding the provider is not enough on its own. Raspberry Shakes are short-period instruments whose channels are EHZ and SHZ; they have never carried HHZ or BHZ, so the default channel_priorities filters them out at both discovery and download and you would silently get nothing. Widen the channels too:

run_pipeline(
    ...,
    extra_providers=("RASPISHAKE",),
    channel_priorities=("HHZ", "BHZ", "EHZ", "SHZ"),
)

Appending rather than replacing matters: channel_priorities is a priority list, so professional stations still match HHZ first and only the shakes fall through to EHZ. (ENZ is deliberately omitted — every Shake with an accelerometer also has EHZ, so it would never be selected.)

Note that Raspberry Shake data is high volume and variable quality, and the default gap rejection discards a meaningful fraction of it.

Two-Step Workflow

Download first, process later with different parameters:

from groundtrack import run_pipeline, process_boxes

# Step 1 - download only
results = run_pipeline(
    norad_id=56873,
    start="2024-04-02T08:40:00Z",
    end="2024-04-02T09:00:00Z",
    cache_dir="data/cache",       # TLEs are cached here to avoid redundant Space-Track requests
    output_dir="data/outputs",
    event_name="shenzhou15_reentry",
)

# Step 2 - process separately with custom settings
process_boxes(
    boxes_root=results["manifest"]["boxes_root"],
    freqmin=1.0,
    freqmax=10.0,
)

Visualization

from groundtrack import (
    plot_track_and_boxes,
    plot_stations,
    plot_all_waveforms,
)
from pathlib import Path

# Plot ground track and download boxes
plot_track_and_boxes(
    track_points=results["track"]["track_points"],
    box_windows=results["boxes"],
)

# Plot all processed waveforms for a specific box
plot_all_waveforms(
    boxes_root=Path(results["manifest"]["boxes_root"]),
    box_ids="box_006",
    t_start_utc="2024-04-02T08:44:00Z",
    t_end_utc="2024-04-02T08:54:00Z",
)

(back to top)

Roadmap

  • Validated against Shenzhou-15 re-entry event
  • Space-Track TLE fetching with local caching
  • Orbital propagation and ground track tiling
  • FDSN station discovery with 100 km corridor filter (configurable)
  • MassDownloader-based waveform acquisition
  • Instrument response removal and bandpass filtering
  • Visualization utilities
  • Automated test suite
  • Full documentation site
  • Ocean-tile filtering to skip all-ocean boxes before FDSN queries (~45% speedup on station query phase)
  • Parallelized station queries for full-orbit passes
  • Automated sonic boom detection and classification
  • Trajectory reconstruction from detection results
  • Live re-entry support with real-time orbital data updates

See the open issues for a full list of proposed features and known issues.

(back to top)

Contributing

Contributions are welcome. If you have a suggestion or find a bug, please open an issue or submit a pull request.

  1. Fork the project
  2. Create your feature branch (git checkout -b feature/YourFeature)
  3. Commit your changes (git commit -m 'Add YourFeature')
  4. Push to the branch (git push origin feature/YourFeature)
  5. Open a pull request

Running the tests

The test suite covers the pure geometry and data modules (geodesy, tiling, types) and requires no network access or external data. Install the test extras and run pytest:

pip install -e ".[test]"
pytest

To see a coverage report for the package:

pytest --cov=groundtrack --cov-report=term-missing

Every push and pull request runs the suite on Python 3.10 and 3.13 via GitHub Actions, and coverage is reported to Codecov.

(back to top)

License

Distributed under the MIT License. See LICENSE for more information.

(back to top)

Contact

Joseph Steinberg - LinkedIn - jstein58@jh.edu

Project Link: https://github.com/jsteinberg34/groundtrack

(back to top)

Acknowledgments

(back to top)

Metadata

Release files for groundtrack 0.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for groundtrack 0.4.0
File Size Uploaded
groundtrack-0.4.0.tar.gz 84.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for groundtrack 0.4.0
File Interpreter ABI Platform
groundtrack-0.4.0-py3-none-any.whl Python 3 none any Details

Total release size: 138.5 kB

Release files / groundtrack-0.4.0.tar.gz

Download URL groundtrack-0.4.0.tar.gz
Size 84.5 kB
Tags Source
SHA-256 checksum
How to use checksums
7a0dc1e60c9c04e9a0a8235761938d159840c86b439a41ce1ac40305e85b33b7
BLAKE2b-256 checksum
How to use checksums
9b4ed1757bfa28ac7d738d35c0ef5f6f3d5a4924eeb8f85f787a24bf63a31836
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 14, 2026.

Transparency log

Release files / groundtrack-0.4.0-py3-none-any.whl

Download URL groundtrack-0.4.0-py3-none-any.whl
Size 54.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6880feeaae18a49bc83e0a7750f43b30cd4a1ea2d8044a28d2f893670733b058
BLAKE2b-256 checksum
How to use checksums
05b4412dfe1f2262b253a9816a3369127f38af55cf41694dc165ea13bc098506
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 14, 2026.

Transparency log

Release history Release notifications | RSS feed

0.6.0

2 release files

0.5.0

2 release files

This release

0.4.0 This release

2 release files

0.3.0

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page