コード例 #1
0
        public void Equality_Reference()
        {
            // happy path
            var chromosome       = "chr1";
            var coordinate       = 1;
            var reference        = "A";
            var alternate        = "A";
            var candidateVariant = new CandidateAllele(chromosome, coordinate, reference, alternate, AlleleCategory.Reference);
            var otherVariant     = new CandidateAllele(chromosome, coordinate, reference, alternate, AlleleCategory.Reference);

            Assert.True(candidateVariant.Equals(otherVariant));

            // error conditions
            otherVariant = new CandidateAllele("chrX", coordinate, reference, alternate, AlleleCategory.Reference);            // different chrom
            Assert.False(candidateVariant.Equals(otherVariant));
            otherVariant = new CandidateAllele(chromosome, 9999, reference, alternate, AlleleCategory.Reference);              // different coord
            Assert.False(candidateVariant.Equals(otherVariant));
            otherVariant = new CandidateAllele(chromosome, coordinate, "XYZ", alternate, AlleleCategory.Reference);            // different reference
            Assert.False(candidateVariant.Equals(otherVariant));
            otherVariant = new CandidateAllele(chromosome, coordinate, reference, "XYZ", AlleleCategory.Reference);            // different alt
            Assert.False(candidateVariant.Equals(otherVariant));
            var otherVariantInsertion = new CandidateAllele(chromosome, coordinate, reference, alternate, AlleleCategory.Mnv); // different variant type

            Assert.False(candidateVariant.Equals(otherVariantInsertion));
            otherVariant = null;
            Assert.False(candidateVariant.Equals(otherVariant));
        }
コード例 #2
0
        public void Constructor_MNV()
        {
            // happy path
            var chromosome       = "chr1";
            var coordinate       = 1;
            var reference        = "ATC";
            var alternate        = "GAA";
            var candidateVariant = new CandidateAllele(chromosome, coordinate, reference, alternate, AlleleCategory.Mnv);

            Assert.Equal(chromosome, candidateVariant.Chromosome);
            Assert.Equal(coordinate, candidateVariant.ReferencePosition);
            Assert.Equal(reference, candidateVariant.ReferenceAllele);
            Assert.Equal(alternate, candidateVariant.AlternateAllele);
            //Verify Length
            Assert.Equal(3, candidateVariant.Length);

            // error conditions
            // chromosome name
            Assert.Throws <ArgumentException>(() => new CandidateAllele("", coordinate, reference, alternate, AlleleCategory.Mnv));
            Assert.Throws <ArgumentException>(() => new CandidateAllele(null, coordinate, reference, alternate, AlleleCategory.Mnv));
            // coordinate
            Assert.Throws <ArgumentException>(() => new CandidateAllele(chromosome, -1, reference, alternate, AlleleCategory.Mnv));
            // reference
            Assert.Throws <ArgumentException>(() => new CandidateAllele(chromosome, coordinate, "", alternate, AlleleCategory.Mnv));
            Assert.Throws <ArgumentException>(() => new CandidateAllele(chromosome, coordinate, null, alternate, AlleleCategory.Mnv));
            // alternate
            Assert.Throws <ArgumentException>(() => new CandidateAllele(chromosome, coordinate, reference, "", AlleleCategory.Mnv));
            Assert.Throws <ArgumentException>(() => new CandidateAllele(chromosome, coordinate, reference, null, AlleleCategory.Mnv));
        }
コード例 #3
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());
        }
コード例 #4
0
        public static CalledAllele Map(CandidateAllele candidate)
        {
            /*
             * var calledAllele = candidate.Type == AlleleCategory.Reference
             *  ? (BaseCalledAllele)new BaseCalledAllele()
             *  : new BaseCalledAllele(candidate.Type);
             */

            var calledAllele = new CalledAllele(candidate.Type);

            calledAllele.Alternate     = candidate.Alternate;
            calledAllele.Reference     = candidate.Reference;
            calledAllele.Chromosome    = candidate.Chromosome;
            calledAllele.Coordinate    = candidate.Coordinate;
            calledAllele.AlleleSupport = candidate.Support;
            Array.Copy(candidate.SupportByDirection, calledAllele.SupportByDirection, candidate.SupportByDirection.Length);

            if (candidate.Type != AlleleCategory.Reference)
            {
                for (var i = 0; i < candidate.ReadCollapsedCounts.Length; i++)
                {
                    calledAllele.ReadCollapsedCounts[i] = candidate.ReadCollapsedCounts[i];
                }
            }
            return(calledAllele);
        }
コード例 #5
0
        public void CreateAndAdd()
        {
            var candidates = new List <CandidateAllele>()
            {
                new CandidateAllele("chr1", 100, "A", "AT", AlleleCategory.Insertion),
                new CandidateAllele("chr1", 100, "A", "A", AlleleCategory.Reference),
                new CandidateAllele("chr1", 100, "A", "T", AlleleCategory.Snv),
                new CandidateAllele("chr1", 200, "A", "T", AlleleCategory.Mnv)
            };

            var batch           = new CandidateBatch(candidates);
            var batchCandidates = batch.GetCandidates();

            Assert.Equal(4, batchCandidates.Count);
            foreach (var candidate in candidates)
            {
                Assert.True(batchCandidates.Contains(candidate));
            }

            // add new candidate
            var newCandidate = new CandidateAllele("chr1", 200, "AT", "A", AlleleCategory.Deletion);

            batch.Add(new List <CandidateAllele>()
            {
                newCandidate
            });

            Assert.Equal(5, batchCandidates.Count);
            Assert.True(batchCandidates.Contains(newCandidate));
        }
コード例 #6
0
        /// <summary>
        /// Create a new candidate allele from alignment and add support.  Exposed only for unit testing.
        /// </summary>
        /// <param name="type"></param>
        /// <param name="chromosome"></param>
        /// <param name="coordinate"></param>
        /// <param name="reference"></param>
        /// <param name="alternate"></param>
        /// <param name="alignment"></param>
        /// <param name="startIndexInRead"></param>
        /// <returns></returns>
        public static CandidateAllele Create(AlleleCategory type, string chromosome, int coordinate, string reference,
                                             string alternate, Read alignment, int startIndexInRead)
        {
            var candidate = new CandidateAllele(chromosome, coordinate, reference, alternate, type);
            var alleleSupportDirection = GetSupportDirection(candidate, alignment, startIndexInRead);

            candidate.SupportByDirection[(int)alleleSupportDirection]++;

            if (alignment.IsDuplex)
            {
                if (alleleSupportDirection == DirectionType.Stitched)
                {
                    candidate.ReadCollapsedCounts[(int)ReadCollapsedType.DuplexStitched]++;
                }
                else
                {
                    candidate.ReadCollapsedCounts[(int)ReadCollapsedType.DuplexNonStitched]++;
                }
            }
            else
            {
                if (alleleSupportDirection == DirectionType.Stitched)
                {
                    candidate.ReadCollapsedCounts[(int)ReadCollapsedType.SimplexStitched]++;
                }
                else
                {
                    candidate.ReadCollapsedCounts[(int)ReadCollapsedType.SimplexNonStitched]++;
                }
            }
            return(candidate);
        }
コード例 #7
0
        public Dictionary <SomaticVariantType, List <VariantSite> > FindVariantSites(Read read, string chromosomeName)
        {
            var pseudoRefChromosome = new string('R', (int)read.CigarData.GetReferenceSpan() + 100);
            var dict = new Dictionary <SomaticVariantType, List <VariantSite> >()
            {
                { SomaticVariantType.Deletion, new List <VariantSite>() },
                { SomaticVariantType.SNP, new List <VariantSite>() },
                { SomaticVariantType.Insertion, new List <VariantSite>() }
            };

            var startIndexInRead            = 0;
            var startIndexInPseudoReference = 1;

            for (var cigarOpIndex = 0; cigarOpIndex < read.CigarData.Count; cigarOpIndex++)
            {
                var             operation = read.CigarData[cigarOpIndex];
                CandidateAllele candidate = null;
                var             type      = SomaticVariantType.SNP;
                var             found     = false;
                switch (operation.Type)
                {
                case 'I':
                    candidate = ExtractInsertionFromOperation(read, pseudoRefChromosome, startIndexInRead, operation.Length, startIndexInPseudoReference, chromosomeName);
                    type      = SomaticVariantType.Insertion;
                    found     = true;
                    break;

                case 'D':
                    candidate = ExtractDeletionFromOperation(read, pseudoRefChromosome, startIndexInRead, operation.Length, startIndexInPseudoReference, chromosomeName);
                    type      = SomaticVariantType.Deletion;
                    found     = true;
                    break;

                case 'M':
                    candidate = ExtractGappedMnv(read, pseudoRefChromosome, startIndexInRead, (int)operation.Length,
                                                 startIndexInPseudoReference, chromosomeName);
                    type  = SomaticVariantType.SNP;
                    found = true;
                    break;
                }

                if (found)
                {
                    dict[type].Add(MapCandidateVariant(read.Position, candidate, candidate == null, startIndexInPseudoReference));
                }

                if (operation.IsReadSpan())
                {
                    startIndexInRead += (int)operation.Length;
                }

                if (operation.IsReferenceSpan())
                {
                    startIndexInPseudoReference += (int)operation.Length;
                }
            }

            return(dict);
        }
コード例 #8
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
        }
コード例 #9
0
        private CandidateAllele Map(BaseCalledAllele called)
        {
            var candidateAllele = new CandidateAllele(called.Chromosome, called.Coordinate, called.Reference,
                                                      called.Alternate, called.Type);

            Array.Copy(called.SupportByDirection, candidateAllele.SupportByDirection, called.SupportByDirection.Length);

            return(candidateAllele);
        }
コード例 #10
0
        public void AddCandidate(CandidateAllele candidate, bool trackOpenEnded = false)
        {
            if (candidate.Type == AlleleCategory.Reference)
            {
                throw new ArgumentException(string.Format("Unable to add candidate '{0}': reference candidates are not tracked.", candidate));
            }

            if (!IsPositionInRegion(candidate.Coordinate))
            {
                throw new ArgumentException(string.Format("Unable to add candidate at position {0} to region '{1}'",
                                                          candidate.Coordinate, Name));
            }

            var regionIndex        = candidate.Coordinate - StartPosition;
            var existingCandidates = _candidateVariantsLookup[regionIndex];

            if (existingCandidates == null)
            {
                _candidateVariantsLookup[regionIndex] = new List <CandidateAllele> {
                    candidate
                }
            }
            ;
            else
            {
                //TJD - this used to be a hash table, not a find,
                //where each variants unique signature was the key.
                //this might be why we have seen a performance hit in the new pisces.

                var foundAtIndex = trackOpenEnded ?
                                   existingCandidates.FindIndex(c => c.Equals(candidate) &&
                                                                c.OpenOnLeft == candidate.OpenOnLeft &&
                                                                c.OpenOnRight == candidate.OpenOnRight) :
                                   existingCandidates.FindIndex(c => c.Equals(candidate));

                if (foundAtIndex == -1)
                {
                    existingCandidates.Add(candidate);
                }
                else
                {
                    var existingMatch = existingCandidates[foundAtIndex];

                    for (var i = 0; i < existingMatch.SupportByDirection.Length; i++)
                    {
                        existingMatch.SupportByDirection[i] += candidate.SupportByDirection[i];
                    }

                    for (var i = 0; i < existingMatch.ReadCollapsedCounts.Length; i++)
                    {
                        existingMatch.ReadCollapsedCounts[i] += candidate.ReadCollapsedCounts[i];
                    }
                }
            }

            UpdateMaxPosition(candidate);
        }
コード例 #11
0
        /// <summary>
        /// Create a new candidate allele from alignment and add support.  Exposed only for unit testing.
        /// </summary>
        /// <param name="type"></param>
        /// <param name="chromosome"></param>
        /// <param name="coordinate"></param>
        /// <param name="reference"></param>
        /// <param name="alternate"></param>
        /// <param name="alignment"></param>
        /// <param name="startIndexInRead"></param>
        /// <returns></returns>
        public static CandidateAllele Create(AlleleCategory type, string chromosome, int coordinate, string reference,
                                             string alternate, Read alignment, int startIndexInRead)
        {
            var candidate = new CandidateAllele(chromosome, coordinate, reference, alternate, type);

            candidate.SupportByDirection[(int)GetSupportDirection(candidate, alignment, startIndexInRead)]++;

            return(candidate);
        }
コード例 #12
0
        /// <summary>
        /// Get the support direction at a particular point in a read, for a given candidate.  Exposed only for unit testing.
        /// </summary>
        /// <param name="candidate"></param>
        /// <param name="bamAlignment"></param>
        /// <param name="startIndexInRead"></param>
        /// <returns></returns>
        public static DirectionType GetSupportDirection(CandidateAllele candidate, Read bamAlignment, int startIndexInRead)
        {
            if (candidate.Type == AlleleCategory.Snv || candidate.Type == AlleleCategory.Reference)
            {
                return(bamAlignment.SequencedBaseDirectionMap[startIndexInRead]);
            }

            var leftAnchorIndex  = startIndexInRead - 1;
            var rightAnchorIndex = candidate.Type == AlleleCategory.Deletion ? startIndexInRead : startIndexInRead + candidate.Length;
            var lastIndex        = bamAlignment.Sequence.Length - 1;

            if (rightAnchorIndex == 0)
            {
                return(bamAlignment.SequencedBaseDirectionMap[rightAnchorIndex]);
            }
            if (leftAnchorIndex == lastIndex) // this should only happen for deletion at the end
            {
                return(bamAlignment.SequencedBaseDirectionMap[lastIndex]);
            }

            if (leftAnchorIndex == rightAnchorIndex - 1)  // for deletions
            {
                if (bamAlignment.CigarDirections != null)
                {
                    return(GetDeletionDirectionForStitchedRead(bamAlignment, leftAnchorIndex, rightAnchorIndex));
                }

                //fall back to old method if we were not tracking directions "inside" deletions.
                var startDirection = bamAlignment.SequencedBaseDirectionMap[leftAnchorIndex];
                var endDirection   = bamAlignment.SequencedBaseDirectionMap[rightAnchorIndex];

                //GB: why do we preferentially do this, below?
                //TD: I believe its arbitrary and also it is what we always used to do.So any changes here would have unknown affects. I think the original point was, if all else fails, at least be predictable.
                return(startDirection == DirectionType.Stitched ? endDirection : startDirection);
            }

            DirectionType direction = DirectionType.Forward;

            // otherwise, walk through and if any direction between anchor points is stitched, return stitched
            for (var i = leftAnchorIndex + 1; i < rightAnchorIndex; i++)
            {
                direction = bamAlignment.SequencedBaseDirectionMap[i];
                if (direction == DirectionType.Stitched)
                {
                    return(DirectionType.Stitched);
                }
            }

            // sanity check that we didn't magically transition from F/R or R/F without stitched region
            if (bamAlignment.SequencedBaseDirectionMap[leftAnchorIndex + 1] != bamAlignment.SequencedBaseDirectionMap[rightAnchorIndex - 1])
            {
                throw new InvalidDataException("Alignment error: Found change in direction without encountering stitched direction");
            }

            return(direction);
        }
コード例 #13
0
        private VariantSite MapCandidateVariant(int readPosition, CandidateAllele allele, bool failed, int refPosition)
        {
            var positionAdjustment = failed ? refPosition : allele.Coordinate;

            var position = readPosition - 2 + positionAdjustment;

            return(new VariantSite(position)
            {
                VcfReferenceAllele = failed ? "N" : allele.Reference,
                VcfAlternateAllele = failed ? "N" : allele.Alternate
            });
        }
コード例 #14
0
        private IEnumerable <CandidateAllele> CreateCandidateAlleleFromForceAlleles(int position, List <Tuple <string, string> > forcedAlleles)
        {
            var candidates = new List <CandidateAllele>();

            foreach (var forcedAllele in forcedAlleles)
            {
                var category        = GetAlleleCategory(forcedAllele.Item1, forcedAllele.Item2);
                var candidateAllele = new CandidateAllele(_chrReference.Name, position, forcedAllele.Item1, forcedAllele.Item2, category);
                candidates.Add(candidateAllele);
            }
            return(candidates);
        }
コード例 #15
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);
        }
コード例 #16
0
        private BaseCalledAllele Map(CandidateAllele candidate)
        {
            var calledAllele = candidate.Type == AlleleCategory.Reference
                ? (BaseCalledAllele) new CalledReference()
                : new CalledVariant(candidate.Type);

            calledAllele.Alternate     = candidate.Alternate;
            calledAllele.Reference     = candidate.Reference;
            calledAllele.Chromosome    = candidate.Chromosome;
            calledAllele.Coordinate    = candidate.Coordinate;
            calledAllele.AlleleSupport = candidate.Support;
            Array.Copy(candidate.SupportByDirection, calledAllele.SupportByDirection, candidate.SupportByDirection.Length);

            return(calledAllele);
        }
コード例 #17
0
 private bool MatchVariants(BaseCalledAllele calledVariant, CandidateAllele candidateVariant, int?expectedSupport = null, float?expectedFreq = null)
 {
     if (calledVariant.Chromosome == candidateVariant.Chromosome &&
         calledVariant.Coordinate == candidateVariant.Coordinate &&
         calledVariant.Reference == candidateVariant.Reference &&
         calledVariant.Alternate == candidateVariant.Alternate &&
         calledVariant.Type == candidateVariant.Type &&
         (expectedFreq == null || calledVariant.Frequency == expectedFreq) &&
         (expectedSupport == null || calledVariant.AlleleSupport == expectedSupport)
         )
     {
         return(true);
     }
     return(false);
 }
コード例 #18
0
 private bool MatchVariants(CalledAllele BaseCalledAllele, CandidateAllele candidateVariant, int?expectedSupport = null, float?expectedFreq = null)
 {
     if (BaseCalledAllele.Chromosome == candidateVariant.Chromosome &&
         BaseCalledAllele.ReferencePosition == candidateVariant.ReferencePosition &&
         BaseCalledAllele.ReferenceAllele == candidateVariant.ReferenceAllele &&
         BaseCalledAllele.AlternateAllele == candidateVariant.AlternateAllele &&
         BaseCalledAllele.Type == candidateVariant.Type &&
         (expectedFreq == null || BaseCalledAllele.Frequency == expectedFreq) &&
         (expectedSupport == null || BaseCalledAllele.AlleleSupport == expectedSupport)
         )
     {
         return(true);
     }
     return(false);
 }
コード例 #19
0
        /// <summary>
        /// Get the support direction at a particular point in a read, for a given candidate.  Exposed only for unit testing.
        /// </summary>
        /// <param name="candidate"></param>
        /// <param name="bamAlignment"></param>
        /// <param name="startIndexInRead"></param>
        /// <returns></returns>
        public static DirectionType GetSupportDirection(CandidateAllele candidate, Read bamAlignment, int startIndexInRead)
        {
            if (candidate.Type == AlleleCategory.Snv || candidate.Type == AlleleCategory.Reference)
            {
                return(bamAlignment.SequencedBaseDirectionMap[startIndexInRead]);
            }

            var leftAnchorIndex  = startIndexInRead - 1;
            var rightAnchorIndex = candidate.Type == AlleleCategory.Deletion ? startIndexInRead : startIndexInRead + candidate.Length;
            var lastIndex        = bamAlignment.Sequence.Length - 1;

            if (rightAnchorIndex == 0)
            {
                return(bamAlignment.SequencedBaseDirectionMap[rightAnchorIndex]);
            }
            if (leftAnchorIndex == lastIndex) // this should only happen for deletion at the end
            {
                return(bamAlignment.SequencedBaseDirectionMap[lastIndex]);
            }

            if (leftAnchorIndex == rightAnchorIndex - 1)  // for deletions
            {
                var startDirection = bamAlignment.SequencedBaseDirectionMap[leftAnchorIndex];
                var endDirection   = bamAlignment.SequencedBaseDirectionMap[rightAnchorIndex];

                return(startDirection == DirectionType.Stitched ? endDirection : startDirection);
            }

            DirectionType direction = DirectionType.Forward;

            // otherwise, walk through and if any direction between anchor points is stitched, return stitched
            for (var i = leftAnchorIndex + 1; i < rightAnchorIndex; i++)
            {
                direction = bamAlignment.SequencedBaseDirectionMap[i];
                if (direction == DirectionType.Stitched)
                {
                    return(DirectionType.Stitched);
                }
            }

            // sanity check that we didn't magically transition from F/R or R/F without stitched region
            if (bamAlignment.SequencedBaseDirectionMap[leftAnchorIndex + 1] != bamAlignment.SequencedBaseDirectionMap[rightAnchorIndex - 1])
            {
                throw new Exception("Found change in direction without encountering stitched direction");
            }

            return(direction);
        }
コード例 #20
0
        public static CandidateAllele Map(CalledAllele called)
        {
            var candidateAllele = new CandidateAllele(called.Chromosome, called.Coordinate, called.Reference,
                                                      called.Alternate, called.Type);

            Array.Copy(called.SupportByDirection, candidateAllele.SupportByDirection, called.SupportByDirection.Length);

            if (called.Type != AlleleCategory.Reference)
            {
                for (var i = 0; i < called.ReadCollapsedCounts.Length; i++)
                {
                    candidateAllele.ReadCollapsedCounts[i] = called.ReadCollapsedCounts[i];
                }
            }

            return(candidateAllele);
        }
コード例 #21
0
ファイル: RegionState.cs プロジェクト: gwennberry/Pisces
        public void AddCandidate(CandidateAllele candidate)
        {
            if (candidate.Type == AlleleCategory.Reference)
            {
                throw new ArgumentException(string.Format("Unable to add candidate '{0}': reference candidates are not tracked.", candidate));
            }

            if (!IsPositionInRegion(candidate.Coordinate))
            {
                throw new ArgumentException(string.Format("Unable to add candidate at position {0} to region '{1}'",
                                                          candidate.Coordinate, Name));
            }

            var regionIndex        = candidate.Coordinate - StartPosition;
            var existingCandidates = _candidateVariantsLookup[regionIndex];

            if (existingCandidates == null)
            {
                _candidateVariantsLookup[regionIndex] = new List <CandidateAllele>()
                {
                    candidate
                }
            }
            ;
            else
            {
                var foundAtIndex = existingCandidates.IndexOf(candidate);
                if (foundAtIndex == -1)
                {
                    existingCandidates.Add(candidate);
                }
                else
                {
                    var existingMatch = existingCandidates[foundAtIndex];

                    for (var i = 0; i < existingMatch.SupportByDirection.Length; i++)
                    {
                        existingMatch.SupportByDirection[i] += candidate.SupportByDirection[i];
                    }
                }
            }

            UpdateMaxPosition(candidate);
        }
コード例 #22
0
        public void CandidateAllele_IsFullyAnchored()
        {
            var candidateVariant = new CandidateAllele("chr1", 1, "AGC", "AGCTACT", AlleleCategory.Insertion);

            candidateVariant.OpenOnLeft  = true;
            candidateVariant.OpenOnRight = true;
            Assert.False(candidateVariant.FullyAnchored);

            candidateVariant.OpenOnLeft  = true;
            candidateVariant.OpenOnRight = false;
            Assert.False(candidateVariant.FullyAnchored);

            candidateVariant.OpenOnLeft  = false;
            candidateVariant.OpenOnRight = true;
            Assert.False(candidateVariant.FullyAnchored);

            candidateVariant.OpenOnLeft  = false;
            candidateVariant.OpenOnRight = false;
            Assert.True(candidateVariant.FullyAnchored);
        }
コード例 #23
0
        private void UpdateMaxPosition(CandidateAllele candidate)
        {
            int otherEnd = 0;

            switch (candidate.Type)
            {
            case AlleleCategory.Deletion:
                otherEnd = candidate.ReferencePosition + candidate.ReferenceAllele.Length;
                break;

            case AlleleCategory.Insertion:
                otherEnd = candidate.ReferencePosition + 1;
                break;

            case AlleleCategory.Mnv:
                otherEnd = candidate.ReferencePosition + candidate.ReferenceAllele.Length - 1;
                break;
            }
            if (otherEnd > MaxAlleleEndpoint)
            {
                MaxAlleleEndpoint = otherEnd;
            }
        }
コード例 #24
0
        public void TestOpennessUpdates()
        {
            // The generally the openness of the variant does not change, but when
            // SNVs of opposing endedness collapse into another variant the endedness will become anchored.
            var MNVFullOpenLeft = GetBasicMNV();

            MNVFullOpenLeft.OpenOnLeft = true;
            var MNVFullOpenRight = GetBasicMNV();

            MNVFullOpenRight.OpenOnRight = true;
            var snvOpenLeft = new CandidateAllele("chr1", 12, "T", "A", AlleleCategory.Snv);

            snvOpenLeft.OpenOnLeft = true;
            var snvOpenRight = new CandidateAllele("chr1", 5, "T", "A", AlleleCategory.Snv);

            snvOpenRight.OpenOnRight = true;

            // Baseline tests
            ExecuteEndednessTest(new List <CandidateAllele>()
            {
                MNVFullOpenLeft, snvOpenLeft
            }, true, false);
            ExecuteEndednessTest(new List <CandidateAllele>()
            {
                MNVFullOpenRight, snvOpenRight
            }, false, true);

            // Collapse Tests
            ExecuteEndednessTest(new List <CandidateAllele>()
            {
                MNVFullOpenLeft, snvOpenRight
            }, false, false);
            ExecuteEndednessTest(new List <CandidateAllele>()
            {
                MNVFullOpenLeft, snvOpenRight
            }, false, false);
        }
コード例 #25
0
        public static CalledAllele Map(CandidateAllele candidate)
        {
            var calledAllele = new CalledAllele(candidate.Type);

            calledAllele.AlternateAllele     = candidate.AlternateAllele;
            calledAllele.ReferenceAllele     = candidate.ReferenceAllele;
            calledAllele.Chromosome          = candidate.Chromosome;
            calledAllele.ReferencePosition   = candidate.ReferencePosition;
            calledAllele.AlleleSupport       = candidate.Support;
            calledAllele.WellAnchoredSupport = candidate.WellAnchoredSupport;
            calledAllele.IsForcedToReport    = candidate.IsForcedAllele;

            Array.Copy(candidate.SupportByDirection, calledAllele.SupportByDirection, candidate.SupportByDirection.Length);
            Array.Copy(candidate.WellAnchoredSupportByDirection, calledAllele.WellAnchoredSupportByDirection, candidate.WellAnchoredSupportByDirection.Length);

            if (candidate.Type != AlleleCategory.Reference)
            {
                for (var i = 0; i < candidate.ReadCollapsedCountsMut.Length; i++)
                {
                    calledAllele.ReadCollapsedCountsMut[i] = candidate.ReadCollapsedCountsMut[i];
                }
            }

            if (candidate.SupportByAmplicon.AmpliconNames != null)
            {
                calledAllele.SupportByAmplicon = new Models.AmpliconCounts()
                {
                    AmpliconNames     = new string[Constants.MaxNumOverlappingAmplicons],
                    CountsForAmplicon = new int[Constants.MaxNumOverlappingAmplicons]
                };

                Array.Copy(candidate.SupportByAmplicon.AmpliconNames, calledAllele.SupportByAmplicon.AmpliconNames, candidate.SupportByAmplicon.AmpliconNames.Length);
                Array.Copy(candidate.SupportByAmplicon.CountsForAmplicon, calledAllele.SupportByAmplicon.CountsForAmplicon, candidate.SupportByAmplicon.CountsForAmplicon.Length);
            }

            return(calledAllele);
        }
コード例 #26
0
        public static CalledAllele Map(CandidateAllele candidate)
        {
            var calledAllele = new CalledAllele(candidate.Type);

            calledAllele.AlternateAllele     = candidate.AlternateAllele;
            calledAllele.ReferenceAllele     = candidate.ReferenceAllele;
            calledAllele.Chromosome          = candidate.Chromosome;
            calledAllele.ReferencePosition   = candidate.ReferencePosition;
            calledAllele.AlleleSupport       = candidate.Support;
            calledAllele.WellAnchoredSupport = candidate.WellAnchoredSupport;
            calledAllele.IsForcedToReport    = candidate.IsForcedAllele;

            Array.Copy(candidate.SupportByDirection, calledAllele.SupportByDirection, candidate.SupportByDirection.Length);
            Array.Copy(candidate.WellAnchoredSupportByDirection, calledAllele.WellAnchoredSupportByDirection, candidate.WellAnchoredSupportByDirection.Length);

            if (candidate.Type != AlleleCategory.Reference)
            {
                for (var i = 0; i < candidate.ReadCollapsedCountsMut.Length; i++)
                {
                    calledAllele.ReadCollapsedCountsMut[i] = candidate.ReadCollapsedCountsMut[i];
                }
            }
            return(calledAllele);
        }
コード例 #27
0
ファイル: AlleleHelperTests.cs プロジェクト: snashraf/Pisces
        public void MapToBaseCalledAllele()
        {
            //Called variant
            var allele = new CandidateAllele("chr1", 1, "A", "G", AlleleCategory.Snv);

            allele.SupportByDirection = new[] { 10, 20, 30 };
            var BaseCalledAllele = AlleleHelper.Map(allele);

            Assert.True(BaseCalledAllele.Type != AlleleCategory.Reference);
            Assert.Equal(BaseCalledAllele.Chromosome, allele.Chromosome);
            Assert.Equal(BaseCalledAllele.Coordinate, allele.Coordinate);
            Assert.Equal(BaseCalledAllele.Reference, allele.Reference);
            Assert.Equal(BaseCalledAllele.Alternate, allele.Alternate);
            Assert.Equal(BaseCalledAllele.Type, allele.Type);
            Assert.Equal(BaseCalledAllele.SupportByDirection.Count(), allele.SupportByDirection.Count());
            for (int i = 0; i < allele.SupportByDirection.Count(); i++)
            {
                Assert.Equal(BaseCalledAllele.SupportByDirection[i], allele.SupportByDirection[i]);
            }

            //Called reference
            allele.Type = AlleleCategory.Reference;
            var calledReference = AlleleHelper.Map(allele);

            Assert.True(calledReference.Type == AlleleCategory.Reference);
            Assert.Equal(calledReference.Chromosome, allele.Chromosome);
            Assert.Equal(calledReference.Coordinate, allele.Coordinate);
            Assert.Equal(calledReference.Reference, allele.Reference);
            Assert.Equal(calledReference.Alternate, allele.Alternate);
            Assert.Equal(calledReference.Type, allele.Type);
            Assert.Equal(calledReference.SupportByDirection.Count(), allele.SupportByDirection.Count());
            for (int i = 0; i < allele.SupportByDirection.Count(); i++)
            {
                Assert.Equal(calledReference.SupportByDirection[i], allele.SupportByDirection[i]);
            }
        }
コード例 #28
0
ファイル: RegionStateTests.cs プロジェクト: gwennberry/Pisces
        public void ExecuteTest_GetCandidates(bool withReference, bool withIntervals)
        {
            var testRegion   = new RegionState(1, 50);
            var chrReference = new ChrReference()
            {
                Name     = "chr1",
                Sequence = string.Concat(Enumerable.Repeat("A", 50))
            };
            var snv1 = new CandidateAllele("chr1", 5, "A", "T", AlleleCategory.Snv)
            {
                SupportByDirection = new [] { 10, 5, 0 }
            };
            var snv2 = new CandidateAllele("chr1", 15, "A", "T", AlleleCategory.Snv)
            {
                SupportByDirection = new[] { 10, 5, 0 }
            };

            testRegion.AddCandidate(snv1);
            testRegion.AddCandidate(snv2);

            for (var i = 0; i < 5; i++)
            {
                testRegion.AddAlleleCount(5, AlleleType.A, DirectionType.Stitched);  // ref @ variant position
                testRegion.AddAlleleCount(6, AlleleType.A, DirectionType.Stitched);  // ref by itself
                testRegion.AddAlleleCount(10, AlleleType.C, DirectionType.Stitched); // nonref by itself (no ref)
                testRegion.AddAlleleCount(15, AlleleType.A, DirectionType.Reverse);  // ref (multiple directions) + nonref
                testRegion.AddAlleleCount(15, AlleleType.A, DirectionType.Forward);
                testRegion.AddAlleleCount(15, AlleleType.T, DirectionType.Reverse);
            }

            ChrIntervalSet intervals = null;

            if (withIntervals)
            {
                intervals = new ChrIntervalSet(new List <CallSomaticVariants.Logic.RegionState.Region>()
                {
                    new CallSomaticVariants.Logic.RegionState.Region(3, 6),
                    new CallSomaticVariants.Logic.RegionState.Region(16, 16)
                }, "chr1");
            }
            var expectedList = new List <CandidateAllele>();

            expectedList.Add(snv1);
            expectedList.Add(snv2);

            if (withReference)
            {
                expectedList.Add(new CandidateAllele("chr1", 5, "A", "A", AlleleCategory.Reference)
                {
                    SupportByDirection = new[] { 0, 0, 5 }
                });
                expectedList.Add(new CandidateAllele("chr1", 6, "A", "A", AlleleCategory.Reference)
                {
                    SupportByDirection = new[] { 0, 0, 5 }
                });
                expectedList.Add(new CandidateAllele("chr1", 10, "A", "A", AlleleCategory.Reference)
                {
                    SupportByDirection = new[] { 0, 0, 0 }
                });
                expectedList.Add(new CandidateAllele("chr1", 15, "A", "A", AlleleCategory.Reference)
                {
                    SupportByDirection = new[] { 5, 5, 0 }
                });
            }

            if (withIntervals)
            {
                expectedList = expectedList.Where(c => c.Coordinate == 5 || c.Coordinate == 6 || c.Type != AlleleCategory.Reference).ToList();
                if (withReference)
                {
                    expectedList.Add(new CandidateAllele("chr1", 3, "A", "A", AlleleCategory.Reference)
                    {
                        SupportByDirection = new[] { 0, 0, 0 }
                    });
                    expectedList.Add(new CandidateAllele("chr1", 4, "A", "A", AlleleCategory.Reference)
                    {
                        SupportByDirection = new[] { 0, 0, 0 }
                    });
                    expectedList.Add(new CandidateAllele("chr1", 16, "A", "A", AlleleCategory.Reference)
                    {
                        SupportByDirection = new[] { 0, 0, 0 }
                    });
                }
            }
            var allCandidates = testRegion.GetAllCandidates(withReference, chrReference, intervals);

            VerifyCandidates(expectedList, allCandidates);
        }
コード例 #29
0
ファイル: RegionStateTests.cs プロジェクト: gwennberry/Pisces
        public void AddAndGetCandidates()
        {
            // -----------------------------------------------
            // simple test case adding candidate to empty region
            // -----------------------------------------------
            var testRegion = new RegionState(1000, 2000);
            var snv1       = new CandidateAllele("chr1", 1500, "A", "T", AlleleCategory.Snv)
            {
                SupportByDirection = new[] { 10, 0, 0 }
            };

            testRegion.AddCandidate(snv1);

            var allCandidates = testRegion.GetAllCandidates(false, null);

            Assert.Equal(allCandidates.Count, 1);

            var fetchedCandidate = allCandidates[0];

            Assert.True(fetchedCandidate.Equals(snv1));

            // -----------------------------------------------
            // add same type of candidate but at different position
            // -----------------------------------------------
            var snv2 = new CandidateAllele("chr1", 1501, "A", "T", AlleleCategory.Snv)
            {
                SupportByDirection = new[] { 5, 0, 0 }
            };

            testRegion.AddCandidate(snv2);

            allCandidates = testRegion.GetAllCandidates(false, null);
            Assert.Equal(allCandidates.Count, 2);

            // make sure coverage is preserved
            fetchedCandidate = allCandidates.FirstOrDefault(c => c.Equals(snv1));
            Assert.True(fetchedCandidate != null && fetchedCandidate.Support == 10);
            fetchedCandidate = allCandidates.FirstOrDefault(c => c.Equals(snv2));
            Assert.True(fetchedCandidate != null && fetchedCandidate.Support == 5);

            // -----------------------------------------------
            // add a different type of candidate at same position
            // -----------------------------------------------
            var deletion1 = new CandidateAllele("chr1", 1500, "AT", "A", AlleleCategory.Deletion)
            {
                SupportByDirection = new[] { 15, 0, 0 }
            };

            testRegion.AddCandidate(deletion1);

            allCandidates = testRegion.GetAllCandidates(false, null);
            Assert.Equal(allCandidates.Count, 3);

            // make sure coverage is preserved
            fetchedCandidate = allCandidates.FirstOrDefault(c => c.Equals(snv1));
            Assert.True(fetchedCandidate != null && fetchedCandidate.Support == 10);
            fetchedCandidate = allCandidates.FirstOrDefault(c => c.Equals(snv2));
            Assert.True(fetchedCandidate != null && fetchedCandidate.Support == 5);
            fetchedCandidate = allCandidates.FirstOrDefault(c => c.Equals(deletion1));
            Assert.True(fetchedCandidate != null && fetchedCandidate.Support == 15);

            // -----------------------------------------------
            // add same variant, but more coverage
            // -----------------------------------------------
            var moreSnv1 = new CandidateAllele("chr1", 1500, "A", "T", AlleleCategory.Snv)
            {
                SupportByDirection = new[] { 2, 0, 0 }
            };

            testRegion.AddCandidate(moreSnv1);

            allCandidates = testRegion.GetAllCandidates(false, null);
            Assert.Equal(allCandidates.Count, 3);

            // make sure coverage is incremented
            fetchedCandidate = allCandidates.FirstOrDefault(c => c.Equals(snv1));
            Assert.True(fetchedCandidate != null && fetchedCandidate.Support == 12);

            // make sure coverage is preserved
            fetchedCandidate = allCandidates.FirstOrDefault(c => c.Equals(snv2));
            Assert.True(fetchedCandidate != null && fetchedCandidate.Support == 5);
            fetchedCandidate = allCandidates.FirstOrDefault(c => c.Equals(deletion1));
            Assert.True(fetchedCandidate != null && fetchedCandidate.Support == 15);

            var moreDeletion1 = new CandidateAllele("chr1", 1500, "AT", "A", AlleleCategory.Deletion)
            {
                SupportByDirection = new[] { 0, 18, 0 }
            };

            testRegion.AddCandidate(moreDeletion1);

            allCandidates = testRegion.GetAllCandidates(false, null);
            Assert.Equal(allCandidates.Count, 3);

            // make sure coverage is incremented
            fetchedCandidate = allCandidates.FirstOrDefault(c => c.Equals(deletion1));
            Assert.True(fetchedCandidate != null && fetchedCandidate.Support == 33);

            // make sure coverage is preserved
            fetchedCandidate = allCandidates.FirstOrDefault(c => c.Equals(snv1));
            Assert.True(fetchedCandidate != null && fetchedCandidate.Support == 12);
            fetchedCandidate = allCandidates.FirstOrDefault(c => c.Equals(snv2));
            Assert.True(fetchedCandidate != null && fetchedCandidate.Support == 5);

            // -----------------------------------------------
            // add insertion that goes off block
            // -----------------------------------------------
            var edgeInsertion = new CandidateAllele("chr1", 2000, "A", "TCG", AlleleCategory.Insertion)
            {
                SupportByDirection = new[] { 5, 0, 0 }
            };

            testRegion.AddCandidate(edgeInsertion);

            allCandidates = testRegion.GetAllCandidates(false, null);
            Assert.Equal(allCandidates.Count, 4);
            Assert.Equal(2001, testRegion.MaxAlleleEndpoint);

            // -----------------------------------------------
            // add mnv that goes off block
            // -----------------------------------------------
            var edgeMnv = new CandidateAllele("chr1", 1999, "ATCC", "TCGG", AlleleCategory.Mnv)
            {
                SupportByDirection = new[] { 5, 0, 0 }
            };

            testRegion.AddCandidate(edgeMnv);

            allCandidates = testRegion.GetAllCandidates(false, null);
            Assert.Equal(allCandidates.Count, 5);
            Assert.Equal(2002, testRegion.MaxAlleleEndpoint);

            // -----------------------------------------------
            // add deletion that goes off block
            // -----------------------------------------------
            var edgeDeletion = new CandidateAllele("chr1", 1999, "A" + new string('T', 25), "A", AlleleCategory.Deletion)
            {
                SupportByDirection = new[] { 5, 0, 0 }
            };

            testRegion.AddCandidate(edgeDeletion);

            allCandidates = testRegion.GetAllCandidates(false, null);
            Assert.Equal(allCandidates.Count, 6);
            Assert.Equal(2025, testRegion.MaxAlleleEndpoint);

            // -----------------------------------------------
            // add variant that goes off block but not as far as the deletion did - max endpoint should stay the same
            // -----------------------------------------------
            var edgeMnv2 = new CandidateAllele("chr1", 1999, "ATCGA", "TCGCT", AlleleCategory.Mnv)
            {
                SupportByDirection = new[] { 5, 0, 0 }
            };

            testRegion.AddCandidate(edgeMnv2);

            allCandidates = testRegion.GetAllCandidates(false, null);
            Assert.Equal(allCandidates.Count, 7);
            Assert.Equal(2025, testRegion.MaxAlleleEndpoint);
        }
コード例 #30
0
 public CandidateIndel(CandidateAllele baseCandidateAllele)
     : base(baseCandidateAllele.Chromosome, baseCandidateAllele.ReferencePosition, baseCandidateAllele.ReferenceAllele, baseCandidateAllele.AlternateAllele, baseCandidateAllele.Type)
 {
     SupportByDirection = baseCandidateAllele.SupportByDirection;
     IsKnown            = baseCandidateAllele.IsKnown;
 }