FA-55826 / Astronomical coordinate conventions / Open access
Slit sky coordinate: Along-slit nod is projected onto north with a detector-axis angle convention · case 01
The adapter reports an incorrect nod north while other fields remain valid.
ROOT CAUSE
Along-slit nod is projected onto north with a detector-axis angle convention. Faulty expression: d['q']*d['s']
VERIFIED REPAIR
Preserve the declared model convention at this site: d['q']*d['c']
Unsuccessful approach: A partial convention repair still uses -d['q']*d['c']
Case contract
A spectrograph slit has supplied sine s and cosine c of position angle east of north. Sky offsets east E,north N map along slit E*s+N*c and across E*c-N*s. Slit scale a converts angle to detector pixels; spatial reference r and nod offset q are separate. Output fields are defined by: along_slit = d['E']*d['s']+d['N']*d['c']; across_slit = d['E']*d['c']-d['N']*d['s']; spatial_pixel = d['r']+(d['E']*d['s']+d['N']*d['c'])/d['a']; nodded_along = d['E']*d['s']+d['N']*d['c']-d['q']; nod_east = d['q']*d['s']; nod_north = d['q']*d['c']
Why this case matters
Catalog, detector, sky-coordinate, and spectroscopy adapters must preserve the association between numeric coordinates and their declared reference conventions.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(d):
return {'along_slit': d['E']*d['s']+d['N']*d['c'], 'across_slit': d['E']*d['c']-d['N']*d['s'], 'spatial_pixel': d['r']+(d['E']*d['s']+d['N']*d['c'])/d['a'], 'nodded_along': d['E']*d['s']+d['N']*d['c']-d['q'], 'nod_east': d['q']*d['s'], 'nod_north': d['q']*d['s']}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = {1: [({'E': 3, 'N': 5, 's': 0, 'c': 1, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': 5, 'across_slit': 3, 'spatial_pixel': 12.5, 'nodded_along': 1, 'nod_east': 0, 'nod_north': 4}), ({'E': 3, 'N': 5, 's': 1, 'c': 0, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': 3, 'across_slit': -5, 'spatial_pixel': 11.5, 'nodded_along': -1, 'nod_east': 4, 'nod_north': 0}), ({'E': 3, 'N': 5, 's': 0, 'c': -1, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': -5, 'across_slit': -3, 'spatial_pixel': 7.5, 'nodded_along': -9, 'nod_east': 0, 'nod_north': -4}), ({'E': 0, 'N': 0, 's': 0, 'c': 1, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': 0, 'across_slit': 0, 'spatial_pixel': 10.0, 'nodded_along': -4, 'nod_east': 0, 'nod_north': 4}), ({'E': 3, 'N': 5, 's': 0, 'c': 1, 'a': 2, 'r': 10, 'q': 0}, {'along_slit': 5, 'across_slit': 3, 'spatial_pixel': 12.5, 'nodded_along': 5, 'nod_east': 0, 'nod_north': 0}), ({'E': 3, 'N': 5, 's': 0, 'c': 1, 'a': -2, 'r': 0, 'q': 4}, {'along_slit': 5, 'across_slit': 3, 'spatial_pixel': -2.5, 'nodded_along': 1, 'nod_east': 0, 'nod_north': 4})], 2: [({'E': 4, 'N': 5, 's': 0, 'c': 1, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': 5, 'across_slit': 4, 'spatial_pixel': 12.5, 'nodded_along': 1, 'nod_east': 0, 'nod_north': 4}), ({'E': 4, 'N': 5, 's': 1, 'c': 0, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': 4, 'across_slit': -5, 'spatial_pixel': 12.0, 'nodded_along': 0, 'nod_east': 4, 'nod_north': 0}), ({'E': 4, 'N': 5, 's': 0, 'c': -1, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': -5, 'across_slit': -4, 'spatial_pixel': 7.5, 'nodded_along': -9, 'nod_east': 0, 'nod_north': -4}), ({'E': 1, 'N': 0, 's': 0, 'c': 1, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': 0, 'across_slit': 1, 'spatial_pixel': 10.0, 'nodded_along': -4, 'nod_east': 0, 'nod_north': 4}), ({'E': 4, 'N': 5, 's': 0, 'c': 1, 'a': 2, 'r': 10, 'q': 0}, {'along_slit': 5, 'across_slit': 4, 'spatial_pixel': 12.5, 'nodded_along': 5, 'nod_east': 0, 'nod_north': 0}), ({'E': 4, 'N': 5, 's': 0, 'c': 1, 'a': -2, 'r': 0, 'q': 4}, {'along_slit': 5, 'across_slit': 4, 'spatial_pixel': -2.5, 'nodded_along': 1, 'nod_east': 0, 'nod_north': 4})], 3: [({'E': 5, 'N': 5, 's': 0, 'c': 1, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': 5, 'across_slit': 5, 'spatial_pixel': 12.5, 'nodded_along': 1, 'nod_east': 0, 'nod_north': 4}), ({'E': 5, 'N': 5, 's': 1, 'c': 0, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': 5, 'across_slit': -5, 'spatial_pixel': 12.5, 'nodded_along': 1, 'nod_east': 4, 'nod_north': 0}), ({'E': 5, 'N': 5, 's': 0, 'c': -1, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': -5, 'across_slit': -5, 'spatial_pixel': 7.5, 'nodded_along': -9, 'nod_east': 0, 'nod_north': -4}), ({'E': 2, 'N': 0, 's': 0, 'c': 1, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': 0, 'across_slit': 2, 'spatial_pixel': 10.0, 'nodded_along': -4, 'nod_east': 0, 'nod_north': 4}), ({'E': 5, 'N': 5, 's': 0, 'c': 1, 'a': 2, 'r': 10, 'q': 0}, {'along_slit': 5, 'across_slit': 5, 'spatial_pixel': 12.5, 'nodded_along': 5, 'nod_east': 0, 'nod_north': 0}), ({'E': 5, 'N': 5, 's': 0, 'c': 1, 'a': -2, 'r': 0, 'q': 4}, {'along_slit': 5, 'across_slit': 5, 'spatial_pixel': -2.5, 'nodded_along': 1, 'nod_east': 0, 'nod_north': 4})], 4: [({'E': 6, 'N': 5, 's': 0, 'c': 1, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': 5, 'across_slit': 6, 'spatial_pixel': 12.5, 'nodded_along': 1, 'nod_east': 0, 'nod_north': 4}), ({'E': 6, 'N': 5, 's': 1, 'c': 0, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': 6, 'across_slit': -5, 'spatial_pixel': 13.0, 'nodded_along': 2, 'nod_east': 4, 'nod_north': 0}), ({'E': 6, 'N': 5, 's': 0, 'c': -1, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': -5, 'across_slit': -6, 'spatial_pixel': 7.5, 'nodded_along': -9, 'nod_east': 0, 'nod_north': -4}), ({'E': 3, 'N': 0, 's': 0, 'c': 1, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': 0, 'across_slit': 3, 'spatial_pixel': 10.0, 'nodded_along': -4, 'nod_east': 0, 'nod_north': 4}), ({'E': 6, 'N': 5, 's': 0, 'c': 1, 'a': 2, 'r': 10, 'q': 0}, {'along_slit': 5, 'across_slit': 6, 'spatial_pixel': 12.5, 'nodded_along': 5, 'nod_east': 0, 'nod_north': 0}), ({'E': 6, 'N': 5, 's': 0, 'c': 1, 'a': -2, 'r': 0, 'q': 4}, {'along_slit': 5, 'across_slit': 6, 'spatial_pixel': -2.5, 'nodded_along': 1, 'nod_east': 0, 'nod_north': 4})], 5: [({'E': 7, 'N': 5, 's': 0, 'c': 1, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': 5, 'across_slit': 7, 'spatial_pixel': 12.5, 'nodded_along': 1, 'nod_east': 0, 'nod_north': 4}), ({'E': 7, 'N': 5, 's': 1, 'c': 0, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': 7, 'across_slit': -5, 'spatial_pixel': 13.5, 'nodded_along': 3, 'nod_east': 4, 'nod_north': 0}), ({'E': 7, 'N': 5, 's': 0, 'c': -1, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': -5, 'across_slit': -7, 'spatial_pixel': 7.5, 'nodded_along': -9, 'nod_east': 0, 'nod_north': -4}), ({'E': 4, 'N': 0, 's': 0, 'c': 1, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': 0, 'across_slit': 4, 'spatial_pixel': 10.0, 'nodded_along': -4, 'nod_east': 0, 'nod_north': 4}), ({'E': 7, 'N': 5, 's': 0, 'c': 1, 'a': 2, 'r': 10, 'q': 0}, {'along_slit': 5, 'across_slit': 7, 'spatial_pixel': 12.5, 'nodded_along': 5, 'nod_east': 0, 'nod_north': 0}), ({'E': 7, 'N': 5, 's': 0, 'c': 1, 'a': -2, 'r': 0, 'q': 4}, {'along_slit': 5, 'across_slit': 7, 'spatial_pixel': -2.5, 'nodded_along': 1, 'nod_east': 0, 'nod_north': 4})]}
for i, (record, expected) in enumerate(fixtures[N]):
check('astronomical fixture %s' % i, solve(record), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| astronomical fixture 0 | {'across_slit': 3, 'along_slit': 5, 'nod_east': 0, 'nod_north': 0, 'nodded_along': 1, 'spatial_pixel': 12.5} | {'across_slit': 3, 'along_slit': 5, 'nod_east': 0, 'nod_north': 4, 'nodded_along': 1, 'spatial_pixel': 12.5} | Failed |
| astronomical fixture 1 | {'across_slit': -5, 'along_slit': 3, 'nod_east': 4, 'nod_north': 4, 'nodded_along': -1, 'spatial_pixel': 11.5} | {'across_slit': -5, 'along_slit': 3, 'nod_east': 4, 'nod_north': 0, 'nodded_along': -1, 'spatial_pixel': 11.5} | Failed |
| astronomical fixture 2 | {'across_slit': -3, 'along_slit': -5, 'nod_east': 0, 'nod_north': 0, 'nodded_along': -9, 'spatial_pixel': 7.5} | {'across_slit': -3, 'along_slit': -5, 'nod_east': 0, 'nod_north': -4, 'nodded_along': -9, 'spatial_pixel': 7.5} | Failed |
| astronomical fixture 3 | {'across_slit': 0, 'along_slit': 0, 'nod_east': 0, 'nod_north': 0, 'nodded_along': -4, 'spatial_pixel': 10.0} | {'across_slit': 0, 'along_slit': 0, 'nod_east': 0, 'nod_north': 4, 'nodded_along': -4, 'spatial_pixel': 10.0} | Failed |
| astronomical fixture 4 | {'across_slit': 3, 'along_slit': 5, 'nod_east': 0, 'nod_north': 0, 'nodded_along': 5, 'spatial_pixel': 12.5} | {'across_slit': 3, 'along_slit': 5, 'nod_east': 0, 'nod_north': 0, 'nodded_along': 5, 'spatial_pixel': 12.5} | Passed |
| astronomical fixture 5 | {'across_slit': 3, 'along_slit': 5, 'nod_east': 0, 'nod_north': 0, 'nodded_along': 1, 'spatial_pixel': -2.5} | {'across_slit': 3, 'along_slit': 5, 'nod_east': 0, 'nod_north': 4, 'nodded_along': 1, 'spatial_pixel': -2.5} | Failed |
SHA-256 / 005e241a0d5e4682be35bf5215d35613e3361e9180e7bce3d82503a72326629f
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(d):
return {'along_slit': d['E']*d['s']+d['N']*d['c'], 'across_slit': d['E']*d['c']-d['N']*d['s'], 'spatial_pixel': d['r']+(d['E']*d['s']+d['N']*d['c'])/d['a'], 'nodded_along': d['E']*d['s']+d['N']*d['c']-d['q'], 'nod_east': d['q']*d['s'], 'nod_north': -d['q']*d['c']}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = {1: [({'E': 3, 'N': 5, 's': 0, 'c': 1, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': 5, 'across_slit': 3, 'spatial_pixel': 12.5, 'nodded_along': 1, 'nod_east': 0, 'nod_north': 4}), ({'E': 3, 'N': 5, 's': 1, 'c': 0, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': 3, 'across_slit': -5, 'spatial_pixel': 11.5, 'nodded_along': -1, 'nod_east': 4, 'nod_north': 0}), ({'E': 3, 'N': 5, 's': 0, 'c': -1, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': -5, 'across_slit': -3, 'spatial_pixel': 7.5, 'nodded_along': -9, 'nod_east': 0, 'nod_north': -4}), ({'E': 0, 'N': 0, 's': 0, 'c': 1, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': 0, 'across_slit': 0, 'spatial_pixel': 10.0, 'nodded_along': -4, 'nod_east': 0, 'nod_north': 4}), ({'E': 3, 'N': 5, 's': 0, 'c': 1, 'a': 2, 'r': 10, 'q': 0}, {'along_slit': 5, 'across_slit': 3, 'spatial_pixel': 12.5, 'nodded_along': 5, 'nod_east': 0, 'nod_north': 0}), ({'E': 3, 'N': 5, 's': 0, 'c': 1, 'a': -2, 'r': 0, 'q': 4}, {'along_slit': 5, 'across_slit': 3, 'spatial_pixel': -2.5, 'nodded_along': 1, 'nod_east': 0, 'nod_north': 4})], 2: [({'E': 4, 'N': 5, 's': 0, 'c': 1, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': 5, 'across_slit': 4, 'spatial_pixel': 12.5, 'nodded_along': 1, 'nod_east': 0, 'nod_north': 4}), ({'E': 4, 'N': 5, 's': 1, 'c': 0, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': 4, 'across_slit': -5, 'spatial_pixel': 12.0, 'nodded_along': 0, 'nod_east': 4, 'nod_north': 0}), ({'E': 4, 'N': 5, 's': 0, 'c': -1, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': -5, 'across_slit': -4, 'spatial_pixel': 7.5, 'nodded_along': -9, 'nod_east': 0, 'nod_north': -4}), ({'E': 1, 'N': 0, 's': 0, 'c': 1, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': 0, 'across_slit': 1, 'spatial_pixel': 10.0, 'nodded_along': -4, 'nod_east': 0, 'nod_north': 4}), ({'E': 4, 'N': 5, 's': 0, 'c': 1, 'a': 2, 'r': 10, 'q': 0}, {'along_slit': 5, 'across_slit': 4, 'spatial_pixel': 12.5, 'nodded_along': 5, 'nod_east': 0, 'nod_north': 0}), ({'E': 4, 'N': 5, 's': 0, 'c': 1, 'a': -2, 'r': 0, 'q': 4}, {'along_slit': 5, 'across_slit': 4, 'spatial_pixel': -2.5, 'nodded_along': 1, 'nod_east': 0, 'nod_north': 4})], 3: [({'E': 5, 'N': 5, 's': 0, 'c': 1, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': 5, 'across_slit': 5, 'spatial_pixel': 12.5, 'nodded_along': 1, 'nod_east': 0, 'nod_north': 4}), ({'E': 5, 'N': 5, 's': 1, 'c': 0, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': 5, 'across_slit': -5, 'spatial_pixel': 12.5, 'nodded_along': 1, 'nod_east': 4, 'nod_north': 0}), ({'E': 5, 'N': 5, 's': 0, 'c': -1, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': -5, 'across_slit': -5, 'spatial_pixel': 7.5, 'nodded_along': -9, 'nod_east': 0, 'nod_north': -4}), ({'E': 2, 'N': 0, 's': 0, 'c': 1, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': 0, 'across_slit': 2, 'spatial_pixel': 10.0, 'nodded_along': -4, 'nod_east': 0, 'nod_north': 4}), ({'E': 5, 'N': 5, 's': 0, 'c': 1, 'a': 2, 'r': 10, 'q': 0}, {'along_slit': 5, 'across_slit': 5, 'spatial_pixel': 12.5, 'nodded_along': 5, 'nod_east': 0, 'nod_north': 0}), ({'E': 5, 'N': 5, 's': 0, 'c': 1, 'a': -2, 'r': 0, 'q': 4}, {'along_slit': 5, 'across_slit': 5, 'spatial_pixel': -2.5, 'nodded_along': 1, 'nod_east': 0, 'nod_north': 4})], 4: [({'E': 6, 'N': 5, 's': 0, 'c': 1, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': 5, 'across_slit': 6, 'spatial_pixel': 12.5, 'nodded_along': 1, 'nod_east': 0, 'nod_north': 4}), ({'E': 6, 'N': 5, 's': 1, 'c': 0, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': 6, 'across_slit': -5, 'spatial_pixel': 13.0, 'nodded_along': 2, 'nod_east': 4, 'nod_north': 0}), ({'E': 6, 'N': 5, 's': 0, 'c': -1, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': -5, 'across_slit': -6, 'spatial_pixel': 7.5, 'nodded_along': -9, 'nod_east': 0, 'nod_north': -4}), ({'E': 3, 'N': 0, 's': 0, 'c': 1, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': 0, 'across_slit': 3, 'spatial_pixel': 10.0, 'nodded_along': -4, 'nod_east': 0, 'nod_north': 4}), ({'E': 6, 'N': 5, 's': 0, 'c': 1, 'a': 2, 'r': 10, 'q': 0}, {'along_slit': 5, 'across_slit': 6, 'spatial_pixel': 12.5, 'nodded_along': 5, 'nod_east': 0, 'nod_north': 0}), ({'E': 6, 'N': 5, 's': 0, 'c': 1, 'a': -2, 'r': 0, 'q': 4}, {'along_slit': 5, 'across_slit': 6, 'spatial_pixel': -2.5, 'nodded_along': 1, 'nod_east': 0, 'nod_north': 4})], 5: [({'E': 7, 'N': 5, 's': 0, 'c': 1, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': 5, 'across_slit': 7, 'spatial_pixel': 12.5, 'nodded_along': 1, 'nod_east': 0, 'nod_north': 4}), ({'E': 7, 'N': 5, 's': 1, 'c': 0, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': 7, 'across_slit': -5, 'spatial_pixel': 13.5, 'nodded_along': 3, 'nod_east': 4, 'nod_north': 0}), ({'E': 7, 'N': 5, 's': 0, 'c': -1, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': -5, 'across_slit': -7, 'spatial_pixel': 7.5, 'nodded_along': -9, 'nod_east': 0, 'nod_north': -4}), ({'E': 4, 'N': 0, 's': 0, 'c': 1, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': 0, 'across_slit': 4, 'spatial_pixel': 10.0, 'nodded_along': -4, 'nod_east': 0, 'nod_north': 4}), ({'E': 7, 'N': 5, 's': 0, 'c': 1, 'a': 2, 'r': 10, 'q': 0}, {'along_slit': 5, 'across_slit': 7, 'spatial_pixel': 12.5, 'nodded_along': 5, 'nod_east': 0, 'nod_north': 0}), ({'E': 7, 'N': 5, 's': 0, 'c': 1, 'a': -2, 'r': 0, 'q': 4}, {'along_slit': 5, 'across_slit': 7, 'spatial_pixel': -2.5, 'nodded_along': 1, 'nod_east': 0, 'nod_north': 4})]}
for i, (record, expected) in enumerate(fixtures[N]):
check('astronomical fixture %s' % i, solve(record), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| astronomical fixture 0 | {'across_slit': 3, 'along_slit': 5, 'nod_east': 0, 'nod_north': -4, 'nodded_along': 1, 'spatial_pixel': 12.5} | {'across_slit': 3, 'along_slit': 5, 'nod_east': 0, 'nod_north': 4, 'nodded_along': 1, 'spatial_pixel': 12.5} | Failed |
| astronomical fixture 1 | {'across_slit': -5, 'along_slit': 3, 'nod_east': 4, 'nod_north': 0, 'nodded_along': -1, 'spatial_pixel': 11.5} | {'across_slit': -5, 'along_slit': 3, 'nod_east': 4, 'nod_north': 0, 'nodded_along': -1, 'spatial_pixel': 11.5} | Passed |
| astronomical fixture 2 | {'across_slit': -3, 'along_slit': -5, 'nod_east': 0, 'nod_north': 4, 'nodded_along': -9, 'spatial_pixel': 7.5} | {'across_slit': -3, 'along_slit': -5, 'nod_east': 0, 'nod_north': -4, 'nodded_along': -9, 'spatial_pixel': 7.5} | Failed |
| astronomical fixture 3 | {'across_slit': 0, 'along_slit': 0, 'nod_east': 0, 'nod_north': -4, 'nodded_along': -4, 'spatial_pixel': 10.0} | {'across_slit': 0, 'along_slit': 0, 'nod_east': 0, 'nod_north': 4, 'nodded_along': -4, 'spatial_pixel': 10.0} | Failed |
| astronomical fixture 4 | {'across_slit': 3, 'along_slit': 5, 'nod_east': 0, 'nod_north': 0, 'nodded_along': 5, 'spatial_pixel': 12.5} | {'across_slit': 3, 'along_slit': 5, 'nod_east': 0, 'nod_north': 0, 'nodded_along': 5, 'spatial_pixel': 12.5} | Passed |
| astronomical fixture 5 | {'across_slit': 3, 'along_slit': 5, 'nod_east': 0, 'nod_north': -4, 'nodded_along': 1, 'spatial_pixel': -2.5} | {'across_slit': 3, 'along_slit': 5, 'nod_east': 0, 'nod_north': 4, 'nodded_along': 1, 'spatial_pixel': -2.5} | Failed |
SHA-256 / 31e57cce1dca5a9b8dc6527ef8a0ab26c9bd9b34f10be44541bb7fb8175aaccc
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(d):
return {'along_slit': d['E']*d['s']+d['N']*d['c'], 'across_slit': d['E']*d['c']-d['N']*d['s'], 'spatial_pixel': d['r']+(d['E']*d['s']+d['N']*d['c'])/d['a'], 'nodded_along': d['E']*d['s']+d['N']*d['c']-d['q'], 'nod_east': d['q']*d['s'], 'nod_north': d['q']*d['c']}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = {1: [({'E': 3, 'N': 5, 's': 0, 'c': 1, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': 5, 'across_slit': 3, 'spatial_pixel': 12.5, 'nodded_along': 1, 'nod_east': 0, 'nod_north': 4}), ({'E': 3, 'N': 5, 's': 1, 'c': 0, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': 3, 'across_slit': -5, 'spatial_pixel': 11.5, 'nodded_along': -1, 'nod_east': 4, 'nod_north': 0}), ({'E': 3, 'N': 5, 's': 0, 'c': -1, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': -5, 'across_slit': -3, 'spatial_pixel': 7.5, 'nodded_along': -9, 'nod_east': 0, 'nod_north': -4}), ({'E': 0, 'N': 0, 's': 0, 'c': 1, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': 0, 'across_slit': 0, 'spatial_pixel': 10.0, 'nodded_along': -4, 'nod_east': 0, 'nod_north': 4}), ({'E': 3, 'N': 5, 's': 0, 'c': 1, 'a': 2, 'r': 10, 'q': 0}, {'along_slit': 5, 'across_slit': 3, 'spatial_pixel': 12.5, 'nodded_along': 5, 'nod_east': 0, 'nod_north': 0}), ({'E': 3, 'N': 5, 's': 0, 'c': 1, 'a': -2, 'r': 0, 'q': 4}, {'along_slit': 5, 'across_slit': 3, 'spatial_pixel': -2.5, 'nodded_along': 1, 'nod_east': 0, 'nod_north': 4})], 2: [({'E': 4, 'N': 5, 's': 0, 'c': 1, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': 5, 'across_slit': 4, 'spatial_pixel': 12.5, 'nodded_along': 1, 'nod_east': 0, 'nod_north': 4}), ({'E': 4, 'N': 5, 's': 1, 'c': 0, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': 4, 'across_slit': -5, 'spatial_pixel': 12.0, 'nodded_along': 0, 'nod_east': 4, 'nod_north': 0}), ({'E': 4, 'N': 5, 's': 0, 'c': -1, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': -5, 'across_slit': -4, 'spatial_pixel': 7.5, 'nodded_along': -9, 'nod_east': 0, 'nod_north': -4}), ({'E': 1, 'N': 0, 's': 0, 'c': 1, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': 0, 'across_slit': 1, 'spatial_pixel': 10.0, 'nodded_along': -4, 'nod_east': 0, 'nod_north': 4}), ({'E': 4, 'N': 5, 's': 0, 'c': 1, 'a': 2, 'r': 10, 'q': 0}, {'along_slit': 5, 'across_slit': 4, 'spatial_pixel': 12.5, 'nodded_along': 5, 'nod_east': 0, 'nod_north': 0}), ({'E': 4, 'N': 5, 's': 0, 'c': 1, 'a': -2, 'r': 0, 'q': 4}, {'along_slit': 5, 'across_slit': 4, 'spatial_pixel': -2.5, 'nodded_along': 1, 'nod_east': 0, 'nod_north': 4})], 3: [({'E': 5, 'N': 5, 's': 0, 'c': 1, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': 5, 'across_slit': 5, 'spatial_pixel': 12.5, 'nodded_along': 1, 'nod_east': 0, 'nod_north': 4}), ({'E': 5, 'N': 5, 's': 1, 'c': 0, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': 5, 'across_slit': -5, 'spatial_pixel': 12.5, 'nodded_along': 1, 'nod_east': 4, 'nod_north': 0}), ({'E': 5, 'N': 5, 's': 0, 'c': -1, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': -5, 'across_slit': -5, 'spatial_pixel': 7.5, 'nodded_along': -9, 'nod_east': 0, 'nod_north': -4}), ({'E': 2, 'N': 0, 's': 0, 'c': 1, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': 0, 'across_slit': 2, 'spatial_pixel': 10.0, 'nodded_along': -4, 'nod_east': 0, 'nod_north': 4}), ({'E': 5, 'N': 5, 's': 0, 'c': 1, 'a': 2, 'r': 10, 'q': 0}, {'along_slit': 5, 'across_slit': 5, 'spatial_pixel': 12.5, 'nodded_along': 5, 'nod_east': 0, 'nod_north': 0}), ({'E': 5, 'N': 5, 's': 0, 'c': 1, 'a': -2, 'r': 0, 'q': 4}, {'along_slit': 5, 'across_slit': 5, 'spatial_pixel': -2.5, 'nodded_along': 1, 'nod_east': 0, 'nod_north': 4})], 4: [({'E': 6, 'N': 5, 's': 0, 'c': 1, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': 5, 'across_slit': 6, 'spatial_pixel': 12.5, 'nodded_along': 1, 'nod_east': 0, 'nod_north': 4}), ({'E': 6, 'N': 5, 's': 1, 'c': 0, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': 6, 'across_slit': -5, 'spatial_pixel': 13.0, 'nodded_along': 2, 'nod_east': 4, 'nod_north': 0}), ({'E': 6, 'N': 5, 's': 0, 'c': -1, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': -5, 'across_slit': -6, 'spatial_pixel': 7.5, 'nodded_along': -9, 'nod_east': 0, 'nod_north': -4}), ({'E': 3, 'N': 0, 's': 0, 'c': 1, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': 0, 'across_slit': 3, 'spatial_pixel': 10.0, 'nodded_along': -4, 'nod_east': 0, 'nod_north': 4}), ({'E': 6, 'N': 5, 's': 0, 'c': 1, 'a': 2, 'r': 10, 'q': 0}, {'along_slit': 5, 'across_slit': 6, 'spatial_pixel': 12.5, 'nodded_along': 5, 'nod_east': 0, 'nod_north': 0}), ({'E': 6, 'N': 5, 's': 0, 'c': 1, 'a': -2, 'r': 0, 'q': 4}, {'along_slit': 5, 'across_slit': 6, 'spatial_pixel': -2.5, 'nodded_along': 1, 'nod_east': 0, 'nod_north': 4})], 5: [({'E': 7, 'N': 5, 's': 0, 'c': 1, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': 5, 'across_slit': 7, 'spatial_pixel': 12.5, 'nodded_along': 1, 'nod_east': 0, 'nod_north': 4}), ({'E': 7, 'N': 5, 's': 1, 'c': 0, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': 7, 'across_slit': -5, 'spatial_pixel': 13.5, 'nodded_along': 3, 'nod_east': 4, 'nod_north': 0}), ({'E': 7, 'N': 5, 's': 0, 'c': -1, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': -5, 'across_slit': -7, 'spatial_pixel': 7.5, 'nodded_along': -9, 'nod_east': 0, 'nod_north': -4}), ({'E': 4, 'N': 0, 's': 0, 'c': 1, 'a': 2, 'r': 10, 'q': 4}, {'along_slit': 0, 'across_slit': 4, 'spatial_pixel': 10.0, 'nodded_along': -4, 'nod_east': 0, 'nod_north': 4}), ({'E': 7, 'N': 5, 's': 0, 'c': 1, 'a': 2, 'r': 10, 'q': 0}, {'along_slit': 5, 'across_slit': 7, 'spatial_pixel': 12.5, 'nodded_along': 5, 'nod_east': 0, 'nod_north': 0}), ({'E': 7, 'N': 5, 's': 0, 'c': 1, 'a': -2, 'r': 0, 'q': 4}, {'along_slit': 5, 'across_slit': 7, 'spatial_pixel': -2.5, 'nodded_along': 1, 'nod_east': 0, 'nod_north': 4})]}
for i, (record, expected) in enumerate(fixtures[N]):
check('astronomical fixture %s' % i, solve(record), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| astronomical fixture 0 | {'across_slit': 3, 'along_slit': 5, 'nod_east': 0, 'nod_north': 4, 'nodded_along': 1, 'spatial_pixel': 12.5} | {'across_slit': 3, 'along_slit': 5, 'nod_east': 0, 'nod_north': 4, 'nodded_along': 1, 'spatial_pixel': 12.5} | Passed |
| astronomical fixture 1 | {'across_slit': -5, 'along_slit': 3, 'nod_east': 4, 'nod_north': 0, 'nodded_along': -1, 'spatial_pixel': 11.5} | {'across_slit': -5, 'along_slit': 3, 'nod_east': 4, 'nod_north': 0, 'nodded_along': -1, 'spatial_pixel': 11.5} | Passed |
| astronomical fixture 2 | {'across_slit': -3, 'along_slit': -5, 'nod_east': 0, 'nod_north': -4, 'nodded_along': -9, 'spatial_pixel': 7.5} | {'across_slit': -3, 'along_slit': -5, 'nod_east': 0, 'nod_north': -4, 'nodded_along': -9, 'spatial_pixel': 7.5} | Passed |
| astronomical fixture 3 | {'across_slit': 0, 'along_slit': 0, 'nod_east': 0, 'nod_north': 4, 'nodded_along': -4, 'spatial_pixel': 10.0} | {'across_slit': 0, 'along_slit': 0, 'nod_east': 0, 'nod_north': 4, 'nodded_along': -4, 'spatial_pixel': 10.0} | Passed |
| astronomical fixture 4 | {'across_slit': 3, 'along_slit': 5, 'nod_east': 0, 'nod_north': 0, 'nodded_along': 5, 'spatial_pixel': 12.5} | {'across_slit': 3, 'along_slit': 5, 'nod_east': 0, 'nod_north': 0, 'nodded_along': 5, 'spatial_pixel': 12.5} | Passed |
| astronomical fixture 5 | {'across_slit': 3, 'along_slit': 5, 'nod_east': 0, 'nod_north': 4, 'nodded_along': 1, 'spatial_pixel': -2.5} | {'across_slit': 3, 'along_slit': 5, 'nod_east': 0, 'nod_north': 4, 'nodded_along': 1, 'spatial_pixel': -2.5} | Passed |
SHA-256 / d0e97af665e27e06f84d4a8f17b07909d3792d196afed7cd2d23d5e5c964e895
Verification & scope
Explicitly stipulated finite algebraic adapter; no standards conformance, physical accuracy, or production-library claim. Inputs are the documented finite valid model domain. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.
Observations recorded using Python 3.12.14 at 2026-09-29T14:46:01.406135+00:00.
Case digest / 1c12d4ea7191742ccc300b43dc6efbfa0280351f7f49bc31970e75560a62ba90