Пример #1
0
        //if I was not in a hurry, we could refactor this into the Config class and let it be re-used by Scylla and VQR...
        private static VcfWriterConfig GetWriterConfigToMatchInputVcf(string vcfIn)
        {
            List <string> vcfHeaderLines;

            using (var reader = new VcfReader(vcfIn))
            {
                vcfHeaderLines = reader.HeaderLines;
            }


            PiscesOptionsParser piscesOptionsParser = VcfConsumerAppParsingUtils.GetPiscesOptionsFromVcfHeader(vcfHeaderLines);

            if (piscesOptionsParser.ParsingFailed)
            {
                Logger.WriteToLog("Unable to parse the original Pisces commandline");
                throw new ArgumentException("Unable to parse the input vcf header: " + vcfIn);
            }

            VariantCallingParameters variantCallingParams = piscesOptionsParser.PiscesOptions.VariantCallingParameters;
            VcfWritingParameters     vcfWritingParams     = piscesOptionsParser.PiscesOptions.VcfWritingParameters;
            BamFilterParameters      bamFilterParams      = piscesOptionsParser.PiscesOptions.BamFilterParameters;

            var config = new VcfWriterConfig(variantCallingParams, vcfWritingParams, bamFilterParams, null, false, false);

            return(config);
        }
        public CallableNeighborhood(VcfNeighborhood vcfNeighborhood, VariantCallingParameters variantCallingParams, ChrReference chrReference = null)
        {
            //housekeeping

            _nbhdGTcalculator = GenotypeCreator.CreateGenotypeCalculator(variantCallingParams.PloidyModel, variantCallingParams.MinimumFrequencyFilter,
                                                                         variantCallingParams.MinimumCoverage,
                                                                         variantCallingParams.DiploidSNVThresholdingParameters,
                                                                         variantCallingParams.DiploidINDELThresholdingParameters,
                                                                         variantCallingParams.AdaptiveGenotypingParameters,
                                                                         variantCallingParams.MinimumGenotypeQScore, variantCallingParams.MaximumGenotypeQScore, variantCallingParams.TargetLODFrequency);


            _vcfNeighborhood        = vcfNeighborhood;
            _acceptedPhasedVariants = new List <CalledAllele>();
            _rejectedPhasedVariants = new List <CalledAllele>();
            UsedRefCountsLookup     = new Dictionary <int, SuckedUpRefRecord>();
            MaxQScore = variantCallingParams.MaximumVariantQScore;

            //prep vcf nbhd for use, so we know the final range of loci in play
            vcfNeighborhood.OrderVariantSitesByFirstTrueStartPosition();
            vcfNeighborhood.SetRangeOfInterest();

            //set reference bases here, then let go of the chr
            if ((chrReference == null) || (chrReference.Sequence == null)) //be gentle if they did not include a ref genome
            {
                NbhdReferenceSequenceSubstring = new String('R', vcfNeighborhood.LastPositionOfInterestWithLookAhead - vcfNeighborhood.FirstPositionOfInterest);
            }
            else
            {
                NbhdReferenceSequenceSubstring = chrReference.Sequence.Substring(vcfNeighborhood.FirstPositionOfInterest - 1, vcfNeighborhood.LastPositionOfInterestWithLookAhead - vcfNeighborhood.FirstPositionOfInterest);
            }
        }
Пример #3
0
        public VcfWriterConfig(VariantCallingParameters callerOptions,
                               VcfWritingParameters outputOptions, BamFilterParameters bamFilterOptions, SampleAggregationParameters sampleAggregationParameters,
                               bool debugMode, bool outputBiasFiles, bool hasForcedGT = false)
        {
            DepthFilterThreshold                = outputOptions.OutputGvcfFile ? callerOptions.MinimumCoverage : (callerOptions.LowDepthFilter > callerOptions.MinimumCoverage) ? callerOptions.LowDepthFilter : (int?)null;
            IndelRepeatFilterThreshold          = callerOptions.IndelRepeatFilter > 0 ? callerOptions.IndelRepeatFilter : (int?)null;
            VariantQualityFilterThreshold       = callerOptions.MinimumVariantQScoreFilter;
            GenotypeQualityFilterThreshold      = callerOptions.LowGenotypeQualityFilter.HasValue && callerOptions.MinimumVariantQScoreFilter > callerOptions.MinimumVariantQScore ? callerOptions.LowGenotypeQualityFilter : null;
            StrandBiasFilterThreshold           = callerOptions.StrandBiasAcceptanceCriteria < 1 ? callerOptions.StrandBiasAcceptanceCriteria : (float?)null;
            AmpliconBiasFilterThreshold         = callerOptions.AmpliconBiasFilterThreshold > 0 ? callerOptions.AmpliconBiasFilterThreshold : (float?)null;
            FrequencyFilterThreshold            = GetMinFreqFilterForVcfHeader(callerOptions);
            MinFrequencyThreshold               = callerOptions.MinimumFrequency;
            ShouldOutputNoCallFraction          = outputOptions.ReportNoCalls;
            ShouldOutputStrandBiasAndNoiseLevel = ShouldOutputNoiseLevelAndStrandBias(debugMode, outputBiasFiles, callerOptions.StrandBiasAcceptanceCriteria);
            ShouldFilterOnlyOneStrandCoverage   = callerOptions.FilterOutVariantsPresentOnlyOneStrand;
            EstimatedBaseCallQuality            = callerOptions.NoiseLevelUsedForQScoring;
            ShouldOutputRcCounts                = outputOptions.ReportRcCounts;
            ShouldOutputTsCounts                = outputOptions.ReportTsCounts;
            AllowMultipleVcfLinesPerLoci        = outputOptions.AllowMultipleVcfLinesPerLoci;
            PloidyModel = callerOptions.PloidyModel;
            RMxNFilterMaxLengthRepeat = callerOptions.RMxNFilterMaxLengthRepeat;
            RMxNFilterMinRepetitions  = callerOptions.RMxNFilterMinRepetitions;
            RMxNFilterFrequencyLimit  = callerOptions.RMxNFilterFrequencyLimit;
            NoiseModel            = callerOptions.NoiseModel;
            ShouldReportGp        = outputOptions.ReportGp;
            NoCallFilterThreshold = callerOptions.NoCallFilterThreshold;
            ShouldOutputSuspiciousCoverageFraction = outputOptions.ReportSuspiciousCoverageFraction;

            if (sampleAggregationParameters != null)
            {
                ShouldOutputProbeBias        = true;
                ProbePoolBiasFilterThreshold = sampleAggregationParameters.ProbePoolBiasThreshold;
            }
            HasForcedGt = hasForcedGT;
        }
        public void Validate_HappyPath()
        {
            //check defaults are reasonable (after validation):
            var VariantCallingParameters = new VariantCallingParameters();

            Assert.Equal(VariantCallingParameters.MinimumFrequency, 0.01F);
            Assert.Equal(VariantCallingParameters.MinimumFrequencyFilter, -1);
            Assert.Equal(VariantCallingParameters.TargetLODFrequency, -1);

            VariantCallingParameters.Validate();

            Assert.Equal(VariantCallingParameters.MinimumFrequency, 0.01F);
            Assert.Equal(VariantCallingParameters.MinimumFrequencyFilter, 0.01F);
            Assert.Equal(VariantCallingParameters.TargetLODFrequency, 0.01F);

            //check defaults for low-freq var calling
            VariantCallingParameters = new VariantCallingParameters();
            VariantCallingParameters.MinimumFrequency = 0.0001F;

            Assert.Equal(VariantCallingParameters.MinimumFrequency, 0.0001F);
            Assert.Equal(VariantCallingParameters.MinimumFrequencyFilter, -1);
            Assert.Equal(VariantCallingParameters.TargetLODFrequency, -1);

            VariantCallingParameters.Validate();

            Assert.Equal(VariantCallingParameters.MinimumFrequency, 0.0001F);
            Assert.Equal(VariantCallingParameters.MinimumFrequencyFilter, 0.0001F);
            Assert.Equal(VariantCallingParameters.TargetLODFrequency, 0.0001F);

            //check defaults for high-freq calling
            VariantCallingParameters = new VariantCallingParameters();
            VariantCallingParameters.MinimumFrequency = 0.20F;

            Assert.Equal(VariantCallingParameters.MinimumFrequency, 0.20F);
            Assert.Equal(VariantCallingParameters.MinimumFrequencyFilter, -1);
            Assert.Equal(VariantCallingParameters.TargetLODFrequency, -1);

            VariantCallingParameters.Validate();

            Assert.Equal(VariantCallingParameters.MinimumFrequency, 0.20F);
            Assert.Equal(VariantCallingParameters.MinimumFrequencyFilter, 0.20F);
            Assert.Equal(VariantCallingParameters.TargetLODFrequency, 0.20F);

            //check defaults for typical case calling
            VariantCallingParameters = new VariantCallingParameters();
            VariantCallingParameters.MinimumFrequency       = 0.01F;
            VariantCallingParameters.MinimumFrequencyFilter = 0.026F;
            VariantCallingParameters.TargetLODFrequency     = 0.05F;

            Assert.Equal(VariantCallingParameters.MinimumFrequency, 0.01F);
            Assert.Equal(VariantCallingParameters.MinimumFrequencyFilter, 0.026F);
            Assert.Equal(VariantCallingParameters.TargetLODFrequency, 0.05F);

            VariantCallingParameters.Validate();

            Assert.Equal(VariantCallingParameters.MinimumFrequency, 0.01F);
            Assert.Equal(VariantCallingParameters.MinimumFrequencyFilter, 0.026F);
            Assert.Equal(VariantCallingParameters.TargetLODFrequency, 0.05F);
        }
        public DiploidAdaptiveGenotyper()
        {
            var defaultParams = new VariantCallingParameters();

            _adaptiveGenotypingParameters = new AdaptiveGenotypingParameters();
            MinGQScore         = defaultParams.MinimumGenotypeQScore;
            MaxGQScore         = defaultParams.MaximumGenotypeQScore;
            MinDepthToGenotype = defaultParams.MinimumCoverage;
        }
Пример #6
0
 public VcfNeighborhoodBuilder(PhasableVariantCriteria phasableVariantCriteria, VariantCallingParameters variantCallingParams, IVcfVariantSource vcfVariantSource)
 {
     _chrsToProcess        = phasableVariantCriteria.ChrToProcessArray;
     _passingOnly          = phasableVariantCriteria.PassingVariantsOnly;
     _hetOnly              = phasableVariantCriteria.HetVariantsOnly;
     _phasingDistance      = phasableVariantCriteria.PhasingDistance;
     _vcfVariantSource     = vcfVariantSource;
     _neighborhoods        = new List <VcfNeighborhood>();
     _variantCallingParams = variantCallingParams;
 }
Пример #7
0
        public void CheckAddingFilters()
        {
            var originalVcfVariant  = TestHelper.CreateDummyAllele("chr1", 123, "A", "T", 1000, 156);
            var originalVcfVariant2 = TestHelper.CreateDummyAllele("chr1", 124, "A", "T", 1000, 156);
            var vs1 = new VariantSite(originalVcfVariant);
            var vs2 = new VariantSite(originalVcfVariant2);

            var variantCallingParameters = new VariantCallingParameters();

            //Set up filters so calls are sure to trigger them.
            variantCallingParameters.LowDepthFilter             = 2000;
            variantCallingParameters.MinimumFrequencyFilter     = 0.80F;
            variantCallingParameters.MinimumVariantQScoreFilter = 300;


            var caller = new VariantCaller(variantCallingParameters, new BamFilterParameters());


            var nbhd = new VcfNeighborhood(new VariantCallingParameters(), 0, "chr1", vs1, vs2, "");

            nbhd.SetRangeOfInterest();
            nbhd.AddAcceptedPhasedVariant(
                new CalledAllele(AlleleCategory.Snv)
            {
                Chromosome        = "chr1",
                ReferencePosition = 123,
                ReferenceAllele   = "A",
                AlternateAllele   = "T",
                VariantQscore     = 100,
                TotalCoverage     = 1000,
                AlleleSupport     = 500
            });
            nbhd.UsedRefCountsLookup = new Dictionary <int, SuckedUpRefRecord>()
            {
            };

            caller.CallMNVs(nbhd);
            caller.CallRefs(nbhd);

            var acceptedMNVs = nbhd.CalledVariants;
            var acceptedRefs = nbhd.CalledRefs;

            Assert.Equal(1, acceptedMNVs.Count);
            Assert.Equal(1, acceptedMNVs[123].Count);

            Assert.True(acceptedMNVs[123][0].Filters.Contains(FilterType.LowDepth));
            Assert.True(acceptedMNVs[123][0].Filters.Contains(FilterType.LowVariantFrequency));
            Assert.True(acceptedMNVs[123][0].Filters.Contains(FilterType.LowVariantQscore));

            Assert.Equal(2, acceptedRefs.Count);

            Assert.True(acceptedRefs[123].Filters.Contains(FilterType.LowDepth));
            Assert.True(acceptedRefs[123].Filters.Contains(FilterType.LowVariantQscore));
            //note reference calls dont win the "LowVariantFrequency" flag.
        }
Пример #8
0
        public DiploidGenotypeCalculator()
        {
            var defaultParams = new VariantCallingParameters();

            _diploidSnvThresholdingParameters   = defaultParams.DiploidSNVThresholdingParameters;
            _diploidIndelThresholdingParameters = defaultParams.DiploidINDELThresholdingParameters;
            MinGQScore         = defaultParams.MinimumGenotypeQScore;
            MaxGQScore         = defaultParams.MaximumGenotypeQScore;
            MinDepthToGenotype = defaultParams.MinimumCoverage;
            MinVarFrequency    = _diploidSnvThresholdingParameters.MinorVF;
        }
Пример #9
0
        private static float?GetMinFreqFilterForVcfHeader(VariantCallingParameters callerOptions)
        {
            //this gets the right value when the min frequency is a definite number.
            //Ie, any pisces genotyping methods that have a min freq cutoff.
            var frequencyFilterThreshold = (callerOptions.MinimumFrequencyFilter > callerOptions.MinimumFrequency) ? callerOptions.MinimumFrequencyFilter : (float?)null;

            //AdaptiveGT needs special handling, because there is no hard-coded minimum frequency to call a GT 0/1 variant.
            //But we cant have NULL or NAN in the vcf header. Using the min emit freq instead is appropriate here.
            if (callerOptions.PloidyModel == PloidyModel.DiploidByAdaptiveGT)
            {
                frequencyFilterThreshold = callerOptions.MinimumFrequency;
            }

            return(frequencyFilterThreshold);
        }
Пример #10
0
        public VcfNeighborhood(VariantCallingParameters variantCallingParams, string refName, VariantSite vs1, VariantSite vs2, string interveningRef)
        {
            _nbhdGTcalculator = GenotypeCreator.CreateGenotypeCalculator(variantCallingParams.PloidyModel, variantCallingParams.MinimumFrequencyFilter,
                                                                         variantCallingParams.MinimumCoverage,
                                                                         variantCallingParams.DiploidThresholdingParameters,
                                                                         variantCallingParams.MinimumGenotpyeQScore, variantCallingParams.MaximumGenotpyeQScore);
            VcfVariantSites         = new List <VariantSite>();
            _referenceName          = refName;
            _acceptedPhasedVariants = new List <CalledAllele>();
            _rejectedPhasedVariants = new List <CalledAllele>();
            UsedRefCountsLookup     = new Dictionary <int, int>();

            AddVariantSite(vs1, vs1.VcfReferenceAllele.Substring(0, 1));
            AddVariantSite(vs2, interveningRef);

            SetID();
        }
        public AdaptiveGtOptions()
        {
            // Set defaults
            VariantCallingParams = new VariantCallingParameters
            {
                PloidyModel = Pisces.Domain.Types.PloidyModel.DiploidByAdaptiveGT,
                IsMale      = false
            };

            VcfWritingParams = new VcfWritingParameters
            {
                OutputGvcfFile = false,
                ForceCrush     = true,
                ReportGp       = true
            };

            SetDerivedValues();
        }
Пример #12
0
        public VcfNeighborhoodBuilder(PhasableVariantCriteria phasableVariantCriteria, VariantCallingParameters variantCallingParams,
                                      IVcfVariantSource vcfVariantSource, int batchSize)
        {
            _variantCallingParams     = variantCallingParams;
            _phasableVariantCriteria  = phasableVariantCriteria;
            _vcfVariantSource         = vcfVariantSource;
            _nextBatchOfNeighborhoods = new List <VcfNeighborhood>();
            _unfinshedNeighborhoods   = new List <VcfNeighborhood>();
            _maxNumNbhdsInBatch       = batchSize;

            var lastVariantSite = new VariantSite()
            {
                VcfReferenceAllele   = "",
                VcfAlternateAllele   = "",
                ReferenceName        = "",
                VcfReferencePosition = 0
            };
        }
Пример #13
0
        public void CallAVariantInANewLocation()
        {
            //set up the original variants
            var originalVcfVariant1 = TestHelper.CreateDummyAllele("chr1", 123, "A", "T", 1000, 156);
            var originalVcfVariant2 = TestHelper.CreateDummyAllele("chr1", 124, "A", "T", 1000, 156);
            var originalVcfVariant3 = TestHelper.CreateDummyAllele("chr1", 234, "A", "T", 1000, 156);
            var originalVcfVariant4 = TestHelper.CreateDummyAllele("chr1", 234, "A", "T", 1000, 156);

            var vs1 = new VariantSite(originalVcfVariant1);
            var vs2 = new VariantSite(originalVcfVariant2);
            var vs3 = new VariantSite(originalVcfVariant3);
            var vs4 = new VariantSite(originalVcfVariant4);

            var vcParams = new VariantCallingParameters();

            vcParams.Validate();
            var caller = new VariantCaller(vcParams, new BamFilterParameters());
            var nbhd   = new VcfNeighborhood(vcParams, 0, "chr1", vs1, vs2, "");

            nbhd.AddVariantSite(vs3, "RRRRR"); //note, we do not add vs4, that is not going to get used for phasing. Sps it is a variant that failed filters.
            nbhd.SetRangeOfInterest();

            //now stage one candidate MNV:
            var newMNV = new CalledAllele(AlleleCategory.Snv)
            {
                Chromosome        = "chr1",
                ReferencePosition = 129,
                ReferenceAllele   = "A",
                AlternateAllele   = "TT",
                VariantQscore     = 100,
                TotalCoverage     = 1000,
                AlleleSupport     = 500
            };


            nbhd.AddAcceptedPhasedVariant(newMNV);
            var suckedUpRefRecord1000 = new SuckedUpRefRecord()
            {
                Counts = 1000, AlleleThatClaimedIt = new CalledAllele()
            };

            nbhd.UsedRefCountsLookup = new Dictionary <int, SuckedUpRefRecord>()
            {
                { 124, suckedUpRefRecord1000 }
            };

            caller.CallMNVs(nbhd);
            caller.CallRefs(nbhd);

            var acceptedMNVs = nbhd.CalledVariants;
            var acceptedRefs = nbhd.CalledRefs;


            var vcfVariant0asRef = new VcfVariant()
            {
                ReferenceName     = "chr1",
                ReferencePosition = 123,
                ReferenceAllele   = "A",
                VariantAlleles    = new[] { "." },
                Genotypes         = new List <Dictionary <string, string> >()
                {
                    new Dictionary <string, string>()
                    {
                        { "GT", "0/." }
                    }
                },
            };

            var vcfVariant3asRef = new VcfVariant()
            {
                ReferenceName     = "chr1",
                ReferencePosition = 234,
                ReferenceAllele   = "A",
                VariantAlleles    = new[] { "." },
                Genotypes         = new List <Dictionary <string, string> >()
                {
                    new Dictionary <string, string>()
                    {
                        { "GT", "0/." }
                    }
                },
            };

            var vcfVariant2asNull = new VcfVariant()
            {
                ReferenceName     = "chr1",
                ReferencePosition = 124,
                ReferenceAllele   = "A",
                VariantAlleles    = new[] { "." },
                Genotypes         = new List <Dictionary <string, string> >()
                {
                    new Dictionary <string, string>()
                    {
                        { "GT", "./." }
                    }
                },
            };

            Assert.Equal(1, acceptedMNVs.Count);
            Assert.Equal(1, acceptedMNVs[129].Count);

            Assert.Equal(3, acceptedRefs.Count);

            VcfMergerTests.CheckVariantsMatch(vcfVariant0asRef, acceptedRefs[123]);
            VcfMergerTests.CheckVariantsMatch(vcfVariant2asNull, acceptedRefs[124]);
            VcfMergerTests.CheckVariantsMatch(newMNV, acceptedMNVs[129][0]);
            VcfMergerTests.CheckVariantsMatch(vcfVariant3asRef, acceptedRefs[234]);
        }
Пример #14
0
        private static Genotype GetGenotype(CalledAllele VariantA, CalledAllele VariantB, VariantComparisonCase Case,
                                            int TotalDepth, double VarFrequency, double VarFrequencyA, double VarFrequencyB, SampleAggregationParameters SampleAggregationOptions, VariantCallingParameters variantCallingParameters)
        {
            var gtA    = Genotype.RefLikeNoCall;
            var gtB    = Genotype.RefLikeNoCall;
            var tempGT = Genotype.RefLikeNoCall;

            if (VariantB != null)
            {
                gtB = VariantB.Genotype;
            }
            if (VariantA != null)
            {
                gtA = VariantA.Genotype;
            }

            //cases:  {0/0 , 0/1,  1/1, ./.} , choose 2.

            //if (A == B)  GTString  = A;

            bool RefPresent = ((VariantA != null && VariantA.HasARefAllele) || (VariantB != null && VariantB.HasARefAllele));
            bool AltPresent = ((VariantA != null && VariantA.HasAnAltAllele) || (VariantB != null && VariantB.HasAnAltAllele));

            if (!AltPresent && RefPresent)
            {
                tempGT = Genotype.HomozygousRef;
            }
            else if (AltPresent && RefPresent)
            {
                tempGT = Genotype.HeterozygousAltRef;
            }
            else if (AltPresent && !RefPresent)
            {
                tempGT = Genotype.HomozygousAlt;

                //todo, expand to cover nocalls and heterozygous calls.
            }
            else //(no alt and no reference detected.)
            {
                tempGT = Genotype.RefLikeNoCall;
            }

            //if its  no call, thats fine. we are done
            if (tempGT == Genotype.RefLikeNoCall)
            {
                return(tempGT);
            }

            //if the merged GT implies a variant call,
            //it has to pass some minimal criteria, or it gets
            //re-classified as a ref type or a no-call.
            //So. now, check the combined result passed some minimum criteria:

            //First, never call it a Variant if the combined freq
            //is smaller than the reporting threshold.
            //If the freq is low, we should call "0/0" or "./.".  , but not "1/1" or "0/1"
            //So change any "0/1"s or "1/1"s over to "./.".

            //if we would have called a variant... but...
            if (Case != VariantComparisonCase.AgreedOnReference)
            {
                // ifcombined freq <1% and both per-pool freq <3% -> 0/0
                // ifcombined freq <1% and a per-pool freq >3% -> ./.
                // ifcombined freq >1% and <3%      -> ./.

                //if combined freq <1%
                if (VarFrequency < variantCallingParameters.MinimumFrequency)
                {
                    //if its < 3% in both pools but still <1% overall
                    if ((VarFrequencyA < variantCallingParameters.MinimumFrequencyFilter) &&
                        (VarFrequencyB < variantCallingParameters.MinimumFrequencyFilter))
                    {
                        tempGT = Genotype.HomozygousRef;
                    }
                    else                     //if its > 3% in at least one pool but still <1% overall
                    {
                        tempGT = Genotype.AltLikeNoCall;
                    }
                }
                else if (VarFrequency < variantCallingParameters.MinimumFrequencyFilter)
                {//if combined freq more than 1% but still < 3%
                    tempGT = Genotype.AltLikeNoCall;
                }

                //next - we have to clean up any multiple allelic sites.
            }
            // also, dont call it a variant *or* a reference
            // if the combined Depth is less than the minimum.
            // (this case is defensive programing.  The SVC should already call
            // each pool variant as ".\." , due to indiviudal low depth,
            // so the combined results
            // shoud already be ".\." by default. )
            else if (TotalDepth < variantCallingParameters.MinimumCoverage)
            {
                // note, this could happen even though your input variants are one 'no call' and one 'var',
                //or even two variants-failing-filters.
                tempGT = Genotype.RefLikeNoCall;
            }
            return(tempGT);
        }
        public void Validate_Pathological()
        {
            //check it fixes the LOD

            var VariantCallingParameters = new VariantCallingParameters();

            VariantCallingParameters.MinimumFrequency       = 0.03F;
            VariantCallingParameters.MinimumFrequencyFilter = 0.03F;
            VariantCallingParameters.TargetLODFrequency     = 0.005F;

            VariantCallingParameters.Validate();

            Assert.Equal(VariantCallingParameters.MinimumFrequency, 0.03F);
            Assert.Equal(VariantCallingParameters.MinimumFrequencyFilter, 0.03F);
            Assert.Equal(VariantCallingParameters.TargetLODFrequency, 0.03F);

            //check it fixes the filter

            VariantCallingParameters = new VariantCallingParameters();
            VariantCallingParameters.MinimumFrequency       = 0.03F;
            VariantCallingParameters.MinimumFrequencyFilter = 0.02F;
            VariantCallingParameters.TargetLODFrequency     = 0.02F;

            VariantCallingParameters.Validate();

            Assert.Equal(VariantCallingParameters.MinimumFrequency, 0.03F);
            Assert.Equal(VariantCallingParameters.MinimumFrequencyFilter, 0.03F);
            Assert.Equal(VariantCallingParameters.TargetLODFrequency, 0.03F);

            //check it catches the LOD mess

            VariantCallingParameters = new VariantCallingParameters();
            VariantCallingParameters.MinimumFrequency       = 0.03F;
            VariantCallingParameters.MinimumFrequencyFilter = -2F;
            VariantCallingParameters.TargetLODFrequency     = -3F;

            VariantCallingParameters.Validate();

            Assert.Equal(VariantCallingParameters.MinimumFrequency, 0.03F);
            Assert.Equal(VariantCallingParameters.MinimumFrequencyFilter, 0.03F);
            Assert.Equal(VariantCallingParameters.TargetLODFrequency, 0.03F);


            //check it catches the Filter mess

            VariantCallingParameters = new VariantCallingParameters();
            VariantCallingParameters.MinimumFrequency       = 0.03F;
            VariantCallingParameters.MinimumFrequencyFilter = -3F;
            VariantCallingParameters.TargetLODFrequency     = 0.04F;

            VariantCallingParameters.Validate();

            Assert.Equal(VariantCallingParameters.MinimumFrequency, 0.03F);
            Assert.Equal(VariantCallingParameters.MinimumFrequencyFilter, 0.03F);
            Assert.Equal(VariantCallingParameters.TargetLODFrequency, 0.04F);

            //check it catches the Freq mess (nothing we can do here but throw)

            VariantCallingParameters = new VariantCallingParameters();
            VariantCallingParameters.MinimumFrequency       = -3F;
            VariantCallingParameters.MinimumFrequencyFilter = 0.03F;
            VariantCallingParameters.TargetLODFrequency     = 0.04F;

            Assert.Throws <ArgumentException>(() => VariantCallingParameters.Validate());
        }
Пример #16
0
        private static BiasResults GetProbePoolBiasScore(VariantComparisonCase Case, CalledAllele Consensus,
                                                         float ProbePoolBiasThreshold, VariantCallingParameters variantCallingParameters, int AltCountA, int AltCountB, int DepthA, int DepthB, Genotype Genotype, bool AltChangeToRef)
        {
            double      ProbePoolPScore        = 0;    //no bias;
            double      ProbePoolGATKBiasScore = -100; //no bias;
            int         NoiseLevel             = Consensus.NoiseLevelApplied;
            BiasResults PB = new BiasResults();

            if ((AltChangeToRef) || (Case == VariantComparisonCase.AgreedOnReference))
            {
                PB.GATKBiasScore = ProbePoolGATKBiasScore;
                PB.BiasScore     = ProbePoolPScore;
                return(PB);
            }

            if ((Case == VariantComparisonCase.OneReferenceOneAlternate) ||
                (Case == VariantComparisonCase.CanNotCombine))
            {
                Consensus.Filters.Add(FilterType.PoolBias);
                PB.GATKBiasScore = 0;
                PB.BiasScore     = 1;
                return(PB);
            }

            if (Case == VariantComparisonCase.AgreedOnAlternate)
            {
                int[] supportByPool = new int[]
                {
                    AltCountA, AltCountB, 0
                };
                int[] covByPool = new int[]
                {
                    DepthA, DepthB, 0
                };


                BiasResults ProbePoolBiasResults =
                    StrandBiasCalculator.CalculateStrandBiasResults(
                        covByPool, supportByPool,
                        NoiseLevel, variantCallingParameters.MinimumFrequency, ProbePoolBiasThreshold, StrandBiasModel.Extended);

                ProbePoolGATKBiasScore = Math.Min(0, ProbePoolBiasResults.GATKBiasScore);        //just cap it at upperbound 0, dont go higher.
                ProbePoolGATKBiasScore = Math.Max(-100, ProbePoolGATKBiasScore);                 //just cap it at lowerbound -100, dont go higher.

                ProbePoolPScore = Math.Min(1, ProbePoolBiasResults.BiasScore);

                if (!ProbePoolBiasResults.BiasAcceptable)
                {
                    Consensus.Filters.Add(FilterType.PoolBias);
                }
            }

            PB.GATKBiasScore = ProbePoolGATKBiasScore;
            PB.BiasScore     = ProbePoolPScore;
            return(PB);
        }
        public static Dictionary <string, OptionSet> GetVariantCallingParsingMethods(VariantCallingParameters options)
        {
            var variantCallingOps = new OptionSet
            {
                {
                    "minvq|minvariantqscore=",
                    OptionTypes.INT + " MinimumVariantQScore to report variant",
                    value => options.MinimumVariantQScore = int.Parse(value)
                },
                {
                    "c|mindp|mindepth|mincoverage=",
                    OptionTypes.INT + " Minimum depth to call a variant",
                    value => options.MinimumCoverage = int.Parse(value)
                },
                {
                    "minvf|minimumvariantfrequency|minimumfrequency=",
                    OptionTypes.FLOAT + " MinimumFrequency to call a variant",
                    value => options.MinimumFrequency = float.Parse(value)
                },
                {
                    "targetlodfrequency|targetvf=",
                    OptionTypes.FLOAT + " Target Frequency to call a variant. Ie, to target a 5% allele frequency, we must call down to 2.6%, to capture that 5% allele 95% of the time. This parameter is used by the Somatic Genotyping Model",
                    value => options.TargetLODFrequency = float.Parse(value)
                },
                {
                    "vqfilter|variantqualityfilter=",
                    OptionTypes.INT + " FilteredVariantQScore to report variant as filtered",
                    value => options.MinimumVariantQScoreFilter = int.Parse(value)
                },
                {
                    "vffilter|minvariantfrequencyfilter=",
                    OptionTypes.FLOAT + " FilteredVariantFrequency to report variant as filtered",
                    value => options.MinimumFrequencyFilter = float.Parse(value)
                },
                {
                    "gqfilter|genotypequalityfilter=",
                    OptionTypes.INT + " Filtered Genotype quality to report variant as filtered",
                    value => options.LowGenotypeQualityFilter = int.Parse(value)
                },
                {
                    "repeatfilter_ToBeRetired=",
                    OptionTypes.INT + " FilteredIndelRepeats to report variant as filtered. To be retired. Please transition to RMxN.",
                    value => options.IndelRepeatFilter = int.Parse(value)
                },
                {
                    "mindpfilter|mindepthfilter=",
                    OptionTypes.INT + " FilteredLowDepth to report variant as filtered",
                    value => options.LowDepthFilter = int.Parse(value)
                },
                {
                    "ssfilter|enablesinglestrandfilter=",
                    OptionTypes.BOOL + " Flag variants as filtered if coverage limited to one strand",
                    value => options.FilterOutVariantsPresentOnlyOneStrand = bool.Parse(value)
                },
                {
                    "nl|noiselevelforqmodel=",
                    OptionTypes.INT + " Overrides the noise level to used by the quality model with this value. By default, this is driven by the basecall filter.",
                    value => options.ForcedNoiseLevel = int.Parse(value)
                },
                {
                    "ploidy=",
                    OptionTypes.STRING + $" 'somatic' or 'diploid'. default, {options.PloidyModel}.",
                    value => options.PloidyModel = ConvertToPloidy(value)
                },
                {
                    "diploidsnvgenotypeparameters=",
                    OptionTypes.STRING + " A,B,C. default 0.20,0.70,0.80",
                    value => options.DiploidSNVThresholdingParameters = ConvertToDiploidThresholding(value)
                },
                {
                    "diploidindelgenotypeparameters=",
                    OptionTypes.STRING + " A,B,C. default 0.20,0.70,0.80",
                    value => options.DiploidINDELThresholdingParameters = ConvertToDiploidThresholding(value)
                },
                {
                    "sbmodel=",
                    OptionTypes.STRING + " ",
                    value => options.StrandBiasModel = ConvertToStrandBiasModel(value)
                },
                {
                    "maxvq|maxvariantqscore=",
                    OptionTypes.INT + " MaximumVariantQScore to cap output variant Qscores",
                    value => options.MaximumVariantQScore = int.Parse(value)
                },
                {
                    "maxgq|maxgenotypeqscore=",
                    OptionTypes.INT + " Maximum genotype QScore to cap output variant Qscores ",
                    value => options.MaximumGenotypeQScore = int.Parse(value)
                },
                {
                    "mingq|mingenotypeqscore=",
                    OptionTypes.INT + " Minimum genotype QScore to cap output variant Qscores ",
                    value => options.MinimumGenotypeQScore = int.Parse(value)
                },
                {
                    "sbfilter|maxacceptablestrandbiasfilter=",
                    OptionTypes.FLOAT + " Strand bias cutoff",
                    value => options.StrandBiasAcceptanceCriteria = float.Parse(value)
                },
                {
                    "noisemodel=",
                    OptionTypes.STRING + $" Window/Flat. Default {options.NoiseModel}",
                    value => options.NoiseModel = value.ToLower() == "window" ? NoiseModel.Window : NoiseModel.Flat
                },
                {
                    "gender=",
                    OptionTypes.BOOL + " Gender of the sample, if known. Male=TRUE, Female=FALSE . Default, unset.",
                    value => options.IsMale = value.ToLower() == "male"
                },
                {
                    "rmxnfilter=",
                    OptionTypes.STRING + " M,N,F. Comma-separated list of integers indicating max length of the repeat section (M), the minimum number of repetitions of that repeat (N), to be applied if the variant frequency is less than (F). Default is R5x9,F=20.",
                    value => ParseRMxNFilter(value, ref options.RMxNFilterMaxLengthRepeat, ref options.RMxNFilterMinRepetitions, ref options.RMxNFilterFrequencyLimit)
                },
                {
                    "ncfilter=",
                    OptionTypes.FLOAT + " No-call rate filter",
                    value => options.NoCallFilterThreshold = float.Parse(value)
                }
            };


            var optionDict = new Dictionary <string, OptionSet>
            {
                { OptionSetNames.VariantCalling, variantCallingOps },
            };


            return(optionDict);
        }
Пример #18
0
 public VariantCaller(VariantCallingParameters callerParams, BamFilterParameters bamParams)
 {
     _bamParams    = bamParams;
     _callerParams = callerParams;
 }
Пример #19
0
        private static void RecalculateScoring(CalledAllele VariantA, CalledAllele VariantB,
                                               VariantComparisonCase Case,
                                               AggregateAllele ConsensusAllele, SampleAggregationParameters SampleAggregationOptions, VariantCallingParameters variantCallingParameters)
        {
            int RefCountB = 0, RefCountA = 0;
            int AltCountB = 0, AltCountA = 0;
            int DepthA = 0;
            int DepthB = 0;

            //1) first, calculate all the component values (variant frequency, etc...)
            if (VariantA != null)
            {
                RefCountA = VariantA.ReferenceSupport;
                AltCountA = (VariantA.IsRefType) ? 0 : VariantA.AlleleSupport;
                DepthA    = VariantA.TotalCoverage;
            }

            if (VariantB != null)
            {
                RefCountB = VariantB.ReferenceSupport;
                AltCountB = (VariantB.IsRefType) ? 0 : VariantB.AlleleSupport;
                DepthB    = VariantB.TotalCoverage;
            }


            int TotalDepth     = DepthA + DepthB;
            int ReferenceDepth = RefCountA + RefCountB;
            int AltDepth       = AltCountA + AltCountB;

            double VarFrequency  = ((AltDepth == 0) || (TotalDepth == 0)) ? 0.0 : ((double)AltDepth) / ((double)(TotalDepth));
            double VarFrequencyA = ((AltCountA == 0) || (DepthA == 0)) ? 0.0 : ((double)AltCountA) / ((double)(DepthA));
            double VarFrequencyB = ((AltCountB == 0) || (DepthB == 0)) ? 0.0 : ((double)AltCountB) / ((double)(DepthB));

            ConsensusAllele.TotalCoverage    = TotalDepth;
            ConsensusAllele.AlleleSupport    = AltDepth;
            ConsensusAllele.ReferenceSupport = ReferenceDepth;

            var GT = GetGenotype(VariantA, VariantB, Case,
                                 TotalDepth, VarFrequency, VarFrequencyA, VarFrequencyB, SampleAggregationOptions, variantCallingParameters);

            ConsensusAllele.NoiseLevelApplied = GetCombinedNLValue(VariantA, VariantB, SampleAggregationOptions);
            ConsensusAllele.StrandBiasResults = GetCombinedSBValue(VariantA, VariantB, SampleAggregationOptions);

            //its possible the GTString went from var -> ref when we combined the results.
            //If that is the case we do not want to write "variant" anymore to the .vcf.
            //We also have to re-calculate the Q scores for a reference call.
            //They need to be based on a reference model, not a variant model.
            bool AltChangedToRef = PushThroughRamificationsOfGTChange(VariantA, VariantB,
                                                                      ConsensusAllele, RefCountA, RefCountB, DepthA, DepthB, GT,
                                                                      variantCallingParameters.MaximumVariantQScore, Case);

            ConsensusAllele.Genotype        = GT;
            ConsensusAllele.PoolBiasResults = GetProbePoolBiasScore(Case, ConsensusAllele,
                                                                    SampleAggregationOptions.ProbePoolBiasThreshold, variantCallingParameters, AltCountA, AltCountB, DepthA, DepthB, GT, AltChangedToRef);

            if (SampleAggregationOptions.HowToCombineQScore == SampleAggregationParameters.CombineQScoreMethod.TakeMin)
            {
                ConsensusAllele.VariantQscore = CombineQualitiesByTakingMinValue(VariantA, VariantB);
            }
            else //VariantCallingCombinePoolSettings.CombineQScoreMethod.CombinePoolsAndReCalculate
            {
                //where we apply the reference Q model:
                if (Case == VariantComparisonCase.AgreedOnReference)
                {
                    ConsensusAllele.VariantQscore = CombineQualitiesByPoolingReads(ReferenceDepth, TotalDepth, ConsensusAllele.NoiseLevelApplied,
                                                                                   variantCallingParameters.MaximumVariantQScore);
                }
                else if ((Case == VariantComparisonCase.OneReferenceOneAlternate) && (AltChangedToRef))
                {
                    ConsensusAllele.VariantQscore = CombineQualitiesByPoolingReads(ReferenceDepth, TotalDepth, ConsensusAllele.NoiseLevelApplied,
                                                                                   variantCallingParameters.MaximumVariantQScore);
                }
                else if ((Case == VariantComparisonCase.CanNotCombine) && (AltDepth == 0)) //so the only call we had must have been ref
                {
                    ConsensusAllele.VariantQscore = CombineQualitiesByPoolingReads(ReferenceDepth, TotalDepth, ConsensusAllele.NoiseLevelApplied,
                                                                                   variantCallingParameters.MaximumVariantQScore);
                }

                //where we apply the variant Q model. this is most cases
                else // cases are aggreed on alt, or one alt call.  in which case, apply variant Q model.
                {
                    ConsensusAllele.VariantQscore = CombineQualitiesByPoolingReads(AltDepth, TotalDepth, ConsensusAllele.NoiseLevelApplied,
                                                                                   variantCallingParameters.MaximumVariantQScore);
                }
            }

            //assuming this is only used on Somatic...
            ConsensusAllele.GenotypeQscore = ConsensusAllele.VariantQscore;
            ConsensusAllele.SetType();

            if (ConsensusAllele.IsRefType)
            {
                ConsensusAllele.AlleleSupport = ConsensusAllele.ReferenceSupport;
            }
        }
        public static void AddVariantCallingArgumentParsing(Dictionary <string, OptionSet> parsingMethods, VariantCallingParameters options)
        {
            var variantCallingOptionDict = GetVariantCallingParsingMethods(options);


            foreach (var key in variantCallingOptionDict.Keys)
            {
                foreach (var optSet in variantCallingOptionDict[key])
                {
                    if (!parsingMethods.ContainsKey(key))
                    {
                        parsingMethods.Add(key, new OptionSet());
                    }

                    parsingMethods[key].Add(optSet);
                }
            }
        }
Пример #21
0
        public void VarCallsBecomeRefsAndNulls()
        {
            var originalVcfVariant  = TestHelper.CreateDummyAllele("chr1", 123, "A", "T", 1000, 156);
            var originalVcfVariant2 = TestHelper.CreateDummyAllele("chr1", 124, "A", "T", 1000, 156);
            var vs1 = new VariantSite(originalVcfVariant);
            var vs2 = new VariantSite(originalVcfVariant2);

            var vcParams = new VariantCallingParameters();

            vcParams.Validate();
            var caller = new VariantCaller(vcParams, new BamFilterParameters());

            //since there is an alt at position 124 ( a call of 156 alt / 1000 total, that means 844 original ref calls.
            //Of which we said, 100 will get sucked up. So that leaves 744 / 1000 calls for a reference.
            //So, we can still make a confident ref call.

            var nbhd = new VcfNeighborhood(vcParams, 0, "chr1", vs1, vs2, "");

            nbhd.SetRangeOfInterest();
            nbhd.AddAcceptedPhasedVariant(
                new CalledAllele(AlleleCategory.Snv)
            {
                Chromosome        = "chr1",
                ReferencePosition = 123,
                ReferenceAllele   = "A",
                AlternateAllele   = "T",
                VariantQscore     = 100,
                TotalCoverage     = 1000,
                AlleleSupport     = 500
            });
            nbhd.UsedRefCountsLookup = new Dictionary <int, SuckedUpRefRecord>()
            {
            };

            caller.CallMNVs(nbhd);
            caller.CallRefs(nbhd);

            var acceptedMNVs = nbhd.CalledVariants;
            var acceptedRefs = nbhd.CalledRefs;

            Assert.Equal(1, acceptedMNVs.Count);
            Assert.Equal(1, acceptedMNVs[123].Count);

            Assert.Equal(2, acceptedRefs.Count);


            var vcfVariant2asRef = new VcfVariant()
            {
                ReferenceName     = "chr1",
                ReferencePosition = 124,
                ReferenceAllele   = "A",
                VariantAlleles    = new[] { "." },
                Genotypes         = new List <Dictionary <string, string> >()
                {
                    new Dictionary <string, string>()
                    {
                        { "GT", "0/." }, { "DP", "1000" }, { "AD", "844" }
                    }
                },
            };

            VcfMergerTests.CheckVariantsMatch(originalVcfVariant, acceptedMNVs[123][0]);
            VcfMergerTests.CheckVariantsMatch(vcfVariant2asRef, acceptedRefs[124]);

            // If one has been sucked up and there are refs remaining, we should output it as a ref.
            var suckedUpRefRecord100 = new SuckedUpRefRecord()
            {
                Counts = 100, AlleleThatClaimedIt = new CalledAllele()
            };

            nbhd.UsedRefCountsLookup = new Dictionary <int, SuckedUpRefRecord>()
            {
                { 124, suckedUpRefRecord100 }
            };


            caller.CallMNVs(nbhd);
            caller.CallRefs(nbhd);

            acceptedMNVs = nbhd.CalledVariants;
            acceptedRefs = nbhd.CalledRefs;

            Assert.Equal(1, acceptedMNVs.Count);
            Assert.Equal(1, acceptedMNVs[123].Count);

            Assert.Equal(2, acceptedRefs.Count);

            vcfVariant2asRef = new VcfVariant()
            {
                ReferenceName     = "chr1",
                ReferencePosition = 124,
                ReferenceAllele   = "A",
                VariantAlleles    = new[] { "." },
                Genotypes         = new List <Dictionary <string, string> >()
                {
                    new Dictionary <string, string>()
                    {
                        { "GT", "0/." }, { "DP", "1000" }, { "AD", "744" }
                    }
                },
            };

            VcfMergerTests.CheckVariantsMatch(originalVcfVariant, acceptedMNVs[123][0]);
            VcfMergerTests.CheckVariantsMatch(vcfVariant2asRef, acceptedRefs[124]);


            // If one has been sucked up all the way
            // we should output it as a null.
            var suckedUpRefRecord1000 = new SuckedUpRefRecord()
            {
                Counts = 1000, AlleleThatClaimedIt = new CalledAllele()
            };

            nbhd.UsedRefCountsLookup = new Dictionary <int, SuckedUpRefRecord>()
            {
                { 124, suckedUpRefRecord1000 }
            };

            caller.CallMNVs(nbhd);
            caller.CallRefs(nbhd);

            acceptedMNVs = nbhd.CalledVariants;
            acceptedRefs = nbhd.CalledRefs;

            Assert.Equal(1, acceptedMNVs.Count);
            Assert.Equal(1, acceptedMNVs[123].Count);

            Assert.Equal(2, acceptedRefs.Count);

            var vcfVariant2asNull = new VcfVariant()
            {
                ReferenceName     = "chr1",
                ReferencePosition = 124,
                ReferenceAllele   = "A",
                VariantAlleles    = new[] { "." },
                Genotypes         = new List <Dictionary <string, string> >()
                {
                    new Dictionary <string, string>()
                    {
                        { "GT", "./." }, { "DP", "1000" }, { "AD", "0" }
                    }
                },
            };

            VcfMergerTests.CheckVariantsMatch(originalVcfVariant, acceptedMNVs[123][0]);
            VcfMergerTests.CheckVariantsMatch(vcfVariant2asNull, acceptedRefs[124]);
        }
        public static Dictionary <string, OptionSet> GetVariantCallingParsingMethods(VariantCallingParameters options)
        {
            var variantCallingOps = new OptionSet
            {
                {
                    "minvq|minvariantqscore=",
                    OptionTypes.INT + " MinimumVariantQScore to report variant",
                    value => options.MinimumVariantQScore = int.Parse(value)
                },
                {
                    "c|mindp|mindepth|mincoverage=",
                    OptionTypes.INT + " Minimum depth to call a variant",
                    value => options.MinimumCoverage = int.Parse(value)
                },
                {
                    "minvf|minimumvariantfrequency|minimumfrequency=",
                    OptionTypes.FLOAT + " MinimumFrequency to call a variant",
                    value => options.MinimumFrequency = float.Parse(value)
                },
                {
                    "targetlodfrequency|targetvf=",
                    OptionTypes.FLOAT + " Target Frequency to call a variant. Ie, to target a 5% allele frequency, we must call down to 2.6%, to capture that 5% allele 95% of the time. This parameter is used by the Somatic Genotyping Model",
                    value => options.TargetLODFrequency = float.Parse(value)
                },
                {
                    "vqfilter|variantqualityfilter=",
                    OptionTypes.INT + " FilteredVariantQScore to report variant as filtered",
                    value => options.MinimumVariantQScoreFilter = int.Parse(value)
                },
                {
                    "vffilter|minvariantfrequencyfilter=",
                    OptionTypes.FLOAT + " FilteredVariantFrequency to report variant as filtered",
                    value => options.MinimumFrequencyFilter = float.Parse(value)
                },
                {
                    "gqfilter|genotypequalityfilter=",
                    OptionTypes.INT + " Filtered Genotype quality to report variant as filtered",
                    value => options.LowGenotypeQualityFilter = int.Parse(value)
                },
                {
                    "repeatfilter_ToBeRetired=",
                    OptionTypes.INT + " FilteredIndelRepeats to report variant as filtered. To be retired. Please transition to RMxN.",
                    value => options.IndelRepeatFilter = int.Parse(value)
                },
                {
                    "mindpfilter|mindepthfilter=",
                    OptionTypes.INT + " FilteredLowDepth to report variant as filtered",
                    value => options.LowDepthFilter = int.Parse(value)
                },
                {
                    "ssfilter|enablesinglestrandfilter=",
                    OptionTypes.BOOL + " Flag variants as filtered if coverage limited to one strand",
                    value => options.FilterOutVariantsPresentOnlyOneStrand = bool.Parse(value)
                },
                {
                    "nl|noiselevelforqmodel=",
                    OptionTypes.INT + " Overrides the noise level to used by the quality model with this value. By default, this is driven by the basecall filter.",
                    value => options.ForcedNoiseLevel = int.Parse(value)
                },
                {
                    "ploidy=",
                    OptionTypes.STRING + $" 'somatic' or 'diploid'. default, {options.PloidyModel}. To test drive the new adaptive model, try 'DiploidByAdaptiveGT' ",
                    value => options.PloidyModel = ConvertToPloidy(value)
                },
                {
                    "diploidsnvgenotypeparameters=",
                    OptionTypes.STRING + " A,B,C. default " + options.DiploidSNVThresholdingParameters.ToString(),
                    value => options.DiploidSNVThresholdingParameters = ConvertToDiploidThresholding(value)
                },
                {
                    "diploidindelgenotypeparameters=",
                    OptionTypes.STRING + " A,B,C. default " + options.DiploidINDELThresholdingParameters.ToString(),
                    value => options.DiploidINDELThresholdingParameters = ConvertToDiploidThresholding(value)
                },
                {
                    "adaptivegenotypeparameters_fromfile=",
                    OptionTypes.PATH + " file name. default, none.",
                    value => options.AdaptiveGenotypingParameters = UpdateAdaptiveGenotypingParameters(options.AdaptiveGenotypingParameters, value)
                },
                {
                    "adaptivegenotypeparameters_snvmodel=",
                    OptionTypes.STRING + " A,B,C. default " + OptionHelpers.ListOfParamsToDelimiterSeparatedString(options.AdaptiveGenotypingParameters.SnvModel),
                    value => options.AdaptiveGenotypingParameters.SnvModel = ConvertToAdaptiveGenotypingParameters(value)
                },
                {
                    "adaptivegenotypeparameters_indelmodel=",
                    OptionTypes.STRING + " A,B,C. default " + OptionHelpers.ListOfParamsToDelimiterSeparatedString(options.AdaptiveGenotypingParameters.IndelModel),
                    value => options.AdaptiveGenotypingParameters.IndelModel = ConvertToAdaptiveGenotypingParameters(value)
                },
                {
                    "adaptivegenotypeparameters_snvprior=",
                    OptionTypes.STRING + " A,B,C. default " + OptionHelpers.ListOfParamsToDelimiterSeparatedString(options.AdaptiveGenotypingParameters.SnvPrior),
                    value => options.AdaptiveGenotypingParameters.SnvPrior = ConvertToAdaptiveGenotypingParameters(value)
                },
                {
                    "adaptivegenotypeparameters_indelprior=",
                    OptionTypes.STRING + " A,B,C. default " + OptionHelpers.ListOfParamsToDelimiterSeparatedString(options.AdaptiveGenotypingParameters.IndelPrior),
                    value => options.AdaptiveGenotypingParameters.IndelPrior = ConvertToAdaptiveGenotypingParameters(value)
                },
                {
                    "sbmodel=",
                    OptionTypes.STRING + " ",
                    value => options.StrandBiasModel = ConvertToStrandBiasModel(value)
                },
                {
                    "maxvq|maxvariantqscore=",
                    OptionTypes.INT + " MaximumVariantQScore to cap output variant Qscores. Default, " + options.MaximumVariantQScore,
                    value => options.MaximumVariantQScore = int.Parse(value)
                },
                {
                    "maxgq|maxgenotypeqscore=",
                    OptionTypes.INT + " Maximum genotype QScore to cap output genotype Qscores. Default, " + options.MaximumGenotypeQScore,
                    value => options.MaximumGenotypeQScore = int.Parse(value)
                },
                {
                    "maxgp|maxgenotypeposteriorscore=",
                    OptionTypes.INT + " Maximum genotype posterior score to cap output genotype posteriors. Default, " + options.AdaptiveGenotypingParameters.MaxGenotypePosteriors,
                    value => options.AdaptiveGenotypingParameters.MaxGenotypePosteriors = int.Parse(value)
                },
                {
                    "mingq|mingenotypeqscore=",
                    OptionTypes.INT + " Minimum genotype QScore to cap output genotype Qscores. Default, " + options.MinimumGenotypeQScore,
                    value => options.MinimumGenotypeQScore = int.Parse(value)
                },
                {
                    "sbfilter|maxacceptablestrandbiasfilter=",
                    OptionTypes.FLOAT + " Strand bias cutoff. Default, " + options.StrandBiasAcceptanceCriteria,
                    value => options.StrandBiasAcceptanceCriteria = float.Parse(value)
                },
                {
                    "noisemodel=",
                    OptionTypes.STRING + $" Window/Flat. Default {options.NoiseModel}",
                    value => options.NoiseModel = value.ToLower() == "window" ? NoiseModel.Window : NoiseModel.Flat
                },
                {
                    "gender=",
                    OptionTypes.BOOL + " Gender of the sample, if known. Male=TRUE, Female=FALSE . Default, unset.",
                    value => options.IsMale = value.ToLower() == "male"
                },
                {
                    "rmxnfilter=",
                    OptionTypes.STRING + " M,N,F. Comma-separated list of integers indicating max length of the repeat section (M), the minimum number of repetitions of that repeat (N), to be applied if the variant frequency is less than (F). Default is R5x9,F=20.",
                    value => ParseRMxNFilter(value, ref options.RMxNFilterMaxLengthRepeat, ref options.RMxNFilterMinRepetitions, ref options.RMxNFilterFrequencyLimit)
                },
                {
                    "ncfilter=",
                    OptionTypes.FLOAT + " No-call rate filter",
                    value => options.NoCallFilterThreshold = float.Parse(value)
                },
                {
                    "abfilter=",
                    OptionTypes.FLOAT +
                    " Amplicon bias filter threshold. By default, this filter is off. If on, the threshold has the following meaning: " +
                    " If a variant shows up at Y percent on amplicon A and X percent on amplicon B, the X observation must be at least as probable as the Amplicon bias filter threshold, using the observations of Y as frequency estimate. " +
                    " To turn on, set to a positive float. '0.01' seems to work well. ",
                    value => options.AmpliconBiasFilterThreshold = ParseAmpliconBiasFilter(value, options.AmpliconBiasFilterThreshold)

                                                                   //tjd+ - remember to change the help text when we update the deafult to 'on, 0.01'
                                                                   // "Default value of the threshold is " + options.AmpliconBiasFilterThreshold + ". Set to FALSE to turn off entirely. Set to TRUE is equivalent to omitting this 'abfilter' argument entirely, and invokes the default vaules. If any reads are found without an amplicon name (no XN tag) this feature automatically shutts off." ,
                                                                   //" Amplicon bias filter threshold. By default, if a variant shows up at Y percent on amplicon A and X percent on amplicon B, the X observation must be at least as probable as the Amplicon bias filter threshold, using the observations of Y as frequency estimate. " +
                                                                   //tjd-
                }
            };


            var optionDict = new Dictionary <string, OptionSet>
            {
                { OptionSetNames.VariantCalling, variantCallingOps },
            };


            return(optionDict);
        }