Merge pull request #804 from broadinstitute/jt_read_filters

Allows users to disable the DuplicateReadFilter
This commit is contained in:
jmthibault79 2015-01-21 15:45:48 -05:00
commit d209699485
7 changed files with 127 additions and 6 deletions

View File

@ -34,6 +34,7 @@ import htsjdk.samtools.reference.ReferenceSequenceFile;
import htsjdk.variant.vcf.VCFConstants;
import org.apache.log4j.Logger;
import org.broadinstitute.gatk.engine.arguments.GATKArgumentCollection;
import org.broadinstitute.gatk.engine.filters.DisableableReadFilter;
import org.broadinstitute.gatk.utils.downsampling.DownsampleType;
import org.broadinstitute.gatk.utils.ValidationExclusion;
import org.broadinstitute.gatk.engine.datasources.reads.*;
@ -354,7 +355,7 @@ public class GenomeAnalysisEngine {
final List<ReadFilter> filters = new LinkedList<>();
// First add the user requested filters
if (this.getArguments().readGroupBlackList != null && this.getArguments().readGroupBlackList.size() > 0)
if (this.getArguments().readGroupBlackList != null && !this.getArguments().readGroupBlackList.isEmpty())
filters.add(new ReadGroupBlackListFilter(this.getArguments().readGroupBlackList));
for(final String filterName: this.getArguments().readFilters)
filters.add(this.getFilterManager().createByName(filterName));
@ -363,6 +364,20 @@ public class GenomeAnalysisEngine {
// users need to apply filters that fix up reads that would be removed by default walker filters
filters.addAll(WalkerManager.getReadFilters(walker,this.getFilterManager()));
// disable user-specified read filters, if allowed
for(final String filterName: this.getArguments().disabledReadFilters) {
ReadFilter filterToDisable = this.getFilterManager().createByName(filterName);
if (! (filterToDisable instanceof DisableableReadFilter))
throw new IllegalStateException(filterToDisable + " cannot be disabled");
// so we're not trying to modify the list we're iterating over
List<ReadFilter> filtersCopy = new ArrayList<>(filters);
for (ReadFilter filter : filtersCopy) {
if (filter.getClass() == filterToDisable.getClass())
filters.remove(filter);
}
}
return Collections.unmodifiableList(filters);
}

View File

@ -25,6 +25,7 @@
package org.broadinstitute.gatk.engine;
import org.broadinstitute.gatk.engine.filters.DisableableReadFilter;
import org.broadinstitute.gatk.engine.walkers.*;
import org.broadinstitute.gatk.utils.commandline.Hidden;
import org.broadinstitute.gatk.engine.datasources.rmd.ReferenceOrderedDataSource;
@ -420,12 +421,20 @@ public class WalkerManager extends PluginManager<Walker> {
public static Collection<Class<? extends ReadFilter>> getReadFilterTypes(Class<?> walkerClass) {
List<Class<? extends ReadFilter>> filterTypes = new ArrayList<Class<? extends ReadFilter>>();
while(walkerClass != null) {
// Add the read filters in the ReadFilters annotation
if(walkerClass.isAnnotationPresent(ReadFilters.class)) {
for ( Class c : walkerClass.getAnnotation(ReadFilters.class).value() ) {
if( !filterTypes.contains(c) )
filterTypes.add(c);
}
}
// Remove read filters in the DisabledReadFilters annotation
if(walkerClass.isAnnotationPresent(DisabledReadFilters.class)) {
for ( Class c : walkerClass.getAnnotation(DisabledReadFilters.class).value() ) {
if ( filterTypes.contains(c) )
filterTypes.remove(c);
}
}
walkerClass = walkerClass.getSuperclass();
}
return filterTypes;

View File

@ -117,11 +117,14 @@ public class GATKArgumentCollection {
* documentation. Note that the read name format is e.g. MalformedReadFilter, but at the command line the filter
* name should be given without the Filter suffix; e.g. -rf MalformedRead (NOT -rf MalformedReadFilter, which is not
* recognized by the program). Note also that some read filters are applied by default for some analysis tools; this
* is specified in each tool's documentation. The default filters cannot be disabled.
* is specified in each tool's documentation. The default filters can only be disabled if they are DisableableReadFilters.
*/
@Argument(fullName = "read_filter", shortName = "rf", doc = "Filters to apply to reads before analysis", required = false)
public final List<String> readFilters = new ArrayList<>();
@Argument(fullName = "disable_read_filter", shortName = "drf", doc = "Read filters to disable", required = false)
public final List<String> disabledReadFilters = new ArrayList<>();
@ArgumentCollection
public IntervalArgumentCollection intervalArguments = new IntervalArgumentCollection();
/**

View File

@ -0,0 +1,35 @@
/*
* Copyright (c) 2012 The Broad Institute
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
* THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package org.broadinstitute.gatk.engine.filters;
import org.broadinstitute.gatk.utils.help.DocumentedGATKFeature;
import org.broadinstitute.gatk.utils.help.HelpConstants;
@DocumentedGATKFeature(
groupName = HelpConstants.DOCS_CAT_RF,
summary = "A ReadFilter which can be disabled by using the --disable_read_filter parameter" )
public abstract class DisableableReadFilter extends ReadFilter {
}

View File

@ -59,7 +59,7 @@ import htsjdk.samtools.SAMRecord;
* @since Dec 9, 2009
*/
public class DuplicateReadFilter extends ReadFilter {
public class DuplicateReadFilter extends DisableableReadFilter {
public boolean filterOut( final SAMRecord read ) {
return read.getDuplicateReadFlag();
}

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2012 The Broad Institute
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
* THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package org.broadinstitute.gatk.engine.walkers;
import htsjdk.samtools.filter.SamRecordFilter;
import java.lang.annotation.*;
/**
* An annotation to describe which inherited ReadFilters to disable
*/
@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface DisabledReadFilters {
public Class<? extends SamRecordFilter>[] value() default {};
}

View File

@ -32,6 +32,7 @@ import org.broadinstitute.gatk.utils.commandline.*;
import org.broadinstitute.gatk.utils.contexts.AlignmentContext;
import org.broadinstitute.gatk.utils.contexts.ReferenceContext;
import org.broadinstitute.gatk.engine.filters.MappingQualityUnavailableFilter;
import org.broadinstitute.gatk.engine.filters.DuplicateReadFilter;
import org.broadinstitute.gatk.utils.refdata.RefMetaDataTracker;
import org.broadinstitute.gatk.utils.collections.Pair;
import org.broadinstitute.gatk.utils.exceptions.ReviewedGATKException;
@ -150,8 +151,9 @@ public class EngineFeaturesIntegrationTest extends WalkerTest {
//
// --------------------------------------------------------------------------------
@ReadFilters({MappingQualityUnavailableFilter.class})
public static class DummyReadWalkerWithMapqUnavailableFilter extends ReadWalker<Integer, Integer> {
@ReadFilters({MappingQualityUnavailableFilter.class, DuplicateReadFilter.class})
@DisabledReadFilters({DuplicateReadFilter.class})
public static class DummyReadWalkerWithFilters extends ReadWalker<Integer, Integer> {
@Output
PrintStream out;
@ -179,11 +181,27 @@ public class EngineFeaturesIntegrationTest extends WalkerTest {
@Test(enabled = true)
public void testUserReadFilterAppliedBeforeWalker() {
WalkerTestSpec spec = new WalkerTestSpec("-R " + b37KGReference + " -I " + privateTestDir + "allMAPQ255.bam"
+ " -T DummyReadWalkerWithMapqUnavailableFilter -o %s -L MT -rf ReassignMappingQuality",
+ " -T DummyReadWalkerWithFilters -o %s -L MT -rf ReassignMappingQuality",
1, Arrays.asList("ecf27a776cdfc771defab1c5d19de9ab"));
executeTest("testUserReadFilterAppliedBeforeWalker", spec);
}
@Test(enabled = true)
public void testUserReadFilterDisabledAppliedBeforeWalker() {
WalkerTestSpec spec = new WalkerTestSpec("-R " + b37KGReference + " -I " + privateTestDir + "allMAPQ255.bam"
+ " -T DummyReadWalkerWithFilters -o %s -L MT -drf DuplicateRead",
1, Arrays.asList("897316929176464ebc9ad085f31e7284"));
executeTest("testUserReadFilterDisabledAppliedBeforeWalker", spec);
}
@Test( enabled = true, expectedExceptions = RuntimeException.class )
public void testUserReadFilterDisabledAppliedBeforeWalkerException() {
WalkerTestSpec spec = new WalkerTestSpec("-R " + b37KGReference + " -I " + privateTestDir + "allMAPQ255.bam"
+ " -T DummyReadWalkerWithFilters -o %s -L MT -drf ReassignMappingQuality",
1, Arrays.asList(""));
executeTest("testUserReadFilterDisabledAppliedBeforeWalkerException", spec);
}
@Test
public void testNegativeCompress() {
testBadCompressArgument(-1);