UNPKG

genomic-reader

Version:

A Typescript library for reading BigWig, BigBed, 2bit, and Bam files. Capable of streaming. For use in the browser or on Node.js.

165 lines 7.14 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.loadHeaderData = exports.FileType = void 0; const BinaryParser_1 = require("../util/BinaryParser"); const TwoBitHeaderReader_1 = require("./TwoBitHeaderReader"); const TWOBIT_MAGIC_LTH = 0x1A412743; const TWOBIT_MAGIC_HTL = 0x4327411A; const BIGWIG_MAGIC_LTH = 0x888FFC26; const BIGWIG_MAGIC_HTL = 0x26FC8F88; const BIGBED_MAGIC_LTH = 0x8789F2EB; const BIGBED_MAGIC_HTL = 0xEBF28987; const CHROM_TREE_MAGIC = 0x78CA8C91; const BBFILE_HEADER_SIZE = 64; var FileType; (function (FileType) { FileType["BigWig"] = "BigWig"; FileType["BigBed"] = "BigBed"; FileType["TwoBit"] = "TwoBit"; })(FileType = exports.FileType || (exports.FileType = {})); function loadHeaderData(dataLoader) { return __awaiter(this, void 0, void 0, function* () { const headerData = yield dataLoader.load(0, BBFILE_HEADER_SIZE); let fileType = undefined; let littleEndian = true; let binaryParser = new BinaryParser_1.BinaryParser(headerData, littleEndian); let magic = binaryParser.getUInt(); if (BIGWIG_MAGIC_LTH === magic) { fileType = FileType.BigWig; } else if (BIGBED_MAGIC_LTH === magic) { fileType = FileType.BigBed; } else if (TWOBIT_MAGIC_LTH === magic) { return TwoBitHeaderReader_1.loadTwoBitHeaderData(dataLoader, littleEndian); } else { littleEndian = false; binaryParser = new BinaryParser_1.BinaryParser(headerData, littleEndian); magic = binaryParser.getUInt(); if (BIGWIG_MAGIC_HTL === magic) { fileType = FileType.BigWig; } else if (BIGBED_MAGIC_HTL === magic) { fileType = FileType.BigBed; } else if (TWOBIT_MAGIC_HTL === magic) { return TwoBitHeaderReader_1.loadTwoBitHeaderData(dataLoader, littleEndian); } } if (undefined === fileType) { throw new Error("Unable to determine file type."); } const commonHeader = { bwVersion: binaryParser.getUShort(), nZoomLevels: binaryParser.getUShort(), chromTreeOffset: binaryParser.getLong(), fullDataOffset: binaryParser.getLong(), fullIndexOffset: binaryParser.getLong(), fieldCount: binaryParser.getUShort(), definedFieldCount: binaryParser.getUShort(), autoSqlOffset: binaryParser.getLong(), totalSummaryOffset: binaryParser.getLong(), uncompressBuffSize: binaryParser.getInt(), reserved: binaryParser.getLong() }; const xdata = yield dataLoader.load(BBFILE_HEADER_SIZE, commonHeader.fullDataOffset - BBFILE_HEADER_SIZE + 5); const zoomLevelHeaders = []; binaryParser = new BinaryParser_1.BinaryParser(xdata); for (let i = 1; i <= commonHeader.nZoomLevels; i++) { const zoomNumber = commonHeader.nZoomLevels - i; const zoomLevelHeader = { index: zoomNumber, reductionLevel: binaryParser.getInt(), reserved: binaryParser.getInt(), dataOffset: binaryParser.getLong(), indexOffset: binaryParser.getLong() }; zoomLevelHeaders[zoomNumber] = zoomLevelHeader; } let autosql = undefined; if (commonHeader.autoSqlOffset > 0) { binaryParser.position = commonHeader.autoSqlOffset - BBFILE_HEADER_SIZE; autosql = binaryParser.getString(); } let totalSummary = undefined; if (commonHeader.totalSummaryOffset > 0) { binaryParser.position = commonHeader.totalSummaryOffset - BBFILE_HEADER_SIZE; totalSummary = { basesCovered: binaryParser.getLong(), minVal: binaryParser.getDouble(), maxVal: binaryParser.getDouble(), sumData: binaryParser.getDouble(), sumSquares: binaryParser.getDouble() }; } let chromTree = undefined; if (commonHeader.chromTreeOffset > 0) { binaryParser.position = commonHeader.chromTreeOffset - BBFILE_HEADER_SIZE; const magic = binaryParser.getUInt(); if (CHROM_TREE_MAGIC !== magic) { throw new Error("Chomosome ID B+ Tree not found."); } chromTree = { magic: magic, blockSize: binaryParser.getInt(), keySize: binaryParser.getInt(), valSize: binaryParser.getInt(), itemCount: binaryParser.getLong(), reserved: binaryParser.getLong(), chromToId: {}, chromSize: {}, idToChrom: [] }; buildChromTree(chromTree, binaryParser); } return { fileType: fileType, littleEndian: littleEndian, common: commonHeader, zoomLevelHeaders: zoomLevelHeaders, autosql: autosql, totalSummary: totalSummary, chromTree: chromTree }; }); } exports.loadHeaderData = loadHeaderData; function buildChromTree(chromTree, binaryParser, offset) { if (undefined !== offset) { binaryParser.position = offset; } const type = binaryParser.getByte(); binaryParser.position++; const count = binaryParser.getUShort(); if (1 === type) { for (let i = 0; i < count; i++) { const key = binaryParser.getFixedLengthTrimmedString(chromTree.keySize); const chromId = binaryParser.getInt(); const chromSize = binaryParser.getInt(); chromTree.chromToId[key] = chromId; chromTree.idToChrom[chromId] = key; chromTree.chromSize[key] = chromSize; } } else { for (let i = 0; i < count; i++) { const key = binaryParser.getFixedLengthTrimmedString(chromTree.keySize); const childOffset = binaryParser.getLong(); const bufferOffset = childOffset - BBFILE_HEADER_SIZE; const currOffset = binaryParser.position; buildChromTree(chromTree, binaryParser, bufferOffset); binaryParser.position = currOffset; } } } //# sourceMappingURL=BigWigHeaderReader.js.map