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:
commit
5286a2e81b
53 changed files with 8820 additions and 0 deletions
75
session-scripts/gc-bwtrial.py
Normal file
75
session-scripts/gc-bwtrial.py
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
"""Choose the background mesh size EMPIRICALLY, using the 589 SIMBAD-catalogued
|
||||
Cen A globular clusters that fall in the field as a truth set. For each mesh
|
||||
size we measure (a) how many known GCs are recovered, split by projected radius,
|
||||
and (b) how many total detections there are (a proxy for spurious detections)."""
|
||||
import os, numpy as np, sep, warnings
|
||||
from astropy.io import fits
|
||||
from astropy.wcs import WCS
|
||||
|
||||
import layout
|
||||
warnings.filterwarnings("ignore")
|
||||
S = layout.SESSION
|
||||
NUC_RA, NUC_DEC = 201.365063, -43.019113
|
||||
PIXSCALE = 0.5376
|
||||
|
||||
|
||||
def gk(fwhm=5.0):
|
||||
sig = fwhm / 2.3548
|
||||
n = int(2 * round(3 * sig) + 1)
|
||||
r = np.arange(n) - n // 2
|
||||
xx, yy = np.meshgrid(r, r)
|
||||
k = np.exp(-(xx ** 2 + yy ** 2) / (2 * sig ** 2))
|
||||
return (k / k.sum()).astype(np.float32)
|
||||
|
||||
|
||||
def match(ra1, d1, ra2, d2, tol_as):
|
||||
"""brute-force nearest match, small catalogues"""
|
||||
cd = np.cos(np.radians(d1.mean()))
|
||||
idx = np.full(len(ra1), -1)
|
||||
sep_as = np.full(len(ra1), 9e9)
|
||||
for i in range(len(ra1)):
|
||||
dd = np.hypot((ra2 - ra1[i]) * cd, d2 - d1[i]) * 3600.0
|
||||
j = np.argmin(dd)
|
||||
if dd[j] < tol_as:
|
||||
idx[i] = j
|
||||
sep_as[i] = dd[j]
|
||||
return idx, sep_as
|
||||
|
||||
|
||||
z = np.load(layout.path("_simbad.npz"), allow_pickle=True)
|
||||
m = z["otype"] == "GlC"
|
||||
gra, gdec = z["ra"][m].astype(float), z["dec"][m].astype(float)
|
||||
|
||||
hdr = fits.getheader(layout.path("master-Luminance.fit"))
|
||||
w = WCS(hdr)
|
||||
ny, nx = hdr["NAXIS2"], hdr["NAXIS1"]
|
||||
gx, gy = w.all_world2pix(gra, gdec, 0)
|
||||
inf = (gx > 20) & (gx < nx - 20) & (gy > 20) & (gy < ny - 20)
|
||||
gra, gdec, gx, gy = gra[inf], gdec[inf], gx[inf], gy[inf]
|
||||
cx, cy = [float(v) for v in w.all_world2pix(NUC_RA, NUC_DEC, 0)]
|
||||
grad = np.hypot(gx - cx, gy - cy) * PIXSCALE / 60.0
|
||||
print("known GCs inside the frame: %d (r range %.2f - %.2f arcmin)"
|
||||
% (len(gra), grad.min(), grad.max()))
|
||||
|
||||
d = fits.getdata(layout.path("master-Luminance.fit")).astype(np.float32)
|
||||
d = np.ascontiguousarray(d)
|
||||
sep.set_extract_pixstack(3000000)
|
||||
K = gk()
|
||||
|
||||
bins = [(0, 2), (2, 4), (4, 8), (8, 14), (14, 30)]
|
||||
print("\n%6s %7s | %s" % ("mesh", "Ndet", " ".join("%4.0f-%-4.0f'" % b for b in bins)))
|
||||
for bw in (12, 16, 24, 32, 48, 64, 128):
|
||||
b = sep.Background(d, bw=bw, bh=bw, fw=3, fh=3)
|
||||
ds = d - b.back()
|
||||
rm = b.rms()
|
||||
o = sep.extract(ds, 3.0, err=rm, minarea=5, filter_kernel=K,
|
||||
filter_type="matched", deblend_nthresh=32,
|
||||
deblend_cont=0.005, clean=True)
|
||||
ora, odec = w.all_pix2world(o["x"], o["y"], 0)
|
||||
idx, sp = match(gra, gdec, ora, odec, 2.0)
|
||||
row = []
|
||||
for lo, hi in bins:
|
||||
s = (grad >= lo) & (grad < hi)
|
||||
row.append("%3d/%-3d" % ((idx[s] >= 0).sum(), s.sum()))
|
||||
print("%6d %7d | %s" % (bw, len(o), " ".join(row)))
|
||||
del b, ds, rm, o
|
||||
Loading…
Add table
Add a link
Reference in a new issue