Skip to content

Commit 75a5f59

Browse files
authored
Merge pull request #567 from andviane/master
Proposed fix for #355
2 parents aaaa2e8 + b3142b9 commit 75a5f59

File tree

3 files changed

+86
-27
lines changed

3 files changed

+86
-27
lines changed

biojava-genome/src/main/java/org/biojava/nbio/genome/parsers/gff/Location.java

Lines changed: 34 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -286,34 +286,41 @@ public Location union( Location other )
286286
}
287287

288288
/**
289-
* Return the intersection, or null if no overlap.
290-
*
291-
* @param other The location to intersect.
292-
* @return The maximal location that is contained by both. Returns null if no overlap!
293-
* @throws IllegalArgumentException Locations are on opposite strands.
294-
*/
295-
public Location intersection( Location other )
296-
{
297-
if( isSameStrand( other ) )
298-
{
299-
int start= ( mStart > other.mStart)? mStart: other.mStart; //pick larger
300-
int end= ( mEnd < other.mEnd)? mEnd: other.mEnd; //pick smaller
301-
302-
if( start <= end )
303-
{
304-
return new Location( start, end );
305-
}
306-
else
307-
{
308-
return null;
309-
}
310-
}
311-
else
312-
{
313-
throw new IllegalArgumentException( "Locations are on opposite strands." );
314-
}
289+
* Return the intersection, or null if no overlap.
290+
*
291+
* @param other
292+
* The location to intersect.
293+
* @return The maximal location that is contained by both. Returns null if
294+
* no overlap!
295+
* @throws IllegalArgumentException
296+
* Locations are on opposite strands.
297+
*/
298+
public Location intersection(Location other) {
299+
if (isSameStrand(other)) {
300+
return intersect(mStart, mEnd, other.mStart, other.mEnd);
301+
} else {
302+
throw new IllegalArgumentException("Locations are on opposite strands.");
303+
}
304+
}
305+
306+
private Location intersect(int a1, int a2, int b1, int b2) {
307+
if (a1 > b1) {
308+
return intersect(b1, b2, a1, a2);
309+
}
310+
// Safe to assume a1 <= b1
311+
if (b1 >= a2) {
312+
// b starts after a ends
313+
return null;
314+
} else if (b1 < a2 && b2 <= a2) {
315+
// b starts after a starts and ends before or at where a ends
316+
return new Location(b1, b2);
317+
} else if (b1 >= a1 && a2 <= b2) {
318+
// b starts after a but extends after the end of a
319+
return new Location(b1, a2);
320+
}
321+
return null;
322+
}
315323

316-
}
317324

318325
/**
319326
* Get starting index (origin 0).
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package org.biojava.nbio.genome;
2+
3+
import static org.junit.Assert.*;
4+
5+
import org.biojava.nbio.genome.parsers.gff.Location;
6+
import org.junit.Test;
7+
8+
public class TestIssue355 {
9+
10+
@Test
11+
public void testIssue1() {
12+
Location l1 = Location.fromBio(51227320, 51227381, '+');
13+
Location l2 = Location.fromBio(51227323, 51227382, '+');
14+
15+
Location union = l1.union(l2);
16+
assertEquals(51227320,union.bioStart());
17+
assertEquals(51227382,union.bioEnd());
18+
}
19+
20+
@Test
21+
public void testIssue2() {
22+
Location l1 = Location.fromBio(100, 200, '+');
23+
Location l2 = Location.fromBio(1, 99, '+');
24+
Location intersection = l1.intersection(l2);
25+
assertNull(intersection);
26+
}
27+
28+
}
29+

biojava-genome/src/test/java/org/biojava/nbio/genome/TestLocation.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,29 @@ public void testLocation() {
9191
assertEquals(L(12,20), L(2,20).suffix( L(10,12)));
9292

9393
}
94+
95+
@Test
96+
public void testLocationIntersections() {
97+
// One inside another
98+
Location r21_25 = new Location( 21, 25 );
99+
Location r1_100 = new Location(1, 100 );
100+
101+
assertEquals(r21_25, r21_25.intersection( r1_100));
102+
assertEquals(r21_25, r1_100.intersection( r21_25));
103+
104+
// Non overlapping
105+
Location r10_100 = new Location(10, 100 );
106+
Location r1_9 = new Location( 1, 9 );
107+
108+
assertNull(r10_100.intersection( r1_9));
109+
assertNull(r1_9.intersection( new Location( 9, 10 )));
110+
111+
// Partially overlappping
112+
Location r1_25 = new Location( 1, 25 );
113+
Location r21_100 = new Location(21, 100 );
114+
assertEquals(r21_25, r1_25.intersection( r21_100));
115+
assertEquals(r21_25, r21_100.intersection( r1_25));
116+
}
94117

95118
//shorthand for testing
96119
private static Location L( int s, int e ) {

0 commit comments

Comments
 (0)