UNPKG

phylojs

Version:

A simple typescript library for phylogenetic trees

109 lines (108 loc) 4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.nhxAnnotation = exports.beastAnnotation = exports.newickRecurse = exports.writeNewick = void 0; /** * Writes tree in .newick format. Undefined branch lengths set to 0. * @param {tree} tree The tree to write * @param {annotationWriter} string Function parsing node annotations to string. Defaults to empty string - no annotation case. Can be user Defined or use in-build beastAnnotations or nhxAnnotations * @returns {string} */ function writeNewick(tree, annotationWriter = _annotation => '') { let newickStr = ''; if (tree.root !== undefined) newickStr += newickRecurse(tree.root, annotationWriter) + ';'; return newickStr; } exports.writeNewick = writeNewick; /** * Recurses through tree, writing building up nwk string as it foes * @param {node} Node * @param {annotationWriter} string Function parsing Node.annotation to string. Defaults to empty string, not writing annotations. Can be user Defined or use in-build beastAnnotations or nhxAnnotations * @returns {string} */ function newickRecurse(node, annotationWriter = _annotation => '') { let res = ''; if (!node.isLeaf()) { res += '('; for (let i = 0; i < node.children.length; i++) { if (i > 0) res += ','; res += newickRecurse(node.children[i], annotationWriter); } res += ')'; } // TODO: Add hybrid type to node labels - H, LGT, or R if (node.label !== undefined && node.hybridID == undefined) { res += `"${node.label}"`; } else if (node.label !== undefined && node.hybridID !== undefined) { res += `"${node.label}"#${node.hybridID}`; } else if (node.label == undefined && node.hybridID !== undefined) { res += `#${node.hybridID}`; } res += annotationWriter(node.annotation); if (node.branchLength !== undefined) { node.branchLength == 0 ? (res += ':0.0') : (res += `:${node.branchLength}`); } return res; } exports.newickRecurse = newickRecurse; /** * Writes node annotations to a string in the syle of BEAST. * Eg: [&Type=A,Cols={Red,Blue}] * @param {annotation} typeof Node.prototype.annotation * @returns {string} */ function beastAnnotation(annotation) { let res = ''; if (annotation !== undefined) { const keys = Object.keys(annotation); if (keys.length > 0) { res += '[&'; for (let i = 0; i < keys.length; i++) { const key = keys[i]; if (i > 0) res += ','; res += `${key}=`; const value = annotation[key]; if (Array.isArray(value)) { res += `{${String(value.join(','))}}`; // Convert the array to a comma-separated string } else { res += `${String(value)}`; // Explicitly convert the value to a string } } res += ']'; } } return res; } exports.beastAnnotation = beastAnnotation; /** * Writes node annotations to a string in the syle of NHX. * Eg: [&&NHX:Type=A:Col=Red]. NHX does not appear to support * array date for annotations. Please get in touch if it does! * @param {annotation} typeof Node.prototype.annotation * @returns {string} */ function nhxAnnotation(annotation) { let res = ''; if (annotation !== undefined) { const keys = Object.keys(annotation); if (keys.length > 0) { res += '[&&NHX:'; for (let i = 0; i < keys.length; i++) { const key = keys[i]; if (i > 0) res += ':'; res += `${key}=`; const value = annotation[key]; res += `${String(value)}`; // Explicitly convert the value to a string } res += ']'; } } return res; } exports.nhxAnnotation = nhxAnnotation;