import { ParserOptionsSpec } from './ParserOptionsSpec'; import { Matrix3 } from "../WebGL"; import { assignBonds } from "./utils/assignBonds"; /** * Read an XYZ file from str and return result * * @param {string} str * @param {ParserOptionsSpec} options * @category Parsers */ export function XYZ(str: string, options: ParserOptionsSpec) { options = options || {}; var atoms: any[][] & Record = [[]]; var assignbonds = options.assignBonds === undefined ? true : options.assignBonds; var lines = str.trimStart().split(/\r?\n|\r/); while (lines.length > 0) { if (lines.length < 3) break; var atomCount = parseInt(lines[0]); if (isNaN(atomCount) || atomCount <= 0) break; if (lines.length < atomCount + 2) break; var lattice_re = /Lattice\s*=\s*["\{\}]([^"\{\}]+)["\{\}]\s*/gi; var lattice_match = lattice_re.exec(lines[1]); if (lattice_match != null && lattice_match.length > 1) { var lattice = new Float32Array(lattice_match[1].split(/\s+/) as any); var matrix = new Matrix3( lattice[0], lattice[3], lattice[6], lattice[1], lattice[4], lattice[7], lattice[2], lattice[5], lattice[8] ); atoms.modelData = [{ cryst: { matrix: matrix } }]; } var offset = 2; var start = atoms[atoms.length - 1].length; var end = start + atomCount; for (var i = start; i < end; i++) { var line = lines[offset++]; var tokens = line.trim().split(/\s+/); var atom: Record = {}; atom.serial = i; var elem = tokens[0]; atom.atom = atom.elem = elem[0].toUpperCase() + elem.substring(1, 2).toLowerCase(); atom.x = parseFloat(tokens[1]); atom.y = parseFloat(tokens[2]); atom.z = parseFloat(tokens[3]); atom.hetflag = true; atom.bonds = []; atom.bondOrder = []; atom.properties = {}; atoms[atoms.length - 1][i] = atom; if (tokens.length >= 7) { atom.dx = parseFloat(tokens[4]); atom.dy = parseFloat(tokens[5]); atom.dz = parseFloat(tokens[6]); } } if (options.multimodel) { atoms.push([]); lines.splice(0, offset); } else { break; } } if (assignbonds) { for (let i = 0; i < atoms.length; i++) { assignBonds(atoms[i], options); } } if (options.onemol) { var temp = atoms; atoms = []; atoms.push(temp[0]); for (let i = 1; i < temp.length; i++) { let offset = atoms[0].length; for (let j = 0; j < temp[i].length; j++) { let a = temp[i][j]; for (let k = 0; k < a.bonds.length; k++) { a.bonds[k] = a.bonds[k] + offset; } a.index = atoms[0].length; a.serial = atoms[0].length; atoms[0].push(a); } } } return atoms; }