source: src/World.cpp@ 9ec4b8

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 9ec4b8 was 99db9b, checked in by Frederik Heber <heber@…>, 9 years ago

Replaced all World::getSelected...() to const version where possible.

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