QueryOps.h

Go to the documentation of this file.
00001 //
00002 //  Copyright (C) 2003-2006 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 queryAtomMass(Atom const * at) {
00068     // FIX: this really shouldn't be using integers
00069     return static_cast<int>(round(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

Generated on Sat May 24 08:36:32 2008 for RDCode by  doxygen 1.5.3