static void LoadObservedAlignmentsBAM(string bamFile, bool isPairedEnd, string chromosome, CanvasCoverageMode coverageMode, HitArray observed, Int16[] fragmentLengths)
{
// Sanity check: The .bai file must exist, in order for us to seek to our target chromosome!
string indexPath = bamFile + ".bai";
if (!File.Exists(indexPath))
{
throw new Exception(string.Format("Fatal error: Bam index not found at {0}", indexPath));
}
using (BamReader reader = new BamReader(bamFile))
{
int desiredRefIndex = -1;
desiredRefIndex = reader.GetReferenceIndex(chromosome);
if (desiredRefIndex == -1)
{
throw new ApplicationException(
string.Format("Unable to retrieve the reference sequence index for {0} in {1}.", chromosome,
bamFile));
}
bool result = reader.Jump(desiredRefIndex, 0);
if (!result)
{
// Note: This is not necessarily an error, it just means that there *are* no reads for this chromosome in this
// .bam file. That is not uncommon e.g. for truseq amplicon.
return;
}
int readCount = 0;
int keptReadCount = 0;
string header = reader.GetHeader();
BamAlignment alignment = new BamAlignment();
while (reader.GetNextAlignment(ref alignment, true))
{
readCount++;
// Flag check - Require reads to be aligned, passing filter, non-duplicate:
if (!alignment.IsMapped()) continue;
if (alignment.IsFailedQC()) continue;
if (alignment.IsDuplicate()) continue;
if (alignment.IsReverseStrand()) continue;
if (!alignment.IsMainAlignment()) continue;
// Require the alignment to start with 35 bases of non-indel:
if (alignment.CigarData[0].Type != 'M' || alignment.CigarData[0].Length < 35) continue;
if (isPairedEnd && !alignment.IsProperPair()) continue;
int refID = alignment.RefID;
// quit if the current reference index is different from the desired reference index
if (refID != desiredRefIndex)
break;
if (refID == -1)
continue;
keptReadCount++;
if (coverageMode == CanvasCoverageMode.Binary)
{
observed.Data[alignment.Position] = 1;
}
else
{
observed.Set(alignment.Position);
}
// store fragment size, make sure it's within Int16 range and is positive (simplification for now)
if (coverageMode == CanvasCoverageMode.GCContentWeighted)
fragmentLengths[alignment.Position] = Convert.ToInt16(Math.Max(Math.Min(Int16.MaxValue, alignment.FragmentLength), 0));
}
Console.WriteLine("Kept {0} of {1} total reads", keptReadCount, readCount);
}
}