Mercurial > repos > rliterman > csp2
comparison CSP2/CSP2_env/env-d9b9114564458d9d-741b3de822f2aaca6c6caa4325c4afce/opt/bbmap-39.01-1/current/prok/MergeRibo.java @ 68:5028fdace37b
planemo upload commit 2e9511a184a1ca667c7be0c6321a36dc4e3d116d
author | jpayne |
---|---|
date | Tue, 18 Mar 2025 16:23:26 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
67:0e9998148a16 | 68:5028fdace37b |
---|---|
1 package prok; | |
2 | |
3 import java.io.File; | |
4 import java.io.PrintStream; | |
5 import java.util.ArrayList; | |
6 import java.util.Collections; | |
7 import java.util.Comparator; | |
8 import java.util.HashMap; | |
9 import java.util.Map.Entry; | |
10 import java.util.concurrent.ConcurrentLinkedQueue; | |
11 | |
12 import aligner.SingleStateAlignerFlat2; | |
13 import consensus.BaseGraph; | |
14 import fileIO.ByteFile; | |
15 import fileIO.FileFormat; | |
16 import fileIO.ReadWrite; | |
17 import shared.Parse; | |
18 import shared.Parser; | |
19 import shared.PreParser; | |
20 import shared.ReadStats; | |
21 import shared.Shared; | |
22 import shared.Timer; | |
23 import shared.Tools; | |
24 import stream.ConcurrentReadInputStream; | |
25 import stream.ConcurrentReadOutputStream; | |
26 import stream.FASTQ; | |
27 import stream.FastaReadInputStream; | |
28 import stream.Read; | |
29 import structures.IntHashSet; | |
30 import structures.ListNum; | |
31 import tax.GiToTaxid; | |
32 import template.Accumulator; | |
33 import template.ThreadWaiter; | |
34 | |
35 /** | |
36 * Picks one ribosomal (16S) sequence per taxID. | |
37 * | |
38 * @author Brian Bushnell | |
39 * @date November 19, 2015 | |
40 * | |
41 */ | |
42 public class MergeRibo implements Accumulator<MergeRibo.ProcessThread> { | |
43 | |
44 /*--------------------------------------------------------------*/ | |
45 /*---------------- Initialization ----------------*/ | |
46 /*--------------------------------------------------------------*/ | |
47 | |
48 /** | |
49 * Code entrance from the command line. | |
50 * @param args Command line arguments | |
51 */ | |
52 public static void main(String[] args){ | |
53 //Start a timer immediately upon code entrance. | |
54 Timer t=new Timer(); | |
55 | |
56 //Create an instance of this class | |
57 MergeRibo x=new MergeRibo(args); | |
58 | |
59 //Run the object | |
60 x.process(t); | |
61 | |
62 //Close the print stream if it was redirected | |
63 Shared.closeStream(x.outstream); | |
64 } | |
65 | |
66 /** | |
67 * Constructor. | |
68 * @param args Command line arguments | |
69 */ | |
70 public MergeRibo(String[] args){ | |
71 | |
72 {//Preparse block for help, config files, and outstream | |
73 PreParser pp=new PreParser(args, getClass(), false); | |
74 args=pp.args; | |
75 outstream=pp.outstream; | |
76 } | |
77 | |
78 //Set shared static variables prior to parsing | |
79 ReadWrite.USE_PIGZ=ReadWrite.USE_UNPIGZ=true; | |
80 ReadWrite.MAX_ZIP_THREADS=Shared.threads(); | |
81 // Shared.capBufferLen(40);//This does not help; the slowness comes from unevenness in list length during pickBest. | |
82 //To fix it, long lists should be sorted to be first. | |
83 | |
84 BaseGraph.MAF_sub=0.251f; | |
85 BaseGraph.MAF_del=0.0f; | |
86 BaseGraph.MAF_ins=0.0f; | |
87 BaseGraph.MAF_noref=0.0f; | |
88 BaseGraph.trimDepthFraction=0.3f; | |
89 BaseGraph.trimNs=true; | |
90 | |
91 {//Parse the arguments | |
92 final Parser parser=parse(args); | |
93 Parser.processQuality(); | |
94 | |
95 maxReads=parser.maxReads; | |
96 overwrite=ReadStats.overwrite=parser.overwrite; | |
97 append=ReadStats.append=parser.append; | |
98 | |
99 extin=parser.extin; | |
100 | |
101 out1=parser.out1; | |
102 extout=parser.extout; | |
103 } | |
104 | |
105 validateParams(); | |
106 adjustInterleaving(); //Make sure interleaving agrees with number of input and output files | |
107 checkFileExistence(); //Ensure files can be read and written | |
108 checkStatics(); //Adjust file-related static fields as needed for this program | |
109 | |
110 //Create output FileFormat objects | |
111 ffout1=FileFormat.testOutput(out1, FileFormat.FASTA, extout, true, overwrite, append, ordered); | |
112 | |
113 //Create input FileFormat objects | |
114 ffin=new ArrayList<FileFormat>(in.size()); | |
115 ffalt=FileFormat.testInput(alt, FileFormat.FASTA, extin, true, true); | |
116 for(String s : in){ | |
117 FileFormat ff=FileFormat.testInput(s, FileFormat.FASTA, extin, true, true); | |
118 ffin.add(ff); | |
119 } | |
120 | |
121 //Determine how many threads may be used | |
122 threads=Shared.threads(); | |
123 } | |
124 | |
125 /*--------------------------------------------------------------*/ | |
126 /*---------------- Initialization Helpers ----------------*/ | |
127 /*--------------------------------------------------------------*/ | |
128 | |
129 /** Parse arguments from the command line */ | |
130 private Parser parse(String[] args){ | |
131 | |
132 //Create a parser object | |
133 Parser parser=new Parser(); | |
134 | |
135 //Set any necessary Parser defaults here | |
136 //parser.foo=bar; | |
137 | |
138 //Parse each argument | |
139 for(int i=0; i<args.length; i++){ | |
140 String arg=args[i]; | |
141 | |
142 //Break arguments into their constituent parts, in the form of "a=b" | |
143 String[] split=arg.split("="); | |
144 String a=split[0].toLowerCase(); | |
145 String b=split.length>1 ? split[1] : null; | |
146 if(b!=null && b.equalsIgnoreCase("null")){b=null;} | |
147 | |
148 if(a.equals("verbose")){ | |
149 verbose=Parse.parseBoolean(b); | |
150 }else if(a.equals("ordered")){ | |
151 ordered=Parse.parseBoolean(b); | |
152 }else if(a.equals("consensus")){ | |
153 useConsensus=Parse.parseBoolean(b); | |
154 }else if(a.equals("best")){ | |
155 useConsensus=!Parse.parseBoolean(b); | |
156 }else if(a.equals("fast")){ | |
157 fast=Parse.parseBoolean(b); | |
158 }else if(a.equals("minid")){ | |
159 minID=Float.parseFloat(b); | |
160 }else if(a.equals("maxns")){ | |
161 maxns=Integer.parseInt(b); | |
162 }else if(a.equals("minlen")){ | |
163 minlen=Integer.parseInt(b); | |
164 }else if(a.equals("maxlen")){ | |
165 maxlen=Integer.parseInt(b); | |
166 }else if(a.equals("in")){ | |
167 Tools.addFiles(b, in); | |
168 }else if(a.equals("alt")){ | |
169 alt=b; | |
170 }else if(a.equalsIgnoreCase("process16S") || a.equalsIgnoreCase("16S")){ | |
171 process16S=Parse.parseBoolean(b); | |
172 process18S=!process16S; | |
173 }else if(a.equalsIgnoreCase("process18S") || a.equalsIgnoreCase("18S")){ | |
174 process18S=Parse.parseBoolean(b); | |
175 process16S=!process18S; | |
176 }else if(a.equals("parse_flag_goes_here")){ | |
177 long fake_variable=Parse.parseKMG(b); | |
178 //Set a variable here | |
179 }else if(parser.parse(arg, a, b)){//Parse standard flags in the parser | |
180 //do nothing | |
181 }else if(b==null && new File(arg).exists()){ | |
182 in.add(arg); | |
183 }else{ | |
184 outstream.println("Unknown parameter "+args[i]); | |
185 assert(false) : "Unknown parameter "+args[i]; | |
186 } | |
187 } | |
188 assert(!in.isEmpty()) : "No input file."; | |
189 return parser; | |
190 } | |
191 | |
192 /** Ensure files can be read and written */ | |
193 private void checkFileExistence(){ | |
194 //Ensure output files can be written | |
195 if(!Tools.testOutputFiles(overwrite, append, false, out1)){ | |
196 outstream.println((out1==null)+", "+out1); | |
197 throw new RuntimeException("\n\noverwrite="+overwrite+"; Can't write to output files "+out1+"\n"); | |
198 } | |
199 | |
200 //Ensure input files can be read | |
201 if(!Tools.testInputFiles(false, true, in)){ | |
202 throw new RuntimeException("\nCan't read some input files.\n"); | |
203 } | |
204 | |
205 // //Ensure that no file was specified multiple times | |
206 // if(!Tools.testForDuplicateFiles(true, out1, in.toArray(new String[0]))){ | |
207 // throw new RuntimeException("\nSome file names were specified multiple times.\n"); | |
208 // } | |
209 } | |
210 | |
211 /** Make sure interleaving agrees with number of input and output files */ | |
212 private void adjustInterleaving(){ | |
213 FASTQ.FORCE_INTERLEAVED=FASTQ.TEST_INTERLEAVED=false; | |
214 } | |
215 | |
216 /** Adjust file-related static fields as needed for this program */ | |
217 private static void checkStatics(){ | |
218 //Adjust the number of threads for input file reading | |
219 if(!ByteFile.FORCE_MODE_BF1 && !ByteFile.FORCE_MODE_BF2 && Shared.threads()>2){ | |
220 ByteFile.FORCE_MODE_BF2=true; | |
221 } | |
222 | |
223 assert(FastaReadInputStream.settingsOK()); | |
224 } | |
225 | |
226 /** Ensure parameter ranges are within bounds and required parameters are set */ | |
227 private boolean validateParams(){ | |
228 // assert(minfoo>0 && minfoo<=maxfoo) : minfoo+", "+maxfoo; | |
229 // assert(false) : "TODO"; | |
230 assert(process16S || process18S) : "16S or 18S must be selected."; | |
231 assert(!process16S || !process18S) : "16S or 18S are both selected; only one may be active."; | |
232 return true; | |
233 } | |
234 | |
235 /*--------------------------------------------------------------*/ | |
236 /*---------------- Outer Methods ----------------*/ | |
237 /*--------------------------------------------------------------*/ | |
238 | |
239 /** Create read streams and process all data */ | |
240 void process(Timer t){ | |
241 | |
242 if(process16S){ | |
243 Read[] data=ProkObject.loadConsensusSequenceType("16S", true, true); | |
244 consensus16S=data[0].bases; | |
245 if(verbose){System.err.println("process16S: Loaded 16S consensus, length "+consensus16S.length+": "+new String(consensus16S));} | |
246 } | |
247 if(process18S){ | |
248 Read[] data=ProkObject.loadConsensusSequenceType("18S", true, true); | |
249 consensus18S=data[0].bases; | |
250 if(verbose){System.err.println("process18S: Loaded 18S consensus, length "+consensus18S.length+": "+new String(consensus18S));} | |
251 } | |
252 | |
253 //Turn off read validation in the input threads to increase speed | |
254 final boolean vic=Read.VALIDATE_IN_CONSTRUCTOR; | |
255 Read.VALIDATE_IN_CONSTRUCTOR=Shared.threads()<4; | |
256 | |
257 //Reset counters | |
258 readsProcessed=readsOut=0; | |
259 basesProcessed=basesOut=0; | |
260 | |
261 //Align everything to global consensus | |
262 for(FileFormat ff : ffin) { | |
263 //Create a read input stream | |
264 final ConcurrentReadInputStream cris=makeCris(ff); | |
265 | |
266 //Process the reads in separate threads | |
267 spawnThreads(cris, false); | |
268 errorState|=ReadWrite.closeStream(cris); | |
269 } | |
270 | |
271 if(ffalt!=null){ | |
272 //Create a read input stream | |
273 final ConcurrentReadInputStream cris=makeCris(ffalt); | |
274 | |
275 //Process the reads in separate threads | |
276 spawnThreads(cris, true); | |
277 errorState|=ReadWrite.closeStream(cris); | |
278 } | |
279 | |
280 // queue=new ConcurrentLinkedQueue<ArrayList<Ribo>>(); | |
281 // for(Entry<Integer, ArrayList<Ribo>> e : listMap.entrySet()){ | |
282 // queue.add(e.getValue()); | |
283 // } | |
284 // listMap=null; | |
285 queue=makeQueue(); | |
286 | |
287 //Run a second pass to pick the best SSU per taxID | |
288 spawnThreads(null, false); | |
289 | |
290 //Do anything necessary after processing | |
291 if(ffout1!=null){ | |
292 //Optionally create a read output stream | |
293 final ConcurrentReadOutputStream ros=makeCros(); | |
294 long num=0; | |
295 for(Ribo ribo : bestList){ | |
296 Read r=ribo.r; | |
297 readsOut++; | |
298 basesOut+=r.length(); | |
299 ArrayList<Read> list=new ArrayList<Read>(1); | |
300 list.add(r); | |
301 ros.add(list, num); | |
302 num++; | |
303 } | |
304 //Close the read streams | |
305 errorState|=ReadWrite.closeStream(ros); | |
306 } | |
307 | |
308 if(verbose){outstream.println("Finished; closing streams.");} | |
309 | |
310 //Write anything that was accumulated by ReadStats | |
311 errorState|=ReadStats.writeAll(); | |
312 | |
313 //Reset read validation | |
314 Read.VALIDATE_IN_CONSTRUCTOR=vic; | |
315 | |
316 //Report timing and results | |
317 t.stop(); | |
318 outstream.println(Tools.timeReadsBasesProcessed(t, readsProcessed, basesProcessed, 8)); | |
319 outstream.println(Tools.readsBasesOut(readsProcessed, basesProcessed, readsOut, basesOut, 8, false)); | |
320 | |
321 //Throw an exception of there was an error in a thread | |
322 if(errorState){ | |
323 throw new RuntimeException(getClass().getName()+" terminated in an error state; the output may be corrupt."); | |
324 } | |
325 } | |
326 | |
327 private ConcurrentLinkedQueue<ArrayList<Ribo>> makeQueue(){ | |
328 ArrayList<ArrayList<Ribo>> listList=new ArrayList<ArrayList<Ribo>>(listMap.size()); | |
329 for(Entry<Integer, ArrayList<Ribo>> e : listMap.entrySet()){ | |
330 listList.add(e.getValue()); | |
331 } | |
332 listMap=null; | |
333 Collections.sort(listList, new ListComparator()); | |
334 assert(listList.isEmpty() || listList.get(0).size()>=listList.get(listList.size()-1).size()); | |
335 ConcurrentLinkedQueue<ArrayList<Ribo>> q=new ConcurrentLinkedQueue<ArrayList<Ribo>>(); | |
336 for(ArrayList<Ribo> x : listList){ | |
337 q.add(x); | |
338 } | |
339 return q; | |
340 } | |
341 | |
342 private ConcurrentReadInputStream makeCris(FileFormat ff){ | |
343 ConcurrentReadInputStream cris=ConcurrentReadInputStream.getReadInputStream(maxReads, true, ff, null); | |
344 cris.start(); //Start the stream | |
345 if(verbose){outstream.println("Started cris");} | |
346 boolean paired=cris.paired(); | |
347 assert(!paired) : "This should not be paired input."; | |
348 return cris; | |
349 } | |
350 | |
351 private ConcurrentReadOutputStream makeCros(){ | |
352 if(ffout1==null){return null;} | |
353 | |
354 //Select output buffer size based on whether it needs to be ordered | |
355 final int buff=(ordered ? Tools.mid(16, 128, (Shared.threads()*2)/3) : 8); | |
356 | |
357 final ConcurrentReadOutputStream ros=ConcurrentReadOutputStream.getStream(ffout1, null, buff, null, false); | |
358 ros.start(); //Start the stream | |
359 return ros; | |
360 } | |
361 | |
362 /*--------------------------------------------------------------*/ | |
363 /*---------------- Thread Management ----------------*/ | |
364 /*--------------------------------------------------------------*/ | |
365 | |
366 /** Spawn process threads */ | |
367 private void spawnThreads(final ConcurrentReadInputStream cris, boolean altData){ | |
368 | |
369 //Do anything necessary prior to processing | |
370 | |
371 //Fill a list with ProcessThreads | |
372 if(verbose){System.err.println("Spawning "+threads+" threads.");} | |
373 ArrayList<ProcessThread> alpt=new ArrayList<ProcessThread>(threads); | |
374 for(int i=0; i<threads; i++){ | |
375 alpt.add(new ProcessThread(cris, i, altData)); | |
376 } | |
377 | |
378 //Start the threads and wait for them to finish | |
379 boolean success=ThreadWaiter.startAndWait(alpt, this); | |
380 if(verbose){System.err.println("Threads finished with success="+success+".");} | |
381 errorState&=!success; | |
382 } | |
383 | |
384 @Override | |
385 public final void accumulate(ProcessThread pt){ | |
386 readsProcessed+=pt.readsProcessedT; | |
387 basesProcessed+=pt.basesProcessedT; | |
388 errorState|=(!pt.success); | |
389 } | |
390 | |
391 @Override | |
392 public final boolean success(){return !errorState;} | |
393 | |
394 /*--------------------------------------------------------------*/ | |
395 /*---------------- Inner Methods ----------------*/ | |
396 /*--------------------------------------------------------------*/ | |
397 | |
398 /*--------------------------------------------------------------*/ | |
399 /*---------------- Inner Classes ----------------*/ | |
400 /*--------------------------------------------------------------*/ | |
401 | |
402 /** This class is static to prevent accidental writing to shared variables. | |
403 * It is safe to remove the static modifier. */ | |
404 class ProcessThread extends Thread { | |
405 | |
406 //Constructor | |
407 ProcessThread(final ConcurrentReadInputStream cris_, final int tid_, boolean alt_){ | |
408 cris=cris_; | |
409 tid=tid_; | |
410 processInput=(cris!=null); | |
411 altData=alt_; | |
412 } | |
413 | |
414 //Called by start() | |
415 @Override | |
416 public void run(){ | |
417 //Do anything necessary prior to processing | |
418 | |
419 if(processInput){ | |
420 //Process the reads | |
421 processInner(); | |
422 }else{ | |
423 pickBest(); | |
424 } | |
425 | |
426 //Do anything necessary after processing | |
427 | |
428 //Indicate successful exit status | |
429 success=true; | |
430 } | |
431 | |
432 /** Iterate through the reads */ | |
433 void processInner(){ | |
434 if(verbose && tid==0){System.err.println("processInner() for tid="+tid);} | |
435 | |
436 //Grab the first ListNum of reads | |
437 ListNum<Read> ln=cris.nextList(); | |
438 | |
439 //Check to ensure pairing is as expected | |
440 if(ln!=null && !ln.isEmpty()){ | |
441 Read r=ln.get(0); | |
442 // assert(ffin1.samOrBam() || (r.mate!=null)==cris.paired()); //Disabled due to non-static access | |
443 } | |
444 | |
445 //As long as there is a nonempty read list... | |
446 while(ln!=null && ln.size()>0){ | |
447 // if(verbose){outstream.println("Fetched "+reads.size()+" reads.");} //Disabled due to non-static access | |
448 | |
449 processInput(ln); | |
450 | |
451 //Notify the input stream that the list was used | |
452 cris.returnList(ln); | |
453 // if(verbose){outstream.println("Returned a list.");} //Disabled due to non-static access | |
454 | |
455 //Fetch a new list | |
456 ln=cris.nextList(); | |
457 } | |
458 | |
459 //Notify the input stream that the final list was used | |
460 if(ln!=null){ | |
461 cris.returnList(ln.id, ln.list==null || ln.list.isEmpty()); | |
462 } | |
463 } | |
464 | |
465 void processInput(ListNum<Read> ln){ | |
466 if(verbose && tid==0){System.err.println("processInput() for tid="+tid);} | |
467 | |
468 //Grab the actual read list from the ListNum | |
469 final ArrayList<Read> reads=ln.list; | |
470 | |
471 //Loop through each read in the list | |
472 for(int idx=0; idx<reads.size(); idx++){ | |
473 final Read r1=reads.get(idx); | |
474 | |
475 //Validate reads in worker threads | |
476 if(!r1.validated()){r1.validate(true);} | |
477 | |
478 //Track the initial length for statistics | |
479 final int initialLength1=r1.length(); | |
480 | |
481 //Increment counters | |
482 readsProcessedT++; | |
483 basesProcessedT+=initialLength1; | |
484 | |
485 processRead(r1); | |
486 } | |
487 } | |
488 | |
489 void pickBest(){ | |
490 if(verbose && tid==0){System.err.println("pickBest() for tid="+tid);} | |
491 for(ArrayList<Ribo> list=queue.poll(); list!=null; list=queue.poll()){ | |
492 Ribo best=pickBest(list); | |
493 list.clear(); | |
494 synchronized(bestList){ | |
495 bestList.add(best); | |
496 } | |
497 } | |
498 } | |
499 | |
500 Ribo pickBest(ArrayList<Ribo> list){ | |
501 if(verbose && tid==0){System.err.println("pickBest(list[="+list.size()+"]) for tid="+tid);} | |
502 assert(list!=null && list.size()>0); | |
503 if(list.size()==1){return list.get(0);} | |
504 Collections.sort(list); | |
505 Collections.reverse(list); | |
506 assert(list.get(0).product>=list.get(1).product); | |
507 if(list.size()<3 || fast){return list.get(0);} | |
508 | |
509 Ribo base=list.get(0); | |
510 int pad=Tools.max(10, (1600-base.r.length())); | |
511 BaseGraph bg=new BaseGraph(base.r.name(), base.r.bases, base.r.quality, base.r.numericID, pad); | |
512 for(Ribo r : list){ | |
513 bg.alignAndGenerateMatch(r.r, ssa); | |
514 } | |
515 Read consensus=bg.traverse(); | |
516 Ribo best; | |
517 if(useConsensus){ | |
518 best=new Ribo(consensus, base.tid, 1); | |
519 }else{ | |
520 for(Ribo r : list){ | |
521 float id=align(r.r.bases, consensus.bases); | |
522 r.identity=id; | |
523 r.product=score(r.length(), r.identity); | |
524 } | |
525 Collections.sort(list); | |
526 Collections.reverse(list); | |
527 assert(list.get(0).product>=list.get(1).product); | |
528 best=list.get(0); | |
529 } | |
530 return best; | |
531 } | |
532 | |
533 /** | |
534 * Process a read or a read pair. | |
535 * @return True if the reads should be kept, false if they should be discarded. | |
536 */ | |
537 void processRead(final Read r){ | |
538 if(verbose && tid==0){System.err.println("processRead()");} | |
539 if(r.length()<minlen || r.length()>maxlen){return;} | |
540 if(maxns>=0 && r.countNocalls()>maxns){return;} | |
541 Integer key=GiToTaxid.parseTaxidNumber(r.id, '|'); | |
542 if(verbose && tid==0){System.err.println("key="+key);} | |
543 if(key==null || key==-1 || (altData && seenTaxID.contains(key))){return;} | |
544 float id=align(r); | |
545 if(id<minID){return;} | |
546 Ribo ribo=new Ribo(r, key, id); | |
547 | |
548 synchronized(listMap){ | |
549 ArrayList<Ribo> list=listMap.get(key); | |
550 if(list==null){ | |
551 list=new ArrayList<Ribo>(8); | |
552 listMap.put(key, list); | |
553 } | |
554 list.add(ribo); | |
555 if(!altData){seenTaxID.add(key);} | |
556 } | |
557 } | |
558 | |
559 float align(Read r){ | |
560 float a=(process16S ? align(r.bases, consensus16S) : 0); | |
561 float b=(process18S ? align(r.bases, consensus18S) : 0); | |
562 if(verbose && tid==0){System.err.println("Aligned; a="+a+", b="+b);} | |
563 return Tools.max(a, b); | |
564 } | |
565 | |
566 float align(byte[] query, byte[] ref){ | |
567 int a=0, b=ref.length-1; | |
568 int[] max=ssa.fillUnlimited(query, ref, a, b, -9999); | |
569 if(max==null){return 0;} | |
570 | |
571 final int rows=max[0]; | |
572 final int maxCol=max[1]; | |
573 final int maxState=max[2]; | |
574 final float id=ssa.tracebackIdentity(query, ref, a, b, rows, maxCol, maxState, null); | |
575 return id; | |
576 } | |
577 | |
578 SingleStateAlignerFlat2 ssa=new SingleStateAlignerFlat2(); | |
579 | |
580 /** Number of reads processed by this thread */ | |
581 protected long readsProcessedT=0; | |
582 /** Number of bases processed by this thread */ | |
583 protected long basesProcessedT=0; | |
584 | |
585 /** True only if this thread has completed successfully */ | |
586 boolean success=false; | |
587 | |
588 /** Shared input stream */ | |
589 private final ConcurrentReadInputStream cris; | |
590 /** Thread ID */ | |
591 final int tid; | |
592 | |
593 //Run mode | |
594 final boolean processInput; | |
595 final boolean altData; | |
596 } | |
597 | |
598 private class Ribo implements Comparable<Ribo>{ | |
599 Ribo(Read r_, int tid_, float identity_){ | |
600 r=r_; | |
601 tid=tid_; | |
602 identity=identity_; | |
603 product=score(r.length(), identity); | |
604 } | |
605 | |
606 @Override | |
607 public int compareTo(Ribo b) { | |
608 if(b.product>product){return -1;} | |
609 else if(b.product<product){return 1;} | |
610 else if(b.r.length()>r.length()){return -1;} | |
611 else if(b.r.length()<r.length()){return 1;} | |
612 return 0; | |
613 } | |
614 | |
615 int length(){return r.length();} | |
616 | |
617 Read r; | |
618 int tid; | |
619 float identity; | |
620 float product; | |
621 } | |
622 | |
623 private class ListComparator implements Comparator<ArrayList<Ribo>> { | |
624 | |
625 @Override | |
626 public int compare(ArrayList<Ribo> a, ArrayList<Ribo> b) { | |
627 return a.size()>b.size() ? -1 : a.size()<b.size() ? 1 : 0; | |
628 } | |
629 | |
630 } | |
631 | |
632 private float lengthMult(int len){ | |
633 int idealLength=idealLength(); | |
634 int max=Tools.max(len, idealLength, 1); | |
635 int min=Tools.min(len, idealLength); | |
636 return min/(float)max; | |
637 } | |
638 | |
639 private float score(int len, float identity){ | |
640 return lengthMult(len)*identity; | |
641 } | |
642 | |
643 /*--------------------------------------------------------------*/ | |
644 /*---------------- Fields ----------------*/ | |
645 /*--------------------------------------------------------------*/ | |
646 | |
647 /** Primary input file path */ | |
648 private ArrayList<String> in=new ArrayList<String>(); | |
649 | |
650 /** Alternate input file path */ | |
651 private String alt=null; | |
652 | |
653 /** Primary output file path */ | |
654 private String out1=null; | |
655 | |
656 /** Override input file extension */ | |
657 private String extin=null; | |
658 /** Override output file extension */ | |
659 private String extout=null; | |
660 | |
661 ArrayList<Ribo> bestList=new ArrayList<Ribo>(); | |
662 HashMap<Integer, ArrayList<Ribo>> listMap=new HashMap<Integer, ArrayList<Ribo>>(100000); | |
663 ConcurrentLinkedQueue<ArrayList<Ribo>> queue; | |
664 | |
665 | |
666 IntHashSet seenTaxID=new IntHashSet(1000000); | |
667 | |
668 byte[] consensus16S; | |
669 byte[] consensus18S; | |
670 | |
671 int idealLength(){ | |
672 if(process16S){return consensus16S.length;} | |
673 return consensus18S.length; | |
674 } | |
675 | |
676 boolean useConsensus=false; | |
677 boolean fast=false; | |
678 int maxns=-1; | |
679 int minlen=1; | |
680 int maxlen=4000; | |
681 | |
682 /*--------------------------------------------------------------*/ | |
683 | |
684 /** Number of reads processed */ | |
685 protected long readsProcessed=0; | |
686 /** Number of bases processed */ | |
687 protected long basesProcessed=0; | |
688 | |
689 /** Number of reads retained */ | |
690 protected long readsOut=0; | |
691 /** Number of bases retained */ | |
692 protected long basesOut=0; | |
693 | |
694 /** Quit after processing this many input reads; -1 means no limit */ | |
695 private long maxReads=-1; | |
696 | |
697 private float minID=0.62f; | |
698 | |
699 private boolean process16S=true; | |
700 private boolean process18S=false; | |
701 | |
702 /*--------------------------------------------------------------*/ | |
703 /*---------------- Final Fields ----------------*/ | |
704 /*--------------------------------------------------------------*/ | |
705 | |
706 /** Primary input file */ | |
707 private final ArrayList<FileFormat> ffin; | |
708 private final FileFormat ffalt; | |
709 | |
710 /** Primary output file */ | |
711 private final FileFormat ffout1; | |
712 | |
713 final int threads; | |
714 | |
715 /*--------------------------------------------------------------*/ | |
716 /*---------------- Common Fields ----------------*/ | |
717 /*--------------------------------------------------------------*/ | |
718 | |
719 /** Print status messages to this output stream */ | |
720 private PrintStream outstream=System.err; | |
721 /** Print verbose messages */ | |
722 public static boolean verbose=false; | |
723 /** True if an error was encountered */ | |
724 public boolean errorState=false; | |
725 /** Overwrite existing output files */ | |
726 private boolean overwrite=false; | |
727 /** Append to existing output files */ | |
728 private boolean append=false; | |
729 /** Reads are output in input order */ | |
730 private boolean ordered=false; | |
731 | |
732 } |