source: src/molecule.hpp@ bccbe9

Action_Thermostats Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_StructOpt_integration_tests AutomationFragmentation_failures Candidate_v1.6.1 ChemicalSpaceEvaluator Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Exclude_Hydrogens_annealWithBondGraph Fix_Verbose_Codepatterns ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion Gui_displays_atomic_force_velocity JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool PythonUI_with_named_parameters Recreated_GuiChecks StoppableMakroAction TremoloParser_IncreasedPrecision
Last change on this file since bccbe9 was 67c4ea, checked in by Frederik Heber <heber@…>, 9 years ago

FIX: molecule returned BondCount twice as large.

  • Property mode set to 100755
File size: 14.2 KB
Line 
1/** \file molecule.hpp
2 *
3 * Class definitions of atom and molecule, element and periodentafel
4 */
5
6#ifndef MOLECULES_HPP_
7#define MOLECULES_HPP_
8
9/*********************************************** includes ***********************************/
10
11#ifdef HAVE_CONFIG_H
12#include <config.h>
13#endif
14
15//// STL headers
16#include <map>
17#include <set>
18#include <stack>
19#include <deque>
20#include <list>
21#include <vector>
22
23#include <string>
24
25#include <boost/bimap/bimap.hpp>
26#include <boost/bimap/unordered_set_of.hpp>
27#include <boost/bimap/multiset_of.hpp>
28#include <boost/optional.hpp>
29#include <boost/shared_ptr.hpp>
30
31#include "AtomIdSet.hpp"
32#include "Atom/AtomSet.hpp"
33#include "CodePatterns/Cacheable.hpp"
34#include "CodePatterns/Observer/Observable.hpp"
35#include "Descriptors/AtomIdDescriptor.hpp"
36#include "Fragmentation/HydrogenSaturation_enum.hpp"
37#include "Formula.hpp"
38#include "Helpers/defs.hpp"
39#include "IdPool_policy.hpp"
40#include "IdPool.hpp"
41#include "Shapes/Shape.hpp"
42#include "types.hpp"
43
44/****************************************** forward declarations *****************************/
45
46class atom;
47class bond;
48class BondedParticle;
49class BondGraph;
50class DepthFirstSearchAnalysis;
51class element;
52class ForceMatrix;
53class Graph;
54class LinkedCell_deprecated;
55class ListOfLocalAtoms_t;
56class molecule;
57class MoleculeLeafClass;
58class MoleculeUnittest;
59class RealSpaceMatrix;
60class Vector;
61
62/************************************* Class definitions ****************************************/
63
64/** External function to remove all atoms since this will also delete the molecule
65 *
66 * \param _mol ref pointer to molecule to destroy
67 */
68void removeAtomsinMolecule(molecule *&_mol);
69
70/** The complete molecule.
71 * Class incorporates number of types
72 */
73class molecule : public Observable
74{
75 //!> grant unit test access
76 friend class MoleculeUnittest;
77 //!> function may access cstor
78 friend molecule *NewMolecule();
79 //!> function may access dstor
80 friend void DeleteMolecule(molecule *);
81
82public:
83 typedef AtomIdSet::atomIdSet atomIdSet;
84 typedef AtomIdSet::iterator iterator;
85 typedef AtomIdSet::const_iterator const_iterator;
86
87 int MDSteps; //!< The number of MD steps in Trajectories
88 mutable int NoNonBonds; //!< number of non-hydrogen bonds in molecule
89 mutable int NoCyclicBonds; //!< number of cyclic bonds in molecule, by DepthFirstSearchAnalysis()
90 bool ActiveFlag; //!< in a MoleculeListClass used to discern active from inactive molecules
91 int IndexNr; //!< index of molecule in a MoleculeListClass
92 char name[MAXSTRINGSIZE]; //!< arbitrary name
93
94private:
95 Formula formula;
96 size_t NoNonHydrogen; //!< number of non-hydrogen atoms in molecule
97 int BondCount; //!< number of atoms, brought up-to-date by doCountBonds()
98 moleculeId_t id;
99 AtomIdSet atomIds; //<!set of atomic ids to check uniqueness of atoms
100 IdPool<atomId_t, uniqueId> atomIdPool; //!< pool of internal ids such that way may guarantee uniqueness
101 typedef std::map<atomId_t,atom *> LocalToGlobalId_t;
102 LocalToGlobalId_t LocalToGlobalId; //!< internal map to ease FindAtom
103
104protected:
105
106 molecule();
107 virtual ~molecule();
108
109public:
110
111 /******* Notifications *******/
112
113 //!> enumeration of present notification types: only insertion/removal of atoms or molecules
114 enum NotificationType {
115 AtomInserted,
116 AtomRemoved,
117 AtomNrChanged,
118 AtomMoved,
119 FormulaChanged,
120 MoleculeCenterChanged,
121 MoleculeNameChanged,
122 IndexChanged,
123 BoundingBoxChanged,
124 SelectionChanged,
125 NotificationType_MAX
126 };
127
128 //>! access to last changed element (atom)
129 const atomId_t lastChangedAtomId() const
130 { return _lastchangedatomid; }
131
132public:
133 //getter and setter
134 const std::string getName() const;
135 int getAtomCount() const;
136 size_t getNoNonHydrogen() const{
137 return NoNonHydrogen;
138 }
139
140 int getBondCount() const{
141 return BondCount/2;
142 }
143 moleculeId_t getId() const;
144 void setId(moleculeId_t);
145 void setName(const std::string);
146 const Formula &getFormula() const;
147 unsigned int getElementCount() const;
148 bool hasElement(const element*) const;
149 bool hasElement(atomicNumber_t) const;
150 bool hasElement(const std::string&) const;
151
152 virtual bool changeId(atomId_t newId);
153
154 World::AtomComposite getAtomSet();
155 World::ConstAtomComposite getAtomSet() const;
156
157 // simply pass on all functions to AtomIdSet
158 iterator begin() {
159 return atomIds.begin();
160 }
161 const_iterator begin() const
162 {
163 return atomIds.begin();
164 }
165 iterator end()
166 {
167 return atomIds.end();
168 }
169 const_iterator end() const
170 {
171 return atomIds.end();
172 }
173 bool empty() const
174 {
175 return atomIds.empty();
176 }
177 size_t size() const
178 {
179 return atomIds.size();
180 }
181 const_iterator find(atom * key) const
182 {
183 return atomIds.find(key);
184 }
185
186 /** Returns the set of atomic ids contained in this molecule.
187 *
188 * @return set of atomic ids
189 */
190 const atomIdSet & getAtomIds() const {
191 return atomIds.getAtomIds();
192 }
193
194 std::pair<iterator, bool> insert(atom * const key);
195
196 /** Predicate whether given \a key is contained in this molecule.
197 *
198 * @param key atom to check
199 * @return true - is contained, false - else
200 */
201 bool containsAtom(const atom* key) const
202 {
203 return atomIds.contains(key);
204 }
205
206 /** Predicate whether given \a id is contained in this molecule.
207 *
208 * @param id atomic id to check
209 * @return true - is contained, false - else
210 */
211 bool containsAtom(const atomId_t id) const
212 {
213 return atomIds.contains(id);
214 }
215
216private:
217 friend void atom::removeFromMolecule();
218 /** Erase an atom from the list.
219 * \note This should only be called by atom::removeFromMolecule(),
220 * otherwise it is not assured that the atom knows about it.
221 *
222 * @param loc locator to atom in list
223 * @return iterator to just after removed item (compliant with standard)
224 */
225 const_iterator erase(const_iterator loc);
226
227 /** Erase an atom from the list.
228 * \note This should only be called by atom::removeFromMolecule(),
229 * otherwise it is not assured that the atom knows about it.
230 *
231 * @param *key key to atom in list
232 * @return iterator to just after removed item (compliant with standard)
233 */
234 const_iterator erase(atom * key);
235
236private:
237 friend bool atom::changeNr(int newId);
238 /**
239 * used when changing an ParticleInfo::Nr.
240 * Note that this number is local with this molecule.
241 * Unless you are calling this method from inside an atom don't fiddle with the third parameter.
242 *
243 * @param oldNr old Nr
244 * @param newNr new Nr to set
245 * @param *target ref to atom
246 * @return indicates wether the change could be done or not.
247 */
248 bool changeAtomNr(int oldNr, int newNr, atom* target=0);
249
250 friend bool atom::changeId(atomId_t newId);
251 /**
252 * used when changing an ParticleInfo::Id.
253 * Note that this number is global (and the molecule uses it to know which atoms belong to it)
254 *
255 * @param oldId old Id
256 * @param newId new Id to set
257 * @return indicates wether the change could be done or not.
258 */
259 bool changeAtomId(int oldId, int newId);
260
261 /** Updates the internal lookup fro local to global indices.
262 *
263 * \param pointer pointer to atom
264 */
265 void InsertLocalToGlobalId(atom * const pointer);
266
267 /** Sets the name of the atom.
268 *
269 * The name is set via its element symbol and its internal ParticleInfo::Nr.
270 *
271 * @param _atom atom whose name to set
272 */
273 void setAtomName(atom *_atom) const;
274
275 //!> grant World (only) access to selection state changers
276 friend class World;
277
278 /** Sets the internal selection state to true.
279 *
280 */
281 void select();
282
283 /** Unsets the internal selection state to true.
284 *
285 */
286 void unselect();
287
288public:
289
290 /** Getter to internal selection status.
291 *
292 * \return true - molecule is selected, false - else
293 */
294 bool getSelected() const { return selected; }
295
296 /** Structure for the required information on the bounding box.
297 *
298 */
299 struct BoundingBoxInfo {
300 //!> position of center
301 Vector position;
302 //!> radius of sphere
303 double radius;
304
305 /** Equivalence operator for bounding box.
306 *
307 * \return true - both bounding boxes have same position and radius
308 */
309 bool operator==(const BoundingBoxInfo &_other) const
310 { return (radius == _other.radius) && (position == _other.position); }
311
312 /** Inequivalence operator for bounding box.
313 *
314 * \return true - bounding boxes have either different positions or different radii or both
315 */
316 bool operator!=(const BoundingBoxInfo &_other) const
317 { return !(*this == _other); }
318 };
319
320private:
321
322 /** Returns the current bounding box.
323 *
324 * \return Shape with center and extension of box
325 */
326 BoundingBoxInfo updateBoundingBox() const;
327
328 /** Returns the current center of the molecule.
329 *
330 * \return center
331 */
332 Vector updateMoleculeCenter() const;
333
334 // stuff for keeping bounding box up-to-date efficiently
335
336 //!> Cacheable for the bounding box, ptr such that
337 boost::shared_ptr< Cacheable<BoundingBoxInfo> > BoundingBox;
338
339 //!> Cacheable for the bounding box, ptr such that
340 boost::shared_ptr< Cacheable<Vector> > MoleculeCenter;
341
342 /** Bimap storing atomic ids and the component per axis.
343 *
344 * We need a bimap in order to have the components sorted and be able to
345 * access max and min values in linear time and also access the ids in
346 * constant time in order to update the map, when atoms move, are inserted,
347 * or removed.
348 */
349 typedef boost::bimaps::bimap<
350 boost::bimaps::set_of< atomId_t >,
351 boost::bimaps::multiset_of< double, std::greater<double> >
352 > AtomDistanceMap_t;
353 std::vector<AtomDistanceMap_t> BoundingBoxSweepingAxis;
354
355 //!> typedef for a map with current bond counts per atom
356 typedef std::map<atomId_t, size_t> BondCountsPerAtom_t;
357
358 //!> current bond counts per atom to update the BondCount
359 BondCountsPerAtom_t BondCountsPerAtom;
360
361 //!> typedef for a map with current element per atom
362 typedef std::map<atomId_t, atomicNumber_t> ElementPerAtom_t;
363
364 //!> current element per atom to update the BondCount
365 ElementPerAtom_t ElementPerAtom;
366
367 //!> make setMolecule friend to access associateAtomWithMolecule()
368 friend void atom::setMolecule(molecule *);
369
370 /** Helper function only to be called by specific atom function.
371 *
372 * \param _atom atom to be added to this molecule
373 */
374 void associateAtomWithMolecule(atom *_atom);
375
376 /** Helper function only to be called by specific atom function.
377 *
378 * \param _atom atom to be added to this molecule
379 */
380 void disassociateAtomWithMolecule(atom *_atom);
381
382public:
383
384 /** Returns the current bounding box of this molecule.
385 *
386 * \return bounding box info with center and radius
387 */
388 BoundingBoxInfo getBoundingBox() const;
389
390 /** Function to create a bounding spherical shape for the currently associated atoms.
391 *
392 * \param boundary extra boundary of shape around (i.e. distance between outermost atom
393 * and the shape's surface)
394 */
395 Shape getBoundingSphere(const double boundary = 0.) const;
396
397 /** Creates the bounding box by adding van der Waals-Spheres around every atom.
398 *
399 * \param scale extra scale parameter to enlarge the spheres artifically
400 */
401 Shape getBoundingShape(const double scale = 1.) const;
402
403 /** Returns the current center of this molecule.
404 *
405 * \return center of the molecule
406 */
407 Vector getMoleculeCenter() const;
408
409 /// remove atoms from molecule.
410 bool AddAtom(atom *pointer);
411 bool RemoveAtom(atom *pointer);
412 bool UnlinkAtom(atom *pointer);
413 bool CleanupMolecule();
414
415 /// Add/remove atoms to/from molecule.
416 atom * AddCopyAtom(atom *pointer);
417// bool AddHydrogenReplacementAtom(bond::ptr Bond, atom *BottomOrigin, atom *TopOrigin, atom *TopReplacement, bool IsAngstroem);
418 bond::ptr AddBond(atom *first, atom *second, int degree = 1);
419 bool hasBondStructure() const;
420
421 /// Find atoms.
422 atom * FindAtom(int Nr) const;
423 atom * AskAtom(std::string text);
424 bool isInMolecule(const atom * const _atom) const;
425
426 /// Count and change present atoms' coordination.
427 bool CenterInBox();
428 bool BoundInBox();
429 void CenterEdge();
430 void CenterOrigin();
431 void CenterPeriodic();
432 void CenterAtVector(const Vector &newcenter);
433 void Translate(const Vector &x);
434 void TranslatePeriodically(const Vector &trans);
435 void Mirror(const Vector &x);
436 void Align(const Vector &n);
437 void Scale(const double *factor);
438 void DeterminePeriodicCenter(Vector &center, const enum HydrogenTreatment _treatment = ExcludeHydrogen);
439 const Vector DetermineCenterOfGravity() const;
440 const Vector DetermineCenterOfAll() const;
441 void SetNameFromFilename(const char *filename);
442 bool ScanForPeriodicCorrection();
443 double VolumeOfConvexEnvelope(bool IsAngstroem);
444 RealSpaceMatrix getInertiaTensor() const;
445 void RotateToPrincipalAxisSystem(const Vector &Axis);
446
447 bool CheckBounds(const Vector *x) const;
448 void GetAlignvector(struct lsq_params * par) const;
449
450 /// Initialising routines in fragmentation
451 void OutputBondsList() const;
452
453 bond::ptr CopyBond(atom *left, atom *right, bond::ptr CopyBond);
454
455 molecule *CopyMolecule(const Vector &offset = zeroVec);
456 molecule* CopyMoleculeFromSubRegion(const Shape&);
457
458 /// Fragment molecule by two different approaches:
459 bool StoreBondsToFile(std::string filename, std::string path = "");
460 bool CreateFatherLookupTable(ListOfLocalAtoms_t &LookupTable, int count = 0);
461
462 // Recognize doubly appearing molecules in a list of them
463 int * GetFatherSonAtomicMap(const molecule * const OtherMolecule);
464 bool FillBondStructureFromReference(const molecule * const reference, ListOfLocalAtoms_t &ListOfLocalAtoms, bool FreeList = false);
465 bool FillListOfLocalAtoms(ListOfLocalAtoms_t &ListOfLocalAtoms, const int GlobalAtomCount);
466
467 // Output routines.
468 bool Output(std::ostream * const output) const;
469 void OutputListOfBonds() const;
470
471 // Manipulation routines
472 void flipActiveFlag();
473
474 virtual void update(Observable *publisher);
475 virtual void recieveNotification(Observable *publisher, Notification_ptr notification);
476 virtual void subjectKilled(Observable *publisher);
477
478private:
479 //!> id of last atom that signalled changed associated with this molecule
480 atomId_t _lastchangedatomid;
481
482 int last_atom; //!< number given to last atom
483
484 //!> center of the molecule
485 Vector molcenter;
486
487 //!> internal state whether atom is selected or not
488 bool selected;
489};
490
491molecule *NewMolecule();
492void DeleteMolecule(molecule* mol);
493
494
495
496#endif /*MOLECULES_HPP_*/
497
Note: See TracBrowser for help on using the repository browser.