コード例 #1
0
        public void CallVariants_MnvReallocatesToSnvOutsideInterval()
        {
            var config = new VariantCallerConfig
            {
                MaxVariantQscore         = 100,
                EstimatedBaseCallQuality = 20,
                IncludeReferenceCalls    = true,
                MinFrequency             = 6f / 150
            };

            var intervalSet = new ChrIntervalSet(new List <Region>()
            {
                new Region(1900, 1950)
            }, "chr1");
            var variantCaller = new AlleleCaller(config, intervalSet);

            // -----------------------------------------------
            // Passing MNV that spans interval edge should be called if it begins within intervals
            // Failing MNVs that span interval edge and are reallocated to SNVs should only have those SNVs called if they are within intervals
            // (broken-out SNVs outside intervals should not be called even if they gain enough support to be called).
            // -----------------------------------------------

            var passingMnv = new CandidateAllele("chr1", 1950, "TTT", "CCC", AlleleCategory.Mnv)
            {
                SupportByDirection = new[] { 10, 0, 0 }
            };
            var failingMnv1 = new CandidateAllele("chr1", 1950, "TTT", "GGG", AlleleCategory.Mnv) // only the first SNV should be called (1950 T>G)
            {
                SupportByDirection = new[] { 5, 0, 0 }
            };
            var failingMnv1Booster = new CandidateAllele("chr1", 1949, "TTTT", "GGGG", AlleleCategory.Mnv) // only the second SNV should be called (1950 T>G)
            {
                SupportByDirection = new[] { 5, 0, 0 }
            };
            var failingMnv2 = new CandidateAllele("chr1", 1950, "TTT", "AAA", AlleleCategory.Mnv) // none of these should be called
            {
                SupportByDirection = new[] { 5, 0, 0 }
            };

            var mockStateManager = MockStateManager(306, 0);

            var candidateVariants = new List <CandidateAllele>
            {
                passingMnv,
                failingMnv1,
                failingMnv2,
                failingMnv1Booster
            };

            var batch = new CandidateBatch(candidateVariants)
            {
                MaxClearedPosition = 2000
            };

            var calledVariants = variantCaller.Call(batch, mockStateManager.Object);

            PrintResults(calledVariants.ToList());

            Assert.Equal(2, calledVariants.Count());
        }
コード例 #2
0
        public void CallVariants_MnvTakingRefSupport()
        {
            var config = new VariantCallerConfig
            {
                MaxVariantQscore         = 100,
                EstimatedBaseCallQuality = 20,
                IncludeReferenceCalls    = true
            };

            var variantCaller = new AlleleCaller(config);

            //Failing MNV shouldn't contribute
            var passingMnv = new CandidateAllele("chr1", 305, "TTA", "GTG", AlleleCategory.Mnv)
            {
                SupportByDirection = new[] { 10, 0, 0 }
            };
            var passingSnv = new CandidateAllele("chr1", 306, "T", "G", AlleleCategory.Snv)
            {
                SupportByDirection = new[] { 200, 0, 0 }
            };
            var passingDeletion = new CandidateAllele("chr1", 305, "TTT", "T", AlleleCategory.Deletion)
            {
                SupportByDirection = new[] { 100, 0, 0 }
            };

            var mockAlleleCountSource = MockStateManager(306, 0);

            mockAlleleCountSource.Setup(c => c.GetGappedMnvRefCount(306)).Returns(10);
            mockAlleleCountSource.Setup(c => c.AddGappedMnvRefCount(It.IsAny <Dictionary <int, int> >())).Callback((Dictionary <int, int> lookup) =>
            {
                Assert.Equal(1, lookup.Count);
                Assert.True(lookup.ContainsKey(306));
                Assert.Equal(10, lookup[306]);
            });

            config.MinCoverage      = 0;
            config.MinVariantQscore = 0;
            config.MinFrequency     = 0;

            variantCaller = new AlleleCaller(config);

            var candidateVariants = new List <CandidateAllele>
            {
                passingMnv,
                passingDeletion,
                passingSnv
            };

            var calledVariants = variantCaller.Call(new CandidateBatch(candidateVariants), mockAlleleCountSource.Object);

            PrintResults(calledVariants.ToList());

            Assert.True(calledVariants.Any(v => MatchVariants(v, passingMnv, 10)));                                                                                     // Passing MNV should have additional support from big failed MNV
            Assert.True(calledVariants.Any(v => MatchVariants(v, passingSnv, 200)));                                                                                    // Passing SNV should have coverage that includes the passing MNV but not support
            Assert.True(calledVariants.Any(v => MatchVariants(v, passingDeletion)));                                                                                    // Passing deletion should not do anything here

            Assert.Equal((3 * HighCoverageMultiplier) - passingMnv.Support, ((CalledVariant)calledVariants.First(v => MatchVariants(v, passingSnv))).ReferenceSupport); // Passing SNV should have coverage that includes the passing MNV but not support
        }
コード例 #3
0
        public void PrunedForcedAlleleShouldBeCalled()
        {
            var mockCandidateToBatch = new Mock <ICandidateBatch>();
            var candidateAllele1     = new CandidateAllele("chr1", 10, "G", "T", AlleleCategory.Snv);

            mockCandidateToBatch.Setup(s => s.GetCandidates()).Returns(new List <CandidateAllele> {
                candidateAllele1
            });
            mockCandidateToBatch.SetupGet(s => s.MaxClearedPosition).Returns(100);
            var config = new VariantCallerConfig {
                MinCoverage = 20
            };
            var myChrRef = new ChrReference()
            {
                Name     = "chr1",
                Sequence = "ATGGCCTACGATTAGTAGGT"
            };

            config.ChrReference = myChrRef;
            //config.MinCoverage = 20;
            var mockCoverageCalculator = new Mock <ICoverageCalculator>();

            mockCoverageCalculator.Setup(x => x.Compute(It.IsAny <CalledAllele>(), It.IsAny <IAlleleSource>()));
            var mockGenotypeCalculator = new Mock <IGenotypeCalculator>();

            mockGenotypeCalculator.Setup(x => x.SetGenotypes(It.IsAny <IEnumerable <CalledAllele> >())).Returns <List <CalledAllele> >(s => s);     //note: returns allele to prune
            config.GenotypeCalculator = mockGenotypeCalculator.Object;
            config.LocusProcessor     = new DiploidLocusProcessor();
            var alleleCaller = new AlleleCaller(config, null, null, mockCoverageCalculator.Object);

            var mockAlleleSource = new Mock <IAlleleSource>();



            var observedAllelewithoutForcedAllele = alleleCaller.Call(mockCandidateToBatch.Object, mockAlleleSource.Object);

            Assert.Equal(0, observedAllelewithoutForcedAllele.Count);

            var forcedGtAlleles = new HashSet <Tuple <string, int, string, string> >
            {
                new Tuple <string, int, string, string>("chr1", 10, "G", "T")
            };

            alleleCaller.AddForcedGtAlleles(forcedGtAlleles);

            var observedCalledAllele = alleleCaller.Call(mockCandidateToBatch.Object, mockAlleleSource.Object);

            Assert.Equal(1, observedCalledAllele.Count);
            Assert.True(observedCalledAllele.First().Value.First().IsForcedToReport);
        }
コード例 #4
0
ファイル: Factory.cs プロジェクト: zhaohongqiangsoliva/Pisces
        protected virtual IAlleleCaller CreateVariantCaller(ChrReference chrReference, ChrIntervalSet intervalSet, IAlignmentSource alignmentSource, HashSet <Tuple <string, int, string, string> > forceGtAlleles = null)
        {
            var coverageCalculator = CreateCoverageCalculator(alignmentSource);
            var genotypeCalculator = GenotypeCreator.CreateGenotypeCalculator(
                _options.VariantCallingParameters.PloidyModel, _options.VariantCallingParameters.MinimumFrequencyFilter,
                _options.VariantCallingParameters.MinimumCoverage,
                _options.VariantCallingParameters.DiploidSNVThresholdingParameters,
                _options.VariantCallingParameters.DiploidINDELThresholdingParameters,
                _options.VariantCallingParameters.AdaptiveGenotypingParameters,
                _options.VariantCallingParameters.MinimumGenotypeQScore,
                _options.VariantCallingParameters.MaximumGenotypeQScore,
                _options.VariantCallingParameters.TargetLODFrequency,
                _options.VariantCallingParameters.MinimumFrequency,
                chrReference.Name, _options.VariantCallingParameters.IsMale);

            genotypeCalculator.SetMinFreqFilter(_options.VariantCallingParameters.MinimumFrequencyFilter);

            var locusProcessor = _options.VariantCallingParameters.PloidyModel == PloidyModel.DiploidByThresholding
                ? (ILocusProcessor) new DiploidLocusProcessor()
                : new SomaticLocusProcessor();

            var variantCallerConfig = new VariantCallerConfig
            {
                IncludeReferenceCalls        = _options.VcfWritingParameters.OutputGvcfFile,
                MinVariantQscore             = _options.VariantCallingParameters.MinimumVariantQScore,
                MaxVariantQscore             = _options.VariantCallingParameters.MaximumVariantQScore,
                MinGenotypeQscore            = _options.VariantCallingParameters.MinimumGenotypeQScore,
                MaxGenotypeQscore            = _options.VariantCallingParameters.MaximumGenotypeQScore,
                VariantQscoreFilterThreshold = _options.VariantCallingParameters.MinimumVariantQScoreFilter,
                NoCallFilterThreshold        = _options.VariantCallingParameters.NoCallFilterThreshold,
                AmpliconBiasFilterThreshold  = _options.VariantCallingParameters.AmpliconBiasFilterThreshold,
                MinCoverage  = _options.VariantCallingParameters.MinimumCoverage,
                MinFrequency = genotypeCalculator.MinVarFrequency,
                NoiseLevelUsedForQScoring  = _options.VariantCallingParameters.NoiseLevelUsedForQScoring,
                StrandBiasModel            = _options.VariantCallingParameters.StrandBiasModel,
                StrandBiasFilterThreshold  = _options.VariantCallingParameters.StrandBiasAcceptanceCriteria,
                FilterSingleStrandVariants = _options.VariantCallingParameters.FilterOutVariantsPresentOnlyOneStrand,
                GenotypeCalculator         = genotypeCalculator,
                VariantFreqFilter          = genotypeCalculator.MinVarFrequencyFilter,
                LowGTqFilter       = _options.VariantCallingParameters.LowGenotypeQualityFilter,
                IndelRepeatFilter  = _options.VariantCallingParameters.IndelRepeatFilter,
                LowDepthFilter     = _options.VariantCallingParameters.LowDepthFilter,
                ChrReference       = chrReference,
                RMxNFilterSettings = new RMxNFilterSettings
                {
                    RMxNFilterMaxLengthRepeat = _options.VariantCallingParameters.RMxNFilterMaxLengthRepeat,
                    RMxNFilterMinRepetitions  = _options.VariantCallingParameters.RMxNFilterMinRepetitions,
                    RMxNFilterFrequencyLimit  = _options.VariantCallingParameters.RMxNFilterFrequencyLimit
                },
                NoiseModel     = _options.VariantCallingParameters.NoiseModel,
                LocusProcessor = locusProcessor
            };



            var alleleCaller = new AlleleCaller(variantCallerConfig, intervalSet,
                                                CreateVariantCollapser(chrReference.Name, coverageCalculator),
                                                coverageCalculator);

            alleleCaller.AddForcedGtAlleles(forceGtAlleles);

            return(alleleCaller);
        }
コード例 #5
0
        public void CallVariants_MnvReallocatesToDifferentBlock()
        {
            var config = new VariantCallerConfig
            {
                MaxVariantQscore          = 100,
                NoiseLevelUsedForQScoring = 20,
                IncludeReferenceCalls     = true,
                MinCoverage      = 0,
                MinVariantQscore = 0,
                MinFrequency     = 6f / 150,
                ChrReference     = new ChrReference
                {
                    Sequence = "ACGTACGT",
                    Name     = "Boo"
                },
                GenotypeCalculator = new SomaticGenotyper(),
                LocusProcessor     = new SomaticLocusProcessor()
            };

            var variantCaller = new AlleleCaller(config);

            var passingMnv = new CandidateAllele("chr1", 1999, "TTT", "CCC", AlleleCategory.Mnv)
            {
                SupportByDirection = new[] { 10, 0, 0 }
            };

            var failingMnv = new CandidateAllele("chr1", 2000, "TTT", "GGG", AlleleCategory.Mnv)
            {
                SupportByDirection = new[] { 5, 0, 0 }
            };
            var failingMnv2 = new CandidateAllele("chr1", 1999, "TTT", "AAA", AlleleCategory.Mnv)
            {
                SupportByDirection = new[] { 5, 0, 0 }
            };
            var failingGappedMnv = new CandidateAllele("chr1", 2000, "TTT", "ATA", AlleleCategory.Mnv)
            {
                SupportByDirection = new[] { 5, 0, 0 }
            };


            var mockStateManager = MockStateManager(306, 0);


            variantCaller = new AlleleCaller(config);

            var candidateVariants = new List <CandidateAllele>
            {
                passingMnv,
                failingMnv,
                failingMnv2,
                failingGappedMnv
            };

            var batch = new CandidateBatch(candidateVariants)
            {
                MaxClearedPosition = 2000
            };

            var BaseCalledAlleles = variantCaller.Call(batch, mockStateManager.Object);

            mockStateManager.Setup(c => c.AddCandidates(It.IsAny <IEnumerable <CandidateAllele> >()))
            .Callback((IEnumerable <CandidateAllele> vars) => Console.WriteLine(vars.Count()));
            mockStateManager.Verify(c => c.AddCandidates(It.IsAny <IEnumerable <CandidateAllele> >()), Times.Once);

            // For regular MNVs that span blocks, whole sub-MNV belonging to next block should be passed over together.
            // If it begins with a ref, should skip that ref and just deliver the rest of the MNV. Thus we should have the following added to the next block:
            //  - MNV at 2001 from failingMnv
            //  - SNV at 2001 from failingMnv2
            //  - SNV at 2002 from failingGappedMnv

            mockStateManager.Verify(c => c.AddCandidates(It.Is <IEnumerable <CandidateAllele> >(x => x.Count() == 3)), Times.Once);
            mockStateManager.Verify(c => c.AddCandidates(It.Is <IEnumerable <CandidateAllele> >(x =>
                                                                                                x.Count(a => a.ReferencePosition == 2001) == 2 &&
                                                                                                x.Count(a => a.ReferencePosition == 2002) == 1)),
                                    Times.Once);
            mockStateManager.Verify(c => c.AddCandidates(It.Is <IEnumerable <CandidateAllele> >(x =>
                                                                                                x.Count(a => a.ReferencePosition == 2001 && a.Type == AlleleCategory.Mnv) == 1 &&
                                                                                                x.Count(a => a.ReferencePosition == 2001 && a.Type == AlleleCategory.Snv) == 1 &&
                                                                                                x.Count(a => a.ReferencePosition == 2001 && a.Type == AlleleCategory.Reference) == 0 &&
                                                                                                x.Count(a => a.ReferencePosition == 2002 && a.Type == AlleleCategory.Snv) == 1
                                                                                                )),
                                    Times.Once);

            var variants = BaseCalledAlleles.Values.SelectMany(v => v);

            PrintResults(variants.ToList());

            Assert.True(variants.Any(v => MatchVariants(v, passingMnv, 10))); // Passing MNV should have additional support from big failed MNV
        }
コード例 #6
0
        public void CallVariants_MnvReallocation()
        {
            var config = new VariantCallerConfig
            {
                MaxVariantQscore          = 100,
                NoiseLevelUsedForQScoring = 20,
                IncludeReferenceCalls     = true,
                ChrReference = new ChrReference
                {
                    Sequence = "ACGTACGT",
                    Name     = "Boo"
                },
                GenotypeCalculator = new SomaticGenotyper(),
                LocusProcessor     = new SomaticLocusProcessor()
            };

            var variantCaller = new AlleleCaller(config);

            // -----------------------------------------------
            // Happy path : with refs
            // - Failing MNVs that are sub-MNVs of bigger ones should not be recipients of reallocation; they should be reallocated themselves though.
            // - Failing SNVs should be able to be rescued
            // - Refs should have their support incremented by failed gapped MNVs
            // -----------------------------------------------

            var failingMnvToReallocate = new CandidateAllele("chr1", 101, "TTTTTTTT", "ATCTGTGA", AlleleCategory.Mnv)
            {
                SupportByDirection = new[] { 50, 0, 0 } // Freq is 50/150
            };
            var failingMnvToNotRescue = new CandidateAllele("chr1", 101, "TTT", "ATC", AlleleCategory.Mnv)
            {
                SupportByDirection = new[] { 5, 0, 0 } // Freq is 5/150
            };
            var failingSnvToRescue = new CandidateAllele("chr1", 101, "T", "A", AlleleCategory.Snv)
            {
                SupportByDirection = new[] { 50, 0, 0 } // Freq is 50/150
            };
            var passingMnv = new CandidateAllele("chr1", 105, "TTT", "GTG", AlleleCategory.Mnv)
            {
                SupportByDirection = new[] { 100, 0, 0 } // Freq is 100/150
            };
            var passingDeletion = new CandidateAllele("chr1", 105, "TTT", "T", AlleleCategory.Deletion)
            {
                SupportByDirection = new[] { 100, 0, 0 } // Freq is 100/150
            };

            var mockStateManager = MockStateManager(1000, 1001).Object;

            config.MinCoverage      = 0;
            config.MinVariantQscore = 0;
            config.MinFrequency     = .5f;

            variantCaller = new AlleleCaller(config);

            var candidateVariants = new List <CandidateAllele>
            {
                failingSnvToRescue,
                failingMnvToNotRescue,
                failingMnvToReallocate,
                passingMnv,
                passingDeletion
            };

            var BaseCalledAlleles = variantCaller.Call(new CandidateBatch(candidateVariants), mockStateManager).Values.SelectMany(v => v);

            PrintResults(BaseCalledAlleles.ToList());

            Assert.False(BaseCalledAlleles.Any(v => MatchVariants(v, failingMnvToReallocate)));
            Assert.False(BaseCalledAlleles.Any(v => MatchVariants(v, failingMnvToNotRescue)));
            Assert.True(BaseCalledAlleles.Any(v => MatchVariants(v, passingMnv, 150, 1)));                                                       // Passing MNV should have additional support from big failed MNV
            Assert.True(BaseCalledAlleles.Any(v => MatchVariants(v, failingSnvToRescue, 105)));                                                  // SNV should be rescued and have support from both failed MNVs
            Assert.True(BaseCalledAlleles.Any(v => MatchVariants(v, passingDeletion)));                                                          // Passing deletion should still be called
            // There should NOT be new refs from where the MNV broke down, and should be emitted regardless of support
            Assert.False(BaseCalledAlleles.Any(v => v.ReferencePosition == 102 && v.Type == AlleleCategory.Reference && v.AlleleSupport == 55)); // Should have support from both failed MNVs
            Assert.False(BaseCalledAlleles.Any(v => v.ReferencePosition == 104 && v.Type == AlleleCategory.Reference && v.AlleleSupport == 50)); // Should have support from the big failed MNV only
            //There should not be a new ref at position 106 from the passing gapped MNV
            Assert.False(BaseCalledAlleles.Any(v => v.ReferencePosition == 106 && v.Type == AlleleCategory.Reference && v.AlleleSupport > 0));


            // -----------------------------------------------
            // Happy path : without refs
            // - Failing MNVs that are sub-MNVs of bigger ones should not be recipients of reallocation; they should be reallocated themselves though.
            // - Failing SNVs should be able to be rescued
            // -----------------------------------------------

            failingMnvToReallocate = new CandidateAllele("chr1", 101, "TTTTTTTT", "ATCTGTGA", AlleleCategory.Mnv)
            {
                SupportByDirection = new[] { 50, 0, 0 } // Freq is 50/150
            };
            failingMnvToNotRescue = new CandidateAllele("chr1", 101, "TTT", "ATC", AlleleCategory.Mnv)
            {
                SupportByDirection = new[] { 5, 0, 0 } // Freq is 5/150
            };
            failingSnvToRescue = new CandidateAllele("chr1", 101, "T", "A", AlleleCategory.Snv)
            {
                SupportByDirection = new[] { 50, 0, 0 } // Freq is 50/150
            };
            passingMnv = new CandidateAllele("chr1", 105, "TTT", "GTG", AlleleCategory.Mnv)
            {
                SupportByDirection = new[] { 100, 0, 0 } // Freq is 100/150
            };
            passingDeletion = new CandidateAllele("chr1", 105, "TTT", "T", AlleleCategory.Deletion)
            {
                SupportByDirection = new[] { 100, 0, 0 } // Freq is 100/150
            };

            candidateVariants = new List <CandidateAllele>
            {
                failingSnvToRescue,
                failingMnvToNotRescue,
                failingMnvToReallocate,
                passingMnv,
                passingDeletion
            };

            config.IncludeReferenceCalls = false;
            variantCaller = new AlleleCaller(config);

            BaseCalledAlleles = variantCaller.Call(new CandidateBatch(candidateVariants), mockStateManager).Values.SelectMany(v => v);

            PrintResults(BaseCalledAlleles.ToList());

            Assert.False(BaseCalledAlleles.Any(v => MatchVariants(v, failingMnvToReallocate)));
            Assert.False(BaseCalledAlleles.Any(v => MatchVariants(v, failingMnvToNotRescue)));
            Assert.True(BaseCalledAlleles.Any(v => MatchVariants(v, passingMnv, 150, 1)));      // Passing MNV should have additional support from big failed MNV
            Assert.True(BaseCalledAlleles.Any(v => MatchVariants(v, failingSnvToRescue, 105))); // SNV should be rescued and have support from both failed MNVs
            Assert.True(BaseCalledAlleles.Any(v => MatchVariants(v, passingDeletion)));         // Passing deletion should still be called
            // There should be no refs from where the MNV broke down since we have IncludeReferenceCalls set to false
            Assert.False(BaseCalledAlleles.Any(v => v.ReferencePosition == 102 && v.Type == AlleleCategory.Reference));
            Assert.False(BaseCalledAlleles.Any(v => v.ReferencePosition == 104 && v.Type == AlleleCategory.Reference));
        }
コード例 #7
0
        public void EvaluateVariants()
        {
            var config = new VariantCallerConfig
            {
                MaxVariantQscore          = 100,
                NoiseLevelUsedForQScoring = 20,
                ChrReference = new ChrReference
                {
                    Sequence = "ACGTACGT",
                    Name     = "Boo"
                },
                GenotypeCalculator = new SomaticGenotyper(),
                LocusProcessor     = new SomaticLocusProcessor()
            };

            var variantCaller = new AlleleCaller(config);

            var highCoverageCoordinate = 123;
            var lowCoverageCoordinate  = 456;

            var passingVariant = new CandidateAllele("chr1", highCoverageCoordinate, "A", "T", AlleleCategory.Snv)
            {
                SupportByDirection = new[] { 500, 0, 0 } // Freq is 500/1500, q is 100
            };
            var passingVariant2 = new CandidateAllele("chr1", highCoverageCoordinate, "A", "C", AlleleCategory.Snv)
            {
                SupportByDirection = new[] { 500, 0, 0 } // Freq is 500/1500, q is 100
            };
            var lowFreqVariant = new CandidateAllele("chr2", highCoverageCoordinate, "A", "T", AlleleCategory.Snv)
            {
                SupportByDirection = new[] { 1, 0, 0 } // Freq is 1/1500, q is 0
            };
            var lowCoverageVariant = new CandidateAllele("chr3", lowCoverageCoordinate, "A", "T", AlleleCategory.Snv)
            {
                SupportByDirection = new[] { 10, 0, 0 } // Freq is 10/15, q is 100
            };
            var lowqVariant = new CandidateAllele("chr4", highCoverageCoordinate, "A", "T", AlleleCategory.Snv)
            {
                SupportByDirection = new[] { 40, 0, 0 } // Freq is 40/1500, q is 72
            };
            var passingReferenceHigh = new CandidateAllele("chr1", highCoverageCoordinate, "A", "A", AlleleCategory.Reference)
            {
                SupportByDirection = new[] { 500, 0, 0 } // Freq is 500/1500, q is 100
            };
            var passingReferenceLow = new CandidateAllele("chr3", lowCoverageCoordinate, "A", "A", AlleleCategory.Reference)
            {
                SupportByDirection = new[] { 10, 0, 0 } // Freq is 10/15, q is 100
            };
            var candidateVariants = new List <CandidateAllele>
            {
                passingVariant
            };


            //Variants should be correctly mapped
            var mockAlleleCountSource = MockStateManager(highCoverageCoordinate, lowCoverageCoordinate).Object;
            var BaseCalledAlleles     = variantCaller.Call(new CandidateBatch(candidateVariants), mockAlleleCountSource).Values.SelectMany(v => v);
            var BaseCalledAllele      = BaseCalledAlleles.First();

            Assert.Equal(passingVariant.AlternateAllele, BaseCalledAllele.AlternateAllele);
            Assert.Equal(passingVariant.ReferenceAllele, BaseCalledAllele.ReferenceAllele);
            Assert.Equal(passingVariant.Chromosome, BaseCalledAllele.Chromosome);
            Assert.Equal(passingVariant.ReferencePosition, BaseCalledAllele.ReferencePosition);
            Assert.Equal(passingVariant.Support, BaseCalledAllele.AlleleSupport);
            Assert.True(passingVariant.Type != AlleleCategory.Reference);
            Assert.True(BaseCalledAllele.Type == AlleleCategory.Snv);

            //After the Calculator steps are performed, variants that don't meet
            //our requirements to be callable should drop out

            //High coverage requirement - lowCoverageVariant should drop out.
            config.MinCoverage           = (HighCoverageMultiplier * NumAlleles * NumDirections) - 1;
            config.IncludeReferenceCalls = false;
            config.MinVariantQscore      = 0;
            config.MinFrequency          = 0;

            variantCaller = new AlleleCaller(config);

            candidateVariants = new List <CandidateAllele>
            {
                passingVariant,
                lowFreqVariant,
                lowCoverageVariant
            };

            BaseCalledAlleles = variantCaller.Call(new CandidateBatch(candidateVariants), mockAlleleCountSource).Values.SelectMany(v => v);

            Assert.Equal(2, BaseCalledAlleles.Count());
            Assert.True(BaseCalledAlleles.Any(v => MatchVariants(v, passingVariant)));
            Assert.True(BaseCalledAlleles.Any(v => MatchVariants(v, lowFreqVariant)));
            Assert.False(BaseCalledAlleles.Any(v => MatchVariants(v, lowCoverageVariant)));

            //High coverage but allow reference calls = nothing should drop out
            config.IncludeReferenceCalls = true;

            variantCaller = new AlleleCaller(config);

            candidateVariants = new List <CandidateAllele>
            {
                passingVariant,
                lowFreqVariant,
                lowCoverageVariant
            };

            BaseCalledAlleles = variantCaller.Call(new CandidateBatch(candidateVariants), mockAlleleCountSource).Values.SelectMany(v => v);
            foreach (var cvar in BaseCalledAlleles)
            {
                Console.WriteLine(cvar.VariantQscore);
            }

            Assert.Equal(3, BaseCalledAlleles.Count());

            //High frequency requirement - low frequency variant should drop out
            config.MinCoverage           = 0;
            config.IncludeReferenceCalls = false;
            config.MinVariantQscore      = 0;
            config.MinFrequency          = ((float)lowCoverageVariant.Support + 1) / (HighCoverageMultiplier * NumAlleles * NumDirections);

            BaseCalledAlleles = variantCaller.Call(new CandidateBatch(candidateVariants), mockAlleleCountSource).Values.SelectMany(v => v);

            Assert.Equal(2, BaseCalledAlleles.Count());
            Assert.True(BaseCalledAlleles.Any(v => MatchVariants(v, passingVariant)));
            Assert.False(BaseCalledAlleles.Any(v => MatchVariants(v, lowFreqVariant)));
            Assert.True(BaseCalledAlleles.Any(v => MatchVariants(v, lowCoverageVariant)));

            //High q score requirement - low frequency variant should drop out
            config.MinCoverage           = 0;
            config.IncludeReferenceCalls = false;
            config.MinVariantQscore      = 0;
            config.MinFrequency          = 0;
            config.MinVariantQscore      = VariantQualityCalculator.AssignPoissonQScore(lowqVariant.Support,
                                                                                        (HighCoverageMultiplier * Constants.NumCovContributingAlleleTypes * Constants.NumDirectionTypes), config.NoiseLevelUsedForQScoring,
                                                                                        config.MaxVariantQscore) + 1;

            candidateVariants = new List <CandidateAllele>
            {
                passingVariant,
                passingVariant2,
                lowFreqVariant,
                lowCoverageVariant,
                lowqVariant
            };

            BaseCalledAlleles = variantCaller.Call(new CandidateBatch(candidateVariants), mockAlleleCountSource).Values.SelectMany(v => v);
            Assert.Equal(3, BaseCalledAlleles.Count());
            Assert.True(BaseCalledAlleles.Any(v => MatchVariants(v, passingVariant)));
            Assert.True(BaseCalledAlleles.Any(v => MatchVariants(v, passingVariant2)));
            Assert.False(BaseCalledAlleles.Any(v => MatchVariants(v, lowFreqVariant)));
            Assert.True(BaseCalledAlleles.Any(v => MatchVariants(v, lowCoverageVariant)));
            Assert.False(BaseCalledAlleles.Any(v => MatchVariants(v, lowqVariant)));



            //High genotype q score requirement - low GQ variant should filter

            config.MinCoverage           = 0;
            config.IncludeReferenceCalls = false;
            config.MinVariantQscore      = 0;
            config.MinFrequency          = 0;
            config.GenotypeCalculator    = new DiploidThresholdingGenotyper();
            config.LowGTqFilter          = 20;
            config.MaxGenotypeQscore     = int.MaxValue;

            candidateVariants = new List <CandidateAllele>
            {
                passingVariant,
                passingVariant2,
                lowFreqVariant,
                lowCoverageVariant,
                lowqVariant
            };

            variantCaller     = new AlleleCaller(config);
            BaseCalledAlleles = variantCaller.Call(new CandidateBatch(candidateVariants), mockAlleleCountSource).Values.SelectMany(v => v);
            Assert.Equal(2, BaseCalledAlleles.Count());
            Assert.True(BaseCalledAlleles.Any(v => MatchVariants(v, passingVariant2)));
            Assert.False(BaseCalledAlleles.Any(v => MatchVariants(v, passingVariant)));
            Assert.False(BaseCalledAlleles.Any(v => MatchVariants(v, lowFreqVariant)));
            Assert.True(BaseCalledAlleles.Any(v => MatchVariants(v, lowCoverageVariant)));
            Assert.False(BaseCalledAlleles.Any(v => MatchVariants(v, lowqVariant)));

            var calledList = BaseCalledAlleles.ToList();

            Assert.True(calledList[0].Filters.Contains(FilterType.LowGenotypeQuality)); //1249, forced to 0 for nocall.
            Assert.True(calledList[1].Filters.Contains(FilterType.LowGenotypeQuality)); //1249, forced to 0 for nocall
                                                                                        //Assert.True(calledList[2].Filters.Contains(FilterType.LowGenotypeQuality));//0 pruned

            //go back to somatic config for the rest of the tests.
            config.GenotypeCalculator = new SomaticGenotyper();
            config.LowGTqFilter       = 0;
            config.MaxGenotypeQscore  = 0;
            config.MinVariantQscore   = VariantQualityCalculator.AssignPoissonQScore(lowqVariant.Support,
                                                                                     (HighCoverageMultiplier * Constants.NumCovContributingAlleleTypes * Constants.NumDirectionTypes), config.NoiseLevelUsedForQScoring,
                                                                                     config.MaxVariantQscore) + 1;

            // reference calls included
            candidateVariants = new List <CandidateAllele>
            {
                passingReferenceHigh,
                passingReferenceLow
            };

            variantCaller     = new AlleleCaller(config);
            BaseCalledAlleles = variantCaller.Call(new CandidateBatch(candidateVariants), mockAlleleCountSource).Values.SelectMany(v => v);
            Assert.Equal(2, BaseCalledAlleles.Count());
            Assert.True(BaseCalledAlleles.Any(v => MatchVariants(v, passingReferenceHigh)));
            Assert.True(BaseCalledAlleles.Any(v => MatchVariants(v, passingReferenceLow)));

            // reference calls only included if no passing variant
            candidateVariants = new List <CandidateAllele>
            {
                passingReferenceHigh,
                passingReferenceLow,
                passingVariant,
                passingVariant2,
                lowFreqVariant,
                lowCoverageVariant,
                lowqVariant
            };

            BaseCalledAlleles = variantCaller.Call(new CandidateBatch(candidateVariants), mockAlleleCountSource).Values.SelectMany(v => v);
            Assert.Equal(3, BaseCalledAlleles.Count());
            Assert.False(BaseCalledAlleles.Any(v => MatchVariants(v, passingReferenceHigh)));
            Assert.False(BaseCalledAlleles.Any(v => MatchVariants(v, passingReferenceLow)));
            Assert.True(BaseCalledAlleles.Any(v => MatchVariants(v, passingVariant)));
            Assert.True(BaseCalledAlleles.Any(v => MatchVariants(v, passingVariant2)));
            Assert.False(BaseCalledAlleles.Any(v => MatchVariants(v, lowFreqVariant)));
            Assert.True(BaseCalledAlleles.Any(v => MatchVariants(v, lowCoverageVariant)));
            Assert.False(BaseCalledAlleles.Any(v => MatchVariants(v, lowqVariant)));

            // reference calls only included if no passing variant (lowCoverageVariant fails)

            candidateVariants = new List <CandidateAllele>
            {
                passingReferenceLow,
                lowCoverageVariant,
            };

            config.IncludeReferenceCalls = false;
            config.MinCoverage           = (HighCoverageMultiplier * NumAlleles * NumDirections) - 1;

            variantCaller = new AlleleCaller(config);

            BaseCalledAlleles = variantCaller.Call(new CandidateBatch(candidateVariants), mockAlleleCountSource).Values.SelectMany(v => v);
            Assert.Equal(1, BaseCalledAlleles.Count());
            Assert.True(BaseCalledAlleles.Any(v => MatchVariants(v, passingReferenceLow)));
            Assert.False(BaseCalledAlleles.Any(v => MatchVariants(v, lowCoverageVariant)));

            // candidates outside of intervals are trimmed off

            config.MinCoverage      = 0;
            config.MinVariantQscore = 0;
            config.MinFrequency     = 0;

            variantCaller = new AlleleCaller(config, new ChrIntervalSet(new List <Region>()
            {
                new Region(highCoverageCoordinate, lowCoverageCoordinate)
            }, "chr1"));

            candidateVariants = new List <CandidateAllele>
            {
                passingVariant,
                lowFreqVariant,
                lowCoverageVariant
            };

            BaseCalledAlleles = variantCaller.Call(new CandidateBatch(candidateVariants), mockAlleleCountSource).Values.SelectMany(v => v);

            Assert.Equal(3, BaseCalledAlleles.Count());
            Assert.True(BaseCalledAlleles.Any(v => MatchVariants(v, passingVariant)));
            Assert.True(BaseCalledAlleles.Any(v => MatchVariants(v, lowFreqVariant)));
            Assert.True(BaseCalledAlleles.Any(v => MatchVariants(v, lowCoverageVariant)));

            variantCaller = new AlleleCaller(config, new ChrIntervalSet(new List <Region>()
            {
                new Region(highCoverageCoordinate, highCoverageCoordinate)
            }, "chr1"));

            BaseCalledAlleles = variantCaller.Call(new CandidateBatch(candidateVariants), mockAlleleCountSource).Values.SelectMany(v => v);

            Assert.Equal(2, BaseCalledAlleles.Count());
            Assert.True(BaseCalledAlleles.Any(v => MatchVariants(v, passingVariant)));
            Assert.True(BaseCalledAlleles.Any(v => MatchVariants(v, lowFreqVariant)));
            Assert.False(BaseCalledAlleles.Any(v => MatchVariants(v, lowCoverageVariant)));
        }
コード例 #8
0
        public void EvaluateVariants()
        {
            var config = new VariantCallerConfig
            {
                MaxVariantQscore         = 100,
                EstimatedBaseCallQuality = 20
            };

            var variantCaller = new AlleleCaller(config);

            var highCoverageCoordinate = 123;
            var lowCoverageCoordinate  = 456;

            var passingVariant = new CandidateAllele("chr1", highCoverageCoordinate, "A", "T", AlleleCategory.Snv)
            {
                SupportByDirection = new [] { 500, 0, 0 } // Freq is 500/1500, q is 100
            };
            var passingVariant2 = new CandidateAllele("chr1", highCoverageCoordinate, "A", "C", AlleleCategory.Snv)
            {
                SupportByDirection = new[] { 500, 0, 0 } // Freq is 500/1500, q is 100
            };
            var lowFreqVariant = new CandidateAllele("chr2", highCoverageCoordinate, "A", "T", AlleleCategory.Snv)
            {
                SupportByDirection = new[] { 1, 0, 0 } // Freq is 1/1500, q is 0
            };
            var lowCoverageVariant = new CandidateAllele("chr3", lowCoverageCoordinate, "A", "T", AlleleCategory.Snv)
            {
                SupportByDirection = new[] { 10, 0, 0 } // Freq is 10/15, q is 100
            };
            var lowqVariant = new CandidateAllele("chr4", highCoverageCoordinate, "A", "T", AlleleCategory.Snv)
            {
                SupportByDirection = new[] { 40, 0, 0 } // Freq is 40/1500, q is 72
            };
            var passingReferenceHigh = new CandidateAllele("chr1", highCoverageCoordinate, "A", "A", AlleleCategory.Reference)
            {
                SupportByDirection = new[] { 500, 0, 0 } // Freq is 500/1500, q is 100
            };
            var passingReferenceLow = new CandidateAllele("chr3", lowCoverageCoordinate, "A", "A", AlleleCategory.Reference)
            {
                SupportByDirection = new[] { 10, 0, 0 } // Freq is 10/15, q is 100
            };
            var candidateVariants = new List <CandidateAllele>
            {
                passingVariant
            };


            //Variants should be correctly mapped
            var mockAlleleCountSource = MockStateManager(highCoverageCoordinate, lowCoverageCoordinate).Object;
            var calledVariants        = variantCaller.Call(new CandidateBatch(candidateVariants), mockAlleleCountSource);
            var calledVariant         = calledVariants.First();

            Assert.Equal(passingVariant.Alternate, calledVariant.Alternate);
            Assert.Equal(passingVariant.Reference, calledVariant.Reference);
            Assert.Equal(passingVariant.Chromosome, calledVariant.Chromosome);
            Assert.Equal(passingVariant.Coordinate, calledVariant.Coordinate);
            Assert.Equal(passingVariant.Support, calledVariant.AlleleSupport);
            Assert.True(calledVariant is CalledVariant);
            Assert.True(((CalledVariant)calledVariant).Type == AlleleCategory.Snv);

            //After the Calculator steps are performed, variants that don't meet
            //our requirements to be callable should drop out

            //High coverage requirement - lowCoverageVariant should drop out.
            config.MinCoverage           = (HighCoverageMultiplier * NumAlleles * NumDirections) - 1;
            config.IncludeReferenceCalls = false;
            config.MinVariantQscore      = 0;
            config.MinFrequency          = 0;

            variantCaller = new AlleleCaller(config);

            candidateVariants = new List <CandidateAllele>
            {
                passingVariant,
                lowFreqVariant,
                lowCoverageVariant
            };

            calledVariants = variantCaller.Call(new CandidateBatch(candidateVariants), mockAlleleCountSource);

            Assert.Equal(2, calledVariants.Count());
            Assert.True(calledVariants.Any(v => MatchVariants(v, passingVariant)));
            Assert.True(calledVariants.Any(v => MatchVariants(v, lowFreqVariant)));
            Assert.False(calledVariants.Any(v => MatchVariants(v, lowCoverageVariant)));

            //High coverage but allow reference calls = nothing should drop out
            config.IncludeReferenceCalls = true;

            variantCaller = new AlleleCaller(config);

            candidateVariants = new List <CandidateAllele>
            {
                passingVariant,
                lowFreqVariant,
                lowCoverageVariant
            };

            calledVariants = variantCaller.Call(new CandidateBatch(candidateVariants), mockAlleleCountSource);
            foreach (var cvar in calledVariants)
            {
                Console.WriteLine(cvar.Qscore);
            }

            Assert.Equal(3, calledVariants.Count());

            //High frequency requirement - low frequency variant should drop out
            config.MinCoverage           = 0;
            config.IncludeReferenceCalls = false;
            config.MinVariantQscore      = 0;
            config.MinFrequency          = ((float)lowCoverageVariant.Support + 1) / (HighCoverageMultiplier * NumAlleles * NumDirections);

            calledVariants = variantCaller.Call(new CandidateBatch(candidateVariants), mockAlleleCountSource);

            Assert.Equal(2, calledVariants.Count());
            Assert.True(calledVariants.Any(v => MatchVariants(v, passingVariant)));
            Assert.False(calledVariants.Any(v => MatchVariants(v, lowFreqVariant)));
            Assert.True(calledVariants.Any(v => MatchVariants(v, lowCoverageVariant)));

            //High q score requirement - low frequency variant should drop out
            config.MinCoverage           = 0;
            config.IncludeReferenceCalls = false;
            config.MinVariantQscore      = 0;
            config.MinFrequency          = 0;
            config.MinVariantQscore      = QualityCalculator.AssignPoissonQScore(lowqVariant.Support,
                                                                                 (HighCoverageMultiplier * Constants.NumCovContributingAlleleTypes * Constants.NumDirectionTypes), config.EstimatedBaseCallQuality,
                                                                                 config.MaxVariantQscore) + 1;

            candidateVariants = new List <CandidateAllele>
            {
                passingVariant,
                passingVariant2,
                lowFreqVariant,
                lowCoverageVariant,
                lowqVariant
            };

            calledVariants = variantCaller.Call(new CandidateBatch(candidateVariants), mockAlleleCountSource);
            Assert.Equal(3, calledVariants.Count());
            Assert.True(calledVariants.Any(v => MatchVariants(v, passingVariant)));
            Assert.True(calledVariants.Any(v => MatchVariants(v, passingVariant2)));
            Assert.False(calledVariants.Any(v => MatchVariants(v, lowFreqVariant)));
            Assert.True(calledVariants.Any(v => MatchVariants(v, lowCoverageVariant)));
            Assert.False(calledVariants.Any(v => MatchVariants(v, lowqVariant)));

            // reference calls included
            candidateVariants = new List <CandidateAllele>
            {
                passingReferenceHigh,
                passingReferenceLow
            };

            calledVariants = variantCaller.Call(new CandidateBatch(candidateVariants), mockAlleleCountSource);
            Assert.Equal(2, calledVariants.Count());
            Assert.True(calledVariants.Any(v => MatchVariants(v, passingReferenceHigh)));
            Assert.True(calledVariants.Any(v => MatchVariants(v, passingReferenceLow)));

            // reference calls only included if no passing variant
            candidateVariants = new List <CandidateAllele>
            {
                passingReferenceHigh,
                passingReferenceLow,
                passingVariant,
                passingVariant2,
                lowFreqVariant,
                lowCoverageVariant,
                lowqVariant
            };

            calledVariants = variantCaller.Call(new CandidateBatch(candidateVariants), mockAlleleCountSource);
            Assert.Equal(3, calledVariants.Count());
            Assert.False(calledVariants.Any(v => MatchVariants(v, passingReferenceHigh)));
            Assert.False(calledVariants.Any(v => MatchVariants(v, passingReferenceLow)));
            Assert.True(calledVariants.Any(v => MatchVariants(v, passingVariant)));
            Assert.True(calledVariants.Any(v => MatchVariants(v, passingVariant2)));
            Assert.False(calledVariants.Any(v => MatchVariants(v, lowFreqVariant)));
            Assert.True(calledVariants.Any(v => MatchVariants(v, lowCoverageVariant)));
            Assert.False(calledVariants.Any(v => MatchVariants(v, lowqVariant)));

            // reference calls only included if no passing variant (lowCoverageVariant fails)

            candidateVariants = new List <CandidateAllele>
            {
                passingReferenceLow,
                lowCoverageVariant,
            };

            config.IncludeReferenceCalls = false;
            config.MinCoverage           = (HighCoverageMultiplier * NumAlleles * NumDirections) - 1;

            variantCaller = new AlleleCaller(config);

            calledVariants = variantCaller.Call(new CandidateBatch(candidateVariants), mockAlleleCountSource);
            Assert.Equal(1, calledVariants.Count());
            Assert.True(calledVariants.Any(v => MatchVariants(v, passingReferenceLow)));
            Assert.False(calledVariants.Any(v => MatchVariants(v, lowCoverageVariant)));

            // candidates outside of intervals are trimmed off

            config.MinCoverage      = 0;
            config.MinVariantQscore = 0;
            config.MinFrequency     = 0;

            variantCaller = new AlleleCaller(config, new ChrIntervalSet(new List <Region>()
            {
                new Region(highCoverageCoordinate, lowCoverageCoordinate)
            }, "chr1"));

            candidateVariants = new List <CandidateAllele>
            {
                passingVariant,
                lowFreqVariant,
                lowCoverageVariant
            };

            calledVariants = variantCaller.Call(new CandidateBatch(candidateVariants), mockAlleleCountSource);

            Assert.Equal(3, calledVariants.Count());
            Assert.True(calledVariants.Any(v => MatchVariants(v, passingVariant)));
            Assert.True(calledVariants.Any(v => MatchVariants(v, lowFreqVariant)));
            Assert.True(calledVariants.Any(v => MatchVariants(v, lowCoverageVariant)));

            variantCaller = new AlleleCaller(config, new ChrIntervalSet(new List <Region>()
            {
                new Region(highCoverageCoordinate, highCoverageCoordinate)
            }, "chr1"));

            calledVariants = variantCaller.Call(new CandidateBatch(candidateVariants), mockAlleleCountSource);

            Assert.Equal(2, calledVariants.Count());
            Assert.True(calledVariants.Any(v => MatchVariants(v, passingVariant)));
            Assert.True(calledVariants.Any(v => MatchVariants(v, lowFreqVariant)));
            Assert.False(calledVariants.Any(v => MatchVariants(v, lowCoverageVariant)));
        }