1 package var2; 2 3 import shared.Parse; 4 import shared.Shared; 5 import shared.Tools; 6 import stream.SamLine; 7 import structures.CoverageArray; 8 import structures.CoverageArray2; 9 import structures.CoverageArray3; 10 import structures.CoverageArray3A; 11 12 public class Scaffold { 13 14 /** Assumes SAM format. 15 * e.g.<br> @SQ SN:scaffold_0 LN:1785514 AS:build 9 */ Scaffold(byte[] line, int scafnum)16 public Scaffold(byte[] line, int scafnum){ 17 assert(Tools.startsWith(line, "@SQ\t")) : new String(line); 18 number=scafnum; 19 int a=0, b=0; 20 21 while(b<line.length && line[b]!='\t'){b++;} 22 assert(b>a) : "Missing field 0: "+new String(line); 23 b++; 24 a=b; 25 26 while(b<line.length && line[b]!='\t'){b++;} 27 assert(b>a) : "Missing field 1: "+new String(line); 28 assert(Tools.startsWith(line, "SN:", a)); 29 name=new String(line, a+3, b-a-3); 30 b++; 31 a=b; 32 33 while(b<line.length && line[b]!='\t'){b++;} 34 assert(b>a) : "Missing field 2: "+new String(line); 35 assert(Tools.startsWith(line, "LN:", a)); 36 length=Parse.parseInt(line, a+3, b); 37 b++; 38 a=b; 39 } 40 Scaffold(String name_, int scafnum_, int len_)41 public Scaffold(String name_, int scafnum_, int len_){ 42 name=name_; 43 number=scafnum_; 44 length=len_; 45 } 46 add(SamLine sl)47 public void add(SamLine sl){ 48 int start=sl.pos-1; 49 int stop=sl.stop(start, false, false); 50 increment(start, stop, sl.strand()); 51 } 52 increment(int from, int to, int strand)53 public void increment(int from, int to, int strand){ 54 // assert(trackStrand); 55 if(!initialized()){ 56 synchronized(this){ 57 if(!initialized()){ 58 // assert(ca==null); 59 // assert(caMinus==null); 60 // assert(trackStrand); 61 ca=useCA3A ? new CoverageArray3A(number, length) : useCA3 ? new CoverageArray3(number, length) : new CoverageArray2(number, length); 62 if(trackStrand){ 63 caMinus=useCA3A ? new CoverageArray3A(number, length) : useCA3 ? new CoverageArray3(number, length) : new CoverageArray2(number, length); 64 } 65 } 66 initialized=true; 67 } 68 // assert(ca!=null); 69 // assert(!trackStrand || caMinus!=null) : trackStrand; 70 } 71 assert(initialized()); 72 assert(ca!=null); 73 // assert(!trackStrand || caMinus!=null) : trackStrand; 74 // assert(trackStrand); 75 ca.incrementRangeSynchronized(from, to, 1); 76 if(trackStrand && strand==Shared.MINUS){caMinus.incrementRangeSynchronized(from, to, 1);} 77 } 78 incrementOld(int from, int to, int strand)79 public synchronized void incrementOld(int from, int to, int strand){ 80 if(ca==null){ 81 ca=useCA3 ? new CoverageArray3(number, length) : new CoverageArray2(number, length); 82 } 83 ca.incrementRange(from, to); 84 if(trackStrand && strand==Shared.MINUS){ 85 if(caMinus==null){ 86 caMinus=useCA3 ? new CoverageArray3(number, length) : new CoverageArray2(number, length); 87 } 88 caMinus.incrementRange(from, to); 89 } 90 } 91 getSequence(SamLine sl)92 public String getSequence(SamLine sl) { 93 int start=sl.start(false, false); 94 int stop=sl.stop(start, false, false); 95 return getSequence(start, stop); 96 } 97 getSequence(int start, int stop)98 public String getSequence(int start, int stop) { 99 assert(bases!=null) : this; 100 start=Tools.max(0, start); 101 stop=Tools.min(bases.length-1, stop); 102 String s=new String(bases, start, stop-start+1); 103 return s; 104 } 105 calcCoverage(Var v)106 public int calcCoverage(Var v){ 107 return calcCoverage(v, ca); 108 } 109 minusCoverage(Var v)110 public int minusCoverage(Var v){ 111 assert(trackStrand); 112 return calcCoverage(v, caMinus); 113 } 114 calcCoverage(Var v, CoverageArray ca)115 public int calcCoverage(Var v, CoverageArray ca){ 116 final int a=v.start; 117 final int b=v.stop; 118 // assert(false) : ca.maxIndex+", "+a; 119 if(ca==null || ca.maxIndex<a){return 0;} 120 final int type=v.type(); 121 final int avg; 122 final int rlen=v.reflen(); 123 long sum=0; 124 if(type==Var.SUB || type==Var.NOCALL || type==Var.DEL){ 125 for(int i=a; i<b; i++){ 126 sum+=ca.get(i); 127 } 128 avg=(int)Math.round(sum/(double)rlen); 129 }else if(type==Var.INS){ 130 assert(rlen==0 && a==b); 131 // if(a<=0){sum=2*ca.get(0);} 132 // else if(b>ca.maxIndex) 133 if(b>=ca.maxIndex){ 134 sum=2*ca.get(ca.maxIndex); 135 avg=(int)(sum/2); 136 }else{ 137 sum=ca.get(a)+ca.get(b); 138 avg=(int)Math.ceil(sum/2); 139 } 140 }else if(type==Var.LJUNCT){ 141 //Take coverage from right of junction, unless that's off the end. 142 //but it should be impossible for that to be off the end. 143 avg=ca.get(Tools.min(ca.maxIndex, a+1)); 144 }else if(type==Var.RJUNCT){ 145 //Take coverage from left of junction, unless that's off the end. 146 //but it should be impossible for that to be off the end. 147 avg=ca.get(Tools.max(0, a-1)); 148 }else{ 149 throw new RuntimeException("Unknown type "+type+"\n"+v); 150 } 151 return avg; 152 } 153 154 @Override toString()155 public String toString(){ 156 return "@SQ\tSN:"+name+"\tLN:"+length+"\tID:"+number; 157 } 158 clearCoverage()159 public synchronized void clearCoverage(){ 160 ca=null; 161 caMinus=null; 162 initialized=false; 163 } 164 165 public final String name; 166 public final int number; 167 public final int length; 168 private CoverageArray ca; 169 private CoverageArray caMinus; 170 public byte[] bases; initialized()171 private boolean initialized(){return initialized;}; 172 private boolean initialized; 173 setCA3(boolean b)174 public static void setCA3(boolean b){useCA3=b;} setCA3A(boolean b)175 public static void setCA3A(boolean b){useCA3A=b;} setTrackStrand(boolean b)176 public static void setTrackStrand(boolean b){trackStrand=b;} trackStrand()177 public static boolean trackStrand(){return trackStrand;} 178 179 private static boolean useCA3=false; 180 private static boolean useCA3A=true; 181 private static boolean trackStrand=false; 182 183 } 184