/// <summary> /// Merges regions that share start and end in the same bin /// </summary> private static void MergeRegionList(ref List <BamIndexRegion> regions) { // merge regions with overlapping bins in the list int prevIndex = 0; for (int currentIndex = 1; currentIndex < regions.Count; ++currentIndex) { if ((regions[prevIndex].End >> 16) == (regions[currentIndex].Begin >> 16)) { regions[prevIndex] = new BamIndexRegion(regions[prevIndex].Begin, regions[currentIndex].End); } else { regions[++prevIndex] = regions[currentIndex]; } } // remove the remaining regions int numMergedRegions = prevIndex + 1; int numRegionsToDelete = regions.Count - numMergedRegions; if (numRegionsToDelete > 0) { regions.RemoveRange(numMergedRegions, numRegionsToDelete); } }
/// <summary> /// Reads a BAM index from the supplied filename /// </summary> /// <returns>true if the index was successfully loaded</returns> public bool ReadIndex(string filename) { // check if the file exists if (!File.Exists(filename)) { return(false); } using ( BinaryReader reader = new BinaryReader(new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read))) { // check to see if we have a proper BAM index signature byte[] buffer = reader.ReadBytes(4); string magicNumberString = Encoding.ASCII.GetString(buffer, 0, 4); if (magicNumberString != BamConstants.BaiMagicNumber) { throw new InvalidDataException( string.Format("ERROR: Expected the BAM index magic number to be {0}, but found {1}.", BamConstants.BaiMagicNumber, magicNumberString)); } // read the number of reference sequences uint numReferenceSequences = reader.ReadUInt32(); // iterate over each reference sequence _index.Clear(); for (uint refSeqIndex = 0; refSeqIndex < numReferenceSequences; ++refSeqIndex) { // ======================= // read the binning index // ======================= BamReferenceIndex refIndex = new BamReferenceIndex(); // read the number of bins uint numBins = reader.ReadUInt32(); // iterate over each bin in the regions dictionary for (uint binIndex = 0; binIndex < numBins; ++binIndex) { // read the bin and the number of index regions uint bin = reader.ReadUInt32(); uint numIndexRegions = reader.ReadUInt32(); // read all of the index regions List <BamIndexRegion> bamIndexRegions = new List <BamIndexRegion>(); for (uint regionIndex = 0; regionIndex < numIndexRegions; ++regionIndex) { ulong begin = reader.ReadUInt64(); ulong end = reader.ReadUInt64(); BamIndexRegion indexRegion = new BamIndexRegion(begin, end); bamIndexRegions.Add(indexRegion); } // add the index regions to our dictionary refIndex.RegionsDictionary[bin] = bamIndexRegions; } // ===================== // read the linear index // ===================== // read the linear index size uint numOffsets = reader.ReadUInt32(); for (uint offsetIndex = 0; offsetIndex < numOffsets; ++offsetIndex) { refIndex.OffsetList.Add(reader.ReadUInt64()); } // add the reference index _index.Add(refIndex); } // read the number of unaligned reads without coordinates _numUnalignedWithoutCoordinates = reader.ReadUInt64(); } return(true); }