RDCode: ROMol.h Source File

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