Merge pull request #90 from broadinstitute/eb_allow_read_transform_ordering
Added the functionality to impose a relative ordering on ReadTransformer...
This commit is contained in:
commit
7d833256e8
|
|
@ -62,6 +62,9 @@ public class BQSRReadTransformer extends ReadTransformer {
|
|||
private boolean enabled;
|
||||
private BaseRecalibration bqsr = null;
|
||||
|
||||
@Override
|
||||
public OrderingConstraint getOrderingConstraint() { return OrderingConstraint.MUST_BE_FIRST; }
|
||||
|
||||
@Override
|
||||
public ApplicationTime initializeSub(final GenomeAnalysisEngine engine, final Walker walker) {
|
||||
this.enabled = engine.hasBQSRArgumentSet();
|
||||
|
|
|
|||
|
|
@ -372,7 +372,8 @@ public class GenomeAnalysisEngine {
|
|||
* @param walker the walker we need to apply read transformers too
|
||||
*/
|
||||
public void initializeReadTransformers(final Walker walker) {
|
||||
final List<ReadTransformer> activeTransformers = new ArrayList<ReadTransformer>();
|
||||
// keep a list of the active read transformers sorted based on priority ordering
|
||||
List<ReadTransformer> activeTransformers = new ArrayList<ReadTransformer>();
|
||||
|
||||
final ReadTransformersMode overrideMode = WalkerManager.getWalkerAnnotation(walker, ReadTransformersMode.class);
|
||||
final ReadTransformer.ApplicationTime overrideTime = overrideMode != null ? overrideMode.ApplicationTime() : null;
|
||||
|
|
@ -392,9 +393,41 @@ public class GenomeAnalysisEngine {
|
|||
return readTransformers;
|
||||
}
|
||||
|
||||
private void setReadTransformers(final List<ReadTransformer> readTransformers) {
|
||||
/*
|
||||
* Sanity checks that incompatible read transformers are not active together (and throws an exception if they are).
|
||||
*
|
||||
* @param readTransformers the active read transformers
|
||||
*/
|
||||
protected void checkActiveReadTransformers(final List<ReadTransformer> readTransformers) {
|
||||
if ( readTransformers == null )
|
||||
throw new IllegalArgumentException("read transformers cannot be null");
|
||||
|
||||
ReadTransformer sawMustBeFirst = null;
|
||||
ReadTransformer sawMustBeLast = null;
|
||||
|
||||
for ( final ReadTransformer r : readTransformers ) {
|
||||
if ( r.getOrderingConstraint() == ReadTransformer.OrderingConstraint.MUST_BE_FIRST ) {
|
||||
if ( sawMustBeFirst != null )
|
||||
throw new UserException.IncompatibleReadFiltersException(sawMustBeFirst.toString(), r.toString());
|
||||
sawMustBeFirst = r;
|
||||
} else if ( r.getOrderingConstraint() == ReadTransformer.OrderingConstraint.MUST_BE_LAST ) {
|
||||
if ( sawMustBeLast != null )
|
||||
throw new UserException.IncompatibleReadFiltersException(sawMustBeLast.toString(), r.toString());
|
||||
sawMustBeLast = r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void setReadTransformers(final List<ReadTransformer> readTransformers) {
|
||||
if ( readTransformers == null )
|
||||
throw new ReviewedStingException("read transformers cannot be null");
|
||||
|
||||
// sort them in priority order
|
||||
Collections.sort(readTransformers, new ReadTransformer.ReadTransformerComparator());
|
||||
|
||||
// make sure we don't have an invalid set of active read transformers
|
||||
checkActiveReadTransformers(readTransformers);
|
||||
|
||||
this.readTransformers = readTransformers;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,8 @@ import org.broadinstitute.sting.gatk.GenomeAnalysisEngine;
|
|||
import org.broadinstitute.sting.gatk.walkers.Walker;
|
||||
import org.broadinstitute.sting.utils.sam.GATKSAMRecord;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
/**
|
||||
* Baseclass used to describe a read transformer like BAQ and BQSR
|
||||
*
|
||||
|
|
@ -65,6 +67,11 @@ abstract public class ReadTransformer {
|
|||
|
||||
protected ReadTransformer() {}
|
||||
|
||||
/*
|
||||
* @return the ordering constraint for the given read transformer
|
||||
*/
|
||||
public OrderingConstraint getOrderingConstraint() { return OrderingConstraint.DO_NOT_CARE; }
|
||||
|
||||
/**
|
||||
* Master initialization routine. Called to setup a ReadTransform, using it's overloaded initializeSub routine.
|
||||
*
|
||||
|
|
@ -166,4 +173,33 @@ abstract public class ReadTransformer {
|
|||
*/
|
||||
HANDLED_IN_WALKER
|
||||
}
|
||||
|
||||
/*
|
||||
* This enum specifies the constraints that the given read transformer has relative to any other read transformers being used
|
||||
*/
|
||||
public enum OrderingConstraint {
|
||||
/*
|
||||
* If 2 read transformers are both active and MUST_BE_FIRST, then an error will be generated
|
||||
*/
|
||||
MUST_BE_FIRST,
|
||||
|
||||
/*
|
||||
* No constraints on the ordering for this read transformer
|
||||
*/
|
||||
DO_NOT_CARE,
|
||||
|
||||
/*
|
||||
* If 2 read transformers are both active and MUST_BE_LAST, then an error will be generated
|
||||
*/
|
||||
MUST_BE_LAST
|
||||
}
|
||||
|
||||
public static class ReadTransformerComparator implements Comparator<ReadTransformer> {
|
||||
|
||||
public int compare(final ReadTransformer r1, final ReadTransformer r2) {
|
||||
if ( r1.getOrderingConstraint() == r2.getOrderingConstraint() )
|
||||
return 0;
|
||||
return ( r1.getOrderingConstraint() == OrderingConstraint.MUST_BE_FIRST || r2.getOrderingConstraint() == OrderingConstraint.MUST_BE_LAST ) ? -1 : 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,6 +75,12 @@ public class UserException extends ReviewedStingException {
|
|||
}
|
||||
}
|
||||
|
||||
public static class IncompatibleReadFiltersException extends CommandLineException {
|
||||
public IncompatibleReadFiltersException(final String filter1, final String filter2) {
|
||||
super(String.format("Two read filters are enabled that are incompatible and cannot be used simultaneously: %s and %s", filter1, filter2));
|
||||
}
|
||||
}
|
||||
|
||||
public static class MalformedWalkerArgumentsException extends CommandLineException {
|
||||
public MalformedWalkerArgumentsException(String message) {
|
||||
super(String.format("Malformed walker argument: %s",message));
|
||||
|
|
|
|||
|
|
@ -29,15 +29,23 @@ import org.broadinstitute.sting.BaseTest;
|
|||
import org.broadinstitute.sting.commandline.ArgumentException;
|
||||
import org.broadinstitute.sting.commandline.Tags;
|
||||
import org.broadinstitute.sting.gatk.datasources.reads.SAMReaderID;
|
||||
import org.broadinstitute.sting.gatk.iterators.ReadTransformer;
|
||||
import org.broadinstitute.sting.gatk.walkers.Walker;
|
||||
import org.broadinstitute.sting.gatk.walkers.readutils.PrintReads;
|
||||
import org.broadinstitute.sting.utils.GenomeLocParser;
|
||||
import org.broadinstitute.sting.utils.GenomeLocSortedSet;
|
||||
import org.broadinstitute.sting.utils.exceptions.UserException;
|
||||
import org.broadinstitute.sting.utils.sam.ArtificialSAMUtils;
|
||||
import org.broadinstitute.sting.utils.sam.GATKSAMRecord;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Tests selected functionality in the GenomeAnalysisEngine class
|
||||
|
|
@ -81,4 +89,89 @@ public class GenomeAnalysisEngineUnitTest extends BaseTest {
|
|||
|
||||
testEngine.validateSuppliedIntervals();
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////
|
||||
// Test the ReadTransformer ordering enforcement //
|
||||
///////////////////////////////////////////////////
|
||||
|
||||
public static class TestReadTransformer extends ReadTransformer {
|
||||
|
||||
private OrderingConstraint orderingConstraint = OrderingConstraint.DO_NOT_CARE;
|
||||
private boolean enabled;
|
||||
|
||||
protected TestReadTransformer(final OrderingConstraint orderingConstraint) {
|
||||
this.orderingConstraint = orderingConstraint;
|
||||
enabled = true;
|
||||
}
|
||||
|
||||
// need this because PackageUtils will pick up this class as a possible ReadTransformer
|
||||
protected TestReadTransformer() {
|
||||
enabled = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OrderingConstraint getOrderingConstraint() { return orderingConstraint; }
|
||||
|
||||
@Override
|
||||
public ApplicationTime initializeSub(final GenomeAnalysisEngine engine, final Walker walker) { return ApplicationTime.HANDLED_IN_WALKER; }
|
||||
|
||||
@Override
|
||||
public boolean enabled() { return enabled; }
|
||||
|
||||
@Override
|
||||
public GATKSAMRecord apply(final GATKSAMRecord read) { return read; }
|
||||
|
||||
}
|
||||
|
||||
@DataProvider(name = "ReadTransformerData")
|
||||
public Object[][] makeReadTransformerData() {
|
||||
List<Object[]> tests = new ArrayList<Object[]>();
|
||||
|
||||
for ( final ReadTransformer.OrderingConstraint orderingConstraint1 : ReadTransformer.OrderingConstraint.values() ) {
|
||||
for ( final ReadTransformer.OrderingConstraint orderingConstraint2 : ReadTransformer.OrderingConstraint.values() ) {
|
||||
for ( final ReadTransformer.OrderingConstraint orderingConstraint3 : ReadTransformer.OrderingConstraint.values() ) {
|
||||
tests.add(new Object[]{orderingConstraint1, orderingConstraint2, orderingConstraint3});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tests.toArray(new Object[][]{});
|
||||
}
|
||||
|
||||
@Test(dataProvider = "ReadTransformerData")
|
||||
public void testReadTransformer(final ReadTransformer.OrderingConstraint oc1, final ReadTransformer.OrderingConstraint oc2, final ReadTransformer.OrderingConstraint oc3) {
|
||||
|
||||
final GenomeAnalysisEngine testEngine = new GenomeAnalysisEngine();
|
||||
final List<ReadTransformer> readTransformers = new ArrayList<ReadTransformer>(3);
|
||||
readTransformers.add(new TestReadTransformer(oc1));
|
||||
readTransformers.add(new TestReadTransformer(oc2));
|
||||
readTransformers.add(new TestReadTransformer(oc3));
|
||||
|
||||
final boolean shouldThrowException = numWithConstraint(ReadTransformer.OrderingConstraint.MUST_BE_FIRST, oc1, oc2, oc3) > 1 ||
|
||||
numWithConstraint(ReadTransformer.OrderingConstraint.MUST_BE_LAST, oc1, oc2, oc3) > 1;
|
||||
|
||||
try {
|
||||
testEngine.setReadTransformers(readTransformers);
|
||||
|
||||
Assert.assertFalse(shouldThrowException);
|
||||
Assert.assertEquals(testEngine.getReadTransformers().size(), 3);
|
||||
|
||||
Assert.assertTrue(testEngine.getReadTransformers().get(1).getOrderingConstraint() != ReadTransformer.OrderingConstraint.MUST_BE_FIRST);
|
||||
Assert.assertTrue(testEngine.getReadTransformers().get(2).getOrderingConstraint() != ReadTransformer.OrderingConstraint.MUST_BE_FIRST);
|
||||
Assert.assertTrue(testEngine.getReadTransformers().get(0).getOrderingConstraint() != ReadTransformer.OrderingConstraint.MUST_BE_LAST);
|
||||
Assert.assertTrue(testEngine.getReadTransformers().get(1).getOrderingConstraint() != ReadTransformer.OrderingConstraint.MUST_BE_LAST);
|
||||
} catch (UserException.IncompatibleReadFiltersException e) {
|
||||
Assert.assertTrue(shouldThrowException);
|
||||
}
|
||||
}
|
||||
|
||||
private int numWithConstraint(final ReadTransformer.OrderingConstraint target, final ReadTransformer.OrderingConstraint... constraints ) {
|
||||
int count = 0;
|
||||
for ( final ReadTransformer.OrderingConstraint constraint : constraints ) {
|
||||
if ( constraint == target )
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue