1 package shared;
2 
3 import java.io.File;
4 import java.util.ArrayList;
5 import java.util.Arrays;
6 import java.util.HashSet;
7 
8 import align2.QualityTools;
9 import cardinality.CardinalityTracker;
10 import cardinality.LogLog16;
11 import cardinality.LogLog2;
12 import dna.AminoAcid;
13 import dna.Data;
14 import fileIO.ByteFile;
15 import fileIO.ByteFile1;
16 import fileIO.FileFormat;
17 import fileIO.ReadWrite;
18 import fileIO.TextFile;
19 import jgi.BBMerge;
20 import jgi.CalcTrueQuality;
21 import kmer.AbstractKmerTable;
22 import sketch.SketchObject;
23 import stream.ConcurrentDepot;
24 import stream.ConcurrentReadInputStream;
25 import stream.FASTQ;
26 import stream.FastaReadInputStream;
27 import stream.Read;
28 import stream.ReadStreamByteWriter;
29 import stream.ReadStreamWriter;
30 import stream.SamLine;
31 import stream.SamStreamer;
32 import structures.EntropyTracker;
33 import structures.IntList;
34 import tax.TaxTree;
35 import var2.CallVariants;
36 
37 /**
38  * @author Brian Bushnell
39  * @date Mar 21, 2014
40  *
41  */
42 public class Parser {
43 
44 	/*--------------------------------------------------------------*/
45 	/*----------------        Initialization        ----------------*/
46 	/*--------------------------------------------------------------*/
47 
Parser()48 	public Parser(){}
49 
50 	/*--------------------------------------------------------------*/
51 	/*----------------           Methods            ----------------*/
52 	/*--------------------------------------------------------------*/
53 
parse(String arg, String a, String b)54 	public boolean parse(String arg, String a, String b){
55 		if(isJavaFlag(arg)){return true;}
56 
57 		if(parseQuality(arg, a, b)){return true;}
58 		if(parseZip(arg, a, b)){return true;}
59 		if(parseSam(arg, a, b)){return true;}
60 		if(parseFasta(arg, a, b)){return true;}
61 		if(parseCommonStatic(arg, a, b)){return true;}
62 		if(parseHist(arg, a, b)){return true;}
63 		if(parseQualityAdjust(arg, a, b)){return true;}
64 
65 		if(parseFiles(arg, a, b)){return true;}
66 		if(parseCommon(arg, a, b)){return true;}
67 		if(parseTrim(arg, a, b)){return true;}
68 		if(parseInterleaved(arg, a, b)){return true;}
69 		if(parseMapping(arg, a, b)){return true;}
70 		if(parseCardinality(arg, a, b)){return true;}
71 		return false;
72 	}
73 
parseCommon(String arg, String a, String b)74 	public boolean parseCommon(String arg, String a, String b){
75 		if(a.equals("reads") || a.equals("maxreads")){
76 			maxReads=Parse.parseKMG(b);
77 		}else if(a.equals("samplerate")){
78 			samplerate=Float.parseFloat(b);
79 			assert(samplerate<=1f && samplerate>=0f) : "samplerate="+samplerate+"; should be between 0 and 1";
80 		}else if(a.equals("sampleseed")){
81 			sampleseed=Long.parseLong(b);
82 		}else if(a.equals("append") || a.equals("app")){
83 			append=ReadStats.append=Parse.parseBoolean(b);
84 		}else if(a.equals("overwrite") || a.equals("ow")){
85 			overwrite=Parse.parseBoolean(b);
86 		}else if(a.equals("testsize")){
87 			testsize=Parse.parseBoolean(b);
88 		}else if(a.equals("breaklen") || a.equals("breaklength")){
89 			breakLength=Integer.parseInt(b);
90 		}else if(a.equals("recalibrate") || a.equals("recalibratequality") || a.equals("recal")){
91 			recalibrateQuality=Parse.parseBoolean(b);
92 		}else if(a.equals("silent")){
93 			silent=Parse.parseBoolean(b);
94 		}else{
95 			return false;
96 		}
97 		return true;
98 	}
99 
parseCardinality(String arg, String a, String b)100 	public boolean parseCardinality(String arg, String a, String b){
101 		if(a.equals("cardinality") || a.equals("loglog")){
102 			if(b!=null && b.length()>0 && Tools.isDigit(b.charAt(0))){
103 				try {
104 					loglogk=Integer.parseInt(b);
105 					loglog=loglogk>0;
106 				} catch (NumberFormatException e) {
107 					loglog=Parse.parseBoolean(b);
108 				}
109 			}else{
110 				loglog=Parse.parseBoolean(b);
111 			}
112 		}else if(a.equals("cardinalityout") || a.equals("loglogout")){
113 			if(b!=null && b.length()>0 && Tools.isDigit(b.charAt(0))){
114 				try {
115 					loglogk=Integer.parseInt(b);
116 					loglogOut=loglogk>0;
117 				} catch (NumberFormatException e) {
118 					loglogOut=Parse.parseBoolean(b);
119 				}
120 			}else{
121 				loglogOut=Parse.parseBoolean(b);
122 			}
123 		}else if(a.equals("buckets") || a.equals("loglogbuckets")){
124 			loglogbuckets=Parse.parseIntKMG(b);
125 			assert(loglogbuckets>0);
126 			loglogbuckets=CardinalityTracker.powerOf2AtLeast(loglogbuckets);
127 		}else if(a.equals("loglogbits")){
128 			loglogbits=Integer.parseInt(b);
129 		}else if(a.equals("loglogk") || a.equals("cardinalityk") || a.equals("kcardinality")){
130 			loglogk=Integer.parseInt(b);
131 			loglog=loglogk>0;
132 		}else if(a.equals("loglogklist")){
133 			String[] split2=b.split(",");
134 			for(String k : split2){
135 				loglogKlist.add(Integer.parseInt(k));
136 			}
137 		}else if(a.equals("loglogseed")){
138 			loglogseed=Long.parseLong(b);
139 		}else if(a.equals("loglogminprob")){
140 			loglogMinprob=Float.parseFloat(b);
141 		}else if(a.equals("loglogtype")){
142 			loglogType=b;
143 		}else if(a.equals("loglogmean")){
144 			CardinalityTracker.USE_MEAN=true;
145 			CardinalityTracker.USE_MEDIAN=CardinalityTracker.USE_MWA=CardinalityTracker.USE_HMEAN=CardinalityTracker.USE_GMEAN=false;
146 		}else if(a.equals("loglogmedian")){
147 			CardinalityTracker.USE_MEDIAN=true;
148 			CardinalityTracker.USE_MEAN=CardinalityTracker.USE_MWA=CardinalityTracker.USE_HMEAN=CardinalityTracker.USE_GMEAN=false;
149 		}else if(a.equals("loglogmwa")){
150 			CardinalityTracker.USE_MWA=true;
151 			CardinalityTracker.USE_MEDIAN=CardinalityTracker.USE_MEAN=CardinalityTracker.USE_HMEAN=CardinalityTracker.USE_GMEAN=false;
152 		}else if(a.equals("logloghmean")){
153 			CardinalityTracker.USE_HMEAN=true;
154 			CardinalityTracker.USE_MEDIAN=CardinalityTracker.USE_MEAN=CardinalityTracker.USE_MWA=CardinalityTracker.USE_GMEAN=false;
155 		}else if(a.equals("logloggmean")){
156 			CardinalityTracker.USE_GMEAN=true;
157 			CardinalityTracker.USE_MEDIAN=CardinalityTracker.USE_MEAN=CardinalityTracker.USE_HMEAN=CardinalityTracker.USE_MWA=false;
158 		}else if(a.equals("loglogmantissa")){
159 			LogLog2.setMantissaBits(Integer.parseInt(b));
160 			LogLog16.setMantissaBits(Integer.parseInt(b));
161 		}else if(a.equals("loglogcounts") || a.equals("loglogcount")){
162 			CardinalityTracker.trackCounts=Parse.parseBoolean(b);
163 		}else{
164 			return false;
165 		}
166 
167 		return true;
168 	}
169 
parseInterleaved(String arg, String a, String b)170 	public boolean parseInterleaved(String arg, String a, String b){
171 		if(a.equals("testinterleaved")){
172 			FASTQ.TEST_INTERLEAVED=Parse.parseBoolean(b);
173 			System.err.println("Set TEST_INTERLEAVED to "+FASTQ.TEST_INTERLEAVED);
174 			setInterleaved=true;
175 		}else if(a.equals("forceinterleaved")){
176 			FASTQ.FORCE_INTERLEAVED=Parse.parseBoolean(b);
177 			System.err.println("Set FORCE_INTERLEAVED to "+FASTQ.FORCE_INTERLEAVED);
178 			setInterleaved=true;
179 		}else if(a.equals("interleaved") || a.equals("int")){
180 			if("auto".equalsIgnoreCase(b)){FASTQ.FORCE_INTERLEAVED=!(FASTQ.TEST_INTERLEAVED=true);}
181 			else{
182 				FASTQ.FORCE_INTERLEAVED=FASTQ.TEST_INTERLEAVED=Parse.parseBoolean(b);
183 				System.err.println("Set INTERLEAVED to "+FASTQ.FORCE_INTERLEAVED);
184 				setInterleaved=true;
185 			}
186 		}else if(a.equals("overrideinterleaved")){
187 			boolean x=Parse.parseBoolean(b);
188 			ReadStreamByteWriter.ignorePairAssertions=x;
189 			if(x){setInterleaved=true;}
190 		}else{
191 			return false;
192 		}
193 		return true;
194 	}
195 
parseQTrim(String arg, String a, String b)196 	public boolean parseQTrim(String arg, String a, String b){
197 		if(a.equals("qtrim1")){
198 			if(b!=null && ("f".equalsIgnoreCase(b) || "false".equalsIgnoreCase(b))){qtrim1=false;}
199 			else{
200 				qtrim1=true;
201 				qtrim2=false;
202 			}
203 			a="qtrim";
204 		}else if(a.equals("qtrim2")){
205 			if(b!=null && ("f".equalsIgnoreCase(b) || "false".equalsIgnoreCase(b))){qtrim2=false;}
206 			else{
207 				qtrim2=true;
208 				qtrim1=false;
209 			}
210 			a="qtrim";
211 		}else if(a.equals("trimq2")){
212 			if(b!=null && ("f".equalsIgnoreCase(b) || "false".equalsIgnoreCase(b))){qtrim2=false;}
213 			else{
214 				qtrim2=true;
215 				qtrim1=false;
216 			}
217 			a="trimq";
218 		}
219 
220 		if(a.equals("qtrim")/* || a.equals("trim")*/){
221 			if(b==null || b.length()==0){qtrimRight=qtrimLeft=true;}
222 			else if(b.equalsIgnoreCase("left") || b.equalsIgnoreCase("l")){qtrimLeft=true;qtrimRight=false;}
223 			else if(b.equalsIgnoreCase("right") || b.equalsIgnoreCase("r")){qtrimLeft=false;qtrimRight=true;}
224 			else if(b.equalsIgnoreCase("both") || b.equalsIgnoreCase("rl") || b.equalsIgnoreCase("lr")){qtrimLeft=qtrimRight=true;}
225 			else if(b.equalsIgnoreCase("window") || b.equalsIgnoreCase("w") || b.startsWith("window,") || b.startsWith("w,")){
226 				qtrimLeft=false;
227 				qtrimRight=true;
228 				TrimRead.windowMode=true;
229 				TrimRead.optimalMode=false;
230 				String[] split=b.split(",");
231 				if(b.length()>1){
232 					TrimRead.windowLength=Integer.parseInt(split[1]);
233 				}
234 			}else if(Tools.isDigit(b.charAt(0))){
235 				parseTrimq(a, b);
236 				qtrimRight=true;
237 			}else{qtrimRight=qtrimLeft=Parse.parseBoolean(b);}
238 		}else if(a.equals("optitrim") || a.equals("otf") || a.equals("otm")){
239 			if(b!=null && (b.charAt(0)=='.' || Tools.isDigit(b.charAt(0)))){
240 				TrimRead.optimalMode=true;
241 				TrimRead.optimalBias=Float.parseFloat(b);
242 				assert(TrimRead.optimalBias>=0 && TrimRead.optimalBias<1);
243 			}else{
244 				TrimRead.optimalMode=Parse.parseBoolean(b);
245 			}
246 		}else if(a.equals("trimgoodinterval")){
247 			TrimRead.minGoodInterval=Integer.parseInt(b);
248 		}else if(a.equals("trimright") || a.equals("qtrimright")){
249 			qtrimRight=Parse.parseBoolean(b);
250 		}else if(a.equals("trimleft") || a.equals("qtrimleft")){
251 			qtrimLeft=Parse.parseBoolean(b);
252 		}else if(a.equals("trimq") || a.equals("trimquality") || a.equals("trimq2")){
253 			parseTrimq(a, b);
254 		}else if(a.equals("trimclip")){
255 			trimClip=Parse.parseBoolean(b);
256 		}else if(a.equals("trimpolya")){
257 			trimPolyA=parsePoly(b);
258 		}
259 
260 		else if(a.equals("trimpolyg")){
261 			trimPolyGLeft=trimPolyGRight=parsePoly(b);
262 		}else if(a.equals("trimpolygleft")){
263 			trimPolyGLeft=parsePoly(b);
264 		}else if(a.equals("trimpolygright")){
265 			trimPolyGRight=parsePoly(b);
266 		}else if(a.equals("filterpolyg")){
267 			filterPolyG=parsePoly(b);
268 		}
269 
270 		else if(a.equals("trimpolyc")){
271 			trimPolyCLeft=trimPolyCRight=parsePoly(b);
272 		}else if(a.equals("trimpolycleft")){
273 			trimPolyCLeft=parsePoly(b);
274 		}else if(a.equals("trimpolycricht")){
275 			trimPolyCRight=parsePoly(b);
276 		}else if(a.equals("filterpolyc")){
277 			filterPolyC=parsePoly(b);
278 		}
279 
280 		else{
281 			return false;
282 		}
283 		return true;
284 	}
285 
parsePoly(String b)286 	public static int parsePoly(String b){
287 		int r=2;
288 		if(b!=null){
289 			if(Tools.isDigit(b.charAt(0))){
290 				r=Integer.parseInt(b);
291 			}else{
292 				boolean x=Parse.parseBoolean(b);
293 				r=x ? 2 : 0;
294 			}
295 		}
296 		return r;
297 	}
298 
parseTrim(String arg, String a, String b)299 	public boolean parseTrim(String arg, String a, String b){
300 
301 		if(parseQTrim(arg, a, b)){
302 			//do nothing
303 		}else if(a.equals("forcetrimmod") || a.equals("forcemrimmodulo") || a.equals("ftm")){
304 			forceTrimModulo=Integer.parseInt(b);
305 		}else if(a.equals("ftl") || a.equals("forcetrimleft")){
306 			forceTrimLeft=Integer.parseInt(b);
307 		}else if(a.equals("ftr") || a.equals("forcetrimright")){
308 			forceTrimRight=Integer.parseInt(b);
309 		}else if(a.equals("ftr2") || a.equals("forcetrimright2")){
310 			forceTrimRight2=Integer.parseInt(b);
311 		}else if(a.equals("trimbadsequence")){
312 			trimBadSequence=Parse.parseBoolean(b);
313 		}else if(a.equals("chastityfilter") || a.equals("cf")){
314 			chastityFilter=Parse.parseBoolean(b);
315 		}else if(a.equals("failnobarcode")){
316 			failIfNoBarcode=Parse.parseBoolean(b);
317 		}else if(a.equals("badbarcodes") || a.equals("barcodefilter")){
318 			if(b!=null && (b.equalsIgnoreCase("crash") || b.equalsIgnoreCase("fail"))){
319 				failBadBarcodes=true;
320 				removeBadBarcodes=true;
321 			}else{
322 				removeBadBarcodes=Parse.parseBoolean(b);
323 				failBadBarcodes=false;
324 			}
325 		}else if(a.equals("barcodes") || a.equals("barcode")){
326 			if(b==null || b.length()<1){
327 				barcodes=null;
328 			}else{
329 				barcodes=new HashSet<String>();
330 				for(String s : b.split(",")){
331 					Tools.addNames(s, barcodes, false);
332 				}
333 			}
334 			if(barcodes!=null && barcodes.size()>0 && !failBadBarcodes && !removeBadBarcodes){
335 				removeBadBarcodes=true;
336 			}
337 		}else if(a.equals("requirebothbad") || a.equals("rbb")){
338 			requireBothBad=Parse.parseBoolean(b);
339 		}else if(a.equals("removeifeitherbad") || a.equals("rieb")){
340 			requireBothBad=!Parse.parseBoolean(b);
341 		}else if(a.equals("ml") || a.equals("minlen") || a.equals("minlength")){
342 			minReadLength=Parse.parseIntKMG(b);
343 		}else if(a.equals("maxlength") || a.equals("maxreadlength") || a.equals("maxreadlen") || a.equals("maxlen")){
344 			maxReadLength=Parse.parseIntKMG(b);
345 		}else if(a.equals("mingc")){
346 			minGC=Float.parseFloat(b);
347 //			if(minGC>0){filterGC=true;}
348 			assert(minGC>=0 && minGC<=1) : "mingc should be a decimal number between 0 and 1, inclusive.";
349 		}else if(a.equals("maxgc")){
350 			maxGC=Float.parseFloat(b);
351 //			if(maxGC<1){filterGC=true;}
352 			assert(minGC>=0 && minGC<=1) : "maxgc should be a decimal number between 0 and 1, inclusive.";
353 		}else if(a.equals("usepairgc") || a.equals("pairgc")){
354 			usePairGC=Parse.parseBoolean(b);
355 			ReadStats.usePairGC=usePairGC;
356 		}else if(a.equals("mlf") || a.equals("minlenfrac") || a.equals("minlenfraction") || a.equals("minlengthfraction")){
357 			minLenFraction=Float.parseFloat(b);
358 		}else if(a.equals("maxns")){
359 			maxNs=Integer.parseInt(b);
360 		}else if(a.equals("minconsecutivebases") || a.equals("mcb")){
361 			minConsecutiveBases=Integer.parseInt(b);
362 		}else if(a.equals("minavgquality") || a.equals("minaveragequality") || a.equals("maq")){
363 			if(b.indexOf(',')>-1){
364 				String[] split=b.split(",");
365 				assert(split.length==2) : "maq should be length 1 or 2 (at most 1 comma).\nFormat: maq=quality,bases; e.g. maq=10 or maq=10,20";
366 				minAvgQuality=Float.parseFloat(split[0]);
367 				minAvgQualityBases=Integer.parseInt(split[1]);
368 			}else{
369 				minAvgQuality=Float.parseFloat(b);
370 			}
371 		}else if(a.equals("minavgqualitybases") || a.equals("maqb")){
372 			minAvgQualityBases=Integer.parseInt(b);
373 		}else if(a.equals("minbasequality") || a.equals("mbq")){
374 			minBaseQuality=Byte.parseByte(b);
375 		}else if(a.equals("averagequalitybyprobability") || a.equals("aqbp")){
376 			Read.AVERAGE_QUALITY_BY_PROBABILITY=Parse.parseBoolean(b);
377 		}else if(a.equals("mintl") || a.equals("mintrimlen") || a.equals("mintrimlength")){
378 			minTrimLength=Integer.parseInt(b);
379 		}else if(a.equals("untrim")){
380 			untrim=Parse.parseBoolean(b);
381 		}else if(a.equals("tossjunk")){
382 			boolean x=Parse.parseBoolean(b);
383 			tossJunk=x;
384 			if(x){Read.JUNK_MODE=Read.FLAG_JUNK;}
385 		}else{
386 			return false;
387 		}
388 		return true;
389 	}
390 
parseTrimq(String a, String b)391 	private void parseTrimq(String a, String b){
392 		if(b.indexOf(',')>=0){
393 			String[] split=b.split(",");
394 			trimq2=new float[split.length];
395 			for(int i=0; i<split.length; i++){
396 				trimq2[i]=Float.parseFloat(split[i]);
397 			}
398 			trimq=trimq2.length<1 ? 0 : trimq2[0];
399 		}else{
400 			trimq=Float.parseFloat(b);
401 			trimq2=null;
402 		}
403 //		assert(false) : Arrays.toString(trimq2);
404 	}
405 
406 	public boolean parseFiles(String arg, String a, String b){
407 		if(a.equals("in") || a.equals("input") || a.equals("in1") || a.equals("input1")){
408 			in1=b;
409 		}else if(a.equals("in2") || a.equals("input2")){
410 			in2=b;
411 		}else if(a.equals("out") || a.equals("output") || a.equals("out1") || a.equals("output1")){
412 			out1=b;
413 			setOut=true;
414 		}else if(a.equals("out2") || a.equals("output2")){
415 			out2=b;
416 			setOut=true;
417 		}else if(a.equals("qfin") || a.equals("qfin1")){
418 			qfin1=b;
419 		}else if(a.equals("qfout") || a.equals("qfout1")){
420 			qfout1=b;
421 			setOut=true;
422 		}else if(a.equals("qfin2")){
423 			qfin2=b;
424 		}else if(a.equals("qfout2")){
425 			qfout2=b;
426 			setOut=true;
427 		}else if(a.equals("extin")){
428 			extin=b;
429 		}else if(a.equals("extout")){
430 			extout=b;
431 		}else if(a.equals("outsingle") || a.equals("outs")){
432 			outsingle=b;
433 			setOut=true;
434 		}else{
435 			return false;
436 		}
437 		return true;
438 	}
439 
440 	public boolean parseMapping(String arg, String a, String b){
441 		if(a.equals("idfilter") || a.equals("identityfilter") || a.equals("minidfilter") || a.equals("minidentityfilter") || a.equals("minid")){
442 			minIdFilter=Float.parseFloat(b);
443 			if(minIdFilter>1f){minIdFilter/=100;}
444 			assert(minIdFilter<=1f) : "idfilter should be between 0 and 1.";
445 		}else if(a.equals("maxidfilter") || a.equals("maxidentityfilter") || a.equals("maxid")){
446 			maxIdFilter=Float.parseFloat(b);
447 			if(maxIdFilter>1f){maxIdFilter/=100;}
448 			assert(maxIdFilter<=1f) : "idfilter should be between 0 and 1.";
449 		}else if(a.equals("subfilter")){
450 			subfilter=Integer.parseInt(b);
451 		}else if(a.equals("clipfilter")){
452 			clipfilter=Integer.parseInt(b);
453 		}else if(a.equals("nfilter")){
454 			nfilter=Integer.parseInt(b);
455 		}else if(a.equals("delfilter")){
456 			delfilter=Integer.parseInt(b);
457 		}else if(a.equals("insfilter")){
458 			insfilter=Integer.parseInt(b);
459 		}else if(a.equals("indelfilter")){
460 			indelfilter=Integer.parseInt(b);
461 		}else if(a.equals("dellenfilter")){
462 			dellenfilter=Integer.parseInt(b);
463 		}else if(a.equals("inslenfilter")){
464 			inslenfilter=Integer.parseInt(b);
465 		}else if(a.equals("editfilter")){
466 			editfilter=Integer.parseInt(b);
467 		}else if(a.equals("build") || a.equals("genome")){
468 			build=Integer.parseInt(b);
469 			Data.GENOME_BUILD=build;
470 		}else{
471 			return false;
472 		}
473 		return true;
474 	}
475 
476 
477 	/*--------------------------------------------------------------*/
478 	/*----------------        Static Methods        ----------------*/
479 	/*--------------------------------------------------------------*/
480 
parseConfig(String[] args)481 	static String[] parseConfig(String[] args){
482 		boolean found=false;
483 		for(String s : args){
484 			if(Tools.startsWithIgnoreCase(s, "config=")){
485 				found=true;
486 				break;
487 			}
488 		}
489 		if(!found){return args;}
490 		ArrayList<String> list=new ArrayList<String>();
491 		for(int i=0; i<args.length; i++){
492 			final String arg=(args[i]==null ? "null" : args[i]);
493 			final String[] split=arg.split("=");
494 			final String a=split[0].toLowerCase();
495 			String b=split.length>1 ? split[1] : null;
496 			if("null".equalsIgnoreCase(b)){b=null;}
497 
498 			if(a.equals("config")){
499 				assert(b!=null) : "Bad parameter: "+arg;
500 				for(String bb : b.split(",")){
501 					try{
502 						TextFile tf=new TextFile(bb);
503 						for(String line=tf.nextLine(); line!=null; line=tf.nextLine()){
504 							String line2=line.trim();
505 							if(line2.length()>0 && !line2.startsWith("#")){
506 								list.add(line2);
507 							}
508 						}
509 						tf.close();
510 					}catch(Throwable t){
511 						throw new RuntimeException("Could not process config file "+b+"\nCaused by:\n"+t.toString()+"\n");
512 					}
513 				}
514 			}else if(arg!=null && !"null".equals(arg)){
515 				list.add(arg);
516 			}
517 		}
518 		return list.toArray(new String[list.size()]);
519 	}
520 
parseCommonStatic(String arg, String a, String b)521 	public static boolean parseCommonStatic(String arg, String a, String b){
522 		if(a.equals("null")){
523 			//Do nothing
524 		}else if(a.equals("monitor") || a.equals("killswitch")){
525 			if(Parse.isNumber(b)){
526 				String[] pair=b.split(",");
527 				if(pair.length==1){
528 					KillSwitch.launch(Double.parseDouble(pair[0]));
529 				}else{
530 					assert(pair.length==2) : "monitor takes one or two arguments, like this: monitor=600,0.002";
531 					KillSwitch.launch(Double.parseDouble(pair[0]), Double.parseDouble(pair[1]));
532 				}
533 			}else if(Parse.parseBoolean(b)){
534 				KillSwitch.launch();
535 			}
536 		}else if(a.equals("trd") || a.equals("trc") || a.equals("trimreaddescription") || a.equals("trimreaddescriptions")){
537 			Shared.TRIM_READ_COMMENTS=Parse.parseBoolean(b);
538 			if(!setTrimRname){Shared.TRIM_RNAME=Shared.TRIM_READ_COMMENTS;}
539 		}else if(a.equals("trimrefdescription") || a.equals("trimrefdescriptions") || a.equals("trimrname")){
540 			Shared.TRIM_RNAME=Parse.parseBoolean(b);
541 			setTrimRname=true;
542 		}else if(a.equals("tuc") || a.equals("touppercase")){
543 			Read.TO_UPPER_CASE=Parse.parseBoolean(b);
544 		}else if(a.equals("lctn") || a.equals("lowercaseton")){
545 			Read.LOWER_CASE_TO_N=Parse.parseBoolean(b);
546 		}else if(a.equals("changequality") || a.equals("cq")){
547 			Read.CHANGE_QUALITY=Parse.parseBoolean(b);
548 			BBMerge.changeQuality=Read.CHANGE_QUALITY;
549 		}else if(a.equals("tossbrokenreads") || a.equals("tbr")){
550 			boolean x=Parse.parseBoolean(b);
551 			Read.TOSS_BROKEN_QUALITY=x;
552 			ConcurrentReadInputStream.REMOVE_DISCARDED_READS=x;
553 		}else if(a.equals("nullifybrokenquality") || a.equals("nbq")){
554 			boolean x=Parse.parseBoolean(b);
555 			Read.NULLIFY_BROKEN_QUALITY=x;
556 		}else if(a.equals("dotdashxton")){
557 			boolean x=Parse.parseBoolean(b);
558 			Read.DOT_DASH_X_TO_N=x;
559 		}else if(a.equals("junk")){
560 			if("ignore".equalsIgnoreCase(b)){Read.JUNK_MODE=Read.IGNORE_JUNK;}
561 			else if("crash".equalsIgnoreCase(b) || "fail".equalsIgnoreCase(b)){Read.JUNK_MODE=Read.CRASH_JUNK;}
562 			else if("fix".equalsIgnoreCase(b)){Read.JUNK_MODE=Read.FIX_JUNK;}
563 			else if("flag".equalsIgnoreCase(b) || "discard".equalsIgnoreCase(b)){Read.JUNK_MODE=Read.FLAG_JUNK;}
564 			else if("iupacton".equalsIgnoreCase(b)){Read.JUNK_MODE=Read.FIX_JUNK_AND_IUPAC;}
565 			else{assert(false) : "Bad junk mode: "+arg;}
566 		}else if(a.equals("undefinedton") || a.equals("iupacton") || a.equals("itn")){
567 			Read.IUPAC_TO_N=Parse.parseBoolean(b);
568 		}else if(a.equals("ignorejunk")){
569 			boolean x=Parse.parseBoolean(b);
570 			if(x){Read.JUNK_MODE=Read.IGNORE_JUNK;}
571 			else if(Read.JUNK_MODE==Read.IGNORE_JUNK){Read.JUNK_MODE=Read.CRASH_JUNK;}
572 		}else if(a.equals("flagjunk")){
573 			boolean x=Parse.parseBoolean(b);
574 			if(x){Read.JUNK_MODE=Read.FLAG_JUNK;}
575 			else if(Read.JUNK_MODE==Read.FLAG_JUNK){Read.JUNK_MODE=Read.CRASH_JUNK;}
576 		}else if(a.equals("fixjunk")){
577 			boolean x=Parse.parseBoolean(b);
578 			if(x){Read.JUNK_MODE=Read.FIX_JUNK;}
579 			else if(Read.JUNK_MODE==Read.FIX_JUNK){Read.JUNK_MODE=Read.CRASH_JUNK;}
580 		}else if(a.equals("crashjunk") || a.equals("failjunk")){
581 			boolean x=Parse.parseBoolean(b);
582 			if(x){Read.JUNK_MODE=Read.CRASH_JUNK;}
583 			else if(Read.JUNK_MODE==Read.CRASH_JUNK){Read.JUNK_MODE=Read.IGNORE_JUNK;}
584 		}else if(a.equals("skipvalidation")){
585 			Read.SKIP_SLOW_VALIDATION=Parse.parseBoolean(b);
586 		}else if(a.equals("validate")){
587 			Read.SKIP_SLOW_VALIDATION=!Parse.parseBoolean(b);
588 		}else if(a.equals("validatebranchless")){
589 //			Read.VALIDATE_BRANCHLESS=Parse.parseBoolean(b);
590 		}else if(a.equals("bf1")){
591 			ByteFile.FORCE_MODE_BF1=Parse.parseBoolean(b);
592 			ByteFile.FORCE_MODE_BF2=!ByteFile.FORCE_MODE_BF1;
593 		}else if(a.equals("bf1bufferlen")){
594 			ByteFile1.bufferlen=(int)Parse.parseKMGBinary(b);
595 		}else if(a.equals("utot")){
596 			Read.U_TO_T=Parse.parseBoolean(b);
597 		}else if(a.equals("bf2")){
598 			ByteFile.FORCE_MODE_BF2=Parse.parseBoolean(b);
599 			ByteFile.FORCE_MODE_BF1=!ByteFile.FORCE_MODE_BF2;
600 		}else if(a.equals("bf3")){
601 			ByteFile.FORCE_MODE_BF3=Parse.parseBoolean(b);
602 			if(ByteFile.FORCE_MODE_BF3){
603 				ByteFile.FORCE_MODE_BF1=true;
604 				ByteFile.FORCE_MODE_BF2=false;
605 			}
606 		}else if(a.equals("usejni") || a.equals("jni")){
607 			Shared.USE_JNI=Parse.parseBoolean(b);
608 		}else if(a.equals("usempi") || a.equals("mpi")){
609 			if(b!=null && Tools.isDigit(b.charAt(0))){
610 				Shared.MPI_NUM_RANKS=Integer.parseInt(b);
611 				Shared.USE_MPI=Shared.MPI_NUM_RANKS>0;
612 			}else{
613 				Shared.USE_MPI=Parse.parseBoolean(b);
614 			}
615 		}else if(a.equals("crismpi")){
616 			Shared.USE_CRISMPI=Parse.parseBoolean(b);
617 		}else if(a.equals("mpikeepall")){
618 			Shared.MPI_KEEP_ALL=Parse.parseBoolean(b);
619 		}else if(a.equals("readbufferlength") || a.equals("readbufferlen")){
620 			Shared.setBufferLen((int)Parse.parseKMG(b));
621 		}else if(a.equals("readbufferdata")){
622 			Shared.setBufferData(Parse.parseKMG(b));
623 		}else if(a.equals("readbuffers")){
624 			Shared.setBuffers(Integer.parseInt(b));
625 		}else if(a.equals("rbm") || a.equals("renamebymapping")){
626 			FASTQ.TAG_CUSTOM=Parse.parseBoolean(b);
627 		}else if(a.equals("don") || a.equals("deleteoldname")){
628 			FASTQ.DELETE_OLD_NAME=Parse.parseBoolean(b);
629 		}else if(a.equals("assertcigar")){
630 			ReadStreamWriter.ASSERT_CIGAR=Parse.parseBoolean(b);
631 		}else if(a.equals("verbosesamline")){
632 			SamLine.verbose=Parse.parseBoolean(b);
633 		}else if(a.equals("parsecustom") || a.equals("fastqparsecustom")){
634 			FASTQ.PARSE_CUSTOM=Parse.parseBoolean(b);
635 			System.err.println("Set FASTQ.PARSE_CUSTOM to "+FASTQ.PARSE_CUSTOM);
636 		}else if(a.equals("fairqueues")){
637 			ConcurrentDepot.fair=Parse.parseBoolean(b);
638 		}else if(a.equals("fixheader") || a.equals("fixheaders")){
639 			Read.FIX_HEADER=Parse.parseBoolean(b);
640 		}else if(a.equals("allownullheader") || a.equals("allownullheaders")){
641 			Read.ALLOW_NULL_HEADER=Parse.parseBoolean(b);
642 		}else if(a.equals("aminoin") || a.equals("amino")){
643 			//TODO: ensure changes to this do not conflict with TranslateSixFrames "aain" flag.
644 			Shared.AMINO_IN=SketchObject.amino=Parse.parseBoolean(b);
645 		}else if(a.equals("amino8")){
646 			SketchObject.amino8=Parse.parseBoolean(b);
647 			if(SketchObject.amino8){
648 				Shared.AMINO_IN=SketchObject.amino=true;
649 				AminoAcid.AMINO_SHIFT=3;
650 			}
651 		}else if(a.equals("maxcalledquality")){
652 			int x=Tools.mid(1, Integer.parseInt(b), 93);
653 			Read.setMaxCalledQuality((byte)x);
654 		}else if(a.equals("mincalledquality")){
655 			int x=Tools.mid(0, Integer.parseInt(b), 93);
656 			Read.setMinCalledQuality((byte)x);
657 		}else if(a.equals("t") || a.equals("threads")){
658 			Shared.setThreads(b);
659 			if(!silent){System.err.println("Set threads to "+Shared.threads());}
660 		}else if(a.equals("recalpairnum") || a.equals("recalibratepairnum")){
661 			CalcTrueQuality.USE_PAIRNUM=Parse.parseBoolean(b);
662 		}else if(a.equals("taxpath")){
663 			if("auto".equalsIgnoreCase(b)){
664 				TaxTree.TAX_PATH=TaxTree.defaultTaxPath();
665 			}else{
666 				TaxTree.TAX_PATH=b.replaceAll("\\\\", "/");
667 			}
668 		}else if(a.equals("parallelsort")){
669 			boolean x=Parse.parseBoolean(b);
670 			Shared.setParallelSort(x);
671 		}else if(a.equals("gcbeforemem")){
672 			Shared.GC_BEFORE_PRINT_MEMORY=Parse.parseBoolean(b);
673 		}else if(a.equals("warnifnosequence")){
674 			FastaReadInputStream.WARN_IF_NO_SEQUENCE=Parse.parseBoolean(b);
675 		}else if(a.equals("warnfirsttimeonly")){
676 			FastaReadInputStream.WARN_FIRST_TIME_ONLY=Parse.parseBoolean(b);
677 		}else if(a.equals("silva")){
678 			TaxTree.SILVA_MODE=Parse.parseBoolean(b);
679 		}else if(a.equals("unite")){
680 			TaxTree.UNITE_MODE=Parse.parseBoolean(b);
681 		}else if(a.equals("parallelsort") || a.equals("paralellsort")){
682 			Shared.parallelSort=Parse.parseBoolean(b);
683 		}else if(a.equals("imghq")){
684 			TaxTree.IMG_HQ=Parse.parseBoolean(b);
685 		}
686 
687 		else if(a.equals("callins") ||  a.equals("callinss")){
688 			var2.Var.CALL_INS=Parse.parseBoolean(b);
689 		}else if(a.equals("calldel") || a.equals("calldels")){
690 			var2.Var.CALL_DEL=Parse.parseBoolean(b);
691 		}else if(a.equals("callsub") || a.equals("callsubs") || a.equals("callsnp") || a.equals("callsnps")){
692 			var2.Var.CALL_SUB=Parse.parseBoolean(b);
693 		}else if(a.equals("callindel") || a.equals("callindels")){
694 			var2.Var.CALL_INS=var2.Var.CALL_DEL=Parse.parseBoolean(b);
695 		}else if(a.equals("calljunct") || a.equals("calljunction") || a.equals("calljunctions")){
696 			var2.Var.CALL_JUNCTION=Parse.parseBoolean(b);
697 		}else if(a.equals("callnocall") || a.equals("callnocalls")){
698 			var2.Var.CALL_NOCALL=Parse.parseBoolean(b);
699 		}else if(a.equals("kmg") || a.equals("outputkmg")){
700 			Shared.OUTPUT_KMG=Parse.parseBoolean(b);
701 		}
702 
703 		else if(a.equals("tmpdir")){
704 			Shared.setTmpdir(b);
705 		}
706 
707 		else if(a.equals("comment")){
708 			Shared.comment=b;
709 		}
710 
711 		else if(a.equals("fixextensions") || a.equals("fixextension") || a.equals("tryallextensions")){
712 			Shared.FIX_EXTENSIONS=Parse.parseBoolean(b);
713 		}
714 
715 		else if(a.equals("2passresize") || a.equals("twopassresize")){
716 			AbstractKmerTable.TWO_PASS_RESIZE=Parse.parseBoolean(b);
717 		}
718 
719 		else if(a.equalsIgnoreCase("forceJavaParseDouble")){
720 			Tools.FORCE_JAVA_PARSE_DOUBLE=Parse.parseBoolean(b);
721 		}
722 
723 		else if(a.equalsIgnoreCase("awsServers") || a.equalsIgnoreCase("aws")){
724 			Shared.awsServers=Parse.parseBoolean(b);
725 		}else if(a.equalsIgnoreCase("nerscServers") || a.equalsIgnoreCase("nersc")){
726 			Shared.awsServers=!Parse.parseBoolean(b);
727 		}
728 
729 		else if(a.equals("entropyk") || a.equals("ek")){
730 			EntropyTracker.defaultK=Integer.parseInt(b);
731 			EntropyTracker.setDefaultK=true;
732 		}else if(a.equals("entropywindow") || a.equals("ew")){
733 			EntropyTracker.defaultWindowBases=Integer.parseInt(b);
734 			EntropyTracker.setDefaultWindow=true;
735 		}else if(a.equalsIgnoreCase("protFull")){
736 			TaxTree.protFull=true;
737 		}
738 
739 		else{
740 			return false;
741 		}
742 		return true;
743 	}
744 
parseQuality(String arg, String a, String b)745 	public static boolean parseQuality(String arg, String a, String b){
746 		parsedQuality=true; //For internal verification that this function was indeed called.
747 		if(a.equals("ignorebadquality") || a.equals("ibq")){
748 			FASTQ.IGNORE_BAD_QUALITY=Parse.parseBoolean(b);
749 			if(FASTQ.IGNORE_BAD_QUALITY){Read.CHANGE_QUALITY=false;}
750 		}else if(a.equals("ascii") || a.equals("asciioffset") || a.equals("quality") || a.equals("qual")){
751 			byte x;
752 			if(b.equalsIgnoreCase("sanger")){x=33;}
753 			else if(b.equalsIgnoreCase("illumina")){x=64;}
754 			else if(b.equalsIgnoreCase("auto")){x=-1;FASTQ.DETECT_QUALITY=FASTQ.DETECT_QUALITY_OUT=true;}
755 			else{x=(byte)Integer.parseInt(b);}
756 			qin=qout=x;
757 			FASTQ.SET_QIN=x>-1;
758 		}else if(a.equals("asciiin") || a.equals("qualityin") || a.equals("qualin") || a.equals("qin")){
759 			byte x;
760 			if(b.equalsIgnoreCase("sanger")){x=33;}
761 			else if(b.equalsIgnoreCase("illumina")){x=64;}
762 			else if(b.equalsIgnoreCase("auto")){x=-1;FASTQ.DETECT_QUALITY=true;}
763 			else{x=(byte)Integer.parseInt(b);}
764 			qin=x;
765 			FASTQ.SET_QIN=x>-1;
766 		}else if(a.equals("asciiout") || a.equals("qualityout") || a.equals("qualout") || a.equals("qout")){
767 			byte x;
768 			if(b.equalsIgnoreCase("sanger")){x=33;}
769 			else if(b.equalsIgnoreCase("illumina")){x=64;}
770 			else if(b.equalsIgnoreCase("auto")){x=-1;FASTQ.DETECT_QUALITY_OUT=true;}
771 			else{x=(byte)Integer.parseInt(b);}
772 			qout=x;
773 		}else if(a.equals("fakequality") || a.equals("qfake")){
774 			Shared.FAKE_QUAL=Byte.parseByte(b);
775 		}else if(a.equals("fakefastaqual") || a.equals("fakefastaquality") || a.equals("ffq")){
776 			if(b==null || b.length()<1){b="f";}
777 			if(Character.isLetter(b.charAt(0))){
778 				FastaReadInputStream.FAKE_QUALITY=Parse.parseBoolean(b);
779 			}else{
780 				int x=Integer.parseInt(b);
781 				if(x<1){
782 					FastaReadInputStream.FAKE_QUALITY=false;
783 				}else{
784 					FastaReadInputStream.FAKE_QUALITY=true;
785 					Shared.FAKE_QUAL=(byte)Tools.min(x, 50);
786 				}
787 			}
788 		}else if(a.equals("qauto")){
789 			FASTQ.DETECT_QUALITY=FASTQ.DETECT_QUALITY_OUT=true;
790 		}else{
791 			return false;
792 		}
793 		return true;
794 	}
795 
qhistsNull()796 	private static boolean qhistsNull(){
797 		return ReadStats.BQUAL_HIST_FILE==null && ReadStats.QUAL_HIST_FILE!=null && ReadStats.AVG_QUAL_HIST_FILE!=null && ReadStats.BQUAL_HIST_OVERALL_FILE!=null
798 				&& ReadStats.QUAL_COUNT_HIST_FILE==null;
799 	}
800 
parseHist(String arg, String a, String b)801 	public static boolean parseHist(String arg, String a, String b){
802 		if(a.equals("qualityhistogram") || a.equals("qualityhist") || a.equals("qhist")){
803 			ReadStats.QUAL_HIST_FILE=(b==null || b.equalsIgnoreCase("null") || b.equalsIgnoreCase("none")) ? null : b;
804 			ReadStats.COLLECT_QUALITY_STATS=!qhistsNull();
805 			if(ReadStats.COLLECT_QUALITY_STATS){System.err.println("Set quality histogram output to "+ReadStats.QUAL_HIST_FILE);}
806 		}else if(a.equals("basequalityhistogram") || a.equals("basequalityhist") || a.equals("bqhist")){
807 			ReadStats.BQUAL_HIST_FILE=(b==null || b.equalsIgnoreCase("null") || b.equalsIgnoreCase("none")) ? null : b;
808 			ReadStats.COLLECT_QUALITY_STATS=!qhistsNull();
809 			if(ReadStats.BQUAL_HIST_FILE!=null){System.err.println("Set bquality histogram output to "+ReadStats.BQUAL_HIST_FILE);}
810 		}else if(a.equals("qualitycounthistogram") || a.equals("qualitycounthist") || a.equals("qchist") || a.equals("qdhist") || a.equals("qfhist")){
811 			ReadStats.QUAL_COUNT_HIST_FILE=(b==null || b.equalsIgnoreCase("null") || b.equalsIgnoreCase("none")) ? null : b;
812 			ReadStats.COLLECT_QUALITY_STATS=!qhistsNull();
813 			if(ReadStats.QUAL_COUNT_HIST_FILE!=null){System.err.println("Set qcount histogram output to "+ReadStats.QUAL_COUNT_HIST_FILE);}
814 		}else if(a.equals("averagequalityhistogram") || a.equals("aqhist")){
815 			ReadStats.AVG_QUAL_HIST_FILE=(b==null || b.equalsIgnoreCase("null") || b.equalsIgnoreCase("none")) ? null : b;
816 			ReadStats.COLLECT_QUALITY_STATS=!qhistsNull();
817 			if(ReadStats.COLLECT_QUALITY_STATS){System.err.println("Set average quality histogram output to "+ReadStats.AVG_QUAL_HIST_FILE);}
818 		}else if(a.equals("overallbasequalityhistogram") || a.equals("overallbasequalityhist") || a.equals("obqhist")){
819 			ReadStats.BQUAL_HIST_OVERALL_FILE=(b==null || b.equalsIgnoreCase("null") || b.equalsIgnoreCase("none")) ? null : b;
820 			ReadStats.COLLECT_QUALITY_STATS=(ReadStats.BQUAL_HIST_FILE!=null || ReadStats.QUAL_HIST_FILE!=null || ReadStats.AVG_QUAL_HIST_FILE!=null || ReadStats.BQUAL_HIST_OVERALL_FILE!=null);
821 			if(ReadStats.COLLECT_QUALITY_STATS){System.err.println("Set quality histogram output to "+ReadStats.QUAL_HIST_FILE);}
822 		}else if(a.equals("matchhistogram") || a.equals("matchhist") || a.equals("mhist")){
823 			ReadStats.MATCH_HIST_FILE=(b==null || b.equalsIgnoreCase("null") || b.equalsIgnoreCase("none")) ? null : b;
824 			ReadStats.COLLECT_MATCH_STATS=(ReadStats.MATCH_HIST_FILE!=null);
825 			if(ReadStats.COLLECT_MATCH_STATS){System.err.println("Set match histogram output to "+ReadStats.MATCH_HIST_FILE);}
826 		}else if(a.equals("inserthistogram") || a.equals("inserthist") || a.equals("ihist")){
827 			ReadStats.INSERT_HIST_FILE=(b==null || b.equalsIgnoreCase("null") || b.equalsIgnoreCase("none")) ? null : b;
828 			ReadStats.COLLECT_INSERT_STATS=(ReadStats.INSERT_HIST_FILE!=null);
829 			if(ReadStats.COLLECT_INSERT_STATS){System.err.println("Set insert size histogram output to "+ReadStats.INSERT_HIST_FILE);}
830 		}else if(a.equals("basehistogram") || a.equals("basehist") || a.equals("bhist")){
831 			ReadStats.BASE_HIST_FILE=(b==null || b.equalsIgnoreCase("null") || b.equalsIgnoreCase("none")) ? null : b;
832 			ReadStats.COLLECT_BASE_STATS=(ReadStats.BASE_HIST_FILE!=null);
833 			if(ReadStats.COLLECT_BASE_STATS){System.err.println("Set base content histogram output to "+ReadStats.BASE_HIST_FILE);}
834 		}else if(a.equals("qualityaccuracyhistogram") || a.equals("qahist")){
835 			ReadStats.QUAL_ACCURACY_FILE=(b==null || b.equalsIgnoreCase("null") || b.equalsIgnoreCase("none")) ? null : b;
836 			ReadStats.COLLECT_QUALITY_ACCURACY=(ReadStats.QUAL_ACCURACY_FILE!=null);
837 			if(ReadStats.COLLECT_QUALITY_ACCURACY){System.err.println("Set quality accuracy histogram output to "+ReadStats.QUAL_ACCURACY_FILE);}
838 		}else if(a.equals("indelhistogram") || a.equals("indelhist")){
839 			ReadStats.INDEL_HIST_FILE=(b==null || b.equalsIgnoreCase("null") || b.equalsIgnoreCase("none")) ? null : b;
840 			ReadStats.COLLECT_INDEL_STATS=(ReadStats.INDEL_HIST_FILE!=null);
841 			if(ReadStats.COLLECT_INDEL_STATS){System.err.println("Set indel histogram output to "+ReadStats.INDEL_HIST_FILE);}
842 		}else if(a.equals("errorhistogram") || a.equals("ehist")){
843 			ReadStats.ERROR_HIST_FILE=(b==null || b.equalsIgnoreCase("null") || b.equalsIgnoreCase("none")) ? null : b;
844 			ReadStats.COLLECT_ERROR_STATS=(ReadStats.ERROR_HIST_FILE!=null);
845 			if(ReadStats.COLLECT_ERROR_STATS){System.err.println("Set error histogram output to "+ReadStats.ERROR_HIST_FILE);}
846 		}else if(a.equals("lengthhistogram") || a.equals("lhist")){
847 			ReadStats.LENGTH_HIST_FILE=(b==null || b.equalsIgnoreCase("null") || b.equalsIgnoreCase("none")) ? null : b;
848 			ReadStats.COLLECT_LENGTH_STATS=(ReadStats.LENGTH_HIST_FILE!=null);
849 			if(ReadStats.COLLECT_LENGTH_STATS){System.err.println("Set length histogram output to "+ReadStats.LENGTH_HIST_FILE);}
850 		}else if(a.equals("gchistogram") || a.equals("gchist")){
851 			ReadStats.GC_HIST_FILE=(b==null || b.equalsIgnoreCase("null") || b.equalsIgnoreCase("none")) ? null : b;
852 			ReadStats.COLLECT_GC_STATS=(ReadStats.GC_HIST_FILE!=null);
853 			if(ReadStats.COLLECT_GC_STATS){System.err.println("Set GC histogram output to "+ReadStats.GC_HIST_FILE);}
854 		}else if(a.equals("gcbins") || a.equals("gchistbins")){
855 			if("auto".equalsIgnoreCase(b)){
856 				ReadStats.GC_BINS=4000;
857 				ReadStats.GC_BINS_AUTO=true;
858 			}else{
859 				ReadStats.GC_BINS=Integer.parseInt(b);
860 				ReadStats.GC_BINS_AUTO=false;
861 			}
862 		}else if(a.equals("gcchart") || a.equals("gcplot")){
863 			ReadStats.GC_PLOT_X=Parse.parseBoolean(b);
864 		}else if(a.equals("entropyhistogram") || a.equals("entropyhist") || a.equals("enhist") || a.equals("enthist")){
865 			ReadStats.ENTROPY_HIST_FILE=(b==null || b.equalsIgnoreCase("null") || b.equalsIgnoreCase("none")) ? null : b;
866 			ReadStats.COLLECT_ENTROPY_STATS=(ReadStats.ENTROPY_HIST_FILE!=null);
867 			if(ReadStats.COLLECT_ENTROPY_STATS){System.err.println("Set entropy histogram output to "+ReadStats.ENTROPY_HIST_FILE);}
868 		}else if(a.equals("entropybins") || a.equals("entropyhistbins") || a.equals("entbins") || a.equals("enthistbins")){
869 			if("auto".equalsIgnoreCase(b)){
870 				ReadStats.ENTROPY_BINS=1000;
871 //				ReadStats.ENTROPY_BINS_AUTO=true;
872 			}else{
873 				ReadStats.ENTROPY_BINS=Integer.parseInt(b);
874 //				ReadStats.ENTROPY_BINS_AUTO=false;
875 			}
876 		}else if(a.equals("entropyns") || a.equals("entropyhistns")){
877 			ReadStats.allowEntropyNs=Parse.parseBoolean(b);
878 		}else if(a.equals("timehistogram") || a.equals("thist")){
879 			ReadStats.TIME_HIST_FILE=(b==null || b.equalsIgnoreCase("null") || b.equalsIgnoreCase("none")) ? null : b;
880 			ReadStats.COLLECT_TIME_STATS=(ReadStats.TIME_HIST_FILE!=null);
881 			if(ReadStats.COLLECT_IDENTITY_STATS){System.err.println("Set identity histogram output to "+ReadStats.IDENTITY_HIST_FILE);}
882 		}else if(a.equals("identityhistogram") || a.equals("idhist")){
883 			ReadStats.IDENTITY_HIST_FILE=(b==null || b.equalsIgnoreCase("null") || b.equalsIgnoreCase("none")) ? null : b;
884 			ReadStats.COLLECT_IDENTITY_STATS=(ReadStats.IDENTITY_HIST_FILE!=null);
885 			if(ReadStats.COLLECT_IDENTITY_STATS){System.err.println("Set identity histogram output to "+ReadStats.IDENTITY_HIST_FILE);}
886 		}else if(a.equals("idhistlen") || a.equals("idhistlength") || a.equals("idhistbins") || a.equals("idbins")){
887 			if("auto".equalsIgnoreCase(b)){
888 				ReadStats.ID_BINS=750;
889 				ReadStats.ID_BINS_AUTO=true;
890 			}else{
891 				ReadStats.ID_BINS=Integer.parseInt(b);
892 				ReadStats.ID_BINS_AUTO=false;
893 			}
894 		}
895 
896 		else if(a.equals("maxhistlen")){
897 			ReadStats.MAXLEN=ReadStats.MAXINSERTLEN=ReadStats.MAXLENGTHLEN=Parse.parseIntKMG(b);
898 		}
899 
900 		else if(a.equals("fixindels") || a.equals("ignorevcfindels")){
901 			CallVariants.fixIndels=Parse.parseBoolean(b);
902 		}
903 
904 		else{
905 			return false;
906 		}
907 		return true;
908 	}
909 
parseZip(String arg, String a, String b)910 	public static boolean parseZip(String arg, String a, String b){
911 		if(a.equals("ziplevel") || a.equals("zl")){
912 			int x=Integer.parseInt(b);
913 			if(x>=0){
914 				ReadWrite.ZIPLEVEL=Tools.min(x, 11);
915 			}
916 		}else if(a.equals("bziplevel") || a.equals("bzl")){
917 			int x=Integer.parseInt(b);
918 			if(x>=0){
919 				ReadWrite.BZIPLEVEL=Tools.min(x, 9);
920 			}
921 		}else if(a.equals("allowziplevelchange")){
922 			ReadWrite.ALLOW_ZIPLEVEL_CHANGE=Parse.parseBoolean(b);
923 		}else if(a.equals("usegzip") || a.equals("gzip")){
924 			ReadWrite.USE_GZIP=Parse.parseBoolean(b);
925 		}else if(a.equals("usebgzip") || a.equals("bgzip")){
926 
927 			if(b!=null && Tools.isDigit(b.charAt(0))){
928 				int zt=Integer.parseInt(b);
929 				if(zt<1){ReadWrite.USE_BGZIP=false;}
930 				else{
931 					ReadWrite.USE_BGZIP=true;
932 					ReadWrite.MAX_ZIP_THREADS=zt;
933 				}
934 			}else{ReadWrite.USE_BGZIP=Parse.parseBoolean(b);}
935 			if(ReadWrite.USE_BGZIP){ReadWrite.PREFER_BGZIP=true;}
936 		}else if(a.equals("forcepigz")){
937 			ReadWrite.FORCE_PIGZ=Parse.parseBoolean(b);
938 			if(ReadWrite.FORCE_PIGZ){ReadWrite.USE_PIGZ=true;}
939 		}else if(a.equals("forcebgzip")){
940 			ReadWrite.FORCE_BGZIP=Parse.parseBoolean(b);
941 			if(ReadWrite.FORCE_BGZIP){ReadWrite.USE_BGZIP=true;}
942 		}else if(a.equals("preferbgzip")){
943 			ReadWrite.PREFER_BGZIP=Parse.parseBoolean(b);
944 		}else if(a.equals("zipthreads")){
945 			ReadWrite.MAX_ZIP_THREADS=Integer.parseInt(b);
946 		}else if(a.equals("usepigz") || a.equals("pigz")){
947 			if(b!=null && Tools.isDigit(b.charAt(0))){
948 				int zt=Integer.parseInt(b);
949 				if(zt<1){ReadWrite.USE_PIGZ=false;}
950 				else{
951 					ReadWrite.USE_PIGZ=true;
952 					ReadWrite.MAX_ZIP_THREADS=zt;
953 				}
954 			}else{ReadWrite.USE_PIGZ=Parse.parseBoolean(b);}
955 		}else if(a.equals("zipthreaddivisor") || a.equals("ztd")){
956 			ReadWrite.setZipThreadMult(1/Float.parseFloat(b));
957 		}else if(a.equals("blocksize")){
958 			int x=Integer.parseInt(b);
959 			ReadWrite.PIGZ_BLOCKSIZE=Tools.mid(32, x, 1024);
960 		}else if(a.equals("pigziterations") || a.equals("pigziters")){
961 			int x=Integer.parseInt(b);
962 			ReadWrite.PIGZ_ITERATIONS=Tools.mid(32, x, 1024);
963 		}else if(a.equals("usegunzip") || a.equals("gunzip") || a.equals("ungzip")){
964 			ReadWrite.USE_GUNZIP=Parse.parseBoolean(b);
965 		}else if(a.equals("useunpigz") || a.equals("unpigz")){
966 			ReadWrite.USE_UNPIGZ=Parse.parseBoolean(b);
967 		}else if(a.equals("useunbgzip") || a.equals("unbgzip")){
968 			ReadWrite.USE_UNBGZIP=ReadWrite.PREFER_UNBGZIP=Parse.parseBoolean(b);
969 		}else if(a.equals("preferunbgzip")){
970 			ReadWrite.PREFER_UNBGZIP=Parse.parseBoolean(b);
971 		}else if(a.equals("usebzip2") || a.equals("bzip2")){
972 			ReadWrite.USE_BZIP2=Parse.parseBoolean(b);
973 		}else if(a.equals("usepbzip2") || a.equals("pbzip2")){
974 			ReadWrite.USE_PBZIP2=Parse.parseBoolean(b);
975 		}else if(a.equals("uselbzip2") || a.equals("lbzip2")){
976 			ReadWrite.USE_LBZIP2=Parse.parseBoolean(b);
977 		}else{
978 			return false;
979 		}
980 		return true;
981 	}
982 
parseSam(String arg, String a, String b)983 	public static boolean parseSam(String arg, String a, String b){
984 		if(a.equals("samversion") || a.equals("samv") || a.equals("sam")){
985 			assert(b!=null) : "The sam flag requires a version number, e.g. 'sam=1.4'";
986 			SamLine.VERSION=Float.parseFloat(b);
987 		}else if(a.equals("sambamba")){
988 			Data.USE_SAMBAMBA=Parse.parseBoolean(b);
989 		}else if(a.equals("samtools")){
990 			Data.USE_SAMTOOLS=Parse.parseBoolean(b);
991 		}else if(a.equals("streamerthreads")){
992 			SamStreamer.DEFAULT_THREADS=Integer.parseInt(b);
993 		}else if(a.equals("prefermd") || a.equals("prefermdtag")){
994 			SamLine.PREFER_MDTAG=Parse.parseBoolean(b);
995 		}else if(a.equals("notags")){
996 			SamLine.NO_TAGS=Parse.parseBoolean(b);
997 		}else if(a.equals("mdtag") || a.equals("md")){
998 			SamLine.MAKE_MD_TAG=Parse.parseBoolean(b);
999 		}else if(a.equals("idtag")){
1000 			SamLine.MAKE_IDENTITY_TAG=Parse.parseBoolean(b);
1001 		}else if(a.equals("xmtag") || a.equals("xm")){
1002 			SamLine.MAKE_XM_TAG=Parse.parseBoolean(b);
1003 		}else if(a.equals("smtag")){
1004 			SamLine.MAKE_SM_TAG=Parse.parseBoolean(b);
1005 		}else if(a.equals("amtag")){
1006 			SamLine.MAKE_AM_TAG=Parse.parseBoolean(b);
1007 		}else if(a.equals("nmtag")){
1008 			SamLine.MAKE_NM_TAG=Parse.parseBoolean(b);
1009 		}else if(a.equals("stoptag")){
1010 			SamLine.MAKE_STOP_TAG=Parse.parseBoolean(b);
1011 		}else if(a.equals("lengthtag")){
1012 			SamLine.MAKE_LENGTH_TAG=Parse.parseBoolean(b);
1013 		}else if(a.equals("boundstag")){
1014 			SamLine.MAKE_BOUNDS_TAG=Parse.parseBoolean(b);
1015 		}else if(a.equals("scoretag")){
1016 			SamLine.MAKE_SCORE_TAG=Parse.parseBoolean(b);
1017 		}else if(a.equals("sortscaffolds")){
1018 			SamLine.SORT_SCAFFOLDS=Parse.parseBoolean(b);
1019 		}else if(a.equals("customtag")){
1020 			SamLine.MAKE_CUSTOM_TAGS=Parse.parseBoolean(b);
1021 		}else if(a.equals("nhtag")){
1022 			SamLine.MAKE_NH_TAG=Parse.parseBoolean(b);
1023 		}else if(a.equals("keepnames")){
1024 			SamLine.KEEP_NAMES=Parse.parseBoolean(b);
1025 		}else if(a.equals("saa") || a.equals("secondaryalignmentasterisks")){
1026 			SamLine.SECONDARY_ALIGNMENT_ASTERISKS=Parse.parseBoolean(b);
1027 		}else if(a.equals("inserttag")){
1028 			SamLine.MAKE_INSERT_TAG=Parse.parseBoolean(b);
1029 		}else if(a.equals("correctnesstag")){
1030 			SamLine.MAKE_CORRECTNESS_TAG=Parse.parseBoolean(b);
1031 		}else if(a.equals("intronlen") || a.equals("intronlength")){
1032 			SamLine.INTRON_LIMIT=Integer.parseInt(b);
1033 			SamLine.setintron=true;
1034 		}else if(a.equals("suppressheader") || a.equals("noheader")){
1035 			ReadStreamWriter.NO_HEADER=Parse.parseBoolean(b);
1036 		}else if(a.equals("noheadersequences") || a.equals("nhs") || a.equals("suppressheadersequences")){
1037 			ReadStreamWriter.NO_HEADER_SEQUENCES=Parse.parseBoolean(b);
1038 		}else if(a.equals("tophat")){
1039 			if(Parse.parseBoolean(b)){
1040 				SamLine.MAKE_TOPHAT_TAGS=true;
1041 				FastaReadInputStream.FAKE_QUALITY=true;
1042 				Shared.FAKE_QUAL=40;
1043 				SamLine.MAKE_MD_TAG=true;
1044 			}
1045 		}else if(a.equals("xstag") || a.equals("xs")){
1046 			SamLine.MAKE_XS_TAG=true;
1047 			if(b!=null){
1048 				b=b.toLowerCase();
1049 				if(b.startsWith("fr-")){b=b.substring(3);}
1050 				if(b.equals("ss") || b.equals("secondstrand")){
1051 					SamLine.XS_SECONDSTRAND=true;
1052 				}else if(b.equals("fs") || b.equals("firststrand")){
1053 					SamLine.XS_SECONDSTRAND=false;
1054 				}else if(b.equals("us") || b.equals("unstranded")){
1055 					SamLine.XS_SECONDSTRAND=false;
1056 				}else{
1057 					SamLine.MAKE_XS_TAG=Parse.parseBoolean(b);
1058 				}
1059 			}
1060 			SamLine.setxs=true;
1061 		}else if(a.equals("flipsam")){
1062 			SamLine.FLIP_ON_LOAD=Parse.parseBoolean(b);
1063 		}else if(parseReadgroup(arg, a, b)){
1064 			//do nothing
1065 		}else{
1066 			return false;
1067 		}
1068 		return true;
1069 	}
1070 
parseFasta(String arg, String a, String b)1071 	public static boolean parseFasta(String arg, String a, String b){
1072 		if(a.equals("fastareadlen") || a.equals("fastareadlength")){
1073 			FastaReadInputStream.TARGET_READ_LEN=Integer.parseInt(b);
1074 			FastaReadInputStream.SPLIT_READS=(FastaReadInputStream.TARGET_READ_LEN>0);
1075 		}else if(a.equals("fastaminread") || a.equals("fastaminlen") || a.equals("fastaminlength")){
1076 			FastaReadInputStream.MIN_READ_LEN=Integer.parseInt(b);
1077 		}else if(a.equals("forcesectionname")){
1078 			FastaReadInputStream.FORCE_SECTION_NAME=Parse.parseBoolean(b);
1079 		}else if(a.equals("fastawrap") || a.equals("wrap")){
1080 			Shared.FASTA_WRAP=Parse.parseIntKMG(b);
1081 		}else if(a.equals("fastadump")){
1082 			AbstractKmerTable.FASTA_DUMP=Parse.parseBoolean(b);
1083 		}else{
1084 			return false;
1085 		}
1086 		return true;
1087 	}
1088 
parseQualityAdjust(String arg, String a, String b)1089 	public static boolean parseQualityAdjust(String arg, String a, String b){
1090 		int pass=0;
1091 		if(a.endsWith("_p1") || a.endsWith("_p2")){
1092 			pass=Integer.parseInt(a.substring(a.length()-1))-1;
1093 			a=a.substring(0, a.length()-3);
1094 		}
1095 
1096 		if(a.equals("trackall")){
1097 			CalcTrueQuality.TRACK_ALL=Parse.parseBoolean(b);
1098 		}else if(a.equals("clearmatrices")){
1099 			boolean x=Parse.parseBoolean(b);
1100 			if(x){
1101 				CalcTrueQuality.use_q102=new boolean[] {false, false};
1102 				CalcTrueQuality.use_qap=new boolean[] {false, false};
1103 				CalcTrueQuality.use_qbp=new boolean[] {false, false};
1104 				CalcTrueQuality.use_q10=new boolean[] {false, false};
1105 				CalcTrueQuality.use_q12=new boolean[] {false, false};
1106 				CalcTrueQuality.use_qb12=new boolean[] {false, false};
1107 				CalcTrueQuality.use_qb012=new boolean[] {false, false};
1108 				CalcTrueQuality.use_qb123=new boolean[] {false, false};
1109 				CalcTrueQuality.use_qb234=new boolean[] {false, false};
1110 				CalcTrueQuality.use_q12b12=new boolean[] {false, false};
1111 				CalcTrueQuality.use_qp=new boolean[] {false, false};
1112 				CalcTrueQuality.use_q=new boolean[] {false, false};
1113 			}
1114 		}else if(a.equals("loadq102")){
1115 			CalcTrueQuality.use_q102[pass]=Parse.parseBoolean(b);
1116 		}else if(a.equals("loadqap")){
1117 			CalcTrueQuality.use_qap[pass]=Parse.parseBoolean(b);
1118 		}else if(a.equals("loadqbp")){
1119 			CalcTrueQuality.use_qbp[pass]=Parse.parseBoolean(b);
1120 		}else if(a.equals("loadq10")){
1121 			CalcTrueQuality.use_q10[pass]=Parse.parseBoolean(b);
1122 		}else if(a.equals("loadq12")){
1123 			CalcTrueQuality.use_q12[pass]=Parse.parseBoolean(b);
1124 		}else if(a.equals("loadqb12")){
1125 			CalcTrueQuality.use_qb12[pass]=Parse.parseBoolean(b);
1126 		}else if(a.equals("loadqb012")){
1127 			CalcTrueQuality.use_qb012[pass]=Parse.parseBoolean(b);
1128 		}else if(a.equals("loadqb123")){
1129 			CalcTrueQuality.use_qb123[pass]=Parse.parseBoolean(b);
1130 		}else if(a.equals("loadqb234")){
1131 			CalcTrueQuality.use_qb234[pass]=Parse.parseBoolean(b);
1132 		}else if(a.equals("loadq12b12")){
1133 			CalcTrueQuality.use_q12b12[pass]=Parse.parseBoolean(b);
1134 		}else if(a.equals("loadqp")){
1135 			CalcTrueQuality.use_qp[pass]=Parse.parseBoolean(b);
1136 		}else if(a.equals("loadq")){
1137 			CalcTrueQuality.use_q[pass]=Parse.parseBoolean(b);
1138 		}else if(a.equals("observationcutoff")){
1139 			long x=Parse.parseIntKMG(b);
1140 			CalcTrueQuality.OBSERVATION_CUTOFF[pass]=x;
1141 		}else if(a.equals("recalpasses")){
1142 			CalcTrueQuality.passes=Integer.parseInt(b);
1143 		}else if(a.equals("recalqmax")){
1144 			int x=Tools.mid(1, Integer.parseInt(b), 93);
1145 			CalcTrueQuality.setQmax(x);
1146 			Read.setMaxCalledQuality(Tools.max(x, Read.MAX_CALLED_QUALITY()));
1147 		}else if(a.equals("recalqmin")){
1148 			int x=Tools.mid(0, Integer.parseInt(b), 93);
1149 			Read.setMinCalledQuality(Tools.min(x, Read.MIN_CALLED_QUALITY()));
1150 		}else if(a.equals("recalwithposition") || a.equals("recalwithpos") || a.equals("recalusepos")){
1151 			boolean x=Parse.parseBoolean(b);
1152 			if(!x){
1153 				Arrays.fill(CalcTrueQuality.use_qp, false);
1154 				Arrays.fill(CalcTrueQuality.use_qbp, false);
1155 				Arrays.fill(CalcTrueQuality.use_qap, false);
1156 			}
1157 		}else if(a.equals("qmatrixmode")){
1158 			if("weighted".equalsIgnoreCase(b) || "weightedaverage".equalsIgnoreCase(b)){
1159 				CalcTrueQuality.USE_WEIGHTED_AVERAGE=true;
1160 			}else if("average".equalsIgnoreCase(b) || "avg".equalsIgnoreCase(b)){
1161 				CalcTrueQuality.USE_WEIGHTED_AVERAGE=false;
1162 				CalcTrueQuality.USE_AVERAGE=true;
1163 			}else if("max".equalsIgnoreCase(b)){
1164 				CalcTrueQuality.USE_AVERAGE=CalcTrueQuality.USE_WEIGHTED_AVERAGE=false;
1165 			}
1166 		}else{
1167 			return false;
1168 		}
1169 		return true;
1170 	}
1171 
isJavaFlag(String arg)1172 	static boolean isJavaFlag(String arg){
1173 		if(arg==null){return false;}
1174 		if(arg.startsWith("-Xmx") || arg.startsWith("-Xms") || arg.startsWith("-Xmn") || arg.startsWith("-xmx") || arg.startsWith("-xms") || arg.startsWith("-xmn")){
1175 			return arg.length()>4 && Tools.isDigit(arg.charAt(4));
1176 		}
1177 		if(arg.startsWith("Xmx") || arg.startsWith("Xms") || arg.startsWith("Xmn") || arg.startsWith("xmx")){
1178 			return arg.length()>3 && (Tools.isDigit(arg.charAt(3)) || arg.charAt(3)=='=');
1179 		}
1180 		if(arg.equals("-ea") || arg.equals("-da") || arg.equals("ea") || arg.equals("da")){
1181 			return true;
1182 		}
1183 		if(arg.equals("ExitOnOutOfMemoryError") || arg.equals("exitonoutofmemoryerror") || arg.equals("eoom")){return true;}
1184 		if(arg.equals("-ExitOnOutOfMemoryError") || arg.equals("-exitonoutofmemoryerror") || arg.equals("-eoom")){return true;}
1185 
1186 		return false;
1187 	}
1188 
1189 	/** Return true if the user seems confused */
parseHelp(String[] args, boolean autoExit)1190 	static boolean parseHelp(String[] args, boolean autoExit){
1191 		if(args==null || args.length==0 || (args.length==1 && args[0]==null)){
1192 			if(autoExit){printHelp(1);}
1193 			return true;
1194 		}
1195 
1196 		final String s=args[args.length-1].toLowerCase();
1197 
1198 		if(s.equals("-version") || s.equals("--version") || (s.equals("version") && !new File(s).exists())){
1199 			if(autoExit){printHelp(0);}
1200 			return true;
1201 		}else if(s.equals("-h") || s.equals("-help") || s.equals("--help")
1202 				|| s.equals("?") || s.equals("-?") || (s.equals("help") && !new File(s).exists())){
1203 			if(autoExit){printHelp(0);}
1204 			return true;
1205 		}
1206 		return false;
1207 	}
1208 
printHelp(int exitCode)1209 	public static void printHelp(int exitCode){
1210 		System.err.println("BBMap version "+Shared.BBMAP_VERSION_STRING);
1211 		System.err.println("For help, please run the shellscript with no parameters, or look in /docs/.");
1212 		System.exit(exitCode);
1213 	}
1214 
1215 	/** Set SamLine Readgroup Strings */
parseReadgroup(String arg, String a, String b)1216 	public static boolean parseReadgroup(String arg, String a, String b){
1217 		if(a.equals("readgroup") || a.equals("readgroupid") || a.equals("rgid")){
1218 			SamLine.READGROUP_ID=b;
1219 			if(b!=null){SamLine.READGROUP_TAG="RG:Z:"+b;}
1220 		}else if(a.equals("readgroupcn") || a.equals("rgcn")){
1221 			SamLine.READGROUP_CN=b;
1222 		}else if(a.equals("readgroupds") || a.equals("rgds")){
1223 			SamLine.READGROUP_DS=b;
1224 		}else if(a.equals("readgroupdt") || a.equals("rgdt")){
1225 			SamLine.READGROUP_DT=b;
1226 		}else if(a.equals("readgroupfo") || a.equals("rgfo")){
1227 			SamLine.READGROUP_FO=b;
1228 		}else if(a.equals("readgroupks") || a.equals("rgks")){
1229 			SamLine.READGROUP_KS=b;
1230 		}else if(a.equals("readgrouplb") || a.equals("rglb")){
1231 			SamLine.READGROUP_LB=b;
1232 		}else if(a.equals("readgrouppg") || a.equals("rgpg")){
1233 			SamLine.READGROUP_PG=b;
1234 		}else if(a.equals("readgrouppi") || a.equals("rgpi")){
1235 			SamLine.READGROUP_PI=b;
1236 		}else if(a.equals("readgrouppl") || a.equals("rgpl")){
1237 			SamLine.READGROUP_PL=b;
1238 		}else if(a.equals("readgrouppu") || a.equals("rgpu")){
1239 			SamLine.READGROUP_PU=b;
1240 		}else if(a.equals("readgroupsm") || a.equals("rgsm")){
1241 			SamLine.READGROUP_SM=b;
1242 		}else{
1243 			return false;
1244 		}
1245 		return true;
1246 	}
1247 
1248 	/** Fix Readgroup Strings */
postparseReadgroup(String fname)1249 	public static void postparseReadgroup(String fname){
1250 		if(fname==null){return;}
1251 		fname=ReadWrite.stripToCore(fname);
1252 		if("filename".equalsIgnoreCase(SamLine.READGROUP_ID)){
1253 			SamLine.READGROUP_ID=fname;
1254 			if(fname!=null){SamLine.READGROUP_TAG="RG:Z:"+fname;}
1255 		}
1256 		if("filename".equalsIgnoreCase(SamLine.READGROUP_CN)){
1257 			SamLine.READGROUP_CN=fname;
1258 		}
1259 		if("filename".equalsIgnoreCase(SamLine.READGROUP_DS)){
1260 			SamLine.READGROUP_DS=fname;
1261 		}
1262 		if("filename".equalsIgnoreCase(SamLine.READGROUP_DT)){
1263 			SamLine.READGROUP_DT=fname;
1264 		}
1265 		if("filename".equalsIgnoreCase(SamLine.READGROUP_FO)){
1266 			SamLine.READGROUP_FO=fname;
1267 		}
1268 		if("filename".equalsIgnoreCase(SamLine.READGROUP_KS)){
1269 			SamLine.READGROUP_KS=fname;
1270 		}
1271 		if("filename".equalsIgnoreCase(SamLine.READGROUP_LB)){
1272 			SamLine.READGROUP_LB=fname;
1273 		}
1274 		if("filename".equalsIgnoreCase(SamLine.READGROUP_PG)){
1275 			SamLine.READGROUP_PG=fname;
1276 		}
1277 		if("filename".equalsIgnoreCase(SamLine.READGROUP_PI)){
1278 			SamLine.READGROUP_PI=fname;
1279 		}
1280 		if("filename".equalsIgnoreCase(SamLine.READGROUP_PL)){
1281 			SamLine.READGROUP_PL=fname;
1282 		}
1283 		if("filename".equalsIgnoreCase(SamLine.READGROUP_PU)){
1284 			SamLine.READGROUP_PU=fname;
1285 		}
1286 		if("filename".equalsIgnoreCase(SamLine.READGROUP_SM)){
1287 			SamLine.READGROUP_SM=fname;
1288 		}
1289 	}
1290 
1291 
1292 	/*--------------------------------------------------------------*/
1293 	/*----------------            Fields            ----------------*/
1294 	/*--------------------------------------------------------------*/
1295 
trimE()1296 	public float trimE(){
1297 		return (float)QualityTools.phredToProbError(trimq);
1298 	}
1299 
trimE2()1300 	public float[] trimE2(){
1301 		return QualityTools.phredToProbError(trimq2==null ? new float[] {trimq} : trimq2);
1302 	}
1303 
1304 	public boolean loglog=false;
1305 	public boolean loglogOut=false;
1306 	public int loglogbuckets=2048;//1999
1307 	public int loglogbits=8;
1308 	public int loglogk=31;
1309 	public long loglogseed=-1;
1310 	public float loglogMinprob=0;
1311 	public IntList loglogKlist=new IntList();
1312 
1313 	public boolean recalibrateQuality=false;
1314 
1315 	public int forceTrimModulo=-1;
1316 	public int forceTrimLeft=-1;
1317 	public int forceTrimRight=-1;
1318 	public int forceTrimRight2=-1;
1319 	public int build=1;
1320 
1321 	public long maxReads=-1;
1322 	public float samplerate=1f;
1323 	public long sampleseed=-1;
1324 
1325 	public boolean qtrimLeft=false;
1326 	public boolean qtrimRight=false;
1327 	public boolean trimClip=false;
1328 	public int trimPolyA=0;
1329 
1330 	public int trimPolyGLeft=0;
1331 	public int trimPolyGRight=0;
1332 	public int filterPolyG=0;
1333 
1334 	public int trimPolyCLeft=0;
1335 	public int trimPolyCRight=0;
1336 	public int filterPolyC=0;
1337 
1338 	public boolean qtrim1=false;
1339 	public boolean qtrim2=false;
1340 
1341 	public float trimq=6;
1342 	public float[] trimq2=null;
1343 	public float minAvgQuality=0;
1344 	public byte minBaseQuality=0;
1345 	public int minAvgQualityBases=0;
1346 	public int maxNs=-1;
1347 	public int minConsecutiveBases=0;
1348 	public int minReadLength=0;
1349 	public int maxReadLength=-1;
1350 	public int minTrimLength=-1;
1351 	public float minLenFraction=0;
1352 	public float minGC=0;
1353 	public float maxGC=1;
1354 	public boolean usePairGC=true;
1355 //	public boolean filterGC=false;
1356 	public boolean untrim=false;
1357 	public boolean tossJunk=false;
1358 
1359 	public float minIdFilter=-1;
1360 	public float maxIdFilter=999999999;
1361 	public int subfilter=-1;
1362 	public int clipfilter=-1;
1363 	public int delfilter=-1;
1364 	public int insfilter=-1;
1365 	public int indelfilter=-1;
1366 	public int dellenfilter=-1;
1367 	public int inslenfilter=-1;
1368 	public int editfilter=-1;
1369 	public int nfilter=-1;
1370 
1371 	public int breakLength=0;
1372 	/** Toss pair only if both reads are shorter than limit */
1373 	public boolean requireBothBad=false;
1374 	public boolean trimBadSequence=false;
1375 	public boolean chastityFilter=false;
1376 	public boolean removeBadBarcodes=false;
1377 	public boolean failBadBarcodes=false;
1378 	public boolean failIfNoBarcode=false;
1379 
1380 	public HashSet<String> barcodes=null;
1381 
1382 	/** Permission to overwrite existing files */
1383 	public boolean overwrite=false;
1384 
1385 	/** Permission to append to existing files */
1386 	public boolean append=false;
1387 	public boolean testsize=false;
1388 
1389 	/** Whether input file interleaving was explicitly set */
1390 	public boolean setInterleaved=false;
1391 
1392 	public String in1=null;
1393 	public String in2=null;
1394 
1395 	public String qfin1=null;
1396 	public String qfin2=null;
1397 
1398 	public String out1=null;
1399 	public String out2=null;
1400 	public String outsingle=null;
1401 	public boolean setOut=false;
1402 
1403 	public String qfout1=null;
1404 	public String qfout2=null;
1405 
1406 	public String extin=null;
1407 	public String extout=null;
1408 
1409 	/*--------------------------------------------------------------*/
1410 	/*----------------        Static Fields         ----------------*/
1411 	/*--------------------------------------------------------------*/
1412 
1413 	public static String loglogType="LogLog2";
1414 	public static boolean silent=false;
1415 
1416 	private static boolean setTrimRname=false;
1417 	private static byte qin=-1;
1418 	private static byte qout=-1;
1419 	private static boolean parsedQuality=false;
1420 
processQuality()1421 	public static void processQuality(){
1422 //		assert(parsedQuality);
1423 		if(!parsedQuality){return;}
1424 		if(qin!=-1 && qout!=-1){
1425 			FASTQ.ASCII_OFFSET=qin;
1426 			FASTQ.ASCII_OFFSET_OUT=qout;
1427 			FASTQ.DETECT_QUALITY=false;
1428 		}else if(qin!=-1){
1429 			FASTQ.ASCII_OFFSET=qin;
1430 			FASTQ.DETECT_QUALITY=false;
1431 		}else if(qout!=-1){
1432 			FASTQ.ASCII_OFFSET_OUT=qout;
1433 			FASTQ.DETECT_QUALITY_OUT=false;
1434 		}
1435 	}
1436 
validateStdio(FileFormat... ffa)1437 	public boolean validateStdio(FileFormat... ffa) {
1438 		boolean b=true;
1439 		for(FileFormat ff:ffa){
1440 			b=validateStdio(ff)&b;
1441 		}
1442 		return b;
1443 	}
1444 
validateStdio(FileFormat ff)1445 	public boolean validateStdio(FileFormat ff) {
1446 		if(ff==null || !ff.stdio()){return true;}
1447 		if(ff.fastq() && ff.stdin()){
1448 			assert(setInterleaved) : "\nERROR: When piping fastq data from stdin, interleaving must be explicitly stated\n"
1449 					+ "with the flag int=f for unpaired data or int=t for paired data.\n";
1450 		}
1451 		final int ext=ff.rawExtensionCode();
1452 		if(ff.stdout() && ext==FileFormat.UNKNOWN){
1453 			assert(false) : "\nERROR: When piping reads to stdout, the output format must be specified with an extension,\n"
1454 					+ "such as stdout.fq or stdout.sam.gz.\n";
1455 		}
1456 		if(ff.stdin() && ext==FileFormat.UNKNOWN){
1457 			assert(false) : "\nERROR: When piping reads from stdin, the input format should be specified with an extension,\n"
1458 					+ "such as stdin.fq or stdin.sam.gz.\n";
1459 		}
1460 		return true;
1461 	}
1462 
1463 }
1464