Technical documentation — version 4 (no JPL)
This program takes a ZTF objectId (e.g., ZTF26abmusfv) and automatically rejects
known solar‑system objects (asteroids) and high proper‑motion stars (HPM stars).
It does so by consulting multiple independent data sources in a degrading hierarchy:
fastest, most‑certain checks run first; only when they fail do slower, less‑certain checks execute.
The goal is to filter out these two dominant classes of false positives,
leaving behind candidates that may be genuine transients (supernovae, variable stars, etc.).
Each layer attempts to reject the source. If a layer succeeds, the process stops immediately and the source is classified as “known asteroid” or “high proper‑motion star”. If all layers fail, the source remains unclassified and is flagged for manual review.
L1 ALeRCE avro interface → check ssnamenr (∼200 ms)
│
▼ (ssnamenr empty)
L2 Heidelberg Gaia DR3 → search for high‑PM stars (∼2–10 s)
│
▼ (no HPM candidate)
L3 VizieR (Gaia DR3 / UCAC5 / URAT1 / TICv8.2) (∼3–15 s)
│
▼ (no HPM candidate)
L4 Simbad stellar database (∼1–5 s)
│
▼ (no HPM candidate)
L5 RANSAC linear fit on own detections (∼0.1 s)
ssnamenr
ZTF’s real‑time pipeline cross‑matches every alert against the Minor Planet Center (MPC) orbit catalogue.
If a known asteroid lies within 30″ of the detection, the field ssnamenr is populated
with its MPC number (e.g., 35891). The program retrieves the original Avro alert via
https://avro.alerce.online/get_avro_info and inspects this field.
If non‑empty, the source is immediately rejected as a known asteroid.
Queries the Gaia DR3 catalogue hosted at the University of Heidelberg (ARI) via TAP. Searches for sources within increasing radii (120″ → 300″ → 600″ → 1200″) that have proper motion > 200, 150, 100, 50 mas/yr, low RUWE (<1.4), and a valid parallax. The best candidate is selected by scoring alignment between the observed position and the position predicted by extrapolating the catalogue epoch to the observation epoch. If a good match is found, the source is rejected as a high proper‑motion star.
Sequentially queries four catalogues through the CDS VizieR service: Gaia DR3, UCAC5, URAT1, and TICv8.2. For each catalogue, it searches within 120″, 300″, 600″ and requires proper motion > 10 mas/yr. Candidate positions are propagated from the catalogue epoch to the mean observation MJD. If the propagated position falls within a tolerance (5× expected displacement), the source is rejected as a high proper‑motion star.
| Catalogue | Reference epoch (MJD) | Typical PM precision |
|---|---|---|
| Gaia DR3 | 57388.5 | ∼0.02 mas/yr |
| UCAC5 | 55200.0 | ∼1 mas/yr |
| URAT1 | 56700.0 | ∼2 mas/yr |
| TICv8.2 | 58119.0 | ∼1 mas/yr |
Uses the CDS Simbad service to search for known stellar objects within 120″, 300″, 600″. Requires proper motion > 10 mas/yr. The same epoch‑extrapolation logic is applied. If a match is found, the source is rejected as a known star.
When no external catalogue match exists, the program fits a straight line to the
source’s own ZTF detection points (RA vs. time, Dec vs. time) using
RANSAC (Random Sample Consensus) regression.
Only detections from the same objectId are used.
The fitted slope gives the angular velocity in arcsec/hr.
From the velocity, an approximate proper motion in mas/yr is derived.
The source is then labelled based on the following criteria:
| Condition | Label | Interpretation |
|---|---|---|
| v < 0.5″/hr, RMS < 0.5″, R² > 0.80, span > 1 h | high_proper_motion_star | Reject as HPM star |
| v > 2″/hr, RMS < 0.5″, R² > 0.90 | sso_candidate | Possible solar‑system object (but no MPC match) |
| 0.5 ≤ v ≤ 2″/hr, RMS < 0.5″, R² > 0.70 | gray_zone | Ambiguous – manual review recommended |
| Otherwise | unknown / unreliable | Likely stationary or insufficient data |
If the fit is reliable (R² ≥ 0.5, inlier fraction ≥ 50%), the label is reported; otherwise the source remains unclassified.
Install all dependencies with:
pip install requests alerce astroquery astropy scikit-learn pandas numpy
| Library | Version tested | Purpose in this pipeline |
|---|---|---|
requests | ≥2.31 | HTTP calls to ALeRCE Avro API (L1) |
alerce | ≥3.0 | Official ALeRCE Python client – fetches ZTF detections |
astroquery | ≥0.4.7 | TAP queries (Heidelberg Gaia DR3), VizieR catalogue access, Simbad queries |
astropy | ≥5.3 | SkyCoord, Time conversions, coordinate transformations |
scikit-learn | ≥1.3 | RANSACRegressor for linear fitting (L5) |
pandas | ≥2.0 | DataFrame handling for detection tables |
numpy | ≥1.24 | Numerical operations (trigonometry, statistics) |
| Layer | Service / Endpoint | Protocol |
|---|---|---|
| L1 | https://avro.alerce.online/get_avro_info | REST (JSON) |
| L2 | https://gaia.ari.uni-heidelberg.de/tap | TAP (ADQL) |
| L3 | CDS VizieR (http://vizier.cds.unistra.fr/viz-bin/VizieR) | VizieR protocol |
| L4 | CDS Simbad (http://simbad.u-strasbg.fr/simbad) | VOTable |
| L5 | Own ZTF detections (via ALeRCE query_detections) | Internal |
A single ZTF objectId string (e.g., ZTF26abmusfv).
Target: ZTF26abmusfv
ZTF coords: RA=263.431011 Dec=-13.696609 Mean MJD=61261.2
========== L1: ALeRCE avro interface checking ssnamenr ==========
Requesting avro: oid=ZTF26abmusfv, candid=3507168715315015016
✅ Found known asteroid: ssnamenr=35891
Distance: 9.0″
Predicted magnitude: 18.0
⏭️ L1 confirmed as known asteroid, skipping remaining layers.
📋 Final report — ZTF26abmusfv
✅ Conclusion: Known asteroid (avro ssnamenr=35891)
Offset: 9.00″
V magnitude: 18.0
========================================
ZTF Source Classifier v4 — No JPL
========================================
Enter ZTF object ID: ZTF26abegooo
Querying ZTF26abegooo ...
Target: ZTF26abegooo
ZTF coords: RA=349.785140 Dec=-6.225504 Mean MJD=61233.4
========== L1: ALeRCE avro interface checking ssnamenr ==========
Requesting avro: oid=ZTF26abegooo, candid=3438462660215015014
[info] ssnamenr empty or missing, proceeding to next layers
========== L2: Gaia DR3 @ Heidelberg ==========
INFO: Query finished. [astroquery.utils.tap.core]
[Heidelberg] r= 120″ pm> 200 ... INFO: Query finished. [astroquery.utils.tap.core]
✅ 1 cand
========== L3: VizieR (Gaia DR3/UCAC5/URAT1/TICv8.2) ==========
[VizieR:Gaia DR3] r=120″ ... ✅ 17 row(s)
❌ Rejected: Gaia DR3 2631967160264218752 pm=30.8 mas/yr sep=108.0″ > disp=0.3″
❌ Rejected: Gaia DR3 2631967263342966400 pm=14.5 mas/yr sep=55.1″ > disp=0.2″
❌ Rejected: Gaia DR3 2631967332062443776 pm=16.2 mas/yr sep=36.5″ > disp=0.2″
✅ Accepted: Gaia DR3 2631967439437024384 pm=1701.5 mas/yr sep=0.3″
========== L4: Simbad (stellar verification) ==========
[simbad] r=120″ ...
[simbad] 7 raw
✅ Accepted: EGGR 555 pm=1701.5 mas/yr
========== L5: RANSAC (self-detection points only) ==========
✅ high_proper_motion_star: v=0.000232″/hr PM≈2035 mas/yr RMS=0.085″ R²=0.8949 span=1654h inliers=161/163 (reliable)
============================================================
📋 Full Report — ZTF26abegooo
ZTF: RA=349.785140° Dec=-6.225504° Mean MJD=61233.4
============================================================
L1 ❌ avro ssnamenr: avro request failed or no candid
L2 ✅ Heidelberg Gaia DR3: Gaia DR3 2631967439437024384 pm=1701.5 mas/yr pred=(349.78517,-6.22559) sep=0.3″
L3 ✅ VizieR: Gaia DR3 2631967439437024384 pm=1701.5 mas/yr pred=(349.78517,-6.22559) sep=0.3″
L4 ✅ Simbad: EGGR 555 pm=1701.5 mas/yr pred=(349.78517,-6.22559) sep=0.3″
L5 ✅ RANSAC: high_proper_motion_star v=0.000232″/hr PM≈2035 mas/yr R²=0.8949 inliers=161/163
------------------------------------------------------------
✅ Conclusion: High proper-motion star confirmed (L2)
Source: Gaia DR3 2631967439437024384
Proper motion: 1701.5 mas/yr
Predicted position: RA=349.785168° Dec=-6.225594°
Offset: 0.34″
| Catalogue | Reference MJD | Approximate date |
|---|---|---|
| Gaia DR3 | 57388.5 | 2016‑01‑01 (J2016.0) |
| UCAC5 | 55200.0 | 2000‑01‑01 (J2000.0) |
| URAT1 | 56700.0 | 2014‑01‑01 |
| TICv8.2 | 58119.0 | 2018‑01‑01 |
| Simbad (mixed) | 51544.5 | 2000‑01‑01 (J2000.0, assumed) |
Δt = (observation_MJD − catalogue_MJD) / 365.25 [years] predicted_RA = catalogue_RA + (pmRA × Δt) / (1e3 × 3600 × cos(catalogue_Dec)) predicted_Dec = catalogue_Dec + (pmDec × Δt) / (1e3 × 3600) expected_displacement = sqrt(pmRA² + pmDec²) × |Δt| / 1000 [arcsec]
The source is accepted if the separation between predicted position and observed position
is less than max(expected_displacement × 5, 10″).
This tool is intended for use only after classification and before reporting to TNS. Its design purpose is to add an extra filter for ZTF automated reporting, removing false high‑proper‑motion stars and asteroids in the final step before submission, thereby reducing erroneous automated reports from ZTF.
Please note that this is a test version only and has not been integrated into any automated pipeline. You are free to modify the code and adapt it for other applications as needed.
Note on L1 reliability:
Even though the avro interface returns a non‑empty ssnamenr, this does not guarantee with absolute certainty that the source is a known asteroid.
However, the probability of a false positive is very low. Moreover, using this single‑alert check is significantly more efficient than requesting a large list of known asteroids from the MPC for the same field, since the MPC imposes strict access limits on bulk queries.
Thus, we consider L1 as a practical and efficient rejection criterion.
If you have suggestions for improvement, please contact me at nq605717588@gmail.com.
The source code for this pipeline is available at: https://github.com/DCAP-MinruiNing/DCAP.
Documentation generated for internal use. Last updated: August 2026.