source: src/World.cpp@ a7aebd

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

World removes empty molecules.

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