From 9579aace1ff56210eefb7f32ec2ab1ab65e0fe27 Mon Sep 17 00:00:00 2001 From: aaron Date: Fri, 23 Jul 2010 01:56:10 +0000 Subject: [PATCH] updates to code dependent on Tribble, as well as the following Tribble changes: - makes writing to disk optional for indexes using the indexCreator classes (allow the user to specify the index file, if null don't write it) - removed some system.out debugging code - fixed version checking in interval tree - made indexes store and return a LinkedHashSet for sequence names (to ensure they've preserved the ordering in the file) - index creators now read the file before creating the index - changed the Index.write() method to take a LEDataStream instead of a file - removed the sequence dictionary code on the header - added utils for getting LEDataStreams - added a base Tribble exception git-svn-id: file:///humgen/gsa-scr1/gsa-engineering/svn_contents/trunk@3857 348d0f76-0448-11de-a6fe-93d51630548a --- .../builders/TribbleRMDTrackBuilder.java | 47 ++++- .../builders/IndexPerformanceTests.java | 175 ++++++++++++++++++ .../TribbleRMDTrackBuilderUnitTest.java | 4 +- .../utils/genotype/vcf/VCFWriterUnitTest.java | 2 +- .../{tribble-122M.jar => tribble-124M.jar} | Bin 187414 -> 191541 bytes .../{tribble-122M.xml => tribble-124M.xml} | 2 +- 6 files changed, 218 insertions(+), 12 deletions(-) create mode 100644 java/test/org/broadinstitute/sting/gatk/refdata/tracks/builders/IndexPerformanceTests.java rename settings/repository/org.broad/{tribble-122M.jar => tribble-124M.jar} (78%) rename settings/repository/org.broad/{tribble-122M.xml => tribble-124M.xml} (64%) 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 60436fb15..254aea5a1 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 @@ -26,13 +26,17 @@ package org.broadinstitute.sting.gatk.refdata.tracks.builders; import net.sf.samtools.SAMSequenceDictionary; +import net.sf.samtools.SAMSequenceRecord; import org.apache.log4j.Logger; import org.broad.tribble.*; import org.broad.tribble.index.Index; +import org.broad.tribble.index.IndexCreator; import org.broad.tribble.index.IndexFactory; -import org.broad.tribble.index.linear.LinearIndex; +import org.broad.tribble.index.interval.IntervalIndexCreator; import org.broad.tribble.index.linear.LinearIndexCreator; import org.broad.tribble.source.BasicFeatureSource; +import org.broad.tribble.util.LEDataOutputStream; +import org.broad.tribble.util.LEDataStreamUtils; import org.broad.tribble.vcf.NameAwareCodec; import org.broadinstitute.sting.gatk.refdata.tracks.TribbleTrack; import org.broadinstitute.sting.gatk.refdata.tracks.RMDTrack; @@ -45,8 +49,7 @@ import org.broadinstitute.sting.utils.file.FSLockWithShared; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; -import java.util.HashMap; -import java.util.Map; +import java.util.*; /** @@ -65,9 +68,11 @@ public class TribbleRMDTrackBuilder extends PluginManager implemen */ private static Logger logger = Logger.getLogger(TribbleRMDTrackBuilder.class); + // what index to use + static boolean useLinearIndex = true; // the linear index extension - public static final String linearIndexExtension = ".idx"; + public static final String indexExtension = ".idx"; /** Create a new plugin manager. */ public TribbleRMDTrackBuilder() { @@ -157,7 +162,10 @@ public class TribbleRMDTrackBuilder extends PluginManager implemen Pair reader; try { Index index = loadIndex(inputFile, createCodec(targetClass, name), true); - reader = new Pair(new BasicFeatureSource(inputFile.getAbsolutePath(), index, createCodec(targetClass, name)),index.getSequenceDictionary()); + reader = new Pair(new BasicFeatureSource(inputFile.getAbsolutePath(), + index, + createCodec(targetClass, name)), + sequenceSetToDictionary(index.getSequenceNames())); } catch (FileNotFoundException e) { throw new StingException("Unable to create reader with file " + inputFile, e); } catch (IOException e) { @@ -177,7 +185,7 @@ public class TribbleRMDTrackBuilder extends PluginManager implemen public synchronized static Index loadIndex(File inputFile, FeatureCodec codec, boolean onDisk) throws IOException { // create the index file name, locking on the index file name - File indexFile = new File(inputFile.getAbsoluteFile() + linearIndexExtension); + File indexFile = new File(inputFile.getAbsoluteFile() + indexExtension); FSLockWithShared lock = new FSLockWithShared(indexFile); // acquire a lock on the file @@ -259,7 +267,9 @@ public class TribbleRMDTrackBuilder extends PluginManager implemen locked = lock.exclusiveLock(); if (locked) { logger.info("Writing Tribble index to disk for file " + inputFile); - index.write(indexFile); + LEDataOutputStream stream = LEDataStreamUtils.createOutputStream(indexFile); + index.write(stream); + stream.close(); } else // we can't write it to disk, just store it in memory, tell them this if (onDisk) logger.info("Unable to write to " + indexFile + " for the index file, creating index in memory only"); @@ -280,7 +290,28 @@ public class TribbleRMDTrackBuilder extends PluginManager implemen private static Index createIndexInMemory(File inputFile, FeatureCodec codec) throws IOException { // this can take a while, let them know what we're doing logger.info("Creating Tribble index in memory for file " + inputFile); - LinearIndexCreator creator = new LinearIndexCreator(inputFile,codec,null); + IndexCreator creator; + if (useLinearIndex) + creator = new LinearIndexCreator(inputFile,codec,null); + else + creator = new IntervalIndexCreator(inputFile, codec, null); return creator.createIndex(); } + + /** + * convert a list of Strings into a sequence dictionary + * @param contigList the contig list, in coordinate order, this is allowed to be null + * @return a SAMSequenceDictionary, WITHOUT contig sizes + */ + private static final SAMSequenceDictionary sequenceSetToDictionary(LinkedHashSet contigList) { + SAMSequenceDictionary dict = new SAMSequenceDictionary(); + if (contigList == null) return dict; + + for (String name : contigList) { + SAMSequenceRecord seq = new SAMSequenceRecord(name, 0); + dict.addSequence(seq); + } + return dict; + } + } diff --git a/java/test/org/broadinstitute/sting/gatk/refdata/tracks/builders/IndexPerformanceTests.java b/java/test/org/broadinstitute/sting/gatk/refdata/tracks/builders/IndexPerformanceTests.java new file mode 100644 index 000000000..25fd04b60 --- /dev/null +++ b/java/test/org/broadinstitute/sting/gatk/refdata/tracks/builders/IndexPerformanceTests.java @@ -0,0 +1,175 @@ +package org.broadinstitute.sting.gatk.refdata.tracks.builders; + +import net.sf.picard.reference.IndexedFastaSequenceFile; +import net.sf.samtools.SAMSequenceDictionary; +import org.apache.log4j.Level; +import org.apache.log4j.Logger; +import org.broad.tribble.Feature; +import org.broad.tribble.index.Index; +import org.broad.tribble.index.linear.LinearIndex; +import org.broad.tribble.iterators.CloseableTribbleIterator; +import org.broad.tribble.source.BasicFeatureSource; +import org.broad.tribble.vcf.VCF3Codec; +import org.broad.tribble.vcf.VCFCodec; +import org.broadinstitute.sting.BaseTest; +import org.broadinstitute.sting.gatk.refdata.features.annotator.AnnotatorInputTableCodec; +import org.broadinstitute.sting.utils.GenomeLocParser; +import org.broadinstitute.sting.utils.collections.Pair; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.*; + +/** + * performance tests for different index types + */ +public class IndexPerformanceTests extends BaseTest { + // the RMD track builder + private TribbleRMDTrackBuilder builder; + + // set the logger level + Logger logger = Logger.getLogger(IndexPerformanceTests.class); + + // the input files to test + Map inputFiles = new LinkedHashMap(); + + // the input types + Map inputTypes = new HashMap(); + + PrintWriter writer; + PrintWriter writer2; + /** setup the files we're going to run with, including their names */ + @Before + public void setupFilesAndIndexes() { + logger.setLevel(Level.INFO); + builder = new TribbleRMDTrackBuilder(); + IndexedFastaSequenceFile seq = new IndexedFastaSequenceFile(new File(hg18Reference)); + GenomeLocParser.setupRefContigOrdering(seq); + + // the input files + inputFiles.put("\"10\"",new File("tip10.vcf")); + inputFiles.put("\"100\"",new File("tip100.vcf")); + inputFiles.put("\"1,000\"",new File("tip1000.vcf")); + inputFiles.put("\"10,000\"",new File("tip10000.vcf")); + inputFiles.put("\"100,000\"",new File("tip100000.vcf")); + inputFiles.put("\"1,000,000\"",new File("tip1000000.vcf")); + + for (String name : inputFiles.keySet()) { + inputTypes.put(name,VCFCodec.class); + } + inputFiles.put("Big Table",new File("/humgen/gsa-hpprojects/dev/depristo/oneOffProjects/slowAnnotator/big.table.txt")); + inputTypes.put("Big Table", AnnotatorInputTableCodec.class); + /*inputFiles.put("100", new File("1000.vcf")); + inputFiles.put("Medium (100K) VCF",new File("100K.vcf")); + inputFiles.put("Big Table",new File("/humgen/gsa-hpprojects/dev/depristo/oneOffProjects/slowAnnotator/big.table.txt")); + inputFiles.put("Huge (1M) VCF",new File("1M.vcf")); + // the input types + inputTypes.put("Huge (1M) VCF", VCFCodec.class); + inputTypes.put("Medium (100K) VCF", VCFCodec.class); + inputTypes.put("1000 records VCF", VCFCodec.class); + inputTypes.put("Big Table", AnnotatorInputTableCodec.class);*/ + } + + @Test + public void emptyTest() { + // do nothing + } + + //@Test + public void performanceTest() { + try { + writer = new PrintWriter(new FileWriter("testOutput_linear.txt")); + writer2 = new PrintWriter(new FileWriter("testOutput_tree.txt")); + } catch (IOException e) { + Assert.fail("Unable to open file testOutput.txt"); + } + writer.println("name,index,createTime,seekTime,thousandPerThousand,record_count,index_size"); + writer2.println("name,index,createTime,seekTime,thousandPerThousand,record_count,index_size"); + for (String name : inputFiles.keySet()) { + System.err.println("running " + name + " with linear index"); + printTestLine(name,true); + System.err.println("running " + name + " with tree index"); + printTestLine(name,false); + } + writer.close(); + writer2.close(); + } + + private void printTestLine(String name, boolean useLinear) { + PrintWriter wr = (useLinear) ? writer : writer2; + List values = performIndexTest(name,useLinear); + wr.print(name + "," + ((useLinear) ? "linear" : "tree")); + for (Long l : values) { + wr.print(","); + wr.print(l); + } + wr.println(); + } + + /** + * time various tasks using the specified index + * @param name the name to get + * @return a five-piece: the time to create the index, the time to seek to chromosome 1, and the time to process reading + * every other 1000 bases of chr1 (of the first 100M), the count of records seen in the last oepration, and the index size + */ + public List performIndexTest(String name, boolean useLinear) { + TribbleRMDTrackBuilder.useLinearIndex = useLinear; + deleteIndex(inputFiles.get(name)); + // time creating the index + long createTime = System.currentTimeMillis(); + Pair pairing = builder.createFeatureReader(inputTypes.get(name),inputFiles.get(name)); + createTime = System.currentTimeMillis() - createTime; + System.err.println("index creation took " + createTime); + + // seek to chr1 + long seekTo1 = seekToChr1(pairing); + + // seek every 1000 bases in Chr1 + long count = 0; + long thousandEveryThousand = System.currentTimeMillis(); + try { + for (int x = 1; x < 1000000; x = x + 1000) { + //CloseableTribbleIterator iter = pairing.first.query("chr1", x+(int)Math.floor(Math.random()*1000), x+1000); // query + CloseableTribbleIterator iter = pairing.first.query("chr1", x, x+1000); // query + for (Feature feat : iter) { + count++; + } + } + + } catch (IOException e) { + Assert.fail("Unable to load file for query!!"); + } + thousandEveryThousand = System.currentTimeMillis() - thousandEveryThousand; + System.err.println("thousand every thousand (for first million) took " + thousandEveryThousand); + return Arrays.asList(createTime,seekTo1,thousandEveryThousand,count,new File(inputFiles.get(name) + ".idx").length()); + } + + private long seekToChr1(Pair pairing) { + // time seeking to the first 1M bases of Chr1 + long seekTo1 = System.currentTimeMillis(); + try { + CloseableTribbleIterator iter = pairing.first.query("chr1",1,10000000); // query + } catch (IOException e) { + Assert.fail("Unable to load file for query!!"); + } + seekTo1 = System.currentTimeMillis() - seekTo1; + System.err.println("seeking to chr1 took " + seekTo1); + return seekTo1; + } + + + private void deleteIndex(File fl) { + File indexFile = new File(fl + TribbleRMDTrackBuilder.indexExtension); + boolean deleted = true; + if (indexFile.exists()) + deleted = indexFile.delete(); + if (!deleted) + Assert.fail("Unable to delete index file"); + } + +} 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 262c32b87..c988dae57 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 @@ -73,8 +73,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) - //System.err.println(new File(vcfFile + TribbleRMDTrackBuilder.linearIndexExtension).lastModified()); - Assert.assertTrue(Math.abs(1279591752000l - new File(vcfFile + TribbleRMDTrackBuilder.linearIndexExtension).lastModified()) < 100); + //System.err.println(new File(vcfFile + TribbleRMDTrackBuilder.indexExtension).lastModified()); + Assert.assertTrue(Math.abs(1279591752000l - new File(vcfFile + TribbleRMDTrackBuilder.indexExtension).lastModified()) < 100); } diff --git a/java/test/org/broadinstitute/sting/utils/genotype/vcf/VCFWriterUnitTest.java b/java/test/org/broadinstitute/sting/utils/genotype/vcf/VCFWriterUnitTest.java index 33f69adfb..1cbea1029 100644 --- a/java/test/org/broadinstitute/sting/utils/genotype/vcf/VCFWriterUnitTest.java +++ b/java/test/org/broadinstitute/sting/utils/genotype/vcf/VCFWriterUnitTest.java @@ -76,7 +76,7 @@ public class VCFWriterUnitTest extends BaseTest { counter++; } Assert.assertEquals(2,counter); - new File(fakeVCFFile + TribbleRMDTrackBuilder.linearIndexExtension).delete(); + new File(fakeVCFFile + TribbleRMDTrackBuilder.indexExtension).delete(); fakeVCFFile.delete(); } catch (IOException e ) { diff --git a/settings/repository/org.broad/tribble-122M.jar b/settings/repository/org.broad/tribble-124M.jar similarity index 78% rename from settings/repository/org.broad/tribble-122M.jar rename to settings/repository/org.broad/tribble-124M.jar index a39750e2f13175f384fb868cb6dd97c5c7e8d398..51780b5cb6aff86667394834c9e9b0798663e038 100644 GIT binary patch delta 22625 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 Zb$-b#`tI*aLc|2Pn)#FP+?UzT{2v{FUi|<7 delta 20213 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 diff --git a/settings/repository/org.broad/tribble-122M.xml b/settings/repository/org.broad/tribble-124M.xml similarity index 64% rename from settings/repository/org.broad/tribble-122M.xml rename to settings/repository/org.broad/tribble-124M.xml index 3d74b4640..ffb0daf3d 100644 --- a/settings/repository/org.broad/tribble-122M.xml +++ b/settings/repository/org.broad/tribble-124M.xml @@ -1,3 +1,3 @@ - +