All files / src/parsers XYZ.ts

80.3% Statements 53/66
76.47% Branches 13/17
100% Functions 1/1
79.31% Lines 46/58

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102                        9x 9x   9x 9x 9x 11x 8x 8x 6x   5x 5x 5x                               5x 5x 5x 5x 250x 250x 250x 250x 250x 250x   250x 250x 250x 250x 250x 250x 250x 250x 250x             5x 2x 2x   3x       9x 8x 10x       9x 2x 2x 2x 2x 1x 1x                       9x    
import { ParserOptionsSpec } from './ParserOptionsSpec';
// read an XYZ file from str and return result
 
import { Matrix3 } from "../WebGL";
import { assignBonds } from "./utils/assignBonds";
 
/**
 * @param {string} str
 * @param {ParserOptionsSpec} options
 * @category Parsers
 */
export function XYZ(str: string, options: ParserOptionsSpec) {
  options = options || {};
  var atoms: any[][] & Record<string, any> = [[]];
  var assignbonds =
    options.assignBonds === undefined ? true : options.assignBonds;
  var lines = str.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]);
    Iif (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.replace(/^\s+/, "").replace(/\s+/g, " ").split(" ");
      var atom: Record<string, any> = {};
      atom.serial = i;
      var elem = tokens[0];
      atom.atom = atom.elem =
        elem[0].toUpperCase() + elem.substr(1, 1).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;
      Iif (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]);
    }
  }
 
  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;
}