Avogadro  1.1.0
/home/kitware/dashboards/avogadro/libavogadro/src/molecule.h
00001 /**********************************************************************
00002   Molecule - Molecule class derived from the base Primitive class
00003 
00004   Copyright (C) 2007 Donald Ephraim Curtis
00005   Copyright (C) 2008-2009 Marcus D. Hanwell
00006 
00007   This file is part of the Avogadro molecular editor project.
00008   For more information, see <http://avogadro.openmolecules.net/>
00009 
00010   Avogadro is free software; you can redistribute it and/or modify
00011   it under the terms of the GNU General Public License as published by
00012   the Free Software Foundation; either version 2 of the License, or
00013   (at your option) any later version.
00014 
00015   Avogadro is distributed in the hope that it will be useful,
00016   but WITHOUT ANY WARRANTY; without even the implied warranty of
00017   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018   GNU General Public License for more details.
00019 
00020   You should have received a copy of the GNU General Public License
00021   along with this program; if not, write to the Free Software
00022   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00023   02110-1301, USA.
00024  **********************************************************************/
00025 
00026 #ifndef MOLECULE_H
00027 #define MOLECULE_H
00028 
00029 #include <avogadro/primitive.h>
00030 
00031 // Used by the inline functions
00032 #include <QReadWriteLock>
00033 
00034 #include <vector>
00035 
00036 namespace OpenBabel {
00037   class OBAtom;
00038   class OBBond;
00039   class OBMol;
00040   class OBUnitCell;
00041 }
00042 
00043 namespace Avogadro {
00044 
00045   // Declare new classes
00046   class Atom;
00047   class Bond;
00048   class Cube;
00049   class Fragment;
00050   class Mesh;
00051   class PrimitiveList;
00052   class Residue;
00053   class ZMatrix;
00054 
00066   class MoleculePrivate;
00067   class A_EXPORT Molecule : public Primitive
00068   {
00069   Q_OBJECT
00070   public:
00076     Molecule(QObject *parent=0);
00077 
00082     Molecule(const Molecule &other);
00083 
00087     virtual ~Molecule();
00088 
00092     void update();
00093 
00102     void setFileName(const QString& name);
00103 
00107     QString fileName() const;
00121     Atom *addAtom();
00122 
00128     Atom *addAtom(unsigned long id);
00129 
00138     Atom *addAtom(int atomicNum, const Eigen::Vector3d &pos);
00139 
00147     Atom *addAtom(const Atom &other);
00148 
00152     void removeAtom(Atom *atom);
00153 
00157     void removeAtom(unsigned long id);
00158 
00163     Atom * atom(int index) const;
00164 
00168     Atom *atomById(unsigned long id) const;
00169 
00173     QList<Atom *> atoms() const;
00174 
00180     void setAtomPos(unsigned long id, const Eigen::Vector3d &vec);
00181 
00187     void setAtomPos(unsigned long id, const Eigen::Vector3d *vec);
00188 
00194     const Eigen::Vector3d * atomPos(unsigned long id) const;
00195 
00199     unsigned int numAtoms() const;
00200 
00215     Bond *addBond();
00216 
00222     Bond *addBond(unsigned long id);
00223 
00233     Bond *addBond(unsigned long beginAtomId, unsigned long endAtomId,
00234                   short order = 1);
00235 
00246     Bond *addBond(Atom *beginAtom, Atom* endAtom, short order = 1);
00247 
00251     void removeBond(Bond *bond);
00252 
00256     void removeBond(unsigned long id);
00257 
00262     Bond* bond(int index) const;
00263 
00267     Bond *bondById(unsigned long id) const;
00268 
00272     QList<Bond *> bonds() const;
00273 
00277     unsigned int numBonds() const;
00278 
00291     Residue *addResidue();
00292 
00298     Residue *addResidue(unsigned long id);
00299 
00303     void removeResidue(Residue *residue);
00304 
00308     void removeResidue(unsigned long id);
00309 
00314     Residue* residue(int index);
00315     const Residue* residue(int index) const;
00316 
00320     Residue *residueById(unsigned long id) const;
00321 
00325     QList<Residue *> residues() const;
00326 
00330     unsigned int numResidues() const;
00345     Fragment *addRing();
00346 
00352     Fragment *addRing(unsigned long id);
00353 
00357     void removeRing(Fragment *ring);
00358 
00362     void removeRing(unsigned long id);
00363 
00367     QList<Fragment *> rings();
00368 
00372     unsigned int numRings() const;
00385     Cube *addCube();
00386 
00392     Cube *addCube(unsigned long id);
00393 
00397     void removeCube(Cube *cube);
00398 
00402     void removeCube(unsigned long id);
00403 
00407     Cube* cube(int index) const;
00408 
00412     Cube *cubeById(unsigned long id) const;
00413 
00417     QList<Cube *> cubes() const;
00418 
00422     unsigned int numCubes() const;
00435     Mesh * addMesh();
00436 
00442     Mesh *addMesh(unsigned long id);
00443 
00447     void removeMesh(Mesh *mesh);
00448 
00452     void removeMesh(unsigned long id);
00453 
00457     Mesh* mesh(int index) const;
00458 
00462     Mesh *meshById(unsigned long id) const;
00463 
00467     QList<Mesh *> meshes() const;
00468 
00472     unsigned int numMeshes() const;
00485     ZMatrix * addZMatrix();
00486 
00490     void removeZMatrix(ZMatrix *zmatrix);
00491 
00495     ZMatrix * zMatrix(int index) const;
00496 
00500     QList<ZMatrix *> zMatrices() const;
00501 
00505     unsigned int numZMatrices() const;
00514     void addHydrogens(Atom *atom = 0,
00515                       const QList<unsigned long> &atomIds = QList<unsigned long>(),
00516                       const QList<unsigned long> &bondIds = QList<unsigned long>());
00517 
00523     void removeHydrogens(Atom *atom = 0);
00524 
00529     void setDipoleMoment(const Eigen::Vector3d &moment);
00530 
00538     Eigen::Vector3d dipoleMoment(bool *estimate = 0) const;
00539 
00543     void calculatePartialCharges() const;
00544 
00548     void calculateAromaticity() const;
00549 
00553     void calculateGroupIndices() const;
00554 
00559     Bond* bond(unsigned long id1, unsigned long id2);
00560 
00565     Bond* bond(const Atom*, const Atom*);
00566 
00584     unsigned long conformerSize() { return m_atomPos->size(); }
00585 
00601     bool addConformer(const std::vector<Eigen::Vector3d> &conformer,
00602                       unsigned int index);
00603 
00622     std::vector<Eigen::Vector3d> * addConformer(unsigned int index);
00623 
00631     std::vector<Eigen::Vector3d> * conformer(unsigned int index);
00632 
00640     const std::vector<std::vector<Eigen::Vector3d> *>& conformers() const;
00641 
00649     bool setConformer(unsigned int index);
00650 
00665     bool setAllConformers(const std::vector< std::vector<Eigen::Vector3d>* > conformers, bool deleteExisting = true);
00666 
00671     void clearConformers();
00672 
00676     unsigned int numConformers() const;
00677 
00681     unsigned int currentConformer() const;
00682 
00686     const std::vector<double>& energies() const;
00687 
00694     double energy(int index = -1) const;
00695 
00700     void setEnergy(double energy);
00701 
00707     void setEnergy(int index, double energy);
00708 
00713     void setEnergies(const std::vector<double>& energies);
00714 
00718     void clear();
00719 
00723     QReadWriteLock *lock() const;
00724 
00735     OpenBabel::OBMol OBMol() const;
00736 
00741     bool setOBMol(OpenBabel::OBMol *obmol);
00742 
00747     OpenBabel::OBUnitCell *OBUnitCell() const;
00748 
00754     bool setOBUnitCell(OpenBabel::OBUnitCell *obunitcell);
00766     const Eigen::Vector3d center() const;
00767 
00771     const Eigen::Vector3d normalVector() const;
00772 
00776     double radius() const;
00777 
00781     const Atom *farthestAtom() const;
00782 
00786     void translate(const Eigen::Vector3d&);
00797     Molecule& operator=(const Molecule& other);
00798 
00803     Molecule& operator+=(const Molecule& other);
00820     PrimitiveList copyAtomsAndBonds(const QList<Atom*> &atoms,
00821                                     const QList<Bond*> &bonds);
00822 
00833     PrimitiveList copyAtomsAndBonds(const PrimitiveList &atomsAndBonds);
00836   protected:
00837     MoleculePrivate * const d_ptr;
00838     QString m_fileName;
00839     std::vector<Eigen::Vector3d> *m_atomPos; // Atom position vector
00841     std::vector< std::vector<Eigen::Vector3d>* > m_atomConformers;
00842     mutable unsigned int m_currentConformer;
00843 
00844     mutable bool m_estimatedDipoleMoment;
00845     mutable Eigen::Vector3d *m_dipoleMoment;
00846     mutable bool m_invalidPartialCharges;
00847     mutable bool m_invalidAromaticity;
00848     Q_DECLARE_PRIVATE(Molecule)
00849 
00850     std::vector<Atom *>   m_atoms;
00851     std::vector<Bond *>   m_bonds;
00852     QList<Atom *>         m_atomList;
00853     QList<Bond *>         m_bondList;
00854 
00855     QReadWriteLock *m_lock;
00856 
00862     void computeGeomInfo() const;
00863 
00864   public Q_SLOTS:
00870     void updateMolecule();
00871 
00872   private Q_SLOTS:
00881     void updatePrimitive();
00882 
00889     void updateAtom();
00890 
00897     void updateBond();
00898 
00899   Q_SIGNALS:
00905     void moleculeChanged();
00906 
00911     void primitiveAdded(Primitive *primitive);
00912 
00917     void primitiveUpdated(Primitive *primitive);
00918 
00923     void primitiveRemoved(Primitive *primitive);
00924 
00929     void atomAdded(Atom *atom);
00930 
00935     void atomUpdated(Atom *atom);
00936 
00941     void atomRemoved(Atom *atom);
00942 
00947     void bondAdded(Bond *bond);
00948 
00953     void bondUpdated(Bond *bond);
00954 
00959     void bondRemoved(Bond *bond);
00960   };
00961 
00962   inline Atom * Molecule::atom(int index) const
00963   {
00964     if (index >= 0 && index < m_atomList.size())
00965       return m_atomList[index];
00966     else
00967       return 0;
00968   }
00969 
00970   inline Atom * Molecule::atomById(unsigned long id) const
00971   {
00972     if(id < m_atoms.size() && id != FALSE_ID)
00973       return m_atoms[id];
00974     else
00975       return 0;
00976   }
00977 
00978   inline const Eigen::Vector3d * Molecule::atomPos(unsigned long id) const
00979   {
00980     if (id < m_atomPos->size() && id != FALSE_ID)
00981       return &(*m_atomPos)[id];
00982     else
00983       return 0;
00984   }
00985 
00986   inline Bond * Molecule::bond(int index) const
00987   {
00988     if (index >= 0 && index < m_bondList.size())
00989       return m_bondList[index];
00990     else
00991       return 0;
00992   }
00993 
00994   inline Bond * Molecule::bondById(unsigned long id) const
00995   {
00996     if(id < m_bonds.size() && id != FALSE_ID)
00997       return m_bonds[id];
00998     else
00999       return 0;
01000   }
01001 
01002 } // End namespace Avogadro
01003 
01004 #endif