mirror of
https://github.com/rdkit/rdkit.git
synced 2026-06-04 21:54:27 +08:00
Handle query atoms and bonds in SWIG wrappers (#7431)
* Query atom information in swig * Atom query swig wrapping working * SWIG wrapper for queries * Add match to QueryAtom and QueryBond * CShart test * Added Java test * Replace var with type for Java test * Apply suggestions from code review Co-authored-by: Paolo Tosco <paolo.tosco.mail@gmail.com> * Update Code/JavaWrappers/Queries.i Co-authored-by: Paolo Tosco <paolo.tosco.mail@gmail.com> * Apply suggestions from code review Co-authored-by: Paolo Tosco <paolo.tosco.mail@gmail.com> * Get SWIG build working again * Remove trailing whitespace from Queries.i * Update Queries.i to use shared_ptr * small simplification * remove boost::make_iterator from ROMol.i * further simplification --------- Co-authored-by: Paolo Tosco <paolo.tosco.mail@gmail.com> Co-authored-by: ptosco <paolo.tosco@novartis.com>
This commit is contained in:
@@ -47,9 +47,29 @@
|
||||
#include <GraphMol/MolTransforms/MolTransforms.h>
|
||||
#include <Geometry/point.h>
|
||||
#include <GraphMol/MolOps.h>
|
||||
#include <GraphMol/SmilesParse/SmilesWrite.h>
|
||||
#include <GraphMol/SmilesParse/SmartsWrite.h>
|
||||
|
||||
// from Python wrapper
|
||||
std::string describeQueryHelper(const RDKit::Atom::QUERYATOM_QUERY *q, unsigned int depth) {
|
||||
std::string res;
|
||||
if (q) {
|
||||
for (unsigned int i = 0; i < depth; ++i) {
|
||||
res += " ";
|
||||
}
|
||||
res += q->getFullDescription() + "\n";
|
||||
for (const auto &child :
|
||||
boost::make_iterator_range(q->beginChildren(), q->endChildren())) {
|
||||
res += describeQueryHelper(child.get(), depth + 1);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
%ignore RDKit::Atom::Match(const Atom *) const;
|
||||
%ignore RDKit::Atom::expandQuery;
|
||||
%template(Bond_Vect) std::vector<RDKit::Bond*>;
|
||||
|
||||
%include "enums.swg"
|
||||
@@ -120,4 +140,27 @@
|
||||
$self->setQuery(query);
|
||||
}
|
||||
|
||||
// From Python Wrapper
|
||||
std::string AtomGetSmarts(bool doKekule=false, bool allHsExplicit=false,
|
||||
bool isomericSmiles=true) {
|
||||
std::string res;
|
||||
if (($self)->hasQuery()) {
|
||||
res = RDKit::SmartsWrite::GetAtomSmarts(static_cast<const RDKit::QueryAtom *>(($self)));
|
||||
} else {
|
||||
// FIX: this should not be necessary
|
||||
res = RDKit::SmilesWrite::GetAtomSmiles(($self), doKekule, nullptr, allHsExplicit,
|
||||
isomericSmiles);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
// from Python Wrapper
|
||||
std::string describeQuery() {
|
||||
std::string res = "";
|
||||
res = describeQueryHelper(($self)->getQuery(), 0);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -47,6 +47,8 @@
|
||||
%ignore RDKit::Bond::setBeginAtom(Atom *at);
|
||||
%ignore RDKit::Bond::setEndAtom(Atom *at);
|
||||
%ignore RDKit::getTwiceBondType(const RDKit::Bond &b);
|
||||
%ignore RDKit::Bond::setQuery;
|
||||
%ignore RDKit::Bond::expandQuery;
|
||||
|
||||
%include <GraphMol/Bond.h>
|
||||
|
||||
|
||||
287
Code/JavaWrappers/Queries.i
Normal file
287
Code/JavaWrappers/Queries.i
Normal file
@@ -0,0 +1,287 @@
|
||||
//
|
||||
// Copyright (C) 2024 Gareth Jones, Glysade LLC
|
||||
//
|
||||
// @@ 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.
|
||||
//
|
||||
|
||||
%include <boost_shared_ptr.i>
|
||||
%shared_ptr(RDKit::QueryAtom)
|
||||
%shared_ptr(RDKit::QueryBond)
|
||||
|
||||
// Adapted from the Python Wrappers
|
||||
|
||||
%{
|
||||
#include <GraphMol/RDKitBase.h>
|
||||
#include <GraphMol/RDKitQueries.h>
|
||||
#include <RDGeneral/types.h>
|
||||
%}
|
||||
|
||||
%include <GraphMol/RDKitBase.h>;
|
||||
%include <GraphMol/RDKitQueries.h>;
|
||||
%include <RDGeneral/types.h>;
|
||||
|
||||
/*
|
||||
NOTE: it looks like there is a typo in the below code
|
||||
ATOM_GREATER_QUERY is intentionally being used for the LessQueryAtom
|
||||
and ATOM_LESS_QUERY for GreaterQueryAtom in the python API.
|
||||
The C++ API is internally consistent and logical, but having
|
||||
AtomNumLessQueryAtom(6) return atoms where 6 is less than their atomic
|
||||
number feels backwards in Python.
|
||||
|
||||
*/
|
||||
%define QAFUNC1(funcname, func, type)
|
||||
%inline %{
|
||||
|
||||
boost::shared_ptr<RDKit::QueryAtom> funcname ## EqualsQueryAtom(type val, bool negate=false) {
|
||||
boost::shared_ptr<RDKit::QueryAtom> res(new RDKit::QueryAtom());
|
||||
res->setQuery(RDKit:: ## func(val));
|
||||
if (negate) {
|
||||
res->getQuery()->setNegation(true);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
boost::shared_ptr<RDKit::QueryAtom> funcname ## LessQueryAtom(type val, bool negate=false) {
|
||||
boost::shared_ptr<RDKit::QueryAtom> res(new RDKit::QueryAtom());
|
||||
res->setQuery(
|
||||
RDKit:: ## func <RDKit::ATOM_GREATER_QUERY>(val, std::string( # funcname "Less")));
|
||||
if (negate) {
|
||||
res->getQuery()->setNegation(true);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
boost::shared_ptr<RDKit::QueryAtom> funcname ## GreaterQueryAtom(type val, bool negate=false) {
|
||||
boost::shared_ptr<RDKit::QueryAtom> res(new RDKit::QueryAtom());
|
||||
res->setQuery(
|
||||
RDKit:: ## func <RDKit::ATOM_LESS_QUERY>(val, std::string(# funcname "Greater")));
|
||||
if (negate) {
|
||||
res->getQuery()->setNegation(true);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
%}
|
||||
%enddef
|
||||
|
||||
%define QAFUNC2(funcname, func, type)
|
||||
%inline %{
|
||||
boost::shared_ptr<RDKit::QueryAtom> funcname(bool negate=false) {
|
||||
boost::shared_ptr<RDKit::QueryAtom> res(new RDKit::QueryAtom());
|
||||
res->setQuery(RDKit:: ## func());
|
||||
if (negate) {
|
||||
res->getQuery()->setNegation(true);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
%}
|
||||
%enddef
|
||||
|
||||
QAFUNC1(AtomNum, makeAtomNumQuery, int);
|
||||
QAFUNC1(ExplicitValence, makeAtomExplicitValenceQuery, int);
|
||||
QAFUNC1(TotalValence, makeAtomTotalValenceQuery, int);
|
||||
QAFUNC1(ExplicitDegree, makeAtomExplicitDegreeQuery, int);
|
||||
QAFUNC1(TotalDegree, makeAtomTotalDegreeQuery, int);
|
||||
QAFUNC1(NonHydrogenDegree, makeAtomNonHydrogenDegreeQuery, int);
|
||||
QAFUNC1(HCount, makeAtomHCountQuery, int);
|
||||
QAFUNC1(Mass, makeAtomMassQuery, int);
|
||||
QAFUNC1(Isotope, makeAtomIsotopeQuery, int);
|
||||
QAFUNC1(FormalCharge, makeAtomFormalChargeQuery, int);
|
||||
QAFUNC1(Hybridization, makeAtomHybridizationQuery, int);
|
||||
QAFUNC1(InNRings, makeAtomInNRingsQuery, int);
|
||||
QAFUNC1(MinRingSize, makeAtomMinRingSizeQuery, int);
|
||||
QAFUNC1(RingBondCount, makeAtomRingBondCountQuery, int);
|
||||
QAFUNC1(NumRadicalElectrons, makeAtomNumRadicalElectronsQuery, int);
|
||||
QAFUNC1(NumHeteroatomNeighbors, makeAtomNumHeteroatomNbrsQuery, int);
|
||||
QAFUNC1(NumAliphaticHeteroatomNeighbors,
|
||||
makeAtomNumAliphaticHeteroatomNbrsQuery, int);
|
||||
|
||||
QAFUNC2(IsUnsaturatedQueryAtom, makeAtomUnsaturatedQuery, int);
|
||||
QAFUNC2(IsAromaticQueryAtom, makeAtomAromaticQuery, int);
|
||||
QAFUNC2(IsAliphaticQueryAtom, makeAtomAliphaticQuery, int);
|
||||
QAFUNC2(IsInRingQueryAtom, makeAtomInRingQuery, int);
|
||||
QAFUNC2(HasChiralTagQueryAtom, makeAtomHasChiralTagQuery, int);
|
||||
QAFUNC2(MissingChiralTagQueryAtom, makeAtomMissingChiralTagQuery, int);
|
||||
QAFUNC2(IsBridgeheadQueryAtom, makeAtomIsBridgeheadQuery, int);
|
||||
QAFUNC2(AAtomQueryAtom, makeAAtomQuery, int);
|
||||
QAFUNC2(AHAtomQueryAtom, makeAHAtomQuery, int);
|
||||
QAFUNC2(QAtomQueryAtom, makeQAtomQuery, int);
|
||||
QAFUNC2(QHAtomQueryAtom, makeQHAtomQuery, int);
|
||||
QAFUNC2(XAtomQueryAtom, makeXAtomQuery, int);
|
||||
QAFUNC2(XHAtomQueryAtom, makeXHAtomQuery, int);
|
||||
QAFUNC2(MAtomQueryAtom, makeMAtomQuery, int);
|
||||
QAFUNC2(MHAtomQueryAtom, makeMHAtomQuery, int);
|
||||
|
||||
%{
|
||||
|
||||
template <class Ob, class Ret, class T>
|
||||
boost::shared_ptr<Ret> PropQuery(const std::string &propname, const T &v, bool negate) {
|
||||
boost::shared_ptr<Ret> res(new Ret());
|
||||
res->setQuery(RDKit::makePropQuery<Ob, T>(propname, v));
|
||||
if (negate) {
|
||||
res->getQuery()->setNegation(true);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
template <class Ob, class Ret, class T>
|
||||
boost::shared_ptr<Ret> PropQueryWithTol(const std::string &propname, const T &v, bool negate,
|
||||
const T &tol = T()) {
|
||||
boost::shared_ptr<Ret> res(new Ret());
|
||||
res->setQuery(RDKit::makePropQuery<Ob, T>(propname, v, tol));
|
||||
if (negate) {
|
||||
res->getQuery()->setNegation(true);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
template <class Ob, class Ret>
|
||||
boost::shared_ptr<Ret> PropQueryWithTol(const std::string &propname, const ExplicitBitVect &v,
|
||||
bool negate=false, float tol = 0.0) {
|
||||
boost::shared_ptr<Ret> res(new Ret());
|
||||
res->setQuery(RDKit::makePropQuery<Ob>(propname, v, tol));
|
||||
if (negate) {
|
||||
res->getQuery()->setNegation(true);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
boost::shared_ptr<RDKit::QueryAtom> HasPropQueryAtom(const std::string &propname, bool negate=false) {
|
||||
boost::shared_ptr<RDKit::QueryAtom> res(new RDKit::QueryAtom());
|
||||
res->setQuery(RDKit::makeHasPropQuery<RDKit::Atom>(propname));
|
||||
if (negate) {
|
||||
res->getQuery()->setNegation(true);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
boost::shared_ptr<RDKit::QueryAtom> HasIntPropWithValueQueryAtom(const std::string &propname, int val, bool negate=false) {
|
||||
return PropQuery<RDKit::Atom, RDKit::QueryAtom, int>(propname, val, negate);
|
||||
}
|
||||
|
||||
boost::shared_ptr<RDKit::QueryAtom> HasBoolPropWithValueQueryAtom(const std::string &propname, bool val, bool negate=false) {
|
||||
return PropQuery<RDKit::Atom, RDKit::QueryAtom, bool>(propname, val, negate);
|
||||
}
|
||||
|
||||
boost::shared_ptr<RDKit::QueryAtom> HasStringPropWithValueQueryAtom(const std::string &propname, const std::string &val, bool negate=false) {
|
||||
return PropQuery<RDKit::Atom, RDKit::QueryAtom, std::string>(propname, val, negate);
|
||||
}
|
||||
|
||||
boost::shared_ptr<RDKit::QueryAtom> HasDoublePropWithValueQueryAtom(const std::string &propname, double val, bool negate=false, double tol=0) {
|
||||
return PropQueryWithTol<RDKit::Atom, RDKit::QueryAtom, double>(propname, val, negate, tol);
|
||||
}
|
||||
|
||||
boost::shared_ptr<RDKit::QueryAtom> HasBitVectPropWithValueQueryAtom(const std::string &propname, const ExplicitBitVect &val, bool negate=false, float tol=0) {
|
||||
return PropQueryWithTol<RDKit::Atom, RDKit::QueryAtom>(propname, val, negate, tol);
|
||||
}
|
||||
|
||||
boost::shared_ptr<RDKit::QueryBond> HasPropQueryBond(const std::string &propname, bool negate=false) {
|
||||
boost::shared_ptr<RDKit::QueryBond> res(new RDKit::QueryBond());
|
||||
res->setQuery(RDKit::makeHasPropQuery<RDKit::Bond>(propname));
|
||||
if (negate) {
|
||||
res->getQuery()->setNegation(true);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
boost::shared_ptr<RDKit::QueryBond> HasIntPropWithValueQueryBond(const std::string &propname, int val, bool negate=false) {
|
||||
return PropQuery<RDKit::Bond, RDKit::QueryBond, int>(propname, val, negate);
|
||||
}
|
||||
|
||||
boost::shared_ptr<RDKit::QueryBond> HasBoolPropWithValueQueryBond(const std::string &propname, bool val, bool negate=false) {
|
||||
return PropQuery<RDKit::Bond, RDKit::QueryBond, bool>(propname, val, negate);
|
||||
}
|
||||
|
||||
boost::shared_ptr<RDKit::QueryBond> HasStringPropWithValueQueryBond(const std::string &propname, const std::string &val, bool negate=false) {
|
||||
return PropQuery<RDKit::Bond, RDKit::QueryBond, std::string>(propname, val, negate);
|
||||
}
|
||||
|
||||
boost::shared_ptr<RDKit::QueryBond> HasDoublePropWithValueQueryBond(const std::string &propname, double val, bool negate=false, double tol=0) {
|
||||
return PropQueryWithTol<RDKit::Bond, RDKit::QueryBond, double>(propname, val, negate, tol);
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
boost::shared_ptr<RDKit::QueryAtom> HasPropQueryAtom(const std::string &propname, bool negate=false);
|
||||
boost::shared_ptr<RDKit::QueryBond> HasPropQueryBond(const std::string &propname, bool negate=false);
|
||||
boost::shared_ptr<RDKit::QueryAtom> HasIntPropWithValueQueryAtom(const std::string &propname, int val, bool negate=false);
|
||||
boost::shared_ptr<RDKit::QueryAtom> HasBoolPropWithValueQueryAtom(const std::string &propname, bool val, bool negate=false);
|
||||
boost::shared_ptr<RDKit::QueryAtom> HasStringPropWithValueQueryAtom(const std::string &propname, const std::string &val, bool negate=false);
|
||||
boost::shared_ptr<RDKit::QueryAtom> HasDoublePropWithValueQueryAtom(const std::string &propname, double val, bool negate=false, double tol=0);
|
||||
boost::shared_ptr<RDKit::QueryAtom> HasBitVectPropWithValueQueryAtom(const std::string &propname, const ExplicitBitVect &val, bool negate=false, float tol=0);
|
||||
boost::shared_ptr<RDKit::QueryBond> HasPropQueryBond(const std::string &propname, bool negate=false);
|
||||
boost::shared_ptr<RDKit::QueryBond> HasIntPropWithValueQueryBond(const std::string &propname, int val, bool negate=false);
|
||||
boost::shared_ptr<RDKit::QueryBond> HasBoolPropWithValueQueryBond(const std::string &propname, bool val, bool negate=false);
|
||||
boost::shared_ptr<RDKit::QueryBond> HasStringPropWithValueQueryBond(const std::string &propname, const std::string &val, bool negate=false);
|
||||
boost::shared_ptr<RDKit::QueryBond> HasDoublePropWithValueQueryBond(const std::string &propname, double val, bool negate=false, double tol=0);
|
||||
|
||||
%extend RDKit::QueryAtom {
|
||||
void ExpandQuery(const RDKit::QueryAtom *other, Queries::CompositeQueryType how=Queries::COMPOSITE_AND, bool maintainOrder=true) {
|
||||
PRECONDITION(other, "bad atoms");
|
||||
if (other->hasQuery()) {
|
||||
const RDKit::QueryAtom::QUERYATOM_QUERY *qry = other->getQuery();
|
||||
($self)->expandQuery(qry->copy(), how, maintainOrder);
|
||||
}
|
||||
}
|
||||
|
||||
void setQuery(const RDKit::QueryAtom *other) {
|
||||
PRECONDITION(other, "bad atoms");
|
||||
if (other->hasQuery()) {
|
||||
($self)->setQuery(other->getQuery()->copy());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
%extend RDKit::Atom {
|
||||
void ExpandQuery(const RDKit::QueryAtom *other, Queries::CompositeQueryType how=Queries::COMPOSITE_AND, bool maintainOrder=true) {
|
||||
PRECONDITION(other, "bad atoms");
|
||||
if (other->hasQuery()) {
|
||||
const RDKit::QueryAtom::QUERYATOM_QUERY *qry = other->getQuery();
|
||||
($self)->expandQuery(qry->copy(), how, maintainOrder);
|
||||
}
|
||||
}
|
||||
|
||||
void setQuery(const RDKit::QueryAtom *other) {
|
||||
PRECONDITION(other, "bad atoms");
|
||||
if (other->hasQuery()) {
|
||||
($self)->setQuery(other->getQuery()->copy());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
%extend RDKit::QueryBond {
|
||||
void ExpandQuery(const RDKit::QueryBond *other, Queries::CompositeQueryType how=Queries::COMPOSITE_AND, bool maintainOrder=true) {
|
||||
PRECONDITION(other, "bad bonds");
|
||||
if (other->hasQuery()) {
|
||||
const RDKit::QueryBond::QUERYBOND_QUERY *qry = other->getQuery();
|
||||
($self)->expandQuery(qry->copy(), how, maintainOrder);
|
||||
}
|
||||
}
|
||||
|
||||
void SetQuery(const RDKit::QueryBond *other) {
|
||||
PRECONDITION(other, "bad bonds");
|
||||
if (other->hasQuery()) {
|
||||
($self)->setQuery(other->getQuery()->copy());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
%extend RDKit::Bond {
|
||||
void ExpandQuery(const RDKit::QueryBond *other, Queries::CompositeQueryType how=Queries::COMPOSITE_AND, bool maintainOrder=true) {
|
||||
PRECONDITION(other, "bad bonds");
|
||||
if (other->hasQuery()) {
|
||||
const RDKit::QueryBond::QUERYBOND_QUERY *qry = other->getQuery();
|
||||
($self)->expandQuery(qry->copy(), how, maintainOrder);
|
||||
}
|
||||
}
|
||||
|
||||
void SetQuery(const RDKit::QueryBond *other) {
|
||||
PRECONDITION(other, "bad bonds");
|
||||
if (other->hasQuery()) {
|
||||
($self)->setQuery(other->getQuery()->copy());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -35,6 +35,14 @@
|
||||
#include <GraphMol/QueryAtom.h>
|
||||
%}
|
||||
|
||||
|
||||
%ignore RDKit::QueryAtom::expandQuery;
|
||||
%ignore RDKit::QueryAtom::setQuery;
|
||||
|
||||
%include <GraphMol/QueryAtom.h>
|
||||
|
||||
%extend RDKit::QueryAtom {
|
||||
bool MatchAtom(RDKit::Atom const *what) {
|
||||
return ($self)->Match(what);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,15 @@
|
||||
#include <GraphMol/QueryBond.h>
|
||||
%}
|
||||
|
||||
|
||||
%ignore RDKit::QueryBond::expandQuery;
|
||||
%ignore RDKit::QueryBond::setQuery;
|
||||
|
||||
%include <GraphMol/QueryBond.h>
|
||||
|
||||
%extend RDKit::QueryBond {
|
||||
bool MatchBond(RDKit::Bond const *what) {
|
||||
return ($self)->Match(what);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -38,5 +38,8 @@
|
||||
|
||||
%include <RDGeneral/RDProps.h>
|
||||
|
||||
/* For the time being, assume all properties will be strings */
|
||||
%template(setProp) RDKit::RDProps::setProp<std::string>;
|
||||
%template(setIntProp) RDKit::RDProps::setProp<int>;
|
||||
%template(setBoolProp) RDKit::RDProps::setProp<bool>;
|
||||
%template(setDoubleProp) RDKit::RDProps::setProp<double>;
|
||||
|
||||
|
||||
@@ -198,6 +198,7 @@
|
||||
%newobject replaceSidechains;
|
||||
%newobject deleteSubstructs;
|
||||
%newobject getAtoms;
|
||||
%newobject getBonds;
|
||||
%newobject getAtomNeighbors;
|
||||
%newobject getAtomBonds;
|
||||
|
||||
@@ -563,29 +564,23 @@ void setAllowNontetrahedralChirality(bool);
|
||||
|
||||
/* From Python wrappers -- implied functionality */
|
||||
std::vector<RDKit::Atom*> *getAtoms() {
|
||||
int c = ($self)->getNumAtoms();
|
||||
std::vector<RDKit::Atom*> *atoms = new std::vector<RDKit::Atom*>;
|
||||
for (int i = 0; i < c; i++) {
|
||||
RDKit::Atom* a = ($self)->getAtomWithIdx(i);
|
||||
atoms->push_back(a);
|
||||
}
|
||||
return atoms;
|
||||
auto atoms = ($self)->atoms();
|
||||
return new std::vector<RDKit::Atom*>(atoms.begin(), atoms.end());
|
||||
}
|
||||
|
||||
std::vector<RDKit::Bond*> *getBonds() {
|
||||
auto bonds = ($self)->bonds();
|
||||
return new std::vector<RDKit::Bond*>(bonds.begin(), bonds.end());
|
||||
}
|
||||
|
||||
std::vector<RDKit::Atom*> *getAtomNeighbors(RDKit::Atom *at) {
|
||||
std::vector<RDKit::Atom*> *atoms = new std::vector<RDKit::Atom*>;
|
||||
for(const auto &nbri : boost::make_iterator_range(($self)->getAtomNeighbors(at))){
|
||||
atoms->push_back((*($self))[nbri]);
|
||||
}
|
||||
return atoms;
|
||||
auto atomNbrs = ($self)->atomNeighbors(at);
|
||||
return new std::vector<RDKit::Atom*>(atomNbrs.begin(), atomNbrs.end());
|
||||
}
|
||||
|
||||
std::vector<RDKit::Bond*> *getAtomBonds(RDKit::Atom *at) {
|
||||
std::vector<RDKit::Bond*> *bonds = new std::vector<RDKit::Bond*>;
|
||||
for(const auto &nbri : boost::make_iterator_range(($self)->getAtomBonds(at))){
|
||||
bonds->push_back((*($self))[nbri]);
|
||||
}
|
||||
return bonds;
|
||||
auto bondNbrs = ($self)->atomBonds(at);
|
||||
return new std::vector<RDKit::Bond*>(bondNbrs.begin(), bondNbrs.end());
|
||||
}
|
||||
|
||||
/* From MolPickler.h */
|
||||
|
||||
@@ -257,6 +257,7 @@ typedef unsigned long long int uintmax_t;
|
||||
%include "../Streams.i"
|
||||
%include "../GeneralizedSubstruct.i"
|
||||
%include "../RascalMCES.i"
|
||||
%include "../Queries.i"
|
||||
|
||||
|
||||
// Create a class to throw various sorts of errors for testing. Required for unit tests in ErrorHandlingTests.java
|
||||
|
||||
252
Code/JavaWrappers/csharp_wrapper/RdkitTests/QueryAtomTest.cs
Normal file
252
Code/JavaWrappers/csharp_wrapper/RdkitTests/QueryAtomTest.cs
Normal file
@@ -0,0 +1,252 @@
|
||||
//
|
||||
// Copyright (C) 2020 Gareth Jones, Glysade LLC
|
||||
//
|
||||
// @@ 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.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection.PortableExecutable;
|
||||
using GraphMolWrap;
|
||||
using Xunit;
|
||||
|
||||
namespace RdkitTests
|
||||
{
|
||||
public class QueryAtomTest
|
||||
{
|
||||
[Fact]
|
||||
public void TestChemdrawBlock()
|
||||
{
|
||||
// smiles c1[nH]ccc1
|
||||
// Chemdraw will convert explicit hydrogens in aromatic compounds to query hydrogen count
|
||||
var block = @"
|
||||
ChemDraw05012418152D
|
||||
|
||||
0 0 0 0 0 0 V3000
|
||||
M V30 BEGIN CTAB
|
||||
M V30 COUNTS 5 5 0 0 0
|
||||
M V30 BEGIN ATOM
|
||||
M V30 1 C -0.652854 -0.050688 0.000000 0
|
||||
M V30 2 C -0.240354 0.663783 0.000000 0
|
||||
M V30 3 C 0.566618 0.492256 0.000000 0
|
||||
M V30 4 C 0.652854 -0.328225 0.000000 0
|
||||
M V30 5 N -0.100821 -0.663783 0.000000 0 HCOUNT=1
|
||||
M V30 END ATOM
|
||||
M V30 BEGIN BOND
|
||||
M V30 1 4 1 2
|
||||
M V30 2 4 2 3
|
||||
M V30 3 4 3 4
|
||||
M V30 4 4 4 5
|
||||
M V30 5 4 1 5
|
||||
M V30 END BOND
|
||||
M V30 END CTAB
|
||||
M END
|
||||
";
|
||||
var mol = RWMol.MolFromMolBlock(block, false);
|
||||
Assert.NotNull(mol);
|
||||
Assert.Equal(5U, mol.getNumAtoms());
|
||||
var queryAtom = mol.getAtomWithIdx(4);
|
||||
Assert.True(queryAtom.hasQuery());
|
||||
var smarts = queryAtom.AtomGetSmarts();
|
||||
var expected = "[#7&h{1-}]";
|
||||
Assert.Equal(expected, smarts);
|
||||
var description = queryAtom.describeQuery();
|
||||
expected = "AtomAnd\n AtomAtomicNum 7 = val\n less_AtomImplicitHCount 1 <= \n";
|
||||
Assert.Equal(expected, description);
|
||||
|
||||
var molSmiles = mol.MolToSmiles();
|
||||
var molSmarts = RDKFuncs.MolToSmarts(mol);
|
||||
|
||||
var atom = new Atom(7);
|
||||
atom.setNumExplicitHs(1);
|
||||
mol.replaceAtom(4, atom);
|
||||
mol.clearComputedProps(true);
|
||||
mol.sanitizeMol();
|
||||
|
||||
atom = mol.getAtomWithIdx(4);
|
||||
Assert.Equal(7, atom.getAtomicNum());
|
||||
Assert.Equal(1U, atom.getNumExplicitHs());
|
||||
molSmiles = mol.MolToSmiles();
|
||||
Assert.Equal("c1cc[nH]c1", molSmiles);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestReplaceQuerySimple()
|
||||
{
|
||||
var query = RWMol.MolFromSmiles("c1[nH]ccc1");
|
||||
var nitrogen = query.getAtomWithIdx(2);
|
||||
var imp = nitrogen.getNumImplicitHs();
|
||||
Assert.Equal(1U, imp);
|
||||
var queryAtom = RDKFuncs.replaceAtomWithQueryAtom(query, nitrogen);
|
||||
queryAtom.ExpandQuery(RDKFuncs.ExplicitDegreeEqualsQueryAtom(3));
|
||||
var mol1 = RWMol.MolFromSmiles("Cc1[nH]ccc1");
|
||||
Assert.True(mol1.hasSubstructMatch(query));
|
||||
var mol2 = RWMol.MolFromSmiles("c1[nH]ccc1");
|
||||
Assert.False(mol2.hasSubstructMatch(query));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestExpandQuerySimple()
|
||||
{
|
||||
var query = RWMol.MolFromSmarts("c1nccc1");
|
||||
var mol1 = RWMol.MolFromSmiles("c1[nH]ccc1");
|
||||
Assert.True(mol1.hasSubstructMatch(query));
|
||||
var atom = query.getAtomWithIdx(0);
|
||||
Assert.True(atom.hasQuery());
|
||||
var queryAtom = RDKFuncs.ExplicitDegreeEqualsQueryAtom(3);
|
||||
atom.ExpandQuery(queryAtom, CompositeQueryType.COMPOSITE_AND);
|
||||
Assert.False(mol1.hasSubstructMatch(query));
|
||||
var mol2 = RWMol.MolFromSmiles("Cc1[nH]ccc1");
|
||||
Assert.True(mol2.hasSubstructMatch(query));
|
||||
}
|
||||
|
||||
|
||||
// adapted from Python tests
|
||||
private IList<uint> GetAtomIdxsMatchingQuery(ROMol mol, QueryAtom qa)
|
||||
{
|
||||
return mol.getAtoms().Where(qa.MatchAtom).Select(a => a.getIdx()).ToList();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestQueryAtoms()
|
||||
{
|
||||
var m = RWMol.MolFromSmiles("c1nc(C)n(CC)c1");
|
||||
var qa = RDKFuncs.ExplicitDegreeEqualsQueryAtom(3);
|
||||
var matches = GetAtomIdxsMatchingQuery(m, qa);
|
||||
Assert.Equal(new List<uint> { 2U, 4U }, matches);
|
||||
|
||||
qa.ExpandQuery(RDKFuncs.AtomNumEqualsQueryAtom(6, true));
|
||||
matches = GetAtomIdxsMatchingQuery(m, qa);
|
||||
Assert.Equal(new List<uint> { 4U }, matches);
|
||||
|
||||
qa = RDKFuncs.ExplicitDegreeEqualsQueryAtom(3);
|
||||
qa.ExpandQuery(RDKFuncs.AtomNumEqualsQueryAtom(6, true),
|
||||
CompositeQueryType.COMPOSITE_OR);
|
||||
matches = GetAtomIdxsMatchingQuery(m, qa);
|
||||
Assert.Equal(new List<uint> { 1U, 2U, 4U }, matches);
|
||||
|
||||
qa = RDKFuncs.ExplicitDegreeEqualsQueryAtom(3);
|
||||
qa.ExpandQuery(RDKFuncs.AtomNumEqualsQueryAtom(6, true),
|
||||
CompositeQueryType.COMPOSITE_XOR);
|
||||
matches = GetAtomIdxsMatchingQuery(m, qa);
|
||||
Assert.Equal(new List<uint> { 1U, 2U }, matches);
|
||||
|
||||
qa = RDKFuncs.ExplicitDegreeGreaterQueryAtom(2);
|
||||
matches = GetAtomIdxsMatchingQuery(m, qa);
|
||||
Assert.Equal(new List<uint> { 2U, 4U }, matches);
|
||||
|
||||
qa = RDKFuncs.ExplicitDegreeLessQueryAtom(2);
|
||||
matches = GetAtomIdxsMatchingQuery(m, qa);
|
||||
Assert.Equal(new List<uint> { 3U, 6U }, matches);
|
||||
|
||||
m = RWMol.MolFromSmiles("N[CH][CH]");
|
||||
qa = RDKFuncs.NumRadicalElectronsGreaterQueryAtom(0);
|
||||
matches = GetAtomIdxsMatchingQuery(m, qa);
|
||||
Assert.Equal(new List<uint> { 1U, 2U }, matches);
|
||||
qa = RDKFuncs.NumRadicalElectronsGreaterQueryAtom(1);
|
||||
matches = GetAtomIdxsMatchingQuery(m, qa);
|
||||
Assert.Equal(new List<uint> { 2U }, matches);
|
||||
|
||||
m = RWMol.MolFromSmiles("F[C@H](Cl)C");
|
||||
qa = RDKFuncs.HasChiralTagQueryAtom();
|
||||
matches = GetAtomIdxsMatchingQuery(m, qa);
|
||||
Assert.Equal(new List<uint> { 1U }, matches);
|
||||
qa = RDKFuncs.MissingChiralTagQueryAtom();
|
||||
Assert.Equal(new List<uint> { 1U }, matches);
|
||||
|
||||
m = RWMol.MolFromSmiles("F[CH](Cl)C");
|
||||
qa = RDKFuncs.HasChiralTagQueryAtom();
|
||||
matches = GetAtomIdxsMatchingQuery(m, qa);
|
||||
Assert.Equal(new List<uint> { }, matches);
|
||||
qa = RDKFuncs.MissingChiralTagQueryAtom();
|
||||
matches = GetAtomIdxsMatchingQuery(m, qa);
|
||||
Assert.Equal(new List<uint> { 1U }, matches);
|
||||
|
||||
m = RWMol.MolFromSmiles("CNCON");
|
||||
qa = RDKFuncs.NumHeteroatomNeighborsEqualsQueryAtom(2);
|
||||
matches = GetAtomIdxsMatchingQuery(m, qa);
|
||||
Assert.Equal(new List<uint> { 2U }, matches);
|
||||
qa = RDKFuncs.NumHeteroatomNeighborsGreaterQueryAtom(0);
|
||||
matches = GetAtomIdxsMatchingQuery(m, qa);
|
||||
Assert.Equal(new List<uint> { 0U, 2U, 3U, 4U }, matches);
|
||||
|
||||
m = RWMol.MolFromSmiles("CC12CCN(CC1)C2");
|
||||
qa = RDKFuncs.IsBridgeheadQueryAtom();
|
||||
matches = GetAtomIdxsMatchingQuery(m, qa);
|
||||
Assert.Equal(new List<uint> { 1U, 4U }, matches);
|
||||
|
||||
m = RWMol.MolFromSmiles("OCCOC");
|
||||
qa = RDKFuncs.NonHydrogenDegreeEqualsQueryAtom(2);
|
||||
matches = GetAtomIdxsMatchingQuery(m, qa);
|
||||
Assert.Equal(new List<uint> { 1U, 2U, 3U }, matches);
|
||||
}
|
||||
private IList<uint> GetBondIdxsMatchingQuery(ROMol mol, QueryBond qb)
|
||||
{
|
||||
return mol.getBonds().Where(qb.MatchBond).Select(a => a.getIdx()).ToList();
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void TestBondPropQueries()
|
||||
{
|
||||
var m = RWMol.MolFromSmiles("CCCCCCCCCCCCCC");
|
||||
var bonds = m.getBonds();
|
||||
bonds[0].setProp("hah", "hah");
|
||||
bonds[1].setIntProp("bar", 1);
|
||||
bonds[2].setIntProp("bar", 2);
|
||||
bonds[3].setBoolProp("baz", true);
|
||||
bonds[4].setBoolProp("baz", false);
|
||||
bonds[5].setProp("boo", "hoo");
|
||||
bonds[6].setProp("boo", "-urns");
|
||||
bonds[7].setDoubleProp("boot", 1.0);
|
||||
bonds[8].setDoubleProp("boot", 4.0);
|
||||
bonds[9].setDoubleProp("number", 4.0);
|
||||
bonds[10].setIntProp("number", 4);
|
||||
|
||||
var qb = RDKFuncs.HasIntPropWithValueQueryBond("bar",1);
|
||||
var matches = GetBondIdxsMatchingQuery(m, qb);
|
||||
Assert.Equal(new List<uint> { 1U }, matches);
|
||||
|
||||
qb = RDKFuncs.HasIntPropWithValueQueryBond("bar",2);
|
||||
matches = GetBondIdxsMatchingQuery(m, qb);
|
||||
Assert.Equal(new List<uint> { 2U }, matches);
|
||||
|
||||
qb = RDKFuncs.HasBoolPropWithValueQueryBond("baz",true);
|
||||
matches = GetBondIdxsMatchingQuery(m, qb);
|
||||
Assert.Equal(new List<uint> { 3U }, matches);
|
||||
|
||||
qb = RDKFuncs.HasBoolPropWithValueQueryBond("baz",false);
|
||||
matches = GetBondIdxsMatchingQuery(m, qb);
|
||||
Assert.Equal(new List<uint> { 4U }, matches);
|
||||
|
||||
qb = RDKFuncs.HasStringPropWithValueQueryBond("boo","hoo");
|
||||
matches = GetBondIdxsMatchingQuery(m, qb);
|
||||
Assert.Equal(new List<uint> { 5U }, matches);
|
||||
|
||||
qb = RDKFuncs.HasStringPropWithValueQueryBond("boo","-urns");
|
||||
matches = GetBondIdxsMatchingQuery(m, qb);
|
||||
Assert.Equal(new List<uint> { 6U }, matches);
|
||||
|
||||
qb = RDKFuncs.HasDoublePropWithValueQueryBond("boot",1.0);
|
||||
matches = GetBondIdxsMatchingQuery(m, qb);
|
||||
Assert.Equal(new List<uint> { 7U }, matches);
|
||||
|
||||
qb = RDKFuncs.HasDoublePropWithValueQueryBond("boot",4.0);
|
||||
matches = GetBondIdxsMatchingQuery(m, qb);
|
||||
Assert.Equal(new List<uint> { 8U }, matches);
|
||||
|
||||
qb = RDKFuncs.HasDoublePropWithValueQueryBond("boot",1.0, false, 3.0);
|
||||
matches = GetBondIdxsMatchingQuery(m, qb);
|
||||
Assert.Equal(new List<uint> { 7U, 8U }, matches);
|
||||
|
||||
qb = RDKFuncs.HasIntPropWithValueQueryBond("number",4);
|
||||
matches = GetBondIdxsMatchingQuery(m, qb);
|
||||
Assert.Equal(new List<uint> { 10U }, matches);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -307,6 +307,10 @@ ADD_TEST(JavaRascalMCES
|
||||
java -Djava.library.path=${CMAKE_CURRENT_SOURCE_DIR}
|
||||
-cp "${JUNIT_JAR}${PATH_SEP}${CMAKE_JAVA_TEST_OUTDIR}${PATH_SEP}${CMAKE_CURRENT_SOURCE_DIR}/org.RDKit.jar"
|
||||
org.RDKit.RascalMCESTest)
|
||||
ADD_TEST(JavaQueryAtomTest
|
||||
java -Djava.library.path=${CMAKE_CURRENT_SOURCE_DIR}
|
||||
-cp "${JUNIT_JAR}${PATH_SEP}${CMAKE_JAVA_TEST_OUTDIR}${PATH_SEP}${CMAKE_CURRENT_SOURCE_DIR}/org.RDKit.jar"
|
||||
org.RDKit.QueryAtomTest)
|
||||
|
||||
if(RDK_BUILD_AVALON_SUPPORT)
|
||||
ADD_TEST(JavaAvalonTests
|
||||
|
||||
@@ -226,6 +226,7 @@ typedef unsigned long long int uintmax_t;
|
||||
%include "../Streams.i"
|
||||
%include "../GeneralizedSubstruct.i"
|
||||
%include "../RascalMCES.i"
|
||||
%include "../Queries.i"
|
||||
|
||||
// Create a class to throw various sorts of errors for testing. Required for unit tests in ErrorHandlingTests.java
|
||||
#ifdef INCLUDE_ERROR_GENERATOR
|
||||
|
||||
@@ -0,0 +1,268 @@
|
||||
// Copyright (C) 2020 Gareth Jones, Glysade LLC
|
||||
//
|
||||
// @@ 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.
|
||||
//
|
||||
|
||||
package org.RDKit;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.*;
|
||||
|
||||
public class QueryAtomTest extends GraphMolTest {
|
||||
|
||||
@Test
|
||||
public void testChemdrawBlock() {
|
||||
// smiles c1[nH]ccc1
|
||||
// Chemdraw will convert explicit hydrogens in aromatic compounds to query hydrogen count
|
||||
String block = String.join("\n",
|
||||
"ChemDraw05012418152D",
|
||||
"",
|
||||
"0 0 0 0 0 0 V3000",
|
||||
"M V30 BEGIN CTAB",
|
||||
"M V30 COUNTS 5 5 0 0 0",
|
||||
"M V30 BEGIN ATOM",
|
||||
"M V30 1 C - 0.652854 - 0.050688 0.000000 0",
|
||||
"M V30 2 C - 0.240354 0.663783 0.000000 0",
|
||||
"M V30 3 C 0.566618 0.492256 0.000000 0",
|
||||
"M V30 4 C 0.652854 - 0.328225 0.000000 0",
|
||||
"M V30 5 N - 0.100821 - 0.663783 0.000000 0 HCOUNT = 1",
|
||||
"M V30 END ATOM",
|
||||
"M V30 BEGIN BOND",
|
||||
"M V30 1 4 1 2",
|
||||
"M V30 2 4 2 3",
|
||||
"M V30 3 4 3 4",
|
||||
"M V30 4 4 4 5",
|
||||
"M V30 5 4 1 5",
|
||||
"M V30 END BOND",
|
||||
"M V30 END CTAB",
|
||||
"M END",
|
||||
"");
|
||||
RWMol mol = RWMol.MolFromMolBlock(block, false);
|
||||
assertNotNull(mol);
|
||||
assertEquals(5, mol.getNumAtoms());
|
||||
Atom queryAtom = mol.getAtomWithIdx(4);
|
||||
assertTrue(queryAtom.hasQuery());
|
||||
String smarts = queryAtom.AtomGetSmarts();
|
||||
String expected = "[#7&h{1-}]";
|
||||
assertEquals(expected, smarts);
|
||||
String description = queryAtom.describeQuery();
|
||||
expected = "AtomAnd\n AtomAtomicNum 7 = val\n less_AtomImplicitHCount 1 <= \n";
|
||||
assertEquals(expected, description);
|
||||
|
||||
String molSmiles = mol.MolToSmiles();
|
||||
|
||||
Atom atom = new Atom(7);
|
||||
atom.setNumExplicitHs(1);
|
||||
mol.replaceAtom(4, atom);
|
||||
mol.clearComputedProps(true);
|
||||
mol.sanitizeMol();
|
||||
|
||||
atom = mol.getAtomWithIdx(4);
|
||||
assertEquals(7, atom.getAtomicNum());
|
||||
assertEquals(1, atom.getNumExplicitHs());
|
||||
molSmiles = mol.MolToSmiles();
|
||||
assertEquals("c1cc[nH]c1", molSmiles);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReplaceQuerySimple() {
|
||||
RWMol query = RWMol.MolFromSmiles("c1[nH]ccc1");
|
||||
Atom nitrogen = query.getAtomWithIdx(2);
|
||||
long imp = nitrogen.getNumImplicitHs();
|
||||
assertEquals(1, imp);
|
||||
Atom queryAtom = RDKFuncs.replaceAtomWithQueryAtom(query, nitrogen);
|
||||
queryAtom.ExpandQuery(RDKFuncs.ExplicitDegreeEqualsQueryAtom(3));
|
||||
RWMol mol1 = RWMol.MolFromSmiles("Cc1[nH]ccc1");
|
||||
assertTrue(mol1.hasSubstructMatch(query));
|
||||
RWMol mol2 = RWMol.MolFromSmiles("c1[nH]ccc1");
|
||||
assertFalse(mol2.hasSubstructMatch(query));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpandQuerySimple() {
|
||||
RWMol query = RWMol.MolFromSmarts("c1nccc1");
|
||||
RWMol mol1 = RWMol.MolFromSmiles("c1[nH]ccc1");
|
||||
assertTrue(mol1.hasSubstructMatch(query));
|
||||
Atom atom = query.getAtomWithIdx(0);
|
||||
assertTrue(atom.hasQuery());
|
||||
QueryAtom queryAtom = RDKFuncs.ExplicitDegreeEqualsQueryAtom(3);
|
||||
atom.ExpandQuery(queryAtom, CompositeQueryType.COMPOSITE_AND);
|
||||
assertFalse(mol1.hasSubstructMatch(query));
|
||||
RWMol mol2 = RWMol.MolFromSmiles("Cc1[nH]ccc1");
|
||||
assertTrue(mol2.hasSubstructMatch(query));
|
||||
}
|
||||
|
||||
// adapted from Python tests
|
||||
|
||||
private int[] GetAtomIdxsMatchingQuery(ROMol mol, QueryAtom qa) {
|
||||
List<Integer> indices = new ArrayList<Integer>();
|
||||
for (int i =0; i< mol.getNumAtoms(); i++) {
|
||||
Atom atom = mol.getAtomWithIdx(i);
|
||||
if (qa.MatchAtom(atom)) {
|
||||
indices.add(i);
|
||||
}
|
||||
}
|
||||
int[] arr = new int[indices.size()];
|
||||
for (int i=0; i<arr.length; i++) {
|
||||
arr[i] = indices.get(i);
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueryAtoms() {
|
||||
RWMol m = RWMol.MolFromSmiles("c1nc(C)n(CC)c1");
|
||||
QueryAtom qa = RDKFuncs.ExplicitDegreeEqualsQueryAtom(3);
|
||||
int[] matches = GetAtomIdxsMatchingQuery(m, qa);
|
||||
assertArrayEquals(new int[] {2, 4}, matches);
|
||||
|
||||
qa.ExpandQuery(RDKFuncs.AtomNumEqualsQueryAtom(6, true));
|
||||
matches = GetAtomIdxsMatchingQuery(m, qa);
|
||||
assertArrayEquals(new int[] {4}, matches);
|
||||
|
||||
qa = RDKFuncs.ExplicitDegreeEqualsQueryAtom(3);
|
||||
qa.ExpandQuery(RDKFuncs.AtomNumEqualsQueryAtom(6, true),
|
||||
CompositeQueryType.COMPOSITE_OR);
|
||||
matches = GetAtomIdxsMatchingQuery(m, qa);
|
||||
assertArrayEquals(new int[] {1, 2, 4}, matches);
|
||||
|
||||
qa = RDKFuncs.ExplicitDegreeEqualsQueryAtom(3);
|
||||
qa.ExpandQuery(RDKFuncs.AtomNumEqualsQueryAtom(6, true),
|
||||
CompositeQueryType.COMPOSITE_XOR);
|
||||
matches = GetAtomIdxsMatchingQuery(m, qa);
|
||||
assertArrayEquals(new int[] {1, 2}, matches);
|
||||
|
||||
qa = RDKFuncs.ExplicitDegreeGreaterQueryAtom(2);
|
||||
matches = GetAtomIdxsMatchingQuery(m, qa);
|
||||
assertArrayEquals(new int[] {2, 4}, matches);
|
||||
|
||||
qa = RDKFuncs.ExplicitDegreeLessQueryAtom(2);
|
||||
matches = GetAtomIdxsMatchingQuery(m, qa);
|
||||
assertArrayEquals(new int[] {3, 6}, matches);
|
||||
|
||||
m = RWMol.MolFromSmiles("N[CH][CH]");
|
||||
qa = RDKFuncs.NumRadicalElectronsGreaterQueryAtom(0);
|
||||
matches = GetAtomIdxsMatchingQuery(m, qa);
|
||||
assertArrayEquals(new int[] {1, 2}, matches);
|
||||
qa = RDKFuncs.NumRadicalElectronsGreaterQueryAtom(1);
|
||||
matches = GetAtomIdxsMatchingQuery(m, qa);
|
||||
assertArrayEquals(new int[] {2}, matches);
|
||||
|
||||
m = RWMol.MolFromSmiles("F[C@H](Cl)C");
|
||||
qa = RDKFuncs.HasChiralTagQueryAtom();
|
||||
matches = GetAtomIdxsMatchingQuery(m, qa);
|
||||
assertArrayEquals(new int[] {1}, matches);
|
||||
qa = RDKFuncs.MissingChiralTagQueryAtom();
|
||||
assertArrayEquals(new int[] {1}, matches);
|
||||
|
||||
m = RWMol.MolFromSmiles("F[CH](Cl)C");
|
||||
qa = RDKFuncs.HasChiralTagQueryAtom();
|
||||
matches = GetAtomIdxsMatchingQuery(m, qa);
|
||||
assertArrayEquals(new int[] {}, matches);
|
||||
qa = RDKFuncs.MissingChiralTagQueryAtom();
|
||||
matches = GetAtomIdxsMatchingQuery(m, qa);
|
||||
assertArrayEquals(new int[] {1}, matches);
|
||||
|
||||
m = RWMol.MolFromSmiles("CNCON");
|
||||
qa = RDKFuncs.NumHeteroatomNeighborsEqualsQueryAtom(2);
|
||||
matches = GetAtomIdxsMatchingQuery(m, qa);
|
||||
assertArrayEquals(new int[] {2}, matches);
|
||||
qa = RDKFuncs.NumHeteroatomNeighborsGreaterQueryAtom(0);
|
||||
matches = GetAtomIdxsMatchingQuery(m, qa);
|
||||
assertArrayEquals(new int[] {0, 2, 3, 4}, matches);
|
||||
|
||||
m = RWMol.MolFromSmiles("CC12CCN(CC1)C2");
|
||||
qa = RDKFuncs.IsBridgeheadQueryAtom();
|
||||
matches = GetAtomIdxsMatchingQuery(m, qa);
|
||||
assertArrayEquals(new int[] {1, 4}, matches);
|
||||
|
||||
m = RWMol.MolFromSmiles("OCCOC");
|
||||
qa = RDKFuncs.NonHydrogenDegreeEqualsQueryAtom(2);
|
||||
matches = GetAtomIdxsMatchingQuery(m, qa);
|
||||
assertArrayEquals(new int[] {1, 2, 3}, matches);
|
||||
}
|
||||
|
||||
private int[] GetBondIdxsMatchingQuery(ROMol mol, QueryBond qa) {
|
||||
List<Integer> indices = new ArrayList<Integer>();
|
||||
for (int i =0; i< mol.getNumBonds(); i++) {
|
||||
Bond atom = mol.getBondWithIdx(i);
|
||||
if (qa.MatchBond(atom)) {
|
||||
indices.add(i);
|
||||
}
|
||||
}
|
||||
int[] arr = new int[indices.size()];
|
||||
for (int i=0; i<arr.length; i++) {
|
||||
arr[i] = indices.get(i);
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void TestBondPropQueries() {
|
||||
RWMol m = RWMol.MolFromSmiles("CCCCCCCCCCCCCC");
|
||||
Bond_Vect bonds = m.getBonds();
|
||||
bonds.get(0).setProp("hah", "hah");
|
||||
bonds.get(1).setIntProp("bar", 1);
|
||||
bonds.get(2).setIntProp("bar", 2);
|
||||
bonds.get(3).setBoolProp("baz", true);
|
||||
bonds.get(4).setBoolProp("baz", false);
|
||||
bonds.get(5).setProp("boo", "hoo");
|
||||
bonds.get(6).setProp("boo", "-urns");
|
||||
bonds.get(7).setDoubleProp("boot", 1.0);
|
||||
bonds.get(8).setDoubleProp("boot", 4.0);
|
||||
bonds.get(9).setDoubleProp("number", 4.0);
|
||||
bonds.get(10).setIntProp("number", 4);
|
||||
|
||||
QueryBond qb = RDKFuncs.HasIntPropWithValueQueryBond("bar", 1);
|
||||
int[] matches = GetBondIdxsMatchingQuery(m, qb);
|
||||
assertArrayEquals(new int[] {1}, matches);
|
||||
|
||||
qb = RDKFuncs.HasIntPropWithValueQueryBond("bar", 2);
|
||||
matches = GetBondIdxsMatchingQuery(m, qb);
|
||||
assertArrayEquals(new int[] {2}, matches);
|
||||
|
||||
qb = RDKFuncs.HasBoolPropWithValueQueryBond("baz", true);
|
||||
matches = GetBondIdxsMatchingQuery(m, qb);
|
||||
assertArrayEquals(new int[] {3}, matches);
|
||||
|
||||
qb = RDKFuncs.HasBoolPropWithValueQueryBond("baz", false);
|
||||
matches = GetBondIdxsMatchingQuery(m, qb);
|
||||
assertArrayEquals(new int[] {4}, matches);
|
||||
|
||||
qb = RDKFuncs.HasStringPropWithValueQueryBond("boo", "hoo");
|
||||
matches = GetBondIdxsMatchingQuery(m, qb);
|
||||
assertArrayEquals(new int[] {5}, matches);
|
||||
|
||||
qb = RDKFuncs.HasStringPropWithValueQueryBond("boo", "-urns");
|
||||
matches = GetBondIdxsMatchingQuery(m, qb);
|
||||
assertArrayEquals(new int[] {6}, matches);
|
||||
|
||||
qb = RDKFuncs.HasDoublePropWithValueQueryBond("boot", 1.0);
|
||||
matches = GetBondIdxsMatchingQuery(m, qb);
|
||||
assertArrayEquals(new int[] {7}, matches);
|
||||
|
||||
qb = RDKFuncs.HasDoublePropWithValueQueryBond("boot", 4.0);
|
||||
matches = GetBondIdxsMatchingQuery(m, qb);
|
||||
assertArrayEquals(new int[] {8}, matches);
|
||||
|
||||
qb = RDKFuncs.HasDoublePropWithValueQueryBond("boot", 1.0, false, 3.0);
|
||||
matches = GetBondIdxsMatchingQuery(m, qb);
|
||||
assertArrayEquals(new int[] {7, 8}, matches);
|
||||
|
||||
qb = RDKFuncs.HasIntPropWithValueQueryBond("number", 4);
|
||||
matches = GetBondIdxsMatchingQuery(m, qb);
|
||||
assertArrayEquals(new int[] {10}, matches);
|
||||
}
|
||||
|
||||
public static void main(String args[]) {
|
||||
org.junit.runner.JUnitCore.main("org.RDKit.RascalMCESTest");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user