mirror of
https://github.com/rdkit/rdkit.git
synced 2026-06-04 21:54:27 +08:00
* - When depictions are made using the useMolBlockWedging flag, make sure that kekulization is done after original wedging has been applied to reduce the odds that bond wedges are placed on double bonds - Refactored MinimalLib code to avoid code duplication - get_molblock() should reapplyMolBlockWedging on a copy of the passed molecule rather than on the original - Added unit tests * Update Code/MinimalLib/jswrapper.cpp Co-authored-by: Greg Landrum <greg.landrum@gmail.com> --------- Co-authored-by: ptosco <paolo.tosco@novartis.com> Co-authored-by: Greg Landrum <greg.landrum@gmail.com>
3121 lines
119 KiB
JavaScript
3121 lines
119 KiB
JavaScript
//
|
|
//
|
|
// Copyright (C) 2019 Greg Landrum
|
|
//
|
|
// @@ All Rights Reserved @@
|
|
// This file is part of the RDKit.
|
|
// The contents are covered by the terms of the BSD license
|
|
// which is included in the file license.txt, found at the root
|
|
// of the RDKit source tree.
|
|
//
|
|
|
|
const assert = require('assert');
|
|
const {
|
|
performance
|
|
} = require('perf_hooks');
|
|
// the default path to RDKit_minimal.js can be overridden through
|
|
// the RDKIT_MINIMAL_JS variable if needed
|
|
const minimalLib = process.env.RDKIT_MINIMAL_JS || '../demo/RDKit_minimal.js';
|
|
console.log('Loading ' + minimalLib);
|
|
var initRDKitModule = require(minimalLib);
|
|
var RDKitModule;
|
|
const fs = require('fs');
|
|
const readline = require('readline');
|
|
|
|
const extractBondCoords = (svg, bondDetail) => {
|
|
const getStartEndCoords = (bond) => {
|
|
const m = bond.match(/^.*\s+d='M\s+([^,]+),([^ ]+)\s+L\s+([^,]+),([^ ]+)'.*$/);
|
|
return [[m[1], m[2]], [m[3], m[4]]];
|
|
};
|
|
const bond = svg.split('\n').filter(line => line.includes(bondDetail));
|
|
assert(bond.length === 1);
|
|
return getStartEndCoords(bond[0]);
|
|
}
|
|
const angleDegBetweenVectors = (v1, v2) => 180 / Math.PI * Math.acos((v1[0] * v2[0] + v1[1] * v2[1])
|
|
/ Math.sqrt((v1[0] * v1[0] + v1[1] * v1[1]) * (v2[0] * v2[0] + v2[1] * v2[1])));
|
|
|
|
// the goal here isn't to be comprehensive (the RDKit has tests for that),
|
|
// just to make sure that the wrappers are working as expected
|
|
function test_basics() {
|
|
var bmol = null;
|
|
try {
|
|
bmol = RDKitModule.get_mol("c1ccccc");
|
|
assert(bmol === null);
|
|
} catch {
|
|
assert(bmol === null);
|
|
}
|
|
var mol = RDKitModule.get_mol("c1ccccc1O");
|
|
assert(mol !== null);
|
|
assert.equal(mol.get_smiles(),"Oc1ccccc1");
|
|
assert.equal(mol.get_inchi(),"InChI=1S/C6H6O/c7-6-4-2-1-3-5-6/h1-5,7H");
|
|
assert.equal(RDKitModule.get_inchikey_for_inchi(mol.get_inchi()),"ISWSIDIOOBJBQZ-UHFFFAOYSA-N");
|
|
|
|
assert.equal(mol.get_inchi("-FixedH"),"InChI=1/C6H6O/c7-6-4-2-1-3-5-6/h1-5,7H");
|
|
assert.equal(RDKitModule.get_inchikey_for_inchi(mol.get_inchi("-FixedH")),"ISWSIDIOOBJBQZ-UHFFFAOYNA-N");
|
|
|
|
var mb = mol.get_molblock();
|
|
assert(mb.search("M END")>0);
|
|
var mol2 = RDKitModule.get_mol(mb);
|
|
assert(mol2 !== null);
|
|
assert.equal(mol2.get_smiles(),"Oc1ccccc1");
|
|
|
|
var mjson = mol.get_json();
|
|
assert(mjson.search("rdkitjson")>0);
|
|
var mol3 = RDKitModule.get_mol(mjson);
|
|
assert(mol3 !== null);
|
|
assert.equal(mol3.get_smiles(),"Oc1ccccc1");
|
|
|
|
var descrs = JSON.parse(mol.get_descriptors());
|
|
assert.equal(descrs.NumAromaticRings,1);
|
|
assert.equal(descrs.NumRings,1);
|
|
assert.equal(descrs.amw,94.11299);
|
|
|
|
var checkStringBinaryFpIdentity = (stringFp, binaryFp) => {
|
|
assert.equal(binaryFp.length, Math.ceil(stringFp.length / 8));
|
|
for (var i = 0, c = 0; i < binaryFp.length; ++i) {
|
|
var byte = 0;
|
|
for (var j = 0; j < 8; ++j, ++c) {
|
|
if (stringFp[c] === "1") {
|
|
byte |= (1 << j);
|
|
}
|
|
}
|
|
assert.equal(byte, binaryFp[i]);
|
|
}
|
|
};
|
|
|
|
{
|
|
var fp1 = mol.get_morgan_fp();
|
|
assert.equal(fp1.length, 2048);
|
|
assert.equal((fp1.match(/1/g)||[]).length, 11);
|
|
var fp1Uint8Array = mol.get_morgan_fp_as_uint8array();
|
|
checkStringBinaryFpIdentity(fp1, fp1Uint8Array);
|
|
var fp2 = mol.get_morgan_fp(JSON.stringify({ radius: 0, nBits: 512 }));
|
|
assert.equal(fp2.length, 512);
|
|
assert.equal((fp2.match(/1/g)||[]).length, 3);
|
|
var fp2Uint8Array = mol.get_morgan_fp_as_uint8array(JSON.stringify({ radius: 0, nBits: 512 }));
|
|
checkStringBinaryFpIdentity(fp2, fp2Uint8Array);
|
|
}
|
|
|
|
{
|
|
var fp1 = mol.get_pattern_fp();
|
|
assert.equal(fp1.length, 2048);
|
|
assert.equal((fp1.match(/1/g)||[]).length, 73);
|
|
var fp1Uint8Array = mol.get_pattern_fp_as_uint8array();
|
|
checkStringBinaryFpIdentity(fp1, fp1Uint8Array);
|
|
var fp2 = mol.get_pattern_fp(JSON.stringify({ nBits: 256 }));
|
|
assert.equal(fp2.length, 256);
|
|
assert.equal((fp2.match(/1/g)||[]).length, 65);
|
|
var fp2Uint8Array = mol.get_pattern_fp_as_uint8array(JSON.stringify({ nBits: 256 }));
|
|
checkStringBinaryFpIdentity(fp2, fp2Uint8Array);
|
|
}
|
|
|
|
{
|
|
var fp1 = mol.get_topological_torsion_fp();
|
|
assert.equal(fp1.length, 2048);
|
|
assert.equal((fp1.match(/1/g)||[]).length, 8);
|
|
var fp1Uint8Array = mol.get_topological_torsion_fp_as_uint8array();
|
|
checkStringBinaryFpIdentity(fp1, fp1Uint8Array);
|
|
var fp2 = mol.get_topological_torsion_fp(JSON.stringify({ nBits: 512 }));
|
|
assert.equal(fp2.length, 512);
|
|
assert.equal((fp2.match(/1/g)||[]).length, 8);
|
|
var fp2Uint8Array = mol.get_topological_torsion_fp_as_uint8array(JSON.stringify({ nBits: 512 }));
|
|
checkStringBinaryFpIdentity(fp2, fp2Uint8Array);
|
|
}
|
|
|
|
{
|
|
var fp1 = mol.get_rdkit_fp();
|
|
assert.equal(fp1.length, 2048);
|
|
assert.equal((fp1.match(/1/g)||[]).length, 38);
|
|
var fp1Uint8Array = mol.get_rdkit_fp_as_uint8array();
|
|
checkStringBinaryFpIdentity(fp1, fp1Uint8Array);
|
|
var fp2 = mol.get_rdkit_fp(JSON.stringify({ nBits: 512 }));
|
|
assert.equal(fp2.length, 512);
|
|
assert.equal((fp2.match(/1/g)||[]).length, 37);
|
|
var fp2Uint8Array = mol.get_rdkit_fp_as_uint8array(JSON.stringify({ nBits: 512 }));
|
|
checkStringBinaryFpIdentity(fp2, fp2Uint8Array);
|
|
var fp3 = mol.get_rdkit_fp(JSON.stringify({ nBits: 512, minPath: 2 }));
|
|
assert.equal(fp3.length, 512);
|
|
assert.equal((fp3.match(/1/g)||[]).length, 34);
|
|
var fp3Uint8Array = mol.get_rdkit_fp_as_uint8array(JSON.stringify({ nBits: 512, minPath: 2 }));
|
|
checkStringBinaryFpIdentity(fp3, fp3Uint8Array);
|
|
var fp4 = mol.get_rdkit_fp(JSON.stringify({ nBits: 512, minPath: 2, maxPath: 4 }));
|
|
assert.equal(fp4.length, 512);
|
|
assert.equal((fp4.match(/1/g)||[]).length, 16);
|
|
var fp4Uint8Array = mol.get_rdkit_fp_as_uint8array(JSON.stringify({ nBits: 512, minPath: 2, maxPath: 4 }));
|
|
checkStringBinaryFpIdentity(fp4, fp4Uint8Array);
|
|
}
|
|
|
|
{
|
|
var fp1 = mol.get_atom_pair_fp();
|
|
assert.equal(fp1.length, 2048);
|
|
assert.equal((fp1.match(/1/g)||[]).length, 19);
|
|
var fp1Uint8Array = mol.get_atom_pair_fp_as_uint8array();
|
|
checkStringBinaryFpIdentity(fp1, fp1Uint8Array);
|
|
var fp2 = mol.get_atom_pair_fp(JSON.stringify({ nBits: 512 }));
|
|
assert.equal(fp2.length, 512);
|
|
assert.equal((fp2.match(/1/g)||[]).length, 19);
|
|
var fp2Uint8Array = mol.get_atom_pair_fp_as_uint8array(JSON.stringify({ nBits: 512 }));
|
|
checkStringBinaryFpIdentity(fp2, fp2Uint8Array);
|
|
var fp3 = mol.get_atom_pair_fp(JSON.stringify({ nBits: 512, minLength: 2 }));
|
|
assert.equal(fp3.length, 512);
|
|
assert.equal((fp3.match(/1/g)||[]).length, 13);
|
|
var fp3Uint8Array = mol.get_atom_pair_fp_as_uint8array(JSON.stringify({ nBits: 512, minLength: 2 }));
|
|
checkStringBinaryFpIdentity(fp3, fp3Uint8Array);
|
|
var fp4 = mol.get_atom_pair_fp(JSON.stringify({ nBits: 512, minLength: 2, maxLength: 3 }));
|
|
assert.equal(fp4.length, 512);
|
|
assert.equal((fp4.match(/1/g)||[]).length, 12);
|
|
var fp4Uint8Array = mol.get_atom_pair_fp_as_uint8array(JSON.stringify({ nBits: 512, minLength: 2, maxLength: 3 }));
|
|
checkStringBinaryFpIdentity(fp4, fp4Uint8Array);
|
|
}
|
|
|
|
{
|
|
var fp1 = mol.get_maccs_fp();
|
|
assert.equal(fp1.length, 167);
|
|
assert.equal((fp1.match(/1/g)||[]).length, 10);
|
|
var fp1Uint8Array = mol.get_maccs_fp_as_uint8array();
|
|
checkStringBinaryFpIdentity(fp1, fp1Uint8Array);
|
|
}
|
|
|
|
if (typeof Object.getPrototypeOf(mol).get_avalon_fp === 'function') {
|
|
var fp1 = mol.get_avalon_fp();
|
|
assert.equal(fp1.length, 512);
|
|
assert.equal((fp1.match(/1/g)||[]).length, 19);
|
|
var fp1Uint8Array = mol.get_avalon_fp_as_uint8array();
|
|
checkStringBinaryFpIdentity(fp1, fp1Uint8Array);
|
|
var fp2 = mol.get_avalon_fp(JSON.stringify({ nBits: 2048 }));
|
|
assert.equal(fp2.length, 2048);
|
|
assert.equal((fp2.match(/1/g)||[]).length, 20);
|
|
var fp2Uint8Array = mol.get_avalon_fp_as_uint8array(JSON.stringify({ nBits: 2048 }));
|
|
checkStringBinaryFpIdentity(fp2, fp2Uint8Array);
|
|
}
|
|
|
|
var svg = mol.get_svg();
|
|
assert(svg.search("svg")>0);
|
|
|
|
var qmol = RDKitModule.get_qmol("Oc(c)c");
|
|
assert(qmol !== null);
|
|
var match = mol.get_substruct_match(qmol);
|
|
var pmatch = JSON.parse(match);
|
|
assert.equal(pmatch.atoms.length,4);
|
|
assert.equal(pmatch.atoms[0],6);
|
|
var svg2 = mol.get_svg_with_highlights(match);
|
|
assert(svg2.search("svg")>0);
|
|
assert(svg.search("#FF7F7F")<0);
|
|
assert(svg2.search("#FF7F7F")>0);
|
|
}
|
|
|
|
function test_molblock_nostrict() {
|
|
var molblock = `
|
|
MJ201100
|
|
|
|
10 10 0 0 0 0 0 0 0 0999 V2000
|
|
-1.2946 0.5348 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-2.0090 0.1223 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-2.0090 -0.7027 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-1.2946 -1.1152 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.5801 -0.7027 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.5801 0.1223 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
0.5467 1.2493 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0
|
|
0.1342 0.5348 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
0.5467 -0.1796 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.6907 0.5348 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0
|
|
1 2 2 0 0 0 0
|
|
2 3 1 0 0 0 0
|
|
3 4 2 0 0 0 0
|
|
4 5 1 0 0 0 0
|
|
5 6 2 0 0 0 0
|
|
6 1 1 0 0 0 0
|
|
6 8 1 0 0 0 0
|
|
7 8 1 0 0 0 0
|
|
8 9 1 0 0 0 0
|
|
8 10 1 0 0 0 0
|
|
M STY 1 1 SUP
|
|
M SAL 1 4 7 8 9 10
|
|
M SMT 1 CF3
|
|
M SBL 1 1 7
|
|
M SAP 1 1 8
|
|
M END`;
|
|
var mol = RDKitModule.get_mol(molblock);
|
|
assert(mol !== null);
|
|
var mb = mol.get_molblock();
|
|
assert.equal(mb.includes("M SAP 1 1 8 6"), true);
|
|
var qmol = RDKitModule.get_qmol(molblock);
|
|
assert(qmol !== null);
|
|
var qmb = qmol.get_molblock();
|
|
assert.equal(qmb.includes("M SAP 1 1 8 6"), true);
|
|
}
|
|
|
|
function test_molblock_rgp() {
|
|
var molblock = `
|
|
MJ190400
|
|
|
|
9 9 0 0 0 0 0 0 0 0999 V2000
|
|
-6.5623 0.3105 0.0000 R# 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-5.8478 -0.1019 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-5.1333 0.3105 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-4.4188 -0.1019 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-4.4188 -0.9269 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-5.1333 -1.3394 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-5.8478 -0.9269 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-3.7043 -1.3394 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-2.9898 -0.9268 0.0000 R# 0 0 0 0 0 0 0 0 0 0 0 0
|
|
3 4 4 0 0 0 0
|
|
4 5 4 0 0 0 0
|
|
5 6 4 0 0 0 0
|
|
6 7 4 0 0 0 0
|
|
2 3 4 0 0 0 0
|
|
2 7 4 0 0 0 0
|
|
5 8 1 0 0 0 0
|
|
8 9 1 0 0 0 0
|
|
1 2 1 0 0 0 0
|
|
M RGP 2 1 2 9 1
|
|
M END`;
|
|
var mol = RDKitModule.get_mol(molblock);
|
|
assert(mol !== null);
|
|
}
|
|
|
|
function test_get_aromatic_kekule_form() {
|
|
const aromRegExp = / \d \d 4 \d\n/g;
|
|
const kekRegExp = / \d \d [12] \d\n/g;
|
|
var mol = RDKitModule.get_mol("c1ccccc1");
|
|
var molblock = mol.get_molblock();
|
|
assert (molblock.match(aromRegExp) === null);
|
|
assert (molblock.match(kekRegExp).length === 6);
|
|
var molblock = mol.get_kekule_form();
|
|
assert (molblock.match(aromRegExp) === null);
|
|
assert (molblock.match(kekRegExp).length === 6);
|
|
molblock = mol.get_aromatic_form();
|
|
assert (molblock.match(aromRegExp).length === 6);
|
|
assert (molblock.match(kekRegExp) === null);
|
|
mol.delete();
|
|
mol = RDKitModule.get_qmol(`
|
|
MJ201100
|
|
|
|
6 6 0 0 0 0 0 0 0 0999 V2000
|
|
-0.6473 0.8696 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-1.3617 0.4571 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-1.3617 -0.3679 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.6473 -0.7804 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
0.0671 -0.3679 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
0.0671 0.4571 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
1 2 4 0 0 0 0
|
|
2 3 4 0 0 0 0
|
|
3 4 4 0 0 0 0
|
|
4 5 4 0 0 0 0
|
|
5 6 4 0 0 0 0
|
|
6 1 4 0 0 0 0
|
|
M END
|
|
`);
|
|
molblock = mol.get_aromatic_form();
|
|
assert (molblock.match(aromRegExp).length === 6);
|
|
assert (molblock.match(kekRegExp) === null);
|
|
molblock = mol.get_kekule_form();
|
|
assert (molblock.match(aromRegExp) === null);
|
|
assert (molblock.match(kekRegExp).length === 6);
|
|
mol.delete();
|
|
mol = RDKitModule.get_qmol(`
|
|
MJ201100
|
|
|
|
6 6 0 0 0 0 0 0 0 0999 V2000
|
|
-0.6473 0.8696 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-1.3617 0.4571 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-1.3617 -0.3679 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.6473 -0.7804 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
0.0671 -0.3679 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
0.0671 0.4571 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
1 2 2 0 0 0 0
|
|
2 3 1 0 0 0 0
|
|
3 4 2 0 0 0 0
|
|
4 5 1 0 0 0 0
|
|
5 6 2 0 0 0 0
|
|
6 1 1 0 0 0 0
|
|
M END
|
|
`);
|
|
molblock = mol.get_molblock(JSON.stringify({ kekulize: false }));
|
|
assert (molblock.match(aromRegExp) === null);
|
|
assert (molblock.match(kekRegExp).length === 6);
|
|
mol.convert_to_aromatic_form();
|
|
molblock = mol.get_molblock(JSON.stringify({ kekulize: false }));
|
|
assert (molblock.match(aromRegExp).length === 6);
|
|
assert (molblock.match(kekRegExp) === null);
|
|
mol.convert_to_kekule_form();
|
|
molblock = mol.get_molblock(JSON.stringify({ kekulize: false }));
|
|
assert (molblock.match(aromRegExp) === null);
|
|
assert (molblock.match(kekRegExp).length === 6);
|
|
mol.delete();
|
|
}
|
|
|
|
function test_sketcher_services() {
|
|
var mol = RDKitModule.get_mol("C[C@](F)(Cl)/C=C/C(F)Br");
|
|
assert(mol !== null);
|
|
var tags = mol.get_stereo_tags();
|
|
assert.equal(tags,'{"CIP_atoms":[[1,"(S)"],[6,"(?)"]],"CIP_bonds":[[4,5,"(E)"]]}');
|
|
}
|
|
|
|
function test_sketcher_services2() {
|
|
var mol = RDKitModule.get_mol("c1ccccc1");
|
|
assert(mol !== null);
|
|
var molb = mol.add_hs();
|
|
assert(molb.search(" H ")>0);
|
|
assert.equal((molb.match(/ H /g) || []).length,6);
|
|
|
|
var mol2 = RDKitModule.get_mol(molb);
|
|
assert(mol2 !== null);
|
|
var molb2 = mol2.get_molblock();
|
|
assert(molb2.search(" H ")>0);
|
|
assert.equal((molb2.match(/ H /g) || []).length,6);
|
|
|
|
molb2 = mol2.remove_hs();
|
|
assert(molb2.search(" H ")<0);
|
|
}
|
|
|
|
function test_abbreviations() {
|
|
var bmol = RDKitModule.get_mol("C1CC(C(F)(F)F)C1");
|
|
assert(bmol !== null);
|
|
var mapping = bmol.condense_abbreviations();
|
|
assert.equal(mapping, JSON.stringify({
|
|
atoms: [0, 1, 2, 3, 4, 5, 6, 7],
|
|
bonds: [0, 1, 2, 3, 4, 5, 6, 7],
|
|
}));
|
|
assert.equal(bmol.get_cxsmiles(),"FC(F)(F)C1CCC1");
|
|
mapping = bmol.condense_abbreviations(1.0,false);
|
|
assert.equal(mapping, JSON.stringify({
|
|
atoms: [0, 1, 2, 3, 7],
|
|
bonds: [0, 1, 2, 6, 7],
|
|
}));
|
|
assert.equal(bmol.get_cxsmiles(),"*C1CCC1 |$CF3;;;;$|");
|
|
}
|
|
|
|
function test_substruct_library(done) {
|
|
done.test_substruct_library = false;
|
|
var query = RDKitModule.get_qmol('C1CCCCN1');
|
|
var nonExistingQuery = RDKitModule.get_mol('O=C(O)C(c1ccc(cc1)CCN4CCC(c2nc3ccccc3n2CCOCC)CC4)(C)C');
|
|
const numBitOptions = [-1, 0];
|
|
var patternFpArray = [];
|
|
numBitOptions.forEach((numBits, optIdx) => {
|
|
var smiReader = readline.createInterface({
|
|
input: fs.createReadStream(__dirname + '/../../GraphMol/test_data/compounds.smi')
|
|
});
|
|
var sslib = numBits < 0 ? new RDKitModule.SubstructLibrary() : new RDKitModule.SubstructLibrary(numBits);
|
|
assert.equal(sslib.count_matches(query), 0);
|
|
assert.equal(sslib.get_matches(query), JSON.stringify([]));
|
|
assert.equal(sslib.get_matches_as_uint32array(query).length, 0);
|
|
// var t0 = performance.now()
|
|
// console.log('Started adding trusted SMILES');
|
|
var matches = [];
|
|
var expectedMatches = [39, 64, 80, 127, 128, 234, 240];
|
|
var i = 0;
|
|
var trustedSmiArray = []
|
|
smiReader.on('line', (smi) => {
|
|
sslib.add_trusted_smiles(smi);
|
|
var mol = RDKitModule.get_mol(smi);
|
|
var res = JSON.parse(mol.get_substruct_match(query));
|
|
if (res.atoms) {
|
|
matches.push(i);
|
|
}
|
|
++i;
|
|
mol.delete();
|
|
});
|
|
smiReader.on('close', () => {
|
|
// var t1 = performance.now();
|
|
// console.log('Finished adding trusted SMILES took ' + (t1 - t0) / 1000 + ' seconds');
|
|
for (var i = 0; i < sslib.size(); ++i) {
|
|
trustedSmiArray.push(sslib.get_trusted_smiles(i));
|
|
let excRaised = false;
|
|
try {
|
|
var fp = sslib.get_pattern_fp_as_uint8array(i);
|
|
patternFpArray.push(fp);
|
|
} catch (e) {
|
|
// this is expected to fail when numBits === 0
|
|
excRaised = true;
|
|
}
|
|
assert((excRaised && numBits === 0) || (!excRaised && numBits !== 0));
|
|
}
|
|
assert.equal(trustedSmiArray.length, sslib.size());
|
|
assert.equal(patternFpArray.length, sslib.size());
|
|
assert.equal(trustedSmiArray.length, patternFpArray.length);
|
|
var sslib2 = new RDKitModule.SubstructLibrary();
|
|
for (var i = 0; i < sslib.size(); ++i) {
|
|
sslib2.add_trusted_smiles_and_pattern_fp(trustedSmiArray[i], patternFpArray[i]);
|
|
}
|
|
assert.equal(sslib.size(), sslib2.size());
|
|
{
|
|
assert.equal(sslib.count_matches(query, false), 7);
|
|
var sslibMatches = sslib.get_matches(query);
|
|
assert.equal(sslibMatches, JSON.stringify(expectedMatches));
|
|
assert.equal(sslibMatches, JSON.stringify(matches));
|
|
var sslibMatchesUInt32Array = sslib.get_matches_as_uint32array(query);
|
|
assert.equal(sslibMatchesUInt32Array.length, expectedMatches.length);
|
|
for (var i = 0; i < expectedMatches.length; ++i) {
|
|
assert.equal(sslibMatchesUInt32Array[i], expectedMatches[i]);
|
|
}
|
|
}
|
|
{
|
|
assert.equal(sslib.count_matches(nonExistingQuery, false), 0);
|
|
var sslibMatches = sslib.get_matches(nonExistingQuery);
|
|
assert.equal(sslibMatches, JSON.stringify([]));
|
|
var sslibMatchesUInt32Array = sslib.get_matches_as_uint32array(nonExistingQuery);
|
|
assert.equal(sslibMatchesUInt32Array.length, 0);
|
|
}
|
|
{
|
|
assert.equal(sslib2.count_matches(query, false), 7);
|
|
var sslib2Matches = sslib2.get_matches(query);
|
|
assert.equal(sslib2Matches, JSON.stringify(expectedMatches));
|
|
assert.equal(sslib2Matches, JSON.stringify(matches));
|
|
var sslib2MatchesUInt32Array = sslib2.get_matches_as_uint32array(query);
|
|
assert.equal(sslib2MatchesUInt32Array.length, expectedMatches.length);
|
|
for (var i = 0; i < expectedMatches.length; ++i) {
|
|
assert.equal(sslib2MatchesUInt32Array[i], expectedMatches[i]);
|
|
}
|
|
}
|
|
{
|
|
assert.equal(sslib2.count_matches(nonExistingQuery, false), 0);
|
|
var sslib2Matches = sslib2.get_matches(nonExistingQuery);
|
|
assert.equal(sslib2Matches, JSON.stringify([]));
|
|
var sslib2MatchesUInt32Array = sslib2.get_matches_as_uint32array(nonExistingQuery);
|
|
assert.equal(sslib2MatchesUInt32Array.length, 0);
|
|
}
|
|
sslib.delete();
|
|
sslib2.delete();
|
|
if (optIdx === numBitOptions.length - 1) {
|
|
done.test_substruct_library = true;
|
|
query.delete();
|
|
nonExistingQuery.delete();
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
function test_substruct_library_merge_hs() {
|
|
var sslib = new RDKitModule.SubstructLibrary();
|
|
var mol1 = RDKitModule.get_mol("c1ccccc1");
|
|
var mol2 = RDKitModule.get_mol("Cc1ccccc1");
|
|
sslib.add_trusted_smiles(mol1.get_smiles());
|
|
sslib.add_trusted_smiles(mol2.get_smiles());
|
|
var query = RDKitModule.get_mol(`
|
|
MJ201100 2D
|
|
|
|
6 6 0 0 0 0 0 0 0 0999 V2000
|
|
-1.0491 0.7134 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-1.7635 0.3009 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-1.7635 -0.5241 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-1.0491 -0.9366 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.3346 -0.5241 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.3346 0.3009 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
2 3 1 0 0 0 0
|
|
5 6 2 0 0 0 0
|
|
1 2 2 0 0 0 0
|
|
6 1 1 0 0 0 0
|
|
3 4 2 0 0 0 0
|
|
4 5 1 0 0 0 0
|
|
M END`);
|
|
assert.equal(sslib.get_matches(query), JSON.stringify([0, 1]));
|
|
var query_hs = RDKitModule.get_mol(query.add_hs());
|
|
assert.equal(sslib.get_matches(query_hs), JSON.stringify([]));
|
|
query_hs = RDKitModule.get_mol(query_hs.get_molblock(), JSON.stringify({ mergeQueryHs: true }));
|
|
assert.equal(sslib.get_matches(query_hs), JSON.stringify([0]));
|
|
}
|
|
|
|
function test_substruct_library_empty_mols() {
|
|
var sslib = new RDKitModule.SubstructLibrary();
|
|
var mol1 = RDKitModule.get_mol("");
|
|
var mol2 = RDKitModule.get_mol("");
|
|
sslib.add_trusted_smiles(mol1.get_smiles());
|
|
sslib.add_trusted_smiles(mol2.get_smiles());
|
|
var query = RDKitModule.get_mol("C");
|
|
assert.equal(sslib.get_matches(query), JSON.stringify([]));
|
|
var empty_query = RDKitModule.get_mol("");
|
|
assert.equal(sslib.get_matches(empty_query), JSON.stringify([]));
|
|
}
|
|
|
|
function test_substruct_library_empty_query() {
|
|
var sslib = new RDKitModule.SubstructLibrary();
|
|
var mol1 = RDKitModule.get_mol("C");
|
|
var mol2 = RDKitModule.get_mol("CC");
|
|
sslib.add_trusted_smiles(mol1.get_smiles());
|
|
sslib.add_trusted_smiles(mol2.get_smiles());
|
|
var query = RDKitModule.get_mol("");
|
|
assert.equal(sslib.get_matches(query), JSON.stringify([]));
|
|
}
|
|
|
|
function test_substruct_library_empty_lib() {
|
|
var sslib = new RDKitModule.SubstructLibrary();
|
|
var query = RDKitModule.get_mol("C");
|
|
assert.equal(sslib.get_matches(query), JSON.stringify([]));
|
|
var empty_query = RDKitModule.get_mol("");
|
|
assert.equal(sslib.get_matches(empty_query), JSON.stringify([]));
|
|
}
|
|
|
|
function test_generate_aligned_coords() {
|
|
var smiles = "CCC";
|
|
var mol = RDKitModule.get_mol(smiles);
|
|
var template = "CC";
|
|
var qmol = RDKitModule.get_mol(template);
|
|
assert.equal(mol.generate_aligned_coords(qmol, JSON.stringify({useCoordGen: true})), "");
|
|
}
|
|
|
|
function test_isotope_labels() {
|
|
var mol = RDKitModule.get_mol("[1*]c1cc([2*])c([3*])c[14c]1");
|
|
assert(mol !== null);
|
|
|
|
var textIsoDummyIso = mol.get_svg_with_highlights(JSON.stringify({}));
|
|
var nLinesIsoDummyIso = textIsoDummyIso.split("\n").length;
|
|
|
|
var textNoIsoDummyIso = mol.get_svg_with_highlights(JSON.stringify({ isotopeLabels: false }));
|
|
var nLinesNoIsoDummyIso = textNoIsoDummyIso.split("\n").length;
|
|
|
|
var textIsoNoDummyIso = mol.get_svg_with_highlights(JSON.stringify({ dummyIsotopeLabels: false }));
|
|
var nLinesIsoNoDummyIso = textIsoNoDummyIso.split("\n").length;
|
|
|
|
var textNoIsoNoDummyIso = mol.get_svg_with_highlights(JSON.stringify({ isotopeLabels: false, dummyIsotopeLabels: false }));
|
|
var nLinesNoIsoNoDummyIso = textNoIsoNoDummyIso.split("\n").length;
|
|
|
|
var res = [nLinesNoIsoNoDummyIso, nLinesIsoNoDummyIso, nLinesNoIsoDummyIso, nLinesIsoDummyIso];
|
|
var resSorted = [...res];
|
|
resSorted.sort((a, b) => (a - b));
|
|
assert.ok(res.every((resItem, i) => (resItem === resSorted[i])));
|
|
}
|
|
|
|
function test_generate_aligned_coords_allow_rgroups() {
|
|
var template_molblock = `
|
|
RDKit 2D
|
|
|
|
9 9 0 0 0 0 0 0 0 0999 V2000
|
|
-0.8929 1.0942 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-2.1919 0.3442 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-2.1919 -1.1558 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.8929 -1.9059 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
0.4060 -1.1558 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
0.4060 0.3442 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-3.4910 1.0942 0.0000 R1 0 0 0 0 0 0 0 0 0 0 0 0
|
|
1.7051 1.0942 0.0000 R2 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-3.4910 -1.9059 0.0000 R3 0 0 0 0 0 0 0 0 0 0 0 0
|
|
1 2 2 0
|
|
2 3 1 0
|
|
3 4 2 0
|
|
4 5 1 0
|
|
5 6 2 0
|
|
6 1 1 0
|
|
6 8 1 0
|
|
3 9 1 0
|
|
2 7 1 0
|
|
M RGP 3 7 1 8 2 9 3
|
|
M END`;
|
|
var ortho_meta_smiles = 'c1ccc(-c2ccc(-c3ccccc3)c(-c3ccccc3)c2)cc1';
|
|
var ortho_smiles = 'c1ccc(-c2ccccc2-c2ccccc2)cc1';
|
|
var meta_smiles = 'c1ccc(-c2cccc(-c3ccccc3)c2)cc1';
|
|
var para_smiles = 'c1ccc(-c2ccc(-c3ccccc3)cc2)cc1';
|
|
var biphenyl_smiles = 'c1ccccc1-c1ccccc1';
|
|
var phenyl_smiles = 'c1ccccc1';
|
|
var template_ref = RDKitModule.get_mol(template_molblock);
|
|
var ortho_meta = RDKitModule.get_mol(ortho_meta_smiles);
|
|
var ortho = RDKitModule.get_mol(ortho_smiles);
|
|
var meta = RDKitModule.get_mol(meta_smiles);
|
|
var para = RDKitModule.get_mol(para_smiles);
|
|
var biphenyl = RDKitModule.get_mol(biphenyl_smiles);
|
|
var phenyl = RDKitModule.get_mol(phenyl_smiles);
|
|
assert.equal(JSON.parse(ortho_meta.generate_aligned_coords(
|
|
template_ref, JSON.stringify({ useCoordGen: false, allowRGroups: true}))).atoms.length, 9);
|
|
[ true, false ].forEach(alignOnly => {
|
|
var opts = JSON.stringify({ useCoordGen: false, allowRGroups: true, alignOnly });
|
|
assert.equal(JSON.parse(ortho_meta.generate_aligned_coords(
|
|
template_ref, opts)).atoms.length, 9);
|
|
assert.equal(JSON.parse(ortho.generate_aligned_coords(
|
|
template_ref, opts)).atoms.length, 8);
|
|
assert.equal(JSON.parse(meta.generate_aligned_coords(
|
|
template_ref, opts)).atoms.length, 8);
|
|
assert.equal(JSON.parse(para.generate_aligned_coords(
|
|
template_ref, opts)).atoms.length, 8);
|
|
assert.equal(JSON.parse(biphenyl.generate_aligned_coords(
|
|
template_ref, opts)).atoms.length, 7);
|
|
assert.equal(JSON.parse(phenyl.generate_aligned_coords(
|
|
template_ref, opts)).atoms.length, 6);
|
|
});
|
|
const pyridineRef = RDKitModule.get_mol(`
|
|
MJ201100
|
|
|
|
8 8 0 0 0 0 0 0 0 0999 V2000
|
|
0.0000 0.8250 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.7144 0.4125 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.7144 -0.4124 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
0.0000 -0.8250 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
0.7144 -0.4124 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
0.7144 0.4125 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
|
|
0.0000 1.6500 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
0.0000 -1.6500 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
1 2 2 0 0 0 0
|
|
2 3 1 0 0 0 0
|
|
3 4 2 0 0 0 0
|
|
4 5 1 0 0 0 0
|
|
5 6 2 0 0 0 0
|
|
6 1 1 0 0 0 0
|
|
1 7 1 0 0 0 0
|
|
4 8 1 0 0 0 0
|
|
M END
|
|
`);
|
|
const referenceSmarts = "[*:3]a1a([*:1])aa([*:2])aa1";
|
|
[ true, false ].forEach(alignOnly => {
|
|
var opts = JSON.stringify({ useCoordGen: false, allowRGroups: true, alignOnly, referenceSmarts });
|
|
assert.equal(JSON.parse(ortho_meta.generate_aligned_coords(
|
|
pyridineRef, opts)).atoms.length, 8);
|
|
assert.equal(JSON.parse(ortho.generate_aligned_coords(
|
|
pyridineRef, opts)).atoms.length, 7);
|
|
assert.equal(JSON.parse(meta.generate_aligned_coords(
|
|
pyridineRef, opts)).atoms.length, 7);
|
|
assert.equal(JSON.parse(para.generate_aligned_coords(
|
|
pyridineRef, opts)).atoms.length, 8);
|
|
assert.equal(JSON.parse(biphenyl.generate_aligned_coords(
|
|
pyridineRef, opts)).atoms.length, 7);
|
|
assert.equal(JSON.parse(phenyl.generate_aligned_coords(
|
|
pyridineRef, opts)).atoms.length, 6);
|
|
});
|
|
}
|
|
|
|
function test_generate_aligned_coords_accept_failure() {
|
|
var template_molblock = `
|
|
RDKit 2D
|
|
|
|
9 9 0 0 0 0 0 0 0 0999 V2000
|
|
-0.8929 1.0942 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-2.1919 0.3442 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-2.1919 -1.1558 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.8929 -1.9059 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
0.4060 -1.1558 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
0.4060 0.3442 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-3.4910 1.0942 0.0000 R1 0 0 0 0 0 0 0 0 0 0 0 0
|
|
1.7051 1.0942 0.0000 R2 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-3.4910 -1.9059 0.0000 R3 0 0 0 0 0 0 0 0 0 0 0 0
|
|
1 2 2 0
|
|
2 3 1 0
|
|
3 4 2 0
|
|
4 5 1 0
|
|
5 6 2 0
|
|
6 1 1 0
|
|
6 8 1 0
|
|
3 9 1 0
|
|
2 7 1 0
|
|
M RGP 3 7 1 8 2 9 3
|
|
M END
|
|
`;
|
|
var mol_molblock = `
|
|
RDKit 2D
|
|
|
|
9 9 0 0 0 0 0 0 0 0999 V2000
|
|
-0.8929 1.0942 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-2.1919 0.3442 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-2.1919 -1.1558 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.8929 -1.9059 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
0.4060 -1.1558 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
0.4060 0.3442 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-3.4910 1.0942 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0
|
|
1.7051 1.0942 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-3.4910 -1.9059 0.0000 Br 0 0 0 0 0 0 0 0 0 0 0 0
|
|
1 2 2 0
|
|
2 3 1 0
|
|
3 4 2 0
|
|
4 5 1 0
|
|
5 6 2 0
|
|
6 1 1 0
|
|
6 8 1 0
|
|
3 9 1 0
|
|
2 7 1 0
|
|
M END
|
|
`;
|
|
var template_ref = RDKitModule.get_mol(template_molblock);
|
|
var mol = RDKitModule.get_mol(mol_molblock);
|
|
var res = mol.generate_aligned_coords(template_ref, JSON.stringify({
|
|
useCoordGen: false,
|
|
allowRGroups: true,
|
|
acceptFailure: false
|
|
}));
|
|
assert(res === "");
|
|
assert.equal(mol.get_molblock(), mol_molblock);
|
|
res = mol.generate_aligned_coords(template_ref, JSON.stringify({
|
|
useCoordGen: false,
|
|
allowRGroups: true,
|
|
acceptFailure: true,
|
|
}));
|
|
assert(res === "{}");
|
|
assert.notEqual(mol.get_molblock(), mol_molblock);
|
|
var molNoCoords = RDKitModule.get_mol(mol.get_smiles());
|
|
assert(!molNoCoords.has_coords());
|
|
res = molNoCoords.generate_aligned_coords(template_ref, JSON.stringify({
|
|
useCoordGen: false,
|
|
allowRGroups: true,
|
|
acceptFailure: false,
|
|
}));
|
|
assert(res === "");
|
|
assert(!molNoCoords.has_coords());
|
|
res = molNoCoords.generate_aligned_coords(template_ref, JSON.stringify({
|
|
useCoordGen: false,
|
|
allowRGroups: true,
|
|
acceptFailure: true,
|
|
}));
|
|
assert(res === "{}");
|
|
assert(molNoCoords.has_coords());
|
|
}
|
|
|
|
function test_generate_aligned_coords_align_only() {
|
|
const template_molblock = `
|
|
RDKit 2D
|
|
|
|
6 6 0 0 0 0 0 0 0 0999 V2000
|
|
-13.7477 6.3036 0.0000 R# 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-13.7477 4.7567 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-12.6540 3.6628 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-13.7477 2.5691 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-14.8414 3.6628 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-11.1071 3.6628 0.0000 R# 0 0 0 0 0 0 0 0 0 0 0 0
|
|
1 2 1 0
|
|
2 3 1 0
|
|
3 4 1 0
|
|
4 5 1 0
|
|
2 5 1 0
|
|
3 6 1 0
|
|
M RGP 2 1 1 6 2
|
|
M END
|
|
`;
|
|
const mol_molblock = `
|
|
RDKit 2D
|
|
|
|
18 22 0 0 0 0 0 0 0 0999 V2000
|
|
4.3922 -1.5699 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
2.9211 -2.0479 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
2.5995 -0.5349 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
3.3731 0.8046 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
4.8441 1.2825 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
4.0704 -0.0568 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
1.8666 0.7748 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
|
|
0.7736 -0.3197 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
0.7749 -1.8666 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.7718 -1.8679 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.7731 -0.3208 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-1.8679 0.7718 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-4.0718 -0.0598 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-4.3933 -1.5729 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-2.9222 -2.0509 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-2.6008 -0.5379 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-3.3744 0.8016 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-4.8454 1.2795 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
9 10 1 0
|
|
11 10 1 0
|
|
11 8 1 0
|
|
8 9 1 0
|
|
4 5 1 0
|
|
6 5 1 0
|
|
7 6 1 0
|
|
3 4 1 0
|
|
3 7 1 0
|
|
1 6 1 0
|
|
2 3 1 0
|
|
2 1 1 0
|
|
17 18 1 0
|
|
13 18 1 0
|
|
12 13 1 0
|
|
16 17 1 0
|
|
16 12 1 0
|
|
14 13 1 0
|
|
15 16 1 0
|
|
15 14 1 0
|
|
12 11 1 0
|
|
8 7 1 0
|
|
M END
|
|
`;
|
|
const getCoordArray = (mol) => {
|
|
const molblock = mol.get_molblock().split("\n");
|
|
const numHeavyAtoms = parseInt(molblock[3].substr(0, 3));
|
|
return molblock.filter((_, idx) => idx > 3 && idx < 4 + numHeavyAtoms).map(
|
|
line => [0, 1, 2].map(i => parseFloat(line.substr(i * 10, (i + 1) * 10)))
|
|
);
|
|
};
|
|
const arraySum = (a) => {
|
|
const s = 0.;
|
|
return a.reduce((prev, curr) => prev + curr, s);
|
|
};
|
|
const sqDist = (xyz1, xyz2) => arraySum(xyz1.map((c, i) => (c - xyz2[i]) * (c - xyz2[i])))
|
|
|
|
const template_ref = RDKitModule.get_mol(template_molblock);
|
|
const mol = RDKitModule.get_mol(mol_molblock);
|
|
const molCoords = getCoordArray(mol);
|
|
const bondLength11_12 = Math.sqrt(sqDist(molCoords[11], molCoords[12]));
|
|
const bondLength5_6 = Math.sqrt(sqDist(molCoords[5], molCoords[6]));
|
|
assert(Math.abs(bondLength11_12 - bondLength5_6) < 1.e-4);
|
|
assert(bondLength11_12 > 2.3);
|
|
[ false, true ].forEach(alignOnly => {
|
|
const mol = RDKitModule.get_mol(mol_molblock);
|
|
const res = JSON.parse(mol.generate_aligned_coords(template_ref, JSON.stringify({ allowRGroups: true, alignOnly })));
|
|
assert([ 11, 10, 7, 8, 9, 6 ].every((idx, i) => res.atoms[i] === idx));
|
|
assert(mol.get_smiles() === "C1CC2CCC1N2C1CNC1N1C2CCC1CC2");
|
|
const molAliCoords = getCoordArray(mol);
|
|
const templateCoords = getCoordArray(template_ref);
|
|
res.atoms.forEach((molIdx, templateIdx) => {
|
|
assert(sqDist(molAliCoords[molIdx], templateCoords[templateIdx]) < 1.e-4);
|
|
});
|
|
const bondLengthAli11_12 = Math.sqrt(sqDist(molAliCoords[11], molAliCoords[12]));
|
|
const bondLengthAli5_6 = Math.sqrt(sqDist(molAliCoords[5], molAliCoords[6]));
|
|
assert(Math.abs(bondLengthAli11_12 - bondLengthAli5_6) < 1.e-4);
|
|
if (alignOnly) {
|
|
assert(bondLengthAli11_12 > 2.3);
|
|
} else {
|
|
assert(bondLengthAli11_12 < 1.6);
|
|
}
|
|
});
|
|
}
|
|
|
|
function test_get_mol_no_kekulize() {
|
|
var molIsValid = true;
|
|
try {
|
|
mol = RDKitModule.get_mol("c");
|
|
molIsValid = (mol !== null);
|
|
} catch (e) {
|
|
molIsValid = false;
|
|
}
|
|
assert(!molIsValid);
|
|
mol = RDKitModule.get_mol("c", JSON.stringify({kekulize: false}));
|
|
assert(mol !== null);
|
|
}
|
|
|
|
function test_get_smarts() {
|
|
var mol = RDKitModule.get_mol(`
|
|
MJ201100
|
|
|
|
8 8 0 0 0 0 0 0 0 0999 V2000
|
|
-1.0491 1.5839 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-1.7635 1.1714 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-1.7635 0.3463 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-1.0491 -0.0661 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.3346 0.3463 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.3346 1.1714 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
0.3798 1.5839 0.0000 R# 0 0 0 0 0 0 0 0 0 0 0 0
|
|
0.3798 -0.0661 0.0000 R# 0 0 0 0 0 0 0 0 0 0 0 0
|
|
1 2 2 0 0 0 0
|
|
2 3 1 0 0 0 0
|
|
3 4 2 0 0 0 0
|
|
4 5 1 0 0 0 0
|
|
5 6 2 0 0 0 0
|
|
6 1 1 0 0 0 0
|
|
6 7 1 0 0 2 0
|
|
5 8 1 0 0 2 0
|
|
M RGP 2 7 1 8 2
|
|
M END
|
|
`);
|
|
assert(mol !== null);
|
|
smarts = mol.get_smarts();
|
|
assert(smarts == "[#6]1:[#6]:[#6]:[#6]:[#6](:[#6]:1-&!@*)-&!@*");
|
|
}
|
|
|
|
function test_get_cxsmarts() {
|
|
var mol = RDKitModule.get_mol(`
|
|
MJ201100
|
|
|
|
8 8 0 0 0 0 0 0 0 0999 V2000
|
|
-1.0491 1.5839 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-1.7635 1.1714 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-1.7635 0.3463 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-1.0491 -0.0661 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.3346 0.3463 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.3346 1.1714 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
0.3798 1.5839 0.0000 R# 0 0 0 0 0 0 0 0 0 0 0 0
|
|
0.3798 -0.0661 0.0000 R# 0 0 0 0 0 0 0 0 0 0 0 0
|
|
1 2 2 0 0 0 0
|
|
2 3 1 0 0 0 0
|
|
3 4 2 0 0 0 0
|
|
4 5 1 0 0 0 0
|
|
5 6 2 0 0 0 0
|
|
6 1 1 0 0 0 0
|
|
6 7 1 0 0 2 0
|
|
5 8 1 0 0 2 0
|
|
M RGP 2 7 1 8 2
|
|
M END
|
|
`);
|
|
assert(mol !== null);
|
|
cxsmarts = mol.get_cxsmarts();
|
|
assert(cxsmarts == "[#6]1:[#6]:[#6]:[#6]:[#6](:[#6]:1-&!@*)-&!@* |" +
|
|
"(-1.0491,1.5839,;-1.7635,1.1714,;-1.7635,0.3463,;-1.0491,-0.0661,;" +
|
|
"-0.3346,0.3463,;-0.3346,1.1714,;0.3798,1.5839,;0.3798,-0.0661,)," +
|
|
"atomProp:6.dummyLabel.R1:7.dummyLabel.R2|");
|
|
}
|
|
|
|
function test_normalize_depiction() {
|
|
var mol = RDKitModule.get_mol(`
|
|
MJ201100
|
|
|
|
9 10 0 0 0 0 0 0 0 0999 V2000
|
|
-1.5402 1.3161 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-2.2546 0.9036 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-2.2546 0.0785 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-1.5402 -0.3339 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.8257 0.0785 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.8257 0.9036 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.0411 -0.1764 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
|
|
0.4438 0.4909 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.0410 1.1583 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
1 2 2 0 0 0 0
|
|
2 3 1 0 0 0 0
|
|
3 4 2 0 0 0 0
|
|
4 5 1 0 0 0 0
|
|
5 6 2 0 0 0 0
|
|
6 1 1 0 0 0 0
|
|
8 9 2 0 0 0 0
|
|
6 9 1 0 0 0 0
|
|
7 8 1 0 0 0 0
|
|
5 7 1 0 0 0 0
|
|
M END
|
|
`);
|
|
const scalingFactor = mol.normalize_depiction();
|
|
assert(scalingFactor > 1.8 && scalingFactor < 1.9);
|
|
}
|
|
|
|
function test_straighten_depiction() {
|
|
var benzeneHoriz = RDKitModule.get_mol(`
|
|
MJ201100
|
|
|
|
6 6 0 0 0 0 0 0 0 0999 V2000
|
|
-0.0785 1.6073 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.9035 1.6073 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-1.3160 0.8928 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.9036 0.1783 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.0786 0.1783 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
0.3339 0.8929 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
1 2 2 0 0 0 0
|
|
2 3 1 0 0 0 0
|
|
3 4 2 0 0 0 0
|
|
4 5 1 0 0 0 0
|
|
5 6 2 0 0 0 0
|
|
6 1 1 0 0 0 0
|
|
M END
|
|
`);
|
|
var benzeneVert = RDKitModule.get_mol(`
|
|
MJ201100
|
|
|
|
6 6 0 0 0 0 0 0 0 0999 V2000
|
|
0.2234 1.3054 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.4910 1.7178 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-1.2055 1.3053 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-1.2056 0.4803 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.4911 0.0678 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
0.2234 0.4804 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
1 2 2 0 0 0 0
|
|
2 3 1 0 0 0 0
|
|
3 4 2 0 0 0 0
|
|
4 5 1 0 0 0 0
|
|
5 6 2 0 0 0 0
|
|
6 1 1 0 0 0 0
|
|
M END
|
|
`);
|
|
var benzeneHorizCopy = RDKitModule.get_mol_copy(benzeneHoriz);
|
|
var benzeneVertCopy = RDKitModule.get_mol_copy(benzeneVert);
|
|
benzeneHoriz.straighten_depiction();
|
|
benzeneVert.straighten_depiction();
|
|
assert(benzeneHoriz.get_molblock() !== benzeneHorizCopy.get_molblock());
|
|
assert(benzeneVert.get_molblock() === benzeneVertCopy.get_molblock());
|
|
benzeneHoriz = benzeneHorizCopy;
|
|
benzeneVert = benzeneVertCopy;
|
|
benzeneHorizCopy = RDKitModule.get_mol_copy(benzeneHoriz);
|
|
benzeneVertCopy = RDKitModule.get_mol_copy(benzeneVert);
|
|
benzeneHoriz.straighten_depiction(true);
|
|
benzeneVert.straighten_depiction(true);
|
|
assert(benzeneHoriz.get_molblock() === benzeneHorizCopy.get_molblock());
|
|
assert(benzeneVert.get_molblock() === benzeneVertCopy.get_molblock());
|
|
}
|
|
|
|
function test_has_coords() {
|
|
var mol = RDKitModule.get_mol('CC');
|
|
assert(!mol.has_coords());
|
|
var mol2 = RDKitModule.get_mol(mol.get_new_coords());
|
|
assert(mol2.has_coords() === 2);
|
|
assert(!mol.has_coords());
|
|
mol.set_new_coords();
|
|
assert(mol.has_coords() === 2);
|
|
var mol3 = RDKitModule.get_mol(`
|
|
RDKit 3D
|
|
|
|
9 9 0 0 0 0 0 0 0 0999 V2000
|
|
-0.5909 -0.6086 0.0018 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.2459 0.8185 -0.0936 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
0.8271 -0.1760 0.1017 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-1.1425 -0.9648 0.9113 H 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.8767 -1.2011 -0.8967 H 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.5849 1.4596 0.7584 H 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.2393 1.3618 -1.0674 H 0 0 0 0 0 0 0 0 0 0 0 0
|
|
1.4853 -0.4161 -0.7761 H 0 0 0 0 0 0 0 0 0 0 0 0
|
|
1.3678 -0.2732 1.0608 H 0 0 0 0 0 0 0 0 0 0 0 0
|
|
1 2 1 0
|
|
2 3 1 0
|
|
3 1 1 0
|
|
1 4 1 0
|
|
1 5 1 0
|
|
2 6 1 0
|
|
2 7 1 0
|
|
3 8 1 0
|
|
3 9 1 0
|
|
M END
|
|
`);
|
|
assert(mol3.has_coords() === 3);
|
|
}
|
|
|
|
function test_kekulize() {
|
|
const badAromaticSmiles = 'c1cccc1';
|
|
var mol = null;
|
|
try {
|
|
mol = RDKitModule.get_mol(badAromaticSmiles);
|
|
assert(mol === null);
|
|
} catch {
|
|
assert(mol === null);
|
|
}
|
|
mol = RDKitModule.get_mol(badAromaticSmiles, JSON.stringify({ kekulize: false }));
|
|
assert(mol !== null);
|
|
}
|
|
|
|
function test_sanitize() {
|
|
const badValenceSmiles = 'N(C)(C)(C)C';
|
|
var mol = null;
|
|
try {
|
|
mol = RDKitModule.get_mol(badValenceSmiles);
|
|
assert(mol === null);
|
|
} catch {
|
|
assert(mol === null);
|
|
}
|
|
try {
|
|
mol = RDKitModule.get_mol(badValenceSmiles, JSON.stringify({ kekulize: false }));
|
|
assert(mol === null);
|
|
} catch {
|
|
assert(mol === null);
|
|
}
|
|
mol = RDKitModule.get_mol(badValenceSmiles, JSON.stringify({ sanitize: false }));
|
|
assert(mol !== null);
|
|
}
|
|
|
|
function test_removehs() {
|
|
const badValenceSmiles = 'N1C=CC(=O)c2ccc(N(C)(C)(C)(C)C)cc12';
|
|
mol = RDKitModule.get_mol(badValenceSmiles, JSON.stringify({ sanitize: false, removeHs: false }));
|
|
assert(mol !== null);
|
|
}
|
|
|
|
function test_flexicanvas() {
|
|
var mol = RDKitModule.get_mol("CCCC");
|
|
assert(mol !== null);
|
|
|
|
var svg = mol.get_svg(-1,-1);
|
|
assert(svg.search("svg")>0);
|
|
assert(svg.search("width='87px'")>0);
|
|
assert(svg.search("height='19px'")>0);
|
|
}
|
|
|
|
function test_run_reaction() {
|
|
let rxn1;
|
|
let molList;
|
|
try {
|
|
rxn1 = RDKitModule.get_rxn('[#6:1][O:2]>>[#6:1]=[O:2]');
|
|
molList = molListFromSmiArray(['CC(C)O',]);
|
|
let products;
|
|
try {
|
|
products = rxn1.run_reactants(molList, 10000);
|
|
for (let i = 0; i < products.size(); i++) {
|
|
let element;
|
|
try {
|
|
element = products.get(i);
|
|
let mol;
|
|
try {
|
|
mol = element.next();
|
|
assert(mol && mol.get_smiles() === "CC(C)=O");
|
|
} finally {
|
|
if (mol) {
|
|
mol.delete();
|
|
}
|
|
}
|
|
} finally {
|
|
if (element) {
|
|
element.delete();
|
|
}
|
|
}
|
|
}
|
|
} finally {
|
|
if (products) {
|
|
products.delete();
|
|
}
|
|
}
|
|
} finally {
|
|
if (rxn1) {
|
|
rxn1.delete();
|
|
}
|
|
if (molList) {
|
|
molList.delete();
|
|
}
|
|
}
|
|
}
|
|
|
|
function test_rxn_drawing() {
|
|
{
|
|
var rxn = RDKitModule.get_rxn("[CH3:1][OH:2]>>[CH2:1]=[OH0:2]");
|
|
var svg = rxn.get_svg();
|
|
assert(svg.search("svg") > 0);
|
|
var rxn_from_block = RDKitModule.get_rxn(`$RXN
|
|
|
|
RDKit
|
|
|
|
1 1
|
|
$MOL
|
|
|
|
RDKit 2D
|
|
|
|
2 1 0 0 0 0 0 0 0 0999 V2000
|
|
0.0000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 1 0 0
|
|
1.2990 0.7500 0.0000 O 0 0 0 0 0 0 0 0 0 2 0 0
|
|
1 2 6 0
|
|
V 1 [C&H3:1]
|
|
V 2 [O&H1:2]
|
|
M END
|
|
$MOL
|
|
|
|
RDKit 2D
|
|
|
|
2 1 0 0 0 0 0 0 0 0999 V2000
|
|
0.0000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 1 0 0
|
|
1.2990 0.7500 0.0000 O 0 0 0 0 0 0 0 0 0 2 0 0
|
|
1 2 2 0
|
|
V 1 [C&H2:1]
|
|
V 2 [O&H0:2]
|
|
M END`);
|
|
var svg_from_block = rxn_from_block.get_svg();
|
|
assert(svg_from_block.search("svg") > 0);
|
|
assert(svg.match(/<path/g).length > 0);
|
|
assert(svg.match(/<path/g).length === svg_from_block.match(/<path/g).length);
|
|
}
|
|
{
|
|
var rxn = RDKitModule.get_rxn("[cH:5]1[cH:6][c:7]2[cH:8][n:9][cH:10][cH:11][c:12]2[c:3]([cH:4]1)[C:2](=[O:1])O.[N-:13]=[N+:14]=[N-:15]>C(Cl)Cl.C(=O)(C(=O)Cl)Cl>[cH:5]1[cH:6][c:7]2[cH:8][n:9][cH:10][cH:11][c:12]2[c:3]([cH:4]1)[C:2](=[O:1])[N:13]=[N+:14]=[N-:15]",
|
|
JSON.stringify({ useSmiles: true }));
|
|
{
|
|
var svg = rxn.get_svg();
|
|
assert(svg.search("svg") > 0);
|
|
assert(svg.search("stroke-dasharray" < 0));
|
|
assert(svg.search("ellipse") < 0);
|
|
}
|
|
{
|
|
var svg = rxn.get_svg_with_highlights(JSON.stringify({ kekulize: false }));
|
|
assert(svg.search("svg") > 0);
|
|
assert(svg.search("stroke-dasharray" > 0));
|
|
assert(svg.search("ellipse") < 0);
|
|
}
|
|
{
|
|
var svg = rxn.get_svg_with_highlights(JSON.stringify({ highlightByReactant: true }));
|
|
assert(svg.search("svg") > 0);
|
|
assert(svg.search("stroke-dasharray" < 0));
|
|
assert(svg.search("ellipse") > 0);
|
|
assert(svg.search("#BCD6ED") < 0);
|
|
assert(svg.search("#A8D08D") < 0);
|
|
}
|
|
{
|
|
var svg = rxn.get_svg_with_highlights(JSON.stringify({
|
|
highlightColorsReactants: [[.741, .843, .933], [.659, .816, .553]]
|
|
}));
|
|
assert(svg.search("svg") > 0);
|
|
assert(svg.search("stroke-dasharray" < 0));
|
|
assert(svg.search("ellipse") < 0);
|
|
}
|
|
{
|
|
var svg = rxn.get_svg_with_highlights(JSON.stringify({
|
|
highlightByReactant: true,
|
|
highlightColorsReactants: [[.741, .843, .933], [.659, .816, .553]]
|
|
}));
|
|
assert(svg.search("svg") > 0);
|
|
assert(svg.search("stroke-dasharray" < 0));
|
|
assert(svg.search("ellipse") > 0);
|
|
assert(svg.search("#BCD6ED") > 0);
|
|
assert(svg.search("#A8D08D") > 0);
|
|
}
|
|
rxn.delete();
|
|
}
|
|
{
|
|
var rxn = RDKitModule.get_rxn("[cH:5]1[cH:6][c:7]2[cH:8][n:9][cH:10][cH:11][c:12]2[c:3]([cH:4]1)[C:2](=[O:1])O.[N-:13]=[N+:14]=[N-:15]>C(Cl)Cl.C(=O)(C(=O)Cl)Cl>[cH:5]1[cH:6][c:7]2[cH:8][n:9][cH:10][cH:11][c:12]2[c:3]([cH:4]1)[C:2](=[O:1])[N:13]=[N+:14]=[N-:15]");
|
|
var hasThrown = false;
|
|
var isAromatic = false;
|
|
// if the code is built with exception support it will not throw
|
|
// but rather display molecules in their aromatic form rather
|
|
// than kekulized
|
|
try {
|
|
var svg = rxn.get_svg();
|
|
isAromatic = svg.search("stroke-dasharray" > 0);
|
|
} catch {
|
|
hasThrown = true;
|
|
}
|
|
assert(isAromatic || hasThrown);
|
|
}
|
|
}
|
|
|
|
function test_legacy_stereochem() {
|
|
var origSetting;
|
|
try {
|
|
origSetting = RDKitModule.use_legacy_stereo_perception(true);
|
|
var mol = RDKitModule.get_mol("O[C@@]1(C)C/C(/C1)=C(/C)\\CC");
|
|
assert(mol !== null);
|
|
assert.equal(mol.get_smiles(),"CCC(C)=C1CC(C)(O)C1");
|
|
|
|
RDKitModule.use_legacy_stereo_perception(false);
|
|
mol = RDKitModule.get_mol("O[C@@]1(C)C/C(/C1)=C(/C)\\CC");
|
|
assert(mol !== null);
|
|
assert.equal(mol.get_smiles(),"CC/C(C)=C1\\C[C@](C)(O)C1");
|
|
} finally {
|
|
RDKitModule.use_legacy_stereo_perception(origSetting);
|
|
}
|
|
}
|
|
|
|
function test_allow_non_tetrahedral_chirality() {
|
|
var ctab = `
|
|
Mrv2108 09132105183D
|
|
|
|
5 4 0 0 0 0 999 V2000
|
|
-1.2500 1.4518 0.0000 Pt 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-1.2500 2.2768 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.4250 1.4518 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-2.0750 1.4518 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-1.2500 0.6268 0.0000 Cl 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 END
|
|
`;
|
|
var origSetting;
|
|
try {
|
|
origSetting = RDKitModule.allow_non_tetrahedral_chirality(true);
|
|
var mol = RDKitModule.get_mol(ctab);
|
|
assert(mol !== null);
|
|
assert.equal(mol.get_smiles(), "F[Pt@SP3](F)(Cl)Cl");
|
|
RDKitModule.allow_non_tetrahedral_chirality(false);
|
|
var mol = RDKitModule.get_mol(ctab);
|
|
assert(mol !== null);
|
|
assert.equal(mol.get_smiles(), "F[Pt](F)(Cl)Cl");
|
|
} finally {
|
|
RDKitModule.allow_non_tetrahedral_chirality(origSetting);
|
|
}
|
|
}
|
|
|
|
function test_prop() {
|
|
var mol = RDKitModule.get_mol(`
|
|
MJ201900
|
|
|
|
2 1 0 0 0 0 0 0 0 0999 V2000
|
|
0.1899 1.9526 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.5245 1.5401 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
2 1 1 0 0 0 0
|
|
M END
|
|
`);
|
|
assert.equal(mol.has_prop("test1"), false);
|
|
assert.equal(mol.set_prop("test1","val"), true);
|
|
assert.equal(mol.has_prop("test1"), true);
|
|
assert.equal(mol.get_prop("test1"),"val");
|
|
assert.equal(mol.set_prop("test2","val"), true);
|
|
props = mol.get_prop_list(false, false);
|
|
assert.equal(props.get(0), "test1");
|
|
assert.equal(props.get(1), "test2");
|
|
assert.equal(mol.clear_prop("test3"), false);
|
|
assert.equal(mol.has_prop("test2"), true);
|
|
assert.equal(mol.clear_prop("test2"), true);
|
|
assert.equal(mol.has_prop("test2"), false);
|
|
}
|
|
|
|
function test_highlights() {
|
|
var mol = RDKitModule.get_mol('c1cc(O)ccc1');
|
|
var svg = mol.get_svg_with_highlights(JSON.stringify({
|
|
highlightAtomColors: {
|
|
0: [1.0, 0.0, 0.0],
|
|
1: [1.0, 0.0, 0.0],
|
|
2: [1.0, 0.0, 0.0],
|
|
3: [0.0, 1.0, 0.0],
|
|
4: [1.0, 0.0, 0.0],
|
|
5: [1.0, 0.0, 0.0],
|
|
6: [1.0, 0.0, 0.0],
|
|
}, highlightBondColors: {
|
|
2: [0.0, 0.7, 0.9],
|
|
}, highlightAtomRadii: {
|
|
0: 0.1,
|
|
1: 0.1,
|
|
2: 0.1,
|
|
3: 0.8,
|
|
4: 0.1,
|
|
5: 0.1,
|
|
6: 0.1,
|
|
}, atoms: [0, 1, 2, 3, 4, 5, 6], bonds: [2], width: 127
|
|
}));
|
|
assert(!svg.includes('fill:#FF7F7F'));
|
|
assert(svg.includes('fill:#FF0000'));
|
|
assert(svg.includes('fill:#00FF00'));
|
|
assert(svg.includes('fill:#00B2E5'));
|
|
assert(svg.includes("width='127px'"));
|
|
assert(svg.includes('</svg>'));
|
|
}
|
|
|
|
function test_add_chiral_hs() {
|
|
var mol = RDKitModule.get_mol(`
|
|
MJ201100
|
|
|
|
18 21 0 0 1 0 0 0 0 0999 V2000
|
|
-0.8540 -1.4441 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.3019 -0.8310 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
0.5185 -0.9172 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
0.8540 -0.1635 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
0.6825 0.6434 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.1379 0.7296 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.5504 1.4441 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.4734 -0.0239 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
0.2409 0.3885 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-1.6609 -1.2726 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-2.2130 -1.8857 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-1.9580 -2.6703 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-1.1511 -2.8419 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.5990 -2.2287 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-3.0201 -1.7143 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-3.5720 -2.3275 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-3.3171 -3.1121 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-2.5100 -3.2835 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
|
|
2 3 1 0 0 0 0
|
|
4 3 1 0 0 0 0
|
|
4 5 1 0 0 0 0
|
|
6 5 1 0 0 0 0
|
|
6 7 1 1 0 0 0
|
|
6 8 1 0 0 0 0
|
|
8 9 1 1 0 0 0
|
|
8 2 1 0 0 0 0
|
|
4 9 1 1 0 0 0
|
|
2 1 1 1 0 0 0
|
|
10 11 1 0 0 0 0
|
|
11 12 2 0 0 0 0
|
|
12 13 1 0 0 0 0
|
|
13 14 2 0 0 0 0
|
|
1 10 2 0 0 0 0
|
|
1 14 1 0 0 0 0
|
|
15 16 2 0 0 0 0
|
|
16 17 1 0 0 0 0
|
|
11 15 1 0 0 0 0
|
|
17 18 2 0 0 0 0
|
|
12 18 1 0 0 0 0
|
|
M END
|
|
`);
|
|
var quinoline_scaffold = RDKitModule.get_mol(`
|
|
MJ201100
|
|
|
|
10 11 0 0 1 0 0 0 0 0999 V2000
|
|
-8.1001 2.8219 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-8.8145 2.4094 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-8.8145 1.5843 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-8.1001 1.1718 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-7.3856 1.5843 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-7.3856 2.4094 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-6.6711 1.1718 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-5.9566 1.5842 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-5.9566 2.4092 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-6.6711 2.8218 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
2 3 1 0 0 0 0
|
|
3 4 2 0 0 0 0
|
|
4 5 1 0 0 0 0
|
|
5 6 2 0 0 0 0
|
|
7 8 2 0 0 0 0
|
|
8 9 1 0 0 0 0
|
|
9 10 2 0 0 0 0
|
|
5 7 1 0 0 0 0
|
|
10 6 1 0 0 0 0
|
|
1 2 2 0 0 0 0
|
|
6 1 1 0 0 0 0
|
|
M END
|
|
`);
|
|
var svg1 = mol.get_svg_with_highlights(JSON.stringify({width: 350, height: 300}));
|
|
assert(svg1.includes("width='350px'"));
|
|
assert(svg1.includes("height='300px'"));
|
|
assert(svg1.includes("</svg>"));
|
|
assert(svg1.includes("atom-17"));
|
|
assert(svg1.includes("atom-18"));
|
|
assert(svg1.includes("atom-19"));
|
|
var svg2 = mol.get_svg_with_highlights(JSON.stringify({
|
|
width: 350, height: 300, useMolBlockWedging: true, wedgeBonds: false, addChiralHs: false
|
|
}));
|
|
assert(svg2.includes("width='350px'"));
|
|
assert(svg2.includes("height='300px'"));
|
|
assert(svg2.includes("</svg>"));
|
|
assert(svg2.includes("atom-17"));
|
|
assert(!svg2.includes("atom-18"));
|
|
assert(!svg2.includes("atom-19"));
|
|
assert(mol.get_molblock().includes("4 3 1 6"));
|
|
var molblock = mol.get_molblock(JSON.stringify({ useMolBlockWedging: true }));
|
|
assert(!molblock.includes("4 3 1 6"));
|
|
assert(molblock.includes("6 7 1 1"));
|
|
// Here we want to test that the original molblock wedging is preserved and inverted
|
|
// as the coordinates are rigid-body rotated
|
|
var molCopy;
|
|
molCopy = RDKitModule.get_mol_copy(mol);
|
|
assert(JSON.parse(molCopy.generate_aligned_coords(quinoline_scaffold, JSON.stringify({ acceptFailure: false, alignOnly: true }))));
|
|
molblock = molCopy.get_molblock(JSON.stringify({ useMolBlockWedging: true }));
|
|
assert(molblock.split('\n').some(line => line.match(/^ [1 ]\d [1 ]\d [12] 6 *$/)));
|
|
assert(!molblock.split('\n').some(line => line.match(/^ [1 ]\d [1 ]\d [12] 1 *$/)));
|
|
assert(!molblock.includes("4 3 1 6"));
|
|
assert(molblock.includes("6 7 1 6"));
|
|
molCopy.delete();
|
|
// Here we want to test that the original molblock wedging gets cleared
|
|
// and hence wedging is recomputed as the coordinates are re-generated
|
|
molCopy = RDKitModule.get_mol_copy(mol);
|
|
assert(JSON.parse(molCopy.generate_aligned_coords(quinoline_scaffold, JSON.stringify({ acceptFailure: false }))));
|
|
molblock = molCopy.get_molblock(JSON.stringify({ useMolBlockWedging: true }));
|
|
assert(molblock.split('\n').some(line => line.match(/^ [1 ]\d [1 ]\d [12] 6 *$/)));
|
|
assert(molblock.split('\n').some(line => line.match(/^ [1 ]\d [1 ]\d [12] 1 *$/)));
|
|
molCopy.delete();
|
|
mol.delete();
|
|
quinoline_scaffold.delete();
|
|
}
|
|
|
|
function getWedgedMolAndInvertedWedges() {
|
|
const wedgedMol = RDKitModule.get_mol(`
|
|
RDKit 2D
|
|
|
|
29 34 0 0 1 0 0 0 0 0999 V2000
|
|
1.3719 5.1304 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0
|
|
0.5985 3.7907 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.9482 3.7907 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-1.7216 5.1304 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-3.2685 5.1304 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-3.8994 3.5835 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-2.5597 4.3569 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-2.5597 5.9038 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-3.8994 6.6771 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-5.2389 5.9038 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-6.5784 6.6771 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-5.2389 4.3569 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
1.3719 2.4510 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
0.5985 1.1115 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
1.3719 -0.2276 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
2.9188 -0.2276 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
3.6921 1.1115 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
2.9188 2.4510 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
5.2389 1.1115 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
6.0124 -0.2276 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
5.2389 -1.5673 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
3.6921 -1.5673 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
|
|
3.8996 -5.0201 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
5.2391 -4.2467 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
3.5777 -6.5331 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
4.9909 -5.9040 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
6.0124 -2.9070 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
6.3306 -6.6772 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
6.5784 -5.0201 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
2 1 1 1
|
|
2 3 1 0
|
|
3 4 1 0
|
|
5 4 1 6
|
|
5 6 1 0
|
|
6 7 1 0
|
|
7 8 1 0
|
|
9 8 1 1
|
|
5 9 1 0
|
|
9 10 1 0
|
|
10 11 1 1
|
|
10 12 1 0
|
|
6 12 1 1
|
|
2 13 1 0
|
|
13 14 2 0
|
|
14 15 1 0
|
|
15 16 2 0
|
|
16 17 1 0
|
|
17 18 2 0
|
|
13 18 1 0
|
|
17 19 1 0
|
|
19 20 1 0
|
|
20 21 1 0
|
|
21 22 1 0
|
|
16 22 1 0
|
|
23 24 1 0
|
|
23 25 1 0
|
|
25 26 1 0
|
|
24 27 1 0
|
|
27 26 1 0
|
|
26 28 1 0
|
|
24 29 1 0
|
|
28 29 1 0
|
|
21 27 1 0
|
|
M END
|
|
`);
|
|
|
|
const invertedWedges = ` 2 1 1 6
|
|
2 3 1 0
|
|
3 4 1 0
|
|
5 4 1 1
|
|
5 6 1 0
|
|
6 7 1 0
|
|
7 8 1 0
|
|
9 8 1 6
|
|
5 9 1 0
|
|
9 10 1 0
|
|
10 11 1 6
|
|
10 12 1 0
|
|
6 12 1 6
|
|
2 13 1 0
|
|
13 14 2 0
|
|
14 15 1 0
|
|
15 16 2 0
|
|
16 17 1 0
|
|
17 18 2 0
|
|
13 18 1 0
|
|
17 19 1 0
|
|
19 20 1 0
|
|
20 21 1 0
|
|
21 22 1 0
|
|
16 22 1 0
|
|
23 24 1 0
|
|
23 25 1 0
|
|
25 26 1 0
|
|
24 27 1 0
|
|
27 26 1 0
|
|
26 28 1 0
|
|
24 29 1 0
|
|
28 29 1 0
|
|
21 27 1 0
|
|
`;
|
|
return { wedgedMol, invertedWedges };
|
|
}
|
|
|
|
function test_wedging_all_within_scaffold() {
|
|
const { wedgedMol, invertedWedges } = getWedgedMolAndInvertedWedges();
|
|
const scaffold = RDKitModule.get_mol(`
|
|
RDKit 2D
|
|
|
|
13 14 0 0 1 0 0 0 0 0999 V2000
|
|
-1.6549 2.5755 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.8814 1.2358 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
0.6653 1.2358 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
1.4385 2.5755 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
2.9854 2.5755 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
3.6161 1.0286 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
2.2766 1.8019 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
2.2766 3.3487 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
3.6161 4.1222 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
4.9558 3.3487 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
6.2953 4.1222 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0
|
|
4.9558 1.8019 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-1.6549 -0.1037 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
2 1 1 0
|
|
2 3 1 0
|
|
3 4 1 0
|
|
5 4 1 1
|
|
5 6 1 0
|
|
6 7 1 6
|
|
7 8 1 0
|
|
9 8 1 6
|
|
5 9 1 0
|
|
9 10 1 0
|
|
10 11 1 6
|
|
10 12 1 0
|
|
6 12 1 0
|
|
2 13 1 6
|
|
M END
|
|
`);
|
|
// the "alignOnly" alignment should succeed and preserve molblock wedging
|
|
// (inverted with respect to the original molecule)
|
|
// it should feature a narrow angle between the bridge bonds
|
|
// as the original geometry of the bridge is preserved
|
|
let wedgedMolCopy;
|
|
wedgedMolCopy = RDKitModule.get_mol_copy(wedgedMol);
|
|
assert(JSON.parse(wedgedMolCopy.generate_aligned_coords(scaffold, JSON.stringify({ acceptFailure: false, alignOnly: true }))));
|
|
const mbAlignOnly = wedgedMolCopy.get_molblock(JSON.stringify({ useMolBlockWedging: true }));
|
|
const svgAlignOnly = wedgedMolCopy.get_svg_with_highlights(JSON.stringify({
|
|
width: 350, height: 300, useMolBlockWedging: true, wedgeBonds: false, addChiralHs: false
|
|
}));
|
|
{
|
|
const [xy23, xy26] = extractBondCoords(svgAlignOnly, 'atom-23 atom-26');
|
|
const [_, xy25] = extractBondCoords(svgAlignOnly, 'atom-26 atom-25');
|
|
const v1 = [xy23[0] - xy26[0], xy23[1] - xy26[1]];
|
|
const v2 = [xy25[0] - xy26[0], xy25[1] - xy26[1]];
|
|
const v1v2Theta = angleDegBetweenVectors(v1, v2);
|
|
assert(v1v2Theta > 10 && v1v2Theta < 15);
|
|
}
|
|
assert(mbAlignOnly.includes(invertedWedges));
|
|
// the "rebuild" alignment should succeed and preserve molblock wedging
|
|
// (inverted with respect to the original molecule)
|
|
// it should feature a much wider angle between the bridge bonds as the
|
|
// bridged system is entirely rebuilt since it is not part of the scaffold
|
|
wedgedMolCopy.delete();
|
|
wedgedMolCopy = RDKitModule.get_mol_copy(wedgedMol);
|
|
assert(JSON.parse(wedgedMolCopy.generate_aligned_coords(scaffold, JSON.stringify({ acceptFailure: false }))));
|
|
const mbRebuild = wedgedMolCopy.get_molblock(JSON.stringify({ useMolBlockWedging: true }));
|
|
const svgRebuild = wedgedMolCopy.get_svg_with_highlights(JSON.stringify({
|
|
width: 350, height: 300, useMolBlockWedging: true, wedgeBonds: false, addChiralHs: false
|
|
}));
|
|
{
|
|
const [xy23, xy26] = extractBondCoords(svgRebuild, 'atom-23 atom-26');
|
|
const [_, xy25] = extractBondCoords(svgRebuild, 'atom-26 atom-25');
|
|
const v1 = [xy23[0] - xy26[0], xy23[1] - xy26[1]];
|
|
const v2 = [xy25[0] - xy26[0], xy25[1] - xy26[1]];
|
|
const v1v2Theta = angleDegBetweenVectors(v1, v2);
|
|
assert(v1v2Theta > 105 && v1v2Theta < 110);
|
|
}
|
|
assert(mbRebuild.includes(invertedWedges));
|
|
// the "rebuildCoordGen" alignment should succeed and clear original wedging
|
|
// it should feature an even wider angle between the bridge bonds as CoordGen
|
|
// has a template for the bridged system.
|
|
// Additionally, CoordGen also rebuilds the scaffold, therefore original wedging
|
|
// should be cleared
|
|
wedgedMolCopy.delete();
|
|
wedgedMolCopy = RDKitModule.get_mol_copy(wedgedMol);
|
|
assert(JSON.parse(wedgedMolCopy.generate_aligned_coords(scaffold, JSON.stringify({ acceptFailure: false, useCoordGen: true }))));
|
|
const mbRebuildCoordGen = wedgedMolCopy.get_molblock(JSON.stringify({ useMolBlockWedging: true }));
|
|
const svgRebuildCoordGen = wedgedMolCopy.get_svg_with_highlights(JSON.stringify({
|
|
width: 350, height: 300, useMolBlockWedging: true, wedgeBonds: false, addChiralHs: false
|
|
}));
|
|
{
|
|
const [xy23, xy26] = extractBondCoords(svgRebuildCoordGen, 'atom-23 atom-26');
|
|
const [_, xy25] = extractBondCoords(svgRebuildCoordGen, 'atom-26 atom-25');
|
|
const v1 = [xy23[0] - xy26[0], xy23[1] - xy26[1]];
|
|
const v2 = [xy25[0] - xy26[0], xy25[1] - xy26[1]];
|
|
const v1v2Theta = angleDegBetweenVectors(v1, v2);
|
|
assert(v1v2Theta > 145 && v1v2Theta < 150);
|
|
}
|
|
assert(!mbRebuildCoordGen.includes(invertedWedges));
|
|
wedgedMolCopy.delete();
|
|
}
|
|
|
|
function test_wedging_outside_scaffold() {
|
|
const { wedgedMol, invertedWedges } = getWedgedMolAndInvertedWedges();
|
|
const scaffold = RDKitModule.get_mol(`
|
|
RDKit 2D
|
|
|
|
9 10 0 0 1 0 0 0 0 0999 V2000
|
|
-0.8816 0.5663 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
0.6651 0.5663 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
1.2958 -0.9804 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.0435 -0.2072 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.0435 1.3395 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
1.2958 2.1129 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
2.6355 1.3395 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
3.9750 2.1129 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0
|
|
2.6355 -0.2072 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
2 1 1 1
|
|
2 3 1 0
|
|
3 4 1 6
|
|
4 5 1 0
|
|
6 5 1 6
|
|
2 6 1 0
|
|
6 7 1 0
|
|
7 8 1 6
|
|
7 9 1 0
|
|
3 9 1 0
|
|
M END
|
|
`);
|
|
let wedgedMolCopy;
|
|
wedgedMolCopy = RDKitModule.get_mol_copy(wedgedMol);
|
|
// the "alignOnly" alignment should succeed and preserve molblock wedging
|
|
// (inverted with respect to the original molecule)
|
|
// it should feature a narrow angle between the bridge bonds
|
|
// as the original geometry of the bridge is preserved
|
|
assert(JSON.parse(wedgedMolCopy.generate_aligned_coords(scaffold, JSON.stringify({ acceptFailure: false, alignOnly: true }))));
|
|
const mbAlignOnly = wedgedMolCopy.get_molblock(JSON.stringify({ useMolBlockWedging: true }));
|
|
const svgAlignOnly = wedgedMolCopy.get_svg_with_highlights(JSON.stringify({
|
|
width: 350, height: 300, useMolBlockWedging: true, wedgeBonds: false, addChiralHs: false
|
|
}));
|
|
{
|
|
const [xy23, xy26] = extractBondCoords(svgAlignOnly, 'atom-23 atom-26');
|
|
const [_, xy25] = extractBondCoords(svgAlignOnly, 'atom-26 atom-25');
|
|
const v1 = [xy23[0] - xy26[0], xy23[1] - xy26[1]];
|
|
const v2 = [xy25[0] - xy26[0], xy25[1] - xy26[1]];
|
|
const v1v2Theta = angleDegBetweenVectors(v1, v2);
|
|
assert(v1v2Theta > 10 && v1v2Theta < 15);
|
|
}
|
|
assert(mbAlignOnly.includes(invertedWedges));
|
|
// the "rebuild" alignment should succeed and clear original wedging
|
|
// it should feature a much wider angle between the bridge bonds as the
|
|
// bridged system is entirely rebuilt since it is not part of the scaffold
|
|
wedgedMolCopy.delete();
|
|
wedgedMolCopy = RDKitModule.get_mol_copy(wedgedMol);
|
|
assert(JSON.parse(wedgedMolCopy.generate_aligned_coords(scaffold, JSON.stringify({ acceptFailure: false }))));
|
|
const mbRebuild = wedgedMolCopy.get_molblock(JSON.stringify({ useMolBlockWedging: true }));
|
|
const svgRebuild = wedgedMolCopy.get_svg_with_highlights(JSON.stringify({
|
|
width: 350, height: 300, useMolBlockWedging: true, wedgeBonds: false, addChiralHs: false
|
|
}));
|
|
{
|
|
const [xy23, xy26] = extractBondCoords(svgRebuild, 'atom-23 atom-26');
|
|
const [_, xy25] = extractBondCoords(svgRebuild, 'atom-26 atom-25');
|
|
const v1 = [xy23[0] - xy26[0], xy23[1] - xy26[1]];
|
|
const v2 = [xy25[0] - xy26[0], xy25[1] - xy26[1]];
|
|
const v1v2Theta = angleDegBetweenVectors(v1, v2);
|
|
assert(v1v2Theta > 105 && v1v2Theta < 110);
|
|
}
|
|
assert(!mbRebuild.includes(invertedWedges));
|
|
// the "rebuildCoordGen" alignment should succeed and clear original wedging
|
|
// it should feature an even wider angle between the bridge bonds as CoordGen
|
|
// has a template for the bridged system.
|
|
// Additionally, CoordGen also rebuilds the scaffold, therefore original wedging
|
|
// should be cleared
|
|
wedgedMolCopy.delete();
|
|
wedgedMolCopy = RDKitModule.get_mol_copy(wedgedMol);
|
|
assert(JSON.parse(wedgedMolCopy.generate_aligned_coords(scaffold, JSON.stringify({ acceptFailure: false, useCoordGen: true }))));
|
|
const mbRebuildCoordGen = wedgedMolCopy.get_molblock(JSON.stringify({ useMolBlockWedging: true }));
|
|
const svgRebuildCoordGen = wedgedMolCopy.get_svg_with_highlights(JSON.stringify({
|
|
width: 350, height: 300, useMolBlockWedging: true, wedgeBonds: false, addChiralHs: false
|
|
}));
|
|
{
|
|
const [xy23, xy26] = extractBondCoords(svgRebuildCoordGen, 'atom-23 atom-26');
|
|
const [_, xy25] = extractBondCoords(svgRebuildCoordGen, 'atom-26 atom-25');
|
|
const v1 = [xy23[0] - xy26[0], xy23[1] - xy26[1]];
|
|
const v2 = [xy25[0] - xy26[0], xy25[1] - xy26[1]];
|
|
const v1v2Theta = angleDegBetweenVectors(v1, v2);
|
|
assert(v1v2Theta > 145 && v1v2Theta < 150);
|
|
}
|
|
assert(!mbRebuildCoordGen.includes(invertedWedges));
|
|
wedgedMolCopy.delete();
|
|
}
|
|
|
|
function test_wedging_if_no_match() {
|
|
const { wedgedMol, invertedWedges } = getWedgedMolAndInvertedWedges();
|
|
const scaffoldNoMatch = RDKitModule.get_mol(`
|
|
RDKit 2D
|
|
|
|
13 14 0 0 1 0 0 0 0 0999 V2000
|
|
-1.6549 2.5755 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.8814 1.2358 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
0.6653 1.2358 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
1.4385 2.5755 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
2.9854 2.5755 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
3.6161 1.0286 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
2.2766 1.8019 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
2.2766 3.3487 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
3.6161 4.1222 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
4.9558 3.3487 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
6.2953 4.1222 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0
|
|
4.9558 1.8019 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-1.6549 -0.1037 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
2 1 1 0
|
|
2 3 1 0
|
|
3 4 1 0
|
|
5 4 1 1
|
|
5 6 1 0
|
|
6 7 1 6
|
|
7 8 1 0
|
|
9 8 1 6
|
|
5 9 1 0
|
|
9 10 1 0
|
|
10 11 1 6
|
|
10 12 1 0
|
|
6 12 1 0
|
|
2 13 1 6
|
|
M END
|
|
`);
|
|
let wedgedMolCopy;
|
|
let mb;
|
|
const origMolBlock = wedgedMol.get_molblock(JSON.stringify({ useMolBlockWedging: true }));
|
|
// the "alignOnly" alignment should return "" if acceptFailure is false
|
|
// and preserve the original coordinates
|
|
wedgedMolCopy = RDKitModule.get_mol_copy(wedgedMol);
|
|
assert(wedgedMolCopy.generate_aligned_coords(scaffoldNoMatch, JSON.stringify({ acceptFailure: false, alignOnly: true })) === "");
|
|
mb = wedgedMolCopy.get_molblock(JSON.stringify({ useMolBlockWedging: true }));
|
|
assert(mb === origMolBlock);
|
|
assert(!mb.includes(invertedWedges));
|
|
wedgedMolCopy.delete();
|
|
// the "alignOnly" alignment should return "{}" if acceptFailure is true
|
|
// and generate new coordinates, hence wedging should be cleared
|
|
wedgedMolCopy = RDKitModule.get_mol_copy(wedgedMol);
|
|
assert(wedgedMolCopy.generate_aligned_coords(scaffoldNoMatch, JSON.stringify({ acceptFailure: true, alignOnly: true })) === "{}");
|
|
mb = wedgedMolCopy.get_molblock(JSON.stringify({ useMolBlockWedging: true }));
|
|
assert(mb !== origMolBlock);
|
|
assert(!mb.includes(invertedWedges));
|
|
wedgedMolCopy.delete();
|
|
// the "rebuild" alignment should return "" if acceptFailure is false
|
|
// and preserve the original coordinates
|
|
wedgedMolCopy = RDKitModule.get_mol_copy(wedgedMol);
|
|
assert(wedgedMolCopy.generate_aligned_coords(scaffoldNoMatch, JSON.stringify({ acceptFailure: false })) === "");
|
|
mb = wedgedMolCopy.get_molblock(JSON.stringify({ useMolBlockWedging: true }));
|
|
assert(mb === origMolBlock);
|
|
assert(!mb.includes(invertedWedges));
|
|
wedgedMolCopy.delete();
|
|
// the "rebuild" alignment should return "{}" if acceptFailure is true
|
|
// and generate new coordinates, hence wedging should be cleared
|
|
wedgedMolCopy = RDKitModule.get_mol_copy(wedgedMol);
|
|
assert(wedgedMolCopy.generate_aligned_coords(scaffoldNoMatch, JSON.stringify({ acceptFailure: true })) === "{}");
|
|
mb = wedgedMolCopy.get_molblock(JSON.stringify({ useMolBlockWedging: true }));
|
|
assert(mb !== origMolBlock);
|
|
assert(!mb.includes(invertedWedges));
|
|
wedgedMolCopy.delete();
|
|
// the "rebuildCoordGen" alignment should return "" if acceptFailure is false
|
|
// and preserve the original coordinates
|
|
wedgedMolCopy = RDKitModule.get_mol_copy(wedgedMol);
|
|
assert(wedgedMolCopy.generate_aligned_coords(scaffoldNoMatch, JSON.stringify({ acceptFailure: false, useCoordGen: true })) === "");
|
|
mb = wedgedMolCopy.get_molblock(JSON.stringify({ useMolBlockWedging: true }));
|
|
assert(mb === origMolBlock);
|
|
assert(!mb.includes(invertedWedges));
|
|
wedgedMolCopy.delete();
|
|
// the "rebuildCoordGen" alignment should return "{}" if acceptFailure is true
|
|
// and generate new coordinates, hence wedging should be cleared
|
|
wedgedMolCopy = RDKitModule.get_mol_copy(wedgedMol);
|
|
assert(wedgedMolCopy.generate_aligned_coords(scaffoldNoMatch, JSON.stringify({ acceptFailure: true, useCoordGen: true })) === "{}");
|
|
mb = wedgedMolCopy.get_molblock(JSON.stringify({ useMolBlockWedging: true }));
|
|
assert(mb !== origMolBlock);
|
|
assert(!mb.includes(invertedWedges));
|
|
wedgedMolCopy.delete();
|
|
}
|
|
|
|
function test_get_frags() {
|
|
{
|
|
var mol = RDKitModule.get_mol("n1ccccc1.CC(C)C.OCCCN");
|
|
var expectedFragSmiles = ["c1ccncc1", "CC(C)C", "NCCCO"];
|
|
var expectedFragSmilesNonSanitized = ["CN(C)(C)C", "c1ccc1"];
|
|
var expectedMappings = {
|
|
frags: [0,0,0,0,0,0,1,1,1,1,2,2,2,2,2],
|
|
fragsMolAtomMapping: [[0,1,2,3,4,5],[6,7,8,9],[10,11,12,13,14]],
|
|
};
|
|
var { molList, mappings } = mol.get_frags();
|
|
assert(molList.size() === 3);
|
|
assert(JSON.stringify(JSON.parse(mappings)) === JSON.stringify(expectedMappings));
|
|
var i = 0;
|
|
while (!molList.at_end()) {
|
|
var mol = molList.next();
|
|
assert(mol.get_smiles() === expectedFragSmiles[i++]);
|
|
mol.delete();
|
|
}
|
|
assert(!molList.next());
|
|
molList.delete();
|
|
}
|
|
{
|
|
var mol = RDKitModule.get_mol("N(C)(C)(C)C.c1ccc1", JSON.stringify({sanitize: false}));
|
|
var exceptionThrown = false;
|
|
try {
|
|
mol.get_frags();
|
|
} catch (e) {
|
|
exceptionThrown = true;
|
|
}
|
|
assert(exceptionThrown);
|
|
var { molList, mappings } = mol.get_frags(JSON.stringify({sanitizeFrags: false}));
|
|
assert(molList.size() === 2);
|
|
var i = 0;
|
|
while (!molList.at_end()) {
|
|
var mol = molList.next();
|
|
assert(mol.get_smiles() === expectedFragSmilesNonSanitized[i++]);
|
|
mol.delete();
|
|
}
|
|
assert(!molList.next());
|
|
molList.delete();
|
|
}
|
|
}
|
|
|
|
function test_get_mmpa_frags() {
|
|
{
|
|
var mol = RDKitModule.get_mol("CC(C)CCN1C(=O)CN=C(c2ccccc12)C3CCCCC3");
|
|
var expectedCores = ["O=C1CN=C(C2CCCCC2)c2ccccc2N1CCC([*:1])[*:2]", "CC([*:1])[*:2]", "CC(C[*:2])[*:1]", "CC(CC[*:2])[*:1]",
|
|
"CC(CCN1C(=O)CN=C([*:2])c2ccccc21)[*:1]", "C([*:1])[*:2]", "C(C[*:2])[*:1]", "O=C1CN=C([*:2])c2ccccc2N1CC[*:1]",
|
|
"C([*:1])[*:2]", "O=C1CN=C([*:1])c2ccccc2N1C[*:2]", "O=C1CN=C([*:1])c2ccccc2N1[*:2]"];
|
|
var expectedSidechains = ["C[*:1].C[*:2]", "C[*:1].O=C1CN=C(C2CCCCC2)c2ccccc2N1CC[*:2]", "C[*:1].O=C1CN=C(C2CCCCC2)c2ccccc2N1C[*:2]",
|
|
"C[*:1].O=C1CN=C(C2CCCCC2)c2ccccc2N1[*:2]", "C1CCC([*:2])CC1.C[*:1]", "CC(C)[*:1].O=C1CN=C(C2CCCCC2)c2ccccc2N1C[*:2]",
|
|
"CC(C)[*:1].O=C1CN=C(C2CCCCC2)c2ccccc2N1[*:2]", "C1CCC([*:2])CC1.CC(C)[*:1]", "CC(C)C[*:1].O=C1CN=C(C2CCCCC2)c2ccccc2N1[*:2]",
|
|
"C1CCC([*:1])CC1.CC(C)C[*:2]", "C1CCC([*:1])CC1.CC(C)CC[*:2]"];
|
|
var pairs = mol.get_mmpa_frags(2, 2, 20);
|
|
assert(pairs.cores);
|
|
assert(pairs.cores.size() === 11);
|
|
assert(pairs.sidechains);
|
|
assert(pairs.sidechains.size() === 11);
|
|
var i = 0;
|
|
while (!pairs.cores.at_end()) {
|
|
var m = pairs.cores.next();
|
|
assert(m.get_smiles() === expectedCores[i++]);
|
|
m.delete();
|
|
}
|
|
i = 0;
|
|
while (!pairs.sidechains.at_end()) {
|
|
var m = pairs.sidechains.next();
|
|
assert(m.get_smiles() === expectedSidechains[i++]);
|
|
m.delete();
|
|
}
|
|
assert(!pairs.cores.next());
|
|
assert(!pairs.sidechains.next());
|
|
pairs.cores.delete();
|
|
pairs.sidechains.delete();
|
|
mol.delete();
|
|
}
|
|
{
|
|
var mol = RDKitModule.get_mol("CC(C)CCN1C(=O)CN=C(c2ccccc12)C3CCCCC3");
|
|
var expectedSidechains = ["CC(CCN1C(=O)CN=C(C2CCCCC2)c2ccccc21)[*:1].C[*:1]",
|
|
"CC(C)[*:1].O=C1CN=C(C2CCCCC2)c2ccccc2N1CC[*:1]", "CC(C)C[*:1].O=C1CN=C(C2CCCCC2)c2ccccc2N1C[*:1]",
|
|
"CC(C)CC[*:1].O=C1CN=C(C2CCCCC2)c2ccccc2N1[*:1]", "C1CCC([*:1])CC1.CC(C)CCN1C(=O)CN=C([*:1])c2ccccc21"];
|
|
|
|
var pairs = mol.get_mmpa_frags(1, 1, 20);
|
|
assert(pairs.cores);
|
|
assert(pairs.cores.size() === 5);
|
|
assert(pairs.sidechains);
|
|
assert(pairs.sidechains.size() === 5);
|
|
while (!pairs.cores.at_end()) {
|
|
var m = pairs.cores.next();
|
|
assert(m === null);
|
|
}
|
|
var i = 0;
|
|
while (!pairs.sidechains.at_end()) {
|
|
var m = pairs.sidechains.next();
|
|
assert(m.get_smiles() === expectedSidechains[i++]);
|
|
m.delete();
|
|
}
|
|
assert(!pairs.cores.next());
|
|
assert(!pairs.sidechains.next());
|
|
var numCores = pairs.cores.size();
|
|
for (i = 0; i < numCores; ++i) {
|
|
assert(pairs.cores.at(i) === null);
|
|
}
|
|
for (i = 0; i < numCores; ++i) {
|
|
assert(pairs.cores.pop(0) === null);
|
|
}
|
|
assert(pairs.cores.size() === 0);
|
|
assert(pairs.cores.next() === null);
|
|
pairs.cores.delete();
|
|
pairs.sidechains.delete();
|
|
mol.delete();
|
|
}
|
|
}
|
|
|
|
function test_hs_in_place() {
|
|
{
|
|
var mol = RDKitModule.get_mol("CC");
|
|
assert(!mol.has_coords());
|
|
var descNoH = JSON.parse(mol.get_descriptors());
|
|
assert(`${descNoH.chi0v}` === '2');
|
|
assert(`${descNoH.chi1v}` === '1');
|
|
mol.add_hs_in_place();
|
|
assert(!mol.has_coords());
|
|
assert(mol.get_smiles() === '[H]C([H])([H])C([H])([H])[H]');
|
|
var descH = JSON.parse(mol.get_descriptors());
|
|
assert(`${descH.chi0v}` === '1');
|
|
assert(`${descH.chi1v}` === '0.25');
|
|
mol.delete();
|
|
}
|
|
{
|
|
var mol = RDKitModule.get_mol("C([H])([H])([H])C([H])([H])[H]", JSON.stringify({ removeHs: false }));
|
|
assert(!mol.has_coords());
|
|
var descH = JSON.parse(mol.get_descriptors());
|
|
assert(`${descH.chi0v}` === '1');
|
|
assert(`${descH.chi1v}` === '0.25');
|
|
mol.remove_hs_in_place();
|
|
assert(!mol.has_coords());
|
|
assert(mol.get_smiles() === 'CC');
|
|
var descNoH = JSON.parse(mol.get_descriptors());
|
|
assert(`${descNoH.chi0v}` === '2');
|
|
assert(`${descNoH.chi1v}` === '1');
|
|
mol.delete();
|
|
}
|
|
{
|
|
var mol = RDKitModule.get_mol(`
|
|
MJ201100
|
|
|
|
2 1 0 0 0 0 0 0 0 0999 V2000
|
|
-13.9955 5.1116 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-13.2810 5.5241 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
1 2 1 0 0 0 0
|
|
M END
|
|
`);
|
|
assert(mol.has_coords());
|
|
assert(mol.get_molblock() === `
|
|
RDKit 2D
|
|
|
|
2 1 0 0 0 0 0 0 0 0999 V2000
|
|
-13.9955 5.1116 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-13.2810 5.5241 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
1 2 1 0
|
|
M END
|
|
`);
|
|
var descNoH = JSON.parse(mol.get_descriptors());
|
|
assert(`${descNoH.chi0v}` === '2');
|
|
assert(`${descNoH.chi1v}` === '1');
|
|
mol.add_hs_in_place();
|
|
assert(mol.has_coords());
|
|
assert(mol.get_smiles() === '[H]C([H])([H])C([H])([H])[H]');
|
|
var descH = JSON.parse(mol.get_descriptors());
|
|
assert(`${descH.chi0v}` === '1');
|
|
assert(`${descH.chi1v}` === '0.25');
|
|
assert(mol.get_molblock().includes(`
|
|
RDKit 2D
|
|
|
|
8 7 0 0 0 0 0 0 0 0999 V2000
|
|
-13.9955 5.1116 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-13.2810 5.5241 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
`));
|
|
assert(mol.get_molblock().includes(` 1 2 1 0
|
|
1 3 1 0
|
|
1 4 1 0
|
|
1 5 1 0
|
|
2 6 1 0
|
|
2 7 1 0
|
|
2 8 1 0
|
|
M END
|
|
`));
|
|
mol.delete();
|
|
}
|
|
{
|
|
var mol = RDKitModule.get_mol(`
|
|
MJ201100
|
|
|
|
8 7 0 0 0 0 0 0 0 0999 V2000
|
|
-13.9955 5.1116 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-13.2810 5.5241 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-14.4080 5.8260 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-14.7100 4.6991 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-13.5830 4.3971 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-12.8685 4.8096 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-12.5665 5.9366 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-13.6935 6.2385 0.0000 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
|
|
2 6 1 0 0 0 0
|
|
2 7 1 0 0 0 0
|
|
2 8 1 0 0 0 0
|
|
M END
|
|
`, JSON.stringify({ removeHs: false }));
|
|
assert(mol.has_coords());
|
|
assert(mol.get_molblock() === `
|
|
RDKit 2D
|
|
|
|
8 7 0 0 0 0 0 0 0 0999 V2000
|
|
-13.9955 5.1116 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-13.2810 5.5241 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-14.4080 5.8260 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-14.7100 4.6991 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-13.5830 4.3971 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-12.8685 4.8096 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-12.5665 5.9366 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-13.6935 6.2385 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0
|
|
1 2 1 0
|
|
1 3 1 0
|
|
1 4 1 0
|
|
1 5 1 0
|
|
2 6 1 0
|
|
2 7 1 0
|
|
2 8 1 0
|
|
M END
|
|
`);
|
|
var descH = JSON.parse(mol.get_descriptors());
|
|
assert(`${descH.chi0v}` === '1');
|
|
assert(`${descH.chi1v}` === '0.25');
|
|
mol.remove_hs_in_place();
|
|
assert(mol.has_coords());
|
|
assert(mol.get_smiles() === 'CC');
|
|
var descNoH = JSON.parse(mol.get_descriptors());
|
|
assert(`${descNoH.chi0v}` === '2');
|
|
assert(`${descNoH.chi1v}` === '1');
|
|
assert(mol.get_molblock() === `
|
|
RDKit 2D
|
|
|
|
2 1 0 0 0 0 0 0 0 0999 V2000
|
|
-13.9955 5.1116 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-13.2810 5.5241 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
1 2 1 0
|
|
M END
|
|
`);
|
|
mol.delete();
|
|
}
|
|
}
|
|
|
|
function test_query_colour() {
|
|
var mol;
|
|
try {
|
|
mol = RDKitModule.get_qmol('c1ccc2nc([*:1])nc([*:2])c2c1');
|
|
var svg1 = mol.get_svg_with_highlights(JSON.stringify({width: 350, height: 300}));
|
|
assert(svg1.includes("width='350px'"));
|
|
assert(svg1.includes("height='300px'"));
|
|
assert(svg1.includes("</svg>"));
|
|
assert(svg1.includes("#7F7F7F"));
|
|
var svg2 = mol.get_svg_with_highlights(JSON.stringify({width: 350, height: 300, queryColour: [0.0, 0.0, 0.0]}));
|
|
assert(svg2.includes("width='350px'"));
|
|
assert(svg2.includes("height='300px'"));
|
|
assert(svg2.includes("</svg>"));
|
|
assert(!svg2.includes("#7F7F7F"));
|
|
} finally {
|
|
if (mol) {
|
|
mol.delete();
|
|
}
|
|
}
|
|
}
|
|
|
|
function test_alignment_r_groups_aromatic_ring() {
|
|
var mol;
|
|
var scaffold;
|
|
try {
|
|
mol = RDKitModule.get_mol('c1ccc2nccnc2c1');
|
|
assert(mol !== null);
|
|
scaffold = RDKitModule.get_mol(`
|
|
MJ201100
|
|
|
|
8 8 0 0 0 0 0 0 0 0999 V2000
|
|
-1.0263 -0.3133 0.0000 R# 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-2.4553 0.5116 0.0000 R# 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-1.7408 -0.7258 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-1.7408 -1.5509 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-2.4553 -1.9633 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-3.1698 -1.5509 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-3.1698 -0.7258 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-2.4553 -0.3133 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
3 1 1 0 0 0 0
|
|
8 2 1 0 0 0 0
|
|
4 3 2 0 0 0 0
|
|
5 4 1 0 0 0 0
|
|
6 5 2 0 0 0 0
|
|
7 6 1 0 0 0 0
|
|
8 3 1 0 0 0 0
|
|
8 7 2 0 0 0 0
|
|
M RGP 2 1 2 2 1
|
|
M END`);
|
|
assert(scaffold !== null);
|
|
var res = mol.generate_aligned_coords(scaffold, JSON.stringify({useCoordGen: true, allowRGroups: true}));
|
|
assert(res);
|
|
assert.equal(JSON.parse(res).atoms.length, 8);
|
|
assert.equal(JSON.parse(res).bonds.length, 8);
|
|
} finally {
|
|
if (mol) {
|
|
mol.delete();
|
|
}
|
|
}
|
|
try {
|
|
mol = RDKitModule.get_mol(`
|
|
MJ201100
|
|
|
|
10 11 0 0 0 0 0 0 0 0999 V2000
|
|
3.6937 2.5671 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
2.8687 2.5671 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
2.4561 1.8526 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
2.8687 1.1382 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
3.6937 1.1381 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
4.1062 1.8526 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
4.9313 1.8527 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
|
|
5.3438 2.5671 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
4.9313 3.2816 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
4.1062 3.2816 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
|
|
5 6 1 0 0 0 0
|
|
4 5 2 0 0 0 0
|
|
3 4 1 0 0 0 0
|
|
2 3 2 0 0 0 0
|
|
1 6 2 0 0 0 0
|
|
1 2 1 0 0 0 0
|
|
8 9 1 0 0 0 0
|
|
9 10 2 0 0 0 0
|
|
10 1 1 0 0 0 0
|
|
7 8 2 0 0 0 0
|
|
6 7 1 0 0 0 0
|
|
M END`);
|
|
var res = mol.generate_aligned_coords(scaffold, JSON.stringify({allowRGroups: true, alignOnly: true}));
|
|
assert(res);
|
|
assert.equal(JSON.parse(res).atoms.length, 8);
|
|
assert.equal(JSON.parse(res).bonds.length, 8);
|
|
} finally {
|
|
if (mol) {
|
|
mol.delete();
|
|
}
|
|
if (scaffold) {
|
|
scaffold.delete();
|
|
}
|
|
}
|
|
}
|
|
|
|
function test_is_valid_deprecated() {
|
|
var mol = RDKitModule.get_mol('C');
|
|
assert(mol !== null);
|
|
assert(mol.is_valid());
|
|
var mol;
|
|
try {
|
|
mol = RDKitModule.get_mol('CN(C)(C)C');
|
|
} catch (e) {
|
|
// in case MinimalLib was built without exception support
|
|
mol = null;
|
|
}
|
|
assert(mol === null);
|
|
if (RDKitModule.get_rxn) {
|
|
var rxn;
|
|
rxn = RDKitModule.get_rxn('C>>N');
|
|
assert(rxn !== null);
|
|
try {
|
|
rxn = RDKitModule.get_rxn('Z>>C');
|
|
} catch (e) {
|
|
// in case MinimalLib was built without exception support
|
|
rxn = null;
|
|
}
|
|
assert(rxn === null);
|
|
}
|
|
}
|
|
|
|
function molListFromSmiArray(smiArray) {
|
|
const molList = new RDKitModule.MolList();
|
|
assert(molList);
|
|
smiArray.forEach((smiName) => {
|
|
const [smi, name] = smiName.split(' ');
|
|
let mol;
|
|
try {
|
|
mol = RDKitModule.get_mol(smi);
|
|
assert(mol);
|
|
molList.append(mol);
|
|
} finally {
|
|
if (mol) {
|
|
mol.delete();
|
|
}
|
|
}
|
|
});
|
|
return molList;
|
|
}
|
|
|
|
function test_mol_list() {
|
|
const smiArray = [ 'C1CC1', 'C1CCCC1' ];
|
|
let molList;
|
|
let mol;
|
|
try {
|
|
molList = molListFromSmiArray(smiArray);
|
|
assert(molList);
|
|
assert.equal(molList.size(), 2);
|
|
assert(!molList.at_end());
|
|
try {
|
|
mol = molList.next();
|
|
assert(mol);
|
|
} finally {
|
|
if (mol) {
|
|
mol.delete();
|
|
}
|
|
}
|
|
try {
|
|
mol = molList.next();
|
|
assert(mol);
|
|
} finally {
|
|
if (mol) {
|
|
mol.delete();
|
|
}
|
|
}
|
|
mol = molList.next();
|
|
assert(!mol);
|
|
assert(molList.at_end());
|
|
try {
|
|
mol = molList.at(0);
|
|
assert.equal(mol.get_num_atoms(), 3);
|
|
} finally {
|
|
if (mol) {
|
|
mol.delete();
|
|
}
|
|
}
|
|
try {
|
|
mol = molList.at(1);
|
|
assert.equal(mol.get_num_atoms(), 5);
|
|
} finally {
|
|
if (mol) {
|
|
mol.delete();
|
|
}
|
|
}
|
|
assert(molList.at_end());
|
|
try {
|
|
mol = RDKitModule.get_mol('C1CCC1');
|
|
assert(mol);
|
|
molList.insert(1, mol);
|
|
assert.equal(molList.size(), 3);
|
|
assert(!molList.at_end());
|
|
} finally {
|
|
if (mol) {
|
|
mol.delete();
|
|
}
|
|
}
|
|
molList.reset();
|
|
assert(!molList.at_end());
|
|
try {
|
|
mol = molList.at(1);
|
|
assert.equal(mol.get_num_atoms(), 4);
|
|
} finally {
|
|
if (mol) {
|
|
mol.delete();
|
|
}
|
|
}
|
|
try {
|
|
mol = molList.pop(0);
|
|
assert.equal(mol.get_num_atoms(), 3);
|
|
} finally {
|
|
if (mol) {
|
|
mol.delete();
|
|
}
|
|
}
|
|
assert.equal(molList.size(), 2);
|
|
let i = 0;
|
|
while (!molList.at_end()) {
|
|
try {
|
|
mol = molList.next();
|
|
} finally {
|
|
if (mol) {
|
|
++i;
|
|
mol.delete();
|
|
}
|
|
}
|
|
}
|
|
assert.equal(i, 2);
|
|
assert(molList.at_end());
|
|
try {
|
|
mol = molList.pop(0);
|
|
assert.equal(mol.get_num_atoms(), 4);
|
|
} finally {
|
|
if (mol) {
|
|
mol.delete();
|
|
}
|
|
}
|
|
assert.equal(molList.size(), 1);
|
|
assert(molList.at_end());
|
|
try {
|
|
mol = molList.pop(0);
|
|
assert.equal(mol.get_num_atoms(), 5);
|
|
} finally {
|
|
if (mol) {
|
|
mol.delete();
|
|
}
|
|
}
|
|
assert.equal(molList.size(), 0);
|
|
assert(molList.at_end());
|
|
assert(!molList.pop(0));
|
|
try {
|
|
mol = RDKitModule.get_mol('C1CCCCC1');
|
|
assert(mol);
|
|
molList.append(mol);
|
|
assert.equal(molList.size(), 1);
|
|
assert(!molList.at_end());
|
|
} finally {
|
|
if (mol) {
|
|
mol.delete();
|
|
}
|
|
}
|
|
assert(!molList.at(1));
|
|
try {
|
|
mol = molList.at(0);
|
|
assert(mol);
|
|
assert(mol.get_num_atoms(), 6);
|
|
} finally {
|
|
if (mol) {
|
|
mol.delete();
|
|
}
|
|
}
|
|
} finally {
|
|
if (molList) {
|
|
molList.delete();
|
|
}
|
|
}
|
|
}
|
|
|
|
function test_mcs() {
|
|
{
|
|
const smiArray = [
|
|
"COc1cc2nc(-c3cc(NC(=O)CSc4ccc(Cl)cc4)ccc3)oc2cc1 CHEMBL1479679",
|
|
"COc1cc2nc(-c3cc(NC(=O)CSc4ccc(Cl)cc4)c(C)cc3)oc2cc1 CHEMBL1333382",
|
|
"Cc1cc2oc(-c3cc(NC(=O)CSc4ccc(Cl)cc4)ccc3)nc2cc1 CHEMBL1437584",
|
|
"COc1c(NC(=O)CSc2ccc(Cl)cc2)cc(-c2nc3ccccc3o2)cc1 CHEMBL1601350",
|
|
"Cc1cc2nc(-c3cccc(NC(=O)CSc4ccc(Cl)cc4)c3)oc2cc1C CHEMBL1398008",
|
|
"Cc1cc2oc(-c3cc(NC(=O)CSc4ccc(Cl)cc4)c(C)cc3)nc2cc1 CHEMBL1612903",
|
|
"COc1cc2nc(-c3cc(NC(=O)Cc4ccc(Cl)cc4)c(C)cc3)oc2cc1 CHEMBL1316483",
|
|
"Cc1c(NC(=O)CSc2ccc(Cl)cc2)cccc1-c1nc2cc(Cl)ccc2o1 CHEMBL1568754",
|
|
"COc1ccc2oc(-c3ccc(C)c(NC(=O)COc4cc(C)cc(C)c4)c3)nc2c1 CHEMBL1436972",
|
|
"Cc1ccc(SCC(=O)Nc2cc(-c3nc4cc(C)ccc4o3)c(O)cc2)cc1 CHEMBL1611932",
|
|
];
|
|
let molList;
|
|
let mcsSmarts;
|
|
try {
|
|
molList = molListFromSmiArray(smiArray);
|
|
let mcsMol;
|
|
try {
|
|
mcsMol = RDKitModule.get_mcs_as_mol(molList);
|
|
assert(mcsMol);
|
|
assert.equal(mcsMol.get_smarts(), '[#6]1:[#6]:[#6]2:[#8]:[#6](:[#7]:[#6]:2:[#6]:[#6]:1)-[#6]1:[#6]:[#6](-[#7]-[#6](=[#8])-[#6]):[#6]:[#6]:[#6]:1');
|
|
mcsSmarts = RDKitModule.get_mcs_as_smarts(molList);
|
|
} finally {
|
|
if (mcsMol) {
|
|
mcsMol.delete();
|
|
}
|
|
}
|
|
} finally {
|
|
if (molList) {
|
|
molList.delete();
|
|
}
|
|
}
|
|
assert(mcsSmarts);
|
|
assert.equal(mcsSmarts, '[#6]1:[#6]:[#6]2:[#8]:[#6](:[#7]:[#6]:2:[#6]:[#6]:1)-[#6]1:[#6]:[#6](-[#7]-[#6](=[#8])-[#6]):[#6]:[#6]:[#6]:1');
|
|
}
|
|
{
|
|
const smiArray = ["C1CC1N2CC2", "C1CC1N"];
|
|
let molList;
|
|
try {
|
|
molList = molListFromSmiArray(smiArray);
|
|
let mcsMol;
|
|
try {
|
|
mcsMol = RDKitModule.get_mcs_as_mol(molList);
|
|
assert(mcsMol);
|
|
assert.equal(mcsMol.get_num_atoms(), 4);
|
|
assert.equal(mcsMol.get_num_bonds(), 4);
|
|
} finally {
|
|
if (mcsMol) {
|
|
mcsMol.delete();
|
|
}
|
|
}
|
|
try {
|
|
mcsMol = RDKitModule.get_mcs_as_mol(molList, JSON.stringify({ RingMatchesRingOnly: true }));
|
|
assert(mcsMol);
|
|
assert.equal(mcsMol.get_num_atoms(), 3);
|
|
assert.equal(mcsMol.get_num_bonds(), 3);
|
|
} finally {
|
|
if (mcsMol) {
|
|
mcsMol.delete();
|
|
}
|
|
}
|
|
} finally {
|
|
if (molList) {
|
|
molList.delete();
|
|
}
|
|
}
|
|
}
|
|
{
|
|
const smiArray = ["NC1CCCCC1", "Cc1ccccc1", "Cc1cnccc1", "CC1CCCCN1"];
|
|
let molList;
|
|
const res = new Set();
|
|
try {
|
|
molList = molListFromSmiArray(smiArray);
|
|
["Elements", "Any"].forEach((AtomCompare) => {
|
|
["Order", "OrderExact"].forEach((BondCompare) => {
|
|
const details = {
|
|
AtomCompare,
|
|
BondCompare
|
|
};
|
|
let mcsSmarts;
|
|
mcsSmarts = RDKitModule.get_mcs_as_smarts(molList, JSON.stringify(details));
|
|
assert(mcsSmarts);
|
|
res.add(mcsSmarts);
|
|
});
|
|
});
|
|
} finally {
|
|
if (molList) {
|
|
molList.delete();
|
|
}
|
|
}
|
|
assert(res.size === 4);
|
|
}
|
|
{
|
|
const smiArray = [
|
|
"c1cccc(c12)ccc(c2)-c3n(CCC[NH3+])c(nn3)SCCc4c[nH]c(c45)cccc5",
|
|
"c1cccc(c12)sc(c2)-c3n(CCCC[NH3+])c(nn3)SCCc4c[nH]c(c45)cccc5",
|
|
];
|
|
let molList;
|
|
let mcs;
|
|
try {
|
|
molList = molListFromSmiArray(smiArray);
|
|
mcs = RDKitModule.get_mcs_as_json(molList, JSON.stringify({
|
|
RingMatchesRingOnly: true,
|
|
CompleteRingsOnly: true,
|
|
BondCompare: 'Any',
|
|
AtomCompare: 'Any',
|
|
Timeout: 1,
|
|
}));
|
|
} finally {
|
|
if (molList) {
|
|
molList.delete();
|
|
}
|
|
}
|
|
assert(mcs);
|
|
mcs = JSON.parse(mcs);
|
|
assert(mcs.canceled);
|
|
}
|
|
{
|
|
const smiArray = [
|
|
"Nc1ccc(cc1)C-Cc1c(N)cccc1",
|
|
"Nc1ccc(cc1)C=Cc1c(N)cccc1",
|
|
];
|
|
let molList;
|
|
let mcs;
|
|
try {
|
|
molList = molListFromSmiArray(smiArray);
|
|
mcs = RDKitModule.get_mcs_as_json(molList);
|
|
} finally {
|
|
if (molList) {
|
|
molList.delete();
|
|
}
|
|
}
|
|
assert(mcs);
|
|
mcs = JSON.parse(mcs);
|
|
assert(!mcs.canceled);
|
|
assert(!Array.isArray(mcs.smarts));
|
|
assert(mcs.numAtoms === 8);
|
|
assert(mcs.numBonds === 8);
|
|
assert(mcs.smarts === '[#7]-[#6]1:[#6]:[#6]:[#6](:[#6]:[#6]:1)-[#6]');
|
|
try {
|
|
molList = molListFromSmiArray(smiArray);
|
|
mcs = RDKitModule.get_mcs_as_json(molList, JSON.stringify({StoreAll: true}));
|
|
} finally {
|
|
if (molList) {
|
|
molList.delete();
|
|
}
|
|
}
|
|
assert(mcs);
|
|
mcs = JSON.parse(mcs);
|
|
assert(!mcs.canceled);
|
|
assert(Array.isArray(mcs.smarts));
|
|
assert(mcs.numAtoms === 8);
|
|
assert(mcs.numBonds === 8);
|
|
assert(mcs.smarts.length === 2);
|
|
assert(mcs.smarts.includes('[#6]-[#6]1:[#6]:[#6]:[#6]:[#6]:[#6]:1-[#7]'));
|
|
assert(mcs.smarts.includes('[#7]-[#6]1:[#6]:[#6]:[#6](:[#6]:[#6]:1)-[#6]'));
|
|
}
|
|
{
|
|
const smiArray = [
|
|
"C1CC1",
|
|
"c1ccccc1",
|
|
];
|
|
let molList;
|
|
let mcs;
|
|
try {
|
|
molList = molListFromSmiArray(smiArray);
|
|
mcs = RDKitModule.get_mcs_as_json(molList, JSON.stringify({ CompleteRingsOnly: true }));
|
|
} finally {
|
|
if (molList) {
|
|
molList.delete();
|
|
}
|
|
}
|
|
assert(mcs);
|
|
mcs = JSON.parse(mcs);
|
|
assert(!mcs.canceled);
|
|
assert(!mcs.numAtoms);
|
|
assert(!mcs.numBonds);
|
|
assert(!mcs.smarts);
|
|
try {
|
|
molList = molListFromSmiArray(smiArray);
|
|
mcs = RDKitModule.get_mcs_as_json(molList, JSON.stringify({ CompleteRingsOnly: true, StoreAll: true }));
|
|
} finally {
|
|
if (molList) {
|
|
molList.delete();
|
|
}
|
|
}
|
|
assert(mcs);
|
|
mcs = JSON.parse(mcs);
|
|
assert(!mcs.canceled);
|
|
assert(!mcs.numAtoms);
|
|
assert(!mcs.numBonds);
|
|
assert(!mcs.smarts.length);
|
|
}
|
|
}
|
|
|
|
function test_get_num_atoms_bonds() {
|
|
var mol = RDKitModule.get_mol('CCCC');
|
|
var molH = RDKitModule.get_mol_copy(mol);
|
|
molH.add_hs_in_place();
|
|
assert.equal(mol.get_num_atoms(), molH.get_num_atoms(true));
|
|
assert.equal(mol.get_num_atoms(), 4);
|
|
assert.equal(molH.get_num_atoms(), 14);
|
|
assert.equal(molH.get_num_atoms(false), 14);
|
|
assert.equal(mol.get_num_bonds(), 3);
|
|
assert.equal(molH.get_num_bonds(), 13);
|
|
}
|
|
|
|
function test_sanitize_no_kekulize_no_setaromaticity() {
|
|
var molblock1 = `
|
|
RDKit 2D
|
|
|
|
6 6 0 0 0 0 0 0 0 0999 V2000
|
|
1.5000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
0.7500 -1.2990 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.7500 -1.2990 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-1.5000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.7500 1.2990 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
0.7500 1.2990 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
1 2 2 0
|
|
2 3 1 0
|
|
3 4 2 0
|
|
4 5 1 0
|
|
5 6 2 0
|
|
6 1 1 0
|
|
M END`;
|
|
var molblock2 = `
|
|
RDKit 2D
|
|
|
|
6 6 0 0 0 0 0 0 0 0999 V2000
|
|
1.5000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
0.7500 -1.2990 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.7500 -1.2990 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-1.5000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.7500 1.2990 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
0.7500 1.2990 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
1 2 1 0
|
|
2 3 2 0
|
|
3 4 1 0
|
|
4 5 2 0
|
|
5 6 1 0
|
|
6 1 2 0
|
|
M END`;
|
|
var mol1 = RDKitModule.get_mol(molblock1, JSON.stringify({kekulize: false, setAromaticity: false}));
|
|
var mol2 = RDKitModule.get_mol(molblock2, JSON.stringify({kekulize: false, setAromaticity: false}));
|
|
assert.notEqual(mol1.get_molblock(), mol2.get_molblock());
|
|
mol1.delete();
|
|
mol2.delete();
|
|
mol1 = RDKitModule.get_mol(molblock1);
|
|
mol2 = RDKitModule.get_mol(molblock2);
|
|
assert.equal(mol1.get_molblock(), mol2.get_molblock());
|
|
mol1.delete();
|
|
mol2.delete();
|
|
}
|
|
|
|
function test_partial_sanitization() {
|
|
var mol1 = RDKitModule.get_mol('C1CCC2CCCC2C1', JSON.stringify({
|
|
sanitize: false, removeHs: false, assignStereo: false,
|
|
}));
|
|
var fp1 = mol1.get_morgan_fp(JSON.stringify({radius: 2, nBits: 32}));
|
|
assert.equal(fp1, '00001001010101000000100000110010');
|
|
mol1.delete();
|
|
var mol2 = RDKitModule.get_mol('C1CCC2CCCC2C1', JSON.stringify({
|
|
sanitize: false, removeHs: false, assignStereo: false, fastFindRings: false
|
|
}));
|
|
var exceptionThrown = false;
|
|
try {
|
|
mol2.get_morgan_fp(JSON.stringify({radius: 2, nBits: 32}));
|
|
} catch (e) {
|
|
exceptionThrown = true;
|
|
}
|
|
assert(exceptionThrown);
|
|
mol2.delete();
|
|
}
|
|
|
|
function test_capture_logs() {
|
|
["set_log_tee", "set_log_capture"].forEach((func, i) => {
|
|
console.log(`${i + 1}. ${func}`);
|
|
var logHandle = RDKitModule[func]("dummy");
|
|
assert(!logHandle);
|
|
var logHandle = RDKitModule[func]("rdApp.*");
|
|
assert(logHandle);
|
|
var logBuffer = logHandle.get_buffer();
|
|
assert(!logBuffer);
|
|
var mol = RDKitModule.get_mol("CN(C)(C)C");
|
|
assert(!mol);
|
|
logBuffer = logHandle.get_buffer();
|
|
assert(logBuffer);
|
|
assert(logBuffer.includes('Explicit valence for atom # 1 N, 4, is greater than permitted'));
|
|
logHandle.clear_buffer();
|
|
assert(!logHandle.get_buffer());
|
|
logHandle.delete();
|
|
})
|
|
}
|
|
|
|
function test_rgroup_match_heavy_hydro_none_charged() {
|
|
var templateRef = RDKitModule.get_mol(`
|
|
MJ201100
|
|
|
|
7 7 0 0 0 0 0 0 0 0999 V2000
|
|
-0.5804 1.2045 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-1.2948 0.7920 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-1.2948 -0.0330 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.5804 -0.4455 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
0.1340 -0.0330 0.0000 A 0 0 0 0 0 0 0 0 0 0 0 0
|
|
0.1340 0.7920 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
0.8485 -0.4455 0.0000 R# 0 0 0 0 0 0 0 0 0 0 0 0
|
|
1 2 2 0 0 0 0
|
|
2 3 1 0 0 0 0
|
|
3 4 2 0 0 0 0
|
|
6 1 1 0 0 0 0
|
|
4 5 1 0 0 0 0
|
|
5 6 2 0 0 0 0
|
|
5 7 1 0 0 0 0
|
|
M RGP 1 7 1
|
|
M END
|
|
`);
|
|
assert(templateRef);
|
|
var mol;
|
|
var allowRGroups = true;
|
|
[true, false].forEach((alignOnly) => {
|
|
mol = RDKitModule.get_mol("Cc1ccccc1");
|
|
assert(mol);
|
|
assert.equal(mol.get_num_atoms(), 7);
|
|
assert.equal(JSON.parse(mol.generate_aligned_coords(templateRef, JSON.stringify({ allowRGroups, alignOnly }))).atoms.length, 7);
|
|
mol.delete();
|
|
mol = RDKitModule.get_mol("c1ccccc1");
|
|
assert(mol);
|
|
assert.equal(mol.get_num_atoms(), 6);
|
|
assert.equal(JSON.parse(mol.generate_aligned_coords(templateRef, JSON.stringify({ allowRGroups, alignOnly }))).atoms.length, 6);
|
|
mol.delete();
|
|
mol = RDKitModule.get_mol("[H]c1ccccc1", JSON.stringify({removeHs: false}));
|
|
assert(mol);
|
|
assert.equal(mol.get_num_atoms(), 7);
|
|
assert.equal(JSON.parse(mol.generate_aligned_coords(templateRef, JSON.stringify({ allowRGroups, alignOnly }))).atoms.length, 7);
|
|
mol.delete();
|
|
mol = RDKitModule.get_mol("n1ccccc1");
|
|
assert(mol);
|
|
assert.equal(mol.get_num_atoms(), 6);
|
|
assert.equal(JSON.parse(mol.generate_aligned_coords(templateRef, JSON.stringify({ allowRGroups, alignOnly }))).atoms.length, 6);
|
|
mol.delete();
|
|
mol = RDKitModule.get_mol("C[n+]1ccccc1");
|
|
assert(mol);
|
|
assert.equal(mol.get_num_atoms(), 7);
|
|
assert.equal(JSON.parse(mol.generate_aligned_coords(templateRef, JSON.stringify({ allowRGroups, alignOnly }))).atoms.length, 7);
|
|
mol.delete();
|
|
});
|
|
templateRef.delete();
|
|
}
|
|
|
|
function test_get_sss_json() {
|
|
var fentanylScaffold = RDKitModule.get_mol(`
|
|
MJ201100
|
|
|
|
25 27 0 0 0 0 0 0 0 0999 V2000
|
|
-0.3910 -1.2720 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-1.2160 -1.2721 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-1.6285 -1.9866 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-1.2161 -2.7010 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.3911 -2.7011 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
0.0214 -1.9865 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
0.0213 -0.5575 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.3911 0.1568 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
0.0213 0.8713 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.3911 1.5859 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-1.2161 1.5858 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-1.6287 0.8714 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-1.2161 0.1568 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-1.6286 2.3002 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
0.8463 -0.5575 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
1.2588 0.1569 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-2.4536 2.3002 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-2.8661 1.5858 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-3.6910 1.5858 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-4.1036 0.8712 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-3.6912 0.1568 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-2.8662 0.1567 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-2.4536 0.8713 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
1.2589 -1.2720 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
2.0839 -1.2719 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
1 2 2 0 0 0 0
|
|
2 3 1 0 0 0 0
|
|
3 4 2 0 0 0 0
|
|
4 5 1 0 0 0 0
|
|
5 6 2 0 0 0 0
|
|
6 1 1 0 0 0 0
|
|
9 10 1 0 0 0 0
|
|
12 13 1 0 0 0 0
|
|
8 9 1 0 0 0 0
|
|
8 13 1 0 0 0 0
|
|
10 11 1 0 0 0 0
|
|
11 12 1 0 0 0 0
|
|
11 14 1 0 0 0 0
|
|
1 7 1 0 0 0 0
|
|
7 8 1 0 0 0 0
|
|
7 15 1 0 0 0 0
|
|
14 17 1 0 0 0 0
|
|
17 18 1 0 0 0 0
|
|
19 20 1 0 0 0 0
|
|
20 21 2 0 0 0 0
|
|
21 22 1 0 0 0 0
|
|
22 23 2 0 0 0 0
|
|
18 19 2 0 0 0 0
|
|
23 18 1 0 0 0 0
|
|
15 24 1 0 0 0 0
|
|
24 25 1 0 0 0 0
|
|
15 16 2 0 0 0 0
|
|
M END
|
|
`);
|
|
var bilastine = RDKitModule.get_mol("O=C(O)C(c1ccc(cc1)CCN4CCC(c2nc3ccccc3n2CCOCC)CC4)(C)C");
|
|
var referenceSmarts = "c1ccccc1CCN1CCCCC1";
|
|
var res = bilastine.generate_aligned_coords(fentanylScaffold, JSON.stringify({useCoordGen: true, referenceSmarts}));
|
|
assert(res);
|
|
var resExpected = "{\"atoms\":[6,5,4,9,8,7,10,11,12,13,14,15,30,31],\"bonds\":[13,30,14,29,12,36,11,10,9,5,4,33,8,6,7]}";
|
|
assert.equal(res, resExpected);
|
|
assert.equal(JSON.parse(res).bonds.length, 15);
|
|
bilastine.delete();
|
|
fentanylScaffold.delete();
|
|
}
|
|
|
|
function test_relabel_mapped_dummies() {
|
|
var core = RDKitModule.get_mol("c1cc([4*:2])c([3*:1])cn1");
|
|
assert.equal(core.get_cxsmiles(), "c1cc([4*:2])c([3*:1])cn1 |atomProp:3.dummyLabel.*:3.molAtomMapNumber.2:5.dummyLabel.*:5.molAtomMapNumber.1|");
|
|
core.delete();
|
|
core = RDKitModule.get_mol("c1cc([4*:2])c([3*:1])cn1", JSON.stringify({mappedDummiesAreRGroups: true}));
|
|
assert.equal(core.get_cxsmiles(), "*c1ccncc1* |atomProp:0.dummyLabel.R2:7.dummyLabel.R1|");
|
|
core.delete();
|
|
}
|
|
|
|
function test_assign_cip_labels() {
|
|
var origSetting;
|
|
const getTextSection = (svg) => (
|
|
svg.split('\n').map((line) => line.replace(/^<text.+>([^<]*)<\/text>$/, '$1')).join('')
|
|
);
|
|
try {
|
|
origSetting = RDKitModule.use_legacy_stereo_perception(true);
|
|
{
|
|
var mol = RDKitModule.get_mol('C/C=C/c1ccccc1[S@@](C)=O');
|
|
var svg = mol.get_svg_with_highlights(JSON.stringify({noFreetype: true, addStereoAnnotation: true}));
|
|
assert(getTextSection(svg).includes("(S)"));
|
|
assert(!getTextSection(svg).includes("(R)"));
|
|
mol.delete();
|
|
}
|
|
RDKitModule.use_legacy_stereo_perception(false);
|
|
{
|
|
var mol = RDKitModule.get_mol('C/C=C/c1ccccc1[S@@](C)=O');
|
|
var svg = mol.get_svg_with_highlights(JSON.stringify({noFreetype: true, addStereoAnnotation: true}));
|
|
assert(!getTextSection(svg).includes("(S)"));
|
|
assert(!getTextSection(svg).includes("(R)"));
|
|
mol.delete();
|
|
}
|
|
{
|
|
var mol = RDKitModule.get_mol('C/C=C/c1ccccc1[S@@](C)=O', JSON.stringify({assignCIPLabels: true}));
|
|
var svg = mol.get_svg_with_highlights(JSON.stringify({noFreetype: true, addStereoAnnotation: true}));
|
|
assert(!getTextSection(svg).includes("(S)"));
|
|
assert(getTextSection(svg).includes("(R)"));
|
|
mol.delete();
|
|
}
|
|
} finally {
|
|
RDKitModule.use_legacy_stereo_perception(origSetting);
|
|
}
|
|
}
|
|
|
|
function test_smiles_smarts_params() {
|
|
{
|
|
const amoxicillinPubChem = 'CC1([C@@H](N2[C@H](S1)[C@@H](C2=O)NC(=O)[C@@H](C3=CC=C(C=C3)O)N)C(=O)O)C';
|
|
const mol = RDKitModule.get_mol(amoxicillinPubChem);
|
|
{
|
|
const canonicalSmiles = mol.get_smiles();
|
|
assert(canonicalSmiles === 'CC1(C)S[C@@H]2[C@H](NC(=O)[C@H](N)c3ccc(O)cc3)C(=O)N2[C@H]1C(=O)O');
|
|
}
|
|
['{}', ''].forEach((emptyJson) => {
|
|
const canonicalSmiles = mol.get_smiles(emptyJson);
|
|
assert(canonicalSmiles === 'CC1(C)S[C@@H]2[C@H](NC(=O)[C@H](N)c3ccc(O)cc3)C(=O)N2[C@H]1C(=O)O');
|
|
});
|
|
const nonCanonicalSmiles = mol.get_smiles(JSON.stringify({canonical: false}));
|
|
assert(nonCanonicalSmiles === 'CC1(C)[C@H](C(=O)O)N2[C@H](S1)[C@H](NC(=O)[C@@H](c1ccc(O)cc1)N)C2=O');
|
|
const canonicalSmilesNoStereo = mol.get_smiles(JSON.stringify({doIsomericSmiles: false}));
|
|
assert(canonicalSmilesNoStereo === 'CC1(C)SC2C(NC(=O)C(N)c3ccc(O)cc3)C(=O)N2C1C(=O)O');
|
|
const nonCanonicalSmilesNoStereo = mol.get_smiles(JSON.stringify({doIsomericSmiles: false, canonical: false}));
|
|
assert(nonCanonicalSmilesNoStereo === 'CC1(C)C(C(=O)O)N2C(S1)C(NC(=O)C(c1ccc(O)cc1)N)C2=O');
|
|
mol.delete();
|
|
}
|
|
{
|
|
const bicyclo221heptane = `
|
|
RDKit 2D
|
|
|
|
9 10 0 0 1 0 0 0 0 0999 V2000
|
|
-2.8237 -1.3088 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-1.5723 -0.3996 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-1.5723 1.1473 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.1011 1.6253 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
1.3701 1.1474 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
1.3701 -0.3995 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
2.6217 -1.3087 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
|
|
-0.1009 -0.8775 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
0.8083 0.3739 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
2 1 1 1
|
|
2 3 1 0
|
|
4 3 1 0
|
|
4 5 1 0
|
|
6 5 1 0
|
|
6 7 1 1
|
|
6 8 1 0
|
|
8 9 1 1
|
|
8 2 1 0
|
|
4 9 1 1
|
|
M END
|
|
`;
|
|
const mol = RDKitModule.get_mol(bicyclo221heptane);
|
|
{
|
|
const canonicalCXSmiles = mol.get_cxsmiles();
|
|
const [_, canonicalSmiles, wedging] = canonicalCXSmiles.match(/^(\S+) \|\([^\)]+\),([^\|]+)\|$/);
|
|
assert(canonicalSmiles === 'N[C@@H]1C[C@@H]2C[C@H]1[C@@H](O)C2');
|
|
assert(wedging === 'wD:3.9,wU:1.0,5.4,6.7');
|
|
}
|
|
['{}', ''].forEach((emptyJson) => {
|
|
const canonicalCXSmiles = mol.get_cxsmiles(emptyJson);
|
|
const [_, canonicalSmiles, wedging] = canonicalCXSmiles.match(/^(\S+) \|\([^\)]+\),([^\|]+)\|$/);
|
|
assert(canonicalSmiles === 'N[C@@H]1C[C@@H]2C[C@H]1[C@@H](O)C2');
|
|
assert(wedging === 'wD:3.9,wU:1.0,5.4,6.7');
|
|
});
|
|
{
|
|
const canonicalCXSmiles = mol.get_cxsmiles(JSON.stringify({restoreBondDirOption: 'RestoreBondDirOptionTrue'}));
|
|
const [_, canonicalSmiles, wedging] = canonicalCXSmiles.match(/^(\S+) \|\([^\)]+\),([^\|]+)\|$/);
|
|
assert(canonicalSmiles === 'N[C@@H]1C[C@@H]2C[C@H]1[C@@H](O)C2');
|
|
assert(wedging === 'wU:1.0,3.3,5.4,6.7');
|
|
}
|
|
{
|
|
const nonCanonicalCXSmilesNoStereo = mol.get_cxsmiles(JSON.stringify({doIsomericSmiles: false, canonical: false, CX_ALL_BUT_COORDS: true}));
|
|
assert(nonCanonicalCXSmilesNoStereo === 'OC1CC2CC(N)C1C2');
|
|
const nonCanonicalCXSmilesNoStereoAtomProp = `${nonCanonicalCXSmilesNoStereo} |atomProp:1.atomProp.1.234|`;
|
|
const molWithAtomProp = RDKitModule.get_mol(nonCanonicalCXSmilesNoStereoAtomProp);
|
|
assert(molWithAtomProp);
|
|
const cxSmilesWithAtomProp = molWithAtomProp.get_cxsmiles(JSON.stringify({CX_ALL_BUT_COORDS: true}));
|
|
assert(cxSmilesWithAtomProp === 'NC1CC2CC(O)C1C2 |atomProp:5.atomProp.1.234|');
|
|
molWithAtomProp.delete();
|
|
}
|
|
mol.delete();
|
|
}
|
|
{
|
|
const chiralQuery = RDKitModule.get_qmol('N-[C@H](-C(-O)=O)-C(-C)-C');
|
|
assert(chiralQuery.get_smarts() === 'N-[C@&H1](-C(-O)=O)-C(-C)-C');
|
|
['', '{}'].forEach((emptyJson) => {
|
|
assert(chiralQuery.get_smarts(emptyJson) === 'N-[C@&H1](-C(-O)=O)-C(-C)-C');
|
|
});
|
|
assert(chiralQuery.get_smarts(JSON.stringify({doIsomericSmiles: false})) === 'N-[C&H1](-C(-O)=O)-C(-C)-C');
|
|
}
|
|
{
|
|
const chiralQuery = RDKitModule.get_qmol('N-[C@H](-C(-O)=O)-C(-C)-C |atomProp:1.atomProp.1.234|');
|
|
assert(chiralQuery.get_cxsmarts() === 'N-[C@&H1](-C(-O)=O)-C(-C)-C |atomProp:1.atomProp.1.234|');
|
|
['', '{}'].forEach((emptyJson) => {
|
|
assert(chiralQuery.get_cxsmarts(emptyJson) === 'N-[C@&H1](-C(-O)=O)-C(-C)-C |atomProp:1.atomProp.1.234|');
|
|
});
|
|
assert(chiralQuery.get_cxsmarts(JSON.stringify({doIsomericSmiles: false})) === 'N-[C&H1](-C(-O)=O)-C(-C)-C |atomProp:1.atomProp.1.234|');
|
|
}
|
|
}
|
|
|
|
function test_wedged_bond_atropisomer() {
|
|
var atropisomer = `
|
|
Mrv2311 05242408162D
|
|
|
|
0 0 0 0 0 999 V3000
|
|
M V30 BEGIN CTAB
|
|
M V30 COUNTS 14 15 0 0 0
|
|
M V30 BEGIN ATOM
|
|
M V30 1 C 2.0006 -1.54 0 0
|
|
M V30 2 N 2.0006 -3.08 0 0
|
|
M V30 3 C 0.6669 -3.85 0 0
|
|
M V30 4 C -0.6668 -3.08 0 0
|
|
M V30 5 C -0.6668 -1.54 0 0
|
|
M V30 6 C -2.0006 -0.77 0 0
|
|
M V30 7 C 0.6669 -0.77 0 0
|
|
M V30 8 C 0.6669 0.77 0 0
|
|
M V30 9 C -0.6668 1.54 0 0
|
|
M V30 10 C -2.0006 0.77 0 0
|
|
M V30 11 C -0.6668 3.08 0 0
|
|
M V30 12 C 0.6669 3.85 0 0
|
|
M V30 13 C 2.0006 3.08 0 0
|
|
M V30 14 C 2.0006 1.54 0 0
|
|
M V30 END ATOM
|
|
M V30 BEGIN BOND
|
|
M V30 1 1 1 2
|
|
M V30 2 2 2 3
|
|
M V30 3 1 3 4
|
|
M V30 4 2 4 5
|
|
M V30 5 1 5 6
|
|
M V30 6 1 7 5 CFG=3
|
|
M V30 7 2 7 1
|
|
M V30 8 1 7 8
|
|
M V30 9 2 8 9
|
|
M V30 10 1 9 10
|
|
M V30 11 1 9 11
|
|
M V30 12 2 11 12
|
|
M V30 13 1 12 13
|
|
M V30 14 2 13 14
|
|
M V30 15 1 8 14
|
|
M V30 END BOND
|
|
M V30 END CTAB
|
|
M END
|
|
`;
|
|
var mol = RDKitModule.get_mol(atropisomer);
|
|
assert(mol);
|
|
var svg = mol.get_svg_with_highlights(JSON.stringify({
|
|
useMolBlockWedging: true, noFreetype: true
|
|
}));
|
|
assert(svg.match(/<path class='bond-5 atom-6 atom-4'.*style='fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1\.0px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1' \/>/g).length > 6);
|
|
assert(!svg.match(/<path class='bond-5 atom-6 atom-4'.*style='fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2\.0px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1' \/>/g));
|
|
mol.delete();
|
|
}
|
|
|
|
function test_get_molblock_use_molblock_wedging() {
|
|
var mb = `
|
|
RDKit 2D
|
|
|
|
9 10 0 0 1 0 0 0 0 0999 V2000
|
|
1.4885 -4.5513 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0
|
|
2.0405 -3.9382 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
2.8610 -4.0244 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
3.1965 -3.2707 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
3.0250 -2.4637 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
2.2045 -2.3775 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
1.7920 -1.6630 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
|
|
1.8690 -3.1311 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
2.5834 -2.7186 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
2 1 1 1
|
|
2 3 1 0
|
|
4 3 1 0
|
|
4 5 1 0
|
|
6 5 1 0
|
|
6 7 1 1
|
|
6 8 1 0
|
|
8 9 1 1
|
|
8 2 1 0
|
|
4 9 1 1
|
|
M END
|
|
`;
|
|
var mol = RDKitModule.get_mol(mb);
|
|
assert(mol);
|
|
var molCopy = RDKitModule.get_mol_copy(mol);
|
|
assert(molCopy);
|
|
var mbRDKitWedging = mol.get_molblock();
|
|
assert(mbRDKitWedging !== mb);
|
|
var mbOrigWedging = mol.get_molblock(JSON.stringify({useMolBlockWedging: true}));
|
|
assert(mb === mbOrigWedging);
|
|
var mbRDKitWedgingPostOrig = mol.get_molblock();
|
|
assert(mb !== mbRDKitWedgingPostOrig);
|
|
assert(mbRDKitWedging === mbRDKitWedgingPostOrig);
|
|
mol.delete();
|
|
}
|
|
|
|
initRDKitModule().then(function(instance) {
|
|
var done = {};
|
|
const waitAllTestsFinished = () => {
|
|
const poll = resolve => {
|
|
if (Object.values(done).every(v => v)) {
|
|
resolve();
|
|
} else {
|
|
setTimeout(() => poll(resolve), 100);
|
|
}
|
|
}
|
|
return new Promise(poll);
|
|
}
|
|
RDKitModule = instance;
|
|
console.log(RDKitModule.version());
|
|
test_basics();
|
|
test_molblock_nostrict();
|
|
test_molblock_rgp();
|
|
test_get_aromatic_kekule_form();
|
|
test_sketcher_services();
|
|
test_sketcher_services2();
|
|
test_abbreviations();
|
|
if (RDKitModule.SubstructLibrary) {
|
|
test_substruct_library(done);
|
|
test_substruct_library_merge_hs();
|
|
test_substruct_library_empty_mols();
|
|
test_substruct_library_empty_lib();
|
|
test_substruct_library_empty_query();
|
|
}
|
|
test_generate_aligned_coords();
|
|
test_isotope_labels();
|
|
test_generate_aligned_coords_allow_rgroups();
|
|
test_generate_aligned_coords_accept_failure();
|
|
test_generate_aligned_coords_align_only();
|
|
test_get_mol_no_kekulize();
|
|
test_get_smarts();
|
|
test_get_cxsmarts();
|
|
test_has_coords();
|
|
test_kekulize();
|
|
test_sanitize();
|
|
test_removehs();
|
|
test_normalize_depiction();
|
|
test_straighten_depiction();
|
|
test_flexicanvas();
|
|
if (RDKitModule.get_rxn) {
|
|
test_rxn_drawing();
|
|
test_run_reaction();
|
|
}
|
|
test_legacy_stereochem();
|
|
test_allow_non_tetrahedral_chirality();
|
|
test_prop();
|
|
test_highlights();
|
|
test_add_chiral_hs();
|
|
test_wedging_all_within_scaffold();
|
|
test_wedging_outside_scaffold();
|
|
test_wedging_if_no_match();
|
|
test_get_frags();
|
|
if (RDKitModule.Mol.prototype.get_mmpa_frags) {
|
|
test_get_mmpa_frags();
|
|
}
|
|
test_hs_in_place();
|
|
test_query_colour();
|
|
test_alignment_r_groups_aromatic_ring();
|
|
test_is_valid_deprecated();
|
|
test_mol_list();
|
|
test_get_num_atoms_bonds();
|
|
if (RDKitModule.get_mcs_as_mol) {
|
|
test_mcs();
|
|
}
|
|
test_sanitize_no_kekulize_no_setaromaticity();
|
|
test_partial_sanitization();
|
|
test_capture_logs();
|
|
test_rgroup_match_heavy_hydro_none_charged();
|
|
test_get_sss_json();
|
|
test_relabel_mapped_dummies();
|
|
test_assign_cip_labels();
|
|
test_smiles_smarts_params();
|
|
test_wedged_bond_atropisomer();
|
|
waitAllTestsFinished().then(() =>
|
|
console.log("Tests finished successfully")
|
|
);
|
|
}); |