diff --git a/public/java/src/org/broadinstitute/sting/utils/pileup/PileupElement.java b/public/java/src/org/broadinstitute/sting/utils/pileup/PileupElement.java index 12899e898..053864791 100755 --- a/public/java/src/org/broadinstitute/sting/utils/pileup/PileupElement.java +++ b/public/java/src/org/broadinstitute/sting/utils/pileup/PileupElement.java @@ -81,20 +81,17 @@ public class PileupElement { // // -------------------------------------------------------------------------- - private Integer getReducedReadQualityTagValue() { - return getRead().getIntegerAttribute(ReadUtils.REDUCED_READ_QUALITY_TAG); - } - public boolean isReducedRead() { - return getReducedReadQualityTagValue() != null; + return ReadUtils.isReducedRead(getRead()); } public int getReducedCount() { + if ( ! isReducedRead() ) throw new IllegalArgumentException("Cannot get reduced count for non-reduced read " + getRead().getReadName()); return (int)getQual(); } public byte getReducedQual() { - return (byte)(int)getReducedReadQualityTagValue(); + return (byte)(int)ReadUtils.getReducedReadQualityTagValue(getRead()); } } \ No newline at end of file diff --git a/public/java/src/org/broadinstitute/sting/utils/sam/ReadUtils.java b/public/java/src/org/broadinstitute/sting/utils/sam/ReadUtils.java index 49d79a72c..8beb1b21a 100755 --- a/public/java/src/org/broadinstitute/sting/utils/sam/ReadUtils.java +++ b/public/java/src/org/broadinstitute/sting/utils/sam/ReadUtils.java @@ -43,10 +43,43 @@ import java.util.*; * @version 0.1 */ public class ReadUtils { - public static final String REDUCED_READ_QUALITY_TAG = "RQ"; - private ReadUtils() { } + // ---------------------------------------------------------------------------------------------------- + // + // Reduced read utilities + // + // ---------------------------------------------------------------------------------------------------- + + public static final String REDUCED_READ_QUALITY_TAG = "RQ"; + + public final static Integer getReducedReadQualityTagValue(final SAMRecord read) { + return read.getIntegerAttribute(ReadUtils.REDUCED_READ_QUALITY_TAG); + } + + public final static boolean isReducedRead(final SAMRecord read) { + return getReducedReadQualityTagValue(read) != null; + } + + public final static SAMRecord reducedReadWithReducedQuals(final SAMRecord read) { + if ( ! isReducedRead(read) ) throw new IllegalArgumentException("read must be a reduced read"); + try { + SAMRecord newRead = (SAMRecord)read.clone(); + byte reducedQual = (byte)(int)getReducedReadQualityTagValue(read); + byte[] newQuals = new byte[read.getBaseQualities().length]; + Arrays.fill(newQuals, reducedQual); + newRead.setBaseQualities(newQuals); + return newRead; + } catch ( CloneNotSupportedException e ) { + throw new ReviewedStingException("SAMRecord no longer supports clone", e); + } + } + + // ---------------------------------------------------------------------------------------------------- + // + // General utilities + // + // ---------------------------------------------------------------------------------------------------- public static SAMFileHeader copySAMFileHeader(SAMFileHeader toCopy) { SAMFileHeader copy = new SAMFileHeader(); diff --git a/public/java/test/org/broadinstitute/sting/utils/ReadUtilsUnitTest.java b/public/java/test/org/broadinstitute/sting/utils/ReadUtilsUnitTest.java index 7cb7fec98..e1fdadadc 100755 --- a/public/java/test/org/broadinstitute/sting/utils/ReadUtilsUnitTest.java +++ b/public/java/test/org/broadinstitute/sting/utils/ReadUtilsUnitTest.java @@ -3,6 +3,7 @@ package org.broadinstitute.sting.utils; import net.sf.samtools.SAMFileHeader; import net.sf.samtools.SAMRecord; import org.broadinstitute.sting.BaseTest; +import org.broadinstitute.sting.utils.pileup.PileupElement; import org.broadinstitute.sting.utils.sam.ArtificialSAMUtils; import org.broadinstitute.sting.utils.sam.ReadUtils; import org.testng.Assert; @@ -12,9 +13,10 @@ import org.testng.annotations.Test; public class ReadUtilsUnitTest extends BaseTest { - SAMRecord read; + SAMRecord read, reducedRead; final static String BASES = "ACTG"; final static String QUALS = "!+5?"; + final private static int REDUCED_READ_QUAL = 20; @BeforeTest public void init() { @@ -23,6 +25,11 @@ public class ReadUtilsUnitTest extends BaseTest { read.setReadUnmappedFlag(true); read.setReadBases(new String(BASES).getBytes()); read.setBaseQualityString(new String(QUALS)); + + reducedRead = ArtificialSAMUtils.createArtificialRead(header, "reducedRead", 0, 1, BASES.length()); + reducedRead.setReadBases(BASES.getBytes()); + reducedRead.setBaseQualityString(QUALS); + reducedRead.setAttribute(ReadUtils.REDUCED_READ_QUALITY_TAG, REDUCED_READ_QUAL); } private void testReadBasesAndQuals(SAMRecord read, int expectedStart, int expectedStop) { @@ -38,4 +45,40 @@ public class ReadUtilsUnitTest extends BaseTest { @Test public void testClip2Front() { testReadBasesAndQuals(read, 2, 4); } @Test public void testClip1Back() { testReadBasesAndQuals(read, 0, 3); } @Test public void testClip2Back() { testReadBasesAndQuals(read, 0, 2); } + + @Test + public void testReducedReads() { + Assert.assertFalse(ReadUtils.isReducedRead(read), "isReducedRead is false for normal read"); + Assert.assertEquals(ReadUtils.getReducedReadQualityTagValue(read), null, "No reduced read tag in normal read"); + + Assert.assertTrue(ReadUtils.isReducedRead(reducedRead), "isReducedRead is true for reduced read"); + Assert.assertEquals((int) ReadUtils.getReducedReadQualityTagValue(reducedRead), REDUCED_READ_QUAL, "Reduced read tag is set to expected value"); + } + + @Test + public void testreducedReadWithReducedQualsWithReducedRead() { + SAMRecord replacedRead = ReadUtils.reducedReadWithReducedQuals(reducedRead); + Assert.assertEquals(replacedRead.getReadBases(), reducedRead.getReadBases()); + Assert.assertEquals(replacedRead.getBaseQualities().length, reducedRead.getBaseQualities().length); + for ( int i = 0; i < replacedRead.getBaseQualities().length; i++) + Assert.assertEquals(replacedRead.getBaseQualities()[i], REDUCED_READ_QUAL); + } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void testreducedReadWithReducedQualsWithNormalRead() { + ReadUtils.reducedReadWithReducedQuals(read); + } + + @Test + public void testReducedReadPileupElement() { + PileupElement readp = new PileupElement(read,0); + PileupElement reducedreadp = new PileupElement(reducedRead,0); + + Assert.assertFalse(readp.isReducedRead()); + + Assert.assertTrue(reducedreadp.isReducedRead()); + Assert.assertEquals(reducedreadp.getReducedCount(), 0); + Assert.assertEquals(reducedreadp.getReducedQual(), REDUCED_READ_QUAL); + + } }