RDCode: Bond.h Source File

# 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