GSA-182: Adding support for BED interval files.
git-svn-id: file:///humgen/gsa-scr1/gsa-engineering/svn_contents/trunk@1767 348d0f76-0448-11de-a6fe-93d51630548a
This commit is contained in:
parent
aec83b401d
commit
66fc8ea444
|
|
@ -42,6 +42,7 @@ import org.broadinstitute.sting.gatk.walkers.*;
|
|||
import org.broadinstitute.sting.gatk.filters.ZeroMappingQualityReadFilter;
|
||||
import org.broadinstitute.sting.gatk.io.OutputTracker;
|
||||
import org.broadinstitute.sting.utils.*;
|
||||
import org.broadinstitute.sting.utils.bed.BedParser;
|
||||
import org.broadinstitute.sting.utils.fasta.IndexedFastaSequenceFile;
|
||||
import org.broadinstitute.sting.utils.cmdLine.ArgumentException;
|
||||
import org.broadinstitute.sting.utils.cmdLine.ArgumentSource;
|
||||
|
|
@ -75,17 +76,25 @@ public class GenomeAnalysisEngine {
|
|||
// our argument collection
|
||||
private GATKArgumentCollection argCollection;
|
||||
|
||||
/** Collection of inputs used by the walker. */
|
||||
/**
|
||||
* Collection of inputs used by the walker.
|
||||
*/
|
||||
private Map<ArgumentSource, Object> inputs = new HashMap<ArgumentSource, Object>();
|
||||
|
||||
/** Collection of outputs used by the walker. */
|
||||
/**
|
||||
* Collection of outputs used by the walker.
|
||||
*/
|
||||
private Collection<Stub<?>> outputs = new ArrayList<Stub<?>>();
|
||||
|
||||
|
||||
/** our log, which we want to capture anything from this class */
|
||||
/**
|
||||
* our log, which we want to capture anything from this class
|
||||
*/
|
||||
private static Logger logger = Logger.getLogger(GenomeAnalysisEngine.class);
|
||||
|
||||
/** our walker manager */
|
||||
/**
|
||||
* our walker manager
|
||||
*/
|
||||
private final WalkerManager walkerManager;
|
||||
|
||||
/**
|
||||
|
|
@ -93,7 +102,6 @@ public class GenomeAnalysisEngine {
|
|||
* <p/>
|
||||
* legacy traversal types are sent to legacyTraversal function; as we move more of the traversals to the
|
||||
* new MicroScheduler class we'll be able to delete that function.
|
||||
*
|
||||
*/
|
||||
public GenomeAnalysisEngine() {
|
||||
// make sure our instance variable points to this analysis engine
|
||||
|
|
@ -103,6 +111,7 @@ public class GenomeAnalysisEngine {
|
|||
|
||||
/**
|
||||
* Actually run the GATK with the specified walker.
|
||||
*
|
||||
* @param args the argument collection, where we get all our setup information from
|
||||
* @param my_walker Walker to run over the dataset. Must not be null.
|
||||
* @return the value of this traversal.
|
||||
|
|
@ -142,6 +151,7 @@ public class GenomeAnalysisEngine {
|
|||
|
||||
/**
|
||||
* Add additional, externally managed IO streams for walker input.
|
||||
*
|
||||
* @param argumentSource Field in the walker into which to inject the value.
|
||||
* @param value Instance to inject.
|
||||
*/
|
||||
|
|
@ -151,6 +161,7 @@ public class GenomeAnalysisEngine {
|
|||
|
||||
/**
|
||||
* Add additional, externally managed IO streams for walker output.
|
||||
*
|
||||
* @param stub Instance to inject.
|
||||
*/
|
||||
public void addOutput(Stub<?> stub) {
|
||||
|
|
@ -159,6 +170,7 @@ public class GenomeAnalysisEngine {
|
|||
|
||||
/**
|
||||
* Gets a set of the names of all walkers that the GATK has discovered.
|
||||
*
|
||||
* @return A set of the names of all discovered walkers.
|
||||
*/
|
||||
public Set<String> getWalkerNames() {
|
||||
|
|
@ -167,6 +179,7 @@ public class GenomeAnalysisEngine {
|
|||
|
||||
/**
|
||||
* Retrieves an instance of the walker based on the walker name.
|
||||
*
|
||||
* @param walkerName Name of the walker. Must not be null. If the walker cannot be instantiated, an exception will be thrown.
|
||||
* @return An instance of the walker.
|
||||
*/
|
||||
|
|
@ -210,6 +223,7 @@ public class GenomeAnalysisEngine {
|
|||
|
||||
/**
|
||||
* setup a microscheduler
|
||||
*
|
||||
* @param my_walker our walker of type LocusWalker
|
||||
* @return a new microscheduler
|
||||
*/
|
||||
|
|
@ -236,14 +250,19 @@ public class GenomeAnalysisEngine {
|
|||
* setup the interval regions, from either the interval file of the genome region string
|
||||
*
|
||||
* @param intervals the list of intervals to parse
|
||||
*
|
||||
* @return a list of genomeLoc representing the interval file
|
||||
*/
|
||||
public static List<GenomeLoc> parseIntervalRegion(final List<String> intervals) {
|
||||
List<GenomeLoc> locs = new ArrayList<GenomeLoc>();
|
||||
for (String interval : intervals) {
|
||||
if (new File(interval).exists()) {
|
||||
// support for the bed style interval format
|
||||
if (interval.endsWith(".bed") || interval.endsWith(".BED")) {
|
||||
BedParser parser = new BedParser(new File(interval));
|
||||
locs.addAll(parser.getSortedAndMergedLocations());
|
||||
} else {
|
||||
locs.addAll(GenomeLocParser.intervalFileToList(interval));
|
||||
}
|
||||
} else {
|
||||
locs.addAll(GenomeLocParser.parseGenomeLocs(interval));
|
||||
}
|
||||
|
|
@ -257,6 +276,7 @@ public class GenomeAnalysisEngine {
|
|||
* individual bam files). For instance: if GATK is run with three input bam files (three -I arguments), then the list
|
||||
* returned by this method will contain 3 elements (one for each reader), with each element being a set of sample names
|
||||
* found in the corresponding bam file.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public List<Set<String>> getSamplesByReaders() {
|
||||
|
|
@ -285,6 +305,7 @@ public class GenomeAnalysisEngine {
|
|||
* individual bam files). For instance: if GATK is run with three input bam files (three -I arguments), then the list
|
||||
* returned by this method will contain 3 elements (one for each reader), with each element being a set of library names
|
||||
* found in the corresponding bam file.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public List<Set<String>> getLibrariesByReaders() {
|
||||
|
|
@ -313,6 +334,7 @@ public class GenomeAnalysisEngine {
|
|||
* individual bam files). For instance: if GATK is run with three input bam files (three -I arguments), then the list
|
||||
* returned by this method will contain 3 elements (one for each reader), with each element being a set of remapped read groups
|
||||
* (i.e. as seen by read.getReadGroup().getReadGroupId() in the merged stream) that come from the corresponding bam file.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public List<Set<String>> getMergedReadGroupsByReaders() {
|
||||
|
|
@ -348,7 +370,6 @@ public class GenomeAnalysisEngine {
|
|||
*
|
||||
* @param walker The walker for which to extract info.
|
||||
* @param argCollection The collection of arguments passed to the engine.
|
||||
*
|
||||
* @return The reads object providing reads source info.
|
||||
*/
|
||||
private Reads extractSourceInfo(Walker walker, GATKArgumentCollection argCollection) {
|
||||
|
|
@ -370,6 +391,7 @@ public class GenomeAnalysisEngine {
|
|||
|
||||
/**
|
||||
* Verifies that the supplied set of reads files mesh with what the walker says it requires.
|
||||
*
|
||||
* @param walker Walker to test.
|
||||
* @param arguments Supplied reads files.
|
||||
*/
|
||||
|
|
@ -385,6 +407,7 @@ public class GenomeAnalysisEngine {
|
|||
|
||||
/**
|
||||
* Verifies that the supplied reference file mesh with what the walker says it requires.
|
||||
*
|
||||
* @param walker Walker to test.
|
||||
* @param arguments Supplied reads files.
|
||||
*/
|
||||
|
|
@ -401,6 +424,7 @@ public class GenomeAnalysisEngine {
|
|||
/**
|
||||
* Verifies that all required reference-ordered data has been supplied, and any reference-ordered data that was not
|
||||
* 'allowed' is still present.
|
||||
*
|
||||
* @param walker Walker to test.
|
||||
* @param rods Reference-ordered data to load.
|
||||
*/
|
||||
|
|
@ -426,6 +450,7 @@ public class GenomeAnalysisEngine {
|
|||
|
||||
/**
|
||||
* Now that all files are open, validate the sequence dictionaries of the reads vs. the reference.
|
||||
*
|
||||
* @param reads Reads data source.
|
||||
* @param reference Reference data source.
|
||||
*/
|
||||
|
|
@ -506,7 +531,6 @@ public class GenomeAnalysisEngine {
|
|||
* @param drivingDataSource Data on which to shard.
|
||||
* @param intervals Intervals to use when limiting sharding.
|
||||
* @param maxIterations the maximum number of iterations to run through
|
||||
*
|
||||
* @return Sharding strategy for this driving data source.
|
||||
*/
|
||||
protected ShardStrategy getShardStrategy(Walker walker,
|
||||
|
|
@ -566,7 +590,6 @@ public class GenomeAnalysisEngine {
|
|||
* Gets a data source for the given set of reads.
|
||||
*
|
||||
* @param reads the read source information
|
||||
*
|
||||
* @return A data source for the given set of reads.
|
||||
*/
|
||||
private SAMDataSource createReadsDataSource(Reads reads) {
|
||||
|
|
@ -583,7 +606,6 @@ public class GenomeAnalysisEngine {
|
|||
* Opens a reference sequence file paired with an index.
|
||||
*
|
||||
* @param refFile Handle to a reference sequence file. Non-null.
|
||||
*
|
||||
* @return A thread-safe file wrapper.
|
||||
*/
|
||||
private IndexedFastaSequenceFile openReferenceSequenceFile(File refFile) {
|
||||
|
|
@ -602,7 +624,6 @@ public class GenomeAnalysisEngine {
|
|||
* Open the reference-ordered data sources.
|
||||
*
|
||||
* @param rods the reference order data to execute using
|
||||
*
|
||||
* @return A list of reference-ordered data sources.
|
||||
*/
|
||||
private List<ReferenceOrderedDataSource> getReferenceOrderedDataSources(List<ReferenceOrderedData<? extends ReferenceOrderedDatum>> rods) {
|
||||
|
|
@ -639,6 +660,7 @@ public class GenomeAnalysisEngine {
|
|||
/**
|
||||
* Returns data source object encapsulating all essential info and handlers used to traverse
|
||||
* reads; header merger, individual file readers etc can be accessed through the returned data source object.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public SAMDataSource getDataSource() {
|
||||
|
|
|
|||
|
|
@ -247,9 +247,7 @@ public class GenomeLocSortedSet extends AbstractSet<GenomeLoc> {
|
|||
*/
|
||||
public static GenomeLocSortedSet createSetFromList(List<GenomeLoc> locs) {
|
||||
GenomeLocSortedSet set = new GenomeLocSortedSet();
|
||||
for (GenomeLoc l : locs) {
|
||||
set.add(l);
|
||||
}
|
||||
set.addAll(locs);
|
||||
return set;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,107 @@
|
|||
package org.broadinstitute.sting.utils.bed;
|
||||
|
||||
import org.broadinstitute.sting.utils.StingException;
|
||||
import org.broadinstitute.sting.utils.GenomeLoc;
|
||||
import org.broadinstitute.sting.utils.GenomeLocParser;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: aaron
|
||||
* Date: Oct 5, 2009
|
||||
* Time: 5:46:45 PM
|
||||
*/
|
||||
public class BedParser {
|
||||
// the GATk operates as a one based location, bed files are 0 based
|
||||
static final int TO_ONE_BASED_ADDITION = 1;
|
||||
|
||||
// the buffered reader input
|
||||
private final BufferedReader mIn;
|
||||
|
||||
// our array of locations
|
||||
private List<GenomeLoc> mLocations;
|
||||
|
||||
/**
|
||||
* parse a bed file, given it's location
|
||||
*
|
||||
* @param fl
|
||||
*/
|
||||
public BedParser(File fl) {
|
||||
try {
|
||||
mIn = new BufferedReader(new FileReader(fl));
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new StingException("Unable to open the bed file = " + fl);
|
||||
}
|
||||
mLocations = parseLocations();
|
||||
}
|
||||
|
||||
/**
|
||||
* parse a bed file, given an input reader
|
||||
*
|
||||
* @param fl the bed file
|
||||
*/
|
||||
public BedParser(BufferedReader fl) {
|
||||
mIn = fl;
|
||||
mLocations = parseLocations();
|
||||
}
|
||||
|
||||
/**
|
||||
* parse out the locations
|
||||
*
|
||||
* @return a list of GenomeLocs, sorted and merged
|
||||
*/
|
||||
private List<GenomeLoc> parseLocations() {
|
||||
String line = null;
|
||||
List<GenomeLoc> locArray = new ArrayList<GenomeLoc>();
|
||||
try {
|
||||
while ((line = mIn.readLine()) != null) {
|
||||
locArray.add(parseLocation(line));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new StingException("Unable to parse line in BED file.");
|
||||
}
|
||||
return locArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* parse a single location
|
||||
*
|
||||
* @param line the line, as a string
|
||||
* @return a parsed genome loc
|
||||
*/
|
||||
private GenomeLoc parseLocation(String line) {
|
||||
String contig;
|
||||
int start;
|
||||
int stop;
|
||||
try {
|
||||
String parts[] = line.split("\\s+");
|
||||
contig = parts[0];
|
||||
start = Integer.valueOf(parts[1]) + TO_ONE_BASED_ADDITION;
|
||||
stop = Integer.valueOf(parts[2]); // the ending point is an open interval
|
||||
} catch (Exception e) {
|
||||
throw new StingException("Unable to process bed file line = " + line);
|
||||
}
|
||||
|
||||
// we currently drop the rest of the bed record, which can contain names, scores, etc
|
||||
return GenomeLocParser.createGenomeLoc(contig, start, stop);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* return the sorted, and merged (for overlapping regions)
|
||||
*
|
||||
* @return an arraylist
|
||||
*/
|
||||
public List<GenomeLoc> getLocations() {
|
||||
return mLocations;
|
||||
}
|
||||
|
||||
public List<GenomeLoc> getSortedAndMergedLocations() {
|
||||
List<GenomeLoc> locs = new ArrayList<GenomeLoc>();
|
||||
locs.addAll(mLocations);
|
||||
Collections.sort(locs);
|
||||
return GenomeLocParser.mergeOverlappingLocations(locs);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
package org.broadinstitute.sting.utils.bed;
|
||||
|
||||
import org.broadinstitute.sting.BaseTest;
|
||||
import org.broadinstitute.sting.utils.fasta.IndexedFastaSequenceFile;
|
||||
import org.broadinstitute.sting.utils.StingException;
|
||||
import org.broadinstitute.sting.utils.GenomeLocParser;
|
||||
import org.broadinstitute.sting.utils.GenomeLoc;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.Assert;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: aaron
|
||||
* Date: Oct 5, 2009
|
||||
* Time: 9:09:42 PM
|
||||
* To change this template use File | Settings | File Templates.
|
||||
*/
|
||||
public class BedParserTest extends BaseTest {
|
||||
|
||||
private static IndexedFastaSequenceFile seq;
|
||||
private File bedFile = new File("testdata/sampleBedFile.bed");
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeTests() {
|
||||
try {
|
||||
seq = new IndexedFastaSequenceFile(new File("/broad/1KG/reference/human_b36_both.fasta"));
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new StingException("unable to load the sequence dictionary");
|
||||
}
|
||||
GenomeLocParser.setupRefContigOrdering(seq);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadBedFile() {
|
||||
BedParser parser = new BedParser(bedFile);
|
||||
List<GenomeLoc> location = parser.getLocations();
|
||||
Assert.assertEquals(4, location.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBedParsing() {
|
||||
BedParser parser = new BedParser(bedFile);
|
||||
List<GenomeLoc> location = parser.getLocations();
|
||||
Assert.assertEquals(4, location.size());
|
||||
Assert.assertTrue(location.get(0).getContig().equals("20"));
|
||||
Assert.assertTrue(location.get(1).getContig().equals("20"));
|
||||
Assert.assertTrue(location.get(2).getContig().equals("22"));
|
||||
Assert.assertTrue(location.get(3).getContig().equals("22"));
|
||||
|
||||
// now check the the start positions
|
||||
Assert.assertEquals(1, location.get(0).getStart());
|
||||
Assert.assertEquals(1002, location.get(1).getStart());
|
||||
Assert.assertEquals(1001, location.get(2).getStart());
|
||||
Assert.assertEquals(2001, location.get(3).getStart());
|
||||
|
||||
// now check the the stop positions
|
||||
Assert.assertEquals(999, location.get(0).getStop());
|
||||
Assert.assertEquals(2000, location.get(1).getStop());
|
||||
Assert.assertEquals(5000, location.get(2).getStop());
|
||||
Assert.assertEquals(6000, location.get(3).getStop());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadBedFileOverlapping() {
|
||||
BedParser parser = new BedParser(bedFile);
|
||||
List<GenomeLoc> location = parser.getSortedAndMergedLocations();
|
||||
Assert.assertEquals(3, location.size());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
20 0 999
|
||||
20 1001 2000
|
||||
22 1000 5000 cloneA 960 + 1000 5000 0 2 567,488, 0,3512
|
||||
22 2000 6000 cloneB 900 - 2000 6000 0 2 433,399, 0,3601
|
||||
Loading…
Reference in New Issue