Skip to content

Commit 186876e

Browse files
authored
Fix self-subtraction typo in insertion-locus branch of ReadCollector (#142)
Line 202 compared read_base0_after_insertion to itself instead of read_base0_before_insertion, making the adjacent-positions branch dead. The else-branch happened to compute the same result for that case, so no output was incorrect, but the intent was wrong. Fixes #126
1 parent f9694f5 commit 186876e

3 files changed

Lines changed: 49 additions & 2 deletions

File tree

isovar/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
# See the License for the specific language governing permissions and
1111
# limitations under the License.
1212

13-
__version__ = "1.4.5"
13+
__version__ = "1.4.6"
1414

1515

1616
from .allele_read import AlleleRead

isovar/read_collector.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ def locus_read_from_pysam_aligned_segment(
199199
else:
200200
return None
201201

202-
if read_base0_after_insertion - read_base0_after_insertion == 1:
202+
if read_base0_after_insertion - read_base0_before_insertion == 1:
203203
read_base0_start_inclusive = read_base0_end_exclusive = (
204204
read_base0_before_insertion + 1
205205
)

tests/test_locus_reads.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,3 +297,50 @@ def test_locus_read_none_mapq_with_min_mapping_quality_nonzero():
297297
"Expected read with mapping_quality=None to be skipped when "
298298
"min_mapping_quality=1, but it was accepted"
299299
)
300+
301+
302+
def test_locus_read_insertion_locus_no_insertion_in_read():
303+
"""
304+
When an insertion variant is queried (reference_interval_size == 0) but the
305+
read does NOT carry the insertion, the read positions flanking the locus
306+
should be adjacent (differ by 1) and the returned LocusRead should have
307+
an empty read interval (start == end).
308+
309+
Regression test for GitHub issue #126 — previously the code compared
310+
read_base0_after_insertion to itself instead of read_base0_before_insertion,
311+
making the adjacent-positions branch dead.
312+
"""
313+
# Reference: ACCTTG (positions 0-5). Insertion locus between pos 3 and 4.
314+
# This read has NO insertion — reference positions are contiguous.
315+
pysam_read = make_pysam_read(seq="ACCTTG", cigar="6M", mdtag="6")
316+
read_collector = ReadCollector()
317+
result = read_collector.locus_read_from_pysam_aligned_segment(
318+
pysam_read,
319+
base0_start_inclusive=4,
320+
base0_end_exclusive=4,
321+
)
322+
assert result is not None, "Read without insertion should still be returned"
323+
eq_(result.read_base0_start_inclusive, 4)
324+
eq_(result.read_base0_end_exclusive, 4)
325+
326+
327+
def test_locus_read_insertion_locus_with_insertion_in_read():
328+
"""
329+
When an insertion variant is queried (reference_interval_size == 0) and the
330+
read DOES carry the insertion, the returned LocusRead should have a
331+
non-empty read interval spanning the inserted bases.
332+
333+
Companion to the test above to verify the else-branch still works.
334+
"""
335+
# Reference: ACCTTG. Insertion of G between pos 3 and 4.
336+
# Read: ACCTGTG — 4M1I2M — positions [0,1,2,3,None,4,5]
337+
pysam_read = make_pysam_read(seq="ACCTGTG", cigar="4M1I2M", mdtag="6")
338+
read_collector = ReadCollector()
339+
result = read_collector.locus_read_from_pysam_aligned_segment(
340+
pysam_read,
341+
base0_start_inclusive=4,
342+
base0_end_exclusive=4,
343+
)
344+
assert result is not None, "Read with insertion should be returned"
345+
eq_(result.read_base0_start_inclusive, 4)
346+
eq_(result.read_base0_end_exclusive, 5)

0 commit comments

Comments
 (0)