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); } }
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); }