diff --git a/java/src/org/broadinstitute/sting/analyzecovariates/AnalyzeCovariates.java b/java/src/org/broadinstitute/sting/analyzecovariates/AnalyzeCovariates.java index 7bc49619e..54ea8b47a 100755 --- a/java/src/org/broadinstitute/sting/analyzecovariates/AnalyzeCovariates.java +++ b/java/src/org/broadinstitute/sting/analyzecovariates/AnalyzeCovariates.java @@ -304,7 +304,7 @@ class AnalyzeCovariatesCLP extends CommandLineProgram { } public class AnalyzeCovariates { - public static void main(String args[]) { + public static void main(String args[]) throws Exception { AnalyzeCovariatesCLP clp = new AnalyzeCovariatesCLP(); CommandLineProgram.start( clp, args ); System.exit(0); diff --git a/java/src/org/broadinstitute/sting/commandline/ArgumentException.java b/java/src/org/broadinstitute/sting/commandline/ArgumentException.java index 04993df7d..ae9d34a87 100755 --- a/java/src/org/broadinstitute/sting/commandline/ArgumentException.java +++ b/java/src/org/broadinstitute/sting/commandline/ArgumentException.java @@ -25,12 +25,12 @@ package org.broadinstitute.sting.commandline; -import org.broadinstitute.sting.utils.StingException; +import org.broadinstitute.sting.utils.exceptions.UserError; /** * Generic class for handling misc parsing exceptions. */ -public class ArgumentException extends StingException { +public class ArgumentException extends UserError { public ArgumentException( String message ) { super( message ); } diff --git a/java/src/org/broadinstitute/sting/commandline/CommandLineProgram.java b/java/src/org/broadinstitute/sting/commandline/CommandLineProgram.java index 828032a23..24d88a791 100644 --- a/java/src/org/broadinstitute/sting/commandline/CommandLineProgram.java +++ b/java/src/org/broadinstitute/sting/commandline/CommandLineProgram.java @@ -27,6 +27,7 @@ package org.broadinstitute.sting.commandline; import org.apache.log4j.*; import org.broadinstitute.sting.gatk.phonehome.GATKRunReport; +import org.broadinstitute.sting.utils.exceptions.UserError; import org.broadinstitute.sting.utils.help.ApplicationDetails; import org.broadinstitute.sting.utils.help.HelpFormatter; @@ -161,7 +162,7 @@ public abstract class CommandLineProgram { * @param args the command line arguments passed in */ @SuppressWarnings("unchecked") - public static void start(CommandLineProgram clp, String[] args) { + public static void start(CommandLineProgram clp, String[] args) throws Exception { try { // setup our log layout @@ -256,7 +257,7 @@ public abstract class CommandLineProgram { // we catch all exceptions here. if it makes it to this level, we're in trouble. Let's bail! // TODO: what if the logger is the exception? hmm... logger.fatal("\n"); - throw new RuntimeException(e); + throw e; } } @@ -310,20 +311,13 @@ public abstract class CommandLineProgram { /** * a function used to indicate an error occurred in the command line tool - * - * @param msg message to display */ - private static void printExitSystemMsg(final String msg) { - System.out.printf("The following error has occurred:%n%n"); - System.out.printf("%s:%n%n", msg); - System.out.printf("Please check your command line arguments for any typos or inconsistencies.%n"); - System.out.printf("Also, please review our documentation at:%n"); - System.out.printf(" http://www.broadinstitute.org/gsa/wiki %n%n"); - System.out.printf("To report bugs or to get help resolving undocumented issues, please contact us via our support site at:%n"); - System.out.printf(" http://getsatisfaction.com/gsa %n%n"); - System.out.printf("Please be sure to include the stack trace below when posting a message on the support site:%n"); + private static void printDocumentationReference() { + errorPrintf("Visit our wiki for extensive documentation http://www.broadinstitute.org/gsa/wiki%n"); + errorPrintf("Visit our forum to view answers to commonly asked questions http://getsatisfaction.com/gsa%n"); } + /** * Do a cursory search for the given argument. * @@ -346,16 +340,19 @@ public abstract class CommandLineProgram { System.exit(0); } - /** - * used to indicate an error occured - * - * @param msg the message to display - */ - public static void exitSystemWithError(final String msg) { - printExitSystemMsg(msg); - System.exit(1); + private static void errorPrintf(String format, Object... s) { + String formatted = String.format(format, s); + + if ( formatted.trim().equals("") ) + System.out.println("##### ERROR"); + else { + for ( String part : formatted.split("\n") ) { + System.out.println("##### ERROR " + part); + } + } } + /** * used to indicate an error occured * @@ -363,14 +360,35 @@ public abstract class CommandLineProgram { * @param e the error */ public static void exitSystemWithError(final String msg, Exception e) { - System.out.printf("------------------------------------------------------------------------------------------%n"); - printExitSystemMsg(msg); - System.out.printf("------------------------------------------------------------------------------------------%n"); + errorPrintf("------------------------------------------------------------------------------------------%n"); + errorPrintf("stack trace %n"); e.printStackTrace(); - System.out.printf("------------------------------------------------------------------------------------------%n"); + + errorPrintf("------------------------------------------------------------------------------------------%n"); + errorPrintf("A GATK RUNTIME ERROR has occurred:%n"); + errorPrintf("%n"); + errorPrintf("Please visit to wiki to see if this is a known problem%n"); + errorPrintf("If not, please post the error, with stack trace, to the GATK forum%n"); + printDocumentationReference(); + errorPrintf("%n"); + errorPrintf("MESSAGE: %s%n", msg.trim()); + errorPrintf("------------------------------------------------------------------------------------------%n"); System.exit(1); } + public static void exitSystemWithUserError(UserError e) { + errorPrintf("------------------------------------------------------------------------------------------%n"); + errorPrintf("A USER ERROR has occurred. The invalid arguments or inputs must be corrected before the GATK can proceed%n"); + errorPrintf("%n"); + errorPrintf("See the documentation (rerun with -h) for this tool to view allowable command-line argument.%n"); + printDocumentationReference(); + errorPrintf("%n"); + errorPrintf("MESSAGE: %s%n", e.getMessage().trim()); + errorPrintf("------------------------------------------------------------------------------------------%n"); + System.exit(1); + } + + /** * used to indicate an error occured * diff --git a/java/src/org/broadinstitute/sting/gatk/CommandLineGATK.java b/java/src/org/broadinstitute/sting/gatk/CommandLineGATK.java index 834a3e153..3da263afb 100755 --- a/java/src/org/broadinstitute/sting/gatk/CommandLineGATK.java +++ b/java/src/org/broadinstitute/sting/gatk/CommandLineGATK.java @@ -26,6 +26,7 @@ package org.broadinstitute.sting.gatk; import org.broadinstitute.sting.gatk.arguments.GATKArgumentCollection; +import org.broadinstitute.sting.utils.exceptions.UserError; import org.broadinstitute.sting.utils.text.TextFormattingUtils; import org.broadinstitute.sting.utils.help.ApplicationDetails; import org.broadinstitute.sting.commandline.*; @@ -91,6 +92,8 @@ public class CommandLineGATK extends CommandLineExecutable { CommandLineGATK instance = new CommandLineGATK(); start(instance, argv); System.exit(CommandLineProgram.result); // todo -- this is a painful hack + } catch (UserError e) { + exitSystemWithUserError(e); } catch (Exception e) { exitSystemWithError(e); } diff --git a/java/src/org/broadinstitute/sting/gatk/contexts/variantcontext/VariantContextUtils.java b/java/src/org/broadinstitute/sting/gatk/contexts/variantcontext/VariantContextUtils.java index 03b7e6214..47fb981db 100755 --- a/java/src/org/broadinstitute/sting/gatk/contexts/variantcontext/VariantContextUtils.java +++ b/java/src/org/broadinstitute/sting/gatk/contexts/variantcontext/VariantContextUtils.java @@ -30,6 +30,7 @@ import org.broad.tribble.util.popgen.HardyWeinbergCalculation; import org.broad.tribble.util.variantcontext.*; import org.broadinstitute.sting.utils.*; import org.broad.tribble.vcf.VCFConstants; +import org.broadinstitute.sting.utils.exceptions.UserError; public class VariantContextUtils { final public static JexlEngine engine = new JexlEngine(); @@ -112,7 +113,7 @@ public class VariantContextUtils { throw new StingException("BUG: neither names nor exps can be null: names " + Arrays.toString(names) + " exps=" + Arrays.toString(exps) ); if ( names.length != exps.length ) - throw new StingException("Inconsistent number of provided filter names and expressions: names=" + Arrays.toString(names) + " exps=" + Arrays.toString(exps)); + throw new UserError("Inconsistent number of provided filter names and expressions: names=" + Arrays.toString(names) + " exps=" + Arrays.toString(exps)); Map map = new HashMap(); for ( int i = 0; i < names.length; i++ ) { map.put(names[i], exps[i]); } @@ -148,7 +149,7 @@ public class VariantContextUtils { Expression exp = engine.createExpression(expStr); exps.add(new JexlVCMatchExp(name, exp)); } catch (Exception e) { - throw new StingException("Invalid expression used (" + expStr + "). Please see the JEXL docs for correct syntax."); + throw new UserError.BadArgumentValue(name, "Invalid expression used (" + expStr + "). Please see the JEXL docs for correct syntax.") ; } } @@ -432,7 +433,7 @@ public class VariantContextUtils { for ( String name : vc.getSampleNames() ) { //System.out.printf("Checking %s %b%n", name, names.contains(name)); if ( names.contains(name) ) - throw new StingException("REQUIRE_UNIQUE sample names is true but duplicate names were discovered " + name); + throw new UserError("REQUIRE_UNIQUE sample names is true but duplicate names were discovered " + name); } names.addAll(vc.getSampleNames()); @@ -641,7 +642,7 @@ public class VariantContextUtils { private int getIndex(VariantContext vc) { int i = priorityListOfVCs.indexOf(vc.getName()); - if ( i == -1 ) throw new StingException("Priority list " + priorityListOfVCs + " doesn't contain variant context " + vc.getName()); + if ( i == -1 ) throw new UserError.BadArgumentValue(Utils.join(",", priorityListOfVCs), "Priority list " + priorityListOfVCs + " doesn't contain variant context " + vc.getName()); return i; } @@ -755,4 +756,4 @@ public class VariantContextUtils { return GenomeLocParser.createGenomeLoc(vc.getChr(),(int)vc.getStart(),(int)vc.getEnd()); } -} \ No newline at end of file +} diff --git a/java/src/org/broadinstitute/sting/gatk/datasources/providers/LocusReferenceView.java b/java/src/org/broadinstitute/sting/gatk/datasources/providers/LocusReferenceView.java index e17eccac3..b22170e17 100755 --- a/java/src/org/broadinstitute/sting/gatk/datasources/providers/LocusReferenceView.java +++ b/java/src/org/broadinstitute/sting/gatk/datasources/providers/LocusReferenceView.java @@ -124,7 +124,7 @@ public class LocusReferenceView extends ReferenceView { if ( bounds==null || loc==null) return; // can bounds be null actually??? if ( isLocationWithinBounds(loc) ) return; if ( loc.getContigIndex() != bounds.getContigIndex() ) - throw new StingException("Illegal attempt to expand reference view bounds to accomodate location on a different contig."); + throw new StingException("Illegal attempt to expand reference view bounds to accommodate location on a different contig."); bounds = GenomeLocParser.createGenomeLoc(bounds.getContigIndex(), Math.min(bounds.getStart(),loc.getStart()), diff --git a/java/src/org/broadinstitute/sting/gatk/datasources/simpleDataSources/ReferenceDataSource.java b/java/src/org/broadinstitute/sting/gatk/datasources/simpleDataSources/ReferenceDataSource.java index ab6b7502d..6356ed6d2 100644 --- a/java/src/org/broadinstitute/sting/gatk/datasources/simpleDataSources/ReferenceDataSource.java +++ b/java/src/org/broadinstitute/sting/gatk/datasources/simpleDataSources/ReferenceDataSource.java @@ -30,6 +30,7 @@ import net.sf.picard.reference.FastaSequenceIndexBuilder; import net.sf.picard.sam.CreateSequenceDictionary; import net.sf.picard.reference.IndexedFastaSequenceFile; import net.sf.picard.reference.FastaSequenceIndex; +import org.broadinstitute.sting.utils.exceptions.UserError; import org.broadinstitute.sting.utils.file.FSLockWithShared; import org.broadinstitute.sting.utils.file.FileSystemInabilityToLockException; @@ -81,7 +82,7 @@ public class ReferenceDataSource implements ReferenceDataSourceProgressListener catch (Exception e) { // If lock creation succeeded, the failure must have been generating the index. // If lock creation failed, just skip over index creation entirely. - throw new StingException("Index file does not exist and could not be created. See error below.", e); + throw new StingException("Index file does not exist and could not be created because " + e.getMessage(), e); } finally { indexLock.unlock(); @@ -120,7 +121,7 @@ public class ReferenceDataSource implements ReferenceDataSourceProgressListener new CreateSequenceDictionary().instanceMain(args); if (!tempFile.renameTo(dictFile)) - throw new StingException("Error transferring temp file to dict file"); + throw new StingException("Error transferring temp file " + tempFile + " to dict file " + dictFile); } catch(FileSystemInabilityToLockException ex) { logger.info("Unable to create write lock: " + ex.getMessage()); @@ -129,7 +130,7 @@ public class ReferenceDataSource implements ReferenceDataSourceProgressListener catch (Exception e) { // If lock creation succeeded, the failure must have been generating the index. // If lock creation failed, just skip over index creation entirely. - throw new StingException("Dictionary file does not exist and could not be created. See error below.", e); + throw new StingException("Dictionary file does not exist and could not be created because " + e.getMessage(), e); } finally { dictLock.unlock(); @@ -170,7 +171,7 @@ public class ReferenceDataSource implements ReferenceDataSourceProgressListener } catch (Exception e) { - throw new StingException(String.format("Error reading fasta file %s.", fastaFile.getAbsolutePath()), e); + throw new UserError.CouldNotReadInputFile(fastaFile, e); } finally { dictLock.unlock(); diff --git a/java/src/org/broadinstitute/sting/gatk/datasources/utilities/BAMTagRenamer.java b/java/src/org/broadinstitute/sting/gatk/datasources/utilities/BAMTagRenamer.java index 8a1c9259c..722466cae 100644 --- a/java/src/org/broadinstitute/sting/gatk/datasources/utilities/BAMTagRenamer.java +++ b/java/src/org/broadinstitute/sting/gatk/datasources/utilities/BAMTagRenamer.java @@ -88,7 +88,12 @@ public class BAMTagRenamer extends CommandLineProgram { */ public static void main(String[] argv) { BAMTagRenamer instance = new BAMTagRenamer(); - start(instance, argv); + try { + start(instance, argv); + } catch (Exception e) { + throw new RuntimeException(e); + } + System.exit(CommandLineProgram.result); } } diff --git a/java/src/org/broadinstitute/sting/gatk/executive/MicroScheduler.java b/java/src/org/broadinstitute/sting/gatk/executive/MicroScheduler.java index 5c6850675..bf3fbc5ed 100755 --- a/java/src/org/broadinstitute/sting/gatk/executive/MicroScheduler.java +++ b/java/src/org/broadinstitute/sting/gatk/executive/MicroScheduler.java @@ -45,6 +45,7 @@ import java.util.*; import java.io.File; import net.sf.picard.reference.IndexedFastaSequenceFile; +import org.broadinstitute.sting.utils.exceptions.UserError; /** @@ -85,14 +86,14 @@ public abstract class MicroScheduler { public static MicroScheduler create(GenomeAnalysisEngine engine, Walker walker, SAMDataSource reads, IndexedFastaSequenceFile reference, Collection rods, int nThreadsToUse) { if (walker instanceof TreeReducible && nThreadsToUse > 1) { if(walker.isReduceByInterval()) - throw new StingException(String.format("The analysis %s aggregates results by interval. Due to a current limitation of the GATK, analyses of this type do not currently support parallel execution. Please run your analysis without the -nt option.", engine.getWalkerName(walker.getClass()))); + throw new UserError.BadArgumentValue("nt", String.format("The analysis %s aggregates results by interval. Due to a current limitation of the GATK, analyses of this type do not currently support parallel execution. Please run your analysis without the -nt option.", engine.getWalkerName(walker.getClass()))); if(walker instanceof ReadWalker) - throw new StingException(String.format("The analysis %s is a read walker. Due to a current limitation of the GATK, analyses of this type do not currently support parallel execution. Please run your analysis without the -nt option.", engine.getWalkerName(walker.getClass()))); + throw new UserError.BadArgumentValue("nt", String.format("The analysis %s is a read walker. Due to a current limitation of the GATK, analyses of this type do not currently support parallel execution. Please run your analysis without the -nt option.", engine.getWalkerName(walker.getClass()))); logger.info(String.format("Running the GATK in parallel mode with %d concurrent threads",nThreadsToUse)); return new HierarchicalMicroScheduler(engine, walker, reads, reference, rods, nThreadsToUse); } else { if(nThreadsToUse > 1) - throw new StingException(String.format("The analysis %s currently does not support parallel execution. Please run your analysis without the -nt option.", engine.getWalkerName(walker.getClass()))); + throw new UserError.BadArgumentValue("nt", String.format("The analysis %s currently does not support parallel execution. Please run your analysis without the -nt option.", engine.getWalkerName(walker.getClass()))); return new LinearMicroScheduler(engine, walker, reads, reference, rods); } } diff --git a/java/src/org/broadinstitute/sting/gatk/filters/PlatformUnitFilter.java b/java/src/org/broadinstitute/sting/gatk/filters/PlatformUnitFilter.java index c3f81aa22..e15333f7a 100644 --- a/java/src/org/broadinstitute/sting/gatk/filters/PlatformUnitFilter.java +++ b/java/src/org/broadinstitute/sting/gatk/filters/PlatformUnitFilter.java @@ -8,6 +8,7 @@ import java.util.Set; import java.util.HashSet; import org.broadinstitute.sting.utils.StingException; +import org.broadinstitute.sting.utils.exceptions.UserError; /** * Created by IntelliJ IDEA. @@ -29,7 +30,7 @@ public class PlatformUnitFilter implements SamRecordFilter { if ( pu_attr == null ) { // no platform unit in the record, go get from read group SAMReadGroupRecord rgr = samRecord.getReadGroup(); - if ( rgr == null ) throw new StingException("Read " + samRecord.getReadName() +" has NO associated read group record"); + if ( rgr == null ) throw new UserError.MalformedBam(samRecord, "Read " + samRecord.getReadName() +" has NO associated read group record"); pu_attr = rgr.getAttribute("PU") ; } if ( pu_attr == null ) return false; // could not get PU, forget about the filtering... diff --git a/java/src/org/broadinstitute/sting/gatk/filters/PlatformUnitFilterHelper.java b/java/src/org/broadinstitute/sting/gatk/filters/PlatformUnitFilterHelper.java index 383bf001b..f0d37e8c4 100644 --- a/java/src/org/broadinstitute/sting/gatk/filters/PlatformUnitFilterHelper.java +++ b/java/src/org/broadinstitute/sting/gatk/filters/PlatformUnitFilterHelper.java @@ -25,6 +25,7 @@ package org.broadinstitute.sting.gatk.filters; +import org.broadinstitute.sting.utils.exceptions.UserError; import org.broadinstitute.sting.utils.text.XReadLines; import org.broadinstitute.sting.utils.StingException; @@ -75,7 +76,7 @@ public class PlatformUnitFilterHelper { if ( EMPTYLINE_PATTERN.matcher(line).matches() ) continue; // skip empty lines PlatformUnitFilter.addBlackListedLane(line); // PlatformUnitFilter will trim the line as needed } - } catch ( FileNotFoundException e) { throw new StingException("File " + f + " does not exist."); } // this should NEVER happen + } catch ( FileNotFoundException e) { throw new UserError.CouldNotReadInputFile(f, e); } // this should NEVER happen return; } diff --git a/java/src/org/broadinstitute/sting/gatk/filters/ReadGroupBlackListFilter.java b/java/src/org/broadinstitute/sting/gatk/filters/ReadGroupBlackListFilter.java index 28c1a0a4f..009546c38 100644 --- a/java/src/org/broadinstitute/sting/gatk/filters/ReadGroupBlackListFilter.java +++ b/java/src/org/broadinstitute/sting/gatk/filters/ReadGroupBlackListFilter.java @@ -34,6 +34,7 @@ import net.sf.picard.filter.SamRecordFilter; import net.sf.samtools.SAMRecord; import net.sf.samtools.SAMReadGroupRecord; import org.broadinstitute.sting.utils.StingException; +import org.broadinstitute.sting.utils.exceptions.UserError; import org.broadinstitute.sting.utils.text.XReadLines; /** @@ -93,7 +94,7 @@ public class ReadGroupBlackListFilter implements SamRecordFilter { if (parentFile != null) { message += ", " + parentFile.getAbsolutePath() + ":" + parentLineNum; } - throw new StingException(message, e); + throw new UserError(message); } } else { String[] filterEntry = filter.split(":", 2); @@ -110,7 +111,7 @@ public class ReadGroupBlackListFilter implements SamRecordFilter { message += ", " + parentFile.getAbsolutePath() + ":" + parentLineNum; } message += ", format is :"; - throw new StingException(message); + throw new UserError(message); } if (!filters.containsKey(filterEntry[0])) diff --git a/java/src/org/broadinstitute/sting/gatk/io/ThreadLocalOutputTracker.java b/java/src/org/broadinstitute/sting/gatk/io/ThreadLocalOutputTracker.java index 2fdedca9a..cc162424b 100644 --- a/java/src/org/broadinstitute/sting/gatk/io/ThreadLocalOutputTracker.java +++ b/java/src/org/broadinstitute/sting/gatk/io/ThreadLocalOutputTracker.java @@ -30,6 +30,7 @@ import org.broadinstitute.sting.gatk.io.storage.StorageFactory; import org.broadinstitute.sting.gatk.io.storage.Storage; import org.broadinstitute.sting.gatk.executive.OutputMergeTask; import org.broadinstitute.sting.utils.StingException; +import org.broadinstitute.sting.utils.exceptions.UserError; import java.util.*; import java.io.File; @@ -121,7 +122,7 @@ public class ThreadLocalOutputTracker extends OutputTracker { tempFile.deleteOnExit(); } catch( IOException ex ) { - throw new StingException("Unable to create temporary file for stub: " + stub.getClass().getName() ); + throw new UserError.BadTmpDir("Unable to create temporary file for stub: " + stub.getClass().getName() ); } return tempFile; diff --git a/java/src/org/broadinstitute/sting/gatk/io/storage/OutputStreamStorage.java b/java/src/org/broadinstitute/sting/gatk/io/storage/OutputStreamStorage.java index 33456456d..1ab1cefde 100644 --- a/java/src/org/broadinstitute/sting/gatk/io/storage/OutputStreamStorage.java +++ b/java/src/org/broadinstitute/sting/gatk/io/storage/OutputStreamStorage.java @@ -28,6 +28,7 @@ package org.broadinstitute.sting.gatk.io.storage; import org.broadinstitute.sting.utils.StingException; import org.broadinstitute.sting.gatk.io.stubs.OutputStreamStub; import org.broadinstitute.sting.gatk.io.storage.Storage; +import org.broadinstitute.sting.utils.exceptions.UserError; import java.io.*; import java.nio.channels.FileChannel; @@ -72,7 +73,7 @@ public class OutputStreamStorage extends OutputStream implements Storage, VCFWriter { stream = new PrintStream(file); } catch(IOException ex) { - throw new StingException("Unable to open target output stream", ex); + throw new UserError.CouldNotCreateOutputFile(file, "Unable to open target output stream", ex); } } else if ( stub.getOutputStream() != null ) { @@ -63,7 +64,7 @@ public class VCFWriterStorage implements Storage, VCFWriter { this.stream = new PrintStream(file); } catch(IOException ex) { - throw new StingException("Unable to open target output stream",ex); + throw new UserError.CouldNotCreateOutputFile(file, "Unable to open target output stream",ex); } writer = new StandardVCFWriter(this.stream); writer.writeHeader(stub.getVCFHeader()); @@ -106,7 +107,7 @@ public class VCFWriterStorage implements Storage, VCFWriter { reader.close(); } catch (IOException e) { - throw new StingException("Error reading file " + file + " in VCFWriterStorage: ", e); + throw new UserError.CouldNotReadInputFile(file, "Error reading file in VCFWriterStorage: ", e); } } } diff --git a/java/src/org/broadinstitute/sting/gatk/iterators/LocusIteratorByState.java b/java/src/org/broadinstitute/sting/gatk/iterators/LocusIteratorByState.java index a5902a273..44334983c 100755 --- a/java/src/org/broadinstitute/sting/gatk/iterators/LocusIteratorByState.java +++ b/java/src/org/broadinstitute/sting/gatk/iterators/LocusIteratorByState.java @@ -34,6 +34,7 @@ import org.broadinstitute.sting.gatk.DownsamplingMethod; import org.broadinstitute.sting.gatk.DownsampleType; import org.broadinstitute.sting.gatk.contexts.AlignmentContext; import org.broadinstitute.sting.utils.*; +import org.broadinstitute.sting.utils.exceptions.UserError; import org.broadinstitute.sting.utils.pileup.*; import java.util.*; @@ -197,7 +198,7 @@ public class LocusIteratorByState extends LocusIterator { if ( generateExtendedEvents ) { // we see insertions only once, when we step right onto them; the position on the read is scrolled // past the insertion right after that - if ( eventDelayedFlag > 1 ) throw new StingException("Adjacent I/D events in read "+read.getReadName()); + if ( eventDelayedFlag > 1 ) throw new UserError.MalformedBam(read, "Adjacent I/D events in read "+read.getReadName()); insertedBases = Arrays.copyOfRange(read.getReadBases(),readOffset+1,readOffset+1+curElement.getLength()); eventLength = curElement.getLength() ; eventStart = readOffset; @@ -213,7 +214,7 @@ public class LocusIteratorByState extends LocusIterator { if ( cigarElementCounter == 1) { // generate an extended event only if we just stepped into the deletion (i.e. don't // generate the event at every deleted position on the ref, that's what cigarElementCounter==1 is for!) - if ( eventDelayedFlag > 1 ) throw new StingException("Adjacent I/D events in read "+read.getReadName()); + if ( eventDelayedFlag > 1 ) throw new UserError.MalformedBam(read, "Adjacent I/D events in read "+read.getReadName()); eventLength = curElement.getLength(); eventDelayedFlag = 2; // deletion on the ref causes an immediate return, so we have to delay by 1 only eventStart = readOffset; @@ -545,7 +546,7 @@ public class LocusIteratorByState extends LocusIterator { switch(this.downsamplingMethod.type) { case BY_SAMPLE: if(downsamplingMethod.toCoverage == null) - throw new StingException("Downsampling coverage (-dcov) must be specified when downsampling by sample"); + throw new UserError.BadArgumentValue("dcov", "Downsampling coverage (-dcov) must be specified when downsampling by sample"); this.targetCoverage = downsamplingMethod.toCoverage; break; default: diff --git a/java/src/org/broadinstitute/sting/gatk/refdata/RODRecordIterator.java b/java/src/org/broadinstitute/sting/gatk/refdata/RODRecordIterator.java index fa53f9513..07c2709f0 100644 --- a/java/src/org/broadinstitute/sting/gatk/refdata/RODRecordIterator.java +++ b/java/src/org/broadinstitute/sting/gatk/refdata/RODRecordIterator.java @@ -25,6 +25,7 @@ package org.broadinstitute.sting.gatk.refdata; +import org.broadinstitute.sting.utils.exceptions.UserError; import org.broadinstitute.sting.utils.text.XReadLines; import org.broadinstitute.sting.utils.Utils; import org.broadinstitute.sting.utils.StingException; @@ -130,7 +131,7 @@ public class RODRecordIterator implements Ite try { header = rod.initialize(file); } catch (FileNotFoundException e) { - throw new StingException("ROD "+type.getName() + " failed to initialize properly from file "+file); + throw new UserError.CouldNotReadInputFile(file, "ROD "+type.getName() + " failed to initialize properly from file "+file); } } @@ -194,9 +195,9 @@ public class RODRecordIterator implements Ite parsed_ok = n.parseLine(header,parts) ; } catch ( Exception e ) { - throw new StingException("Failed to parse ROD data ("+type.getName()+") from file "+ file + " at line #"+linenum+ - "\nOffending line: "+line+ - "\nReason ("+e.getClass().getName()+"): "+e.getMessage(),e); + throw new UserError.MalformedFile(file, "Failed to parse ROD data ("+type.getName()+") from file "+ file + " at line #"+linenum+ + "\nOffending line: "+line+ + "\nReason ("+e.getClass().getName()+")", e); } } diff --git a/java/src/org/broadinstitute/sting/gatk/refdata/ReferenceOrderedData.java b/java/src/org/broadinstitute/sting/gatk/refdata/ReferenceOrderedData.java index f00b36f0e..eaa8ab01f 100644 --- a/java/src/org/broadinstitute/sting/gatk/refdata/ReferenceOrderedData.java +++ b/java/src/org/broadinstitute/sting/gatk/refdata/ReferenceOrderedData.java @@ -2,6 +2,7 @@ package org.broadinstitute.sting.gatk.refdata; import org.apache.log4j.Logger; import org.broadinstitute.sting.utils.StingException; +import org.broadinstitute.sting.utils.exceptions.UserError; import java.io.*; import java.lang.reflect.Method; @@ -41,7 +42,7 @@ public class ReferenceOrderedData implements try { str = new BufferedReader(new FileReader(new File(filename))); } catch (FileNotFoundException e) { - throw new StingException("Unable to load the ROD input file " + filename,e); + throw new UserError.CouldNotReadInputFile(new File(filename), "Unable to load the ROD input file", e); } String line = "NO LINES READ IN"; try { @@ -50,7 +51,7 @@ public class ReferenceOrderedData implements else logger.warn("the following file line didn't parsing into a triplet -> " + line); } } catch (IOException e) { - throw new StingException("Failed reading the input rod file " + filename + " last line read was " + line,e); + throw new UserError.CouldNotReadInputFile(new File(filename), "Failed reading the input rod file; last line read was " + line, e); } } diff --git a/java/src/org/broadinstitute/sting/gatk/refdata/SeekableRODIterator.java b/java/src/org/broadinstitute/sting/gatk/refdata/SeekableRODIterator.java index d670c9bfc..9229a8271 100644 --- a/java/src/org/broadinstitute/sting/gatk/refdata/SeekableRODIterator.java +++ b/java/src/org/broadinstitute/sting/gatk/refdata/SeekableRODIterator.java @@ -8,6 +8,7 @@ import org.broadinstitute.sting.gatk.refdata.utils.RODRecordList; import org.broadinstitute.sting.utils.GenomeLoc; import org.broadinstitute.sting.utils.GenomeLocParser; import org.broadinstitute.sting.utils.StingException; +import org.broadinstitute.sting.utils.exceptions.UserError; import java.util.Iterator; import java.util.LinkedList; @@ -164,12 +165,12 @@ public class SeekableRODIterator implements LocationAwareSeekableRODIterator { } int that_contig = r.getLocation().getContigIndex(); if ( curr_contig > that_contig ) - throw new StingException("LocationAwareSeekableRODIterator: contig " +r.getLocation().getContig() + + throw new UserError("LocationAwareSeekableRODIterator: contig " +r.getLocation().getContig() + " occurs out of order in track " + r.getName() ); if ( curr_contig < that_contig ) break; // next record is on a higher contig, we do not need it yet... if ( r.getLocation().getStart() < curr_position ) - throw new StingException("LocationAwareSeekableRODIterator: track "+r.getName() + + throw new UserError("LocationAwareSeekableRODIterator: track "+r.getName() + " is out of coordinate order on contig "+r.getLocation() + " compared to " + curr_contig + ":" + curr_position); if ( r.getLocation().getStart() > curr_position ) break; // next record starts after the current position; we do not need it yet diff --git a/java/src/org/broadinstitute/sting/gatk/refdata/features/refseq/RefSeqCodec.java b/java/src/org/broadinstitute/sting/gatk/refdata/features/refseq/RefSeqCodec.java index fcdc12610..d1c7142f0 100644 --- a/java/src/org/broadinstitute/sting/gatk/refdata/features/refseq/RefSeqCodec.java +++ b/java/src/org/broadinstitute/sting/gatk/refdata/features/refseq/RefSeqCodec.java @@ -7,6 +7,7 @@ import org.broad.tribble.readers.LineReader; import org.broadinstitute.sting.utils.GenomeLoc; import org.broadinstitute.sting.utils.GenomeLocParser; import org.broadinstitute.sting.utils.StingException; +import org.broadinstitute.sting.utils.exceptions.UserError; import java.io.IOException; import java.util.ArrayList; @@ -40,7 +41,7 @@ public class RefSeqCodec implements FeatureCodec { feature.setTranscript_id(fields[1]); if ( fields[3].length()==1 && fields[3].charAt(0)=='+') feature.setStrand(1); else if ( fields[3].length()==1 && fields[3].charAt(0)=='-') feature.setStrand(-1); - else throw new StingException("Expected strand symbol (+/-), found: "+fields[3]); + else throw new UserError.MalformedFile("Expected strand symbol (+/-), found: "+fields[3]); feature.setTranscript_interval(GenomeLocParser.parseGenomeLoc(contig_name, Integer.parseInt(fields[4])+1, Integer.parseInt(fields[5]))); diff --git a/java/src/org/broadinstitute/sting/gatk/refdata/tracks/TribbleTrack.java b/java/src/org/broadinstitute/sting/gatk/refdata/tracks/TribbleTrack.java index 36a7ed414..ef4d71b59 100644 --- a/java/src/org/broadinstitute/sting/gatk/refdata/tracks/TribbleTrack.java +++ b/java/src/org/broadinstitute/sting/gatk/refdata/tracks/TribbleTrack.java @@ -32,6 +32,7 @@ import org.broadinstitute.sting.gatk.refdata.utils.FeatureToGATKFeatureIterator; import org.broadinstitute.sting.gatk.refdata.utils.GATKFeature; import org.broadinstitute.sting.utils.GenomeLoc; import org.broadinstitute.sting.utils.StingException; +import org.broadinstitute.sting.utils.exceptions.UserError; import java.io.File; import java.io.IOException; @@ -80,7 +81,7 @@ public class TribbleTrack extends RMDTrack implements QueryableTrack { try { return new FeatureToGATKFeatureIterator(reader.iterator(),this.getName()); } catch (IOException e) { - throw new StingException("Unable to read from file",e); + throw new UserError.CouldNotReadInputFile(getFile(), "Unable to read from file", e); } } diff --git a/java/src/org/broadinstitute/sting/gatk/refdata/tracks/builders/TribbleRMDTrackBuilder.java b/java/src/org/broadinstitute/sting/gatk/refdata/tracks/builders/TribbleRMDTrackBuilder.java index eeec135aa..c036e596f 100644 --- a/java/src/org/broadinstitute/sting/gatk/refdata/tracks/builders/TribbleRMDTrackBuilder.java +++ b/java/src/org/broadinstitute/sting/gatk/refdata/tracks/builders/TribbleRMDTrackBuilder.java @@ -42,6 +42,7 @@ import org.broadinstitute.sting.gatk.refdata.tracks.RMDTrackCreationException; import org.broadinstitute.sting.utils.collections.Pair; import org.broadinstitute.sting.utils.classloader.PluginManager; import org.broadinstitute.sting.utils.StingException; +import org.broadinstitute.sting.utils.exceptions.UserError; import org.broadinstitute.sting.utils.file.FSLockWithShared; import org.broadinstitute.sting.utils.file.FileSystemInabilityToLockException; @@ -102,7 +103,7 @@ public class TribbleRMDTrackBuilder extends PluginManager implemen public RMDTrack createInstanceOfTrack(Class targetClass, String name, File inputFile) throws RMDTrackCreationException { // return a feature reader track Pair pair = createFeatureReader(targetClass, name, inputFile); - if (pair == null) throw new StingException("Unable to make the feature reader for input file " + inputFile); + if (pair == null) throw new UserError.CouldNotReadInputFile(inputFile, "Unable to make the feature reader for input file"); return new TribbleTrack(targetClass, name, inputFile, pair.first, pair.second, createCodec(targetClass, name)); } @@ -142,7 +143,7 @@ public class TribbleRMDTrackBuilder extends PluginManager implemen try { return new Pair(BasicFeatureSource.getFeatureSource(inputFile.getAbsolutePath(), createCodec(targetClass, name)),null); } catch (IOException e) { - throw new StingException("Unable to create feature reader from file " + inputFile); + throw new UserError.CouldNotReadInputFile(inputFile, "Unable to create feature reader from file", e); } } @@ -169,9 +170,9 @@ public class TribbleRMDTrackBuilder extends PluginManager implemen createCodec(targetClass, name)), sequenceSetToDictionary(index.getSequenceNames())); } catch (FileNotFoundException e) { - throw new StingException("Unable to create reader with file " + inputFile, e); + throw new UserError.CouldNotReadInputFile(inputFile, "Unable to create reader with file", e); } catch (IOException e) { - throw new StingException("Unable to make the index file for " + inputFile, e); + throw new UserError("Unable to make the index file for " + inputFile, e); } return reader; } diff --git a/java/src/org/broadinstitute/sting/gatk/walkers/analyzeannotations/AnnotationDataManager.java b/java/src/org/broadinstitute/sting/gatk/walkers/analyzeannotations/AnnotationDataManager.java index 178f73c1a..49377e8f4 100755 --- a/java/src/org/broadinstitute/sting/gatk/walkers/analyzeannotations/AnnotationDataManager.java +++ b/java/src/org/broadinstitute/sting/gatk/walkers/analyzeannotations/AnnotationDataManager.java @@ -3,7 +3,9 @@ package org.broadinstitute.sting.gatk.walkers.analyzeannotations; import org.broad.tribble.util.variantcontext.VariantContext; import org.broadinstitute.sting.utils.BaseUtils; import org.broadinstitute.sting.utils.StingException; +import org.broadinstitute.sting.utils.exceptions.UserError; +import java.io.File; import java.util.*; import java.io.IOException; import java.io.PrintStream; @@ -106,12 +108,12 @@ public class AnnotationDataManager { // For each annotation we've seen for( final String annotationKey : data.keySet() ) { + String filename = OUTPUT_PREFIX + annotationKey + ".dat"; PrintStream output; try { - output = new PrintStream(OUTPUT_PREFIX + annotationKey + ".dat"); // Create the intermediate data file for this annotation + output = new PrintStream(filename); // Create the intermediate data file for this annotation } catch ( FileNotFoundException e ) { - throw new StingException("Can't create intermediate output annotation data file. Does the output directory exist? " + - OUTPUT_PREFIX + annotationKey + ".dat"); + throw new UserError.CouldNotCreateOutputFile(new File(filename), "Can't create intermediate output annotation data file. Does the output directory exist?", e); } // Output a header line @@ -162,7 +164,7 @@ public class AnnotationDataManager { try { Runtime.getRuntime().exec( rScriptCommandLine ); } catch ( IOException e ) { - throw new StingException( "Unable to execute RScript command: " + rScriptCommandLine ); + throw new UserError.CannotExecuteRScript( rScriptCommandLine, e ); } } } diff --git a/java/src/org/broadinstitute/sting/gatk/walkers/annotator/VariantAnnotatorEngine.java b/java/src/org/broadinstitute/sting/gatk/walkers/annotator/VariantAnnotatorEngine.java index 199ad777e..3a19ed2bb 100755 --- a/java/src/org/broadinstitute/sting/gatk/walkers/annotator/VariantAnnotatorEngine.java +++ b/java/src/org/broadinstitute/sting/gatk/walkers/annotator/VariantAnnotatorEngine.java @@ -51,6 +51,7 @@ import org.broadinstitute.sting.gatk.walkers.annotator.interfaces.*; import org.broadinstitute.sting.gatk.walkers.annotator.genomicannotator.*; import org.broadinstitute.sting.utils.StingException; import org.broadinstitute.sting.utils.classloader.PackageUtils; +import org.broadinstitute.sting.utils.exceptions.UserError; public class VariantAnnotatorEngine { @@ -104,7 +105,7 @@ public class VariantAnnotatorEngine { if ( interfaceClass == null ) interfaceClass = classMap.get(group + "Annotation"); if ( interfaceClass == null ) - throw new StingException("Class " + group + " is not found; please check that you have specified the class name correctly"); + throw new UserError.BadArgumentValue("group", "Class " + group + " is not found; please check that you have specified the class name correctly"); classes.addAll(PackageUtils.getClassesImplementingInterface(interfaceClass)); } // get the specific classes provided @@ -113,7 +114,7 @@ public class VariantAnnotatorEngine { if ( annotationClass == null ) annotationClass = classMap.get(annotation + "Annotation"); if ( annotationClass == null ) - throw new StingException("Class " + annotation + " is not found; please check that you have specified the class name correctly"); + throw new UserError.BadArgumentValue("annotation", "Class " + annotation + " is not found; please check that you have specified the class name correctly"); classes.add(annotationClass); } } diff --git a/java/src/org/broadinstitute/sting/gatk/walkers/annotator/genomicannotator/GenomicAnnotation.java b/java/src/org/broadinstitute/sting/gatk/walkers/annotator/genomicannotator/GenomicAnnotation.java index f1bc69dc8..6bff652fd 100644 --- a/java/src/org/broadinstitute/sting/gatk/walkers/annotator/genomicannotator/GenomicAnnotation.java +++ b/java/src/org/broadinstitute/sting/gatk/walkers/annotator/genomicannotator/GenomicAnnotation.java @@ -41,6 +41,7 @@ import org.broadinstitute.sting.gatk.walkers.annotator.VariantAnnotatorEngine; import org.broadinstitute.sting.gatk.walkers.annotator.interfaces.InfoFieldAnnotation; import org.broadinstitute.sting.utils.BaseUtils; import org.broadinstitute.sting.utils.StingException; +import org.broadinstitute.sting.utils.exceptions.UserError; /** * This plugin for {@link VariantAnnotatorEngine} serves as the core @@ -134,7 +135,7 @@ public class GenomicAnnotation implements InfoFieldAnnotation { //continue; //TODO If this site is monomorphic in the VC, and the current record specifies a particular alternate allele, skip this record. Right? //} else if(alternateAlleles.size() > 1) { - throw new StingException("Record [" + vc + "] contains " + alternateAlleles.size() + " alternate alleles. GenomicAnnotion currently only supports annotating 1 alternate allele."); + throw new UserError.MalformedFile("File associated with " + vc.getName() + " contains record [" + vc + "] contains " + alternateAlleles.size() + " alternate alleles. GenomicAnnotion currently only supports annotating 1 alternate allele."); } boolean positiveStrand = true; //if HAPLOTYPE_STRAND_COLUMN isn't specified, assume positive strand. @@ -144,7 +145,7 @@ public class GenomicAnnotation implements InfoFieldAnnotation { if(hapStrandValue.equals("-") || hapStrandValue.equals("r")) { positiveStrand = false; } else if(!hapStrandValue.equals("+") && !hapStrandValue.equals("f")) { - throw new StingException("Record (" + gatkFeature.getUnderlyingObject() + ") in " + name + " has an invalid value for " + HAPLOTYPE_STRAND_COLUMN + ". This value is: \"" + hapStrandValue + "\""); + throw new UserError.MalformedFile("Record (" + gatkFeature.getUnderlyingObject() + ") in " + name + " has an invalid value for " + HAPLOTYPE_STRAND_COLUMN + ". This value is: \"" + hapStrandValue + "\""); } } diff --git a/java/src/org/broadinstitute/sting/gatk/walkers/annotator/genomicannotator/GenomicAnnotator.java b/java/src/org/broadinstitute/sting/gatk/walkers/annotator/genomicannotator/GenomicAnnotator.java index ce3d94f60..ea43b274c 100644 --- a/java/src/org/broadinstitute/sting/gatk/walkers/annotator/genomicannotator/GenomicAnnotator.java +++ b/java/src/org/broadinstitute/sting/gatk/walkers/annotator/genomicannotator/GenomicAnnotator.java @@ -26,6 +26,7 @@ package org.broadinstitute.sting.gatk.walkers.annotator.genomicannotator; +import java.io.File; import java.io.IOException; import java.util.*; import java.util.Map.Entry; @@ -46,6 +47,7 @@ import org.broadinstitute.sting.gatk.walkers.*; import org.broadinstitute.sting.gatk.walkers.annotator.VariantAnnotatorEngine; import org.broadinstitute.sting.utils.SampleUtils; import org.broadinstitute.sting.utils.StingException; +import org.broadinstitute.sting.utils.exceptions.UserError; import org.broadinstitute.sting.utils.vcf.VCFUtils; /** @@ -92,21 +94,22 @@ public class GenomicAnnotator extends RodWalker implements Tre //read all ROD file headers and construct a set of all column names to be used for validation of command-line args final Set allFullyQualifiedColumnNames = new LinkedHashSet(); final Set allBindingNames = new LinkedHashSet(); - try { for(ReferenceOrderedDataSource ds : getToolkit().getRodDataSources()) { if(! ds.getReferenceOrderedData().getType().equals(AnnotatorInputTableCodec.class)) { continue; //skip all non-AnnotatorInputTable files. } final String bindingName = ds.getName(); + File file = ds.getReferenceOrderedData().getFile(); allBindingNames.add(bindingName); - final ArrayList header = AnnotatorInputTableCodec.readHeader(ds.getReferenceOrderedData().getFile()); - for(String columnName : header) { - allFullyQualifiedColumnNames.add(bindingName + "." + columnName); + try { + final ArrayList header = AnnotatorInputTableCodec.readHeader(file); + for(String columnName : header) { + allFullyQualifiedColumnNames.add(bindingName + "." + columnName); + } + } catch(IOException e) { + throw new UserError.CouldNotReadInputFile(file, "Failed when attempting to read file header. ", e); } } - } catch(IOException e) { - throw new StingException("Failed when attempting to read file header. ", e); - } //parse the JOIN_COLUMNS args, read in the specified files, and validate column names in the = relation. This end result of this loop is to populate the List of joinTables with one entry per -J arg. final List joinTables = new LinkedList(); @@ -115,25 +118,25 @@ public class GenomicAnnotator extends RodWalker implements Tre //parse the tokens final String[] arg = joinArg.split(","); if(arg.length != 3) { - throw new StingException("The following -J arg: \"" + joinArg + "\" must contain 3 comma-separated values. (ex: -J name,/path/to/file,name.columnName=name2.columnName2)"); + throw new UserError.BadArgumentValue("-J", "The following -J arg: \"" + joinArg + "\" must contain 3 comma-separated values. (ex: -J name,/path/to/file,name.columnName=name2.columnName2)"); } final String bindingName = arg[0]; final String filename = arg[1]; final String columnsToJoin = arg[2]; if(allBindingNames.contains(bindingName)) { - throw new StingException("The name \"" + bindingName + "\" in the -J arg: \"" + joinArg + "\" has already been used in another binding."); + throw new UserError.BadArgumentValue("-J", "The name \"" + bindingName + "\" in the -J arg: \"" + joinArg + "\" has already been used in another binding."); } String[] splitOnEquals = columnsToJoin.split("=+"); if(splitOnEquals.length != 2) { - throw new StingException("The -J arg: \"" + joinArg + "\" must specify the columns to join on. (ex: -J name,/path/to/file,name.columnName=name2.columnName2)"); + throw new UserError.BadArgumentValue("-J", "The -J arg: \"" + joinArg + "\" must specify the columns to join on. (ex: -J name,/path/to/file,name.columnName=name2.columnName2)"); } String[] splitOnDot1 = splitOnEquals[0].split("\\."); String[] splitOnDot2 = splitOnEquals[1].split("\\."); if(splitOnDot1.length != 2 || splitOnDot2.length != 2) { - throw new StingException("The -J arg: \"" + joinArg + "\" must fully specify the columns to join on. (ex: -J name,/path/to/file,name.columnName=name2.columnName2)"); + throw new UserError.BadArgumentValue("-J", "The -J arg: \"" + joinArg + "\" must fully specify the columns to join on. (ex: -J name,/path/to/file,name.columnName=name2.columnName2)"); } final String bindingName1 = splitOnDot1[0]; @@ -155,13 +158,13 @@ public class GenomicAnnotator extends RodWalker implements Tre externalBindingName = bindingName1; externalColumnName = columnName1; } else { - throw new StingException("The name \"" + bindingName + "\" in the -J arg: \"" + joinArg + "\" must be specified in one the columns to join on. (ex: -J name,/path/to/file,name.columnName=name2.columnName2)"); + throw new UserError.BadArgumentValue("-J", "The name \"" + bindingName + "\" in the -J arg: \"" + joinArg + "\" must be specified in one the columns to join on. (ex: -J name,/path/to/file,name.columnName=name2.columnName2)"); } //validate externalColumnName final String fullyQualifiedExternalColumnName = externalBindingName + '.' + externalColumnName; if( !allFullyQualifiedColumnNames.contains(fullyQualifiedExternalColumnName) ) { - throw new StingException("The -J arg: \"" + joinArg + "\" specifies an unknown column name: \"" + fullyQualifiedExternalColumnName + "\""); + throw new UserError.BadArgumentValue("-J", "The -J arg: \"" + joinArg + "\" specifies an unknown column name: \"" + fullyQualifiedExternalColumnName + "\""); } //read in the file contents into a JoinTable object @@ -179,7 +182,7 @@ public class GenomicAnnotator extends RodWalker implements Tre fullyQualifiedColumnNames.add(localBindingName + '.' + columnName); } if ( !found ) - throw new StingException("The -J arg: \"" + joinArg + "\" specifies an unknown column name: \"" + localColumnName + "\". It's not one of the column names in the header " + columnNames + " of the file: " + filename); + throw new UserError.BadArgumentValue("-J", "The -J arg: \"" + joinArg + "\" specifies an unknown column name: \"" + localColumnName + "\". It's not one of the column names in the header " + columnNames + " of the file: " + filename); allFullyQualifiedColumnNames.addAll(fullyQualifiedColumnNames); } @@ -192,7 +195,7 @@ public class GenomicAnnotator extends RodWalker implements Tre for ( String columnName : SELECT_COLUMNS ) { if ( !allFullyQualifiedColumnNames.contains(columnName) ) - throw new StingException("The column name '" + columnName + "' provided to -s doesn't match any of the column names in any of the -B files. Here is the list of available column names: " + allFullyQualifiedColumnNames); + throw new UserError.BadArgumentValue("-s", "The column name '" + columnName + "' provided to -s doesn't match any of the column names in any of the -B files. Here is the list of available column names: " + allFullyQualifiedColumnNames); } //instantiate the VariantAnnotatorEngine diff --git a/java/src/org/broadinstitute/sting/gatk/walkers/annotator/genomicannotator/JoinTable.java b/java/src/org/broadinstitute/sting/gatk/walkers/annotator/genomicannotator/JoinTable.java index 854139d86..e4c09d4f9 100755 --- a/java/src/org/broadinstitute/sting/gatk/walkers/annotator/genomicannotator/JoinTable.java +++ b/java/src/org/broadinstitute/sting/gatk/walkers/annotator/genomicannotator/JoinTable.java @@ -26,6 +26,7 @@ package org.broadinstitute.sting.gatk.walkers.annotator.genomicannotator; import java.io.BufferedReader; +import java.io.File; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; @@ -33,6 +34,7 @@ import java.util.HashMap; import java.util.List; import org.broadinstitute.sting.utils.StingException; +import org.broadinstitute.sting.utils.exceptions.UserError; /** * This is a container that holds all data corresponding to a single join table as specified by one -J arg (ex: -J bindingName1,/path/to/file,bindingName1.columnName=bindingName2.columnName2). @@ -109,7 +111,7 @@ public class JoinTable } if(localColumnNameIdx == -1) { - throw new StingException("The -J arg specifies an unknown column name: \"" + localColumnName + "\". It's not one of the column names in the header " + columnNames + " of the file: " + filename); + throw new UserError.BadArgumentValue("-J", "The -J arg specifies an unknown column name: \"" + localColumnName + "\". It's not one of the column names in the header " + columnNames + " of the file: " + filename); } //read in all records and create a map entry for each @@ -124,7 +126,7 @@ public class JoinTable } catch(IOException e) { - throw new StingException("Unable to parse file: " + filename, e); + throw new UserError.CouldNotReadInputFile(new File(filename), "Unable to parse file", e); } finally { diff --git a/java/src/org/broadinstitute/sting/gatk/walkers/annotator/genomicannotator/JoinTableParser.java b/java/src/org/broadinstitute/sting/gatk/walkers/annotator/genomicannotator/JoinTableParser.java index b624b2dfb..a4f25a516 100755 --- a/java/src/org/broadinstitute/sting/gatk/walkers/annotator/genomicannotator/JoinTableParser.java +++ b/java/src/org/broadinstitute/sting/gatk/walkers/annotator/genomicannotator/JoinTableParser.java @@ -33,6 +33,7 @@ import java.util.List; import org.broadinstitute.sting.utils.StingException; import org.broadinstitute.sting.utils.Utils; +import org.broadinstitute.sting.utils.exceptions.UserError; /** * Used to parse files passed to the GenomicAnnotator via the -J arg. @@ -90,7 +91,7 @@ public class JoinTableParser final ArrayList values = Utils.split(line, DELIMITER, header.size()); if ( values.size() != header.size() ) { - throw new StingException(String.format("Encountered a row with %d columns which is different from the number or columns in the header: %d\nHeader: " + header + "\nLine: " + values, values.size(), header.size())); + throw new UserError.MalformedFile(String.format("Encountered a row with %d columns which is different from the number or columns in the header: %d\nHeader: " + header + "\nLine: " + values, values.size(), header.size())); } return values; diff --git a/java/src/org/broadinstitute/sting/gatk/walkers/annotator/genomicannotator/TranscriptToGenomicInfo.java b/java/src/org/broadinstitute/sting/gatk/walkers/annotator/genomicannotator/TranscriptToGenomicInfo.java index 53c63a467..e80a8ca43 100755 --- a/java/src/org/broadinstitute/sting/gatk/walkers/annotator/genomicannotator/TranscriptToGenomicInfo.java +++ b/java/src/org/broadinstitute/sting/gatk/walkers/annotator/genomicannotator/TranscriptToGenomicInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010. + * Copyright (c) 2010, The Broad Institute * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -12,15 +12,14 @@ * * 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. + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. */ package org.broadinstitute.sting.gatk.walkers.annotator.genomicannotator; diff --git a/java/src/org/broadinstitute/sting/gatk/walkers/genotyper/BatchedCallsMerger.java b/java/src/org/broadinstitute/sting/gatk/walkers/genotyper/BatchedCallsMerger.java index 17db761eb..6dafd5869 100755 --- a/java/src/org/broadinstitute/sting/gatk/walkers/genotyper/BatchedCallsMerger.java +++ b/java/src/org/broadinstitute/sting/gatk/walkers/genotyper/BatchedCallsMerger.java @@ -136,7 +136,7 @@ public class BatchedCallsMerger extends LocusWalker imp return VariantContextUtils.simpleMerge(calls, ref.getBase()); } - private AlignmentContext filterForSamples(ReadBackedPileup pileup, Set samples) { + public static AlignmentContext filterForSamples(ReadBackedPileup pileup, Set samples) { ArrayList newPileup = new ArrayList(); diff --git a/java/src/org/broadinstitute/sting/gatk/walkers/varianteval/VariantEvalWalker.java b/java/src/org/broadinstitute/sting/gatk/walkers/varianteval/VariantEvalWalker.java index 853e9961d..c0ca1e5af 100755 --- a/java/src/org/broadinstitute/sting/gatk/walkers/varianteval/VariantEvalWalker.java +++ b/java/src/org/broadinstitute/sting/gatk/walkers/varianteval/VariantEvalWalker.java @@ -127,7 +127,7 @@ public class VariantEvalWalker extends RodWalker { // "set == \"HiSeq.WGS.cleaned.ug.vcf\" || set == \"Intersection\"", // "set == \"HiSeq.WGS.raw.OQ.ug.vcf\"", // "set == \"HiSeq.WGS.raw.OQ.ug.vcf\" || set == \"Intersection\""}; - + @Argument(shortName="selectName", doc="Names to use for the list of stratifications (must be a 1-to-1 mapping)", required=false) protected ArrayList SELECT_NAMES = new ArrayList(); //protected String[] SELECT_NAMES = {"Intersection", "x1", "x2", "x3", "x4"}; @@ -205,7 +205,7 @@ public class VariantEvalWalker extends RodWalker { protected boolean aatUseCodons = false; @Argument(shortName="disI", fullName="discordantInteresting", doc="If passed, write discordant sites as interesting", required=false) - protected boolean DISCORDANT_INTERESTING = false; + protected boolean DISCORDANT_INTERESTING = false; @Argument(fullName="tranchesFile", shortName="tf", doc="The input tranches file describing where to cut the data", required=false) private String TRANCHE_FILENAME = null; @@ -546,20 +546,20 @@ public class VariantEvalWalker extends RodWalker { comp.getNegLog10PError() < (minCompQualScore / 10.0) ) comp = null; - String interesting = evaluation.update2( evalWantsVC ? vc : null, comp, tracker, ref, context, group ); + String interesting = evaluation.update2( evalWantsVC ? vc : null, comp, tracker, ref, context, group ); - /** TODO - -- for Eric: Fix me (current implementation causes GenotypeConcordance - to treat sites that don't match JEXL as no-calls) + /** TODO + -- for Eric: Fix me (current implementation causes GenotypeConcordance + to treat sites that don't match JEXL as no-calls) + + String interesting = null; + if (evalWantsVC) + { + interesting = evaluation.update2( evalWantsVC ? vc : null, comp, tracker, ref, context, group ); + } + **/ - String interesting = null; - if (evalWantsVC) - { - interesting = evaluation.update2( evalWantsVC ? vc : null, comp, tracker, ref, context, group ); - } - **/ - if ( interesting != null ) interestingReasons.add(interesting); break; default: diff --git a/java/src/org/broadinstitute/sting/gatk/walkers/variantutils/CombineVariants.java b/java/src/org/broadinstitute/sting/gatk/walkers/variantutils/CombineVariants.java index 0b981b632..7f90e7b1c 100755 --- a/java/src/org/broadinstitute/sting/gatk/walkers/variantutils/CombineVariants.java +++ b/java/src/org/broadinstitute/sting/gatk/walkers/variantutils/CombineVariants.java @@ -37,9 +37,9 @@ import org.broadinstitute.sting.gatk.walkers.RodWalker; import org.broadinstitute.sting.gatk.walkers.Window; import org.broadinstitute.sting.gatk.walkers.annotator.VariantAnnotatorEngine; import org.broadinstitute.sting.utils.SampleUtils; -import org.broadinstitute.sting.utils.StingException; import org.broadinstitute.sting.commandline.Argument; import org.broadinstitute.sting.commandline.Output; +import org.broadinstitute.sting.utils.exceptions.UserError; import org.broadinstitute.sting.utils.vcf.VCFUtils; import java.util.*; @@ -107,7 +107,7 @@ public class CombineVariants extends RodWalker { Set rodNames = SampleUtils.getRodNamesWithVCFHeader(getToolkit(), null); if ( genotypeMergeOption == VariantContextUtils.GenotypeMergeType.PRIORITIZE && PRIORITY_STRING == null ) - throw new StingException("Priority string must be provided if you want to prioritize genotypes"); + throw new UserError.MissingArgument("rod_priority_list", "Priority string must be provided if you want to prioritize genotypes"); if ( genotypeMergeOption == VariantContextUtils.GenotypeMergeType.PRIORITIZE ) priority = new ArrayList(Arrays.asList(PRIORITY_STRING.split(","))); @@ -115,10 +115,10 @@ public class CombineVariants extends RodWalker { priority = new ArrayList(rodNames); if ( rodNames.size() != priority.size() ) - throw new StingException("The priority list must contain exactly one rod binding per ROD provided to the GATK: rodNames=" + rodNames + " priority=" + priority); + throw new UserError.BadArgumentValue("rod_priority_list", "The priority list must contain exactly one rod binding per ROD provided to the GATK: rodNames=" + rodNames + " priority=" + priority); if ( ! rodNames.containsAll(priority) ) - throw new StingException("Not all priority elements provided as input RODs: " + PRIORITY_STRING); + throw new UserError.BadArgumentValue("rod_priority_list", "Not all priority elements provided as input RODs: " + PRIORITY_STRING); } public Integer map(RefMetaDataTracker tracker, ReferenceContext ref, AlignmentContext context) { diff --git a/java/src/org/broadinstitute/sting/gatk/walkers/variantutils/VariantsToTable.java b/java/src/org/broadinstitute/sting/gatk/walkers/variantutils/VariantsToTable.java index ddf5b38db..712bda9d6 100755 --- a/java/src/org/broadinstitute/sting/gatk/walkers/variantutils/VariantsToTable.java +++ b/java/src/org/broadinstitute/sting/gatk/walkers/variantutils/VariantsToTable.java @@ -64,8 +64,8 @@ public class VariantsToTable extends RodWalker { public int MAX_RECORDS = -1; int nRecords = 0; - @Argument(fullName="allowMultiAllelic", shortName="AMA", doc="If provided, we will not require the site to be biallelic", required=false) - public boolean allowMultiAllelic = false; + @Argument(fullName="ignoreMultiAllelic", shortName="IMA", doc="If provided, we will not require the site to be biallelic", required=false) + public boolean ignoreMultiAllelic = false; private List fieldsToTake; @@ -114,7 +114,7 @@ public class VariantsToTable extends RodWalker { if ( ++nRecords < MAX_RECORDS || MAX_RECORDS == -1 ) { Collection vcs = tracker.getAllVariantContexts(ref, context.getLocation()); for ( VariantContext vc : vcs) { - if ( allowMultiAllelic || vc.isBiallelic() ) { + if ( ! ignoreMultiAllelic || vc.isBiallelic() ) { List vals = new ArrayList(); for ( String field : fieldsToTake ) { diff --git a/java/src/org/broadinstitute/sting/oneoffprojects/tools/JavaIOSpeedTest.java b/java/src/org/broadinstitute/sting/oneoffprojects/tools/JavaIOSpeedTest.java index ebb38bac9..47ee352d4 100755 --- a/java/src/org/broadinstitute/sting/oneoffprojects/tools/JavaIOSpeedTest.java +++ b/java/src/org/broadinstitute/sting/oneoffprojects/tools/JavaIOSpeedTest.java @@ -66,7 +66,11 @@ public class JavaIOSpeedTest extends CommandLineProgram { public static void main(String args[]) { - CommandLineProgram.start(new JavaIOSpeedTest(), args); + try { + CommandLineProgram.start(new JavaIOSpeedTest(), args); + } catch (Exception e) { + throw new RuntimeException(e); + } } } diff --git a/java/src/org/broadinstitute/sting/utils/exceptions/UserError.java b/java/src/org/broadinstitute/sting/utils/exceptions/UserError.java new file mode 100644 index 000000000..79f42d4ad --- /dev/null +++ b/java/src/org/broadinstitute/sting/utils/exceptions/UserError.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2010, 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.utils.exceptions; + +import net.sf.samtools.SAMRecord; +import org.broadinstitute.sting.utils.StingException; + +import java.io.File; + +/** + * Represents the common user errors detected by Sting / GATK + * + * Root class for all GATK user errors, as well as the container for errors themselves + * + * User: depristo + * Date: Sep 3, 2010 + * Time: 2:24:09 PM + */ +public class UserError extends StingException { + public UserError(String msg) { super(msg); } + public UserError(String msg, Throwable e) { super(msg, e); } + private UserError(Throwable e) { super("", e); } // cannot be called, private access + + // todo -- fix up exception cause passing + public static class MissingArgument extends UserError { + public MissingArgument(String arg, String message) { + super(String.format("Argument %s was missing: %s", arg, message)); + } + } + + public static class BadArgumentValue extends UserError { + public BadArgumentValue(String arg, String message) { + super(String.format("Argument %s has a bad value: %s", arg, message)); + } + } + + public static class BadTmpDir extends UserError { + public BadTmpDir(String message) { + super(String.format("Failure working with the tmp directory %s. Override with -Djava.io.tmpdir=X on the command line to a bigger/better file system. Exact error was %s", System.getProperties().get("java.io. tmpdir"), message)); + } + } + + public static class CouldNotReadInputFile extends UserError { + public CouldNotReadInputFile(File file, String message) { + super(String.format("Couldn't read file %s because %s", file.getAbsolutePath(), message)); + } + + public CouldNotReadInputFile(File file, String message, Exception e) { + super(String.format("Couldn't read file %s because %s with exception %s", file.getAbsolutePath(), message, e.getMessage())); + } + + public CouldNotReadInputFile(File file, Exception e) { + this(file, e.getMessage()); + } + } + + + public static class CouldNotCreateOutputFile extends UserError { + public CouldNotCreateOutputFile(File file, String message, Exception e) { + super(String.format("Couldn't write file %s because %s with exception %s", file.getAbsolutePath(), message, e.getMessage())); + } + } + + public static class MalformedBam extends UserError { + public MalformedBam(SAMRecord read, String message) { + super(String.format("SAM/BAM file %s is malformed: %s", read.getFileSource(), message)); + } + } + + public static class MalformedFile extends UserError { + public MalformedFile(String message) { + super(String.format("Unknown file is malformed: %s", message)); + } + + public MalformedFile(String message, Exception e) { + super(String.format("Unknown file is malformed: %s caused by %s", message, e.getMessage())); + } + + public MalformedFile(File f, String message, Exception e) { + super(String.format("File %s is malformed: %s caused by %s", f.getAbsolutePath(), message, e.getMessage())); + } + } + + public static class CannotExecuteRScript extends UserError { + public CannotExecuteRScript(String message, Exception e) { + super(String.format("Unable to execute RScript command: " + message), e); + } + } + +} diff --git a/java/test/org/broadinstitute/sting/WalkerTest.java b/java/test/org/broadinstitute/sting/WalkerTest.java index 1b2ecb68f..36224c9b3 100755 --- a/java/test/org/broadinstitute/sting/WalkerTest.java +++ b/java/test/org/broadinstitute/sting/WalkerTest.java @@ -281,7 +281,11 @@ public class WalkerTest extends BaseTest { cmd2[command.length+3] = ENABLE_REPORTING ? "STANDARD" : "NO_ET"; // run the executable - CommandLineExecutable.start(instance, cmd2); + try { + CommandLineExecutable.start(instance, cmd2); + } catch (Exception e) { + throw new RuntimeException(e); + } // catch failures from the integration test if (CommandLineExecutable.result != 0) { diff --git a/java/test/org/broadinstitute/sting/gatk/walkers/variantrecalibration/VariantRecalibrationWalkersIntegrationTest.java b/java/test/org/broadinstitute/sting/gatk/walkers/variantrecalibration/VariantRecalibrationWalkersIntegrationTest.java index f12507c98..9836001b5 100755 --- a/java/test/org/broadinstitute/sting/gatk/walkers/variantrecalibration/VariantRecalibrationWalkersIntegrationTest.java +++ b/java/test/org/broadinstitute/sting/gatk/walkers/variantrecalibration/VariantRecalibrationWalkersIntegrationTest.java @@ -11,34 +11,35 @@ public class VariantRecalibrationWalkersIntegrationTest extends WalkerTest { static HashMap tranchesFiles = new HashMap(); static HashMap inputVCFFiles = new HashMap(); - @Test - public void testGenerateVariantClusters() { - HashMap e = new HashMap(); - e.put( validationDataLocation + "yri.trio.gatk_glftrio.intersection.annotated.filtered.chr1.vcf", "7c5431a560e9ca257523cf68b808b058" ); - e.put( validationDataLocation + "lowpass.N3.chr1.raw.vcf", "a438635bc96a80c5e6f090d82a394819" ); + // commented out until fixed in SVN + // @Test + // public void testGenerateVariantClusters() { + // HashMap e = new HashMap(); + // e.put( validationDataLocation + "yri.trio.gatk_glftrio.intersection.annotated.filtered.chr1.vcf", "7c5431a560e9ca257523cf68b808b058" ); + // e.put( validationDataLocation + "lowpass.N3.chr1.raw.vcf", "a438635bc96a80c5e6f090d82a394819" ); - for ( Map.Entry entry : e.entrySet() ) { - String vcf = entry.getKey(); - String md5 = entry.getValue(); + // for ( Map.Entry entry : e.entrySet() ) { + // String vcf = entry.getKey(); + // String md5 = entry.getValue(); - WalkerTest.WalkerTestSpec spec = new WalkerTest.WalkerTestSpec( - "-R " + b36KGReference + - " --DBSNP " + GATKDataLocation + "dbsnp_129_b36.rod" + - " -B:hapmap,VCF " + comparisonDataLocation + "Validated/HapMap/3.2/genotypes_r27_nr.b36_fwd.vcf" + - " -weightDBSNP 0.2 -weightHapMap 1.0" + - " -T GenerateVariantClusters" + - " -B:input,VCF " + vcf + - " -L 1:50,000,000-200,000,000" + - " -qual 50.0" + - " --ignore_filter GATK_STANDARD" + - " -an QD -an HRun -an SB" + - " -clusterFile %s", - 1, // just one output file - Arrays.asList(md5)); - List result = executeTest("testGenerateVariantClusters", spec).getFirst(); - clusterFiles.put(vcf, result.get(0).getAbsolutePath()); - } - } + // WalkerTest.WalkerTestSpec spec = new WalkerTest.WalkerTestSpec( + // "-R " + b36KGReference + + // " --DBSNP " + GATKDataLocation + "dbsnp_129_b36.rod" + + // " -B:hapmap,VCF " + comparisonDataLocation + "Validated/HapMap/3.2/genotypes_r27_nr.b36_fwd.vcf" + + // " -weightDBSNP 0.2 -weightHapMap 1.0" + + // " -T GenerateVariantClusters" + + // " -B:input,VCF " + vcf + + // " -L 1:50,000,000-200,000,000" + + // " -qual 50.0" + + // " --ignore_filter GATK_STANDARD" + + // " -an QD -an HRun -an SB" + + // " -clusterFile %s", + // 1, // just one output file + // Arrays.asList(md5)); + // List result = executeTest("testGenerateVariantClusters", spec).getFirst(); + // clusterFiles.put(vcf, result.get(0).getAbsolutePath()); + // } + // } @Test public void testVariantRecalibrator() {