public static void BinOneAlignment(BamAlignment alignment, uint qualityThreshold, Dictionary<string, int> readNameToBinIndex,
HashSet<string> samePositionReadNames, ref long usableFragmentCount, List<GenomicBin> bins, ref int binIndexStart)
{
if (!alignment.IsMapped()) { return; }
if (!alignment.IsMateMapped()) { return; }
if (!alignment.IsPrimaryAlignment()) { return; }
if (!(alignment.IsPaired() && alignment.IsProperPair())) { return; }
bool duplicateFailedQCLowQuality = IsDuplicateFailedQCLowQuality(alignment, qualityThreshold);
// Check whether we have binned the fragment using the mate
if (readNameToBinIndex.ContainsKey(alignment.Name))
{
// Undo binning when one of the reads is a duplicate, fails QC or has low mapping quality
if (duplicateFailedQCLowQuality)
{
usableFragmentCount--;
bins[readNameToBinIndex[alignment.Name]].Count--;
}
readNameToBinIndex.Remove(alignment.Name); // clean up
return;
}
if (duplicateFailedQCLowQuality) { return; }
if (alignment.RefID != alignment.MateRefID) { return; } // does this ever happen?
if (IsRightMostInPair(alignment)) { return; } // look at only one read of the pair
// handle the case where alignment.Position == alignment.MatePosition
if (alignment.Position == alignment.MatePosition)
{
if (samePositionReadNames.Contains(alignment.Name))
{
samePositionReadNames.Remove(alignment.Name);
return;
}
samePositionReadNames.Add(alignment.Name);
}
if (alignment.FragmentLength == 0) { return; } // Janus-SRS-190: 0 when the information is unavailable
// Try to bin the fragment
int fragmentStart = alignment.Position; // 0-based, inclusive
int fragmentStop = alignment.Position + alignment.FragmentLength; // 0-based, exclusive
while (binIndexStart < bins.Count && bins[binIndexStart].Stop <= fragmentStart) // Bins[binIndexStart] on the left of the fragment
{
binIndexStart++;
}
if (binIndexStart >= bins.Count) { return; } // all the remaining fragments are on the right of the last bin
// now Bins[binIndexStart].Stop > fragmentStart
int bestBinIndex = FindBestBin(bins, binIndexStart, fragmentStart, fragmentStop);
if (bestBinIndex >= 0) // Bin the fragment
{
usableFragmentCount++;
bins[bestBinIndex].Count++;
readNameToBinIndex[alignment.Name] = bestBinIndex;
}
}