RDCode: Atom.h Source File

- Main Page
- Namespaces
- Classes
- Files
- Directories

# Atom.h

Go to the documentation of this file.

    00001 //
    00002 //  Copyright (C) 2001-2008 Greg Landrum and Rational Discovery LLC
    00003 //
    00004 //   @@ All Rights Reserved  @@
    00005 //
    00006 /*! \file Atom.h
    00007
    00008   \brief Defines the Atom class and associated typedefs
    00009
    00010 */
    00011 #ifndef _RD_ATOM_H
    00012 #define _RD_ATOM_H
    00013
    00014 // Std stuff
    00015 #include <iostream>
    00016
    00017 // ours
    00018 #include <Query/QueryObjects.h>
    00019 #include <RDGeneral/types.h>
    00020
    00021
    00022 namespace RDKit{
    00023   class ROMol;
    00024   class RWMol;
    00025
    00026   //! The class for representing atoms
    00027   /*!
    00028
    00029     <b>Notes:</b>
    00030       - many of the methods of Atom require that the Atom be associated
    00031         with a molecule (an ROMol).
    00032       - each Atom maintains a Dict of \c properties:
    00033           - Each \c property is keyed by name and can store an
    00034             arbitrary type.
    00035           - \c Properties can be marked as \c calculated, in which case
    00036             they will be cleared when the \c clearComputedProps() method
    00037             is called.
    00038           - Because they have no impact upon chemistry, all \c property
    00039             operations are \c const, this allows extra flexibility for
    00040             clients who need to store extra data on Atom objects.
    00041       - Atom objects are lazy about computing their explicit and implicit valence
    00042         values.  These will not be computed until their values are requested.
    00043
    00044     <b>Chirality:</b>
    00045
    00046     The chirality of an Atom is determined by two things:
    00047       - its \c chiralTag
    00048       - the input order of its bonds
    00049
    00050     For tetrahedral coordination, the \c chiralTag tells you what
    00051     direction you have to rotate to get from bond 2 to bond 3 while looking
    00052     down bond 1. This is pretty much identical to the SMILES represenation of
    00053     chirality
    00054
    00055   */
    00056   class Atom {
    00057     friend class MolPickler; //!< the pickler needs access to our privates
    00058     friend class ROMol;
    00059     friend class RWMol;
    00060   public:
    00061
    00062     typedef boost::shared_ptr<Atom>    ATOM_SPTR;
    00063     typedef boost::shared_ptr<const Atom>    C_ATOM_SPTR;
    00064     // FIX: grn...
    00065     typedef Queries::Query<int,Atom const *,true> QUERYATOM_QUERY;
    00066
    00067     //! store hybridization
    00068     typedef enum {
    00069       UNSPECIFIED=0, //!< hybridization that hasn't been specified
    00070       S,
    00071       SP,
    00072       SP2,
    00073       SP3,
    00074       SP3D,
    00075       SP3D2,
    00076       OTHER          //!< unrecognized hybridization
    00077     } HybridizationType;
    00078
    00079     //! store type of chirality
    00080     typedef enum {
    00081       CHI_UNSPECIFIED=0,  //!< chirality that hasn't been specified
    00082       CHI_TETRAHEDRAL_CW, //!< tetrahedral: clockwise rotation (SMILES @@)
    00083       CHI_TETRAHEDRAL_CCW,//!< tetrahedral: counter-clockwise rotation (SMILES @)
    00084       CHI_OTHER           //!< some unrecognized type of chirality
    00085     } ChiralType;
    00086
    00087     Atom();
    00088     //! construct an Atom with a particular atomic number
    00089     explicit Atom(unsigned int num);
    00090     //! construct an Atom with a particular symbol (looked up in the PeriodicTable)
    00091     explicit Atom(std::string what);
    00092     Atom(const Atom & other);
    00093     virtual ~Atom();
    00094
    00095     //! makes a copy of this Atom and returns a pointer to it.
    00096     /*!
    00097       <b>Note:</b> the caller is responsible for <tt>delete</tt>ing the result
    00098     */
    00099     virtual Atom *copy() const;
    00100
    00101     //! returns our atomic number
    00102     const int getAtomicNum() const { return d_atomicNum; };
    00103     //! sets our atomic number
    00104     void setAtomicNum(int newNum) { d_atomicNum = newNum; };
    00105
    00106     //! returns our symbol (determined by our atomic number)
    00107     std::string getSymbol() const;
    00108
    00109     //! returns a reference to the ROMol that owns this Atom
    00110     ROMol &getOwningMol() const { return *dp_mol; };
    00111
    00112     //! returns our index within the ROMol
    00113     const unsigned int getIdx() const {return d_index;};
    00114     //! sets our index within the ROMol
    00115     /*!
    00116       <b>Notes:</b>
    00117         - this makes no sense if we do not have an owning molecule
    00118         - the index should be <tt>< this->getOwningMol()->getNumAtoms()</tt>
    00119     */
    00120     void setIdx(unsigned int index) {d_index=index;};
    00121
    00122     //! returns the degree of the Atom (number of bonded neighbors)
    00123     /*!
    00124       <b>Notes:</b>
    00125         - requires an owning molecule
    00126     */
    00127     unsigned int getDegree() const;
    00128
    00129     //! \brief returns the total number of Hs (implicit and explicit) that
    00130     //! this Atom is bound to
    00131     /*!
    00132       <b>Notes:</b>
    00133         - requires an owning molecule
    00134     */
    00135     unsigned int getTotalNumHs(bool includeNeighbors=false) const;
    00136
    00137     //! returns the number of implicit Hs this Atom is bound to
    00138     /*!
    00139       <b>Notes:</b>
    00140         - requires an owning molecule
    00141     */
    00142     unsigned int getNumImplicitHs() const;
    00143
    00144     //! returns the number of explicit Hs this Atom is bound to
    00145     int getExplicitValence(bool forceCalc=false) const;
    00146
    00147     //! returns the implicit valence for this Atom
    00148     /*!
    00149       <b>Notes:</b>
    00150         - requires an owning molecule
    00151     */
    00152     int getImplicitValence(bool forceCalc=false) const;
    00153
    00154     //! returns the formal charge of this atom
    00155     const int getFormalCharge() const { return d_formalCharge; };
    00156     //! set's the formal charge of this atom
    00157     void setFormalCharge(int what) { d_formalCharge = what;} ;
    00158
    00159     //! \brief sets our \c noImplicit flag, indicating whether or not
    00160     //!  we are allowed to have implicit Hs
    00161     void setNoImplicit( bool what ) { df_noImplicit = what; };
    00162     //! returns the \c noImplicit flag
    00163     bool getNoImplicit() const { return df_noImplicit; };
    00164
    00165     //! sets our number of explict Hs
    00166     void setNumExplicitHs(unsigned int what) { d_numExplicitHs = what; };
    00167     //! returns our number of explict Hs
    00168     unsigned int getNumExplicitHs() const { return d_numExplicitHs; };
    00169
    00170     //! sets our \c isAromatic flag, indicating whether or not we are aromatic
    00171     void setIsAromatic( bool what ) { df_isAromatic = what; };
    00172     //! returns our \c isAromatic flag
    00173     bool getIsAromatic() const { return df_isAromatic; };
    00174
    00175     //! sets our mass (for isotopes)
    00176     void setMass( double what) { d_mass = what; };
    00177     //! returns our mass
    00178     double getMass() const {return d_mass; };
    00179
    00180     //! sets our \c dativeFlag
    00181     // intended to be used only in construction.
    00182     // NOTE: the dative flag is not currently used anywhere
    00183     void setDativeFlag(int what) {
    00184       d_dativeFlag = what;
    00185     };
    00186     //! returns our \c dativeFlag
    00187     // NOTE: the dative flag is not currently used anywhere
    00188     int getDativeFlag() const {
    00189       return d_dativeFlag;
    00190     };
    00191     bool hasDativeFlag(int what) const {
    00192       return d_dativeFlag==what;
    00193     };
    00194     //! clears our \c dativeFlag
    00195     // NOTE: the dative flag is not currently used anywhere
    00196     void clearDativeFlag(){ d_dativeFlag = 0; };
    00197
    00198     //! sets our \c chiralTag
    00199     void setChiralTag(ChiralType what) { d_chiralTag = what; };
    00200     //! inverts our \c chiralTag
    00201     void invertChirality();
    00202     //! returns our \c chiralTag
    00203     ChiralType getChiralTag() const { return d_chiralTag; };
    00204
    00205     //! sets our hybridization
    00206     void setHybridization(HybridizationType what) { d_hybrid = what; };
    00207     //! returns our hybridization
    00208     HybridizationType getHybridization() const { return d_hybrid; };
    00209
    00210     // ------------------------------------
    00211     // Some words of explanation before getting down into
    00212     // the query stuff.
    00213     // These query functions are really only here so that they
    00214     //  can have real functionality in subclasses (like QueryAtoms).
    00215     // Since pretty much it's gonna be a mistake to call any of these
    00216     //  (ever), we're saddling them all with a precondition which
    00217     //  is guaranteed to fail.  I'd like to have them be pure virtual,
    00218     //  but that doesn't work since we need to be able to instantiate
    00219     //  Atoms.
    00220     // ------------------------------------
    00221
    00222     // This method can be used to distinguish query atoms from standard atoms:
    00223     virtual bool hasQuery() const { return false; };
    00224
    00225     //! NOT CALLABLE
    00226     virtual void setQuery(QUERYATOM_QUERY *what);
    00227
    00228     //! NOT CALLABLE
    00229     virtual QUERYATOM_QUERY *getQuery() const;
    00230     //! NOT CALLABLE
    00231     virtual void expandQuery(QUERYATOM_QUERY *what,
    00232                              Queries::CompositeQueryType how=Queries::COMPOSITE_AND,
    00233                              bool maintainOrder=true);
    00234
    00235     //! returns whether or not we match the argument
    00236     /*!
    00237         <b>Notes:</b>
    00238           - for Atom objects, "match" means that atomic numbers are the same.
    00239     */
    00240     virtual bool Match(Atom const *what) const;
    00241     //! \overload
    00242     virtual bool Match(const ATOM_SPTR what) const;
    00243
    00244
    00245     // ------------------------------------
    00246     //  Local Property Dict functionality
    00247     //  all setProp functions are const because they
    00248     //     are not meant to change the atom chemically
    00249     // ------------------------------------
    00250     //! returns a list with the names of our \c properties
    00251     STR_VECT getPropList() const {
    00252       return dp_props->keys();
    00253     }
    00254
    00255     //! sets a \c property value
    00256     /*!
    00257        \param key the name under which the \c property should be stored.
    00258            If a \c property is already stored under this name, it will be
    00259            replaced.
    00260        \param val the value to be stored
    00261        \param computed (optional) allows the \c property to be flagged
    00262            \c computed.
    00263      */
    00264     template <typename T>
    00265     void setProp(const char *key, T val, bool computed=false) const{
    00266
    00267       //if(!dp_props) dp_props = new Dict();
    00268       std::string what(key);
    00269       setProp(what,val, computed);
    00270     }
    00271
    00272     //! \overload
    00273     template <typename T>
    00274     void setProp(const std::string key, T val, bool computed=false) const {
    00275       if (computed) {
    00276         STR_VECT compLst;
    00277         if(hasProp("computedProps")) getProp("computedProps", compLst);
    00278         if (std::find(compLst.begin(), compLst.end(), key) == compLst.end()) {
    00279           compLst.push_back(key);
    00280           dp_props->setVal("computedProps", compLst);
    00281         }
    00282       }
    00283       //setProp(key.c_str(),val);
    00284       dp_props->setVal(key, val);
    00285     }
    00286
    00287     //! allows retrieval of a particular property value
    00288     /*!
    00289
    00290        \param key the name under which the \c property should be stored.
    00291            If a \c property is already stored under this name, it will be
    00292            replaced.
    00293        \param res a reference to the storage location for the value.
    00294
    00295        <b>Notes:</b>
    00296          - if no \c property with name \c key exists, a KeyErrorException will be thrown.
    00297          - the \c boost::lexical_cast machinery is used to attempt type conversions.
    00298            If this fails, a \c boost::bad_lexical_cast exception will be thrown.
    00299
    00300     */
    00301     template <typename T>
    00302     void getProp(const char *key,T &res) const {
    00303       //PRECONDITION(dp_props,"getProp called on empty property dict");
    00304       dp_props->getVal(key,res);
    00305     }
    00306     //! \overload
    00307     template <typename T>
    00308     void getProp(const std::string key,T &res) const {
    00309       //return getProp(key.c_str(),res);
    00310       dp_props->getVal(key,res);
    00311     }
    00312
    00313     //! returns whether or not we have a \c property with name \c key
    00314     bool hasProp(const char *key) const {
    00315       if(!dp_props) return false;
    00316       return dp_props->hasVal(key);
    00317     };
    00318     //! \overload
    00319     bool hasProp(const std::string key) const {
    00320       if(!dp_props) return false;
    00321       return dp_props->hasVal(key);
    00322     };
    00323
    00324
    00325     //! clears the value of a \c property
    00326     /*!
    00327        <b>Notes:</b>
    00328          - if no \c property with name \c key exists, a KeyErrorException
    00329            will be thrown.
    00330          - if the \c property is marked as \c computed, it will also be removed
    00331            from our list of \c computedProperties
    00332     */
    00333     void clearProp(const char *key) const {
    00334       std::string what(key);
    00335       clearProp(what);
    00336     };
    00337     //! \overload
    00338     void clearProp(const std::string key) const {
    00339       if(hasProp("computedProps")){
    00340         STR_VECT compLst;
    00341         getProp("computedProps", compLst);
    00342         STR_VECT_I svi = std::find(compLst.begin(), compLst.end(), key);
    00343         if (svi != compLst.end()) {
    00344           compLst.erase(svi);
    00345           dp_props->setVal("computedProps", compLst);
    00346         }
    00347       }
    00348       dp_props->clearVal(key);
    00349     };
    00350
    00351     //! clears all of our \c computed \c properties
    00352     void clearComputedProps() const {
    00353       if(!hasProp("computedProps")) return;
    00354       STR_VECT compLst;
    00355       getProp("computedProps", compLst);
    00356       STR_VECT_CI svi;
    00357       for (svi = compLst.begin(); svi != compLst.end(); svi++) {
    00358         dp_props->clearVal(*svi);
    00359       }
    00360       compLst.clear();
    00361       dp_props->setVal("computedProps", compLst);
    00362     }
    00363
    00364     //! returns the perturbation order for a list of integers
    00365     /*!
    00366
    00367       This value is associated with chirality.
    00368
    00369       \param probe a list of bond indices.  This must be the same
    00370         length as our number of incoming bonds (our degree).
    00371
    00372       \return the number of swaps required to convert the ordering
    00373         of the probe list to match the order of our incoming bonds:
    00374         e.g. if our incoming bond order is: <tt>[0,1,2,3]</tt>
    00375         \verbatim
    00376         getPerturbationOrder([1,0,2,3]) = 1
    00377         getPerturbationOrder([1,2,3,0]) = 3
    00378         getPerturbationOrder([1,2,0,3]) = 2
    00379         \endverbatim
    00380
    00381       See the class documentation for a more detailed description
    00382       of our representation of chirality.
    00383
    00384       <b>Notes:</b>
    00385         - requires an owning molecule
    00386
    00387     */
    00388     int getPerturbationOrder(INT_LIST probe) const;
    00389
    00390     //! calculates any of our lazy \c properties
    00391     /*!
    00392       <b>Notes:</b>
    00393         - requires an owning molecule
    00394         - the current lazy \c properties are implicit and explicit valence
    00395     */
    00396     void updatePropertyCache(bool strict=true);
    00397
    00398     //! calculates and returns our explicit valence
    00399     /*!
    00400       <b>Notes:</b>
    00401         - requires an owning molecule
    00402     */
    00403     int calcExplicitValence(bool strict=true);
    00404
    00405     //! calculates and returns our implicit valence
    00406     /*!
    00407       <b>Notes:</b>
    00408         - requires an owning molecule
    00409     */
    00410     int calcImplicitValence(bool strict=true);
    00411
    00412   protected:
    00413     //! sets our owning molecule
    00414     void setOwningMol(ROMol *other);
    00415     //! sets our owning molecule
    00416     void setOwningMol(ROMol &other) {setOwningMol(&other);};
    00417
    00418     bool df_isAromatic;
    00419     bool df_noImplicit;
    00420     int d_dativeFlag;
    00421     unsigned int d_numExplicitHs;
    00422     int d_formalCharge;
    00423     unsigned int d_atomicNum;
    00424     unsigned int d_index;
    00425     // NOTE that these cannot be signed ints, they are calculated using
    00426     // a lazy scheme and are initialized to -1 to indicate that the
    00427     // calculation has not yet been done.
    00428     int d_implicitValence, d_explicitValence;
    00429     ChiralType d_chiralTag;
    00430     HybridizationType d_hybrid;
    00431     double d_mass;
    00432     ROMol *dp_mol;
    00433     Dict *dp_props;
    00434     void initAtom();
    00435   };
    00436
    00437 };
    00438 //! allows Atom objects to be dumped to streams
    00439 std::ostream & operator<<(std::ostream& target, const RDKit::Atom &at);
    00440
    00441 #endif