public void AddAlignment(BamAlignment alignment, ReadNumber readNumber = ReadNumber.NA) { var alignmentCopy = new BamAlignment(alignment); if (alignmentCopy.IsPrimaryAlignment() && !alignmentCopy.IsSupplementaryAlignment()) { if (FragmentSize == 0) { FragmentSize = Math.Abs(alignmentCopy.FragmentLength); // Can be either F1R2 or F2R1 NormalPairOrientation = (!alignmentCopy.IsReverseStrand() && alignmentCopy.IsMateReverseStrand()) || (alignmentCopy.IsReverseStrand() && !alignmentCopy.IsMateReverseStrand()); if (NormalPairOrientation) { if (alignmentCopy.RefID == alignmentCopy.MateRefID) { if (!alignmentCopy.IsReverseStrand()) { if (alignmentCopy.Position > alignmentCopy.MatePosition) { // RF NormalPairOrientation = false; } } else { if (alignmentCopy.MatePosition > alignmentCopy.Position) { // RF NormalPairOrientation = false; } } } } } NumPrimaryReads++; bool useForPos = true; if (useForPos) { if (alignmentCopy.Position > MaxPosition) { MaxPosition = alignment.Position; } if (alignmentCopy.Position < MinPosition) { MinPosition = alignment.Position; } } if (readNumber == ReadNumber.NA) { if (Read1 != null && Read2 != null) { throw new InvalidDataException($"Already have both primary alignments for {alignment.Name}."); } if (Read1 == null) { Read1 = alignmentCopy; } else { Read2 = alignmentCopy; } } else if (readNumber == ReadNumber.Read1) { if (Read1 != null) { throw new InvalidDataException($"Already have a read 1 primary alignment for {alignment.Name}."); } Read1 = alignmentCopy; } else if (readNumber == ReadNumber.Read2) { if (Read2 != null) { throw new InvalidDataException($"Already have a read 2 primary alignment for {alignment.Name}."); } Read2 = alignmentCopy; } } else if (alignmentCopy.IsSupplementaryAlignment()) { switch (readNumber) { case ReadNumber.Read1: if (Read1SupplementaryAlignments == null) { Read1SupplementaryAlignments = new List <BamAlignment>(); } Read1SupplementaryAlignments.Add(alignmentCopy); break; case ReadNumber.Read2: if (Read2SupplementaryAlignments == null) { Read2SupplementaryAlignments = new List <BamAlignment>(); } Read2SupplementaryAlignments.Add(alignmentCopy); break; case ReadNumber.NA: if (Read1SupplementaryAlignments == null) { Read1SupplementaryAlignments = new List <BamAlignment>(); } Read1SupplementaryAlignments.Add(alignmentCopy); break; default: throw new ArgumentOutOfRangeException(nameof(readNumber), readNumber, null); } } else { switch (readNumber) { case ReadNumber.Read1: if (Read1SecondaryAlignments == null) { Read1SecondaryAlignments = new List <BamAlignment>(); } Read1SecondaryAlignments.Add(alignmentCopy); break; case ReadNumber.Read2: if (Read2SecondaryAlignments == null) { Read2SecondaryAlignments = new List <BamAlignment>(); } Read2SecondaryAlignments.Add(alignmentCopy); break; case ReadNumber.NA: if (Read1SecondaryAlignments == null) { Read1SecondaryAlignments = new List <BamAlignment>(); } Read1SecondaryAlignments.Add(alignmentCopy); break; default: throw new ArgumentOutOfRangeException(nameof(readNumber), readNumber, null); } } // Set as improper once we add any alignment that is flagged as improper if (!alignmentCopy.IsProperPair()) { IsImproper = true; } }