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

Generated on Fri Apr 3 06:03:02 2009 for RDCode by  doxygen 1.5.6