From df6499e58c0e1a8d48a8d53c6522452b57c65cc9 Mon Sep 17 00:00:00 2001 From: Eric Banks Date: Wed, 27 Nov 2013 15:53:11 -0500 Subject: [PATCH] Bug fix for RR: stop (incorrectly) pulling the MQ out of the SAMRecord as a byte instead of an int. For reads with high MQs (greater than max byte) the MQ was being treated as negative and failing the min MQ filter. Added unit test. Delivers PT#61567540. --- .../reducereads/SlidingWindow.java | 9 ++++---- .../reducereads/SlidingWindowUnitTest.java | 23 +++++++++++++++++++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/protected/java/src/org/broadinstitute/sting/gatk/walkers/compression/reducereads/SlidingWindow.java b/protected/java/src/org/broadinstitute/sting/gatk/walkers/compression/reducereads/SlidingWindow.java index 964c6b401..d5aa8f944 100644 --- a/protected/java/src/org/broadinstitute/sting/gatk/walkers/compression/reducereads/SlidingWindow.java +++ b/protected/java/src/org/broadinstitute/sting/gatk/walkers/compression/reducereads/SlidingWindow.java @@ -1033,7 +1033,7 @@ public class SlidingWindow { protected void actuallyUpdateHeaderForRead(final LinkedList header, final GATKSAMRecord read, final boolean removeRead, final int startIndex) { final Iterator headerElementIterator = header.listIterator(startIndex); - final byte mappingQuality = (byte) read.getMappingQuality(); + final int mappingQuality = read.getMappingQuality(); final boolean isNegativeStrand = read.getReadNegativeStrandFlag(); // iterator variables @@ -1062,14 +1062,15 @@ public class SlidingWindow { break; case D: - // deletions are added to the baseCounts with the read mapping quality as it's quality score + // deletions are added to the baseCounts with the read mapping quality as its quality score final int nDeletionBases = cigarElement.getLength(); + final byte MQbyte = mappingQuality > Byte.MAX_VALUE ? Byte.MAX_VALUE : (byte)mappingQuality; for ( int i = 0; i < nDeletionBases; i++ ) { headerElement = headerElementIterator.next(); if (removeRead) - headerElement.removeBase(BaseUtils.Base.D.base, mappingQuality, mappingQuality, mappingQuality, mappingQuality, MIN_BASE_QUAL_TO_COUNT, MIN_MAPPING_QUALITY, false, isNegativeStrand); + headerElement.removeBase(BaseUtils.Base.D.base, MQbyte, MQbyte, MQbyte, mappingQuality, MIN_BASE_QUAL_TO_COUNT, MIN_MAPPING_QUALITY, false, isNegativeStrand); else - headerElement.addBase(BaseUtils.Base.D.base, mappingQuality, mappingQuality, mappingQuality, mappingQuality, MIN_BASE_QUAL_TO_COUNT, MIN_MAPPING_QUALITY, false, isNegativeStrand); + headerElement.addBase(BaseUtils.Base.D.base, MQbyte, MQbyte, MQbyte, mappingQuality, MIN_BASE_QUAL_TO_COUNT, MIN_MAPPING_QUALITY, false, isNegativeStrand); } locationIndex += nDeletionBases; break; diff --git a/protected/java/test/org/broadinstitute/sting/gatk/walkers/compression/reducereads/SlidingWindowUnitTest.java b/protected/java/test/org/broadinstitute/sting/gatk/walkers/compression/reducereads/SlidingWindowUnitTest.java index 720f00f98..c49a671e2 100644 --- a/protected/java/test/org/broadinstitute/sting/gatk/walkers/compression/reducereads/SlidingWindowUnitTest.java +++ b/protected/java/test/org/broadinstitute/sting/gatk/walkers/compression/reducereads/SlidingWindowUnitTest.java @@ -860,6 +860,29 @@ public class SlidingWindowUnitTest extends BaseTest { Assert.assertEquals(windowHeader.get(i).getBaseCounts(SlidingWindow.ConsensusType.POSITIVE_CONSENSUS).countOfBase(BaseUtils.Base.A.base), 0); } + @Test + public void testUpdateHeaderForReadWithHighMQ() { + + // set up the window header + final int currentHeaderStart = 100; + final LinkedList windowHeader = new LinkedList<>(); + for ( int i = 0; i < readLength; i++ ) + windowHeader.add(new HeaderElement(currentHeaderStart + i)); + + // set up the read + final GATKSAMRecord read = ArtificialSAMUtils.createArtificialRead(header, "basicRead", 0, currentHeaderStart, readLength); + read.setReadBases(Utils.dupBytes((byte) 'A', readLength)); + read.setBaseQualities(Utils.dupBytes((byte)30, readLength)); + read.setMappingQuality(180); + read.setReadNegativeStrandFlag(false); + + // add the read and make sure it's not filtered because of low MQ (byte vs. int) + final SlidingWindow slidingWindow = new SlidingWindow("1", 0, 10, header, new GATKSAMReadGroupRecord("test"), 0, 0.05, 0.05, 0.05, 20, 20, 10, ReduceReads.DownsampleStrategy.Normal, false); + slidingWindow.actuallyUpdateHeaderForRead(windowHeader, read, false, 0); + for ( int i = 0; i < readLength; i++ ) + Assert.assertEquals(windowHeader.get(i).getBaseCounts(SlidingWindow.ConsensusType.POSITIVE_CONSENSUS).countOfBase(BaseUtils.Base.A.base), 1); + } + ////////////////////////////////////////////////////////////////////////////////// //// This section tests functionality related to polyploid consensus creation //// //////////////////////////////////////////////////////////////////////////////////