RDCode: ROMol.h Source File

- Main Page
- Namespaces
- Classes
- Files
- Directories

# ROMol.h

Go to the documentation of this file.

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