source: src/World.cpp@ efd020

AutomationFragmentation_failures Candidate_v1.6.1 ChemicalSpaceEvaluator Enhanced_StructuralOptimization_continued Exclude_Hydrogens_annealWithBondGraph ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_contraction-expansion Gui_displays_atomic_force_velocity PythonUI_with_named_parameters StoppableMakroAction TremoloParser_IncreasedPrecision
Last change on this file since efd020 was 7294dc, checked in by Frederik Heber <frederik.heber@…>, 8 years ago

FIX: Fixing the use of the trajectories that were changed to maps.

  • as the atom's trajectories are now stored inside a map, i.e. not every step necessarily needs to be present, there will still some places in the code that were meant for the old vector storing.
  • Atom::UpdateStep() updates the current step, not the future step.
  • AtomInfo::append/removeTrajectoryStep() now no longer ASSERT that the step is not the current one. Due to the trajectory in map concept (with current it simply sought by lower_bound()) this is no longer necessary.
  • HydrogenPool no longer adds all trajectory steps till current time.
  • World has commented out code for also copying the current atom positions in case a new time step is added, but this is not used as so far we do not recognize whether it is a new time step ... and also it is not really necessary.
  • TESTS: Removed XFAILs from tests of previous commit. They are all working again.
  • Property mode set to 100644
File size: 33.2 KB
RevLine 
[bcf653]1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
[0aa122]4 * Copyright (C) 2010-2012 University of Bonn. All rights reserved.
[5aaa43]5 * Copyright (C) 2013 Frederik Heber. All rights reserved.
[94d5ac6]6 *
7 *
8 * This file is part of MoleCuilder.
9 *
10 * MoleCuilder is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation, either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * MoleCuilder is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with MoleCuilder. If not, see <http://www.gnu.org/licenses/>.
[bcf653]22 */
23
[5d1611]24/*
25 * World.cpp
26 *
27 * Created on: Feb 3, 2010
28 * Author: crueger
29 */
30
[bf3817]31// include config.h
32#ifdef HAVE_CONFIG_H
33#include <config.h>
34#endif
35
[9eb71b3]36//#include "CodePatterns/MemDebug.hpp"
[112b09]37
[5d1611]38#include "World.hpp"
39
[90c4280]40#include <functional>
[5d1611]41
[3139b2]42#include "Actions/ActionTrait.hpp"
[d297a3]43#include "Actions/ManipulateAtomsProcess.hpp"
[6f0841]44#include "Atom/atom.hpp"
[d297a3]45#include "Box.hpp"
46#include "CodePatterns/Assert.hpp"
[8e1f7af]47#include "config.hpp"
[fc1b24]48#include "Descriptors/AtomDescriptor.hpp"
[865a945]49#include "Descriptors/AtomDescriptor_impl.hpp"
[c1d837]50#include "Descriptors/AtomIdDescriptor.hpp"
[ebc499]51#include "Descriptors/AtomSelectionDescriptor.hpp"
[1c51c8]52#include "Descriptors/MoleculeDescriptor.hpp"
53#include "Descriptors/MoleculeDescriptor_impl.hpp"
[c1d837]54#include "Descriptors/MoleculeIdDescriptor.hpp"
[ebc499]55#include "Descriptors/MoleculeSelectionDescriptor.hpp"
[feb5d0]56#include "Descriptors/SelectiveConstIterator_impl.hpp"
[6e97e5]57#include "Descriptors/SelectiveIterator_impl.hpp"
[42127c]58#include "Element/periodentafel.hpp"
[98dbee]59#include "Fragmentation/Homology/HomologyContainer.hpp"
[3139b2]60#include "Graph/BondGraph.hpp"
[4b8630]61#include "Graph/DepthFirstSearchAnalysis.hpp"
[e4fe8d]62#include "Helpers/defs.hpp"
[d297a3]63#include "LinearAlgebra/RealSpaceMatrix.hpp"
[4834f4]64#include "LinkedCell/LinkedCell_Controller.hpp"
65#include "LinkedCell/PointCloudAdaptor.hpp"
[d297a3]66#include "molecule.hpp"
[ab26c3]67#include "Thermostats/ThermoStatContainer.hpp"
[d297a3]68#include "WorldTime.hpp"
[d346b6]69
[3e4fb6]70#include "IdPool_impl.hpp"
71
[4834f4]72#include "CodePatterns/IteratorAdaptors.hpp"
[ad011c]73#include "CodePatterns/Singleton_impl.hpp"
[02ce36]74#include "CodePatterns/Observer/Channels.hpp"
75#include "CodePatterns/Observer/ObservedContainer_impl.hpp"
[23b547]76
[ce7fdc]77using namespace MoleCuilder;
[4d9c01]78
[7188b1]79/******************************* Notifications ************************/
80
81
82atom* World::_lastchangedatom = NULL;
[fb95a5]83atomId_t World::_lastchangedatomid = -1;
[7188b1]84molecule* World::_lastchangedmol = NULL;
[fb95a5]85moleculeId_t World::_lastchangedmolid = -1;
[7188b1]86
[5d1611]87/******************************* getter and setter ************************/
[f71baf]88periodentafel *&World::getPeriode()
89{
[5d1611]90 return periode;
91}
92
[f71baf]93BondGraph *&World::getBondGraph()
94{
95 return BG;
96}
97
[98dbee]98HomologyContainer &World::getHomologies()
99{
100 return *homologies;
101}
102
103void World::resetHomologies(HomologyContainer *&_homologies)
104{
105 HomologyContainer *oldhomologies = homologies;
106
107 // install new instance, resetting given pointer
108 homologies = _homologies;
109 _homologies = NULL;
110
111 // delete old instance which also informs all observers
112 delete oldhomologies;
113}
114
[f71baf]115void World::setBondGraph(BondGraph *_BG){
116 delete (BG);
117 BG = _BG;
118}
119
[8e1f7af]120config *&World::getConfig(){
121 return configuration;
122}
123
[1c51c8]124// Atoms
125
[7a1ce5]126atom* World::getAtom(AtomDescriptor descriptor){
[fc1b24]127 return descriptor.find();
128}
129
[795c0f]130const atom* World::getAtom(AtomDescriptor descriptor) const{
131 return const_cast<const AtomDescriptor &>(descriptor).find();
132}
133
[4d72e4]134World::AtomComposite World::getAllAtoms(AtomDescriptor descriptor){
[fc1b24]135 return descriptor.findAll();
136}
137
[795c0f]138World::ConstAtomComposite World::getAllAtoms(AtomDescriptor descriptor) const {
139 return const_cast<const AtomDescriptor &>(descriptor).findAll();
140}
141
[4d72e4]142World::AtomComposite World::getAllAtoms(){
[0e2a47]143 return getAllAtoms(AllAtoms());
144}
145
[795c0f]146World::ConstAtomComposite World::getAllAtoms() const {
147 return getAllAtoms(AllAtoms());
148}
149
150int World::numAtoms() const {
[354859]151 return atoms.size();
152}
153
[1c51c8]154// Molecules
155
156molecule *World::getMolecule(MoleculeDescriptor descriptor){
157 return descriptor.find();
158}
159
[97445f]160const molecule *World::getMolecule(MoleculeDescriptor descriptor) const {
161 return const_cast<const MoleculeDescriptor &>(descriptor).find();
162}
163
[1c51c8]164std::vector<molecule*> World::getAllMolecules(MoleculeDescriptor descriptor){
165 return descriptor.findAll();
166}
167
[97445f]168std::vector<const molecule*> World::getAllMolecules(MoleculeDescriptor descriptor) const {
169 return const_cast<const MoleculeDescriptor &>(descriptor).findAll();
170}
171
[97ebf8]172std::vector<molecule*> World::getAllMolecules(){
173 return getAllMolecules(AllMolecules());
174}
175
[97445f]176std::vector<const molecule*> World::getAllMolecules() const {
177 return getAllMolecules(AllMolecules());
178}
179
180int World::numMolecules() const {
[2affd1]181 return molecules.size();
[354859]182}
183
[5f612ee]184// system
185
[84c494]186Box& World::getDomain() {
187 return *cell_size;
188}
189
[cca9ef]190void World::setDomain(const RealSpaceMatrix &mat){
[be97a8]191 OBSERVE;
[84c494]192 *cell_size = mat;
[5f612ee]193}
194
195void World::setDomain(double * matrix)
196{
[b9c847]197 OBSERVE;
[cca9ef]198 RealSpaceMatrix M = ReturnFullMatrixforSymmetric(matrix);
[84c494]199 cell_size->setM(M);
[5f612ee]200}
201
[03abd0]202LinkedCell::LinkedCell_View World::getLinkedCell(double distance)
[4834f4]203{
[d067e35]204 ASSERT( distance >= 0,
[03abd0]205 "World::getLinkedCell() - distance is not positive.");
206 if (distance < 1.) {
207 ELOG(2, "Linked cell grid with length less than 1. is very memory-intense!");
208 distance = 1.;
209 }
[4834f4]210 // we have to grope past the ObservedContainer mechanism and transmorph the map
211 // into a traversable list for the adaptor
212 PointCloudAdaptor< AtomSet::set_t, MapValueIterator<AtomSet::set_t::iterator> > atomset(
213 &(atoms.getContent()),
214 std::string("WorldsAtoms"));
215 return LCcontroller->getView(distance, atomset);
216}
217
[2a8731]218const unsigned World::getTime() const
219{
220 return WorldTime::getTime();
221}
222
[7294dc]223static bool areBondsPresent(const unsigned int _step)
[388ddd]224{
225 bool status = false;
226
227 for (World::AtomConstIterator iter = const_cast<const World &>(World::getInstance()).getAtomIter();
228 (!status) && (iter != const_cast<const World &>(World::getInstance()).atomEnd()); ++iter) {
229 const atom * const Walker = *iter;
230 status |= !Walker->getListOfBondsAtStep(_step).empty();
231 }
232
233 return status;
234}
235
[7294dc]236static bool areAtomsPresent(const unsigned int _step)
237{
238 bool status = false;
239
240 for (World::AtomConstIterator iter = const_cast<const World &>(World::getInstance()).getAtomIter();
241 (!status) && (iter != const_cast<const World &>(World::getInstance()).atomEnd()); ++iter) {
242 const atom * const Walker = *iter;
243 status |= (Walker->getTrajectorySize() >= _step);
244 }
245
246 return status;
247}
248
[9f2071]249static void copyBondgraph(const unsigned int _srcstep, const unsigned int _deststep)
[388ddd]250{
251 // gather all bonds from _srcstep
252 std::set<bond *> SetOfBonds;
253 for (World::AtomConstIterator iter = const_cast<const World &>(World::getInstance()).getAtomIter();
254 iter != const_cast<const World &>(World::getInstance()).atomEnd(); ++iter) {
255 const atom * const Walker = *iter;
256 const BondList bonds = Walker->getListOfBondsAtStep(_srcstep);
257 BOOST_FOREACH( bond::ptr bondptr, bonds) {
258 SetOfBonds.insert(bondptr.get());
259 }
260 }
261 LOG(4, "DEBUG: We gathered " << SetOfBonds.size() << " bonds in total.");
262
263 // copy bond to new time step
264 for (std::set<bond *>::const_iterator bonditer = SetOfBonds.begin();
265 bonditer != SetOfBonds.end(); ++bonditer) {
266 const atom * const Walker = (*bonditer)->leftatom;
267 const atom * const OtherWalker = (*bonditer)->rightatom;
[0763ce]268 bond::ptr const _bond =
269 const_cast<atom *>(Walker)->addBond(_deststep, const_cast<atom *>(OtherWalker));
270 _bond->setDegree((*bonditer)->getDegree());
[388ddd]271 }
272}
273
[7294dc]274//static void copyAtoms(const unsigned int _srcstep, const unsigned int _deststep)
275//{
276// for (World::AtomIterator iter = World::getInstance().getAtomIter();
277// iter != World::getInstance().atomEnd(); ++iter) {
278// atom * const Walker = *iter;
279// Walker->UpdateStep(_deststep);
280// Walker->setPositionAtStep(_deststep, Walker->getPositionAtStep(_srcstep));
281// Walker->setAtomicVelocityAtStep(_deststep, Walker->getAtomicVelocityAtStep(_srcstep));
282// Walker->setAtomicForceAtStep(_deststep, Walker->getAtomicForceAtStep(_srcstep));
283// }
284//}
[9f2071]285
[d297a3]286void World::setTime(const unsigned int _step)
287{
[76163d]288 if (_step != WorldTime::getTime()) {
[388ddd]289 const unsigned int oldstep = WorldTime::getTime();
[46ce1c]290
[7294dc]291// if (!areAtomsPresent(_step))
292// copyAtoms(oldstep, _step);
293
[46ce1c]294 // 1. copy bond graph (such not each addBond causes GUI update)
295 if (!areBondsPresent(_step)) {
296// AtomComposite Set = getAllAtoms();
297// BG->cleanAdjacencyList(Set);
298 copyBondgraph(oldstep, _step);
299 }
300
301 // 2. set new time
[040a5c]302 WorldTime::getInstance().setTime(_step);
[46ce1c]303
304 // 4. scan for connected subgraphs => molecules
[4b8630]305 DepthFirstSearchAnalysis DFS;
306 DFS();
307 DFS.UpdateMoleculeStructure();
[76163d]308 }
[d297a3]309}
310
[387b36]311std::string World::getDefaultName() {
[5f612ee]312 return defaultName;
313}
314
[387b36]315void World::setDefaultName(std::string name)
[5f612ee]316{
[be97a8]317 OBSERVE;
[387b36]318 defaultName = name;
[5f612ee]319};
320
[43dad6]321class ThermoStatContainer * World::getThermostats()
322{
323 return Thermostats;
324}
325
326
[e4b5de]327int World::getExitFlag() {
328 return ExitFlag;
329}
330
331void World::setExitFlag(int flag) {
332 if (ExitFlag < flag)
333 ExitFlag = flag;
334}
[5f612ee]335
[afb47f]336/******************** Methods to change World state *********************/
337
[354859]338molecule* World::createMolecule(){
339 OBSERVE;
340 molecule *mol = NULL;
[cbc5fb]341 mol = NewMolecule();
[3e4fb6]342 moleculeId_t id = moleculeIdPool.getNextId();
[127a8e]343 ASSERT(!molecules.count(id),"proposed id did not specify an unused ID");
344 mol->setId(id);
[244d26]345 // store the molecule by ID
[cbc5fb]346 molecules[mol->getId()] = mol;
[7188b1]347 _lastchangedmol = mol;
[fb95a5]348 _lastchangedmolid = mol->getId();
[7188b1]349 NOTIFY(MoleculeInserted);
[354859]350 return mol;
351}
352
[5cf341]353molecule* World::recreateMolecule(const moleculeId_t &_id)
354{
355 molecule *mol = NULL;
356 if (!molecules.count(_id)) {
357 OBSERVE;
358 mol = NewMolecule();
359 mol->setId(_id);
360 // store the molecule by ID
361 molecules[mol->getId()] = mol;
362 _lastchangedmol = mol;
363 _lastchangedmolid = mol->getId();
364 NOTIFY(MoleculeInserted);
365 }
366 return mol;
367}
368
[cbc5fb]369void World::destroyMolecule(molecule* mol){
[fa7989]370 ASSERT(mol,"Molecule that was meant to be destroyed did not exist");
[cbc5fb]371 destroyMolecule(mol->getId());
372}
373
374void World::destroyMolecule(moleculeId_t id){
375 molecule *mol = molecules[id];
[6d574a]376 ASSERT(mol,"Molecule id that was meant to be destroyed did not exist");
[38f991]377 // give notice about immediate removal
378 {
379 OBSERVE;
380 _lastchangedmol = mol;
[fb95a5]381 _lastchangedmolid = mol->getId();
[38f991]382 NOTIFY(MoleculeRemoved);
383 }
[4965d9f]384 if (isMoleculeSelected(id)) {
[38f991]385 selectedMolecules.erase(id);
[4965d9f]386 NOTIFY(SelectionChanged);
387 }
[f02b53]388 DeleteMolecule(mol);
[7eec64]389 molecules.erase(id);
[3e4fb6]390 moleculeIdPool.releaseId(id);
[cbc5fb]391}
392
[46d958]393atom *World::createAtom(){
394 OBSERVE;
[3e4fb6]395 atomId_t id = atomIdPool.getNextId();
[127a8e]396 ASSERT(!atoms.count(id),"proposed id did not specify an unused ID");
[88d586]397 atom *res = NewAtom(id);
[46d958]398 res->setWorld(this);
[244d26]399 // store the atom by ID
[46d958]400 atoms[res->getId()] = res;
[7188b1]401 _lastchangedatom = res;
[fb95a5]402 _lastchangedatomid = res->getId();
[7188b1]403 NOTIFY(AtomInserted);
[46d958]404 return res;
405}
406
[5cf341]407atom *World::recreateAtom(const atomId_t _id){
408 if (!atoms.count(_id)) {
409 OBSERVE;
410 atom *res = NewAtom(_id);
411 res->setWorld(this);
412 // store the atom by ID
413 atoms[res->getId()] = res;
414 _lastchangedatom = res;
415 _lastchangedatomid = res->getId();
416 NOTIFY(AtomInserted);
417 return res;
418 } else
419 return NULL;
420}
421
[5f612ee]422
[46d958]423int World::registerAtom(atom *atom){
424 OBSERVE;
[3e4fb6]425 atomId_t id = atomIdPool.getNextId();
[88d586]426 atom->setId(id);
[46d958]427 atom->setWorld(this);
428 atoms[atom->getId()] = atom;
[65d7ca]429 _lastchangedatom = atom;
[fb95a5]430 _lastchangedatomid = atom->getId();
[65d7ca]431 NOTIFY(AtomInserted);
[46d958]432 return atom->getId();
433}
434
435void World::destroyAtom(atom* atom){
436 int id = atom->getId();
437 destroyAtom(id);
438}
439
[cbc5fb]440void World::destroyAtom(atomId_t id) {
[46d958]441 atom *atom = atoms[id];
[6d574a]442 ASSERT(atom,"Atom ID that was meant to be destroyed did not exist");
[ab4a33]443 // give notice about immediate removal
444 {
445 OBSERVE;
446 _lastchangedatom = atom;
[fb95a5]447 _lastchangedatomid = atom->getId();
[ab4a33]448 NOTIFY(AtomRemoved);
449 }
[a7aebd]450 // check if it's the last atom
[270bdf]451 molecule *_mol = const_cast<molecule *>(atom->getMolecule());
[cad383]452 if ((_mol == NULL) || (_mol->getAtomCount() > 1))
[a7aebd]453 _mol = NULL;
[4965d9f]454 if (isAtomSelected(id)) {
[38f991]455 selectedAtoms.erase(id);
[4965d9f]456 NOTIFY(SelectionChanged);
457 }
[f02b53]458 DeleteAtom(atom);
[59e7996]459 atoms.erase(id);
[3e4fb6]460 atomIdPool.releaseId(id);
[a7aebd]461 // remove molecule if empty
462 if (_mol != NULL)
463 destroyMolecule(_mol);
[88d586]464}
465
466bool World::changeAtomId(atomId_t oldId, atomId_t newId, atom* target){
467 OBSERVE;
468 // in case this call did not originate from inside the atom, we redirect it,
469 // to also let it know that it has changed
470 if(!target){
471 target = atoms[oldId];
[6d574a]472 ASSERT(target,"Atom with that ID not found");
[88d586]473 return target->changeId(newId);
474 }
475 else{
[3e4fb6]476 if(atomIdPool.reserveId(newId)){
[88d586]477 atoms.erase(oldId);
478 atoms.insert(pair<atomId_t,atom*>(newId,target));
479 return true;
480 }
481 else{
482 return false;
483 }
484 }
[46d958]485}
486
[a7a087]487bool World::changeMoleculeId(moleculeId_t oldId, moleculeId_t newId, molecule* target){
488 OBSERVE;
489 // in case this call did not originate from inside the atom, we redirect it,
490 // to also let it know that it has changed
491 if(!target){
492 target = molecules[oldId];
493 ASSERT(target,"Molecule with that ID not found");
494 return target->changeId(newId);
495 }
496 else{
[3e4fb6]497 if(moleculeIdPool.reserveId(newId)){
[a7a087]498 molecules.erase(oldId);
499 molecules.insert(pair<moleculeId_t,molecule*>(newId,target));
500 return true;
501 }
502 else{
503 return false;
504 }
505 }
506}
507
[7c4e29]508ManipulateAtomsProcess* World::manipulateAtoms(boost::function<void(atom*)> op,std::string name,AtomDescriptor descr){
[3139b2]509 ActionTrait manipulateTrait(name);
[126867]510 return new ManipulateAtomsProcess(op, descr,manipulateTrait);
[7c4e29]511}
512
[0e2a47]513ManipulateAtomsProcess* World::manipulateAtoms(boost::function<void(atom*)> op,std::string name){
514 return manipulateAtoms(op,name,AllAtoms());
515}
516
[afb47f]517/********************* Internal Change methods for double Callback and Observer mechanism ********/
518
519void World::doManipulate(ManipulateAtomsProcess *proc){
520 proc->signOn(this);
521 {
522 OBSERVE;
523 proc->doManipulate(this);
524 }
525 proc->signOff(this);
526}
[865a945]527/******************************* Iterators ********************************/
528
[fa0b18]529// external parts with observers
530
[feb5d0]531CONSTRUCT_SELECTIVE_ITERATOR(atom*,World::AtomSet,AtomDescriptor)
532
533CONSTRUCT_SELECTIVE_CONST_ITERATOR(atom*,World::AtomSet,AtomDescriptor)
[6e97e5]534
[fa0b18]535World::AtomIterator
536World::getAtomIter(AtomDescriptor descr){
537 return AtomIterator(descr,atoms);
538}
[865a945]539
[feb5d0]540World::AtomConstIterator
541World::getAtomIter(AtomDescriptor descr) const{
542 return AtomConstIterator(descr,atoms);
543}
544
[fa0b18]545World::AtomIterator
546World::getAtomIter(){
547 return AtomIterator(AllAtoms(),atoms);
[865a945]548}
[354859]549
[feb5d0]550World::AtomConstIterator
551World::getAtomIter() const{
552 return AtomConstIterator(AllAtoms(),atoms);
553}
554
[fa0b18]555World::AtomIterator
556World::atomEnd(){
[6e97e5]557 return AtomIterator(AllAtoms(),atoms,atoms.end());
[7c4e29]558}
559
[feb5d0]560World::AtomConstIterator
561World::atomEnd() const{
562 return AtomConstIterator(AllAtoms(),atoms,atoms.end());
563}
564
565CONSTRUCT_SELECTIVE_ITERATOR(molecule*,World::MoleculeSet,MoleculeDescriptor)
566
567CONSTRUCT_SELECTIVE_CONST_ITERATOR(molecule*,World::MoleculeSet,MoleculeDescriptor)
[6e97e5]568
[5d880e]569World::MoleculeIterator
570World::getMoleculeIter(MoleculeDescriptor descr){
571 return MoleculeIterator(descr,molecules);
572}
573
[feb5d0]574World::MoleculeConstIterator
575World::getMoleculeIter(MoleculeDescriptor descr) const{
576 return MoleculeConstIterator(descr,molecules);
577}
578
[5d880e]579World::MoleculeIterator
580World::getMoleculeIter(){
581 return MoleculeIterator(AllMolecules(),molecules);
[1c51c8]582}
583
[feb5d0]584World::MoleculeConstIterator
585World::getMoleculeIter() const{
586 return MoleculeConstIterator(AllMolecules(),molecules);
587}
588
[5d880e]589World::MoleculeIterator
590World::moleculeEnd(){
[6e97e5]591 return MoleculeIterator(AllMolecules(),molecules,molecules.end());
[1c51c8]592}
593
[feb5d0]594World::MoleculeConstIterator
595World::moleculeEnd() const{
596 return MoleculeConstIterator(AllMolecules(),molecules,molecules.end());
597}
598
[fa0b18]599// Internal parts, without observers
600
601// Build the AtomIterator from template
602CONSTRUCT_SELECTIVE_ITERATOR(atom*,World::AtomSet::set_t,AtomDescriptor);
603
604
605World::internal_AtomIterator
606World::getAtomIter_internal(AtomDescriptor descr){
607 return internal_AtomIterator(descr,atoms.getContent());
608}
609
610World::internal_AtomIterator
611World::atomEnd_internal(){
612 return internal_AtomIterator(AllAtoms(),atoms.getContent(),atoms.end_internal());
613}
614
[6e97e5]615// build the MoleculeIterator from template
[e3d865]616CONSTRUCT_SELECTIVE_ITERATOR(molecule*,World::MoleculeSet::set_t,MoleculeDescriptor);
[6e97e5]617
[e3d865]618World::internal_MoleculeIterator World::getMoleculeIter_internal(MoleculeDescriptor descr){
619 return internal_MoleculeIterator(descr,molecules.getContent());
[1c51c8]620}
621
[e3d865]622World::internal_MoleculeIterator World::moleculeEnd_internal(){
623 return internal_MoleculeIterator(AllMolecules(),molecules.getContent(),molecules.end_internal());
[1c51c8]624}
625
[90c4280]626/************************** Selection of Atoms and molecules ******************/
627
[7f1865d]628// translate type's selection member functions to overloaded with specific type
629
630template <class T>
631void World::selectVectorOfInstances(const typename T::iterator _begin, const typename T::iterator _end)
632{
633 std::for_each(_begin,_end,
634 boost::bind(&World::selectInstance<typename T::value_type::second_type>,
635 boost::bind(_take<typename T::value_type::second_type,typename T::value_type>::get, _1)));
636}
637
638template <class T>
639void World::unselectVectorOfInstances(const typename T::iterator _begin, const typename T::iterator _end)
640{
641 std::for_each(_begin,_end,
642 boost::bind(&World::unselectInstance<typename T::value_type::second_type>,
643 boost::bind(_take<typename T::value_type::second_type,typename T::value_type>::get, _1)));
644}
645
[90c4280]646// Atoms
647
648void World::clearAtomSelection(){
[69643a]649 OBSERVE;
650 NOTIFY(SelectionChanged);
[7f1865d]651 unselectVectorOfInstances<AtomSet>(selectedAtoms.begin(), selectedAtoms.end());
[90c4280]652 selectedAtoms.clear();
653}
654
[ebc499]655void World::invertAtomSelection(){
656 // get all atoms not selected
657 AtomComposite invertedSelection(getAllAtoms());
658 bool (World::*predicate)(const atom*) const = &World::isSelected; // needed for type resolution of overloaded function
659 AtomComposite::iterator iter =
660 std::remove_if(invertedSelection.begin(), invertedSelection.end(),
661 std::bind1st(std::mem_fun(predicate), this));
662 invertedSelection.erase(iter, invertedSelection.end());
663 // apply new selection
[7f1865d]664 unselectVectorOfInstances<AtomSet>(selectedAtoms.begin(), selectedAtoms.end());
[ebc499]665 selectedAtoms.clear();
666 void (World::*selector)(const atom*) = &World::selectAtom; // needed for type resolution of overloaded function
667 std::for_each(invertedSelection.begin(),invertedSelection.end(),
668 std::bind1st(std::mem_fun(selector),this)); // func is select... see above
669}
670
[cad383]671void World::popAtomSelection(){
[0249ce]672 if (!selectedAtoms_Stack.empty()) {
673 OBSERVE;
674 NOTIFY(SelectionChanged);
675 const atomIdsVector_t atomids = selectedAtoms_Stack.top();
676 boost::function<void (const atomId_t)> IdSelector =
677 boost::bind(static_cast<void (World::*)(const atomId_t)>(&World::selectAtom), this, _1);
678 unselectVectorOfInstances<AtomSet>(selectedAtoms.begin(), selectedAtoms.end());
679 selectedAtoms.clear();
680 std::for_each(atomids.begin(),atomids.end(), IdSelector);
681 selectedAtoms_Stack.pop();
682 }
[cad383]683}
684
685void World::pushAtomSelection(){
686 OBSERVE;
687 NOTIFY(SelectionChanged);
[c1d837]688 atomIdsVector_t atomids(countSelectedAtoms(), (atomId_t)-1);
689 std::copy(
690 MapKeyIterator<AtomSelectionConstIterator>(beginAtomSelection()),
691 MapKeyIterator<AtomSelectionConstIterator>(endAtomSelection()),
692 atomids.begin());
693 selectedAtoms_Stack.push( atomids );
[7f1865d]694 unselectVectorOfInstances<AtomSet>(selectedAtoms.begin(), selectedAtoms.end());
[cad383]695 selectedAtoms.clear();
696}
697
[e4afb4]698void World::selectAtom(const atom *_atom){
[69643a]699 OBSERVE;
700 NOTIFY(SelectionChanged);
[e4afb4]701 // atom * is unchanged in this function, but we do store entity as changeable
702 ASSERT(_atom,"Invalid pointer in selection of atom");
[7f1865d]703 selectAtom(_atom->getId());
[90c4280]704}
705
[e4afb4]706void World::selectAtom(const atomId_t id){
[69643a]707 OBSERVE;
708 NOTIFY(SelectionChanged);
[90c4280]709 ASSERT(atoms.count(id),"Atom Id selected that was not in the world");
710 selectedAtoms[id]=atoms[id];
[7f1865d]711 atoms[id]->select();
[90c4280]712}
713
714void World::selectAllAtoms(AtomDescriptor descr){
[69643a]715 OBSERVE;
716 NOTIFY(SelectionChanged);
[90c4280]717 internal_AtomIterator begin = getAtomIter_internal(descr);
718 internal_AtomIterator end = atomEnd_internal();
[e4afb4]719 void (World::*func)(const atom*) = &World::selectAtom; // needed for type resolution of overloaded function
[90c4280]720 for_each(begin,end,bind1st(mem_fun(func),this)); // func is select... see above
721}
722
[e4afb4]723void World::selectAtomsOfMolecule(const molecule *_mol){
[69643a]724 OBSERVE;
725 NOTIFY(SelectionChanged);
[90c4280]726 ASSERT(_mol,"Invalid pointer to molecule in selection of Atoms of Molecule");
727 // need to make it const to get the fast iterators
728 const molecule *mol = _mol;
[e4afb4]729 void (World::*func)(const atom*) = &World::selectAtom; // needed for type resolution of overloaded function
[90c4280]730 for_each(mol->begin(),mol->end(),bind1st(mem_fun(func),this)); // func is select... see above
731}
732
[e4afb4]733void World::selectAtomsOfMolecule(const moleculeId_t id){
[69643a]734 OBSERVE;
735 NOTIFY(SelectionChanged);
[90c4280]736 ASSERT(molecules.count(id),"No molecule with the given id upon Selection of atoms from molecule");
737 selectAtomsOfMolecule(molecules[id]);
738}
739
[e4afb4]740void World::unselectAtom(const atom *_atom){
[69643a]741 OBSERVE;
742 NOTIFY(SelectionChanged);
[e4afb4]743 ASSERT(_atom,"Invalid pointer in unselection of atom");
744 unselectAtom(_atom->getId());
[61d655e]745}
746
[e4afb4]747void World::unselectAtom(const atomId_t id){
[69643a]748 OBSERVE;
749 NOTIFY(SelectionChanged);
[61d655e]750 ASSERT(atoms.count(id),"Atom Id unselected that was not in the world");
[7f1865d]751 atoms[id]->unselect();
[61d655e]752 selectedAtoms.erase(id);
753}
754
755void World::unselectAllAtoms(AtomDescriptor descr){
[69643a]756 OBSERVE;
757 NOTIFY(SelectionChanged);
[61d655e]758 internal_AtomIterator begin = getAtomIter_internal(descr);
759 internal_AtomIterator end = atomEnd_internal();
[e4afb4]760 void (World::*func)(const atom*) = &World::unselectAtom; // needed for type resolution of overloaded function
[61d655e]761 for_each(begin,end,bind1st(mem_fun(func),this)); // func is unselect... see above
762}
763
[e4afb4]764void World::unselectAtomsOfMolecule(const molecule *_mol){
[69643a]765 OBSERVE;
766 NOTIFY(SelectionChanged);
[61d655e]767 ASSERT(_mol,"Invalid pointer to molecule in selection of Atoms of Molecule");
768 // need to make it const to get the fast iterators
769 const molecule *mol = _mol;
[e4afb4]770 void (World::*func)(const atom*) = &World::unselectAtom; // needed for type resolution of overloaded function
[992bd5]771 for_each(mol->begin(),mol->end(),bind1st(mem_fun(func),this)); // func is unselect... see above
[61d655e]772}
773
[e4afb4]774void World::unselectAtomsOfMolecule(const moleculeId_t id){
[69643a]775 OBSERVE;
776 NOTIFY(SelectionChanged);
[61d655e]777 ASSERT(molecules.count(id),"No molecule with the given id upon Selection of atoms from molecule");
778 unselectAtomsOfMolecule(molecules[id]);
779}
780
[e472eab]781size_t World::countSelectedAtoms() const {
[eacc3b]782 size_t count = 0;
[e472eab]783 for (AtomSet::const_iterator iter = selectedAtoms.begin(); iter != selectedAtoms.end(); ++iter)
[eacc3b]784 count++;
785 return count;
786}
787
[e4afb4]788bool World::isSelected(const atom *_atom) const {
[7f1865d]789 const bool status = isAtomSelected(_atom->getId());
790 ASSERT( status == _atom->selected,
791 "World::isSelected() - mismatch between selection state in atom "+
792 toString(_atom->getId())+" and World.");
793 return status;
[89643d]794}
795
796bool World::isAtomSelected(const atomId_t no) const {
797 return selectedAtoms.find(no) != selectedAtoms.end();
[e0e156]798}
799
[99db9b]800std::vector<atom *> World::getSelectedAtoms() {
[e472eab]801 std::vector<atom *> returnAtoms;
[99db9b]802 std::transform(
803 selectedAtoms.begin(),
804 selectedAtoms.end(),
805 back_inserter(returnAtoms),
806 _take<atom*,World::AtomSet::value_type>::get);
807 return returnAtoms;
808}
809
810std::vector<const atom *> World::getSelectedAtoms() const {
811 std::vector<const atom *> returnAtoms;
812 std::transform(
813 selectedAtoms.begin(),
814 selectedAtoms.end(),
815 back_inserter(returnAtoms),
816 _take<atom*,World::AtomSet::value_type>::get);
[e472eab]817 return returnAtoms;
818}
819
[143263]820std::vector<atomId_t> World::getSelectedAtomIds() const {
821 std::vector<atomId_t> returnAtomIds;
822 std::transform(
823 selectedAtoms.begin(),
824 selectedAtoms.end(),
825 back_inserter(returnAtomIds),
826 _take<atom*,World::AtomSet::value_type>::getKey);
827 return returnAtomIds;
828}
[e472eab]829
[90c4280]830// Molecules
831
832void World::clearMoleculeSelection(){
[69643a]833 OBSERVE;
834 NOTIFY(SelectionChanged);
[7f1865d]835 unselectVectorOfInstances<MoleculeSet>(selectedMolecules.begin(), selectedMolecules.end());
[90c4280]836 selectedMolecules.clear();
837}
838
[ebc499]839void World::invertMoleculeSelection(){
840 // get all molecules not selected
841 typedef std::vector<molecule *> MoleculeVector_t;
842 MoleculeVector_t invertedSelection(getAllMolecules());
843 bool (World::*predicate)(const molecule*) const = &World::isSelected; // needed for type resolution of overloaded function
844 MoleculeVector_t::iterator iter =
845 std::remove_if(invertedSelection.begin(), invertedSelection.end(),
846 std::bind1st(std::mem_fun(predicate), this));
847 invertedSelection.erase(iter, invertedSelection.end());
848 // apply new selection
[7f1865d]849 unselectVectorOfInstances<MoleculeSet>(selectedMolecules.begin(), selectedMolecules.end());
[ebc499]850 selectedMolecules.clear();
851 void (World::*selector)(const molecule*) = &World::selectMolecule; // needed for type resolution of overloaded function
852 std::for_each(invertedSelection.begin(),invertedSelection.end(),
853 std::bind1st(std::mem_fun(selector),this)); // func is select... see above
854}
855
[cad383]856void World::popMoleculeSelection(){
[0249ce]857 if (!selectedMolecules_Stack.empty()) {
858 OBSERVE;
859 NOTIFY(SelectionChanged);
860 const moleculeIdsVector_t moleculeids = selectedMolecules_Stack.top();
861 boost::function<void (const moleculeId_t)> IdSelector =
862 boost::bind(static_cast<void (World::*)(const moleculeId_t)>(&World::selectMolecule), this, _1);
863 unselectVectorOfInstances<MoleculeSet>(selectedMolecules.begin(), selectedMolecules.end());
864 selectedMolecules.clear();
865 std::for_each(moleculeids.begin(),moleculeids.end(), IdSelector);
866 selectedMolecules_Stack.pop();
867 }
[cad383]868}
869
870void World::pushMoleculeSelection(){
871 OBSERVE;
872 NOTIFY(SelectionChanged);
[c1d837]873 moleculeIdsVector_t moleculeids(countSelectedMolecules(), (moleculeId_t)-1);
874 boost::function<moleculeId_t (const molecule*)> IdRetriever =
875 boost::bind(&molecule::getId, _1);
876 std::copy(
877 MapKeyIterator<MoleculeSelectionConstIterator>(beginMoleculeSelection()),
878 MapKeyIterator<MoleculeSelectionConstIterator>(endMoleculeSelection()),
879 moleculeids.begin());
880 selectedMolecules_Stack.push( moleculeids );
[7f1865d]881 unselectVectorOfInstances<MoleculeSet>(selectedMolecules.begin(), selectedMolecules.end());
[cad383]882 selectedMolecules.clear();
883}
884
[e4afb4]885void World::selectMolecule(const molecule *_mol){
[69643a]886 OBSERVE;
887 NOTIFY(SelectionChanged);
[e4afb4]888 // molecule * is unchanged in this function, but we do store entity as changeable
889 ASSERT(_mol,"Invalid pointer to molecule in selection");
[7f1865d]890 selectMolecule(_mol->getId());
[90c4280]891}
892
[e4afb4]893void World::selectMolecule(const moleculeId_t id){
[69643a]894 OBSERVE;
895 NOTIFY(SelectionChanged);
[90c4280]896 ASSERT(molecules.count(id),"Molecule Id selected that was not in the world");
[7f1865d]897 molecules[id]->select();
[90c4280]898 selectedMolecules[id]=molecules[id];
899}
900
[e472eab]901void World::selectAllMolecules(MoleculeDescriptor descr){
[69643a]902 OBSERVE;
903 NOTIFY(SelectionChanged);
[90c4280]904 internal_MoleculeIterator begin = getMoleculeIter_internal(descr);
905 internal_MoleculeIterator end = moleculeEnd_internal();
[e4afb4]906 void (World::*func)(const molecule*) = &World::selectMolecule; // needed for type resolution of overloaded function
[90c4280]907 for_each(begin,end,bind1st(mem_fun(func),this)); // func is select... see above
908}
909
[e4afb4]910void World::selectMoleculeOfAtom(const atom *_atom){
[69643a]911 OBSERVE;
912 NOTIFY(SelectionChanged);
[e4afb4]913 ASSERT(_atom,"Invalid atom pointer in selection of MoleculeOfAtom");
[270bdf]914 const molecule *mol=_atom->getMolecule();
[90c4280]915 // the atom might not be part of a molecule
916 if(mol){
917 selectMolecule(mol);
918 }
919}
920
[e4afb4]921void World::selectMoleculeOfAtom(const atomId_t id){
[69643a]922 OBSERVE;
923 NOTIFY(SelectionChanged);
[90c4280]924 ASSERT(atoms.count(id),"No such atom with given ID in selection of Molecules of Atom");\
925 selectMoleculeOfAtom(atoms[id]);
926}
927
[e4afb4]928void World::unselectMolecule(const molecule *_mol){
[69643a]929 OBSERVE;
930 NOTIFY(SelectionChanged);
[e4afb4]931 ASSERT(_mol,"invalid pointer in unselection of molecule");
932 unselectMolecule(_mol->getId());
[61d655e]933}
934
[e4afb4]935void World::unselectMolecule(const moleculeId_t id){
[69643a]936 OBSERVE;
937 NOTIFY(SelectionChanged);
[61d655e]938 ASSERT(molecules.count(id),"No such molecule with ID in unselection");
[7f1865d]939 molecules[id]->unselect();
[61d655e]940 selectedMolecules.erase(id);
941}
942
[e472eab]943void World::unselectAllMolecules(MoleculeDescriptor descr){
[69643a]944 OBSERVE;
945 NOTIFY(SelectionChanged);
[61d655e]946 internal_MoleculeIterator begin = getMoleculeIter_internal(descr);
947 internal_MoleculeIterator end = moleculeEnd_internal();
[e4afb4]948 void (World::*func)(const molecule*) = &World::unselectMolecule; // needed for type resolution of overloaded function
[61d655e]949 for_each(begin,end,bind1st(mem_fun(func),this)); // func is unselect... see above
950}
951
[e4afb4]952void World::unselectMoleculeOfAtom(const atom *_atom){
[69643a]953 OBSERVE;
954 NOTIFY(SelectionChanged);
[e4afb4]955 ASSERT(_atom,"Invalid atom pointer in selection of MoleculeOfAtom");
[270bdf]956 const molecule *mol=_atom->getMolecule();
[61d655e]957 // the atom might not be part of a molecule
958 if(mol){
959 unselectMolecule(mol);
960 }
961}
962
[e4afb4]963void World::unselectMoleculeOfAtom(const atomId_t id){
[69643a]964 OBSERVE;
965 NOTIFY(SelectionChanged);
[61d655e]966 ASSERT(atoms.count(id),"No such atom with given ID in selection of Molecules of Atom");\
967 unselectMoleculeOfAtom(atoms[id]);
968}
969
[e472eab]970size_t World::countSelectedMolecules() const {
[eacc3b]971 size_t count = 0;
[e472eab]972 for (MoleculeSet::const_iterator iter = selectedMolecules.begin(); iter != selectedMolecules.end(); ++iter)
[eacc3b]973 count++;
974 return count;
975}
976
[e4afb4]977bool World::isSelected(const molecule *_mol) const {
[7f1865d]978 const bool status = isMoleculeSelected(_mol->getId());
979 ASSERT( status == _mol->selected,
980 "World::isSelected() - mismatch in selection status between mol "+
981 toString(_mol->getId())+" and World.");
982 return status;
[89643d]983}
984
985bool World::isMoleculeSelected(const moleculeId_t no) const {
986 return selectedMolecules.find(no) != selectedMolecules.end();
[e0e156]987}
988
[97445f]989std::vector<molecule *> World::getSelectedMolecules() {
[e472eab]990 std::vector<molecule *> returnMolecules;
[97445f]991 std::transform(
992 selectedMolecules.begin(),
993 selectedMolecules.end(),
994 back_inserter(returnMolecules),
995 _take<molecule*,World::MoleculeSet::value_type>::get);
996 return returnMolecules;
997}
998
999std::vector<const molecule *> World::getSelectedMolecules() const {
1000 std::vector<const molecule *> returnMolecules;
1001 std::transform(
1002 selectedMolecules.begin(),
1003 selectedMolecules.end(),
1004 back_inserter(returnMolecules),
1005 _take<molecule*,World::MoleculeSet::value_type>::get);
[e472eab]1006 return returnMolecules;
1007}
1008
[143263]1009std::vector<moleculeId_t> World::getSelectedMoleculeIds() const {
1010 std::vector<moleculeId_t> returnMoleculeIds;
1011 std::transform(
1012 selectedMolecules.begin(),
1013 selectedMolecules.end(),
1014 back_inserter(returnMoleculeIds),
1015 _take<molecule*,World::MoleculeSet::value_type>::getKey);
1016 return returnMoleculeIds;
1017}
1018
[3839e5]1019/******************* Iterators over Selection *****************************/
1020World::AtomSelectionIterator World::beginAtomSelection(){
1021 return selectedAtoms.begin();
1022}
1023
1024World::AtomSelectionIterator World::endAtomSelection(){
1025 return selectedAtoms.end();
1026}
1027
[38f991]1028World::AtomSelectionConstIterator World::beginAtomSelection() const{
1029 return selectedAtoms.begin();
1030}
1031
1032World::AtomSelectionConstIterator World::endAtomSelection() const{
1033 return selectedAtoms.end();
1034}
1035
[3839e5]1036
1037World::MoleculeSelectionIterator World::beginMoleculeSelection(){
1038 return selectedMolecules.begin();
1039}
1040
1041World::MoleculeSelectionIterator World::endMoleculeSelection(){
1042 return selectedMolecules.end();
1043}
1044
[38f991]1045World::MoleculeSelectionConstIterator World::beginMoleculeSelection() const{
1046 return selectedMolecules.begin();
1047}
1048
1049World::MoleculeSelectionConstIterator World::endMoleculeSelection() const{
1050 return selectedMolecules.end();
1051}
1052
[5d1611]1053/******************************* Singleton Stuff **************************/
1054
[7a1ce5]1055World::World() :
[cd5047]1056 Observable("World"),
[f71baf]1057 BG(new BondGraph(true)), // assume Angstroem for the moment
[4ae823]1058 periode(new periodentafel(true)),
[8e1f7af]1059 configuration(new config),
[98dbee]1060 homologies(new HomologyContainer()),
[43dad6]1061 Thermostats(new ThermoStatContainer),
[e4b5de]1062 ExitFlag(0),
[fa0b18]1063 atoms(this),
[90c4280]1064 selectedAtoms(this),
[3e4fb6]1065 atomIdPool(0, 20, 100),
[51be2a]1066 molecules(this),
[90c4280]1067 selectedMolecules(this),
[2affd1]1068 moleculeIdPool(0, 20,100)
[7dad10]1069{
[84c494]1070 cell_size = new Box;
[cca9ef]1071 RealSpaceMatrix domain;
[84c494]1072 domain.at(0,0) = 20;
1073 domain.at(1,1) = 20;
1074 domain.at(2,2) = 20;
1075 cell_size->setM(domain);
[4834f4]1076 LCcontroller = new LinkedCell::LinkedCell_Controller(*cell_size);
[387b36]1077 defaultName = "none";
[02ce36]1078 Channels *OurChannel = new Channels;
[574d377]1079 Observable::insertNotificationChannel( std::make_pair( static_cast<Observable *>(this), OurChannel) );
[7188b1]1080 for (size_t type = 0; type < (size_t)NotificationType_MAX; ++type)
[02ce36]1081 OurChannel->addChannel(type);
[7dad10]1082}
[5d1611]1083
1084World::~World()
[354859]1085{
[4834f4]1086 delete LCcontroller;
[84c494]1087 delete cell_size;
[cbc5fb]1088 MoleculeSet::iterator molIter;
1089 for(molIter=molecules.begin();molIter!=molecules.end();++molIter){
1090 DeleteMolecule((*molIter).second);
1091 }
1092 molecules.clear();
1093 AtomSet::iterator atIter;
1094 for(atIter=atoms.begin();atIter!=atoms.end();++atIter){
1095 DeleteAtom((*atIter).second);
[46d958]1096 }
1097 atoms.clear();
[7188b1]1098
[f71baf]1099 delete BG;
[6cb9c76]1100 delete periode;
1101 delete configuration;
1102 delete Thermostats;
[09f615]1103 delete homologies;
[354859]1104}
[5d1611]1105
[23b547]1106// Explicit instantiation of the singleton mechanism at this point
[5d1611]1107
[3e4fb6]1108// moleculeId_t und atomId_t sind gleicher Basistyp, deswegen nur einen von beiden konstruieren
[b97a60]1109CONSTRUCT_IDPOOL(atomId_t, uniqueId)
1110CONSTRUCT_IDPOOL(moleculeId_t, continuousId)
[3e4fb6]1111
[23b547]1112CONSTRUCT_SINGLETON(World)
[5d1611]1113
[e2c2b1]1114CONSTRUCT_OBSERVEDCONTAINER(World::AtomSTLSet, UnobservedIterator<World::AtomSTLSet> )
[5f1d5b8]1115
[e2c2b1]1116CONSTRUCT_OBSERVEDCONTAINER(World::MoleculeSTLSet, UnobservedIterator<World::MoleculeSTLSet> )
Note: See TracBrowser for help on using the repository browser.