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 hydrogen count
273 template <class T>
274 T *makeAtomHCountQuery(int what, const std::string &descr) {
275  return makeAtomSimpleQuery<T>(what, queryAtomHCount, descr);
276 }
277 //! \overload
278 ATOM_EQUALS_QUERY *makeAtomHCountQuery(int what);
279 
280 //! returns a Query for matching ring atoms
281 template <class T>
282 T *makeAtomHasImplicitHQuery(const std::string &descr) {
283  return makeAtomSimpleQuery<T>(true, queryAtomHasImplicitH, descr);
284 }
285 //! \overload
286 ATOM_EQUALS_QUERY *makeAtomHasImplicitHQuery();
287 
288 //! returns a Query for matching implicit hydrogen count
289 template <class T>
290 T *makeAtomImplicitHCountQuery(int what, const std::string &descr) {
291  return makeAtomSimpleQuery<T>(what, queryAtomImplicitHCount, descr);
292 }
293 //! \overload
294 ATOM_EQUALS_QUERY *makeAtomImplicitHCountQuery(int what);
295 
296 //! returns a Query for matching the \c isAromatic flag
297 template <class T>
298 T *makeAtomAromaticQuery(const std::string &descr) {
299  return makeAtomSimpleQuery<T>(true, queryAtomAromatic, descr);
300 }
301 //! \overload
302 ATOM_EQUALS_QUERY *makeAtomAromaticQuery();
303 
304 //! returns a Query for matching aliphatic atoms
305 template <class T>
306 T *makeAtomAliphaticQuery(const std::string &descr) {
307  return makeAtomSimpleQuery<T>(true, queryAtomAliphatic, descr);
308 }
309 //! \overload
310 ATOM_EQUALS_QUERY *makeAtomAliphaticQuery();
311 
312 //! returns a Query for matching atoms with a particular mass
313 template <class T>
314 T *makeAtomMassQuery(int what, const std::string &descr) {
315  return makeAtomSimpleQuery<T>(massIntegerConversionFactor * what,
316  queryAtomMass, descr);
317 }
318 //! \overload
319 ATOM_EQUALS_QUERY *makeAtomMassQuery(int what);
320 
321 //! returns a Query for matching atoms with a particular isotope
322 template <class T>
323 T *makeAtomIsotopeQuery(int what, const std::string &descr) {
324  return makeAtomSimpleQuery<T>(what, queryAtomIsotope, descr);
325 }
326 //! \overload
327 ATOM_EQUALS_QUERY *makeAtomIsotopeQuery(int what);
328 
329 //! returns a Query for matching formal charge
330 template <class T>
331 T *makeAtomFormalChargeQuery(int what, const std::string &descr) {
332  return makeAtomSimpleQuery<T>(what, queryAtomFormalCharge, descr);
333 }
334 //! \overload
335 ATOM_EQUALS_QUERY *makeAtomFormalChargeQuery(int what);
336 
337 //! returns a Query for matching hybridization
338 template <class T>
339 T *makeAtomHybridizationQuery(int what, const std::string &descr) {
340  return makeAtomSimpleQuery<T>(what, queryAtomHybridization, descr);
341 }
342 //! \overload
343 ATOM_EQUALS_QUERY *makeAtomHybridizationQuery(int what);
344 
345 //! returns a Query for matching the number of radical electrons
346 template <class T>
347 T *makeAtomNumRadicalElectronsQuery(int what, const std::string &descr) {
348  return makeAtomSimpleQuery<T>(what, queryAtomNumRadicalElectrons, descr);
349 }
350 //! \overload
351 ATOM_EQUALS_QUERY *makeAtomNumRadicalElectronsQuery(int what);
352 
353 //! returns a Query for matching whether or not chirality has been set on the
354 //! atom
355 template <class T>
356 T *makeAtomHasChiralTagQuery(const std::string &descr) {
357  return makeAtomSimpleQuery<T>(true, queryAtomHasChiralTag, descr);
358 }
359 //! \overloadquery
360 ATOM_EQUALS_QUERY *makeAtomHasChiralTagQuery();
361 
362 //! returns a Query for matching whether or not a potentially chiral atom is
363 //! missing a chiral tag
364 template <class T>
365 T *makeAtomMissingChiralTagQuery(const std::string &descr) {
366  return makeAtomSimpleQuery<T>(true, queryAtomMissingChiralTag, descr);
367 }
368 //! \overloadquery
369 ATOM_EQUALS_QUERY *makeAtomMissingChiralTagQuery();
370 
371 //! returns a Query for matching atoms with unsaturation:
372 template <class T>
373 T *makeAtomUnsaturatedQuery(const std::string &descr) {
374  return makeAtomSimpleQuery<T>(true, queryAtomUnsaturated, descr);
375 }
376 //! \overload
377 ATOM_EQUALS_QUERY *makeAtomUnsaturatedQuery();
378 
379 //! returns a Query for matching ring atoms
380 template <class T>
381 T *makeAtomInRingQuery(const std::string &descr) {
382  return makeAtomSimpleQuery<T>(true, queryIsAtomInRing, descr);
383 }
384 //! \overload
385 ATOM_EQUALS_QUERY *makeAtomInRingQuery();
386 
387 //! returns a Query for matching atoms in a particular number of rings
388 template <class T>
389 T *makeAtomInNRingsQuery(int what, const std::string &descr) {
390  return makeAtomSimpleQuery<T>(what, queryIsAtomInNRings, descr);
391 }
392 //! \overload
393 ATOM_EQUALS_QUERY *makeAtomInNRingsQuery(int what);
394 
395 //! returns a Query for matching atoms in rings of a particular size
396 ATOM_EQUALS_QUERY *makeAtomInRingOfSizeQuery(int tgt);
397 
398 //! returns a Query for matching an atom's minimum ring size
399 template <class T>
400 T *makeAtomMinRingSizeQuery(int tgt, const std::string &descr) {
401  return makeAtomSimpleQuery<T>(tgt, queryAtomMinRingSize, descr);
402 }
403 //! \overload
404 ATOM_EQUALS_QUERY *makeAtomMinRingSizeQuery(int tgt);
405 
406 //! returns a Query for matching atoms with a particular number of ring bonds
407 template <class T>
408 T *makeAtomRingBondCountQuery(int what, const std::string &descr) {
409  return makeAtomSimpleQuery<T>(what, queryAtomRingBondCount, descr);
410 }
411 //! \overload
412 ATOM_EQUALS_QUERY *makeAtomRingBondCountQuery(int what);
413 
414 //! returns a Query for matching generic A atoms (heavy atoms)
415 ATOM_EQUALS_QUERY *makeAAtomQuery();
416 //! returns a Query for matching generic AH atoms (any atom)
417 ATOM_EQUALS_QUERY *makeAHAtomQuery();
418 //! returns a Query for matching generic Q atoms (heteroatoms)
419 ATOM_OR_QUERY *makeQAtomQuery();
420 //! returns a Query for matching generic QH atoms (heteroatom or H)
421 ATOM_EQUALS_QUERY *makeQHAtomQuery();
422 //! returns a Query for matching generic X atoms (halogens)
423 ATOM_OR_QUERY *makeXAtomQuery();
424 //! returns a Query for matching generic XH atoms (halogen or H)
425 ATOM_OR_QUERY *makeXHAtomQuery();
426 //! returns a Query for matching generic M atoms (metals)
427 ATOM_OR_QUERY *makeMAtomQuery();
428 //! returns a Query for matching generic MH atoms (metals or H)
429 ATOM_OR_QUERY *makeMHAtomQuery();
430 
431 //! returns a Query for matching atoms that have ring bonds
432 template <class T>
433 T *makeAtomHasRingBondQuery(const std::string &descr) {
434  return makeAtomSimpleQuery<T>(1, queryAtomHasRingBond, descr);
435 }
436 //! \overload
437 ATOM_EQUALS_QUERY *makeAtomHasRingBondQuery();
438 
439 //! returns a Query for matching bond orders
440 BOND_EQUALS_QUERY *makeBondOrderEqualsQuery(Bond::BondType what);
441 //! returns a Query for matching bond directions
442 BOND_EQUALS_QUERY *makeBondDirEqualsQuery(Bond::BondDir what);
443 //! returns a Query for matching bonds with stereo set
444 BOND_EQUALS_QUERY *makeBondHasStereoQuery();
445 //! returns a Query for matching ring bonds
446 BOND_EQUALS_QUERY *makeBondIsInRingQuery();
447 //! returns a Query for matching bonds in rings of a particular size
448 BOND_EQUALS_QUERY *makeBondInRingOfSizeQuery(int what);
449 //! returns a Query for matching a bond's minimum ring size
450 BOND_EQUALS_QUERY *makeBondMinRingSizeQuery(int what);
451 //! returns a Query for matching bonds in a particular number of rings
452 BOND_EQUALS_QUERY *makeBondInNRingsQuery(int tgt);
453 
454 //! returns a Query for matching any bond
455 BOND_NULL_QUERY *makeBondNullQuery();
456 //! returns a Query for matching any atom
457 ATOM_NULL_QUERY *makeAtomNullQuery();
458 
459 static inline int queryAtomRingMembership(Atom const *at) {
460  return static_cast<int>(
461  at->getOwningMol().getRingInfo()->numAtomRings(at->getIdx()));
462 }
463 // I'm pretty sure that this typedef shouldn't be necessary,
464 // but VC++ generates a warning about const Atom const * in
465 // the definition of Match, then complains about an override
466 // that differs only by const/volatile (c4301), then generates
467 // incorrect code if we don't do this... so let's do it.
468 typedef Atom const *ConstAtomPtr;
469 
470 class AtomRingQuery : public Queries::EqualityQuery<int, ConstAtomPtr, true> {
471  public:
472  AtomRingQuery() : Queries::EqualityQuery<int, ConstAtomPtr, true>(-1) {
473  // default is to just do a number of rings query:
474  this->setDescription("AtomInNRings");
476  };
477  explicit AtomRingQuery(int v)
478  : Queries::EqualityQuery<int, ConstAtomPtr, true>(v) {
479  // default is to just do a number of rings query:
480  this->setDescription("AtomInNRings");
482  };
483 
484  virtual bool Match(const ConstAtomPtr what) const {
485  int v = this->TypeConvert(what, Queries::Int2Type<true>());
486  bool res;
487  if (this->d_val < 0) {
488  res = v != 0;
489  } else {
490  res = !Queries::queryCmp(v, this->d_val, this->d_tol);
491  }
492  if (this->getNegation()) {
493  res = !res;
494  }
495  return res;
496  }
497 
498  //! returns a copy of this query
500  AtomRingQuery *res = new AtomRingQuery(this->d_val);
501  res->setNegation(getNegation());
502  res->setTol(this->getTol());
503  res->d_description = this->d_description;
504  res->d_dataFunc = this->d_dataFunc;
505  return res;
506  }
507 };
508 
509 //! allows use of recursive structure queries (e.g. recursive SMARTS)
511  : public Queries::SetQuery<int, Atom const *, true> {
512  public:
514  : Queries::SetQuery<int, Atom const *, true>(), d_serialNumber(0) {
515  setDataFunc(getAtIdx);
516  setDescription("RecursiveStructure");
517  };
518  //! initialize from an ROMol pointer
519  /*!
520  <b>Notes</b>
521  - this takes over ownership of the pointer
522  */
523  RecursiveStructureQuery(ROMol const *query, unsigned int serialNumber = 0)
524  : Queries::SetQuery<int, Atom const *, true>(),
525  d_serialNumber(serialNumber) {
526  setQueryMol(query);
527  setDataFunc(getAtIdx);
528  setDescription("RecursiveStructure");
529  };
530  //! returns the index of an atom
531  static inline int getAtIdx(Atom const *at) {
532  PRECONDITION(at, "bad atom argument");
533  return at->getIdx();
534  };
535 
536  //! sets the molecule we'll use recursively
537  /*!
538  <b>Notes</b>
539  - this takes over ownership of the pointer
540  */
541  void setQueryMol(ROMol const *query) { dp_queryMol.reset(query); }
542  //! returns a pointer to our query molecule
543  ROMol const *getQueryMol() const { return dp_queryMol.get(); };
544 
545  //! returns a copy of this query
548  res->dp_queryMol.reset(new ROMol(*dp_queryMol, true));
549 
550  std::set<int>::const_iterator i;
551  for (i = d_set.begin(); i != d_set.end(); i++) {
552  res->insert(*i);
553  }
554  res->setNegation(getNegation());
556  res->d_serialNumber = d_serialNumber;
557  return res;
558  }
559  unsigned int getSerialNumber() const { return d_serialNumber; };
560 
561 #ifdef RDK_THREADSAFE_SSS
562  boost::mutex d_mutex;
563 #endif
564  private:
565  boost::shared_ptr<const ROMol> dp_queryMol;
566  unsigned int d_serialNumber;
567 };
568 
569 template <typename T>
570 int nullDataFun(T) {
571  return 1;
572 }
573 template <typename T>
574 bool nullQueryFun(T) {
575  return true;
576 }
577 
578 typedef Bond const *ConstBondPtr;
579 
580 // ! Query whether an atom has a property
581 template <class TargetPtr>
582 class HasPropQuery : public Queries::EqualityQuery<int, TargetPtr, true> {
583  std::string propname;
584 
585  public:
586  HasPropQuery() : Queries::EqualityQuery<int, TargetPtr, true>(), propname() {
587  // default is to just do a number of rings query:
588  this->setDescription("AtomHasProp");
589  this->setDataFunc(0);
590  };
591  explicit HasPropQuery(const std::string &v)
592  : Queries::EqualityQuery<int, TargetPtr, true>(), propname(v) {
593  // default is to just do a number of rings query:
594  this->setDescription("AtomHasProp");
595  this->setDataFunc(0);
596  };
597 
598  virtual bool Match(const TargetPtr what) const {
599  bool res = what->hasProp(propname);
600  if (this->getNegation()) {
601  res = !res;
602  }
603  return res;
604  }
605 
606  //! returns a copy of this query
608  HasPropQuery *res = new HasPropQuery(this->propname);
609  res->setNegation(this->getNegation());
610  res->d_description = this->d_description;
611  return res;
612  }
613 };
614 
617 
618 //! returns a Query for matching atoms that have a particular property
619 template <class Target>
621  const std::string &property) {
622  return new HasPropQuery<const Target *>(property);
623 }
624 
625 // ! Query whether an atom has a property with a value
626 template <class TargetPtr, class T>
628  : public Queries::EqualityQuery<int, TargetPtr, true> {
629  std::string propname;
630  T val;
631  T tolerance;
632 
633  public:
635  : Queries::EqualityQuery<int, TargetPtr, true>(), propname(), val() {
636  // default is to just do a number of rings query:
637  this->setDescription("HasPropWithValue");
638  this->setDataFunc(0);
639  };
640  explicit HasPropWithValueQuery(const std::string &prop, const T &v,
641  const T &tol = 0.0)
642  : Queries::EqualityQuery<int, TargetPtr, true>(),
643  propname(prop),
644  val(v),
645  tolerance(tol) {
646  // default is to just do a number of rings query:
647  this->setDescription("HasPropWithValue");
648  this->setDataFunc(0);
649  };
650 
651  virtual bool Match(const TargetPtr what) const {
652  bool res = what->hasProp(propname);
653  if (res) {
654  try {
655  T atom_val = what->template getProp<T>(propname);
656  res = Queries::queryCmp(atom_val, this->val, this->tolerance) == 0;
657  } catch (KeyErrorException e) {
658  res = false;
659  } catch (boost::bad_any_cast) {
660  res = false;
661  }
662 #ifdef __GNUC__
663 #if (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 2))
664  catch (...) {
665  // catch all -- this is currently necessary to
666  // trap some bugs in boost+gcc configurations
667  // Normally, this is not the correct thing to
668  // do, but the only exception above is due
669  // to the boost any_cast which is trapped
670  // by the Boost python wrapper when it shouldn't
671  // be.
672  res = false;
673  }
674 #endif
675 #endif
676  }
677  if (this->getNegation()) {
678  res = !res;
679  }
680  return res;
681  }
682 
683  //! returns a copy of this query
685  HasPropWithValueQuery *res =
686  new HasPropWithValueQuery(this->propname, this->val, this->tolerance);
687  res->setNegation(this->getNegation());
688  res->d_description = this->d_description;
689  return res;
690  }
691 };
692 
693 template <class TargetPtr>
694 class HasPropWithValueQuery<TargetPtr, std::string>
695  : public Queries::EqualityQuery<int, TargetPtr, true> {
696  std::string propname;
697  std::string val;
698 
699  public:
701  : Queries::EqualityQuery<int, TargetPtr, true>(), propname(), val() {
702  // default is to just do a number of rings query:
703  this->setDescription("HasPropWithValue");
704  this->setDataFunc(0);
705  };
706  explicit HasPropWithValueQuery(const std::string &prop, const std::string &v,
707  const std::string &tol = "")
708  : Queries::EqualityQuery<int, TargetPtr, true>(), propname(prop), val(v) {
709  RDUNUSED_PARAM(tol);
710  // default is to just do a number of rings query:
711  this->setDescription("HasPropWithValue");
712  this->setDataFunc(0);
713  };
714 
715  virtual bool Match(const TargetPtr what) const {
716  bool res = what->hasProp(propname);
717  if (res) {
718  try {
719  std::string atom_val = what->template getProp<std::string>(propname);
720  res = atom_val == this->val;
721  } catch (KeyErrorException) {
722  res = false;
723  } catch (boost::bad_any_cast) {
724  res = false;
725  }
726 #ifdef __GNUC__
727 #if (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 2))
728  catch (...) {
729  // catch all -- this is currently necessary to
730  // trap some bugs in boost+gcc configurations
731  // Normally, this is not the correct thing to
732  // do, but the only exception above is due
733  // to the boost any_cast which is trapped
734  // by the Boost python wrapper when it shouldn't
735  // be.
736  res = false;
737  }
738 #endif
739 #endif
740  }
741  if (this->getNegation()) {
742  res = !res;
743  }
744  return res;
745  }
746 
747  //! returns a copy of this query
751  this->val);
752  res->setNegation(this->getNegation());
753  res->d_description = this->d_description;
754  return res;
755  }
756 };
757 
758 template <class Target, class T>
760  const std::string &propname, const T &val, const T &tolerance = T()) {
761  return new HasPropWithValueQuery<const Target *, T>(propname, val, tolerance);
762 }
763 
764 bool isComplexQuery(const Bond *b);
765 bool isComplexQuery(const Atom *a);
766 bool isAtomAromatic(const Atom *a);
767 };
768 
769 #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:591
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:381
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:339
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:314
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:499
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:715
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:543
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:468
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:616
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:400
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:531
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:290
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:759
Queries::Query< int, TargetPtr, true > * copy() const
returns a copy of this query
Definition: QueryOps.h:748
T * makeAtomHasChiralTagQuery(const std::string &descr)
Definition: QueryOps.h:356
BondType
the type of Bond
Definition: Bond.h:57
bool nullQueryFun(T)
Definition: QueryOps.h:574
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:106
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:484
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:651
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:598
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:323
T * makeAtomAliphaticQuery(const std::string &descr)
returns a Query for matching aliphatic atoms
Definition: QueryOps.h:306
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:373
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:365
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:486
BOND_NULL_QUERY * makeBondNullQuery()
returns a Query for matching any bond
allows use of recursive structure queries (e.g. recursive SMARTS)
Definition: QueryOps.h:510
bool isAtomAromatic(const Atom *a)
Bond const * ConstBondPtr
Definition: QueryOps.h:578
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:706
static int queryAtomAromatic(Atom const *at)
Definition: QueryOps.h:70
unsigned int getNumExplicitHs() const
returns our number of explict Hs
Definition: Atom.h:216
Includes a bunch of functionality for handling Atom and Bond queries.
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:408
T * makeAtomAromaticQuery(const std::string &descr)
returns a Query for matching the isAromatic flag
Definition: QueryOps.h:298
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:331
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:684
int getImplicitValence() const
returns the implicit valence for this Atom
RingInfo * getRingInfo() const
Definition: ROMol.h:379
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:541
BOND_EQUALS_QUERY * makeBondHasStereoQuery()
returns a Query for matching bonds with stereo set
unsigned int getSerialNumber() const
Definition: QueryOps.h:559
RecursiveStructureQuery(ROMol const *query, unsigned int serialNumber=0)
initialize from an ROMol pointer
Definition: QueryOps.h:523
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:433
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:282
Queries::Query< int, TargetPtr, true > * copy() const
returns a copy of this query
Definition: QueryOps.h:607
T * makeAtomInNRingsQuery(int what, const std::string &descr)
returns a Query for matching atoms in a particular number of rings
Definition: QueryOps.h:389
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:640
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:347
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:570
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:459
Queries::EqualityQuery< int, Atom const *, true > ATOM_PROP_QUERY
Definition: QueryOps.h:615
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:620
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:546
T * makeAtomHCountQuery(int what, const std::string &descr)
returns a Query for matching hydrogen count
Definition: QueryOps.h:274
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