All files / src/parsers/utils assignBonds.ts

94.11% Statements 64/68
88.88% Branches 16/18
100% Functions 2/2
93.22% Lines 55/59

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 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119                321x   15041x     321x 321x   321x 15041x 15041x 15041x 15041x 15041x 977x   15041x 2127x   15041x 4076x     15041x     321x 14976x 58247x 58247x 263160x   263160x   20726x 20726x 20726x 18862x 18862x 18862x 18862x 1864x     1864x                 321x                             321x   977x 977x   2127x 2127x   4076x 4076x   4076x 15041x 15041x 176836x 176836x 72906x 70360x 70360x 70360x 70360x           4076x 52988x 52988x         38012x   14976x 14976x            
import { areConnected } from "./areConnected";
 
/*
 * @param {AtomSpec[]} atoms
 */
export function assignBonds(atoms) {
  // assign bonds - yuck, can't count on connect records
 
  for (var i = 0, n = atoms.length; i < n; i++) {
    // Don't reindex if atoms are already indexed
    if (!atoms[i].index) atoms[i].index = i;
  }
 
  var grid = {};
  var MAX_BOND_LENGTH = 4.95; // (largest bond length, Cs) 2.25 * 2 * 1.1 (fudge factor)
 
  for (var index = 0; index < atoms.length; index++) {
    var atom = atoms[index];
    var x = Math.floor(atom.x / MAX_BOND_LENGTH);
    var y = Math.floor(atom.y / MAX_BOND_LENGTH);
    var z = Math.floor(atom.z / MAX_BOND_LENGTH);
    if (!grid[x]) {
      grid[x] = {};
    }
    if (!grid[x][y]) {
      grid[x][y] = {};
    }
    if (!grid[x][y][z]) {
      grid[x][y][z] = [];
    }
 
    grid[x][y][z].push(atom);
  }
 
  var findConnections = function (points, otherPoints) {
    for (var i = 0; i < points.length; i++) {
      var atom1 = points[i];
      for (var j = 0; j < otherPoints.length; j++) {
        var atom2 = otherPoints[j];
 
        if (areConnected(atom1, atom2)) {
          //gracefully handle one-sided bonds
          var a2i = atom1.bonds.indexOf(atom2.index);
          var a1i = atom2.bonds.indexOf(atom1.index);
          if (a2i == -1 && a1i == -1) {
            atom1.bonds.push(atom2.index);
            atom1.bondOrder.push(1);
            atom2.bonds.push(atom1.index);
            atom2.bondOrder.push(1);
          } else Iif (a2i == -1) {
            atom1.bonds.push(atom2.index);
            atom1.bondOrder.push(atom2.bondOrder[a1i]);
          } else Iif (a1i == -1) {
            atom2.bonds.push(atom1.index);
            atom2.bondOrder.push(atom1.bondOrder[a2i]);
          }
        }
      }
    }
  };
 
  /*const*/ var OFFSETS = [
    { x: 0, y: 0, z: 1 },
    { x: 0, y: 1, z: -1 },
    { x: 0, y: 1, z: 0 },
    { x: 0, y: 1, z: 1 },
    { x: 1, y: -1, z: -1 },
    { x: 1, y: -1, z: 0 },
    { x: 1, y: -1, z: 1 },
    { x: 1, y: 0, z: -1 },
    { x: 1, y: 0, z: 0 },
    { x: 1, y: 0, z: 1 },
    { x: 1, y: 1, z: -1 },
    { x: 1, y: 1, z: 0 },
    { x: 1, y: 1, z: 1 },
  ];
  for (let x in grid) {
    // @ts-ignore
    x = parseInt(x);
    for (let y in grid[x]) {
      // @ts-ignore
      y = parseInt(y);
      for (let z in grid[x][y]) {
        // @ts-ignore
        z = parseInt(z);
        let points = grid[x][y][z];
 
        for (let i = 0; i < points.length; i++) {
          let atom1 = points[i];
          for (let j = i + 1; j < points.length; j++) {
            let atom2 = points[j];
            if (areConnected(atom1, atom2)) {
              if (atom1.bonds.indexOf(atom2.index) == -1) {
                atom1.bonds.push(atom2.index);
                atom1.bondOrder.push(1);
                atom2.bonds.push(atom1.index);
                atom2.bondOrder.push(1);
              }
            }
          }
        }
 
        for (let o = 0; o < OFFSETS.length; o++) {
          let offset = OFFSETS[o];
          if (
            !grid[x + offset.x] ||
            !grid[x + offset.x][y + offset.y] ||
            !grid[x + offset.x][y + offset.y][z + offset.z]
          )
            continue;
 
          let otherPoints = grid[x + offset.x][y + offset.y][z + offset.z];
          findConnections(points, otherPoints);
        }
      }
    }
  }
}