Enable get_molblock(details_json) from MinimalLib (#5806)

* - enable get_molblock(details_json) from MinimalLib as it is already enabled in CFFI
- enable useMolBlockWedging on get_molblock() in both CFFI and JS MinimalLib
- add tests

* - expose also addChiralHs

Co-authored-by: Tosco, Paolo <paolo.tosco@novartis.com>
This commit is contained in:
Paolo Tosco
2022-11-29 17:37:34 +01:00
committed by GitHub
parent 234ed45b1e
commit c94a47bbd3
7 changed files with 95 additions and 57 deletions

View File

@@ -17,6 +17,31 @@
#endif
#include <assert.h>
static const char molblock_native_wedging[] = "\n\
MJ201100 \n\
\n\
9 10 0 0 1 0 0 0 0 0999 V2000\n\
1.4885 -4.5513 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0\n\
2.0405 -3.9382 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n\
2.8610 -4.0244 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n\
3.1965 -3.2707 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n\
3.0250 -2.4637 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n\
2.2045 -2.3775 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n\
1.7920 -1.6630 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0\n\
1.8690 -3.1311 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n\
2.5834 -2.7186 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n\
2 1 1 1 0 0 0\n\
2 3 1 0 0 0 0\n\
4 3 1 0 0 0 0\n\
4 5 1 0 0 0 0\n\
6 5 1 0 0 0 0\n\
6 7 1 1 0 0 0\n\
6 8 1 0 0 0 0\n\
8 9 1 1 0 0 0\n\
8 2 1 0 0 0 0\n\
4 9 1 1 0 0 0\n\
M END\n";
void test_io() {
char *pkl;
size_t pkl_size;
@@ -124,6 +149,22 @@ M END",
free(molblock);
molblock = NULL;
pkl2 = get_mol(molblock_native_wedging, &pkl2_size, "");
assert(pkl2);
assert(pkl2_size > 0);
molblock = get_molblock(pkl2, pkl2_size, NULL);
assert(strstr(molblock, "4 3 1 6"));
assert(!strstr(molblock, "H "));
free(molblock);
molblock = get_molblock(pkl2, pkl2_size, "{\"useMolBlockWedging\":true}");
assert(!strstr(molblock, "4 3 1 6"));
assert(!strstr(molblock, "H "));
free(molblock);
molblock = get_molblock(pkl2, pkl2_size, "{\"addChiralHs\":true}");
assert(strstr(molblock, "H "));
free(molblock);
free(pkl2);
molblock = get_v3kmolblock(pkl, pkl_size, NULL);
pkl2 = get_mol(molblock, &pkl2_size, "");
assert(pkl2);
@@ -237,32 +278,7 @@ void test_svg() {
free(pkl);
pkl = get_mol(
"\n\
MJ201100 \n\
\n\
9 10 0 0 1 0 0 0 0 0999 V2000\n\
1.4885 -4.5513 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0\n\
2.0405 -3.9382 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n\
2.8610 -4.0244 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n\
3.1965 -3.2707 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n\
3.0250 -2.4637 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n\
2.2045 -2.3775 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n\
1.7920 -1.6630 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0\n\
1.8690 -3.1311 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n\
2.5834 -2.7186 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n\
2 1 1 1 0 0 0\n\
2 3 1 0 0 0 0\n\
4 3 1 0 0 0 0\n\
4 5 1 0 0 0 0\n\
6 5 1 0 0 0 0\n\
6 7 1 1 0 0 0\n\
6 8 1 0 0 0 0\n\
8 9 1 1 0 0 0\n\
8 2 1 0 0 0 0\n\
4 9 1 1 0 0 0\n\
M END\n",
&pkl_size, "");
pkl = get_mol(molblock_native_wedging, &pkl_size, "");
assert(pkl);
assert(pkl_size > 0);
char *svg1 = get_svg(pkl, pkl_size, "{\"width\":350,\"height\":300}");

View File

@@ -153,27 +153,6 @@ std::string cxsmiles_helper(const char *pkl, size_t pkl_sz,
auto data = MolToCXSmiles(mol, params);
return data;
}
std::string molblock_helper(const char *pkl, size_t pkl_sz,
const char *details_json, bool forceV3000) {
if (!pkl || !pkl_sz) {
return "";
}
auto mol = mol_from_pkl(pkl, pkl_sz);
bool includeStereo = true;
bool kekulize = true;
if (details_json && strlen(details_json)) {
boost::property_tree::ptree pt;
std::istringstream ss;
ss.str(details_json);
boost::property_tree::read_json(ss, pt);
PT_OPT_GET(includeStereo);
PT_OPT_GET(kekulize);
}
auto data = MolToMolBlock(mol, includeStereo, -1, kekulize, forceV3000);
return data;
}
} // namespace
extern "C" char *get_smiles(const char *pkl, size_t pkl_sz,
const char *details_json) {
@@ -195,12 +174,20 @@ extern "C" char *get_cxsmiles(const char *pkl, size_t pkl_sz,
}
extern "C" char *get_molblock(const char *pkl, size_t pkl_sz,
const char *details_json) {
auto data = molblock_helper(pkl, pkl_sz, details_json, false);
if (!pkl || !pkl_sz) {
return "";
}
auto mol = mol_from_pkl(pkl, pkl_sz);
auto data = MinimalLib::molblock_helper(mol, details_json, false);
return str_to_c(data);
}
extern "C" char *get_v3kmolblock(const char *pkl, size_t pkl_sz,
const char *details_json) {
auto data = molblock_helper(pkl, pkl_sz, details_json, true);
if (!pkl || !pkl_sz) {
return "";
}
auto mol = mol_from_pkl(pkl, pkl_sz);
auto data = MinimalLib::molblock_helper(mol, details_json, true);
return str_to_c(data);
}
extern "C" char *get_json(const char *pkl, size_t pkl_sz, const char *) {

View File

@@ -16,6 +16,7 @@
#include <GraphMol/SmilesParse/SmilesParse.h>
#include <GraphMol/SmilesParse/SmilesWrite.h>
#include <GraphMol/FileParsers/FileParsers.h>
#include <GraphMol/FileParsers/MolFileStereochem.h>
#include <RDGeneral/FileParseException.h>
#include <GraphMol/MolDraw2D/MolDraw2D.h>
#include <GraphMol/MolDraw2D/MolDraw2DSVG.h>
@@ -448,6 +449,30 @@ std::string process_rxn_details(
return "";
}
std::string molblock_helper(RWMol &mol, const char *details_json, bool forceV3000) {
bool includeStereo = true;
bool kekulize = true;
bool useMolBlockWedging = false;
bool addChiralHs = false;
if (details_json && strlen(details_json)) {
boost::property_tree::ptree pt;
std::istringstream ss;
ss.str(details_json);
boost::property_tree::read_json(ss, pt);
LPT_OPT_GET(includeStereo);
LPT_OPT_GET(kekulize);
LPT_OPT_GET(useMolBlockWedging);
LPT_OPT_GET(addChiralHs);
}
if (useMolBlockWedging) {
reapplyMolBlockWedging(mol);
}
if (addChiralHs) {
MolDraw2DUtils::prepareMolForDrawing(mol, false, true, false, false, false);
}
return MolToMolBlock(mol, includeStereo, -1, kekulize, forceV3000);
}
void get_sss_json(const ROMol &d_mol, const ROMol &q_mol,
const MatchVectType &match, rj::Value &obj,
rj::Document &doc) {

View File

@@ -335,8 +335,10 @@ EMSCRIPTEN_BINDINGS(RDKit_minimal) {
.function("get_cxsmiles", &JSMol::get_cxsmiles)
.function("get_smarts", &JSMol::get_smarts)
.function("get_cxsmarts", &JSMol::get_cxsmarts)
.function("get_molblock", &JSMol::get_molblock)
.function("get_v3Kmolblock", &JSMol::get_v3Kmolblock)
.function("get_molblock", select_overload<std::string() const>(&JSMol::get_molblock))
.function("get_molblock", select_overload<std::string(const std::string &) const>(&JSMol::get_molblock))
.function("get_v3Kmolblock", select_overload<std::string() const>(&JSMol::get_v3Kmolblock))
.function("get_v3Kmolblock", select_overload<std::string(const std::string &) const>(&JSMol::get_v3Kmolblock))
.function("get_as_uint8array", &get_as_uint8array)
.function("get_inchi", &JSMol::get_inchi)
.function("get_json", &JSMol::get_json)

View File

@@ -121,17 +121,17 @@ std::string JSMol::get_inchi() const {
ExtraInchiReturnValues rv;
return MolToInchi(*d_mol, rv);
}
std::string JSMol::get_molblock() const {
std::string JSMol::get_molblock(const std::string &details) const {
if (!d_mol) {
return "";
}
return MolToMolBlock(*d_mol);
return MinimalLib::molblock_helper(*d_mol, details.c_str(), false);
}
std::string JSMol::get_v3Kmolblock() const {
std::string JSMol::get_v3Kmolblock(const std::string &details) const {
if (!d_mol) {
return "";
}
return MolToV3KMolBlock(*d_mol);
return MinimalLib::molblock_helper(*d_mol, details.c_str(), true);
}
std::string JSMol::get_json() const {
if (!d_mol) {

View File

@@ -24,8 +24,14 @@ class JSMol {
std::string get_cxsmiles() const;
std::string get_smarts() const;
std::string get_cxsmarts() const;
std::string get_molblock() const;
std::string get_v3Kmolblock() const;
std::string get_molblock(const std::string &details) const;
std::string get_molblock() const {
return get_molblock("{}");
}
std::string get_v3Kmolblock(const std::string &details) const;
std::string get_v3Kmolblock() const {
return get_v3Kmolblock("{}");
}
std::string get_pickle() const;
std::string get_inchi() const;
std::string get_json() const;

View File

@@ -1060,6 +1060,8 @@ M END
assert(svg2.includes("atom-8"));
assert(!svg2.includes("atom-9"));
assert(!svg2.includes("atom-10"));
assert(mol.get_molblock().includes("4 3 1 6"));
assert(!mol.get_molblock(JSON.stringify({ useMolBlockWedging: true })).includes("4 3 1 6"));
}
function test_get_frags() {