molstar
Version:
A comprehensive macromolecular library.
98 lines (96 loc) • 4.43 kB
JavaScript
"use strict";
/**
* Copyright (c) 2025 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.attachRGroup = attachRGroup;
const ligand_graph_1 = require("../../extensions/json-cif/ligand-graph");
const utils_1 = require("../../extensions/json-cif/utils");
const linear_algebra_1 = require("../../mol-math/linear-algebra");
async function attachRGroup(pGraph, rgroupName, pAtomOrId) {
var _a, _b, _c;
const pAtom = pGraph.getAtom(pAtomOrId);
if (((_a = pAtom === null || pAtom === void 0 ? void 0 : pAtom.row) === null || _a === void 0 ? void 0 : _a.type_symbol) !== 'H') {
throw new Error('R-group attachment point must be a hydrogen atom.');
}
const { molfile, jsoncif: rgroupData } = await (0, utils_1.molfileToJSONCif)(RGroups[rgroupName]);
const attachIdx = (_b = molfile.attachmentPoints) === null || _b === void 0 ? void 0 : _b[0].atomIdx;
if (typeof attachIdx !== 'number') {
throw new Error('R-group attachment point not specified.');
}
// Compute and apply rGroup transformation
const pBonds = pGraph.getBonds(pAtom);
if (pBonds.length !== 1) {
throw new Error('R-group attachment point must have exactly 1 bond.');
}
const pDir = pGraph.getBondDirection(pBonds[0]);
const pPivot = pBonds[0].atom_2;
linear_algebra_1.Vec3.negate(pDir, pDir);
linear_algebra_1.Vec3.normalize(pDir, pDir);
const rGraph = new ligand_graph_1.JSONCifLigandGraph(rgroupData.dataBlocks[0]);
const rAtom = rGraph.getAtomAtIndex(attachIdx - 1);
if (((_c = rAtom.row) === null || _c === void 0 ? void 0 : _c.type_symbol) !== 'R#') {
throw new Error('R-group attachment point is not a R# atom.');
}
const rCoords = rGraph.getAtomCoords(rAtom);
const rBonds = rGraph.getBonds(rAtom);
if (rBonds.length !== 1) {
throw new Error('R-group R# atom must have exactly 1 bond.');
}
const rPivot = rGraph.getAtom(rBonds[0].atom_2);
const rDir = rGraph.getBondDirection(rBonds[0]);
linear_algebra_1.Vec3.normalize(rDir, rDir);
const rotation = linear_algebra_1.Vec3.makeRotation((0, linear_algebra_1.Mat4)(), rDir, pDir);
const translation = linear_algebra_1.Mat4.fromTranslation((0, linear_algebra_1.Mat4)(), linear_algebra_1.Vec3.sub((0, linear_algebra_1.Vec3)(), pGraph.getAtomCoords(pPivot), rCoords));
const C = linear_algebra_1.Mat4.fromTranslation((0, linear_algebra_1.Mat4)(), linear_algebra_1.Vec3.negate((0, linear_algebra_1.Vec3)(), rCoords));
const CT = linear_algebra_1.Mat4.fromTranslation((0, linear_algebra_1.Mat4)(), rCoords);
const T0 = linear_algebra_1.Mat4.mul3((0, linear_algebra_1.Mat4)(), CT, rotation, C);
const T = linear_algebra_1.Mat4.mul((0, linear_algebra_1.Mat4)(), translation, T0);
rGraph.transformCoords(T);
// Merge the two graphs
pGraph.removeAtom(pAtom);
rGraph.removeAtom(rAtom);
const newAtomMap = new Map();
// Add atoms
for (const a of rGraph.atoms) {
const newAtom = pGraph.addAtom(a.row);
newAtomMap.set(a.key, newAtom);
if (a === rPivot) {
pGraph.addOrUpdateBond(pPivot, newAtom, rBonds[0].props);
}
}
// Add bonds
for (const a of rGraph.atoms) {
if (a === rAtom)
continue;
const bonds = rGraph.getBonds(a);
const atom1 = newAtomMap.get(a.key);
for (const b of bonds) {
if (b.atom_2 === rAtom)
continue;
const atom2 = newAtomMap.get(b.atom_2.key);
pGraph.addOrUpdateBond(atom1, atom2, b.props);
}
}
return pGraph;
}
// Assumes the "attachment point (M APO)" points to a hydrogen atom that gets removed
// when the R-group is attached.
const RGroups = {
CH3: `CH3
-OEChem-05072507373D
5 4 0 0 0 0 0 0 0999 V2000
0.0000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
0.5541 0.7996 0.4965 R# 0 0 0 0 0 0 0 0 0 0 0 0
0.6833 -0.8134 -0.2536 H 0 0 0 0 0 0 0 0 0 0 0 0
-0.7782 -0.3735 0.6692 H 0 0 0 0 0 0 0 0 0 0 0 0
-0.4593 0.3874 -0.9121 H 0 0 0 0 0 0 0 0 0 0 0 0
1 2 1 0 0 0 0
1 3 1 0 0 0 0
1 4 1 0 0 0 0
1 5 1 0 0 0 0
M APO 1 2 1
M END`
};