public StitchingResult TryStitch(AlignmentSet set)
        {
            try
            {
                if (set.PartnerRead1 == null || set.PartnerRead2 == null)
                {
                    throw new ArgumentException("Set has missing read.");
                }

                if (IsStitchable(set))
                {
                    // Assumption is that exactly one read is first mate
                    var r1IsFirstMate = !set.PartnerRead2.IsFirstMate;

                    // Assumption is that exactly one read is forward and one read is reverse, and each component read is only one direction
                    // GetStitchedCigar returns null if cigars can't possibly agree
                    var stitchingInfo = _cigarReconciler.GetStitchedCigar(set.PartnerRead1.CigarData,
                                                                          set.PartnerRead1.Position,
                                                                          set.PartnerRead2.CigarData, set.PartnerRead2.Position,
                                                                          set.PartnerRead1.SequencedBaseDirectionMap.First() == DirectionType.Reverse, set.IsOutie, set.PartnerRead1.Sequence, set.PartnerRead2.Sequence, set.PartnerRead1.Qualities, set.PartnerRead2.Qualities, r1IsFirstMate);

                    if (stitchingInfo != null && stitchingInfo.NumDisagreeingBases + (_countNsTowardNumDisagreeingBases ? stitchingInfo.NumNDisagreements : 0) > _thresholdNumDisagreeingBases)
                    {
                        stitchingInfo = null;
                    }

                    if (stitchingInfo != null)
                    {
                        var stitchedCigar = stitchingInfo.StitchedCigar;

                        if (stitchedCigar == null)
                        // there's an overlap but we can't figure out the cigar - TODO revisit
                        {
                            AddDebugStatusCount(ReadsOverlapButWeCanTFigureOutTheCigar);
                            //_statusCounter.AddDebugStatusCount(ReadsOverlapButWeCanTFigureOutTheCigar);
                            return(new StitchingResult(false, stitchingInfo.NumDisagreeingBases, stitchingInfo.NumDisagreeingBases, stitchingInfo.NumNDisagreements));
                        }

                        // Returns null if unable to generate consensus
                        var mergedRead = stitchingInfo.IsSimple ? _readMerger.GenerateConsensusRead(set.PartnerRead1, set.PartnerRead2, stitchingInfo, set.IsOutie)  :
                                         _readMerger.GenerateConsensusRead(set.PartnerRead1, set.PartnerRead2,
                                                                           stitchingInfo, set.IsOutie);

                        if (mergedRead != null)
                        {
                            mergedRead.BamAlignment.RefID      = set.PartnerRead1.BamAlignment.RefID;
                            mergedRead.IsDuplex                = set.PartnerRead1.IsDuplex || set.PartnerRead2.IsDuplex;
                            mergedRead.CigarDirections         = stitchingInfo.StitchedDirections;
                            mergedRead.BamAlignment.MapQuality = Math.Max(set.PartnerRead1.MapQuality,
                                                                          set.PartnerRead2.MapQuality);

                            if (_dontStitchHomopolymerBridge)
                            {
                                var bridgeAnchored = stitchingInfo.IsSimple ?
                                                     OverlapEvaluator.BridgeAnchored(stitchingInfo.OverlapBases) : OverlapEvaluator.BridgeAnchored(mergedRead);
                                if (!bridgeAnchored)
                                {
                                    AddDebugStatusCount(OverlappingBasesAreRepeatCannotReliablyStitch);
                                    //_statusCounter.AddDebugStatusCount(OverlappingBasesAreRepeatCannotReliablyStitch);
                                    return(new StitchingResult(false, stitchingInfo.NumAgreements, stitchingInfo.NumDisagreeingBases, stitchingInfo.NumNDisagreements));
                                }
                            }

                            set.ReadsForProcessing.Add(mergedRead);

                            AddDebugStatusCount(ReadsSuccesfullyMerge);
                            //_statusCounter.AddDebugStatusCount(ReadsSuccesfullyMerge);

                            return(new StitchingResult(true, stitchingInfo.NumAgreements, stitchingInfo.NumDisagreeingBases, stitchingInfo.NumNDisagreements));
                        }
                    }
                }

                // If we didn't return true already, stitching failed.
                if (_debug)
                {
                    Logger.WriteToLog("Stitching failed on read " + set.PartnerRead1.Name);
                }

                if (_nifyUnstitchablePairs && IsStitchable(set))
                {
                    // TODO consider removing this functionality.
                    // Give a merged, Nified read if the pairs are stitchable (i.e. overlap) but conflicting
                    try
                    {
                        var mergedRead = _readMerger.GenerateNifiedMergedRead(set, _useSoftclippedBases);
                        mergedRead.BamAlignment.RefID      = set.PartnerRead1.BamAlignment.RefID;
                        mergedRead.IsDuplex                = set.PartnerRead1.IsDuplex || set.PartnerRead2.IsDuplex;
                        mergedRead.BamAlignment.MapQuality = Math.Max(set.PartnerRead1.MapQuality,
                                                                      set.PartnerRead2.MapQuality);
                        set.ReadsForProcessing.Add(mergedRead);

                        AddDebugStatusCount(UnstitchablePairNIfied);
                        //_statusCounter.AddDebugStatusCount(UnstitchablePairNIfied);
                        return(new StitchingResult(true, 0, 0, 0));
                    }
                    catch (Exception e)
                    {
                        Logger.WriteExceptionToLog(e);
                        //_statusCounter.AddDebugStatusCount(UnstitchablePairUnableToNifyReturnedIndividually);
                        AddDebugStatusCount(UnstitchablePairUnableToNifyReturnedIndividually);
                        set.ReadsForProcessing.Add(set.PartnerRead1);
                        set.ReadsForProcessing.Add(set.PartnerRead2);
                    }
                }
                else
                {
                    AddDebugStatusCount(UnstitchablePairReturnedIndividually);
                    //_statusCounter.AddDebugStatusCount(UnstitchablePairReturnedIndividually);
                    set.ReadsForProcessing.Add(set.PartnerRead1);
                    set.ReadsForProcessing.Add(set.PartnerRead2);
                }
                return(new StitchingResult(false, 0, 0, 0));
            }
            catch (Exception e)
            {
                throw new Exception("Stitching failed for read '" + set.PartnerRead1.Name + "': " + e.Message + "..." + e.StackTrace, e.InnerException);
            }
        }
Exemple #2
0
        public bool TryStitch(AlignmentSet set)
        {
            if (set.PartnerRead1 == null || set.PartnerRead2 == null)
            {
                throw new ArgumentException("Set has missing read.");
            }

            if (IsStitchable(set))
            {
                // Assumption is that exactly one read is forward and one read is reverse, and each component read is only one direction
                // GetStitchedCigar returns null if cigars can't possibly agree
                var stitchingInfo = _cigarReconciler.GetStitchedCigar(set.PartnerRead1.CigarData, set.PartnerRead1.Position,
                                                                      set.PartnerRead2.CigarData, set.PartnerRead2.Position,
                                                                      set.PartnerRead1.SequencedBaseDirectionMap.First() == DirectionType.Reverse, set.IsOutie);

                if (stitchingInfo != null)
                {
                    var stitchedCigar = stitchingInfo.StitchedCigar;

                    if (stitchedCigar == null) // there's an overlap but we can't figure out the cigar - TODO revisit
                    {
                        _statusCounter.AddDebugStatusCount("Reads overlap but we can't figure out the cigar");
                        return(false);
                    }

                    // Returns null if unable to generate consensus
                    var mergedRead = _readMerger.GenerateConsensusRead(set.PartnerRead1, set.PartnerRead2, stitchingInfo, set.IsOutie);

                    if (mergedRead != null)
                    {
                        mergedRead.BamAlignment.RefID      = set.PartnerRead1.BamAlignment.RefID;
                        mergedRead.IsDuplex                = set.PartnerRead1.IsDuplex || set.PartnerRead2.IsDuplex;
                        mergedRead.CigarDirections         = stitchingInfo.StitchedDirections;
                        mergedRead.BamAlignment.MapQuality = Math.Max(set.PartnerRead1.MapQuality, set.PartnerRead2.MapQuality);

                        set.ReadsForProcessing.Add(mergedRead);

                        _statusCounter.AddDebugStatusCount("Reads succesfully merge");
                        return(true);
                    }
                }
            }

            // If we didn't return true already, stitching failed.
            if (_debug)
            {
                Logger.WriteToLog("Stitching failed on read " + set.PartnerRead1.Name);
            }

            if (_nifyUnstitchablePairs && IsStitchable(set))
            {
                // Give a merged, Nified read if the pairs are stitchable (i.e. overlap) but conflicting
                var mergedRead = _readMerger.GenerateNifiedMergedRead(set, _useSoftclippedBases);
                mergedRead.BamAlignment.RefID      = set.PartnerRead1.BamAlignment.RefID;
                mergedRead.IsDuplex                = set.PartnerRead1.IsDuplex || set.PartnerRead2.IsDuplex;
                mergedRead.BamAlignment.MapQuality = Math.Max(set.PartnerRead1.MapQuality,
                                                              set.PartnerRead2.MapQuality);
                set.ReadsForProcessing.Add(mergedRead);

                _statusCounter.AddDebugStatusCount("Unstitchable pair N-ified");
                return(true);
            }
            else
            {
                _statusCounter.AddDebugStatusCount("Unstitchable pair returned individually");
                set.ReadsForProcessing.Add(set.PartnerRead1);
                set.ReadsForProcessing.Add(set.PartnerRead2);
            }
            return(false);
        }