jpayne@68: package consensus; jpayne@68: jpayne@68: import java.io.PrintStream; jpayne@68: import java.util.ArrayList; jpayne@68: import java.util.LinkedHashMap; jpayne@68: import java.util.Map.Entry; jpayne@68: jpayne@68: import fileIO.ByteFile; jpayne@68: import fileIO.ByteStreamWriter; jpayne@68: import fileIO.FileFormat; jpayne@68: import fileIO.ReadWrite; jpayne@68: import prok.ProkObject; jpayne@68: import shared.Parse; jpayne@68: import shared.Parser; jpayne@68: import shared.PreParser; jpayne@68: import shared.ReadStats; jpayne@68: import shared.Shared; jpayne@68: import shared.Timer; jpayne@68: import shared.Tools; jpayne@68: import sketch.SketchObject; jpayne@68: import stream.ConcurrentReadInputStream; jpayne@68: import stream.ConcurrentReadOutputStream; jpayne@68: import stream.FASTQ; jpayne@68: import stream.FastaReadInputStream; jpayne@68: import stream.Read; jpayne@68: import stream.SamLine; jpayne@68: import stream.SamReadStreamer; jpayne@68: import stream.SamStreamer; jpayne@68: import structures.ByteBuilder; jpayne@68: import structures.ListNum; jpayne@68: import template.Accumulator; jpayne@68: import template.ThreadWaiter; jpayne@68: import var2.Realigner; jpayne@68: import var2.SamFilter; jpayne@68: jpayne@68: /** jpayne@68: * Alters a reference to represent the consensus of aligned reads. jpayne@68: * jpayne@68: * @author Brian Bushnell jpayne@68: * @date September 6, 1019 jpayne@68: * jpayne@68: */ jpayne@68: public class ConsensusMaker extends ConsensusObject implements Accumulator { jpayne@68: jpayne@68: /*--------------------------------------------------------------*/ jpayne@68: /*---------------- Initialization ----------------*/ jpayne@68: /*--------------------------------------------------------------*/ jpayne@68: jpayne@68: /** jpayne@68: * Code entrance from the command line. jpayne@68: * @param args Command line arguments jpayne@68: */ jpayne@68: public static void main(String[] args){ jpayne@68: //Start a timer immediately upon code entrance. jpayne@68: Timer t=new Timer(); jpayne@68: jpayne@68: //Create an instance of this class jpayne@68: ConsensusMaker x=new ConsensusMaker(args); jpayne@68: jpayne@68: //Run the object jpayne@68: x.process(t); jpayne@68: jpayne@68: //Close the print stream if it was redirected jpayne@68: Shared.closeStream(x.outstream); jpayne@68: } jpayne@68: jpayne@68: /** jpayne@68: * Constructor. jpayne@68: * @param args Command line arguments jpayne@68: */ jpayne@68: public ConsensusMaker(String[] args){ jpayne@68: jpayne@68: {//Preparse block for help, config files, and outstream jpayne@68: PreParser pp=new PreParser(args, getClass(), false); jpayne@68: args=pp.args; jpayne@68: outstream=pp.outstream; jpayne@68: } jpayne@68: jpayne@68: //Set shared static variables prior to parsing jpayne@68: ReadWrite.USE_PIGZ=ReadWrite.USE_UNPIGZ=true; jpayne@68: ReadWrite.MAX_ZIP_THREADS=Shared.threads(); jpayne@68: FASTQ.TEST_INTERLEAVED=FASTQ.FORCE_INTERLEAVED=false; jpayne@68: jpayne@68: samFilter.includeUnmapped=false; jpayne@68: // samFilter.includeSupplimentary=false; jpayne@68: // samFilter.includeDuplicate=false; jpayne@68: samFilter.includeNonPrimary=false; jpayne@68: samFilter.includeQfail=false; jpayne@68: // samFilter.minMapq=4; jpayne@68: jpayne@68: {//Parse the arguments jpayne@68: final Parser parser=parse(args); jpayne@68: jpayne@68: Parser.processQuality(); jpayne@68: jpayne@68: maxReads=parser.maxReads; jpayne@68: overwrite=ReadStats.overwrite=parser.overwrite; jpayne@68: append=ReadStats.append=parser.append; jpayne@68: jpayne@68: in=parser.in1; jpayne@68: extin=parser.extin; jpayne@68: jpayne@68: out=parser.out1; jpayne@68: extout=parser.extout; jpayne@68: silent=Parser.silent; jpayne@68: } jpayne@68: jpayne@68: { jpayne@68: // if("auto".equalsIgnoreCase(atomic)){Scaffold.setCA3A(Shared.threads()>8);} jpayne@68: // else{Scaffold.setCA3A(Parse.parseBoolean(atomic));} jpayne@68: jpayne@68: if(ploidy<1){System.err.println("WARNING: ploidy not set; assuming ploidy=1."); ploidy=1;} jpayne@68: samFilter.setSamtoolsFilter(); jpayne@68: jpayne@68: streamerThreads=Tools.max(1, Tools.min(streamerThreads, Shared.threads())); jpayne@68: assert(streamerThreads>0) : streamerThreads; jpayne@68: } jpayne@68: jpayne@68: validateParams(); jpayne@68: fixExtensions(); //Add or remove .gz or .bz2 as needed jpayne@68: checkFileExistence(); //Ensure files can be read and written jpayne@68: checkStatics(); //Adjust file-related static fields as needed for this program jpayne@68: jpayne@68: //Create output FileFormat objects jpayne@68: ffout=FileFormat.testOutput(out, FileFormat.FASTA, extout, true, overwrite, append, ordered); jpayne@68: ffmodel=FileFormat.testOutput(outModel, FileFormat.ALM, null, true, overwrite, false, ordered); jpayne@68: jpayne@68: //Create input FileFormat objects jpayne@68: ffin=FileFormat.testInput(in, FileFormat.SAM, extin, true, true); jpayne@68: ffref=FileFormat.testInput(ref, FileFormat.FASTA, null, true, true); jpayne@68: jpayne@68: if(inModelFile!=null){ jpayne@68: ArrayList list=(ArrayList)ReadWrite.readObject(inModelFile, false); jpayne@68: inModel=list.get(0); jpayne@68: inModel.calcProbs(); jpayne@68: inModel.makeWeights(); jpayne@68: } jpayne@68: } jpayne@68: jpayne@68: /*--------------------------------------------------------------*/ jpayne@68: /*---------------- Initialization Helpers ----------------*/ jpayne@68: /*--------------------------------------------------------------*/ jpayne@68: jpayne@68: /** Parse arguments from the command line */ jpayne@68: private Parser parse(String[] args){ jpayne@68: jpayne@68: //Create a parser object jpayne@68: Parser parser=new Parser(); jpayne@68: jpayne@68: //Set any necessary Parser defaults here jpayne@68: //parser.foo=bar; jpayne@68: jpayne@68: //Parse each argument jpayne@68: for(int i=0; i1 ? split[1] : null; jpayne@68: if(b!=null && b.equalsIgnoreCase("null")){b=null;} jpayne@68: jpayne@68: if(a.equals("verbose")){ jpayne@68: verbose=Parse.parseBoolean(b); jpayne@68: BaseGraph.verbose=verbose; jpayne@68: }else if(a.equals("ref")){ jpayne@68: ref=b; jpayne@68: }else if(a.equals("outm") || a.equals("outmodel") || a.equals("model") || a.equals("alm")){ jpayne@68: outModel=b; jpayne@68: }else if(a.equals("inm") || a.equals("inmodel")){ jpayne@68: inModelFile=b; jpayne@68: }else if(a.equals("hist") || a.equals("histogram")){ jpayne@68: outHistFile=b; jpayne@68: }else if(a.equals("realign")){ jpayne@68: realign=Parse.parseBoolean(b); jpayne@68: }else if(a.equals("printscores")){ jpayne@68: printScores=Parse.parseBoolean(b); jpayne@68: }else if(a.equalsIgnoreCase("useMapq")){ jpayne@68: useMapq=Parse.parseBoolean(b); jpayne@68: }else if(a.equalsIgnoreCase("identityCeiling") || a.equalsIgnoreCase("idceiling") || a.equalsIgnoreCase("ceiling")){ jpayne@68: double d=Double.parseDouble(b); jpayne@68: if(d<=2){d=d*100;} jpayne@68: identityCeiling=(int)d; jpayne@68: invertIdentity=true; jpayne@68: }else if(a.equalsIgnoreCase("invertIdentity")){ jpayne@68: invertIdentity=Parse.parseBoolean(b); jpayne@68: }else if(a.equals("name") || a.equals("rename") || a.equals("header")){ jpayne@68: name=b; jpayne@68: }else if(a.equals("noindels")){ jpayne@68: noIndels=Parse.parseBoolean(b); jpayne@68: }else if(a.equalsIgnoreCase("onlyConvertNs") || a.equalsIgnoreCase("nOnly") || a.equalsIgnoreCase("onlyN")){ jpayne@68: onlyConvertNs=Parse.parseBoolean(b); jpayne@68: }else if(a.equals("ploidy")){ jpayne@68: ploidy=Integer.parseInt(b); jpayne@68: }else if(a.equals("mindepth")){ jpayne@68: minDepth=Integer.parseInt(b); jpayne@68: }else if(a.equals("trimdepth") || a.equals("trimdepthfraction")){ jpayne@68: trimDepthFraction=Float.parseFloat(b); jpayne@68: }else if(a.equalsIgnoreCase("trimNs")){ jpayne@68: trimNs=Parse.parseBoolean(b); jpayne@68: }else if(a.equalsIgnoreCase("mafn") || a.equals("mafnoref")){ jpayne@68: MAF_noref=Float.parseFloat(b); jpayne@68: }else if(a.equalsIgnoreCase("mafsub")){ jpayne@68: MAF_sub=Float.parseFloat(b); jpayne@68: }else if(a.equalsIgnoreCase("mafdel")){ jpayne@68: MAF_del=Float.parseFloat(b); jpayne@68: }else if(a.equalsIgnoreCase("mafins")){ jpayne@68: MAF_ins=Float.parseFloat(b); jpayne@68: }else if(a.equalsIgnoreCase("maf")){ jpayne@68: MAF_ins=MAF_noref=MAF_del=MAF_sub=Float.parseFloat(b); jpayne@68: }else if(a.equalsIgnoreCase("mafindel")){ jpayne@68: MAF_ins=MAF_del=Float.parseFloat(b); jpayne@68: }else if(a.equals("clearfilters")){ jpayne@68: if(Parse.parseBoolean(b)){ jpayne@68: samFilter.clear(); jpayne@68: } jpayne@68: }else if(a.equals("parse_flag_goes_here")){ jpayne@68: long fake_variable=Parse.parseKMG(b); jpayne@68: //Set a variable here jpayne@68: }else if(samFilter.parse(arg, a, b)){ jpayne@68: //do nothing jpayne@68: }else if(parser.parse(arg, a, b)){//Parse standard flags in the parser jpayne@68: //do nothing jpayne@68: }else{ jpayne@68: outstream.println("Unknown parameter "+args[i]); jpayne@68: assert(false) : "Unknown parameter "+args[i]; jpayne@68: } jpayne@68: } jpayne@68: jpayne@68: if(ref!=null && !Tools.existsInput(ref)){ jpayne@68: specialRef=ProkObject.isSpecialType(ref); jpayne@68: } jpayne@68: jpayne@68: return parser; jpayne@68: } jpayne@68: jpayne@68: /** Add or remove .gz or .bz2 as needed */ jpayne@68: private void fixExtensions(){ jpayne@68: in=Tools.fixExtension(in); jpayne@68: if(!specialRef){ref=Tools.fixExtension(ref);} jpayne@68: } jpayne@68: jpayne@68: /** Ensure files can be read and written */ jpayne@68: private void checkFileExistence(){ jpayne@68: jpayne@68: //Ensure there is an input file jpayne@68: if(in==null){throw new RuntimeException("Error - an input file is required.");} jpayne@68: jpayne@68: //Ensure there is an input file jpayne@68: if(ref==null){throw new RuntimeException("Error - a reference file is required.");} jpayne@68: jpayne@68: //Ensure output files can be written jpayne@68: if(!Tools.testOutputFiles(overwrite, append, false, out, outModel, outHistFile)){ jpayne@68: outstream.println((out==null)+", "+out); jpayne@68: throw new RuntimeException("\n\noverwrite="+overwrite+"; Can't write to output file "+out+" or "+outModel+"\n"); jpayne@68: } jpayne@68: jpayne@68: //Ensure input files can be read jpayne@68: if(!Tools.testInputFiles(true, true, in, inModelFile, (specialRef ? null : ref))){ jpayne@68: throw new RuntimeException("\nCan't read some input files.\n"); jpayne@68: } jpayne@68: jpayne@68: //Ensure that no file was specified multiple times jpayne@68: if(!Tools.testForDuplicateFiles(true, in, ref, out, outModel, outHistFile, inModelFile)){ jpayne@68: throw new RuntimeException("\nSome file names were specified multiple times.\n"); jpayne@68: } jpayne@68: } jpayne@68: jpayne@68: /** Adjust file-related static fields as needed for this program */ jpayne@68: private static void checkStatics(){ jpayne@68: //Adjust the number of threads for input file reading jpayne@68: if(!ByteFile.FORCE_MODE_BF1 && !ByteFile.FORCE_MODE_BF2 && Shared.threads()>2){ jpayne@68: ByteFile.FORCE_MODE_BF2=true; jpayne@68: } jpayne@68: jpayne@68: assert(FastaReadInputStream.settingsOK()); jpayne@68: } jpayne@68: jpayne@68: /** Ensure parameter ranges are within bounds and required parameters are set */ jpayne@68: private boolean validateParams(){ jpayne@68: // assert(minfoo>0 && minfoo<=maxfoo) : minfoo+", "+maxfoo; jpayne@68: return true; jpayne@68: } jpayne@68: jpayne@68: private void writeHist(String fname){ jpayne@68: ByteStreamWriter bsw=new ByteStreamWriter(fname, overwrite, append, false); jpayne@68: bsw.start(); jpayne@68: bsw.print("#Value\tIdentity"); jpayne@68: if(inModel!=null){ jpayne@68: bsw.print("\tScore"); jpayne@68: } jpayne@68: bsw.nl(); jpayne@68: for(int i=0; i0){ jpayne@68: outstream.println(Tools.number("Avg Score:", 100*scoreSum/alignedReads, 3, 8)); jpayne@68: } jpayne@68: jpayne@68: //Throw an exception of there was an error in a thread jpayne@68: if(errorState){ jpayne@68: throw new RuntimeException(getClass().getName()+" terminated in an error state; the output may be corrupt."); jpayne@68: } jpayne@68: } jpayne@68: jpayne@68: private synchronized LinkedHashMap loadReferenceCustom(){ jpayne@68: assert(!loadedRef); jpayne@68: if(specialRef){return loadReferenceSpecial();} jpayne@68: ConcurrentReadInputStream cris=makeRefCris(); jpayne@68: LinkedHashMap map=new LinkedHashMap(); jpayne@68: ListNum ln=cris.nextList(); jpayne@68: for(; ln!=null && !ln.isEmpty(); ln=cris.nextList()){ jpayne@68: if(verbose){outstream.println("Fetched "+ln.size()+" reference sequences.");} jpayne@68: for(Read r : ln){ jpayne@68: if(r.bases!=null && r.bases.length>0){ jpayne@68: BaseGraph bg=new BaseGraph(r.id, r.bases, r.quality, r.numericID, 0); jpayne@68: map.put(r.name(), bg); jpayne@68: // if(inModel!=null && inModel.name.equals(bg.name)){ jpayne@68: //// assert(false) : Arrays.toString(bg.refWeights)+"\n"+Arrays.toString(inModel.refWeights); jpayne@68: // bg.refWeights=inModel.refWeights; jpayne@68: // bg.insWeights=inModel.insWeights; jpayne@68: // bg.delWeights=inModel.delWeights; jpayne@68: // }else{ jpayne@68: // bg.insWeights=new float[bg.ref.length]; jpayne@68: // bg.delWeights=new float[bg.ref.length]; jpayne@68: // Arrays.fill(bg.insWeights, 1); jpayne@68: // Arrays.fill(bg.delWeights, 1); jpayne@68: //// assert(false) : Arrays.toString(bg.delWeights); jpayne@68: // } jpayne@68: } jpayne@68: } jpayne@68: if(ln!=null){ jpayne@68: cris.returnList(ln.id, ln.list==null || ln.list.isEmpty()); jpayne@68: } jpayne@68: } jpayne@68: if(verbose){outstream.println("Loaded "+map.size()+" reference sequences.");} jpayne@68: loadedRef=true; jpayne@68: return map; jpayne@68: } jpayne@68: jpayne@68: //For ribo subunits in resources directory jpayne@68: private synchronized LinkedHashMap loadReferenceSpecial(){ jpayne@68: assert(!loadedRef); jpayne@68: Read[] array=ProkObject.loadConsensusSequenceType(ref, false, false); jpayne@68: Read r=array[0]; jpayne@68: BaseGraph bg=new BaseGraph(r.id, r.bases, r.quality, r.numericID, 0); jpayne@68: LinkedHashMap map=new LinkedHashMap(); jpayne@68: map.put(r.name(), bg); jpayne@68: return map; jpayne@68: } jpayne@68: jpayne@68: private synchronized void makeRefMap2(){ jpayne@68: assert(refMap!=null && refMap2==null); jpayne@68: if(verbose){outstream.println("Making refMap2.");} jpayne@68: refMap2=new LinkedHashMap((refMap.size()*3)/2); jpayne@68: for(Entry e : refMap.entrySet()){ jpayne@68: String key=e.getKey(); jpayne@68: if(verbose){outstream.println("Considering "+key);} jpayne@68: BaseGraph value=e.getValue(); jpayne@68: String key2=Tools.trimToWhitespace(key); jpayne@68: if(verbose){outstream.println("key2="+key2);} jpayne@68: // if(verbose){outstream.println("put "+key2+", "+value);} jpayne@68: refMap2.put(key2, value); jpayne@68: // if(verbose){outstream.println("putted "+key2+", "+value);} jpayne@68: jpayne@68: if(defaultRname==null){defaultRname=key;} jpayne@68: } jpayne@68: // assert(false) : refMap+"\n"+refMap2; jpayne@68: if(verbose){outstream.println("Made refMap2.");} jpayne@68: } jpayne@68: jpayne@68: private ConcurrentReadInputStream makeRefCris(){ jpayne@68: ConcurrentReadInputStream cris=ConcurrentReadInputStream.getReadInputStream(maxReads, true, ffref, null); jpayne@68: cris.start(); //Start the stream jpayne@68: if(verbose){outstream.println("Started cris");} jpayne@68: boolean paired=cris.paired(); jpayne@68: assert(!paired) : "References should not be paired."; jpayne@68: return cris; jpayne@68: } jpayne@68: jpayne@68: private SamStreamer makeStreamer(FileFormat ff){ jpayne@68: if(ff==null){return null;} jpayne@68: SamStreamer ss=new SamReadStreamer(ff, streamerThreads, true, maxReads); jpayne@68: ss.start(); //Start the stream jpayne@68: if(verbose){outstream.println("Started Streamer");} jpayne@68: return ss; jpayne@68: } jpayne@68: jpayne@68: private ConcurrentReadInputStream makeCris(FileFormat ff){ jpayne@68: ConcurrentReadInputStream cris=ConcurrentReadInputStream.getReadInputStream(maxReads, true, ff, null); jpayne@68: cris.start(); //Start the stream jpayne@68: if(verbose){outstream.println("Started cris");} jpayne@68: boolean paired=cris.paired(); jpayne@68: assert(!paired); jpayne@68: return cris; jpayne@68: } jpayne@68: jpayne@68: private ConcurrentReadOutputStream makeCros(){ jpayne@68: if(ffout==null){return null;} jpayne@68: jpayne@68: //Select output buffer size based on whether it needs to be ordered jpayne@68: final int buff=(ordered ? Tools.mid(16, 128, (Shared.threads()*2)/3) : 8); jpayne@68: jpayne@68: final ConcurrentReadOutputStream ros=ConcurrentReadOutputStream.getStream(ffout, null, buff, null, false); jpayne@68: ros.start(); //Start the stream jpayne@68: return ros; jpayne@68: } jpayne@68: jpayne@68: /*--------------------------------------------------------------*/ jpayne@68: /*---------------- Thread Management ----------------*/ jpayne@68: /*--------------------------------------------------------------*/ jpayne@68: jpayne@68: /** Spawn process threads */ jpayne@68: private void spawnThreads(final SamStreamer ss){ jpayne@68: jpayne@68: //Do anything necessary prior to processing jpayne@68: jpayne@68: //Determine how many threads may be used jpayne@68: final int threads=Shared.threads(); jpayne@68: jpayne@68: //Fill a list with ProcessThreads jpayne@68: ArrayList alpt=new ArrayList(threads); jpayne@68: for(int i=0; i alpt=new ArrayList(threads); jpayne@68: for(int i=0; i consensusList=new ArrayList(200); jpayne@68: ArrayList graphList=new ArrayList(200); jpayne@68: long num=0; jpayne@68: for(Entry e : refMap.entrySet()){ jpayne@68: BaseGraph bg=e.getValue(); jpayne@68: graphList.add(bg); jpayne@68: jpayne@68: Read r=bg.traverse(); jpayne@68: if(name!=null){r.id=name;} jpayne@68: consensusList.add(r); jpayne@68: jpayne@68: refCount+=bg.refCount; jpayne@68: subCount+=bg.subCount; jpayne@68: delCount+=bg.delCount; jpayne@68: insCount+=bg.insCount; jpayne@68: jpayne@68: readsOut++; jpayne@68: basesOut+=r.length(); jpayne@68: jpayne@68: if(consensusList.size()>=200){ jpayne@68: if(ros!=null){ros.add(consensusList, num);} jpayne@68: consensusList=new ArrayList(200); jpayne@68: num++; jpayne@68: } jpayne@68: } jpayne@68: if(consensusList.size()>0){ jpayne@68: if(ros!=null){ros.add(consensusList, num);} jpayne@68: consensusList=new ArrayList(200); jpayne@68: num++; jpayne@68: } jpayne@68: if(graphList.size()>0 && ffmodel!=null){ jpayne@68: // ReadWrite.writeObjectInThread(graphList, ffmodel.name(), true); jpayne@68: ReadWrite.writeAsync(graphList, ffmodel.name(), true); jpayne@68: } jpayne@68: } jpayne@68: jpayne@68: @Override jpayne@68: public final void accumulate(ProcessThread pt){ jpayne@68: readsProcessed+=pt.readsProcessedT; jpayne@68: basesProcessed+=pt.basesProcessedT; jpayne@68: alignedReads+=pt.alignedReadsT; jpayne@68: identitySum+=pt.identitySumT; jpayne@68: scoreSum+=pt.scoreSumT; jpayne@68: for(int i=0; i ln=ss.nextReads(); ln!=null; ln=ss.nextReads()){ jpayne@68: processList(ln); jpayne@68: } jpayne@68: }else{ jpayne@68: for(ListNum ln=cris.nextList(); ln!=null && ln.size()>0; ln=cris.nextList()){ jpayne@68: processList(ln); jpayne@68: cris.returnList(ln); jpayne@68: } jpayne@68: } jpayne@68: jpayne@68: } jpayne@68: jpayne@68: void processList(ListNum ln){ jpayne@68: jpayne@68: //Loop through each read in the list jpayne@68: for(Read r : ln){ jpayne@68: jpayne@68: //Validate reads in worker threads jpayne@68: if(!r.validated()){r.validate(true);} jpayne@68: jpayne@68: //Track the initial length for statistics jpayne@68: final int initialLength=r.length(); jpayne@68: jpayne@68: //Increment counters jpayne@68: readsProcessedT++; jpayne@68: basesProcessedT+=initialLength; jpayne@68: jpayne@68: { jpayne@68: //Reads are processed in this block. jpayne@68: processRead(r); jpayne@68: } jpayne@68: } jpayne@68: } jpayne@68: jpayne@68: /** jpayne@68: * Process a read or a read pair. jpayne@68: * @param r Read 1 jpayne@68: * @param r2 Read 2 (may be null) jpayne@68: * @return True if the reads should be kept, false if they should be discarded. jpayne@68: */ jpayne@68: void processRead(final Read r){ jpayne@68: if(r.bases==null || r.length()<=1){return;} jpayne@68: jpayne@68: final SamLine sl=r.samline; jpayne@68: if(sl!=null && !sl.mapped()){return;} jpayne@68: final String rname=(sl==null ? defaultRname : sl.rnameS()); jpayne@68: BaseGraph bg=refMap.get(rname); jpayne@68: if(bg==null){bg=refMap2.get(Tools.trimToWhitespace(rname));} jpayne@68: assert(bg!=null) : "Can't find graph for "+rname; jpayne@68: float identity; jpayne@68: float score=0;//unused jpayne@68: jpayne@68: // assert(false) : r; jpayne@68: if(sl==null){ jpayne@68: // identity=SketchObject.alignAndMakeMatch(r, bg.original); jpayne@68: // assert(false) : bg.refWeights[0]; jpayne@68: // identity=SketchObject.alignAndMakeMatch(r, bg.original, bg.refWeights, bg.insWeights, bg.delWeights); jpayne@68: identity=SketchObject.alignAndMakeMatch(r, bg.original, bg.refWeights); jpayne@68: if(identity<=0){return;} jpayne@68: assert(r.match!=null) : identity+", "+r; jpayne@68: }else{ jpayne@68: assert(sl!=null && sl.mapped() && sl.seq!=null) : sl; jpayne@68: assert(r.match!=null); jpayne@68: if(samFilter!=null && !samFilter.passesFilter(sl)){return;} jpayne@68: identity=sl.calcIdentity(); jpayne@68: } jpayne@68: assert(r.match!=null && identity>0) : identity+", "+r; jpayne@68: jpayne@68: if(inModel!=null){ jpayne@68: jpayne@68: if(verbose){System.err.println(r.start+"\t"+r.stop+"\t"+new String(r.match));} jpayne@68: score=inModel.score(r, false, true); jpayne@68: if(printScores){ jpayne@68: // System.err.println(identity+"\t"+score+"\t"+inModel.score(r, false, true)); jpayne@68: System.err.println(String.format("%.5f\t%.5f", identity, score)); jpayne@68: } jpayne@68: // assert(false); jpayne@68: // if(score<0){ jpayne@68: // verbose=true; jpayne@68: // inModel.score(r, false, false); jpayne@68: // } jpayne@68: // assert(!verbose); jpayne@68: } jpayne@68: jpayne@68: alignedReadsT++; jpayne@68: identitySumT+=identity; jpayne@68: scoreSumT+=score; jpayne@68: idHistT[Tools.mid(0, Math.round(100*identity), 100)]++; jpayne@68: scoreHistT[Tools.mid(0, Math.round(100*score), 100)]++; jpayne@68: jpayne@68: jpayne@68: jpayne@68: // assert(sl.calcIdentity()<=0.78) : sl.calcIdentity()+", "+samFilter.maxId; jpayne@68: // assert(false) : sl.cigar+", "+sl.calcIdentity(); jpayne@68: jpayne@68: // System.err.println(rname); jpayne@68: jpayne@68: if(realigner!=null) { jpayne@68: assert(false); jpayne@68: realigner.realign(r, sl, bg.original, true); jpayne@68: } jpayne@68: jpayne@68: bg.add(r); jpayne@68: } jpayne@68: jpayne@68: long[] idHistT=new long[101]; jpayne@68: long[] scoreHistT=new long[101]; jpayne@68: jpayne@68: /** Number of reads processed by this thread */ jpayne@68: protected long readsProcessedT=0; jpayne@68: /** Number of bases processed by this thread */ jpayne@68: protected long basesProcessedT=0; jpayne@68: jpayne@68: protected long alignedReadsT=0; jpayne@68: jpayne@68: double identitySumT=0; jpayne@68: double scoreSumT=0; jpayne@68: jpayne@68: /** True only if this thread has completed successfully */ jpayne@68: boolean success=false; jpayne@68: jpayne@68: /** Shared input stream */ jpayne@68: private final SamStreamer ss; jpayne@68: /** Alternate input stream */ jpayne@68: private final ConcurrentReadInputStream cris; jpayne@68: /** Thread ID */ jpayne@68: final int tid; jpayne@68: /** For realigning reads */ jpayne@68: final Realigner realigner; jpayne@68: } jpayne@68: jpayne@68: /*--------------------------------------------------------------*/ jpayne@68: /*---------------- Fields ----------------*/ jpayne@68: /*--------------------------------------------------------------*/ jpayne@68: jpayne@68: /** Read input file path */ jpayne@68: private String in=null; jpayne@68: /** Reference input file path */ jpayne@68: private String ref=null; jpayne@68: jpayne@68: private String inModelFile; jpayne@68: private BaseGraph inModel; jpayne@68: private String outHistFile; jpayne@68: jpayne@68: /** Consensus output file path */ jpayne@68: private String out=null; jpayne@68: /** Model output file path */ jpayne@68: private String outModel=null; jpayne@68: jpayne@68: /** Override input file extension */ jpayne@68: private String extin=null; jpayne@68: /** Override output file extension */ jpayne@68: private String extout=null; jpayne@68: jpayne@68: /*--------------------------------------------------------------*/ jpayne@68: jpayne@68: /** Number of reads processed */ jpayne@68: protected long readsProcessed=0; jpayne@68: /** Number of bases processed */ jpayne@68: protected long basesProcessed=0; jpayne@68: jpayne@68: protected long alignedReads=0; jpayne@68: jpayne@68: protected double identitySum=0; jpayne@68: protected double scoreSum=0; jpayne@68: jpayne@68: /** Number of reads retained */ jpayne@68: protected long readsOut=0; jpayne@68: /** Number of bases retained */ jpayne@68: protected long basesOut=0; jpayne@68: jpayne@68: /** Quit after processing this many input reads; -1 means no limit */ jpayne@68: private long maxReads=-1; jpayne@68: jpayne@68: public long subCount=0; jpayne@68: public long refCount=0; jpayne@68: public long delCount=0; jpayne@68: public long insCount=0; jpayne@68: jpayne@68: long[] idHist=new long[101]; jpayne@68: long[] scoreHist=new long[101]; jpayne@68: boolean printScores=false; jpayne@68: jpayne@68: /*--------------------------------------------------------------*/ jpayne@68: jpayne@68: /** Threads dedicated to reading the sam file */ jpayne@68: private int streamerThreads=SamStreamer.DEFAULT_THREADS; jpayne@68: jpayne@68: private String name=null; jpayne@68: jpayne@68: private boolean loadedRef=false; jpayne@68: private boolean specialRef=false; jpayne@68: jpayne@68: private boolean realign=false; jpayne@68: jpayne@68: private int ploidy=1; jpayne@68: jpayne@68: private final boolean silent; jpayne@68: jpayne@68: public final SamFilter samFilter=new SamFilter(); jpayne@68: /** Uses full ref names */ jpayne@68: public LinkedHashMap refMap; jpayne@68: /** Uses truncated ref names */ jpayne@68: public LinkedHashMap refMap2; jpayne@68: jpayne@68: private String defaultRname=null; jpayne@68: jpayne@68: /*--------------------------------------------------------------*/ jpayne@68: /*---------------- Final Fields ----------------*/ jpayne@68: /*--------------------------------------------------------------*/ jpayne@68: jpayne@68: /** Read input file */ jpayne@68: private final FileFormat ffin; jpayne@68: /** Reference input file */ jpayne@68: private final FileFormat ffref; jpayne@68: jpayne@68: /** Consensus output file */ jpayne@68: private final FileFormat ffout; jpayne@68: /** Model output file */ jpayne@68: private final FileFormat ffmodel; jpayne@68: jpayne@68: /*--------------------------------------------------------------*/ jpayne@68: /*---------------- Common Fields ----------------*/ jpayne@68: /*--------------------------------------------------------------*/ jpayne@68: jpayne@68: /** Print status messages to this output stream */ jpayne@68: private PrintStream outstream=System.err; jpayne@68: /** True if an error was encountered */ jpayne@68: public boolean errorState=false; jpayne@68: /** Overwrite existing output files */ jpayne@68: private boolean overwrite=false; jpayne@68: /** Append to existing output files */ jpayne@68: private boolean append=false; jpayne@68: /** Reads ARE output in input order, even though this is false */ jpayne@68: private final boolean ordered=false; jpayne@68: jpayne@68: }