File: BandedAligner.java

package info (click to toggle)
bbmap 38.90%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 21,520 kB
  • sloc: java: 265,882; sh: 14,954; python: 5,247; ansic: 2,074; perl: 96; xml: 38; makefile: 37
file content (172 lines) | stat: -rwxr-xr-x 5,872 bytes parent folder | download | duplicates (4)
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
166
167
168
169
170
171
172
package align2;

import java.util.Arrays;

import shared.Shared;
import shared.Tools;

/**
 * @author Brian Bushnell
 * @date Aug 5, 2013
 *
 */
public abstract class BandedAligner {
	
	public BandedAligner(int width_){
		maxWidth=Tools.max(width_, 3)|1;
		assert(maxWidth>=3) : "width<3 : "+width_+" -> "+maxWidth;
		assert(big>maxWidth/2);
	}
	
	public static final BandedAligner makeBandedAligner(int width_){
		//TODO: Remove the false condition when BandedAlignerJNI yields identical results to BandedAlignerConcrete.
		BandedAligner ba=((Shared.USE_JNI && false) ? new BandedAlignerJNI(width_) : new BandedAlignerConcrete(width_));
		return ba;
	}
	
	public final int alignQuadrupleProgressive(final byte[] query, final byte[] ref, int minEdits, int maxEdits, final boolean exact){
		maxEdits=Tools.min(maxEdits, Tools.max(query.length, ref.length));
		minEdits=Tools.min(minEdits, maxEdits);
		//System.err.println("maxEdits="+maxEdits+", "+minEdits);
		for(long i=minEdits, me=-1; me<maxEdits; i=i*4){
			me=Tools.min(i, maxEdits);
			if(me*2>maxEdits){me=maxEdits;}
			int edits=alignQuadruple(query, ref, (int)me, exact);
//			System.err.println("i="+i+", me="+me+", minEdits="+minEdits+", maxEdits="+maxEdits+", edits="+edits);
			if(edits<me){return edits;}
		}
		return maxEdits;
	}
	
	public final int alignQuadruple(final byte[] query, final byte[] ref, final int maxEdits, final boolean exact){
		final int a=alignForward(query, ref, 0, 0, maxEdits, exact);
		final int b=alignReverse(query, ref, query.length-1, ref.length-1, maxEdits, exact);
		final int me2=Tools.min(maxEdits, Tools.max(a, b));
		if(me2==0){return 0;}
		final int c=alignForwardRC(query, ref, query.length-1, 0, me2, exact);
		final int d=alignReverseRC(query, ref, 0, ref.length-1, me2, exact);
//		System.err.println("a="+a+", b="+b+", c="+c+", d="+d);
		return Tools.min(Tools.max(a, b), Tools.max(c, d));
	}
	
	public final int alignDouble(final byte[] query, final byte[] ref, final int maxEdits, final boolean exact){
		final int a=alignForward(query, ref, 0, 0, maxEdits, exact);
		if(a==0){return 0;}
		final int c=alignForwardRC(query, ref, query.length-1, 0, a, exact);
		return Tools.min(a, c);
	}
	
	/**
	 * @param query
	 * @param ref
	 * @param qstart
	 * @param rstart
	 * @return Edit distance
	 */
	public abstract int alignForward(final byte[] query, final byte[] ref, final int qstart, final int rstart, final int maxEdits, final boolean exact);
	
	/**
	 * @param query
	 * @param ref
	 * @param qstart
	 * @param rstart
	 * @return Edit distance
	 */
	public abstract int alignForwardRC(final byte[] query, final byte[] ref, final int qstart, final int rstart, final int maxEdits, final boolean exact);
	
	/**
	 * @param query
	 * @param ref
	 * @param qstart
	 * @param rstart
	 * @return Edit distance
	 */
	public abstract int alignReverse(final byte[] query, final byte[] ref, final int qstart, final int rstart, final int maxEdits, final boolean exact);
	
	/**
	 * @param query
	 * @param ref
	 * @param qstart
	 * @param rstart
	 * @return Edit distance
	 */
	public abstract int alignReverseRC(final byte[] query, final byte[] ref, final int qstart, final int rstart, final int maxEdits, final boolean exact);
	
	protected void fillBig(int[] array){
		final int lim=array.length-1;
		for(int i=1; i<lim; i++){array[i]=big;}
	}
	
	/** Score is lastRow-edits */
	public final int score(){
		return lastRow-lastEdits+1;
	}
	
	/** Position of min value in array (meaning the best alignment) relative to the middle of the array. */
	protected int lastOffset(int[] array, int halfWidth){
		final int center=halfWidth+1;
		int minLoc=center;
		for(int i=1; i<=halfWidth; i++){
			if(array[center+i]<array[minLoc]){minLoc=center+i;}
			if(array[center-i]<array[minLoc]){minLoc=center-i;}
		}
		return center-minLoc;
	}
	
	protected int penalizeOffCenter_old(int[] array, int halfWidth){
		if(verbose){
			System.err.println("penalizeOffCenter_old("+Arrays.toString(array)+", "+halfWidth);
		}
		final int center=halfWidth+1;
		int edits=array[center];
		for(int i=1; i<=halfWidth; i++){
			array[center+i]=Tools.min(big, array[center+i]+i);
			edits=Tools.min(edits, array[center+i]);
			array[center-i]=Tools.min(big, array[center-i]+i);
			edits=Tools.min(edits, array[center-i]);
		}
		if(verbose){
			System.err.println("returned "+edits);
		}
		return edits;
	}
	
	protected int penalizeOffCenter(int[] array, int halfWidth){
		if(verbose){
			System.err.println("penalizeOffCenter("+Arrays.toString(array)+", "+halfWidth);
		}
		final int center=halfWidth+1;
		int edits=array[center];
		for(int i=1; i<=halfWidth; i++){
			array[center+i]=Tools.min(big, Tools.max(i, array[center+i]));
			edits=Tools.min(edits, array[center+i]);
			array[center-i]=Tools.min(big, Tools.max(i, array[center-i]));
			edits=Tools.min(edits, array[center-i]);
		}
		if(verbose){
			System.err.println("returned "+edits);
		}
		return edits;
	}
	
	/** Final row aligned in last alignment. */
	public int lastRow;
	/** Final edits value in last alignment. */
	public int lastEdits;

	/** Position of min value in array (meaning the best alignment) relative to the middle of the array.
	 * Positive value is to the right (ref sequence longer than query), negative value left (ref shorter than query) */
	protected int lastOffset;
	
	public int lastRefLoc;
	public int lastQueryLoc;
	
	public final int maxWidth;
	
	public static final int big=99999999;
	public static boolean verbose=false;
	/** Penalizes non-length-neutral alignments.
	 * This causes query-to-ref alignment to yield same score as ref-to-query alignment, which is useful for assertions.  */
	public static boolean penalizeOffCenter=true;
	
}