jpayne@68
|
1 package sketch;
|
jpayne@68
|
2
|
jpayne@68
|
3 import java.io.PrintStream;
|
jpayne@68
|
4 import java.util.ArrayList;
|
jpayne@68
|
5 import java.util.Collections;
|
jpayne@68
|
6 import java.util.HashMap;
|
jpayne@68
|
7 import java.util.Map.Entry;
|
jpayne@68
|
8 import java.util.concurrent.atomic.AtomicInteger;
|
jpayne@68
|
9
|
jpayne@68
|
10 import fileIO.ByteFile;
|
jpayne@68
|
11 import fileIO.ByteStreamWriter;
|
jpayne@68
|
12 import fileIO.FileFormat;
|
jpayne@68
|
13 import fileIO.ReadWrite;
|
jpayne@68
|
14 import shared.Parse;
|
jpayne@68
|
15 import shared.Parser;
|
jpayne@68
|
16 import shared.PreParser;
|
jpayne@68
|
17 import shared.ReadStats;
|
jpayne@68
|
18 import shared.Shared;
|
jpayne@68
|
19 import shared.Timer;
|
jpayne@68
|
20 import shared.Tools;
|
jpayne@68
|
21 import stream.FASTQ;
|
jpayne@68
|
22 import stream.FastaReadInputStream;
|
jpayne@68
|
23 import stream.Read;
|
jpayne@68
|
24 import structures.ByteBuilder;
|
jpayne@68
|
25 import structures.FloatList;
|
jpayne@68
|
26 import tax.TaxNode;
|
jpayne@68
|
27 import tax.TaxTree;
|
jpayne@68
|
28 import template.Accumulator;
|
jpayne@68
|
29 import template.ThreadWaiter;
|
jpayne@68
|
30
|
jpayne@68
|
31 /**
|
jpayne@68
|
32 * Compares SSUs, all-to-all or fractional matrix.
|
jpayne@68
|
33 *
|
jpayne@68
|
34 * @author Brian Bushnell
|
jpayne@68
|
35 * @date December 2, 2019
|
jpayne@68
|
36 *
|
jpayne@68
|
37 */
|
jpayne@68
|
38 public class CompareSSU implements Accumulator<CompareSSU.ProcessThread> {
|
jpayne@68
|
39
|
jpayne@68
|
40 /*--------------------------------------------------------------*/
|
jpayne@68
|
41 /*---------------- Initialization ----------------*/
|
jpayne@68
|
42 /*--------------------------------------------------------------*/
|
jpayne@68
|
43
|
jpayne@68
|
44 /**
|
jpayne@68
|
45 * Code entrance from the command line.
|
jpayne@68
|
46 * @param args Command line arguments
|
jpayne@68
|
47 */
|
jpayne@68
|
48 public static void main(String[] args){
|
jpayne@68
|
49 //Start a timer immediately upon code entrance.
|
jpayne@68
|
50 Timer t=new Timer();
|
jpayne@68
|
51
|
jpayne@68
|
52 //Create an instance of this class
|
jpayne@68
|
53 CompareSSU x=new CompareSSU(args);
|
jpayne@68
|
54
|
jpayne@68
|
55 //Run the object
|
jpayne@68
|
56 x.process(t);
|
jpayne@68
|
57
|
jpayne@68
|
58 //Close the print stream if it was redirected
|
jpayne@68
|
59 Shared.closeStream(x.outstream);
|
jpayne@68
|
60 }
|
jpayne@68
|
61
|
jpayne@68
|
62 /**
|
jpayne@68
|
63 * Constructor.
|
jpayne@68
|
64 * @param args Command line arguments
|
jpayne@68
|
65 */
|
jpayne@68
|
66 public CompareSSU(String[] args){
|
jpayne@68
|
67
|
jpayne@68
|
68 {//Preparse block for help, config files, and outstream
|
jpayne@68
|
69 PreParser pp=new PreParser(args, getClass(), false);
|
jpayne@68
|
70 args=pp.args;
|
jpayne@68
|
71 outstream=pp.outstream;
|
jpayne@68
|
72 }
|
jpayne@68
|
73
|
jpayne@68
|
74 //Set shared static variables prior to parsing
|
jpayne@68
|
75 ReadWrite.USE_PIGZ=ReadWrite.USE_UNPIGZ=true;
|
jpayne@68
|
76 ReadWrite.MAX_ZIP_THREADS=Shared.threads();
|
jpayne@68
|
77
|
jpayne@68
|
78 {//Parse the arguments
|
jpayne@68
|
79 final Parser parser=parse(args);
|
jpayne@68
|
80 Parser.processQuality();
|
jpayne@68
|
81
|
jpayne@68
|
82 maxReads=parser.maxReads;
|
jpayne@68
|
83 overwrite=ReadStats.overwrite=parser.overwrite;
|
jpayne@68
|
84 append=ReadStats.append=parser.append;
|
jpayne@68
|
85
|
jpayne@68
|
86 in1=parser.in1;
|
jpayne@68
|
87
|
jpayne@68
|
88 out1=parser.out1;
|
jpayne@68
|
89 }
|
jpayne@68
|
90
|
jpayne@68
|
91 validateParams();
|
jpayne@68
|
92 if(in1==null){throw new RuntimeException("Error - at least one input file is required.");}
|
jpayne@68
|
93 FASTQ.FORCE_INTERLEAVED=FASTQ.TEST_INTERLEAVED=false;
|
jpayne@68
|
94 checkFileExistence(); //Ensure files can be read and written
|
jpayne@68
|
95 checkStatics(); //Adjust file-related static fields as needed for this program
|
jpayne@68
|
96
|
jpayne@68
|
97 //Create output FileFormat objects
|
jpayne@68
|
98 ffout1=FileFormat.testOutput(out1, FileFormat.TXT, null, true, overwrite, append, ordered);
|
jpayne@68
|
99
|
jpayne@68
|
100 tree=(treeFile==null) ? null : TaxTree.loadTaxTree(treeFile, outstream, true, false);
|
jpayne@68
|
101
|
jpayne@68
|
102 SSUMap.r16SFile=in1;
|
jpayne@68
|
103 if(SSUMap.r16SFile!=null){
|
jpayne@68
|
104 SSUMap.load(outstream);
|
jpayne@68
|
105 HashMap<Integer, byte[]> ssuMap=SSUMap.r16SMap;
|
jpayne@68
|
106 ssuList=new ArrayList<Read>(ssuMap.size());
|
jpayne@68
|
107 for(Entry<Integer, byte[]> e : ssuMap.entrySet()){
|
jpayne@68
|
108 int id=e.getKey();
|
jpayne@68
|
109 byte[] value=e.getValue();
|
jpayne@68
|
110 if(value.length>=minlen && value.length<=maxlen){
|
jpayne@68
|
111 Read r=new Read(value, null, id);//Sets numeric ID to TaxID.
|
jpayne@68
|
112 if(maxns<0 || r.countNocalls()<=maxns){
|
jpayne@68
|
113 ssuList.add(r);
|
jpayne@68
|
114 }
|
jpayne@68
|
115 }
|
jpayne@68
|
116 }
|
jpayne@68
|
117 Collections.shuffle(ssuList);
|
jpayne@68
|
118 }
|
jpayne@68
|
119 for(int i=0; i<idLists.length; i++){
|
jpayne@68
|
120 idLists[i]=new FloatList();
|
jpayne@68
|
121 }
|
jpayne@68
|
122 }
|
jpayne@68
|
123
|
jpayne@68
|
124 /*--------------------------------------------------------------*/
|
jpayne@68
|
125 /*---------------- Initialization Helpers ----------------*/
|
jpayne@68
|
126 /*--------------------------------------------------------------*/
|
jpayne@68
|
127
|
jpayne@68
|
128 /** Parse arguments from the command line */
|
jpayne@68
|
129 private Parser parse(String[] args){
|
jpayne@68
|
130
|
jpayne@68
|
131 //Create a parser object
|
jpayne@68
|
132 Parser parser=new Parser();
|
jpayne@68
|
133
|
jpayne@68
|
134 //Set any necessary Parser defaults here
|
jpayne@68
|
135 //parser.foo=bar;
|
jpayne@68
|
136
|
jpayne@68
|
137 //Parse each argument
|
jpayne@68
|
138 for(int i=0; i<args.length; i++){
|
jpayne@68
|
139 String arg=args[i];
|
jpayne@68
|
140
|
jpayne@68
|
141 //Break arguments into their constituent parts, in the form of "a=b"
|
jpayne@68
|
142 String[] split=arg.split("=");
|
jpayne@68
|
143 String a=split[0].toLowerCase();
|
jpayne@68
|
144 String b=split.length>1 ? split[1] : null;
|
jpayne@68
|
145 if(b!=null && b.equalsIgnoreCase("null")){b=null;}
|
jpayne@68
|
146
|
jpayne@68
|
147 if(a.equals("verbose")){
|
jpayne@68
|
148 verbose=Parse.parseBoolean(b);
|
jpayne@68
|
149 }else if(a.equals("tree")){
|
jpayne@68
|
150 treeFile=b;
|
jpayne@68
|
151 }else if(a.equals("ordered")){
|
jpayne@68
|
152 ordered=Parse.parseBoolean(b);
|
jpayne@68
|
153 }else if(a.equals("ata") || a.equals("alltoall")){
|
jpayne@68
|
154 allToAll=Parse.parseBoolean(b);
|
jpayne@68
|
155 }else if(a.equals("store") || a.equals("storeresults")){
|
jpayne@68
|
156 storeResults=Parse.parseBoolean(b);
|
jpayne@68
|
157 }else if(a.equals("minlen") || a.equals("maxlength")){
|
jpayne@68
|
158 minlen=Parse.parseIntKMG(b);
|
jpayne@68
|
159 }else if(a.equals("maxlen") || a.equals("maxlength")){
|
jpayne@68
|
160 maxlen=Parse.parseIntKMG(b);
|
jpayne@68
|
161 }else if(a.equalsIgnoreCase("maxns")){
|
jpayne@68
|
162 maxns=Parse.parseIntKMG(b);
|
jpayne@68
|
163 }else if(a.equals("parse_flag_goes_here")){
|
jpayne@68
|
164 long fake_variable=Parse.parseKMG(b);
|
jpayne@68
|
165 //Set a variable here
|
jpayne@68
|
166 }else if(parser.parse(arg, a, b)){//Parse standard flags in the parser
|
jpayne@68
|
167 //do nothing
|
jpayne@68
|
168 }else{
|
jpayne@68
|
169 outstream.println("Unknown parameter "+args[i]);
|
jpayne@68
|
170 assert(false) : "Unknown parameter "+args[i];
|
jpayne@68
|
171 }
|
jpayne@68
|
172 }
|
jpayne@68
|
173
|
jpayne@68
|
174 return parser;
|
jpayne@68
|
175 }
|
jpayne@68
|
176
|
jpayne@68
|
177 /** Ensure files can be read and written */
|
jpayne@68
|
178 private void checkFileExistence(){
|
jpayne@68
|
179 //Ensure output files can be written
|
jpayne@68
|
180 if(!Tools.testOutputFiles(overwrite, append, false, out1)){
|
jpayne@68
|
181 outstream.println((out1==null)+", "+out1);
|
jpayne@68
|
182 throw new RuntimeException("\n\noverwrite="+overwrite+"; Can't write to output file "+out1+"\n");
|
jpayne@68
|
183 }
|
jpayne@68
|
184
|
jpayne@68
|
185 //Ensure input files can be read
|
jpayne@68
|
186 if(!Tools.testInputFiles(false, true, in1)){
|
jpayne@68
|
187 throw new RuntimeException("\nCan't read some input files.\n");
|
jpayne@68
|
188 }
|
jpayne@68
|
189
|
jpayne@68
|
190 //Ensure that no file was specified multiple times
|
jpayne@68
|
191 if(!Tools.testForDuplicateFiles(true, in1, out1)){
|
jpayne@68
|
192 throw new RuntimeException("\nSome file names were specified multiple times.\n");
|
jpayne@68
|
193 }
|
jpayne@68
|
194 }
|
jpayne@68
|
195
|
jpayne@68
|
196 /** Adjust file-related static fields as needed for this program */
|
jpayne@68
|
197 private static void checkStatics(){
|
jpayne@68
|
198 //Adjust the number of threads for input file reading
|
jpayne@68
|
199 if(!ByteFile.FORCE_MODE_BF1 && !ByteFile.FORCE_MODE_BF2 && Shared.threads()>2){
|
jpayne@68
|
200 ByteFile.FORCE_MODE_BF2=true;
|
jpayne@68
|
201 }
|
jpayne@68
|
202
|
jpayne@68
|
203 assert(FastaReadInputStream.settingsOK());
|
jpayne@68
|
204 }
|
jpayne@68
|
205
|
jpayne@68
|
206 /** Ensure parameter ranges are within bounds and required parameters are set */
|
jpayne@68
|
207 private boolean validateParams(){
|
jpayne@68
|
208 return true;
|
jpayne@68
|
209 }
|
jpayne@68
|
210
|
jpayne@68
|
211 /*--------------------------------------------------------------*/
|
jpayne@68
|
212 /*---------------- Outer Methods ----------------*/
|
jpayne@68
|
213 /*--------------------------------------------------------------*/
|
jpayne@68
|
214
|
jpayne@68
|
215 /** Create read streams and process all data */
|
jpayne@68
|
216 void process(Timer t){
|
jpayne@68
|
217
|
jpayne@68
|
218 ByteStreamWriter bsw=makeBSW(ffout1);
|
jpayne@68
|
219 if(bsw!=null){
|
jpayne@68
|
220 bsw.forcePrint("#Level\tIdentity\tQueryID\tRefID\n");
|
jpayne@68
|
221 }
|
jpayne@68
|
222
|
jpayne@68
|
223 //Reset counters
|
jpayne@68
|
224 queriesProcessed=0;
|
jpayne@68
|
225 comparisons=0;
|
jpayne@68
|
226
|
jpayne@68
|
227 //Process the reads in separate threads
|
jpayne@68
|
228 spawnThreads(bsw);
|
jpayne@68
|
229
|
jpayne@68
|
230 if(verbose){outstream.println("Finished; closing streams.");}
|
jpayne@68
|
231
|
jpayne@68
|
232 //Close the read streams
|
jpayne@68
|
233 if(bsw!=null){errorState|=bsw.poisonAndWait();}
|
jpayne@68
|
234
|
jpayne@68
|
235 {
|
jpayne@68
|
236 ByteBuilder bb=new ByteBuilder();
|
jpayne@68
|
237 bb.append("\nLevel \tCount\tMean"+(storeResults ? "\tMedian\t90%ile\t10%ile\tSTDev" : "")+"\n");
|
jpayne@68
|
238 outstream.print(bb);
|
jpayne@68
|
239 final int minlen="superkingdom".length();
|
jpayne@68
|
240 for(int level=0; level<taxLevels; level++){
|
jpayne@68
|
241 if(counts[level]>0){
|
jpayne@68
|
242 bb.clear();
|
jpayne@68
|
243 bb.append(TaxTree.levelToStringExtended(level));
|
jpayne@68
|
244 while(bb.length()<minlen){bb.space();}
|
jpayne@68
|
245 bb.tab().append(counts[level]).tab();
|
jpayne@68
|
246 bb.append(sums[level]/counts[level]*100, 3);
|
jpayne@68
|
247 if(storeResults){
|
jpayne@68
|
248 FloatList list=idLists[level];
|
jpayne@68
|
249 list.sort();
|
jpayne@68
|
250 double stdev=list.stdev();
|
jpayne@68
|
251 double median=list.median();
|
jpayne@68
|
252 // double mode=list.mode();
|
jpayne@68
|
253 double percent90=list.percentile(0.9f);
|
jpayne@68
|
254 double percent10=list.percentile(0.1f);
|
jpayne@68
|
255 bb.tab().append(median*100, 3).tab().append(percent90*100, 3).tab().append(percent10*100, 3).tab().append(stdev*100, 3);
|
jpayne@68
|
256 }
|
jpayne@68
|
257 bb.nl();
|
jpayne@68
|
258 outstream.print(bb);
|
jpayne@68
|
259 }
|
jpayne@68
|
260 }
|
jpayne@68
|
261 }
|
jpayne@68
|
262
|
jpayne@68
|
263 //Report timing and results
|
jpayne@68
|
264 t.stop();
|
jpayne@68
|
265 outstream.println();
|
jpayne@68
|
266 outstream.println(Tools.timeQueriesComparisonsProcessed(t, queriesProcessed, comparisons, 8));
|
jpayne@68
|
267
|
jpayne@68
|
268 //Throw an exception of there was an error in a thread
|
jpayne@68
|
269 if(errorState){
|
jpayne@68
|
270 throw new RuntimeException(getClass().getName()+" terminated in an error state; the output may be corrupt.");
|
jpayne@68
|
271 }
|
jpayne@68
|
272 }
|
jpayne@68
|
273
|
jpayne@68
|
274 /*--------------------------------------------------------------*/
|
jpayne@68
|
275 /*---------------- Thread Management ----------------*/
|
jpayne@68
|
276 /*--------------------------------------------------------------*/
|
jpayne@68
|
277
|
jpayne@68
|
278 /** Spawn process threads */
|
jpayne@68
|
279 private void spawnThreads(ByteStreamWriter bsw){
|
jpayne@68
|
280
|
jpayne@68
|
281 //Do anything necessary prior to processing
|
jpayne@68
|
282
|
jpayne@68
|
283 //Determine how many threads may be used
|
jpayne@68
|
284 final int threads=Shared.threads();
|
jpayne@68
|
285
|
jpayne@68
|
286 //Fill a list with ProcessThreads
|
jpayne@68
|
287 ArrayList<ProcessThread> alpt=new ArrayList<ProcessThread>(threads);
|
jpayne@68
|
288 for(int i=0; i<threads; i++){
|
jpayne@68
|
289 alpt.add(new ProcessThread(bsw, i, threads));
|
jpayne@68
|
290 }
|
jpayne@68
|
291
|
jpayne@68
|
292 //Start the threads and wait for them to finish
|
jpayne@68
|
293 boolean success=ThreadWaiter.startAndWait(alpt, this);
|
jpayne@68
|
294 errorState&=!success;
|
jpayne@68
|
295
|
jpayne@68
|
296 //Do anything necessary after processing
|
jpayne@68
|
297
|
jpayne@68
|
298 }
|
jpayne@68
|
299
|
jpayne@68
|
300 @Override
|
jpayne@68
|
301 public final void accumulate(ProcessThread pt){
|
jpayne@68
|
302 queriesProcessed+=pt.querysProcessedT;
|
jpayne@68
|
303 comparisons+=pt.comparisonsT;
|
jpayne@68
|
304 errorState|=(!pt.success);
|
jpayne@68
|
305
|
jpayne@68
|
306 for(int i=0; i<taxLevels; i++){
|
jpayne@68
|
307 idLists[i].addAll(pt.idListsT[i]);
|
jpayne@68
|
308 counts[i]+=pt.countsT[i];
|
jpayne@68
|
309 sums[i]+=pt.sumsT[i];
|
jpayne@68
|
310 }
|
jpayne@68
|
311 }
|
jpayne@68
|
312
|
jpayne@68
|
313 @Override
|
jpayne@68
|
314 public final boolean success(){return !errorState;}
|
jpayne@68
|
315
|
jpayne@68
|
316 /*--------------------------------------------------------------*/
|
jpayne@68
|
317 /*---------------- Inner Methods ----------------*/
|
jpayne@68
|
318 /*--------------------------------------------------------------*/
|
jpayne@68
|
319
|
jpayne@68
|
320 private static ByteStreamWriter makeBSW(FileFormat ff){
|
jpayne@68
|
321 if(ff==null){return null;}
|
jpayne@68
|
322 ByteStreamWriter bsw=new ByteStreamWriter(ff);
|
jpayne@68
|
323 bsw.start();
|
jpayne@68
|
324 return bsw;
|
jpayne@68
|
325 }
|
jpayne@68
|
326
|
jpayne@68
|
327 /*--------------------------------------------------------------*/
|
jpayne@68
|
328 /*---------------- Inner Classes ----------------*/
|
jpayne@68
|
329 /*--------------------------------------------------------------*/
|
jpayne@68
|
330
|
jpayne@68
|
331 /** This class is static to prevent accidental writing to shared variables.
|
jpayne@68
|
332 * It is safe to remove the static modifier. */
|
jpayne@68
|
333 class ProcessThread extends Thread {
|
jpayne@68
|
334
|
jpayne@68
|
335 //Constructor
|
jpayne@68
|
336 ProcessThread(ByteStreamWriter bsw_, final int tid_, final int threads_){
|
jpayne@68
|
337 bsw=bsw_;
|
jpayne@68
|
338 threadID=tid_;
|
jpayne@68
|
339 threads=threads_;
|
jpayne@68
|
340 listCopy=new ArrayList<Read>(ssuList.size());
|
jpayne@68
|
341 listCopy.addAll(ssuList);
|
jpayne@68
|
342 for(int i=0; i<idListsT.length; i++){
|
jpayne@68
|
343 idListsT[i]=new FloatList();
|
jpayne@68
|
344 }
|
jpayne@68
|
345 }
|
jpayne@68
|
346
|
jpayne@68
|
347 //Called by start()
|
jpayne@68
|
348 @Override
|
jpayne@68
|
349 public void run(){
|
jpayne@68
|
350 //Do anything necessary prior to processing
|
jpayne@68
|
351
|
jpayne@68
|
352 //Process the reads
|
jpayne@68
|
353 processInner();
|
jpayne@68
|
354
|
jpayne@68
|
355 //Do anything necessary after processing
|
jpayne@68
|
356
|
jpayne@68
|
357 //Indicate successful exit status
|
jpayne@68
|
358 success=true;
|
jpayne@68
|
359 }
|
jpayne@68
|
360
|
jpayne@68
|
361 /** Iterate through the reads */
|
jpayne@68
|
362 void processInner(){
|
jpayne@68
|
363 final long limit=Tools.min(ssuList.size(), (maxReads>0 ? maxReads : Integer.MAX_VALUE));
|
jpayne@68
|
364
|
jpayne@68
|
365 for(int num=next.getAndIncrement(); num<limit; num=next.getAndIncrement()){
|
jpayne@68
|
366 Read r=ssuList.get(num);
|
jpayne@68
|
367 processRead(r);
|
jpayne@68
|
368 }
|
jpayne@68
|
369 }
|
jpayne@68
|
370
|
jpayne@68
|
371 void processRead(Read query){
|
jpayne@68
|
372 if(query.numericID<1){return;}//invalid TID
|
jpayne@68
|
373 final int qid=(int)query.numericID;
|
jpayne@68
|
374 if(tree.getNode(qid)==null) {return;}
|
jpayne@68
|
375 if(querysProcessedT%5==0) {
|
jpayne@68
|
376 Collections.shuffle(listCopy);
|
jpayne@68
|
377 }
|
jpayne@68
|
378 querysProcessedT++;
|
jpayne@68
|
379
|
jpayne@68
|
380 ByteBuilder bb=new ByteBuilder();
|
jpayne@68
|
381
|
jpayne@68
|
382 long seen=0;
|
jpayne@68
|
383 for(Read ref :listCopy){
|
jpayne@68
|
384 int rid=(int)ref.numericID;
|
jpayne@68
|
385 if(rid!=qid && rid>0 && tree.getNode(rid)!=null){
|
jpayne@68
|
386 int aid=tree.commonAncestor(qid, rid);
|
jpayne@68
|
387 if(aid>0){
|
jpayne@68
|
388 TaxNode tn=tree.getNode(aid);
|
jpayne@68
|
389 if(tn.isRanked()){
|
jpayne@68
|
390 int level=tn.levelExtended;
|
jpayne@68
|
391 long mask=1L<<level;
|
jpayne@68
|
392 if(allToAll || ((mask&printLevels)!=0 && (mask&seen)==0)){
|
jpayne@68
|
393 seen|=mask;
|
jpayne@68
|
394 float identity=compare(query, ref, level);
|
jpayne@68
|
395 bb.append(TaxTree.levelToStringExtended(level)).tab().append(identity, 6);
|
jpayne@68
|
396 bb.tab().append(qid).tab().append(rid).nl();
|
jpayne@68
|
397 }
|
jpayne@68
|
398 }
|
jpayne@68
|
399 }
|
jpayne@68
|
400 }
|
jpayne@68
|
401 }
|
jpayne@68
|
402 if(bsw!=null){
|
jpayne@68
|
403 bsw.addJob(bb);
|
jpayne@68
|
404 }
|
jpayne@68
|
405 }
|
jpayne@68
|
406
|
jpayne@68
|
407 float compare(Read query, Read ref, int level){
|
jpayne@68
|
408 comparisonsT++;
|
jpayne@68
|
409 float identity=SketchObject.align(query.bases, ref.bases);
|
jpayne@68
|
410 if(storeResults){idListsT[level].add(identity);}
|
jpayne@68
|
411 countsT[level]++;
|
jpayne@68
|
412 sumsT[level]+=identity;
|
jpayne@68
|
413 return identity;
|
jpayne@68
|
414 }
|
jpayne@68
|
415
|
jpayne@68
|
416 /** Number of reads processed by this thread */
|
jpayne@68
|
417 protected long querysProcessedT=0;
|
jpayne@68
|
418 /** Number of bases processed by this thread */
|
jpayne@68
|
419 protected long comparisonsT=0;
|
jpayne@68
|
420
|
jpayne@68
|
421 /** True only if this thread has completed successfully */
|
jpayne@68
|
422 boolean success=false;
|
jpayne@68
|
423
|
jpayne@68
|
424 /** Shared output stream */
|
jpayne@68
|
425 private final ByteStreamWriter bsw;
|
jpayne@68
|
426 /** Thread ID */
|
jpayne@68
|
427 final int threadID;
|
jpayne@68
|
428
|
jpayne@68
|
429 final int threads;
|
jpayne@68
|
430
|
jpayne@68
|
431 ArrayList<Read> listCopy;
|
jpayne@68
|
432
|
jpayne@68
|
433 final FloatList[] idListsT=new FloatList[taxLevels];
|
jpayne@68
|
434 long[] countsT=new long[taxLevels];
|
jpayne@68
|
435 double[] sumsT=new double[taxLevels];
|
jpayne@68
|
436 }
|
jpayne@68
|
437
|
jpayne@68
|
438 /*--------------------------------------------------------------*/
|
jpayne@68
|
439 /*---------------- Fields ----------------*/
|
jpayne@68
|
440 /*--------------------------------------------------------------*/
|
jpayne@68
|
441
|
jpayne@68
|
442 /** Primary input file path */
|
jpayne@68
|
443 private String in1=null;
|
jpayne@68
|
444
|
jpayne@68
|
445 private String treeFile="auto";
|
jpayne@68
|
446
|
jpayne@68
|
447 /** Primary output file path */
|
jpayne@68
|
448 private String out1=null;
|
jpayne@68
|
449
|
jpayne@68
|
450 public static ArrayList<Read> ssuList=null;
|
jpayne@68
|
451
|
jpayne@68
|
452 final static int taxLevels=TaxTree.numTaxLevelNamesExtended;
|
jpayne@68
|
453 static final String[] printLevelsArray=new String[] {"strain", "species", "genus", "family", "order", "class", "phylum", "superkingdom", "life"};
|
jpayne@68
|
454 static final long printLevels=makePrintLevels(printLevelsArray);
|
jpayne@68
|
455
|
jpayne@68
|
456 private final TaxTree tree;
|
jpayne@68
|
457
|
jpayne@68
|
458 private static final long makePrintLevels(String[] names){
|
jpayne@68
|
459 long mask=0;
|
jpayne@68
|
460 for(String s : names){
|
jpayne@68
|
461 int level=TaxTree.stringToLevelExtended(s);
|
jpayne@68
|
462 mask|=(1L<<level);
|
jpayne@68
|
463 }
|
jpayne@68
|
464 return mask;
|
jpayne@68
|
465 }
|
jpayne@68
|
466
|
jpayne@68
|
467 private FloatList[] idLists=new FloatList[taxLevels];
|
jpayne@68
|
468 private long[] counts=new long[taxLevels];
|
jpayne@68
|
469 private double[] sums=new double[taxLevels];
|
jpayne@68
|
470
|
jpayne@68
|
471 private int minlen=0;
|
jpayne@68
|
472 private int maxlen=Integer.MAX_VALUE;
|
jpayne@68
|
473 private int maxns=-1;
|
jpayne@68
|
474
|
jpayne@68
|
475 /*--------------------------------------------------------------*/
|
jpayne@68
|
476
|
jpayne@68
|
477 /** Number of reads processed */
|
jpayne@68
|
478 protected long queriesProcessed=0;
|
jpayne@68
|
479 /** Number of bases processed */
|
jpayne@68
|
480 protected long comparisons=0;
|
jpayne@68
|
481
|
jpayne@68
|
482 /** Quit after processing this many input reads; -1 means no limit */
|
jpayne@68
|
483 private long maxReads=-1;
|
jpayne@68
|
484
|
jpayne@68
|
485 private AtomicInteger next=new AtomicInteger(0);
|
jpayne@68
|
486
|
jpayne@68
|
487 private boolean allToAll=false;
|
jpayne@68
|
488 private boolean storeResults=false;
|
jpayne@68
|
489
|
jpayne@68
|
490 /*--------------------------------------------------------------*/
|
jpayne@68
|
491 /*---------------- Final Fields ----------------*/
|
jpayne@68
|
492 /*--------------------------------------------------------------*/
|
jpayne@68
|
493
|
jpayne@68
|
494 /** Primary output file */
|
jpayne@68
|
495 private final FileFormat ffout1;
|
jpayne@68
|
496
|
jpayne@68
|
497 /*--------------------------------------------------------------*/
|
jpayne@68
|
498 /*---------------- Common Fields ----------------*/
|
jpayne@68
|
499 /*--------------------------------------------------------------*/
|
jpayne@68
|
500
|
jpayne@68
|
501 /** Print status messages to this output stream */
|
jpayne@68
|
502 private PrintStream outstream=System.err;
|
jpayne@68
|
503 /** Print verbose messages */
|
jpayne@68
|
504 public static boolean verbose=false;
|
jpayne@68
|
505 /** True if an error was encountered */
|
jpayne@68
|
506 public boolean errorState=false;
|
jpayne@68
|
507 /** Overwrite existing output files */
|
jpayne@68
|
508 private boolean overwrite=false;
|
jpayne@68
|
509 /** Append to existing output files */
|
jpayne@68
|
510 private boolean append=false;
|
jpayne@68
|
511 /** Reads are output in input order */
|
jpayne@68
|
512 private boolean ordered=false;
|
jpayne@68
|
513
|
jpayne@68
|
514 }
|