annotate CSP2/CSP2_env/env-d9b9114564458d9d-741b3de822f2aaca6c6caa4325c4afce/opt/bbmap-39.01-1/current/bloom/KCountArray.java @ 68:5028fdace37b

planemo upload commit 2e9511a184a1ca667c7be0c6321a36dc4e3d116d
author jpayne
date Tue, 18 Mar 2025 16:23:26 -0400
parents
children
rev   line source
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 }