private void ExecuteTest(Read read, Action <List <CandidateIndel> > assertions, int minBasecallQuality = 0)
        {
            var finder = new IndelTargetFinder(minBasecallQuality);

            var result = finder.FindIndels(read, _refSeq, _chr);

            assertions(result);
        }
Пример #2
0
        public List <BamAlignment> ExtractReads(PairResult pairResult, INmCalculator nmCalculator, bool doRealign = true, int readsToSilence = 0)
        {
            var pair = pairResult.ReadPair;

            if (pair.PairStatus == PairStatus.LeaveUntouched)
            {
                return(pair.GetAlignments().ToList());
            }
            var reads = new List <BamAlignment>();

            // TODO clean this up, should really not have two layers (pair result and readpair) here
            if (pairResult.ReadPair.Stitched)
            {
                const bool recalculateNm = true; // Always recalculate NM for stitched reads
                // TODO more explicitly assume/check that there is actually only one here
                foreach (var alignment in pairResult.Alignments)
                {
                    if (doRealign)
                    {
                        var finalReadR1 = RealignSingleAlignment(alignment, out var realignedR1);
                        pair.RealignedR1 = realignedR1;

                        SilenceReads(finalReadR1, null, readsToSilence, realignedR1, false);

                        pair.StitchedNm = UpdateAndAddAlignment(finalReadR1, false, null, reads, nmCalculator, recalculateNm);
                    }
                    else
                    {
                        SilenceReads(alignment, null, readsToSilence, false, false);

                        pair.StitchedNm = UpdateAndAddAlignment(alignment, false, null, reads, nmCalculator, recalculateNm);
                    }
                }

                return(reads);
            }
            if (pair.IsComplete(false) && (pair.PairStatus == PairStatus.Paired || pair.PairStatus == PairStatus.OffTarget))
            {
                var realignedR1 = false;

                var             realignedR2      = false;
                var             forcedSoftclipR1 = false;
                var             forcedSoftclipR2 = false;
                var             sketchy          = false;
                var             origRead1        = pair.Read1;
                var             origRead2        = pair.Read2;
                int?            r1Nm             = pair.Read1.GetIntTag("NM");
                int?            r2Nm             = pair.Read2.GetIntTag("NM");
                List <PreIndel> pairIndels       = null;

                if (pair.PairStatus == PairStatus.Paired)
                {
                    if (doRealign)
                    {
                        List <PreIndel> r1Indels = _hasExistingIndels && pairResult.R1Nm <= 2
                            ? pairResult.OriginalIndelsR1 ?? _indelTargetFinder.FindIndels(origRead1, _chromosome)
                            : _emptyList;
                        List <PreIndel> r2Indels = _hasExistingIndels && pairResult.R2Nm <= 2
                            ? pairResult.OriginalIndelsR2 ?? _indelTargetFinder.FindIndels(origRead2, _chromosome)
                            : _emptyList;

                        if (_pairAware && _hasExistingIndels && (r1Indels.Any() || r2Indels.Any()))
                        {
                            pairIndels = _finder.GetPairSpecificIndels(pair, r1Indels, r2Indels, ref r1Nm, ref r2Nm);
                        }

                        var confirmedAccepted = new List <HashableIndel>();

                        bool confirmedR1;
                        bool confirmedR2;


                        // TODO should we pay attention to whether one already has an indel and one doesn't, and realign/confirm the one that does, or that has the better one, first?
                        var try1Read1 = _evaluator.GetFinalAlignment(origRead1,
                                                                     out realignedR1, out forcedSoftclipR1, out confirmedR1, out sketchy, selectedIndels: pairIndels,
                                                                     existingIndels: r1Indels, confirmedAccepteds: confirmedAccepted, mateIndels: r2Indels);

                        pair.Read1 = try1Read1;
                        if ((realignedR1 || confirmedR1) && confirmedAccepted.Any())
                        {
                            pair.Read2 = _evaluator.GetFinalAlignment(origRead2,
                                                                      out realignedR2, out forcedSoftclipR2, out confirmedR2, out sketchy, selectedIndels: pairIndels,
                                                                      existingIndels: r2Indels, confirmedAccepteds: confirmedAccepted);
                        }
                        else
                        {
                            confirmedAccepted.Clear();
                            var try1Read2 = _evaluator.GetFinalAlignment(origRead2,
                                                                         out realignedR2, out forcedSoftclipR2, out confirmedR2, out sketchy, selectedIndels: pairIndels,
                                                                         existingIndels: r2Indels, confirmedAccepteds: confirmedAccepted, mateIndels: r1Indels);
                            pair.Read2 = try1Read2;

                            if ((realignedR2 || confirmedR2) && confirmedAccepted.Any())
                            {
                                pair.Read1 = _evaluator.GetFinalAlignment(origRead1,
                                                                          out realignedR1, out forcedSoftclipR1, out confirmedR1, out sketchy, selectedIndels: pairIndels,
                                                                          existingIndels: r1Indels, confirmedAccepteds: confirmedAccepted);
                            }
                        }

                        pairResult.R1Confirmed = confirmedR1;
                        pairResult.R2Confirmed = confirmedR2;
                    }

                    if (realignedR1 || realignedR2)
                    {
                        pair.Realigned = true;
                    }
                }

                pair.RealignedR1 = realignedR1;
                pair.RealignedR2 = realignedR2;

                // Silence realigned pair if needed
                SilenceReads(pair.Read1, pair.Read2, readsToSilence, realignedR1, realignedR2);
                // Silence original reads in case needed
                SilenceReads(origRead1, origRead2, readsToSilence, false, false);

                if (_allowedToStitch && !(forcedSoftclipR1 || forcedSoftclipR2) && (!_skipRestitchIfNothingChanged || (realignedR1 || realignedR2)))
                {
                    reads = _restitcher.GetRestitchedReads(pair, origRead1, origRead2, r1Nm, r2Nm, pairIndels != null, nmCalculator,
                                                           realignedR1 || realignedR2 || (r1Nm + r2Nm > 0), sketchy);

                    var isStitched = reads.Count == 1;
                    pair.Stitched             = isStitched;
                    pairResult.TriedStitching = true;

                    if (!isStitched)
                    {
                        reads.Clear();
                        // TODO looks like we are passing through EC twice - here and in the below foreach
                        HandleUnstitchedReads(pair, reads, realignedR1, realignedR2, nmCalculator);
                    }
                    foreach (var bamAlignment in reads)
                    {
                        _evidenceCollector.CollectEvidence(bamAlignment, true, isStitched, _chromosome);
                    }
                }
                else
                {
                    HandleUnstitchedReads(pair, reads, realignedR1, realignedR2, nmCalculator);
                }
            }
            else
            {
                if (doRealign)
                {
                    var finalReadR1 = RealignSingleAlignment(pair.Read1, out var realignedR1);
                    var finalReadR2 = RealignSingleAlignment(pair.Read2, out var realignedR2);
                    pair.RealignedR1 = realignedR1;
                    pair.RealignedR2 = realignedR2;
                    if (realignedR1 || realignedR2)
                    {
                        pair.Realigned = true;
                    }
                    SilenceReads(finalReadR1, finalReadR2, readsToSilence, realignedR1, realignedR2);
                    pair.Nm1 = UpdateAndAddAlignment(finalReadR1, realignedR2, finalReadR2, reads, nmCalculator, realignedR1);
                    pair.Nm2 = UpdateAndAddAlignment(finalReadR2, realignedR1, finalReadR1, reads, nmCalculator, realignedR2);
                }
                else
                {
                    SilenceReads(pair.Read1, pair.Read2, readsToSilence, false, false);

                    pair.Nm1 = UpdateAndAddAlignment(pair.Read1, false, pair.Read2, reads, nmCalculator, false);
                    pair.Nm2 = UpdateAndAddAlignment(pair.Read2, false, pair.Read1, reads, nmCalculator, false);
                }
            }


            return(reads);
        }