FA-56231 / Astronomical coordinate conventions / Open access
Occultation shadow coordinate: Star-to-shadow coordinate reverses the moving shadow subtraction · case 01
The adapter reports an incorrect relative star while other fields remain valid.
ROOT CAUSE
Star-to-shadow coordinate reverses the moving shadow subtraction. Faulty expression: d['xs']-d['x0']+d['v']*(d['t']-d['t0'])
VERIFIED REPAIR
Preserve the declared model convention at this site: d['xs']-d['x0']-d['v']*(d['t']-d['t0'])
Unsuccessful approach: A partial convention repair still uses d['xs']-d['v']*(d['t']-d['t0'])
Case contract
A reduced occultation shadow travels with signed nonzero velocity v along x. Star coordinate xs is fixed, shadow center starts x0 at epoch t0, and positive half-chord h is supplied. Closest longitudinal crossing is t0+(xs-x0)/v; contacts are ordered using absolute transit duration. Output fields are defined by: crossing_epoch = d['t0']+(d['xs']-d['x0'])/d['v']; shadow_center = d['x0']+d['v']*(d['t']-d['t0']); relative_star = d['xs']-d['x0']-d['v']*(d['t']-d['t0']); first_contact = d['t0']+(d['xs']-d['x0'])/d['v']-abs(d['h']/d['v']); last_contact = d['t0']+(d['xs']-d['x0'])/d['v']+abs(d['h']/d['v']); duration = 2*abs(d['h']/d['v'])
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 {'crossing_epoch': d['t0']+(d['xs']-d['x0'])/d['v'], 'shadow_center': d['x0']+d['v']*(d['t']-d['t0']), 'relative_star': d['xs']-d['x0']+d['v']*(d['t']-d['t0']), 'first_contact': d['t0']+(d['xs']-d['x0'])/d['v']-abs(d['h']/d['v']), 'last_contact': d['t0']+(d['xs']-d['x0'])/d['v']+abs(d['h']/d['v']), 'duration': 2*abs(d['h']/d['v'])}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = {1: [({'xs': 20, 'x0': 4, 'v': 2, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 108.0, 'shadow_center': 14, 'relative_star': 6, 'first_contact': 105.0, 'last_contact': 111.0, 'duration': 6.0}), ({'xs': 20, 'x0': 4, 'v': -2, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 92.0, 'shadow_center': -6, 'relative_star': 26, 'first_contact': 89.0, 'last_contact': 95.0, 'duration': 6.0}), ({'xs': 20, 'x0': 4, 'v': 2, 't0': 100, 'h': 0, 't': 105}, {'crossing_epoch': 108.0, 'shadow_center': 14, 'relative_star': 6, 'first_contact': 108.0, 'last_contact': 108.0, 'duration': 0.0}), ({'xs': 4, 'x0': 4, 'v': 2, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 100.0, 'shadow_center': 14, 'relative_star': -10, 'first_contact': 97.0, 'last_contact': 103.0, 'duration': 6.0}), ({'xs': 20, 'x0': 4, 'v': 2, 't0': 100, 'h': 6, 't': 100}, {'crossing_epoch': 108.0, 'shadow_center': 4, 'relative_star': 16, 'first_contact': 105.0, 'last_contact': 111.0, 'duration': 6.0}), ({'xs': 20, 'x0': -3, 'v': 4, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 105.75, 'shadow_center': 17, 'relative_star': 3, 'first_contact': 104.25, 'last_contact': 107.25, 'duration': 3.0})], 2: [({'xs': 21, 'x0': 4, 'v': 2, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 108.5, 'shadow_center': 14, 'relative_star': 7, 'first_contact': 105.5, 'last_contact': 111.5, 'duration': 6.0}), ({'xs': 21, 'x0': 4, 'v': -2, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 91.5, 'shadow_center': -6, 'relative_star': 27, 'first_contact': 88.5, 'last_contact': 94.5, 'duration': 6.0}), ({'xs': 21, 'x0': 4, 'v': 2, 't0': 100, 'h': 0, 't': 105}, {'crossing_epoch': 108.5, 'shadow_center': 14, 'relative_star': 7, 'first_contact': 108.5, 'last_contact': 108.5, 'duration': 0.0}), ({'xs': 5, 'x0': 4, 'v': 2, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 100.5, 'shadow_center': 14, 'relative_star': -9, 'first_contact': 97.5, 'last_contact': 103.5, 'duration': 6.0}), ({'xs': 21, 'x0': 4, 'v': 2, 't0': 100, 'h': 6, 't': 100}, {'crossing_epoch': 108.5, 'shadow_center': 4, 'relative_star': 17, 'first_contact': 105.5, 'last_contact': 111.5, 'duration': 6.0}), ({'xs': 21, 'x0': -3, 'v': 4, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 106.0, 'shadow_center': 17, 'relative_star': 4, 'first_contact': 104.5, 'last_contact': 107.5, 'duration': 3.0})], 3: [({'xs': 22, 'x0': 4, 'v': 2, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 109.0, 'shadow_center': 14, 'relative_star': 8, 'first_contact': 106.0, 'last_contact': 112.0, 'duration': 6.0}), ({'xs': 22, 'x0': 4, 'v': -2, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 91.0, 'shadow_center': -6, 'relative_star': 28, 'first_contact': 88.0, 'last_contact': 94.0, 'duration': 6.0}), ({'xs': 22, 'x0': 4, 'v': 2, 't0': 100, 'h': 0, 't': 105}, {'crossing_epoch': 109.0, 'shadow_center': 14, 'relative_star': 8, 'first_contact': 109.0, 'last_contact': 109.0, 'duration': 0.0}), ({'xs': 6, 'x0': 4, 'v': 2, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 101.0, 'shadow_center': 14, 'relative_star': -8, 'first_contact': 98.0, 'last_contact': 104.0, 'duration': 6.0}), ({'xs': 22, 'x0': 4, 'v': 2, 't0': 100, 'h': 6, 't': 100}, {'crossing_epoch': 109.0, 'shadow_center': 4, 'relative_star': 18, 'first_contact': 106.0, 'last_contact': 112.0, 'duration': 6.0}), ({'xs': 22, 'x0': -3, 'v': 4, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 106.25, 'shadow_center': 17, 'relative_star': 5, 'first_contact': 104.75, 'last_contact': 107.75, 'duration': 3.0})], 4: [({'xs': 23, 'x0': 4, 'v': 2, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 109.5, 'shadow_center': 14, 'relative_star': 9, 'first_contact': 106.5, 'last_contact': 112.5, 'duration': 6.0}), ({'xs': 23, 'x0': 4, 'v': -2, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 90.5, 'shadow_center': -6, 'relative_star': 29, 'first_contact': 87.5, 'last_contact': 93.5, 'duration': 6.0}), ({'xs': 23, 'x0': 4, 'v': 2, 't0': 100, 'h': 0, 't': 105}, {'crossing_epoch': 109.5, 'shadow_center': 14, 'relative_star': 9, 'first_contact': 109.5, 'last_contact': 109.5, 'duration': 0.0}), ({'xs': 7, 'x0': 4, 'v': 2, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 101.5, 'shadow_center': 14, 'relative_star': -7, 'first_contact': 98.5, 'last_contact': 104.5, 'duration': 6.0}), ({'xs': 23, 'x0': 4, 'v': 2, 't0': 100, 'h': 6, 't': 100}, {'crossing_epoch': 109.5, 'shadow_center': 4, 'relative_star': 19, 'first_contact': 106.5, 'last_contact': 112.5, 'duration': 6.0}), ({'xs': 23, 'x0': -3, 'v': 4, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 106.5, 'shadow_center': 17, 'relative_star': 6, 'first_contact': 105.0, 'last_contact': 108.0, 'duration': 3.0})], 5: [({'xs': 24, 'x0': 4, 'v': 2, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 110.0, 'shadow_center': 14, 'relative_star': 10, 'first_contact': 107.0, 'last_contact': 113.0, 'duration': 6.0}), ({'xs': 24, 'x0': 4, 'v': -2, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 90.0, 'shadow_center': -6, 'relative_star': 30, 'first_contact': 87.0, 'last_contact': 93.0, 'duration': 6.0}), ({'xs': 24, 'x0': 4, 'v': 2, 't0': 100, 'h': 0, 't': 105}, {'crossing_epoch': 110.0, 'shadow_center': 14, 'relative_star': 10, 'first_contact': 110.0, 'last_contact': 110.0, 'duration': 0.0}), ({'xs': 8, 'x0': 4, 'v': 2, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 102.0, 'shadow_center': 14, 'relative_star': -6, 'first_contact': 99.0, 'last_contact': 105.0, 'duration': 6.0}), ({'xs': 24, 'x0': 4, 'v': 2, 't0': 100, 'h': 6, 't': 100}, {'crossing_epoch': 110.0, 'shadow_center': 4, 'relative_star': 20, 'first_contact': 107.0, 'last_contact': 113.0, 'duration': 6.0}), ({'xs': 24, 'x0': -3, 'v': 4, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 106.75, 'shadow_center': 17, 'relative_star': 7, 'first_contact': 105.25, 'last_contact': 108.25, 'duration': 3.0})]}
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 | {'crossing_epoch': 108.0, 'duration': 6.0, 'first_contact': 105.0, 'last_contact': 111.0, 'relative_star': 26, 'shadow_center': 14} | {'crossing_epoch': 108.0, 'duration': 6.0, 'first_contact': 105.0, 'last_contact': 111.0, 'relative_star': 6, 'shadow_center': 14} | Failed |
| astronomical fixture 1 | {'crossing_epoch': 92.0, 'duration': 6.0, 'first_contact': 89.0, 'last_contact': 95.0, 'relative_star': 6, 'shadow_center': -6} | {'crossing_epoch': 92.0, 'duration': 6.0, 'first_contact': 89.0, 'last_contact': 95.0, 'relative_star': 26, 'shadow_center': -6} | Failed |
| astronomical fixture 2 | {'crossing_epoch': 108.0, 'duration': 0.0, 'first_contact': 108.0, 'last_contact': 108.0, 'relative_star': 26, 'shadow_center': 14} | {'crossing_epoch': 108.0, 'duration': 0.0, 'first_contact': 108.0, 'last_contact': 108.0, 'relative_star': 6, 'shadow_center': 14} | Failed |
| astronomical fixture 3 | {'crossing_epoch': 100.0, 'duration': 6.0, 'first_contact': 97.0, 'last_contact': 103.0, 'relative_star': 10, 'shadow_center': 14} | {'crossing_epoch': 100.0, 'duration': 6.0, 'first_contact': 97.0, 'last_contact': 103.0, 'relative_star': -10, 'shadow_center': 14} | Failed |
| astronomical fixture 4 | {'crossing_epoch': 108.0, 'duration': 6.0, 'first_contact': 105.0, 'last_contact': 111.0, 'relative_star': 16, 'shadow_center': 4} | {'crossing_epoch': 108.0, 'duration': 6.0, 'first_contact': 105.0, 'last_contact': 111.0, 'relative_star': 16, 'shadow_center': 4} | Passed |
| astronomical fixture 5 | {'crossing_epoch': 105.75, 'duration': 3.0, 'first_contact': 104.25, 'last_contact': 107.25, 'relative_star': 43, 'shadow_center': 17} | {'crossing_epoch': 105.75, 'duration': 3.0, 'first_contact': 104.25, 'last_contact': 107.25, 'relative_star': 3, 'shadow_center': 17} | Failed |
SHA-256 / 22b1e9afc3b8f1cbe2fc36748704b0870e82ddf5a62c24d937273e7996ce0840
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(d):
return {'crossing_epoch': d['t0']+(d['xs']-d['x0'])/d['v'], 'shadow_center': d['x0']+d['v']*(d['t']-d['t0']), 'relative_star': d['xs']-d['v']*(d['t']-d['t0']), 'first_contact': d['t0']+(d['xs']-d['x0'])/d['v']-abs(d['h']/d['v']), 'last_contact': d['t0']+(d['xs']-d['x0'])/d['v']+abs(d['h']/d['v']), 'duration': 2*abs(d['h']/d['v'])}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = {1: [({'xs': 20, 'x0': 4, 'v': 2, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 108.0, 'shadow_center': 14, 'relative_star': 6, 'first_contact': 105.0, 'last_contact': 111.0, 'duration': 6.0}), ({'xs': 20, 'x0': 4, 'v': -2, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 92.0, 'shadow_center': -6, 'relative_star': 26, 'first_contact': 89.0, 'last_contact': 95.0, 'duration': 6.0}), ({'xs': 20, 'x0': 4, 'v': 2, 't0': 100, 'h': 0, 't': 105}, {'crossing_epoch': 108.0, 'shadow_center': 14, 'relative_star': 6, 'first_contact': 108.0, 'last_contact': 108.0, 'duration': 0.0}), ({'xs': 4, 'x0': 4, 'v': 2, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 100.0, 'shadow_center': 14, 'relative_star': -10, 'first_contact': 97.0, 'last_contact': 103.0, 'duration': 6.0}), ({'xs': 20, 'x0': 4, 'v': 2, 't0': 100, 'h': 6, 't': 100}, {'crossing_epoch': 108.0, 'shadow_center': 4, 'relative_star': 16, 'first_contact': 105.0, 'last_contact': 111.0, 'duration': 6.0}), ({'xs': 20, 'x0': -3, 'v': 4, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 105.75, 'shadow_center': 17, 'relative_star': 3, 'first_contact': 104.25, 'last_contact': 107.25, 'duration': 3.0})], 2: [({'xs': 21, 'x0': 4, 'v': 2, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 108.5, 'shadow_center': 14, 'relative_star': 7, 'first_contact': 105.5, 'last_contact': 111.5, 'duration': 6.0}), ({'xs': 21, 'x0': 4, 'v': -2, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 91.5, 'shadow_center': -6, 'relative_star': 27, 'first_contact': 88.5, 'last_contact': 94.5, 'duration': 6.0}), ({'xs': 21, 'x0': 4, 'v': 2, 't0': 100, 'h': 0, 't': 105}, {'crossing_epoch': 108.5, 'shadow_center': 14, 'relative_star': 7, 'first_contact': 108.5, 'last_contact': 108.5, 'duration': 0.0}), ({'xs': 5, 'x0': 4, 'v': 2, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 100.5, 'shadow_center': 14, 'relative_star': -9, 'first_contact': 97.5, 'last_contact': 103.5, 'duration': 6.0}), ({'xs': 21, 'x0': 4, 'v': 2, 't0': 100, 'h': 6, 't': 100}, {'crossing_epoch': 108.5, 'shadow_center': 4, 'relative_star': 17, 'first_contact': 105.5, 'last_contact': 111.5, 'duration': 6.0}), ({'xs': 21, 'x0': -3, 'v': 4, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 106.0, 'shadow_center': 17, 'relative_star': 4, 'first_contact': 104.5, 'last_contact': 107.5, 'duration': 3.0})], 3: [({'xs': 22, 'x0': 4, 'v': 2, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 109.0, 'shadow_center': 14, 'relative_star': 8, 'first_contact': 106.0, 'last_contact': 112.0, 'duration': 6.0}), ({'xs': 22, 'x0': 4, 'v': -2, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 91.0, 'shadow_center': -6, 'relative_star': 28, 'first_contact': 88.0, 'last_contact': 94.0, 'duration': 6.0}), ({'xs': 22, 'x0': 4, 'v': 2, 't0': 100, 'h': 0, 't': 105}, {'crossing_epoch': 109.0, 'shadow_center': 14, 'relative_star': 8, 'first_contact': 109.0, 'last_contact': 109.0, 'duration': 0.0}), ({'xs': 6, 'x0': 4, 'v': 2, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 101.0, 'shadow_center': 14, 'relative_star': -8, 'first_contact': 98.0, 'last_contact': 104.0, 'duration': 6.0}), ({'xs': 22, 'x0': 4, 'v': 2, 't0': 100, 'h': 6, 't': 100}, {'crossing_epoch': 109.0, 'shadow_center': 4, 'relative_star': 18, 'first_contact': 106.0, 'last_contact': 112.0, 'duration': 6.0}), ({'xs': 22, 'x0': -3, 'v': 4, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 106.25, 'shadow_center': 17, 'relative_star': 5, 'first_contact': 104.75, 'last_contact': 107.75, 'duration': 3.0})], 4: [({'xs': 23, 'x0': 4, 'v': 2, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 109.5, 'shadow_center': 14, 'relative_star': 9, 'first_contact': 106.5, 'last_contact': 112.5, 'duration': 6.0}), ({'xs': 23, 'x0': 4, 'v': -2, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 90.5, 'shadow_center': -6, 'relative_star': 29, 'first_contact': 87.5, 'last_contact': 93.5, 'duration': 6.0}), ({'xs': 23, 'x0': 4, 'v': 2, 't0': 100, 'h': 0, 't': 105}, {'crossing_epoch': 109.5, 'shadow_center': 14, 'relative_star': 9, 'first_contact': 109.5, 'last_contact': 109.5, 'duration': 0.0}), ({'xs': 7, 'x0': 4, 'v': 2, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 101.5, 'shadow_center': 14, 'relative_star': -7, 'first_contact': 98.5, 'last_contact': 104.5, 'duration': 6.0}), ({'xs': 23, 'x0': 4, 'v': 2, 't0': 100, 'h': 6, 't': 100}, {'crossing_epoch': 109.5, 'shadow_center': 4, 'relative_star': 19, 'first_contact': 106.5, 'last_contact': 112.5, 'duration': 6.0}), ({'xs': 23, 'x0': -3, 'v': 4, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 106.5, 'shadow_center': 17, 'relative_star': 6, 'first_contact': 105.0, 'last_contact': 108.0, 'duration': 3.0})], 5: [({'xs': 24, 'x0': 4, 'v': 2, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 110.0, 'shadow_center': 14, 'relative_star': 10, 'first_contact': 107.0, 'last_contact': 113.0, 'duration': 6.0}), ({'xs': 24, 'x0': 4, 'v': -2, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 90.0, 'shadow_center': -6, 'relative_star': 30, 'first_contact': 87.0, 'last_contact': 93.0, 'duration': 6.0}), ({'xs': 24, 'x0': 4, 'v': 2, 't0': 100, 'h': 0, 't': 105}, {'crossing_epoch': 110.0, 'shadow_center': 14, 'relative_star': 10, 'first_contact': 110.0, 'last_contact': 110.0, 'duration': 0.0}), ({'xs': 8, 'x0': 4, 'v': 2, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 102.0, 'shadow_center': 14, 'relative_star': -6, 'first_contact': 99.0, 'last_contact': 105.0, 'duration': 6.0}), ({'xs': 24, 'x0': 4, 'v': 2, 't0': 100, 'h': 6, 't': 100}, {'crossing_epoch': 110.0, 'shadow_center': 4, 'relative_star': 20, 'first_contact': 107.0, 'last_contact': 113.0, 'duration': 6.0}), ({'xs': 24, 'x0': -3, 'v': 4, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 106.75, 'shadow_center': 17, 'relative_star': 7, 'first_contact': 105.25, 'last_contact': 108.25, 'duration': 3.0})]}
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 | {'crossing_epoch': 108.0, 'duration': 6.0, 'first_contact': 105.0, 'last_contact': 111.0, 'relative_star': 10, 'shadow_center': 14} | {'crossing_epoch': 108.0, 'duration': 6.0, 'first_contact': 105.0, 'last_contact': 111.0, 'relative_star': 6, 'shadow_center': 14} | Failed |
| astronomical fixture 1 | {'crossing_epoch': 92.0, 'duration': 6.0, 'first_contact': 89.0, 'last_contact': 95.0, 'relative_star': 30, 'shadow_center': -6} | {'crossing_epoch': 92.0, 'duration': 6.0, 'first_contact': 89.0, 'last_contact': 95.0, 'relative_star': 26, 'shadow_center': -6} | Failed |
| astronomical fixture 2 | {'crossing_epoch': 108.0, 'duration': 0.0, 'first_contact': 108.0, 'last_contact': 108.0, 'relative_star': 10, 'shadow_center': 14} | {'crossing_epoch': 108.0, 'duration': 0.0, 'first_contact': 108.0, 'last_contact': 108.0, 'relative_star': 6, 'shadow_center': 14} | Failed |
| astronomical fixture 3 | {'crossing_epoch': 100.0, 'duration': 6.0, 'first_contact': 97.0, 'last_contact': 103.0, 'relative_star': -6, 'shadow_center': 14} | {'crossing_epoch': 100.0, 'duration': 6.0, 'first_contact': 97.0, 'last_contact': 103.0, 'relative_star': -10, 'shadow_center': 14} | Failed |
| astronomical fixture 4 | {'crossing_epoch': 108.0, 'duration': 6.0, 'first_contact': 105.0, 'last_contact': 111.0, 'relative_star': 20, 'shadow_center': 4} | {'crossing_epoch': 108.0, 'duration': 6.0, 'first_contact': 105.0, 'last_contact': 111.0, 'relative_star': 16, 'shadow_center': 4} | Failed |
| astronomical fixture 5 | {'crossing_epoch': 105.75, 'duration': 3.0, 'first_contact': 104.25, 'last_contact': 107.25, 'relative_star': 0, 'shadow_center': 17} | {'crossing_epoch': 105.75, 'duration': 3.0, 'first_contact': 104.25, 'last_contact': 107.25, 'relative_star': 3, 'shadow_center': 17} | Failed |
SHA-256 / e0f69a54643fd482632b853ca3a454c56a40d724adf00ab65be8c7a6cdc64e94
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(d):
return {'crossing_epoch': d['t0']+(d['xs']-d['x0'])/d['v'], 'shadow_center': d['x0']+d['v']*(d['t']-d['t0']), 'relative_star': d['xs']-d['x0']-d['v']*(d['t']-d['t0']), 'first_contact': d['t0']+(d['xs']-d['x0'])/d['v']-abs(d['h']/d['v']), 'last_contact': d['t0']+(d['xs']-d['x0'])/d['v']+abs(d['h']/d['v']), 'duration': 2*abs(d['h']/d['v'])}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = {1: [({'xs': 20, 'x0': 4, 'v': 2, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 108.0, 'shadow_center': 14, 'relative_star': 6, 'first_contact': 105.0, 'last_contact': 111.0, 'duration': 6.0}), ({'xs': 20, 'x0': 4, 'v': -2, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 92.0, 'shadow_center': -6, 'relative_star': 26, 'first_contact': 89.0, 'last_contact': 95.0, 'duration': 6.0}), ({'xs': 20, 'x0': 4, 'v': 2, 't0': 100, 'h': 0, 't': 105}, {'crossing_epoch': 108.0, 'shadow_center': 14, 'relative_star': 6, 'first_contact': 108.0, 'last_contact': 108.0, 'duration': 0.0}), ({'xs': 4, 'x0': 4, 'v': 2, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 100.0, 'shadow_center': 14, 'relative_star': -10, 'first_contact': 97.0, 'last_contact': 103.0, 'duration': 6.0}), ({'xs': 20, 'x0': 4, 'v': 2, 't0': 100, 'h': 6, 't': 100}, {'crossing_epoch': 108.0, 'shadow_center': 4, 'relative_star': 16, 'first_contact': 105.0, 'last_contact': 111.0, 'duration': 6.0}), ({'xs': 20, 'x0': -3, 'v': 4, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 105.75, 'shadow_center': 17, 'relative_star': 3, 'first_contact': 104.25, 'last_contact': 107.25, 'duration': 3.0})], 2: [({'xs': 21, 'x0': 4, 'v': 2, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 108.5, 'shadow_center': 14, 'relative_star': 7, 'first_contact': 105.5, 'last_contact': 111.5, 'duration': 6.0}), ({'xs': 21, 'x0': 4, 'v': -2, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 91.5, 'shadow_center': -6, 'relative_star': 27, 'first_contact': 88.5, 'last_contact': 94.5, 'duration': 6.0}), ({'xs': 21, 'x0': 4, 'v': 2, 't0': 100, 'h': 0, 't': 105}, {'crossing_epoch': 108.5, 'shadow_center': 14, 'relative_star': 7, 'first_contact': 108.5, 'last_contact': 108.5, 'duration': 0.0}), ({'xs': 5, 'x0': 4, 'v': 2, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 100.5, 'shadow_center': 14, 'relative_star': -9, 'first_contact': 97.5, 'last_contact': 103.5, 'duration': 6.0}), ({'xs': 21, 'x0': 4, 'v': 2, 't0': 100, 'h': 6, 't': 100}, {'crossing_epoch': 108.5, 'shadow_center': 4, 'relative_star': 17, 'first_contact': 105.5, 'last_contact': 111.5, 'duration': 6.0}), ({'xs': 21, 'x0': -3, 'v': 4, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 106.0, 'shadow_center': 17, 'relative_star': 4, 'first_contact': 104.5, 'last_contact': 107.5, 'duration': 3.0})], 3: [({'xs': 22, 'x0': 4, 'v': 2, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 109.0, 'shadow_center': 14, 'relative_star': 8, 'first_contact': 106.0, 'last_contact': 112.0, 'duration': 6.0}), ({'xs': 22, 'x0': 4, 'v': -2, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 91.0, 'shadow_center': -6, 'relative_star': 28, 'first_contact': 88.0, 'last_contact': 94.0, 'duration': 6.0}), ({'xs': 22, 'x0': 4, 'v': 2, 't0': 100, 'h': 0, 't': 105}, {'crossing_epoch': 109.0, 'shadow_center': 14, 'relative_star': 8, 'first_contact': 109.0, 'last_contact': 109.0, 'duration': 0.0}), ({'xs': 6, 'x0': 4, 'v': 2, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 101.0, 'shadow_center': 14, 'relative_star': -8, 'first_contact': 98.0, 'last_contact': 104.0, 'duration': 6.0}), ({'xs': 22, 'x0': 4, 'v': 2, 't0': 100, 'h': 6, 't': 100}, {'crossing_epoch': 109.0, 'shadow_center': 4, 'relative_star': 18, 'first_contact': 106.0, 'last_contact': 112.0, 'duration': 6.0}), ({'xs': 22, 'x0': -3, 'v': 4, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 106.25, 'shadow_center': 17, 'relative_star': 5, 'first_contact': 104.75, 'last_contact': 107.75, 'duration': 3.0})], 4: [({'xs': 23, 'x0': 4, 'v': 2, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 109.5, 'shadow_center': 14, 'relative_star': 9, 'first_contact': 106.5, 'last_contact': 112.5, 'duration': 6.0}), ({'xs': 23, 'x0': 4, 'v': -2, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 90.5, 'shadow_center': -6, 'relative_star': 29, 'first_contact': 87.5, 'last_contact': 93.5, 'duration': 6.0}), ({'xs': 23, 'x0': 4, 'v': 2, 't0': 100, 'h': 0, 't': 105}, {'crossing_epoch': 109.5, 'shadow_center': 14, 'relative_star': 9, 'first_contact': 109.5, 'last_contact': 109.5, 'duration': 0.0}), ({'xs': 7, 'x0': 4, 'v': 2, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 101.5, 'shadow_center': 14, 'relative_star': -7, 'first_contact': 98.5, 'last_contact': 104.5, 'duration': 6.0}), ({'xs': 23, 'x0': 4, 'v': 2, 't0': 100, 'h': 6, 't': 100}, {'crossing_epoch': 109.5, 'shadow_center': 4, 'relative_star': 19, 'first_contact': 106.5, 'last_contact': 112.5, 'duration': 6.0}), ({'xs': 23, 'x0': -3, 'v': 4, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 106.5, 'shadow_center': 17, 'relative_star': 6, 'first_contact': 105.0, 'last_contact': 108.0, 'duration': 3.0})], 5: [({'xs': 24, 'x0': 4, 'v': 2, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 110.0, 'shadow_center': 14, 'relative_star': 10, 'first_contact': 107.0, 'last_contact': 113.0, 'duration': 6.0}), ({'xs': 24, 'x0': 4, 'v': -2, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 90.0, 'shadow_center': -6, 'relative_star': 30, 'first_contact': 87.0, 'last_contact': 93.0, 'duration': 6.0}), ({'xs': 24, 'x0': 4, 'v': 2, 't0': 100, 'h': 0, 't': 105}, {'crossing_epoch': 110.0, 'shadow_center': 14, 'relative_star': 10, 'first_contact': 110.0, 'last_contact': 110.0, 'duration': 0.0}), ({'xs': 8, 'x0': 4, 'v': 2, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 102.0, 'shadow_center': 14, 'relative_star': -6, 'first_contact': 99.0, 'last_contact': 105.0, 'duration': 6.0}), ({'xs': 24, 'x0': 4, 'v': 2, 't0': 100, 'h': 6, 't': 100}, {'crossing_epoch': 110.0, 'shadow_center': 4, 'relative_star': 20, 'first_contact': 107.0, 'last_contact': 113.0, 'duration': 6.0}), ({'xs': 24, 'x0': -3, 'v': 4, 't0': 100, 'h': 6, 't': 105}, {'crossing_epoch': 106.75, 'shadow_center': 17, 'relative_star': 7, 'first_contact': 105.25, 'last_contact': 108.25, 'duration': 3.0})]}
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 | {'crossing_epoch': 108.0, 'duration': 6.0, 'first_contact': 105.0, 'last_contact': 111.0, 'relative_star': 6, 'shadow_center': 14} | {'crossing_epoch': 108.0, 'duration': 6.0, 'first_contact': 105.0, 'last_contact': 111.0, 'relative_star': 6, 'shadow_center': 14} | Passed |
| astronomical fixture 1 | {'crossing_epoch': 92.0, 'duration': 6.0, 'first_contact': 89.0, 'last_contact': 95.0, 'relative_star': 26, 'shadow_center': -6} | {'crossing_epoch': 92.0, 'duration': 6.0, 'first_contact': 89.0, 'last_contact': 95.0, 'relative_star': 26, 'shadow_center': -6} | Passed |
| astronomical fixture 2 | {'crossing_epoch': 108.0, 'duration': 0.0, 'first_contact': 108.0, 'last_contact': 108.0, 'relative_star': 6, 'shadow_center': 14} | {'crossing_epoch': 108.0, 'duration': 0.0, 'first_contact': 108.0, 'last_contact': 108.0, 'relative_star': 6, 'shadow_center': 14} | Passed |
| astronomical fixture 3 | {'crossing_epoch': 100.0, 'duration': 6.0, 'first_contact': 97.0, 'last_contact': 103.0, 'relative_star': -10, 'shadow_center': 14} | {'crossing_epoch': 100.0, 'duration': 6.0, 'first_contact': 97.0, 'last_contact': 103.0, 'relative_star': -10, 'shadow_center': 14} | Passed |
| astronomical fixture 4 | {'crossing_epoch': 108.0, 'duration': 6.0, 'first_contact': 105.0, 'last_contact': 111.0, 'relative_star': 16, 'shadow_center': 4} | {'crossing_epoch': 108.0, 'duration': 6.0, 'first_contact': 105.0, 'last_contact': 111.0, 'relative_star': 16, 'shadow_center': 4} | Passed |
| astronomical fixture 5 | {'crossing_epoch': 105.75, 'duration': 3.0, 'first_contact': 104.25, 'last_contact': 107.25, 'relative_star': 3, 'shadow_center': 17} | {'crossing_epoch': 105.75, 'duration': 3.0, 'first_contact': 104.25, 'last_contact': 107.25, 'relative_star': 3, 'shadow_center': 17} | Passed |
SHA-256 / b985e0faeb375f1eef36508f20ae1b4c1647b5a2ef056c8d39c6c96b2494ffb8
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:05.177897+00:00.
Case digest / 856c515bb6f89d41b7053b5ea9fd08bcb0e2811fd1e1eb2bca99b83ddead4bf3