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

Expose replaceAtomWithQueryAtom to Python #7380

Merged
merged 4 commits into from
May 7, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
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
39 changes: 26 additions & 13 deletions Code/GraphMol/Wrap/Queries.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,12 @@ Ret *PropQueryWithTol(const std::string &propname, const ExplicitBitVect &v,
return res;
}

namespace {
Atom *replaceAtomWithQueryAtomHelper(ROMol &mol, Atom &atom) {
return QueryOps::replaceAtomWithQueryAtom(static_cast<RWMol *>(&mol), &atom);
Copy link
Contributor

Choose a reason for hiding this comment

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

Might be useful to make a note that replaceAtomWithQueryAtom copies the atom. I'm not sure this is actually documented anywhere.

}
}

struct queries_wrapper {
static void wrap() {
#define QADEF1(_funcname_) \
Expand Down Expand Up @@ -210,29 +216,29 @@ struct queries_wrapper {

python::def("HasPropQueryAtom", HasPropQueryAtom,
(python::arg("propname"), python::arg("negate") = false),
"Returns a QueryAtom that matches when the propery 'propname' "
"Returns a QueryAtom that matches when the property 'propname' "
"exists in the atom.",
python::return_value_policy<python::manage_new_object>());

python::def("HasPropQueryBond", HasPropQueryBond,
(python::arg("propname"), python::arg("negate") = false),
"Returns a QueryBond that matches when the propery 'propname' "
"Returns a QueryBond that matches when the property 'propname' "
"exists in the bond.",
python::return_value_policy<python::manage_new_object>());

python::def("HasIntPropWithValueQueryAtom",
PropQueryWithTol<Atom, QueryAtom, int>,
(python::arg("propname"), python::arg("val"),
python::arg("negate") = false, python::arg("tolerance") = 0),
"Returns a QueryAtom that matches when the propery 'propname' "
"Returns a QueryAtom that matches when the property 'propname' "
"has the specified int value.",
python::return_value_policy<python::manage_new_object>());

python::def("HasBoolPropWithValueQueryAtom",
PropQuery<Atom, QueryAtom, bool>,
(python::arg("propname"), python::arg("val"),
python::arg("negate") = false),
"Returns a QueryAtom that matches when the propery 'propname' "
"Returns a QueryAtom that matches when the property 'propname' "
"has the specified boolean"
" value.",
python::return_value_policy<python::manage_new_object>());
Expand All @@ -241,7 +247,7 @@ struct queries_wrapper {
PropQuery<Atom, QueryAtom, std::string>,
(python::arg("propname"), python::arg("val"),
python::arg("negate") = false),
"Returns a QueryAtom that matches when the propery 'propname' "
"Returns a QueryAtom that matches when the property 'propname' "
"has the specified string "
"value.",
python::return_value_policy<python::manage_new_object>());
Expand All @@ -250,7 +256,7 @@ struct queries_wrapper {
PropQueryWithTol<Atom, QueryAtom, double>,
(python::arg("propname"), python::arg("val"),
python::arg("negate") = false, python::arg("tolerance") = 0.0),
"Returns a QueryAtom that matches when the propery 'propname' "
"Returns a QueryAtom that matches when the property 'propname' "
"has the specified "
"value +- tolerance",
python::return_value_policy<python::manage_new_object>());
Expand All @@ -259,7 +265,7 @@ struct queries_wrapper {
PropQueryWithTol<Atom, QueryAtom>,
(python::arg("propname"), python::arg("val"),
python::arg("negate") = false, python::arg("tolerance") = 0),
"Returns a QueryAtom that matches when the propery 'propname' "
"Returns a QueryAtom that matches when the property 'propname' "
"has the specified explicit bit vector"
" value. The Tolerance is the allowed Tanimoto difference",
python::return_value_policy<python::manage_new_object>());
Expand All @@ -268,29 +274,29 @@ struct queries_wrapper {
// Bond Queries
python::def("HasPropQueryBond", HasPropQueryBond,
(python::arg("propname"), python::arg("negate") = false),
"Returns a QueryBond that matches when the propery 'propname' "
"Returns a QueryBond that matches when the property 'propname' "
"exists in the bond.",
python::return_value_policy<python::manage_new_object>());

python::def("HasPropQueryBond", HasPropQueryBond,
(python::arg("propname"), python::arg("negate") = false),
"Returns a QueryBond that matches when the propery 'propname' "
"Returns a QueryBond that matches when the property 'propname' "
"exists in the bond.",
python::return_value_policy<python::manage_new_object>());

python::def("HasIntPropWithValueQueryBond",
PropQueryWithTol<Bond, QueryBond, int>,
(python::arg("propname"), python::arg("val"),
python::arg("negate") = false, python::arg("tolerance") = 0),
"Returns a QueryBond that matches when the propery 'propname' "
"Returns a QueryBond that matches when the property 'propname' "
"has the specified int value.",
python::return_value_policy<python::manage_new_object>());

python::def("HasBoolPropWithValueQueryBond",
PropQuery<Bond, QueryBond, bool>,
(python::arg("propname"), python::arg("val"),
python::arg("negate") = false),
"Returns a QueryBond that matches when the propery 'propname' "
"Returns a QueryBond that matches when the property 'propname' "
"has the specified boolean"
" value.",
python::return_value_policy<python::manage_new_object>());
Expand All @@ -299,7 +305,7 @@ struct queries_wrapper {
PropQuery<Bond, QueryBond, std::string>,
(python::arg("propname"), python::arg("val"),
python::arg("negate") = false),
"Returns a QueryBond that matches when the propery 'propname' "
"Returns a QueryBond that matches when the property 'propname' "
"has the specified string "
"value.",
python::return_value_policy<python::manage_new_object>());
Expand All @@ -308,10 +314,17 @@ struct queries_wrapper {
PropQueryWithTol<Bond, QueryBond, double>,
(python::arg("propname"), python::arg("val"),
python::arg("negate") = false, python::arg("tolerance") = 0.0),
"Returns a QueryBond that matches when the propery 'propname' "
"Returns a QueryBond that matches when the property 'propname' "
"has the specified "
"value +- tolerance",
python::return_value_policy<python::manage_new_object>());

std::string docString = R"DOC(Changes the given atom in the molecule to
a query atom and returns the atom which can then be modified, for example
with additional query contstraints added.)DOC";
Copy link
Contributor

Choose a reason for hiding this comment

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

contstraints => constraints

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for fixing propery -> property btw!

python::def("ReplaceAtomWithQueryAtom", replaceAtomWithQueryAtomHelper,
(python::arg("mol"), python::arg("atom")), docString.c_str(),
python::return_value_policy<python::reference_existing_object>());
};
};
} // namespace RDKit
Expand Down
13 changes: 13 additions & 0 deletions Code/GraphMol/Wrap/rough_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3920,6 +3920,19 @@ def testAdjustQueryPropertiesgithubIssue1474(self):
self.assertEqual(ap.GetAtomWithIdx(0).GetPropsAsDict()["foo"], "bar")
self.assertEqual(ap.GetAtomWithIdx(1).GetPropsAsDict()["foo"], "bar")

def testReplaceAtomWithQueryAtom(self):
mol = Chem.MolFromSmiles("CC(C)C")
qmol = Chem.MolFromSmiles("C")
matches = mol.GetSubstructMatches(qmol)
self.assertEqual(((0,), (1,), (2,), (3,)), matches)

atom = qmol.GetAtomWithIdx(0)
natom = rdqueries.ReplaceAtomWithQueryAtom(qmol, atom)
qa = rdqueries.ExplicitDegreeEqualsQueryAtom(3)
natom.ExpandQuery(qa, Chem.CompositeQueryType.COMPOSITE_AND)
matches = mol.GetSubstructMatches(qmol)
self.assertEqual(((1,),), matches)

def testGithubIssue579(self):
fileN = os.path.join(RDConfig.RDBaseDir, 'Code', 'GraphMol', 'FileParsers', 'test_data',
'NCI_aids_few.sdf.gz')
Expand Down