diff --git a/java/src/org/broadinstitute/sting/commandline/CommandLineUtils.java b/java/src/org/broadinstitute/sting/commandline/CommandLineUtils.java index 9048cd200..417c5d0e7 100644 --- a/java/src/org/broadinstitute/sting/commandline/CommandLineUtils.java +++ b/java/src/org/broadinstitute/sting/commandline/CommandLineUtils.java @@ -48,7 +48,7 @@ public class CommandLineUtils { * @return A key-value mapping of argument full names to argument values. Produces best string representation * possible given the information available. */ - public static Map getApproximateCommandLineArguments(Collection argumentProviders) { + public static Map getApproximateCommandLineArguments(Object... argumentProviders) { Map commandLineArguments = new LinkedHashMap(); for(Object argumentProvider: argumentProviders) { @@ -67,47 +67,23 @@ public class CommandLineUtils { return commandLineArguments; } -// public static Map getApproximateCommandLineArguments(Collection argumentProviders) { -// Map commandLineArguments = new LinkedHashMap(); -// -// for(Object argumentProvider: argumentProviders) { -// Map argBings = ParsingEngine.extractArgumentBindings(argumentProvider); -// List argumentSources = ParsingEngine.extractArgumentSources(argumentProvider.getClass()); -// for(ArgumentSource argumentSource: argumentSources) { -// Object argumentValue = JVMUtils.getFieldValue(argumentSource.field,argumentProvider); -// String argumentValueString = argumentValue != null ? argumentValue.toString() : null; -// -// for(ArgumentDefinition definition: argumentSource.createArgumentDefinitions()) { -// String argumentName = definition.fullName; -// commandLineArguments.put(argumentName,argumentValueString); -// } -// } -// } -// -// return commandLineArguments; -// } - - public static String createApproximateCommandLineArgumentString(GenomeAnalysisEngine toolkit, Walker walker) { - return createApproximateCommandLineArgumentString(toolkit, null, walker); - } - - public static String createApproximateCommandLineArgumentString(GenomeAnalysisEngine toolkit, Collection otherArgumentProviders, Walker walker) { + /** + * Create an approximate list of command-line arguments based on the given argument providers. + * @param argumentProviders Argument providers to inspect. + * @return A string representing the given command-line arguments. + */ + public static String createApproximateCommandLineArgumentString(Object... argumentProviders) { + Map commandLineArgs = getApproximateCommandLineArguments(argumentProviders); StringBuffer sb = new StringBuffer(); - sb.append("analysis_type="); - sb.append(toolkit.getWalkerName(walker.getClass())); - - ArrayList allArgumentProviders = new ArrayList(); - allArgumentProviders.add(toolkit.getArguments()); - allArgumentProviders.add(walker); - if (otherArgumentProviders != null) allArgumentProviders.addAll(otherArgumentProviders); - - Map commandLineArgs = getApproximateCommandLineArguments(allArgumentProviders); + boolean first = true; for ( Map.Entry commandLineArg : commandLineArgs.entrySet() ) { - sb.append(" "); + if(!first) + sb.append(" "); sb.append(commandLineArg.getKey()); sb.append("="); sb.append(commandLineArg.getValue()); + first = false; } return sb.toString(); diff --git a/java/src/org/broadinstitute/sting/commandline/ParsingEngine.java b/java/src/org/broadinstitute/sting/commandline/ParsingEngine.java index 261197ec8..05088f186 100755 --- a/java/src/org/broadinstitute/sting/commandline/ParsingEngine.java +++ b/java/src/org/broadinstitute/sting/commandline/ParsingEngine.java @@ -368,23 +368,6 @@ public class ParsingEngine { return new ArrayList(bindings.keySet()); } -// List argumentSources = new ArrayList(); -// while( sourceClass != null ) { -// Field[] fields = sourceClass.getDeclaredFields(); -// for( Field field: fields ) { -// if( ArgumentTypeDescriptor.isArgumentAnnotationPresent(field) ) -// argumentSources.add( new ArgumentSource(parentFields, field) ); -// if( field.isAnnotationPresent(ArgumentCollection.class) ) { -// Field[] newParentFields = Arrays.copyOf(parentFields, parentFields.length + 1); -// newParentFields[parentFields.length] = field; -// argumentSources.addAll( extractArgumentSources(field.getType(), newParentFields) ); -// } -// } -// sourceClass = sourceClass.getSuperclass(); -// } -// return argumentSources; -// } - public static Map extractArgumentBindings(Object obj) { if ( obj == null ) throw new IllegalArgumentException("Incoming object cannot be null"); return extractArgumentBindings(obj, obj.getClass(), new Field[0]); diff --git a/java/src/org/broadinstitute/sting/gatk/CommandLineExecutable.java b/java/src/org/broadinstitute/sting/gatk/CommandLineExecutable.java index 81555540f..4a64d16b5 100644 --- a/java/src/org/broadinstitute/sting/gatk/CommandLineExecutable.java +++ b/java/src/org/broadinstitute/sting/gatk/CommandLineExecutable.java @@ -28,6 +28,10 @@ package org.broadinstitute.sting.gatk; import org.broadinstitute.sting.gatk.arguments.GATKArgumentCollection; import org.broadinstitute.sting.commandline.CommandLineProgram; import org.broadinstitute.sting.commandline.ArgumentTypeDescriptor; +import org.broadinstitute.sting.gatk.io.stubs.OutputStreamArgumentTypeDescriptor; +import org.broadinstitute.sting.gatk.io.stubs.SAMFileReaderArgumentTypeDescriptor; +import org.broadinstitute.sting.gatk.io.stubs.SAMFileWriterArgumentTypeDescriptor; +import org.broadinstitute.sting.gatk.io.stubs.VCFWriterArgumentTypeDescriptor; import org.broadinstitute.sting.gatk.phonehome.GATKRunReport; import org.broadinstitute.sting.gatk.walkers.Walker; @@ -39,15 +43,13 @@ import net.sf.picard.filter.SamRecordFilter; * @author aaron */ public abstract class CommandLineExecutable extends CommandLineProgram { - public Object GATKResult = null; - /** * The actual engine which performs the analysis. */ - protected GenomeAnalysisEngine GATKEngine = new GenomeAnalysisEngine(); + protected GenomeAnalysisEngine engine = new GenomeAnalysisEngine(); // get the analysis name - protected abstract String getAnalysisName(); + public abstract String getAnalysisName(); /** * Gets the GATK argument bundle. @@ -55,8 +57,10 @@ public abstract class CommandLineExecutable extends CommandLineProgram { */ protected abstract GATKArgumentCollection getArgumentCollection(); - // override select arguments - protected void overrideArguments() { } + /** + * A list of all the arguments initially used as sources. + */ + private final Collection argumentSources = new ArrayList(); /** * this is the function that the inheriting class can expect to have called @@ -65,21 +69,30 @@ public abstract class CommandLineExecutable extends CommandLineProgram { * @return the return code to exit the program with */ protected int execute() throws Exception { - Walker mWalker = GATKEngine.getWalkerByName(getAnalysisName()); + argumentSources.add(this); + + Walker walker = engine.getWalkerByName(getAnalysisName()); try { - Collection filters = GATKEngine.createFiltersForWalker(getArgumentCollection(),mWalker); + Collection filters = engine.createFiltersForWalker(getArgumentCollection(),walker); // load the arguments into the walker / filters. - loadArgumentsIntoObject(mWalker); - for (SamRecordFilter filter: filters) + // TODO: The fact that this extra load call exists here when all the parsing happens at the engine + // TODO: level indicates that we're doing something wrong. Turn this around so that the GATK can drive + // TODO: argument processing. + loadArgumentsIntoObject(walker); + argumentSources.add(walker); + + for (SamRecordFilter filter: filters) { loadArgumentsIntoObject(filter); + argumentSources.add(filter); + } // set the analysis name in the argument collection - GATKResult = GATKEngine.execute(getArgumentCollection(), mWalker, filters); - generateGATKRunReport(mWalker); + engine.execute(getArgumentCollection(), walker, filters); + generateGATKRunReport(walker); } catch ( Exception e ) { - generateGATKRunReport(mWalker, e); + generateGATKRunReport(walker, e); throw e; } @@ -94,9 +107,9 @@ public abstract class CommandLineExecutable extends CommandLineProgram { * * @param e the exception, can be null if no exception occurred */ - private void generateGATKRunReport(Walker mWalker, Exception e) { + private void generateGATKRunReport(Walker walker, Exception e) { if ( getArgumentCollection().phoneHomeType != GATKRunReport.PhoneHomeOption.NO_ET ) { - GATKRunReport report = new GATKRunReport(mWalker, e, GATKEngine, getArgumentCollection().phoneHomeType ); + GATKRunReport report = new GATKRunReport(walker, e, engine, getArgumentCollection().phoneHomeType ); if ( getArgumentCollection().phoneHomeType == GATKRunReport.PhoneHomeOption.STDOUT ) report.postReport(System.out); else @@ -108,10 +121,10 @@ public abstract class CommandLineExecutable extends CommandLineProgram { * Convenience method for fully parameterized generateGATKRunReport when an exception has * not occurred * - * @param mWalker + * @param walker */ - private void generateGATKRunReport(Walker mWalker) { - generateGATKRunReport(mWalker, null); + private void generateGATKRunReport(Walker walker) { + generateGATKRunReport(walker, null); } /** @@ -119,7 +132,10 @@ public abstract class CommandLineExecutable extends CommandLineProgram { * @return A collection of type descriptors generating implementation-dependent placeholders. */ protected Collection getArgumentTypeDescriptors() { - return GATKEngine.getArgumentTypeDescriptors(); + return Arrays.asList( new VCFWriterArgumentTypeDescriptor(engine,System.out,argumentSources), + new SAMFileReaderArgumentTypeDescriptor(engine), + new SAMFileWriterArgumentTypeDescriptor(engine,System.out), + new OutputStreamArgumentTypeDescriptor(engine,System.out) ); } /** @@ -143,10 +159,10 @@ public abstract class CommandLineExecutable extends CommandLineProgram { Collection argumentSources = new ArrayList(); - Walker walker = GATKEngine.getWalkerByName(getAnalysisName()); + Walker walker = engine.getWalkerByName(getAnalysisName()); argumentSources.add(walker.getClass()); - Collection filters = GATKEngine.createFiltersForWalker(getArgumentCollection(),walker); + Collection filters = engine.createFiltersForWalker(getArgumentCollection(),walker); for(SamRecordFilter filter: filters) argumentSources.add(filter.getClass()); @@ -156,7 +172,7 @@ public abstract class CommandLineExecutable extends CommandLineProgram { @Override protected String getArgumentSourceName( Class argumentSource ) { - return GATKEngine.getWalkerName((Class)argumentSource); + return engine.getWalkerName((Class)argumentSource); } /** @@ -166,6 +182,6 @@ public abstract class CommandLineExecutable extends CommandLineProgram { */ @Override protected void addTags(Object key, List tags) { - GATKEngine.addTags(key,tags); + engine.addTags(key,tags); } -} + } diff --git a/java/src/org/broadinstitute/sting/gatk/CommandLineGATK.java b/java/src/org/broadinstitute/sting/gatk/CommandLineGATK.java index f3973d236..6003112d4 100755 --- a/java/src/org/broadinstitute/sting/gatk/CommandLineGATK.java +++ b/java/src/org/broadinstitute/sting/gatk/CommandLineGATK.java @@ -66,7 +66,7 @@ public class CommandLineGATK extends CommandLineExecutable { } @Override - protected String getAnalysisName() { + public String getAnalysisName() { return analysisName; } @@ -132,7 +132,7 @@ public class CommandLineGATK extends CommandLineExecutable { String additionalHelp; // If no analysis name is present, fill in extra help on the walkers. - WalkerManager walkerManager = GATKEngine.getWalkerManager(); + WalkerManager walkerManager = engine.getWalkerManager(); String analysisName = getAnalysisName(); if(analysisName != null && walkerManager.exists(getAnalysisName())) additionalHelp = getWalkerHelp(walkerManager.getWalkerClassByName(getAnalysisName())); @@ -153,7 +153,7 @@ public class CommandLineGATK extends CommandLineExecutable { formatter.format("Description:%n"); - WalkerManager walkerManager = GATKEngine.getWalkerManager(); + WalkerManager walkerManager = engine.getWalkerManager(); String walkerHelpText = walkerManager.getWalkerDescriptionText(walkerType); printDescriptorLine(formatter,WALKER_INDENT,"",WALKER_INDENT,FIELD_SEPARATOR,walkerHelpText,TextFormattingUtils.DEFAULT_LINE_WIDTH); @@ -173,7 +173,7 @@ public class CommandLineGATK extends CommandLineExecutable { formatter.format("Available analyses:%n"); // Get the list of walker names from the walker manager. - WalkerManager walkerManager = GATKEngine.getWalkerManager(); + WalkerManager walkerManager = engine.getWalkerManager(); // Build a list sorted by walker display name. As this information is collected, keep track of the longest // package / walker name for later formatting. diff --git a/java/src/org/broadinstitute/sting/gatk/GenomeAnalysisEngine.java b/java/src/org/broadinstitute/sting/gatk/GenomeAnalysisEngine.java index 23520c3dd..e537aadb1 100755 --- a/java/src/org/broadinstitute/sting/gatk/GenomeAnalysisEngine.java +++ b/java/src/org/broadinstitute/sting/gatk/GenomeAnalysisEngine.java @@ -563,19 +563,6 @@ public class GenomeAnalysisEngine { } - /** - * Subclasses of CommandLinePrograms can provide their own types of command-line arguments. - * @return A collection of type descriptors generating implementation-dependent placeholders. - */ - protected Collection getArgumentTypeDescriptors() { - return Arrays.asList( new VCFWriterArgumentTypeDescriptor(this,System.out), - new SAMFileReaderArgumentTypeDescriptor(this), - new SAMFileWriterArgumentTypeDescriptor(this,System.out), - new OutputStreamArgumentTypeDescriptor(this,System.out) ); - } - - - /** * Bundles all the source information about the reads into a unified data structure. * diff --git a/java/src/org/broadinstitute/sting/gatk/io/stubs/SAMFileWriterArgumentTypeDescriptor.java b/java/src/org/broadinstitute/sting/gatk/io/stubs/SAMFileWriterArgumentTypeDescriptor.java index 2570c142d..c7b110b96 100644 --- a/java/src/org/broadinstitute/sting/gatk/io/stubs/SAMFileWriterArgumentTypeDescriptor.java +++ b/java/src/org/broadinstitute/sting/gatk/io/stubs/SAMFileWriterArgumentTypeDescriptor.java @@ -144,7 +144,6 @@ public class SAMFileWriterArgumentTypeDescriptor extends ArgumentTypeDescriptor * @return Argument definition for the BAM file itself. Will not be null. */ private ArgumentDefinition createBAMCompressionArgumentDefinition(ArgumentSource source) { - Annotation annotation = getArgumentAnnotation(source); return new ArgumentDefinition( ArgumentIOType.ARGUMENT, int.class, COMPRESSION_FULLNAME, @@ -161,7 +160,6 @@ public class SAMFileWriterArgumentTypeDescriptor extends ArgumentTypeDescriptor } private ArgumentDefinition createWriteIndexArgumentDefinition(ArgumentSource source) { - Annotation annotation = getArgumentAnnotation(source); return new ArgumentDefinition( ArgumentIOType.ARGUMENT, boolean.class, CREATE_INDEX_FULLNAME, diff --git a/java/src/org/broadinstitute/sting/gatk/io/stubs/VCFWriterArgumentTypeDescriptor.java b/java/src/org/broadinstitute/sting/gatk/io/stubs/VCFWriterArgumentTypeDescriptor.java index 237b3c734..f3f00c1d4 100644 --- a/java/src/org/broadinstitute/sting/gatk/io/stubs/VCFWriterArgumentTypeDescriptor.java +++ b/java/src/org/broadinstitute/sting/gatk/io/stubs/VCFWriterArgumentTypeDescriptor.java @@ -25,15 +25,18 @@ package org.broadinstitute.sting.gatk.io.stubs; +import org.broad.tribble.vcf.VCFHeaderLine; import org.broad.tribble.vcf.VCFWriter; import org.broadinstitute.sting.commandline.*; +import org.broadinstitute.sting.gatk.CommandLineExecutable; import org.broadinstitute.sting.gatk.GenomeAnalysisEngine; +import org.broadinstitute.sting.utils.classloader.JVMUtils; +import org.broadinstitute.sting.utils.exceptions.ReviewedStingException; import java.io.File; import java.io.OutputStream; -import java.util.List; -import java.util.Arrays; -import java.util.HashSet; +import java.lang.annotation.Annotation; +import java.util.*; /** * Injects new command-line arguments into the system providing support for the genotype writer. @@ -42,8 +45,9 @@ import java.util.HashSet; * @version 0.1 */ public class VCFWriterArgumentTypeDescriptor extends ArgumentTypeDescriptor { - + private static final String NO_HEADER_ARG_NAME = "NO_HEADER"; private static final HashSet SUPPORTED_ZIPPED_SUFFIXES = new HashSet(); + // // static list of zipped suffixes supported by this system. // @@ -55,21 +59,28 @@ public class VCFWriterArgumentTypeDescriptor extends ArgumentTypeDescriptor { /** * The engine into which output stubs should be fed. */ - private GenomeAnalysisEngine engine; + private final GenomeAnalysisEngine engine; /** * The default location to which data should be written if the user specifies no such location. */ private final OutputStream defaultOutputStream; + /** + * The sources into which arguments were injected. + */ + private final Collection argumentSources; + /** * Create a new GenotypeWriter argument, notifying the given engine when that argument has been created. * @param engine the engine to be notified. * @param defaultOutputStream the default output stream to be written to if nothing else is specified. + * @param argumentSources sources from which command-line arguments should be derived. */ - public VCFWriterArgumentTypeDescriptor(GenomeAnalysisEngine engine, OutputStream defaultOutputStream) { + public VCFWriterArgumentTypeDescriptor(GenomeAnalysisEngine engine, OutputStream defaultOutputStream, Collection argumentSources) { this.engine = engine; this.defaultOutputStream = defaultOutputStream; + this.argumentSources = argumentSources; } /** @@ -84,7 +95,7 @@ public class VCFWriterArgumentTypeDescriptor extends ArgumentTypeDescriptor { @Override public List createArgumentDefinitions( ArgumentSource source ) { - return Arrays.asList( createDefaultArgumentDefinition(source) ); + return Arrays.asList( createDefaultArgumentDefinition(source),createNoHeaderArgumentDefinition()); } /** @@ -98,7 +109,7 @@ public class VCFWriterArgumentTypeDescriptor extends ArgumentTypeDescriptor { @Override public Object createTypeDefault(ArgumentSource source,Class type) { - VCFWriterStub stub = new VCFWriterStub(defaultOutputStream, false); + VCFWriterStub stub = new VCFWriterStub(defaultOutputStream, false, argumentSources, false); engine.addOutput(stub); return stub; } @@ -119,8 +130,11 @@ public class VCFWriterArgumentTypeDescriptor extends ArgumentTypeDescriptor { // Should we compress the output stream? boolean compress = writerFileName != null && SUPPORTED_ZIPPED_SUFFIXES.contains(getFileSuffix(writerFileName)); + boolean skipWritingHeader = argumentIsPresent(createNoHeaderArgumentDefinition(),matches); + // Create a stub for the given object. - VCFWriterStub stub = (writerFile != null) ? new VCFWriterStub(writerFile, compress) : new VCFWriterStub(System.out, compress); + VCFWriterStub stub = (writerFile != null) ? new VCFWriterStub(writerFile, compress, argumentSources, skipWritingHeader) + : new VCFWriterStub(defaultOutputStream, compress, argumentSources, skipWritingHeader); // WARNING: Side effects required by engine! parsingEngine.addTags(stub,getArgumentTags(matches)); @@ -129,6 +143,27 @@ public class VCFWriterArgumentTypeDescriptor extends ArgumentTypeDescriptor { return stub; } + /** + * Creates the optional compression level argument for the BAM file. + * @return Argument definition for the BAM file itself. Will not be null. + */ + private ArgumentDefinition createNoHeaderArgumentDefinition() { + return new ArgumentDefinition( ArgumentIOType.ARGUMENT, + boolean.class, + NO_HEADER_ARG_NAME, + NO_HEADER_ARG_NAME, + "Don't output the usual VCF header tag with the command line. FOR DEBUGGING PURPOSES ONLY. This option is required in order to pass integration tests.", + false, + true, + false, + true, + null, + null, + null, + null ); + } + + /** * Returns a lower-cased version of the suffix of the provided file. * @param fileName the file name. Must not be null. @@ -140,4 +175,5 @@ public class VCFWriterArgumentTypeDescriptor extends ArgumentTypeDescriptor { return ""; return fileName.substring(indexOfLastDot).toLowerCase(); } + } diff --git a/java/src/org/broadinstitute/sting/gatk/io/stubs/VCFWriterStub.java b/java/src/org/broadinstitute/sting/gatk/io/stubs/VCFWriterStub.java index 7cc4a77e8..f9b86665e 100755 --- a/java/src/org/broadinstitute/sting/gatk/io/stubs/VCFWriterStub.java +++ b/java/src/org/broadinstitute/sting/gatk/io/stubs/VCFWriterStub.java @@ -28,11 +28,18 @@ package org.broadinstitute.sting.gatk.io.stubs; import java.io.File; import java.io.PrintStream; import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.TreeSet; import org.broad.tribble.util.variantcontext.VariantContext; import org.broad.tribble.vcf.VCFHeader; +import org.broad.tribble.vcf.VCFHeaderLine; import org.broad.tribble.vcf.VCFWriter; +import org.broadinstitute.sting.commandline.CommandLineUtils; +import org.broadinstitute.sting.gatk.CommandLineExecutable; import org.broadinstitute.sting.gatk.io.OutputTracker; +import org.broadinstitute.sting.utils.classloader.JVMUtils; /** * A stub for routing and management of genotype reading and writing. @@ -55,7 +62,7 @@ public class VCFWriterStub implements Stub, VCFWriter { private final PrintStream genotypeStream; /** - * The cached VCF header (initilized to null) + * The cached VCF header (initialized to null) */ private VCFHeader vcfHeader = null; @@ -64,6 +71,17 @@ public class VCFWriterStub implements Stub, VCFWriter { */ private final boolean isCompressed; + /** + * A hack: push the argument sources into the VCF header so that the VCF header + * can rebuild the command-line arguments. + */ + private final Collection argumentSources; + + /** + * Should the header be written out? A hidden argument. + */ + private final boolean skipWritingHeader; + /** * Connects this stub with an external stream capable of serving the * requests of the consumer of this stub. @@ -75,10 +93,12 @@ public class VCFWriterStub implements Stub, VCFWriter { * @param genotypeFile file to (ultimately) create. * @param isCompressed should we compress the output stream? */ - public VCFWriterStub(File genotypeFile, boolean isCompressed) { + public VCFWriterStub(File genotypeFile, boolean isCompressed, Collection argumentSources, boolean skipWritingHeader) { this.genotypeFile = genotypeFile; this.genotypeStream = null; this.isCompressed = isCompressed; + this.argumentSources = argumentSources; + this.skipWritingHeader = skipWritingHeader; } /** @@ -86,10 +106,12 @@ public class VCFWriterStub implements Stub, VCFWriter { * @param genotypeStream stream to (ultimately) write. * @param isCompressed should we compress the output stream? */ - public VCFWriterStub(OutputStream genotypeStream, boolean isCompressed) { + public VCFWriterStub(OutputStream genotypeStream, boolean isCompressed, Collection argumentSources, boolean skipWritingHeader) { this.genotypeFile = null; this.genotypeStream = new PrintStream(genotypeStream); this.isCompressed = isCompressed; + this.argumentSources = argumentSources; + this.skipWritingHeader = skipWritingHeader; } /** @@ -134,7 +156,18 @@ public class VCFWriterStub implements Stub, VCFWriter { public void writeHeader(VCFHeader header) { vcfHeader = header; - outputTracker.getStorage(this).writeHeader(header); + + // Check for the command-line argument header line. If not present, add it in. + VCFHeaderLine commandLineArgHeaderLine = getCommandLineArgumentHeaderLine(); + boolean foundCommandLineHeaderLine = false; + for(VCFHeaderLine line: vcfHeader.getMetaData()) { + if(line.getKey().equals(commandLineArgHeaderLine.getKey())) + foundCommandLineHeaderLine = true; + } + if(!foundCommandLineHeaderLine && !skipWritingHeader) + vcfHeader.addMetaDataLine(commandLineArgHeaderLine); + + outputTracker.getStorage(this).writeHeader(vcfHeader); } /** @@ -150,4 +183,22 @@ public class VCFWriterStub implements Stub, VCFWriter { public void close() { outputTracker.getStorage(this).close(); } + + /** + * Gets a string representation of this object. + * @return + */ + @Override + public String toString() { + return getClass().getName(); + } + + /** + * Gets the appropriately formatted header for a VCF file + * @return VCF file header. + */ + private VCFHeaderLine getCommandLineArgumentHeaderLine() { + CommandLineExecutable executable = JVMUtils.getObjectOfType(argumentSources,CommandLineExecutable.class); + return new VCFHeaderLine(executable.getAnalysisName(), "\"" + CommandLineUtils.createApproximateCommandLineArgumentString(argumentSources) + "\""); + } } \ No newline at end of file diff --git a/java/src/org/broadinstitute/sting/gatk/walkers/annotator/VariantAnnotator.java b/java/src/org/broadinstitute/sting/gatk/walkers/annotator/VariantAnnotator.java index ac58a6665..b70b00f94 100755 --- a/java/src/org/broadinstitute/sting/gatk/walkers/annotator/VariantAnnotator.java +++ b/java/src/org/broadinstitute/sting/gatk/walkers/annotator/VariantAnnotator.java @@ -80,9 +80,6 @@ public class VariantAnnotator extends RodWalker { @Argument(fullName="vcfContainsOnlyIndels", shortName="dels",doc="Use if you are annotating an indel vcf, currently VERY experimental", required = false) protected boolean indelsOnly = false; - @Argument(fullName = "NO_HEADER", shortName = "NO_HEADER", doc = "Don't output the usual VCF header tag with the command line. FOR DEBUGGING PURPOSES ONLY. This option is required in order to pass integration tests.", required = false) - protected Boolean NO_VCF_HEADER_LINE = false; - private HashMap nonVCFsampleName = new HashMap(); private VariantAnnotatorEngine engine; @@ -145,9 +142,6 @@ public class VariantAnnotator extends RodWalker { if ( isUniqueHeaderLine(line, hInfo) ) hInfo.add(line); } - if ( !NO_VCF_HEADER_LINE ) { - hInfo.add(new VCFHeaderLine("VariantAnnotator", "\"" + CommandLineUtils.createApproximateCommandLineArgumentString(getToolkit(), this) + "\"")); - } VCFHeader vcfHeader = new VCFHeader(hInfo, samples); vcfWriter.writeHeader(vcfHeader); diff --git a/java/src/org/broadinstitute/sting/gatk/walkers/filters/VariantFiltrationWalker.java b/java/src/org/broadinstitute/sting/gatk/walkers/filters/VariantFiltrationWalker.java index 499da88da..671e9e4e3 100755 --- a/java/src/org/broadinstitute/sting/gatk/walkers/filters/VariantFiltrationWalker.java +++ b/java/src/org/broadinstitute/sting/gatk/walkers/filters/VariantFiltrationWalker.java @@ -72,10 +72,6 @@ public class VariantFiltrationWalker extends RodWalker { @Argument(fullName="maskName", shortName="mask", doc="The text to put in the FILTER field if a 'mask' rod is provided and overlaps with a variant call; [default:'Mask']", required=false) protected String MASK_NAME = "Mask"; - @Hidden - @Argument(fullName = "NO_HEADER", shortName = "NO_HEADER", doc = "Don't output the usual VCF header tag with the command line. FOR DEBUGGING PURPOSES ONLY. This option is required in order to pass integration tests.", required = false) - protected Boolean NO_VCF_HEADER_LINE = false; - // JEXL expressions for the filters List filterExps; List genotypeFilterExps; @@ -113,10 +109,6 @@ public class VariantFiltrationWalker extends RodWalker { } } - if ( !NO_VCF_HEADER_LINE ) { - hInfo.add(new VCFHeaderLine("VariantFiltration", "\"" + CommandLineUtils.createApproximateCommandLineArgumentString(getToolkit(), this) + "\"")); - } - writer.writeHeader(new VCFHeader(hInfo, vc.getSampleNames())); } diff --git a/java/src/org/broadinstitute/sting/gatk/walkers/genotyper/UnifiedGenotyper.java b/java/src/org/broadinstitute/sting/gatk/walkers/genotyper/UnifiedGenotyper.java index 759555f39..39dfadea5 100755 --- a/java/src/org/broadinstitute/sting/gatk/walkers/genotyper/UnifiedGenotyper.java +++ b/java/src/org/broadinstitute/sting/gatk/walkers/genotyper/UnifiedGenotyper.java @@ -71,10 +71,6 @@ public class UnifiedGenotyper extends LocusWalker { ///////////////////////////// @Argument(fullName="fdr_filter_level", shortName="fdr_filter_level", doc="The FDR level at which to start filtering.", required=false) private double FDR_FILTER_LEVEL = 0.0; - - ///////////////////////////// - // Debug Arguments - ///////////////////////////// - @Hidden - @Argument(fullName = "NO_HEADER", shortName = "NO_HEADER", doc = "Don't output the usual VCF header tag with the command line. FOR DEBUGGING PURPOSES ONLY. This option is required in order to pass integration tests.", required = false) - protected Boolean NO_VCF_HEADER_LINE = false; ///////////////////////////// // Private Member Variables @@ -167,9 +160,6 @@ public class ApplyVariantCuts extends RodWalker { // setup the header fields final Set hInfo = new HashSet(); hInfo.addAll(VCFUtils.getHeaderFields(getToolkit())); - if( !NO_VCF_HEADER_LINE ) { - hInfo.add(new VCFHeaderLine("ApplyVariantCuts", "\"" + CommandLineUtils.createApproximateCommandLineArgumentString(getToolkit(), this) + "\"")); - } final TreeSet samples = new TreeSet(); samples.addAll(SampleUtils.getUniqueSamplesFromRods(getToolkit())); diff --git a/java/src/org/broadinstitute/sting/gatk/walkers/variantrecalibration/VariantRecalibrator.java b/java/src/org/broadinstitute/sting/gatk/walkers/variantrecalibration/VariantRecalibrator.java index aafc3054d..227880ef3 100755 --- a/java/src/org/broadinstitute/sting/gatk/walkers/variantrecalibration/VariantRecalibrator.java +++ b/java/src/org/broadinstitute/sting/gatk/walkers/variantrecalibration/VariantRecalibrator.java @@ -111,9 +111,6 @@ public class VariantRecalibrator extends RodWalker { @Argument(fullName="setKey", shortName="setKey", doc="Key, by default set, in the INFO key=value tag emitted describing which set the combined VCF record came from. Set to null if you don't want the set field emitted.", required=false) public String SET_KEY = "set"; - @Hidden - @Argument(fullName = "NO_HEADER", shortName = "NO_HEADER", doc = "Don't output the usual VCF header tag with the command line. FOR DEBUGGING PURPOSES ONLY. This option is required in order to pass integration tests.", required = false) - protected Boolean NO_VCF_HEADER_LINE = false; - private List priority = null; private VariantAnnotatorEngine engine; @@ -105,9 +101,6 @@ public class CombineVariants extends RodWalker { Set headerLines = VCFUtils.smartMergeHeaders(vcfRods.values(), logger); if ( SET_KEY != null ) headerLines.add(new VCFInfoHeaderLine(SET_KEY, 1, VCFHeaderLineType.String, "Source VCF for the merged record in CombineVariants")); - if ( !NO_VCF_HEADER_LINE ) { - headerLines.add(new VCFHeaderLine("CombineVariants", "\"" + CommandLineUtils.createApproximateCommandLineArgumentString(getToolkit(), this) + "\"")); - } vcfWriter.writeHeader(new VCFHeader(headerLines, samples)); } diff --git a/java/src/org/broadinstitute/sting/queue/extensions/gatk/GATKExtensionsGenerator.java b/java/src/org/broadinstitute/sting/queue/extensions/gatk/GATKExtensionsGenerator.java index da62305a4..b4d96a124 100644 --- a/java/src/org/broadinstitute/sting/queue/extensions/gatk/GATKExtensionsGenerator.java +++ b/java/src/org/broadinstitute/sting/queue/extensions/gatk/GATKExtensionsGenerator.java @@ -83,7 +83,7 @@ public class GATKExtensionsGenerator extends CommandLineProgram { @Override protected Collection getArgumentTypeDescriptors() { List typeDescriptors = new ArrayList(); - typeDescriptors.add(new VCFWriterArgumentTypeDescriptor(GATKEngine,System.out)); + typeDescriptors.add(new VCFWriterArgumentTypeDescriptor(GATKEngine,System.out,Collections.emptyList())); typeDescriptors.add(new SAMFileReaderArgumentTypeDescriptor(GATKEngine)); typeDescriptors.add(new SAMFileWriterArgumentTypeDescriptor(GATKEngine,System.out)); typeDescriptors.add(new OutputStreamArgumentTypeDescriptor(GATKEngine,System.out)); diff --git a/java/src/org/broadinstitute/sting/utils/classloader/JVMUtils.java b/java/src/org/broadinstitute/sting/utils/classloader/JVMUtils.java index 9b7c2c4de..83258aaf9 100755 --- a/java/src/org/broadinstitute/sting/utils/classloader/JVMUtils.java +++ b/java/src/org/broadinstitute/sting/utils/classloader/JVMUtils.java @@ -31,6 +31,7 @@ import java.lang.reflect.Modifier; import java.lang.reflect.Field; import java.io.File; import java.io.IOException; +import java.util.Collection; import java.util.List; import java.util.ArrayList; import java.util.Arrays; @@ -146,4 +147,35 @@ public class JVMUtils { } } + /** + * Gets a single object in the list matching or type-compatible with the given type. Exceptions out if multiple objects match. + * @param type The desired type. + * @param The selected type. + * @return A collection of the given arguments with the specified type. + */ + public static T getObjectOfType(Collection objectsToFilter, Class type) { + // TODO: Make JVM utils. + Collection selectedObjects = getObjectsOfType(objectsToFilter,type); + if(selectedObjects.size() > 1) + throw new ReviewedStingException("User asked for a single instance of the type, multiple were present"); + if(selectedObjects.size() == 0) + throw new ReviewedStingException("User asked for a single instance of the type, but none were present"); + return selectedObjects.iterator().next(); + } + + /** + * Gets a collection of all objects in the list matching or type-compatible with the given type. + * @param type The desired type. + * @param Again, the desired type. Used so that clients can ignore type safety. + * @return A collection of the given arguments with the specified type. + */ + public static Collection getObjectsOfType(Collection objectsToFilter, Class type) { + Collection selectedObjects = new ArrayList(); + for(Object object: objectsToFilter) { + if(type.isAssignableFrom(object.getClass())) + selectedObjects.add((T)object); + } + return selectedObjects; + } + } diff --git a/java/src/org/broadinstitute/sting/utils/classloader/PackageUtils.java b/java/src/org/broadinstitute/sting/utils/classloader/PackageUtils.java index 4f570aa7a..7d49de573 100755 --- a/java/src/org/broadinstitute/sting/utils/classloader/PackageUtils.java +++ b/java/src/org/broadinstitute/sting/utils/classloader/PackageUtils.java @@ -62,8 +62,6 @@ public class PackageUtils { * Private constructor. No instantiating this class! */ private PackageUtils() {} - { - } /** * Return the classes that implement the specified interface. diff --git a/java/test/org/broadinstitute/sting/gatk/walkers/VariantsToVCFIntegrationTest.java b/java/test/org/broadinstitute/sting/gatk/walkers/VariantsToVCFIntegrationTest.java index 348501b1e..2a40ea1fb 100755 --- a/java/test/org/broadinstitute/sting/gatk/walkers/VariantsToVCFIntegrationTest.java +++ b/java/test/org/broadinstitute/sting/gatk/walkers/VariantsToVCFIntegrationTest.java @@ -28,7 +28,8 @@ public class VariantsToVCFIntegrationTest extends WalkerTest { " -T VariantsToVCF" + " -L 1:10,000,000-11,000,000" + " -sample NA123AB" + - " -o %s", + " -o %s" + + " -NO_HEADER", 1, // just one output file md5); executeTest("testVariantsToVCFUsingGeliInput #1", spec).getFirst(); @@ -45,7 +46,8 @@ public class VariantsToVCFIntegrationTest extends WalkerTest { " -T VariantsToVCF" + " -L 1:10,000,000-11,000,000" + " -sample NA123AB" + - " -o %s", + " -o %s" + + " -NO_HEADER", 1, // just one output file md5); executeTest("testVariantsToVCFUsingGeliInput #2", spec).getFirst(); @@ -61,7 +63,8 @@ public class VariantsToVCFIntegrationTest extends WalkerTest { " -B:variant,HapMap " + validationDataLocation + "rawHapMap.yri.chr1.txt" + " -T VariantsToVCF" + " -L 1:1-1,000,000" + - " -o %s", + " -o %s" + + " -NO_HEADER", 1, // just one output file md5); executeTest("testVariantsToVCFUsingHapMapInput", spec).getFirst(); @@ -76,7 +79,8 @@ public class VariantsToVCFIntegrationTest extends WalkerTest { "-R " + b36KGReference + " -B:variant,VCF " + validationDataLocation + "complexExample.vcf4" + " -T VariantsToVCF" + - " -o %s", + " -o %s" + + " -NO_HEADER", 1, // just one output file md5); executeTest("testVariantsToVCFUsingVCFInput", spec).getFirst(); diff --git a/java/test/org/broadinstitute/sting/gatk/walkers/annotator/genomicannotator/GenomicAnnotatorIntegrationTest.java b/java/test/org/broadinstitute/sting/gatk/walkers/annotator/genomicannotator/GenomicAnnotatorIntegrationTest.java index c0bc2150f..28f394d28 100755 --- a/java/test/org/broadinstitute/sting/gatk/walkers/annotator/genomicannotator/GenomicAnnotatorIntegrationTest.java +++ b/java/test/org/broadinstitute/sting/gatk/walkers/annotator/genomicannotator/GenomicAnnotatorIntegrationTest.java @@ -6,7 +6,8 @@ import java.util.Arrays; import org.broadinstitute.sting.WalkerTest; import org.junit.Test; -public class GenomicAnnotatorIntegrationTest extends WalkerTest { +public class + GenomicAnnotatorIntegrationTest extends WalkerTest { @Test public void testGenomicAnnotatorOnDbSNP() { @@ -34,7 +35,8 @@ public class GenomicAnnotatorIntegrationTest extends WalkerTest { " -m" + //generate many records from one input record if necessary " -o %s" + " -BTI variant" + - " -s dbsnp.name,dbsnp.refUCSC,dbsnp.strand,dbsnp.observed,dbsnp.avHet", + " -s dbsnp.name,dbsnp.refUCSC,dbsnp.strand,dbsnp.observed,dbsnp.avHet" + + " -NO_HEADER", 1, Arrays.asList(md5WithDashSArg)); executeTest("test with dbSNP and -s arg", specWithSArg); diff --git a/java/test/org/broadinstitute/sting/gatk/walkers/genotyper/UnifiedGenotyperIntegrationTest.java b/java/test/org/broadinstitute/sting/gatk/walkers/genotyper/UnifiedGenotyperIntegrationTest.java index b00d6fb6e..7a9fb7112 100755 --- a/java/test/org/broadinstitute/sting/gatk/walkers/genotyper/UnifiedGenotyperIntegrationTest.java +++ b/java/test/org/broadinstitute/sting/gatk/walkers/genotyper/UnifiedGenotyperIntegrationTest.java @@ -11,7 +11,8 @@ import java.util.Map; // Note that this class also serves as an integration test for the VariantAnnotator! // // ********************************************************************************** // -public class UnifiedGenotyperIntegrationTest extends WalkerTest { +public class + UnifiedGenotyperIntegrationTest extends WalkerTest { private final static String baseCommand = "-T UnifiedGenotyper -R " + b36KGReference + " -NO_HEADER"; diff --git a/java/test/org/broadinstitute/sting/gatk/walkers/variantutils/LiftoverVariantsIntegrationTest.java b/java/test/org/broadinstitute/sting/gatk/walkers/variantutils/LiftoverVariantsIntegrationTest.java index 32dd48f8e..31a2ea656 100755 --- a/java/test/org/broadinstitute/sting/gatk/walkers/variantutils/LiftoverVariantsIntegrationTest.java +++ b/java/test/org/broadinstitute/sting/gatk/walkers/variantutils/LiftoverVariantsIntegrationTest.java @@ -38,7 +38,7 @@ public class LiftoverVariantsIntegrationTest extends WalkerTest { @Test public void testb36Tohg19() { WalkerTestSpec spec = new WalkerTestSpec( - "-T LiftoverVariants -o %s -R " + b36KGReference + " -B:variant,vcf " + validationDataLocation + "yri.trio.gatk_glftrio.intersection.annotated.filtered.chr1.500.noheader.vcf -chain " + validationDataLocation + "b36ToHg19.broad.over.chain -dict /seq/references/Homo_sapiens_assembly19/v0/Homo_sapiens_assembly19.dict", + "-T LiftoverVariants -o %s -R " + b36KGReference + " -B:variant,vcf " + validationDataLocation + "yri.trio.gatk_glftrio.intersection.annotated.filtered.chr1.500.noheader.vcf -chain " + validationDataLocation + "b36ToHg19.broad.over.chain -dict /seq/references/Homo_sapiens_assembly19/v0/Homo_sapiens_assembly19.dict -NO_HEADER", 1, Arrays.asList("1637877892a019061e74eb3d9a9d100f")); executeTest("test b36 to hg19", spec); diff --git a/java/test/org/broadinstitute/sting/gatk/walkers/variantutils/SelectVariantsIntegrationTest.java b/java/test/org/broadinstitute/sting/gatk/walkers/variantutils/SelectVariantsIntegrationTest.java index 4bc3bd514..0a01780c3 100755 --- a/java/test/org/broadinstitute/sting/gatk/walkers/variantutils/SelectVariantsIntegrationTest.java +++ b/java/test/org/broadinstitute/sting/gatk/walkers/variantutils/SelectVariantsIntegrationTest.java @@ -16,7 +16,7 @@ public class SelectVariantsIntegrationTest extends WalkerTest { String samplesFile = validationDataLocation + "SelectVariants.samples.txt"; WalkerTestSpec spec = new WalkerTestSpec( - baseTestString(" -sn A -sn '[CDH]' -sn " + samplesFile + " -env -ef -select 'AF < 0.2' -B:variant,VCF " + testfile), + baseTestString(" -sn A -sn '[CDH]' -sn " + samplesFile + " -env -ef -select 'AF < 0.2' -B:variant,VCF " + testfile + " -NO_HEADER"), 1, Arrays.asList("3a15628b5980031c629c0c33e7e60b40") );