diff --git a/public/java/src/org/broadinstitute/sting/gatk/refdata/RefMetaDataTracker.java b/public/java/src/org/broadinstitute/sting/gatk/refdata/RefMetaDataTracker.java index 73685d758..ab6ce9ce9 100644 --- a/public/java/src/org/broadinstitute/sting/gatk/refdata/RefMetaDataTracker.java +++ b/public/java/src/org/broadinstitute/sting/gatk/refdata/RefMetaDataTracker.java @@ -56,7 +56,7 @@ public class RefMetaDataTracker { else { Map tmap = new HashMap(allBindings.size()); for ( RODRecordList rod : allBindings ) { - if ( rod != null ) + if ( rod != null && ! rod.isEmpty() ) tmap.put(canonicalName(rod.getName()), rod); } @@ -141,17 +141,37 @@ public class RefMetaDataTracker { @Requires({"type != null", "onlyAtThisLoc != null"}) public T getFirstValue(final Class type, final GenomeLoc onlyAtThisLoc) { return safeGetFirst(getValues(type, onlyAtThisLoc)); + } - // - // ROD binding accessors - // + /** + * Gets all of the Tribble features bound to RodBinding spanning this locus, returning them as + * a list of specific type T extending Feature. + * + * Note that this function assumes that all of the bound features are instances of or + * subclasses of T. A ClassCastException will occur if this isn't the case. + * + * @param rodBinding Only Features coming from the track associated with this rodBinding are fetched + * @param The Tribble Feature type of the rodBinding, and consequently the type of the resulting list of Features + * @return A freshly allocated list of all of the bindings, or an empty list if none are bound. + */ @Requires({"rodBinding != null"}) @Ensures("result != null") public List getValues(final RodBinding rodBinding) { return addValues(rodBinding.getName(), rodBinding.getType(), new ArrayList(1), getTrackDataByName(rodBinding), null, false, false); } + /** + * Gets all of the Tribble features bound to any RodBinding in rodBindings, + * spanning this locus, returning them as a list of specific type T extending Feature. + * + * Note that this function assumes that all of the bound features are instances of or + * subclasses of T. A ClassCastException will occur if this isn't the case. + * + * @param rodBindings Only Features coming from the tracks associated with one of rodBindings are fetched + * @param The Tribble Feature type of the rodBinding, and consequently the type of the resulting list of Features + * @return A freshly allocated list of all of the bindings, or an empty list if none are bound. + */ @Requires({"rodBindings != null"}) @Ensures("result != null") public List getValues(final Collection> rodBindings) { @@ -161,12 +181,28 @@ public class RefMetaDataTracker { return results; } + /** + * The same logic as @link #getValues(RodBinding) but enforces that each Feature start at onlyAtThisLoc + * + * @param rodBinding Only Features coming from the track associated with this rodBinding are fetched + * @param The Tribble Feature type of the rodBinding, and consequently the type of the resulting list of Features + * @param onlyAtThisLoc only Features starting at this site are considered + * @return A freshly allocated list of all of the bindings, or an empty list if none are bound. + */ @Requires({"rodBinding != null", "onlyAtThisLoc != null"}) @Ensures("result != null") public List getValues(final RodBinding rodBinding, final GenomeLoc onlyAtThisLoc) { return addValues(rodBinding.getName(), rodBinding.getType(), new ArrayList(1), getTrackDataByName(rodBinding), onlyAtThisLoc, true, false); } + /** + * The same logic as @link #getValues(List) but enforces that each Feature start at onlyAtThisLoc + * + * @param rodBindings Only Features coming from the tracks associated with one of rodBindings are fetched + * @param The Tribble Feature type of the rodBinding, and consequently the type of the resulting list of Features + * @param onlyAtThisLoc only Features starting at this site are considered + * @return A freshly allocated list of all of the bindings, or an empty list if none are bound. + */ @Requires({"rodBindings != null", "onlyAtThisLoc != null"}) @Ensures("result != null") public List getValues(final Collection> rodBindings, final GenomeLoc onlyAtThisLoc) { @@ -176,16 +212,44 @@ public class RefMetaDataTracker { return results; } + /** + * Uses the same logic as @getValues(RodBinding) to determine the list + * of eligible Features and select a single element from the resulting set + * of eligible features. + * + * @param rodBinding Only Features coming from the track associated with this rodBinding are fetched + * @param as above + * @return A random single element the eligible Features found, or null if none are bound. + */ @Requires({"rodBinding != null"}) public T getFirstValue(final RodBinding rodBinding) { return safeGetFirst(addValues(rodBinding.getName(), rodBinding.getType(), null, getTrackDataByName(rodBinding), null, false, true)); } + /** + * Uses the same logic as @getValues(RodBinding, GenomeLoc) to determine the list + * of eligible Features and select a single element from the resulting set + * of eligible features. + * + * @param rodBinding Only Features coming from the track associated with this rodBinding are fetched + * @param as above + * @param onlyAtThisLoc only Features starting at this site are considered + * @return A random single element the eligible Features found, or null if none are bound. + */ @Requires({"rodBinding != null", "onlyAtThisLoc != null"}) public T getFirstValue(final RodBinding rodBinding, final GenomeLoc onlyAtThisLoc) { return safeGetFirst(addValues(rodBinding.getName(), rodBinding.getType(), null, getTrackDataByName(rodBinding), onlyAtThisLoc, true, true)); } + /** + * Uses the same logic as @getValues(List) to determine the list + * of eligible Features and select a single element from the resulting set + * of eligible features. + * + * @param rodBindings Only Features coming from the tracks associated with these rodBindings are fetched + * @param as above + * @return A random single element the eligible Features found, or null if none are bound. + */ @Requires({"rodBindings != null"}) public T getFirstValue(final Collection> rodBindings) { for ( RodBinding rodBinding : rodBindings ) { @@ -196,6 +260,16 @@ public class RefMetaDataTracker { return null; } + /** + * Uses the same logic as @getValues(RodBinding,GenomeLoc) to determine the list + * of eligible Features and select a single element from the resulting set + * of eligible features. + * + * @param rodBindings Only Features coming from the tracks associated with these rodBindings are fetched + * @param as above + * @param onlyAtThisLoc only Features starting at this site are considered + * @return A random single element the eligible Features found, or null if none are bound. + */ @Requires({"rodBindings != null", "onlyAtThisLoc != null"}) public T getFirstValue(final Collection> rodBindings, final GenomeLoc onlyAtThisLoc) { for ( RodBinding rodBinding : rodBindings ) { @@ -275,24 +349,6 @@ public class RefMetaDataTracker { return l; } - @Deprecated - public List getValuesAsGATKFeatures(final RodBinding rodBinding) { - return getValuesAsGATKFeatures(rodBinding.getName()); - } - - - /** - * get all the GATK features associated with a specific track name - * @param name the name of the track we're looking for - * @return a list of GATKFeatures for the target rmd - * - * Important: The list returned by this function is guaranteed not to be null, but may be empty! - */ - @Deprecated - public List getValuesAsGATKFeatures(final String name) { - return getTrackDataByName(name); - } - /** * Get all of the RMD tracks at the current site. Each track is returned as a single compound * object (RODRecordList) that may contain multiple RMD records associated with the current site. @@ -300,13 +356,7 @@ public class RefMetaDataTracker { * @return List of all tracks */ public List getBoundRodTracks() { - LinkedList bound = new LinkedList(); - - for ( RODRecordList value : map.values() ) { - if ( value.size() != 0 ) bound.add(value); - } - - return bound; + return new ArrayList(map.values()); } /** @@ -361,10 +411,10 @@ public class RefMetaDataTracker { values = addValues(name, type, values, rodList, curLocation, requireStartHere, takeFirstOnly ); if ( takeFirstOnly && ! values.isEmpty() ) break; - } + } - return values; - } + return values; + } diff --git a/public/java/src/org/broadinstitute/sting/utils/GenomeLocParser.java b/public/java/src/org/broadinstitute/sting/utils/GenomeLocParser.java index a5c6e0537..8d9768681 100644 --- a/public/java/src/org/broadinstitute/sting/utils/GenomeLocParser.java +++ b/public/java/src/org/broadinstitute/sting/utils/GenomeLocParser.java @@ -34,6 +34,7 @@ import net.sf.samtools.SAMRecord; import net.sf.samtools.SAMSequenceDictionary; import net.sf.samtools.SAMSequenceRecord; import org.apache.log4j.Logger; +import org.broad.tribble.Feature; import org.broadinstitute.sting.utils.exceptions.ReviewedStingException; import org.broadinstitute.sting.utils.exceptions.UserException; @@ -443,6 +444,15 @@ public class GenomeLocParser { } } + /** + * Creates a GenomeLoc from a Tribble feature + * @param feature + * @return + */ + public GenomeLoc createGenomeLoc(final Feature feature) { + return createGenomeLoc(feature.getChr(), feature.getStart(), feature.getEnd()); + } + /** * create a new genome loc, given the contig name, and a single position. Must be on the reference * @@ -457,19 +467,6 @@ public class GenomeLocParser { return createGenomeLoc(contig, getContigIndex(contig), pos, pos); } -// /** -// * Creates a new GenomeLoc without performing any validation on its contig or bounds. -// * FOR UNIT TESTING PURPOSES ONLY! -// * -// * @param contig the contig name -// * @param start start position of the interval -// * @param stop stop position of the interval -// * @return a new GenomeLoc representing the specified location -// */ -// public GenomeLoc createGenomeLocWithoutValidation( String contig, int start, int stop ) { -// return new GenomeLoc(contig, getContigIndexWithoutException(contig), start, stop); -// } - /** * create a new genome loc from an existing loc, with a new start position * Note that this function will NOT explicitly check the ending offset, in case someone wants to diff --git a/public/java/test/org/broadinstitute/sting/gatk/refdata/RefMetaDataTrackerUnitTest.java b/public/java/test/org/broadinstitute/sting/gatk/refdata/RefMetaDataTrackerUnitTest.java index 4c5bdbcda..ec05ae2a1 100644 --- a/public/java/test/org/broadinstitute/sting/gatk/refdata/RefMetaDataTrackerUnitTest.java +++ b/public/java/test/org/broadinstitute/sting/gatk/refdata/RefMetaDataTrackerUnitTest.java @@ -181,20 +181,12 @@ public class RefMetaDataTrackerUnitTest { private void testSimpleBindings(String name, RefMetaDataTracker tracker, RODRecordList expected) { List asValues = tracker.getValues(Feature.class, name); - List asFeatures = tracker.getValuesAsGATKFeatures(name); Assert.assertEquals(tracker.hasValues(name), expected != null); - Assert.assertEquals(asFeatures.size(), expected == null ? 0 : expected.size()); Assert.assertEquals(asValues.size(), expected == null ? 0 : expected.size()); if ( expected != null ) { for ( GATKFeature e : expected ) { - boolean foundFeature = false; - for ( GATKFeature f : asFeatures ) { - if ( e.getUnderlyingObject() == f.getUnderlyingObject() ) foundFeature = true; - } - Assert.assertTrue(foundFeature, "Never found expected GATKFeature " + e + " bound to " + name + " in " + tracker); - boolean foundValue = false; for ( Feature f : asValues ) { if ( e.getUnderlyingObject() == f ) foundValue = true;