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
ROMol & getOwningMol() const
returns a reference to the ROMol that owns this Atom
Definition: Atom.h:124
HasPropQuery(const std::string &v)
Definition: QueryOps.h:599
bool getNegation() const
returns whether or not we are negated
Definition: Query.h:63
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
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
Queries::OrQuery< int, Bond const *, true > BOND_OR_QUERY
Definition: QueryOps.h:36
double round(double v)
rounds a value to the closest int
Queries::LessQuery< int, Atom const *, true > ATOM_LESS_QUERY
Definition: QueryOps.h:52
bool isBondInRingOfSize(unsigned int idx, unsigned int size) const
returns whether or not the bond with index idx is in a size - ring.
Queries::Query< int, ConstAtomPtr, true > * copy() const
returns a copy of this query
Definition: QueryOps.h:507
void setNegation(bool what)
sets whether or not we are negated
Definition: Query.h:61
virtual bool Match(const TargetPtr what) const
returns whether or not we match the argument
Definition: QueryOps.h:723
Queries::Query< int, Atom const *, true > ATOM_NULL_QUERY
Definition: QueryOps.h:65
ATOM_NULL_QUERY * makeAtomNullQuery()
returns a Query for matching any atom
ROMol const * getQueryMol() const
returns a pointer to our query molecule
Definition: QueryOps.h:551
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
unsigned int getTotalNumHs(bool includeNeighbors=false) const
returns the total number of Hs (implicit and explicit) that this Atom is bound to ...
Queries::EqualityQuery< int, Bond const *, true > BOND_PROP_QUERY
Definition: QueryOps.h:624
a Query implementing AND: requires any child to be true
Definition: OrQuery.h:19
unsigned int getNumRadicalElectrons() const
returns the number of radical electrons for this Atom
Definition: Atom.h:197
unsigned int getIsotope() const
returns our isotope number
Definition: Atom.h:229
BondDir getBondDir() const
returns our direction
Definition: Bond.h:277
double getMass() const
returns our mass
unsigned int queryAtomAllBondProduct(Atom const *at)
BondStereo getStereo() const
returns our stereo code
Definition: Bond.h:298
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
Queries::GreaterQuery< int, Bond const *, true > BOND_GREATER_QUERY
Definition: QueryOps.h:45
static int queryBondOrder(Bond const *bond)
Definition: QueryOps.h:137
int TypeConvert(intwhat, Int2Type< false >) const
calls our dataFunc (if it&#39;s set) on what and returns the result, otherwise returns what ...
Definition: Query.h:150
static int queryAtomImplicitHCount(Atom const *at)
Definition: QueryOps.h:88
unsigned int getIdx() const
returns our index within the ROMol
Definition: Atom.h:130
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
Queries::Query< int, TargetPtr, true > * copy() const
returns a copy of this query
Definition: QueryOps.h:756
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
unsigned int minAtomRingSize(unsigned int idx) const
returns the size of the smallest ring atom idx is involved in
virtual bool Match(const ConstAtomPtr what) const
Definition: QueryOps.h:492
unsigned int getDegree() const
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
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
virtual bool Match(const TargetPtr what) const
returns whether or not we match the argument
Definition: QueryOps.h:659
Queries::LessEqualQuery< int, Bond const *, true > BOND_LESSEQUAL_QUERY
Definition: QueryOps.h:56
virtual bool Match(const TargetPtr what) const
returns whether or not we match the argument
Definition: QueryOps.h:606
a Query implementing a range: arguments must fall in a particular range of values.
Definition: RangeQuery.h:26
unsigned int getTotalDegree() const
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
int getAtomicNum() const
returns our atomic number
Definition: Atom.h:116
T * makeAtomUnsaturatedQuery(const std::string &descr)
returns a Query for matching atoms with unsaturation:
Definition: QueryOps.h:381
unsigned int numAtomRings(unsigned int idx) const
returns the number of rings atom idx is involved in
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
int getExplicitValence() const
returns the explicit valence (including Hs) of this atom
Queries::LessQuery< int, Bond const *, true > BOND_LESS_QUERY
Definition: QueryOps.h:53
MolGraph const & getTopology() const
brief returns a pointer to our underlying BGL object
Definition: ROMol.h:484
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
a Query implementing <= using a particular value (and an optional tolerance)
Queries::Query< bool, Atom const *, true > ATOM_BOOL_QUERY
Definition: QueryOps.h:29
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
unsigned int getNumExplicitHs() const
returns our number of explict Hs
Definition: Atom.h:216
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)
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
ChiralType getChiralTag() const
returns our chiralTag
Definition: Atom.h:236
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
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
Queries::Query< int, TargetPtr, true > * copy() const
returns a copy of this query
Definition: QueryOps.h:692
int getImplicitValence() const
returns the implicit valence for this Atom
RingInfo * getRingInfo() const
Definition: ROMol.h:377
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
bool isAtomInRingOfSize(unsigned int idx, unsigned int size) const
returns whether or not the atom with index idx is in a size - ring.
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
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
unsigned int getSerialNumber() const
Definition: QueryOps.h:567
RecursiveStructureQuery(ROMol const *query, unsigned int serialNumber=0)
initialize from an ROMol pointer
Definition: QueryOps.h:531
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
unsigned int numBondRings(unsigned int idx) const
returns the number of rings bond idx is involved in
HybridizationType getHybridization() const
returns our hybridization
Definition: Atom.h:243
Queries::AndQuery< int, Atom const *, true > ATOM_AND_QUERY
Definition: QueryOps.h:32
static int queryAtomNumRadicalElectrons(Atom const *at)
Definition: QueryOps.h:120
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
T * makeAtomHasImplicitHQuery(const std::string &descr)
returns a Query for matching ring atoms
Definition: QueryOps.h:290
Queries::Query< int, TargetPtr, true > * copy() const
returns a copy of this query
Definition: QueryOps.h:615
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
bool hasProp(const std::string &key) const
Definition: RDProps.h:116
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.
T * makeAtomNumRadicalElectronsQuery(int what, const std::string &descr)
returns a Query for matching the number of radical electrons
Definition: QueryOps.h:355
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
T * makeAtomSimpleQuery(int what, int func(Atom const *), const std::string &description="Atom Simple")
Definition: QueryOps.h:215
int getFormalCharge() const
returns the formal charge of this atom
Definition: Atom.h:203
int queryBondIsInRingOfSize(Bond const *bond)
Definition: QueryOps.h:205
unsigned int getIdx() const
returns our index within the ROMol
Definition: Bond.h:164
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
OBOND_ITER_PAIR getAtomBonds(Atom const *at) const
provides access to all Bond objects connected to an Atom
ROMol & getOwningMol() const
returns a reference to the ROMol that owns this Bond
Definition: Bond.h:149
static int queryAtomRingMembership(Atom const *at)
Definition: QueryOps.h:467
Queries::EqualityQuery< int, Atom const *, true > ATOM_PROP_QUERY
Definition: QueryOps.h:623
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
BOND_EQUALS_QUERY * makeBondIsInRingQuery()
returns a Query for matching ring bonds
unsigned int minBondRingSize(unsigned int idx) const
returns the size of the smallest ring bond idx is involved in
The class for representing atoms.
Definition: Atom.h:68
BondType getBondType() const
returns our bondType
Definition: Bond.h:122
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
bool getIsAromatic() const
returns our isAromatic flag
Definition: Atom.h:221
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
Queries::Query< int, Atom const *, true > * copy() const
returns a copy of this query
Definition: QueryOps.h:554
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)
const int getTol() const
returns out tolerance
Definition: EqualityQuery.h:45
static int queryIsBondInNRings(Bond const *at)
Definition: QueryOps.h:143