UNPKG

ideogram

Version:

Chromosome visualization for the web

165 lines (134 loc) 4.39 kB
function getDelimiterTsvLinesAndInit(source, content) { var delimiter, tsvLines, init; if (typeof chrBands === 'undefined' && source !== 'native') { delimiter = /\t/; tsvLines = content.split(/\r\n|\n/); init = 1; } else { delimiter = / /; tsvLines = content; init = 0; } return [delimiter, tsvLines, init]; } function updateChromosomes(chromosomes) { var tmp, i; if (chromosomes instanceof Array && typeof chromosomes[0] === 'object') { tmp = []; for (i = 0; i < chromosomes.length; i++) { tmp.push(chromosomes[i].name); } chromosomes = tmp; } return chromosomes; } function getLineObject(chr, columns, stain, taxid) { return { chr: chr, bp: { start: parseInt(columns[5], 10), stop: parseInt(columns[6], 10) }, iscn: { start: parseInt(columns[3], 10), stop: parseInt(columns[4], 10) }, px: { start: -1, stop: -1, width: -1 }, name: columns[1] + columns[2], stain: stain, taxid: taxid }; } function getStain(columns) { var stain = columns[7]; // For e.g. acen and gvar, columns[8] (density) is undefined if (columns[8]) stain += columns[8]; return stain; } function updateLines(lines, columns, taxid) { var chr, stain, line; chr = columns[0]; if (chr in lines === false) lines[chr] = []; stain = getStain(columns); line = getLineObject(chr, columns, stain, taxid); lines[chr].push(line); return lines; } /** * Reports if a cytogenetic band should be included in parse results * * TODO: * Normalize ideogram.chromosomes upstream. * * This function is complex because ideogram.chromosomes is (likely * unnecessarily) complex. The "ideogram.chromosomes" object can * take many forms depending on the use case, and this results in * hard-to-reason-about functions like this. * * Normalizing ideogram.chromosomes to a common format somewhere upstream * would likely make this specific function and Ideogram in general much * more maintainable. */ function shouldSkipBand(chrs, chr, taxid, ideo) { var hasChrs, chrsAreList, chrNotInList, chrsAreObject, innerChrsAreStrings, matchingChrObjs, chrNotInObject, multiorganism = ideo.config.multiorganism; hasChrs = typeof chrs !== 'undefined' && chrs !== null; if (!hasChrs) return false; chrsAreList = Array.isArray(chrs); chrNotInList = chrsAreList && chrs.indexOf(chr) === -1; chrsAreObject = typeof chrs === 'object'; if (chrsAreList && !chrsAreObject && chrNotInList) return true; if (taxid in chrs === false && multiorganism) return false; if (!multiorganism) { // Encountered in single organism when showing subset of all chromosomes, // e.g. only human X and Y as in https://eweitz.github.io/ideogram/homology-basic matchingChrObjs = chrs.filter(thisChr => thisChr === chr); chrNotInObject = matchingChrObjs.length === 0; } else { innerChrsAreStrings = typeof chrs[taxid][0] === 'string'; if (innerChrsAreStrings) { chrNotInObject = chrs[taxid].includes(chr) === false; } else { matchingChrObjs = chrs[taxid].filter(thisChr => thisChr.name === chr); chrNotInObject = matchingChrObjs.length === 0; } } return chrNotInObject; } /** * Parses cytogenetic band data from a TSV file, or, if band data is * prefetched, from an array * * NCBI: * #chromosome arm band iscn_start iscn_stop bp_start bp_stop stain density * ftp://ftp.ncbi.nlm.nih.gov/pub/gdp/ideogram_9606_GCF_000001305.14_550_V1 */ function parseBands(taxid, chromosomes, ideo) { var delimiter, tsvLines, columns, chr, i, init, source, content, lines = {}; content = ideo.bandData[taxid]; if (Array.isArray(content)) source = 'native'; chromosomes = updateChromosomes(chromosomes); // Destructure assignment fails oddly when transpiled. 2019-05-23 var result = getDelimiterTsvLinesAndInit(source, content); delimiter = result[0]; tsvLines = result[1]; init = result[2]; for (i = init; i < tsvLines.length; i++) { columns = tsvLines[i].split(delimiter); chr = columns[0]; if (shouldSkipBand(chromosomes, chr, taxid, ideo)) { // If specific chromosomes are configured, then skip processing all // other fetched chromosomes. continue; } lines = updateLines(lines, columns, taxid); } return lines; } export {parseBands};