package shared; import java.io.File; import java.io.PrintStream; import java.io.PrintWriter; import java.io.StringWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.BitSet; import java.util.Collection; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.Locale; import java.util.Random; import java.util.concurrent.atomic.AtomicIntegerArray; import java.util.concurrent.atomic.AtomicLongArray; import java.util.regex.Pattern; import dna.AminoAcid; import dna.Data; import fileIO.ByteFile; import fileIO.FileFormat; import fileIO.ReadWrite; import sketch.Sketch; import stream.Read; import stream.ReadInputStream; import stream.SamLine; import stream.SiteScore; import structures.CoverageArray; import structures.IntHashSet; import structures.IntList; public final class Tools { public static void main(String[] args){ long[] array=new long[1000]; for(int i=0; i<10; i++){ for(int j=0; j...args){ if(args==null || args.length==0){return true;} ArrayList list=new ArrayList(); for(ArrayList als : args){ if(als!=null){ list.addAll(als); } } return testOutputFiles(overwrite, append, allowDuplicates, list.toArray(new String[list.size()])); } /** Checks for permission to overwrite files, and output name collisions. */ public static boolean testOutputFiles(boolean overwrite, boolean append, boolean allowDuplicates, String...args){ if(args==null || args.length==0){return true;} HashSet set=new HashSet(args.length*2); int terms=0; for(String s : args){ if(s!=null){ if(isOutputFileName(s)){ terms++; if(!overwrite && !append && new File(s).exists()){ assert(overwrite) : "File "+s+" exists and overwrite=false"; return false; } if(!allowDuplicates && set.contains(s)){ assert(false) : "Duplicate file "+s+" was specified for multiple output streams."; return false; } set.add(s); } } } return true; } /** Checks for permission to read files, and input name collisions. */ public static boolean testInputFiles(boolean allowDuplicates, boolean throwException, ArrayList...args){ if(args==null || args.length==0){return true;} ArrayList list=new ArrayList(); for(ArrayList als : args){ if(als!=null){ list.addAll(als); } } return testInputFiles(allowDuplicates, throwException, list.toArray(new String[list.size()])); } /** Checks for permission to read files, and input name collisions. */ public static boolean testInputFiles(boolean allowDuplicates, boolean throwException, String[]...args){ if(args==null || args.length==0){return true;} for(String[] s : args){ if(!testInputFiles(allowDuplicates, throwException, s)){return false;} } return true; } /** Checks for permission to read files, and input name collisions. */ public static boolean testInputFilesALA(boolean allowDuplicates, boolean throwException, ArrayList list1, ArrayList list2, String...args){ ArrayList list3=new ArrayList(); if(list1!=null){list3.addAll(list1);} if(list2!=null){list3.addAll(list2);} if(args!=null){for(String s : args){list3.add(s);}} return testInputFiles(allowDuplicates, throwException, list3.toArray(new String[0])); } /** Checks for permission to read files, and input name collisions. */ public static boolean testInputFiles(boolean allowDuplicates, boolean throwException, String...args){ if(args==null || args.length==0){return true;} HashSet set=new HashSet(args.length*2); int terms=0; for(String s : args){ if(s!=null){ String s2=s.toLowerCase(); if(canRead(s)){ terms++; }else{ if(throwException){throw new RuntimeException("Can't read file '"+s+"'");} return false; } if(!allowDuplicates && set.contains(s2)){ if(throwException){throw new RuntimeException("Duplicate file "+s+" was specified for multiple input streams.");} return false; } set.add(s2); } } return true; } /** Checks for permission to overwrite files, and output name collisions. */ public static boolean testForDuplicateFilesALA(boolean throwException, ArrayList list1, ArrayList list2, String...args){ ArrayList list3=new ArrayList(); if(list1!=null){list3.addAll(list1);} if(list2!=null){list3.addAll(list2);} if(args!=null){for(String s : args){list3.add(s);}} return testForDuplicateFiles(throwException, list3.toArray(new String[0])); } /** Checks for permission to overwrite files, and output name collisions. * @return True if no problems are detected */ public static boolean testForDuplicateFiles(boolean throwException, String...args){ if(args==null || args.length==0){return true;} HashSet set=new HashSet(args.length*2); int terms=0; for(String s0 : args){ if(s0!=null){ String s=s0.toLowerCase(); terms++; if(set.contains(s) && !s.equals("stdout") && !s.startsWith("stdout.") && !s.equals("stderr") && !s.startsWith("stderr.")){ if(throwException){throw new RuntimeException("File '"+s0+"' was specified multiple times.");} return false; } set.add(s); } } return true; } public static final boolean canWrite(String s, boolean overwrite){ if(isNullFileName(s) || isSpecialOutputName(s)){return true;} File f=new File(s); if(f.exists()){return overwrite && f.canWrite();} return true; } // public static final boolean outputDestinationExists(String s){ // if(isNullFileName(s)){return false;} // if(isSpecialOutputName(s)){return false;} // File f=new File(s); // return f.exists(); // } public static final boolean isOutputFileName(String s){ return !(isNullFileName(s) || isSpecialOutputName(s)); } public static final boolean isNullFileName(String s){ if(s==null || s.equalsIgnoreCase("null") || s.equalsIgnoreCase("none")){return true;} for(int i=0; i list){ if(b==null){ list.clear(); return true; } boolean added=false; boolean failed=false; if(b.indexOf(',')>0){ for(String s : b.split(",")){ boolean x=addFiles(s, list); added|=x; failed|=!x; } }else{ String s=b; if(b.indexOf('@')>0 && !new File(b).exists()){s=b.split("@")[0];} if(new File(s).exists() || s.equalsIgnoreCase("stdin") || s.toLowerCase().startsWith("stdin.")){ list.add(b); return true; }else{ return false; } } return added&!failed; } public static void fill(int[] target, int[] source) { for(int i=0; i fixExtension(ArrayList fnames){ if(!Shared.FIX_EXTENSIONS){return fnames;} if(fnames==null){return fnames;} for(int i=0; i split(byte[] line, int start, byte delimiter) { if(line.length list=new ArrayList(8); while(b list, final int max, int min, final PrintStream outstream){ if(!containsReadsOutsideSizeRange(list, min, max)){return;} assert(max>0 || min>0) : "min or max read length must be positive."; assert(max<1 || max>=min) : "max read length must be at least min read length: "+max+"<"+min; min=Tools.max(0, min); ArrayList temp=new ArrayList(list.size()*2); for(Read r : list){ if(r==null || r.bases==null){ temp.add(r); }else if(r.length() list, int size){ for(Read r : list){ if(r!=null && r.bases!=null){ if(r.length()>size){ assert(r.mate==null) : "Read of length "+r.length()+">"+size+". Paired input is incompatible with 'breaklength'"; return true; } } } return false; } private static boolean containsReadsOutsideSizeRange(ArrayList list, int min, int max){ for(Read r : list){ if(r!=null && r.bases!=null){ if((max>0 && r.length()>max) || r.length()=0; i--, j--){ array[j]=array[i]; } } public static void shiftLeft(final byte[] array, final int amt){ for(int i=amt, j=0; ierror; i++){ guess=guess+dif*0.9; y2=actualToObservedCoverage(guess); dif=y-y2; } return guess; } /** Derived from curve-fitting simulated data. * Yields actual kmer coverage from observed kmer coverage. * Not perfectly accurate but the deviation is typically under 5%. */ public static double observedToActualCoverage(double y){ return Tools.max(0, y-Math.exp(-0.885*(y-1))); } /** Derived from curve-fitting simulated data. * Yields observed kmer coverage from actual kmer coverage. * Not perfectly accurate but the deviation is typically under 10%. */ private static double actualToObservedCoverage(double x){ return x+Math.exp(-0.597*x); } public static double kmerToReadCoverage(double cov, double readlen, int k){ return readlen<=k ? 0 : cov*readlen/(readlen-k+1); } public static double readToKmerCoverage(double cov, double readlen, int k){ return readlen<=k ? 0 : cov*(readlen-k+1)/readlen; } public static boolean isNumeric(String s) { if(s==null || s.length()<1){return false;} char first=s.charAt(0); int dots=0, signs=0, nums=0; if(first=='-'){signs++;} else if(first>='0' && first<='9'){nums++;} else if(first=='.'){dots++;} else{return false;} for(int i=1; i='0' && c<='9'){nums++;} else if(c=='.'){dots++;} else{return false;} } return nums>0 && dots<=1; } public static boolean isDigitOrSign(int c) {return c<0 ? false : signOrDigitMap[c];} public static boolean isNumeric(int c) {return c<0 ? false : numericMap[c];} public static boolean isDigit(int c) {return c>='0' && c<='9';} public static boolean isLetter(int c) {return c<0 ? false : letterMap[c];} public static boolean isLetterOrDigit(int c) {return c<0 ? false : isDigit(c) || letterMap[c];} public static boolean isUpperCase(int c) {return c>='A' && c<='Z';} public static boolean isLowerCase(int c) {return c>='a' && c<='z';} public static int toUpperCase(int c) {return c<'a' || c>'z' ? c : c-32;} public static int toLowerCase(int c) {return c<'A' || c>'Z' ? c : c+32;} public static boolean isDigitOrSign(byte c) {return c<0 ? false : signOrDigitMap[c];} public static boolean isNumeric(byte c) {return c<0 ? false : numericMap[c];} public static boolean isDigit(byte c) {return c>='0' && c<='9';} public static boolean isLetter(byte c) {return c<0 ? false : letterMap[c];} public static boolean isLetterOrDigit(byte c) {return c<0 ? false : isDigit(c) || letterMap[c];} public static boolean isUpperCase(byte c) {return c>='A' && c<='Z';} public static boolean isLowerCase(byte c) {return c>='a' && c<='z';} public static byte toUpperCase(byte c) {return c<'a' || c>'z' ? c : (byte)(c-32);} public static byte toLowerCase(byte c) {return c<'A' || c>'Z' ? c : (byte)(c+32);} public static boolean isDigitOrSign(char c) {return c>127 ? false : signOrDigitMap[c];} public static boolean isNumeric(char c) {return c>127 ? false : numericMap[c];} public static boolean isDigit(char c) {return c>='0' && c<='9';} public static boolean isLetter(char c) {return c>127 ? false : letterMap[c];} public static boolean isLetterOrDigit(char c) {return c<0 ? false : isDigit(c) || letterMap[c];} public static boolean isUpperCase(char c) {return c>='A' && c<='Z';} public static boolean isLowerCase(char c) {return c>='a' && c<='z';} public static char toUpperCase(char c) {return c<'a' || c>'z' ? c : (char)(c-32);} public static char toLowerCase(char c) {return c<'A' || c>'Z' ? c : (char)(c+32);} //Taken from https://stackoverflow.com/questions/1149703/how-can-i-convert-a-stack-trace-to-a-string public static String toString(Throwable t){ StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); t.printStackTrace(pw); String sStackTrace = sw.toString(); return sStackTrace; } public static int countKmers(byte[] bases, int k){ if(bases==null || bases.length=k){kmers=kmers+len-k+1;} len=0; } } if(len>=k){kmers=kmers+len-k+1;} return kmers; } public static double countCorrectKmers(byte[] quals, int k){ if(quals==null || quals.length0){ len++; prob=prob*align2.QualityTools.PROB_CORRECT[q]; if(len>k){ byte oldq=quals[i-k]; prob=prob*align2.QualityTools.PROB_CORRECT_INVERSE[oldq]; } if(len>=k){kmers+=prob;} }else{ len=0; prob=1; } } return kmers; } public static long estimateFileSize(String fname){ FileFormat ff=FileFormat.testInput(fname, FileFormat.FASTQ, null, false, false); if(ff==null || ff.stdio()){return -1;} double mult=1; if(ff.compressed()){ if(ff.bam()){mult=6;} if(ff.fasta()){mult=5;} else{mult=4;} } File f=new File(fname); long size=f.length(); double diskEstimate=size*mult; return (long)diskEstimate; } /** * @param fname * @param readsToFetch * @param extraOverheadPerRead * @param earlyExit * @return {memEstimate, diskEstimate, memRatio, diskRatio, numReadsEstimate}; */ public static double[] estimateFileMemory(String fname, int readsToFetch, double extraOverheadPerRead, boolean earlyExit, boolean lowComplexity){ FileFormat ff=FileFormat.testInput(fname, FileFormat.FASTQ, null, false, false); if(ff==null || ff.stdio()){return null;} File f=new File(fname); final long size=f.length(); if(earlyExit){ long available=Shared.memFree(); double memRatio, diskRatio, readRatio; if(ff.compressed()){ memRatio=40; diskRatio=5; }else{ memRatio=8; diskRatio=1; } readRatio=diskRatio/100; long memEstimate=(long)(memRatio*size); long diskEstimate=(long)(diskRatio*size); long readsEstimate=(long)(readRatio*size); // System.err.println(memEstimate+", "+available+", "+(memEstimate*1.5)+", "+readsEstimate+", "+(memEstimate*2.1 reads=ReadInputStream.toReads(ff, readsToFetch); long minBytes=Integer.MAX_VALUE; long maxBytes=1; long sumBytes=0; long minMem=Integer.MAX_VALUE; long maxMem=1; long sumMem=0; long minLen=Integer.MAX_VALUE; long maxLen=1; long sumLen=0; long minQLen=Integer.MAX_VALUE; long maxQLen=1; long sumQLen=0; long minHdr=Integer.MAX_VALUE; long maxHdr=1; long sumHdr=0; long readCount=0; BitSet qualities=new BitSet(); if(reads==null || reads.size()<1){ minBytes=maxBytes=minLen=maxLen=minMem=maxMem=minHdr=maxHdr=1; }else{ for(Read r1 : reads){ long x; readCount++; x=r1.length(); minLen=min(minLen, x); maxLen=max(maxLen, x); sumLen+=x; x=r1.qlength(); minQLen=min(minQLen, x); maxQLen=max(maxQLen, x); sumQLen+=x; if(x>0){ for(byte q : r1.quality){qualities.set(q);} } x=r1.countBytes(); minMem=min(minMem, x); maxMem=max(maxMem, x); sumMem+=x; x=r1.id.length(); minHdr=min(minHdr, x); maxHdr=max(maxHdr, x); sumHdr+=x; x=r1.countFastqBytes(); minBytes=min(minBytes, x); maxBytes=max(maxBytes, x); sumBytes+=x; Read r2=r1.mate; if(r2!=null){ readCount++; x=r2.length(); minLen=min(minLen, x); maxLen=max(maxLen, x); sumLen+=x; x=r2.qlength(); minQLen=min(minQLen, x); maxQLen=max(maxQLen, x); sumQLen+=x; if(x>0){ for(byte q : r2.quality){qualities.set(q);} } x=r2.countBytes(); minMem=min(minMem, x); maxMem=max(maxMem, x); sumMem+=x; x=r2.id.length(); minHdr=min(minHdr, x); maxHdr=max(maxHdr, x); sumHdr+=x; x=r2.countFastqBytes(); minBytes=min(minBytes, x); maxBytes=max(maxBytes, x); sumBytes+=x; } } } int numQualities=Tools.max(2, qualities.cardinality()); double bitsPerQuality=(Math.log(numQualities)/Math.log(2)); boolean binned=numQualities<=8; double compressedSize; if(ff.compressed()){ compressedSize=0.125*( //bytes per bit 0.2*sumHdr //Repetitive header characters +(lowComplexity ? 0.5 : 1.5)*sumLen +(binned ? 0.5 : 2.5)*sumQLen +(4*6*readCount) //@, +, and newline +(8*2*readCount) //Actual information content of a typical header ); if(ff.bz2() || ff.fqz()){ compressedSize*=0.83; } }else{ compressedSize=sumBytes; } double memRatio=(sumMem+readCount*extraOverheadPerRead)/compressedSize; double diskRatio=sumBytes/compressedSize; long memEstimate=(long)(memRatio*size); long diskEstimate=(long)(diskRatio*size); double readRatio=readCount/(double)(Tools.max(1, sumBytes)); long readEstimate=(long)(readRatio*diskEstimate); // assert(false) : readCount+", "+sumBytes+", "+readRatio+", "+size; // System.err.println("compressedSize="+compressedSize); // System.err.println("memRatio="+memRatio); // System.err.println("diskRatio="+diskRatio); // assert(false) : diskEstimate+", "+minBytes+", "+ // double worstCase=estimate*1.75; return new double[] {memEstimate, diskEstimate, memRatio, diskRatio, readEstimate}; } public static final boolean nextBoolean(Random randy){ return randy.nextBoolean(); // int r=randy.nextInt()&0x7FFFFFFF; // return r%294439>=147219; } public static float[] inverse(float[] array) { float[] out=new float[array.length]; for(int i=0; i=32 && c<=126); } return ok; } /** Changes headers to consist of printable ASCII characters. */ public static String fixHeader(String s, boolean allowNull, boolean processAssertions){ // assert(false) : new String(specialChars); if(checkHeader(s)){return s;} if(s==null || s.length()==0){ if(processAssertions && !allowNull){KillSwitch.kill("Sequence found with null header (unfixable). To bypass, set allownullheader=true.");} return ""; } StringBuilder sb=new StringBuilder(s.length()); for(int i=0; i=0 && c<=255){ d=specialChars[c]; }else{ d='X'; } // System.err.println(c+"="+(int)c); sb.append(d); } return sb.toString(); } public static int secondHighestPosition(int[] array) { int maxP, maxP2; if(array[0]>=array[1]){ maxP=0; maxP2=1; }else{ maxP=1; maxP2=0; } for(int i=2; iarray[maxP2]){ if(x>=array[maxP]){ maxP2=maxP; maxP=i; }else{ maxP2=i; } } } return maxP2; } /** * Returns this file name if it is a file, or all the files in the directory if it is a directory. * @param b * @param fasta * @param fastq * @param sam * @param any * @return A list of files */ public static ArrayList getFileOrFiles(String b, ArrayList list, boolean fasta, boolean fastq, boolean sam, boolean any){ if(list==null){list=new ArrayList();} String[] split=b.split(","); for(String s : split){ File f=new File(s); if(f.isDirectory()){ for(File f2 : f.listFiles()){ if(f2.isFile()){ String name=f2.getName().toLowerCase(); String ext=ReadWrite.rawExtension(name); boolean pass=any || (fasta && FileFormat.isFasta(ext)) || (fastq && FileFormat.isFastq(ext)) || (sam && FileFormat.isSamOrBam(ext)); if(pass){ String s2=f2.getAbsolutePath(); list.add(s2); } } } }else{ list.add(s); } } return list; } public static ArrayList toAdapterList(String name, int maxLength){ if(maxLength<1){maxLength=Integer.MAX_VALUE;} if(name==null){return null;} String[] split; LinkedHashSet set=new LinkedHashSet(); //Prevents duplicates if(new File(name).exists()){ split=new String[] {name}; }else{ split=name.split(","); } for(String s : split){ if(new File(s).exists()){ ArrayList reads=ReadInputStream.toReads(s, FileFormat.FASTA, -1); for(Read r : reads){ if(r!=null && r.length()>0){ byte[] array=checkAdapter(r.bases, maxLength); if(array.length>0){set.add(new String(array));} } } }else{ byte[] array=checkAdapter(s.getBytes(), maxLength); if(array.length>0){set.add(new String(array));} } } if(set.isEmpty()){return null;} ArrayList list=new ArrayList(set.size()); for(String s : set){ list.add(s.getBytes()); } return list; } private static byte[] checkAdapter(byte[] array, int maxLength){ if(array.length>maxLength){array=Arrays.copyOf(array, maxLength);} for(int i=0; i=0; i--){ if(array[i]=='N'){trailingNs++;} } if(trailingNs>0){ array=Arrays.copyOf(array, array.length-trailingNs); } return array; } public static byte[][] toAdapters(String name, final int maxLength){ ArrayList list=toAdapterList(name, maxLength); return list==null ? null : list.toArray(new byte[list.size()][]); } /** Add names to a collection. * This can be a literal name, or a text file with one name per line, * or a fastq, fasta, or sam file, in which case the read names will be added. * @param s * @param names * @return Number added */ public static final int addNames(String s, Collection names, boolean allowSubprocess){ int added=0; if(new File(s).exists()){ int[] vector=FileFormat.testFormat(s, false, false); final int type=vector[0]; ByteFile bf=ByteFile.makeByteFile(s, allowSubprocess); if(type==FileFormat.FASTQ){ int num=0; for(byte[] line=bf.nextLine(); line!=null; line=bf.nextLine(), num++){ if((num&3)==0 && line.length>0){ names.add(new String(line, 1, line.length-1)); } } }else if(type==FileFormat.FASTA){ for(byte[] line=bf.nextLine(); line!=null; line=bf.nextLine()){ if(line.length>0 && line[0]=='>'){ names.add(new String(line, 1, line.length-1)); } } }else if(type==FileFormat.SAM){ for(byte[] line=bf.nextLine(); line!=null; line=bf.nextLine()){ if(line.length>0 && line[0]!='@'){ String name=SamLine.parseNameOnly(line); if(name!=null && name.length()>0){names.add(name);} } } }else{ for(byte[] line=bf.nextLine(); line!=null; line=bf.nextLine()){ if(line.length>0){ names.add(new String(line)); } } } bf.close(); }else{ added++; names.add(s); } return added; } /** * Make copies of any read with ambiguous bases to represent all possible non-ambiguous representations. * @param reads A list of reads * @param minlen minimum length of reads to replicate * @return A list of reads with no ambiguity codes. */ public static ArrayList replicateAmbiguous(ArrayList reads, int minlen) { ArrayList out=new ArrayList(); for(Read r1 : reads){ final Read r2=r1.mate; r1.mate=null; if(r1.containsUndefined() && r1.length()>=minlen){ ArrayList temp=makeReplicates(r1); out.addAll(temp); }else{ out.add(r1); } if(r2!=null){ r2.mate=null; if(r2.containsUndefined() && r2.length()>=minlen){ ArrayList temp=makeReplicates(r2); out.addAll(temp); }else{ out.add(r2); } } } return out; } /** * Make copies of this read to represent all possible non-ambiguous representations. * Return a list of all fully-defined versions. * @param r A read to replicate * @return A list of reads with no ambiguity codes. */ public static ArrayList makeReplicates(final Read r) { // System.err.println("\n***Called makeReplicates("+new String(r.bases)+")"); ArrayList temp=null; if(!r.containsUndefined()){ temp=new ArrayList(); temp.add(r); return temp; } final byte[] bases=r.bases; for(int i=0; i out; if(temp.get(0).containsUndefined()){ out=new ArrayList(); for(Read rr : temp){ out.addAll(makeReplicates(rr)); } }else{ out=temp; } return out; } /** * @param r A read * @param pos The position of an ambiguous base * @param out A list of replicates */ private static ArrayList replicateAtPosition(final Read r, final int pos) { // System.err.println("Called replicateAtPosition("+new String(r.bases)+", "+pos+")"); if(r.quality!=null){ r.quality[pos]=Shared.FAKE_QUAL; } final byte[] bases=r.bases; final byte b=bases[pos]; final int num=AminoAcid.baseToNumberExtended[b]&0xF; assert(num>0 && Integer.bitCount(num)>1 && Integer.bitCount(num)<=4) : b+", "+num; ArrayList out=new ArrayList(4); for(int i=0; i<4; i++){ int mask=(1<=0 ? x : containsReverse(big, small, maxMismatches); } /** Returns index of first matching location */ public static final int containsForward(final byte[] big, final byte[] small, final int maxMismatches){ final int ilimit=big.length-small.length; // System.err.println("Entering: ilimit="+ilimit+", maxMismatches="+maxMismatches+", small.length="+small.length); for(int i=0; i<=ilimit; i++){ int mismatches=0; for(int j=0; j X[] condenseStrict(X[] array){ if(array==null){return array;} int nulls=0; for(X x : array){if(x==null){nulls++;}} if(nulls==0){return array;} X[] array2=Arrays.copyOf(array, array.length-nulls); int j=0; for(X x : array){ if(x!=null){ array2[j]=x; j++; } } return array2; } /** Creates a new list without null elements. */ public static final ArrayList condenseNew(ArrayList list){ ArrayList temp=new ArrayList(list.size()); for(X x : list){ if(x!=null){temp.add(x);} } return temp; } //This should also be correct. I'm not sure which is faster. // /** Removes null elements by shrinking the list. Will not change list order. */ // public static final int condenseStrict(ArrayList list){ // if(list==null || list.size()==0){return 0;} // int removed=0; // int last=0; // // for(int i=0; i ssl, float fractionOfMax, boolean retainPaired){ //// assert(false); // if(ssl==null || ssl.size()==0){return -999999;} // if(ssl.size()==1){return ssl.get(0).score;} // int maxScore=-999999; // for(SiteScore ss : ssl){ // maxScore=Tools.max(maxScore, ss.score); // } // // int cutoff=(int) (maxScore*fractionOfMax); // trimSitesBelowCutoff(ssl, cutoff, retainPaired); //// trimSitesBelowCutoffInplace(ssl, cutoff); // return maxScore; // } /** minSitesToRetain should be set to 1 if the list is not sorted by score (for efficiency of removal). Otherwise, it can be higher. */ public static final int trimSiteList(ArrayList ssl, float fractionOfMax, boolean retainPaired, boolean retainSemiperfect, int minSitesToRetain, int maxSitesToRetain){ // assert(false); if(ssl==null || ssl.size()==0){return -999999;} if(ssl.size()==1){return ssl.get(0).score;} int maxScore=-999999; if(minSitesToRetain>1 && minSitesToRetain ssl, int cutoff, boolean retainPaired, boolean retainSemiperfect, int minSitesToRetain, int maxSitesToRetain){ // assert(false); if(ssl==null || ssl.size()==0){return;} if(ssl.size()==1){return;} trimSitesBelowCutoff(ssl, cutoff, retainPaired, retainSemiperfect, minSitesToRetain, maxSitesToRetain); } public static final > boolean inOrder(ArrayList list){ if(list==null || list.size()<2){return true;} for(int i=1; i0){return false;} } return true; } public static final int mergeDuplicateSites(ArrayList list, boolean doAssertions, boolean mergeDifferentGaps){ if(list==null || list.size()<2){return 0;} Shared.sort(list, SiteScore.PCOMP); int removed=0; SiteScore a=list.get(0); for(int i=1; ib.score || a.slowScore>b.slowScore)))){ throw new RuntimeException("\n"+SiteScore.header()+"\n"+a.toText()+"\n"+b.toText()+"\n"); } assert(a.perfect==b.perfect || (a.perfect && (a.score>b.score || a.slowScore>b.slowScore))) : "\n"+SiteScore.header()+"\n"+a.toText()+"\n"+b.toText()+"\n"; } a.setSlowScore(max(a.slowScore, b.slowScore)); // a.setPairedScore(a.pairedScore<=0 && b.pairedScore<=0 ? 0 : max(a.slowScore+1, a.pairedScore, b.pairedScore)); a.setPairedScore((a.pairedScore<=a.slowScore && b.pairedScore<=a.slowScore) ? 0 : max(0, a.pairedScore, b.pairedScore)); a.setScore(max(a.score, b.score)); a.perfect=(a.perfect || b.perfect); a.semiperfect=(a.semiperfect || b.semiperfect); removed++; list.set(i, null); }else if(mergeDifferentGaps && a.positionalMatch(b, false)){ //Same outermost boundaries, different gaps SiteScore better=null; if(a.score!=b.score){ better=(a.score>b.score ? a : b); }else if(a.slowScore!=b.slowScore){ better=(a.slowScore>b.slowScore ? a : b); }else if(a.pairedScore!=b.pairedScore){ better=(a.pairedScore>b.pairedScore ? a : b); }else{ better=a; } a.setSlowScore(max(a.slowScore, b.slowScore)); a.setPairedScore((a.pairedScore<=a.slowScore && b.pairedScore<=a.slowScore) ? 0 : max(0, a.pairedScore, b.pairedScore)); a.setScore(max(a.score, b.score)); a.perfect=(a.perfect || b.perfect);//TODO: This is not correct. And perfect sites should not have gaps anyway. a.semiperfect=(a.semiperfect || b.semiperfect); a.gaps=better.gaps; removed++; list.set(i, null); } else{ a=b; } } // if(removed>0){condense(list);} if(removed>0){condenseStrict(list);} return removed; } public static final int subsumeOverlappingSites(ArrayList list, boolean subsumeIfOnlyStartMatches, boolean subsumeInexact){ if(list==null || list.size()<2){return 0;} Shared.sort(list, SiteScore.PCOMP); int removed=0; for(int i=0; ia.start); if(overlappingA && a.strand==b.strand){ SiteScore better=null; if(a.perfect!=b.perfect){ better=a.perfect ? a : b; }else if(a.semiperfect!=b.semiperfect){ better=a.semiperfect ? a : b; }else if(a.score!=b.score){ better=(a.score>b.score ? a : b); }else if(a.slowScore!=b.slowScore){ better=(a.slowScore>b.slowScore ? a : b); }else if(a.pairedScore!=b.pairedScore){ better=(a.pairedScore>b.pairedScore ? a : b); }else if(a.pairedScore!=b.pairedScore){ better=(a.quickScore>b.quickScore ? a : b); }else{ better=a; } // if((a.perfect && b.perfect) || (a.semiperfect && b.semiperfect)){ if(a.semiperfect && b.semiperfect){ if(a.start==b.start || a.stop==b.stop){ list.set(i, better); list.set(j, null); removed++; a=better; }else{ //retain both of them } }else if(a.perfect || b.perfect){ list.set(i, better); list.set(j, null); removed++; a=better; }else if(a.semiperfect || b.semiperfect){ if(a.start==b.start && a.stop==b.stop){ list.set(i, better); list.set(j, null); removed++; a=better; }else{ //retain both of them } }else if(subsumeInexact || (a.start==b.start && (subsumeIfOnlyStartMatches || a.stop==b.stop))){ assert(!a.semiperfect && !a.perfect && !b.semiperfect && !b.perfect); a.setLimits(min(a.start, b.start), max(a.stop, b.stop)); a.setSlowScore(max(a.slowScore, b.slowScore)); a.setPairedScore(a.pairedScore<=0 && b.pairedScore<=0 ? 0 : max(a.slowScore+1, a.pairedScore, b.pairedScore)); a.quickScore=max(a.quickScore, b.quickScore); a.setScore(max(a.score, b.score, a.pairedScore)); a.gaps=better.gaps;//Warning! Merging gaps would be better; this could cause out-of-bounds. //TODO: Test for a subsumption length limit. list.set(j, null); removed++; } } } } } } // if(removed>0){condense(list);} if(removed>0){condenseStrict(list);} return removed; } public static final int removeOverlappingSites(ArrayList list, boolean requireAMatchingEnd){ if(list==null || list.size()<2){return 0;} Shared.sort(list, SiteScore.PCOMP); int removed=0; for(int i=0; ia.start); if(overlappingA && a.strand==b.strand){ SiteScore better=null; if(a.perfect!=b.perfect){ better=a.perfect ? a : b; }else if(a.score!=b.score){ better=(a.score>b.score ? a : b); }else if(a.slowScore!=b.slowScore){ better=(a.slowScore>b.slowScore ? a : b); }else if(a.pairedScore!=b.pairedScore){ better=(a.pairedScore>b.pairedScore ? a : b); }else if(a.pairedScore!=b.pairedScore){ better=(a.quickScore>b.quickScore ? a : b); }else{ better=a; } if(a.start==b.start && a.stop==b.stop){ list.set(i, better); list.set(j, null); a=better; removed++; }else if(a.start==b.start || a.stop==b.stop){ //In this case they cannot both be perfect list.set(i, better); list.set(j, null); a=better; removed++; }else if(!requireAMatchingEnd && a.score!=b.score){ list.set(i, better); list.set(j, null); a=better; removed++; } } } } } } // if(removed>0){condense(list);} if(removed>0){condenseStrict(list);} return removed; } /** Returns the number of sitescores in the list within "thresh" of the top score. Assumes list is sorted descending. * This is used to determine whether a mapping is ambiguous. */ public static final int countTopScores(ArrayList list, int thresh){ assert(thresh>=0) : thresh; if(list==null || list.isEmpty()){return 0;} int count=1; final SiteScore ss=list.get(0); final int limit=ss.score-thresh; for(int i=1; i list, int maxSwScore, float multSingle, float multPaired){ if(list==null || list.size()==0){return 0;} assert(multSingle>=multPaired); int initialSize=list.size(); final int swScoreThresh=(int)(maxSwScore*multSingle); //Change low-quality alignments to no-hits. final int swScoreThreshPaired=(int)(maxSwScore*multPaired); if(list.get(0).score=0; i--){ SiteScore ss=list.get(i); assert(ss.score==ss.slowScore) : ss.quickScore+", "+ss.slowScore+", "+ss.pairedScore+", "+ss.score+"\n"+ss; assert(i==0 || ss.slowScore<=list.get(i-1).slowScore) : "List is not sorted by singleton score!"; if(ss.pairedScore>0){ assert(ss.pairedScore>ss.quickScore || ss.pairedScore>ss.slowScore) : ss; if(ss.slowScore list, int maxSwScore, float multSingle){ // if(list==null || list.size()==0){return 0;} // // int initialSize=list.size(); // final int swScoreThresh=(int)(maxSwScore*multSingle); //Change low-quality alignments to no-hits. // if(list.get(0).score=0; i--){ // for(int i=list.size()-1; i>1; i--){ // SiteScore ss=list.get(i); // assert(ss.score==ss.slowScore); // assert(i==0 || ss.slowScore<=list.get(i-1).slowScore) : "List is not sorted by singleton score!"; // assert(ss.pairedScore==0) : ss.toText(); // if(ss.slowScore list, int thresh){ if(list==null || list.size()==0){return 0;} int initialSize=list.size(); if(list.get(0).score=0; i--){ for(int i=list.size()-1; i>1; i--){ SiteScore ss=list.get(i); assert(ss.score==ss.slowScore || (ss.score<=0 && ss.slowScore<=0)) : ss; assert(i==0 || ss.slowScore<=list.get(i-1).slowScore) : "List is not sorted by singleton score!"; assert(ss.pairedScore<=0) : ss.toText(); if(ss.slowScore list, int maxSwScore, float multSingle, float multPaired, int expectedSites){ if(list==null || list.size()==0){return 0;} assert(multSingle>=multPaired); int initialSize=list.size(); final int swScoreThresh=(int)(maxSwScore*multSingle); //Change low-quality alignments to no-hits. final int swScoreThreshPaired=(int)(maxSwScore*multPaired); final int swScoreThresh2=(int)(maxSwScore*multSingle*1.2f); final int swScoreThreshPaired2=(int)(maxSwScore*multPaired*1.1f); if(list.get(0).scoremin; i--){ if(list.get(i).slowScore>=nthBest){break;} list.remove(i); } for(int i=list.size()-1; i>=0; i--){ SiteScore ss=list.get(i); assert(ss.score==ss.slowScore); assert(i==0 || ss.slowScore<=list.get(i-1).slowScore) : "List is not sorted by singleton score!"; if(ss.pairedScore>0){ int thresh=(i>=expectedSites ? swScoreThreshPaired2 : swScoreThreshPaired); assert(ss.pairedScore>ss.quickScore || ss.pairedScore>ss.slowScore) : ss; if(ss.slowScore=expectedSites ? swScoreThresh2 : swScoreThresh); // assert(ss.pairedScore==0) : ss.toText(); //Disable in case of negative values if(ss.slowScore list, int maxSwScore, float multSingle, int expectedSites){ if(list==null || list.size()==0){return 0;} for(int i=expectedSites/2; imin; i--){ if(list.get(i).slowScore>=nthBest){break;} list.remove(i); } // for(int i=list.size()-1; i>=0; i--){ for(int i=list.size()-1; i>=1; i--){ SiteScore ss=list.get(i); assert(ss.score==ss.slowScore); assert(i==0 || ss.slowScore<=list.get(i-1).slowScore) : "List is not sorted by singleton score!"; assert(ss.pairedScore<=0) : ss.toText(); //This was "==0" but that makes the assertion fire for negative values. int thresh=(i>=expectedSites ? swScoreThresh2 : swScoreThresh); if(ss.slowScore ssl, int cutoff, boolean retainPaired){ // trimSitesBelowCutoff(ssl, cutoff, retainPaired, 1); // } // public static final void trimSitesBelowCutoff(ArrayList ssl, int cutoff, boolean retainPaired, int minSitesToRetain){ //// assert(false); // assert(minSitesToRetain>=1); // if(ssl==null || ssl.size() ssl2=new ArrayList(ssl.size()); // for(SiteScore ss : ssl){ // if(ss.score>=cutoff || (retainPaired && ss.pairedScore>0)){ // ssl2.add(ss); // } // } // //// Shared.sort(ssl2); //// System.err.println("Cutoff: "+cutoff); //// for(SiteScore ss : ssl2){ //// System.err.print("("+ss.chrom+", "+ss.score+"), "); //// } //// System.err.println(); // // if(ssl2.size()==ssl.size()){return;} //// System.err.println("cutoff: "+cutoff+",\tsize: "+ssl.size()+" -> "+ssl2.size()); // ssl.clear(); // ssl.addAll(ssl2); // } public static final void trimSitesBelowCutoff(ArrayList ssl, int cutoff, boolean retainPaired, boolean retainSemiperfect, int minSitesToRetain, int maxSitesToRetain){ // assert(false); assert(minSitesToRetain>=1); assert(maxSitesToRetain>minSitesToRetain) : maxSitesToRetain+", "+minSitesToRetain+"\nError - maxsites2 must be greater than "+minSitesToRetain+"!"; if(ssl==null || ssl.size()<=minSitesToRetain){return;} while(ssl.size()>maxSitesToRetain){ssl.remove(ssl.size()-1);} int removed=0; final int maxToRemove=ssl.size()-minSitesToRetain; assert(minSitesToRetain==1 || inOrder(ssl)); if(retainPaired){ for(int i=ssl.size()-1; i>=0; i--){ SiteScore ss=ssl.get(i); if(!retainSemiperfect || !ss.semiperfect){ if(ss.score=maxToRemove){ assert(removed==maxToRemove); break; } } } } }else{ for(int i=ssl.size()-1; i>=0; i--){ SiteScore ss=ssl.get(i); if(!retainSemiperfect || !ss.semiperfect){ if(ss.score=maxToRemove){ assert(removed==maxToRemove); break; } } } } } if(removed>0){ condenseStrict(ssl); } assert(ssl.size()>=minSitesToRetain); } //Messes up order // public static final void trimSitesBelowCutoffInplace(ArrayList ssl, int cutoff, boolean retainPaired){ //// assert(false); // if(ssl==null || ssl.size()<2){return;} // // for(int i=0; i126){return sb;} sb.append('\n'); for(int i=0; i126){break;} sb.append((char)b); } return sb; } public static boolean equals(long[] a, long[] b){ if(a==b){return true;} if(a==null || b==null){return false;} if(a.length!=b.length){return false;} for(int i=0; iarray.length){return false;} for(int i=s.length()-1, j=array.length-1; i>=0 && j>=0; i--, j--){ if(s.charAt(i)!=array[j]){return false;} } return true; } /** * @param array * @param s * @return True if the array starts with the String. */ public static boolean startsWith(byte[] array, String s, int initialPos) { if(array==null || s==null || array.length+initialPos=Integer.MIN_VALUE) : x; return (int)x; } public static void multiplyBy(int[] array, double mult) { for(int i=0; i0){sum+=1.0/x;} } return array.length/sum; } public static int cardinality(int[] array){ int x=0; for(int y : array){if(y!=0){x++;}} return x; } public static double weightedAverage(long[] array){ if(array.length<2){ return array.length==1 ? array[0] : 0; } double wsum=0; long div=0; final int mid=array.length/2; for(int i=0; i0){return i;} } return 0; } public static long maxHistogram(long[] array){ for(int i=array.length-1; i>=0; i--){ if(array[i]>0){return i;} } return 0; } public static long sum(AtomicIntegerArray array){ long x=0; for(int i=0; i void reverseInPlace(final X[] array){ if(array==null){return;} reverseInPlace(array, 0, array.length); } public static void reverseInPlace(final X[] array, final int from, final int to){ if(array==null){return;} final int len=to-from; final int max=from+len/2, last=to-1; for(int i=from; i=count[i-1]) : "\n\ncount["+i+"]="+count[i]+"\ncount["+(i-1)+"]="+count[i-1]+"\n"; } int pos=count.length-1; for(int sum=0; pos>1 && summaxLengthToKeep2){data[i]=null;} } } public static int findLimitForHighFreqEntries(int[][] data, float fractionToExclude){ if(fractionToExclude<=0){return Integer.MAX_VALUE;} int[] count=new int[data.length]; long numBases=0; for(int i=0; i=count[i-1]) : "\n\ncount["+i+"]="+count[i]+"\ncount["+(i-1)+"]="+count[i-1]+"\n"; } int pos=count.length-1; for(int sum=0; pos>1 && sum=minLength){ if(isClumpy(array, maxDist, fraction)){ removedSites+=array.length; removedKeys++; data[i]=null; } } } // System.err.println("Removed\t"+removedSites+"\t/ "+total+"\tsites," + // " or "+String.format(Locale.ROOT, "%.4f", (removedSites*100f/total))+"%"); // System.err.println("Removed\t"+removedKeys+"\t/ "+data.length+"\tkeys," + // " or "+String.format(Locale.ROOT, "%.4f", (removedKeys*100f/data.length))+"%"); } public static HashSet banClumpyEntries(final int[][] data, final int maxDist, final int minLength, final float fraction){ HashSet set=new HashSet(128); long total=0; long removedSites=0; long removedKeys=0; if(maxDist<=0){return set;} for(int i=0; i=minLength){ if(isClumpy(array, maxDist, fraction)){ removedSites+=array.length; removedKeys++; set.add(i); } } } // System.err.println("Banned\t"+removedSites+"\t/ "+total+"\tsites," + // " or "+String.format(Locale.ROOT, "%.4f", (removedSites*100f/total))+"%"); // System.err.println("Banned\t"+removedKeys+"\t/ "+data.length+"\tkeys," + // " or "+String.format(Locale.ROOT, "%.4f", (removedKeys*100f/data.length))+"%"); return set; } public static final boolean isClumpy(final int[] array, final int maxDist, final float fraction){ if(array==null){return false;} int count=0; for(int i=1; i=(array.length*fraction); } public static int[] makeLengthHistogram(int[][] x, int buckets) { int[] lengths=new int[x.length]; long total=0; for(int i=0; i10000000000000L){ div=1000000000000L; ext="T"; }else if(x>10000000000L){ div=1000000000L; ext="B"; }else if(x>10000000){ div=1000000; ext="M"; }else if(x>100000){ div=1000; ext="K"; } return String.format(Locale.ROOT, "%.2f", x/div)+ext; } /** Replace characters in the array with different characters according to the map */ public static int remapAndCount(byte[] remap, byte[] array) { if(array==null){return 0;} assert(remap!=null); int swaps=0; for(int i=0; i0 ? new String(array) : in); } public static int[] makeHistogram(AtomicLongArray data, int buckets) { long total=sum(data); long increment=total/(buckets+1); int[] hist=new int[buckets+1]; long sum=0; long target=increment/2; int ptr=0; for(int i=0; ix.length){ Data.sysout.println("Reverted to old histogram mode."); return makeLengthHistogram2(x, buckets, verbose); } int[] counts=new int[max+1]; long total=0; for(int i=0; i=0){ counts[a]++; total+=a; } } return makeLengthHistogram4(counts, buckets, total, verbose); } /** Uses counts of occurrences of lengths rather than raw lengths */ public static int[] makeLengthHistogram4(int[] counts, int buckets, long total, boolean verbose) { if(total<=0){ total=0; for(int i=1; i=target){ return i; } } return array.length-1; } /** Returns the percentile of a histogram */ public static int percentileHistogram(long[] array, double fraction){ if(array==null || array.length<1){return 0;} long target=(long)(sum(array)*fraction); long sum=0; for(int i=0; i=target){ return i; } } return array.length-1; } public static int calcModeHistogram(long array[]){ if(array==null || array.length<1){return 0;} int median=percentileHistogram(array, 0.5); int mode=0; long modeCount=array[mode]; for(int i=1; imodeCount || (count==modeCount && absdif(i, median)b ? a-b : b-a; } public static float absdif(float a, float b) { return a>b ? a-b : b-a; } public static double absdif(double a, double b) { return a>b ? a-b : b-a; } /** Uses unsigned math */ public static final int absdifUnsigned(int a, int b){ return (a<0 == b<0) ? a>b ? a-b : b-a : Integer.MAX_VALUE; } /** True iff (a1,b1) overlaps (a2,b2) */ public static final boolean overlap(int a1, int b1, int a2, int b2){ assert(a1<=b1 && a2<=b2) : a1+", "+b1+", "+a2+", "+b2; return a2<=b1 && b2>=a1; } public static final int overlapLength(int a1, int b1, int a2, int b2){ if(!overlap(a1,b1,a2,b2)){return 0;} if(a1<=a2){ return b1>=b2 ? b2-a2+1 : b1-a2+1; }else{ return b2>=b1 ? b1-a1+1 : b2-a1+1; } } /** Is (a1, b1) within (a2, b2) ? */ public static final boolean isWithin(int a1, int b1, int a2, int b2){ assert(a1<=b1 && a2<=b2) : a1+", "+b1+", "+a2+", "+b2; return a1>=a2 && b1<=b2; } public static final int constrict(int point, int a, int b){ assert(a<=b); return(pointb ? b : point); } public static final int indexOf(byte[] array, char b){ return indexOf(array, (byte)b, 0); } public static final int indexOf(byte[] array, byte b){ return indexOf(array, b, 0); } public static final int indexOfNth(byte[] array, byte b, int n){ return indexOfNth(array, b, n, 0); } public static final int indexOfNth(byte[] array, char b, int n){ return indexOfNth(array, (byte)b, n, 0); } public static final int indexOf(final byte[] array, final char b, final int start){return indexOf(array, (byte)b, start);} public static final int indexOf(final byte[] array, final byte b, final int start){ int i=start; while(i=0){return Arrays.copyOf(array, index);} } return array; } public static final int indexOfWhitespace(byte[] array){ int i=0; while(i=0){return array.substring(0, index);} } return array; } public static final int indexOfWhitespace(String array){ int i=0; while(i=0 && array[i]!=b){i--;} return i; } public static final int stringLength(long x){ if(x<0){ if(x==Integer.MIN_VALUE){return 11;} return lengthOf(-x)+1; } return lengthOf(x); } public static final int stringLength(int x){ if(x<0){ if(x==Long.MIN_VALUE){return 20;} return lengthOf(-x)+1; } return lengthOf(x); } public static final int lengthOf(int x){ assert(x>=0); int i=1; while(x>ilens[i]){i++;} return i; } public static final int lengthOf(long x){ assert(x>=0); int i=1; while(x>llens[i]){i++;} return i; } public static final int max(byte[] array){return array[maxIndex(array)];} public static final int maxIndex(byte[] array){ byte max=array[0]; int maxIndex=0; for(int i=1; imax){max=array[i];maxIndex=i;} } return maxIndex; } public static final int max(short[] array){return array[maxIndex(array)];} public static final int maxIndex(short[] array){ short max=array[0]; int maxIndex=0; for(int i=1; imax){max=array[i];maxIndex=i;} } return maxIndex; } public static final int max(int[] array){return array[maxIndex(array)];} public static final int maxIndex(int[] array){ int max=array[0], maxIndex=0; for(int i=1; imax){max=array[i];maxIndex=i;} } return maxIndex; } public static final long max(long[] array){return array[maxIndex(array)];} public static final int maxIndex(long[] array){ long max=array[0]; int maxIndex=0; for(int i=1; imax){max=array[i];maxIndex=i;} } return maxIndex; } public static final double max(double[] array){return array[maxIndex(array)];} public static final int maxIndex(double[] array){ double max=array[0]; int maxIndex=0; for(int i=1; imax){max=array[i];maxIndex=i;} } return maxIndex; } public static final double standardDeviation(long[] numbers){ if(numbers==null || numbers.length<2){return 0;} long sum=sum(numbers); double avg=sum/(double)numbers.length; double sumdev2=0; for(int i=0; i=0); long[] r=new long[bins]; if(bins==0){return r;} double mult=bins/(double)array.length; for(int i=0; i0){System.err.println(i+"->"+j+": "+array[i]);} } return r; } public static final void pause(int millis){ try { Thread.sleep(millis); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static final int min(int x, int y){return xy ? x : y;} public static final int min(int x, int y, int z){return xy ? (x>z ? x : z) : (y>z ? y : z);} public static final int min(int x, int y, int z, int z2){return min(min(x,y), min(z,z2));} public static final int max(int x, int y, int z, int z2){return max(max(x,y), max(z,z2));} //Median of 3 public static final int mid(int x, int y, int z){return xy ? x : y;} public static final byte min(byte x, byte y){return xy ? x : y;} public static final byte min(byte x, byte y, byte z){return xy ? max(x, z) : max(y, z);} public static final byte min(byte x, byte y, byte z, byte a){return min(min(x, y), min(z, a));} public static final byte max(byte x, byte y, byte z, byte a){return max(max(x, y), max(z, a));} public static final byte mid(byte x, byte y, byte z){return xy ? x : y;} public static final long min(long x, long y, long z){return xy ? (x>z ? x : z) : (y>z ? y : z);} public static final long min(long x, long y, long z, long z2){return min(min(x,y), min(z,z2));} public static final long max(long x, long y, long z, long z2){return max(max(x,y), max(z,z2));} public static final long mid(long x, long y, long z){return xInteger.MAX_VALUE ? Integer.MAX_VALUE : (int)x;} public static final double min(double x, double y){return xy ? x : y;} public static final double min(double x, double y, double z){return xy ? (x>z ? x : z) : (y>z ? y : z);} public static final double mid(double x, double y, double z){return xy ? x : y;} public static final float min(float x, float y, float z){return xy ? (x>z ? x : z) : (y>z ? y : z);} public static final float min(float x, float y, float z, float z2){return min(min(x, y), min(z, z2));} public static final float max(float x, float y, float z, float z2){return max(max(x, y), max(z, z2));} public static final float mid(float x, float y, float z){return x"+"\n"+r); // } // assert(false); double p=randy.nextDouble(); return -Math.log(1-p)/lamda; } public static double log2(double d){ return Math.log(d)*invlog2; } public static double logRoot2(double d){ return Math.log(d)*invlogRoot2; } public static double log1point2(double d){ return Math.log(d)*invlog1point2; } private static final double log2=Math.log(2); private static final double invlog2=1/log2; private static final double logRoot2=Math.log(Math.sqrt(2)); private static final double invlogRoot2=1/logRoot2; private static final double log1point2=Math.log(1.2); private static final double invlog1point2=1/log1point2; public static final boolean[] digitMap; public static final boolean[] signOrDigitMap; public static final boolean[] numericMap; public static final boolean[] letterMap; /** ASCII equivalents for extended-ASCII characters */ public static final char[] specialChars; public static final int[] ilens; public static final long[] llens; /* Precompiled regular expressions */ /** A single whitespace */ public static final Pattern whitespace = Pattern.compile("\\s"); /** Multiple whitespace */ public static final Pattern whitespacePlus = Pattern.compile("\\s+"); /** Comma */ public static final Pattern commaPattern = Pattern.compile(","); /** Tab */ public static final Pattern tabPattern = Pattern.compile("\t"); /** Colon */ public static final Pattern colonPattern = Pattern.compile(":"); /** Semicolon */ public static final Pattern semiPattern = Pattern.compile(";"); /** Pipe */ public static final Pattern pipePattern = Pattern.compile("\\|"); /** Space */ public static final Pattern spacePattern = Pattern.compile(" "); /** Equals */ public static final Pattern equalsPattern = Pattern.compile("="); /** Equals */ public static final Pattern underscorePattern = Pattern.compile("_"); public static boolean FORCE_JAVA_PARSE_DOUBLE=false; static{ digitMap=new boolean[128]; signOrDigitMap=new boolean[128]; numericMap=new boolean[128]; letterMap=new boolean[128]; for(int i='a'; i<='z'; i++){letterMap[i]=true;} for(int i='A'; i<='Z'; i++){letterMap[i]=true;} for(int i='0'; i<='9'; i++){digitMap[i]=numericMap[i]=signOrDigitMap[i]=true;} numericMap['-']=signOrDigitMap['-']=true; numericMap['.']=true; ilens=new int[Integer.toString(Integer.MAX_VALUE).length()+1]; llens=new long[Long.toString(Long.MAX_VALUE).length()+1]; for(int i=1, x=9; i X getLast(ArrayList list) { return (list.size()>0 ? list.get(list.size()-1) : null); } }