<key>=<value> tagging support for command-line arguments. Unfortunately, still

very hard to validate and still very hard to use (requires core hacking to 
support additional tags).


git-svn-id: file:///humgen/gsa-scr1/gsa-engineering/svn_contents/trunk@5038 348d0f76-0448-11de-a6fe-93d51630548a
This commit is contained in:
hanna 2011-01-21 00:22:42 +00:00
parent fc73569d62
commit aea121a9d5
12 changed files with 220 additions and 82 deletions

View File

@ -51,7 +51,7 @@ public class ArgumentMatch implements Iterable<ArgumentMatch> {
/**
* An ordered, freeform collection of tags.
*/
public final List<String> tags;
public final Tags tags;
/**
* Create a new argument match, defining its properties later. Used to create invalid arguments.
@ -65,10 +65,10 @@ public class ArgumentMatch implements Iterable<ArgumentMatch> {
* @param label Label of the argument match. Must not be null.
* @param definition The associated definition, if one exists. May be null.
*/
private ArgumentMatch(String label,ArgumentDefinition definition) {
private ArgumentMatch(final String label, final ArgumentDefinition definition) {
this.label = label;
this.definition = definition;
this.tags = Collections.emptyList();
this.tags = new Tags();
}
/**
@ -78,7 +78,7 @@ public class ArgumentMatch implements Iterable<ArgumentMatch> {
* @param index Position of the argument. Must not be null.
* @param tags ordered freeform text tags associated with this argument.
*/
public ArgumentMatch( String label, ArgumentDefinition definition, int index, List<String> tags ) {
public ArgumentMatch(final String label, final ArgumentDefinition definition, final int index, final Tags tags) {
this( label, definition, index, null, tags );
}
@ -90,7 +90,7 @@ public class ArgumentMatch implements Iterable<ArgumentMatch> {
* @param value Value for the argument at this position.
* @param tags ordered freeform text tags associated with this argument.
*/
private ArgumentMatch( String label, ArgumentDefinition definition, int index, String value, List<String> tags ) {
private ArgumentMatch(final String label, final ArgumentDefinition definition, final int index, final String value, final Tags tags) {
this.label = label;
this.definition = definition;
@ -102,6 +102,26 @@ public class ArgumentMatch implements Iterable<ArgumentMatch> {
this.tags = tags;
}
/**
* Check to see whether two ArgumentMatch objects are equal.
* @param other Object to which this should be compared.
* @return True if objects are equal, false if objects are not equal or incomparable.
*/
@Override
public boolean equals(Object other) {
// this clearly isn't null, since this.equals() when this == null would result in an NPE.
if(other == null)
return false;
if(!(other instanceof ArgumentMatch))
return false;
ArgumentMatch otherArgumentMatch = (ArgumentMatch)other;
return this.definition.equals(otherArgumentMatch.definition) &&
this.label.equals(otherArgumentMatch.label) &&
this.indices.equals(otherArgumentMatch.indices) &&
this.tags.equals(otherArgumentMatch.tags);
}
/**
* Reformat the given entries with the given multiplexer and key.
* TODO: Generify this.

View File

@ -213,10 +213,12 @@ public abstract class ArgumentTypeDescriptor {
* @param matches The matches for the given argument.
* @return The value of the argument if available, or null if not present.
*/
protected List<String> getArgumentTags(ArgumentMatches matches) {
List<String> tags = new ArrayList<String>();
for( ArgumentMatch match: matches ) {
tags.addAll(match.tags);
protected Tags getArgumentTags(ArgumentMatches matches) {
Tags tags = new Tags();
for(ArgumentMatch match: matches) {
if(!tags.isEmpty() && !match.tags.isEmpty())
throw new ReviewedStingException("BUG: multiple conflicting sets of tags are available, and the type descriptor specifies no way of resolving the conflict.");
tags = match.tags;
}
return tags;
}
@ -303,7 +305,7 @@ class SimpleArgumentTypeDescriptor extends ArgumentTypeDescriptor {
ArgumentDefinition defaultDefinition = createDefaultArgumentDefinition(source);
String value = getArgumentValue( defaultDefinition, matches );
Object result;
List<String> tags = getArgumentTags( matches );
Tags tags = getArgumentTags(matches);
// lets go through the types we support
try {
@ -383,7 +385,7 @@ class CompoundArgumentTypeDescriptor extends ArgumentTypeDescriptor {
public Object parse(ParsingEngine parsingEngine,ArgumentSource source, Class type, ArgumentMatches matches) {
Class componentType;
Object result;
List<String> tags = new ArrayList<String>();
Tags tags;
if( Collection.class.isAssignableFrom(type) ) {
@ -414,8 +416,10 @@ class CompoundArgumentTypeDescriptor extends ArgumentTypeDescriptor {
for( ArgumentMatch match: matches ) {
for( ArgumentMatch value: match ) {
collection.add( componentArgumentParser.parse(parsingEngine,source,componentType,new ArgumentMatches(value)) );
tags.addAll(value.tags);
Object object = componentArgumentParser.parse(parsingEngine,source,componentType,new ArgumentMatches(value));
collection.add( object );
// WARNING: Side effect!
parsingEngine.addTags(object,value.tags);
}
}
@ -436,16 +440,15 @@ class CompoundArgumentTypeDescriptor extends ArgumentTypeDescriptor {
int i = 0;
for( ArgumentMatch value: values ) {
Array.set( result,i++,componentArgumentParser.parse(parsingEngine,source,componentType,new ArgumentMatches(value)));
tags.addAll(value.tags);
Object object = componentArgumentParser.parse(parsingEngine,source,componentType,new ArgumentMatches(value));
Array.set(result,i++,object);
// WARNING: Side effect!
parsingEngine.addTags(object,value.tags);
}
}
else
throw new ReviewedStingException("Unsupported compound argument type: " + type);
// WARNING: Side effect!
parsingEngine.addTags(result,tags);
return result;
}

View File

@ -72,7 +72,7 @@ public class ParsingEngine {
/**
* List of tags associated with the given instantiation of the command-line argument.
*/
private final Map<Object,List<String>> tags = new IdentityHashMap<Object,List<String>>();
private final Map<Object,Tags> tags = new IdentityHashMap<Object,Tags>();
/**
* our log, which we want to capture anything from org.broadinstitute.sting
@ -291,7 +291,7 @@ public class ParsingEngine {
* @param key The key created.
* @param tags List of tags, or empty list if no tags are present.
*/
public void addTags(Object key, List<String> tags) {
public void addTags(Object key, final Tags tags) {
this.tags.put(key,tags);
}
@ -300,9 +300,9 @@ public class ParsingEngine {
* @param key Key for which to find a tag.
* @return List of tags associated with this key.
*/
public List<String> getTags(Object key) {
public Tags getTags(Object key) {
if(!tags.containsKey(key))
return Collections.emptyList();
return new Tags();
return tags.get(key);
}

View File

@ -80,16 +80,31 @@ public abstract class ParsingMethod {
String argument = matcher.group(1).trim();
List<String> tags = new ArrayList<String>();
if(matcher.group(2) != null)
tags.addAll(Utils.split(matcher.group(2),","));
Tags tags = new Tags();
if(matcher.group(2) != null) {
for(String tag: Utils.split(matcher.group(2),",")) {
// Check for presence of an '=' sign, indicating a key-value pair in the tag line.
int equalDelimiterPos = tag.indexOf('=');
if(equalDelimiterPos >= 0) {
// Sanity check; ensure that there aren't multiple '=' in this key-value pair.
if(tag.indexOf('=',equalDelimiterPos+1) >= 0)
throw new ArgumentException(String.format("Tag %s passed to argument %s is malformed. Please ensure that " +
"key-value tags are of the form <key>=<value>, and neither key " +
"nor value contain the '=' character", tag, argument));
tags.addKeyValueTag(tag.substring(0,equalDelimiterPos),tag.substring(equalDelimiterPos+1));
}
else
tags.addPositionalTag(tag);
}
}
// Find the most appropriate argument definition for the given argument.
ArgumentDefinition argumentDefinition = definitions.findArgumentDefinition( argument, definitionMatcher );
// Try to find a matching argument. If found, label that as the match. If not found, add the argument
// with a null definition.
ArgumentMatch argumentMatch = new ArgumentMatch( argument, argumentDefinition, position, tags );
ArgumentMatch argumentMatch = new ArgumentMatch(argument,argumentDefinition,position,tags);
return argumentMatch;
}
@ -102,7 +117,7 @@ public abstract class ParsingMethod {
/**
* Tags, on the other hand, can start with any word character.
*/
private static final String TAG_TEXT = "[\\w\\-\\.]*";
private static final String TAG_TEXT = "[\\w\\-\\.\\=]*";
public static ParsingMethod FullNameParsingMethod = new ParsingMethod(Pattern.compile(String.format("\\s*--(%1$s)(?:\\:(%2$s(?:,%2$s)*))?\\s*",ARGUMENT_TEXT,TAG_TEXT)),
ArgumentDefinitions.FullNameDefinitionMatcher) {};

View File

@ -0,0 +1,102 @@
/*
* Copyright (c) 2011, The Broad Institute
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
package org.broadinstitute.sting.commandline;
import java.util.*;
/**
* Models the tags that can appear after command-line arguments
* in the GATK.
*/
public class Tags {
/**
* Storage for the ordered, unkeyed, positional tags.
*/
private final List<String> positionalTags = new ArrayList<String>();
/**
* Storage for key-value tags of the form <key>=<value>
*/
private Map<String,String> keyValueTags = new HashMap<String,String>();
/**
* Tests to see whether two tag sets are equal.
* @param other Other object to test for equality.
* @return True if objects are the same. False if objects differ.
*/
@Override
public boolean equals(Object other) {
if(other == null)
return false;
if(!(other instanceof Tags))
return false;
Tags otherTags = (Tags)other;
return this.positionalTags.equals(otherTags.positionalTags) && this.keyValueTags.equals(otherTags.keyValueTags);
}
/**
* Returns whether any tags are specified on the command-line for this operation.
* @return True if the tags are empty; false otherwise.
*/
public boolean isEmpty() {
return positionalTags.isEmpty() && keyValueTags.isEmpty();
}
/**
* Retrieves the list of all positional tags associated with this argument.
* @return A list of positional tags.
*/
public List<String> getPositionalTags() {
return Collections.unmodifiableList(positionalTags);
}
/**
* Gets the value associated with a given <key>=<value> argument tag.
* @param key The key for which to retrieve the value.
* @return The value paired with the given key, or null if no such element exists.
*/
public String getValue(final String key) {
return keyValueTags.get(key);
}
/**
* Adds positional tag(s) to the tag object.
* @param tags The tag strings to add.
*/
protected void addPositionalTag(final String... tags) {
positionalTags.addAll(Arrays.asList(tags));
}
/**
* Adds a <key>-<value> tag to this tag library.
* @param key key tag to add.
* @param value value to associate with this key.
*/
protected void addKeyValueTag(final String key, final String value) {
keyValueTags.put(key,value);
}
}

View File

@ -25,6 +25,7 @@
package org.broadinstitute.sting.gatk;
import org.broadinstitute.sting.commandline.Tags;
import org.broadinstitute.sting.gatk.arguments.GATKArgumentCollection;
import org.broadinstitute.sting.commandline.CommandLineProgram;
import org.broadinstitute.sting.commandline.ArgumentTypeDescriptor;
@ -206,7 +207,7 @@ public abstract class CommandLineExecutable extends CommandLineProgram {
private List<SAMReaderID> unpackBAMFileList(GATKArgumentCollection argCollection) {
List<SAMReaderID> unpackedReads = new ArrayList<SAMReaderID>();
for( String inputFileName: argCollection.samFiles ) {
List<String> inputFileNameTags = parser.getTags(inputFileName);
Tags inputFileNameTags = parser.getTags(inputFileName);
inputFileName = expandFileName(inputFileName);
if (inputFileName.toLowerCase().endsWith(".list") ) {
try {
@ -239,27 +240,28 @@ public abstract class CommandLineExecutable extends CommandLineProgram {
private Collection<RMDTriplet> unpackRODBindings(GATKArgumentCollection argCollection) {
Collection<RMDTriplet> rodBindings = new ArrayList<RMDTriplet>();
for (String fileName: argCollection.RODBindings) {
List<String> parameters = parser.getTags(fileName);
Tags tags = parser.getTags(fileName);
fileName = expandFileName(fileName);
RMDStorageType storageType = null;
if(argCollection.rodInputType != null)
storageType = argCollection.rodInputType;
else if(fileName.toLowerCase().endsWith("stdin"))
storageType = RMDStorageType.STREAM;
else
storageType = RMDStorageType.FILE;
if(parameters.size() != 2)
List<String> positionalTags = tags.getPositionalTags();
if(positionalTags.size() != 2)
throw new UserException("Invalid syntax for -B (reference-ordered data) input flag. " +
"Please use the following syntax when providing reference-ordered " +
"data: -B:<name>,<type> <filename>.");
// Assume that if tags are present, those tags are name and type.
// Name is always first, followed by type.
String name = parameters.get(0);
String type = parameters.get(1);
String name = positionalTags.get(0);
String type = positionalTags.get(1);
RMDStorageType storageType = null;
if(tags.getValue("storage") != null)
storageType = Enum.valueOf(RMDStorageType.class,tags.getValue("storage"));
else if(fileName.toLowerCase().endsWith("stdin"))
storageType = RMDStorageType.STREAM;
else
storageType = RMDStorageType.FILE;
rodBindings.add(new RMDTriplet(name,type,fileName,storageType));
}

View File

@ -212,11 +212,6 @@ public class GATKArgumentCollection {
@Input(fullName = "read_group_black_list", shortName="rgbl", doc="Filters out read groups matching <TAG>:<STRING> or a .txt file containing the filter strings one per line.", required = false)
public List<String> readGroupBlackList = null;
@Element(required=false)
@Argument(fullName="rod_input_type",shortName="rit",doc="Indicates whether to use a file approach or a streaming approach to loading ROD data",required=false)
@Hidden
public RMDTriplet.RMDStorageType rodInputType = null;
@Element(required=false)
@Argument(fullName="processingTracker",shortName="C",doc="A lockable, shared file for coordinating distributed GATK runs",required=false)
@Hidden
@ -392,9 +387,6 @@ public class GATKArgumentCollection {
(other.processingTrackerFile != null && !other.processingTrackerFile.equals(this.processingTrackerFile)))
return false;
if(rodInputType != other.rodInputType)
return false;
if ( restartProcessingTracker != other.restartProcessingTracker )
return false;

View File

@ -1,5 +1,7 @@
package org.broadinstitute.sting.gatk.datasources.simpleDataSources;
import org.broadinstitute.sting.commandline.Tags;
import java.io.File;
import java.util.List;
import java.util.Collections;
@ -20,14 +22,14 @@ public class SAMReaderID {
/**
* A list of tags associated with this BAM file.
*/
protected final List<String> tags;
protected final Tags tags;
/**
* Creates an identifier for a SAM file based on read.
* @param samFile The source file for SAM data.
* @param tags tags to use when creating a reader ID.
*/
public SAMReaderID(File samFile, List<String> tags) {
public SAMReaderID(File samFile, Tags tags) {
this.samFile = samFile;
this.tags = tags;
}
@ -37,7 +39,7 @@ public class SAMReaderID {
* @param samFileName The source filename for SAM data.
* @param tags tags to use when creating a reader ID.
*/
public SAMReaderID(String samFileName, List<String> tags) {
public SAMReaderID(String samFileName, Tags tags) {
this(new File(samFileName),tags);
}
@ -45,8 +47,8 @@ public class SAMReaderID {
* Gets the tags associated with the given BAM file.
* @return A collection of the tags associated with this file.
*/
public List<String> getTags() {
return Collections.unmodifiableList(tags);
public Tags getTags() {
return tags;
}
/**

View File

@ -30,6 +30,7 @@ import org.broad.tribble.util.variantcontext.Allele;
import org.broad.tribble.util.variantcontext.VariantContext;
import org.broad.tribble.util.variantcontext.Genotype;
import org.broad.tribble.vcf.*;
import org.broadinstitute.sting.commandline.Tags;
import org.broadinstitute.sting.gatk.filters.*;
import org.broadinstitute.sting.gatk.refdata.*;
import org.broadinstitute.sting.gatk.refdata.features.refseq.RefSeqCodec;
@ -272,13 +273,13 @@ public class IndelGenotyperV2Walker extends ReadWalker<Integer,Integer> {
int nNorm = 0;
int nTum = 0;
for ( SAMReaderID rid : getToolkit().getReadsDataSource().getReaderIDs() ) {
List<String> tags = rid.getTags() ;
if ( tags.isEmpty() && call_somatic )
Tags tags = rid.getTags() ;
if ( tags.getPositionalTags().isEmpty() && call_somatic )
throw new UserException.BadInput("In somatic mode all input bam files must be tagged as either 'normal' or 'tumor'. Untagged file: "+
getToolkit().getSourceFileForReaderID(rid));
boolean normal = false;
boolean tumor = false;
for ( String s : tags ) { // we allow additional unrelated tags (and we do not use them), but we REQUIRE one of Tumor/Normal to be present if --somatic is on
for ( String s : tags.getPositionalTags() ) { // we allow additional unrelated tags (and we do not use them), but we REQUIRE one of Tumor/Normal to be present if --somatic is on
if ( "NORMAL".equals(s.toUpperCase()) ) {
normal = true;
nNorm++;
@ -469,9 +470,9 @@ public class IndelGenotyperV2Walker extends ReadWalker<Integer,Integer> {
if ( call_somatic ) {
List<String> tags = getToolkit().getReaderIDForRead(read).getTags();
Tags tags = getToolkit().getReaderIDForRead(read).getTags();
boolean assigned = false;
for ( String s : tags ) {
for ( String s : tags.getPositionalTags() ) {
if ( "NORMAL".equals(s.toUpperCase()) ) {
normal_context.add(read,ref.getBases());
assigned = true;

View File

@ -4,6 +4,7 @@ import static org.testng.Assert.fail;
import net.sf.picard.reference.IndexedFastaSequenceFile;
import net.sf.samtools.SAMRecord;
import org.broadinstitute.sting.BaseTest;
import org.broadinstitute.sting.commandline.Tags;
import org.broadinstitute.sting.gatk.datasources.shards.Shard;
import org.broadinstitute.sting.gatk.datasources.shards.ShardStrategy;
import org.broadinstitute.sting.gatk.datasources.shards.ShardStrategyFactory;
@ -87,7 +88,7 @@ public class SAMBAMDataSourceUnitTest extends BaseTest {
logger.warn("Executing testLinearBreakIterateAll");
// setup the data
readers.add(new SAMReaderID(new File(validationDataLocation+"/NA12878.chrom6.SLX.SRP000032.2009_06.selected.bam"),Collections.<String>emptyList()));
readers.add(new SAMReaderID(new File(validationDataLocation+"/NA12878.chrom6.SLX.SRP000032.2009_06.selected.bam"),new Tags()));
// the sharding strat.
SAMDataSource data = new SAMDataSource(readers,genomeLocParser);
@ -131,7 +132,7 @@ public class SAMBAMDataSourceUnitTest extends BaseTest {
logger.warn("Executing testMergingTwoBAMFiles");
// setup the test files
readers.add(new SAMReaderID(new File(validationDataLocation + "/NA12878.chrom6.SLX.SRP000032.2009_06.selected.bam"),Collections.<String>emptyList()));
readers.add(new SAMReaderID(new File(validationDataLocation + "/NA12878.chrom6.SLX.SRP000032.2009_06.selected.bam"),new Tags()));
// the sharding strat.
SAMDataSource data = new SAMDataSource(readers,genomeLocParser);
@ -171,8 +172,8 @@ public class SAMBAMDataSourceUnitTest extends BaseTest {
// setup the data and the counter before our second run
readers.clear();
readers.add(new SAMReaderID(new File(validationDataLocation + "/NA12878.chrom6.SLX.SRP000032.2009_06.selected.bam"),Collections.<String>emptyList()));
readers.add(new SAMReaderID(new File(validationDataLocation + "/NA12878.chrom6.SLX.SRP000032.2009_06.selected.bam"),Collections.<String>emptyList()));
readers.add(new SAMReaderID(new File(validationDataLocation + "/NA12878.chrom6.SLX.SRP000032.2009_06.selected.bam"),new Tags()));
readers.add(new SAMReaderID(new File(validationDataLocation + "/NA12878.chrom6.SLX.SRP000032.2009_06.selected.bam"),new Tags()));
count = 0;
// the sharding strat.

View File

@ -3,6 +3,7 @@ package org.broadinstitute.sting.gatk.traversals;
import net.sf.picard.reference.ReferenceSequenceFile;
import net.sf.picard.reference.IndexedFastaSequenceFile;
import org.broadinstitute.sting.BaseTest;
import org.broadinstitute.sting.commandline.Tags;
import org.broadinstitute.sting.gatk.GenomeAnalysisEngine;
import org.broadinstitute.sting.gatk.ReadMetrics;
import org.broadinstitute.sting.gatk.datasources.providers.ShardDataProvider;
@ -61,7 +62,7 @@ import java.util.Collections;
public class TraverseReadsUnitTest extends BaseTest {
private ReferenceSequenceFile seq;
private SAMReaderID bam = new SAMReaderID(new File(validationDataLocation + "index_test.bam"),Collections.<String>emptyList()); // TCGA-06-0188.aligned.duplicates_marked.bam");
private SAMReaderID bam = new SAMReaderID(new File(validationDataLocation + "index_test.bam"),new Tags()); // TCGA-06-0188.aligned.duplicates_marked.bam");
private File refFile = new File(validationDataLocation + "Homo_sapiens_assembly17.fasta");
private List<SAMReaderID> bamList;
private Walker countReadWalker;

View File

@ -54,11 +54,11 @@ public class VCFStreamingIntegrationTest extends WalkerTest {
inputStream.close();
WalkerTestSpec spec = new WalkerTestSpec(
"-T SelectVariants " +
"-R " + b36KGReference + " " +
"-B:variant,vcf " + tmpFifo.getAbsolutePath() + " " +
"-rit STREAM --NO_HEADER " +
"-o %s",
"-T SelectVariants" +
" -R " + b36KGReference +
" -B:variant,vcf,storage=STREAM " + tmpFifo.getAbsolutePath() +
" --NO_HEADER" +
" -o %s",
1,
Arrays.asList("2cae3d16f9ed00b07d87e9c49272d877")
);
@ -78,12 +78,12 @@ public class VCFStreamingIntegrationTest extends WalkerTest {
// Output select to FIFO
WalkerTestSpec selectTestSpec = new WalkerTestSpec(
"-T SelectVariants " +
"-R " + b36KGReference + " " +
"-B:variant,vcf " + testFile + " " +
"--NO_HEADER " +
"-select 'QD > 2.0' " +
"-o " + tmpFifo.getAbsolutePath(),
"-T SelectVariants" +
" -R " + b36KGReference +
" -B:variant,vcf,storage=STREAM " + testFile +
" --NO_HEADER" +
" -select 'QD > 2.0'" +
" -o " + tmpFifo.getAbsolutePath(),
0,
Collections.<String>emptyList()
);
@ -91,13 +91,12 @@ public class VCFStreamingIntegrationTest extends WalkerTest {
// Eval compare the full set to the subselection.
selectTestSpec = new WalkerTestSpec(
"-T VariantEval " +
"-R " + b36KGReference + " " +
"-B:eval,vcf " + testFile + " " +
"-B:comp,vcf " + tmpFifo.getAbsolutePath() + " " +
"-E CompOverlap -noStandard " +
"-rit STREAM " +
"-reportType CSV -o %s",
"-T VariantEval" +
" -R " + b36KGReference +
" -B:eval,vcf " + testFile +
" -B:comp,vcf,storage=STREAM " + tmpFifo.getAbsolutePath() +
" -E CompOverlap -noStandard" +
" -reportType CSV -o %s",
1,
Arrays.asList("f7df3ac0777b1a45aa7a58228a290600")
);