Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
* planned new feature: during import of long reads, (optionally) correct for short exon alignment issues.
* separate new read import and classification of isoforms.

## [2.0.6]

* fixed: `has_overlap`/`get_overlap` gave wrong results for reverse-strand features, where genomic coordinates are sometimes passed as `(end, start)` instead of `(start, end)`; this caused `add_domains_to_table` to silently miss overlapping domains on the reverse strand (#23)

## [2.0.5]

* fixed: gtf/gff3 import no longer reads the file twice for the progress bar (was pre-counting all lines); progress is now tracked by bytes read, roughly halving import time with `progress_bar=True` (#37)
Expand Down
2 changes: 1 addition & 1 deletion VERSION.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.0.5
2.0.6
13 changes: 9 additions & 4 deletions src/isotools/_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,14 +276,19 @@ def find_orfs(sequence, start_codons=None, stop_codons=None, ref_cds=None):

def has_overlap(r1, r2):
"check the overlap of two intervals"
# assuming start < end
return r1[1] > r2[0] and r2[1] > r1[0]
# coordinates on reverse-strand features are sometimes passed as (end, start);
# normalize rather than assume start < end. Only the first two elements
# are used -- r1/r2 may be e.g. an intervaltree.Interval with extra data
r1_lo, r1_hi = min(r1[0], r1[1]), max(r1[0], r1[1])
r2_lo, r2_hi = min(r2[0], r2[1]), max(r2[0], r2[1])
return r1_hi > r2_lo and r2_hi > r1_lo


def get_overlap(r1, r2):
"check the overlap of two intervals"
# assuming start < end
return max(0, min(r1[1], r2[1]) - max(r1[0], r2[0]))
r1_lo, r1_hi = min(r1[0], r1[1]), max(r1[0], r1[1])
r2_lo, r2_hi = min(r2[0], r2[1]), max(r2[0], r2[1])
return max(0, min(r1_hi, r2_hi) - max(r1_lo, r2_lo))


def get_intersects(tr1, tr2):
Expand Down
10 changes: 10 additions & 0 deletions tests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,13 @@ Two different test styles exist in this directory:

**When adding a test for a specific bug or feature, use style 1.** Reserve
the pipeline chain for genuine end-to-end integration concerns.

## File organization

One test file per feature area, named after what it covers -- not
necessarily 1:1 with a source file, but close (`domain_test.py` for
`domains.py`, `splice_graph_test.py` for `splice_graph.py`, `orf_test.py`
for ORF-prediction logic in `gene.py`, `data_import_test.py` for import
functions in `_transcriptome_io.py`, `utils_test.py` for the general
primitives in `_utils.py`, etc.). Before creating a new file, check whether
an existing one already covers that area.
18 changes: 18 additions & 0 deletions tests/utils_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from isotools._utils import has_overlap, get_overlap


def test_has_overlap_flipped_coordinates():
# regression test for #23: coordinates on reverse-strand features are
# sometimes passed as (end, start) rather than (start, end) -- both
# orderings must give the same result
assert has_overlap((90, 118), (100, 200)) is True
assert has_overlap((118, 90), (100, 200)) is True # previously wrongly False
assert has_overlap((10, 20), (100, 200)) is False
assert has_overlap((20, 10), (100, 200)) is False


def test_get_overlap_flipped_coordinates():
assert get_overlap((90, 118), (100, 200)) == 18
assert get_overlap((118, 90), (100, 200)) == 18 # previously wrong result
assert get_overlap((10, 20), (100, 200)) == 0
assert get_overlap((20, 10), (100, 200)) == 0
Loading