broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(data):
    origin,scroll,point,records,window = data
    x,y = point[0]-origin[0]+scroll[0],point[1]-origin[1]+scroll[1]
    hits = []
    for index,(ident,owner,rect,z,exposed,transparent,clip,proxy,enabled) in enumerate(records):
        if owner != window or not exposed or transparent: continue
        x0,y0,x1,y1 = rect
        if not (x0 <= x < x1 and y0 <= y < y1): continue
        if clip is not None and not (clip[0] <= x < clip[2] and clip[1] <= y < clip[3]): continue
        hits.append((z,-index,proxy if proxy else ident))
    if not hits: return None
    return [max(hits,key=lambda hit:(-hit[0],hit[1]))[2],[x,y]]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('contract fixture 1', solve([[N,10],[N+1,3],[N+1,11],[['a','w',[0,0,8,8],1,True,False,None,'',True]],'w'],), ['a',[N+2,4]])
check('contract fixture 2', solve([[0,0],[0,0],[1,1],[['back','w',[0,0,4,4],1,True,False,None,'',True],['front','w',[0,0,4,4],5,True,False,None,'proxy',False]],'w'],), ['proxy',[1,1]])
check('contract fixture 3', solve([[0,0],[0,0],[1,1],[['first','w',[0,0,4,4],2,True,False,None,'',True],['second','w',[0,0,4,4],2,True,False,None,'',True]],'w'],), ['first',[1,1]])
check('contract fixture 4', solve([[0,0],[0,0],[1,1],[['a','other',[0,0,4,4],1,True,False,None,'',True],['b','w',[0,0,4,4],2,False,False,None,'',True],['c','w',[0,0,4,4],3,True,True,None,'',True]],'w'],), None)
check('contract fixture 5', solve([[0,0],[0,0],[4,1],[['a','w',[0,0,4,4],1,True,False,None,'',True]],'w'],), None)
check('contract fixture 6', solve([[0,0],[0,0],[2,2],[['a','w',[0,0,4,4],1,True,False,[0,0,2,2],'',True]],'w'],), None)
check('contract fixture 7', solve([[0,0],[0,0],[0,0],[['a','w',[0,0,4,4],1,True,False,None,'',True]],'w'],), ['a',[0,0]])
check('contract fixture 8', solve([[0,0],[0,0],[1,1],[],'w'],), None)
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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(data):
    origin,scroll,point,records,window = data
    x,y = point[0]-origin[0]+scroll[0],point[1]-origin[1]+scroll[1]
    hits = []
    for index,(ident,owner,rect,z,exposed,transparent,clip,proxy,enabled) in enumerate(records):
        if owner != window or not exposed or transparent: continue
        x0,y0,x1,y1 = rect
        if not (x0 <= x < x1 and y0 <= y < y1): continue
        if clip is not None and not (clip[0] <= x < clip[2] and clip[1] <= y < clip[3]): continue
        hits.append((z,-index,proxy if proxy else ident))
    if not hits: return None
    return [max(hits,key=lambda hit:hit[1])[2],[x,y]]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('contract fixture 1', solve([[N,10],[N+1,3],[N+1,11],[['a','w',[0,0,8,8],1,True,False,None,'',True]],'w'],), ['a',[N+2,4]])
check('contract fixture 2', solve([[0,0],[0,0],[1,1],[['back','w',[0,0,4,4],1,True,False,None,'',True],['front','w',[0,0,4,4],5,True,False,None,'proxy',False]],'w'],), ['proxy',[1,1]])
check('contract fixture 3', solve([[0,0],[0,0],[1,1],[['first','w',[0,0,4,4],2,True,False,None,'',True],['second','w',[0,0,4,4],2,True,False,None,'',True]],'w'],), ['first',[1,1]])
check('contract fixture 4', solve([[0,0],[0,0],[1,1],[['a','other',[0,0,4,4],1,True,False,None,'',True],['b','w',[0,0,4,4],2,False,False,None,'',True],['c','w',[0,0,4,4],3,True,True,None,'',True]],'w'],), None)
check('contract fixture 5', solve([[0,0],[0,0],[4,1],[['a','w',[0,0,4,4],1,True,False,None,'',True]],'w'],), None)
check('contract fixture 6', solve([[0,0],[0,0],[2,2],[['a','w',[0,0,4,4],1,True,False,[0,0,2,2],'',True]],'w'],), None)
check('contract fixture 7', solve([[0,0],[0,0],[0,0],[['a','w',[0,0,4,4],1,True,False,None,'',True]],'w'],), ['a',[0,0]])
check('contract fixture 8', solve([[0,0],[0,0],[1,1],[],'w'],), None)
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)

prompt:
Semantic hit testing selects background objects before foreground objects.

Input [window_origin,scroll,point,records,expected_window]. Pointer is screen coordinates. Convert to document coordinates by subtracting window_origin and adding scroll. Records [id,window,rect,z,exposed,transparent,clip,proxy,enabled]; rect and optional clip are [x0,y0,x1,y1], half-open. Zero/reversed rectangles never hit. Reject other windows or unexposed records. Transparent records do not themselves hit. Reject points outside clip. Among hits largest z wins, ties retain first input. Disabled semantics remain inspectable. Return proxy ID when nonempty, else own ID, plus [document_x,document_y]. None when no hit. This is semantic hit selection, not pixel rendering or focus navigation.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(data):
    origin,scroll,point,records,window = data
    x,y = point[0]-origin[0]+scroll[0],point[1]-origin[1]+scroll[1]
    hits = []
    for index,(ident,owner,rect,z,exposed,transparent,clip,proxy,enabled) in enumerate(records):
        if owner != window or not exposed or transparent: continue
        x0,y0,x1,y1 = rect
        if not (x0 <= x < x1 and y0 <= y < y1): continue
        if clip is not None and not (clip[0] <= x < clip[2] and clip[1] <= y < clip[3]): continue
        hits.append((z,index,proxy if proxy else ident))
    if not hits: return None
    return [max(hits,key=lambda hit:(hit[0],hit[1]))[2],[x,y]]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('contract fixture 1', solve([[N,10],[N+1,3],[N+1,11],[['a','w',[0,0,8,8],1,True,False,None,'',True]],'w'],), ['a',[N+2,4]])
check('contract fixture 2', solve([[0,0],[0,0],[1,1],[['back','w',[0,0,4,4],1,True,False,None,'',True],['front','w',[0,0,4,4],5,True,False,None,'proxy',False]],'w'],), ['proxy',[1,1]])
check('contract fixture 3', solve([[0,0],[0,0],[1,1],[['first','w',[0,0,4,4],2,True,False,None,'',True],['second','w',[0,0,4,4],2,True,False,None,'',True]],'w'],), ['first',[1,1]])
check('contract fixture 4', solve([[0,0],[0,0],[1,1],[['a','other',[0,0,4,4],1,True,False,None,'',True],['b','w',[0,0,4,4],2,False,False,None,'',True],['c','w',[0,0,4,4],3,True,True,None,'',True]],'w'],), None)
check('contract fixture 5', solve([[0,0],[0,0],[4,1],[['a','w',[0,0,4,4],1,True,False,None,'',True]],'w'],), None)
check('contract fixture 6', solve([[0,0],[0,0],[2,2],[['a','w',[0,0,4,4],1,True,False,[0,0,2,2],'',True]],'w'],), None)
check('contract fixture 7', solve([[0,0],[0,0],[0,0],[['a','w',[0,0,4,4],1,True,False,None,'',True]],'w'],), ['a',[0,0]])
check('contract fixture 8', solve([[0,0],[0,0],[1,1],[],'w'],), None)
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)

meaning: Fixture-count band, not measured model difficulty

deps: stdlib

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(data):
    origin,scroll,point,records,window = data
    x,y = point[0]-origin[0]+scroll[0],point[1]-origin[1]+scroll[1]
    hits = []
    for index,(ident,owner,rect,z,exposed,transparent,clip,proxy,enabled) in enumerate(records):
        if owner != window or not exposed or transparent: continue
        x0,y0,x1,y1 = rect
        if not (x0 <= x < x1 and y0 <= y < y1): continue
        if clip is not None and not (clip[0] <= x < clip[2] and clip[1] <= y < clip[3]): continue
        hits.append((z,index+1,proxy if proxy else ident))
    if not hits: return None
    return [max(hits,key=lambda hit:(hit[0],hit[1]))[2],[x,y]]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('contract fixture 1', solve([[N,10],[N+1,3],[N+1,11],[['a','w',[0,0,8,8],1,True,False,None,'',True]],'w'],), ['a',[N+2,4]])
check('contract fixture 2', solve([[0,0],[0,0],[1,1],[['back','w',[0,0,4,4],1,True,False,None,'',True],['front','w',[0,0,4,4],5,True,False,None,'proxy',False]],'w'],), ['proxy',[1,1]])
check('contract fixture 3', solve([[0,0],[0,0],[1,1],[['first','w',[0,0,4,4],2,True,False,None,'',True],['second','w',[0,0,4,4],2,True,False,None,'',True]],'w'],), ['first',[1,1]])
check('contract fixture 4', solve([[0,0],[0,0],[1,1],[['a','other',[0,0,4,4],1,True,False,None,'',True],['b','w',[0,0,4,4],2,False,False,None,'',True],['c','w',[0,0,4,4],3,True,True,None,'',True]],'w'],), None)
check('contract fixture 5', solve([[0,0],[0,0],[4,1],[['a','w',[0,0,4,4],1,True,False,None,'',True]],'w'],), None)
check('contract fixture 6', solve([[0,0],[0,0],[2,2],[['a','w',[0,0,4,4],1,True,False,[0,0,2,2],'',True]],'w'],), None)
check('contract fixture 7', solve([[0,0],[0,0],[0,0],[['a','w',[0,0,4,4],1,True,False,None,'',True]],'w'],), ['a',[0,0]])
check('contract fixture 8', solve([[0,0],[0,0],[1,1],[],'w'],), None)
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)

prompt:
Equal-stack semantic objects reverse native encounter precedence.

Input [window_origin,scroll,point,records,expected_window]. Pointer is screen coordinates. Convert to document coordinates by subtracting window_origin and adding scroll. Records [id,window,rect,z,exposed,transparent,clip,proxy,enabled]; rect and optional clip are [x0,y0,x1,y1], half-open. Zero/reversed rectangles never hit. Reject other windows or unexposed records. Transparent records do not themselves hit. Reject points outside clip. Among hits largest z wins, ties retain first input. Disabled semantics remain inspectable. Return proxy ID when nonempty, else own ID, plus [document_x,document_y]. None when no hit. This is semantic hit selection, not pixel rendering or focus navigation.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(data):
    origin,scroll,point,records,window = data
    x,y = point[0]-origin[0]+scroll[0],point[1]-origin[1]+scroll[1]
    hits = []
    for index,(ident,owner,rect,z,exposed,transparent,clip,proxy,enabled) in enumerate(records):
        if owner != window or not exposed or transparent: continue
        x0,y0,x1,y1 = rect
        if not (x0 <= x < x1 and y0 <= y < y1): continue
        if clip is not None and not (clip[0] <= x < clip[2] and clip[1] <= y < clip[3]): continue
        hits.append((z,-index,ident))
    if not hits: return None
    return [max(hits,key=lambda hit:(hit[0],hit[1]))[2],[x,y]]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('contract fixture 1', solve([[N,10],[N+1,3],[N+1,11],[['a','w',[0,0,8,8],1,True,False,None,'',True]],'w'],), ['a',[N+2,4]])
check('contract fixture 2', solve([[0,0],[0,0],[1,1],[['back','w',[0,0,4,4],1,True,False,None,'',True],['front','w',[0,0,4,4],5,True,False,None,'proxy',False]],'w'],), ['proxy',[1,1]])
check('contract fixture 3', solve([[0,0],[0,0],[1,1],[['first','w',[0,0,4,4],2,True,False,None,'',True],['second','w',[0,0,4,4],2,True,False,None,'',True]],'w'],), ['first',[1,1]])
check('contract fixture 4', solve([[0,0],[0,0],[1,1],[['a','other',[0,0,4,4],1,True,False,None,'',True],['b','w',[0,0,4,4],2,False,False,None,'',True],['c','w',[0,0,4,4],3,True,True,None,'',True]],'w'],), None)
check('contract fixture 5', solve([[0,0],[0,0],[4,1],[['a','w',[0,0,4,4],1,True,False,None,'',True]],'w'],), None)
check('contract fixture 6', solve([[0,0],[0,0],[2,2],[['a','w',[0,0,4,4],1,True,False,[0,0,2,2],'',True]],'w'],), None)
check('contract fixture 7', solve([[0,0],[0,0],[0,0],[['a','w',[0,0,4,4],1,True,False,None,'',True]],'w'],), ['a',[0,0]])
check('contract fixture 8', solve([[0,0],[0,0],[1,1],[],'w'],), None)
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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(data):
    origin,scroll,point,records,window = data
    x,y = point[0]-origin[0]+scroll[0],point[1]-origin[1]+scroll[1]
    hits = []
    for index,(ident,owner,rect,z,exposed,transparent,clip,proxy,enabled) in enumerate(records):
        if owner != window or not exposed or transparent: continue
        x0,y0,x1,y1 = rect
        if not (x0 <= x < x1 and y0 <= y < y1): continue
        if clip is not None and not (clip[0] <= x < clip[2] and clip[1] <= y < clip[3]): continue
        hits.append((z,-index,proxy if proxy and enabled else ident))
    if not hits: return None
    return [max(hits,key=lambda hit:(hit[0],hit[1]))[2],[x,y]]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('contract fixture 1', solve([[N,10],[N+1,3],[N+1,11],[['a','w',[0,0,8,8],1,True,False,None,'',True]],'w'],), ['a',[N+2,4]])
check('contract fixture 2', solve([[0,0],[0,0],[1,1],[['back','w',[0,0,4,4],1,True,False,None,'',True],['front','w',[0,0,4,4],5,True,False,None,'proxy',False]],'w'],), ['proxy',[1,1]])
check('contract fixture 3', solve([[0,0],[0,0],[1,1],[['first','w',[0,0,4,4],2,True,False,None,'',True],['second','w',[0,0,4,4],2,True,False,None,'',True]],'w'],), ['first',[1,1]])
check('contract fixture 4', solve([[0,0],[0,0],[1,1],[['a','other',[0,0,4,4],1,True,False,None,'',True],['b','w',[0,0,4,4],2,False,False,None,'',True],['c','w',[0,0,4,4],3,True,True,None,'',True]],'w'],), None)
check('contract fixture 5', solve([[0,0],[0,0],[4,1],[['a','w',[0,0,4,4],1,True,False,None,'',True]],'w'],), None)
check('contract fixture 6', solve([[0,0],[0,0],[2,2],[['a','w',[0,0,4,4],1,True,False,[0,0,2,2],'',True]],'w'],), None)
check('contract fixture 7', solve([[0,0],[0,0],[0,0],[['a','w',[0,0,4,4],1,True,False,None,'',True]],'w'],), ['a',[0,0]])
check('contract fixture 8', solve([[0,0],[0,0],[1,1],[],'w'],), None)
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)

prompt:
Semantic hit results return anonymous native records instead of semantic proxies.

Input [window_origin,scroll,point,records,expected_window]. Pointer is screen coordinates. Convert to document coordinates by subtracting window_origin and adding scroll. Records [id,window,rect,z,exposed,transparent,clip,proxy,enabled]; rect and optional clip are [x0,y0,x1,y1], half-open. Zero/reversed rectangles never hit. Reject other windows or unexposed records. Transparent records do not themselves hit. Reject points outside clip. Among hits largest z wins, ties retain first input. Disabled semantics remain inspectable. Return proxy ID when nonempty, else own ID, plus [document_x,document_y]. None when no hit. This is semantic hit selection, not pixel rendering or focus navigation.

split: open-access


evaluation_group: astro-detector-cutout-reference

prompt:
The adapter reports an incorrect crpix x while other fields remain valid.

A one-based FITS-like detector cutout has zero-based start sx,sy, explicit halo hx,hy, and unchanged plate scale. CRPIX belongs to the padded cutout; valid bounds exclude halo. Data section uses inclusive pixel endpoints. Output fields are defined by: crpix_x = d['rx']-d['sx']+d['hx']; crpix_y = d['ry']-d['sy']+d['hy']; science_first_x = d['hx']+1; science_last_x = d['hx']+d['w']; parent_first_y = d['sy']+1; parent_last_y = d['sy']+d['h']

split: open-access


evaluation_group: astro-detector-cutout-reference

prompt:
The adapter reports an incorrect crpix y while other fields remain valid.

A one-based FITS-like detector cutout has zero-based start sx,sy, explicit halo hx,hy, and unchanged plate scale. CRPIX belongs to the padded cutout; valid bounds exclude halo. Data section uses inclusive pixel endpoints. Output fields are defined by: crpix_x = d['rx']-d['sx']+d['hx']; crpix_y = d['ry']-d['sy']+d['hy']; science_first_x = d['hx']+1; science_last_x = d['hx']+d['w']; parent_first_y = d['sy']+1; parent_last_y = d['sy']+d['h']

split: open-access


evaluation_group: astro-detector-cutout-reference

prompt:
The adapter reports an incorrect science first x while other fields remain valid.

A one-based FITS-like detector cutout has zero-based start sx,sy, explicit halo hx,hy, and unchanged plate scale. CRPIX belongs to the padded cutout; valid bounds exclude halo. Data section uses inclusive pixel endpoints. Output fields are defined by: crpix_x = d['rx']-d['sx']+d['hx']; crpix_y = d['ry']-d['sy']+d['hy']; science_first_x = d['hx']+1; science_last_x = d['hx']+d['w']; parent_first_y = d['sy']+1; parent_last_y = d['sy']+d['h']

split: open-access


evaluation_group: astro-detector-cutout-reference

prompt:
The adapter reports an incorrect science last x while other fields remain valid.

A one-based FITS-like detector cutout has zero-based start sx,sy, explicit halo hx,hy, and unchanged plate scale. CRPIX belongs to the padded cutout; valid bounds exclude halo. Data section uses inclusive pixel endpoints. Output fields are defined by: crpix_x = d['rx']-d['sx']+d['hx']; crpix_y = d['ry']-d['sy']+d['hy']; science_first_x = d['hx']+1; science_last_x = d['hx']+d['w']; parent_first_y = d['sy']+1; parent_last_y = d['sy']+d['h']

split: open-access


evaluation_group: astro-detector-cutout-reference

prompt:
The adapter reports an incorrect parent first y while other fields remain valid.

A one-based FITS-like detector cutout has zero-based start sx,sy, explicit halo hx,hy, and unchanged plate scale. CRPIX belongs to the padded cutout; valid bounds exclude halo. Data section uses inclusive pixel endpoints. Output fields are defined by: crpix_x = d['rx']-d['sx']+d['hx']; crpix_y = d['ry']-d['sy']+d['hy']; science_first_x = d['hx']+1; science_last_x = d['hx']+d['w']; parent_first_y = d['sy']+1; parent_last_y = d['sy']+d['h']

split: open-access


evaluation_group: astro-detector-cutout-reference

prompt:
The adapter reports an incorrect parent last y while other fields remain valid.

A one-based FITS-like detector cutout has zero-based start sx,sy, explicit halo hx,hy, and unchanged plate scale. CRPIX belongs to the padded cutout; valid bounds exclude halo. Data section uses inclusive pixel endpoints. Output fields are defined by: crpix_x = d['rx']-d['sx']+d['hx']; crpix_y = d['ry']-d['sy']+d['hy']; science_first_x = d['hx']+1; science_last_x = d['hx']+d['w']; parent_first_y = d['sy']+1; parent_last_y = d['sy']+d['h']

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(d):
    return {'reference_x': (d['rx']-d['sx'])/d['bx'], 'reference_y': (d['ry']-d['sy']-(d['by']+1)/2)/d['by']+1, 'plate_scale': d['scale']*d['bx'], 'spectral_step': d['disp']*d['by'], 'footprint_pixels': d['bx']*d['by'], 'last_center_x': d['sx']+(d['bx']+1)/2+(d['nx']-1)*d['bx']}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = {1: [({'rx': 13, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 5.75, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 13, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 1, 'by': 1, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 11.0, 'reference_y': 18.0, 'plate_scale': 3, 'spectral_step': 5, 'footprint_pixels': 1, 'last_center_x': 14.0}), ({'rx': 13, 'ry': 21, 'sx': 0, 'sy': 0, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 6.75, 'reference_y': 5.625, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 23.5}), ({'rx': 13, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 3, 'by': 2, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 4.0, 'reference_y': 9.25, 'plate_scale': 9, 'spectral_step': 10, 'footprint_pixels': 6, 'last_center_x': 37.0}), ({'rx': 13, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': -2, 'disp': -3, 'nx': 12, 'ny': 16}, {'reference_x': 5.75, 'reference_y': 4.875, 'plate_scale': -4, 'spectral_step': -12, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 13, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 1, 'ny': 1}, {'reference_x': 5.75, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 3.5})], 2: [({'rx': 14, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 6.25, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 14, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 1, 'by': 1, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 12.0, 'reference_y': 18.0, 'plate_scale': 3, 'spectral_step': 5, 'footprint_pixels': 1, 'last_center_x': 14.0}), ({'rx': 14, 'ry': 21, 'sx': 0, 'sy': 0, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 7.25, 'reference_y': 5.625, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 23.5}), ({'rx': 14, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 3, 'by': 2, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 4.333333333333334, 'reference_y': 9.25, 'plate_scale': 9, 'spectral_step': 10, 'footprint_pixels': 6, 'last_center_x': 37.0}), ({'rx': 14, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': -2, 'disp': -3, 'nx': 12, 'ny': 16}, {'reference_x': 6.25, 'reference_y': 4.875, 'plate_scale': -4, 'spectral_step': -12, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 14, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 1, 'ny': 1}, {'reference_x': 6.25, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 3.5})], 3: [({'rx': 15, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 6.75, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 15, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 1, 'by': 1, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 13.0, 'reference_y': 18.0, 'plate_scale': 3, 'spectral_step': 5, 'footprint_pixels': 1, 'last_center_x': 14.0}), ({'rx': 15, 'ry': 21, 'sx': 0, 'sy': 0, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 7.75, 'reference_y': 5.625, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 23.5}), ({'rx': 15, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 3, 'by': 2, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 4.666666666666666, 'reference_y': 9.25, 'plate_scale': 9, 'spectral_step': 10, 'footprint_pixels': 6, 'last_center_x': 37.0}), ({'rx': 15, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': -2, 'disp': -3, 'nx': 12, 'ny': 16}, {'reference_x': 6.75, 'reference_y': 4.875, 'plate_scale': -4, 'spectral_step': -12, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 15, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 1, 'ny': 1}, {'reference_x': 6.75, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 3.5})], 4: [({'rx': 16, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 7.25, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 16, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 1, 'by': 1, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 14.0, 'reference_y': 18.0, 'plate_scale': 3, 'spectral_step': 5, 'footprint_pixels': 1, 'last_center_x': 14.0}), ({'rx': 16, 'ry': 21, 'sx': 0, 'sy': 0, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 8.25, 'reference_y': 5.625, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 23.5}), ({'rx': 16, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 3, 'by': 2, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 5.0, 'reference_y': 9.25, 'plate_scale': 9, 'spectral_step': 10, 'footprint_pixels': 6, 'last_center_x': 37.0}), ({'rx': 16, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': -2, 'disp': -3, 'nx': 12, 'ny': 16}, {'reference_x': 7.25, 'reference_y': 4.875, 'plate_scale': -4, 'spectral_step': -12, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 16, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 1, 'ny': 1}, {'reference_x': 7.25, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 3.5})], 5: [({'rx': 17, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 7.75, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 17, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 1, 'by': 1, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 15.0, 'reference_y': 18.0, 'plate_scale': 3, 'spectral_step': 5, 'footprint_pixels': 1, 'last_center_x': 14.0}), ({'rx': 17, 'ry': 21, 'sx': 0, 'sy': 0, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 8.75, 'reference_y': 5.625, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 23.5}), ({'rx': 17, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 3, 'by': 2, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 5.333333333333333, 'reference_y': 9.25, 'plate_scale': 9, 'spectral_step': 10, 'footprint_pixels': 6, 'last_center_x': 37.0}), ({'rx': 17, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': -2, 'disp': -3, 'nx': 12, 'ny': 16}, {'reference_x': 7.75, 'reference_y': 4.875, 'plate_scale': -4, 'spectral_step': -12, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 17, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 1, 'ny': 1}, {'reference_x': 7.75, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 3.5})]}
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)

evaluation_group: astro-binned-detector-centers

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(d):
    return {'reference_x': (d['rx']-d['sx']-1)/d['bx']+1, 'reference_y': (d['ry']-d['sy']-(d['by']+1)/2)/d['by']+1, 'plate_scale': d['scale']*d['bx'], 'spectral_step': d['disp']*d['by'], 'footprint_pixels': d['bx']*d['by'], 'last_center_x': d['sx']+(d['bx']+1)/2+(d['nx']-1)*d['bx']}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = {1: [({'rx': 13, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 5.75, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 13, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 1, 'by': 1, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 11.0, 'reference_y': 18.0, 'plate_scale': 3, 'spectral_step': 5, 'footprint_pixels': 1, 'last_center_x': 14.0}), ({'rx': 13, 'ry': 21, 'sx': 0, 'sy': 0, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 6.75, 'reference_y': 5.625, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 23.5}), ({'rx': 13, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 3, 'by': 2, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 4.0, 'reference_y': 9.25, 'plate_scale': 9, 'spectral_step': 10, 'footprint_pixels': 6, 'last_center_x': 37.0}), ({'rx': 13, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': -2, 'disp': -3, 'nx': 12, 'ny': 16}, {'reference_x': 5.75, 'reference_y': 4.875, 'plate_scale': -4, 'spectral_step': -12, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 13, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 1, 'ny': 1}, {'reference_x': 5.75, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 3.5})], 2: [({'rx': 14, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 6.25, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 14, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 1, 'by': 1, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 12.0, 'reference_y': 18.0, 'plate_scale': 3, 'spectral_step': 5, 'footprint_pixels': 1, 'last_center_x': 14.0}), ({'rx': 14, 'ry': 21, 'sx': 0, 'sy': 0, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 7.25, 'reference_y': 5.625, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 23.5}), ({'rx': 14, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 3, 'by': 2, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 4.333333333333334, 'reference_y': 9.25, 'plate_scale': 9, 'spectral_step': 10, 'footprint_pixels': 6, 'last_center_x': 37.0}), ({'rx': 14, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': -2, 'disp': -3, 'nx': 12, 'ny': 16}, {'reference_x': 6.25, 'reference_y': 4.875, 'plate_scale': -4, 'spectral_step': -12, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 14, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 1, 'ny': 1}, {'reference_x': 6.25, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 3.5})], 3: [({'rx': 15, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 6.75, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 15, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 1, 'by': 1, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 13.0, 'reference_y': 18.0, 'plate_scale': 3, 'spectral_step': 5, 'footprint_pixels': 1, 'last_center_x': 14.0}), ({'rx': 15, 'ry': 21, 'sx': 0, 'sy': 0, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 7.75, 'reference_y': 5.625, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 23.5}), ({'rx': 15, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 3, 'by': 2, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 4.666666666666666, 'reference_y': 9.25, 'plate_scale': 9, 'spectral_step': 10, 'footprint_pixels': 6, 'last_center_x': 37.0}), ({'rx': 15, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': -2, 'disp': -3, 'nx': 12, 'ny': 16}, {'reference_x': 6.75, 'reference_y': 4.875, 'plate_scale': -4, 'spectral_step': -12, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 15, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 1, 'ny': 1}, {'reference_x': 6.75, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 3.5})], 4: [({'rx': 16, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 7.25, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 16, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 1, 'by': 1, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 14.0, 'reference_y': 18.0, 'plate_scale': 3, 'spectral_step': 5, 'footprint_pixels': 1, 'last_center_x': 14.0}), ({'rx': 16, 'ry': 21, 'sx': 0, 'sy': 0, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 8.25, 'reference_y': 5.625, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 23.5}), ({'rx': 16, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 3, 'by': 2, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 5.0, 'reference_y': 9.25, 'plate_scale': 9, 'spectral_step': 10, 'footprint_pixels': 6, 'last_center_x': 37.0}), ({'rx': 16, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': -2, 'disp': -3, 'nx': 12, 'ny': 16}, {'reference_x': 7.25, 'reference_y': 4.875, 'plate_scale': -4, 'spectral_step': -12, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 16, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 1, 'ny': 1}, {'reference_x': 7.25, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 3.5})], 5: [({'rx': 17, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 7.75, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 17, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 1, 'by': 1, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 15.0, 'reference_y': 18.0, 'plate_scale': 3, 'spectral_step': 5, 'footprint_pixels': 1, 'last_center_x': 14.0}), ({'rx': 17, 'ry': 21, 'sx': 0, 'sy': 0, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 8.75, 'reference_y': 5.625, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 23.5}), ({'rx': 17, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 3, 'by': 2, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 5.333333333333333, 'reference_y': 9.25, 'plate_scale': 9, 'spectral_step': 10, 'footprint_pixels': 6, 'last_center_x': 37.0}), ({'rx': 17, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': -2, 'disp': -3, 'nx': 12, 'ny': 16}, {'reference_x': 7.75, 'reference_y': 4.875, 'plate_scale': -4, 'spectral_step': -12, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 17, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 1, 'ny': 1}, {'reference_x': 7.75, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 3.5})]}
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)

prompt:
The adapter reports an incorrect reference x while other fields remain valid.

Pixel centers are one-based. A bin of bx by by starts at zero-based crop sx,sy. Its first center is start+(bin+1)/2. The supplied dispersion and plate scales are per unbinned pixel; bin integral weights count physical contributing pixels. Output fields are defined by: reference_x = (d['rx']-d['sx']-(d['bx']+1)/2)/d['bx']+1; reference_y = (d['ry']-d['sy']-(d['by']+1)/2)/d['by']+1; plate_scale = d['scale']*d['bx']; spectral_step = d['disp']*d['by']; footprint_pixels = d['bx']*d['by']; last_center_x = d['sx']+(d['bx']+1)/2+(d['nx']-1)*d['bx']

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(d):
    return {'reference_x': (d['rx']-d['sx']-(d['bx']+1)/2)/d['bx']+1, 'reference_y': (d['ry']-d['sy']-(d['bx']+1)/2)/d['by']+1, 'plate_scale': d['scale']*d['bx'], 'spectral_step': d['disp']*d['by'], 'footprint_pixels': d['bx']*d['by'], 'last_center_x': d['sx']+(d['bx']+1)/2+(d['nx']-1)*d['bx']}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = {1: [({'rx': 13, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 5.75, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 13, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 1, 'by': 1, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 11.0, 'reference_y': 18.0, 'plate_scale': 3, 'spectral_step': 5, 'footprint_pixels': 1, 'last_center_x': 14.0}), ({'rx': 13, 'ry': 21, 'sx': 0, 'sy': 0, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 6.75, 'reference_y': 5.625, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 23.5}), ({'rx': 13, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 3, 'by': 2, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 4.0, 'reference_y': 9.25, 'plate_scale': 9, 'spectral_step': 10, 'footprint_pixels': 6, 'last_center_x': 37.0}), ({'rx': 13, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': -2, 'disp': -3, 'nx': 12, 'ny': 16}, {'reference_x': 5.75, 'reference_y': 4.875, 'plate_scale': -4, 'spectral_step': -12, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 13, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 1, 'ny': 1}, {'reference_x': 5.75, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 3.5})], 2: [({'rx': 14, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 6.25, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 14, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 1, 'by': 1, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 12.0, 'reference_y': 18.0, 'plate_scale': 3, 'spectral_step': 5, 'footprint_pixels': 1, 'last_center_x': 14.0}), ({'rx': 14, 'ry': 21, 'sx': 0, 'sy': 0, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 7.25, 'reference_y': 5.625, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 23.5}), ({'rx': 14, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 3, 'by': 2, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 4.333333333333334, 'reference_y': 9.25, 'plate_scale': 9, 'spectral_step': 10, 'footprint_pixels': 6, 'last_center_x': 37.0}), ({'rx': 14, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': -2, 'disp': -3, 'nx': 12, 'ny': 16}, {'reference_x': 6.25, 'reference_y': 4.875, 'plate_scale': -4, 'spectral_step': -12, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 14, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 1, 'ny': 1}, {'reference_x': 6.25, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 3.5})], 3: [({'rx': 15, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 6.75, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 15, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 1, 'by': 1, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 13.0, 'reference_y': 18.0, 'plate_scale': 3, 'spectral_step': 5, 'footprint_pixels': 1, 'last_center_x': 14.0}), ({'rx': 15, 'ry': 21, 'sx': 0, 'sy': 0, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 7.75, 'reference_y': 5.625, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 23.5}), ({'rx': 15, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 3, 'by': 2, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 4.666666666666666, 'reference_y': 9.25, 'plate_scale': 9, 'spectral_step': 10, 'footprint_pixels': 6, 'last_center_x': 37.0}), ({'rx': 15, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': -2, 'disp': -3, 'nx': 12, 'ny': 16}, {'reference_x': 6.75, 'reference_y': 4.875, 'plate_scale': -4, 'spectral_step': -12, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 15, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 1, 'ny': 1}, {'reference_x': 6.75, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 3.5})], 4: [({'rx': 16, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 7.25, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 16, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 1, 'by': 1, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 14.0, 'reference_y': 18.0, 'plate_scale': 3, 'spectral_step': 5, 'footprint_pixels': 1, 'last_center_x': 14.0}), ({'rx': 16, 'ry': 21, 'sx': 0, 'sy': 0, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 8.25, 'reference_y': 5.625, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 23.5}), ({'rx': 16, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 3, 'by': 2, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 5.0, 'reference_y': 9.25, 'plate_scale': 9, 'spectral_step': 10, 'footprint_pixels': 6, 'last_center_x': 37.0}), ({'rx': 16, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': -2, 'disp': -3, 'nx': 12, 'ny': 16}, {'reference_x': 7.25, 'reference_y': 4.875, 'plate_scale': -4, 'spectral_step': -12, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 16, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 1, 'ny': 1}, {'reference_x': 7.25, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 3.5})], 5: [({'rx': 17, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 7.75, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 17, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 1, 'by': 1, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 15.0, 'reference_y': 18.0, 'plate_scale': 3, 'spectral_step': 5, 'footprint_pixels': 1, 'last_center_x': 14.0}), ({'rx': 17, 'ry': 21, 'sx': 0, 'sy': 0, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 8.75, 'reference_y': 5.625, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 23.5}), ({'rx': 17, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 3, 'by': 2, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 5.333333333333333, 'reference_y': 9.25, 'plate_scale': 9, 'spectral_step': 10, 'footprint_pixels': 6, 'last_center_x': 37.0}), ({'rx': 17, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': -2, 'disp': -3, 'nx': 12, 'ny': 16}, {'reference_x': 7.75, 'reference_y': 4.875, 'plate_scale': -4, 'spectral_step': -12, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 17, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 1, 'ny': 1}, {'reference_x': 7.75, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 3.5})]}
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)

evaluation_group: astro-binned-detector-centers

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(d):
    return {'reference_x': (d['rx']-d['sx']-(d['bx']+1)/2)/d['bx']+1, 'reference_y': (d['ry']-d['sy']-(d['by']+1)/2)/d['bx']+1, 'plate_scale': d['scale']*d['bx'], 'spectral_step': d['disp']*d['by'], 'footprint_pixels': d['bx']*d['by'], 'last_center_x': d['sx']+(d['bx']+1)/2+(d['nx']-1)*d['bx']}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = {1: [({'rx': 13, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 5.75, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 13, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 1, 'by': 1, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 11.0, 'reference_y': 18.0, 'plate_scale': 3, 'spectral_step': 5, 'footprint_pixels': 1, 'last_center_x': 14.0}), ({'rx': 13, 'ry': 21, 'sx': 0, 'sy': 0, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 6.75, 'reference_y': 5.625, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 23.5}), ({'rx': 13, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 3, 'by': 2, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 4.0, 'reference_y': 9.25, 'plate_scale': 9, 'spectral_step': 10, 'footprint_pixels': 6, 'last_center_x': 37.0}), ({'rx': 13, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': -2, 'disp': -3, 'nx': 12, 'ny': 16}, {'reference_x': 5.75, 'reference_y': 4.875, 'plate_scale': -4, 'spectral_step': -12, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 13, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 1, 'ny': 1}, {'reference_x': 5.75, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 3.5})], 2: [({'rx': 14, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 6.25, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 14, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 1, 'by': 1, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 12.0, 'reference_y': 18.0, 'plate_scale': 3, 'spectral_step': 5, 'footprint_pixels': 1, 'last_center_x': 14.0}), ({'rx': 14, 'ry': 21, 'sx': 0, 'sy': 0, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 7.25, 'reference_y': 5.625, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 23.5}), ({'rx': 14, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 3, 'by': 2, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 4.333333333333334, 'reference_y': 9.25, 'plate_scale': 9, 'spectral_step': 10, 'footprint_pixels': 6, 'last_center_x': 37.0}), ({'rx': 14, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': -2, 'disp': -3, 'nx': 12, 'ny': 16}, {'reference_x': 6.25, 'reference_y': 4.875, 'plate_scale': -4, 'spectral_step': -12, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 14, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 1, 'ny': 1}, {'reference_x': 6.25, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 3.5})], 3: [({'rx': 15, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 6.75, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 15, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 1, 'by': 1, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 13.0, 'reference_y': 18.0, 'plate_scale': 3, 'spectral_step': 5, 'footprint_pixels': 1, 'last_center_x': 14.0}), ({'rx': 15, 'ry': 21, 'sx': 0, 'sy': 0, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 7.75, 'reference_y': 5.625, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 23.5}), ({'rx': 15, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 3, 'by': 2, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 4.666666666666666, 'reference_y': 9.25, 'plate_scale': 9, 'spectral_step': 10, 'footprint_pixels': 6, 'last_center_x': 37.0}), ({'rx': 15, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': -2, 'disp': -3, 'nx': 12, 'ny': 16}, {'reference_x': 6.75, 'reference_y': 4.875, 'plate_scale': -4, 'spectral_step': -12, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 15, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 1, 'ny': 1}, {'reference_x': 6.75, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 3.5})], 4: [({'rx': 16, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 7.25, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 16, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 1, 'by': 1, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 14.0, 'reference_y': 18.0, 'plate_scale': 3, 'spectral_step': 5, 'footprint_pixels': 1, 'last_center_x': 14.0}), ({'rx': 16, 'ry': 21, 'sx': 0, 'sy': 0, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 8.25, 'reference_y': 5.625, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 23.5}), ({'rx': 16, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 3, 'by': 2, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 5.0, 'reference_y': 9.25, 'plate_scale': 9, 'spectral_step': 10, 'footprint_pixels': 6, 'last_center_x': 37.0}), ({'rx': 16, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': -2, 'disp': -3, 'nx': 12, 'ny': 16}, {'reference_x': 7.25, 'reference_y': 4.875, 'plate_scale': -4, 'spectral_step': -12, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 16, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 1, 'ny': 1}, {'reference_x': 7.25, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 3.5})], 5: [({'rx': 17, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 7.75, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 17, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 1, 'by': 1, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 15.0, 'reference_y': 18.0, 'plate_scale': 3, 'spectral_step': 5, 'footprint_pixels': 1, 'last_center_x': 14.0}), ({'rx': 17, 'ry': 21, 'sx': 0, 'sy': 0, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 8.75, 'reference_y': 5.625, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 23.5}), ({'rx': 17, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 3, 'by': 2, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 5.333333333333333, 'reference_y': 9.25, 'plate_scale': 9, 'spectral_step': 10, 'footprint_pixels': 6, 'last_center_x': 37.0}), ({'rx': 17, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': -2, 'disp': -3, 'nx': 12, 'ny': 16}, {'reference_x': 7.75, 'reference_y': 4.875, 'plate_scale': -4, 'spectral_step': -12, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 17, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 1, 'ny': 1}, {'reference_x': 7.75, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 3.5})]}
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)

prompt:
The adapter reports an incorrect reference y while other fields remain valid.

Pixel centers are one-based. A bin of bx by by starts at zero-based crop sx,sy. Its first center is start+(bin+1)/2. The supplied dispersion and plate scales are per unbinned pixel; bin integral weights count physical contributing pixels. Output fields are defined by: reference_x = (d['rx']-d['sx']-(d['bx']+1)/2)/d['bx']+1; reference_y = (d['ry']-d['sy']-(d['by']+1)/2)/d['by']+1; plate_scale = d['scale']*d['bx']; spectral_step = d['disp']*d['by']; footprint_pixels = d['bx']*d['by']; last_center_x = d['sx']+(d['bx']+1)/2+(d['nx']-1)*d['bx']

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(d):
    return {'reference_x': (d['rx']-d['sx']-(d['bx']+1)/2)/d['bx']+1, 'reference_y': (d['ry']-d['sy']-(d['by']+1)/2)/d['by']+1, 'plate_scale': d['scale']/d['bx'], 'spectral_step': d['disp']*d['by'], 'footprint_pixels': d['bx']*d['by'], 'last_center_x': d['sx']+(d['bx']+1)/2+(d['nx']-1)*d['bx']}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = {1: [({'rx': 13, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 5.75, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 13, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 1, 'by': 1, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 11.0, 'reference_y': 18.0, 'plate_scale': 3, 'spectral_step': 5, 'footprint_pixels': 1, 'last_center_x': 14.0}), ({'rx': 13, 'ry': 21, 'sx': 0, 'sy': 0, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 6.75, 'reference_y': 5.625, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 23.5}), ({'rx': 13, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 3, 'by': 2, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 4.0, 'reference_y': 9.25, 'plate_scale': 9, 'spectral_step': 10, 'footprint_pixels': 6, 'last_center_x': 37.0}), ({'rx': 13, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': -2, 'disp': -3, 'nx': 12, 'ny': 16}, {'reference_x': 5.75, 'reference_y': 4.875, 'plate_scale': -4, 'spectral_step': -12, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 13, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 1, 'ny': 1}, {'reference_x': 5.75, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 3.5})], 2: [({'rx': 14, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 6.25, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 14, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 1, 'by': 1, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 12.0, 'reference_y': 18.0, 'plate_scale': 3, 'spectral_step': 5, 'footprint_pixels': 1, 'last_center_x': 14.0}), ({'rx': 14, 'ry': 21, 'sx': 0, 'sy': 0, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 7.25, 'reference_y': 5.625, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 23.5}), ({'rx': 14, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 3, 'by': 2, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 4.333333333333334, 'reference_y': 9.25, 'plate_scale': 9, 'spectral_step': 10, 'footprint_pixels': 6, 'last_center_x': 37.0}), ({'rx': 14, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': -2, 'disp': -3, 'nx': 12, 'ny': 16}, {'reference_x': 6.25, 'reference_y': 4.875, 'plate_scale': -4, 'spectral_step': -12, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 14, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 1, 'ny': 1}, {'reference_x': 6.25, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 3.5})], 3: [({'rx': 15, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 6.75, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 15, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 1, 'by': 1, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 13.0, 'reference_y': 18.0, 'plate_scale': 3, 'spectral_step': 5, 'footprint_pixels': 1, 'last_center_x': 14.0}), ({'rx': 15, 'ry': 21, 'sx': 0, 'sy': 0, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 7.75, 'reference_y': 5.625, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 23.5}), ({'rx': 15, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 3, 'by': 2, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 4.666666666666666, 'reference_y': 9.25, 'plate_scale': 9, 'spectral_step': 10, 'footprint_pixels': 6, 'last_center_x': 37.0}), ({'rx': 15, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': -2, 'disp': -3, 'nx': 12, 'ny': 16}, {'reference_x': 6.75, 'reference_y': 4.875, 'plate_scale': -4, 'spectral_step': -12, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 15, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 1, 'ny': 1}, {'reference_x': 6.75, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 3.5})], 4: [({'rx': 16, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 7.25, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 16, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 1, 'by': 1, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 14.0, 'reference_y': 18.0, 'plate_scale': 3, 'spectral_step': 5, 'footprint_pixels': 1, 'last_center_x': 14.0}), ({'rx': 16, 'ry': 21, 'sx': 0, 'sy': 0, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 8.25, 'reference_y': 5.625, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 23.5}), ({'rx': 16, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 3, 'by': 2, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 5.0, 'reference_y': 9.25, 'plate_scale': 9, 'spectral_step': 10, 'footprint_pixels': 6, 'last_center_x': 37.0}), ({'rx': 16, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': -2, 'disp': -3, 'nx': 12, 'ny': 16}, {'reference_x': 7.25, 'reference_y': 4.875, 'plate_scale': -4, 'spectral_step': -12, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 16, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 1, 'ny': 1}, {'reference_x': 7.25, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 3.5})], 5: [({'rx': 17, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 7.75, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 17, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 1, 'by': 1, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 15.0, 'reference_y': 18.0, 'plate_scale': 3, 'spectral_step': 5, 'footprint_pixels': 1, 'last_center_x': 14.0}), ({'rx': 17, 'ry': 21, 'sx': 0, 'sy': 0, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 8.75, 'reference_y': 5.625, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 23.5}), ({'rx': 17, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 3, 'by': 2, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 5.333333333333333, 'reference_y': 9.25, 'plate_scale': 9, 'spectral_step': 10, 'footprint_pixels': 6, 'last_center_x': 37.0}), ({'rx': 17, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': -2, 'disp': -3, 'nx': 12, 'ny': 16}, {'reference_x': 7.75, 'reference_y': 4.875, 'plate_scale': -4, 'spectral_step': -12, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 17, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 1, 'ny': 1}, {'reference_x': 7.75, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 3.5})]}
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)

evaluation_group: astro-binned-detector-centers

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(d):
    return {'reference_x': (d['rx']-d['sx']-(d['bx']+1)/2)/d['bx']+1, 'reference_y': (d['ry']-d['sy']-(d['by']+1)/2)/d['by']+1, 'plate_scale': d['scale'], 'spectral_step': d['disp']*d['by'], 'footprint_pixels': d['bx']*d['by'], 'last_center_x': d['sx']+(d['bx']+1)/2+(d['nx']-1)*d['bx']}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = {1: [({'rx': 13, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 5.75, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 13, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 1, 'by': 1, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 11.0, 'reference_y': 18.0, 'plate_scale': 3, 'spectral_step': 5, 'footprint_pixels': 1, 'last_center_x': 14.0}), ({'rx': 13, 'ry': 21, 'sx': 0, 'sy': 0, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 6.75, 'reference_y': 5.625, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 23.5}), ({'rx': 13, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 3, 'by': 2, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 4.0, 'reference_y': 9.25, 'plate_scale': 9, 'spectral_step': 10, 'footprint_pixels': 6, 'last_center_x': 37.0}), ({'rx': 13, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': -2, 'disp': -3, 'nx': 12, 'ny': 16}, {'reference_x': 5.75, 'reference_y': 4.875, 'plate_scale': -4, 'spectral_step': -12, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 13, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 1, 'ny': 1}, {'reference_x': 5.75, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 3.5})], 2: [({'rx': 14, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 6.25, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 14, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 1, 'by': 1, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 12.0, 'reference_y': 18.0, 'plate_scale': 3, 'spectral_step': 5, 'footprint_pixels': 1, 'last_center_x': 14.0}), ({'rx': 14, 'ry': 21, 'sx': 0, 'sy': 0, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 7.25, 'reference_y': 5.625, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 23.5}), ({'rx': 14, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 3, 'by': 2, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 4.333333333333334, 'reference_y': 9.25, 'plate_scale': 9, 'spectral_step': 10, 'footprint_pixels': 6, 'last_center_x': 37.0}), ({'rx': 14, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': -2, 'disp': -3, 'nx': 12, 'ny': 16}, {'reference_x': 6.25, 'reference_y': 4.875, 'plate_scale': -4, 'spectral_step': -12, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 14, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 1, 'ny': 1}, {'reference_x': 6.25, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 3.5})], 3: [({'rx': 15, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 6.75, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 15, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 1, 'by': 1, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 13.0, 'reference_y': 18.0, 'plate_scale': 3, 'spectral_step': 5, 'footprint_pixels': 1, 'last_center_x': 14.0}), ({'rx': 15, 'ry': 21, 'sx': 0, 'sy': 0, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 7.75, 'reference_y': 5.625, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 23.5}), ({'rx': 15, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 3, 'by': 2, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 4.666666666666666, 'reference_y': 9.25, 'plate_scale': 9, 'spectral_step': 10, 'footprint_pixels': 6, 'last_center_x': 37.0}), ({'rx': 15, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': -2, 'disp': -3, 'nx': 12, 'ny': 16}, {'reference_x': 6.75, 'reference_y': 4.875, 'plate_scale': -4, 'spectral_step': -12, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 15, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 1, 'ny': 1}, {'reference_x': 6.75, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 3.5})], 4: [({'rx': 16, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 7.25, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 16, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 1, 'by': 1, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 14.0, 'reference_y': 18.0, 'plate_scale': 3, 'spectral_step': 5, 'footprint_pixels': 1, 'last_center_x': 14.0}), ({'rx': 16, 'ry': 21, 'sx': 0, 'sy': 0, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 8.25, 'reference_y': 5.625, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 23.5}), ({'rx': 16, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 3, 'by': 2, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 5.0, 'reference_y': 9.25, 'plate_scale': 9, 'spectral_step': 10, 'footprint_pixels': 6, 'last_center_x': 37.0}), ({'rx': 16, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': -2, 'disp': -3, 'nx': 12, 'ny': 16}, {'reference_x': 7.25, 'reference_y': 4.875, 'plate_scale': -4, 'spectral_step': -12, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 16, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 1, 'ny': 1}, {'reference_x': 7.25, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 3.5})], 5: [({'rx': 17, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 7.75, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 17, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 1, 'by': 1, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 15.0, 'reference_y': 18.0, 'plate_scale': 3, 'spectral_step': 5, 'footprint_pixels': 1, 'last_center_x': 14.0}), ({'rx': 17, 'ry': 21, 'sx': 0, 'sy': 0, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 8.75, 'reference_y': 5.625, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 23.5}), ({'rx': 17, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 3, 'by': 2, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 5.333333333333333, 'reference_y': 9.25, 'plate_scale': 9, 'spectral_step': 10, 'footprint_pixels': 6, 'last_center_x': 37.0}), ({'rx': 17, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': -2, 'disp': -3, 'nx': 12, 'ny': 16}, {'reference_x': 7.75, 'reference_y': 4.875, 'plate_scale': -4, 'spectral_step': -12, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 17, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 1, 'ny': 1}, {'reference_x': 7.75, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 3.5})]}
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)

prompt:
The adapter reports an incorrect plate scale while other fields remain valid.

Pixel centers are one-based. A bin of bx by by starts at zero-based crop sx,sy. Its first center is start+(bin+1)/2. The supplied dispersion and plate scales are per unbinned pixel; bin integral weights count physical contributing pixels. Output fields are defined by: reference_x = (d['rx']-d['sx']-(d['bx']+1)/2)/d['bx']+1; reference_y = (d['ry']-d['sy']-(d['by']+1)/2)/d['by']+1; plate_scale = d['scale']*d['bx']; spectral_step = d['disp']*d['by']; footprint_pixels = d['bx']*d['by']; last_center_x = d['sx']+(d['bx']+1)/2+(d['nx']-1)*d['bx']

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(d):
    return {'reference_x': (d['rx']-d['sx']-(d['bx']+1)/2)/d['bx']+1, 'reference_y': (d['ry']-d['sy']-(d['by']+1)/2)/d['by']+1, 'plate_scale': d['scale']*d['bx'], 'spectral_step': d['disp']*d['bx'], 'footprint_pixels': d['bx']*d['by'], 'last_center_x': d['sx']+(d['bx']+1)/2+(d['nx']-1)*d['bx']}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = {1: [({'rx': 13, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 5.75, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 13, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 1, 'by': 1, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 11.0, 'reference_y': 18.0, 'plate_scale': 3, 'spectral_step': 5, 'footprint_pixels': 1, 'last_center_x': 14.0}), ({'rx': 13, 'ry': 21, 'sx': 0, 'sy': 0, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 6.75, 'reference_y': 5.625, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 23.5}), ({'rx': 13, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 3, 'by': 2, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 4.0, 'reference_y': 9.25, 'plate_scale': 9, 'spectral_step': 10, 'footprint_pixels': 6, 'last_center_x': 37.0}), ({'rx': 13, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': -2, 'disp': -3, 'nx': 12, 'ny': 16}, {'reference_x': 5.75, 'reference_y': 4.875, 'plate_scale': -4, 'spectral_step': -12, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 13, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 1, 'ny': 1}, {'reference_x': 5.75, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 3.5})], 2: [({'rx': 14, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 6.25, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 14, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 1, 'by': 1, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 12.0, 'reference_y': 18.0, 'plate_scale': 3, 'spectral_step': 5, 'footprint_pixels': 1, 'last_center_x': 14.0}), ({'rx': 14, 'ry': 21, 'sx': 0, 'sy': 0, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 7.25, 'reference_y': 5.625, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 23.5}), ({'rx': 14, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 3, 'by': 2, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 4.333333333333334, 'reference_y': 9.25, 'plate_scale': 9, 'spectral_step': 10, 'footprint_pixels': 6, 'last_center_x': 37.0}), ({'rx': 14, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': -2, 'disp': -3, 'nx': 12, 'ny': 16}, {'reference_x': 6.25, 'reference_y': 4.875, 'plate_scale': -4, 'spectral_step': -12, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 14, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 1, 'ny': 1}, {'reference_x': 6.25, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 3.5})], 3: [({'rx': 15, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 6.75, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 15, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 1, 'by': 1, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 13.0, 'reference_y': 18.0, 'plate_scale': 3, 'spectral_step': 5, 'footprint_pixels': 1, 'last_center_x': 14.0}), ({'rx': 15, 'ry': 21, 'sx': 0, 'sy': 0, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 7.75, 'reference_y': 5.625, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 23.5}), ({'rx': 15, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 3, 'by': 2, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 4.666666666666666, 'reference_y': 9.25, 'plate_scale': 9, 'spectral_step': 10, 'footprint_pixels': 6, 'last_center_x': 37.0}), ({'rx': 15, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': -2, 'disp': -3, 'nx': 12, 'ny': 16}, {'reference_x': 6.75, 'reference_y': 4.875, 'plate_scale': -4, 'spectral_step': -12, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 15, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 1, 'ny': 1}, {'reference_x': 6.75, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 3.5})], 4: [({'rx': 16, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 7.25, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 16, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 1, 'by': 1, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 14.0, 'reference_y': 18.0, 'plate_scale': 3, 'spectral_step': 5, 'footprint_pixels': 1, 'last_center_x': 14.0}), ({'rx': 16, 'ry': 21, 'sx': 0, 'sy': 0, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 8.25, 'reference_y': 5.625, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 23.5}), ({'rx': 16, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 3, 'by': 2, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 5.0, 'reference_y': 9.25, 'plate_scale': 9, 'spectral_step': 10, 'footprint_pixels': 6, 'last_center_x': 37.0}), ({'rx': 16, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': -2, 'disp': -3, 'nx': 12, 'ny': 16}, {'reference_x': 7.25, 'reference_y': 4.875, 'plate_scale': -4, 'spectral_step': -12, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 16, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 1, 'ny': 1}, {'reference_x': 7.25, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 3.5})], 5: [({'rx': 17, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 7.75, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 17, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 1, 'by': 1, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 15.0, 'reference_y': 18.0, 'plate_scale': 3, 'spectral_step': 5, 'footprint_pixels': 1, 'last_center_x': 14.0}), ({'rx': 17, 'ry': 21, 'sx': 0, 'sy': 0, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 8.75, 'reference_y': 5.625, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 23.5}), ({'rx': 17, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 3, 'by': 2, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 5.333333333333333, 'reference_y': 9.25, 'plate_scale': 9, 'spectral_step': 10, 'footprint_pixels': 6, 'last_center_x': 37.0}), ({'rx': 17, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': -2, 'disp': -3, 'nx': 12, 'ny': 16}, {'reference_x': 7.75, 'reference_y': 4.875, 'plate_scale': -4, 'spectral_step': -12, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 17, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 1, 'ny': 1}, {'reference_x': 7.75, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 3.5})]}
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)

evaluation_group: astro-binned-detector-centers

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(d):
    return {'reference_x': (d['rx']-d['sx']-(d['bx']+1)/2)/d['bx']+1, 'reference_y': (d['ry']-d['sy']-(d['by']+1)/2)/d['by']+1, 'plate_scale': d['scale']*d['bx'], 'spectral_step': d['disp']/d['by'], 'footprint_pixels': d['bx']*d['by'], 'last_center_x': d['sx']+(d['bx']+1)/2+(d['nx']-1)*d['bx']}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = {1: [({'rx': 13, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 5.75, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 13, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 1, 'by': 1, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 11.0, 'reference_y': 18.0, 'plate_scale': 3, 'spectral_step': 5, 'footprint_pixels': 1, 'last_center_x': 14.0}), ({'rx': 13, 'ry': 21, 'sx': 0, 'sy': 0, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 6.75, 'reference_y': 5.625, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 23.5}), ({'rx': 13, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 3, 'by': 2, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 4.0, 'reference_y': 9.25, 'plate_scale': 9, 'spectral_step': 10, 'footprint_pixels': 6, 'last_center_x': 37.0}), ({'rx': 13, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': -2, 'disp': -3, 'nx': 12, 'ny': 16}, {'reference_x': 5.75, 'reference_y': 4.875, 'plate_scale': -4, 'spectral_step': -12, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 13, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 1, 'ny': 1}, {'reference_x': 5.75, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 3.5})], 2: [({'rx': 14, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 6.25, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 14, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 1, 'by': 1, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 12.0, 'reference_y': 18.0, 'plate_scale': 3, 'spectral_step': 5, 'footprint_pixels': 1, 'last_center_x': 14.0}), ({'rx': 14, 'ry': 21, 'sx': 0, 'sy': 0, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 7.25, 'reference_y': 5.625, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 23.5}), ({'rx': 14, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 3, 'by': 2, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 4.333333333333334, 'reference_y': 9.25, 'plate_scale': 9, 'spectral_step': 10, 'footprint_pixels': 6, 'last_center_x': 37.0}), ({'rx': 14, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': -2, 'disp': -3, 'nx': 12, 'ny': 16}, {'reference_x': 6.25, 'reference_y': 4.875, 'plate_scale': -4, 'spectral_step': -12, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 14, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 1, 'ny': 1}, {'reference_x': 6.25, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 3.5})], 3: [({'rx': 15, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 6.75, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 15, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 1, 'by': 1, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 13.0, 'reference_y': 18.0, 'plate_scale': 3, 'spectral_step': 5, 'footprint_pixels': 1, 'last_center_x': 14.0}), ({'rx': 15, 'ry': 21, 'sx': 0, 'sy': 0, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 7.75, 'reference_y': 5.625, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 23.5}), ({'rx': 15, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 3, 'by': 2, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 4.666666666666666, 'reference_y': 9.25, 'plate_scale': 9, 'spectral_step': 10, 'footprint_pixels': 6, 'last_center_x': 37.0}), ({'rx': 15, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': -2, 'disp': -3, 'nx': 12, 'ny': 16}, {'reference_x': 6.75, 'reference_y': 4.875, 'plate_scale': -4, 'spectral_step': -12, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 15, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 1, 'ny': 1}, {'reference_x': 6.75, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 3.5})], 4: [({'rx': 16, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 7.25, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 16, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 1, 'by': 1, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 14.0, 'reference_y': 18.0, 'plate_scale': 3, 'spectral_step': 5, 'footprint_pixels': 1, 'last_center_x': 14.0}), ({'rx': 16, 'ry': 21, 'sx': 0, 'sy': 0, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 8.25, 'reference_y': 5.625, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 23.5}), ({'rx': 16, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 3, 'by': 2, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 5.0, 'reference_y': 9.25, 'plate_scale': 9, 'spectral_step': 10, 'footprint_pixels': 6, 'last_center_x': 37.0}), ({'rx': 16, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': -2, 'disp': -3, 'nx': 12, 'ny': 16}, {'reference_x': 7.25, 'reference_y': 4.875, 'plate_scale': -4, 'spectral_step': -12, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 16, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 1, 'ny': 1}, {'reference_x': 7.25, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 3.5})], 5: [({'rx': 17, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 7.75, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 17, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 1, 'by': 1, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 15.0, 'reference_y': 18.0, 'plate_scale': 3, 'spectral_step': 5, 'footprint_pixels': 1, 'last_center_x': 14.0}), ({'rx': 17, 'ry': 21, 'sx': 0, 'sy': 0, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 8.75, 'reference_y': 5.625, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 23.5}), ({'rx': 17, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 3, 'by': 2, 'scale': 3, 'disp': 5, 'nx': 12, 'ny': 16}, {'reference_x': 5.333333333333333, 'reference_y': 9.25, 'plate_scale': 9, 'spectral_step': 10, 'footprint_pixels': 6, 'last_center_x': 37.0}), ({'rx': 17, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': -2, 'disp': -3, 'nx': 12, 'ny': 16}, {'reference_x': 7.75, 'reference_y': 4.875, 'plate_scale': -4, 'spectral_step': -12, 'footprint_pixels': 8, 'last_center_x': 25.5}), ({'rx': 17, 'ry': 21, 'sx': 2, 'sy': 3, 'bx': 2, 'by': 4, 'scale': 3, 'disp': 5, 'nx': 1, 'ny': 1}, {'reference_x': 7.75, 'reference_y': 4.875, 'plate_scale': 6, 'spectral_step': 20, 'footprint_pixels': 8, 'last_center_x': 3.5})]}
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)

prompt:
The adapter reports an incorrect spectral step while other fields remain valid.

Pixel centers are one-based. A bin of bx by by starts at zero-based crop sx,sy. Its first center is start+(bin+1)/2. The supplied dispersion and plate scales are per unbinned pixel; bin integral weights count physical contributing pixels. Output fields are defined by: reference_x = (d['rx']-d['sx']-(d['bx']+1)/2)/d['bx']+1; reference_y = (d['ry']-d['sy']-(d['by']+1)/2)/d['by']+1; plate_scale = d['scale']*d['bx']; spectral_step = d['disp']*d['by']; footprint_pixels = d['bx']*d['by']; last_center_x = d['sx']+(d['bx']+1)/2+(d['nx']-1)*d['bx']

split: open-access