source: src/World.cpp@ 52575c

Action_Thermostats Add_AtomRandomPerturbation Add_FitFragmentPartialChargesAction Add_RotateAroundBondAction Add_SelectAtomByNameAction Added_ParseSaveFragmentResults AddingActions_SaveParseParticleParameters Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_ParticleName_to_Atom Adding_StructOpt_integration_tests AtomFragments Automaking_mpqc_open AutomationFragmentation_failures Candidate_v1.5.4 Candidate_v1.6.0 Candidate_v1.6.1 ChangeBugEmailaddress ChangingTestPorts ChemicalSpaceEvaluator CombiningParticlePotentialParsing Combining_Subpackages Debian_Package_split Debian_package_split_molecuildergui_only Disabling_MemDebug Docu_Python_wait EmpiricalPotential_contain_HomologyGraph EmpiricalPotential_contain_HomologyGraph_documentation Enable_parallel_make_install Enhance_userguide Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Example_ManyWaysToTranslateAtom Exclude_Hydrogens_annealWithBondGraph FitPartialCharges_GlobalError Fix_BoundInBox_CenterInBox_MoleculeActions Fix_ChargeSampling_PBC Fix_ChronosMutex Fix_FitPartialCharges Fix_FitPotential_needs_atomicnumbers Fix_ForceAnnealing Fix_IndependentFragmentGrids Fix_ParseParticles Fix_ParseParticles_split_forward_backward_Actions Fix_PopActions Fix_QtFragmentList_sorted_selection Fix_Restrictedkeyset_FragmentMolecule Fix_StatusMsg Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns Fix_fitting_potentials Fixes ForceAnnealing_goodresults ForceAnnealing_oldresults ForceAnnealing_tocheck ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion FragmentAction_writes_AtomFragments FragmentMolecule_checks_bonddegrees GeometryObjects Gui_Fixes Gui_displays_atomic_force_velocity ImplicitCharges IndependentFragmentGrids IndependentFragmentGrids_IndividualZeroInstances IndependentFragmentGrids_IntegrationTest IndependentFragmentGrids_Sole_NN_Calculation JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool JobMarket_unresolvable_hostname_fix MoreRobust_FragmentAutomation ODR_violation_mpqc_open PartialCharges_OrthogonalSummation PdbParser_setsAtomName PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks Rewrite_FitPartialCharges RotateToPrincipalAxisSystem_UndoRedo SaturateAtoms_findBestMatching SaturateAtoms_singleDegree StoppableMakroAction Subpackage_CodePatterns Subpackage_JobMarket Subpackage_LinearAlgebra Subpackage_levmar Subpackage_mpqc_open Subpackage_vmg Switchable_LogView ThirdParty_MPQC_rebuilt_buildsystem TrajectoryDependenant_MaxOrder TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps TremoloParser_setsAtomName Ubuntu_1604_changes stable
Last change on this file since 52575c was 65d7ca, checked in by Michael Ankele <ankele@…>, 12 years ago

Fix: World::registerAtom() did not notify observers

  • Property mode set to 100644
File size: 22.3 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 * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
6 */
7
8/*
9 * World.cpp
10 *
11 * Created on: Feb 3, 2010
12 * Author: crueger
13 */
14
15// include config.h
16#ifdef HAVE_CONFIG_H
17#include <config.h>
18#endif
19
20#include "CodePatterns/MemDebug.hpp"
21
22#include "World.hpp"
23
24#include <functional>
25
26#include "Actions/ActionTrait.hpp"
27#include "Actions/ManipulateAtomsProcess.hpp"
28#include "Atom/atom.hpp"
29#include "Atom/AtomObserver.hpp"
30#include "Box.hpp"
31#include "CodePatterns/Assert.hpp"
32#include "config.hpp"
33#include "Descriptors/AtomDescriptor.hpp"
34#include "Descriptors/AtomDescriptor_impl.hpp"
35#include "Descriptors/AtomSelectionDescriptor.hpp"
36#include "Descriptors/MoleculeDescriptor.hpp"
37#include "Descriptors/MoleculeDescriptor_impl.hpp"
38#include "Descriptors/MoleculeSelectionDescriptor.hpp"
39#include "Descriptors/SelectiveIterator_impl.hpp"
40#include "Element/periodentafel.hpp"
41#include "Graph/BondGraph.hpp"
42#include "Graph/DepthFirstSearchAnalysis.hpp"
43#include "Helpers/defs.hpp"
44#include "LinearAlgebra/RealSpaceMatrix.hpp"
45#include "LinkedCell/LinkedCell_Controller.hpp"
46#include "LinkedCell/PointCloudAdaptor.hpp"
47#include "molecule.hpp"
48#include "MoleculeListClass.hpp"
49#include "Thermostats/ThermoStatContainer.hpp"
50#include "WorldTime.hpp"
51
52#include "IdPool_impl.hpp"
53
54#include "CodePatterns/IteratorAdaptors.hpp"
55#include "CodePatterns/Singleton_impl.hpp"
56#include "CodePatterns/Observer/Channels.hpp"
57#include "CodePatterns/Observer/ObservedContainer_impl.hpp"
58
59using namespace MoleCuilder;
60
61/******************************* Notifications ************************/
62
63
64atom* World::_lastchangedatom = NULL;
65molecule* World::_lastchangedmol = NULL;
66
67/******************************* getter and setter ************************/
68periodentafel *&World::getPeriode()
69{
70 return periode;
71}
72
73BondGraph *&World::getBondGraph()
74{
75 return BG;
76}
77
78void World::setBondGraph(BondGraph *_BG){
79 delete (BG);
80 BG = _BG;
81}
82
83config *&World::getConfig(){
84 return configuration;
85}
86
87// Atoms
88
89atom* World::getAtom(AtomDescriptor descriptor){
90 return descriptor.find();
91}
92
93World::AtomComposite World::getAllAtoms(AtomDescriptor descriptor){
94 return descriptor.findAll();
95}
96
97World::AtomComposite World::getAllAtoms(){
98 return getAllAtoms(AllAtoms());
99}
100
101int World::numAtoms(){
102 return atoms.size();
103}
104
105// Molecules
106
107molecule *World::getMolecule(MoleculeDescriptor descriptor){
108 return descriptor.find();
109}
110
111std::vector<molecule*> World::getAllMolecules(MoleculeDescriptor descriptor){
112 return descriptor.findAll();
113}
114
115std::vector<molecule*> World::getAllMolecules(){
116 return getAllMolecules(AllMolecules());
117}
118
119int World::numMolecules(){
120 return molecules_deprecated->ListOfMolecules.size();
121}
122
123// system
124
125Box& World::getDomain() {
126 return *cell_size;
127}
128
129void World::setDomain(const RealSpaceMatrix &mat){
130 OBSERVE;
131 *cell_size = mat;
132}
133
134void World::setDomain(double * matrix)
135{
136 OBSERVE;
137 RealSpaceMatrix M = ReturnFullMatrixforSymmetric(matrix);
138 cell_size->setM(M);
139}
140
141LinkedCell::LinkedCell_View World::getLinkedCell(const double distance)
142{
143 // we have to grope past the ObservedContainer mechanism and transmorph the map
144 // into a traversable list for the adaptor
145 PointCloudAdaptor< AtomSet::set_t, MapValueIterator<AtomSet::set_t::iterator> > atomset(
146 &(atoms.getContent()),
147 std::string("WorldsAtoms"));
148 return LCcontroller->getView(distance, atomset);
149}
150
151void World::setTime(const unsigned int _step)
152{
153 if (_step != WorldTime::getTime()) {
154 // set new time
155 WorldTime::getInstance().setTime(_step);
156 // TODO: removed when BondGraph creates the adjacency
157 // 1. remove all of World's molecules
158 for (MoleculeIterator iter = getMoleculeIter();
159 getMoleculeIter() != moleculeEnd();
160 iter = getMoleculeIter()) {
161 getMolecules()->erase(*iter);
162 destroyMolecule(*iter);
163 }
164 // 2. (re-)create bondgraph
165 AtomComposite Set = getAllAtoms();
166 BG->CreateAdjacency(Set);
167
168 // 3. scan for connected subgraphs => molecules
169 DepthFirstSearchAnalysis DFS;
170 DFS();
171 DFS.UpdateMoleculeStructure();
172 }
173}
174
175std::string World::getDefaultName() {
176 return defaultName;
177}
178
179void World::setDefaultName(std::string name)
180{
181 OBSERVE;
182 defaultName = name;
183};
184
185class ThermoStatContainer * World::getThermostats()
186{
187 return Thermostats;
188}
189
190
191int World::getExitFlag() {
192 return ExitFlag;
193}
194
195void World::setExitFlag(int flag) {
196 if (ExitFlag < flag)
197 ExitFlag = flag;
198}
199
200/******************** Methods to change World state *********************/
201
202molecule* World::createMolecule(){
203 OBSERVE;
204 molecule *mol = NULL;
205 mol = NewMolecule();
206 moleculeId_t id = moleculeIdPool.getNextId();
207 ASSERT(!molecules.count(id),"proposed id did not specify an unused ID");
208 mol->setId(id);
209 // store the molecule by ID
210 molecules[mol->getId()] = mol;
211 mol->signOn(this);
212 _lastchangedmol = mol;
213 NOTIFY(MoleculeInserted);
214 return mol;
215}
216
217void World::destroyMolecule(molecule* mol){
218 OBSERVE;
219 ASSERT(mol,"Molecule that was meant to be destroyed did not exist");
220 destroyMolecule(mol->getId());
221}
222
223void World::destroyMolecule(moleculeId_t id){
224 molecule *mol = molecules[id];
225 ASSERT(mol,"Molecule id that was meant to be destroyed did not exist");
226 // give notice about immediate removal
227 {
228 OBSERVE;
229 _lastchangedmol = mol;
230 NOTIFY(MoleculeRemoved);
231 }
232 DeleteMolecule(mol);
233 if (isMoleculeSelected(id))
234 selectedMolecules.erase(id);
235 molecules.erase(id);
236 moleculeIdPool.releaseId(id);
237}
238
239atom *World::createAtom(){
240 OBSERVE;
241 atomId_t id = atomIdPool.getNextId();
242 ASSERT(!atoms.count(id),"proposed id did not specify an unused ID");
243 atom *res = NewAtom(id);
244 res->setWorld(this);
245 // sign on to global atom change tracker
246 AtomObserver::getInstance().AtomInserted(res);
247 // store the atom by ID
248 atoms[res->getId()] = res;
249 _lastchangedatom = res;
250 NOTIFY(AtomInserted);
251 return res;
252}
253
254
255int World::registerAtom(atom *atom){
256 OBSERVE;
257 atomId_t id = atomIdPool.getNextId();
258 atom->setId(id);
259 atom->setWorld(this);
260 atoms[atom->getId()] = atom;
261 _lastchangedatom = atom;
262 NOTIFY(AtomInserted);
263 return atom->getId();
264}
265
266void World::destroyAtom(atom* atom){
267 int id = atom->getId();
268 destroyAtom(id);
269}
270
271void World::destroyAtom(atomId_t id) {
272 atom *atom = atoms[id];
273 ASSERT(atom,"Atom ID that was meant to be destroyed did not exist");
274 // give notice about immediate removal
275 {
276 OBSERVE;
277 _lastchangedatom = atom;
278 NOTIFY(AtomRemoved);
279 }
280 DeleteAtom(atom);
281 if (isAtomSelected(id))
282 selectedAtoms.erase(id);
283 atoms.erase(id);
284 atomIdPool.releaseId(id);
285}
286
287bool World::changeAtomId(atomId_t oldId, atomId_t newId, atom* target){
288 OBSERVE;
289 // in case this call did not originate from inside the atom, we redirect it,
290 // to also let it know that it has changed
291 if(!target){
292 target = atoms[oldId];
293 ASSERT(target,"Atom with that ID not found");
294 return target->changeId(newId);
295 }
296 else{
297 if(atomIdPool.reserveId(newId)){
298 atoms.erase(oldId);
299 atoms.insert(pair<atomId_t,atom*>(newId,target));
300 return true;
301 }
302 else{
303 return false;
304 }
305 }
306}
307
308bool World::changeMoleculeId(moleculeId_t oldId, moleculeId_t newId, molecule* target){
309 OBSERVE;
310 // in case this call did not originate from inside the atom, we redirect it,
311 // to also let it know that it has changed
312 if(!target){
313 target = molecules[oldId];
314 ASSERT(target,"Molecule with that ID not found");
315 return target->changeId(newId);
316 }
317 else{
318 if(moleculeIdPool.reserveId(newId)){
319 molecules.erase(oldId);
320 molecules.insert(pair<moleculeId_t,molecule*>(newId,target));
321 return true;
322 }
323 else{
324 return false;
325 }
326 }
327}
328
329ManipulateAtomsProcess* World::manipulateAtoms(boost::function<void(atom*)> op,std::string name,AtomDescriptor descr){
330 ActionTrait manipulateTrait(name);
331 return new ManipulateAtomsProcess(op, descr,manipulateTrait,false);
332}
333
334ManipulateAtomsProcess* World::manipulateAtoms(boost::function<void(atom*)> op,std::string name){
335 return manipulateAtoms(op,name,AllAtoms());
336}
337
338/********************* Internal Change methods for double Callback and Observer mechanism ********/
339
340void World::doManipulate(ManipulateAtomsProcess *proc){
341 proc->signOn(this);
342 {
343 OBSERVE;
344 proc->doManipulate(this);
345 }
346 proc->signOff(this);
347}
348/******************************* Iterators ********************************/
349
350// external parts with observers
351
352CONSTRUCT_SELECTIVE_ITERATOR(atom*,World::AtomSet,AtomDescriptor);
353
354World::AtomIterator
355World::getAtomIter(AtomDescriptor descr){
356 return AtomIterator(descr,atoms);
357}
358
359World::AtomIterator
360World::getAtomIter(){
361 return AtomIterator(AllAtoms(),atoms);
362}
363
364World::AtomIterator
365World::atomEnd(){
366 return AtomIterator(AllAtoms(),atoms,atoms.end());
367}
368
369CONSTRUCT_SELECTIVE_ITERATOR(molecule*,World::MoleculeSet,MoleculeDescriptor);
370
371World::MoleculeIterator
372World::getMoleculeIter(MoleculeDescriptor descr){
373 return MoleculeIterator(descr,molecules);
374}
375
376World::MoleculeIterator
377World::getMoleculeIter(){
378 return MoleculeIterator(AllMolecules(),molecules);
379}
380
381World::MoleculeIterator
382World::moleculeEnd(){
383 return MoleculeIterator(AllMolecules(),molecules,molecules.end());
384}
385
386// Internal parts, without observers
387
388// Build the AtomIterator from template
389CONSTRUCT_SELECTIVE_ITERATOR(atom*,World::AtomSet::set_t,AtomDescriptor);
390
391
392World::internal_AtomIterator
393World::getAtomIter_internal(AtomDescriptor descr){
394 return internal_AtomIterator(descr,atoms.getContent());
395}
396
397World::internal_AtomIterator
398World::atomEnd_internal(){
399 return internal_AtomIterator(AllAtoms(),atoms.getContent(),atoms.end_internal());
400}
401
402// build the MoleculeIterator from template
403CONSTRUCT_SELECTIVE_ITERATOR(molecule*,World::MoleculeSet::set_t,MoleculeDescriptor);
404
405World::internal_MoleculeIterator World::getMoleculeIter_internal(MoleculeDescriptor descr){
406 return internal_MoleculeIterator(descr,molecules.getContent());
407}
408
409World::internal_MoleculeIterator World::moleculeEnd_internal(){
410 return internal_MoleculeIterator(AllMolecules(),molecules.getContent(),molecules.end_internal());
411}
412
413/************************** Selection of Atoms and molecules ******************/
414
415// Atoms
416
417void World::clearAtomSelection(){
418 OBSERVE;
419 NOTIFY(SelectionChanged);
420 selectedAtoms.clear();
421}
422
423void World::invertAtomSelection(){
424 // get all atoms not selected
425 AtomComposite invertedSelection(getAllAtoms());
426 bool (World::*predicate)(const atom*) const = &World::isSelected; // needed for type resolution of overloaded function
427 AtomComposite::iterator iter =
428 std::remove_if(invertedSelection.begin(), invertedSelection.end(),
429 std::bind1st(std::mem_fun(predicate), this));
430 invertedSelection.erase(iter, invertedSelection.end());
431 // apply new selection
432 selectedAtoms.clear();
433 void (World::*selector)(const atom*) = &World::selectAtom; // needed for type resolution of overloaded function
434 std::for_each(invertedSelection.begin(),invertedSelection.end(),
435 std::bind1st(std::mem_fun(selector),this)); // func is select... see above
436}
437
438void World::selectAtom(const atom *_atom){
439 OBSERVE;
440 NOTIFY(SelectionChanged);
441 // atom * is unchanged in this function, but we do store entity as changeable
442 ASSERT(_atom,"Invalid pointer in selection of atom");
443 selectedAtoms[_atom->getId()]=const_cast<atom *>(_atom);
444}
445
446void World::selectAtom(const atomId_t id){
447 OBSERVE;
448 NOTIFY(SelectionChanged);
449 ASSERT(atoms.count(id),"Atom Id selected that was not in the world");
450 selectedAtoms[id]=atoms[id];
451}
452
453void World::selectAllAtoms(AtomDescriptor descr){
454 OBSERVE;
455 NOTIFY(SelectionChanged);
456 internal_AtomIterator begin = getAtomIter_internal(descr);
457 internal_AtomIterator end = atomEnd_internal();
458 void (World::*func)(const atom*) = &World::selectAtom; // needed for type resolution of overloaded function
459 for_each(begin,end,bind1st(mem_fun(func),this)); // func is select... see above
460}
461
462void World::selectAtomsOfMolecule(const molecule *_mol){
463 OBSERVE;
464 NOTIFY(SelectionChanged);
465 ASSERT(_mol,"Invalid pointer to molecule in selection of Atoms of Molecule");
466 // need to make it const to get the fast iterators
467 const molecule *mol = _mol;
468 void (World::*func)(const atom*) = &World::selectAtom; // needed for type resolution of overloaded function
469 for_each(mol->begin(),mol->end(),bind1st(mem_fun(func),this)); // func is select... see above
470}
471
472void World::selectAtomsOfMolecule(const moleculeId_t id){
473 OBSERVE;
474 NOTIFY(SelectionChanged);
475 ASSERT(molecules.count(id),"No molecule with the given id upon Selection of atoms from molecule");
476 selectAtomsOfMolecule(molecules[id]);
477}
478
479void World::unselectAtom(const atom *_atom){
480 OBSERVE;
481 NOTIFY(SelectionChanged);
482 ASSERT(_atom,"Invalid pointer in unselection of atom");
483 unselectAtom(_atom->getId());
484}
485
486void World::unselectAtom(const atomId_t id){
487 OBSERVE;
488 NOTIFY(SelectionChanged);
489 ASSERT(atoms.count(id),"Atom Id unselected that was not in the world");
490 selectedAtoms.erase(id);
491}
492
493void World::unselectAllAtoms(AtomDescriptor descr){
494 OBSERVE;
495 NOTIFY(SelectionChanged);
496 internal_AtomIterator begin = getAtomIter_internal(descr);
497 internal_AtomIterator end = atomEnd_internal();
498 void (World::*func)(const atom*) = &World::unselectAtom; // needed for type resolution of overloaded function
499 for_each(begin,end,bind1st(mem_fun(func),this)); // func is unselect... see above
500}
501
502void World::unselectAtomsOfMolecule(const molecule *_mol){
503 OBSERVE;
504 NOTIFY(SelectionChanged);
505 ASSERT(_mol,"Invalid pointer to molecule in selection of Atoms of Molecule");
506 // need to make it const to get the fast iterators
507 const molecule *mol = _mol;
508 void (World::*func)(const atom*) = &World::unselectAtom; // needed for type resolution of overloaded function
509 for_each(mol->begin(),mol->end(),bind1st(mem_fun(func),this)); // func is unselect... see above
510}
511
512void World::unselectAtomsOfMolecule(const moleculeId_t id){
513 OBSERVE;
514 NOTIFY(SelectionChanged);
515 ASSERT(molecules.count(id),"No molecule with the given id upon Selection of atoms from molecule");
516 unselectAtomsOfMolecule(molecules[id]);
517}
518
519size_t World::countSelectedAtoms() const {
520 size_t count = 0;
521 for (AtomSet::const_iterator iter = selectedAtoms.begin(); iter != selectedAtoms.end(); ++iter)
522 count++;
523 return count;
524}
525
526bool World::isSelected(const atom *_atom) const {
527 return isAtomSelected(_atom->getId());
528}
529
530bool World::isAtomSelected(const atomId_t no) const {
531 return selectedAtoms.find(no) != selectedAtoms.end();
532}
533
534const std::vector<atom *> World::getSelectedAtoms() const {
535 std::vector<atom *> returnAtoms;
536 returnAtoms.resize(countSelectedAtoms());
537 int count = 0;
538 for (AtomSet::const_iterator iter = selectedAtoms.begin(); iter != selectedAtoms.end(); ++iter)
539 returnAtoms[count++] = iter->second;
540 return returnAtoms;
541}
542
543
544// Molecules
545
546void World::clearMoleculeSelection(){
547 OBSERVE;
548 NOTIFY(SelectionChanged);
549 selectedMolecules.clear();
550}
551
552void World::invertMoleculeSelection(){
553 // get all molecules not selected
554 typedef std::vector<molecule *> MoleculeVector_t;
555 MoleculeVector_t invertedSelection(getAllMolecules());
556 bool (World::*predicate)(const molecule*) const = &World::isSelected; // needed for type resolution of overloaded function
557 MoleculeVector_t::iterator iter =
558 std::remove_if(invertedSelection.begin(), invertedSelection.end(),
559 std::bind1st(std::mem_fun(predicate), this));
560 invertedSelection.erase(iter, invertedSelection.end());
561 // apply new selection
562 selectedMolecules.clear();
563 void (World::*selector)(const molecule*) = &World::selectMolecule; // needed for type resolution of overloaded function
564 std::for_each(invertedSelection.begin(),invertedSelection.end(),
565 std::bind1st(std::mem_fun(selector),this)); // func is select... see above
566}
567
568void World::selectMolecule(const molecule *_mol){
569 OBSERVE;
570 NOTIFY(SelectionChanged);
571 // molecule * is unchanged in this function, but we do store entity as changeable
572 ASSERT(_mol,"Invalid pointer to molecule in selection");
573 selectedMolecules[_mol->getId()]=const_cast<molecule *>(_mol);
574}
575
576void World::selectMolecule(const moleculeId_t id){
577 OBSERVE;
578 NOTIFY(SelectionChanged);
579 ASSERT(molecules.count(id),"Molecule Id selected that was not in the world");
580 selectedMolecules[id]=molecules[id];
581}
582
583void World::selectAllMolecules(MoleculeDescriptor descr){
584 OBSERVE;
585 NOTIFY(SelectionChanged);
586 internal_MoleculeIterator begin = getMoleculeIter_internal(descr);
587 internal_MoleculeIterator end = moleculeEnd_internal();
588 void (World::*func)(const molecule*) = &World::selectMolecule; // needed for type resolution of overloaded function
589 for_each(begin,end,bind1st(mem_fun(func),this)); // func is select... see above
590}
591
592void World::selectMoleculeOfAtom(const atom *_atom){
593 OBSERVE;
594 NOTIFY(SelectionChanged);
595 ASSERT(_atom,"Invalid atom pointer in selection of MoleculeOfAtom");
596 molecule *mol=_atom->getMolecule();
597 // the atom might not be part of a molecule
598 if(mol){
599 selectMolecule(mol);
600 }
601}
602
603void World::selectMoleculeOfAtom(const atomId_t id){
604 OBSERVE;
605 NOTIFY(SelectionChanged);
606 ASSERT(atoms.count(id),"No such atom with given ID in selection of Molecules of Atom");\
607 selectMoleculeOfAtom(atoms[id]);
608}
609
610void World::unselectMolecule(const molecule *_mol){
611 OBSERVE;
612 NOTIFY(SelectionChanged);
613 ASSERT(_mol,"invalid pointer in unselection of molecule");
614 unselectMolecule(_mol->getId());
615}
616
617void World::unselectMolecule(const moleculeId_t id){
618 OBSERVE;
619 NOTIFY(SelectionChanged);
620 ASSERT(molecules.count(id),"No such molecule with ID in unselection");
621 selectedMolecules.erase(id);
622}
623
624void World::unselectAllMolecules(MoleculeDescriptor descr){
625 OBSERVE;
626 NOTIFY(SelectionChanged);
627 internal_MoleculeIterator begin = getMoleculeIter_internal(descr);
628 internal_MoleculeIterator end = moleculeEnd_internal();
629 void (World::*func)(const molecule*) = &World::unselectMolecule; // needed for type resolution of overloaded function
630 for_each(begin,end,bind1st(mem_fun(func),this)); // func is unselect... see above
631}
632
633void World::unselectMoleculeOfAtom(const atom *_atom){
634 OBSERVE;
635 NOTIFY(SelectionChanged);
636 ASSERT(_atom,"Invalid atom pointer in selection of MoleculeOfAtom");
637 molecule *mol=_atom->getMolecule();
638 // the atom might not be part of a molecule
639 if(mol){
640 unselectMolecule(mol);
641 }
642}
643
644void World::unselectMoleculeOfAtom(const atomId_t id){
645 OBSERVE;
646 NOTIFY(SelectionChanged);
647 ASSERT(atoms.count(id),"No such atom with given ID in selection of Molecules of Atom");\
648 unselectMoleculeOfAtom(atoms[id]);
649}
650
651size_t World::countSelectedMolecules() const {
652 size_t count = 0;
653 for (MoleculeSet::const_iterator iter = selectedMolecules.begin(); iter != selectedMolecules.end(); ++iter)
654 count++;
655 return count;
656}
657
658bool World::isSelected(const molecule *_mol) const {
659 return isMoleculeSelected(_mol->getId());
660}
661
662bool World::isMoleculeSelected(const moleculeId_t no) const {
663 return selectedMolecules.find(no) != selectedMolecules.end();
664}
665
666const std::vector<molecule *> World::getSelectedMolecules() const {
667 std::vector<molecule *> returnMolecules;
668 returnMolecules.resize(countSelectedMolecules());
669 int count = 0;
670 for (MoleculeSet::const_iterator iter = selectedMolecules.begin(); iter != selectedMolecules.end(); ++iter)
671 returnMolecules[count++] = iter->second;
672 return returnMolecules;
673}
674
675/******************* Iterators over Selection *****************************/
676World::AtomSelectionIterator World::beginAtomSelection(){
677 return selectedAtoms.begin();
678}
679
680World::AtomSelectionIterator World::endAtomSelection(){
681 return selectedAtoms.end();
682}
683
684World::AtomSelectionConstIterator World::beginAtomSelection() const{
685 return selectedAtoms.begin();
686}
687
688World::AtomSelectionConstIterator World::endAtomSelection() const{
689 return selectedAtoms.end();
690}
691
692
693World::MoleculeSelectionIterator World::beginMoleculeSelection(){
694 return selectedMolecules.begin();
695}
696
697World::MoleculeSelectionIterator World::endMoleculeSelection(){
698 return selectedMolecules.end();
699}
700
701World::MoleculeSelectionConstIterator World::beginMoleculeSelection() const{
702 return selectedMolecules.begin();
703}
704
705World::MoleculeSelectionConstIterator World::endMoleculeSelection() const{
706 return selectedMolecules.end();
707}
708
709/******************************* Singleton Stuff **************************/
710
711World::World() :
712 Observable("World"),
713 BG(new BondGraph(true)), // assume Angstroem for the moment
714 periode(new periodentafel(true)),
715 configuration(new config),
716 Thermostats(new ThermoStatContainer),
717 ExitFlag(0),
718 atoms(this),
719 selectedAtoms(this),
720 atomIdPool(0, 20, 100),
721 molecules(this),
722 selectedMolecules(this),
723 moleculeIdPool(0, 20,100),
724 molecules_deprecated(new MoleculeListClass(this))
725{
726 cell_size = new Box;
727 RealSpaceMatrix domain;
728 domain.at(0,0) = 20;
729 domain.at(1,1) = 20;
730 domain.at(2,2) = 20;
731 cell_size->setM(domain);
732 LCcontroller = new LinkedCell::LinkedCell_Controller(*cell_size);
733 defaultName = "none";
734 Channels *OurChannel = new Channels;
735 NotificationChannels.insert( std::make_pair( this, OurChannel) );
736 for (size_t type = 0; type < (size_t)NotificationType_MAX; ++type)
737 OurChannel->addChannel(type);
738 molecules_deprecated->signOn(this);
739}
740
741World::~World()
742{
743 molecules_deprecated->signOff(this);
744 delete LCcontroller;
745 delete cell_size;
746 delete molecules_deprecated;
747 MoleculeSet::iterator molIter;
748 for(molIter=molecules.begin();molIter!=molecules.end();++molIter){
749 DeleteMolecule((*molIter).second);
750 }
751 molecules.clear();
752 AtomSet::iterator atIter;
753 for(atIter=atoms.begin();atIter!=atoms.end();++atIter){
754 DeleteAtom((*atIter).second);
755 }
756 atoms.clear();
757
758 // empty notifications
759 std::map<Observable *, Channels*>::iterator iter = NotificationChannels.find(this);
760 ASSERT(iter != NotificationChannels.end(),
761 "World::~World() - cannot find our Channels in NotificationChannels.");
762 delete iter->second;
763 NotificationChannels.erase(iter);
764
765 delete BG;
766 delete periode;
767 delete configuration;
768 delete Thermostats;
769}
770
771// Explicit instantiation of the singleton mechanism at this point
772
773// moleculeId_t und atomId_t sind gleicher Basistyp, deswegen nur einen von beiden konstruieren
774CONSTRUCT_IDPOOL(atomId_t, uniqueId)
775CONSTRUCT_IDPOOL(moleculeId_t, continuousId)
776
777CONSTRUCT_SINGLETON(World)
778
779CONSTRUCT_OBSERVEDCONTAINER(World::AtomSTLSet)
780
781CONSTRUCT_OBSERVEDCONTAINER(World::MoleculeSTLSet)
782
783/******************************* deprecated Legacy Stuff ***********************/
784
785MoleculeListClass *&World::getMolecules() {
786 return molecules_deprecated;
787}
Note: See TracBrowser for help on using the repository browser.