Move the processing code under pipeline/
Preparing to merge this repository into a combined astrophotography repo. session-scripts/ becomes pipeline/ because the scripts import layout.py from their own directory and must stay together, and because 'pipeline' says what it is rather than how it came about. observing/ stays at the top level: observing plans are not processing code.
This commit is contained in:
parent
653ca103cd
commit
c6299f41ab
53 changed files with 0 additions and 0 deletions
|
|
@ -1,191 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
mo_mpc.py -- "was there a known minor planet in the frame?"
|
||||
|
||||
Purpose
|
||||
-------
|
||||
The NGC 5128 (Centaurus A) LRGB session of 2026-07-21 was searched for moving
|
||||
objects (see _mo_dets.npz / _mo_tracklets.npy). Before any detection can be
|
||||
called a *new* object, we must rule out that it is simply a catalogued minor
|
||||
planet that happened to drift through the field. This script asks the
|
||||
authoritative services what known small bodies were inside the field of view at
|
||||
the epoch of the exposures.
|
||||
|
||||
Field / epoch
|
||||
-------------
|
||||
Field centre : RA 13 25 27.37, Dec -43 01 10.9 (J2000)
|
||||
= 201.36404 deg, -43.01969 deg
|
||||
Field size : 42.9' x 28.6' (half-diagonal ~25.8')
|
||||
Search radius: 30 arcmin (0.5 deg) -- comfortably encloses the whole frame
|
||||
Epoch : 2026-07-21 09:22 UTC (= 2026 07 21.39), mid-luminance-sequence
|
||||
(luminance ran 08:56-10:00 UTC, session ended ~11:16 UTC)
|
||||
Observatory : Q62, iTelescope / Siding Spring Observatory
|
||||
|
||||
Services queried
|
||||
----------------
|
||||
1. JPL Small-Body Identification API
|
||||
https://ssd-api.jpl.nasa.gov/sb_ident.api
|
||||
Primary source. Well documented, accepts arbitrary (including future) epochs
|
||||
because it propagates orbits rather than serving a precomputed ephemeris.
|
||||
IMPORTANT UNITS GOTCHA: despite some documentation wording, fov-ra-hwidth and
|
||||
fov-dec-hwidth are interpreted in DEGREES, not arcminutes. Passing "30"
|
||||
yields a 30-degree half-width box (the API echoes the box it used in
|
||||
["observer"]["fov_offset"], which is worth checking every run).
|
||||
Queried twice: sb-kind=a (asteroids) and sb-kind=c (comets).
|
||||
|
||||
2. MPC "MPChecker" / minor planet checker
|
||||
https://minorplanetcenter.net/cgi-bin/mpcheck.cgi (classic HTTP POST form)
|
||||
https://www.minorplanetcenter.net/cgi-bin/checkmp.cgi
|
||||
Cross-check. Kept in the script even if it fails, so the log records whether
|
||||
the MPC endpoint was reachable and what it said.
|
||||
|
||||
Output
|
||||
------
|
||||
Raw responses (JSON + HTML) and a human-readable summary are appended to
|
||||
intermediates/_mpc_query.txt
|
||||
Nothing is fabricated: if a service errors or refuses the epoch, the error text
|
||||
itself is written to the log.
|
||||
"""
|
||||
|
||||
import json
|
||||
import math
|
||||
import sys
|
||||
import datetime
|
||||
|
||||
import requests
|
||||
|
||||
import layout
|
||||
|
||||
# ---------------------------------------------------------------- field/epoch
|
||||
RA_SEX = "13-25-27.37"
|
||||
DEC_SEX = "M43-01-10.9" # JPL uses a leading "M" for a negative Dec
|
||||
RA_DEG = 201.36404
|
||||
DEC_DEG = -43.01969
|
||||
OBS_TIME = "2026-07-21_09:22:00"
|
||||
MPC_CODE = "Q62" # iTelescope, Siding Spring
|
||||
RADIUS_ARCMIN = 30.0
|
||||
HWIDTH_DEG = RADIUS_ARCMIN / 60.0 # = 0.5 deg; API wants DEGREES here
|
||||
VMAG_LIM = 22.0
|
||||
|
||||
OUT = layout.path("_mpc_query.txt")
|
||||
|
||||
log_lines = []
|
||||
|
||||
|
||||
def log(s=""):
|
||||
print(s)
|
||||
log_lines.append(str(s))
|
||||
|
||||
|
||||
# ------------------------------------------------------------------ JPL query
|
||||
def jpl(sb_kind):
|
||||
"""Query ssd-api.jpl.nasa.gov/sb_ident.api for one small-body class."""
|
||||
params = {
|
||||
"sb-kind": sb_kind, # 'a' = asteroid, 'c' = comet
|
||||
"mpc-code": MPC_CODE,
|
||||
"obs-time": OBS_TIME,
|
||||
"fov-ra-center": RA_SEX,
|
||||
"fov-dec-center": DEC_SEX,
|
||||
"fov-ra-hwidth": f"{HWIDTH_DEG}",
|
||||
"fov-dec-hwidth": f"{HWIDTH_DEG}",
|
||||
"mag-required": "true",
|
||||
"two-pass": "true",
|
||||
"vmag-lim": f"{VMAG_LIM}",
|
||||
}
|
||||
r = requests.get("https://ssd-api.jpl.nasa.gov/sb_ident.api",
|
||||
params=params, timeout=180)
|
||||
log(f"--- JPL sb_ident sb-kind={sb_kind} -> HTTP {r.status_code}")
|
||||
log(f" URL: {r.url}")
|
||||
if r.status_code != 200:
|
||||
log(" RAW: " + r.text[:2000])
|
||||
return None
|
||||
d = r.json()
|
||||
log(" observer : " + json.dumps(d.get("observer", {})))
|
||||
log(" n_first_pass : " + str(d.get("n_first_pass")))
|
||||
log(" n_second_pass: " + str(d.get("n_second_pass")))
|
||||
return d
|
||||
|
||||
|
||||
def show(d, label):
|
||||
"""Print the refined (second-pass) hits, falling back to first pass."""
|
||||
if d is None:
|
||||
return
|
||||
rows = d.get("data_second_pass") or []
|
||||
fields = d.get("fields_second") or []
|
||||
if not rows:
|
||||
rows = d.get("data_first_pass") or []
|
||||
fields = d.get("fields_first") or []
|
||||
log(f" [{label}] no second-pass data; showing first pass")
|
||||
log(f" fields: {fields}")
|
||||
if not rows:
|
||||
log(f" [{label}] NO OBJECTS in field.")
|
||||
return
|
||||
for row in rows:
|
||||
log(" " + " | ".join(str(x) for x in row))
|
||||
|
||||
|
||||
# ------------------------------------------------------------------ MPC query
|
||||
def mpchecker():
|
||||
"""Classic MPChecker POST form. Recorded even if it fails."""
|
||||
data = {
|
||||
"year": "2026", "month": "07", "day": "21.39",
|
||||
"which": "pos",
|
||||
"ra": "13 25 27.37", "decl": "-43 01 10.9",
|
||||
"TextArea": "",
|
||||
"radius": str(int(RADIUS_ARCMIN)),
|
||||
"limit": f"{VMAG_LIM}",
|
||||
"oc": MPC_CODE,
|
||||
"sort": "d", "mot": "h", "tmot": "s",
|
||||
"pdes": "u", "needed": "f", "ps": "n", "type": "p",
|
||||
}
|
||||
for url in ("https://minorplanetcenter.net/cgi-bin/mpcheck.cgi",
|
||||
"https://www.minorplanetcenter.net/cgi-bin/checkmp.cgi"):
|
||||
try:
|
||||
r = requests.post(url, data=data, timeout=120,
|
||||
headers={"User-Agent": "Mozilla/5.0 (mo_mpc.py)"})
|
||||
log(f"--- MPC POST {url} -> HTTP {r.status_code}, {len(r.text)} bytes")
|
||||
log(r.text[:8000])
|
||||
except Exception as e: # noqa: BLE001
|
||||
log(f"--- MPC POST {url} -> EXCEPTION {type(e).__name__}: {e}")
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------- main
|
||||
if __name__ == "__main__":
|
||||
log("MPC / minor-planet field check")
|
||||
log("run at " + datetime.datetime.utcnow().isoformat() + "Z")
|
||||
log(f"field centre {RA_SEX} {DEC_SEX} (J2000) = {RA_DEG}, {DEC_DEG}")
|
||||
log(f"epoch {OBS_TIME} UTC, obs code {MPC_CODE}, "
|
||||
f"radius {RADIUS_ARCMIN}' , V<{VMAG_LIM}")
|
||||
log()
|
||||
|
||||
for kind, label in (("a", "asteroids"), ("c", "comets")):
|
||||
try:
|
||||
show(jpl(kind), label)
|
||||
except Exception as e: # noqa: BLE001
|
||||
log(f" JPL {label} EXCEPTION {type(e).__name__}: {e}")
|
||||
log()
|
||||
|
||||
mpchecker()
|
||||
|
||||
# --- derived summary: total sky motion and position angle for JPL hits ---
|
||||
log()
|
||||
log("=== derived summary (from JPL second pass, sb-kind=a) ===")
|
||||
try:
|
||||
d = jpl("a")
|
||||
for row in (d.get("data_second_pass") or []):
|
||||
name, ra, dec = row[0], row[1], row[2]
|
||||
norm = float(row[5])
|
||||
vmag = row[6]
|
||||
dra, ddec = float(row[7]), float(row[8]) # "/h, RA rate has cos(dec)
|
||||
tot = math.hypot(dra, ddec)
|
||||
pa = math.degrees(math.atan2(dra, ddec)) % 360.0 # N through E
|
||||
log(f"{name}: RA {ra} Dec {dec} V={vmag} "
|
||||
f"{norm:.0f}\" ({norm/60:.1f}') from centre "
|
||||
f"motion {tot:.1f}\"/hr at PA {pa:.1f} deg "
|
||||
f"(dRA*cos(dec)={dra:.1f}, dDec={ddec:.1f} \"/hr)")
|
||||
except Exception as e: # noqa: BLE001
|
||||
log(f"summary EXCEPTION {type(e).__name__}: {e}")
|
||||
|
||||
with open(OUT, "w", encoding="utf-8") as fh:
|
||||
fh.write("\n".join(log_lines) + "\n")
|
||||
print("\nwrote " + OUT)
|
||||
Loading…
Add table
Add a link
Reference in a new issue