source: src/World.cpp@ ff4fff9

CombiningParticlePotentialParsing
Last change on this file since ff4fff9 was 2affd1, checked in by Frederik Heber <heber@…>, 9 years ago

Removed molecules_deprecated from World and unnecessary includes of MoleculeListClass and all insert/erase.

  • this goes along the lines of removing "remove me when we don't need MoleculeCistClass anymore".
  • Property mode set to 100644
File size: 32.1 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
236void 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
261void World::setTime(const unsigned int _step)
262{
263 if (_step != WorldTime::getTime()) {
264 const unsigned int oldstep = WorldTime::getTime();
265
266 // 1. copy bond graph (such not each addBond causes GUI update)
267 if (!areBondsPresent(_step)) {
268// AtomComposite Set = getAllAtoms();
269// BG->cleanAdjacencyList(Set);
270 copyBondgraph(oldstep, _step);
271 }
272
273 // 2. set new time
274 WorldTime::getInstance().setTime(_step);
275
276 // 4. scan for connected subgraphs => molecules
277 DepthFirstSearchAnalysis DFS;
278 DFS();
279 DFS.UpdateMoleculeStructure();
280 }
281}
282
283std::string World::getDefaultName() {
284 return defaultName;
285}
286
287void World::setDefaultName(std::string name)
288{
289 OBSERVE;
290 defaultName = name;
291};
292
293class ThermoStatContainer * World::getThermostats()
294{
295 return Thermostats;
296}
297
298
299int World::getExitFlag() {
300 return ExitFlag;
301}
302
303void World::setExitFlag(int flag) {
304 if (ExitFlag < flag)
305 ExitFlag = flag;
306}
307
308/******************** Methods to change World state *********************/
309
310molecule* World::createMolecule(){
311 OBSERVE;
312 molecule *mol = NULL;
313 mol = NewMolecule();
314 moleculeId_t id = moleculeIdPool.getNextId();
315 ASSERT(!molecules.count(id),"proposed id did not specify an unused ID");
316 mol->setId(id);
317 // store the molecule by ID
318 molecules[mol->getId()] = mol;
319 _lastchangedmol = mol;
320 _lastchangedmolid = mol->getId();
321 NOTIFY(MoleculeInserted);
322 return mol;
323}
324
325molecule* World::recreateMolecule(const moleculeId_t &_id)
326{
327 molecule *mol = NULL;
328 if (!molecules.count(_id)) {
329 OBSERVE;
330 mol = NewMolecule();
331 mol->setId(_id);
332 // store the molecule by ID
333 molecules[mol->getId()] = mol;
334 _lastchangedmol = mol;
335 _lastchangedmolid = mol->getId();
336 NOTIFY(MoleculeInserted);
337 }
338 return mol;
339}
340
341void World::destroyMolecule(molecule* mol){
342 ASSERT(mol,"Molecule that was meant to be destroyed did not exist");
343 destroyMolecule(mol->getId());
344}
345
346void World::destroyMolecule(moleculeId_t id){
347 molecule *mol = molecules[id];
348 ASSERT(mol,"Molecule id that was meant to be destroyed did not exist");
349 // give notice about immediate removal
350 {
351 OBSERVE;
352 _lastchangedmol = mol;
353 _lastchangedmolid = mol->getId();
354 NOTIFY(MoleculeRemoved);
355 }
356 if (isMoleculeSelected(id)) {
357 selectedMolecules.erase(id);
358 NOTIFY(SelectionChanged);
359 }
360 DeleteMolecule(mol);
361 molecules.erase(id);
362 moleculeIdPool.releaseId(id);
363}
364
365atom *World::createAtom(){
366 OBSERVE;
367 atomId_t id = atomIdPool.getNextId();
368 ASSERT(!atoms.count(id),"proposed id did not specify an unused ID");
369 atom *res = NewAtom(id);
370 res->setWorld(this);
371 // store the atom by ID
372 atoms[res->getId()] = res;
373 _lastchangedatom = res;
374 _lastchangedatomid = res->getId();
375 NOTIFY(AtomInserted);
376 return res;
377}
378
379atom *World::recreateAtom(const atomId_t _id){
380 if (!atoms.count(_id)) {
381 OBSERVE;
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 } else
391 return NULL;
392}
393
394
395int World::registerAtom(atom *atom){
396 OBSERVE;
397 atomId_t id = atomIdPool.getNextId();
398 atom->setId(id);
399 atom->setWorld(this);
400 atoms[atom->getId()] = atom;
401 _lastchangedatom = atom;
402 _lastchangedatomid = atom->getId();
403 NOTIFY(AtomInserted);
404 return atom->getId();
405}
406
407void World::destroyAtom(atom* atom){
408 int id = atom->getId();
409 destroyAtom(id);
410}
411
412void World::destroyAtom(atomId_t id) {
413 atom *atom = atoms[id];
414 ASSERT(atom,"Atom ID that was meant to be destroyed did not exist");
415 // give notice about immediate removal
416 {
417 OBSERVE;
418 _lastchangedatom = atom;
419 _lastchangedatomid = atom->getId();
420 NOTIFY(AtomRemoved);
421 }
422 // check if it's the last atom
423 molecule *_mol = const_cast<molecule *>(atom->getMolecule());
424 if ((_mol == NULL) || (_mol->getAtomCount() > 1))
425 _mol = NULL;
426 if (isAtomSelected(id)) {
427 selectedAtoms.erase(id);
428 NOTIFY(SelectionChanged);
429 }
430 DeleteAtom(atom);
431 atoms.erase(id);
432 atomIdPool.releaseId(id);
433 // remove molecule if empty
434 if (_mol != NULL)
435 destroyMolecule(_mol);
436}
437
438bool World::changeAtomId(atomId_t oldId, atomId_t newId, atom* target){
439 OBSERVE;
440 // in case this call did not originate from inside the atom, we redirect it,
441 // to also let it know that it has changed
442 if(!target){
443 target = atoms[oldId];
444 ASSERT(target,"Atom with that ID not found");
445 return target->changeId(newId);
446 }
447 else{
448 if(atomIdPool.reserveId(newId)){
449 atoms.erase(oldId);
450 atoms.insert(pair<atomId_t,atom*>(newId,target));
451 return true;
452 }
453 else{
454 return false;
455 }
456 }
457}
458
459bool World::changeMoleculeId(moleculeId_t oldId, moleculeId_t newId, molecule* target){
460 OBSERVE;
461 // in case this call did not originate from inside the atom, we redirect it,
462 // to also let it know that it has changed
463 if(!target){
464 target = molecules[oldId];
465 ASSERT(target,"Molecule with that ID not found");
466 return target->changeId(newId);
467 }
468 else{
469 if(moleculeIdPool.reserveId(newId)){
470 molecules.erase(oldId);
471 molecules.insert(pair<moleculeId_t,molecule*>(newId,target));
472 return true;
473 }
474 else{
475 return false;
476 }
477 }
478}
479
480ManipulateAtomsProcess* World::manipulateAtoms(boost::function<void(atom*)> op,std::string name,AtomDescriptor descr){
481 ActionTrait manipulateTrait(name);
482 return new ManipulateAtomsProcess(op, descr,manipulateTrait);
483}
484
485ManipulateAtomsProcess* World::manipulateAtoms(boost::function<void(atom*)> op,std::string name){
486 return manipulateAtoms(op,name,AllAtoms());
487}
488
489/********************* Internal Change methods for double Callback and Observer mechanism ********/
490
491void World::doManipulate(ManipulateAtomsProcess *proc){
492 proc->signOn(this);
493 {
494 OBSERVE;
495 proc->doManipulate(this);
496 }
497 proc->signOff(this);
498}
499/******************************* Iterators ********************************/
500
501// external parts with observers
502
503CONSTRUCT_SELECTIVE_ITERATOR(atom*,World::AtomSet,AtomDescriptor)
504
505CONSTRUCT_SELECTIVE_CONST_ITERATOR(atom*,World::AtomSet,AtomDescriptor)
506
507World::AtomIterator
508World::getAtomIter(AtomDescriptor descr){
509 return AtomIterator(descr,atoms);
510}
511
512World::AtomConstIterator
513World::getAtomIter(AtomDescriptor descr) const{
514 return AtomConstIterator(descr,atoms);
515}
516
517World::AtomIterator
518World::getAtomIter(){
519 return AtomIterator(AllAtoms(),atoms);
520}
521
522World::AtomConstIterator
523World::getAtomIter() const{
524 return AtomConstIterator(AllAtoms(),atoms);
525}
526
527World::AtomIterator
528World::atomEnd(){
529 return AtomIterator(AllAtoms(),atoms,atoms.end());
530}
531
532World::AtomConstIterator
533World::atomEnd() const{
534 return AtomConstIterator(AllAtoms(),atoms,atoms.end());
535}
536
537CONSTRUCT_SELECTIVE_ITERATOR(molecule*,World::MoleculeSet,MoleculeDescriptor)
538
539CONSTRUCT_SELECTIVE_CONST_ITERATOR(molecule*,World::MoleculeSet,MoleculeDescriptor)
540
541World::MoleculeIterator
542World::getMoleculeIter(MoleculeDescriptor descr){
543 return MoleculeIterator(descr,molecules);
544}
545
546World::MoleculeConstIterator
547World::getMoleculeIter(MoleculeDescriptor descr) const{
548 return MoleculeConstIterator(descr,molecules);
549}
550
551World::MoleculeIterator
552World::getMoleculeIter(){
553 return MoleculeIterator(AllMolecules(),molecules);
554}
555
556World::MoleculeConstIterator
557World::getMoleculeIter() const{
558 return MoleculeConstIterator(AllMolecules(),molecules);
559}
560
561World::MoleculeIterator
562World::moleculeEnd(){
563 return MoleculeIterator(AllMolecules(),molecules,molecules.end());
564}
565
566World::MoleculeConstIterator
567World::moleculeEnd() const{
568 return MoleculeConstIterator(AllMolecules(),molecules,molecules.end());
569}
570
571// Internal parts, without observers
572
573// Build the AtomIterator from template
574CONSTRUCT_SELECTIVE_ITERATOR(atom*,World::AtomSet::set_t,AtomDescriptor);
575
576
577World::internal_AtomIterator
578World::getAtomIter_internal(AtomDescriptor descr){
579 return internal_AtomIterator(descr,atoms.getContent());
580}
581
582World::internal_AtomIterator
583World::atomEnd_internal(){
584 return internal_AtomIterator(AllAtoms(),atoms.getContent(),atoms.end_internal());
585}
586
587// build the MoleculeIterator from template
588CONSTRUCT_SELECTIVE_ITERATOR(molecule*,World::MoleculeSet::set_t,MoleculeDescriptor);
589
590World::internal_MoleculeIterator World::getMoleculeIter_internal(MoleculeDescriptor descr){
591 return internal_MoleculeIterator(descr,molecules.getContent());
592}
593
594World::internal_MoleculeIterator World::moleculeEnd_internal(){
595 return internal_MoleculeIterator(AllMolecules(),molecules.getContent(),molecules.end_internal());
596}
597
598/************************** Selection of Atoms and molecules ******************/
599
600// translate type's selection member functions to overloaded with specific type
601
602template <class T>
603void World::selectVectorOfInstances(const typename T::iterator _begin, const typename T::iterator _end)
604{
605 std::for_each(_begin,_end,
606 boost::bind(&World::selectInstance<typename T::value_type::second_type>,
607 boost::bind(_take<typename T::value_type::second_type,typename T::value_type>::get, _1)));
608}
609
610template <class T>
611void World::unselectVectorOfInstances(const typename T::iterator _begin, const typename T::iterator _end)
612{
613 std::for_each(_begin,_end,
614 boost::bind(&World::unselectInstance<typename T::value_type::second_type>,
615 boost::bind(_take<typename T::value_type::second_type,typename T::value_type>::get, _1)));
616}
617
618// Atoms
619
620void World::clearAtomSelection(){
621 OBSERVE;
622 NOTIFY(SelectionChanged);
623 unselectVectorOfInstances<AtomSet>(selectedAtoms.begin(), selectedAtoms.end());
624 selectedAtoms.clear();
625}
626
627void World::invertAtomSelection(){
628 // get all atoms not selected
629 AtomComposite invertedSelection(getAllAtoms());
630 bool (World::*predicate)(const atom*) const = &World::isSelected; // needed for type resolution of overloaded function
631 AtomComposite::iterator iter =
632 std::remove_if(invertedSelection.begin(), invertedSelection.end(),
633 std::bind1st(std::mem_fun(predicate), this));
634 invertedSelection.erase(iter, invertedSelection.end());
635 // apply new selection
636 unselectVectorOfInstances<AtomSet>(selectedAtoms.begin(), selectedAtoms.end());
637 selectedAtoms.clear();
638 void (World::*selector)(const atom*) = &World::selectAtom; // needed for type resolution of overloaded function
639 std::for_each(invertedSelection.begin(),invertedSelection.end(),
640 std::bind1st(std::mem_fun(selector),this)); // func is select... see above
641}
642
643void World::popAtomSelection(){
644 OBSERVE;
645 NOTIFY(SelectionChanged);
646 const atomIdsVector_t atomids = selectedAtoms_Stack.top();
647 boost::function<void (const atomId_t)> IdSelector =
648 boost::bind(static_cast<void (World::*)(const atomId_t)>(&World::selectAtom), this, _1);
649 unselectVectorOfInstances<AtomSet>(selectedAtoms.begin(), selectedAtoms.end());
650 selectedAtoms.clear();
651 std::for_each(atomids.begin(),atomids.end(), IdSelector);
652 selectedAtoms_Stack.pop();
653}
654
655void World::pushAtomSelection(){
656 OBSERVE;
657 NOTIFY(SelectionChanged);
658 atomIdsVector_t atomids(countSelectedAtoms(), (atomId_t)-1);
659 std::copy(
660 MapKeyIterator<AtomSelectionConstIterator>(beginAtomSelection()),
661 MapKeyIterator<AtomSelectionConstIterator>(endAtomSelection()),
662 atomids.begin());
663 selectedAtoms_Stack.push( atomids );
664 unselectVectorOfInstances<AtomSet>(selectedAtoms.begin(), selectedAtoms.end());
665 selectedAtoms.clear();
666}
667
668void World::selectAtom(const atom *_atom){
669 OBSERVE;
670 NOTIFY(SelectionChanged);
671 // atom * is unchanged in this function, but we do store entity as changeable
672 ASSERT(_atom,"Invalid pointer in selection of atom");
673 selectAtom(_atom->getId());
674}
675
676void World::selectAtom(const atomId_t id){
677 OBSERVE;
678 NOTIFY(SelectionChanged);
679 ASSERT(atoms.count(id),"Atom Id selected that was not in the world");
680 selectedAtoms[id]=atoms[id];
681 atoms[id]->select();
682}
683
684void World::selectAllAtoms(AtomDescriptor descr){
685 OBSERVE;
686 NOTIFY(SelectionChanged);
687 internal_AtomIterator begin = getAtomIter_internal(descr);
688 internal_AtomIterator end = atomEnd_internal();
689 void (World::*func)(const atom*) = &World::selectAtom; // needed for type resolution of overloaded function
690 for_each(begin,end,bind1st(mem_fun(func),this)); // func is select... see above
691}
692
693void World::selectAtomsOfMolecule(const molecule *_mol){
694 OBSERVE;
695 NOTIFY(SelectionChanged);
696 ASSERT(_mol,"Invalid pointer to molecule in selection of Atoms of Molecule");
697 // need to make it const to get the fast iterators
698 const molecule *mol = _mol;
699 void (World::*func)(const atom*) = &World::selectAtom; // needed for type resolution of overloaded function
700 for_each(mol->begin(),mol->end(),bind1st(mem_fun(func),this)); // func is select... see above
701}
702
703void World::selectAtomsOfMolecule(const moleculeId_t id){
704 OBSERVE;
705 NOTIFY(SelectionChanged);
706 ASSERT(molecules.count(id),"No molecule with the given id upon Selection of atoms from molecule");
707 selectAtomsOfMolecule(molecules[id]);
708}
709
710void World::unselectAtom(const atom *_atom){
711 OBSERVE;
712 NOTIFY(SelectionChanged);
713 ASSERT(_atom,"Invalid pointer in unselection of atom");
714 unselectAtom(_atom->getId());
715}
716
717void World::unselectAtom(const atomId_t id){
718 OBSERVE;
719 NOTIFY(SelectionChanged);
720 ASSERT(atoms.count(id),"Atom Id unselected that was not in the world");
721 atoms[id]->unselect();
722 selectedAtoms.erase(id);
723}
724
725void World::unselectAllAtoms(AtomDescriptor descr){
726 OBSERVE;
727 NOTIFY(SelectionChanged);
728 internal_AtomIterator begin = getAtomIter_internal(descr);
729 internal_AtomIterator end = atomEnd_internal();
730 void (World::*func)(const atom*) = &World::unselectAtom; // needed for type resolution of overloaded function
731 for_each(begin,end,bind1st(mem_fun(func),this)); // func is unselect... see above
732}
733
734void World::unselectAtomsOfMolecule(const molecule *_mol){
735 OBSERVE;
736 NOTIFY(SelectionChanged);
737 ASSERT(_mol,"Invalid pointer to molecule in selection of Atoms of Molecule");
738 // need to make it const to get the fast iterators
739 const molecule *mol = _mol;
740 void (World::*func)(const atom*) = &World::unselectAtom; // needed for type resolution of overloaded function
741 for_each(mol->begin(),mol->end(),bind1st(mem_fun(func),this)); // func is unselect... see above
742}
743
744void World::unselectAtomsOfMolecule(const moleculeId_t id){
745 OBSERVE;
746 NOTIFY(SelectionChanged);
747 ASSERT(molecules.count(id),"No molecule with the given id upon Selection of atoms from molecule");
748 unselectAtomsOfMolecule(molecules[id]);
749}
750
751size_t World::countSelectedAtoms() const {
752 size_t count = 0;
753 for (AtomSet::const_iterator iter = selectedAtoms.begin(); iter != selectedAtoms.end(); ++iter)
754 count++;
755 return count;
756}
757
758bool World::isSelected(const atom *_atom) const {
759 const bool status = isAtomSelected(_atom->getId());
760 ASSERT( status == _atom->selected,
761 "World::isSelected() - mismatch between selection state in atom "+
762 toString(_atom->getId())+" and World.");
763 return status;
764}
765
766bool World::isAtomSelected(const atomId_t no) const {
767 return selectedAtoms.find(no) != selectedAtoms.end();
768}
769
770std::vector<atom *> World::getSelectedAtoms() {
771 std::vector<atom *> returnAtoms;
772 std::transform(
773 selectedAtoms.begin(),
774 selectedAtoms.end(),
775 back_inserter(returnAtoms),
776 _take<atom*,World::AtomSet::value_type>::get);
777 return returnAtoms;
778}
779
780std::vector<const atom *> World::getSelectedAtoms() const {
781 std::vector<const atom *> returnAtoms;
782 std::transform(
783 selectedAtoms.begin(),
784 selectedAtoms.end(),
785 back_inserter(returnAtoms),
786 _take<atom*,World::AtomSet::value_type>::get);
787 return returnAtoms;
788}
789
790std::vector<atomId_t> World::getSelectedAtomIds() const {
791 std::vector<atomId_t> returnAtomIds;
792 std::transform(
793 selectedAtoms.begin(),
794 selectedAtoms.end(),
795 back_inserter(returnAtomIds),
796 _take<atom*,World::AtomSet::value_type>::getKey);
797 return returnAtomIds;
798}
799
800// Molecules
801
802void World::clearMoleculeSelection(){
803 OBSERVE;
804 NOTIFY(SelectionChanged);
805 unselectVectorOfInstances<MoleculeSet>(selectedMolecules.begin(), selectedMolecules.end());
806 selectedMolecules.clear();
807}
808
809void World::invertMoleculeSelection(){
810 // get all molecules not selected
811 typedef std::vector<molecule *> MoleculeVector_t;
812 MoleculeVector_t invertedSelection(getAllMolecules());
813 bool (World::*predicate)(const molecule*) const = &World::isSelected; // needed for type resolution of overloaded function
814 MoleculeVector_t::iterator iter =
815 std::remove_if(invertedSelection.begin(), invertedSelection.end(),
816 std::bind1st(std::mem_fun(predicate), this));
817 invertedSelection.erase(iter, invertedSelection.end());
818 // apply new selection
819 unselectVectorOfInstances<MoleculeSet>(selectedMolecules.begin(), selectedMolecules.end());
820 selectedMolecules.clear();
821 void (World::*selector)(const molecule*) = &World::selectMolecule; // needed for type resolution of overloaded function
822 std::for_each(invertedSelection.begin(),invertedSelection.end(),
823 std::bind1st(std::mem_fun(selector),this)); // func is select... see above
824}
825
826void World::popMoleculeSelection(){
827 OBSERVE;
828 NOTIFY(SelectionChanged);
829 const moleculeIdsVector_t moleculeids = selectedMolecules_Stack.top();
830 boost::function<void (const moleculeId_t)> IdSelector =
831 boost::bind(static_cast<void (World::*)(const moleculeId_t)>(&World::selectMolecule), this, _1);
832 unselectVectorOfInstances<MoleculeSet>(selectedMolecules.begin(), selectedMolecules.end());
833 selectedMolecules.clear();
834 std::for_each(moleculeids.begin(),moleculeids.end(), IdSelector);
835 selectedMolecules_Stack.pop();
836}
837
838void World::pushMoleculeSelection(){
839 OBSERVE;
840 NOTIFY(SelectionChanged);
841 moleculeIdsVector_t moleculeids(countSelectedMolecules(), (moleculeId_t)-1);
842 boost::function<moleculeId_t (const molecule*)> IdRetriever =
843 boost::bind(&molecule::getId, _1);
844 std::copy(
845 MapKeyIterator<MoleculeSelectionConstIterator>(beginMoleculeSelection()),
846 MapKeyIterator<MoleculeSelectionConstIterator>(endMoleculeSelection()),
847 moleculeids.begin());
848 selectedMolecules_Stack.push( moleculeids );
849 unselectVectorOfInstances<MoleculeSet>(selectedMolecules.begin(), selectedMolecules.end());
850 selectedMolecules.clear();
851}
852
853void World::selectMolecule(const molecule *_mol){
854 OBSERVE;
855 NOTIFY(SelectionChanged);
856 // molecule * is unchanged in this function, but we do store entity as changeable
857 ASSERT(_mol,"Invalid pointer to molecule in selection");
858 selectMolecule(_mol->getId());
859}
860
861void World::selectMolecule(const moleculeId_t id){
862 OBSERVE;
863 NOTIFY(SelectionChanged);
864 ASSERT(molecules.count(id),"Molecule Id selected that was not in the world");
865 molecules[id]->select();
866 selectedMolecules[id]=molecules[id];
867}
868
869void World::selectAllMolecules(MoleculeDescriptor descr){
870 OBSERVE;
871 NOTIFY(SelectionChanged);
872 internal_MoleculeIterator begin = getMoleculeIter_internal(descr);
873 internal_MoleculeIterator end = moleculeEnd_internal();
874 void (World::*func)(const molecule*) = &World::selectMolecule; // needed for type resolution of overloaded function
875 for_each(begin,end,bind1st(mem_fun(func),this)); // func is select... see above
876}
877
878void World::selectMoleculeOfAtom(const atom *_atom){
879 OBSERVE;
880 NOTIFY(SelectionChanged);
881 ASSERT(_atom,"Invalid atom pointer in selection of MoleculeOfAtom");
882 const molecule *mol=_atom->getMolecule();
883 // the atom might not be part of a molecule
884 if(mol){
885 selectMolecule(mol);
886 }
887}
888
889void World::selectMoleculeOfAtom(const atomId_t id){
890 OBSERVE;
891 NOTIFY(SelectionChanged);
892 ASSERT(atoms.count(id),"No such atom with given ID in selection of Molecules of Atom");\
893 selectMoleculeOfAtom(atoms[id]);
894}
895
896void World::unselectMolecule(const molecule *_mol){
897 OBSERVE;
898 NOTIFY(SelectionChanged);
899 ASSERT(_mol,"invalid pointer in unselection of molecule");
900 unselectMolecule(_mol->getId());
901}
902
903void World::unselectMolecule(const moleculeId_t id){
904 OBSERVE;
905 NOTIFY(SelectionChanged);
906 ASSERT(molecules.count(id),"No such molecule with ID in unselection");
907 molecules[id]->unselect();
908 selectedMolecules.erase(id);
909}
910
911void World::unselectAllMolecules(MoleculeDescriptor descr){
912 OBSERVE;
913 NOTIFY(SelectionChanged);
914 internal_MoleculeIterator begin = getMoleculeIter_internal(descr);
915 internal_MoleculeIterator end = moleculeEnd_internal();
916 void (World::*func)(const molecule*) = &World::unselectMolecule; // needed for type resolution of overloaded function
917 for_each(begin,end,bind1st(mem_fun(func),this)); // func is unselect... see above
918}
919
920void World::unselectMoleculeOfAtom(const atom *_atom){
921 OBSERVE;
922 NOTIFY(SelectionChanged);
923 ASSERT(_atom,"Invalid atom pointer in selection of MoleculeOfAtom");
924 const molecule *mol=_atom->getMolecule();
925 // the atom might not be part of a molecule
926 if(mol){
927 unselectMolecule(mol);
928 }
929}
930
931void World::unselectMoleculeOfAtom(const atomId_t id){
932 OBSERVE;
933 NOTIFY(SelectionChanged);
934 ASSERT(atoms.count(id),"No such atom with given ID in selection of Molecules of Atom");\
935 unselectMoleculeOfAtom(atoms[id]);
936}
937
938size_t World::countSelectedMolecules() const {
939 size_t count = 0;
940 for (MoleculeSet::const_iterator iter = selectedMolecules.begin(); iter != selectedMolecules.end(); ++iter)
941 count++;
942 return count;
943}
944
945bool World::isSelected(const molecule *_mol) const {
946 const bool status = isMoleculeSelected(_mol->getId());
947 ASSERT( status == _mol->selected,
948 "World::isSelected() - mismatch in selection status between mol "+
949 toString(_mol->getId())+" and World.");
950 return status;
951}
952
953bool World::isMoleculeSelected(const moleculeId_t no) const {
954 return selectedMolecules.find(no) != selectedMolecules.end();
955}
956
957std::vector<molecule *> World::getSelectedMolecules() {
958 std::vector<molecule *> returnMolecules;
959 std::transform(
960 selectedMolecules.begin(),
961 selectedMolecules.end(),
962 back_inserter(returnMolecules),
963 _take<molecule*,World::MoleculeSet::value_type>::get);
964 return returnMolecules;
965}
966
967std::vector<const molecule *> World::getSelectedMolecules() const {
968 std::vector<const molecule *> returnMolecules;
969 std::transform(
970 selectedMolecules.begin(),
971 selectedMolecules.end(),
972 back_inserter(returnMolecules),
973 _take<molecule*,World::MoleculeSet::value_type>::get);
974 return returnMolecules;
975}
976
977std::vector<moleculeId_t> World::getSelectedMoleculeIds() const {
978 std::vector<moleculeId_t> returnMoleculeIds;
979 std::transform(
980 selectedMolecules.begin(),
981 selectedMolecules.end(),
982 back_inserter(returnMoleculeIds),
983 _take<molecule*,World::MoleculeSet::value_type>::getKey);
984 return returnMoleculeIds;
985}
986
987/******************* Iterators over Selection *****************************/
988World::AtomSelectionIterator World::beginAtomSelection(){
989 return selectedAtoms.begin();
990}
991
992World::AtomSelectionIterator World::endAtomSelection(){
993 return selectedAtoms.end();
994}
995
996World::AtomSelectionConstIterator World::beginAtomSelection() const{
997 return selectedAtoms.begin();
998}
999
1000World::AtomSelectionConstIterator World::endAtomSelection() const{
1001 return selectedAtoms.end();
1002}
1003
1004
1005World::MoleculeSelectionIterator World::beginMoleculeSelection(){
1006 return selectedMolecules.begin();
1007}
1008
1009World::MoleculeSelectionIterator World::endMoleculeSelection(){
1010 return selectedMolecules.end();
1011}
1012
1013World::MoleculeSelectionConstIterator World::beginMoleculeSelection() const{
1014 return selectedMolecules.begin();
1015}
1016
1017World::MoleculeSelectionConstIterator World::endMoleculeSelection() const{
1018 return selectedMolecules.end();
1019}
1020
1021/******************************* Singleton Stuff **************************/
1022
1023World::World() :
1024 Observable("World"),
1025 BG(new BondGraph(true)), // assume Angstroem for the moment
1026 periode(new periodentafel(true)),
1027 configuration(new config),
1028 homologies(new HomologyContainer()),
1029 Thermostats(new ThermoStatContainer),
1030 ExitFlag(0),
1031 atoms(this),
1032 selectedAtoms(this),
1033 atomIdPool(0, 20, 100),
1034 molecules(this),
1035 selectedMolecules(this),
1036 moleculeIdPool(0, 20,100)
1037{
1038 cell_size = new Box;
1039 RealSpaceMatrix domain;
1040 domain.at(0,0) = 20;
1041 domain.at(1,1) = 20;
1042 domain.at(2,2) = 20;
1043 cell_size->setM(domain);
1044 LCcontroller = new LinkedCell::LinkedCell_Controller(*cell_size);
1045 defaultName = "none";
1046 Channels *OurChannel = new Channels;
1047 Observable::insertNotificationChannel( std::make_pair( static_cast<Observable *>(this), OurChannel) );
1048 for (size_t type = 0; type < (size_t)NotificationType_MAX; ++type)
1049 OurChannel->addChannel(type);
1050}
1051
1052World::~World()
1053{
1054 delete LCcontroller;
1055 delete cell_size;
1056 MoleculeSet::iterator molIter;
1057 for(molIter=molecules.begin();molIter!=molecules.end();++molIter){
1058 DeleteMolecule((*molIter).second);
1059 }
1060 molecules.clear();
1061 AtomSet::iterator atIter;
1062 for(atIter=atoms.begin();atIter!=atoms.end();++atIter){
1063 DeleteAtom((*atIter).second);
1064 }
1065 atoms.clear();
1066
1067 delete BG;
1068 delete periode;
1069 delete configuration;
1070 delete Thermostats;
1071 delete homologies;
1072}
1073
1074// Explicit instantiation of the singleton mechanism at this point
1075
1076// moleculeId_t und atomId_t sind gleicher Basistyp, deswegen nur einen von beiden konstruieren
1077CONSTRUCT_IDPOOL(atomId_t, uniqueId)
1078CONSTRUCT_IDPOOL(moleculeId_t, continuousId)
1079
1080CONSTRUCT_SINGLETON(World)
1081
1082CONSTRUCT_OBSERVEDCONTAINER(World::AtomSTLSet, UnobservedIterator<World::AtomSTLSet> )
1083
1084CONSTRUCT_OBSERVEDCONTAINER(World::MoleculeSTLSet, UnobservedIterator<World::MoleculeSTLSet> )
Note: See TracBrowser for help on using the repository browser.