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 queryAtomTotalValence(Atom const * at) { return at->getExplicitValence()+at->getImplicitValence(); };
    00065   static int queryAtomUnsaturated(Atom const * at) { return static_cast<int>(at->getDegree())<at->getExplicitValence(); };
    00066   static int queryAtomNum(Atom const * at) { return at->getAtomicNum(); };
    00067   static int massIntegerConversionFactor=1000;
    00068   static int queryAtomMass(Atom const * at) {
    00069     return static_cast<int>(round(massIntegerConversionFactor*at->getMass()));
    00070   };
    00071   static int queryAtomFormalCharge(Atom const * at) {
    00072       return static_cast<int>(at->getFormalCharge());
    00073   };
    00074   static int queryAtomHybridization(Atom const * at) { return at->getHybridization(); };
    00075   unsigned int queryAtomBondProduct(Atom const * at);
    00076   unsigned int queryAtomAllBondProduct(Atom const * at);
    00077
    00078
    00079   // -------------------------------------------------
    00080   // common bond queries
    00081
    00082   static int queryBondOrder(Bond const * bond) { return static_cast<int>(bond->getBondType()); };
    00083   static int queryBondDir(Bond const * bond) { return static_cast<int>(bond->getBondDir()); };
    00084   static int queryIsBondInNRings(Bond const * at) {
    00085     return at->getOwningMol().getRingInfo()->numBondRings(at->getIdx());
    00086   };
    00087
    00088   // -------------------------------------------------
    00089   // ring queries
    00090
    00091   static int queryIsAtomInNRings(Atom const * at) {
    00092     return at->getOwningMol().getRingInfo()->numAtomRings(at->getIdx());
    00093   };
    00094   static int queryIsAtomInRing(Atom const * at) {
    00095     return at->getOwningMol().getRingInfo()->numAtomRings(at->getIdx())!=0;
    00096   };
    00097   static int queryIsBondInRing(Bond const * bond) {
    00098     return bond->getOwningMol().getRingInfo()->numBondRings(bond->getIdx())!=0;
    00099   };
    00100   static int queryAtomMinRingSize(Atom const *at){
    00101     return at->getOwningMol().getRingInfo()->minAtomRingSize(at->getIdx());
    00102   };
    00103   static int queryBondMinRingSize(Bond const *bond){
    00104     return bond->getOwningMol().getRingInfo()->minBondRingSize(bond->getIdx());
    00105   };
    00106
    00107   static int queryAtomRingBondCount(Atom const *at) {
    00108     // EFF: cache this result
    00109     int res=0;
    00110     ROMol::GRAPH_MOL_BOND_PMAP::type pMap = at->getOwningMol().getBondPMap();
    00111     ROMol::OBOND_ITER_PAIR atomBonds=at->getOwningMol().getAtomBonds(at);
    00112     while(atomBonds.first != atomBonds.second){
    00113       unsigned int bondIdx=pMap[*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 total valence
    00145   ATOM_EQUALS_QUERY *makeAtomTotalValenceQuery(int what);
    00146   //! returns a Query for matching explicit valence
    00147   ATOM_EQUALS_QUERY *makeAtomExplicitDegreeQuery(int what);
    00148   //! returns a Query for matching atomic degree
    00149   ATOM_EQUALS_QUERY *makeAtomTotalDegreeQuery(int what);
    00150   //! returns a Query for matching hydrogen count
    00151   ATOM_EQUALS_QUERY *makeAtomHCountQuery(int what);
    00152   //! returns a Query for matching the \c isAromatic flag
    00153   ATOM_EQUALS_QUERY *makeAtomAromaticQuery();
    00154   //! returns a Query for matching aliphatic atoms
    00155   ATOM_EQUALS_QUERY *makeAtomAliphaticQuery();
    00156   //! returns a Query for matching atoms with a particular mass (for isotopes)
    00157   ATOM_EQUALS_QUERY *makeAtomMassQuery(int what);
    00158   //! returns a Query for matching formal charge
    00159   ATOM_EQUALS_QUERY *makeAtomFormalChargeQuery(int what);
    00160   //! returns a Query for matching hybridization
    00161   ATOM_EQUALS_QUERY *makeAtomHybridizationQuery(int what);
    00162   //! returns a Query for matching atoms with unsaturation:
    00163   ATOM_EQUALS_QUERY *makeAtomUnsaturatedQuery();
    00164
    00165   //! returns a Query for matching ring atoms
    00166   ATOM_EQUALS_QUERY *makeAtomInRingQuery();
    00167   //! returns a Query for matching atoms in a particular number of rings
    00168   ATOM_EQUALS_QUERY *makeAtomInNRingsQuery(int what);
    00169   //! returns a Query for matching atoms in rings of a particular size
    00170   ATOM_EQUALS_QUERY *makeAtomInRingOfSizeQuery(int tgt);
    00171   //! returns a Query for matching an atom's minimum ring size
    00172   ATOM_EQUALS_QUERY *makeAtomMinRingSizeQuery(int tgt);
    00173   //! returns a Query for matching atoms with a particular number of ring bonds
    00174   ATOM_EQUALS_QUERY *makeAtomRingBondCountQuery(int what);
    00175
    00176   //! returns a Query for matching bond orders
    00177   BOND_EQUALS_QUERY *makeBondOrderEqualsQuery(Bond::BondType what);
    00178   //! returns a Query for matching bond directions
    00179   BOND_EQUALS_QUERY *makeBondDirEqualsQuery(Bond::BondDir what);
    00180   //! returns a Query for matching ring bonds
    00181   BOND_EQUALS_QUERY *makeBondIsInRingQuery();
    00182   //! returns a Query for matching bonds in rings of a particular size
    00183   BOND_EQUALS_QUERY *makeBondInRingOfSizeQuery(int what);
    00184   //! returns a Query for matching a bond's minimum ring size
    00185   BOND_EQUALS_QUERY *makeBondMinRingSizeQuery(int what);
    00186   //! returns a Query for matching bonds in a particular number of rings
    00187   BOND_EQUALS_QUERY *makeBondInNRingsQuery(int tgt);
    00188
    00189   //! returns a Query for matching any bond
    00190   BOND_NULL_QUERY *makeBondNullQuery();
    00191   //! returns a Query for matching any atom
    00192   ATOM_NULL_QUERY *makeAtomNullQuery();
    00193
    00194   static int queryAtomRingMembership(Atom const *at) {
    00195     return static_cast<int>(at->getOwningMol().getRingInfo()->numAtomRings(at->getIdx()));
    00196   }
    00197   // I'm pretty sure that this typedef shouldn't be necessary,
    00198   // but VC++ generates a warning about const Atom const * in
    00199   // the definition of Match, then complains about an override
    00200   // that differs only by const/volatile (c4301), then generates
    00201   // incorrect code if we don't do this... so let's do it.
    00202   typedef Atom const *ConstAtomPtr;
    00203
    00204   class AtomRingQuery : public Queries::EqualityQuery<int, ConstAtomPtr,true> {
    00205   public:
    00206     AtomRingQuery() : Queries::EqualityQuery<int,ConstAtomPtr,true>(-1) {
    00207       // default is to just do a number of rings query:
    00208       this->setDescription("AtomInNRings");
    00209       this->setDataFunc(queryAtomRingMembership);
    00210     };
    00211     explicit AtomRingQuery(int v) : Queries::EqualityQuery<int,ConstAtomPtr,true>(v) {
    00212       // default is to just do a number of rings query:
    00213       this->setDescription("AtomInNRings");
    00214       this->setDataFunc(queryAtomRingMembership);
    00215     };
    00216
    00217     virtual bool Match(const ConstAtomPtr what) const {
    00218       int v = this->TypeConvert(what,Queries::Int2Type<true>());
    00219       bool res;
    00220       if(this->d_val<0){
    00221         res = v!=0;
    00222       } else {
    00223         res=!Queries::queryCmp(v,this->d_val,this->d_tol);
    00224       }
    00225       if(this->getNegation()){
    00226         res=!res;
    00227       }
    00228       return res;
    00229     }
    00230
    00231     //! returns a copy of this query
    00232     Queries::Query<int,ConstAtomPtr,true> *
    00233     copy() const {
    00234       AtomRingQuery *res = new AtomRingQuery(this->d_val);
    00235       res->setNegation(getNegation());
    00236       res->setTol(this->getTol());
    00237       res->d_description = this->d_description;
    00238       res->d_dataFunc = this->d_dataFunc;
    00239       return res;
    00240     }
    00241   };
    00242
    00243   //! allows use of recursive structure queries (e.g. recursive SMARTS)
    00244   class RecursiveStructureQuery : public Queries::SetQuery<int,Atom const *,true> {
    00245   public:
    00246     RecursiveStructureQuery() : Queries::SetQuery<int,Atom const *,true>() {
    00247       setDataFunc(getAtIdx);
    00248       setDescription("RecursiveStructure");
    00249     };
    00250     //! initialize from an ROMol pointer
    00251     /*!
    00252       <b>Notes</b>
    00253         - this takes over ownership of the pointer
    00254     */
    00255     RecursiveStructureQuery(ROMol const *query) : Queries::SetQuery<int,Atom const *,true>() {
    00256       setQueryMol(query);
    00257       setDataFunc(getAtIdx);
    00258       setDescription("RecursiveStructure");
    00259     };
    00260     //! returns the index of an atom
    00261     static int getAtIdx(Atom const *at) { return at->getIdx(); };
    00262
    00263     //! sets the molecule we'll use recursively
    00264     /*!
    00265       <b>Notes</b>
    00266         - this takes over ownership of the pointer
    00267     */
    00268     void setQueryMol(ROMol const *query) {
    00269       dp_queryMol.reset(query);
    00270     }
    00271     //! returns a pointer to our query molecule
    00272     ROMol const * getQueryMol() const { return dp_queryMol.get(); };
    00273
    00274     //! returns a copy of this query
    00275     Queries::Query<int,Atom const *,true> *
    00276     copy() const {
    00277       RecursiveStructureQuery *res =
    00278         new RecursiveStructureQuery();
    00279       res->dp_queryMol = dp_queryMol;
    00280
    00281       std::set<int>::const_iterator i;
    00282       for(i=d_set.begin();i!=d_set.end();i++){
    00283         res->insert(*i);
    00284       }
    00285       res->setNegation(getNegation());
    00286       res->d_description = d_description;
    00287       return res;
    00288     }
    00289
    00290   private:
    00291     boost::shared_ptr<const ROMol>dp_queryMol;
    00292
    00293   };
    00294
    00295   template <typename T>
    00296   int nullDataFun(T arg) { return 1; }
    00297   template <typename T>
    00298   bool nullQueryFun(T arg) { return true; }
    00299
    00300 };
    00301
    00302
    00303 #endif