Bond.h

Go to the documentation of this file.
00001 //
00002 //  Copyright (C) 2001-2006 Greg Landrum and Rational Discovery LLC
00003 //
00004 //   @@ All Rights Reserved  @@
00005 //
00006 #ifndef _RD_BOND_H
00007 #define _RD_BOND_H
00008 
00009 // std stuff
00010 #include <iostream>
00011 
00012 // Ours
00013 // FIX: grn...
00014 #include <Query/QueryObjects.h>
00015 #include <RDGeneral/types.h>
00016 
00017 namespace RDKit{
00018   class ROMol;
00019   class RWMol;
00020   class Atom;
00021   typedef boost::shared_ptr<Atom>    ATOM_SPTR;
00022 
00023   //! class for representing a bond
00024   /*!
00025 
00026     <b>Notes:</b>
00027       - many of the methods of Atom require that the Atom be associated
00028         with a molecule (an ROMol).
00029       - each Bond maintains a Dict of \c properties:  
00030           - Each \c property is keyed by name and can store an
00031             arbitrary type.
00032           - \c Properties can be marked as \c calculated, in which case
00033             they will be cleared when the \c clearComputedProps() method
00034             is called.
00035           - Because they have no impact upon chemistry, all \c property
00036             operations are \c const, this allows extra flexibility for
00037             clients who need to store extra data on Bond objects.
00038 
00039   */
00040   class Bond {
00041     friend class RWMol;
00042     friend class ROMol;
00043   public:
00044     typedef boost::shared_ptr<Bond>    BOND_SPTR;
00045     // FIX: grn...
00046     typedef Queries::Query<int,Bond const *,true> QUERYBOND_QUERY;
00047 
00048     //! the type of Bond
00049     typedef enum {
00050       UNSPECIFIED = 0,
00051       SINGLE,
00052       DOUBLE,
00053       TRIPLE,
00054       QUADRUPLE,
00055       QUINTUPLE,
00056       HEXTUPLE,
00057       ONEANDAHALF,
00058       TWOANDAHALF,
00059       THREEANDAHALF,
00060       FOURANDAHALF,
00061       FIVEANDAHALF,
00062       AROMATIC,
00063       IONIC,
00064       HYDROGEN,
00065       THREECENTER,
00066       DATIVEONE,   //!< one-electron dative (e.g. from a C in a Cp ring to a metal)
00067       DATIVE,      //!< standard two-electron dative
00068       DATIVEL,     //!< standard two-electron dative
00069       DATIVER,     //!< standard two-electron dative
00070       OTHER
00071     } BondType;
00072 
00073     //! the bond's direction (for chirality)
00074     typedef enum {   
00075       NONE=0,         //!< no special style
00076       BEGINWEDGE,     //!< wedged: narrow at begin
00077       BEGINDASH,      //!< dashed: narrow at begin
00078       // FIX: this may not really be adequate
00079       ENDDOWNRIGHT,   //!< for cis/trans
00080       ENDUPRIGHT,     //!<  ditto
00081       EITHERDOUBLE,   //!< a "crossed" double bond 
00082       UNKNOWN,        //!< intentionally unspecified stereochemistry
00083     } BondDir;
00084     
00085     //! the nature of the bond's stereochem (for cis/trans)
00086     typedef enum {   // stereochemistry of double bonds
00087       STEREONONE=0,  // no special style
00088       STEREOANY,     // intentionally unspecified
00089       // -- Put any true specifications about this point so
00090       // that we can do comparisons like if(bond->getStereo()>Bond::STEREOANY) 
00091       STEREOZ,       // Z double bond
00092       STEREOE,       // E double bond
00093     } BondStereo;
00094     
00095     Bond();
00096     //! construct with a particular BondType
00097     explicit Bond(BondType bT);
00098     Bond(const Bond &other);
00099     virtual ~Bond();
00100     Bond &operator=(const Bond &other);
00101 
00102     //! returns a copy
00103     /*!
00104       <b>Note:</b> the caller is responsible for <tt>delete</tt>ing
00105        the returned pointer.
00106     */
00107     virtual Bond *copy() const;
00108 
00109     //! returns our \c bondType
00110     const BondType getBondType() const { return d_bondType; };
00111     //! sets our \c bondType
00112     void setBondType(BondType bT) { d_bondType = bT; };
00113     //! \brief returns our \c bondType as a double
00114     //!   (e.g. SINGLE->1.0, AROMATIC->1.5, etc.)
00115     double getBondTypeAsDouble() const;
00116 
00117     //! returns our contribution to the explicit valence of an Atom
00118     /*!
00119       <b>Notes:</b>
00120         - requires an owning molecule
00121     */
00122     double getValenceContrib(const Atom *at) const;
00123     // \overload
00124     double getValenceContrib(ATOM_SPTR at) const;
00125 
00126     //! sets our \c isAromatic flag
00127     void setIsAromatic( bool what ) { df_isAromatic = what; };
00128     //! returns the status of our \c isAromatic flag
00129     bool getIsAromatic() const { return df_isAromatic; };
00130 
00131     //! sets our \c isConjugated flag
00132     void setIsConjugated(bool what) {df_isConjugated = what;};
00133     //! returns the status of our \c isConjugated flag
00134     bool getIsConjugated() const {return df_isConjugated;};
00135   
00136     //! returns a reference to the ROMol that owns this Bond
00137     ROMol &getOwningMol() const { return *dp_mol; };
00138     //! sets our owning molecule
00139     void setOwningMol(ROMol *other);
00140     //! sets our owning molecule
00141     void setOwningMol(ROMol &other) {setOwningMol(&other);};
00142 
00143     //! returns our index within the ROMol
00144     /*!
00145       <b>Notes:</b>
00146         - this makes no sense if we do not have an owning molecule
00147 
00148     */
00149     unsigned int getIdx() const {return d_index;};
00150     //! sets our index within the ROMol
00151     /*!
00152       <b>Notes:</b>
00153         - this makes no sense if we do not have an owning molecule
00154         - the index should be <tt>< this->getOwningMol()->getNumBonds()</tt>
00155     */
00156     void setIdx(unsigned int index) {d_index=index;};
00157 
00158     //! returns the index of our begin Atom
00159     /*!
00160       <b>Notes:</b>
00161         - this makes no sense if we do not have an owning molecule
00162     */
00163     unsigned int getBeginAtomIdx() const { return d_beginAtomIdx; };
00164 
00165     //! returns the index of our end Atom
00166     /*!
00167       <b>Notes:</b>
00168         - this makes no sense if we do not have an owning molecule
00169     */
00170     unsigned int getEndAtomIdx() const { return d_endAtomIdx; };
00171 
00172     //! given the index of one Atom, returns the index of the other
00173     /*!
00174       <b>Notes:</b>
00175         - this makes no sense if we do not have an owning molecule
00176     */
00177     unsigned int getOtherAtomIdx(unsigned int thisIdx) const;
00178 
00179     //! sets the index of our begin Atom
00180     /*!
00181       <b>Notes:</b>
00182         - requires an owning molecule
00183     */
00184     void setBeginAtomIdx(unsigned int what);
00185     //! sets the index of our end Atom
00186     /*!
00187       <b>Notes:</b>
00188         - requires an owning molecule
00189     */
00190     void setEndAtomIdx(unsigned int what);
00191 
00192     //! sets our begin Atom
00193     /*!
00194       <b>Notes:</b>
00195         - requires an owning molecule
00196     */
00197     void setBeginAtom(Atom *at);
00198     //! \overload
00199     void setBeginAtom(ATOM_SPTR at);
00200     //! sets our end Atom
00201     /*!
00202       <b>Notes:</b>
00203         - requires an owning molecule
00204     */
00205     void setEndAtom(Atom *at);
00206     //! \overload
00207     void setEndAtom(ATOM_SPTR at);
00208 
00209 
00210     //! returns a pointer to our begin Atom
00211     /*!
00212       <b>Notes:</b>
00213         - requires an owning molecule
00214     */
00215     Atom *getBeginAtom() const;
00216     //! returns a pointer to our end Atom
00217     /*!
00218       <b>Notes:</b>
00219         - requires an owning molecule
00220     */
00221     Atom *getEndAtom() const;
00222     //! returns a pointer to the other Atom
00223     /*!
00224       <b>Notes:</b>
00225         - requires an owning molecule
00226     */
00227     Atom *getOtherAtom(Atom const *what) const;
00228 
00229     // ------------------------------------
00230     // Please see the note in Atom.h for some explanation
00231     // of these methods
00232     // ------------------------------------
00233   
00234     // This method can be used to distinguish query bonds from standard bonds
00235     virtual bool hasQuery() const { return false; };
00236 
00237     // FIX: the const crap here is all mucked up.
00238     //! NOT CALLABLE
00239     virtual void setQuery(QUERYBOND_QUERY *what);
00240     //! NOT CALLABLE
00241     virtual QUERYBOND_QUERY *getQuery() const;
00242 
00243     //! NOT CALLABLE
00244     void expandQuery(QUERYBOND_QUERY *what,
00245                      Queries::CompositeQueryType how=Queries::COMPOSITE_AND,
00246                      bool maintainOrder=true);
00247 
00248     //! returns whether or not we match the argument
00249     /*!
00250         <b>Notes:</b>
00251           - for Bond objects, "match" means that either one of the Bonds
00252             has \c bondType Bond::UNSPECIFIED or both Bonds have the
00253             same \c bondType.
00254     */
00255     virtual bool Match(Bond const *what) const;
00256     //! \overload
00257     virtual bool Match(const Bond::BOND_SPTR what) const;
00258   
00259     //! sets our direction
00260     void setBondDir(BondDir what) { d_dirTag = what; };
00261     //! returns our direction
00262     BondDir getBondDir() const { return d_dirTag; };
00263   
00264     //! sets our stereo code
00265     void setStereo(BondStereo what) { d_stereo = what; };
00266     //! returns our stereo code
00267     BondStereo getStereo() const { return d_stereo; };
00268 
00269     //! returns the indices of our stereo atoms
00270     const INT_VECT &getStereoAtoms() const { return d_stereoAtoms; };
00271     //! \overload
00272     INT_VECT &getStereoAtoms() { return d_stereoAtoms; };
00273   
00274     // ------------------------------------
00275     //  Local Property Dict functionality
00276     //  FIX: at some point this stuff should go in a mixin class
00277     // ------------------------------------
00278     //! returns a list with the names of our \c properties
00279     STR_VECT getPropList() const {
00280       return dp_props->keys();
00281     }
00282 
00283     //! sets a \c property value
00284     /*!
00285        \param key the name under which the \c property should be stored.
00286            If a \c property is already stored under this name, it will be
00287            replaced.
00288        \param val the value to be stored
00289        \param computed (optional) allows the \c property to be flagged
00290            \c computed.
00291      */
00292     template <typename T>
00293     void setProp(const char *key,T val, bool computed=false) const{
00294       //if(!dp_props) dp_props = new Dict();
00295       std::string what(key);
00296       setProp(what,val, computed);
00297     }
00298     //! \overload
00299     template <typename T>
00300     void setProp(const std::string key,T val, bool computed=false ) const{
00301       //setProp(key.c_str(),val);
00302       if (computed) {
00303         STR_VECT compLst;
00304         if(hasProp("computedProps")) getProp("computedProps", compLst);
00305         if (std::find(compLst.begin(), compLst.end(), key) == compLst.end()) {
00306           compLst.push_back(key);
00307           dp_props->setVal("computedProps", compLst);
00308         }
00309       }
00310       dp_props->setVal(key,val);
00311     }
00312 
00313     //! allows retrieval of a particular property value
00314     /*!
00315 
00316        \param key the name under which the \c property should be stored.
00317            If a \c property is already stored under this name, it will be
00318            replaced.
00319        \param res a reference to the storage location for the value.
00320 
00321        <b>Notes:</b>
00322          - if no \c property with name \c key exists, a KeyErrorException will be thrown.
00323          - the \c boost::lexical_cast machinery is used to attempt type conversions.
00324            If this fails, a \c boost::bad_lexical_cast exception will be thrown.
00325 
00326     */
00327     template <typename T>
00328     void getProp(const char *key,T &res) const {
00329       PRECONDITION(dp_props,"getProp called on empty property dict");
00330       dp_props->getVal(key,res);
00331     }
00332     //! \overload
00333     template <typename T>
00334     void getProp(const std::string key,T &res) const {
00335       PRECONDITION(dp_props,"getProp called on empty property dict");
00336       dp_props->getVal(key,res);
00337     
00338     }
00339 
00340     //! returns whether or not we have a \c property with name \c key
00341     bool hasProp(const char *key) const {
00342       if(!dp_props) return false;
00343       return dp_props->hasVal(key);
00344     };
00345     //! \overload
00346     bool hasProp(const std::string key) const {
00347       if(!dp_props) return false;
00348       return dp_props->hasVal(key);
00349     };
00350 
00351     //! clears the value of a \c property
00352     /*!
00353        <b>Notes:</b>
00354          - if no \c property with name \c key exists, a KeyErrorException
00355            will be thrown.
00356          - if the \c property is marked as \c computed, it will also be removed
00357            from our list of \c computedProperties
00358     */
00359     void clearProp(const char *key) const {
00360       std::string what(key);
00361       clearProp(what);
00362     };
00363     //! \overload
00364     void clearProp(const std::string key) const {
00365       if(hasProp("computedProps")){
00366         STR_VECT compLst;
00367         getProp("computedProps", compLst);
00368         STR_VECT_I svi = std::find(compLst.begin(), compLst.end(), key);
00369         if (svi != compLst.end()) {
00370           compLst.erase(svi);
00371           dp_props->setVal("computedProps", compLst);
00372         }
00373       }
00374       dp_props->clearVal(key);
00375     };
00376 
00377     //! clears all of our \c computed \c properties
00378     void clearComputedProps() const {
00379       if(!hasProp("computedProps")) return;
00380       STR_VECT compLst;
00381       getProp("computedProps", compLst);
00382       STR_VECT_CI svi;
00383       for (svi = compLst.begin(); svi != compLst.end(); svi++) {
00384         dp_props->clearVal(*svi);
00385       }
00386       compLst.clear();
00387       dp_props->setVal("computedProps", compLst);
00388     }
00389 
00390     //! calculates any of our lazy \c properties
00391     /*!
00392       <b>Notes:</b>
00393         - requires an owning molecule
00394     */
00395     void updatePropertyCache(bool strict=true) {;};
00396 
00397   protected:
00398     //! sets our owning molecule
00399     //void setOwningMol(ROMol *other);
00400     //! sets our owning molecule
00401     //void setOwningMol(ROMol &other) {setOwningMol(&other);};
00402     BondType d_bondType;
00403     ROMol *dp_mol;
00404     bool df_isAromatic;
00405     bool df_isConjugated;
00406     unsigned int d_index;
00407     unsigned int d_beginAtomIdx,d_endAtomIdx;
00408     BondDir d_dirTag;
00409     BondStereo d_stereo;
00410     INT_VECT d_stereoAtoms;
00411     //Atom::ATOM_SPTR dsp_beginAtom,dsp_endAtom;
00412     Dict *dp_props;
00413 
00414     void initBond();
00415   };
00416 
00417 };
00418 
00419 //! allows Bond objects to be dumped to streams
00420 extern std::ostream & operator<<(std::ostream& target, const RDKit::Bond &b);
00421 
00422 #endif

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