groundtrack 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- groundtrack-0.1.0/LICENSE +21 -0
- groundtrack-0.1.0/PKG-INFO +348 -0
- groundtrack-0.1.0/README.md +329 -0
- groundtrack-0.1.0/pyproject.toml +22 -0
- groundtrack-0.1.0/setup.cfg +4 -0
- groundtrack-0.1.0/src/groundtrack/__init__.py +23 -0
- groundtrack-0.1.0/src/groundtrack/download.py +386 -0
- groundtrack-0.1.0/src/groundtrack/geodesy.py +140 -0
- groundtrack-0.1.0/src/groundtrack/io.py +82 -0
- groundtrack-0.1.0/src/groundtrack/pipeline.py +187 -0
- groundtrack-0.1.0/src/groundtrack/plotting.py +480 -0
- groundtrack-0.1.0/src/groundtrack/processing.py +509 -0
- groundtrack-0.1.0/src/groundtrack/stations.py +216 -0
- groundtrack-0.1.0/src/groundtrack/tiling.py +159 -0
- groundtrack-0.1.0/src/groundtrack/track.py +345 -0
- groundtrack-0.1.0/src/groundtrack/types.py +61 -0
- groundtrack-0.1.0/src/groundtrack.egg-info/PKG-INFO +348 -0
- groundtrack-0.1.0/src/groundtrack.egg-info/SOURCES.txt +19 -0
- groundtrack-0.1.0/src/groundtrack.egg-info/dependency_links.txt +1 -0
- groundtrack-0.1.0/src/groundtrack.egg-info/requires.txt +9 -0
- groundtrack-0.1.0/src/groundtrack.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Joseph Steinberg
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: groundtrack
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Seismic detection pipeline for orbital reentry events
|
|
5
|
+
Author-email: Joseph Steinberg <josephsteinberg933@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Requires-Python: >=3.10
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Requires-Dist: numpy
|
|
11
|
+
Requires-Dist: obspy
|
|
12
|
+
Requires-Dist: spacetrack
|
|
13
|
+
Requires-Dist: pandas
|
|
14
|
+
Requires-Dist: skyfield
|
|
15
|
+
Provides-Extra: plotting
|
|
16
|
+
Requires-Dist: matplotlib; extra == "plotting"
|
|
17
|
+
Requires-Dist: cartopy; extra == "plotting"
|
|
18
|
+
Dynamic: license-file
|
|
19
|
+
|
|
20
|
+
# Groundtrack
|
|
21
|
+
|
|
22
|
+
<a name="readme-top"></a>
|
|
23
|
+
|
|
24
|
+
<!-- PROJECT SHIELDS -->
|
|
25
|
+
[![Contributors][contributors-shield]][contributors-url]
|
|
26
|
+
[![Forks][forks-shield]][forks-url]
|
|
27
|
+
[![Stargazers][stars-shield]][stars-url]
|
|
28
|
+
[![Issues][issues-shield]][issues-url]
|
|
29
|
+
[![MIT License][license-shield]][license-url]
|
|
30
|
+
[![LinkedIn][linkedin-shield]][linkedin-url]
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
<!-- PROJECT LOGO -->
|
|
34
|
+
<br />
|
|
35
|
+
<div align="center">
|
|
36
|
+
<a href="https://github.com/jsteinberg34/groundtrack">
|
|
37
|
+
<img src="images/logo.png" alt="Logo" width="80" height="80">
|
|
38
|
+
</a>
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
<h3 align="center">Groundtrack</h3>
|
|
42
|
+
|
|
43
|
+
<p align="center">
|
|
44
|
+
Seismic detection pipeline for atmospheric re-entry events using orbital ground tracks and seismic station data.
|
|
45
|
+
<br />
|
|
46
|
+
<br />
|
|
47
|
+
<a href="#usage"><strong>Quick Start »</strong></a>
|
|
48
|
+
·
|
|
49
|
+
<a href="https://github.com/jsteinberg34/groundtrack/issues">Report Bug</a>
|
|
50
|
+
·
|
|
51
|
+
<a href="https://github.com/jsteinberg34/groundtrack/issues">Request Feature</a>
|
|
52
|
+
</p>
|
|
53
|
+
</div>
|
|
54
|
+
|
|
55
|
+
<!-- TABLE OF CONTENTS -->
|
|
56
|
+
<details>
|
|
57
|
+
<summary>Table of Contents</summary>
|
|
58
|
+
<ol>
|
|
59
|
+
<li><a href="#about-the-project">About The Project</a></li>
|
|
60
|
+
<li><a href="#built-with">Built With</a></li>
|
|
61
|
+
<li><a href="#getting-started">Getting Started</a></li>
|
|
62
|
+
<li><a href="#usage">Usage</a></li>
|
|
63
|
+
<li><a href="#roadmap">Roadmap</a></li>
|
|
64
|
+
<li><a href="#contributing">Contributing</a></li>
|
|
65
|
+
<li><a href="#license">License</a></li>
|
|
66
|
+
<li><a href="#contact">Contact</a></li>
|
|
67
|
+
<li><a href="#acknowledgments">Acknowledgments</a></li>
|
|
68
|
+
</ol>
|
|
69
|
+
</details>
|
|
70
|
+
|
|
71
|
+
<!-- ABOUT THE PROJECT -->
|
|
72
|
+
## About The Project
|
|
73
|
+
|
|
74
|
+
Groundtrack is a Python library developed to assist with detecting and analyzing seismic signals that are produced when an object re-enters the atmosphere, building off the work of Dr. Fernando: <insert paper reference>. When space debris or a spacecraft re-enters the atmosphere at hypersonic speeds, they generate 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:
|
|
75
|
+
|
|
76
|
+
1. Fetches TLE elements from Space-Track using a user-provided NORAD ID
|
|
77
|
+
2. Propagates the ground track over a user-defined analysis window
|
|
78
|
+
3. Tiles the track into spatial boxes and queries FDSN providers for any nearby seismic stations that fall within a given box
|
|
79
|
+
4. Downloads waveform data for stations within a configurable distance from the ground track
|
|
80
|
+
5. Applies instrument response removal and bandpass filtering
|
|
81
|
+
6. Provides optional visualization tools for validating output
|
|
82
|
+
|
|
83
|
+
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 (insert link to his research). The pipeline was first validated in multiple proof-of-concept notebooks replicating published detection results before being migrated into this library format.
|
|
84
|
+
|
|
85
|
+
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
### Built With
|
|
90
|
+
|
|
91
|
+
This section should list any major frameworks/libraries used to bootstrap your project. Leave any add-ons/plugins for the acknowledgements section. Here are a few examples.
|
|
92
|
+
|
|
93
|
+
* [![Python][Python]][Python-url]
|
|
94
|
+
* [![NumPy][NumPy]][NumPy-url]
|
|
95
|
+
* [![ObsPy][ObsPy]][ObsPy-url]
|
|
96
|
+
* [![pandas][pandas]][pandas-url]
|
|
97
|
+
* [![Space-Track][SpaceTrack]][SpaceTrack-url]
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
### Optional Features
|
|
102
|
+
|
|
103
|
+
Groundtrack includes built-in plotting utilities for analyzing re-entry events:
|
|
104
|
+
|
|
105
|
+
- Ground track + download boxes visualization
|
|
106
|
+
- Station distribution maps
|
|
107
|
+
- Raw vs. processed waveform comparisons
|
|
108
|
+
|
|
109
|
+
Install with plotting support:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
pip install groundtrack[plotting]
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
* [![matplotlib][matplotlib]][matplotlib-url]
|
|
116
|
+
* [![cartopy][cartopy]][cartopy-url]
|
|
117
|
+
|
|
118
|
+
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
<!-- GETTING STARTED -->
|
|
122
|
+
## Getting Started
|
|
123
|
+
|
|
124
|
+
### Prerequisites
|
|
125
|
+
|
|
126
|
+
- Python 3.10+
|
|
127
|
+
- A free [Space-Track](https://www.space-track.org/auth/createAccount) account for TLE and TIP message access
|
|
128
|
+
|
|
129
|
+
### Installation
|
|
130
|
+
|
|
131
|
+
Install from PyPI:
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
pip install groundtrack
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
With optional plotting support:
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
pip install groundtrack[plotting]
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Credentials
|
|
144
|
+
|
|
145
|
+
Groundtrack requires Space-Track credentials to fetch orbital data. Set them as environment variables:
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
export SPACETRACK_USER="your_email@example.com"
|
|
149
|
+
export SPACETRACK_PASS="your_password"
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Or pass them directly to `run_pipeline()`:
|
|
153
|
+
|
|
154
|
+
```python
|
|
155
|
+
results = run_pipeline(
|
|
156
|
+
...,
|
|
157
|
+
username="your_email@example.com",
|
|
158
|
+
password="your_password",
|
|
159
|
+
)
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
<!-- USAGE EXAMPLES -->
|
|
166
|
+
## Usage
|
|
167
|
+
|
|
168
|
+
### Minimal Example
|
|
169
|
+
|
|
170
|
+
```python
|
|
171
|
+
from groundtrack import run_pipeline
|
|
172
|
+
|
|
173
|
+
results = run_pipeline(
|
|
174
|
+
norad_id=56873,
|
|
175
|
+
start="2024-04-02T08:40:00Z",
|
|
176
|
+
end="2024-04-02T09:00:00Z",
|
|
177
|
+
cache_dir="data/cache",
|
|
178
|
+
output_dir="data/outputs",
|
|
179
|
+
event_name="shenzhou15_reentry",
|
|
180
|
+
)
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### With Processing and Custom Parameters
|
|
184
|
+
|
|
185
|
+
```python
|
|
186
|
+
results = run_pipeline(
|
|
187
|
+
norad_id=56873,
|
|
188
|
+
start="2024-04-02T08:40:00Z",
|
|
189
|
+
end="2024-04-02T09:00:00Z",
|
|
190
|
+
cache_dir="data/cache",
|
|
191
|
+
output_dir="data/outputs",
|
|
192
|
+
event_name="shenzhou15_reentry",
|
|
193
|
+
corridor_km=100.0, # station inclusion threshold
|
|
194
|
+
chunk_km=300.0, # along-track box size
|
|
195
|
+
apply_processing=True, # remove instrument response + bandpass
|
|
196
|
+
freqmin=1.0, # bandpass lower corner (Hz)
|
|
197
|
+
freqmax=20.0, # bandpass upper corner (Hz)
|
|
198
|
+
)
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### Two-Step Workflow
|
|
202
|
+
|
|
203
|
+
Download first, process later with different parameters:
|
|
204
|
+
|
|
205
|
+
```python
|
|
206
|
+
from groundtrack import run_pipeline, process_boxes
|
|
207
|
+
|
|
208
|
+
# Step 1 - download only
|
|
209
|
+
results = run_pipeline(
|
|
210
|
+
norad_id=56873,
|
|
211
|
+
start="2024-04-02T08:40:00Z",
|
|
212
|
+
end="2024-04-02T09:00:00Z",
|
|
213
|
+
cache_dir="data/cache",
|
|
214
|
+
output_dir="data/outputs",
|
|
215
|
+
event_name="shenzhou15_reentry",
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
# Step 2 - process separately with custom settings
|
|
219
|
+
process_boxes(
|
|
220
|
+
boxes_root=results["manifest"]["boxes_root"],
|
|
221
|
+
freqmin=1.0,
|
|
222
|
+
freqmax=10.0,
|
|
223
|
+
)
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### Visualization
|
|
227
|
+
|
|
228
|
+
```python
|
|
229
|
+
from groundtrack import (
|
|
230
|
+
plot_track_and_boxes,
|
|
231
|
+
plot_stations,
|
|
232
|
+
plot_all_waveforms,
|
|
233
|
+
)
|
|
234
|
+
from pathlib import Path
|
|
235
|
+
|
|
236
|
+
# Plot ground track and download boxes
|
|
237
|
+
plot_track_and_boxes(
|
|
238
|
+
track_points=results["track"]["track_points"],
|
|
239
|
+
box_windows=results["boxes"],
|
|
240
|
+
)
|
|
241
|
+
|
|
242
|
+
# Plot all processed waveforms for a specific box
|
|
243
|
+
plot_all_waveforms(
|
|
244
|
+
boxes_root=Path(results["manifest"]["boxes_root"]),
|
|
245
|
+
box_ids="box_006",
|
|
246
|
+
t_start_utc="2024-04-02T08:44:00Z",
|
|
247
|
+
t_end_utc="2024-04-02T08:54:00Z",
|
|
248
|
+
)
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
<!-- ROADMAP -->
|
|
255
|
+
## Roadmap
|
|
256
|
+
|
|
257
|
+
- [x] Orbital propagation and ground track tiling
|
|
258
|
+
- [x] FDSN station discovery with 100 km corridor filter
|
|
259
|
+
- [x] MassDownloader-based waveform acquisition
|
|
260
|
+
- [x] Instrument response removal and bandpass filtering
|
|
261
|
+
- [x] Visualization utilities
|
|
262
|
+
- [ ] Automated test suite
|
|
263
|
+
- [ ] Full documentation site
|
|
264
|
+
- [ ] Parallelized inventory queries for full-orbit runs
|
|
265
|
+
- [ ] ML classification of seismic station data
|
|
266
|
+
|
|
267
|
+
See the [open issues](https://github.com/jsteinberg34/groundtrack/issues) for a full list of proposed features and known issues.
|
|
268
|
+
|
|
269
|
+
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
<!-- CONTRIBUTING -->
|
|
274
|
+
## Contributing
|
|
275
|
+
|
|
276
|
+
Contributions are welcome. If you have a suggestion or find a bug, please open an issue or submit a pull request.
|
|
277
|
+
|
|
278
|
+
1. Fork the project
|
|
279
|
+
2. Create your feature branch (`git checkout -b feature/YourFeature`)
|
|
280
|
+
3. Commit your changes (`git commit -m 'Add YourFeature'`)
|
|
281
|
+
4. Push to the branch (`git push origin feature/YourFeature`)
|
|
282
|
+
5. Open a pull request
|
|
283
|
+
|
|
284
|
+
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
<!-- LICENSE -->
|
|
288
|
+
## License
|
|
289
|
+
|
|
290
|
+
Distributed under the MIT License. See `LICENSE` for more information.
|
|
291
|
+
|
|
292
|
+
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
|
293
|
+
|
|
294
|
+
<!-- CONTACT -->
|
|
295
|
+
## Contact
|
|
296
|
+
|
|
297
|
+
Joseph Steinberg - [LinkedIn](https://www.linkedin.com/in/joey-steinberg/) - josephsteinberg933@gmail.com
|
|
298
|
+
|
|
299
|
+
Project Link: [https://github.com/jsteinberg34/groundtrack](https://github.com/jsteinberg34/groundtrack)
|
|
300
|
+
|
|
301
|
+
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
<!-- ACKNOWLEDGMENTS -->
|
|
306
|
+
## Acknowledgments
|
|
307
|
+
|
|
308
|
+
- [Dr. Benjamin Fernando](https://eps.jhu.edu) — Johns Hopkins University, Department of Earth and Planetary Sciences. Scientific methodology and validation.
|
|
309
|
+
- [ObsPy](https://docs.obspy.org/) — Core seismic data library
|
|
310
|
+
- [Skyfield](https://rhodesmill.org/skyfield/) — Orbital propagation
|
|
311
|
+
- [Space-Track](https://www.space-track.org) — TLE and TIP message data
|
|
312
|
+
- [Ed Williams' Aviation Formulary](http://www.edwilliams.org/avform147.htm) — Cross-track distance formula
|
|
313
|
+
|
|
314
|
+
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
|
315
|
+
|
|
316
|
+
<!-- MARKDOWN LINKS & IMAGES -->
|
|
317
|
+
[contributors-shield]: https://img.shields.io/github/contributors/jsteinberg34/groundtrack.svg?style=for-the-badge
|
|
318
|
+
[contributors-url]: https://github.com/jsteinberg34/groundtrack/graphs/contributors
|
|
319
|
+
[forks-shield]: https://img.shields.io/github/forks/jsteinberg34/groundtrack.svg?style=for-the-badge
|
|
320
|
+
[forks-url]: https://github.com/jsteinberg34/groundtrack/forks
|
|
321
|
+
[stars-shield]: https://img.shields.io/github/stars/jsteinberg34/groundtrack.svg?style=for-the-badge
|
|
322
|
+
[stars-url]: https://github.com/jsteinberg34/groundtrack/stargazers
|
|
323
|
+
[issues-shield]: https://img.shields.io/github/issues/jsteinberg34/groundtrack.svg?style=for-the-badge
|
|
324
|
+
[issues-url]: https://github.com/jsteinberg34/groundtrack/issues
|
|
325
|
+
[license-shield]: https://img.shields.io/badge/license-MIT-green?style=for-the-badge
|
|
326
|
+
[license-url]: https://github.com/jsteinberg34/groundtrack/blob/main/LICENSE
|
|
327
|
+
[linkedin-shield]: https://img.shields.io/badge/-LinkedIn-black.svg?style=for-the-badge&logo=linkedin&colorB=555
|
|
328
|
+
[linkedin-url]: https://www.linkedin.com/in/joey-steinberg/
|
|
329
|
+
[product-screenshot]: images/screenshot.png
|
|
330
|
+
[Python]: https://img.shields.io/badge/Python-3.10+-blue?style=for-the-badge&logo=python
|
|
331
|
+
[Python-url]: https://www.python.org/
|
|
332
|
+
[NumPy]: https://img.shields.io/badge/numpy-%23013243.svg?style=for-the-badge&logo=numpy
|
|
333
|
+
[NumPy-url]: https://numpy.org/
|
|
334
|
+
|
|
335
|
+
[ObsPy]: https://img.shields.io/badge/ObsPy-seismology-orange?style=for-the-badge
|
|
336
|
+
[ObsPy-url]: https://docs.obspy.org/
|
|
337
|
+
|
|
338
|
+
[pandas]: https://img.shields.io/badge/pandas-150458?style=for-the-badge&logo=pandas
|
|
339
|
+
[pandas-url]: https://pandas.pydata.org/
|
|
340
|
+
|
|
341
|
+
[SpaceTrack]: https://img.shields.io/badge/Space--Track-API-blue?style=for-the-badge
|
|
342
|
+
[SpaceTrack-url]: https://www.space-track.org/
|
|
343
|
+
|
|
344
|
+
[matplotlib]: https://img.shields.io/badge/matplotlib-plotting-blue?style=for-the-badge
|
|
345
|
+
[matplotlib-url]: https://matplotlib.org/
|
|
346
|
+
|
|
347
|
+
[cartopy]: https://img.shields.io/badge/cartopy-mapping-green?style=for-the-badge
|
|
348
|
+
[cartopy-url]: https://scitools.org.uk/cartopy/docs/latest/
|
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
# Groundtrack
|
|
2
|
+
|
|
3
|
+
<a name="readme-top"></a>
|
|
4
|
+
|
|
5
|
+
<!-- PROJECT SHIELDS -->
|
|
6
|
+
[![Contributors][contributors-shield]][contributors-url]
|
|
7
|
+
[![Forks][forks-shield]][forks-url]
|
|
8
|
+
[![Stargazers][stars-shield]][stars-url]
|
|
9
|
+
[![Issues][issues-shield]][issues-url]
|
|
10
|
+
[![MIT License][license-shield]][license-url]
|
|
11
|
+
[![LinkedIn][linkedin-shield]][linkedin-url]
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
<!-- PROJECT LOGO -->
|
|
15
|
+
<br />
|
|
16
|
+
<div align="center">
|
|
17
|
+
<a href="https://github.com/jsteinberg34/groundtrack">
|
|
18
|
+
<img src="images/logo.png" alt="Logo" width="80" height="80">
|
|
19
|
+
</a>
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
<h3 align="center">Groundtrack</h3>
|
|
23
|
+
|
|
24
|
+
<p align="center">
|
|
25
|
+
Seismic detection pipeline for atmospheric re-entry events using orbital ground tracks and seismic station data.
|
|
26
|
+
<br />
|
|
27
|
+
<br />
|
|
28
|
+
<a href="#usage"><strong>Quick Start »</strong></a>
|
|
29
|
+
·
|
|
30
|
+
<a href="https://github.com/jsteinberg34/groundtrack/issues">Report Bug</a>
|
|
31
|
+
·
|
|
32
|
+
<a href="https://github.com/jsteinberg34/groundtrack/issues">Request Feature</a>
|
|
33
|
+
</p>
|
|
34
|
+
</div>
|
|
35
|
+
|
|
36
|
+
<!-- TABLE OF CONTENTS -->
|
|
37
|
+
<details>
|
|
38
|
+
<summary>Table of Contents</summary>
|
|
39
|
+
<ol>
|
|
40
|
+
<li><a href="#about-the-project">About The Project</a></li>
|
|
41
|
+
<li><a href="#built-with">Built With</a></li>
|
|
42
|
+
<li><a href="#getting-started">Getting Started</a></li>
|
|
43
|
+
<li><a href="#usage">Usage</a></li>
|
|
44
|
+
<li><a href="#roadmap">Roadmap</a></li>
|
|
45
|
+
<li><a href="#contributing">Contributing</a></li>
|
|
46
|
+
<li><a href="#license">License</a></li>
|
|
47
|
+
<li><a href="#contact">Contact</a></li>
|
|
48
|
+
<li><a href="#acknowledgments">Acknowledgments</a></li>
|
|
49
|
+
</ol>
|
|
50
|
+
</details>
|
|
51
|
+
|
|
52
|
+
<!-- ABOUT THE PROJECT -->
|
|
53
|
+
## About The Project
|
|
54
|
+
|
|
55
|
+
Groundtrack is a Python library developed to assist with detecting and analyzing seismic signals that are produced when an object re-enters the atmosphere, building off the work of Dr. Fernando: <insert paper reference>. When space debris or a spacecraft re-enters the atmosphere at hypersonic speeds, they generate 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:
|
|
56
|
+
|
|
57
|
+
1. Fetches TLE elements from Space-Track using a user-provided NORAD ID
|
|
58
|
+
2. Propagates the ground track over a user-defined analysis window
|
|
59
|
+
3. Tiles the track into spatial boxes and queries FDSN providers for any nearby seismic stations that fall within a given box
|
|
60
|
+
4. Downloads waveform data for stations within a configurable distance from the ground track
|
|
61
|
+
5. Applies instrument response removal and bandpass filtering
|
|
62
|
+
6. Provides optional visualization tools for validating output
|
|
63
|
+
|
|
64
|
+
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 (insert link to his research). The pipeline was first validated in multiple proof-of-concept notebooks replicating published detection results before being migrated into this library format.
|
|
65
|
+
|
|
66
|
+
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
### Built With
|
|
71
|
+
|
|
72
|
+
This section should list any major frameworks/libraries used to bootstrap your project. Leave any add-ons/plugins for the acknowledgements section. Here are a few examples.
|
|
73
|
+
|
|
74
|
+
* [![Python][Python]][Python-url]
|
|
75
|
+
* [![NumPy][NumPy]][NumPy-url]
|
|
76
|
+
* [![ObsPy][ObsPy]][ObsPy-url]
|
|
77
|
+
* [![pandas][pandas]][pandas-url]
|
|
78
|
+
* [![Space-Track][SpaceTrack]][SpaceTrack-url]
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
### Optional Features
|
|
83
|
+
|
|
84
|
+
Groundtrack includes built-in plotting utilities for analyzing re-entry events:
|
|
85
|
+
|
|
86
|
+
- Ground track + download boxes visualization
|
|
87
|
+
- Station distribution maps
|
|
88
|
+
- Raw vs. processed waveform comparisons
|
|
89
|
+
|
|
90
|
+
Install with plotting support:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
pip install groundtrack[plotting]
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
* [![matplotlib][matplotlib]][matplotlib-url]
|
|
97
|
+
* [![cartopy][cartopy]][cartopy-url]
|
|
98
|
+
|
|
99
|
+
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
<!-- GETTING STARTED -->
|
|
103
|
+
## Getting Started
|
|
104
|
+
|
|
105
|
+
### Prerequisites
|
|
106
|
+
|
|
107
|
+
- Python 3.10+
|
|
108
|
+
- A free [Space-Track](https://www.space-track.org/auth/createAccount) account for TLE and TIP message access
|
|
109
|
+
|
|
110
|
+
### Installation
|
|
111
|
+
|
|
112
|
+
Install from PyPI:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
pip install groundtrack
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
With optional plotting support:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
pip install groundtrack[plotting]
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Credentials
|
|
125
|
+
|
|
126
|
+
Groundtrack requires Space-Track credentials to fetch orbital data. Set them as environment variables:
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
export SPACETRACK_USER="your_email@example.com"
|
|
130
|
+
export SPACETRACK_PASS="your_password"
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Or pass them directly to `run_pipeline()`:
|
|
134
|
+
|
|
135
|
+
```python
|
|
136
|
+
results = run_pipeline(
|
|
137
|
+
...,
|
|
138
|
+
username="your_email@example.com",
|
|
139
|
+
password="your_password",
|
|
140
|
+
)
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
<!-- USAGE EXAMPLES -->
|
|
147
|
+
## Usage
|
|
148
|
+
|
|
149
|
+
### Minimal Example
|
|
150
|
+
|
|
151
|
+
```python
|
|
152
|
+
from groundtrack import run_pipeline
|
|
153
|
+
|
|
154
|
+
results = run_pipeline(
|
|
155
|
+
norad_id=56873,
|
|
156
|
+
start="2024-04-02T08:40:00Z",
|
|
157
|
+
end="2024-04-02T09:00:00Z",
|
|
158
|
+
cache_dir="data/cache",
|
|
159
|
+
output_dir="data/outputs",
|
|
160
|
+
event_name="shenzhou15_reentry",
|
|
161
|
+
)
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### With Processing and Custom Parameters
|
|
165
|
+
|
|
166
|
+
```python
|
|
167
|
+
results = run_pipeline(
|
|
168
|
+
norad_id=56873,
|
|
169
|
+
start="2024-04-02T08:40:00Z",
|
|
170
|
+
end="2024-04-02T09:00:00Z",
|
|
171
|
+
cache_dir="data/cache",
|
|
172
|
+
output_dir="data/outputs",
|
|
173
|
+
event_name="shenzhou15_reentry",
|
|
174
|
+
corridor_km=100.0, # station inclusion threshold
|
|
175
|
+
chunk_km=300.0, # along-track box size
|
|
176
|
+
apply_processing=True, # remove instrument response + bandpass
|
|
177
|
+
freqmin=1.0, # bandpass lower corner (Hz)
|
|
178
|
+
freqmax=20.0, # bandpass upper corner (Hz)
|
|
179
|
+
)
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Two-Step Workflow
|
|
183
|
+
|
|
184
|
+
Download first, process later with different parameters:
|
|
185
|
+
|
|
186
|
+
```python
|
|
187
|
+
from groundtrack import run_pipeline, process_boxes
|
|
188
|
+
|
|
189
|
+
# Step 1 - download only
|
|
190
|
+
results = run_pipeline(
|
|
191
|
+
norad_id=56873,
|
|
192
|
+
start="2024-04-02T08:40:00Z",
|
|
193
|
+
end="2024-04-02T09:00:00Z",
|
|
194
|
+
cache_dir="data/cache",
|
|
195
|
+
output_dir="data/outputs",
|
|
196
|
+
event_name="shenzhou15_reentry",
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
# Step 2 - process separately with custom settings
|
|
200
|
+
process_boxes(
|
|
201
|
+
boxes_root=results["manifest"]["boxes_root"],
|
|
202
|
+
freqmin=1.0,
|
|
203
|
+
freqmax=10.0,
|
|
204
|
+
)
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Visualization
|
|
208
|
+
|
|
209
|
+
```python
|
|
210
|
+
from groundtrack import (
|
|
211
|
+
plot_track_and_boxes,
|
|
212
|
+
plot_stations,
|
|
213
|
+
plot_all_waveforms,
|
|
214
|
+
)
|
|
215
|
+
from pathlib import Path
|
|
216
|
+
|
|
217
|
+
# Plot ground track and download boxes
|
|
218
|
+
plot_track_and_boxes(
|
|
219
|
+
track_points=results["track"]["track_points"],
|
|
220
|
+
box_windows=results["boxes"],
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
# Plot all processed waveforms for a specific box
|
|
224
|
+
plot_all_waveforms(
|
|
225
|
+
boxes_root=Path(results["manifest"]["boxes_root"]),
|
|
226
|
+
box_ids="box_006",
|
|
227
|
+
t_start_utc="2024-04-02T08:44:00Z",
|
|
228
|
+
t_end_utc="2024-04-02T08:54:00Z",
|
|
229
|
+
)
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
<!-- ROADMAP -->
|
|
236
|
+
## Roadmap
|
|
237
|
+
|
|
238
|
+
- [x] Orbital propagation and ground track tiling
|
|
239
|
+
- [x] FDSN station discovery with 100 km corridor filter
|
|
240
|
+
- [x] MassDownloader-based waveform acquisition
|
|
241
|
+
- [x] Instrument response removal and bandpass filtering
|
|
242
|
+
- [x] Visualization utilities
|
|
243
|
+
- [ ] Automated test suite
|
|
244
|
+
- [ ] Full documentation site
|
|
245
|
+
- [ ] Parallelized inventory queries for full-orbit runs
|
|
246
|
+
- [ ] ML classification of seismic station data
|
|
247
|
+
|
|
248
|
+
See the [open issues](https://github.com/jsteinberg34/groundtrack/issues) for a full list of proposed features and known issues.
|
|
249
|
+
|
|
250
|
+
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
<!-- CONTRIBUTING -->
|
|
255
|
+
## Contributing
|
|
256
|
+
|
|
257
|
+
Contributions are welcome. If you have a suggestion or find a bug, please open an issue or submit a pull request.
|
|
258
|
+
|
|
259
|
+
1. Fork the project
|
|
260
|
+
2. Create your feature branch (`git checkout -b feature/YourFeature`)
|
|
261
|
+
3. Commit your changes (`git commit -m 'Add YourFeature'`)
|
|
262
|
+
4. Push to the branch (`git push origin feature/YourFeature`)
|
|
263
|
+
5. Open a pull request
|
|
264
|
+
|
|
265
|
+
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
<!-- LICENSE -->
|
|
269
|
+
## License
|
|
270
|
+
|
|
271
|
+
Distributed under the MIT License. See `LICENSE` for more information.
|
|
272
|
+
|
|
273
|
+
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
|
274
|
+
|
|
275
|
+
<!-- CONTACT -->
|
|
276
|
+
## Contact
|
|
277
|
+
|
|
278
|
+
Joseph Steinberg - [LinkedIn](https://www.linkedin.com/in/joey-steinberg/) - josephsteinberg933@gmail.com
|
|
279
|
+
|
|
280
|
+
Project Link: [https://github.com/jsteinberg34/groundtrack](https://github.com/jsteinberg34/groundtrack)
|
|
281
|
+
|
|
282
|
+
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
<!-- ACKNOWLEDGMENTS -->
|
|
287
|
+
## Acknowledgments
|
|
288
|
+
|
|
289
|
+
- [Dr. Benjamin Fernando](https://eps.jhu.edu) — Johns Hopkins University, Department of Earth and Planetary Sciences. Scientific methodology and validation.
|
|
290
|
+
- [ObsPy](https://docs.obspy.org/) — Core seismic data library
|
|
291
|
+
- [Skyfield](https://rhodesmill.org/skyfield/) — Orbital propagation
|
|
292
|
+
- [Space-Track](https://www.space-track.org) — TLE and TIP message data
|
|
293
|
+
- [Ed Williams' Aviation Formulary](http://www.edwilliams.org/avform147.htm) — Cross-track distance formula
|
|
294
|
+
|
|
295
|
+
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
|
296
|
+
|
|
297
|
+
<!-- MARKDOWN LINKS & IMAGES -->
|
|
298
|
+
[contributors-shield]: https://img.shields.io/github/contributors/jsteinberg34/groundtrack.svg?style=for-the-badge
|
|
299
|
+
[contributors-url]: https://github.com/jsteinberg34/groundtrack/graphs/contributors
|
|
300
|
+
[forks-shield]: https://img.shields.io/github/forks/jsteinberg34/groundtrack.svg?style=for-the-badge
|
|
301
|
+
[forks-url]: https://github.com/jsteinberg34/groundtrack/forks
|
|
302
|
+
[stars-shield]: https://img.shields.io/github/stars/jsteinberg34/groundtrack.svg?style=for-the-badge
|
|
303
|
+
[stars-url]: https://github.com/jsteinberg34/groundtrack/stargazers
|
|
304
|
+
[issues-shield]: https://img.shields.io/github/issues/jsteinberg34/groundtrack.svg?style=for-the-badge
|
|
305
|
+
[issues-url]: https://github.com/jsteinberg34/groundtrack/issues
|
|
306
|
+
[license-shield]: https://img.shields.io/badge/license-MIT-green?style=for-the-badge
|
|
307
|
+
[license-url]: https://github.com/jsteinberg34/groundtrack/blob/main/LICENSE
|
|
308
|
+
[linkedin-shield]: https://img.shields.io/badge/-LinkedIn-black.svg?style=for-the-badge&logo=linkedin&colorB=555
|
|
309
|
+
[linkedin-url]: https://www.linkedin.com/in/joey-steinberg/
|
|
310
|
+
[product-screenshot]: images/screenshot.png
|
|
311
|
+
[Python]: https://img.shields.io/badge/Python-3.10+-blue?style=for-the-badge&logo=python
|
|
312
|
+
[Python-url]: https://www.python.org/
|
|
313
|
+
[NumPy]: https://img.shields.io/badge/numpy-%23013243.svg?style=for-the-badge&logo=numpy
|
|
314
|
+
[NumPy-url]: https://numpy.org/
|
|
315
|
+
|
|
316
|
+
[ObsPy]: https://img.shields.io/badge/ObsPy-seismology-orange?style=for-the-badge
|
|
317
|
+
[ObsPy-url]: https://docs.obspy.org/
|
|
318
|
+
|
|
319
|
+
[pandas]: https://img.shields.io/badge/pandas-150458?style=for-the-badge&logo=pandas
|
|
320
|
+
[pandas-url]: https://pandas.pydata.org/
|
|
321
|
+
|
|
322
|
+
[SpaceTrack]: https://img.shields.io/badge/Space--Track-API-blue?style=for-the-badge
|
|
323
|
+
[SpaceTrack-url]: https://www.space-track.org/
|
|
324
|
+
|
|
325
|
+
[matplotlib]: https://img.shields.io/badge/matplotlib-plotting-blue?style=for-the-badge
|
|
326
|
+
[matplotlib-url]: https://matplotlib.org/
|
|
327
|
+
|
|
328
|
+
[cartopy]: https://img.shields.io/badge/cartopy-mapping-green?style=for-the-badge
|
|
329
|
+
[cartopy-url]: https://scitools.org.uk/cartopy/docs/latest/
|