RDCode: QueryOps.h Source File

# QueryOps.h

Go to the documentation of this file.

    00001 //
    00002 //  Copyright (C) 2003-2008 Greg Landrum and Rational Discovery LLC
    00003 //
    00004 //   @@ All Rights Reserved  @@
    00005 //
    00006
    00007 //! \file QueryOps.h
    00008 /*!
    00009     \brief Includes a bunch of functionality for handling Atom and Bond queries.
    00010 */
    00011 #ifndef _RD_QUERY_OPS_H
    00012 #define _RD_QUERY_OPS_H
    00013
    00014 #include <GraphMol/RDKitBase.h>
    00015 #include <Query/QueryObjects.h>
    00016
    00017 namespace RDKit{
    00018   typedef Queries::Query<bool,Atom const *,true> ATOM_BOOL_QUERY;
    00019   typedef Queries::Query<bool,Bond const *,true> BOND_BOOL_QUERY;
    00020
    00021   typedef Queries::AndQuery<int,Atom const *,true> ATOM_AND_QUERY;
    00022   typedef Queries::AndQuery<int,Bond const *,true> BOND_AND_QUERY;
    00023
    00024   typedef Queries::OrQuery<int,Atom const *,true> ATOM_OR_QUERY;
    00025   typedef Queries::OrQuery<int,Bond const *,true> BOND_OR_QUERY;
    00026
    00027   typedef Queries::XOrQuery<int,Atom const *,true> ATOM_XOR_QUERY;
    00028   typedef Queries::XOrQuery<int,Bond const *,true> BOND_XOR_QUERY;
    00029
    00030   typedef Queries::EqualityQuery<int,Atom const *,true> ATOM_EQUALS_QUERY;
    00031   typedef Queries::EqualityQuery<int,Bond const *,true> BOND_EQUALS_QUERY;
    00032
    00033   typedef Queries::GreaterQuery<int,Atom const *,true> ATOM_GREATER_QUERY;
    00034   typedef Queries::GreaterQuery<int,Bond const *,true> BOND_GREATER_QUERY;
    00035
    00036   typedef Queries::GreaterEqualQuery<int,Atom const *,true> ATOM_GREATEREQUAL_QUERY;
    00037   typedef Queries::GreaterEqualQuery<int,Bond const *,true> BOND_GREATEREQUAL_QUERY;
    00038
    00039   typedef Queries::LessQuery<int,Atom const *,true> ATOM_LESS_QUERY;
    00040   typedef Queries::LessQuery<int,Bond const *,true> BOND_LESS_QUERY;
    00041
    00042   typedef Queries::LessEqualQuery<int,Atom const *,true> ATOM_LESSEQUAL_QUERY;
    00043   typedef Queries::LessEqualQuery<int,Bond const *,true> BOND_LESSEQUAL_QUERY;
    00044
    00045   typedef Queries::RangeQuery<int,Atom const *,true> ATOM_RANGE_QUERY;
    00046   typedef Queries::RangeQuery<int,Bond const *,true> BOND_RANGE_QUERY;
    00047
    00048   typedef Queries::SetQuery<int,Atom const *,true> ATOM_SET_QUERY;
    00049   typedef Queries::SetQuery<int,Bond const *,true> BOND_SET_QUERY;
    00050
    00051   typedef Queries::Query<int,Bond const *,true> BOND_NULL_QUERY;
    00052   typedef Queries::Query<int,Atom const *,true> ATOM_NULL_QUERY;
    00053
    00054   // -------------------------------------------------
    00055   // common atom queries
    00056
    00057   static int queryAtomAromatic(Atom const * at) { return at->getIsAromatic(); };
    00058   static int queryAtomAliphatic(Atom const * at) { return !(at->getIsAromatic()); };
    00059   static int queryAtomExplicitDegree(Atom const * at) { return at->getDegree(); };
    00060   static int queryAtomTotalDegree(Atom const * at) { return at->getDegree()+at->getImplicitValence(); };
    00061   static int queryAtomHeavyAtomDegree(Atom const * at) { return at->getDegree(); };
    00062   static int queryAtomHCount(Atom const * at) { return at->getTotalNumHs(true); };
    00063   static int queryAtomImplicitValence(Atom const * at) { return at->getImplicitValence(); };
    00064   static int queryAtomExplicitValence(Atom const * at) { return at->getExplicitValence() - at->getNumExplicitHs(); };
    00065   static int queryAtomTotalValence(Atom const * at) { return at->getExplicitValence()+at->getImplicitValence(); };
    00066   static int queryAtomUnsaturated(Atom const * at) { return static_cast<int>(at->getDegree())<at->getExplicitValence(); };
    00067   static int queryAtomNum(Atom const * at) { return at->getAtomicNum(); };
    00068   static int massIntegerConversionFactor=1000;
    00069   static int queryAtomMass(Atom const * at) {
    00070     return static_cast<int>(round(massIntegerConversionFactor*at->getMass()));
    00071   };
    00072   static int queryAtomFormalCharge(Atom const * at) {
    00073       return static_cast<int>(at->getFormalCharge());
    00074   };
    00075   static int queryAtomHybridization(Atom const * at) { return at->getHybridization(); };
    00076   unsigned int queryAtomBondProduct(Atom const * at);
    00077   unsigned int queryAtomAllBondProduct(Atom const * at);
    00078
    00079
    00080   // -------------------------------------------------
    00081   // common bond queries
    00082
    00083   static int queryBondOrder(Bond const * bond) { return static_cast<int>(bond->getBondType()); };
    00084   static int queryBondDir(Bond const * bond) { return static_cast<int>(bond->getBondDir()); };
    00085   static int queryIsBondInNRings(Bond const * at) {
    00086     return at->getOwningMol().getRingInfo()->numBondRings(at->getIdx());
    00087   };
    00088
    00089   // -------------------------------------------------
    00090   // ring queries
    00091
    00092   static int queryIsAtomInNRings(Atom const * at) {
    00093     return at->getOwningMol().getRingInfo()->numAtomRings(at->getIdx());
    00094   };
    00095   static int queryIsAtomInRing(Atom const * at) {
    00096     return at->getOwningMol().getRingInfo()->numAtomRings(at->getIdx())!=0;
    00097   };
    00098   static int queryIsBondInRing(Bond const * bond) {
    00099     return bond->getOwningMol().getRingInfo()->numBondRings(bond->getIdx())!=0;
    00100   };
    00101   static int queryAtomMinRingSize(Atom const *at){
    00102     return at->getOwningMol().getRingInfo()->minAtomRingSize(at->getIdx());
    00103   };
    00104   static int queryBondMinRingSize(Bond const *bond){
    00105     return bond->getOwningMol().getRingInfo()->minBondRingSize(bond->getIdx());
    00106   };
    00107
    00108   static int queryAtomRingBondCount(Atom const *at) {
    00109     // EFF: cache this result
    00110     int res=0;
    00111     ROMol::OBOND_ITER_PAIR atomBonds=at->getOwningMol().getAtomBonds(at);
    00112     while(atomBonds.first != atomBonds.second){
    00113       unsigned int bondIdx=at->getOwningMol().getTopology()[*atomBonds.first]->getIdx();
    00114       if(at->getOwningMol().getRingInfo()->numBondRings(bondIdx)) {
    00115         res++;
    00116       }
    00117       ++atomBonds.first;
    00118     }
    00119     return res;
    00120   }
    00121
    00122   template <int tgt>
    00123   int queryAtomIsInRingOfSize(Atom const *at) {
    00124     if(at->getOwningMol().getRingInfo()->isAtomInRingOfSize(at->getIdx(),tgt)){
    00125       return tgt;
    00126     } else {
    00127       return 0;
    00128     }
    00129   };
    00130   template <int tgt>
    00131   int queryBondIsInRingOfSize(Bond const *bond) {
    00132     if(bond->getOwningMol().getRingInfo()->isBondInRingOfSize(bond->getIdx(),tgt)){
    00133       return tgt;
    00134     } else {
    00135       return 0;
    00136     }
    00137   };
    00138
    00139
    00140   //! returns a Query for matching atomic number
    00141   ATOM_EQUALS_QUERY *makeAtomNumEqualsQuery(int what);
    00142   //! returns a Query for matching implicit valence
    00143   ATOM_EQUALS_QUERY *makeAtomImplicitValenceQuery(int what);
    00144   //! returns a Query for matching explicit valence
    00145   ATOM_EQUALS_QUERY *makeAtomExplicitValenceQuery(int what);
    00146   //! returns a Query for matching total valence
    00147   ATOM_EQUALS_QUERY *makeAtomTotalValenceQuery(int what);
    00148   //! returns a Query for matching explicit valence
    00149   ATOM_EQUALS_QUERY *makeAtomExplicitDegreeQuery(int what);
    00150   //! returns a Query for matching atomic degree
    00151   ATOM_EQUALS_QUERY *makeAtomTotalDegreeQuery(int what);
    00152   //! returns a Query for matching hydrogen count
    00153   ATOM_EQUALS_QUERY *makeAtomHCountQuery(int what);
    00154   //! returns a Query for matching the \c isAromatic flag
    00155   ATOM_EQUALS_QUERY *makeAtomAromaticQuery();
    00156   //! returns a Query for matching aliphatic atoms
    00157   ATOM_EQUALS_QUERY *makeAtomAliphaticQuery();
    00158   //! returns a Query for matching atoms with a particular mass (for isotopes)
    00159   ATOM_EQUALS_QUERY *makeAtomMassQuery(int what);
    00160   //! returns a Query for matching formal charge
    00161   ATOM_EQUALS_QUERY *makeAtomFormalChargeQuery(int what);
    00162   //! returns a Query for matching hybridization
    00163   ATOM_EQUALS_QUERY *makeAtomHybridizationQuery(int what);
    00164   //! returns a Query for matching atoms with unsaturation:
    00165   ATOM_EQUALS_QUERY *makeAtomUnsaturatedQuery();
    00166
    00167   //! returns a Query for matching ring atoms
    00168   ATOM_EQUALS_QUERY *makeAtomInRingQuery();
    00169   //! returns a Query for matching atoms in a particular number of rings
    00170   ATOM_EQUALS_QUERY *makeAtomInNRingsQuery(int what);
    00171   //! returns a Query for matching atoms in rings of a particular size
    00172   ATOM_EQUALS_QUERY *makeAtomInRingOfSizeQuery(int tgt);
    00173   //! returns a Query for matching an atom's minimum ring size
    00174   ATOM_EQUALS_QUERY *makeAtomMinRingSizeQuery(int tgt);
    00175   //! returns a Query for matching atoms with a particular number of ring bonds
    00176   ATOM_EQUALS_QUERY *makeAtomRingBondCountQuery(int what);
    00177
    00178   //! returns a Query for matching bond orders
    00179   BOND_EQUALS_QUERY *makeBondOrderEqualsQuery(Bond::BondType what);
    00180   //! returns a Query for matching bond directions
    00181   BOND_EQUALS_QUERY *makeBondDirEqualsQuery(Bond::BondDir what);
    00182   //! returns a Query for matching ring bonds
    00183   BOND_EQUALS_QUERY *makeBondIsInRingQuery();
    00184   //! returns a Query for matching bonds in rings of a particular size
    00185   BOND_EQUALS_QUERY *makeBondInRingOfSizeQuery(int what);
    00186   //! returns a Query for matching a bond's minimum ring size
    00187   BOND_EQUALS_QUERY *makeBondMinRingSizeQuery(int what);
    00188   //! returns a Query for matching bonds in a particular number of rings
    00189   BOND_EQUALS_QUERY *makeBondInNRingsQuery(int tgt);
    00190
    00191   //! returns a Query for matching any bond
    00192   BOND_NULL_QUERY *makeBondNullQuery();
    00193   //! returns a Query for matching any atom
    00194   ATOM_NULL_QUERY *makeAtomNullQuery();
    00195
    00196   static int queryAtomRingMembership(Atom const *at) {
    00197     return static_cast<int>(at->getOwningMol().getRingInfo()->numAtomRings(at->getIdx()));
    00198   }
    00199   // I'm pretty sure that this typedef shouldn't be necessary,
    00200   // but VC++ generates a warning about const Atom const * in
    00201   // the definition of Match, then complains about an override
    00202   // that differs only by const/volatile (c4301), then generates
    00203   // incorrect code if we don't do this... so let's do it.
    00204   typedef Atom const *ConstAtomPtr;
    00205
    00206   class AtomRingQuery : public Queries::EqualityQuery<int, ConstAtomPtr,true> {
    00207   public:
    00208     AtomRingQuery() : Queries::EqualityQuery<int,ConstAtomPtr,true>(-1) {
    00209       // default is to just do a number of rings query:
    00210       this->setDescription("AtomInNRings");
    00211       this->setDataFunc(queryAtomRingMembership);
    00212     };
    00213     explicit AtomRingQuery(int v) : Queries::EqualityQuery<int,ConstAtomPtr,true>(v) {
    00214       // default is to just do a number of rings query:
    00215       this->setDescription("AtomInNRings");
    00216       this->setDataFunc(queryAtomRingMembership);
    00217     };
    00218
    00219     virtual bool Match(const ConstAtomPtr what) const {
    00220       int v = this->TypeConvert(what,Queries::Int2Type<true>());
    00221       bool res;
    00222       if(this->d_val<0){
    00223         res = v!=0;
    00224       } else {
    00225         res=!Queries::queryCmp(v,this->d_val,this->d_tol);
    00226       }
    00227       if(this->getNegation()){
    00228         res=!res;
    00229       }
    00230       return res;
    00231     }
    00232
    00233     //! returns a copy of this query
    00234     Queries::Query<int,ConstAtomPtr,true> *
    00235     copy() const {
    00236       AtomRingQuery *res = new AtomRingQuery(this->d_val);
    00237       res->setNegation(getNegation());
    00238       res->setTol(this->getTol());
    00239       res->d_description = this->d_description;
    00240       res->d_dataFunc = this->d_dataFunc;
    00241       return res;
    00242     }
    00243   };
    00244
    00245   //! allows use of recursive structure queries (e.g. recursive SMARTS)
    00246   class RecursiveStructureQuery : public Queries::SetQuery<int,Atom const *,true> {
    00247   public:
    00248     RecursiveStructureQuery() : Queries::SetQuery<int,Atom const *,true>() {
    00249       setDataFunc(getAtIdx);
    00250       setDescription("RecursiveStructure");
    00251     };
    00252     //! initialize from an ROMol pointer
    00253     /*!
    00254       <b>Notes</b>
    00255         - this takes over ownership of the pointer
    00256     */
    00257     RecursiveStructureQuery(ROMol const *query) : Queries::SetQuery<int,Atom const *,true>() {
    00258       setQueryMol(query);
    00259       setDataFunc(getAtIdx);
    00260       setDescription("RecursiveStructure");
    00261     };
    00262     //! returns the index of an atom
    00263     static int getAtIdx(Atom const *at) { return at->getIdx(); };
    00264
    00265     //! sets the molecule we'll use recursively
    00266     /*!
    00267       <b>Notes</b>
    00268         - this takes over ownership of the pointer
    00269     */
    00270     void setQueryMol(ROMol const *query) {
    00271       dp_queryMol.reset(query);
    00272     }
    00273     //! returns a pointer to our query molecule
    00274     ROMol const * getQueryMol() const { return dp_queryMol.get(); };
    00275
    00276     //! returns a copy of this query
    00277     Queries::Query<int,Atom const *,true> *
    00278     copy() const {
    00279       RecursiveStructureQuery *res =
    00280         new RecursiveStructureQuery();
    00281       res->dp_queryMol = dp_queryMol;
    00282
    00283       std::set<int>::const_iterator i;
    00284       for(i=d_set.begin();i!=d_set.end();i++){
    00285         res->insert(*i);
    00286       }
    00287       res->setNegation(getNegation());
    00288       res->d_description = d_description;
    00289       return res;
    00290     }
    00291
    00292   private:
    00293     boost::shared_ptr<const ROMol>dp_queryMol;
    00294
    00295   };
    00296
    00297   template <typename T>
    00298   int nullDataFun(T arg) { return 1; }
    00299   template <typename T>
    00300   bool nullQueryFun(T arg) { return true; }
    00301
    00302 };
    00303
    00304
    00305 #endif