From 66c652d687ec5b5e15b33255441e31b775d20c3c Mon Sep 17 00:00:00 2001 From: Eric Banks Date: Thu, 14 Jul 2011 11:56:10 -0400 Subject: [PATCH 02/35] Added some extra error checks in the VCF codec. Now that we've moved this back into the GATK, changed some of the standard exceptions to be USerErrors (instead of TribbleExceptions). --- .../utils/codecs/vcf/AbstractVCFCodec.java | 25 ++++++++++--------- .../sting/utils/exceptions/UserException.java | 10 ++++++++ 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/public/java/src/org/broadinstitute/sting/utils/codecs/vcf/AbstractVCFCodec.java b/public/java/src/org/broadinstitute/sting/utils/codecs/vcf/AbstractVCFCodec.java index 01344a117..710127f7a 100755 --- a/public/java/src/org/broadinstitute/sting/utils/codecs/vcf/AbstractVCFCodec.java +++ b/public/java/src/org/broadinstitute/sting/utils/codecs/vcf/AbstractVCFCodec.java @@ -7,6 +7,8 @@ import org.broad.tribble.NameAwareCodec; import org.broad.tribble.TribbleException; import org.broad.tribble.readers.LineReader; import org.broad.tribble.util.ParsingUtils; +import org.broadinstitute.sting.utils.exceptions.ReviewedStingException; +import org.broadinstitute.sting.utils.exceptions.UserException; import org.broadinstitute.sting.utils.variantcontext.Allele; import org.broadinstitute.sting.utils.variantcontext.Genotype; import org.broadinstitute.sting.utils.variantcontext.VariantContext; @@ -96,6 +98,9 @@ public abstract class AbstractVCFCodec implements FeatureCodec, NameAwareCodec, for ( String str : headerStrings ) { if ( !str.startsWith(VCFHeader.METADATA_INDICATOR) ) { String[] strings = str.substring(1).split(VCFConstants.FIELD_SEPARATOR); + if ( strings.length < VCFHeader.HEADER_FIELDS.values().length ) + throw new TribbleException.InvalidHeader("there are not enough columns present in the header line: " + str); + int arrayIndex = 0; for (VCFHeader.HEADER_FIELDS field : VCFHeader.HEADER_FIELDS.values()) { try { @@ -159,12 +164,11 @@ public abstract class AbstractVCFCodec implements FeatureCodec, NameAwareCodec, } private Feature reallyDecode(String line) { - try { // the same line reader is not used for parsing the header and parsing lines, if we see a #, we've seen a header line if (line.startsWith(VCFHeader.HEADER_INDICATOR)) return null; // our header cannot be null, we need the genotype sample names and counts - if (header == null) throw new IllegalStateException("VCF Header cannot be null when decoding a record"); + if (header == null) throw new ReviewedStingException("VCF Header cannot be null when decoding a record"); if (parts == null) parts = new String[Math.min(header.getColumnCount(), NUM_STANDARD_FIELDS+1)]; @@ -174,17 +178,18 @@ public abstract class AbstractVCFCodec implements FeatureCodec, NameAwareCodec, // if we have don't have a header, or we have a header with no genotyping data check that we have eight columns. Otherwise check that we have nine (normal colummns + genotyping data) if (( (header == null || (header != null && !header.hasGenotypingData())) && nParts != NUM_STANDARD_FIELDS) || (header != null && header.hasGenotypingData() && nParts != (NUM_STANDARD_FIELDS + 1)) ) - throw new IllegalArgumentException("There aren't enough columns for line " + line + " (we expected " + (header == null ? NUM_STANDARD_FIELDS : NUM_STANDARD_FIELDS + 1) + - " tokens, and saw " + nParts + " )"); + throw new UserException.MalformedVCF("there aren't enough columns for line " + line + " (we expected " + (header == null ? NUM_STANDARD_FIELDS : NUM_STANDARD_FIELDS + 1) + + " tokens, and saw " + nParts + " )", lineNo); return parseVCFLine(parts); - } catch (TribbleException e) { - throw new TribbleException.InvalidDecodeLine(e.getMessage(), line); - } } protected void generateException(String message) { - throw new TribbleException.InvalidDecodeLine(message, lineNo); + throw new UserException.MalformedVCF(message, lineNo); + } + + private static void generateException(String message, int lineNo) { + throw new UserException.MalformedVCF(message, lineNo); } /** @@ -472,10 +477,6 @@ public abstract class AbstractVCFCodec implements FeatureCodec, NameAwareCodec, return true; } - private static void generateException(String message, int lineNo) { - throw new TribbleException.InvalidDecodeLine(message, lineNo); - } - private static int computeForwardClipping(List unclippedAlleles, String ref) { boolean clipping = true; // Note that the computation of forward clipping here is meant only to see whether there is a common diff --git a/public/java/src/org/broadinstitute/sting/utils/exceptions/UserException.java b/public/java/src/org/broadinstitute/sting/utils/exceptions/UserException.java index 0be4bec91..17c4a7df4 100755 --- a/public/java/src/org/broadinstitute/sting/utils/exceptions/UserException.java +++ b/public/java/src/org/broadinstitute/sting/utils/exceptions/UserException.java @@ -154,6 +154,16 @@ public class UserException extends ReviewedStingException { } } + public static class MalformedVCF extends UserException { + public MalformedVCF(String message, String line) { + super(String.format("The provided VCF file is malformed at line %s: %s", line, message)); + } + + public MalformedVCF(String message, int lineNo) { + super(String.format("The provided VCF file is malformed at line nmber %d: %s", lineNo, message)); + } + } + public static class ReadMissingReadGroup extends MalformedBAM { public ReadMissingReadGroup(SAMRecord read) { super(read, String.format("Read %s is either missing the read group or its read group is not defined in the BAM header, both of which are required by the GATK. Please use http://www.broadinstitute.org/gsa/wiki/index.php/ReplaceReadGroups to fix this problem", read.getReadName())); From ed6beae1f3769c247b9a4fc80121985baad6443f Mon Sep 17 00:00:00 2001 From: Eric Banks Date: Thu, 14 Jul 2011 13:55:35 -0400 Subject: [PATCH 03/35] Adding headers to diffable reading for VCFs --- .../gatk/walkers/diffengine/VCFDiffableReader.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/public/java/src/org/broadinstitute/sting/gatk/walkers/diffengine/VCFDiffableReader.java b/public/java/src/org/broadinstitute/sting/gatk/walkers/diffengine/VCFDiffableReader.java index 06d14366f..5677574bd 100644 --- a/public/java/src/org/broadinstitute/sting/gatk/walkers/diffengine/VCFDiffableReader.java +++ b/public/java/src/org/broadinstitute/sting/gatk/walkers/diffengine/VCFDiffableReader.java @@ -26,16 +26,12 @@ package org.broadinstitute.sting.gatk.walkers.diffengine; import org.broad.tribble.readers.AsciiLineReader; import org.broad.tribble.readers.LineReader; -import org.broadinstitute.sting.utils.codecs.vcf.VCFCodec; -import org.broadinstitute.sting.utils.codecs.vcf.VCFConstants; -import org.broadinstitute.sting.utils.codecs.vcf.VCFHeader; +import org.broadinstitute.sting.utils.codecs.vcf.*; import org.broadinstitute.sting.utils.variantcontext.Genotype; import org.broadinstitute.sting.utils.variantcontext.VariantContext; import java.io.*; -import java.util.Arrays; import java.util.Map; -import java.util.zip.GZIPInputStream; /** @@ -58,7 +54,11 @@ public class VCFDiffableReader implements DiffableReader { VCFCodec vcfCodec = new VCFCodec(); // must be read as state is stored in reader itself - vcfCodec.readHeader(lineReader); + VCFHeader header = (VCFHeader)vcfCodec.readHeader(lineReader); + for ( VCFHeaderLine headerLine : header.getMetaData() ) { + final String key = (headerLine instanceof VCFNamedHeaderLine ? headerLine.getKey() + "." + ((VCFNamedHeaderLine) headerLine).getName() : headerLine.getKey()); + root.add(key, headerLine.toString()); + } String line = lineReader.readLine(); int count = 0; From 9540df69986c16112b5fdd57efebf72846d86424 Mon Sep 17 00:00:00 2001 From: Eric Banks Date: Thu, 14 Jul 2011 14:00:19 -0400 Subject: [PATCH 04/35] Oops, forgot to update unit test --- .../sting/gatk/walkers/diffengine/DiffableReaderUnitTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/java/test/org/broadinstitute/sting/gatk/walkers/diffengine/DiffableReaderUnitTest.java b/public/java/test/org/broadinstitute/sting/gatk/walkers/diffengine/DiffableReaderUnitTest.java index baa2f0383..a0cb47770 100644 --- a/public/java/test/org/broadinstitute/sting/gatk/walkers/diffengine/DiffableReaderUnitTest.java +++ b/public/java/test/org/broadinstitute/sting/gatk/walkers/diffengine/DiffableReaderUnitTest.java @@ -87,7 +87,7 @@ public class DiffableReaderUnitTest extends BaseTest { Assert.assertSame(diff.getParent(), DiffElement.ROOT); DiffNode node = diff.getValueAsNode(); - Assert.assertEquals(node.getElements().size(), 9); + Assert.assertEquals(node.getElements().size(), 10); // chr1 2646 rs62635284 G A 0.15 PASS AC=2;AF=1.00;AN=2 GT:AD:DP:GL:GQ 1/1:53,75:3:-12.40,-0.90,-0.00:9.03 DiffNode rec1 = node.getElement("chr1:2646").getValueAsNode(); From 5ffeddd3b1ac5f83d6018dad0a178ae785a4dc39 Mon Sep 17 00:00:00 2001 From: Mark DePristo Date: Thu, 14 Jul 2011 14:45:16 -0400 Subject: [PATCH 05/35] better to use _ instead of ., as this is a special case later. --- .../sting/gatk/walkers/diffengine/VCFDiffableReader.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/public/java/src/org/broadinstitute/sting/gatk/walkers/diffengine/VCFDiffableReader.java b/public/java/src/org/broadinstitute/sting/gatk/walkers/diffengine/VCFDiffableReader.java index 5677574bd..a812babaf 100644 --- a/public/java/src/org/broadinstitute/sting/gatk/walkers/diffengine/VCFDiffableReader.java +++ b/public/java/src/org/broadinstitute/sting/gatk/walkers/diffengine/VCFDiffableReader.java @@ -56,7 +56,9 @@ public class VCFDiffableReader implements DiffableReader { // must be read as state is stored in reader itself VCFHeader header = (VCFHeader)vcfCodec.readHeader(lineReader); for ( VCFHeaderLine headerLine : header.getMetaData() ) { - final String key = (headerLine instanceof VCFNamedHeaderLine ? headerLine.getKey() + "." + ((VCFNamedHeaderLine) headerLine).getName() : headerLine.getKey()); + String key = headerLine.getKey(); + if ( headerLine instanceof VCFNamedHeaderLine ) + key += "_" + ((VCFNamedHeaderLine) headerLine).getName(); root.add(key, headerLine.toString()); } From c0bbeb23ba0200d80f940a395ddc019fdb61f093 Mon Sep 17 00:00:00 2001 From: Mark DePristo Date: Thu, 14 Jul 2011 15:12:28 -0400 Subject: [PATCH 06/35] Now providing more information when the index on the fly isn't equal to the one created by reading the file from disk. --- .../test/org/broadinstitute/sting/WalkerTest.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/public/java/test/org/broadinstitute/sting/WalkerTest.java b/public/java/test/org/broadinstitute/sting/WalkerTest.java index dacaf2738..d65f4ec34 100755 --- a/public/java/test/org/broadinstitute/sting/WalkerTest.java +++ b/public/java/test/org/broadinstitute/sting/WalkerTest.java @@ -26,7 +26,9 @@ package org.broadinstitute.sting; import org.apache.commons.lang.StringUtils; +import org.broad.tribble.FeatureCodec; import org.broad.tribble.Tribble; +import org.broad.tribble.index.Index; import org.broad.tribble.index.IndexFactory; import org.broadinstitute.sting.utils.codecs.vcf.VCFCodec; import org.broadinstitute.sting.gatk.CommandLineExecutable; @@ -64,10 +66,19 @@ public class WalkerTest extends BaseTest { } System.out.println("Verifying on-the-fly index " + indexFile + " for test " + name + " using file " + resultFile); - Assert.assertTrue(IndexFactory.onDiskIndexEqualToNewlyCreatedIndex(resultFile, indexFile, new VCFCodec()), "Index on disk from indexing on the fly not equal to the index created after the run completed"); + Index indexFromOutputFile = IndexFactory.createIndex(resultFile, new VCFCodec()); + Index dynamicIndex = IndexFactory.loadIndex(indexFile.getAbsolutePath()); + + if ( ! indexFromOutputFile.equals(dynamicIndex) ) { + Assert.fail(String.format("Index on disk from indexing on the fly not equal to the index created after the run completed. FileIndex %s vs. on-the-fly %s%n", + indexFromOutputFile.getProperties(), + dynamicIndex.getProperties())); + } } } + + public List assertMatchingMD5s(final String name, List resultFiles, List expectedMD5s) { List md5s = new ArrayList(); for (int i = 0; i < resultFiles.size(); i++) { From 9f5180ab053d7116b194f2ef09b5f157dbeb4cca Mon Sep 17 00:00:00 2001 From: Mauricio Carneiro Date: Thu, 14 Jul 2011 16:42:17 -0400 Subject: [PATCH 07/35] Recalibrates a list of bam files allowing multiple bams to be recalibrated out of a single 'mother' queue job. --- .../qscripts/RecalibrateBaseQualities.scala | 39 +++++++++++++------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/public/scala/qscript/org/broadinstitute/sting/queue/qscripts/RecalibrateBaseQualities.scala b/public/scala/qscript/org/broadinstitute/sting/queue/qscripts/RecalibrateBaseQualities.scala index dc9ae0f4b..88c7f5ff7 100755 --- a/public/scala/qscript/org/broadinstitute/sting/queue/qscripts/RecalibrateBaseQualities.scala +++ b/public/scala/qscript/org/broadinstitute/sting/queue/qscripts/RecalibrateBaseQualities.scala @@ -3,6 +3,7 @@ package org.broadinstitute.sting.queue.qscripts import org.broadinstitute.sting.queue.QScript import org.broadinstitute.sting.queue.extensions.gatk._ import net.sf.samtools.SAMFileReader +import io.Source._ /** * Created by IntelliJ IDEA. @@ -37,21 +38,35 @@ class RecalibrateBaseQualities extends QScript { return samReader.getFileHeader.getSequenceDictionary.getSequences.size() } + // Reads a BAM LIST file and creates a scala list with all the files + def createListFromFile(in: File):List[File] = { + if (in.toString.endsWith("bam")) + return List(in) + var l: List[File] = List() + for (bam <- fromFile(in).getLines) + l :+= new File(bam) + return l + } + def script = { - nContigs = getNumberOfContigs(input) + val bamList = createListFromFile(input) + nContigs = getNumberOfContigs(bamList(0)) - val recalFile1: File = swapExt(input, ".bam", ".recal1.csv") - val recalFile2: File = swapExt(input, ".bam", ".recal2.csv") - val recalBam: File = swapExt(input, ".bam", ".recal.bam") - val path1: String = input + "before" - val path2: String = input + "after" - - add(cov(input, recalFile1), - recal(input, recalFile1, recalBam), - cov(recalBam, recalFile2), - analyzeCovariates(recalFile1, path1), - analyzeCovariates(recalFile2, path2)) + for (bam <- bamList) { + + val recalFile1: File = swapExt(bam, ".bam", ".recal1.csv") + val recalFile2: File = swapExt(bam, ".bam", ".recal2.csv") + val recalBam: File = swapExt(bam, ".bam", ".recal.bam") + val path1: String = bam + "before" + val path2: String = bam + "after" + + add(cov(bam, recalFile1), + recal(bam, recalFile1, recalBam), + cov(recalBam, recalFile2), + analyzeCovariates(recalFile1, path1), + analyzeCovariates(recalFile2, path2)) + } } trait CommandLineGATKArgs extends CommandLineGATK { From 09ffe277ae7d3418f75510cabe65e6c9a8fa8f25 Mon Sep 17 00:00:00 2001 From: Mauricio Carneiro Date: Thu, 14 Jul 2011 17:09:35 -0400 Subject: [PATCH 08/35] Added a qscripts util package with some utility functions commonly shared across queue scripts. Refactored some of my public scripts to use it in an effort to make queue scripts more reusable and "supportable". --- .../qscripts/DataProcessingPipeline.scala | 38 ++---------- .../qscripts/RecalibrateBaseQualities.scala | 20 +----- .../sting/queue/qscripts/utils/Utils.scala | 62 +++++++++++++++++++ 3 files changed, 71 insertions(+), 49 deletions(-) create mode 100644 public/scala/qscript/org/broadinstitute/sting/queue/qscripts/utils/Utils.scala diff --git a/public/scala/qscript/org/broadinstitute/sting/queue/qscripts/DataProcessingPipeline.scala b/public/scala/qscript/org/broadinstitute/sting/queue/qscripts/DataProcessingPipeline.scala index f9369ee3f..e62b1b926 100755 --- a/public/scala/qscript/org/broadinstitute/sting/queue/qscripts/DataProcessingPipeline.scala +++ b/public/scala/qscript/org/broadinstitute/sting/queue/qscripts/DataProcessingPipeline.scala @@ -4,13 +4,13 @@ import org.broadinstitute.sting.queue.extensions.gatk._ import org.broadinstitute.sting.queue.QScript import org.broadinstitute.sting.queue.function.ListWriterFunction -import scala.io.Source._ import collection.JavaConversions._ import org.broadinstitute.sting.gatk.walkers.indels.IndelRealigner.ConsensusDeterminationModel import org.broadinstitute.sting.queue.extensions.picard._ -import net.sf.samtools.{SAMFileReader, SAMReadGroupRecord} +import net.sf.samtools.{SAMFileReader} import net.sf.samtools.SAMFileHeader.SortOrder +import org.broadinstitute.sting.queue.qscripts.utils.Utils class DataProcessingPipeline extends QScript { qscript => @@ -103,18 +103,6 @@ class DataProcessingPipeline extends QScript { val ds: String) {} - // Utility function to check if there are multiple samples in a BAM file (currently we can't deal with that) - def hasMultipleSamples(readGroups: java.util.List[SAMReadGroupRecord]): Boolean = { - var sample: String = "" - for (r <- readGroups) { - if (sample.isEmpty) - sample = r.getSample - else if (sample != r.getSample) - return true; - } - return false - } - // Utility function to merge all bam files of similar samples. Generates one BAM file per sample. // It uses the sample information on the header of the input BAM files. // @@ -135,7 +123,7 @@ class DataProcessingPipeline extends QScript { // only allow one sample per file. Bam files with multiple samples would require pre-processing of the file // with PrintReads to separate the samples. Tell user to do it himself! - assert(!hasMultipleSamples(readGroups), "The pipeline requires that only one sample is present in a BAM file. Please separate the samples in " + bam) + assert(!Utils.hasMultipleSamples(readGroups), "The pipeline requires that only one sample is present in a BAM file. Please separate the samples in " + bam) // Fill out the sample table with the readgroups in this file for (rg <- readGroups) { @@ -157,12 +145,6 @@ class DataProcessingPipeline extends QScript { return sampleBamFiles.toMap } - // Checks how many contigs are in the dataset. Uses the BAM file header information. - def getNumberOfContigs(bamFile: File): Int = { - val samReader = new SAMFileReader(new File(bamFile)) - return samReader.getFileHeader.getSequenceDictionary.getSequences.size() - } - // Rebuilds the Read Group string to give BWA def addReadGroups(inBam: File, outBam: File, samReader: SAMFileReader) { val readGroups = samReader.getFileHeader.getReadGroups @@ -206,15 +188,7 @@ class DataProcessingPipeline extends QScript { return realignedBams } - // Reads a BAM LIST file and creates a scala list with all the files - def createListFromFile(in: File):List[File] = { - if (in.toString.endsWith("bam")) - return List(in) - var l: List[File] = List() - for (bam <- fromFile(in).getLines) - l :+= new File(bam) - return l - } + @@ -226,8 +200,8 @@ class DataProcessingPipeline extends QScript { def script = { // keep a record of the number of contigs in the first bam file in the list - val bams = createListFromFile(input) - nContigs = getNumberOfContigs(bams(0)) + val bams = Utils.createListFromFile(input) + nContigs = Utils.getNumberOfContigs(bams(0)) val realignedBams = if (useBWApe || useBWAse) {performAlignment(bams)} else {bams} diff --git a/public/scala/qscript/org/broadinstitute/sting/queue/qscripts/RecalibrateBaseQualities.scala b/public/scala/qscript/org/broadinstitute/sting/queue/qscripts/RecalibrateBaseQualities.scala index 88c7f5ff7..b2960f150 100755 --- a/public/scala/qscript/org/broadinstitute/sting/queue/qscripts/RecalibrateBaseQualities.scala +++ b/public/scala/qscript/org/broadinstitute/sting/queue/qscripts/RecalibrateBaseQualities.scala @@ -4,6 +4,7 @@ import org.broadinstitute.sting.queue.QScript import org.broadinstitute.sting.queue.extensions.gatk._ import net.sf.samtools.SAMFileReader import io.Source._ +import org.broadinstitute.sting.queue.qscripts.utils.Utils /** * Created by IntelliJ IDEA. @@ -33,25 +34,10 @@ class RecalibrateBaseQualities extends QScript { val queueLogDir: String = ".qlog/" var nContigs: Int = 0 - def getNumberOfContigs(bamFile: File): Int = { - val samReader = new SAMFileReader(new File(bamFile)) - return samReader.getFileHeader.getSequenceDictionary.getSequences.size() - } - - // Reads a BAM LIST file and creates a scala list with all the files - def createListFromFile(in: File):List[File] = { - if (in.toString.endsWith("bam")) - return List(in) - var l: List[File] = List() - for (bam <- fromFile(in).getLines) - l :+= new File(bam) - return l - } - def script = { - val bamList = createListFromFile(input) - nContigs = getNumberOfContigs(bamList(0)) + val bamList = Utils.createListFromFile(input) + nContigs = Utils.getNumberOfContigs(bamList(0)) for (bam <- bamList) { diff --git a/public/scala/qscript/org/broadinstitute/sting/queue/qscripts/utils/Utils.scala b/public/scala/qscript/org/broadinstitute/sting/queue/qscripts/utils/Utils.scala new file mode 100644 index 000000000..ff94744ee --- /dev/null +++ b/public/scala/qscript/org/broadinstitute/sting/queue/qscripts/utils/Utils.scala @@ -0,0 +1,62 @@ +package org.broadinstitute.sting.queue.qscripts.utils + +import java.io.File +import io.Source._ +import net.sf.samtools.{SAMReadGroupRecord, SAMFileReader} + +import collection.JavaConversions._ + + +/** + * Created by IntelliJ IDEA. + * User: carneiro + * Date: 7/14/11 + * Time: 4:57 PM + * To change this template use File | Settings | File Templates. + */ + +object Utils { + + /** + * Takes a bam list file and produces a scala list with each file allowing the bam list + * to have empty lines and comment lines (lines starting with #). + */ + def createListFromFile(in: File):List[File] = { + // If the file provided ends with .bam, it is not a bam list, we treat it as a single file. + // and return a list with only this file. + if (in.toString.endsWith(".bam")) + return List(in) + + var list: List[File] = List() + for (bam <- fromFile(in).getLines) + if (!bam.startsWith("#") && !bam.isEmpty ) + list :+= new File(bam.trim()) + list + } + + /** + * Returns the number of contigs in the BAM file header. + */ + + def getNumberOfContigs(bamFile: File): Int = { + val samReader = new SAMFileReader(new File(bamFile)) + samReader.getFileHeader.getSequenceDictionary.getSequences.size() + } + + /** + * Check if there are multiple samples in a BAM file + */ + + def hasMultipleSamples(readGroups: java.util.List[SAMReadGroupRecord]): Boolean = { + var sample: String = "" + for (r <- readGroups) { + if (sample.isEmpty) + sample = r.getSample + else if (sample != r.getSample) + return true; + } + false + } + + +} \ No newline at end of file From 43c6a8565bfe77e4c50317a3e8858b754d4afcba Mon Sep 17 00:00:00 2001 From: Mauricio Carneiro Date: Thu, 14 Jul 2011 17:10:44 -0400 Subject: [PATCH 09/35] looks better now. --- .../org/broadinstitute/sting/queue/qscripts/utils/Utils.scala | 2 -- 1 file changed, 2 deletions(-) diff --git a/public/scala/qscript/org/broadinstitute/sting/queue/qscripts/utils/Utils.scala b/public/scala/qscript/org/broadinstitute/sting/queue/qscripts/utils/Utils.scala index ff94744ee..1189b376c 100644 --- a/public/scala/qscript/org/broadinstitute/sting/queue/qscripts/utils/Utils.scala +++ b/public/scala/qscript/org/broadinstitute/sting/queue/qscripts/utils/Utils.scala @@ -37,7 +37,6 @@ object Utils { /** * Returns the number of contigs in the BAM file header. */ - def getNumberOfContigs(bamFile: File): Int = { val samReader = new SAMFileReader(new File(bamFile)) samReader.getFileHeader.getSequenceDictionary.getSequences.size() @@ -46,7 +45,6 @@ object Utils { /** * Check if there are multiple samples in a BAM file */ - def hasMultipleSamples(readGroups: java.util.List[SAMReadGroupRecord]): Boolean = { var sample: String = "" for (r <- readGroups) { From a670d6420ad586b7138326b994822ce1f6682629 Mon Sep 17 00:00:00 2001 From: Mauricio Carneiro Date: Fri, 15 Jul 2011 14:31:43 -0400 Subject: [PATCH 12/35] Refactoring Qscript utils into queue general utils package. --- .../sting/queue/qscripts/DataProcessingPipeline.scala | 4 ++-- .../sting/queue/qscripts/RecalibrateBaseQualities.scala | 4 +--- .../org/broadinstitute/sting/queue/util}/Utils.scala | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) rename public/scala/{qscript/org/broadinstitute/sting/queue/qscripts/utils => src/org/broadinstitute/sting/queue/util}/Utils.scala (96%) diff --git a/public/scala/qscript/org/broadinstitute/sting/queue/qscripts/DataProcessingPipeline.scala b/public/scala/qscript/org/broadinstitute/sting/queue/qscripts/DataProcessingPipeline.scala index e62b1b926..40ac43a81 100755 --- a/public/scala/qscript/org/broadinstitute/sting/queue/qscripts/DataProcessingPipeline.scala +++ b/public/scala/qscript/org/broadinstitute/sting/queue/qscripts/DataProcessingPipeline.scala @@ -7,10 +7,10 @@ import org.broadinstitute.sting.queue.function.ListWriterFunction import collection.JavaConversions._ import org.broadinstitute.sting.gatk.walkers.indels.IndelRealigner.ConsensusDeterminationModel import org.broadinstitute.sting.queue.extensions.picard._ -import net.sf.samtools.{SAMFileReader} +import net.sf.samtools.SAMFileReader import net.sf.samtools.SAMFileHeader.SortOrder -import org.broadinstitute.sting.queue.qscripts.utils.Utils +import org.broadinstitute.sting.queue.util.Utils class DataProcessingPipeline extends QScript { qscript => diff --git a/public/scala/qscript/org/broadinstitute/sting/queue/qscripts/RecalibrateBaseQualities.scala b/public/scala/qscript/org/broadinstitute/sting/queue/qscripts/RecalibrateBaseQualities.scala index b2960f150..8ba880291 100755 --- a/public/scala/qscript/org/broadinstitute/sting/queue/qscripts/RecalibrateBaseQualities.scala +++ b/public/scala/qscript/org/broadinstitute/sting/queue/qscripts/RecalibrateBaseQualities.scala @@ -2,9 +2,7 @@ package org.broadinstitute.sting.queue.qscripts import org.broadinstitute.sting.queue.QScript import org.broadinstitute.sting.queue.extensions.gatk._ -import net.sf.samtools.SAMFileReader -import io.Source._ -import org.broadinstitute.sting.queue.qscripts.utils.Utils +import org.broadinstitute.sting.queue.util.Utils /** * Created by IntelliJ IDEA. diff --git a/public/scala/qscript/org/broadinstitute/sting/queue/qscripts/utils/Utils.scala b/public/scala/src/org/broadinstitute/sting/queue/util/Utils.scala similarity index 96% rename from public/scala/qscript/org/broadinstitute/sting/queue/qscripts/utils/Utils.scala rename to public/scala/src/org/broadinstitute/sting/queue/util/Utils.scala index 1189b376c..5b80503a3 100644 --- a/public/scala/qscript/org/broadinstitute/sting/queue/qscripts/utils/Utils.scala +++ b/public/scala/src/org/broadinstitute/sting/queue/util/Utils.scala @@ -1,4 +1,4 @@ -package org.broadinstitute.sting.queue.qscripts.utils +package org.broadinstitute.sting.queue.util import java.io.File import io.Source._ From 7b7d40d5d97461f3b4cf71bf7b6efc0695a97f91 Mon Sep 17 00:00:00 2001 From: Mauricio Carneiro Date: Fri, 15 Jul 2011 14:34:50 -0400 Subject: [PATCH 13/35] A better name for the qscript utilities. Throw here every method you find yourself repeatedly implementing in your qscripts! Refactoring appropriately. --- .../sting/queue/qscripts/DataProcessingPipeline.scala | 8 ++++---- .../sting/queue/qscripts/RecalibrateBaseQualities.scala | 6 +++--- .../sting/queue/util/{Utils.scala => QScriptUtils.scala} | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) rename public/scala/src/org/broadinstitute/sting/queue/util/{Utils.scala => QScriptUtils.scala} (98%) diff --git a/public/scala/qscript/org/broadinstitute/sting/queue/qscripts/DataProcessingPipeline.scala b/public/scala/qscript/org/broadinstitute/sting/queue/qscripts/DataProcessingPipeline.scala index 40ac43a81..050604b4e 100755 --- a/public/scala/qscript/org/broadinstitute/sting/queue/qscripts/DataProcessingPipeline.scala +++ b/public/scala/qscript/org/broadinstitute/sting/queue/qscripts/DataProcessingPipeline.scala @@ -10,7 +10,7 @@ import org.broadinstitute.sting.queue.extensions.picard._ import net.sf.samtools.SAMFileReader import net.sf.samtools.SAMFileHeader.SortOrder -import org.broadinstitute.sting.queue.util.Utils +import org.broadinstitute.sting.queue.util.QScriptUtils class DataProcessingPipeline extends QScript { qscript => @@ -123,7 +123,7 @@ class DataProcessingPipeline extends QScript { // only allow one sample per file. Bam files with multiple samples would require pre-processing of the file // with PrintReads to separate the samples. Tell user to do it himself! - assert(!Utils.hasMultipleSamples(readGroups), "The pipeline requires that only one sample is present in a BAM file. Please separate the samples in " + bam) + assert(!QScriptUtils.hasMultipleSamples(readGroups), "The pipeline requires that only one sample is present in a BAM file. Please separate the samples in " + bam) // Fill out the sample table with the readgroups in this file for (rg <- readGroups) { @@ -200,8 +200,8 @@ class DataProcessingPipeline extends QScript { def script = { // keep a record of the number of contigs in the first bam file in the list - val bams = Utils.createListFromFile(input) - nContigs = Utils.getNumberOfContigs(bams(0)) + val bams = QScriptUtils.createListFromFile(input) + nContigs = QScriptUtils.getNumberOfContigs(bams(0)) val realignedBams = if (useBWApe || useBWAse) {performAlignment(bams)} else {bams} diff --git a/public/scala/qscript/org/broadinstitute/sting/queue/qscripts/RecalibrateBaseQualities.scala b/public/scala/qscript/org/broadinstitute/sting/queue/qscripts/RecalibrateBaseQualities.scala index 8ba880291..56ca36925 100755 --- a/public/scala/qscript/org/broadinstitute/sting/queue/qscripts/RecalibrateBaseQualities.scala +++ b/public/scala/qscript/org/broadinstitute/sting/queue/qscripts/RecalibrateBaseQualities.scala @@ -2,7 +2,7 @@ package org.broadinstitute.sting.queue.qscripts import org.broadinstitute.sting.queue.QScript import org.broadinstitute.sting.queue.extensions.gatk._ -import org.broadinstitute.sting.queue.util.Utils +import org.broadinstitute.sting.queue.util.QScriptUtils /** * Created by IntelliJ IDEA. @@ -34,8 +34,8 @@ class RecalibrateBaseQualities extends QScript { def script = { - val bamList = Utils.createListFromFile(input) - nContigs = Utils.getNumberOfContigs(bamList(0)) + val bamList = QScriptUtils.createListFromFile(input) + nContigs = QScriptUtils.getNumberOfContigs(bamList(0)) for (bam <- bamList) { diff --git a/public/scala/src/org/broadinstitute/sting/queue/util/Utils.scala b/public/scala/src/org/broadinstitute/sting/queue/util/QScriptUtils.scala similarity index 98% rename from public/scala/src/org/broadinstitute/sting/queue/util/Utils.scala rename to public/scala/src/org/broadinstitute/sting/queue/util/QScriptUtils.scala index 5b80503a3..e2f1f1608 100644 --- a/public/scala/src/org/broadinstitute/sting/queue/util/Utils.scala +++ b/public/scala/src/org/broadinstitute/sting/queue/util/QScriptUtils.scala @@ -15,7 +15,7 @@ import collection.JavaConversions._ * To change this template use File | Settings | File Templates. */ -object Utils { +object QScriptUtils { /** * Takes a bam list file and produces a scala list with each file allowing the bam list From 224d373997e0f4775207654ad4e246caad6c9aac Mon Sep 17 00:00:00 2001 From: Mauricio Carneiro Date: Fri, 15 Jul 2011 15:19:10 -0400 Subject: [PATCH 17/35] No need to double overload the file constructor --- .../src/org/broadinstitute/sting/queue/util/QScriptUtils.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/scala/src/org/broadinstitute/sting/queue/util/QScriptUtils.scala b/public/scala/src/org/broadinstitute/sting/queue/util/QScriptUtils.scala index e2f1f1608..9fb4fa30d 100644 --- a/public/scala/src/org/broadinstitute/sting/queue/util/QScriptUtils.scala +++ b/public/scala/src/org/broadinstitute/sting/queue/util/QScriptUtils.scala @@ -38,7 +38,7 @@ object QScriptUtils { * Returns the number of contigs in the BAM file header. */ def getNumberOfContigs(bamFile: File): Int = { - val samReader = new SAMFileReader(new File(bamFile)) + val samReader = new SAMFileReader(bamFile) samReader.getFileHeader.getSequenceDictionary.getSequences.size() } From 72f4cf9c0ecbd8608d207ee59a5e5bd36a395be8 Mon Sep 17 00:00:00 2001 From: Menachem Fromer Date: Fri, 15 Jul 2011 17:44:31 -0400 Subject: [PATCH 28/35] Walker to perform deterministic annotation of phasing by transmission (to be compatible with RBP's definition of consecutive pairwise phasing) --- .../sting/gatk/walkers/phasing/ReadBackedPhasingWalker.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/java/src/org/broadinstitute/sting/gatk/walkers/phasing/ReadBackedPhasingWalker.java b/public/java/src/org/broadinstitute/sting/gatk/walkers/phasing/ReadBackedPhasingWalker.java index 1d9616aac..fbe6e5b5a 100755 --- a/public/java/src/org/broadinstitute/sting/gatk/walkers/phasing/ReadBackedPhasingWalker.java +++ b/public/java/src/org/broadinstitute/sting/gatk/walkers/phasing/ReadBackedPhasingWalker.java @@ -242,7 +242,7 @@ public class ReadBackedPhasingWalker extends RodWalker KEYS_TO_KEEP_IN_REDUCED_VCF = new HashSet(Arrays.asList("PQ")); + private static final Set KEYS_TO_KEEP_IN_REDUCED_VCF = new HashSet(Arrays.asList(PQ_KEY)); private VariantContext reduceVCToSamples(VariantContext vc, List samplesToPhase) { // for ( String sample : samplesToPhase ) From 1e4798d5d0303df6b9cd42e9f7f2d30956004668 Mon Sep 17 00:00:00 2001 From: Mauricio Carneiro Date: Fri, 15 Jul 2011 19:34:14 -0400 Subject: [PATCH 31/35] Added targets to build.xml to re-run only tests that have failed (integration, unit, performance or pipeline tests). This is very useful and easy. After running any test (for example ant integrationtest) and seeing failures, you can rerun ONLY THE TESTS THAT FAILED by using one of the following commands: ant failed-integration ant failed-pipeline ant failed-test ant failed-performance obviously matching whatever tests you were running and got failures on. This should run only the failed tests, and you can keep using this command until you have fixed everything. (Thanks to David Roazen for major help with ANT) --- build.xml | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/build.xml b/build.xml index 986d89213..91eb1f8e9 100644 --- a/build.xml +++ b/build.xml @@ -785,6 +785,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -819,6 +863,22 @@ + + + + + + + + + + + + + + + + From fd1df31ef0ab60ec735ff5692132441224a02659 Mon Sep 17 00:00:00 2001 From: Mauricio Carneiro Date: Fri, 15 Jul 2011 19:39:42 -0400 Subject: [PATCH 32/35] changing the output directory names for Analyze Covariates --- .../sting/queue/qscripts/RecalibrateBaseQualities.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/public/scala/qscript/org/broadinstitute/sting/queue/qscripts/RecalibrateBaseQualities.scala b/public/scala/qscript/org/broadinstitute/sting/queue/qscripts/RecalibrateBaseQualities.scala index 56ca36925..fca420816 100755 --- a/public/scala/qscript/org/broadinstitute/sting/queue/qscripts/RecalibrateBaseQualities.scala +++ b/public/scala/qscript/org/broadinstitute/sting/queue/qscripts/RecalibrateBaseQualities.scala @@ -42,8 +42,8 @@ class RecalibrateBaseQualities extends QScript { val recalFile1: File = swapExt(bam, ".bam", ".recal1.csv") val recalFile2: File = swapExt(bam, ".bam", ".recal2.csv") val recalBam: File = swapExt(bam, ".bam", ".recal.bam") - val path1: String = bam + "before" - val path2: String = bam + "after" + val path1: String = bam + ".before" + val path2: String = bam + ".after" add(cov(bam, recalFile1), recal(bam, recalFile1, recalBam), @@ -83,7 +83,7 @@ class RecalibrateBaseQualities extends QScript { case class analyzeCovariates (inRecalFile: File, outPath: String) extends AnalyzeCovariates { this.resources = R this.recal_file = inRecalFile - this.output_dir = outPath.toString + this.output_dir = outPath this.analysisName = queueLogDir + inRecalFile + ".analyze_covariates" this.jobName = queueLogDir + inRecalFile + ".analyze_covariates" } From ed55182a4c5553eb517569567e5193a12eb7e68a Mon Sep 17 00:00:00 2001 From: Mauricio Carneiro Date: Sat, 16 Jul 2011 00:09:00 -0400 Subject: [PATCH 33/35] Removing Broad specific paths from parameters and making them required. This should make it unambiguous for people inside and outside the Broad to use the DataProcessingPipeline (as per request in the GetSatisfaction) --- .../qscripts/DataProcessingPipeline.scala | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/public/scala/qscript/org/broadinstitute/sting/queue/qscripts/DataProcessingPipeline.scala b/public/scala/qscript/org/broadinstitute/sting/queue/qscripts/DataProcessingPipeline.scala index 050604b4e..4d4499990 100755 --- a/public/scala/qscript/org/broadinstitute/sting/queue/qscripts/DataProcessingPipeline.scala +++ b/public/scala/qscript/org/broadinstitute/sting/queue/qscripts/DataProcessingPipeline.scala @@ -3,10 +3,11 @@ package org.broadinstitute.sting.queue.qscripts import org.broadinstitute.sting.queue.extensions.gatk._ import org.broadinstitute.sting.queue.QScript import org.broadinstitute.sting.queue.function.ListWriterFunction +import org.broadinstitute.sting.queue.extensions.picard._ +import org.broadinstitute.sting.gatk.walkers.indels.IndelRealigner.ConsensusDeterminationModel +import org.broadinstitute.sting.utils.baq.BAQ.CalculationMode import collection.JavaConversions._ -import org.broadinstitute.sting.gatk.walkers.indels.IndelRealigner.ConsensusDeterminationModel -import org.broadinstitute.sting.queue.extensions.picard._ import net.sf.samtools.SAMFileReader import net.sf.samtools.SAMFileHeader.SortOrder @@ -29,6 +30,11 @@ class DataProcessingPipeline extends QScript { @Input(doc="Reference fasta file", fullName="reference", shortName="R", required=true) var reference: File = _ + @Input(doc="dbsnp ROD to use (must be in VCF format)", fullName="dbsnp", shortName="D", required=true) + var dbSNP: File = _ + + @Input(doc="extra VCF files to use as reference indels for Indel Realignment", fullName="extra_indels", shortName="indels", required=true) + var indels: File = _ /**************************************************************************** @@ -42,12 +48,6 @@ class DataProcessingPipeline extends QScript { @Input(doc="The path to the binary of bwa (usually BAM files have already been mapped - but if you want to remap this is the option)", fullName="path_to_bwa", shortName="bwa", required=false) var bwaPath: File = _ - @Input(doc="dbsnp ROD to use (must be in VCF format)", fullName="dbsnp", shortName="D", required=false) - var dbSNP: File = new File("/humgen/gsa-hpprojects/GATK/data/dbsnp_132_b37.leftAligned.vcf") - - @Input(doc="extra VCF files to use as reference indels for Indel Realignment", fullName="extra_indels", shortName="indels", required=false) - var indels: File = new File("/humgen/gsa-hpprojects/GATK/data/Comparisons/Unvalidated/AFR+EUR+ASN+1KG.dindel_august_release_merged_pilot1.20110126.sites.vcf") - @Input(doc="the project name determines the final output (BAM file) base name. Example NA12878 yields NA12878.processed.bam", fullName="project", shortName="p", required=false) var projectName: String = "project" @@ -295,7 +295,7 @@ class DataProcessingPipeline extends QScript { this.targetIntervals = tIntervals this.out = outBam this.rodBind :+= RodBind("dbsnp", "VCF", dbSNP) - this.rodBind :+= RodBind("indels", "VCF", qscript.indels) + this.rodBind :+= RodBind("indels", "VCF", indels) this.consensusDeterminationModel = consensusDeterminationModel this.compress = 0 this.scatterCount = nContigs @@ -318,7 +318,7 @@ class DataProcessingPipeline extends QScript { case class recal (inBam: File, inRecalFile: File, outBam: File) extends TableRecalibration with CommandLineGATKArgs { this.input_file :+= inBam this.recal_file = inRecalFile - this.baq = org.broadinstitute.sting.utils.baq.BAQ.CalculationMode.CALCULATE_AS_NECESSARY + this.baq = CalculationMode.CALCULATE_AS_NECESSARY this.out = outBam if (!qscript.intervalString.isEmpty()) this.intervalsString ++= List(qscript.intervalString) else if (qscript.intervals != null) this.intervals :+= qscript.intervals From dd92a14b40b6270cf093b38830aab3987b8d0d25 Mon Sep 17 00:00:00 2001 From: Mauricio Carneiro Date: Sat, 16 Jul 2011 00:23:35 -0400 Subject: [PATCH 34/35] Made extra indel VCF optional but DBSNP mandatory. --- .../queue/qscripts/DataProcessingPipeline.scala | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/public/scala/qscript/org/broadinstitute/sting/queue/qscripts/DataProcessingPipeline.scala b/public/scala/qscript/org/broadinstitute/sting/queue/qscripts/DataProcessingPipeline.scala index 4d4499990..d55b86d69 100755 --- a/public/scala/qscript/org/broadinstitute/sting/queue/qscripts/DataProcessingPipeline.scala +++ b/public/scala/qscript/org/broadinstitute/sting/queue/qscripts/DataProcessingPipeline.scala @@ -33,10 +33,6 @@ class DataProcessingPipeline extends QScript { @Input(doc="dbsnp ROD to use (must be in VCF format)", fullName="dbsnp", shortName="D", required=true) var dbSNP: File = _ - @Input(doc="extra VCF files to use as reference indels for Indel Realignment", fullName="extra_indels", shortName="indels", required=true) - var indels: File = _ - - /**************************************************************************** * Optional Parameters ****************************************************************************/ @@ -45,6 +41,10 @@ class DataProcessingPipeline extends QScript { // @Input(doc="path to Picard's SortSam.jar (if re-aligning a previously processed BAM file)", fullName="path_to_sort_jar", shortName="sort", required=false) // var sortSamJar: File = _ // + + @Input(doc="extra VCF files to use as reference indels for Indel Realignment", fullName="extra_indels", shortName="indels", required=false) + var indels: File = _ + @Input(doc="The path to the binary of bwa (usually BAM files have already been mapped - but if you want to remap this is the option)", fullName="path_to_bwa", shortName="bwa", required=false) var bwaPath: File = _ @@ -284,7 +284,8 @@ class DataProcessingPipeline extends QScript { this.out = outIntervals this.mismatchFraction = 0.0 this.rodBind :+= RodBind("dbsnp", "VCF", dbSNP) - this.rodBind :+= RodBind("indels", "VCF", indels) + if (!indels.isEmpty) + this.rodBind :+= RodBind("indels", "VCF", indels) this.scatterCount = nContigs this.analysisName = queueLogDir + outIntervals + ".target" this.jobName = queueLogDir + outIntervals + ".target" @@ -295,7 +296,8 @@ class DataProcessingPipeline extends QScript { this.targetIntervals = tIntervals this.out = outBam this.rodBind :+= RodBind("dbsnp", "VCF", dbSNP) - this.rodBind :+= RodBind("indels", "VCF", indels) + if (!indels.isEmpty) + this.rodBind :+= RodBind("indels", "VCF", indels) this.consensusDeterminationModel = consensusDeterminationModel this.compress = 0 this.scatterCount = nContigs From 5e7bc862a34d7366c168209261ea5aedb812c790 Mon Sep 17 00:00:00 2001 From: Mark DePristo Date: Sat, 16 Jul 2011 08:51:21 -0400 Subject: [PATCH 35/35] Rev tribble to include new equal() method that prints out details of why two indices are not the same. --- .../{tribble-3.jar => tribble-4.jar} | Bin 258609 -> 286423 bytes .../{tribble-3.xml => tribble-4.xml} | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename settings/repository/org.broad/{tribble-3.jar => tribble-4.jar} (69%) rename settings/repository/org.broad/{tribble-3.xml => tribble-4.xml} (58%) diff --git a/settings/repository/org.broad/tribble-3.jar b/settings/repository/org.broad/tribble-4.jar similarity index 69% rename from settings/repository/org.broad/tribble-3.jar rename to settings/repository/org.broad/tribble-4.jar index f0ab44a05fb969693b20757be8d29b18f3b611a6..1f82f3cc05b8f02f117506269a8b96110cff591a 100644 GIT binary patch delta 50001 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 diff --git a/settings/repository/org.broad/tribble-3.xml b/settings/repository/org.broad/tribble-4.xml similarity index 58% rename from settings/repository/org.broad/tribble-3.xml rename to settings/repository/org.broad/tribble-4.xml index c35358331..07235efb0 100644 --- a/settings/repository/org.broad/tribble-3.xml +++ b/settings/repository/org.broad/tribble-4.xml @@ -1,4 +1,4 @@ -