CoolFace
Apppublic

mmrech/asteroidnet2

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes
App README

☄️ AsteroidNET v0.2

Automated Near-Earth Object Detection System Dr. Matheus Machado Rech · IASC / Pan-STARRS / ZTF

![CI](https://github.com/mmrech/asteroidnet/actions/workflows/ci.yml) ![Deploy](https://github.com/mmrech/asteroidnet/actions/workflows/deploy-hf.yml) ![HuggingFace](https://huggingface.co/spaces/mmrech/asteroidnet)


What it does

AsteroidNET is a 6-stage automated pipeline for detecting moving solar system objects in multi-epoch FITS imaging data, compatible with IASC campaign packages from the Caça Asteroides MCTI program.

FITS Frames (4×, ~30 min cadence)
  ↓  Stage 1: Ingest + validate (TAI/UTC corrected, byte-swapped)
  ↓  Stage 2: Preprocess (two-pass background, cosmic-ray rejection, alignment)
  ↓  Stage 3: Source extraction (two-pass DAOStarFinder, aperture photometry)
  ↓  Stage 4: Catalog matching (Gaia DR3 stars + SkyBoT known SSOs removed)
  ↓  Stage 5: Tracklet linking (Hough-transform + KD-tree, kinematic validation)
  ↓  Stage 6: Classification (RF → CNN two-stage) + Orbit determination
  ↓  Output: MPC 80-column astrometric records, ready for submission

New in v0.2

FeatureDetails
Real FITS supportUpload IASC campaign packages directly in the UI
TAI/UTC correctionPS1 MJD-OBS is TAI; ZTF is UTC — 37-second offset handled correctly
Byte-order fixFITS big-endian data converted to float32 native before Background2D (silent bottleneck bug prevented)
Two-pass backgroundSource masking for unbiased sky estimation in crowded fields
SkyBoT integrationIMCCE cone-search removes all known solar system objects from candidates
PS1 header fixesMissing TIMESYS=TAI and RADESYS=FK5 added defensively
ZTF data accessIRSA IBE API for multi-epoch science images
Training data builderMine PS1/ZTF archives with MPC/SkyBoT labels for classifier training
GitHub Actions CI/CDTests run on every PR; auto-deploys to HF Spaces on push to main

Gradio UI Tabs

  1. 1.Processar Imagens IASC — Upload real FITS files, run full pipeline, get MPC records
  2. 2.Pipeline Simulator — Simulate on synthetic data with configurable parameters
  3. 3.MPC Formatter — Generate exact 80-column MPC astrometric records
  4. 4.Tracklet Visualizer — Inspect sky motion, ΔRA/ΔDec, and residuals
  5. 5.About — Documentation and usage guide

Using with IASC / Caça Asteroides MCTI

  1. 1.Register at iasc.cosmosearch.org
  2. 2.Download a campaign FITS package (4 frames, ~30 min cadence, same sky field)
  3. 3.Upload all 4 .fits files in the Processar Imagens IASC tab
  4. 4.Enter your MPC observatory code (F51 for Pan-STARRS; use 500 if unknown)
  5. 5.Click Run Pipeline — candidate tracklets are detected and MPC records generated
  6. 6.Copy the MPC records and submit to IASC for verification

Installation (local)

bash
git clone https://github.com/mmrech/asteroidnet
cd asteroidnet
pip install -r requirements-dev.txt
pip install -e .
pytest tests/ -v
python app.py

Data Sources

SourceTypeURL
Pan-STARRS DR2Single-epoch warp FITS images (0.25″/px)ps1images.stsci.edu
ZTF DR8Science + difference images (1.012″/px)irsa.ipac.caltech.edu
IMCCE SkyBoTKnown SSO cone-search (1889–2060)ssp.imcce.fr/webservices/skybot
MPC MPCORBOrbital elements for all known minor planetsminorplanetcenter.net
JPL HorizonsHigh-precision ephemerides via astroqueryssd.jpl.nasa.gov

Critical Implementation Notes

TAI vs UTC (the most important gotcha)

Pan-STARRS MJD-OBS is in TAI (International Atomic Time), which is 37 seconds ahead of UTC. ZTF uses UTC. A 37-second error corresponds to 0.5–2 arcseconds of apparent asteroid motion — enough to place a predicted position outside the detection aperture.

python
# Pan-STARRS: MJD-OBS is TAI
t_ps1 = Time(header["MJD-OBS"], format="mjd", scale="tai").utc

# ZTF: OBSMJD is UTC
t_ztf = Time(header["OBSMJD"], format="mjd", scale="utc")

Byte-order and bottleneck

FITS data is stored big-endian. The bottleneck library (used by Background2D for speed) silently falls back to slower numpy when given non-native-endian arrays — but with different numerical results due to different summation order. Fix: always call .astype(np.float32) after reading FITS data.

Two-pass background subtraction

Sources bias the background estimate upward if not masked. Always:

  1. 1.Rough background → detect sources → build mask
  2. 2.Refined background with masked sources → final subtraction

Architecture

asteroidnet/
├── config/           loader.py, defaults.yaml
├── data_access/      ps1_client.py, ztf_client.py, skybot_client.py
├── fits_ingestor/    ingestor.py
├── image_preprocessor/ preprocessor.py
├── source_extractor/ detector.py
├── catalog_matcher/  matcher.py
├── tracklet_linker/  linker.py
├── candidate_classifier/ classifier.py
├── orbit_determination/  gauss_method.py
├── reporting/        mpc_formatter.py
├── training/         dataset_builder.py
├── pipeline/         runner.py
└── utils/            time_utils.py, synthetic.py

Performance Targets

MetricTargetNotes
Recovery rate (SNR ≥ 5)≥ 90%SC-001
False positive rate< 1%SC-002
Star removal completeness> 99.5%Gaia DR3
Astrometric residual RMS< 1 arcsecPer tracklet
Processing time (4 frames)< 5 minOn CPU

License

MIT — see LICENSE

Citation

If you use AsteroidNET in your research, please cite:

bibtex
@software{rech2026asteroidnet,
  author = {Rech, Matheus Machado},
  title  = {AsteroidNET: Automated Near-Earth Object Detection System},
  year   = {2026},
  url    = {https://github.com/mmrech/asteroidnet}
}