RDCode: ROMol.h Source File

# ROMol.h

Go to the documentation of this file.

    00001 //
    00002 //  Copyright (C) 2003-2009 Greg Landrum and Rational Discovery LLC
    00003 //
    00004 //   @@ All Rights Reserved  @@
    00005 //
    00006 /*! \file ROMol.h
    00007
    00008   \brief Defines the primary molecule class \c ROMol as well as associated typedefs
    00009
    00010 */
    00011
    00012 #ifndef __RD_ROMOL_H__
    00013 #define __RD_ROMOL_H__
    00014
    00015 /// Std stuff
    00016 #include <utility>
    00017 #include <map>
    00018
    00019 // boost stuff
    00020 #include <boost/graph/adjacency_list.hpp>
    00021 #include <boost/smart_ptr.hpp>
    00022
    00023 // our stuff
    00024 #include "Atom.h"
    00025 #include "Bond.h"
    00026
    00027 #include "Conformer.h"
    00028
    00029 namespace RDKit{
    00030   class Atom;
    00031   class Bond;
    00032   typedef boost::shared_ptr<Atom>    ATOM_SPTR;
    00033   typedef boost::shared_ptr<Bond>    BOND_SPTR;
    00034
    00035   //! This is the BGL type used to store the topology:
    00036   typedef boost::adjacency_list< boost::vecS,
    00037                                  boost::vecS,
    00038                                  boost::undirectedS,
    00039                                  ATOM_SPTR,
    00040                                  BOND_SPTR> MolGraph;
    00041   class MolPickler;
    00042   class RWMol;
    00043   class QueryAtom;
    00044   class QueryBond;
    00045   class RingInfo;
    00046
    00047   template <class T1,class T2>
    00048   class AtomIterator_;
    00049   class BondIterator_;
    00050   class ConstBondIterator_;
    00051
    00052   template <class T1,class T2>
    00053   class AromaticAtomIterator_;
    00054   template <class T1,class T2>
    00055   class HeteroatomIterator_;
    00056   template <class T1,class T2>
    00057   class QueryAtomIterator_;
    00058
    00059
    00060
    00061
    00062   extern const int ci_RIGHTMOST_ATOM;
    00063   extern const int ci_LEADING_BOND;
    00064   extern const int ci_ATOM_HOLDER;
    00065
    00066
    00067   //! ROMol is a molecule class that is intended to have a fixed topology
    00068   /*!
    00069     This is the primary class for most molecule operations.
    00070
    00071     If you need to be manipulating the molecule (e.g. adding or deleting
    00072     atoms or bonds, use an RWMol instead.
    00073
    00074     <b>Notes:</b>
    00075       - each ROMol maintains a Dict of \c properties:
    00076           - Each \c property is keyed by name and can store an
    00077             arbitrary type.
    00078           - \c Properties can be marked as \c calculated, in which case
    00079             they will be cleared when the \c clearComputedProps() method
    00080             is called.
    00081           - Because they have no impact upon chemistry, all \c property
    00082             operations are \c const, this allows extra flexibility for
    00083             clients who need to store extra data on ROMol objects.
    00084
    00085       - each ROMol has collections of \c bookmarks for Atoms and Bonds:
    00086           - the Atom bookmarks and Bond bookmarks are stored separately
    00087             from each other
    00088           - each \c bookmark, an integer, can map to more than one
    00089             Atom or Bond
    00090           - these are currently used in molecule construction, but
    00091             could also be useful for reaction mapping and the like
    00092
    00093       - information about rings (SSSR and the like) is stored in the
    00094         molecule's RingInfo pointer.
    00095
    00096    */
    00097
    00098   class ROMol {
    00099   public:
    00100     friend class MolPickler;
    00101     friend class RWMol;
    00102
    00103     //! \cond TYPEDEFS
    00104
    00105     //! \name typedefs
    00106     //@{
    00107     typedef MolGraph::vertex_descriptor vertex_descriptor;
    00108     typedef MolGraph::edge_descriptor edge_descriptor;
    00109
    00110     typedef MolGraph::edge_iterator EDGE_ITER;
    00111     typedef MolGraph::out_edge_iterator OEDGE_ITER;
    00112     typedef MolGraph::vertex_iterator VERTEX_ITER;
    00113     typedef MolGraph::adjacency_iterator ADJ_ITER;
    00114     typedef std::pair<EDGE_ITER,EDGE_ITER> BOND_ITER_PAIR;
    00115     typedef std::pair<OEDGE_ITER,OEDGE_ITER> OBOND_ITER_PAIR;
    00116     typedef std::pair<VERTEX_ITER,VERTEX_ITER> ATOM_ITER_PAIR;
    00117     typedef std::pair<ADJ_ITER,ADJ_ITER> ADJ_ITER_PAIR;
    00118
    00119     typedef std::vector<ATOM_SPTR> ATOM_SPTR_VECT;
    00120     typedef ATOM_SPTR_VECT::iterator ATOM_SPTR_VECT_I;
    00121     typedef ATOM_SPTR_VECT::const_iterator ATOM_SPTR_VECT_CI;
    00122     typedef std::vector<BOND_SPTR> BOND_SPTR_VECT;
    00123     typedef BOND_SPTR_VECT::iterator BOND_SPTR_VECT_I;
    00124     typedef BOND_SPTR_VECT::const_iterator BOND_SPTR_VECT_CI;
    00125
    00126     typedef std::vector<Atom *> ATOM_PTR_VECT;
    00127     typedef ATOM_PTR_VECT::iterator ATOM_PTR_VECT_I;
    00128     typedef ATOM_PTR_VECT::const_iterator ATOM_PTR_VECT_CI;
    00129     typedef std::vector<Bond *> BOND_PTR_VECT;
    00130     typedef BOND_PTR_VECT::iterator BOND_PTR_VECT_I;
    00131     typedef BOND_PTR_VECT::const_iterator BOND_PTR_VECT_CI;
    00132
    00133     typedef std::list<Atom *> ATOM_PTR_LIST;
    00134     typedef ATOM_PTR_LIST::iterator ATOM_PTR_LIST_I;
    00135     typedef ATOM_PTR_LIST::const_iterator ATOM_PTR_LIST_CI;
    00136     typedef std::list<Bond *> BOND_PTR_LIST;
    00137     typedef BOND_PTR_LIST::iterator BOND_PTR_LIST_I;
    00138     typedef BOND_PTR_LIST::const_iterator BOND_PTR_LIST_CI;
    00139
    00140     // list of conformations
    00141     typedef std::list<CONFORMER_SPTR> CONF_SPTR_LIST;
    00142     typedef CONF_SPTR_LIST::iterator CONF_SPTR_LIST_I;
    00143     typedef CONF_SPTR_LIST::const_iterator CONF_SPTR_LIST_CI;
    00144     typedef std::pair<CONF_SPTR_LIST_I, CONF_SPTR_LIST_I> CONFS_I_PAIR;
    00145
    00146     // ROFIX: these will need to be readonly somehow?
    00147     typedef std::map<int,ATOM_PTR_LIST> ATOM_BOOKMARK_MAP;
    00148     typedef std::map<int,BOND_PTR_LIST> BOND_BOOKMARK_MAP;
    00149
    00150     typedef class AtomIterator_<Atom,ROMol> AtomIterator;
    00151     typedef class AtomIterator_<const Atom,const ROMol> ConstAtomIterator;
    00152     typedef class BondIterator_ BondIterator;
    00153     typedef class ConstBondIterator_ ConstBondIterator;
    00154     typedef class AromaticAtomIterator_<Atom,ROMol> AromaticAtomIterator;
    00155     typedef class AromaticAtomIterator_<const Atom,const ROMol> ConstAromaticAtomIterator;
    00156     typedef class HeteroatomIterator_<Atom,ROMol> HeteroatomIterator;
    00157     typedef class HeteroatomIterator_<const Atom,const ROMol> ConstHeteroatomIterator;
    00158     typedef class QueryAtomIterator_<Atom,ROMol> QueryAtomIterator;
    00159     typedef class QueryAtomIterator_<const Atom,const ROMol> ConstQueryAtomIterator;
    00160
    00161
    00162     typedef CONF_SPTR_LIST_I ConformerIterator;
    00163     typedef  CONF_SPTR_LIST_CI ConstConformerIterator;
    00164
    00165     //@}
    00166     //! \endcond
    00167
    00168     ROMol() { initMol(); }
    00169
    00170     //! copy constructor with a twist
    00171     /*!
    00172       \param other     the molecule to be copied
    00173       \param quickCopy (optional) if this is true, the resulting ROMol will not
    00174            copy any of the properties or bookmarks and conformers from \c other.  This can
    00175            make the copy substantially faster (thus the name).
    00176     */
    00177     ROMol(const ROMol &other,bool quickCopy=false) {dp_props=0;dp_ringInfo=0;initFromOther(other,quickCopy);};
    00178     //! construct a molecule from a pickle string
    00179     ROMol(const std::string &binStr);
    00180
    00181     virtual ~ROMol() { destroy(); };
    00182
    00183
    00184     //! \name Atoms
    00185     //@{
    00186
    00187     //! returns our number of Atoms
    00188     unsigned int getNumAtoms(bool onlyHeavy=1) const;
    00189     //! returns a pointer to a particular Atom
    00190     Atom *getAtomWithIdx(unsigned int idx);
    00191     //! \overload
    00192     const Atom *getAtomWithIdx(unsigned int idx) const;
    00193     //! returns the degree (number of neighbors) of an Atom in the graph
    00194     unsigned int getAtomDegree(const Atom *at) const;
    00195     //! \overload
    00196     unsigned int getAtomDegree(ATOM_SPTR at) const;
    00197     //@}
    00198
    00199     //! \name Bonds
    00200     //@{
    00201
    00202     //! returns our number of Bonds
    00203     unsigned int getNumBonds(bool onlyHeavy=1) const;
    00204     //! returns a pointer to a particular Bond
    00205     Bond *getBondWithIdx(unsigned int idx);
    00206     //! \overload
    00207     const Bond * getBondWithIdx(unsigned int idx) const;
    00208     //! returns a pointer to the bond between two atoms, Null on failure
    00209     Bond *getBondBetweenAtoms(unsigned int idx1,unsigned int idx2);
    00210     //! \overload
    00211     const Bond *getBondBetweenAtoms(unsigned int idx1,unsigned int idx2) const;
    00212     //@}
    00213
    00214
    00215     //! \name Bookmarks
    00216     //@{
    00217
    00218     //! associates an Atom pointer with a bookmark
    00219     void setAtomBookmark(ATOM_SPTR at,int mark) {d_atomBookmarks[mark].push_back(at.get());};
    00220     //! \overload
    00221     void setAtomBookmark(Atom *at,int mark) {d_atomBookmarks[mark].push_back(at);};
    00222     //! returns the first Atom associated with the \c bookmark provided
    00223     Atom *getAtomWithBookmark(int mark);
    00224     //! returns all Atoms associated with the \c bookmark provided
    00225     ATOM_PTR_LIST &getAllAtomsWithBookmark(int mark);
    00226     //! removes a \c bookmark from our collection
    00227     void clearAtomBookmark(const int mark);
    00228     //! removes a particular Atom from the list associated with the \c bookmark
    00229     void clearAtomBookmark(const int mark,const Atom *atom);
    00230     //! \overload
    00231     void clearAtomBookmark(const int mark,ATOM_SPTR atom) {clearAtomBookmark(mark,atom.get());};
    00232     //! blows out all atomic \c bookmarks
    00233     void clearAllAtomBookmarks() { d_atomBookmarks.clear(); };
    00234     //! queries whether or not any atoms are associated with a \c bookmark
    00235     bool hasAtomBookmark(int mark) const {return d_atomBookmarks.count(mark);};
    00236     //! returns a pointer to all of our atom \c bookmarks
    00237     ATOM_BOOKMARK_MAP *getAtomBookmarks() { return &d_atomBookmarks; };
    00238
    00239     //! associates a Bond pointer with a bookmark
    00240     void setBondBookmark(BOND_SPTR bond,int mark) {d_bondBookmarks[mark].push_back(bond.get());};
    00241     //! \overload
    00242     void setBondBookmark(Bond *bond,int mark) {d_bondBookmarks[mark].push_back(bond);};
    00243     //! returns the first Bond associated with the \c bookmark provided
    00244     Bond *getBondWithBookmark(int mark);
    00245     //! returns all bonds associated with the \c bookmark provided
    00246     BOND_PTR_LIST &getAllBondsWithBookmark(int mark);
    00247     //! removes a \c bookmark from our collection
    00248     void clearBondBookmark(int mark);
    00249     //! removes a particular Bond from the list associated with the \c bookmark
    00250     void clearBondBookmark(int mark,const Bond *bond);
    00251     //! \overload
    00252     void clearBondBookmark(int mark,BOND_SPTR bond) {clearBondBookmark(mark,bond.get());};
    00253     //! blows out all bond \c bookmarks
    00254     void clearAllBondBookmarks() { d_bondBookmarks.clear(); };
    00255     //! queries whether or not any bonds are associated with a \c bookmark
    00256     bool hasBondBookmark(int mark) const {return d_bondBookmarks.count(mark);};
    00257     //! returns a pointer to all of our bond \c bookmarks
    00258     BOND_BOOKMARK_MAP *getBondBookmarks() { return &d_bondBookmarks; };
    00259
    00260     //@}
    00261
    00262
    00263     //! \name Conformers
    00264     //@{
    00265
    00266     //! return the conformer with a specified ID
    00267     //! if the ID is negative the first conformation will be returned
    00268     const Conformer &getConformer(int id=-1) const;
    00269
    00270     //! return the conformer with a specified ID
    00271     //! if the ID is negative the first conformation will be returned
    00272     Conformer &getConformer(int id=-1);
    00273
    00274     //! Delete the conformation with the specified ID
    00275     void removeConformer(unsigned int id);
    00276
    00277     //! Clear all the conformations on the molecule
    00278     void clearConformers() {d_confs.clear();}
    00279
    00280     //! Add a new conformation to the molecule
    00281     /*!
    00282       \param conf - conformation to be added to the molecule, this molecule takes ownership
    00283                     of the conformer
    00284       \param assignId - a unique ID will be assigned to the the conformation if true
    00285                         otherwise it is assumed that the conformation already has an (unique) ID set
    00286     */
    00287     unsigned int addConformer(Conformer * conf, bool assignId=false);
    00288
    00289     inline unsigned int getNumConformers() const {
    00290       return d_confs.size();
    00291     }
    00292
    00293     //@}
    00294
    00295
    00296     //! \name Topology
    00297     //@{
    00298
    00299     //! returns a pointer to our RingInfo structure
    00300     //! <b>Note:</b> the client should not delete this.
    00301     RingInfo *getRingInfo() const { return dp_ringInfo; };
    00302
    00303     //! provides access to all neighbors around an Atom
    00304     /*!
    00305       \param at the atom whose neighbors we are looking for
    00306
    00307       <b>Usage</b>
    00308       \code
    00309         ... molPtr is a const ROMol & ...
    00310         ... atomPtr is a const Atom * ...
    00311         ROMol::ADJ_ITER nbrIdx,endNbrs;
    00312         boost::tie(nbrIdx,endNbrs) = molPtr.getAtomNeighbors(atomPtr);
    00313         while(nbrIdx!=endNbrs){
    00314           const ATOM_SPTR at=molPtr[*nbrIdx];
    00315           ... do something with the Atom ...
    00316           ++nbrIdx;
    00317         }
    00318       \endcode
    00319
    00320     */
    00321     ADJ_ITER_PAIR getAtomNeighbors(Atom const *at) const;
    00322     //! \overload
    00323     ADJ_ITER_PAIR getAtomNeighbors(ATOM_SPTR at) const;
    00324
    00325     //! provides access to all Bond objects connected to an Atom
    00326     /*!
    00327       \param at the atom whose neighbors we are looking for
    00328
    00329       <b>Usage</b>
    00330       \code
    00331         ... molPtr is a const ROMol * ...
    00332         ... atomPtr is a const Atom * ...
    00333         ROMol::OEDGE_ITER beg,end;
    00334         boost::tie(beg,end) = molPtr->getAtomBonds(atomPtr);
    00335         while(beg!=end){
    00336           const BOND_SPTR bond=(*molPtr)[*beg];
    00337           ... do something with the Bond ...
    00338           ++beg;
    00339         }
    00340       \endcode
    00341       or, if you need a non-const Bond *:
    00342       \code
    00343         ... molPtr is a ROMol * ...
    00344         ... atomPtr is a const Atom * ...
    00345         ROMol::OEDGE_ITER beg,end;
    00346         boost::tie(beg,end) = molPtr->getAtomBonds(atomPtr);
    00347         while(beg!=end){
    00348           BOND_SPTR bond=(*molPtr)[*beg];
    00349           ... do something with the Bond ...
    00350           ++beg;
    00351         }
    00352       \endcode
    00353
    00354
    00355     */
    00356     OBOND_ITER_PAIR getAtomBonds(Atom const *at) const;
    00357
    00358     //! returns an iterator pair for looping over all Atoms
    00359     /*!
    00360
    00361       <b>Usage</b>
    00362       \code
    00363
    00364         ROMol::VERTEX_ITER atBegin,atEnd;
    00365         boost::tie(atBegin,atEnd) = mol.getVertices();
    00366         while(atBegin!=atEnd){
    00367           ATOM_SPTR at2=mol[*atBegin];
    00368           ... do something with the Atom ...
    00369           ++atBegin;
    00370         }
    00371       \endcode
    00372     */
    00373     ATOM_ITER_PAIR getVertices();
    00374     //! returns an iterator pair for looping over all Bonds
    00375     /*!
    00376
    00377       <b>Usage</b>
    00378       \code
    00379
    00380         ROMol::EDGE_ITER firstB,lastB;
    00381         boost::tie(firstB,lastB) = mol.getEdges();
    00382         while(firstB!=lastB){
    00383           BOND_SPTR bond = mol[*firstB];
    00384           ... do something with the Bond ...
    00385           ++firstB;
    00386         }
    00387       \endcode
    00388     */
    00389     BOND_ITER_PAIR getEdges();
    00390     //! \overload
    00391     ATOM_ITER_PAIR getVertices() const;
    00392     //! \overload
    00393     BOND_ITER_PAIR getEdges() const;
    00394
    00395     //! brief returns a pointer to our underlying BGL object
    00396     /*!
    00397         This can be useful if you need to call other BGL algorithms:
    00398
    00399         Here's an example:
    00400         \code
    00401            ... mol is a const ROMol ...
    00402            ... mapping is an INT_VECT ...
    00403            mapping.resize(mol.getNumAtoms());
    00404            const MolGraph &G_p = mol.getTopology();
    00405            int res = boost::connected_components(G_p,&mapping[0]);
    00406         \endcode
    00407      */
    00408     MolGraph const &getTopology() const { return d_graph; };
    00409     //@}
    00410
    00411
    00412     //! \name Iterators
    00413     //@{
    00414
    00415     //! get an AtomIterator pointing at our first Atom
    00416     AtomIterator beginAtoms();
    00417     //! \overload
    00418     ConstAtomIterator beginAtoms() const;
    00419     //! get an AtomIterator pointing at the end of our Atoms
    00420     AtomIterator endAtoms();
    00421     //! \overload
    00422     ConstAtomIterator endAtoms() const;
    00423     //! get a BondIterator pointing at our first Bond
    00424     BondIterator beginBonds();
    00425     //! \overload
    00426     ConstBondIterator beginBonds() const;
    00427     //! get a BondIterator pointing at the end of our Bonds
    00428     BondIterator endBonds();
    00429     //! \overload
    00430     ConstBondIterator endBonds() const;
    00431
    00432     //! get an AtomIterator pointing at our first aromatic Atom
    00433     AromaticAtomIterator beginAromaticAtoms();
    00434     //! \overload
    00435     ConstAromaticAtomIterator beginAromaticAtoms() const;
    00436     //! get an AtomIterator pointing at the end of our Atoms
    00437     AromaticAtomIterator endAromaticAtoms();
    00438     //! \overload
    00439     ConstAromaticAtomIterator endAromaticAtoms() const;
    00440
    00441     //! get an AtomIterator pointing at our first hetero Atom
    00442     HeteroatomIterator beginHeteros();
    00443     //! \overload
    00444     ConstHeteroatomIterator beginHeteros() const;
    00445     //! get an AtomIterator pointing at the end of our Atoms
    00446     HeteroatomIterator endHeteros();
    00447     //! \overload
    00448     ConstHeteroatomIterator endHeteros() const;
    00449
    00450     //! get an AtomIterator pointing at our first Atom that matches \c query
    00451     QueryAtomIterator beginQueryAtoms(QueryAtom const *query);
    00452     //! \overload
    00453     ConstQueryAtomIterator beginQueryAtoms(QueryAtom const *) const;
    00454     //! gte an AtomIterator pointing at the end of our Atoms
    00455     QueryAtomIterator endQueryAtoms();
    00456     //! \overload
    00457     ConstQueryAtomIterator endQueryAtoms() const;
    00458
    00459     inline ConformerIterator beginConformers() {
    00460       return d_confs.begin();
    00461     }
    00462
    00463     inline ConformerIterator endConformers() {
    00464       return d_confs.end();
    00465     }
    00466
    00467     inline ConstConformerIterator beginConformers() const {
    00468       return d_confs.begin();
    00469     }
    00470
    00471     inline ConstConformerIterator endConformers() const {
    00472       return d_confs.end();
    00473     }
    00474
    00475     //@}
    00476
    00477     //! \name Properties
    00478     //@{
    00479
    00480     //! returns a list with the names of our \c properties
    00481     STR_VECT getPropList(bool includePrivate=true,
    00482                          bool includeComputed=true) const {
    00483       const STR_VECT &tmp=dp_props->keys();
    00484       STR_VECT res,computed;
    00485       if(!includeComputed && hasProp("computedProps")){
    00486         getProp("computedProps",computed);
    00487         computed.push_back("computedProps");
    00488       }
    00489
    00490       STR_VECT::const_iterator pos = tmp.begin();
    00491       while(pos!=tmp.end()){
    00492         if((includePrivate || (*pos)[0]!='_') &&
    00493          std::find(computed.begin(),computed.end(),*pos)==computed.end()){
    00494           res.push_back(*pos);
    00495         }
    00496         pos++;
    00497       }
    00498       return res;
    00499     }
    00500
    00501
    00502     //! sets a \c property value
    00503     /*!
    00504        \param key the name under which the \c property should be stored.
    00505            If a \c property is already stored under this name, it will be
    00506            replaced.
    00507        \param val the value to be stored
    00508        \param computed (optional) allows the \c property to be flagged
    00509            \c computed.
    00510      */
    00511     template <typename T>
    00512     void setProp(const char *key, T val, bool computed=false) const {
    00513       std::string what(key);
    00514       setProp(what,val, computed);
    00515     }
    00516     //! \overload
    00517     template <typename T>
    00518     void setProp(const std::string key, T val, bool computed=false) const {
    00519       if (computed) {
    00520         STR_VECT compLst;
    00521         getProp("computedProps", compLst);
    00522         if (std::find(compLst.begin(), compLst.end(), key) == compLst.end()) {
    00523           compLst.push_back(key);
    00524           dp_props->setVal("computedProps", compLst);
    00525         }
    00526       }
    00527       dp_props->setVal(key, val);
    00528     }
    00529
    00530     //! allows retrieval of a particular property value
    00531     /*!
    00532
    00533        \param key the name under which the \c property should be stored.
    00534            If a \c property is already stored under this name, it will be
    00535            replaced.
    00536        \param res a reference to the storage location for the value.
    00537
    00538        <b>Notes:</b>
    00539          - if no \c property with name \c key exists, a KeyErrorException will be thrown.
    00540          - the \c boost::lexical_cast machinery is used to attempt type conversions.
    00541            If this fails, a \c boost::bad_lexical_cast exception will be thrown.
    00542
    00543     */
    00544     template <typename T>
    00545     void getProp(const char *key, T &res) const {
    00546       dp_props->getVal(key, res);
    00547     }
    00548     //! \overload
    00549     template <typename T>
    00550     void getProp(const std::string key, T &res) const {
    00551       //getProp(key.c_str(), res);
    00552       dp_props->getVal(key, res);
    00553     }
    00554
    00555     //! returns whether or not we have a \c property with name \c key
    00556     bool hasProp(const char *key) const {
    00557       if (!dp_props) return false;
    00558       return dp_props->hasVal(key);
    00559     }
    00560     //! \overload
    00561     bool hasProp(const std::string key) const {
    00562       if (!dp_props) return false;
    00563       return dp_props->hasVal(key);
    00564       //return hasProp(key.c_str());
    00565     }
    00566
    00567     //! clears the value of a \c property
    00568     /*!
    00569        <b>Notes:</b>
    00570          - if no \c property with name \c key exists, a KeyErrorException
    00571            will be thrown.
    00572          - if the \c property is marked as \c computed, it will also be removed
    00573            from our list of \c computedProperties
    00574     */
    00575     void clearProp(const char *key) const {
    00576       std::string what(key);
    00577       clearProp(what);
    00578     };
    00579     //! \overload
    00580     void clearProp(const std::string key) const {
    00581       STR_VECT compLst;
    00582       getProp("computedProps", compLst);
    00583       STR_VECT_I svi = std::find(compLst.begin(), compLst.end(), key);
    00584       if (svi != compLst.end()) {
    00585         compLst.erase(svi);
    00586         dp_props->setVal("computedProps", compLst);
    00587       }
    00588
    00589       dp_props->clearVal(key);
    00590     };
    00591
    00592     //! clears all of our \c computed \c properties
    00593     void clearComputedProps(bool includeRings=true) const;
    00594     //! calculates any of our lazy \c properties
    00595     /*!
    00596       <b>Notes:</b>
    00597          - this calls \c updatePropertyCache() on each of our Atoms and Bonds
    00598     */
    00599     void updatePropertyCache(bool strict=true);
    00600
    00601     //@}
    00602
    00603
    00604     //! \name Misc
    00605     //@{
    00606     //! sends some debugging info to a stream
    00607     void debugMol(std::ostream& str) const;
    00608     //@}
    00609
    00610
    00611     ATOM_SPTR operator[](const vertex_descriptor &v) { return d_graph[v]; };
    00612     const ATOM_SPTR operator[](const vertex_descriptor &v)  const { return d_graph[v]; };
    00613
    00614     BOND_SPTR operator[](const edge_descriptor &e) { return d_graph[e]; };
    00615     const BOND_SPTR operator[](const edge_descriptor &e)  const { return d_graph[e]; };
    00616
    00617   private:
    00618     MolGraph d_graph;
    00619     ATOM_BOOKMARK_MAP d_atomBookmarks;
    00620     BOND_BOOKMARK_MAP d_bondBookmarks;
    00621     Dict *dp_props;
    00622     RingInfo *dp_ringInfo;
    00623     CONF_SPTR_LIST d_confs;
    00624     ROMol &operator=(const ROMol &); // disable assignment
    00625
    00626 #ifdef WIN32
    00627   protected:
    00628 #endif
    00629     void initMol();
    00630     virtual void destroy();
    00631     //! adds an Atom to our collection
    00632     /*!
    00633       \param atom          pointer to the Atom to add
    00634       \param updateLabel   (optional) if this is true, the new Atom will be
    00635                            our \c activeAtom
    00636       \param takeOwnership (optional) if this is true, we take ownership of \c atom
    00637                            instead of copying it.
    00638
    00639       \return the new number of atoms
    00640     */
    00641     unsigned int addAtom(Atom *atom,bool updateLabel=true,bool takeOwnership=false);
    00642     //! adds an Atom to our collection
    00643     /*!
    00644       \param atom          pointer to the Atom to add
    00645       \param updateLabel   (optional) if this is true, the new Atom will be
    00646                            our \c activeAtom
    00647
    00648
    00649       \return the new number of atoms
    00650
    00651       <b>Note:</b> since this is using a smart pointer, we don't need to worry about
    00652       issues of ownership.
    00653
    00654     */
    00655     unsigned int addAtom(ATOM_SPTR,bool updateLabel=true);
    00656     //! adds a Bond to our collection
    00657     /*!
    00658       \param bond          pointer to the Bond to add
    00659       \param takeOwnership (optional) if this is true, we take ownership of \c bond
    00660                            instead of copying it.
    00661
    00662       \return the new number of bonds
    00663     */
    00664     unsigned int addBond(Bond *bond,bool takeOwnership=false);
    00665     //! adds a Bond to our collection
    00666     /*!
    00667       \param bond          pointer to the Bond to add
    00668
    00669       \return the new number of bonds
    00670
    00671       <b>Note:</b> since this is using a smart pointer, we don't need to worry about
    00672       issues of ownership.
    00673     */
    00674     unsigned int addBond(BOND_SPTR bsp);
    00675
    00676
    00677     //! initializes from the contents of another molecule
    00678     /*!
    00679       \param other     the molecule to be copied
    00680       \param quickCopy (optional) if this is true, we will not
    00681            copy any of the properties or bookmarks and conformers from \c other.  This can
    00682            make the copy substantially faster (thus the name).
    00683     */
    00684     void initFromOther(const ROMol &other,bool quickCopy);
    00685
    00686   };
    00687
    00688   typedef std::vector<ROMol> MOL_VECT;
    00689   typedef boost::shared_ptr<ROMol>    ROMOL_SPTR;
    00690   typedef std::vector<ROMol *> MOL_PTR_VECT;
    00691   typedef std::vector<ROMOL_SPTR> MOL_SPTR_VECT;
    00692
    00693   typedef MOL_PTR_VECT::const_iterator MOL_PTR_VECT_CI;
    00694   typedef MOL_PTR_VECT::iterator MOL_PTR_VECT_I;
    00695
    00696 }; // end of RDKit namespace
    00697 #endif