1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
|
package structures;
import java.util.ArrayList;
import java.util.Collections;
import shared.Tools;
/** A numeric range, assuming 0-based, base-centered numbering,
* including a contig number. */
public class CRange implements Comparable<CRange>{
/*--------------------------------------------------------------*/
public CRange(long c_, int a_, int b_){
this(c_, a_, b_, null);
}
public CRange(long c_, int a_, int b_, Object o_){
a=a_;
b=b_;
c=c_;
obj=o_;
assert(a<=b) : a+">"+b;
}
/*--------------------------------------------------------------*/
public boolean includes(int p){
return p>=a && p<=b;
}
public boolean intersects(int p1, int p2){
return overlap(a, b, p1, p2);
}
public boolean adjacent(int p1, int p2) {
return adjacent(a, b, p1, p2);
}
public boolean touches(int p1, int p2) {
return touch(a, b, p1, p2);
}
public boolean includes(int p1, int p2){
return include(a, b, p1, p2);
}
/*--------------------------------------------------------------*/
public boolean intersects(CRange r){
return c==r.c && intersects(r.a, r.b);
}
public boolean touches(CRange r){
return c==r.c && (intersects(r.a, r.b) || adjacent(r.a, r.b));
}
public boolean includes(CRange r){
return c==r.c && includes(r.a, r.b);
}
public int length() {
return b-a+1;
}
/*--------------------------------------------------------------*/
public CRange merge(CRange r){
assert(touches(r));
CRange r2=new CRange(c, min(a, r.a), max(b, r.b), obj);
assert(r2.includes(this));
assert(r2.includes(r));
assert(r2.length()<=length()+r.length());
return r2;
}
public void absorb(CRange r){
assert(touches(r));
a=min(a, r.a);
b=max(b, r.b);
}
@Override
public int hashCode(){
return Integer.rotateLeft(~a, 16)^b^Long.hashCode(Long.rotateRight(c, 8));
}
@Override
public boolean equals(Object r){
return equals((CRange)r);
}
public boolean equals(CRange r){
return c==r.c &&a==r.a && b==r.b;
}
@Override
public int compareTo(CRange r) {
if(c!=r.c) {return c>r.c ? 1 : -1;}
if(a!=r.a) {return a-r.a;}
return b-r.b;
}
@Override
public String toString(){
return "(c"+c+":"+a+(a==b ? "" : (" - "+b))+")";
}
/*--------------------------------------------------------------*/
public static int mergeList(ArrayList<CRange> ranges, boolean sort) {
if(ranges.size()<2){return 0;}
if(sort){Collections.sort(ranges);}
CRange current=ranges.get(0);
int removed=0;
for(int i=1; i<ranges.size(); i++) {
CRange r=ranges.get(i);
if(current.touches(r)) {
current.absorb(r);
ranges.set(i, null);
removed++;
}else{
current=r;
}
}
if(removed>0){
Tools.condenseStrict(ranges);
}
return removed;
}
public static boolean include(int a1, int b1, int a2, int b2){
assert(a1<=b1 && a2<=b2) : a1+", "+b1+", "+a2+", "+b2;
return a2>=a1 && b2<=b1;
}
public static boolean overlap(int a1, int b1, int a2, int b2){
assert(a1<=b1 && a2<=b2) : a1+", "+b1+", "+a2+", "+b2;
return a2<=b1 && b2>=a1;
}
public static boolean touch(int a1, int b1, int a2, int b2){
assert(a1<=b1 && a2<=b2) : a1+", "+b1+", "+a2+", "+b2;
return a2<=b1+1 && b2>=a1-1;
}
public static boolean adjacent(int a1, int b1, int a2, int b2){
assert(a1<=b1 && a2<=b2) : a1+", "+b1+", "+a2+", "+b2;
return a2==b1+1 && b2==a1-1;
}
private static final int min(int x, int y){return x<y ? x : y;}
private static final int max(int x, int y){return x>y ? x : y;}
/*--------------------------------------------------------------*/
/** Left point, inclusive */
public int a;
/** Right point, inclusive */
public int b;
/** Contig or sequence number */
public final long c;
public Object obj; //For attaching things
}
|