package align2; import java.util.Arrays; import dna.AminoAcid; import dna.ChromosomeArray; public final class KeyRing { public static final void main(String[] args){ int len=Integer.parseInt(args[0]); float density=(float) Double.parseDouble(args[1]); int chunksize=13; if(args.length>2){chunksize=Integer.parseInt(args[2]);} byte[] qual=new byte[len]; Arrays.fill(qual, (byte)20); int[] offsets=KeyRing.makeOffsets(qual, chunksize, density, 2); System.out.println(Arrays.toString(offsets)); } public static final int[] makeKeys(String s, int[] offsets, int chunksize){ if(offsets==null){return null;} assert(chunksize>0 && chunksize<16); assert(offsets!=null) : s.length()+", "+s; int[] keys=new int[offsets.length]; // System.out.println(Arrays.toString(offsets)); for(int i=0; i0 && chunksize<16); assert(offsets!=null) : s.length+", "+new String(s); int[] keys=new int[offsets.length]; // System.out.println(Arrays.toString(offsets)); for(int i=0; i>(2*(chunksize-i-1))); temp=(temp&3); sb.append((char)AminoAcid.numberToBase[temp]); } String s=sb.toString(); assert(key==ChromosomeArray.toNumber(0, s.length()-1, s)) : Integer.toHexString(key)+" -> "+s+" != "+Integer.toHexString(ChromosomeArray.toNumber(0, s.length()-1, s)); return sb.toString(); } /* public static final int[] makeOffsets(int readlen, int blocksize, int overlap, int minKeysDesired){ assert(blocksize>0); assert(overlap=minKeysDesired){ // while(middles+20); // middles=(midslots/spacing); // } // } int middles=(midslots/spacing); if(middles0); //due to the escape conditions // float fspacing=midslots/(float)(middles+1); float fspacing=midslots/(float)(middles); assert(fspacing>=1); int[] offsets=new int[middles+2]; offsets[0]=0; offsets[offsets.length-1]=slots-1; for(int i=1; i<=middles; i++){ offsets[i]=Math.round(fspacing*i); } // System.out.println("readlen = \t"+readlen); // System.out.println("blocksize = \t"+blocksize); // System.out.println("overlap = \t"+overlap); // System.out.println("slots = \t"+slots); // System.out.println("midslots = \t"+midslots); // System.out.println("spacing = \t"+spacing); // System.out.println("middles = \t"+middles); // System.out.println("fspacing = \t"+fspacing); // System.out.println("Offsets = \t"+Arrays.toString(offsets)); return offsets; }*/ /** This is only useful for low-quality reads, with no-calls. Otherwise it just wastes time... */ public static final int[] reverseOffsets(final int[] offsetsP, final int k, final int readlen){ int[] offsetsM=new int[offsetsP.length]; for(int i=0; i=0); assert(x+k<=readlen); x=readlen-(x+k); assert(x>=0); assert(x+k<=readlen) : "\n"+Arrays.toString(offsetsP)+"\n"+Arrays.toString(offsetsM)+"\n"+i+"\n"+x+"\n"+readlen; offsetsM[i]=x; } return offsetsM; } public static final int[] makeOffsetsWithDensity(int readlen, int blocksize, float density, int minKeysDesired){ assert(blocksize>0); assert(density0); assert(blocksize<=readlen) : readlen+", "+blocksize+", "+density+", "+minKeysDesired; int slots=readlen-blocksize+1; int midslots=slots-2; int desired=(int)Math.ceil((readlen*density)/blocksize); assert(desired>=0); desired=Tools.max(minKeysDesired, desired); desired=Tools.min(slots, desired); if(slots==1 || desired==1){return new int[] {0};} if(desired==2){return new int[] {0, slots-1};} int middles=desired-2; assert(middles>0); //due to the escape conditions // float fspacing=midslots/(float)(middles+1); float fspacing=midslots/(float)(middles); assert(fspacing>=1); int[] offsets=new int[desired]; offsets[0]=0; offsets[offsets.length-1]=slots-1; for(int i=1; i<=middles; i++){ offsets[i]=Math.round(fspacing*i); } // System.out.println("readlen = \t"+readlen); // System.out.println("blocksize = \t"+blocksize); // System.out.println("overlap = \t"+overlap); // System.out.println("slots = \t"+slots); // System.out.println("midslots = \t"+midslots); // System.out.println("spacing = \t"+spacing); // System.out.println("middles = \t"+middles); // System.out.println("fspacing = \t"+fspacing); // System.out.println("Offsets = \t"+Arrays.toString(offsets)); return offsets; } public static final int[] makeOffsetsWithNumberOfKeys(int readlen, int blocksize, int maxKeys){ assert(maxKeys>0); // System.err.println("readlen, blocksize, maxKeys = "+readlen+","+blocksize+","+maxKeys); if(blocksize>readlen){return null;} int slots=readlen-blocksize+1; // System.err.println("slots = "+slots); if(slots==1 || maxKeys==1){return new int[] {slots/2};} if(slots==2 || maxKeys==2){return new int[] {0, slots-1};} if(slots==3 || maxKeys==3){return new int[] {0, slots/2, slots-1};} int midslots=slots-2; maxKeys=Tools.min(maxKeys, slots); int middles=Tools.min(maxKeys-2, midslots); // System.err.println("midslots = "+midslots); // System.err.println("middles = "+middles); assert(middles>0); //due to the escape conditions // float fspacing=midslots/(float)(middles+0); //Bad - leaves 2 adjacent keys at the end. float fspacing=midslots/(float)(middles+1f); fspacing=Tools.max(1f, fspacing); assert(fspacing>=1); int[] offsets=new int[middles+2]; offsets[0]=0; offsets[offsets.length-1]=slots-1; // for(int i=1; i<=middles; i++){ // offsets[i]=Math.round(fspacing*i); // } for(int i=1; i<=middles; i++){ offsets[i]=Math.round(fspacing*i); } if(middles>2){ offsets[1]=(int)fspacing; offsets[middles]=(int) Math.ceil(fspacing*middles); } // System.out.println("readlen = \t"+readlen); // System.out.println("blocksize = \t"+blocksize); //// System.out.println("overlap = \t"+overlap); // System.out.println("slots = \t"+slots); // System.out.println("midslots = \t"+midslots); //// System.out.println("spacing = \t"+spacing); // System.out.println("middles = \t"+middles); // System.out.println("fspacing = \t"+fspacing); // System.out.println("Offsets = \t"+Arrays.toString(offsets)); for(int i=1; i0); // assert(overlap=2); // // int slots=readlen-blocksize+1; // int midslots=slots-2; // int spacing=blocksize-overlap; // // if(slots<=minKeysDesired){return slots;} // if(slots<=spacing+1){return Tools.min(3, slots);} // // int middles=(midslots/spacing); // if(middles0); //due to the escape conditions // return middles+2; // } public static final int desiredKeysFromDensity(int readlen, int blocksize, float density, int minKeysDesired){ assert(blocksize>0); assert(density<=blocksize) : density+", "+blocksize; assert(density>0); assert(blocksize<=readlen) : readlen+", "+blocksize+", "+density+", "+minKeysDesired; int slots=readlen-blocksize+1; int desired=(int)Math.ceil((readlen*density)/blocksize); assert(desired>=0); desired=Tools.max(minKeysDesired, desired); desired=Tools.min(slots, desired); return desired; } public static final int[] makeOffsets(final int readlen, int blocksize, float density, int minKeysDesired){ assert(blocksize>0); assert(blocksize<=readlen) : readlen+", "+blocksize+", "+density+", "+minKeysDesired; if(readlen0) : readlen+","+blocksize+","+density+","+minKeysDesired+","+desiredKeys; int[] offsets=makeOffsetsWithNumberOfKeys(readlen, blocksize, desiredKeys); // System.out.println("desiredKeys="+desiredKeys+", actual="+(offsets==null ? 0 : offsets.length)); assert(offsets!=null) :readlen+","+blocksize+","+density+","+minKeysDesired+","+desiredKeys; return offsets; } public static final int[] makeOffsets(byte[] qual, int blocksize, float density, int minKeysDesired){ int readlen=qual.length; assert(blocksize>0); assert(blocksize<=readlen) : readlen+", "+blocksize+", "+density+", "+minKeysDesired; int left=0, right=readlen-1; for(int i=left, cntr=0; i=0 && cntr0){ for(int i=0; i=density); assert(blocksize>0); assert(blocksize<=readlen) : readlen+", "+blocksize+", "+density+", "+minKeysDesired; int left=0, right=readlen-blocksize; //This can be set as low as .90 for long reads, if qualities are accurate. final float errorLimit=KEEP_BAD_KEYS ? 2f : 0.94f; //Default: .95f while(left<=right && keyErrorProb[left]>errorLimit){left++;} while(right>=left && keyErrorProb[right]>errorLimit){right--;} // System.out.println("left="+left+", right="+right+", readlen="+readlen+", " + // "blocksize="+blocksize+", density="+density+", minKeysDesired="+minKeysDesired); if(right0){ for(int i=0; i=density); assert(blocksize>0); assert(blocksize<=readlen) : readlen+", "+blocksize+", "+density+", "+minKeysDesired; final int maxProbIndex=readlen-blocksize; // assert(maxProbIndex==keyErrorProb.length-1); assert(maxProbIndex<=keyErrorProb.length-1) : maxProbIndex+", "+keyErrorProb.length; int left=0, right=maxProbIndex; final float errorLimit2=KEEP_BAD_KEYS ? 2f : 0.9999f; //Default: .95f //This can be set as low as .90 for long reads, if qualities are accurate. final float errorLimit1=KEEP_BAD_KEYS ? 2f : (semiperfectmode ? 0.99f : 0.94f); //Default: .95f while(left<=right && keyErrorProb[left]>=errorLimit1){left++;} while(right>=left && keyErrorProb[right]>=errorLimit1){right--;} // System.out.println("Left="+left+", right="+right); int potentialKeys=0; for(int i=left; i<=right; i++){ if(keyErrorProb[i]