Added hardClipLeadingInsertions UnitTest for the ReadClipper

fixed issue where a read starting with an insertion followed by a deletion would break, clipper can now safely clip the insertion and the deletion if that's the case.

note: test is turned off until contract changes to allow hanging insertions (left/right).
This commit is contained in:
Mauricio Carneiro 2011-12-16 17:22:40 -05:00
parent 075be52adc
commit fcc21180e8
3 changed files with 57 additions and 9 deletions

View File

@ -204,16 +204,12 @@ public class ReadClipper {
for(CigarElement cigarElement : read.getCigar().getCigarElements()) {
if (cigarElement.getOperator() != CigarOperator.HARD_CLIP && cigarElement.getOperator() != CigarOperator.SOFT_CLIP &&
cigarElement.getOperator() != CigarOperator.INSERTION && cigarElement.getOperator() != CigarOperator.DELETION)
cigarElement.getOperator() != CigarOperator.INSERTION)
break;
else if (cigarElement.getOperator() == CigarOperator.INSERTION) {
else if (cigarElement.getOperator() == CigarOperator.INSERTION)
this.addOp(new ClippingOp(0, cigarElement.getLength() - 1));
}
else if (cigarElement.getOperator() == CigarOperator.DELETION) {
throw new ReviewedStingException("No read should start with a deletion. Aligner bug?");
}
}
return clipRead(ClippingRepresentation.HARDCLIP_BASES);
}

View File

@ -176,4 +176,16 @@ public class ClipReadsTestUtils {
Assert.assertEquals(actual.isEmpty(), expected.isEmpty());
}
public static Cigar invertCigar (Cigar cigar) {
Stack<CigarElement> cigarStack = new Stack<CigarElement>();
for (CigarElement cigarElement : cigar.getCigarElements())
cigarStack.push(cigarElement);
Cigar invertedCigar = new Cigar();
while (!cigarStack.isEmpty())
invertedCigar.add(cigarStack.pop());
return invertedCigar;
}
}

View File

@ -46,7 +46,7 @@ import java.util.List;
public class ReadClipperUnitTest extends BaseTest {
List<Cigar> cigarList;
int maximumCigarSize = 10;
int maximumCigarSize = 6; // 6 is the minimum necessary number to try all combinations of cigar types with guarantee of clipping an element with length = 2
@BeforeClass
public void init() {
@ -277,10 +277,31 @@ public class ReadClipperUnitTest extends BaseTest {
// logger.warn(String.format("Cigar %s -> %s -- PASSED!", read.getCigarString(), clippedRead.getCigarString()));
}
logger.warn("PASSED");
}
@Test(enabled = false)
public void testHardClipLeadingInsertions() {
for (Cigar cigar : cigarList) {
if (startsWithInsertion(cigar)) {
GATKSAMRecord read = ClipReadsTestUtils.makeReadFromCigar(cigar);
GATKSAMRecord clippedRead = (new ReadClipper(read)).hardClipLeadingInsertions();
int expectedLength = read.getReadLength() - leadingInsertionLength(read.getCigar());
if (cigarHasElementsDifferentThanInsertionsAndHardClips(read.getCigar()))
expectedLength -= leadingInsertionLength(ClipReadsTestUtils.invertCigar(read.getCigar()));
if (! clippedRead.isEmpty()) {
Assert.assertEquals(expectedLength, clippedRead.getReadLength(), String.format("%s -> %s", read.getCigarString(), clippedRead.getCigarString())); // check that everything else is still there
Assert.assertFalse(startsWithInsertion(clippedRead.getCigar())); // check that the insertions are gone
}
else
Assert.assertTrue(expectedLength == 0, String.format("expected length: %d", expectedLength)); // check that the read was expected to be fully clipped
}
}
}
private void assertNoLowQualBases(GATKSAMRecord read, byte low_qual) {
if (!read.isEmpty()) {
byte [] quals = read.getBaseQualities();
@ -289,5 +310,24 @@ public class ReadClipperUnitTest extends BaseTest {
}
}
private boolean startsWithInsertion(Cigar cigar) {
return leadingInsertionLength(cigar) > 0;
}
private int leadingInsertionLength(Cigar cigar) {
for (CigarElement cigarElement : cigar.getCigarElements()) {
if (cigarElement.getOperator() == CigarOperator.INSERTION)
return cigarElement.getLength();
if (cigarElement.getOperator() != CigarOperator.HARD_CLIP)
break;
}
return 0;
}
private boolean cigarHasElementsDifferentThanInsertionsAndHardClips (Cigar cigar) {
for (CigarElement cigarElement : cigar.getCigarElements())
if (cigarElement.getOperator() != CigarOperator.INSERTION && cigarElement.getOperator() != CigarOperator.HARD_CLIP)
return true;
return false;
}
}