UNPKG

@gmod/cram

Version:

read CRAM files with pure Javascript

84 lines 3.99 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const errors_ts_1 = require("../../errors.js"); const index_ts_1 = __importDefault(require("../slice/index.js")); const util_ts_1 = require("../util.js"); const compressionScheme_ts_1 = __importDefault(require("./compressionScheme.js")); const sectionParsers_ts_1 = require("../sectionParsers.js"); class CramContainer { constructor(file, filePosition) { this.file = file; this.filePosition = filePosition; } getHeader() { return this._readContainerHeader(this.filePosition); } async getCompressionHeaderBlock() { const containerHeader = await this.getHeader(); // if there are no records in the container, there will be no compression // header if (!containerHeader.numRecords) { return null; } const { majorVersion } = await this.file.getDefinition(); const sectionParsers = (0, sectionParsers_ts_1.getSectionParsers)(majorVersion); const block = await this.getFirstBlock(); if (block.contentType !== 'COMPRESSION_HEADER') { throw new errors_ts_1.CramMalformedError(`invalid content type ${block.contentType} in compression header block`); } const content = (0, util_ts_1.parseItem)(block.content, sectionParsers.cramCompressionHeader.parser, 0, block.contentPosition); return { ...block, parsedContent: content, }; } async getFirstBlock() { const containerHeader = await this.getHeader(); return this.file.readBlock(containerHeader._endPosition); } // parses the compression header data into a CramContainerCompressionScheme // object async getCompressionScheme() { const header = await this.getCompressionHeaderBlock(); if (!header) { return undefined; } return new compressionScheme_ts_1.default(header.parsedContent); } getSlice(slicePosition, sliceSize) { // note: slicePosition is relative to the end of the container header // TODO: perhaps we should cache slices? return new index_ts_1.default(this, slicePosition, sliceSize); } async _readContainerHeader(position) { const { majorVersion } = await this.file.getDefinition(); const sectionParsers = (0, sectionParsers_ts_1.getSectionParsers)(majorVersion); const { cramContainerHeader1, cramContainerHeader2 } = sectionParsers; // parse the container header. do it in 2 pieces because you cannot tell // how much to buffer until you read numLandmarks const bytes1 = await this.file.read(cramContainerHeader1.maxLength, position); const header1 = (0, util_ts_1.parseItem)(bytes1, cramContainerHeader1.parser); const numLandmarksSize = (0, util_ts_1.itf8Size)(header1.numLandmarks); const bytes2 = await this.file.read(cramContainerHeader2.maxLength(header1.numLandmarks), position + header1._size - numLandmarksSize); const header2 = (0, util_ts_1.parseItem)(bytes2, cramContainerHeader2.parser); if (this.file.validateChecksums && header2.crc32 !== undefined) { await this.file.checkCrc32(position, header1._size + header2._size - numLandmarksSize - 4, header2.crc32, `container header beginning at position ${position}`); } return { ...header1, ...header2, _size: header1._size + header2._size - numLandmarksSize, _endPosition: header1._size + header2._size - numLandmarksSize + position, }; } } exports.default = CramContainer; 'getHeader getCompressionHeaderBlock getCompressionScheme' .split(' ') .forEach(method => { (0, util_ts_1.tinyMemoize)(CramContainer, method); }); //# sourceMappingURL=index.js.map