UNPKG

@gmod/bed

Version:

A BED file format parser with autoSql support

100 lines 4.21 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const autoSql_ts_1 = __importDefault(require("./autoSql.js")); const defaultTypes_ts_1 = __importDefault(require("./defaultTypes.js")); const util_ts_1 = require("./util.js"); const strandMap = { '.': 0, '-': -1, '+': 1 }; // heuristic that a BED file is BED12 like...the number in col 10 is // blockCount-like function isBed12Like(fields) { return (fields.length >= 12 && !Number.isNaN(Number.parseInt(fields[9], 10)) && fields[10]?.split(',').filter(f => !!f).length === Number.parseInt(fields[9], 10)); } class BED { constructor(arguments_ = {}) { if (arguments_.autoSql) { this.autoSql = (0, util_ts_1.detectTypes)( // @ts-expect-error autoSql_ts_1.default.parse(arguments_.autoSql)); } else if (arguments_.type) { // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (!defaultTypes_ts_1.default[arguments_.type]) { throw new Error('Type not found'); } this.autoSql = (0, util_ts_1.detectTypes)(defaultTypes_ts_1.default[arguments_.type]); } else { this.autoSql = (0, util_ts_1.detectTypes)(defaultTypes_ts_1.default.defaultBedSchema); this.attemptDefaultBed = true; } } /* * parses a line of text as a BED line with the loaded autoSql schema * * @param line - a BED line as tab delimited text or array * @param opts - supply opts.uniqueId * @return a object representing a feature */ parseLine(line, options = {}) { const { autoSql } = this; const { uniqueId } = options; const fields = Array.isArray(line) ? line : line.split('\t'); let feature = {}; if (!this.attemptDefaultBed || // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition (this.attemptDefaultBed && isBed12Like(fields))) { for (let index = 0; index < autoSql.fields.length; index++) { const autoField = autoSql.fields[index]; let columnValue = fields[index]; const { isNumeric, isArray, arrayIsNumeric, name } = autoField; if (columnValue === null || columnValue === undefined) { break; } if (columnValue !== '.') { if (isNumeric) { const number_ = Number(columnValue); columnValue = Number.isNaN(number_) ? columnValue : number_; } else if (isArray) { columnValue = columnValue.split(','); if (columnValue.at(-1) === '') { columnValue.pop(); } if (arrayIsNumeric) { columnValue = columnValue.map(Number); } } feature[name] = columnValue; } } } else { const fieldNames = ['chrom', 'chromStart', 'chromEnd', 'name']; feature = Object.fromEntries(fields.map((f, index) => [fieldNames[index] || 'field' + index, f])); feature.chromStart = +feature.chromStart; feature.chromEnd = +feature.chromEnd; if (!Number.isNaN(Number.parseFloat(feature.field4))) { feature.score = +feature.field4; delete feature.field4; } if (feature.field5 === '+' || feature.field5 === '-') { feature.strand = feature.field5; delete feature.field5; } } if (uniqueId) { feature.uniqueId = uniqueId; } feature.strand = strandMap[feature.strand] || 0; feature.chrom = decodeURIComponent(feature.chrom); return feature; } } exports.default = BED; //# sourceMappingURL=parser.js.map