jpayne@68
|
1 package bloom;
|
jpayne@68
|
2
|
jpayne@68
|
3 import java.io.Serializable;
|
jpayne@68
|
4 import java.util.Locale;
|
jpayne@68
|
5 import java.util.concurrent.atomic.AtomicInteger;
|
jpayne@68
|
6 import java.util.concurrent.atomic.AtomicIntegerArray;
|
jpayne@68
|
7
|
jpayne@68
|
8 import dna.AminoAcid;
|
jpayne@68
|
9 import shared.Shared;
|
jpayne@68
|
10 import shared.Tools;
|
jpayne@68
|
11 import structures.ByteBuilder;
|
jpayne@68
|
12
|
jpayne@68
|
13 /**
|
jpayne@68
|
14 * @author Brian Bushnell
|
jpayne@68
|
15 * @date Jul 5, 2012
|
jpayne@68
|
16 */
|
jpayne@68
|
17 public abstract class KCountArray implements Serializable {
|
jpayne@68
|
18
|
jpayne@68
|
19 /**
|
jpayne@68
|
20 *
|
jpayne@68
|
21 */
|
jpayne@68
|
22 private static final long serialVersionUID = 1590374813059942002L;
|
jpayne@68
|
23
|
jpayne@68
|
24 public static KCountArray makeNew(long cells_, int cbits_){
|
jpayne@68
|
25 return makeNew(cells_, cbits_, 1);
|
jpayne@68
|
26 }
|
jpayne@68
|
27
|
jpayne@68
|
28 public static KCountArray makeNew(long cells_, int cbits_, int hashes_){
|
jpayne@68
|
29 return makeNew(cells_, cbits_, hashes_, null, 0);
|
jpayne@68
|
30 }
|
jpayne@68
|
31
|
jpayne@68
|
32 //TODO: Get rid of keys_ arg.
|
jpayne@68
|
33 public static KCountArray makeNew(long cells_, int cbits_, int hashes_, KCountArray prefilter, int prefilterLimit_){
|
jpayne@68
|
34 KCountArray kca=new KCountArray7MTA(cells_, cbits_, hashes_, prefilter, prefilterLimit_);
|
jpayne@68
|
35 kca.initialize();
|
jpayne@68
|
36 return kca;
|
jpayne@68
|
37 }
|
jpayne@68
|
38
|
jpayne@68
|
39 protected KCountArray(final long cells_, int cbits_){
|
jpayne@68
|
40 assert(cbits_<=32);
|
jpayne@68
|
41 assert(Integer.bitCount(cbits_)==1);
|
jpayne@68
|
42 assert(Long.bitCount(cells_)==1) || this.getClass()==KCountArray7MT.class : this.getClass();
|
jpayne@68
|
43
|
jpayne@68
|
44 numArrays=64;
|
jpayne@68
|
45 arrayBits=31-Integer.numberOfLeadingZeros(numArrays);
|
jpayne@68
|
46 arrayMask=numArrays-1;
|
jpayne@68
|
47
|
jpayne@68
|
48 while(cbits_*cells_<32*numArrays){
|
jpayne@68
|
49 assert(false) : cells_+", "+cbits_+", "+numArrays+", "+(cbits_*cells_)+"<"+(32*numArrays);
|
jpayne@68
|
50 cbits_*=2;
|
jpayne@68
|
51 } //Increases bits per cell so that at minimum each array is size 1
|
jpayne@68
|
52
|
jpayne@68
|
53 assert(cbits_<=32);
|
jpayne@68
|
54
|
jpayne@68
|
55 cells=cells_;
|
jpayne@68
|
56 cellBits=cbits_;
|
jpayne@68
|
57 valueMask=(cellBits==32 ? Integer.MAX_VALUE : ~((-1)<<cellBits));
|
jpayne@68
|
58 maxValue=min(Integer.MAX_VALUE, ~((-1)<<min(cellBits,31)));
|
jpayne@68
|
59 cellsPerWord=32/cellBits;
|
jpayne@68
|
60 indexShift=Integer.numberOfTrailingZeros(cellsPerWord);
|
jpayne@68
|
61 cellMask=cellsPerWord-1;
|
jpayne@68
|
62
|
jpayne@68
|
63 if(verbose){
|
jpayne@68
|
64 System.out.println(description());
|
jpayne@68
|
65 }
|
jpayne@68
|
66 }
|
jpayne@68
|
67
|
jpayne@68
|
68 protected KCountArray(final long cells_, int cbits_, int arrays_){
|
jpayne@68
|
69 assert(cbits_<=32);
|
jpayne@68
|
70 assert(Integer.bitCount(cbits_)==1);
|
jpayne@68
|
71 assert(Long.bitCount(cells_)==1) || this.getClass()==KCountArray7MT.class || this.getClass()==KCountArray7MTA.class || this.getClass()==KCountArray8MT.class;
|
jpayne@68
|
72
|
jpayne@68
|
73 numArrays=arrays_;
|
jpayne@68
|
74 assert(Integer.bitCount(numArrays)==1) : numArrays+", "+cells_+", "+cbits_;
|
jpayne@68
|
75 arrayBits=31-Integer.numberOfLeadingZeros(numArrays);
|
jpayne@68
|
76 arrayMask=numArrays-1;
|
jpayne@68
|
77
|
jpayne@68
|
78 while(cbits_*cells_<32*numArrays){
|
jpayne@68
|
79 assert(false) : cells_+", "+cbits_+", "+numArrays+", "+(cbits_*cells_)+"<"+(32*numArrays);
|
jpayne@68
|
80 cbits_*=2;
|
jpayne@68
|
81 } //Increases bits per cell so that at minimum each array is size 1
|
jpayne@68
|
82
|
jpayne@68
|
83 assert(cbits_<=32) : "Why?";
|
jpayne@68
|
84
|
jpayne@68
|
85 cells=cells_;
|
jpayne@68
|
86 cellBits=cbits_;
|
jpayne@68
|
87 valueMask=(cellBits==32 ? Integer.MAX_VALUE : ~((-1)<<cellBits));
|
jpayne@68
|
88 maxValue=min(Integer.MAX_VALUE, ~((-1)<<min(cellBits,31)));
|
jpayne@68
|
89 cellsPerWord=32/cellBits;
|
jpayne@68
|
90 indexShift=Integer.numberOfTrailingZeros(cellsPerWord);
|
jpayne@68
|
91 cellMask=cellsPerWord-1;
|
jpayne@68
|
92
|
jpayne@68
|
93 if(verbose){
|
jpayne@68
|
94 System.out.println(description());
|
jpayne@68
|
95 }
|
jpayne@68
|
96 }
|
jpayne@68
|
97
|
jpayne@68
|
98 public abstract int read(long key);
|
jpayne@68
|
99 public int read(long keys[]){throw new RuntimeException("Unimplemented.");}
|
jpayne@68
|
100 public final int read(long key, int k, boolean makeCanonical){return read(makeCanonical ? makeCanonical2(key, k) : key);}
|
jpayne@68
|
101
|
jpayne@68
|
102 public abstract void write(long key, int value);
|
jpayne@68
|
103
|
jpayne@68
|
104 //TODO: Consider adding a boolean for return old value.
|
jpayne@68
|
105 public final void increment(long key){increment(key, 1);}
|
jpayne@68
|
106 public final void decrement(long key){decrement(key, 1);}
|
jpayne@68
|
107
|
jpayne@68
|
108 /** Returns nothing for simplicity. */
|
jpayne@68
|
109 public abstract void increment(long key, int incr);
|
jpayne@68
|
110
|
jpayne@68
|
111 /** Returns unincremented value */
|
jpayne@68
|
112 public abstract int incrementAndReturnUnincremented(long key, int incr);
|
jpayne@68
|
113
|
jpayne@68
|
114 // /** Returns unincremented value */
|
jpayne@68
|
115 // public final int incrementAndReturnUnincremented(Kmer kmer, int incr){
|
jpayne@68
|
116 // return incrementAndReturnUnincremented(kmer.xor(), incr);
|
jpayne@68
|
117 // }
|
jpayne@68
|
118
|
jpayne@68
|
119 //For long kmers.
|
jpayne@68
|
120 public int incrementAndReturnUnincremented(long[] keys, int incr){
|
jpayne@68
|
121 throw new RuntimeException("Unimplemented.");
|
jpayne@68
|
122 }
|
jpayne@68
|
123
|
jpayne@68
|
124 /** Optional method. */
|
jpayne@68
|
125 public void decrement(long key, int incr){
|
jpayne@68
|
126 throw new RuntimeException("This class "+getClass().getName()+" does not support decrement.");
|
jpayne@68
|
127 }
|
jpayne@68
|
128
|
jpayne@68
|
129 public final int readPrecise(long key, int k, boolean makeCanonical){
|
jpayne@68
|
130 assert(k<=32);
|
jpayne@68
|
131 int b=read(makeCanonical ? makeCanonical2(key, k) : key);
|
jpayne@68
|
132 if(b<1){return b;}
|
jpayne@68
|
133 int a=readLeft(key, k, makeCanonical);
|
jpayne@68
|
134 if(a>=b){return b;}
|
jpayne@68
|
135 int c=readRight(key, k, makeCanonical);
|
jpayne@68
|
136 if(c>=b){return b;}
|
jpayne@68
|
137 return (int)(((long)a+(long)c)/2);
|
jpayne@68
|
138 // return max(a, c);
|
jpayne@68
|
139 // int mid=Tools.min(a, b, c);
|
jpayne@68
|
140 // System.out.println("a="+a+", b="+b+", c="+c+" -> "+mid);
|
jpayne@68
|
141 // return mid;
|
jpayne@68
|
142 }
|
jpayne@68
|
143
|
jpayne@68
|
144 public final int readPreciseMin(long key, int k, boolean makeCanonical){
|
jpayne@68
|
145 assert(k<=32);
|
jpayne@68
|
146 int b=read(makeCanonical ? makeCanonical2(key, k) : key);
|
jpayne@68
|
147 if(b<1){return b;}
|
jpayne@68
|
148 int a=readLeft(key, k, makeCanonical);
|
jpayne@68
|
149 if(a<1){return a;}
|
jpayne@68
|
150 int c=readRight(key, k, makeCanonical);
|
jpayne@68
|
151 return Tools.min(a, b, c);
|
jpayne@68
|
152 }
|
jpayne@68
|
153
|
jpayne@68
|
154 /**
|
jpayne@68
|
155 * @param key Kmer to evaluate
|
jpayne@68
|
156 * @return Sum of counts of all 4 possible left-adjacent kmers
|
jpayne@68
|
157 */
|
jpayne@68
|
158 public int readLeft(long key, int k, boolean makeCanonical){throw new RuntimeException("Unsupported.");}
|
jpayne@68
|
159 /**
|
jpayne@68
|
160 * @param key Kmer to evaluate
|
jpayne@68
|
161 * @return Sum of counts of all 4 possible right-adjacent kmers
|
jpayne@68
|
162 */
|
jpayne@68
|
163 public int readRight(long key, int k, boolean makeCanonical){throw new RuntimeException("Unsupported.");}
|
jpayne@68
|
164 /**
|
jpayne@68
|
165 * @param key Kmer to evaluate
|
jpayne@68
|
166 * @return Array of counts of all 4 possible left-adjacent kmers
|
jpayne@68
|
167 */
|
jpayne@68
|
168 public int[] readAllLeft(final long key, final int k, boolean makeCanonical, int[] rvec){throw new RuntimeException("Unsupported.");}
|
jpayne@68
|
169 /**
|
jpayne@68
|
170 * @param key Kmer to evaluate
|
jpayne@68
|
171 * @return Array of counts of all 4 possible right-adjacent kmers
|
jpayne@68
|
172 */
|
jpayne@68
|
173 public int[] readAllRight(final long key, final int k, boolean makeCanonical, int[] rvec){throw new RuntimeException("Unsupported.");}
|
jpayne@68
|
174
|
jpayne@68
|
175 public void increment(long[] keys){
|
jpayne@68
|
176 synchronized(this){
|
jpayne@68
|
177 for(long key : keys){
|
jpayne@68
|
178 increment(key);
|
jpayne@68
|
179 }
|
jpayne@68
|
180 }
|
jpayne@68
|
181 }
|
jpayne@68
|
182
|
jpayne@68
|
183 public abstract long[] transformToFrequency();
|
jpayne@68
|
184 public final long[] transformToFrequency(int[][] matrix){
|
jpayne@68
|
185 long[] freq=new long[100000];
|
jpayne@68
|
186 int maxFreq=freq.length-1;
|
jpayne@68
|
187
|
jpayne@68
|
188 if(cellBits!=32){
|
jpayne@68
|
189 assert(cellBits>0);
|
jpayne@68
|
190 for(int[] array : matrix){
|
jpayne@68
|
191 for(int i=0; i<array.length; i++){
|
jpayne@68
|
192 int word=array[i];
|
jpayne@68
|
193 int j=cellsPerWord;
|
jpayne@68
|
194 // System.out.println("initial: word = "+word+", j = "+Integer.toHexString(j)+", cellbits="+cellBits);
|
jpayne@68
|
195 for(; word!=0; j--){
|
jpayne@68
|
196 int x=word&valueMask;
|
jpayne@68
|
197 int x2=(int)min(x, maxFreq);
|
jpayne@68
|
198 freq[x2]++;
|
jpayne@68
|
199 word=(word>>>cellBits);
|
jpayne@68
|
200 // System.out.println("word = "+word+", j = "+Integer.toHexString(j)+", cellbits="+cellBits);
|
jpayne@68
|
201 }
|
jpayne@68
|
202 freq[0]+=j;
|
jpayne@68
|
203 }
|
jpayne@68
|
204 }
|
jpayne@68
|
205 }else{
|
jpayne@68
|
206 for(int[] array : matrix){
|
jpayne@68
|
207 for(int i=0; i<array.length; i++){
|
jpayne@68
|
208 int word=array[i];
|
jpayne@68
|
209 int x2=(int)min(word, maxFreq);
|
jpayne@68
|
210 freq[x2]++;
|
jpayne@68
|
211 }
|
jpayne@68
|
212 }
|
jpayne@68
|
213 }
|
jpayne@68
|
214 return freq;
|
jpayne@68
|
215 }
|
jpayne@68
|
216
|
jpayne@68
|
217 public final long[] transformToFrequency(AtomicIntegerArray[] matrix){
|
jpayne@68
|
218 long[] freq=new long[100000];
|
jpayne@68
|
219 int maxFreq=freq.length-1;
|
jpayne@68
|
220
|
jpayne@68
|
221 if(cellBits!=32){
|
jpayne@68
|
222 assert(cellBits>0);
|
jpayne@68
|
223 for(AtomicIntegerArray array : matrix){
|
jpayne@68
|
224 for(int i=0; i<array.length(); i++){
|
jpayne@68
|
225 int word=array.get(i);
|
jpayne@68
|
226 int j=cellsPerWord;
|
jpayne@68
|
227 // System.out.println("initial: word = "+word+", j = "+Integer.toHexString(j)+", cellbits="+cellBits);
|
jpayne@68
|
228 for(; word!=0; j--){
|
jpayne@68
|
229 int x=word&valueMask;
|
jpayne@68
|
230 int x2=(int)min(x, maxFreq);
|
jpayne@68
|
231 freq[x2]++;
|
jpayne@68
|
232 word=(word>>>cellBits);
|
jpayne@68
|
233 // System.out.println("word = "+word+", j = "+Integer.toHexString(j)+", cellbits="+cellBits);
|
jpayne@68
|
234 }
|
jpayne@68
|
235 freq[0]+=j;
|
jpayne@68
|
236 }
|
jpayne@68
|
237 }
|
jpayne@68
|
238 }else{
|
jpayne@68
|
239 for(AtomicIntegerArray array : matrix){
|
jpayne@68
|
240 for(int i=0; i<array.length(); i++){
|
jpayne@68
|
241 int word=array.get(i);
|
jpayne@68
|
242 int x2=(int)min(word, maxFreq);
|
jpayne@68
|
243 freq[x2]++;
|
jpayne@68
|
244 }
|
jpayne@68
|
245 }
|
jpayne@68
|
246 }
|
jpayne@68
|
247 return freq;
|
jpayne@68
|
248 }
|
jpayne@68
|
249
|
jpayne@68
|
250 public final ByteBuilder description(){
|
jpayne@68
|
251 ByteBuilder sb=new ByteBuilder();
|
jpayne@68
|
252 long words=cells/cellsPerWord;
|
jpayne@68
|
253 int wordsPerArray=(int)(words/numArrays);
|
jpayne@68
|
254 sb.append("cells: \t"+cells).append('\n');
|
jpayne@68
|
255 sb.append("cellBits:\t"+cellBits).append('\n');
|
jpayne@68
|
256 sb.append("valueMask:\t"+Long.toHexString(valueMask)).append('\n');
|
jpayne@68
|
257 sb.append("maxValue:\t"+maxValue).append('\n');
|
jpayne@68
|
258 sb.append("cellsPerWord:\t"+cellsPerWord).append('\n');
|
jpayne@68
|
259 sb.append("indexShift:\t"+indexShift).append('\n');
|
jpayne@68
|
260 sb.append("words: \t"+words).append('\n');
|
jpayne@68
|
261 sb.append("wordsPerArray:\t"+wordsPerArray).append('\n');
|
jpayne@68
|
262 sb.append("numArrays:\t"+numArrays).append('\n');
|
jpayne@68
|
263 sb.append("Memory: \t"+mem()).append('\n');
|
jpayne@68
|
264 sb.append("Usage: \t"+String.format(Locale.ROOT, "%.3f%%",usedFraction()*100));
|
jpayne@68
|
265 return sb;
|
jpayne@68
|
266 }
|
jpayne@68
|
267
|
jpayne@68
|
268 public final String toShortString(){
|
jpayne@68
|
269 return "mem = "+mem()+" \tcells = "+toKMG(cells)+" \tused = "+String.format(Locale.ROOT, "%.3f%%",usedFraction()*100);
|
jpayne@68
|
270 }
|
jpayne@68
|
271
|
jpayne@68
|
272 public final String toShortString(int hashes){
|
jpayne@68
|
273 return ("hashes = "+hashes+" \t ")+
|
jpayne@68
|
274 "mem = "+mem()+" \tcells = "+toKMG(cells)+" \tused = "+String.format(Locale.ROOT, "%.3f%%",usedFraction()*100);
|
jpayne@68
|
275 }
|
jpayne@68
|
276
|
jpayne@68
|
277 @Override
|
jpayne@68
|
278 public final String toString(){
|
jpayne@68
|
279 return description().toString();
|
jpayne@68
|
280 }
|
jpayne@68
|
281
|
jpayne@68
|
282 public abstract CharSequence toContentsString();
|
jpayne@68
|
283
|
jpayne@68
|
284 public abstract double usedFraction();
|
jpayne@68
|
285
|
jpayne@68
|
286 public abstract double usedFraction(int mindepth);
|
jpayne@68
|
287
|
jpayne@68
|
288 public abstract long cellsUsed(int mindepth);
|
jpayne@68
|
289
|
jpayne@68
|
290 public final double estimateUniqueKmers(int hashes){
|
jpayne@68
|
291 double f=usedFraction();
|
jpayne@68
|
292 double f2=(1-Math.pow(1-f, 1.0/hashes));
|
jpayne@68
|
293 double n=(-cells)*Math.log(1-f2);
|
jpayne@68
|
294 return n;
|
jpayne@68
|
295 }
|
jpayne@68
|
296
|
jpayne@68
|
297 public final double estimateUniqueKmers(int hashes, int mindepth){
|
jpayne@68
|
298 // assert(false) : this.getClass().getName();
|
jpayne@68
|
299 double f=usedFraction(mindepth);
|
jpayne@68
|
300 double f2=(1-Math.pow(1-f, 1.0/hashes));
|
jpayne@68
|
301 double n=(-cells)*Math.log(1-f2);
|
jpayne@68
|
302 return n;
|
jpayne@68
|
303 }
|
jpayne@68
|
304
|
jpayne@68
|
305 public final double estimateUniqueKmersFromUsedFraction(int hashes, double usedFraction){
|
jpayne@68
|
306 double f=usedFraction;
|
jpayne@68
|
307 double f2=(1-Math.pow(1-f, 1.0/hashes));
|
jpayne@68
|
308 double n=(-cells)*Math.log(1-f2);
|
jpayne@68
|
309 return n;
|
jpayne@68
|
310 }
|
jpayne@68
|
311
|
jpayne@68
|
312 public final String mem(){
|
jpayne@68
|
313 long mem=(cells*cellBits)/8;
|
jpayne@68
|
314 if(mem<(1<<20)){
|
jpayne@68
|
315 return (String.format(Locale.ROOT, "%.2f KB", mem*1d/(1<<10)));
|
jpayne@68
|
316 }else if(mem<(1<<30)){
|
jpayne@68
|
317 return (String.format(Locale.ROOT, "%.2f MB", mem*1d/(1<<20)));
|
jpayne@68
|
318 }else{
|
jpayne@68
|
319 return (String.format(Locale.ROOT, "%.2f GB", mem*1d/(1<<30)));
|
jpayne@68
|
320 }
|
jpayne@68
|
321 }
|
jpayne@68
|
322
|
jpayne@68
|
323 public static String toKMG(long x){
|
jpayne@68
|
324 double div=1;
|
jpayne@68
|
325 String ext="";
|
jpayne@68
|
326 if(x>10000000000L){
|
jpayne@68
|
327 div=1000000000L;
|
jpayne@68
|
328 ext="B";
|
jpayne@68
|
329 }else if(x>10000000){
|
jpayne@68
|
330 div=1000000;
|
jpayne@68
|
331 ext="M";
|
jpayne@68
|
332 }else if(x>100000){
|
jpayne@68
|
333 div=1000;
|
jpayne@68
|
334 ext="K";
|
jpayne@68
|
335 }
|
jpayne@68
|
336 return String.format(Locale.ROOT, "%.2f", x/div)+ext;
|
jpayne@68
|
337 }
|
jpayne@68
|
338
|
jpayne@68
|
339 static final AtomicIntegerArray[] allocMatrix(final int numArrays, final int wordsPerArray){
|
jpayne@68
|
340 final AtomicIntegerArray[] matrix=new AtomicIntegerArray[numArrays];
|
jpayne@68
|
341 final AllocThread[] array=new AllocThread[Tools.min(Tools.max(Shared.threads()/2, 1), numArrays)];
|
jpayne@68
|
342 final AtomicInteger next=new AtomicInteger(0);
|
jpayne@68
|
343 for(int i=0; i<array.length; i++){
|
jpayne@68
|
344 array[i]=new AllocThread(matrix, next, wordsPerArray);
|
jpayne@68
|
345 }
|
jpayne@68
|
346 for(int i=0; i<array.length; i++){array[i].start();}
|
jpayne@68
|
347 for(AllocThread at : array){
|
jpayne@68
|
348 while(at.getState()!=Thread.State.TERMINATED){
|
jpayne@68
|
349 try {
|
jpayne@68
|
350 at.join();
|
jpayne@68
|
351 } catch (InterruptedException e) {
|
jpayne@68
|
352 // TODO Auto-generated catch block
|
jpayne@68
|
353 e.printStackTrace();
|
jpayne@68
|
354 }
|
jpayne@68
|
355 }
|
jpayne@68
|
356 }
|
jpayne@68
|
357 return matrix;
|
jpayne@68
|
358 }
|
jpayne@68
|
359
|
jpayne@68
|
360 private static class AllocThread extends Thread{
|
jpayne@68
|
361
|
jpayne@68
|
362 AllocThread(AtomicIntegerArray[] matrix_, AtomicInteger next_, int wordsPerArray_){
|
jpayne@68
|
363 matrix=matrix_;
|
jpayne@68
|
364 next=next_;
|
jpayne@68
|
365 wordsPerArray=wordsPerArray_;
|
jpayne@68
|
366 }
|
jpayne@68
|
367
|
jpayne@68
|
368 @Override
|
jpayne@68
|
369 public void run(){
|
jpayne@68
|
370 int x=next.getAndIncrement();
|
jpayne@68
|
371 while(x<matrix.length){
|
jpayne@68
|
372 matrix[x]=new AtomicIntegerArray(wordsPerArray);
|
jpayne@68
|
373 x=next.getAndIncrement();
|
jpayne@68
|
374 }
|
jpayne@68
|
375 }
|
jpayne@68
|
376
|
jpayne@68
|
377 private final AtomicIntegerArray[] matrix;
|
jpayne@68
|
378 private final AtomicInteger next;
|
jpayne@68
|
379 private final int wordsPerArray;
|
jpayne@68
|
380
|
jpayne@68
|
381 }
|
jpayne@68
|
382
|
jpayne@68
|
383
|
jpayne@68
|
384 // long hash(long x, int y){throw new RuntimeException("Not supported.");}
|
jpayne@68
|
385 abstract long hash(long x, int y);
|
jpayne@68
|
386
|
jpayne@68
|
387 public static final int min(int x, int y){return x<y ? x : y;}
|
jpayne@68
|
388 public static final int max(int x, int y){return x>y ? x : y;}
|
jpayne@68
|
389 public static final long min(long x, long y){return x<y ? x : y;}
|
jpayne@68
|
390 public static final long max(long x, long y){return x>y ? x : y;}
|
jpayne@68
|
391
|
jpayne@68
|
392 /** Any necessary initialization. */
|
jpayne@68
|
393 public void initialize(){}
|
jpayne@68
|
394
|
jpayne@68
|
395 /** Any necessary shutdown steps. */
|
jpayne@68
|
396 public void shutdown(){}
|
jpayne@68
|
397
|
jpayne@68
|
398 public final long cells;
|
jpayne@68
|
399 public final int cellBits;
|
jpayne@68
|
400 /** Originally this was different than valueMask in the case that valueMask was negative, but now they are the same. */
|
jpayne@68
|
401 public final int maxValue;
|
jpayne@68
|
402
|
jpayne@68
|
403 protected final int cellsPerWord;
|
jpayne@68
|
404 protected final int indexShift;
|
jpayne@68
|
405 protected final int cellMask;
|
jpayne@68
|
406 protected final int valueMask;
|
jpayne@68
|
407
|
jpayne@68
|
408 protected static int minArrays=calcMinArrays();
|
jpayne@68
|
409 protected final int arrayBits;
|
jpayne@68
|
410 protected final int numArrays;
|
jpayne@68
|
411 protected final int arrayMask;
|
jpayne@68
|
412
|
jpayne@68
|
413 public static boolean verbose=false;
|
jpayne@68
|
414
|
jpayne@68
|
415 private static final int calcMinArrays(){
|
jpayne@68
|
416 int x=Tools.max(Shared.threads(), 2);
|
jpayne@68
|
417 while(Integer.bitCount(x)!=1){x++;}
|
jpayne@68
|
418 return x;
|
jpayne@68
|
419 }
|
jpayne@68
|
420
|
jpayne@68
|
421 public static final boolean isCanonical(long key, int k){
|
jpayne@68
|
422 assert(k>3 && k<=32);
|
jpayne@68
|
423 long b=AminoAcid.reverseComplementBinaryFast(key, k);
|
jpayne@68
|
424 return key>=b;
|
jpayne@68
|
425 }
|
jpayne@68
|
426
|
jpayne@68
|
427 /** Assumes that the key is not canonical */
|
jpayne@68
|
428 public static final long makeCanonical(final long key, final int k){
|
jpayne@68
|
429 assert(k>3 && k<=32);
|
jpayne@68
|
430 // assert(!isCanonical(key, k));
|
jpayne@68
|
431 final long r=AminoAcid.reverseComplementBinaryFast(key, k);
|
jpayne@68
|
432 assert(r>=key);
|
jpayne@68
|
433 // assert(isCanonical(r, k));
|
jpayne@68
|
434 // assert(AminoAcid.reverseComplementBinaryFast(r, k)==key);
|
jpayne@68
|
435 return r;
|
jpayne@68
|
436 }
|
jpayne@68
|
437
|
jpayne@68
|
438
|
jpayne@68
|
439 public static final long makeCanonical2(final long key, final int k){
|
jpayne@68
|
440 assert(k>3 && k<=32);
|
jpayne@68
|
441 if(isCanonical(key, k)){return key;}
|
jpayne@68
|
442 long r=AminoAcid.reverseComplementBinaryFast(key, k);
|
jpayne@68
|
443 // assert(isCanonical(r, k)) : k+"\n"+Long.toBinaryString(key)+"\n"+Long.toBinaryString(r)+"\n"+Long.toBinaryString(AminoAcid.reverseComplementBinaryFast(r, k));
|
jpayne@68
|
444 // assert(AminoAcid.reverseComplementBinaryFast(r, k)==key) : k+"\n"+Long.toBinaryString(key)+"\n"+Long.toBinaryString(r)+"\n"+Long.toBinaryString(AminoAcid.reverseComplementBinaryFast(r, k));
|
jpayne@68
|
445 return r;
|
jpayne@68
|
446 }
|
jpayne@68
|
447
|
jpayne@68
|
448 public KCountArray prefilter(){
|
jpayne@68
|
449 throw new RuntimeException("TODO: Override");
|
jpayne@68
|
450 }
|
jpayne@68
|
451
|
jpayne@68
|
452 public void purgeFilter(){
|
jpayne@68
|
453 throw new RuntimeException("TODO: Override");
|
jpayne@68
|
454 }
|
jpayne@68
|
455
|
jpayne@68
|
456 /** Increases accuracy of overloaded multi-bit tables */
|
jpayne@68
|
457 public static boolean LOCKED_INCREMENT=false;
|
jpayne@68
|
458 public static boolean SET_LOCKED_INCREMENT=false;
|
jpayne@68
|
459
|
jpayne@68
|
460 }
|