source: src/World.cpp@ e65de8

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 e65de8 was e472eab, checked in by Frederik Heber <heber@…>, 15 years ago

Added new all/none selection actions for atoms and molecules.

  • Property mode set to 100644
File size: 20.8 KB
Line 
1/*
2 * World.cpp
3 *
4 * Created on: Feb 3, 2010
5 * Author: crueger
6 */
7
8#include "Helpers/MemDebug.hpp"
9
10#include "World.hpp"
11
12#include <functional>
13
14#include "atom.hpp"
15#include "config.hpp"
16#include "molecule.hpp"
17#include "periodentafel.hpp"
18#include "ThermoStatContainer.hpp"
19#include "Descriptors/AtomDescriptor.hpp"
20#include "Descriptors/AtomDescriptor_impl.hpp"
21#include "Descriptors/MoleculeDescriptor.hpp"
22#include "Descriptors/MoleculeDescriptor_impl.hpp"
23#include "Descriptors/SelectiveIterator_impl.hpp"
24#include "Actions/ManipulateAtomsProcess.hpp"
25#include "Helpers/Assert.hpp"
26#include "Box.hpp"
27#include "Matrix.hpp"
28#include "defs.hpp"
29
30#include "Patterns/Singleton_impl.hpp"
31#include "Patterns/ObservedContainer_impl.hpp"
32
33using namespace std;
34
35/******************************* getter and setter ************************/
36periodentafel *&World::getPeriode(){
37 return periode;
38}
39
40config *&World::getConfig(){
41 return configuration;
42}
43
44// Atoms
45
46atom* World::getAtom(AtomDescriptor descriptor){
47 return descriptor.find();
48}
49
50vector<atom*> World::getAllAtoms(AtomDescriptor descriptor){
51 return descriptor.findAll();
52}
53
54vector<atom*> World::getAllAtoms(){
55 return getAllAtoms(AllAtoms());
56}
57
58int World::numAtoms(){
59 return atoms.size();
60}
61
62// Molecules
63
64molecule *World::getMolecule(MoleculeDescriptor descriptor){
65 return descriptor.find();
66}
67
68std::vector<molecule*> World::getAllMolecules(MoleculeDescriptor descriptor){
69 return descriptor.findAll();
70}
71
72std::vector<molecule*> World::getAllMolecules(){
73 return getAllMolecules(AllMolecules());
74}
75
76int World::numMolecules(){
77 return molecules_deprecated->ListOfMolecules.size();
78}
79
80// system
81
82Box& World::getDomain() {
83 return *cell_size;
84}
85
86void World::setDomain(const Matrix &mat){
87 OBSERVE;
88 *cell_size = mat;
89}
90
91void World::setDomain(double * matrix)
92{
93 OBSERVE;
94 Matrix M = ReturnFullMatrixforSymmetric(matrix);
95 cell_size->setM(M);
96}
97
98std::string World::getDefaultName() {
99 return defaultName;
100}
101
102void World::setDefaultName(std::string name)
103{
104 OBSERVE;
105 defaultName = name;
106};
107
108class ThermoStatContainer * World::getThermostats()
109{
110 return Thermostats;
111}
112
113
114int World::getExitFlag() {
115 return ExitFlag;
116}
117
118void World::setExitFlag(int flag) {
119 if (ExitFlag < flag)
120 ExitFlag = flag;
121}
122
123/******************** Methods to change World state *********************/
124
125molecule* World::createMolecule(){
126 OBSERVE;
127 molecule *mol = NULL;
128 mol = NewMolecule();
129 moleculeId_t id = getNextMoleculeId();
130 ASSERT(!molecules.count(id),"proposed id did not specify an unused ID");
131 mol->setId(id);
132 // store the molecule by ID
133 molecules[mol->getId()] = mol;
134 mol->signOn(this);
135 return mol;
136}
137
138void World::destroyMolecule(molecule* mol){
139 OBSERVE;
140 destroyMolecule(mol->getId());
141}
142
143void World::destroyMolecule(moleculeId_t id){
144 OBSERVE;
145 molecule *mol = molecules[id];
146 ASSERT(mol,"Molecule id that was meant to be destroyed did not exist");
147 DeleteMolecule(mol);
148 molecules.erase(id);
149 releaseMoleculeId(id);
150}
151
152atom *World::createAtom(){
153 OBSERVE;
154 atomId_t id = getNextAtomId();
155 ASSERT(!atoms.count(id),"proposed id did not specify an unused ID");
156 atom *res = NewAtom(id);
157 res->setWorld(this);
158 // store the atom by ID
159 atoms[res->getId()] = res;
160 return res;
161}
162
163
164int World::registerAtom(atom *atom){
165 OBSERVE;
166 atomId_t id = getNextAtomId();
167 atom->setId(id);
168 atom->setWorld(this);
169 atoms[atom->getId()] = atom;
170 return atom->getId();
171}
172
173void World::destroyAtom(atom* atom){
174 OBSERVE;
175 int id = atom->getId();
176 destroyAtom(id);
177}
178
179void World::destroyAtom(atomId_t id) {
180 OBSERVE;
181 atom *atom = atoms[id];
182 ASSERT(atom,"Atom ID that was meant to be destroyed did not exist");
183 DeleteAtom(atom);
184 atoms.erase(id);
185 releaseAtomId(id);
186}
187
188bool World::changeAtomId(atomId_t oldId, atomId_t newId, atom* target){
189 OBSERVE;
190 // in case this call did not originate from inside the atom, we redirect it,
191 // to also let it know that it has changed
192 if(!target){
193 target = atoms[oldId];
194 ASSERT(target,"Atom with that ID not found");
195 return target->changeId(newId);
196 }
197 else{
198 if(reserveAtomId(newId)){
199 atoms.erase(oldId);
200 atoms.insert(pair<atomId_t,atom*>(newId,target));
201 return true;
202 }
203 else{
204 return false;
205 }
206 }
207}
208
209ManipulateAtomsProcess* World::manipulateAtoms(boost::function<void(atom*)> op,std::string name,AtomDescriptor descr){
210 return new ManipulateAtomsProcess(op, descr,name,true);
211}
212
213ManipulateAtomsProcess* World::manipulateAtoms(boost::function<void(atom*)> op,std::string name){
214 return manipulateAtoms(op,name,AllAtoms());
215}
216
217/********************* Internal Change methods for double Callback and Observer mechanism ********/
218
219void World::doManipulate(ManipulateAtomsProcess *proc){
220 proc->signOn(this);
221 {
222 OBSERVE;
223 proc->doManipulate(this);
224 }
225 proc->signOff(this);
226}
227/******************************* IDManagement *****************************/
228
229// Atoms
230
231atomId_t World::getNextAtomId(){
232 // try to find an Id in the pool;
233 if(!atomIdPool.empty()){
234 atomIdPool_t::iterator iter=atomIdPool.begin();
235 atomId_t id = iter->first;
236 pair<atomId_t,atomId_t> newRange = make_pair(id+1,iter->second);
237 // we wont use this iterator anymore, so we don't care about invalidating
238 atomIdPool.erase(iter);
239 if(newRange.first<newRange.second){
240 atomIdPool.insert(newRange);
241 }
242 return id;
243 }
244 // Nothing in the pool... we are out of luck
245 return currAtomId++;
246}
247
248void World::releaseAtomId(atomId_t id){
249 atomIdPool.insert(make_pair(id,id+1));
250 defragAtomIdPool();
251}
252
253bool World::reserveAtomId(atomId_t id){
254 if(id>=currAtomId ){
255 pair<atomId_t,atomId_t> newRange = make_pair(currAtomId,id);
256 if(newRange.first<newRange.second){
257 atomIdPool.insert(newRange);
258 }
259 currAtomId=id+1;
260 defragAtomIdPool();
261 return true;
262 }
263 // look for a range that matches the request
264 for(atomIdPool_t::iterator iter=atomIdPool.begin();iter!=atomIdPool.end();++iter){
265 if(iter->first>id){
266 // we have coverd all available ranges... nothing to be found here
267 break;
268 }
269 // no need to check first, since it has to be <=id, since otherwise we would have broken out
270 if(iter->second > id){
271 // we found a matching range... get the id from this range
272
273 // split up this range at the point of id
274 pair<atomId_t,atomId_t> bottomRange = make_pair(iter->first,id);
275 pair<atomId_t,atomId_t> topRange = make_pair(id+1,iter->second);
276 // remove this range
277 atomIdPool.erase(iter);
278 if(bottomRange.first<bottomRange.second){
279 atomIdPool.insert(bottomRange);
280 }
281 if(topRange.first<topRange.second){
282 atomIdPool.insert(topRange);
283 }
284 defragAtomIdPool();
285 return true;
286 }
287 }
288 // this ID could not be reserved
289 return false;
290}
291
292void World::defragAtomIdPool(){
293 // check if the situation is bad enough to make defragging neccessary
294 if((numAtomDefragSkips<MAX_FRAGMENTATION_SKIPS) &&
295 (atomIdPool.size()<lastAtomPoolSize+MAX_POOL_FRAGMENTATION)){
296 ++numAtomDefragSkips;
297 return;
298 }
299 for(atomIdPool_t::iterator iter = atomIdPool.begin();iter!=atomIdPool.end();){
300 // see if this range is adjacent to the next one
301 atomIdPool_t::iterator next = iter;
302 next++;
303 if(next!=atomIdPool.end() && (next->first==iter->second)){
304 // merge the two ranges
305 pair<atomId_t,atomId_t> newRange = make_pair(iter->first,next->second);
306 atomIdPool.erase(iter);
307 atomIdPool.erase(next);
308 pair<atomIdPool_t::iterator,bool> res = atomIdPool.insert(newRange);
309 ASSERT(res.second,"Id-Pool was confused");
310 iter=res.first;
311 continue;
312 }
313 ++iter;
314 }
315 if(!atomIdPool.empty()){
316 // check if the last range is at the border
317 atomIdPool_t::iterator iter = atomIdPool.end();
318 iter--;
319 if(iter->second==currAtomId){
320 currAtomId=iter->first;
321 atomIdPool.erase(iter);
322 }
323 }
324 lastAtomPoolSize=atomIdPool.size();
325 numAtomDefragSkips=0;
326}
327
328// Molecules
329
330moleculeId_t World::getNextMoleculeId(){
331 // try to find an Id in the pool;
332 if(!moleculeIdPool.empty()){
333 moleculeIdPool_t::iterator iter=moleculeIdPool.begin();
334 moleculeId_t id = iter->first;
335 pair<moleculeId_t,moleculeId_t> newRange = make_pair(id+1,iter->second);
336 // we wont use this iterator anymore, so we don't care about invalidating
337 moleculeIdPool.erase(iter);
338 if(newRange.first<newRange.second){
339 moleculeIdPool.insert(newRange);
340 }
341 return id;
342 }
343 // Nothing in the pool... we are out of luck
344 return currMoleculeId++;
345}
346
347void World::releaseMoleculeId(moleculeId_t id){
348 moleculeIdPool.insert(make_pair(id,id+1));
349 defragMoleculeIdPool();
350}
351
352bool World::reserveMoleculeId(moleculeId_t id){
353 if(id>=currMoleculeId ){
354 pair<moleculeId_t,moleculeId_t> newRange = make_pair(currMoleculeId,id);
355 if(newRange.first<newRange.second){
356 moleculeIdPool.insert(newRange);
357 }
358 currMoleculeId=id+1;
359 defragMoleculeIdPool();
360 return true;
361 }
362 // look for a range that matches the request
363 for(moleculeIdPool_t::iterator iter=moleculeIdPool.begin();iter!=moleculeIdPool.end();++iter){
364 if(iter->first>id){
365 // we have coverd all available ranges... nothing to be found here
366 break;
367 }
368 // no need to check first, since it has to be <=id, since otherwise we would have broken out
369 if(iter->second > id){
370 // we found a matching range... get the id from this range
371
372 // split up this range at the point of id
373 pair<moleculeId_t,moleculeId_t> bottomRange = make_pair(iter->first,id);
374 pair<moleculeId_t,moleculeId_t> topRange = make_pair(id+1,iter->second);
375 // remove this range
376 moleculeIdPool.erase(iter);
377 if(bottomRange.first<bottomRange.second){
378 moleculeIdPool.insert(bottomRange);
379 }
380 if(topRange.first<topRange.second){
381 moleculeIdPool.insert(topRange);
382 }
383 defragMoleculeIdPool();
384 return true;
385 }
386 }
387 // this ID could not be reserved
388 return false;
389}
390
391void World::defragMoleculeIdPool(){
392 // check if the situation is bad enough to make defragging neccessary
393 if((numMoleculeDefragSkips<MAX_FRAGMENTATION_SKIPS) &&
394 (moleculeIdPool.size()<lastMoleculePoolSize+MAX_POOL_FRAGMENTATION)){
395 ++numMoleculeDefragSkips;
396 return;
397 }
398 for(moleculeIdPool_t::iterator iter = moleculeIdPool.begin();iter!=moleculeIdPool.end();){
399 // see if this range is adjacent to the next one
400 moleculeIdPool_t::iterator next = iter;
401 next++;
402 if(next!=moleculeIdPool.end() && (next->first==iter->second)){
403 // merge the two ranges
404 pair<moleculeId_t,moleculeId_t> newRange = make_pair(iter->first,next->second);
405 moleculeIdPool.erase(iter);
406 moleculeIdPool.erase(next);
407 pair<moleculeIdPool_t::iterator,bool> res = moleculeIdPool.insert(newRange);
408 ASSERT(res.second,"Id-Pool was confused");
409 iter=res.first;
410 continue;
411 }
412 ++iter;
413 }
414 if(!moleculeIdPool.empty()){
415 // check if the last range is at the border
416 moleculeIdPool_t::iterator iter = moleculeIdPool.end();
417 iter--;
418 if(iter->second==currMoleculeId){
419 currMoleculeId=iter->first;
420 moleculeIdPool.erase(iter);
421 }
422 }
423 lastMoleculePoolSize=moleculeIdPool.size();
424 numMoleculeDefragSkips=0;
425}
426
427/******************************* Iterators ********************************/
428
429// external parts with observers
430
431CONSTRUCT_SELECTIVE_ITERATOR(atom*,World::AtomSet,AtomDescriptor);
432
433World::AtomIterator
434World::getAtomIter(AtomDescriptor descr){
435 return AtomIterator(descr,atoms);
436}
437
438World::AtomIterator
439World::getAtomIter(){
440 return AtomIterator(AllAtoms(),atoms);
441}
442
443World::AtomIterator
444World::atomEnd(){
445 return AtomIterator(AllAtoms(),atoms,atoms.end());
446}
447
448CONSTRUCT_SELECTIVE_ITERATOR(molecule*,World::MoleculeSet,MoleculeDescriptor);
449
450World::MoleculeIterator
451World::getMoleculeIter(MoleculeDescriptor descr){
452 return MoleculeIterator(descr,molecules);
453}
454
455World::MoleculeIterator
456World::getMoleculeIter(){
457 return MoleculeIterator(AllMolecules(),molecules);
458}
459
460World::MoleculeIterator
461World::moleculeEnd(){
462 return MoleculeIterator(AllMolecules(),molecules,molecules.end());
463}
464
465// Internal parts, without observers
466
467// Build the AtomIterator from template
468CONSTRUCT_SELECTIVE_ITERATOR(atom*,World::AtomSet::set_t,AtomDescriptor);
469
470
471World::internal_AtomIterator
472World::getAtomIter_internal(AtomDescriptor descr){
473 return internal_AtomIterator(descr,atoms.getContent());
474}
475
476World::internal_AtomIterator
477World::atomEnd_internal(){
478 return internal_AtomIterator(AllAtoms(),atoms.getContent(),atoms.end_internal());
479}
480
481// build the MoleculeIterator from template
482CONSTRUCT_SELECTIVE_ITERATOR(molecule*,World::MoleculeSet::set_t,MoleculeDescriptor);
483
484World::internal_MoleculeIterator World::getMoleculeIter_internal(MoleculeDescriptor descr){
485 return internal_MoleculeIterator(descr,molecules.getContent());
486}
487
488World::internal_MoleculeIterator World::moleculeEnd_internal(){
489 return internal_MoleculeIterator(AllMolecules(),molecules.getContent(),molecules.end_internal());
490}
491
492/************************** Selection of Atoms and molecules ******************/
493
494// Atoms
495
496void World::clearAtomSelection(){
497 selectedAtoms.clear();
498}
499
500void World::selectAtom(atom *atom){
501 ASSERT(atom,"Invalid pointer in selection of atom");
502 selectedAtoms[atom->getId()]=atom;
503}
504
505void World::selectAtom(atomId_t id){
506 ASSERT(atoms.count(id),"Atom Id selected that was not in the world");
507 selectedAtoms[id]=atoms[id];
508}
509
510void World::selectAllAtoms(AtomDescriptor descr){
511 internal_AtomIterator begin = getAtomIter_internal(descr);
512 internal_AtomIterator end = atomEnd_internal();
513 void (World::*func)(atom*) = &World::selectAtom; // needed for type resolution of overloaded function
514 for_each(begin,end,bind1st(mem_fun(func),this)); // func is select... see above
515}
516
517void World::selectAtomsOfMolecule(molecule *_mol){
518 ASSERT(_mol,"Invalid pointer to molecule in selection of Atoms of Molecule");
519 // need to make it const to get the fast iterators
520 const molecule *mol = _mol;
521 void (World::*func)(atom*) = &World::selectAtom; // needed for type resolution of overloaded function
522 for_each(mol->begin(),mol->end(),bind1st(mem_fun(func),this)); // func is select... see above
523}
524
525void World::selectAtomsOfMolecule(moleculeId_t id){
526 ASSERT(molecules.count(id),"No molecule with the given id upon Selection of atoms from molecule");
527 selectAtomsOfMolecule(molecules[id]);
528}
529
530void World::unselectAtom(atom *atom){
531 ASSERT(atom,"Invalid pointer in unselection of atom");
532 unselectAtom(atom->getId());
533}
534
535void World::unselectAtom(atomId_t id){
536 ASSERT(atoms.count(id),"Atom Id unselected that was not in the world");
537 selectedAtoms.erase(id);
538}
539
540void World::unselectAllAtoms(AtomDescriptor descr){
541 internal_AtomIterator begin = getAtomIter_internal(descr);
542 internal_AtomIterator end = atomEnd_internal();
543 void (World::*func)(atom*) = &World::unselectAtom; // needed for type resolution of overloaded function
544 for_each(begin,end,bind1st(mem_fun(func),this)); // func is unselect... see above
545}
546
547void World::unselectAtomsOfMolecule(molecule *_mol){
548 ASSERT(_mol,"Invalid pointer to molecule in selection of Atoms of Molecule");
549 // need to make it const to get the fast iterators
550 const molecule *mol = _mol;
551 void (World::*func)(atom*) = &World::unselectAtom; // needed for type resolution of overloaded function
552 for_each(mol->begin(),mol->end(),bind1st(mem_fun(func),this)); // func is unsselect... see above
553}
554
555void World::unselectAtomsOfMolecule(moleculeId_t id){
556 ASSERT(molecules.count(id),"No molecule with the given id upon Selection of atoms from molecule");
557 unselectAtomsOfMolecule(molecules[id]);
558}
559
560size_t World::countSelectedAtoms() const {
561 size_t count = 0;
562 for (AtomSet::const_iterator iter = selectedAtoms.begin(); iter != selectedAtoms.end(); ++iter)
563 count++;
564 return count;
565}
566
567bool World::isSelected(atom *atom) const {
568 return selectedAtoms.find(atom->getId()) != selectedAtoms.end();
569}
570
571const std::vector<atom *> World::getSelectedAtoms() const {
572 std::vector<atom *> returnAtoms;
573 returnAtoms.resize(countSelectedAtoms());
574 int count = 0;
575 for (AtomSet::const_iterator iter = selectedAtoms.begin(); iter != selectedAtoms.end(); ++iter)
576 returnAtoms[count++] = iter->second;
577 return returnAtoms;
578}
579
580
581// Molecules
582
583void World::clearMoleculeSelection(){
584 selectedMolecules.clear();
585}
586
587void World::selectMolecule(molecule *mol){
588 ASSERT(mol,"Invalid pointer to molecule in selection");
589 selectedMolecules[mol->getId()]=mol;
590}
591
592void World::selectMolecule(moleculeId_t id){
593 ASSERT(molecules.count(id),"Molecule Id selected that was not in the world");
594 selectedMolecules[id]=molecules[id];
595}
596
597void World::selectAllMolecules(MoleculeDescriptor descr){
598 internal_MoleculeIterator begin = getMoleculeIter_internal(descr);
599 internal_MoleculeIterator end = moleculeEnd_internal();
600 void (World::*func)(molecule*) = &World::selectMolecule; // needed for type resolution of overloaded function
601 for_each(begin,end,bind1st(mem_fun(func),this)); // func is select... see above
602}
603
604void World::selectMoleculeOfAtom(atom *atom){
605 ASSERT(atom,"Invalid atom pointer in selection of MoleculeOfAtom");
606 molecule *mol=atom->getMolecule();
607 // the atom might not be part of a molecule
608 if(mol){
609 selectMolecule(mol);
610 }
611}
612
613void World::selectMoleculeOfAtom(atomId_t id){
614 ASSERT(atoms.count(id),"No such atom with given ID in selection of Molecules of Atom");\
615 selectMoleculeOfAtom(atoms[id]);
616}
617
618void World::unselectMolecule(molecule *mol){
619 ASSERT(mol,"invalid pointer in unselection of molecule");
620 unselectMolecule(mol->getId());
621}
622
623void World::unselectMolecule(moleculeId_t id){
624 ASSERT(molecules.count(id),"No such molecule with ID in unselection");
625 selectedMolecules.erase(id);
626}
627
628void World::unselectAllMolecules(MoleculeDescriptor descr){
629 internal_MoleculeIterator begin = getMoleculeIter_internal(descr);
630 internal_MoleculeIterator end = moleculeEnd_internal();
631 void (World::*func)(molecule*) = &World::unselectMolecule; // needed for type resolution of overloaded function
632 for_each(begin,end,bind1st(mem_fun(func),this)); // func is unselect... see above
633}
634
635void World::unselectMoleculeOfAtom(atom *atom){
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(atomId_t id){
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(molecule *mol) const {
657 return selectedMolecules.find(mol->getId()) != selectedMolecules.end();
658}
659
660const std::vector<molecule *> World::getSelectedMolecules() const {
661 std::vector<molecule *> returnMolecules;
662 returnMolecules.resize(countSelectedMolecules());
663 int count = 0;
664 for (MoleculeSet::const_iterator iter = selectedMolecules.begin(); iter != selectedMolecules.end(); ++iter)
665 returnMolecules[count++] = iter->second;
666 return returnMolecules;
667}
668
669/******************* Iterators over Selection *****************************/
670World::AtomSelectionIterator World::beginAtomSelection(){
671 return selectedAtoms.begin();
672}
673
674World::AtomSelectionIterator World::endAtomSelection(){
675 return selectedAtoms.end();
676}
677
678
679World::MoleculeSelectionIterator World::beginMoleculeSelection(){
680 return selectedMolecules.begin();
681}
682
683World::MoleculeSelectionIterator World::endMoleculeSelection(){
684 return selectedMolecules.end();
685}
686
687/******************************* Singleton Stuff **************************/
688
689World::World() :
690 Observable("World"),
691 periode(new periodentafel),
692 configuration(new config),
693 Thermostats(new ThermoStatContainer),
694 ExitFlag(0),
695 atoms(this),
696 selectedAtoms(this),
697 currAtomId(0),
698 lastAtomPoolSize(0),
699 numAtomDefragSkips(0),
700 molecules(this),
701 selectedMolecules(this),
702 currMoleculeId(0),
703 molecules_deprecated(new MoleculeListClass(this))
704{
705 cell_size = new Box;
706 Matrix domain;
707 domain.at(0,0) = 20;
708 domain.at(1,1) = 20;
709 domain.at(2,2) = 20;
710 cell_size->setM(domain);
711 defaultName = "none";
712 molecules_deprecated->signOn(this);
713}
714
715World::~World()
716{
717 molecules_deprecated->signOff(this);
718 delete cell_size;
719 delete molecules_deprecated;
720 delete periode;
721 delete configuration;
722 delete Thermostats;
723 MoleculeSet::iterator molIter;
724 for(molIter=molecules.begin();molIter!=molecules.end();++molIter){
725 DeleteMolecule((*molIter).second);
726 }
727 molecules.clear();
728 AtomSet::iterator atIter;
729 for(atIter=atoms.begin();atIter!=atoms.end();++atIter){
730 DeleteAtom((*atIter).second);
731 }
732 atoms.clear();
733}
734
735// Explicit instantiation of the singleton mechanism at this point
736
737CONSTRUCT_SINGLETON(World)
738
739/******************************* deprecated Legacy Stuff ***********************/
740
741MoleculeListClass *&World::getMolecules() {
742 return molecules_deprecated;
743}
Note: See TracBrowser for help on using the repository browser.