FA-12546 / Genomic coordinate mapping / Open access
Reverse alignments apply soft clipping at the wrong query end · case 01
Original read positions map to the wrong reference base after reverse orientation and asymmetric soft clipping.
ROOT CAUSE
Original query indexes are consumed directly in alignment orientation without accounting for reverse alignment.
VERIFIED REPAIR
Reverse the original query index over the full query length, then remove the alignment-leading soft clip and reject clipped bases.
Unsuccessful approach: Reversing only the unclipped aligned segment loses the position of asymmetric leading and trailing soft clips.
Case contract
For a synthetic ungapped alignment with leading/trailing soft clip lengths in alignment orientation, map a zero-based original read index to reference base or None. Query length is lead+aligned+trail. Reverse alignments reverse indexes across the entire query before clipping.
Why this case matters
An abstract offline coordinate model isolates this software mapping defect; it does not model biological interpretation.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(lead, aligned, trail, start, reverse, pos):
q=pos-lead
return start+q if 0<=q<aligned else None
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
lead=N; aligned=4; trail=N+2; length=lead+aligned+trail
check('reverse first aligned original base',solve(lead,aligned,trail,100,True,trail),103)
check('reverse last aligned original base',solve(lead,aligned,trail,100,True,trail+3),100)
check('reverse preceding clipped base',solve(lead,aligned,trail,100,True,trail-1),None)
check('reverse following clipped base',solve(lead,aligned,trail,100,True,trail+4),None)
check('forward first aligned base',solve(lead,aligned,trail,100,False,lead),100)
check('forward last aligned base',solve(lead,aligned,trail,100,False,lead+3),103)
check('forward leading clip',solve(lead,aligned,trail,100,False,lead-1),None)
check('outside original read',solve(lead,aligned,trail,100,True,length),None)
check('negative original index',solve(lead,aligned,trail,100,True,-1),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)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| reverse first aligned original base | 102 | 103 | Failed |
| reverse last aligned original base | None | 100 | Failed |
| reverse preceding clipped base | 101 | None | Failed |
| reverse following clipped base | None | None | Passed |
| forward first aligned base | 100 | 100 | Passed |
| forward last aligned base | 103 | 103 | Passed |
| forward leading clip | None | None | Passed |
| outside original read | None | None | Passed |
| negative original index | None | None | Passed |
SHA-256 / 4f62f4a45243fa4e6a11df0ab1be380968f06b91e8351525113d0b5c026bbb50
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(lead, aligned, trail, start, reverse, pos):
q=pos-lead
if reverse: q=aligned-1-q
return start+q if 0<=q<aligned else None
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
lead=N; aligned=4; trail=N+2; length=lead+aligned+trail
check('reverse first aligned original base',solve(lead,aligned,trail,100,True,trail),103)
check('reverse last aligned original base',solve(lead,aligned,trail,100,True,trail+3),100)
check('reverse preceding clipped base',solve(lead,aligned,trail,100,True,trail-1),None)
check('reverse following clipped base',solve(lead,aligned,trail,100,True,trail+4),None)
check('forward first aligned base',solve(lead,aligned,trail,100,False,lead),100)
check('forward last aligned base',solve(lead,aligned,trail,100,False,lead+3),103)
check('forward leading clip',solve(lead,aligned,trail,100,False,lead-1),None)
check('outside original read',solve(lead,aligned,trail,100,True,length),None)
check('negative original index',solve(lead,aligned,trail,100,True,-1),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)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| reverse first aligned original base | 101 | 103 | Failed |
| reverse last aligned original base | None | 100 | Failed |
| reverse preceding clipped base | 102 | None | Failed |
| reverse following clipped base | None | None | Passed |
| forward first aligned base | 100 | 100 | Passed |
| forward last aligned base | 103 | 103 | Passed |
| forward leading clip | None | None | Passed |
| outside original read | None | None | Passed |
| negative original index | None | None | Passed |
SHA-256 / 1a9fb2bca275c5c8b8150d563e8401ef7c8bf10fd9ae07ce8f1bb882446394ad
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(lead, aligned, trail, start, reverse, pos):
length=lead+aligned+trail
if not 0<=pos<length: return None
q=(length-1-pos if reverse else pos)-lead
return start+q if 0<=q<aligned else None
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
lead=N; aligned=4; trail=N+2; length=lead+aligned+trail
check('reverse first aligned original base',solve(lead,aligned,trail,100,True,trail),103)
check('reverse last aligned original base',solve(lead,aligned,trail,100,True,trail+3),100)
check('reverse preceding clipped base',solve(lead,aligned,trail,100,True,trail-1),None)
check('reverse following clipped base',solve(lead,aligned,trail,100,True,trail+4),None)
check('forward first aligned base',solve(lead,aligned,trail,100,False,lead),100)
check('forward last aligned base',solve(lead,aligned,trail,100,False,lead+3),103)
check('forward leading clip',solve(lead,aligned,trail,100,False,lead-1),None)
check('outside original read',solve(lead,aligned,trail,100,True,length),None)
check('negative original index',solve(lead,aligned,trail,100,True,-1),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)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| reverse first aligned original base | 103 | 103 | Passed |
| reverse last aligned original base | 100 | 100 | Passed |
| reverse preceding clipped base | None | None | Passed |
| reverse following clipped base | None | None | Passed |
| forward first aligned base | 100 | 100 | Passed |
| forward last aligned base | 103 | 103 | Passed |
| forward leading clip | None | None | Passed |
| outside original read | None | None | Passed |
| negative original index | None | None | Passed |
SHA-256 / 005ee3b887374d31474949dd01eff723bada96b1d3749feb08ccc2d75ee8f38e
Verification & scope
Synthetic coordinate fixtures only; not a production annotation or alignment implementation. 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:38:57.931391+00:00.
Case digest / 2f699373bfd326e5db43e6da2c0dc4eed38a6eab3cb4f688a51b931eba4072a0