source: src/World.cpp@ 9f2071

Action_Thermostats Add_AtomRandomPerturbation Add_SelectAtomByNameAction Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_StructOpt_integration_tests AutomationFragmentation_failures Candidate_v1.6.1 Candidate_v1.7.0 ChangeBugEmailaddress ChemicalSpaceEvaluator Docu_Python_wait EmpiricalPotential_contain_HomologyGraph_documentation Enhance_userguide Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Example_ManyWaysToTranslateAtom Exclude_Hydrogens_annealWithBondGraph Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns ForceAnnealing_oldresults ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion Gui_displays_atomic_force_velocity IndependentFragmentGrids_IntegrationTest JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks StoppableMakroAction TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps stable
Last change on this file since 9f2071 was 9f2071, checked in by Frederik Heber <frederik.heber@…>, 8 years ago

FIX: World::setTime() now correctly copies the current state to the next time step.

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