jpayne@68
|
1 package aligner;
|
jpayne@68
|
2
|
jpayne@68
|
3 import java.util.Arrays;
|
jpayne@68
|
4
|
jpayne@68
|
5 import dna.AminoAcid;
|
jpayne@68
|
6 import dna.ChromosomeArray;
|
jpayne@68
|
7 import dna.Data;
|
jpayne@68
|
8 import shared.Tools;
|
jpayne@68
|
9 import stream.Read;
|
jpayne@68
|
10 import stream.SiteScore;
|
jpayne@68
|
11
|
jpayne@68
|
12 /**
|
jpayne@68
|
13 * Based on MSA9ts, with transform scores tweaked for PacBio. */
|
jpayne@68
|
14 public final class MultiStateAligner9PacBioAdapter3 {
|
jpayne@68
|
15
|
jpayne@68
|
16
|
jpayne@68
|
17 public MultiStateAligner9PacBioAdapter3(int maxRows_, int maxColumns_){
|
jpayne@68
|
18 // assert(maxColumns_>=200);
|
jpayne@68
|
19 // assert(maxRows_>=200);
|
jpayne@68
|
20 maxRows=maxRows_;
|
jpayne@68
|
21 maxColumns=maxColumns_;
|
jpayne@68
|
22 packed=new int[3][maxRows+1][];
|
jpayne@68
|
23
|
jpayne@68
|
24 for(int i=0; i<3; i++){
|
jpayne@68
|
25 packed[i][0]=new int[maxColumns+1];
|
jpayne@68
|
26 packed[i][1]=new int[maxColumns+1];
|
jpayne@68
|
27 packed[i][2]=new int[maxColumns+1];
|
jpayne@68
|
28 for(int j=3; j<maxRows+1; j++){
|
jpayne@68
|
29 packed[i][j]=packed[i][j-2];
|
jpayne@68
|
30 }
|
jpayne@68
|
31 }
|
jpayne@68
|
32
|
jpayne@68
|
33 insScoreArray=new int[maxRows+1];
|
jpayne@68
|
34 delScoreArray=new int[maxColumns+1];
|
jpayne@68
|
35 matchScoreArray=new int[maxRows+1];
|
jpayne@68
|
36 subScoreArray=new int[maxRows+1];
|
jpayne@68
|
37 for(int i=0; i<insScoreArray.length; i++){
|
jpayne@68
|
38 insScoreArray[i]=(i==0 ? POINTSoff_INS :
|
jpayne@68
|
39 i<LIMIT_FOR_COST_3 ? POINTSoff_INS2 :
|
jpayne@68
|
40 i<LIMIT_FOR_COST_4 ? POINTSoff_INS3 : POINTSoff_INS4);
|
jpayne@68
|
41 }
|
jpayne@68
|
42 for(int i=0; i<delScoreArray.length; i++){
|
jpayne@68
|
43 delScoreArray[i]=(i==0 ? POINTSoff_DEL :
|
jpayne@68
|
44 i<LIMIT_FOR_COST_3 ? POINTSoff_DEL2 :
|
jpayne@68
|
45 i<LIMIT_FOR_COST_4 ? POINTSoff_DEL3 : POINTSoff_DEL4);
|
jpayne@68
|
46 }
|
jpayne@68
|
47 for(int i=0; i<matchScoreArray.length; i++){
|
jpayne@68
|
48 matchScoreArray[i]=(i==0 ? POINTSoff_MATCH2 : POINTSoff_MATCH);
|
jpayne@68
|
49 }
|
jpayne@68
|
50 for(int i=0; i<subScoreArray.length; i++){
|
jpayne@68
|
51 subScoreArray[i]=(i==0 ? POINTSoff_SUB : i<LIMIT_FOR_COST_3 ? POINTSoff_SUB2 : POINTSoff_SUB3);
|
jpayne@68
|
52 }
|
jpayne@68
|
53
|
jpayne@68
|
54 vertLimit=new int[maxRows+1];
|
jpayne@68
|
55 horizLimit=new int[maxColumns+1];
|
jpayne@68
|
56 Arrays.fill(vertLimit, BADoff);
|
jpayne@68
|
57 Arrays.fill(horizLimit, BADoff);
|
jpayne@68
|
58
|
jpayne@68
|
59 for(int matrix=0; matrix<packed.length; matrix++){
|
jpayne@68
|
60 for(int i=1; i<=3; i++){
|
jpayne@68
|
61 for(int j=0; j<packed[matrix][i].length; j++){
|
jpayne@68
|
62 packed[matrix][i][j]|=BADoff;
|
jpayne@68
|
63 }
|
jpayne@68
|
64 }
|
jpayne@68
|
65
|
jpayne@68
|
66 //Initializes the rows; not needed.
|
jpayne@68
|
67 for(int i=1; i<=2; i++){
|
jpayne@68
|
68
|
jpayne@68
|
69 int score=calcInsScoreOffset(i);
|
jpayne@68
|
70 packed[matrix][i][0]=score;
|
jpayne@68
|
71 }
|
jpayne@68
|
72 }
|
jpayne@68
|
73 }
|
jpayne@68
|
74
|
jpayne@68
|
75
|
jpayne@68
|
76 /** return new int[] {rows, maxC, maxS, max};
|
jpayne@68
|
77 * Will not fill areas that cannot match minScore */
|
jpayne@68
|
78 public final int[] fillLimited(byte[] read, byte[] ref, int refStartLoc, int refEndLoc, int minScore){
|
jpayne@68
|
79 return fillLimitedX(read, ref, refStartLoc, refEndLoc, minScore);
|
jpayne@68
|
80 }
|
jpayne@68
|
81
|
jpayne@68
|
82
|
jpayne@68
|
83 /** return new int[] {rows, maxC, maxS, max};
|
jpayne@68
|
84 * Will not fill areas that cannot match minScore */
|
jpayne@68
|
85 private final int[] fillLimitedX(byte[] read, byte[] ref, int refStartLoc, int refEndLoc, int minScore){
|
jpayne@68
|
86 // minScore=0;
|
jpayne@68
|
87 // assert(minScore>0);
|
jpayne@68
|
88 rows=read.length;
|
jpayne@68
|
89 columns=refEndLoc-refStartLoc+1;
|
jpayne@68
|
90
|
jpayne@68
|
91 if(/*read.length<40 || */false || minScore<=0 || columns>read.length+Tools.min(100, read.length)){
|
jpayne@68
|
92 // assert(false) : minScore;
|
jpayne@68
|
93 return fillUnlimited(read, ref, refStartLoc, refEndLoc);
|
jpayne@68
|
94 }
|
jpayne@68
|
95
|
jpayne@68
|
96 minScore-=100; //Increases quality trivially
|
jpayne@68
|
97
|
jpayne@68
|
98 assert(rows<=maxRows) : "Check that values are in-bounds before calling this function: "+rows+", "+maxRows+"\n"+
|
jpayne@68
|
99 refStartLoc+", "+refEndLoc+", "+rows+", "+maxRows+", "+columns+", "+maxColumns+"\n"+new String(read)+"\n";
|
jpayne@68
|
100 assert(columns<=maxColumns) : "Check that values are in-bounds before calling this function: "+columns+", "+maxColumns+"\n"+
|
jpayne@68
|
101 refStartLoc+", "+refEndLoc+", "+rows+", "+maxRows+", "+columns+", "+maxColumns+"\n"+new String(read)+"\n";
|
jpayne@68
|
102
|
jpayne@68
|
103 assert(refStartLoc>=0) : "Check that values are in-bounds before calling this function: "+refStartLoc+"\n"+
|
jpayne@68
|
104 refStartLoc+", "+refEndLoc+", "+rows+", "+maxRows+", "+columns+", "+maxColumns+"\n"+new String(read)+"\n";
|
jpayne@68
|
105 assert(refEndLoc<ref.length) : "Check that values are in-bounds before calling this function: "+refEndLoc+", "+ref.length+"\n"+
|
jpayne@68
|
106 refStartLoc+", "+refEndLoc+", "+rows+", "+maxRows+", "+columns+", "+maxColumns+"\n"+new String(read)+"\n";
|
jpayne@68
|
107
|
jpayne@68
|
108 // for(int x=0; x<packed.length; x++){
|
jpayne@68
|
109 // for(int y=1; y<rows+1; y++){
|
jpayne@68
|
110 // Arrays.fill(packed[x][y], 1, columns+1, BADoff);
|
jpayne@68
|
111 // }
|
jpayne@68
|
112 // }
|
jpayne@68
|
113 for(int x=0; x<packed.length; x++){
|
jpayne@68
|
114
|
jpayne@68
|
115 // Arrays.fill(packed[x][1], 1, columns+1, BADoff);
|
jpayne@68
|
116 Arrays.fill(packed[x][rows], 1, columns+1, BADoff);
|
jpayne@68
|
117 // for(int y=1; y<rows+1; y++){
|
jpayne@68
|
118 // Arrays.fill(packed[x][y], 1, columns+1, BADoff);
|
jpayne@68
|
119 // }
|
jpayne@68
|
120 }
|
jpayne@68
|
121
|
jpayne@68
|
122 int minGoodCol=1;
|
jpayne@68
|
123 int maxGoodCol=columns;
|
jpayne@68
|
124
|
jpayne@68
|
125 final int minScore_off=(minScore<<SCOREOFFSET);
|
jpayne@68
|
126 final int maxGain=(read.length-1)*POINTSoff_MATCH2+POINTSoff_MATCH;
|
jpayne@68
|
127 final int floor=minScore_off-maxGain;
|
jpayne@68
|
128 // final int subfloor=Tools.max(BADoff, floor-200*POINTSoff_MATCH2);
|
jpayne@68
|
129 final int subfloor=floor-5*POINTSoff_MATCH2;
|
jpayne@68
|
130 assert(subfloor>BADoff); //TODO: Actually, it needs to be substantially more.
|
jpayne@68
|
131 assert(subfloor<minScore_off) : minScore_off+", "+floor+", "+BADoff+", "+subfloor;
|
jpayne@68
|
132
|
jpayne@68
|
133 if(verbose2){
|
jpayne@68
|
134 System.out.println();
|
jpayne@68
|
135 System.out.println("minScore="+minScore+"\t"+minScore_off);
|
jpayne@68
|
136 System.out.println("maxGain="+(maxGain>>SCOREOFFSET)+"\t"+(maxGain));
|
jpayne@68
|
137 System.out.println("floor="+(floor>>SCOREOFFSET)+"\t"+(floor));
|
jpayne@68
|
138 System.out.println("subfloor="+(subfloor>>SCOREOFFSET)+"\t"+(subfloor));
|
jpayne@68
|
139 System.out.println("BADoff="+(BADoff>>SCOREOFFSET)+"\t"+(BADoff));
|
jpayne@68
|
140 System.out.println("maxGain="+(maxGain>>SCOREOFFSET)+"\t"+(maxGain));
|
jpayne@68
|
141 System.out.println();
|
jpayne@68
|
142 }
|
jpayne@68
|
143
|
jpayne@68
|
144 vertLimit[rows]=minScore_off;
|
jpayne@68
|
145 for(int i=rows-1; i>=0; i--){
|
jpayne@68
|
146 vertLimit[i]=Tools.max(vertLimit[i+1]-POINTSoff_MATCH2, floor);
|
jpayne@68
|
147 }
|
jpayne@68
|
148
|
jpayne@68
|
149 horizLimit[columns]=minScore_off;
|
jpayne@68
|
150 for(int i=columns-1; i>=0; i--){
|
jpayne@68
|
151 horizLimit[i]=Tools.max(horizLimit[i+1]-POINTSoff_MATCH2, floor);
|
jpayne@68
|
152 }
|
jpayne@68
|
153
|
jpayne@68
|
154 for(int row=1; row<=rows; row++){
|
jpayne@68
|
155
|
jpayne@68
|
156 {
|
jpayne@68
|
157 int score=calcInsScoreOffset(row);
|
jpayne@68
|
158 packed[0][row][0]=score;
|
jpayne@68
|
159 packed[1][row][0]=score;
|
jpayne@68
|
160 packed[2][row][0]=score;
|
jpayne@68
|
161 }
|
jpayne@68
|
162
|
jpayne@68
|
163 int colStart=minGoodCol;
|
jpayne@68
|
164 int colStop=maxGoodCol;
|
jpayne@68
|
165
|
jpayne@68
|
166 minGoodCol=-1;
|
jpayne@68
|
167 maxGoodCol=-2;
|
jpayne@68
|
168
|
jpayne@68
|
169 final int vlimit=vertLimit[row];
|
jpayne@68
|
170
|
jpayne@68
|
171 if(verbose2){
|
jpayne@68
|
172 System.out.println();
|
jpayne@68
|
173 System.out.println("row="+row);
|
jpayne@68
|
174 System.out.println("colStart="+colStart);
|
jpayne@68
|
175 System.out.println("colStop="+colStop);
|
jpayne@68
|
176 System.out.println("vlimit="+(vlimit>>SCOREOFFSET)+"\t"+(vlimit));
|
jpayne@68
|
177 }
|
jpayne@68
|
178
|
jpayne@68
|
179 if(colStart<0 || colStop<colStart){break;}
|
jpayne@68
|
180
|
jpayne@68
|
181
|
jpayne@68
|
182 if(colStart>1){
|
jpayne@68
|
183 assert(row>0);
|
jpayne@68
|
184 packed[MODE_MS][row][colStart-1]=subfloor;
|
jpayne@68
|
185 packed[MODE_INS][row][colStart-1]=subfloor;
|
jpayne@68
|
186 packed[MODE_DEL][row][colStart-1]=subfloor;
|
jpayne@68
|
187 }
|
jpayne@68
|
188
|
jpayne@68
|
189
|
jpayne@68
|
190 for(int col=colStart; col<=columns; col++){
|
jpayne@68
|
191
|
jpayne@68
|
192
|
jpayne@68
|
193 if(verbose2){
|
jpayne@68
|
194 System.out.println("\ncol "+col);
|
jpayne@68
|
195 }
|
jpayne@68
|
196
|
jpayne@68
|
197 final byte call0=(row<2 ? (byte)'?' : read[row-2]);
|
jpayne@68
|
198 final byte call1=read[row-1];
|
jpayne@68
|
199 final byte ref0=(col<2 ? (byte)'!' : ref[refStartLoc+col-2]);
|
jpayne@68
|
200 final byte ref1=ref[refStartLoc+col-1];
|
jpayne@68
|
201
|
jpayne@68
|
202 // final boolean match=(read[row-1]==ref[refStartLoc+col-1]);
|
jpayne@68
|
203 // final boolean prevMatch=(row<2 || col<2 ? false : read[row-2]==ref[refStartLoc+col-2]);
|
jpayne@68
|
204 final boolean match=(call1==ref1);
|
jpayne@68
|
205 final boolean prevMatch=(call0==ref0);
|
jpayne@68
|
206
|
jpayne@68
|
207 // System.err.println("")
|
jpayne@68
|
208
|
jpayne@68
|
209 iterationsLimited++;
|
jpayne@68
|
210 final int limit=Tools.max(vlimit, horizLimit[col]);
|
jpayne@68
|
211 final int limit3=Tools.max(floor, (match ? limit-POINTSoff_MATCH2 : limit-POINTSoff_SUB3));
|
jpayne@68
|
212
|
jpayne@68
|
213 final int delNeeded=Tools.max(0, row-col-1);
|
jpayne@68
|
214 final int insNeeded=Tools.max(0, (rows-row)-(columns-col)-1);
|
jpayne@68
|
215
|
jpayne@68
|
216 final int delPenalty=calcDelScoreOffset(delNeeded);
|
jpayne@68
|
217 final int insPenalty=calcInsScoreOffset(insNeeded);
|
jpayne@68
|
218
|
jpayne@68
|
219
|
jpayne@68
|
220 final int scoreFromDiag_MS=packed[MODE_MS][row-1][col-1]&SCOREMASK;
|
jpayne@68
|
221 final int scoreFromDel_MS=packed[MODE_DEL][row-1][col-1]&SCOREMASK;
|
jpayne@68
|
222 final int scoreFromIns_MS=packed[MODE_INS][row-1][col-1]&SCOREMASK;
|
jpayne@68
|
223
|
jpayne@68
|
224 final int scoreFromDiag_DEL=packed[MODE_MS][row][col-1]&SCOREMASK;
|
jpayne@68
|
225 final int scoreFromDel_DEL=packed[MODE_DEL][row][col-1]&SCOREMASK;
|
jpayne@68
|
226
|
jpayne@68
|
227 final int scoreFromDiag_INS=packed[MODE_MS][row-1][col]&SCOREMASK;
|
jpayne@68
|
228 final int scoreFromIns_INS=packed[MODE_INS][row-1][col]&SCOREMASK;
|
jpayne@68
|
229
|
jpayne@68
|
230 // if(scoreFromDiag_MS<limit3 && scoreFromDel_MS<limit3 && scoreFromIns_MS<limit3
|
jpayne@68
|
231 // && scoreFromDiag_DEL<limit && scoreFromDel_DEL<limit && scoreFromDiag_INS<limit && scoreFromIns_INS<limit){
|
jpayne@68
|
232 // iterationsLimited--; //A "fast" iteration
|
jpayne@68
|
233 // }
|
jpayne@68
|
234
|
jpayne@68
|
235 if((scoreFromDiag_MS<=limit3 && scoreFromDel_MS<=limit3 && scoreFromIns_MS<=limit3)){
|
jpayne@68
|
236 packed[MODE_MS][row][col]=subfloor;
|
jpayne@68
|
237 }else{//Calculate match and sub scores
|
jpayne@68
|
238 final int streak=(packed[MODE_MS][row-1][col-1]&TIMEMASK);
|
jpayne@68
|
239
|
jpayne@68
|
240 {//Calculate match/sub score
|
jpayne@68
|
241
|
jpayne@68
|
242 int score;
|
jpayne@68
|
243 int time;
|
jpayne@68
|
244 byte prevState;
|
jpayne@68
|
245
|
jpayne@68
|
246 if(match){
|
jpayne@68
|
247
|
jpayne@68
|
248 int scoreMS=scoreFromDiag_MS+(prevMatch ? POINTSoff_MATCH2 : POINTSoff_MATCH);
|
jpayne@68
|
249 int scoreD=scoreFromDel_MS+POINTSoff_MATCH;
|
jpayne@68
|
250 int scoreI=scoreFromIns_MS+POINTSoff_MATCH;
|
jpayne@68
|
251
|
jpayne@68
|
252 // byte prevState;
|
jpayne@68
|
253 if(scoreMS>=scoreD && scoreMS>=scoreI){
|
jpayne@68
|
254 score=scoreMS;
|
jpayne@68
|
255 time=(prevMatch ? streak+1 : 1);
|
jpayne@68
|
256 prevState=MODE_MS;
|
jpayne@68
|
257 }else if(scoreD>=scoreI){
|
jpayne@68
|
258 score=scoreD;
|
jpayne@68
|
259 time=1;
|
jpayne@68
|
260 prevState=MODE_DEL;
|
jpayne@68
|
261 }else{
|
jpayne@68
|
262 score=scoreI;
|
jpayne@68
|
263 time=1;
|
jpayne@68
|
264 prevState=MODE_INS;
|
jpayne@68
|
265 }
|
jpayne@68
|
266
|
jpayne@68
|
267 }else{
|
jpayne@68
|
268
|
jpayne@68
|
269 int scoreMS;
|
jpayne@68
|
270 if(ref1!='N' && call1!='N'){
|
jpayne@68
|
271 scoreMS=scoreFromDiag_MS+(prevMatch ? (streak<=1 ? POINTSoff_SUBR : POINTSoff_SUB) : subScoreArray[streak]);
|
jpayne@68
|
272 }else{
|
jpayne@68
|
273 scoreMS=scoreFromDiag_MS+POINTSoff_NOCALL;
|
jpayne@68
|
274 }
|
jpayne@68
|
275
|
jpayne@68
|
276 int scoreD=scoreFromDel_MS+POINTSoff_SUB; //+2 to move it as close as possible to the deletion / insertion
|
jpayne@68
|
277 int scoreI=scoreFromIns_MS+POINTSoff_SUB;
|
jpayne@68
|
278
|
jpayne@68
|
279 if(scoreMS>=scoreD && scoreMS>=scoreI){
|
jpayne@68
|
280 score=scoreMS;
|
jpayne@68
|
281 time=(prevMatch ? 1 : streak+1);
|
jpayne@68
|
282 // time=(prevMatch ? (streak==1 ? 3 : 1) : streak+1);
|
jpayne@68
|
283 prevState=MODE_MS;
|
jpayne@68
|
284 }else if(scoreD>=scoreI){
|
jpayne@68
|
285 score=scoreD;
|
jpayne@68
|
286 time=1;
|
jpayne@68
|
287 prevState=MODE_DEL;
|
jpayne@68
|
288 }else{
|
jpayne@68
|
289 score=scoreI;
|
jpayne@68
|
290 time=1;
|
jpayne@68
|
291 prevState=MODE_INS;
|
jpayne@68
|
292 }
|
jpayne@68
|
293 }
|
jpayne@68
|
294
|
jpayne@68
|
295 final int limit2;
|
jpayne@68
|
296 if(delNeeded>0){
|
jpayne@68
|
297 limit2=limit-delPenalty;
|
jpayne@68
|
298 }else if(insNeeded>0){
|
jpayne@68
|
299 limit2=limit-insPenalty;
|
jpayne@68
|
300 }else{
|
jpayne@68
|
301 limit2=limit;
|
jpayne@68
|
302 }
|
jpayne@68
|
303 assert(limit2>=limit);
|
jpayne@68
|
304
|
jpayne@68
|
305 if(verbose2){System.err.println("MS: \tlimit2="+(limit2>>SCOREOFFSET)+"\t, score="+(score>>SCOREOFFSET));}
|
jpayne@68
|
306
|
jpayne@68
|
307 if(score>=limit2){
|
jpayne@68
|
308 maxGoodCol=col;
|
jpayne@68
|
309 if(minGoodCol<0){minGoodCol=col;}
|
jpayne@68
|
310 }else{
|
jpayne@68
|
311 score=subfloor;
|
jpayne@68
|
312 }
|
jpayne@68
|
313
|
jpayne@68
|
314 assert(time<=MAX_TIME);//if(time>MAX_TIME){time=MAX_TIME-3;}
|
jpayne@68
|
315 assert(score>=MINoff_SCORE || score==BADoff) : "Score overflow - use MSA2 instead";
|
jpayne@68
|
316 assert(score<=MAXoff_SCORE) : "Score overflow - use MSA2 instead";
|
jpayne@68
|
317 // packed[MODE_MS][row][col]=(score|prevState|time);
|
jpayne@68
|
318 packed[MODE_MS][row][col]=(score|time);
|
jpayne@68
|
319 assert((score&SCOREMASK)==score);
|
jpayne@68
|
320 // assert((prevState&MODEMASK)==prevState);
|
jpayne@68
|
321 assert((time&TIMEMASK)==time);
|
jpayne@68
|
322 }
|
jpayne@68
|
323 }
|
jpayne@68
|
324
|
jpayne@68
|
325 if((scoreFromDiag_DEL<=limit && scoreFromDel_DEL<=limit)){
|
jpayne@68
|
326 // assert((scoreFromDiag_DEL<=limit && scoreFromDel_DEL<=limit)) : scoreFromDiag_DEL+", "+row;
|
jpayne@68
|
327 packed[MODE_DEL][row][col]=subfloor;
|
jpayne@68
|
328 }else{//Calculate DEL score
|
jpayne@68
|
329
|
jpayne@68
|
330 final int streak=packed[MODE_DEL][row][col-1]&TIMEMASK;
|
jpayne@68
|
331
|
jpayne@68
|
332 int scoreMS=scoreFromDiag_DEL+POINTSoff_DEL;
|
jpayne@68
|
333 int scoreD=scoreFromDel_DEL+delScoreArray[streak];
|
jpayne@68
|
334 // int scoreI=scoreFromIns+POINTSoff_DEL;
|
jpayne@68
|
335
|
jpayne@68
|
336
|
jpayne@68
|
337 if(ref1=='N'){
|
jpayne@68
|
338 scoreMS+=POINTSoff_DEL_REF_N;
|
jpayne@68
|
339 scoreD+=POINTSoff_DEL_REF_N;
|
jpayne@68
|
340 }
|
jpayne@68
|
341
|
jpayne@68
|
342 //if(match){scoreMS=subfloor;}
|
jpayne@68
|
343
|
jpayne@68
|
344 int score;
|
jpayne@68
|
345 int time;
|
jpayne@68
|
346 byte prevState;
|
jpayne@68
|
347 if(scoreMS>=scoreD){
|
jpayne@68
|
348 score=scoreMS;
|
jpayne@68
|
349 time=1;
|
jpayne@68
|
350 prevState=MODE_MS;
|
jpayne@68
|
351 }else{
|
jpayne@68
|
352 score=scoreD;
|
jpayne@68
|
353 time=streak+1;
|
jpayne@68
|
354 prevState=MODE_DEL;
|
jpayne@68
|
355 }
|
jpayne@68
|
356
|
jpayne@68
|
357 final int limit2;
|
jpayne@68
|
358 if(insNeeded>0){
|
jpayne@68
|
359 limit2=limit-insPenalty;
|
jpayne@68
|
360 }else if(delNeeded>0){
|
jpayne@68
|
361 limit2=limit-calcDelScoreOffset(time+delNeeded)+calcDelScoreOffset(time);
|
jpayne@68
|
362 }else{
|
jpayne@68
|
363 limit2=limit;
|
jpayne@68
|
364 }
|
jpayne@68
|
365 assert(limit2>=limit);
|
jpayne@68
|
366 if(verbose2){System.err.println("DEL: \tlimit2="+(limit2>>SCOREOFFSET)+"\t, score="+(score>>SCOREOFFSET));}
|
jpayne@68
|
367
|
jpayne@68
|
368 if(score>=limit2){
|
jpayne@68
|
369 maxGoodCol=col;
|
jpayne@68
|
370 if(minGoodCol<0){minGoodCol=col;}
|
jpayne@68
|
371 }else{
|
jpayne@68
|
372 score=subfloor;
|
jpayne@68
|
373 }
|
jpayne@68
|
374
|
jpayne@68
|
375 assert(time<=MAX_TIME);//if(time>MAX_TIME){time=MAX_TIME-3;}
|
jpayne@68
|
376 assert(score>=MINoff_SCORE || score==BADoff) : "Score overflow - use MSA2 instead";
|
jpayne@68
|
377 assert(score<=MAXoff_SCORE) : "Score overflow - use MSA2 instead";
|
jpayne@68
|
378 // packed[MODE_DEL][row][col]=(score|prevState|time);
|
jpayne@68
|
379 packed[MODE_DEL][row][col]=(score|time);
|
jpayne@68
|
380 assert((score&SCOREMASK)==score);
|
jpayne@68
|
381 // assert((prevState&MODEMASK)==prevState);
|
jpayne@68
|
382 assert((time&TIMEMASK)==time);
|
jpayne@68
|
383 }
|
jpayne@68
|
384
|
jpayne@68
|
385 if(scoreFromDiag_INS<=limit && scoreFromIns_INS<=limit){
|
jpayne@68
|
386 packed[MODE_INS][row][col]=subfloor;
|
jpayne@68
|
387 }else{//Calculate INS score
|
jpayne@68
|
388
|
jpayne@68
|
389 final int streak=packed[MODE_INS][row-1][col]&TIMEMASK;
|
jpayne@68
|
390
|
jpayne@68
|
391 int scoreMS=scoreFromDiag_INS+POINTSoff_INS;
|
jpayne@68
|
392 // int scoreD=scoreFromDel+POINTSoff_INS;
|
jpayne@68
|
393 int scoreI=scoreFromIns_INS+insScoreArray[streak];
|
jpayne@68
|
394
|
jpayne@68
|
395
|
jpayne@68
|
396 // System.err.println("("+row+","+col+")\t"+scoreFromDiag+"+"+POINTSoff_INS+"="+scoreM+", "+
|
jpayne@68
|
397 // scoreFromSub+"+"+POINTSoff_INS+"="+scoreS+", "
|
jpayne@68
|
398 // +scoreD+", "+scoreFromIns+"+"+
|
jpayne@68
|
399 // (streak==0 ? POINTSoff_INS : streak<LIMIT_FOR_COST_3 ? POINTSoff_INS2 : POINTSoff_INS3)+"="+scoreI);
|
jpayne@68
|
400
|
jpayne@68
|
401 //if(match){scoreMS=subfloor;}
|
jpayne@68
|
402
|
jpayne@68
|
403 int score;
|
jpayne@68
|
404 int time;
|
jpayne@68
|
405 byte prevState;
|
jpayne@68
|
406 if(scoreMS>=scoreI){
|
jpayne@68
|
407 score=scoreMS;
|
jpayne@68
|
408 time=1;
|
jpayne@68
|
409 prevState=MODE_MS;
|
jpayne@68
|
410 }else{
|
jpayne@68
|
411 score=scoreI;
|
jpayne@68
|
412 time=streak+1;
|
jpayne@68
|
413 prevState=MODE_INS;
|
jpayne@68
|
414 }
|
jpayne@68
|
415
|
jpayne@68
|
416 final int limit2;
|
jpayne@68
|
417 if(delNeeded>0){
|
jpayne@68
|
418 limit2=limit-delPenalty;
|
jpayne@68
|
419 }else if(insNeeded>0){
|
jpayne@68
|
420 limit2=limit-calcInsScoreOffset(time+insNeeded)+calcInsScoreOffset(time);
|
jpayne@68
|
421 }else{
|
jpayne@68
|
422 limit2=limit;
|
jpayne@68
|
423 }
|
jpayne@68
|
424 assert(limit2>=limit);
|
jpayne@68
|
425
|
jpayne@68
|
426 if(verbose2){System.err.println("INS: \tlimit2="+(limit2>>SCOREOFFSET)+"\t, score="+(score>>SCOREOFFSET));}
|
jpayne@68
|
427 if(score>=limit2){
|
jpayne@68
|
428 maxGoodCol=col;
|
jpayne@68
|
429 if(minGoodCol<0){minGoodCol=col;}
|
jpayne@68
|
430 }else{
|
jpayne@68
|
431 score=subfloor;
|
jpayne@68
|
432 }
|
jpayne@68
|
433
|
jpayne@68
|
434 assert(time<=MAX_TIME);//if(time>MAX_TIME){time=MAX_TIME-3;}
|
jpayne@68
|
435 assert(score>=MINoff_SCORE || score==BADoff) : "Score overflow - use MSA2 instead";
|
jpayne@68
|
436 assert(score<=MAXoff_SCORE) : "Score overflow - use MSA2 instead";
|
jpayne@68
|
437 // packed[MODE_INS][row][col]=(score|prevState|time);
|
jpayne@68
|
438 packed[MODE_INS][row][col]=(score|time);
|
jpayne@68
|
439 assert((score&SCOREMASK)==score);
|
jpayne@68
|
440 // assert((prevState&MODEMASK)==prevState);
|
jpayne@68
|
441 assert((time&TIMEMASK)==time);
|
jpayne@68
|
442 }
|
jpayne@68
|
443
|
jpayne@68
|
444
|
jpayne@68
|
445 if(col>=colStop){
|
jpayne@68
|
446 if(col>colStop && maxGoodCol<col){break;}
|
jpayne@68
|
447 if(row>1){
|
jpayne@68
|
448 packed[MODE_MS][row-1][col+1]=subfloor;
|
jpayne@68
|
449 packed[MODE_INS][row-1][col+1]=subfloor;
|
jpayne@68
|
450 packed[MODE_DEL][row-1][col+1]=subfloor;
|
jpayne@68
|
451 }
|
jpayne@68
|
452 }
|
jpayne@68
|
453 }
|
jpayne@68
|
454 }
|
jpayne@68
|
455
|
jpayne@68
|
456
|
jpayne@68
|
457 int maxCol=-1;
|
jpayne@68
|
458 int maxState=-1;
|
jpayne@68
|
459 int maxScore=Integer.MIN_VALUE;
|
jpayne@68
|
460
|
jpayne@68
|
461 for(int state=0; state<packed.length; state++){
|
jpayne@68
|
462 for(int col=1; col<=columns; col++){
|
jpayne@68
|
463 int x=packed[state][rows][col]&SCOREMASK;
|
jpayne@68
|
464 if(x>maxScore){
|
jpayne@68
|
465 maxScore=x;
|
jpayne@68
|
466 maxCol=col;
|
jpayne@68
|
467 maxState=state;
|
jpayne@68
|
468 }
|
jpayne@68
|
469 }
|
jpayne@68
|
470 }
|
jpayne@68
|
471
|
jpayne@68
|
472 assert(maxScore>=BADoff);
|
jpayne@68
|
473 // if(maxScore==BADoff){
|
jpayne@68
|
474 // return null;
|
jpayne@68
|
475 // }
|
jpayne@68
|
476 // if(maxScore<floor){
|
jpayne@68
|
477 // return null;
|
jpayne@68
|
478 // }
|
jpayne@68
|
479 if(maxScore<minScore_off){
|
jpayne@68
|
480 return null;
|
jpayne@68
|
481 }
|
jpayne@68
|
482
|
jpayne@68
|
483 maxScore>>=SCOREOFFSET;
|
jpayne@68
|
484
|
jpayne@68
|
485 // System.err.println("Returning "+rows+", "+maxCol+", "+maxState+", "+maxScore);
|
jpayne@68
|
486 return new int[] {rows, maxCol, maxState, maxScore};
|
jpayne@68
|
487 }
|
jpayne@68
|
488
|
jpayne@68
|
489
|
jpayne@68
|
490 /** return new int[] {rows, maxC, maxS, max};
|
jpayne@68
|
491 * Does not require a min score (ie, same as old method) */
|
jpayne@68
|
492 private final int[] fillUnlimited(byte[] read, byte[] ref, int refStartLoc, int refEndLoc){
|
jpayne@68
|
493 rows=read.length;
|
jpayne@68
|
494 columns=refEndLoc-refStartLoc+1;
|
jpayne@68
|
495
|
jpayne@68
|
496 final int maxGain=(read.length-1)*POINTSoff_MATCH2+POINTSoff_MATCH;
|
jpayne@68
|
497 final int subfloor=0-2*maxGain;
|
jpayne@68
|
498 assert(subfloor>BADoff && subfloor*2>BADoff); //TODO: Actually, it needs to be substantially more.
|
jpayne@68
|
499
|
jpayne@68
|
500 //temporary, for finding a bug
|
jpayne@68
|
501 if(rows>maxRows || columns>maxColumns){
|
jpayne@68
|
502 throw new RuntimeException("rows="+rows+", maxRows="+maxRows+", cols="+columns+", maxCols="+maxColumns+"\n"+new String(read)+"\n");
|
jpayne@68
|
503 }
|
jpayne@68
|
504
|
jpayne@68
|
505 assert(rows<=maxRows) : "Check that values are in-bounds before calling this function: "+rows+", "+maxRows;
|
jpayne@68
|
506 assert(columns<=maxColumns) : "Check that values are in-bounds before calling this function: "+columns+", "+maxColumns;
|
jpayne@68
|
507
|
jpayne@68
|
508 assert(refStartLoc>=0) : "Check that values are in-bounds before calling this function: "+refStartLoc;
|
jpayne@68
|
509 assert(refEndLoc<ref.length) : "Check that values are in-bounds before calling this function: "+refEndLoc+", "+ref.length;
|
jpayne@68
|
510
|
jpayne@68
|
511 for(int row=1; row<=rows; row++){
|
jpayne@68
|
512
|
jpayne@68
|
513 {
|
jpayne@68
|
514 int score=calcInsScoreOffset(row);
|
jpayne@68
|
515 packed[0][row][0]=score;
|
jpayne@68
|
516 packed[1][row][0]=score;
|
jpayne@68
|
517 packed[2][row][0]=score;
|
jpayne@68
|
518 }
|
jpayne@68
|
519
|
jpayne@68
|
520 // int minc=max(1, row-20);
|
jpayne@68
|
521 // int maxc=min(columns, row+20);
|
jpayne@68
|
522
|
jpayne@68
|
523 for(int col=1; col<=columns; col++){
|
jpayne@68
|
524 iterationsUnlimited++;
|
jpayne@68
|
525
|
jpayne@68
|
526 // final boolean match=(read[row-1]==ref[refStartLoc+col-1]);
|
jpayne@68
|
527 // final boolean prevMatch=(row<2 || col<2 ? false : read[row-2]==ref[refStartLoc+col-2]);
|
jpayne@68
|
528
|
jpayne@68
|
529 final byte call0=(row<2 ? (byte)'?' : read[row-2]);
|
jpayne@68
|
530 final byte call1=read[row-1];
|
jpayne@68
|
531 final byte ref0=(col<2 ? (byte)'!' : ref[refStartLoc+col-2]);
|
jpayne@68
|
532 final byte ref1=ref[refStartLoc+col-1];
|
jpayne@68
|
533
|
jpayne@68
|
534 final boolean match=(call1==ref1);
|
jpayne@68
|
535 final boolean prevMatch=(call0==ref0);
|
jpayne@68
|
536
|
jpayne@68
|
537 {//Calculate match and sub scores
|
jpayne@68
|
538
|
jpayne@68
|
539 final int scoreFromDiag=packed[MODE_MS][row-1][col-1]&SCOREMASK;
|
jpayne@68
|
540 final int scoreFromDel=packed[MODE_DEL][row-1][col-1]&SCOREMASK;
|
jpayne@68
|
541 final int scoreFromIns=packed[MODE_INS][row-1][col-1]&SCOREMASK;
|
jpayne@68
|
542 final int streak=(packed[MODE_MS][row-1][col-1]&TIMEMASK);
|
jpayne@68
|
543
|
jpayne@68
|
544 {//Calculate match/sub score
|
jpayne@68
|
545
|
jpayne@68
|
546 if(match){
|
jpayne@68
|
547
|
jpayne@68
|
548 int scoreMS=scoreFromDiag+(prevMatch ? POINTSoff_MATCH2 : POINTSoff_MATCH);
|
jpayne@68
|
549 int scoreD=scoreFromDel+POINTSoff_MATCH;
|
jpayne@68
|
550 int scoreI=scoreFromIns+POINTSoff_MATCH;
|
jpayne@68
|
551
|
jpayne@68
|
552 int score;
|
jpayne@68
|
553 int time;
|
jpayne@68
|
554 // byte prevState;
|
jpayne@68
|
555 if(scoreMS>=scoreD && scoreMS>=scoreI){
|
jpayne@68
|
556 score=scoreMS;
|
jpayne@68
|
557 time=(prevMatch ? streak+1 : 1);
|
jpayne@68
|
558 // prevState=MODE_MS;
|
jpayne@68
|
559 }else if(scoreD>=scoreI){
|
jpayne@68
|
560 score=scoreD;
|
jpayne@68
|
561 time=1;
|
jpayne@68
|
562 // prevState=MODE_DEL;
|
jpayne@68
|
563 }else{
|
jpayne@68
|
564 score=scoreI;
|
jpayne@68
|
565 time=1;
|
jpayne@68
|
566 // prevState=MODE_INS;
|
jpayne@68
|
567 }
|
jpayne@68
|
568
|
jpayne@68
|
569 assert(time<=MAX_TIME);//if(time>MAX_TIME){time=MAX_TIME-3;}
|
jpayne@68
|
570 assert(score>=MINoff_SCORE) : "Score overflow - use MSA2 instead";
|
jpayne@68
|
571 assert(score<=MAXoff_SCORE) : "Score overflow - use MSA2 instead";
|
jpayne@68
|
572 // packed[MODE_MS][row][col]=(score|prevState|time);
|
jpayne@68
|
573 packed[MODE_MS][row][col]=(score|time);
|
jpayne@68
|
574 assert((score&SCOREMASK)==score);
|
jpayne@68
|
575 // assert((prevState&MODEMASK)==prevState);
|
jpayne@68
|
576 assert((time&TIMEMASK)==time);
|
jpayne@68
|
577
|
jpayne@68
|
578 }else{
|
jpayne@68
|
579
|
jpayne@68
|
580 int scoreMS;
|
jpayne@68
|
581 if(ref1!='N' && call1!='N'){
|
jpayne@68
|
582 scoreMS=scoreFromDiag+(prevMatch ? (streak<=1 ? POINTSoff_SUBR : POINTSoff_SUB) : subScoreArray[streak]);
|
jpayne@68
|
583 }else{
|
jpayne@68
|
584 scoreMS=scoreFromDiag+POINTSoff_NOCALL;
|
jpayne@68
|
585 }
|
jpayne@68
|
586
|
jpayne@68
|
587 int scoreD=scoreFromDel+POINTSoff_SUB; //+2 to move it as close as possible to the deletion / insertion
|
jpayne@68
|
588 int scoreI=scoreFromIns+POINTSoff_SUB;
|
jpayne@68
|
589
|
jpayne@68
|
590 int score;
|
jpayne@68
|
591 int time;
|
jpayne@68
|
592 byte prevState;
|
jpayne@68
|
593 if(scoreMS>=scoreD && scoreMS>=scoreI){
|
jpayne@68
|
594 score=scoreMS;
|
jpayne@68
|
595 time=(prevMatch ? 1 : streak+1);
|
jpayne@68
|
596 // time=(prevMatch ? (streak==1 ? 3 : 1) : streak+1);
|
jpayne@68
|
597 prevState=MODE_MS;
|
jpayne@68
|
598 }else if(scoreD>=scoreI){
|
jpayne@68
|
599 score=scoreD;
|
jpayne@68
|
600 time=1;
|
jpayne@68
|
601 prevState=MODE_DEL;
|
jpayne@68
|
602 }else{
|
jpayne@68
|
603 score=scoreI;
|
jpayne@68
|
604 time=1;
|
jpayne@68
|
605 prevState=MODE_INS;
|
jpayne@68
|
606 }
|
jpayne@68
|
607
|
jpayne@68
|
608 assert(time<=MAX_TIME);//if(time>MAX_TIME){time=MAX_TIME-3;}
|
jpayne@68
|
609 assert(score>=MINoff_SCORE) : "Score overflow - use MSA2 instead";
|
jpayne@68
|
610 assert(score<=MAXoff_SCORE) : "Score overflow - use MSA2 instead";
|
jpayne@68
|
611 // packed[MODE_MS][row][col]=(score|prevState|time);
|
jpayne@68
|
612 packed[MODE_MS][row][col]=(score|time);
|
jpayne@68
|
613 assert((score&SCOREMASK)==score);
|
jpayne@68
|
614 // assert((prevState&MODEMASK)==prevState);
|
jpayne@68
|
615 assert((time&TIMEMASK)==time);
|
jpayne@68
|
616 }
|
jpayne@68
|
617 }
|
jpayne@68
|
618 }
|
jpayne@68
|
619
|
jpayne@68
|
620 {//Calculate DEL score
|
jpayne@68
|
621
|
jpayne@68
|
622 final int streak=packed[MODE_DEL][row][col-1]&TIMEMASK;
|
jpayne@68
|
623
|
jpayne@68
|
624 final int scoreFromDiag=packed[MODE_MS][row][col-1]&SCOREMASK;
|
jpayne@68
|
625 final int scoreFromDel=packed[MODE_DEL][row][col-1]&SCOREMASK;
|
jpayne@68
|
626
|
jpayne@68
|
627 int scoreMS=scoreFromDiag+POINTSoff_DEL;
|
jpayne@68
|
628 int scoreD=scoreFromDel+delScoreArray[streak];
|
jpayne@68
|
629 // int scoreI=scoreFromIns+POINTSoff_DEL;
|
jpayne@68
|
630
|
jpayne@68
|
631 if(ref1=='N'){
|
jpayne@68
|
632 scoreMS+=POINTSoff_DEL_REF_N;
|
jpayne@68
|
633 scoreD+=POINTSoff_DEL_REF_N;
|
jpayne@68
|
634 }
|
jpayne@68
|
635
|
jpayne@68
|
636 //if(match){scoreMS=subfloor;}
|
jpayne@68
|
637
|
jpayne@68
|
638 int score;
|
jpayne@68
|
639 int time;
|
jpayne@68
|
640 byte prevState;
|
jpayne@68
|
641 if(scoreMS>=scoreD){
|
jpayne@68
|
642 score=scoreMS;
|
jpayne@68
|
643 time=1;
|
jpayne@68
|
644 prevState=MODE_MS;
|
jpayne@68
|
645 }else{
|
jpayne@68
|
646 score=scoreD;
|
jpayne@68
|
647 time=streak+1;
|
jpayne@68
|
648 prevState=MODE_DEL;
|
jpayne@68
|
649 }
|
jpayne@68
|
650
|
jpayne@68
|
651 assert(time<=MAX_TIME);//if(time>MAX_TIME){time=MAX_TIME-3;}
|
jpayne@68
|
652 assert(score>=MINoff_SCORE) : "Score overflow - use MSA2 instead";
|
jpayne@68
|
653 assert(score<=MAXoff_SCORE) : "Score overflow - use MSA2 instead";
|
jpayne@68
|
654 // packed[MODE_DEL][row][col]=(score|prevState|time);
|
jpayne@68
|
655 packed[MODE_DEL][row][col]=(score|time);
|
jpayne@68
|
656 assert((score&SCOREMASK)==score);
|
jpayne@68
|
657 // assert((prevState&MODEMASK)==prevState);
|
jpayne@68
|
658 assert((time&TIMEMASK)==time);
|
jpayne@68
|
659 }
|
jpayne@68
|
660
|
jpayne@68
|
661 {//Calculate INS score
|
jpayne@68
|
662
|
jpayne@68
|
663 final int streak=packed[MODE_INS][row-1][col]&TIMEMASK;
|
jpayne@68
|
664
|
jpayne@68
|
665 final int scoreFromDiag=packed[MODE_MS][row-1][col]&SCOREMASK;
|
jpayne@68
|
666 final int scoreFromIns=packed[MODE_INS][row-1][col]&SCOREMASK;
|
jpayne@68
|
667
|
jpayne@68
|
668 int scoreMS=scoreFromDiag+POINTSoff_INS;
|
jpayne@68
|
669 // int scoreD=scoreFromDel+POINTSoff_INS;
|
jpayne@68
|
670 int scoreI=scoreFromIns+insScoreArray[streak];
|
jpayne@68
|
671
|
jpayne@68
|
672 // System.err.println("("+row+","+col+")\t"+scoreFromDiag+"+"+POINTSoff_INS+"="+scoreM+", "+
|
jpayne@68
|
673 // scoreFromSub+"+"+POINTSoff_INS+"="+scoreS+", "
|
jpayne@68
|
674 // +scoreD+", "+scoreFromIns+"+"+
|
jpayne@68
|
675 // (streak==0 ? POINTSoff_INS : streak<LIMIT_FOR_COST_3 ? POINTSoff_INS2 : POINTSoff_INS3)+"="+scoreI);
|
jpayne@68
|
676
|
jpayne@68
|
677 //if(match){scoreMS=subfloor;}
|
jpayne@68
|
678
|
jpayne@68
|
679 int score;
|
jpayne@68
|
680 int time;
|
jpayne@68
|
681 byte prevState;
|
jpayne@68
|
682 if(scoreMS>=scoreI){
|
jpayne@68
|
683 score=scoreMS;
|
jpayne@68
|
684 time=1;
|
jpayne@68
|
685 prevState=MODE_MS;
|
jpayne@68
|
686 }else{
|
jpayne@68
|
687 score=scoreI;
|
jpayne@68
|
688 time=streak+1;
|
jpayne@68
|
689 prevState=MODE_INS;
|
jpayne@68
|
690 }
|
jpayne@68
|
691
|
jpayne@68
|
692 assert(time<=MAX_TIME);//if(time>MAX_TIME){time=MAX_TIME-3;}
|
jpayne@68
|
693 assert(score>=MINoff_SCORE) : "Score overflow - use MSA2 instead";
|
jpayne@68
|
694 assert(score<=MAXoff_SCORE) : "Score overflow - use MSA2 instead";
|
jpayne@68
|
695 // packed[MODE_INS][row][col]=(score|prevState|time);
|
jpayne@68
|
696 packed[MODE_INS][row][col]=(score|time);
|
jpayne@68
|
697 assert((score&SCOREMASK)==score);
|
jpayne@68
|
698 // assert((prevState&MODEMASK)==prevState);
|
jpayne@68
|
699 assert((time&TIMEMASK)==time);
|
jpayne@68
|
700 }
|
jpayne@68
|
701 }
|
jpayne@68
|
702 }
|
jpayne@68
|
703
|
jpayne@68
|
704
|
jpayne@68
|
705 int maxCol=-1;
|
jpayne@68
|
706 int maxState=-1;
|
jpayne@68
|
707 int maxScore=Integer.MIN_VALUE;
|
jpayne@68
|
708
|
jpayne@68
|
709 for(int state=0; state<packed.length; state++){
|
jpayne@68
|
710 for(int col=1; col<=columns; col++){
|
jpayne@68
|
711 int x=packed[state][rows][col]&SCOREMASK;
|
jpayne@68
|
712 if(x>maxScore){
|
jpayne@68
|
713 maxScore=x;
|
jpayne@68
|
714 maxCol=col;
|
jpayne@68
|
715 maxState=state;
|
jpayne@68
|
716 }
|
jpayne@68
|
717 }
|
jpayne@68
|
718 }
|
jpayne@68
|
719 maxScore>>=SCOREOFFSET;
|
jpayne@68
|
720
|
jpayne@68
|
721 // System.err.println("Returning "+rows+", "+maxCol+", "+maxState+", "+maxScore);
|
jpayne@68
|
722 return new int[] {rows, maxCol, maxState, maxScore};
|
jpayne@68
|
723 }
|
jpayne@68
|
724
|
jpayne@68
|
725
|
jpayne@68
|
726 /** Generates the match string */
|
jpayne@68
|
727 public final byte[] traceback(byte[] read, byte[] ref, int refStartLoc, int refEndLoc, int row, int col, int state){
|
jpayne@68
|
728 // assert(false);
|
jpayne@68
|
729 assert(refStartLoc<=refEndLoc) : refStartLoc+", "+refEndLoc;
|
jpayne@68
|
730 assert(row==rows);
|
jpayne@68
|
731
|
jpayne@68
|
732 byte[] out=new byte[row+col-1]; //TODO if an out of bound crash occurs, try removing the "-1".
|
jpayne@68
|
733 int outPos=0;
|
jpayne@68
|
734
|
jpayne@68
|
735 if(state==MODE_INS){
|
jpayne@68
|
736 //TODO ? Maybe not needed.
|
jpayne@68
|
737 }
|
jpayne@68
|
738
|
jpayne@68
|
739 while(row>0 && col>0){
|
jpayne@68
|
740
|
jpayne@68
|
741 // byte prev0=(byte)(packed[state][row][col]&MODEMASK);
|
jpayne@68
|
742
|
jpayne@68
|
743 final int time=packed[state][row][col]&TIMEMASK;
|
jpayne@68
|
744 final byte prev;
|
jpayne@68
|
745
|
jpayne@68
|
746 // System.err.println("state="+state+", prev="+prev+", row="+row+", col="+col+", score="+scores[state][row][col]);
|
jpayne@68
|
747
|
jpayne@68
|
748 if(state==MODE_MS){
|
jpayne@68
|
749 if(time>1){prev=(byte)state;}
|
jpayne@68
|
750 else{
|
jpayne@68
|
751 final int scoreFromDiag=packed[MODE_MS][row-1][col-1]&SCOREMASK;
|
jpayne@68
|
752 final int scoreFromDel=packed[MODE_DEL][row-1][col-1]&SCOREMASK;
|
jpayne@68
|
753 final int scoreFromIns=packed[MODE_INS][row-1][col-1]&SCOREMASK;
|
jpayne@68
|
754 if(scoreFromDiag>=scoreFromDel && scoreFromDiag>=scoreFromIns){prev=MODE_MS;}
|
jpayne@68
|
755 else if(scoreFromDel>=scoreFromIns){prev=MODE_DEL;}
|
jpayne@68
|
756 else{prev=MODE_INS;}
|
jpayne@68
|
757 }
|
jpayne@68
|
758
|
jpayne@68
|
759 byte c=read[row-1];
|
jpayne@68
|
760 byte r=ref[refStartLoc+col-1];
|
jpayne@68
|
761 if(c==r){
|
jpayne@68
|
762 out[outPos]='m';
|
jpayne@68
|
763 }else{
|
jpayne@68
|
764 if(!AminoAcid.isFullyDefined(c)){
|
jpayne@68
|
765 out[outPos]='N';
|
jpayne@68
|
766 }else if(!AminoAcid.isFullyDefined(r)){
|
jpayne@68
|
767 // out[outPos]='X';
|
jpayne@68
|
768 out[outPos]='N';
|
jpayne@68
|
769 }else{
|
jpayne@68
|
770 out[outPos]='S';
|
jpayne@68
|
771 }
|
jpayne@68
|
772 }
|
jpayne@68
|
773
|
jpayne@68
|
774 row--;
|
jpayne@68
|
775 col--;
|
jpayne@68
|
776 }else if(state==MODE_DEL){
|
jpayne@68
|
777 if(time>1){prev=(byte)state;}
|
jpayne@68
|
778 else{
|
jpayne@68
|
779 final int scoreFromDiag=packed[MODE_MS][row][col-1]&SCOREMASK;
|
jpayne@68
|
780 final int scoreFromDel=packed[MODE_DEL][row][col-1]&SCOREMASK;
|
jpayne@68
|
781 if(scoreFromDiag>=scoreFromDel){prev=MODE_MS;}
|
jpayne@68
|
782 else{prev=MODE_DEL;}
|
jpayne@68
|
783 }
|
jpayne@68
|
784
|
jpayne@68
|
785 byte r=ref[refStartLoc+col-1];
|
jpayne@68
|
786 out[outPos]='D';
|
jpayne@68
|
787
|
jpayne@68
|
788 col--;
|
jpayne@68
|
789 }else{
|
jpayne@68
|
790 if(time>1){prev=(byte)state;}
|
jpayne@68
|
791 else{
|
jpayne@68
|
792 final int scoreFromDiag=packed[MODE_MS][row-1][col]&SCOREMASK;
|
jpayne@68
|
793 final int scoreFromIns=packed[MODE_INS][row-1][col]&SCOREMASK;
|
jpayne@68
|
794 if(scoreFromDiag>=scoreFromIns){prev=MODE_MS;}
|
jpayne@68
|
795 else{prev=MODE_INS;}
|
jpayne@68
|
796 }
|
jpayne@68
|
797
|
jpayne@68
|
798 assert(state==MODE_INS) : state;
|
jpayne@68
|
799 if(col==0){
|
jpayne@68
|
800 out[outPos]='X';
|
jpayne@68
|
801 }else if(col>=columns){
|
jpayne@68
|
802 out[outPos]='Y';
|
jpayne@68
|
803 }else{
|
jpayne@68
|
804 out[outPos]='I';
|
jpayne@68
|
805 }
|
jpayne@68
|
806 row--;
|
jpayne@68
|
807 }
|
jpayne@68
|
808
|
jpayne@68
|
809 // assert(prev==prev0);
|
jpayne@68
|
810 state=prev;
|
jpayne@68
|
811 outPos++;
|
jpayne@68
|
812 }
|
jpayne@68
|
813
|
jpayne@68
|
814 assert(row==0 || col==0);
|
jpayne@68
|
815 if(col!=row){
|
jpayne@68
|
816 while(row>0){
|
jpayne@68
|
817 out[outPos]='X';
|
jpayne@68
|
818 outPos++;
|
jpayne@68
|
819 row--;
|
jpayne@68
|
820 col--;
|
jpayne@68
|
821 }
|
jpayne@68
|
822 if(col>0){
|
jpayne@68
|
823 //do nothing
|
jpayne@68
|
824 }
|
jpayne@68
|
825 }
|
jpayne@68
|
826
|
jpayne@68
|
827
|
jpayne@68
|
828 //Shrink and reverse the string
|
jpayne@68
|
829 byte[] out2=new byte[outPos];
|
jpayne@68
|
830 for(int i=0; i<outPos; i++){
|
jpayne@68
|
831 out2[i]=out[outPos-i-1];
|
jpayne@68
|
832 }
|
jpayne@68
|
833 out=null;
|
jpayne@68
|
834
|
jpayne@68
|
835 return out2;
|
jpayne@68
|
836 }
|
jpayne@68
|
837
|
jpayne@68
|
838 /** @return {score, bestRefStart, bestRefStop} */
|
jpayne@68
|
839 public final int[] score(final byte[] read, final byte[] ref, final int refStartLoc, final int refEndLoc,
|
jpayne@68
|
840 final int maxRow, final int maxCol, final int maxState){
|
jpayne@68
|
841
|
jpayne@68
|
842 int row=maxRow;
|
jpayne@68
|
843 int col=maxCol;
|
jpayne@68
|
844 int state=maxState;
|
jpayne@68
|
845
|
jpayne@68
|
846 assert(maxState>=0 && maxState<packed.length) :
|
jpayne@68
|
847 maxState+", "+maxRow+", "+maxCol+"\n"+new String(read)+"\n"+toString(ref, refStartLoc, refEndLoc);
|
jpayne@68
|
848 assert(maxRow>=0 && maxRow<packed[0].length) :
|
jpayne@68
|
849 maxState+", "+maxRow+", "+maxCol+"\n"+new String(read)+"\n"+toString(ref, refStartLoc, refEndLoc);
|
jpayne@68
|
850 assert(maxCol>=0 && maxCol<packed[0][0].length) :
|
jpayne@68
|
851 maxState+", "+maxRow+", "+maxCol+"\n"+new String(read)+"\n"+toString(ref, refStartLoc, refEndLoc);
|
jpayne@68
|
852
|
jpayne@68
|
853 int score=packed[maxState][maxRow][maxCol]&SCOREMASK; //Or zero, if it is to be recalculated
|
jpayne@68
|
854
|
jpayne@68
|
855 if(row<rows){
|
jpayne@68
|
856 int difR=rows-row;
|
jpayne@68
|
857 int difC=columns-col;
|
jpayne@68
|
858
|
jpayne@68
|
859 while(difR>difC){
|
jpayne@68
|
860 score+=POINTSoff_NOREF;
|
jpayne@68
|
861 difR--;
|
jpayne@68
|
862 }
|
jpayne@68
|
863
|
jpayne@68
|
864 row+=difR;
|
jpayne@68
|
865 col+=difR;
|
jpayne@68
|
866
|
jpayne@68
|
867 }
|
jpayne@68
|
868
|
jpayne@68
|
869 assert(refStartLoc<=refEndLoc);
|
jpayne@68
|
870 assert(row==rows);
|
jpayne@68
|
871
|
jpayne@68
|
872
|
jpayne@68
|
873 final int bestRefStop=refStartLoc+col-1;
|
jpayne@68
|
874
|
jpayne@68
|
875 while(row>0 && col>0){
|
jpayne@68
|
876 // System.err.println("state="+state+", row="+row+", col="+col);
|
jpayne@68
|
877
|
jpayne@68
|
878
|
jpayne@68
|
879
|
jpayne@68
|
880 // byte prev0=(byte)(packed[state][row][col]&MODEMASK);
|
jpayne@68
|
881
|
jpayne@68
|
882 final int time=packed[state][row][col]&TIMEMASK;
|
jpayne@68
|
883 final byte prev;
|
jpayne@68
|
884
|
jpayne@68
|
885 if(state==MODE_MS){
|
jpayne@68
|
886 if(time>1){prev=(byte)state;}
|
jpayne@68
|
887 else{
|
jpayne@68
|
888 final int scoreFromDiag=packed[MODE_MS][row-1][col-1]&SCOREMASK;
|
jpayne@68
|
889 final int scoreFromDel=packed[MODE_DEL][row-1][col-1]&SCOREMASK;
|
jpayne@68
|
890 final int scoreFromIns=packed[MODE_INS][row-1][col-1]&SCOREMASK;
|
jpayne@68
|
891 if(scoreFromDiag>=scoreFromDel && scoreFromDiag>=scoreFromIns){prev=MODE_MS;}
|
jpayne@68
|
892 else if(scoreFromDel>=scoreFromIns){prev=MODE_DEL;}
|
jpayne@68
|
893 else{prev=MODE_INS;}
|
jpayne@68
|
894 }
|
jpayne@68
|
895 row--;
|
jpayne@68
|
896 col--;
|
jpayne@68
|
897 }else if(state==MODE_DEL){
|
jpayne@68
|
898 if(time>1){prev=(byte)state;}
|
jpayne@68
|
899 else{
|
jpayne@68
|
900 final int scoreFromDiag=packed[MODE_MS][row][col-1]&SCOREMASK;
|
jpayne@68
|
901 final int scoreFromDel=packed[MODE_DEL][row][col-1]&SCOREMASK;
|
jpayne@68
|
902 if(scoreFromDiag>=scoreFromDel){prev=MODE_MS;}
|
jpayne@68
|
903 else{prev=MODE_DEL;}
|
jpayne@68
|
904 }
|
jpayne@68
|
905 col--;
|
jpayne@68
|
906 }else{
|
jpayne@68
|
907 assert(state==MODE_INS);
|
jpayne@68
|
908 if(time>1){prev=(byte)state;}
|
jpayne@68
|
909 else{
|
jpayne@68
|
910 final int scoreFromDiag=packed[MODE_MS][row-1][col]&SCOREMASK;
|
jpayne@68
|
911 final int scoreFromIns=packed[MODE_INS][row-1][col]&SCOREMASK;
|
jpayne@68
|
912 if(scoreFromDiag>=scoreFromIns){prev=MODE_MS;}
|
jpayne@68
|
913 else{prev=MODE_INS;}
|
jpayne@68
|
914 }
|
jpayne@68
|
915 row--;
|
jpayne@68
|
916 }
|
jpayne@68
|
917
|
jpayne@68
|
918 if(col<0){
|
jpayne@68
|
919 System.err.println(row);
|
jpayne@68
|
920 break; //prevents an out of bounds access
|
jpayne@68
|
921
|
jpayne@68
|
922 }
|
jpayne@68
|
923
|
jpayne@68
|
924 // assert(prev==prev0);
|
jpayne@68
|
925 state=prev;
|
jpayne@68
|
926
|
jpayne@68
|
927 // System.err.println("state2="+state+", row2="+row+", col2="+col+"\n");
|
jpayne@68
|
928 }
|
jpayne@68
|
929 // assert(false) : row+", "+col;
|
jpayne@68
|
930 if(row>col){
|
jpayne@68
|
931 col-=row;
|
jpayne@68
|
932 }
|
jpayne@68
|
933
|
jpayne@68
|
934 final int bestRefStart=refStartLoc+col;
|
jpayne@68
|
935
|
jpayne@68
|
936 score>>=SCOREOFFSET;
|
jpayne@68
|
937 int[] rvec;
|
jpayne@68
|
938 if(bestRefStart<refStartLoc || bestRefStop>refEndLoc){ //Suggest extra padding in cases of overflow
|
jpayne@68
|
939 int padLeft=Tools.max(0, refStartLoc-bestRefStart);
|
jpayne@68
|
940 int padRight=Tools.max(0, bestRefStop-refEndLoc);
|
jpayne@68
|
941 rvec=new int[] {score, bestRefStart, bestRefStop, padLeft, padRight};
|
jpayne@68
|
942 }else{
|
jpayne@68
|
943 rvec=new int[] {score, bestRefStart, bestRefStop};
|
jpayne@68
|
944 }
|
jpayne@68
|
945 return rvec;
|
jpayne@68
|
946 }
|
jpayne@68
|
947
|
jpayne@68
|
948
|
jpayne@68
|
949 /** Will not fill areas that cannot match minScore.
|
jpayne@68
|
950 * @return {score, bestRefStart, bestRefStop} */
|
jpayne@68
|
951 public final int[] fillAndScoreLimited(byte[] read, byte[] ref, int refStartLoc, int refEndLoc, int minScore){
|
jpayne@68
|
952 int a=Tools.max(0, refStartLoc);
|
jpayne@68
|
953 int b=Tools.min(ref.length-1, refEndLoc);
|
jpayne@68
|
954 assert(b>=a);
|
jpayne@68
|
955
|
jpayne@68
|
956 int[] score;
|
jpayne@68
|
957
|
jpayne@68
|
958 if(b-a>=maxColumns){
|
jpayne@68
|
959 System.err.println("Warning: Max alignment columns exceeded; restricting range. "+(b-a+1)+" > "+maxColumns);
|
jpayne@68
|
960 assert(false) : refStartLoc+", "+refEndLoc;
|
jpayne@68
|
961 b=Tools.min(ref.length-1, a+maxColumns-1);
|
jpayne@68
|
962 }
|
jpayne@68
|
963 int[] max=fillLimited(read, ref, a, b, minScore);
|
jpayne@68
|
964 score=(max==null ? null : score(read, ref, a, b, max[0], max[1], max[2]));
|
jpayne@68
|
965
|
jpayne@68
|
966 return score;
|
jpayne@68
|
967 }
|
jpayne@68
|
968
|
jpayne@68
|
969
|
jpayne@68
|
970
|
jpayne@68
|
971 public final static int scoreNoIndels(byte[] read, SiteScore ss){
|
jpayne@68
|
972 ChromosomeArray cha=Data.getChromosome(ss.chrom);
|
jpayne@68
|
973 return scoreNoIndels(read, cha.array, ss.start, ss);
|
jpayne@68
|
974 }
|
jpayne@68
|
975
|
jpayne@68
|
976 public final static int scoreNoIndels(byte[] read, final int chrom, final int refStart){
|
jpayne@68
|
977 ChromosomeArray cha=Data.getChromosome(chrom);
|
jpayne@68
|
978 return scoreNoIndels(read, cha.array, refStart, null);
|
jpayne@68
|
979 }
|
jpayne@68
|
980
|
jpayne@68
|
981 public final static int scoreNoIndels(byte[] read, SiteScore ss, byte[] baseScores){
|
jpayne@68
|
982 ChromosomeArray cha=Data.getChromosome(ss.chrom);
|
jpayne@68
|
983 return scoreNoIndels(read, cha.array, baseScores, ss.start, ss);
|
jpayne@68
|
984 }
|
jpayne@68
|
985
|
jpayne@68
|
986 public final static int scoreNoIndels(byte[] read, final int chrom, final int refStart, byte[] baseScores){
|
jpayne@68
|
987 ChromosomeArray cha=Data.getChromosome(chrom);
|
jpayne@68
|
988 return scoreNoIndels(read, cha.array, baseScores, refStart, null);
|
jpayne@68
|
989 }
|
jpayne@68
|
990
|
jpayne@68
|
991 public final static int scoreNoIndels(byte[] read, byte[] ref, final int refStart, final SiteScore ss){
|
jpayne@68
|
992
|
jpayne@68
|
993 int score=0;
|
jpayne@68
|
994 int mode=-1;
|
jpayne@68
|
995 int timeInMode=0;
|
jpayne@68
|
996
|
jpayne@68
|
997 //This block handles cases where the read runs outside the reference
|
jpayne@68
|
998 //Of course, padding the reference with 'N' would be better, but...
|
jpayne@68
|
999 int readStart=0;
|
jpayne@68
|
1000 int readStop=read.length;
|
jpayne@68
|
1001 final int refStop=refStart+read.length;
|
jpayne@68
|
1002 boolean semiperfect=true;
|
jpayne@68
|
1003 int norefs=0;
|
jpayne@68
|
1004
|
jpayne@68
|
1005 if(refStart<0){
|
jpayne@68
|
1006 readStart=0-refStart;
|
jpayne@68
|
1007 score+=POINTS_NOREF*readStart;
|
jpayne@68
|
1008 norefs+=readStart;
|
jpayne@68
|
1009 }
|
jpayne@68
|
1010 if(refStop>ref.length){
|
jpayne@68
|
1011 int dif=(refStop-ref.length);
|
jpayne@68
|
1012 readStop-=dif;
|
jpayne@68
|
1013 score+=POINTS_NOREF*dif;
|
jpayne@68
|
1014 norefs+=dif;
|
jpayne@68
|
1015 }
|
jpayne@68
|
1016
|
jpayne@68
|
1017 // if(refStart<0 || refStart+read.length>ref.length){return -99999;} //No longer needed.
|
jpayne@68
|
1018
|
jpayne@68
|
1019 for(int i=readStart; i<readStop; i++){
|
jpayne@68
|
1020 byte c=read[i];
|
jpayne@68
|
1021 byte r=ref[refStart+i];
|
jpayne@68
|
1022
|
jpayne@68
|
1023 if(c==r && c!='N'){
|
jpayne@68
|
1024 if(mode==MODE_MS){
|
jpayne@68
|
1025 timeInMode++;
|
jpayne@68
|
1026 score+=POINTS_MATCH2;
|
jpayne@68
|
1027 }else{
|
jpayne@68
|
1028 timeInMode=0;
|
jpayne@68
|
1029 score+=POINTS_MATCH;
|
jpayne@68
|
1030 }
|
jpayne@68
|
1031 mode=MODE_MS;
|
jpayne@68
|
1032 }else if(c<0 || c=='N'){
|
jpayne@68
|
1033 score+=POINTS_NOCALL;
|
jpayne@68
|
1034 semiperfect=false;
|
jpayne@68
|
1035 }else if(r<0 || r=='N'){
|
jpayne@68
|
1036 score+=POINTS_NOREF;
|
jpayne@68
|
1037 norefs++;
|
jpayne@68
|
1038 }else{
|
jpayne@68
|
1039 if(mode==MODE_SUB){timeInMode++;}
|
jpayne@68
|
1040 else{timeInMode=0;}
|
jpayne@68
|
1041
|
jpayne@68
|
1042 if(timeInMode==0){score+=POINTS_SUB;}
|
jpayne@68
|
1043 else if(timeInMode<LIMIT_FOR_COST_3){score+=POINTS_SUB2;}
|
jpayne@68
|
1044 else{score+=POINTS_SUB3;}
|
jpayne@68
|
1045 mode=MODE_SUB;
|
jpayne@68
|
1046 semiperfect=false;
|
jpayne@68
|
1047 }
|
jpayne@68
|
1048 }
|
jpayne@68
|
1049
|
jpayne@68
|
1050 if(semiperfect && ss!=null){ss.semiperfect=((ss.stop==ss.start+read.length-1) && (norefs<=read.length/2));}
|
jpayne@68
|
1051
|
jpayne@68
|
1052 return score;
|
jpayne@68
|
1053 }
|
jpayne@68
|
1054
|
jpayne@68
|
1055
|
jpayne@68
|
1056 public final static int scoreNoIndels(byte[] read, byte[] ref, byte[] baseScores, final int refStart, SiteScore ss){
|
jpayne@68
|
1057
|
jpayne@68
|
1058 int score=0;
|
jpayne@68
|
1059 int mode=-1;
|
jpayne@68
|
1060 int timeInMode=0;
|
jpayne@68
|
1061 int norefs=0;
|
jpayne@68
|
1062
|
jpayne@68
|
1063 //This block handles cases where the read runs outside the reference
|
jpayne@68
|
1064 //Of course, padding the reference with 'N' would be better, but...
|
jpayne@68
|
1065 int readStart=0;
|
jpayne@68
|
1066 int readStop=read.length;
|
jpayne@68
|
1067 final int refStop=refStart+read.length;
|
jpayne@68
|
1068 boolean semiperfect=true;
|
jpayne@68
|
1069
|
jpayne@68
|
1070 if(refStart<0){
|
jpayne@68
|
1071 readStart=0-refStart;
|
jpayne@68
|
1072 score+=POINTS_NOREF*readStart;
|
jpayne@68
|
1073 norefs+=readStart;
|
jpayne@68
|
1074 }
|
jpayne@68
|
1075 if(refStop>ref.length){
|
jpayne@68
|
1076 int dif=(refStop-ref.length);
|
jpayne@68
|
1077 readStop-=dif;
|
jpayne@68
|
1078 score+=POINTS_NOREF*dif;
|
jpayne@68
|
1079 norefs+=dif;
|
jpayne@68
|
1080 }
|
jpayne@68
|
1081
|
jpayne@68
|
1082 // if(refStart<0 || refStart+read.length>ref.length){return -99999;} //No longer needed.
|
jpayne@68
|
1083
|
jpayne@68
|
1084 for(int i=readStart; i<readStop; i++){
|
jpayne@68
|
1085 byte c=read[i];
|
jpayne@68
|
1086 byte r=ref[refStart+i];
|
jpayne@68
|
1087
|
jpayne@68
|
1088 if(c==r && c!='N'){
|
jpayne@68
|
1089 if(mode==MODE_MS){
|
jpayne@68
|
1090 timeInMode++;
|
jpayne@68
|
1091 score+=POINTS_MATCH2;
|
jpayne@68
|
1092 }else{
|
jpayne@68
|
1093 timeInMode=0;
|
jpayne@68
|
1094 score+=POINTS_MATCH;
|
jpayne@68
|
1095 }
|
jpayne@68
|
1096 score+=baseScores[i];
|
jpayne@68
|
1097 mode=MODE_MS;
|
jpayne@68
|
1098 }else if(c<0 || c=='N'){
|
jpayne@68
|
1099 score+=POINTS_NOCALL;
|
jpayne@68
|
1100 semiperfect=false;
|
jpayne@68
|
1101 }else if(r<0 || r=='N'){
|
jpayne@68
|
1102 score+=POINTS_NOREF;
|
jpayne@68
|
1103 norefs++;
|
jpayne@68
|
1104 }else{
|
jpayne@68
|
1105 if(mode==MODE_SUB){timeInMode++;}
|
jpayne@68
|
1106 else{timeInMode=0;}
|
jpayne@68
|
1107
|
jpayne@68
|
1108 if(timeInMode==0){score+=POINTS_SUB;}
|
jpayne@68
|
1109 else if(timeInMode<LIMIT_FOR_COST_3){score+=POINTS_SUB2;}
|
jpayne@68
|
1110 else{score+=POINTS_SUB3;}
|
jpayne@68
|
1111 mode=MODE_SUB;
|
jpayne@68
|
1112 semiperfect=false;
|
jpayne@68
|
1113 }
|
jpayne@68
|
1114 }
|
jpayne@68
|
1115
|
jpayne@68
|
1116 if(semiperfect && ss!=null){ss.semiperfect=((ss.stop==ss.start+read.length-1) && (norefs<=read.length/2));}
|
jpayne@68
|
1117 assert(Read.CHECKSITE(ss, read, -1));
|
jpayne@68
|
1118
|
jpayne@68
|
1119 return score;
|
jpayne@68
|
1120 }
|
jpayne@68
|
1121
|
jpayne@68
|
1122
|
jpayne@68
|
1123 public final static int scoreNoIndelsAndMakeMatchString(byte[] read, byte[] ref, byte[] baseScores, final int refStart, byte[][] matchReturn){
|
jpayne@68
|
1124 int score=0;
|
jpayne@68
|
1125 int mode=-1;
|
jpayne@68
|
1126 int timeInMode=0;
|
jpayne@68
|
1127
|
jpayne@68
|
1128 assert(refStart<=ref.length) : refStart+", "+ref.length;
|
jpayne@68
|
1129
|
jpayne@68
|
1130 //This block handles cases where the read runs outside the reference
|
jpayne@68
|
1131 //Of course, padding the reference with 'N' would be better, but...
|
jpayne@68
|
1132 int readStart=0;
|
jpayne@68
|
1133 int readStop=read.length;
|
jpayne@68
|
1134 final int refStop=refStart+read.length;
|
jpayne@68
|
1135 if(refStart<0){
|
jpayne@68
|
1136 readStart=0-refStart;
|
jpayne@68
|
1137 score+=POINTS_NOREF*readStart;
|
jpayne@68
|
1138 }
|
jpayne@68
|
1139 if(refStop>ref.length){
|
jpayne@68
|
1140 int dif=(refStop-ref.length);
|
jpayne@68
|
1141 System.err.println("dif="+dif+", ref.length="+ref.length+", refStop="+refStop);
|
jpayne@68
|
1142 readStop-=dif;
|
jpayne@68
|
1143 score+=POINTS_NOREF*dif;
|
jpayne@68
|
1144 }
|
jpayne@68
|
1145 assert(refStart+readStop<=ref.length) : "readStart="+readStart+", readStop="+readStop+
|
jpayne@68
|
1146 ", refStart="+refStart+", refStop="+refStop+", ref.length="+ref.length+", read.length="+read.length;
|
jpayne@68
|
1147
|
jpayne@68
|
1148 assert(matchReturn!=null);
|
jpayne@68
|
1149 assert(matchReturn.length==1);
|
jpayne@68
|
1150 if(matchReturn[0]==null || matchReturn[0].length!=read.length){
|
jpayne@68
|
1151 assert(matchReturn[0]==null || matchReturn[0].length<read.length) : matchReturn[0].length+"!="+read.length;
|
jpayne@68
|
1152 matchReturn[0]=new byte[read.length];
|
jpayne@68
|
1153 }
|
jpayne@68
|
1154 final byte[] match=matchReturn[0];
|
jpayne@68
|
1155
|
jpayne@68
|
1156 // if(refStart<0 || refStart+read.length>ref.length){return -99999;} //No longer needed.
|
jpayne@68
|
1157
|
jpayne@68
|
1158 for(int i=readStart; i<readStop; i++){
|
jpayne@68
|
1159 byte c=read[i];
|
jpayne@68
|
1160 byte r=ref[refStart+i];
|
jpayne@68
|
1161
|
jpayne@68
|
1162 assert(r!='.' && c!='.');
|
jpayne@68
|
1163
|
jpayne@68
|
1164 if(c==r && c!='N'){
|
jpayne@68
|
1165 if(mode==MODE_MS){
|
jpayne@68
|
1166 timeInMode++;
|
jpayne@68
|
1167 score+=POINTS_MATCH2;
|
jpayne@68
|
1168 }else{
|
jpayne@68
|
1169 timeInMode=0;
|
jpayne@68
|
1170 score+=POINTS_MATCH;
|
jpayne@68
|
1171 }
|
jpayne@68
|
1172 score+=baseScores[i];
|
jpayne@68
|
1173 match[i]='m';
|
jpayne@68
|
1174 mode=MODE_MS;
|
jpayne@68
|
1175 }else if(c<0 || c=='N'){
|
jpayne@68
|
1176 score+=POINTS_NOCALL;
|
jpayne@68
|
1177 match[i]='N';
|
jpayne@68
|
1178 }else if(r<0 || r=='N'){
|
jpayne@68
|
1179 score+=POINTS_NOREF;
|
jpayne@68
|
1180 // match[i]='m';
|
jpayne@68
|
1181 match[i]='N';
|
jpayne@68
|
1182 }else{
|
jpayne@68
|
1183 match[i]='S';
|
jpayne@68
|
1184 if(mode==MODE_SUB){timeInMode++;}
|
jpayne@68
|
1185 else{timeInMode=0;}
|
jpayne@68
|
1186
|
jpayne@68
|
1187 if(timeInMode==0){score+=POINTS_SUB;}
|
jpayne@68
|
1188 else if(timeInMode<LIMIT_FOR_COST_3){score+=POINTS_SUB2;}
|
jpayne@68
|
1189 else{score+=POINTS_SUB3;}
|
jpayne@68
|
1190 mode=MODE_SUB;
|
jpayne@68
|
1191 }
|
jpayne@68
|
1192 }
|
jpayne@68
|
1193
|
jpayne@68
|
1194 return score;
|
jpayne@68
|
1195 }
|
jpayne@68
|
1196
|
jpayne@68
|
1197
|
jpayne@68
|
1198 public final static int scoreNoIndelsAndMakeMatchString(byte[] read, byte[] ref, final int refStart, byte[][] matchReturn){
|
jpayne@68
|
1199 int score=0;
|
jpayne@68
|
1200 int mode=-1;
|
jpayne@68
|
1201 int timeInMode=0;
|
jpayne@68
|
1202
|
jpayne@68
|
1203 assert(refStart<=ref.length) : refStart+", "+ref.length;
|
jpayne@68
|
1204
|
jpayne@68
|
1205 //This block handles cases where the read runs outside the reference
|
jpayne@68
|
1206 //Of course, padding the reference with 'N' would be better, but...
|
jpayne@68
|
1207 int readStart=0;
|
jpayne@68
|
1208 int readStop=read.length;
|
jpayne@68
|
1209 final int refStop=refStart+read.length;
|
jpayne@68
|
1210 if(refStart<0){
|
jpayne@68
|
1211 readStart=0-refStart;
|
jpayne@68
|
1212 score+=POINTS_NOREF*readStart;
|
jpayne@68
|
1213 }
|
jpayne@68
|
1214 if(refStop>ref.length){
|
jpayne@68
|
1215 int dif=(refStop-ref.length);
|
jpayne@68
|
1216 System.err.println("dif="+dif+", ref.length="+ref.length+", refStop="+refStop);
|
jpayne@68
|
1217 readStop-=dif;
|
jpayne@68
|
1218 score+=POINTS_NOREF*dif;
|
jpayne@68
|
1219 }
|
jpayne@68
|
1220 assert(refStart+readStop<=ref.length) : "readStart="+readStart+", readStop="+readStop+
|
jpayne@68
|
1221 ", refStart="+refStart+", refStop="+refStop+", ref.length="+ref.length+", read.length="+read.length;
|
jpayne@68
|
1222
|
jpayne@68
|
1223 assert(matchReturn!=null);
|
jpayne@68
|
1224 assert(matchReturn.length==1);
|
jpayne@68
|
1225 if(matchReturn[0]==null || matchReturn[0].length!=read.length){
|
jpayne@68
|
1226 assert(matchReturn[0]==null || matchReturn[0].length<read.length) : matchReturn[0].length+"!="+read.length;
|
jpayne@68
|
1227 matchReturn[0]=new byte[read.length];
|
jpayne@68
|
1228 }
|
jpayne@68
|
1229 final byte[] match=matchReturn[0];
|
jpayne@68
|
1230
|
jpayne@68
|
1231 // if(refStart<0 || refStart+read.length>ref.length){return -99999;} //No longer needed.
|
jpayne@68
|
1232
|
jpayne@68
|
1233 for(int i=readStart; i<readStop; i++){
|
jpayne@68
|
1234 byte c=read[i];
|
jpayne@68
|
1235 byte r=ref[refStart+i];
|
jpayne@68
|
1236
|
jpayne@68
|
1237 assert(r!='.' && c!='.');
|
jpayne@68
|
1238
|
jpayne@68
|
1239 if(c==r && c!='N'){
|
jpayne@68
|
1240 if(mode==MODE_MS){
|
jpayne@68
|
1241 timeInMode++;
|
jpayne@68
|
1242 score+=POINTS_MATCH2;
|
jpayne@68
|
1243 }else{
|
jpayne@68
|
1244 timeInMode=0;
|
jpayne@68
|
1245 score+=POINTS_MATCH;
|
jpayne@68
|
1246 }
|
jpayne@68
|
1247 match[i]='m';
|
jpayne@68
|
1248 mode=MODE_MS;
|
jpayne@68
|
1249 }else if(c<0 || c=='N'){
|
jpayne@68
|
1250 score+=POINTS_NOCALL;
|
jpayne@68
|
1251 match[i]='N';
|
jpayne@68
|
1252 }else if(r<0 || r=='N'){
|
jpayne@68
|
1253 score+=POINTS_NOREF;
|
jpayne@68
|
1254 // match[i]='m';
|
jpayne@68
|
1255 match[i]='N';
|
jpayne@68
|
1256 }else{
|
jpayne@68
|
1257 match[i]='S';
|
jpayne@68
|
1258 if(mode==MODE_SUB){timeInMode++;}
|
jpayne@68
|
1259 else{timeInMode=0;}
|
jpayne@68
|
1260
|
jpayne@68
|
1261 if(timeInMode==0){score+=POINTS_SUB;}
|
jpayne@68
|
1262 else if(timeInMode<LIMIT_FOR_COST_3){score+=POINTS_SUB2;}
|
jpayne@68
|
1263 else{score+=POINTS_SUB3;}
|
jpayne@68
|
1264 mode=MODE_SUB;
|
jpayne@68
|
1265 }
|
jpayne@68
|
1266 }
|
jpayne@68
|
1267
|
jpayne@68
|
1268 return score;
|
jpayne@68
|
1269 }
|
jpayne@68
|
1270
|
jpayne@68
|
1271 public static final int maxQuality(int numBases){
|
jpayne@68
|
1272 return POINTS_MATCH+(numBases-1)*(POINTS_MATCH2);
|
jpayne@68
|
1273 }
|
jpayne@68
|
1274
|
jpayne@68
|
1275 public static final int maxQuality(byte[] baseScores){
|
jpayne@68
|
1276 return POINTS_MATCH+(baseScores.length-1)*(POINTS_MATCH2)+Tools.sumInt(baseScores);
|
jpayne@68
|
1277 }
|
jpayne@68
|
1278
|
jpayne@68
|
1279 public static final int maxImperfectScore(int numBases){
|
jpayne@68
|
1280 // int maxQ=maxQuality(numBases);
|
jpayne@68
|
1281 //// maxImperfectSwScore=maxQ-(POINTS_MATCH2+POINTS_MATCH2)+(POINTS_MATCH+POINTS_SUB);
|
jpayne@68
|
1282 // int maxI=maxQ+POINTS_DEL;
|
jpayne@68
|
1283 // maxI=Tools.max(maxI, maxQ+POINTS_INS-POINTS_MATCH2);
|
jpayne@68
|
1284 // maxI=Tools.min(maxI, maxQ-(POINTS_MATCH2+POINTS_MATCH2)+(POINTS_MATCH+POINTS_SUB));
|
jpayne@68
|
1285
|
jpayne@68
|
1286 int maxQ=maxQuality(numBases);
|
jpayne@68
|
1287 int maxI=maxQ+Tools.min(POINTS_DEL, POINTS_INS-POINTS_MATCH2);
|
jpayne@68
|
1288 assert(maxI<(maxQ-(POINTS_MATCH2+POINTS_MATCH2)+(POINTS_MATCH+POINTS_SUB)));
|
jpayne@68
|
1289 return maxI;
|
jpayne@68
|
1290 }
|
jpayne@68
|
1291
|
jpayne@68
|
1292 public static final int maxImperfectScore(byte[] baseScores){
|
jpayne@68
|
1293 // int maxQ=maxQuality(numBases);
|
jpayne@68
|
1294 //// maxImperfectSwScore=maxQ-(POINTS_MATCH2+POINTS_MATCH2)+(POINTS_MATCH+POINTS_SUB);
|
jpayne@68
|
1295 // int maxI=maxQ+POINTS_DEL;
|
jpayne@68
|
1296 // maxI=Tools.max(maxI, maxQ+POINTS_INS-POINTS_MATCH2);
|
jpayne@68
|
1297 // maxI=Tools.min(maxI, maxQ-(POINTS_MATCH2+POINTS_MATCH2)+(POINTS_MATCH+POINTS_SUB));
|
jpayne@68
|
1298
|
jpayne@68
|
1299 int maxQ=maxQuality(baseScores);
|
jpayne@68
|
1300 int maxI=maxQ+Tools.min(POINTS_DEL, POINTS_INS-POINTS_MATCH2);
|
jpayne@68
|
1301 assert(maxI<(maxQ-(POINTS_MATCH2+POINTS_MATCH2)+(POINTS_MATCH+POINTS_SUB)));
|
jpayne@68
|
1302 return maxI;
|
jpayne@68
|
1303 }
|
jpayne@68
|
1304
|
jpayne@68
|
1305 public static final String toString(int[] a){
|
jpayne@68
|
1306
|
jpayne@68
|
1307 int width=7;
|
jpayne@68
|
1308
|
jpayne@68
|
1309 StringBuilder sb=new StringBuilder((a.length+1)*width+2);
|
jpayne@68
|
1310 for(int num : a){
|
jpayne@68
|
1311 String s=" "+num;
|
jpayne@68
|
1312 int spaces=width-s.length();
|
jpayne@68
|
1313 assert(spaces>=0) : width+", "+s.length()+", "+s+", "+num+", "+spaces;
|
jpayne@68
|
1314 for(int i=0; i<spaces; i++){sb.append(' ');}
|
jpayne@68
|
1315 sb.append(s);
|
jpayne@68
|
1316 }
|
jpayne@68
|
1317
|
jpayne@68
|
1318 return sb.toString();
|
jpayne@68
|
1319 }
|
jpayne@68
|
1320
|
jpayne@68
|
1321 public static final String toTimePacked(int[] a){
|
jpayne@68
|
1322 int width=7;
|
jpayne@68
|
1323
|
jpayne@68
|
1324 StringBuilder sb=new StringBuilder((a.length+1)*width+2);
|
jpayne@68
|
1325 for(int num_ : a){
|
jpayne@68
|
1326 int num=num_&TIMEMASK;
|
jpayne@68
|
1327 String s=" "+num;
|
jpayne@68
|
1328 int spaces=width-s.length();
|
jpayne@68
|
1329 assert(spaces>=0) : width+", "+s.length()+", "+s+", "+num+", "+spaces;
|
jpayne@68
|
1330 for(int i=0; i<spaces; i++){sb.append(' ');}
|
jpayne@68
|
1331 sb.append(s);
|
jpayne@68
|
1332 }
|
jpayne@68
|
1333
|
jpayne@68
|
1334 return sb.toString();
|
jpayne@68
|
1335 }
|
jpayne@68
|
1336
|
jpayne@68
|
1337 public static final String toScorePacked(int[] a){
|
jpayne@68
|
1338 int width=7;
|
jpayne@68
|
1339
|
jpayne@68
|
1340 String minString=" -";
|
jpayne@68
|
1341 String maxString=" ";
|
jpayne@68
|
1342 while(minString.length()<width){minString+='9';}
|
jpayne@68
|
1343 while(maxString.length()<width){maxString+='9';}
|
jpayne@68
|
1344
|
jpayne@68
|
1345 StringBuilder sb=new StringBuilder((a.length+1)*width+2);
|
jpayne@68
|
1346 for(int num_ : a){
|
jpayne@68
|
1347 int num=num_>>SCOREOFFSET;
|
jpayne@68
|
1348 String s=" "+num;
|
jpayne@68
|
1349 if(s.length()>width){s=num>0 ? maxString : minString;}
|
jpayne@68
|
1350 int spaces=width-s.length();
|
jpayne@68
|
1351 assert(spaces>=0) : width+", "+s.length()+", "+s+", "+num+", "+spaces;
|
jpayne@68
|
1352 for(int i=0; i<spaces; i++){sb.append(' ');}
|
jpayne@68
|
1353 sb.append(s);
|
jpayne@68
|
1354 }
|
jpayne@68
|
1355
|
jpayne@68
|
1356 return sb.toString();
|
jpayne@68
|
1357 }
|
jpayne@68
|
1358
|
jpayne@68
|
1359 public static final String toString(byte[] a){
|
jpayne@68
|
1360
|
jpayne@68
|
1361 int width=6;
|
jpayne@68
|
1362
|
jpayne@68
|
1363 StringBuilder sb=new StringBuilder((a.length+1)*width+2);
|
jpayne@68
|
1364 for(int num : a){
|
jpayne@68
|
1365 String s=" "+num;
|
jpayne@68
|
1366 int spaces=width-s.length();
|
jpayne@68
|
1367 assert(spaces>=0);
|
jpayne@68
|
1368 for(int i=0; i<spaces; i++){sb.append(' ');}
|
jpayne@68
|
1369 sb.append(s);
|
jpayne@68
|
1370 }
|
jpayne@68
|
1371
|
jpayne@68
|
1372 return sb.toString();
|
jpayne@68
|
1373 }
|
jpayne@68
|
1374
|
jpayne@68
|
1375 public static final String toString(byte[] ref, int startLoc, int stopLoc){
|
jpayne@68
|
1376 StringBuilder sb=new StringBuilder(stopLoc-startLoc+1);
|
jpayne@68
|
1377 for(int i=startLoc; i<=stopLoc; i++){sb.append((char)ref[i]);}
|
jpayne@68
|
1378 return sb.toString();
|
jpayne@68
|
1379 }
|
jpayne@68
|
1380
|
jpayne@68
|
1381 public static int calcDelScore(int len){
|
jpayne@68
|
1382 if(len<=0){return 0;}
|
jpayne@68
|
1383 int score=POINTS_DEL;
|
jpayne@68
|
1384
|
jpayne@68
|
1385 if(len>LIMIT_FOR_COST_4){
|
jpayne@68
|
1386 score+=(len-LIMIT_FOR_COST_4)*POINTS_DEL4;
|
jpayne@68
|
1387 len=LIMIT_FOR_COST_4;
|
jpayne@68
|
1388 }
|
jpayne@68
|
1389 if(len>LIMIT_FOR_COST_3){
|
jpayne@68
|
1390 score+=(len-LIMIT_FOR_COST_3)*POINTS_DEL3;
|
jpayne@68
|
1391 len=LIMIT_FOR_COST_3;
|
jpayne@68
|
1392 }
|
jpayne@68
|
1393 if(len>1){
|
jpayne@68
|
1394 score+=(len-1)*POINTS_DEL2;
|
jpayne@68
|
1395 }
|
jpayne@68
|
1396 return score;
|
jpayne@68
|
1397 }
|
jpayne@68
|
1398
|
jpayne@68
|
1399 private static int calcDelScoreOffset(int len){
|
jpayne@68
|
1400 if(len<=0){return 0;}
|
jpayne@68
|
1401 int score=POINTSoff_DEL;
|
jpayne@68
|
1402
|
jpayne@68
|
1403 if(len>LIMIT_FOR_COST_4){
|
jpayne@68
|
1404 score+=(len-LIMIT_FOR_COST_4)*POINTSoff_DEL4;
|
jpayne@68
|
1405 len=LIMIT_FOR_COST_4;
|
jpayne@68
|
1406 }
|
jpayne@68
|
1407 if(len>LIMIT_FOR_COST_3){
|
jpayne@68
|
1408 score+=(len-LIMIT_FOR_COST_3)*POINTSoff_DEL3;
|
jpayne@68
|
1409 len=LIMIT_FOR_COST_3;
|
jpayne@68
|
1410 }
|
jpayne@68
|
1411 if(len>1){
|
jpayne@68
|
1412 score+=(len-1)*POINTSoff_DEL2;
|
jpayne@68
|
1413 }
|
jpayne@68
|
1414 return score;
|
jpayne@68
|
1415 }
|
jpayne@68
|
1416
|
jpayne@68
|
1417 private static int calcMatchScoreOffset(int len){
|
jpayne@68
|
1418 if(len<=0){return 0;}
|
jpayne@68
|
1419 int score=POINTSoff_MATCH;
|
jpayne@68
|
1420
|
jpayne@68
|
1421 if(len>1){
|
jpayne@68
|
1422 score+=(len-1)*POINTSoff_MATCH2;
|
jpayne@68
|
1423 }
|
jpayne@68
|
1424 return score;
|
jpayne@68
|
1425 }
|
jpayne@68
|
1426
|
jpayne@68
|
1427 private static int calcSubScoreOffset(int len){
|
jpayne@68
|
1428 if(len<=0){return 0;}
|
jpayne@68
|
1429 int score=POINTSoff_SUB;
|
jpayne@68
|
1430
|
jpayne@68
|
1431 if(len>LIMIT_FOR_COST_3){
|
jpayne@68
|
1432 score+=(len-LIMIT_FOR_COST_3)*POINTSoff_SUB3;
|
jpayne@68
|
1433 len=LIMIT_FOR_COST_3;
|
jpayne@68
|
1434 }
|
jpayne@68
|
1435 if(len>1){
|
jpayne@68
|
1436 score+=(len-1)*POINTSoff_SUB2;
|
jpayne@68
|
1437 }
|
jpayne@68
|
1438 return score;
|
jpayne@68
|
1439 }
|
jpayne@68
|
1440
|
jpayne@68
|
1441 public static int calcInsScore(int len){
|
jpayne@68
|
1442 if(len<=0){return 0;}
|
jpayne@68
|
1443 int score=POINTS_INS;
|
jpayne@68
|
1444
|
jpayne@68
|
1445 if(len>LIMIT_FOR_COST_4){
|
jpayne@68
|
1446 score+=(len-LIMIT_FOR_COST_4)*POINTS_INS4;
|
jpayne@68
|
1447 len=LIMIT_FOR_COST_4;
|
jpayne@68
|
1448 }
|
jpayne@68
|
1449 if(len>LIMIT_FOR_COST_3){
|
jpayne@68
|
1450 score+=(len-LIMIT_FOR_COST_3)*POINTS_INS3;
|
jpayne@68
|
1451 len=LIMIT_FOR_COST_3;
|
jpayne@68
|
1452 }
|
jpayne@68
|
1453 if(len>1){
|
jpayne@68
|
1454 score+=(len-1)*POINTS_INS2;
|
jpayne@68
|
1455 }
|
jpayne@68
|
1456 return score;
|
jpayne@68
|
1457 }
|
jpayne@68
|
1458
|
jpayne@68
|
1459 private static int calcInsScoreOffset(int len){
|
jpayne@68
|
1460 if(len<=0){return 0;}
|
jpayne@68
|
1461 int score=POINTSoff_INS;
|
jpayne@68
|
1462 if(len>LIMIT_FOR_COST_4){
|
jpayne@68
|
1463 score+=(len-LIMIT_FOR_COST_4)*POINTSoff_INS4;
|
jpayne@68
|
1464 len=LIMIT_FOR_COST_4;
|
jpayne@68
|
1465 }
|
jpayne@68
|
1466 if(len>LIMIT_FOR_COST_3){
|
jpayne@68
|
1467 score+=(len-LIMIT_FOR_COST_3)*POINTSoff_INS3;
|
jpayne@68
|
1468 len=LIMIT_FOR_COST_3;
|
jpayne@68
|
1469 }
|
jpayne@68
|
1470 if(len>1){
|
jpayne@68
|
1471 score+=(len-1)*POINTSoff_INS2;
|
jpayne@68
|
1472 }
|
jpayne@68
|
1473 return score;
|
jpayne@68
|
1474 }
|
jpayne@68
|
1475
|
jpayne@68
|
1476
|
jpayne@68
|
1477 private final int maxRows;
|
jpayne@68
|
1478 private final int maxColumns;
|
jpayne@68
|
1479
|
jpayne@68
|
1480 private final int[][][] packed;
|
jpayne@68
|
1481
|
jpayne@68
|
1482 private final int[] vertLimit;
|
jpayne@68
|
1483 private final int[] horizLimit;
|
jpayne@68
|
1484
|
jpayne@68
|
1485 private final int[] insScoreArray;
|
jpayne@68
|
1486 private final int[] delScoreArray;
|
jpayne@68
|
1487 private final int[] matchScoreArray;
|
jpayne@68
|
1488 private final int[] subScoreArray;
|
jpayne@68
|
1489
|
jpayne@68
|
1490 CharSequence showVertLimit(){
|
jpayne@68
|
1491 StringBuilder sb=new StringBuilder();
|
jpayne@68
|
1492 for(int i=0; i<=rows; i++){sb.append(vertLimit[i]>>SCOREOFFSET).append(",");}
|
jpayne@68
|
1493 return sb;
|
jpayne@68
|
1494 }
|
jpayne@68
|
1495 CharSequence showHorizLimit(){
|
jpayne@68
|
1496 StringBuilder sb=new StringBuilder();
|
jpayne@68
|
1497 for(int i=0; i<=columns; i++){sb.append(horizLimit[i]>>SCOREOFFSET).append(",");}
|
jpayne@68
|
1498 return sb;
|
jpayne@68
|
1499 }
|
jpayne@68
|
1500
|
jpayne@68
|
1501 // public static final int MODEBITS=2;
|
jpayne@68
|
1502 public static final int TIMEBITS=12;
|
jpayne@68
|
1503 public static final int SCOREBITS=32-TIMEBITS;
|
jpayne@68
|
1504 public static final int MAX_TIME=((1<<TIMEBITS)-1);
|
jpayne@68
|
1505 public static final int MAX_SCORE=((1<<(SCOREBITS-1))-1)-2000;
|
jpayne@68
|
1506 public static final int MIN_SCORE=0-MAX_SCORE; //Keeps it 1 point above "BAD".
|
jpayne@68
|
1507
|
jpayne@68
|
1508 // public static final int MODEOFFSET=0; //Always zero.
|
jpayne@68
|
1509 // public static final int TIMEOFFSET=0;
|
jpayne@68
|
1510 public static final int SCOREOFFSET=TIMEBITS;
|
jpayne@68
|
1511
|
jpayne@68
|
1512 // public static final int MODEMASK=~((-1)<<MODEBITS);
|
jpayne@68
|
1513 // public static final int TIMEMASK=(~((-1)<<TIMEBITS))<<TIMEOFFSET;
|
jpayne@68
|
1514 public static final int TIMEMASK=~((-1)<<TIMEBITS);
|
jpayne@68
|
1515 public static final int SCOREMASK=(~((-1)<<SCOREBITS))<<SCOREOFFSET;
|
jpayne@68
|
1516
|
jpayne@68
|
1517 private static final byte MODE_MS=0;
|
jpayne@68
|
1518 private static final byte MODE_DEL=1;
|
jpayne@68
|
1519 private static final byte MODE_INS=2;
|
jpayne@68
|
1520 private static final byte MODE_SUB=3;
|
jpayne@68
|
1521
|
jpayne@68
|
1522 public static final int POINTS_NOREF=-10;
|
jpayne@68
|
1523 public static final int POINTS_NOCALL=-10;
|
jpayne@68
|
1524 public static final int POINTS_MATCH=90;
|
jpayne@68
|
1525 public static final int POINTS_MATCH2=100; //Note: Changing to 90 substantially reduces false positives
|
jpayne@68
|
1526 public static final int POINTS_COMPATIBLE=50;
|
jpayne@68
|
1527 public static final int POINTS_SUB=-143;
|
jpayne@68
|
1528 public static final int POINTS_SUBR=-161; //increased penalty if prior match streak was at most 1
|
jpayne@68
|
1529 public static final int POINTS_SUB2=-54;
|
jpayne@68
|
1530 public static final int POINTS_SUB3=-35;
|
jpayne@68
|
1531 public static final int POINTS_MATCHSUB=-10;
|
jpayne@68
|
1532 public static final int POINTS_INS=-207;
|
jpayne@68
|
1533 public static final int POINTS_INS2=-51;
|
jpayne@68
|
1534 public static final int POINTS_INS3=-37;
|
jpayne@68
|
1535 public static final int POINTS_INS4=-15;
|
jpayne@68
|
1536 public static final int POINTS_DEL=-273;
|
jpayne@68
|
1537 public static final int POINTS_DEL2=-38;
|
jpayne@68
|
1538 public static final int POINTS_DEL3=-27;
|
jpayne@68
|
1539 public static final int POINTS_DEL4=-15;
|
jpayne@68
|
1540 public static final int POINTS_DEL_REF_N=-10;
|
jpayne@68
|
1541
|
jpayne@68
|
1542
|
jpayne@68
|
1543 public static final int LIMIT_FOR_COST_3=5;
|
jpayne@68
|
1544 public static final int LIMIT_FOR_COST_4=30;
|
jpayne@68
|
1545
|
jpayne@68
|
1546 public static final int BAD=MIN_SCORE-1;
|
jpayne@68
|
1547
|
jpayne@68
|
1548
|
jpayne@68
|
1549 public static final int POINTSoff_NOREF=(POINTS_NOREF<<SCOREOFFSET);
|
jpayne@68
|
1550 public static final int POINTSoff_NOCALL=(POINTS_NOCALL<<SCOREOFFSET);
|
jpayne@68
|
1551 public static final int POINTSoff_MATCH=(POINTS_MATCH<<SCOREOFFSET);
|
jpayne@68
|
1552 public static final int POINTSoff_MATCH2=(POINTS_MATCH2<<SCOREOFFSET);
|
jpayne@68
|
1553 public static final int POINTSoff_COMPATIBLE=(POINTS_COMPATIBLE<<SCOREOFFSET);
|
jpayne@68
|
1554 public static final int POINTSoff_SUB=(POINTS_SUB<<SCOREOFFSET);
|
jpayne@68
|
1555 public static final int POINTSoff_SUBR=(POINTS_SUBR<<SCOREOFFSET);
|
jpayne@68
|
1556 public static final int POINTSoff_SUB2=(POINTS_SUB2<<SCOREOFFSET);
|
jpayne@68
|
1557 public static final int POINTSoff_SUB3=(POINTS_SUB3<<SCOREOFFSET);
|
jpayne@68
|
1558 public static final int POINTSoff_MATCHSUB=(POINTS_MATCHSUB<<SCOREOFFSET);
|
jpayne@68
|
1559 public static final int POINTSoff_INS=(POINTS_INS<<SCOREOFFSET);
|
jpayne@68
|
1560 public static final int POINTSoff_INS2=(POINTS_INS2<<SCOREOFFSET);
|
jpayne@68
|
1561 public static final int POINTSoff_INS3=(POINTS_INS3<<SCOREOFFSET);
|
jpayne@68
|
1562 public static final int POINTSoff_INS4=(POINTS_INS4<<SCOREOFFSET);
|
jpayne@68
|
1563 public static final int POINTSoff_DEL=(POINTS_DEL<<SCOREOFFSET);
|
jpayne@68
|
1564 public static final int POINTSoff_DEL2=(POINTS_DEL2<<SCOREOFFSET);
|
jpayne@68
|
1565 public static final int POINTSoff_DEL3=(POINTS_DEL3<<SCOREOFFSET);
|
jpayne@68
|
1566 public static final int POINTSoff_DEL4=(POINTS_DEL4<<SCOREOFFSET);
|
jpayne@68
|
1567 public static final int POINTSoff_DEL_REF_N=(POINTS_DEL_REF_N<<SCOREOFFSET);
|
jpayne@68
|
1568 public static final int BADoff=(BAD<<SCOREOFFSET);
|
jpayne@68
|
1569 public static final int MAXoff_SCORE=MAX_SCORE<<SCOREOFFSET;
|
jpayne@68
|
1570 public static final int MINoff_SCORE=MIN_SCORE<<SCOREOFFSET;
|
jpayne@68
|
1571
|
jpayne@68
|
1572 private int rows;
|
jpayne@68
|
1573 private int columns;
|
jpayne@68
|
1574
|
jpayne@68
|
1575 public long iterationsLimited=0;
|
jpayne@68
|
1576 public long iterationsUnlimited=0;
|
jpayne@68
|
1577
|
jpayne@68
|
1578 public boolean verbose=false;
|
jpayne@68
|
1579 public boolean verbose2=false;
|
jpayne@68
|
1580
|
jpayne@68
|
1581 }
|