66 lines
2.7 KiB
Python
66 lines
2.7 KiB
Python
"""Extraction-time vetting: a present-but-bad frame must never become training truth."""
|
|
|
|
import numpy as np
|
|
|
|
import dataset_build
|
|
from conftest import solar_disc, write_fits
|
|
from suvi import paths
|
|
|
|
|
|
#: Scale putting a peak-1.0 synthetic disc's IMG_MEAN inside each band's
|
|
#: physical bounds (header_v1 rightly rejects a 304A frame as dim as a 94A one).
|
|
BAND_SCALE = {94: 0.5, 131: 0.5, 171: 1.0, 195: 2.0, 284: 2.0, 304: 3.0}
|
|
|
|
|
|
def slot_files(tmp_path, image, refcrota=None):
|
|
rows = {}
|
|
extra = {"REFCROTA": refcrota} if refcrota is not None else {}
|
|
for wavelength in paths.WAVELENGTHS:
|
|
path = tmp_path / f"{wavelength}.fits"
|
|
write_fits(str(path), image * BAND_SCALE[wavelength],
|
|
headers={"WAVELNTH": wavelength, **extra})
|
|
rows[wavelength] = str(path.relative_to(tmp_path))
|
|
return rows
|
|
|
|
|
|
def test_extract_accepts_a_healthy_slot(tmp_path):
|
|
rows = slot_files(tmp_path, solar_disc(size=1280, radius=386, peak=1.0))
|
|
when, block, reason = dataset_build._extract((str(tmp_path), 16, 1715400000, rows))
|
|
assert reason is None
|
|
assert block is not None
|
|
|
|
|
|
def test_extract_vetoes_a_frame_with_no_disc(tmp_path):
|
|
"""all-zero pixels parse fine and would enter the shard as 'truth' unvetted."""
|
|
rows = slot_files(tmp_path, np.zeros((1280, 1280), dtype=np.float32))
|
|
when, block, reason = dataset_build._extract((str(tmp_path), 16, 1715400000, rows))
|
|
assert block is None
|
|
assert reason in ("disc_v1", "header_v1")
|
|
|
|
|
|
def test_extract_vetoes_a_bar_across_the_disc(tmp_path):
|
|
"""The real 2024 failure: a detector-row bar that header_v1 and disc_v1 pass.
|
|
|
|
Dim enough to leave IMG_MEAN inside every band's bounds, as most real bars do.
|
|
"""
|
|
from test_detectors import REFCROTA, detector_line_bar
|
|
|
|
barred = detector_line_bar(solar_disc(size=1280, radius=386, peak=1.0), offset=100.0,
|
|
value=0.5)
|
|
rows = slot_files(tmp_path, barred, refcrota=REFCROTA)
|
|
when, block, reason = dataset_build._extract((str(tmp_path), 16, 1715400000, rows))
|
|
assert block is None and reason == "field_v1"
|
|
|
|
|
|
def test_extract_vetoes_a_file_whose_header_cannot_be_read(tmp_path):
|
|
rows = slot_files(tmp_path, solar_disc(size=1280, radius=386, peak=1.0))
|
|
(tmp_path / rows[paths.WAVELENGTHS[0]]).write_bytes(b"not a fits file")
|
|
when, block, reason = dataset_build._extract((str(tmp_path), 16, 1715400000, rows))
|
|
assert block is None and reason == "header_v1"
|
|
|
|
|
|
def test_extract_drops_a_slot_missing_a_band(tmp_path):
|
|
rows = slot_files(tmp_path, solar_disc(size=1280, radius=386, peak=1.0))
|
|
del rows[paths.WAVELENGTHS[-1]]
|
|
when, block, reason = dataset_build._extract((str(tmp_path), 16, 1715400000, rows))
|
|
assert block is None and reason is None
|