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