Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update MinimalLib for Function Exposure: runReactants #7210

Merged
merged 6 commits into from
May 9, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions Code/MinimalLib/jswrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -351,11 +351,13 @@ emscripten::val get_mmpa_frags_helper(const JSMol &self, unsigned int minCuts,
return obj;
}
#endif

} // namespace

using namespace emscripten;
EMSCRIPTEN_BINDINGS(RDKit_minimal) {
register_vector<std::string>("StringList");
register_vector<JSMolList>("VectorJSMolListPtr");

class_<JSMol>("Mol")
.function("is_valid", &JSMol::is_valid)
Expand Down Expand Up @@ -565,6 +567,9 @@ EMSCRIPTEN_BINDINGS(RDKit_minimal) {
#ifdef RDK_BUILD_MINIMAL_LIB_RXN
class_<JSReaction>("Reaction")
#ifdef __EMSCRIPTEN__
.function("run_reactants", select_overload<std::vector<JSMolList>(
const JSMolList &, unsigned int) const>(
&JSReaction::run_reactants))
.function("draw_to_canvas_with_offset", &draw_rxn_to_canvas_with_offset)
.function("draw_to_canvas", &draw_rxn_to_canvas)
.function("draw_to_canvas_with_highlights",
Expand Down
60 changes: 46 additions & 14 deletions Code/MinimalLib/minilib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ namespace rj = rapidjson;
using namespace RDKit;

namespace {
static const char *NO_SUPPORT_FOR_PATTERN_FPS = "This SubstructLibrary was built without support for pattern fps";
static const char *NO_SUPPORT_FOR_PATTERN_FPS =
"This SubstructLibrary was built without support for pattern fps";

std::string mappingToJsonArray(const ROMol &mol) {
std::vector<unsigned int> atomMapping;
Expand Down Expand Up @@ -561,9 +562,7 @@ void JSMol::straighten_depiction(bool minimizeRotation) {
RDDepict::straightenDepiction(*d_mol, -1, minimizeRotation);
}

bool JSMol::is_valid() const {
return true;
}
bool JSMol::is_valid() const { return true; }

std::pair<JSMolList *, std::string> JSMol::get_frags(
const std::string &details_json) {
Expand Down Expand Up @@ -642,9 +641,40 @@ std::string JSReaction::get_svg_with_highlights(
int h = d_defaultHeight;
return MinimalLib::rxn_to_svg(*d_rxn, w, h, details);
}
bool JSReaction::is_valid() const { return true; }

bool JSReaction::is_valid() const {
return true;
std::vector<JSMolList> JSReaction::run_reactants(const JSMolList &reactants,
unsigned int maxProducts) const {
if (!d_rxn) {
std::cerr << "Error: d_rxn is null\n";
return {};
}
d_rxn->initReactantMatchers();
RDKit::MOL_SPTR_VECT reactant_vec;

for (const auto &reactant : reactants.mols()) {
if (!reactant) {
std::cerr << "Error: reactant is null\n";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't do error reporting straight to std::cerr.
I think you need to thrown an exception here, but @ptosco should suggest what he thinks is the best approach for error handling in minilib

continue;
}
reactant_vec.push_back(RDKit::ROMOL_SPTR(reactant));
}

std::vector<RDKit::MOL_SPTR_VECT> prods;
try {
prods = d_rxn->runReactants(reactant_vec, maxProducts);
} catch (const std::exception& e) {
std::cerr << "Error running reactants: " << e.what() << '\n';
return {};
}
std::vector<JSMolList> newResults;
for (auto &mol_array: prods) {
if (mol_array.empty()) {
std::cerr << "Warning: mol_array is empty\n";
}
newResults.push_back(JSMolList(mol_array));
}
return newResults;
}
#endif

Expand Down Expand Up @@ -694,9 +724,10 @@ size_t JSMolList::insert(size_t idx, const JSMol &mol) {
}

#ifdef RDK_BUILD_MINIMAL_LIB_SUBSTRUCTLIBRARY
JSSubstructLibrary::JSSubstructLibrary(unsigned int num_bits) :
d_fpHolder(nullptr) {
boost::shared_ptr<CachedTrustedSmilesMolHolder> molHolderSptr(new CachedTrustedSmilesMolHolder());
JSSubstructLibrary::JSSubstructLibrary(unsigned int num_bits)
: d_fpHolder(nullptr) {
boost::shared_ptr<CachedTrustedSmilesMolHolder> molHolderSptr(
new CachedTrustedSmilesMolHolder());
boost::shared_ptr<PatternHolder> fpHolderSptr;
d_molHolder = molHolderSptr.get();
if (num_bits) {
Expand Down Expand Up @@ -872,16 +903,17 @@ bool allow_non_tetrahedral_chirality(bool value) {
#ifdef RDK_BUILD_MINIMAL_LIB_MCS
namespace {
MCSResult getMcsResult(const JSMolList &molList,
const std::string &details_json) {
const std::string &details_json) {
MCSParameters p;
if (!details_json.empty()) {
parseMCSParametersJSON(details_json.c_str(), &p);
}
return RDKit::findMCS(molList.mols(), &p);
}
} // namespace
} // namespace

std::string get_mcs_as_json(const JSMolList &molList, const std::string &details_json) {
std::string get_mcs_as_json(const JSMolList &molList,
const std::string &details_json) {
auto mcsResult = getMcsResult(molList, details_json);
rj::Document doc;
doc.SetObject();
Expand Down Expand Up @@ -915,13 +947,13 @@ std::string get_mcs_as_json(const JSMolList &molList, const std::string &details
}

std::string get_mcs_as_smarts(const JSMolList &molList,
const std::string &details_json) {
const std::string &details_json) {
auto res = getMcsResult(molList, details_json);
return res.SmartsString;
}

JSMol *get_mcs_as_mol(const JSMolList &molList,
const std::string &details_json) {
const std::string &details_json) {
auto res = getMcsResult(molList, details_json);
return new JSMol(new RWMol(*res.QueryMol));
}
Expand Down
4 changes: 3 additions & 1 deletion Code/MinimalLib/minilib.h
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,9 @@ class JSReaction {
[deprecated("please check the get_rxn return value for non-nullness "
"instead")]] bool
is_valid() const;


std::vector<JSMolList> run_reactants(const JSMolList &reactants, unsigned int maxProducts) const;
static constexpr int maxProducts = 1000;
std::string get_svg(int width, int height) const;
std::string get_svg() const {
return get_svg(d_defaultWidth, d_defaultHeight);
Expand Down
16 changes: 15 additions & 1 deletion Code/MinimalLib/tests/tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -1099,6 +1099,19 @@ function test_flexicanvas() {
assert(svg.search("height='19px'")>0);
}

function test_run_reaction() {
var rxn1 = RDKitModule.get_rxn('[#6:1][O:2]>>[#6:1]=[O:2]');
var molList = molListFromSmiArray(['CC(C)O',]);
try {
var reactants = rxn1.run_reactants(molList, 10000);
for (let i = 0; i < reactants.size(); i++) {
const element = reactants.get(i);
assert(element.next().get_smiles() === "CC(C)=O");
}
} catch (e) {
console.log(e);
}
}
function test_rxn_drawing() {
{
var rxn = RDKitModule.get_rxn("[CH3:1][OH:2]>>[CH2:1]=[OH0:2]");
Expand Down Expand Up @@ -2849,6 +2862,7 @@ initRDKitModule().then(function(instance) {
test_flexicanvas();
if (RDKitModule.get_rxn) {
test_rxn_drawing();
test_run_reaction();
}
test_legacy_stereochem();
test_allow_non_tetrahedral_chirality();
Expand Down Expand Up @@ -2881,4 +2895,4 @@ initRDKitModule().then(function(instance) {
waitAllTestsFinished().then(() =>
console.log("Tests finished successfully")
);
});
});