Solve by pointing where the header allows it, and refuse doubtful solutions
Three fixes and one refusal, all found by working on the wide-field narrowband session that would not solve. The detection floor was a fixed 12 pixels, which quietly assumed a well sampled star. At 0.53 arcsec/px with 5.9 px seeing that is right; at 3.5 arcsec/px the stars are undersampled at 1.75 px FWHM and cover a handful of pixels each, so the floor discarded nearly every real star and kept blends and galaxies instead. It now scales with the measured seeing, and that session went from 305 usable detections to 600. Matching now happens over the frame's inscribed circle rather than a cone reaching its corners. On a 4 degree field the old cone covered 33 square degrees of sky against 16 of image, so half the catalogue was not in the picture at all. Where the header records a roll angle - and iTelescope's does - the orientation no longer has to be recovered from scratch. Rotation, scale and parity are applied directly and only the residual pointing error is searched, by histogramming every detection-to-catalogue offset and taking the peak. Asterism matching remains as the fallback for headers that say nothing about orientation. The refusal matters most. With catalogue depth slices added, the wide field produced a "solution" of 25 stars at 2.50 px residual, claiming a centre half a degree from the pointing. A genuine solve on that field matches hundreds of stars and refines to well under a pixel. Accepting it would have silently corrupted every position in the science catalogue, so a solution must now reach 40 stars AND 1.5 px or it is discarded and the session is reported as unsolved. A wrong WCS is worse than no WCS. NGC 2030 improves from 0.31 to 0.12 arcsec on 123 stars under the pointing-based match. NGC 2070 is honestly unsolved.
This commit is contained in:
parent
3eb5ab6a03
commit
3c4ae5c77e
2 changed files with 170 additions and 21 deletions
|
|
@ -32,13 +32,26 @@ def measure_frame(path, max_stars=MAX_STARS):
|
|||
rms = float(bkg.globalrms)
|
||||
sub = data - bkg.back()
|
||||
|
||||
objs = sep.extract(sub, DETECT_SIGMA, err=rms, minarea=9,
|
||||
objs = sep.extract(sub, DETECT_SIGMA, err=rms, minarea=5,
|
||||
deblend_cont=0.005)
|
||||
# Saturated cores and cosmic-ray hits both make poor registration anchors
|
||||
# and poor seeing estimates, so they are excluded before anything is
|
||||
# measured from them.
|
||||
objs = objs[(objs["flag"] == 0) & (objs["npix"] > 12) &
|
||||
(objs["npix"] < 3000)]
|
||||
# Saturated cores and cosmic-ray hits make poor registration anchors and
|
||||
# poor seeing estimates, so they go first.
|
||||
objs = objs[(objs["flag"] == 0) & (objs["npix"] < 3000)]
|
||||
|
||||
# The minimum size has to follow the SAMPLING, not be a fixed number of
|
||||
# pixels. A fixed floor of 12 px assumes a well sampled star: at 0.53
|
||||
# arcsec/px with 5.9 px seeing that is right, but at 3.5 arcsec/px the
|
||||
# stars are undersampled at 1.75 px FWHM and cover only a handful of
|
||||
# pixels each, so the same floor discards nearly every real star and keeps
|
||||
# blends and galaxies instead. That is what made the wide-field sessions
|
||||
# impossible to plate solve: the surviving detections were not the objects
|
||||
# the catalogue lists.
|
||||
if len(objs) > 10:
|
||||
rad0, _ = sep.flux_radius(sub, objs["x"], objs["y"], 6.0 * objs["a"],
|
||||
0.5, normflux=objs["flux"])
|
||||
fwhm0 = float(np.median(rad0) * 2.0)
|
||||
min_npix = max(4, int(0.5 * np.pi * (fwhm0 / 2.0) ** 2))
|
||||
objs = objs[objs["npix"] >= min_npix]
|
||||
if len(objs) == 0:
|
||||
del data, sub, bkg
|
||||
return dict(sky=sky, rms=rms, fwhm=np.nan, nstars=0,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue