ROMol.h

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