/* * 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 htsjdk.variant.variantcontext; // the imports for unit testing. import htsjdk.tribble.TribbleException; import htsjdk.variant.VariantBaseTest; import htsjdk.variant.utils.GeneralUtils; import org.testng.Assert; import org.testng.annotations.Test; import java.util.Arrays; import java.util.EnumMap; import java.util.List; /** * Basic unit test for Genotype likelihoods objects */ public class GenotypeLikelihoodsUnitTest extends VariantBaseTest { double [] v = new double[]{-10.5, -1.25, -5.11}; final static String vGLString = "-10.50,-1.25,-5.11"; final static String vPLString = "93,0,39"; double[] triAllelic = new double[]{-4.2,-2.0,-3.0,-1.6,0.0,-4.0}; //AA,AB,AC,BB,BC,CC @Test public void testFromVector2() { GenotypeLikelihoods gl = GenotypeLikelihoods.fromLog10Likelihoods(v); assertDoubleArraysAreEqual(gl.getAsVector(), v); Assert.assertEquals(gl.getAsString(), vPLString); } @Test public void testFromString1() { GenotypeLikelihoods gl = GenotypeLikelihoods.fromPLField(vPLString); assertDoubleArraysAreEqual(gl.getAsVector(), new double[]{-9.3, 0, -3.9}); Assert.assertEquals(gl.getAsString(), vPLString); } @Test public void testFromString2() { GenotypeLikelihoods gl = GenotypeLikelihoods.fromGLField(vGLString); assertDoubleArraysAreEqual(gl.getAsVector(), v); Assert.assertEquals(gl.getAsString(), vPLString); } @Test (expectedExceptions = TribbleException.class) public void testErrorBadFormat() { GenotypeLikelihoods gl = GenotypeLikelihoods.fromPLField("adf,b,c"); gl.getAsVector(); } @Test public void testGetAsMap(){ GenotypeLikelihoods gl = GenotypeLikelihoods.fromLog10Likelihoods(v); //Log scale EnumMap<GenotypeType,Double> glMap = gl.getAsMap(false); Assert.assertEquals(v[GenotypeType.HOM_REF.ordinal()-1],glMap.get(GenotypeType.HOM_REF)); Assert.assertEquals(v[GenotypeType.HET.ordinal()-1],glMap.get(GenotypeType.HET)); Assert.assertEquals(v[GenotypeType.HOM_VAR.ordinal()-1],glMap.get(GenotypeType.HOM_VAR)); //Linear scale glMap = gl.getAsMap(true); double [] vl = GeneralUtils.normalizeFromLog10(v); Assert.assertEquals(vl[GenotypeType.HOM_REF.ordinal()-1],glMap.get(GenotypeType.HOM_REF)); Assert.assertEquals(vl[GenotypeType.HET.ordinal()-1],glMap.get(GenotypeType.HET)); Assert.assertEquals(vl[GenotypeType.HOM_VAR.ordinal()-1],glMap.get(GenotypeType.HOM_VAR)); //Test missing likelihoods gl = GenotypeLikelihoods.fromPLField("."); glMap = gl.getAsMap(false); Assert.assertNull(glMap); } @Test public void testCalculateNumLikelihoods() { for (int nAlleles=2; nAlleles<=5; nAlleles++) // simplest case: diploid Assert.assertEquals(GenotypeLikelihoods.numLikelihoods(nAlleles, 2), nAlleles*(nAlleles+1)/2); // some special cases: ploidy = 20, #alleles = 4 Assert.assertEquals(GenotypeLikelihoods.numLikelihoods(4, 20), 1771); } @Test public void testGetLog10GQ(){ GenotypeLikelihoods gl = GenotypeLikelihoods.fromPLField(vPLString); //GQ for the best guess genotype Assert.assertEquals(gl.getLog10GQ(GenotypeType.HET),-3.9); double[] test = GeneralUtils.normalizeFromLog10(gl.getAsVector()); //GQ for the other genotypes Assert.assertEquals(gl.getLog10GQ(GenotypeType.HOM_REF), Math.log10(1.0 - test[GenotypeType.HOM_REF.ordinal()-1])); Assert.assertEquals(gl.getLog10GQ(GenotypeType.HOM_VAR), Math.log10(1.0 - test[GenotypeType.HOM_VAR.ordinal()-1])); //Test missing likelihoods gl = GenotypeLikelihoods.fromPLField("."); Assert.assertEquals(gl.getLog10GQ(GenotypeType.HOM_REF),Double.NEGATIVE_INFINITY); Assert.assertEquals(gl.getLog10GQ(GenotypeType.HET),Double.NEGATIVE_INFINITY); Assert.assertEquals(gl.getLog10GQ(GenotypeType.HOM_VAR),Double.NEGATIVE_INFINITY); } @Test public void testgetQualFromLikelihoods() { double[] likelihoods = new double[]{-1, 0, -2}; // qual values we expect for each possible "best" genotype double[] expectedQuals = new double[]{-0.04100161, -1, -0.003930294}; for ( int i = 0; i < likelihoods.length; i++ ) { Assert.assertEquals(GenotypeLikelihoods.getGQLog10FromLikelihoods(i, likelihoods), expectedQuals[i], 1e-6, "GQ value for genotype " + i + " was not calculated correctly"); } } // this test is completely broken, the method is wrong. public void testGetQualFromLikelihoodsMultiAllelicBroken() { GenotypeLikelihoods gl = GenotypeLikelihoods.fromLog10Likelihoods(triAllelic); double actualGQ = gl.getLog10GQ(GenotypeType.HET); double expectedGQ = 1.6; Assert.assertEquals(actualGQ,expectedGQ); } public void testGetQualFromLikelihoodsMultiAllelic() { GenotypeLikelihoods gl = GenotypeLikelihoods.fromLog10Likelihoods(triAllelic); Allele ref = Allele.create((byte)'A',true); Allele alt1 = Allele.create((byte)'C'); Allele alt2 = Allele.create((byte)'T'); List<Allele> allAlleles = Arrays.asList(ref,alt1,alt2); List<Allele> gtAlleles = Arrays.asList(alt1,alt2); GenotypeBuilder gtBuilder = new GenotypeBuilder(); gtBuilder.alleles(gtAlleles); double actualGQ = gl.getLog10GQ(gtBuilder.make(),allAlleles); double expectedGQ = 1.6; Assert.assertEquals(actualGQ,expectedGQ); } private void assertDoubleArraysAreEqual(double[] v1, double[] v2) { Assert.assertEquals(v1.length, v2.length); for ( int i = 0; i < v1.length; i++ ) { Assert.assertEquals(v1[i], v2[i], 1e-6); } } @Test public void testCalculatePLindex(){ int counter = 0; for ( int i = 0; i <= 3; i++ ) { for ( int j = i; j <= 3; j++ ) { Assert.assertEquals(GenotypeLikelihoods.calculatePLindex(i, j), GenotypeLikelihoods.PLindexConversion[counter++], "PL index of alleles " + i + "," + j + " was not calculated correctly"); } } } @Test public void testGetAllelePair(){ allelePairTest(0, 0, 0); allelePairTest(1, 0, 1); allelePairTest(2, 1, 1); allelePairTest(3, 0, 2); allelePairTest(4, 1, 2); allelePairTest(5, 2, 2); allelePairTest(6, 0, 3); allelePairTest(7, 1, 3); allelePairTest(8, 2, 3); allelePairTest(9, 3, 3); } private void allelePairTest(int PLindex, int allele1, int allele2) { Assert.assertEquals(GenotypeLikelihoods.getAllelePair(PLindex).alleleIndex1, allele1, "allele index " + allele1 + " from PL index " + PLindex + " was not calculated correctly"); Assert.assertEquals(GenotypeLikelihoods.getAllelePair(PLindex).alleleIndex2, allele2, "allele index " + allele2 + " from PL index " + PLindex + " was not calculated correctly"); } }