Processing and analysis code for remote-telescope imaging sessions

The scripts that processed the NGC 5128 session of 2026-07-21 previously
lived inside the data directory and addressed it with absolute paths.
Code and data are now separated: the code lives here, and a session is
located at runtime through the ASTRO_SESSION environment variable.

layout.py is what makes that work. It maps a FILENAME to the
subdirectory that file belongs in, using the same rules the session
directories are organised with, so a script can go on asking for
'master-Red.fit' or '_stars.npz' without any call site knowing the
directory structure. Anything unrecognised resolves to the session root,
which is visible and correctable rather than silently wrong.

restructure.py reorganises a flat session directory into that layout. It
is idempotent and dry-run by default.

The 50 session scripts are kept as they were run rather than tidied into
a library. They were written in sequence as the work went along, several
of them by parallel agents, and they show it - but they are the honest
provenance of a published set of results, and the productionised pipeline
should be able to reproduce those results exactly.

Verified before committing: all 51 files compile without warnings, and
verify_core.py, closeup.py and triptych.py were run end to end against
the reorganised session, correctly finding inputs across calibrated/,
stacks/masters/ and final/ and writing outputs back to the right places.
This commit is contained in:
laurence 2026-07-21 15:29:49 +01:00
commit 5286a2e81b
53 changed files with 8820 additions and 0 deletions

View file

@ -0,0 +1,32 @@
"""Gaia DR3 astrometry via the VizieR mirror I/355/gaiadr3 (the ESA Gaia archive
was down for maintenance). Same rationale as gc-gaia-astrom.py."""
import os, numpy as np
from astroquery.vizier import Vizier
from astropy.coordinates import SkyCoord
import astropy.units as u
import layout
S = layout.SESSION
c = SkyCoord(201.36404, -43.01969, unit="deg")
cols = ["RA_ICRS", "DE_ICRS", "Source", "Gmag", "BPmag", "RPmag", "BP-RP",
"Plx", "e_Plx", "pmRA", "e_pmRA", "pmDE", "e_pmDE", "RUWE"]
v = Vizier(columns=cols, row_limit=-1, column_filters={"Gmag": "<21.0"})
t = v.query_region(c, radius=0.42 * u.deg, catalog="I/355/gaiadr3")[0]
print("rows:", len(t), t.colnames)
d = {}
for k, name in [("ra", "RA_ICRS"), ("dec", "DE_ICRS"), ("g", "Gmag"),
("bp", "BPmag"), ("rp", "RPmag"), ("bprp", "BP-RP"),
("plx", "Plx"), ("eplx", "e_Plx"), ("pmra", "pmRA"),
("epmra", "e_pmRA"), ("pmdec", "pmDE"), ("epmdec", "e_pmDE"),
("ruwe", "RUWE")]:
if name in t.colnames:
col = t[name]
d[k] = np.array(col.filled(np.nan) if hasattr(col, "filled") else col, dtype=float)
np.savez(layout.path("_gaia_astrom.npz"), **d)
g = d["g"]
print("saved. G<18 %d | 18-20 %d | >=20 %d" %
((g < 18).sum(), ((g >= 18) & (g < 20)).sum(), (g >= 20).sum()))
print("finite plx %d, finite pm %d" % (np.isfinite(d["plx"]).sum(), np.isfinite(d["pmra"]).sum()))