jpayne@68: package clump; jpayne@68: jpayne@68: import java.io.Serializable; jpayne@68: jpayne@68: import hiseq.FlowcellCoordinate; jpayne@68: import shared.KillSwitch; jpayne@68: import shared.Tools; jpayne@68: import stream.Read; jpayne@68: import structures.IntList; jpayne@68: jpayne@68: class ReadKey implements Serializable, Comparable { jpayne@68: jpayne@68: // public static ReadKey makeKeyIfNeeded(Read r){ jpayne@68: // if(r.obj==null){ jpayne@68: // return makeKey(r, true); jpayne@68: // } jpayne@68: // return (ReadKey)r.obj; jpayne@68: // } jpayne@68: jpayne@68: public static ReadKey makeKey(Read r, boolean setObject){ jpayne@68: assert(r.obj==null); jpayne@68: try { jpayne@68: ReadKey rk=new ReadKey(r); jpayne@68: if(setObject){r.obj=rk;} jpayne@68: return rk; jpayne@68: } catch (OutOfMemoryError e) { jpayne@68: KillSwitch.memKill(e); jpayne@68: throw new RuntimeException(e); jpayne@68: } jpayne@68: } jpayne@68: jpayne@68: private ReadKey(Read r){ jpayne@68: this(r, 0, 0, true); jpayne@68: } jpayne@68: jpayne@68: private ReadKey(Read r, long kmer_, int position_, boolean plus_){ jpayne@68: kmer=kmer_; jpayne@68: position=position_; jpayne@68: clump=null; jpayne@68: assert(!r.swapped()); jpayne@68: flipped=false; jpayne@68: kmerMinusStrand=!plus_; jpayne@68: jpayne@68: if(Clump.opticalOnly){ jpayne@68: FlowcellCoordinate fc=FlowcellCoordinate.getFC(); jpayne@68: fc.setFrom(r.id); jpayne@68: lane=fc.lane; jpayne@68: tile=fc.tile; jpayne@68: x=fc.x; jpayne@68: y=fc.y; jpayne@68: } jpayne@68: // expectedErrors=r.expectedErrorsIncludingMate(true); jpayne@68: } jpayne@68: jpayne@68: protected ReadKey(){} jpayne@68: jpayne@68: public void set(long kmer_, int position_, boolean minus_){ jpayne@68: setKmer(kmer_); jpayne@68: setPosition(position_); jpayne@68: // setClump(null); jpayne@68: kmerMinusStrand=minus_; jpayne@68: } jpayne@68: jpayne@68: private long setKmer(long kmer_){ jpayne@68: return kmer=kmer_; jpayne@68: } jpayne@68: jpayne@68: private int setPosition(int position_){ jpayne@68: return position=position_; jpayne@68: } jpayne@68: jpayne@68: public Clump setClump(Clump clump_){ jpayne@68: return clump=clump_; jpayne@68: } jpayne@68: jpayne@68: private boolean setFlipped(boolean flipped_){ jpayne@68: assert(flipped!=flipped_); jpayne@68: return flipped=flipped_; jpayne@68: } jpayne@68: jpayne@68: public void clear(){ jpayne@68: setKmer(0); jpayne@68: setPosition(0); jpayne@68: setClump(null); jpayne@68: kmerMinusStrand=false; jpayne@68: } jpayne@68: jpayne@68: public void flip(Read r, int k){ jpayne@68: assert(r.swapped()==flipped); jpayne@68: r.reverseComplement(); jpayne@68: r.setSwapped(!r.swapped()); jpayne@68: setFlipped(!flipped); jpayne@68: if(r.length()>=k){setPosition(r.length()-position+k-2);} jpayne@68: assert(r.swapped()==flipped); jpayne@68: } jpayne@68: jpayne@68: @Override jpayne@68: public int compareTo(ReadKey b){ jpayne@68: if(kmer!=b.kmer){return kmer>b.kmer ? -1 : 1;} //Bigger kmers first... jpayne@68: if(kmerMinusStrand!=b.kmerMinusStrand){return kmerMinusStrand ? 1 : -1;} jpayne@68: if(position!=b.position){return positionb.expectedErrors ? 1 : -1;//Higher quality first jpayne@68: // } jpayne@68: return 0; jpayne@68: } jpayne@68: jpayne@68: @Override jpayne@68: public boolean equals(Object b){ jpayne@68: return equals((ReadKey)b, false); jpayne@68: } jpayne@68: jpayne@68: @Override jpayne@68: public int hashCode() { jpayne@68: int x=(int)((kmer^position)&0xFFFFFFFFL); jpayne@68: return kmerMinusStrand ? -x : x; jpayne@68: } jpayne@68: jpayne@68: /** True if this physically contains b (ignoring mismatches) */ jpayne@68: public boolean physicallyContains(ReadKey b, int aLen, int bLen){ jpayne@68: if(bLen>aLen){return false;} jpayne@68: if(kmer!=b.kmer){return false;} jpayne@68: final int dif=position-b.position; jpayne@68: int bStart=dif, bStop=dif+bLen; jpayne@68: return bStart>=0 && bStop<=aLen; jpayne@68: } jpayne@68: jpayne@68: /** True if this physically contains b as a prefix or suffix (ignoring mismatches). jpayne@68: * More restrictive than physicallyContains. */ jpayne@68: public boolean physicalAffix(ReadKey b, int aLen, int bLen){ jpayne@68: if(bLen>aLen){return false;} jpayne@68: if(kmer!=b.kmer){return false;} jpayne@68: final int dif=position-b.position; jpayne@68: int bStart=dif, bStop=dif+bLen; jpayne@68: return (bStart==0 || bStop==aLen) && bStart>=0 && bStop<=aLen; jpayne@68: } jpayne@68: jpayne@68: /** Note that this is different than compareTo()==0 jpayne@68: * That's to prevent sortYEarly comparison making things unequal. jpayne@68: * @param b jpayne@68: * @return True if equal jpayne@68: */ jpayne@68: public boolean equals(ReadKey b, boolean containment){ jpayne@68: if(b==null){return false;} jpayne@68: if(kmer!=b.kmer){return false;} jpayne@68: if(!containment && (kmerMinusStrand!=b.kmerMinusStrand || position!=b.position)){return false;} jpayne@68: if(Clump.opticalOnly){ jpayne@68: if(lane!=b.lane){return false;} jpayne@68: if(!spanTiles()){ jpayne@68: if(tile!=b.tile){return false;} jpayne@68: } jpayne@68: } jpayne@68: return true; jpayne@68: } jpayne@68: public boolean equals(ReadKey b){ jpayne@68: return equals(b, false); jpayne@68: } jpayne@68: jpayne@68: @Override jpayne@68: public String toString(){ jpayne@68: return position+","+(kmerMinusStrand ? ",t" : ",f")+","+kmer+"\t"+lane+","+tile+","+x+","+y; jpayne@68: } jpayne@68: jpayne@68: public float distance(ReadKey rkb){ jpayne@68: if(lane!=rkb.lane){return FlowcellCoordinate.big;} jpayne@68: jpayne@68: long a=Tools.absdif(x, rkb.x), b=Tools.absdif(y, rkb.y); jpayne@68: if(tile!=rkb.tile){ jpayne@68: if(spanTiles()){ jpayne@68: if(spanAdjacentOnly && Tools.absdif(tile, rkb.tile)>1){return FlowcellCoordinate.big;} jpayne@68: if(spanTilesX && spanTilesY){ jpayne@68: return Tools.min(a, b); jpayne@68: }else if(spanTilesX){ jpayne@68: return a; jpayne@68: }else{ jpayne@68: return b; jpayne@68: } jpayne@68: }else{ jpayne@68: return FlowcellCoordinate.big; jpayne@68: } jpayne@68: } jpayne@68: return (float)Math.sqrt(a*a+b*b); jpayne@68: } jpayne@68: jpayne@68: public boolean near(ReadKey rkb, float dist){ jpayne@68: return distance(rkb)