RDKit
Open-source cheminformatics and machine learning.
QueryOps.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2003-2017 Greg Landrum and Rational Discovery LLC
3 //
4 // @@ All Rights Reserved @@
5 // This file is part of the RDKit.
6 // The contents are covered by the terms of the BSD license
7 // which is included in the file license.txt, found at the root
8 // of the RDKit source tree.
9 //
10 
11 //! \file QueryOps.h
12 /*!
13  \brief Includes a bunch of functionality for handling Atom and Bond queries.
14 */
15 #ifndef _RD_QUERY_OPS_H
16 #define _RD_QUERY_OPS_H
17 
18 #include <GraphMol/RDKitBase.h>
19 #include <Query/QueryObjects.h>
20 #include <Query/Query.h>
21 
22 #ifdef RDK_THREADSAFE_SSS
24 #include <boost/thread/mutex.hpp>
26 #endif
27 
28 namespace RDKit {
31 
34 
37 
40 
43 
46 
51 
54 
57 
60 
63 
66 
67 // -------------------------------------------------
68 // common atom queries
69 
70 static inline int queryAtomAromatic(Atom const *at) {
71  return at->getIsAromatic();
72 };
73 static inline int queryAtomAliphatic(Atom const *at) {
74  return !(at->getIsAromatic());
75 };
76 static inline int queryAtomExplicitDegree(Atom const *at) {
77  return at->getDegree();
78 };
79 static inline int queryAtomTotalDegree(Atom const *at) {
80  return at->getTotalDegree();
81 };
82 static inline int queryAtomHeavyAtomDegree(Atom const *at) {
83  return at->getTotalDegree() - at->getTotalNumHs(true);
84 };
85 static inline int queryAtomHCount(Atom const *at) {
86  return at->getTotalNumHs(true);
87 };
88 static inline int queryAtomImplicitHCount(Atom const *at) {
89  return at->getTotalNumHs(false);
90 };
91 static inline int queryAtomHasImplicitH(Atom const *at) {
92  return int(at->getTotalNumHs(false) > 0);
93 };
94 static inline int queryAtomImplicitValence(Atom const *at) {
95  return at->getImplicitValence();
96 };
97 static inline int queryAtomExplicitValence(Atom const *at) {
98  return at->getExplicitValence() - at->getNumExplicitHs();
99 };
100 static inline int queryAtomTotalValence(Atom const *at) {
101  return at->getExplicitValence() + at->getImplicitValence();
102 };
103 static inline int queryAtomUnsaturated(Atom const *at) {
104  return static_cast<int>(at->getDegree()) < at->getExplicitValence();
105 };
106 static inline int queryAtomNum(Atom const *at) { return at->getAtomicNum(); };
108 static inline int queryAtomMass(Atom const *at) {
109  return static_cast<int>(round(massIntegerConversionFactor * at->getMass()));
110 };
111 static inline int queryAtomIsotope(Atom const *at) {
112  return static_cast<int>(at->getIsotope());
113 };
114 static inline int queryAtomFormalCharge(Atom const *at) {
115  return static_cast<int>(at->getFormalCharge());
116 };
117 static inline int queryAtomHybridization(Atom const *at) {
118  return at->getHybridization();
119 };
120 static inline int queryAtomNumRadicalElectrons(Atom const *at) {
121  return at->getNumRadicalElectrons();
122 };
123 static inline int queryAtomHasChiralTag(Atom const *at) {
124  return at->getChiralTag() != Atom::CHI_UNSPECIFIED;
125 };
126 static inline int queryAtomMissingChiralTag(Atom const *at) {
127  return at->getChiralTag() == Atom::CHI_UNSPECIFIED &&
129 };
130 
131 unsigned int queryAtomBondProduct(Atom const *at);
132 unsigned int queryAtomAllBondProduct(Atom const *at);
133 
134 // -------------------------------------------------
135 // common bond queries
136 
137 static inline int queryBondOrder(Bond const *bond) {
138  return static_cast<int>(bond->getBondType());
139 };
140 static inline int queryBondDir(Bond const *bond) {
141  return static_cast<int>(bond->getBondDir());
142 };
143 static inline int queryIsBondInNRings(Bond const *at) {
144  return at->getOwningMol().getRingInfo()->numBondRings(at->getIdx());
145 };
146 static inline int queryBondHasStereo(Bond const *bnd) {
147  return bnd->getStereo() > Bond::STEREONONE;
148 };
149 
150 // -------------------------------------------------
151 // ring queries
152 
153 static inline int queryIsAtomInNRings(Atom const *at) {
154  return at->getOwningMol().getRingInfo()->numAtomRings(at->getIdx());
155 };
156 static inline int queryIsAtomInRing(Atom const *at) {
157  return at->getOwningMol().getRingInfo()->numAtomRings(at->getIdx()) != 0;
158 };
159 static inline int queryAtomHasRingBond(Atom const *at) {
160  ROMol::OBOND_ITER_PAIR atomBonds = at->getOwningMol().getAtomBonds(at);
161  while (atomBonds.first != atomBonds.second) {
162  unsigned int bondIdx =
163  at->getOwningMol().getTopology()[*atomBonds.first]->getIdx();
164  if (at->getOwningMol().getRingInfo()->numBondRings(bondIdx)) {
165  return 1;
166  }
167  ++atomBonds.first;
168  }
169  return 0;
170 };
171 static inline int queryIsBondInRing(Bond const *bond) {
172  return bond->getOwningMol().getRingInfo()->numBondRings(bond->getIdx()) != 0;
173 };
174 static inline int queryAtomMinRingSize(Atom const *at) {
175  return at->getOwningMol().getRingInfo()->minAtomRingSize(at->getIdx());
176 };
177 static inline int queryBondMinRingSize(Bond const *bond) {
178  return bond->getOwningMol().getRingInfo()->minBondRingSize(bond->getIdx());
179 };
180 
181 static inline int queryAtomRingBondCount(Atom const *at) {
182  // EFF: cache this result
183  int res = 0;
184  ROMol::OBOND_ITER_PAIR atomBonds = at->getOwningMol().getAtomBonds(at);
185  while (atomBonds.first != atomBonds.second) {
186  unsigned int bondIdx =
187  at->getOwningMol().getTopology()[*atomBonds.first]->getIdx();
188  if (at->getOwningMol().getRingInfo()->numBondRings(bondIdx)) {
189  res++;
190  }
191  ++atomBonds.first;
192  }
193  return res;
194 }
195 
196 template <int tgt>
198  if (at->getOwningMol().getRingInfo()->isAtomInRingOfSize(at->getIdx(), tgt)) {
199  return tgt;
200  } else {
201  return 0;
202  }
203 };
204 template <int tgt>
205 int queryBondIsInRingOfSize(Bond const *bond) {
206  if (bond->getOwningMol().getRingInfo()->isBondInRingOfSize(bond->getIdx(),
207  tgt)) {
208  return tgt;
209  } else {
210  return 0;
211  }
212 };
213 
214 template <class T>
215 T *makeAtomSimpleQuery(int what, int func(Atom const *),
216  const std::string &description = "Atom Simple") {
217  T *res = new T;
218  res->setVal(what);
219  res->setDataFunc(func);
220  res->setDescription(description);
221  return res;
222 }
223 
224 //! returns a Query for matching atomic number
225 template <class T>
226 T *makeAtomNumQuery(int what, const std::string &descr) {
227  return makeAtomSimpleQuery<T>(what, queryAtomNum, descr);
228 }
229 //! \overload
230 ATOM_EQUALS_QUERY *makeAtomNumQuery(int what);
231 
232 //! returns a Query for matching implicit valence
233 template <class T>
234 T *makeAtomImplicitValenceQuery(int what, const std::string &descr) {
235  return makeAtomSimpleQuery<T>(what, queryAtomImplicitValence, descr);
236 }
237 //! \overload
238 ATOM_EQUALS_QUERY *makeAtomImplicitValenceQuery(int what);
239 
240 //! returns a Query for matching explicit valence
241 template <class T>
242 T *makeAtomExplicitValenceQuery(int what, const std::string &descr) {
243  return makeAtomSimpleQuery<T>(what, queryAtomExplicitValence, descr);
244 }
245 //! \overload
246 ATOM_EQUALS_QUERY *makeAtomExplicitValenceQuery(int what);
247 
248 //! returns a Query for matching total valence
249 template <class T>
250 T *makeAtomTotalValenceQuery(int what, const std::string &descr) {
251  return makeAtomSimpleQuery<T>(what, queryAtomTotalValence, descr);
252 }
253 //! \overload
254 ATOM_EQUALS_QUERY *makeAtomTotalValenceQuery(int what);
255 
256 //! returns a Query for matching explicit degree
257 template <class T>
258 T *makeAtomExplicitDegreeQuery(int what, const std::string &descr) {
259  return makeAtomSimpleQuery<T>(what, queryAtomExplicitDegree, descr);
260 }
261 //! \overload
262 ATOM_EQUALS_QUERY *makeAtomExplicitDegreeQuery(int what);
263 
264 //! returns a Query for matching atomic degree
265 template <class T>
266 T *makeAtomTotalDegreeQuery(int what, const std::string &descr) {
267  return makeAtomSimpleQuery<T>(what, queryAtomTotalDegree, descr);
268 }
269 //! \overload
270 ATOM_EQUALS_QUERY *makeAtomTotalDegreeQuery(int what);
271 
272 //! returns a Query for matching heavy atom degree
273 template <class T>
274 T *makeAtomHeavyAtomDegreeQuery(int what, const std::string &descr) {
275  return makeAtomSimpleQuery<T>(what, queryAtomHeavyAtomDegree, descr);
276 }
277 //! \overload
278 ATOM_EQUALS_QUERY *makeAtomHeavyAtomDegreeQuery(int what);
279 
280 //! returns a Query for matching hydrogen count
281 template <class T>
282 T *makeAtomHCountQuery(int what, const std::string &descr) {
283  return makeAtomSimpleQuery<T>(what, queryAtomHCount, descr);
284 }
285 //! \overload
286 ATOM_EQUALS_QUERY *makeAtomHCountQuery(int what);
287 
288 //! returns a Query for matching ring atoms
289 template <class T>
290 T *makeAtomHasImplicitHQuery(const std::string &descr) {
291  return makeAtomSimpleQuery<T>(true, queryAtomHasImplicitH, descr);
292 }
293 //! \overload
294 ATOM_EQUALS_QUERY *makeAtomHasImplicitHQuery();
295 
296 //! returns a Query for matching implicit hydrogen count
297 template <class T>
298 T *makeAtomImplicitHCountQuery(int what, const std::string &descr) {
299  return makeAtomSimpleQuery<T>(what, queryAtomImplicitHCount, descr);
300 }
301 //! \overload
302 ATOM_EQUALS_QUERY *makeAtomImplicitHCountQuery(int what);
303 
304 //! returns a Query for matching the \c isAromatic flag
305 template <class T>
306 T *makeAtomAromaticQuery(const std::string &descr) {
307  return makeAtomSimpleQuery<T>(true, queryAtomAromatic, descr);
308 }
309 //! \overload
310 ATOM_EQUALS_QUERY *makeAtomAromaticQuery();
311 
312 //! returns a Query for matching aliphatic atoms
313 template <class T>
314 T *makeAtomAliphaticQuery(const std::string &descr) {
315  return makeAtomSimpleQuery<T>(true, queryAtomAliphatic, descr);
316 }
317 //! \overload
318 ATOM_EQUALS_QUERY *makeAtomAliphaticQuery();
319 
320 //! returns a Query for matching atoms with a particular mass
321 template <class T>
322 T *makeAtomMassQuery(int what, const std::string &descr) {
323  return makeAtomSimpleQuery<T>(massIntegerConversionFactor * what,
324  queryAtomMass, descr);
325 }
326 //! \overload
327 ATOM_EQUALS_QUERY *makeAtomMassQuery(int what);
328 
329 //! returns a Query for matching atoms with a particular isotope
330 template <class T>
331 T *makeAtomIsotopeQuery(int what, const std::string &descr) {
332  return makeAtomSimpleQuery<T>(what, queryAtomIsotope, descr);
333 }
334 //! \overload
335 ATOM_EQUALS_QUERY *makeAtomIsotopeQuery(int what);
336 
337 //! returns a Query for matching formal charge
338 template <class T>
339 T *makeAtomFormalChargeQuery(int what, const std::string &descr) {
340  return makeAtomSimpleQuery<T>(what, queryAtomFormalCharge, descr);
341 }
342 //! \overload
343 ATOM_EQUALS_QUERY *makeAtomFormalChargeQuery(int what);
344 
345 //! returns a Query for matching hybridization
346 template <class T>
347 T *makeAtomHybridizationQuery(int what, const std::string &descr) {
348  return makeAtomSimpleQuery<T>(what, queryAtomHybridization, descr);
349 }
350 //! \overload
351 ATOM_EQUALS_QUERY *makeAtomHybridizationQuery(int what);
352 
353 //! returns a Query for matching the number of radical electrons
354 template <class T>
355 T *makeAtomNumRadicalElectronsQuery(int what, const std::string &descr) {
356  return makeAtomSimpleQuery<T>(what, queryAtomNumRadicalElectrons, descr);
357 }
358 //! \overload
359 ATOM_EQUALS_QUERY *makeAtomNumRadicalElectronsQuery(int what);
360 
361 //! returns a Query for matching whether or not chirality has been set on the
362 //! atom
363 template <class T>
364 T *makeAtomHasChiralTagQuery(const std::string &descr) {
365  return makeAtomSimpleQuery<T>(true, queryAtomHasChiralTag, descr);
366 }
367 //! \overloadquery
368 ATOM_EQUALS_QUERY *makeAtomHasChiralTagQuery();
369 
370 //! returns a Query for matching whether or not a potentially chiral atom is
371 //! missing a chiral tag
372 template <class T>
373 T *makeAtomMissingChiralTagQuery(const std::string &descr) {
374  return makeAtomSimpleQuery<T>(true, queryAtomMissingChiralTag, descr);
375 }
376 //! \overloadquery
377 ATOM_EQUALS_QUERY *makeAtomMissingChiralTagQuery();
378 
379 //! returns a Query for matching atoms with unsaturation:
380 template <class T>
381 T *makeAtomUnsaturatedQuery(const std::string &descr) {
382  return makeAtomSimpleQuery<T>(true, queryAtomUnsaturated, descr);
383 }
384 //! \overload
385 ATOM_EQUALS_QUERY *makeAtomUnsaturatedQuery();
386 
387 //! returns a Query for matching ring atoms
388 template <class T>
389 T *makeAtomInRingQuery(const std::string &descr) {
390  return makeAtomSimpleQuery<T>(true, queryIsAtomInRing, descr);
391 }
392 //! \overload
393 ATOM_EQUALS_QUERY *makeAtomInRingQuery();
394 
395 //! returns a Query for matching atoms in a particular number of rings
396 template <class T>
397 T *makeAtomInNRingsQuery(int what, const std::string &descr) {
398  return makeAtomSimpleQuery<T>(what, queryIsAtomInNRings, descr);
399 }
400 //! \overload
401 ATOM_EQUALS_QUERY *makeAtomInNRingsQuery(int what);
402 
403 //! returns a Query for matching atoms in rings of a particular size
404 ATOM_EQUALS_QUERY *makeAtomInRingOfSizeQuery(int tgt);
405 
406 //! returns a Query for matching an atom's minimum ring size
407 template <class T>
408 T *makeAtomMinRingSizeQuery(int tgt, const std::string &descr) {
409  return makeAtomSimpleQuery<T>(tgt, queryAtomMinRingSize, descr);
410 }
411 //! \overload
412 ATOM_EQUALS_QUERY *makeAtomMinRingSizeQuery(int tgt);
413 
414 //! returns a Query for matching atoms with a particular number of ring bonds
415 template <class T>
416 T *makeAtomRingBondCountQuery(int what, const std::string &descr) {
417  return makeAtomSimpleQuery<T>(what, queryAtomRingBondCount, descr);
418 }
419 //! \overload
420 ATOM_EQUALS_QUERY *makeAtomRingBondCountQuery(int what);
421 
422 //! returns a Query for matching generic A atoms (heavy atoms)
423 ATOM_EQUALS_QUERY *makeAAtomQuery();
424 //! returns a Query for matching generic AH atoms (any atom)
425 ATOM_EQUALS_QUERY *makeAHAtomQuery();
426 //! returns a Query for matching generic Q atoms (heteroatoms)
427 ATOM_OR_QUERY *makeQAtomQuery();
428 //! returns a Query for matching generic QH atoms (heteroatom or H)
429 ATOM_EQUALS_QUERY *makeQHAtomQuery();
430 //! returns a Query for matching generic X atoms (halogens)
431 ATOM_OR_QUERY *makeXAtomQuery();
432 //! returns a Query for matching generic XH atoms (halogen or H)
433 ATOM_OR_QUERY *makeXHAtomQuery();
434 //! returns a Query for matching generic M atoms (metals)
435 ATOM_OR_QUERY *makeMAtomQuery();
436 //! returns a Query for matching generic MH atoms (metals or H)
437 ATOM_OR_QUERY *makeMHAtomQuery();
438 
439 //! returns a Query for matching atoms that have ring bonds
440 template <class T>
441 T *makeAtomHasRingBondQuery(const std::string &descr) {
442  return makeAtomSimpleQuery<T>(1, queryAtomHasRingBond, descr);
443 }
444 //! \overload
445 ATOM_EQUALS_QUERY *makeAtomHasRingBondQuery();
446 
447 //! returns a Query for matching bond orders
448 BOND_EQUALS_QUERY *makeBondOrderEqualsQuery(Bond::BondType what);
449 //! returns a Query for matching bond directions
450 BOND_EQUALS_QUERY *makeBondDirEqualsQuery(Bond::BondDir what);
451 //! returns a Query for matching bonds with stereo set
452 BOND_EQUALS_QUERY *makeBondHasStereoQuery();
453 //! returns a Query for matching ring bonds
454 BOND_EQUALS_QUERY *makeBondIsInRingQuery();
455 //! returns a Query for matching bonds in rings of a particular size
456 BOND_EQUALS_QUERY *makeBondInRingOfSizeQuery(int what);
457 //! returns a Query for matching a bond's minimum ring size
458 BOND_EQUALS_QUERY *makeBondMinRingSizeQuery(int what);
459 //! returns a Query for matching bonds in a particular number of rings
460 BOND_EQUALS_QUERY *makeBondInNRingsQuery(int tgt);
461 
462 //! returns a Query for matching any bond
463 BOND_NULL_QUERY *makeBondNullQuery();
464 //! returns a Query for matching any atom
465 ATOM_NULL_QUERY *makeAtomNullQuery();
466 
467 static inline int queryAtomRingMembership(Atom const *at) {
468  return static_cast<int>(
469  at->getOwningMol().getRingInfo()->numAtomRings(at->getIdx()));
470 }
471 // I'm pretty sure that this typedef shouldn't be necessary,
472 // but VC++ generates a warning about const Atom const * in
473 // the definition of Match, then complains about an override
474 // that differs only by const/volatile (c4301), then generates
475 // incorrect code if we don't do this... so let's do it.
476 typedef Atom const *ConstAtomPtr;
477 
478 class AtomRingQuery : public Queries::EqualityQuery<int, ConstAtomPtr, true> {
479  public:
480  AtomRingQuery() : Queries::EqualityQuery<int, ConstAtomPtr, true>(-1) {
481  // default is to just do a number of rings query:
482  this->setDescription("AtomInNRings");
484  };
485  explicit AtomRingQuery(int v)
486  : Queries::EqualityQuery<int, ConstAtomPtr, true>(v) {
487  // default is to just do a number of rings query:
488  this->setDescription("AtomInNRings");
490  };
491 
492  virtual bool Match(const ConstAtomPtr what) const {
493  int v = this->TypeConvert(what, Queries::Int2Type<true>());
494  bool res;
495  if (this->d_val < 0) {
496  res = v != 0;
497  } else {
498  res = !Queries::queryCmp(v, this->d_val, this->d_tol);
499  }
500  if (this->getNegation()) {
501  res = !res;
502  }
503  return res;
504  }
505 
506  //! returns a copy of this query
508  AtomRingQuery *res = new AtomRingQuery(this->d_val);
509  res->setNegation(getNegation());
510  res->setTol(this->getTol());
511  res->d_description = this->d_description;
512  res->d_dataFunc = this->d_dataFunc;
513  return res;
514  }
515 };
516 
517 //! allows use of recursive structure queries (e.g. recursive SMARTS)
519  : public Queries::SetQuery<int, Atom const *, true> {
520  public:
522  : Queries::SetQuery<int, Atom const *, true>(), d_serialNumber(0) {
523  setDataFunc(getAtIdx);
524  setDescription("RecursiveStructure");
525  };
526  //! initialize from an ROMol pointer
527  /*!
528  <b>Notes</b>
529  - this takes over ownership of the pointer
530  */
531  RecursiveStructureQuery(ROMol const *query, unsigned int serialNumber = 0)
532  : Queries::SetQuery<int, Atom const *, true>(),
533  d_serialNumber(serialNumber) {
534  setQueryMol(query);
535  setDataFunc(getAtIdx);
536  setDescription("RecursiveStructure");
537  };
538  //! returns the index of an atom
539  static inline int getAtIdx(Atom const *at) {
540  PRECONDITION(at, "bad atom argument");
541  return at->getIdx();
542  };
543 
544  //! sets the molecule we'll use recursively
545  /*!
546  <b>Notes</b>
547  - this takes over ownership of the pointer
548  */
549  void setQueryMol(ROMol const *query) { dp_queryMol.reset(query); }
550  //! returns a pointer to our query molecule
551  ROMol const *getQueryMol() const { return dp_queryMol.get(); };
552 
553  //! returns a copy of this query
556  res->dp_queryMol.reset(new ROMol(*dp_queryMol, true));
557 
558  std::set<int>::const_iterator i;
559  for (i = d_set.begin(); i != d_set.end(); i++) {
560  res->insert(*i);
561  }
562  res->setNegation(getNegation());
564  res->d_serialNumber = d_serialNumber;
565  return res;
566  }
567  unsigned int getSerialNumber() const { return d_serialNumber; };
568 
569 #ifdef RDK_THREADSAFE_SSS
570  boost::mutex d_mutex;
571 #endif
572  private:
573  boost::shared_ptr<const ROMol> dp_queryMol;
574  unsigned int d_serialNumber;
575 };
576 
577 template <typename T>
578 int nullDataFun(T) {
579  return 1;
580 }
581 template <typename T>
582 bool nullQueryFun(T) {
583  return true;
584 }
585 
586 typedef Bond const *ConstBondPtr;
587 
588 // ! Query whether an atom has a property
589 template <class TargetPtr>
590 class HasPropQuery : public Queries::EqualityQuery<int, TargetPtr, true> {
591  std::string propname;
592 
593  public:
594  HasPropQuery() : Queries::EqualityQuery<int, TargetPtr, true>(), propname() {
595  // default is to just do a number of rings query:
596  this->setDescription("AtomHasProp");
597  this->setDataFunc(0);
598  };
599  explicit HasPropQuery(const std::string &v)
600  : Queries::EqualityQuery<int, TargetPtr, true>(), propname(v) {
601  // default is to just do a number of rings query:
602  this->setDescription("AtomHasProp");
603  this->setDataFunc(0);
604  };
605 
606  virtual bool Match(const TargetPtr what) const {
607  bool res = what->hasProp(propname);
608  if (this->getNegation()) {
609  res = !res;
610  }
611  return res;
612  }
613 
614  //! returns a copy of this query
616  HasPropQuery *res = new HasPropQuery(this->propname);
617  res->setNegation(this->getNegation());
618  res->d_description = this->d_description;
619  return res;
620  }
621 };
622 
625 
626 //! returns a Query for matching atoms that have a particular property
627 template <class Target>
629  const std::string &property) {
630  return new HasPropQuery<const Target *>(property);
631 }
632 
633 // ! Query whether an atom has a property with a value
634 template <class TargetPtr, class T>
636  : public Queries::EqualityQuery<int, TargetPtr, true> {
637  std::string propname;
638  T val;
639  T tolerance;
640 
641  public:
643  : Queries::EqualityQuery<int, TargetPtr, true>(), propname(), val() {
644  // default is to just do a number of rings query:
645  this->setDescription("HasPropWithValue");
646  this->setDataFunc(0);
647  };
648  explicit HasPropWithValueQuery(const std::string &prop, const T &v,
649  const T &tol = 0.0)
650  : Queries::EqualityQuery<int, TargetPtr, true>(),
651  propname(prop),
652  val(v),
653  tolerance(tol) {
654  // default is to just do a number of rings query:
655  this->setDescription("HasPropWithValue");
656  this->setDataFunc(0);
657  };
658 
659  virtual bool Match(const TargetPtr what) const {
660  bool res = what->hasProp(propname);
661  if (res) {
662  try {
663  T atom_val = what->template getProp<T>(propname);
664  res = Queries::queryCmp(atom_val, this->val, this->tolerance) == 0;
665  } catch (KeyErrorException e) {
666  res = false;
667  } catch (boost::bad_any_cast) {
668  res = false;
669  }
670 #ifdef __GNUC__
671 #if (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 2))
672  catch (...) {
673  // catch all -- this is currently necessary to
674  // trap some bugs in boost+gcc configurations
675  // Normally, this is not the correct thing to
676  // do, but the only exception above is due
677  // to the boost any_cast which is trapped
678  // by the Boost python wrapper when it shouldn't
679  // be.
680  res = false;
681  }
682 #endif
683 #endif
684  }
685  if (this->getNegation()) {
686  res = !res;
687  }
688  return res;
689  }
690 
691  //! returns a copy of this query
693  HasPropWithValueQuery *res =
694  new HasPropWithValueQuery(this->propname, this->val, this->tolerance);
695  res->setNegation(this->getNegation());
696  res->d_description = this->d_description;
697  return res;
698  }
699 };
700 
701 template <class TargetPtr>
702 class HasPropWithValueQuery<TargetPtr, std::string>
703  : public Queries::EqualityQuery<int, TargetPtr, true> {
704  std::string propname;
705  std::string val;
706 
707  public:
709  : Queries::EqualityQuery<int, TargetPtr, true>(), propname(), val() {
710  // default is to just do a number of rings query:
711  this->setDescription("HasPropWithValue");
712  this->setDataFunc(0);
713  };
714  explicit HasPropWithValueQuery(const std::string &prop, const std::string &v,
715  const std::string &tol = "")
716  : Queries::EqualityQuery<int, TargetPtr, true>(), propname(prop), val(v) {
717  RDUNUSED_PARAM(tol);
718  // default is to just do a number of rings query:
719  this->setDescription("HasPropWithValue");
720  this->setDataFunc(0);
721  };
722 
723  virtual bool Match(const TargetPtr what) const {
724  bool res = what->hasProp(propname);
725  if (res) {
726  try {
727  std::string atom_val = what->template getProp<std::string>(propname);
728  res = atom_val == this->val;
729  } catch (KeyErrorException) {
730  res = false;
731  } catch (boost::bad_any_cast) {
732  res = false;
733  }
734 #ifdef __GNUC__
735 #if (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 2))
736  catch (...) {
737  // catch all -- this is currently necessary to
738  // trap some bugs in boost+gcc configurations
739  // Normally, this is not the correct thing to
740  // do, but the only exception above is due
741  // to the boost any_cast which is trapped
742  // by the Boost python wrapper when it shouldn't
743  // be.
744  res = false;
745  }
746 #endif
747 #endif
748  }
749  if (this->getNegation()) {
750  res = !res;
751  }
752  return res;
753  }
754 
755  //! returns a copy of this query
759  this->val);
760  res->setNegation(this->getNegation());
761  res->d_description = this->d_description;
762  return res;
763  }
764 };
765 
766 template <class Target, class T>
768  const std::string &propname, const T &val, const T &tolerance = T()) {
769  return new HasPropWithValueQuery<const Target *, T>(propname, val, tolerance);
770 }
771 
772 bool isComplexQuery(const Bond *b);
773 bool isComplexQuery(const Atom *a);
774 bool isAtomAromatic(const Atom *a);
775 };
776 
777 #endif
HasPropQuery(const std::string &v)
Definition: QueryOps.h:599
Queries::XOrQuery< int, Atom const *, true > ATOM_XOR_QUERY
Definition: QueryOps.h:38
T * makeAtomTotalValenceQuery(int what, const std::string &descr)
returns a Query for matching total valence
Definition: QueryOps.h:250
T * makeAtomInRingQuery(const std::string &descr)
returns a Query for matching ring atoms
Definition: QueryOps.h:389
ATOM_OR_QUERY * makeMHAtomQuery()
returns a Query for matching generic MH atoms (metals or H)
static int queryAtomTotalDegree(Atom const *at)
Definition: QueryOps.h:79
ATOM_EQUALS_QUERY * makeQHAtomQuery()
returns a Query for matching generic QH atoms (heteroatom or H)
static int queryAtomMissingChiralTag(Atom const *at)
Definition: QueryOps.h:126
int queryCmp(const T1 v1, const T2 v2, const T1 tol)
Definition: Query.h:177
BondStereo getStereo() const
returns our stereo code
Definition: Bond.h:298
T * makeAtomHybridizationQuery(int what, const std::string &descr)
returns a Query for matching hybridization
Definition: QueryOps.h:347
static int queryAtomHybridization(Atom const *at)
Definition: QueryOps.h:117
T * makeAtomMassQuery(int what, const std::string &descr)
returns a Query for matching atoms with a particular mass
Definition: QueryOps.h:322
unsigned int numBondRings(unsigned int idx) const
returns the number of rings bond idx is involved in
Queries::OrQuery< int, Bond const *, true > BOND_OR_QUERY
Definition: QueryOps.h:36
double round(double v)
rounds a value to the closest int
ROMol & getOwningMol() const
returns a reference to the ROMol that owns this Bond
Definition: Bond.h:149
Queries::LessQuery< int, Atom const *, true > ATOM_LESS_QUERY
Definition: QueryOps.h:52
void setNegation(bool what)
sets whether or not we are negated
Definition: Query.h:61
Queries::Query< int, Atom const *, true > ATOM_NULL_QUERY
Definition: QueryOps.h:65
ATOM_NULL_QUERY * makeAtomNullQuery()
returns a Query for matching any atom
a Query implementing AND: requires all children to be true
Definition: AndQuery.h:20
T * makeAtomImplicitValenceQuery(int what, const std::string &descr)
returns a Query for matching implicit valence
Definition: QueryOps.h:234
void setTol(MatchFuncArgType what)
sets our tolerance
Definition: EqualityQuery.h:43
Atom const * ConstAtomPtr
Definition: QueryOps.h:476
BOND_EQUALS_QUERY * makeBondOrderEqualsQuery(Bond::BondType what)
returns a Query for matching bond orders
Queries::EqualityQuery< int, Bond const *, true > BOND_PROP_QUERY
Definition: QueryOps.h:624
int getImplicitValence() const
returns the implicit valence for this Atom
a Query implementing AND: requires any child to be true
Definition: OrQuery.h:19
HybridizationType getHybridization() const
returns our hybridization
Definition: Atom.h:243
unsigned int getTotalNumHs(bool includeNeighbors=false) const
returns the total number of Hs (implicit and explicit) that this Atom is bound to ...
unsigned int queryAtomAllBondProduct(Atom const *at)
T * makeAtomMinRingSizeQuery(int tgt, const std::string &descr)
returns a Query for matching an atom&#39;s minimum ring size
Definition: QueryOps.h:408
STL namespace.
Queries::Query< int, Bond const *, true > BOND_NULL_QUERY
Definition: QueryOps.h:64
static int queryAtomExplicitDegree(Atom const *at)
Definition: QueryOps.h:76
bool getIsAromatic() const
returns our isAromatic flag
Definition: Atom.h:221
Queries::GreaterQuery< int, Bond const *, true > BOND_GREATER_QUERY
Definition: QueryOps.h:45
static int queryBondOrder(Bond const *bond)
Definition: QueryOps.h:137
bool getNegation() const
returns whether or not we are negated
Definition: Query.h:63
static int queryAtomImplicitHCount(Atom const *at)
Definition: QueryOps.h:88
unsigned int minBondRingSize(unsigned int idx) const
returns the size of the smallest ring bond idx is involved in
unsigned int getNumRadicalElectrons() const
returns the number of radical electrons for this Atom
Definition: Atom.h:197
Queries::Query< bool, Bond const *, true > BOND_BOOL_QUERY
Definition: QueryOps.h:30
static int getAtIdx(Atom const *at)
returns the index of an atom
Definition: QueryOps.h:539
Queries::SetQuery< int, Bond const *, true > BOND_SET_QUERY
Definition: QueryOps.h:62
T * makeAtomImplicitHCountQuery(int what, const std::string &descr)
returns a Query for matching implicit hydrogen count
Definition: QueryOps.h:298
static int queryAtomMass(Atom const *at)
Definition: QueryOps.h:108
Queries::EqualityQuery< int, const Target *, true > * makePropQuery(const std::string &propname, const T &val, const T &tolerance=T())
Definition: QueryOps.h:767
T * makeAtomHasChiralTagQuery(const std::string &descr)
Definition: QueryOps.h:364
BondType
the type of Bond
Definition: Bond.h:57
bool nullQueryFun(T)
Definition: QueryOps.h:582
pulls in the core RDKit functionality
Queries::GreaterEqualQuery< int, Atom const *, true > ATOM_GREATEREQUAL_QUERY
Definition: QueryOps.h:48
static int queryBondHasStereo(Bond const *bnd)
Definition: QueryOps.h:146
static int queryIsBondInRing(Bond const *bond)
Definition: QueryOps.h:171
ROMol is a molecule class that is intended to have a fixed topology.
Definition: ROMol.h:103
Queries::GreaterEqualQuery< int, Bond const *, true > BOND_GREATEREQUAL_QUERY
Definition: QueryOps.h:50
Queries::Query< int, TargetPtr, true > * copy() const
returns a copy of this query
Definition: QueryOps.h:615
BondDir getBondDir() const
returns our direction
Definition: Bond.h:277
double getMass() const
returns our mass
int getExplicitValence() const
returns the explicit valence (including Hs) of this atom
virtual bool Match(const TargetPtr what) const
returns whether or not we match the argument
Definition: QueryOps.h:659
T * makeAtomExplicitDegreeQuery(int what, const std::string &descr)
returns a Query for matching explicit degree
Definition: QueryOps.h:258
Queries::LessEqualQuery< int, Atom const *, true > ATOM_LESSEQUAL_QUERY
Definition: QueryOps.h:55
static int queryAtomHasChiralTag(Atom const *at)
Definition: QueryOps.h:123
static int queryBondDir(Bond const *bond)
Definition: QueryOps.h:140
RingInfo * getRingInfo() const
Definition: ROMol.h:377
unsigned int getIsotope() const
returns our isotope number
Definition: Atom.h:229
ATOM_OR_QUERY * makeXHAtomQuery()
returns a Query for matching generic XH atoms (halogen or H)
static int queryAtomUnsaturated(Atom const *at)
Definition: QueryOps.h:103
Queries::LessEqualQuery< int, Bond const *, true > BOND_LESSEQUAL_QUERY
Definition: QueryOps.h:56
a Query implementing a range: arguments must fall in a particular range of values.
Definition: RangeQuery.h:26
int queryAtomIsInRingOfSize(Atom const *at)
Definition: QueryOps.h:197
ATOM_OR_QUERY * makeMAtomQuery()
returns a Query for matching generic M atoms (metals)
bool isComplexQuery(const Bond *b)
T * makeAtomIsotopeQuery(int what, const std::string &descr)
returns a Query for matching atoms with a particular isotope
Definition: QueryOps.h:331
T * makeAtomAliphaticQuery(const std::string &descr)
returns a Query for matching aliphatic atoms
Definition: QueryOps.h:314
BOND_EQUALS_QUERY * makeBondInNRingsQuery(int tgt)
returns a Query for matching bonds in a particular number of rings
const int massIntegerConversionFactor
Definition: QueryOps.h:107
T * makeAtomUnsaturatedQuery(const std::string &descr)
returns a Query for matching atoms with unsaturation:
Definition: QueryOps.h:381
T * makeAtomMissingChiralTagQuery(const std::string &descr)
Definition: QueryOps.h:373
class to allow integer values to pick templates
Definition: Query.h:26
static int queryAtomIsotope(Atom const *at)
Definition: QueryOps.h:111
unsigned int getSerialNumber() const
Definition: QueryOps.h:567
Queries::LessQuery< int, Bond const *, true > BOND_LESS_QUERY
Definition: QueryOps.h:53
virtual bool Match(const TargetPtr what) const
returns whether or not we match the argument
Definition: QueryOps.h:606
Queries::Query< int, TargetPtr, true > * copy() const
returns a copy of this query
Definition: QueryOps.h:692
BOND_NULL_QUERY * makeBondNullQuery()
returns a Query for matching any bond
allows use of recursive structure queries (e.g. recursive SMARTS)
Definition: QueryOps.h:518
bool isAtomAromatic(const Atom *a)
Bond const * ConstBondPtr
Definition: QueryOps.h:586
static int queryAtomExplicitValence(Atom const *at)
Definition: QueryOps.h:97
static int queryIsAtomInRing(Atom const *at)
Definition: QueryOps.h:156
int getFormalCharge() const
returns the formal charge of this atom
Definition: Atom.h:203
a Query implementing <= using a particular value (and an optional tolerance)
Queries::Query< bool, Atom const *, true > ATOM_BOOL_QUERY
Definition: QueryOps.h:29
unsigned int getIdx() const
returns our index within the ROMol
Definition: Atom.h:130
HasPropWithValueQuery(const std::string &prop, const std::string &v, const std::string &tol="")
Definition: QueryOps.h:714
static int queryAtomAromatic(Atom const *at)
Definition: QueryOps.h:70
Std stuff.
Definition: Atom.h:29
static int queryBondMinRingSize(Bond const *bond)
Definition: QueryOps.h:177
static int queryAtomNum(Atom const *at)
Definition: QueryOps.h:106
Queries::EqualityQuery< int, Bond const *, true > BOND_EQUALS_QUERY
Definition: QueryOps.h:42
ATOM_EQUALS_QUERY * makeAHAtomQuery()
returns a Query for matching generic AH atoms (any atom)
Queries::XOrQuery< int, Bond const *, true > BOND_XOR_QUERY
Definition: QueryOps.h:39
MatchFuncArgType(* d_dataFunc)(DataFuncArgType)
Definition: Query.h:146
ATOM_OR_QUERY * makeXAtomQuery()
returns a Query for matching generic X atoms (halogens)
int getAtomicNum() const
returns our atomic number
Definition: Atom.h:116
bool hasProp(const std::string &key) const
Definition: RDProps.h:116
T * makeAtomRingBondCountQuery(int what, const std::string &descr)
returns a Query for matching atoms with a particular number of ring bonds
Definition: QueryOps.h:416
T * makeAtomAromaticQuery(const std::string &descr)
returns a Query for matching the isAromatic flag
Definition: QueryOps.h:306
static int queryAtomFormalCharge(Atom const *at)
Definition: QueryOps.h:114
a Query implementing < using a particular value (and an optional tolerance)
Definition: LessQuery.h:20
a Query implementing ==: arguments must match a particular value (within an optional tolerance) ...
Definition: EqualityQuery.h:22
T * makeAtomNumQuery(int what, const std::string &descr)
returns a Query for matching atomic number
Definition: QueryOps.h:226
OBOND_ITER_PAIR getAtomBonds(Atom const *at) const
provides access to all Bond objects connected to an Atom
Queries::Query< int, TargetPtr, true > * copy() const
returns a copy of this query
Definition: QueryOps.h:756
T * makeAtomFormalChargeQuery(int what, const std::string &descr)
returns a Query for matching formal charge
Definition: QueryOps.h:339
class for representing a bond
Definition: Bond.h:47
#define RDUNUSED_PARAM(x)
Definition: Invariant.h:194
static int queryAtomHeavyAtomDegree(Atom const *at)
Definition: QueryOps.h:82
T * makeAtomExplicitValenceQuery(int what, const std::string &descr)
returns a Query for matching explicit valence
Definition: QueryOps.h:242
void insert(const MatchFuncArgType what)
insert an entry into our set
Definition: SetQuery.h:32
void setDataFunc(int(*what)(ConstAtomPtr))
sets our data function
Definition: Query.h:90
unsigned int getNumExplicitHs() const
returns our number of explict Hs
Definition: Atom.h:216
Queries::AndQuery< int, Bond const *, true > BOND_AND_QUERY
Definition: QueryOps.h:33
BondDir
the bond&#39;s direction (for chirality)
Definition: Bond.h:84
static int queryIsAtomInNRings(Atom const *at)
Definition: QueryOps.h:153
MolGraph const & getTopology() const
brief returns a pointer to our underlying BGL object
Definition: ROMol.h:484
void setQueryMol(ROMol const *query)
sets the molecule we&#39;ll use recursively
Definition: QueryOps.h:549
BOND_EQUALS_QUERY * makeBondHasStereoQuery()
returns a Query for matching bonds with stereo set
Queries::Query< int, ConstAtomPtr, true > * copy() const
returns a copy of this query
Definition: QueryOps.h:507
const int getTol() const
returns out tolerance
Definition: EqualityQuery.h:45
RecursiveStructureQuery(ROMol const *query, unsigned int serialNumber=0)
initialize from an ROMol pointer
Definition: QueryOps.h:531
ROMol const * getQueryMol() const
returns a pointer to our query molecule
Definition: QueryOps.h:551
static int queryAtomHasImplicitH(Atom const *at)
Definition: QueryOps.h:91
#define PRECONDITION(expr, mess)
Definition: Invariant.h:107
static int queryAtomMinRingSize(Atom const *at)
Definition: QueryOps.h:174
Queries::Query< int, Atom const *, true > * copy() const
returns a copy of this query
Definition: QueryOps.h:554
unsigned int getDegree() const
ROMol & getOwningMol() const
returns a reference to the ROMol that owns this Atom
Definition: Atom.h:124
Queries::AndQuery< int, Atom const *, true > ATOM_AND_QUERY
Definition: QueryOps.h:32
static int queryAtomNumRadicalElectrons(Atom const *at)
Definition: QueryOps.h:120
bool isAtomInRingOfSize(unsigned int idx, unsigned int size) const
returns whether or not the atom with index idx is in a size - ring.
T * makeAtomHasRingBondQuery(const std::string &descr)
returns a Query for matching atoms that have ring bonds
Definition: QueryOps.h:441
Queries::EqualityQuery< int, Atom const *, true > ATOM_EQUALS_QUERY
Definition: QueryOps.h:41
std::string d_description
Definition: Query.h:139
BondType getBondType() const
returns our bondType
Definition: Bond.h:122
T * makeAtomHasImplicitHQuery(const std::string &descr)
returns a Query for matching ring atoms
Definition: QueryOps.h:290
T * makeAtomInNRingsQuery(int what, const std::string &descr)
returns a Query for matching atoms in a particular number of rings
Definition: QueryOps.h:397
static int queryAtomAliphatic(Atom const *at)
Definition: QueryOps.h:73
Queries::RangeQuery< int, Atom const *, true > ATOM_RANGE_QUERY
Definition: QueryOps.h:58
HasPropWithValueQuery(const std::string &prop, const T &v, const T &tol=0.0)
Definition: QueryOps.h:648
T * makeAtomHeavyAtomDegreeQuery(int what, const std::string &descr)
returns a Query for matching heavy atom degree
Definition: QueryOps.h:274
a Query implementing > using a particular value (and an optional tolerance)
Definition: GreaterQuery.h:20
BOND_EQUALS_QUERY * makeBondMinRingSizeQuery(int what)
returns a Query for matching a bond&#39;s minimum ring size
ATOM_EQUALS_QUERY * makeAtomInRingOfSizeQuery(int tgt)
returns a Query for matching atoms in rings of a particular size
const std::string _ChiralityPossible
static int queryAtomRingBondCount(Atom const *at)
Definition: QueryOps.h:181
a Query implementing >= using a particular value (and an optional tolerance)
Pulls in all the query types.
int TypeConvert(int what, Int2Type< false >) const
calls our dataFunc (if it&#39;s set) on what and returns the result, otherwise returns what ...
Definition: Query.h:150
T * makeAtomNumRadicalElectronsQuery(int what, const std::string &descr)
returns a Query for matching the number of radical electrons
Definition: QueryOps.h:355
ChiralType getChiralTag() const
returns our chiralTag
Definition: Atom.h:236
Queries::GreaterQuery< int, Atom const *, true > ATOM_GREATER_QUERY
Definition: QueryOps.h:44
chirality that hasn&#39;t been specified
Definition: Atom.h:93
BOND_EQUALS_QUERY * makeBondDirEqualsQuery(Bond::BondDir what)
returns a Query for matching bond directions
Queries::OrQuery< int, Atom const *, true > ATOM_OR_QUERY
Definition: QueryOps.h:35
unsigned int getTotalDegree() const
T * makeAtomSimpleQuery(int what, int func(Atom const *), const std::string &description="Atom Simple")
Definition: QueryOps.h:215
unsigned int numAtomRings(unsigned int idx) const
returns the number of rings atom idx is involved in
int queryBondIsInRingOfSize(Bond const *bond)
Definition: QueryOps.h:205
int nullDataFun(T)
Definition: QueryOps.h:578
static int queryAtomHasRingBond(Atom const *at)
Definition: QueryOps.h:159
BOND_EQUALS_QUERY * makeBondInRingOfSizeQuery(int what)
returns a Query for matching bonds in rings of a particular size
virtual bool Match(const ConstAtomPtr what) const
Definition: QueryOps.h:492
bool isBondInRingOfSize(unsigned int idx, unsigned int size) const
returns whether or not the bond with index idx is in a size - ring.
static int queryAtomRingMembership(Atom const *at)
Definition: QueryOps.h:467
Queries::EqualityQuery< int, Atom const *, true > ATOM_PROP_QUERY
Definition: QueryOps.h:623
unsigned int minAtomRingSize(unsigned int idx) const
returns the size of the smallest ring atom idx is involved in
Base class for all queries.
Definition: Query.h:45
static int queryAtomHCount(Atom const *at)
Definition: QueryOps.h:85
Queries::RangeQuery< int, Bond const *, true > BOND_RANGE_QUERY
Definition: QueryOps.h:59
unsigned int queryAtomBondProduct(Atom const *at)
static int queryAtomTotalValence(Atom const *at)
Definition: QueryOps.h:100
unsigned int getIdx() const
returns our index within the ROMol
Definition: Bond.h:164
BOND_EQUALS_QUERY * makeBondIsInRingQuery()
returns a Query for matching ring bonds
virtual bool Match(const TargetPtr what) const
returns whether or not we match the argument
Definition: QueryOps.h:723
The class for representing atoms.
Definition: Atom.h:68
a Query implementing XOR: requires exactly one child to be true
Definition: XOrQuery.h:20
void setDescription(const std::string &descr)
sets our text description
Definition: Query.h:66
Queries::EqualityQuery< int, const Target *, true > * makeHasPropQuery(const std::string &property)
returns a Query for matching atoms that have a particular property
Definition: QueryOps.h:628
ATOM_EQUALS_QUERY * makeAAtomQuery()
returns a Query for matching generic A atoms (heavy atoms)
static int queryAtomImplicitValence(Atom const *at)
Definition: QueryOps.h:94
Class to allow us to throw a KeyError from C++ and have it make it back to Python.
Definition: Exceptions.h:48
T * makeAtomHCountQuery(int what, const std::string &descr)
returns a Query for matching hydrogen count
Definition: QueryOps.h:282
T * makeAtomTotalDegreeQuery(int what, const std::string &descr)
returns a Query for matching atomic degree
Definition: QueryOps.h:266
Queries::SetQuery< int, Atom const *, true > ATOM_SET_QUERY
Definition: QueryOps.h:61
ATOM_OR_QUERY * makeQAtomQuery()
returns a Query for matching generic Q atoms (heteroatoms)
static int queryIsBondInNRings(Bond const *at)
Definition: QueryOps.h:143