source: src/World.cpp@ d6b12c

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 d6b12c was 69643a, checked in by Frederik Heber <heber@…>, 13 years ago

World: made selection changes observable

  • 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 return atom->getId();
262}
263
264void World::destroyAtom(atom* atom){
265 int id = atom->getId();
266 destroyAtom(id);
267}
268
269void World::destroyAtom(atomId_t id) {
270 atom *atom = atoms[id];
271 ASSERT(atom,"Atom ID that was meant to be destroyed did not exist");
272 // give notice about immediate removal
273 {
274 OBSERVE;
275 _lastchangedatom = atom;
276 NOTIFY(AtomRemoved);
277 }
278 DeleteAtom(atom);
279 if (isAtomSelected(id))
280 selectedAtoms.erase(id);
281 atoms.erase(id);
282 atomIdPool.releaseId(id);
283}
284
285bool World::changeAtomId(atomId_t oldId, atomId_t newId, atom* target){
286 OBSERVE;
287 // in case this call did not originate from inside the atom, we redirect it,
288 // to also let it know that it has changed
289 if(!target){
290 target = atoms[oldId];
291 ASSERT(target,"Atom with that ID not found");
292 return target->changeId(newId);
293 }
294 else{
295 if(atomIdPool.reserveId(newId)){
296 atoms.erase(oldId);
297 atoms.insert(pair<atomId_t,atom*>(newId,target));
298 return true;
299 }
300 else{
301 return false;
302 }
303 }
304}
305
306bool World::changeMoleculeId(moleculeId_t oldId, moleculeId_t newId, molecule* target){
307 OBSERVE;
308 // in case this call did not originate from inside the atom, we redirect it,
309 // to also let it know that it has changed
310 if(!target){
311 target = molecules[oldId];
312 ASSERT(target,"Molecule with that ID not found");
313 return target->changeId(newId);
314 }
315 else{
316 if(moleculeIdPool.reserveId(newId)){
317 molecules.erase(oldId);
318 molecules.insert(pair<moleculeId_t,molecule*>(newId,target));
319 return true;
320 }
321 else{
322 return false;
323 }
324 }
325}
326
327ManipulateAtomsProcess* World::manipulateAtoms(boost::function<void(atom*)> op,std::string name,AtomDescriptor descr){
328 ActionTrait manipulateTrait(name);
329 return new ManipulateAtomsProcess(op, descr,manipulateTrait,false);
330}
331
332ManipulateAtomsProcess* World::manipulateAtoms(boost::function<void(atom*)> op,std::string name){
333 return manipulateAtoms(op,name,AllAtoms());
334}
335
336/********************* Internal Change methods for double Callback and Observer mechanism ********/
337
338void World::doManipulate(ManipulateAtomsProcess *proc){
339 proc->signOn(this);
340 {
341 OBSERVE;
342 proc->doManipulate(this);
343 }
344 proc->signOff(this);
345}
346/******************************* Iterators ********************************/
347
348// external parts with observers
349
350CONSTRUCT_SELECTIVE_ITERATOR(atom*,World::AtomSet,AtomDescriptor);
351
352World::AtomIterator
353World::getAtomIter(AtomDescriptor descr){
354 return AtomIterator(descr,atoms);
355}
356
357World::AtomIterator
358World::getAtomIter(){
359 return AtomIterator(AllAtoms(),atoms);
360}
361
362World::AtomIterator
363World::atomEnd(){
364 return AtomIterator(AllAtoms(),atoms,atoms.end());
365}
366
367CONSTRUCT_SELECTIVE_ITERATOR(molecule*,World::MoleculeSet,MoleculeDescriptor);
368
369World::MoleculeIterator
370World::getMoleculeIter(MoleculeDescriptor descr){
371 return MoleculeIterator(descr,molecules);
372}
373
374World::MoleculeIterator
375World::getMoleculeIter(){
376 return MoleculeIterator(AllMolecules(),molecules);
377}
378
379World::MoleculeIterator
380World::moleculeEnd(){
381 return MoleculeIterator(AllMolecules(),molecules,molecules.end());
382}
383
384// Internal parts, without observers
385
386// Build the AtomIterator from template
387CONSTRUCT_SELECTIVE_ITERATOR(atom*,World::AtomSet::set_t,AtomDescriptor);
388
389
390World::internal_AtomIterator
391World::getAtomIter_internal(AtomDescriptor descr){
392 return internal_AtomIterator(descr,atoms.getContent());
393}
394
395World::internal_AtomIterator
396World::atomEnd_internal(){
397 return internal_AtomIterator(AllAtoms(),atoms.getContent(),atoms.end_internal());
398}
399
400// build the MoleculeIterator from template
401CONSTRUCT_SELECTIVE_ITERATOR(molecule*,World::MoleculeSet::set_t,MoleculeDescriptor);
402
403World::internal_MoleculeIterator World::getMoleculeIter_internal(MoleculeDescriptor descr){
404 return internal_MoleculeIterator(descr,molecules.getContent());
405}
406
407World::internal_MoleculeIterator World::moleculeEnd_internal(){
408 return internal_MoleculeIterator(AllMolecules(),molecules.getContent(),molecules.end_internal());
409}
410
411/************************** Selection of Atoms and molecules ******************/
412
413// Atoms
414
415void World::clearAtomSelection(){
416 OBSERVE;
417 NOTIFY(SelectionChanged);
418 selectedAtoms.clear();
419}
420
421void World::invertAtomSelection(){
422 // get all atoms not selected
423 AtomComposite invertedSelection(getAllAtoms());
424 bool (World::*predicate)(const atom*) const = &World::isSelected; // needed for type resolution of overloaded function
425 AtomComposite::iterator iter =
426 std::remove_if(invertedSelection.begin(), invertedSelection.end(),
427 std::bind1st(std::mem_fun(predicate), this));
428 invertedSelection.erase(iter, invertedSelection.end());
429 // apply new selection
430 selectedAtoms.clear();
431 void (World::*selector)(const atom*) = &World::selectAtom; // needed for type resolution of overloaded function
432 std::for_each(invertedSelection.begin(),invertedSelection.end(),
433 std::bind1st(std::mem_fun(selector),this)); // func is select... see above
434}
435
436void World::selectAtom(const atom *_atom){
437 OBSERVE;
438 NOTIFY(SelectionChanged);
439 // atom * is unchanged in this function, but we do store entity as changeable
440 ASSERT(_atom,"Invalid pointer in selection of atom");
441 selectedAtoms[_atom->getId()]=const_cast<atom *>(_atom);
442}
443
444void World::selectAtom(const atomId_t id){
445 OBSERVE;
446 NOTIFY(SelectionChanged);
447 ASSERT(atoms.count(id),"Atom Id selected that was not in the world");
448 selectedAtoms[id]=atoms[id];
449}
450
451void World::selectAllAtoms(AtomDescriptor descr){
452 OBSERVE;
453 NOTIFY(SelectionChanged);
454 internal_AtomIterator begin = getAtomIter_internal(descr);
455 internal_AtomIterator end = atomEnd_internal();
456 void (World::*func)(const atom*) = &World::selectAtom; // needed for type resolution of overloaded function
457 for_each(begin,end,bind1st(mem_fun(func),this)); // func is select... see above
458}
459
460void World::selectAtomsOfMolecule(const molecule *_mol){
461 OBSERVE;
462 NOTIFY(SelectionChanged);
463 ASSERT(_mol,"Invalid pointer to molecule in selection of Atoms of Molecule");
464 // need to make it const to get the fast iterators
465 const molecule *mol = _mol;
466 void (World::*func)(const atom*) = &World::selectAtom; // needed for type resolution of overloaded function
467 for_each(mol->begin(),mol->end(),bind1st(mem_fun(func),this)); // func is select... see above
468}
469
470void World::selectAtomsOfMolecule(const moleculeId_t id){
471 OBSERVE;
472 NOTIFY(SelectionChanged);
473 ASSERT(molecules.count(id),"No molecule with the given id upon Selection of atoms from molecule");
474 selectAtomsOfMolecule(molecules[id]);
475}
476
477void World::unselectAtom(const atom *_atom){
478 OBSERVE;
479 NOTIFY(SelectionChanged);
480 ASSERT(_atom,"Invalid pointer in unselection of atom");
481 unselectAtom(_atom->getId());
482}
483
484void World::unselectAtom(const atomId_t id){
485 OBSERVE;
486 NOTIFY(SelectionChanged);
487 ASSERT(atoms.count(id),"Atom Id unselected that was not in the world");
488 selectedAtoms.erase(id);
489}
490
491void World::unselectAllAtoms(AtomDescriptor descr){
492 OBSERVE;
493 NOTIFY(SelectionChanged);
494 internal_AtomIterator begin = getAtomIter_internal(descr);
495 internal_AtomIterator end = atomEnd_internal();
496 void (World::*func)(const atom*) = &World::unselectAtom; // needed for type resolution of overloaded function
497 for_each(begin,end,bind1st(mem_fun(func),this)); // func is unselect... see above
498}
499
500void World::unselectAtomsOfMolecule(const molecule *_mol){
501 OBSERVE;
502 NOTIFY(SelectionChanged);
503 ASSERT(_mol,"Invalid pointer to molecule in selection of Atoms of Molecule");
504 // need to make it const to get the fast iterators
505 const molecule *mol = _mol;
506 void (World::*func)(const atom*) = &World::unselectAtom; // needed for type resolution of overloaded function
507 for_each(mol->begin(),mol->end(),bind1st(mem_fun(func),this)); // func is unsselect... see above
508}
509
510void World::unselectAtomsOfMolecule(const moleculeId_t id){
511 OBSERVE;
512 NOTIFY(SelectionChanged);
513 ASSERT(molecules.count(id),"No molecule with the given id upon Selection of atoms from molecule");
514 unselectAtomsOfMolecule(molecules[id]);
515}
516
517size_t World::countSelectedAtoms() const {
518 size_t count = 0;
519 for (AtomSet::const_iterator iter = selectedAtoms.begin(); iter != selectedAtoms.end(); ++iter)
520 count++;
521 return count;
522}
523
524bool World::isSelected(const atom *_atom) const {
525 return isAtomSelected(_atom->getId());
526}
527
528bool World::isAtomSelected(const atomId_t no) const {
529 return selectedAtoms.find(no) != selectedAtoms.end();
530}
531
532const std::vector<atom *> World::getSelectedAtoms() const {
533 std::vector<atom *> returnAtoms;
534 returnAtoms.resize(countSelectedAtoms());
535 int count = 0;
536 for (AtomSet::const_iterator iter = selectedAtoms.begin(); iter != selectedAtoms.end(); ++iter)
537 returnAtoms[count++] = iter->second;
538 return returnAtoms;
539}
540
541
542// Molecules
543
544void World::clearMoleculeSelection(){
545 OBSERVE;
546 NOTIFY(SelectionChanged);
547 selectedMolecules.clear();
548}
549
550void World::invertMoleculeSelection(){
551 // get all molecules not selected
552 typedef std::vector<molecule *> MoleculeVector_t;
553 MoleculeVector_t invertedSelection(getAllMolecules());
554 bool (World::*predicate)(const molecule*) const = &World::isSelected; // needed for type resolution of overloaded function
555 MoleculeVector_t::iterator iter =
556 std::remove_if(invertedSelection.begin(), invertedSelection.end(),
557 std::bind1st(std::mem_fun(predicate), this));
558 invertedSelection.erase(iter, invertedSelection.end());
559 // apply new selection
560 selectedMolecules.clear();
561 void (World::*selector)(const molecule*) = &World::selectMolecule; // needed for type resolution of overloaded function
562 std::for_each(invertedSelection.begin(),invertedSelection.end(),
563 std::bind1st(std::mem_fun(selector),this)); // func is select... see above
564}
565
566void World::selectMolecule(const molecule *_mol){
567 OBSERVE;
568 NOTIFY(SelectionChanged);
569 // molecule * is unchanged in this function, but we do store entity as changeable
570 ASSERT(_mol,"Invalid pointer to molecule in selection");
571 selectedMolecules[_mol->getId()]=const_cast<molecule *>(_mol);
572}
573
574void World::selectMolecule(const moleculeId_t id){
575 OBSERVE;
576 NOTIFY(SelectionChanged);
577 ASSERT(molecules.count(id),"Molecule Id selected that was not in the world");
578 selectedMolecules[id]=molecules[id];
579}
580
581void World::selectAllMolecules(MoleculeDescriptor descr){
582 OBSERVE;
583 NOTIFY(SelectionChanged);
584 internal_MoleculeIterator begin = getMoleculeIter_internal(descr);
585 internal_MoleculeIterator end = moleculeEnd_internal();
586 void (World::*func)(const molecule*) = &World::selectMolecule; // needed for type resolution of overloaded function
587 for_each(begin,end,bind1st(mem_fun(func),this)); // func is select... see above
588}
589
590void World::selectMoleculeOfAtom(const atom *_atom){
591 OBSERVE;
592 NOTIFY(SelectionChanged);
593 ASSERT(_atom,"Invalid atom pointer in selection of MoleculeOfAtom");
594 molecule *mol=_atom->getMolecule();
595 // the atom might not be part of a molecule
596 if(mol){
597 selectMolecule(mol);
598 }
599}
600
601void World::selectMoleculeOfAtom(const atomId_t id){
602 OBSERVE;
603 NOTIFY(SelectionChanged);
604 ASSERT(atoms.count(id),"No such atom with given ID in selection of Molecules of Atom");\
605 selectMoleculeOfAtom(atoms[id]);
606}
607
608void World::unselectMolecule(const molecule *_mol){
609 OBSERVE;
610 NOTIFY(SelectionChanged);
611 ASSERT(_mol,"invalid pointer in unselection of molecule");
612 unselectMolecule(_mol->getId());
613}
614
615void World::unselectMolecule(const moleculeId_t id){
616 OBSERVE;
617 NOTIFY(SelectionChanged);
618 ASSERT(molecules.count(id),"No such molecule with ID in unselection");
619 selectedMolecules.erase(id);
620}
621
622void World::unselectAllMolecules(MoleculeDescriptor descr){
623 OBSERVE;
624 NOTIFY(SelectionChanged);
625 internal_MoleculeIterator begin = getMoleculeIter_internal(descr);
626 internal_MoleculeIterator end = moleculeEnd_internal();
627 void (World::*func)(const molecule*) = &World::unselectMolecule; // needed for type resolution of overloaded function
628 for_each(begin,end,bind1st(mem_fun(func),this)); // func is unselect... see above
629}
630
631void World::unselectMoleculeOfAtom(const atom *_atom){
632 OBSERVE;
633 NOTIFY(SelectionChanged);
634 ASSERT(_atom,"Invalid atom pointer in selection of MoleculeOfAtom");
635 molecule *mol=_atom->getMolecule();
636 // the atom might not be part of a molecule
637 if(mol){
638 unselectMolecule(mol);
639 }
640}
641
642void World::unselectMoleculeOfAtom(const atomId_t id){
643 OBSERVE;
644 NOTIFY(SelectionChanged);
645 ASSERT(atoms.count(id),"No such atom with given ID in selection of Molecules of Atom");\
646 unselectMoleculeOfAtom(atoms[id]);
647}
648
649size_t World::countSelectedMolecules() const {
650 size_t count = 0;
651 for (MoleculeSet::const_iterator iter = selectedMolecules.begin(); iter != selectedMolecules.end(); ++iter)
652 count++;
653 return count;
654}
655
656bool World::isSelected(const molecule *_mol) const {
657 return isMoleculeSelected(_mol->getId());
658}
659
660bool World::isMoleculeSelected(const moleculeId_t no) const {
661 return selectedMolecules.find(no) != selectedMolecules.end();
662}
663
664const std::vector<molecule *> World::getSelectedMolecules() const {
665 std::vector<molecule *> returnMolecules;
666 returnMolecules.resize(countSelectedMolecules());
667 int count = 0;
668 for (MoleculeSet::const_iterator iter = selectedMolecules.begin(); iter != selectedMolecules.end(); ++iter)
669 returnMolecules[count++] = iter->second;
670 return returnMolecules;
671}
672
673/******************* Iterators over Selection *****************************/
674World::AtomSelectionIterator World::beginAtomSelection(){
675 return selectedAtoms.begin();
676}
677
678World::AtomSelectionIterator World::endAtomSelection(){
679 return selectedAtoms.end();
680}
681
682World::AtomSelectionConstIterator World::beginAtomSelection() const{
683 return selectedAtoms.begin();
684}
685
686World::AtomSelectionConstIterator World::endAtomSelection() const{
687 return selectedAtoms.end();
688}
689
690
691World::MoleculeSelectionIterator World::beginMoleculeSelection(){
692 return selectedMolecules.begin();
693}
694
695World::MoleculeSelectionIterator World::endMoleculeSelection(){
696 return selectedMolecules.end();
697}
698
699World::MoleculeSelectionConstIterator World::beginMoleculeSelection() const{
700 return selectedMolecules.begin();
701}
702
703World::MoleculeSelectionConstIterator World::endMoleculeSelection() const{
704 return selectedMolecules.end();
705}
706
707/******************************* Singleton Stuff **************************/
708
709World::World() :
710 Observable("World"),
711 BG(new BondGraph(true)), // assume Angstroem for the moment
712 periode(new periodentafel(true)),
713 configuration(new config),
714 Thermostats(new ThermoStatContainer),
715 ExitFlag(0),
716 atoms(this),
717 selectedAtoms(this),
718 atomIdPool(0, 20, 100),
719 molecules(this),
720 selectedMolecules(this),
721 moleculeIdPool(0, 20,100),
722 molecules_deprecated(new MoleculeListClass(this))
723{
724 cell_size = new Box;
725 RealSpaceMatrix domain;
726 domain.at(0,0) = 20;
727 domain.at(1,1) = 20;
728 domain.at(2,2) = 20;
729 cell_size->setM(domain);
730 LCcontroller = new LinkedCell::LinkedCell_Controller(*cell_size);
731 defaultName = "none";
732 Channels *OurChannel = new Channels;
733 NotificationChannels.insert( std::make_pair( this, OurChannel) );
734 for (size_t type = 0; type < (size_t)NotificationType_MAX; ++type)
735 OurChannel->addChannel(type);
736 molecules_deprecated->signOn(this);
737}
738
739World::~World()
740{
741 molecules_deprecated->signOff(this);
742 delete LCcontroller;
743 delete cell_size;
744 delete molecules_deprecated;
745 MoleculeSet::iterator molIter;
746 for(molIter=molecules.begin();molIter!=molecules.end();++molIter){
747 DeleteMolecule((*molIter).second);
748 }
749 molecules.clear();
750 AtomSet::iterator atIter;
751 for(atIter=atoms.begin();atIter!=atoms.end();++atIter){
752 DeleteAtom((*atIter).second);
753 }
754 atoms.clear();
755
756 // empty notifications
757 std::map<Observable *, Channels*>::iterator iter = NotificationChannels.find(this);
758 ASSERT(iter != NotificationChannels.end(),
759 "World::~World() - cannot find our Channels in NotificationChannels.");
760 delete iter->second;
761 NotificationChannels.erase(iter);
762
763 delete BG;
764 delete periode;
765 delete configuration;
766 delete Thermostats;
767}
768
769// Explicit instantiation of the singleton mechanism at this point
770
771// moleculeId_t und atomId_t sind gleicher Basistyp, deswegen nur einen von beiden konstruieren
772CONSTRUCT_IDPOOL(atomId_t, uniqueId)
773CONSTRUCT_IDPOOL(moleculeId_t, continuousId)
774
775CONSTRUCT_SINGLETON(World)
776
777CONSTRUCT_OBSERVEDCONTAINER(World::AtomSTLSet)
778
779CONSTRUCT_OBSERVEDCONTAINER(World::MoleculeSTLSet)
780
781/******************************* deprecated Legacy Stuff ***********************/
782
783MoleculeListClass *&World::getMolecules() {
784 return molecules_deprecated;
785}
Note: See TracBrowser for help on using the repository browser.