From 0b03e28b60876c00370b577016b4e5d0ea5e6202 Mon Sep 17 00:00:00 2001 From: aaron Date: Fri, 4 Jun 2010 06:34:26 +0000 Subject: [PATCH] updating the tribble library to include the reference dictionary reading / writing. We now check the dictionaries of any tracks that have them against the reference (all new tribble tracks and out-of-date tracks will have this). Also renamed some classes to be more reflective of their function. git-svn-id: file:///humgen/gsa-scr1/gsa-engineering/svn_contents/trunk@3485 348d0f76-0448-11de-a6fe-93d51630548a --- .../sting/gatk/GenomeAnalysisEngine.java | 81 ++++++++++++------ .../ReferenceOrderedDataSource.java | 10 +-- .../sting/gatk/refdata/tracks/RMDTrack.java | 11 ++- ...tureReaderTrack.java => TribbleTrack.java} | 21 ++++- .../builders/TribbleRMDTrackBuilder.java | 46 ++++++---- .../walkers/DbSNPWindowCounter.java | 2 +- .../tracks/RMDTrackManagerUnitTest.java | 4 +- .../TribbleRMDTrackBuilderUnitTest.java | 3 +- settings/repository/org.broad/tribble-87.xml | 3 - .../{tribble-87.jar => tribble-88.jar} | Bin 217452 -> 219967 bytes settings/repository/org.broad/tribble-88.xml | 3 + 11 files changed, 123 insertions(+), 61 deletions(-) rename java/src/org/broadinstitute/sting/gatk/refdata/tracks/{FeatureReaderTrack.java => TribbleTrack.java} (85%) delete mode 100644 settings/repository/org.broad/tribble-87.xml rename settings/repository/org.broad/{tribble-87.jar => tribble-88.jar} (89%) create mode 100644 settings/repository/org.broad/tribble-88.xml diff --git a/java/src/org/broadinstitute/sting/gatk/GenomeAnalysisEngine.java b/java/src/org/broadinstitute/sting/gatk/GenomeAnalysisEngine.java index 71968fdb0..883dde665 100755 --- a/java/src/org/broadinstitute/sting/gatk/GenomeAnalysisEngine.java +++ b/java/src/org/broadinstitute/sting/gatk/GenomeAnalysisEngine.java @@ -334,8 +334,6 @@ public class GenomeAnalysisEngine { validateSuppliedReferenceAgainstWalker(my_walker, argCollection); referenceDataSource = openReferenceSequenceFile(argCollection.referenceFile); - validateReadsAndReferenceAreCompatible(readsDataSource, referenceDataSource); - // // please don't use these in the future, use the new syntax <- if we're not using these please remove them // @@ -353,6 +351,9 @@ public class GenomeAnalysisEngine { List tracks = manager.getReferenceMetaDataSources(argCollection.RODBindings); validateSuppliedReferenceOrderedDataAgainstWalker(my_walker, tracks); + // validate all the sequence dictionaries against the reference + validateSourcesAgainstReference(readsDataSource, referenceDataSource, tracks); + rodDataSources = getReferenceOrderedDataSources(my_walker, tracks); } @@ -604,22 +605,16 @@ public class GenomeAnalysisEngine { } /** - * Now that all files are open, validate the sequence dictionaries of the reads vs. the reference. + * Now that all files are open, validate the sequence dictionaries of the reads vs. the reference vrs the reference ordered data (if available). * * @param reads Reads data source. * @param reference Reference data source. + * @param tracks a collection of the reference ordered data tracks */ - private void validateReadsAndReferenceAreCompatible(SAMDataSource reads, ReferenceSequenceFile reference) { - if (reads == null || reference == null) + private void validateSourcesAgainstReference(SAMDataSource reads, ReferenceSequenceFile reference, Collection tracks) { + if ((reads == null && (tracks == null || tracks.isEmpty())) || reference == null ) return; - // Compile a set of sequence names that exist in the BAM files. - SAMSequenceDictionary readsDictionary = reads.getHeader().getSequenceDictionary(); - - Set readsSequenceNames = new TreeSet(); - for (SAMSequenceRecord dictionaryEntry : readsDictionary.getSequences()) - readsSequenceNames.add(dictionaryEntry.getSequenceName()); - // Compile a set of sequence names that exist in the reference file. SAMSequenceDictionary referenceDictionary = reference.getSequenceDictionary(); @@ -627,32 +622,70 @@ public class GenomeAnalysisEngine { for (SAMSequenceRecord dictionaryEntry : referenceDictionary.getSequences()) referenceSequenceNames.add(dictionaryEntry.getSequenceName()); - if (readsSequenceNames.size() == 0) { - logger.info("Reads file is unmapped. Skipping validation against reference."); - return; + + if (reads != null) { + // Compile a set of sequence names that exist in the BAM files. + SAMSequenceDictionary readsDictionary = reads.getHeader().getSequenceDictionary(); + + Set readsSequenceNames = new TreeSet(); + for (SAMSequenceRecord dictionaryEntry : readsDictionary.getSequences()) + readsSequenceNames.add(dictionaryEntry.getSequenceName()); + + + if (readsSequenceNames.size() == 0) { + logger.info("Reads file is unmapped. Skipping validation against reference."); + return; + } + + // compare the reads to the reference + compareTwoDictionaries("reads", readsDictionary, readsSequenceNames, referenceDictionary, referenceSequenceNames); } + // compare the tracks to the reference, if they have a sequence dictionary + for (RMDTrack track : tracks) { + SAMSequenceDictionary trackDict = track.getSequenceDictionary(); + if (trackDict == null) { + logger.info("Track " + track.getName() + "doesn't have a sequence dictionary built in, skipping dictionary validation"); + continue; + } + Set trackSequences = new TreeSet(); + for (SAMSequenceRecord dictionaryEntry : trackDict.getSequences()) + trackSequences.add(dictionaryEntry.getSequenceName()); + compareTwoDictionaries(track.getName(), trackDict, trackSequences, referenceDictionary, referenceSequenceNames); + } + + } + + /** + * compare two dictionaries, warning if one isn't a subset of the other, or erroring out if they have no overlap + * @param compareToName the name of the track or bam (used in the output to the user) + * @param comparedToDictionary the dictionary to compare to + * @param compareToSequenceNames the unique sequence names in the compared to dictionary + * @param referenceDictionary the reference dictionary + * @param referenceSequenceNames the reference unique sequence names + */ + private void compareTwoDictionaries(String compareToName, SAMSequenceDictionary comparedToDictionary, Set compareToSequenceNames, SAMSequenceDictionary referenceDictionary, Set referenceSequenceNames) { // If there's no overlap between reads and reference, data will be bogus. Throw an exception. - Set intersectingSequenceNames = new HashSet(readsSequenceNames); + Set intersectingSequenceNames = new HashSet(compareToSequenceNames); intersectingSequenceNames.retainAll(referenceSequenceNames); if (intersectingSequenceNames.size() == 0) { StringBuilder error = new StringBuilder(); - error.append("No overlap exists between sequence dictionary of the reads and the sequence dictionary of the reference. Perhaps you're using the wrong reference?\n"); + error.append("No overlap exists between sequence dictionary of the " + compareToName + " and the sequence dictionary of the reference. Perhaps you're using the wrong reference?\n"); error.append(System.getProperty("line.separator")); - error.append(String.format("Reads contigs: %s%n", prettyPrintSequenceRecords(readsDictionary))); + error.append(String.format(compareToName + " contigs: %s%n", prettyPrintSequenceRecords(comparedToDictionary))); error.append(String.format("Reference contigs: %s%n", prettyPrintSequenceRecords(referenceDictionary))); logger.error(error.toString()); - Utils.scareUser("No overlap exists between sequence dictionary of the reads and the sequence dictionary of the reference."); + Utils.scareUser("No overlap exists between sequence dictionary of " + compareToName + " and the sequence dictionary of the reference."); } // If the two datasets are not equal and neither is a strict subset of the other, warn the user. - if (!readsSequenceNames.equals(referenceSequenceNames) && - !readsSequenceNames.containsAll(referenceSequenceNames) && - !referenceSequenceNames.containsAll(readsSequenceNames)) { + if (!compareToSequenceNames.equals(referenceSequenceNames) && + !compareToSequenceNames.containsAll(referenceSequenceNames) && + !referenceSequenceNames.containsAll(compareToSequenceNames)) { StringBuilder warning = new StringBuilder(); - warning.append("Limited overlap exists between sequence dictionary of the reads and the sequence dictionary of the reference. Perhaps you're using the wrong reference?\n"); + warning.append("Limited overlap exists between sequence dictionary of the " + compareToName + " and the sequence dictionary of the reference. Perhaps you're using the wrong reference?\n"); warning.append(System.getProperty("line.separator")); - warning.append(String.format("Reads contigs: %s%n", prettyPrintSequenceRecords(readsDictionary))); + warning.append(String.format(compareToName + " contigs: %s%n", prettyPrintSequenceRecords(comparedToDictionary))); warning.append(String.format("Reference contigs: %s%n", prettyPrintSequenceRecords(referenceDictionary))); logger.warn(warning.toString()); } diff --git a/java/src/org/broadinstitute/sting/gatk/datasources/simpleDataSources/ReferenceOrderedDataSource.java b/java/src/org/broadinstitute/sting/gatk/datasources/simpleDataSources/ReferenceOrderedDataSource.java index cd2880f91..fe56bca0b 100755 --- a/java/src/org/broadinstitute/sting/gatk/datasources/simpleDataSources/ReferenceOrderedDataSource.java +++ b/java/src/org/broadinstitute/sting/gatk/datasources/simpleDataSources/ReferenceOrderedDataSource.java @@ -3,7 +3,7 @@ package org.broadinstitute.sting.gatk.datasources.simpleDataSources; import org.broad.tribble.FeatureReader; import org.broadinstitute.sting.gatk.datasources.shards.Shard; import org.broadinstitute.sting.gatk.refdata.SeekableRODIterator; -import org.broadinstitute.sting.gatk.refdata.tracks.FeatureReaderTrack; +import org.broadinstitute.sting.gatk.refdata.tracks.TribbleTrack; import org.broadinstitute.sting.gatk.refdata.tracks.RMDTrack; import org.broadinstitute.sting.gatk.refdata.tracks.builders.TribbleRMDTrackBuilder; import org.broadinstitute.sting.gatk.refdata.utils.FeatureToGATKFeatureIterator; @@ -15,8 +15,6 @@ import org.broadinstitute.sting.utils.GenomeLoc; import org.broadinstitute.sting.utils.StingException; import java.io.IOException; -import java.util.Arrays; -import java.util.LinkedList; import java.util.List; /** * User: hanna @@ -52,7 +50,7 @@ public class ReferenceOrderedDataSource implements SimpleDataSource { public ReferenceOrderedDataSource( Walker walker, RMDTrack rod) { this.rod = rod; if (rod.supportsQuery()) - iteratorPool = new ReferenceOrderedQueryDataPool(new TribbleRMDTrackBuilder(), (FeatureReaderTrack)rod); + iteratorPool = new ReferenceOrderedQueryDataPool(new TribbleRMDTrackBuilder(), (TribbleTrack)rod); else iteratorPool = new ReferenceOrderedDataPool( walker, rod ); } @@ -187,7 +185,7 @@ class ReferenceOrderedQueryDataPool extends ResourcePool implemen @Override public RMDTrack createInstanceOfTrack(Class targetClass, String name, File inputFile) throws RMDTrackCreationException { // return a feature reader track - return new FeatureReaderTrack(targetClass, this.createByType(targetClass).getFeatureType(), name, inputFile, createFeatureReader(targetClass, inputFile)); + Pair pair = createFeatureReader(targetClass, inputFile); + if (pair == null) throw new StingException("Unable to make the feature reader for input file " + inputFile); + return new TribbleTrack(targetClass, this.createByType(targetClass).getFeatureType(), name, inputFile, pair.first, pair.second); } /** @@ -103,13 +106,13 @@ public class TribbleRMDTrackBuilder extends PluginManager implemen * @param inputFile the input file to create the track from (of the codec type) * @return the FeatureReader instance */ - public FeatureReader createFeatureReader(Class targetClass, File inputFile) { - FeatureReader reader = null; + public Pair createFeatureReader(Class targetClass, File inputFile) { + Pair pair = null; if (inputFile.getAbsolutePath().endsWith(".gz")) - reader = createBasicFeatureReaderNoAssumedIndex(targetClass, inputFile); + pair = createBasicFeatureReaderNoAssumedIndex(targetClass, inputFile); else - reader = getLinearFeatureReader(targetClass, inputFile); - return reader; + pair = getLinearFeatureReader(targetClass, inputFile); + return pair; } /** @@ -121,11 +124,11 @@ public class TribbleRMDTrackBuilder extends PluginManager implemen * @param inputFile the file to load * @return a feature reader implementation */ - private BasicFeatureReader createBasicFeatureReaderNoAssumedIndex(Class targetClass, File inputFile) { + private Pair createBasicFeatureReaderNoAssumedIndex(Class targetClass, File inputFile) { // we might not know the index type, try loading with the default reader constructor - logger.debug("Attempting to blindly load " + inputFile); + logger.info("Attempting to blindly load " + inputFile + " as a tabix indexed file"); try { - return new BasicFeatureReader(inputFile.getAbsolutePath(),this.createByType(targetClass)); + return new Pair(new BasicFeatureReader(inputFile.getAbsolutePath(),this.createByType(targetClass)),null); } catch (IOException e) { throw new StingException("Unable to create feature reader from file " + inputFile); } @@ -137,11 +140,11 @@ public class TribbleRMDTrackBuilder extends PluginManager implemen * @param inputFile the tribble file to parse * @return the input file as a FeatureReader */ - private FeatureReader getLinearFeatureReader(Class targetClass, File inputFile) { - FeatureReader reader; + private Pair getLinearFeatureReader(Class targetClass, File inputFile) { + Pair reader; try { Index index = loadIndex(inputFile, this.createByType(targetClass), true); - reader = new BasicFeatureReader(inputFile.getAbsolutePath(), index, this.createByType(targetClass)); + reader = new Pair(new BasicFeatureReader(inputFile.getAbsolutePath(), index, this.createByType(targetClass)),index.getSequenceDictionary()); } catch (FileNotFoundException e) { throw new StingException("Unable to create reader with file " + inputFile, e); } catch (IOException e) { @@ -160,9 +163,6 @@ public class TribbleRMDTrackBuilder extends PluginManager implemen */ public synchronized static Index loadIndex(File inputFile, FeatureCodec codec, boolean onDisk) throws IOException { - // our return index - LinearIndex returnIndex = null; - // create the index file name, locking on the index file name File indexFile = new File(inputFile.getAbsoluteFile() + linearIndexExtension); FSLock lock = new FSLock(indexFile); @@ -178,7 +178,12 @@ public class TribbleRMDTrackBuilder extends PluginManager implemen // if the file exists, and we can read it, load the index from disk (i.e. wasn't deleted in the last step). if (indexFile.exists() && indexFile.canRead() && obtainedLock) { logger.info("Loading Tribble index from disk for file " + inputFile); - return LinearIndex.createIndex(indexFile); + Index index = LinearIndex.createIndex(indexFile); + if (index.isCurrentVersion()) + return index; + + logger.warn("Index file " + indexFile + " is out of date (old version), deleting and updating the index file"); + indexFile.delete(); } return writeIndexToDisk(inputFile, codec, onDisk, indexFile, obtainedLock); } @@ -200,6 +205,9 @@ public class TribbleRMDTrackBuilder extends PluginManager implemen */ private static LinearIndex writeIndexToDisk(File inputFile, FeatureCodec codec, boolean onDisk, File indexFile, boolean obtainedLock) throws IOException { LinearIndexCreator create = new LinearIndexCreator(inputFile, codec); + + // this can take a while, let them know what we're doing + logger.info("Creating Tribble index in memory for file " + inputFile); LinearIndex index = create.createIndex(null); // we don't want to write initially, so we pass in null // if the index doesn't exist, and we can write to the directory, and we got a lock: write to the disk @@ -207,7 +215,7 @@ public class TribbleRMDTrackBuilder extends PluginManager implemen (!indexFile.exists() || indexFile.canWrite()) && onDisk && obtainedLock) { - logger.info("Creating Tribble Index on disk for file " + inputFile); + logger.info("Writing Tribble index to disk for file " + inputFile); index.write(indexFile); return index; } diff --git a/java/src/org/broadinstitute/sting/oneoffprojects/walkers/DbSNPWindowCounter.java b/java/src/org/broadinstitute/sting/oneoffprojects/walkers/DbSNPWindowCounter.java index b9ed2cf3b..a7ca7b5ba 100644 --- a/java/src/org/broadinstitute/sting/oneoffprojects/walkers/DbSNPWindowCounter.java +++ b/java/src/org/broadinstitute/sting/oneoffprojects/walkers/DbSNPWindowCounter.java @@ -46,7 +46,7 @@ public class DbSNPWindowCounter extends LocusWalker { public void initialize() { TribbleRMDTrackBuilder builder = new TribbleRMDTrackBuilder(); - reader = builder.createFeatureReader(DbSNPCodec.class,myDbSNPFile); + reader = builder.createFeatureReader(DbSNPCodec.class,myDbSNPFile).first; } diff --git a/java/test/org/broadinstitute/sting/gatk/refdata/tracks/RMDTrackManagerUnitTest.java b/java/test/org/broadinstitute/sting/gatk/refdata/tracks/RMDTrackManagerUnitTest.java index c7a09d7e2..ad812b7e4 100644 --- a/java/test/org/broadinstitute/sting/gatk/refdata/tracks/RMDTrackManagerUnitTest.java +++ b/java/test/org/broadinstitute/sting/gatk/refdata/tracks/RMDTrackManagerUnitTest.java @@ -71,7 +71,7 @@ public class RMDTrackManagerUnitTest extends BaseTest { int count = 0; Iterator fIter; try { - fIter = ((FeatureReaderTrack) t).query("1", 1, 5000); + fIter = ((TribbleTrack) t).query("1", 1, 5000); } catch (IOException e) { throw new StingException("blah I/O exception"); } @@ -126,7 +126,7 @@ public class RMDTrackManagerUnitTest extends BaseTest { long firstTime = System.currentTimeMillis(); long count = 0; try { - fIter = ((FeatureReaderTrack) t).query("1", x, x + intervalSize); + fIter = ((TribbleTrack) t).query("1", x, x + intervalSize); } catch (IOException e) { throw new StingException("blah I/O exception"); } diff --git a/java/test/org/broadinstitute/sting/gatk/refdata/tracks/builders/TribbleRMDTrackBuilderUnitTest.java b/java/test/org/broadinstitute/sting/gatk/refdata/tracks/builders/TribbleRMDTrackBuilderUnitTest.java index 75bfb301a..63c22dd37 100644 --- a/java/test/org/broadinstitute/sting/gatk/refdata/tracks/builders/TribbleRMDTrackBuilderUnitTest.java +++ b/java/test/org/broadinstitute/sting/gatk/refdata/tracks/builders/TribbleRMDTrackBuilderUnitTest.java @@ -70,7 +70,8 @@ public class TribbleRMDTrackBuilderUnitTest extends BaseTest { Assert.fail("IO exception unexpected" + e.getMessage()); } // make sure we didn't write the file (check that it's timestamp is within bounds) - Assert.assertTrue(Math.abs(1274210993000l - new File(vcfFile + TribbleRMDTrackBuilder.linearIndexExtension).lastModified()) < 100); + //System.err.println(new File(vcfFile + TribbleRMDTrackBuilder.linearIndexExtension).lastModified()); + Assert.assertTrue(Math.abs(1275597793000l - new File(vcfFile + TribbleRMDTrackBuilder.linearIndexExtension).lastModified()) < 100); } diff --git a/settings/repository/org.broad/tribble-87.xml b/settings/repository/org.broad/tribble-87.xml deleted file mode 100644 index bb714a30d..000000000 --- a/settings/repository/org.broad/tribble-87.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/settings/repository/org.broad/tribble-87.jar b/settings/repository/org.broad/tribble-88.jar similarity index 89% rename from settings/repository/org.broad/tribble-87.jar rename to settings/repository/org.broad/tribble-88.jar index 35d047b5814796dae7ff9799fa194d02776d2beb..6786642fdb4f1769179e4118ab3c0ffe97211a2f 100644 GIT binary patch delta 10117 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 NDO3GD)05$Q`fuZXNZtSd diff --git a/settings/repository/org.broad/tribble-88.xml b/settings/repository/org.broad/tribble-88.xml new file mode 100644 index 000000000..1c14d8043 --- /dev/null +++ b/settings/repository/org.broad/tribble-88.xml @@ -0,0 +1,3 @@ + + +