source: src/World.cpp@ cad383

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

Added push/pop[Atoms|Molecules]Selection to World.

  • this is mostly convenience for MakroActions to use selections and still keep the selection from the user.
  • Property mode set to 100644
File size: 26.8 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() > 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::popAtomSelection(){
568 OBSERVE;
569 NOTIFY(SelectionChanged);
570 selectedAtoms = selectedAtoms_Stack.top();
571 selectedAtoms_Stack.pop();
572}
573
574void World::pushAtomSelection(){
575 OBSERVE;
576 NOTIFY(SelectionChanged);
577 selectedAtoms_Stack.push( selectedAtoms );
578 selectedAtoms.clear();
579}
580
581void World::selectAtom(const atom *_atom){
582 OBSERVE;
583 NOTIFY(SelectionChanged);
584 // atom * is unchanged in this function, but we do store entity as changeable
585 ASSERT(_atom,"Invalid pointer in selection of atom");
586 selectedAtoms[_atom->getId()]=const_cast<atom *>(_atom);
587}
588
589void World::selectAtom(const atomId_t id){
590 OBSERVE;
591 NOTIFY(SelectionChanged);
592 ASSERT(atoms.count(id),"Atom Id selected that was not in the world");
593 selectedAtoms[id]=atoms[id];
594}
595
596void World::selectAllAtoms(AtomDescriptor descr){
597 OBSERVE;
598 NOTIFY(SelectionChanged);
599 internal_AtomIterator begin = getAtomIter_internal(descr);
600 internal_AtomIterator end = atomEnd_internal();
601 void (World::*func)(const atom*) = &World::selectAtom; // needed for type resolution of overloaded function
602 for_each(begin,end,bind1st(mem_fun(func),this)); // func is select... see above
603}
604
605void World::selectAtomsOfMolecule(const molecule *_mol){
606 OBSERVE;
607 NOTIFY(SelectionChanged);
608 ASSERT(_mol,"Invalid pointer to molecule in selection of Atoms of Molecule");
609 // need to make it const to get the fast iterators
610 const molecule *mol = _mol;
611 void (World::*func)(const atom*) = &World::selectAtom; // needed for type resolution of overloaded function
612 for_each(mol->begin(),mol->end(),bind1st(mem_fun(func),this)); // func is select... see above
613}
614
615void World::selectAtomsOfMolecule(const moleculeId_t id){
616 OBSERVE;
617 NOTIFY(SelectionChanged);
618 ASSERT(molecules.count(id),"No molecule with the given id upon Selection of atoms from molecule");
619 selectAtomsOfMolecule(molecules[id]);
620}
621
622void World::unselectAtom(const atom *_atom){
623 OBSERVE;
624 NOTIFY(SelectionChanged);
625 ASSERT(_atom,"Invalid pointer in unselection of atom");
626 unselectAtom(_atom->getId());
627}
628
629void World::unselectAtom(const atomId_t id){
630 OBSERVE;
631 NOTIFY(SelectionChanged);
632 ASSERT(atoms.count(id),"Atom Id unselected that was not in the world");
633 selectedAtoms.erase(id);
634}
635
636void World::unselectAllAtoms(AtomDescriptor descr){
637 OBSERVE;
638 NOTIFY(SelectionChanged);
639 internal_AtomIterator begin = getAtomIter_internal(descr);
640 internal_AtomIterator end = atomEnd_internal();
641 void (World::*func)(const atom*) = &World::unselectAtom; // needed for type resolution of overloaded function
642 for_each(begin,end,bind1st(mem_fun(func),this)); // func is unselect... see above
643}
644
645void World::unselectAtomsOfMolecule(const molecule *_mol){
646 OBSERVE;
647 NOTIFY(SelectionChanged);
648 ASSERT(_mol,"Invalid pointer to molecule in selection of Atoms of Molecule");
649 // need to make it const to get the fast iterators
650 const molecule *mol = _mol;
651 void (World::*func)(const atom*) = &World::unselectAtom; // needed for type resolution of overloaded function
652 for_each(mol->begin(),mol->end(),bind1st(mem_fun(func),this)); // func is unselect... see above
653}
654
655void World::unselectAtomsOfMolecule(const moleculeId_t id){
656 OBSERVE;
657 NOTIFY(SelectionChanged);
658 ASSERT(molecules.count(id),"No molecule with the given id upon Selection of atoms from molecule");
659 unselectAtomsOfMolecule(molecules[id]);
660}
661
662size_t World::countSelectedAtoms() const {
663 size_t count = 0;
664 for (AtomSet::const_iterator iter = selectedAtoms.begin(); iter != selectedAtoms.end(); ++iter)
665 count++;
666 return count;
667}
668
669bool World::isSelected(const atom *_atom) const {
670 return isAtomSelected(_atom->getId());
671}
672
673bool World::isAtomSelected(const atomId_t no) const {
674 return selectedAtoms.find(no) != selectedAtoms.end();
675}
676
677const std::vector<atom *> World::getSelectedAtoms() const {
678 std::vector<atom *> returnAtoms;
679 returnAtoms.resize(countSelectedAtoms());
680 int count = 0;
681 for (AtomSet::const_iterator iter = selectedAtoms.begin(); iter != selectedAtoms.end(); ++iter)
682 returnAtoms[count++] = iter->second;
683 return returnAtoms;
684}
685
686
687// Molecules
688
689void World::clearMoleculeSelection(){
690 OBSERVE;
691 NOTIFY(SelectionChanged);
692 selectedMolecules.clear();
693}
694
695void World::invertMoleculeSelection(){
696 // get all molecules not selected
697 typedef std::vector<molecule *> MoleculeVector_t;
698 MoleculeVector_t invertedSelection(getAllMolecules());
699 bool (World::*predicate)(const molecule*) const = &World::isSelected; // needed for type resolution of overloaded function
700 MoleculeVector_t::iterator iter =
701 std::remove_if(invertedSelection.begin(), invertedSelection.end(),
702 std::bind1st(std::mem_fun(predicate), this));
703 invertedSelection.erase(iter, invertedSelection.end());
704 // apply new selection
705 selectedMolecules.clear();
706 void (World::*selector)(const molecule*) = &World::selectMolecule; // needed for type resolution of overloaded function
707 std::for_each(invertedSelection.begin(),invertedSelection.end(),
708 std::bind1st(std::mem_fun(selector),this)); // func is select... see above
709}
710
711void World::popMoleculeSelection(){
712 OBSERVE;
713 NOTIFY(SelectionChanged);
714 selectedMolecules = selectedMolecules_Stack.top();
715 selectedMolecules_Stack.pop();
716}
717
718void World::pushMoleculeSelection(){
719 OBSERVE;
720 NOTIFY(SelectionChanged);
721 selectedMolecules_Stack.push( selectedMolecules );
722 selectedMolecules.clear();
723}
724
725void World::selectMolecule(const molecule *_mol){
726 OBSERVE;
727 NOTIFY(SelectionChanged);
728 // molecule * is unchanged in this function, but we do store entity as changeable
729 ASSERT(_mol,"Invalid pointer to molecule in selection");
730 selectedMolecules[_mol->getId()]=const_cast<molecule *>(_mol);
731}
732
733void World::selectMolecule(const moleculeId_t id){
734 OBSERVE;
735 NOTIFY(SelectionChanged);
736 ASSERT(molecules.count(id),"Molecule Id selected that was not in the world");
737 selectedMolecules[id]=molecules[id];
738}
739
740void World::selectAllMolecules(MoleculeDescriptor descr){
741 OBSERVE;
742 NOTIFY(SelectionChanged);
743 internal_MoleculeIterator begin = getMoleculeIter_internal(descr);
744 internal_MoleculeIterator end = moleculeEnd_internal();
745 void (World::*func)(const molecule*) = &World::selectMolecule; // needed for type resolution of overloaded function
746 for_each(begin,end,bind1st(mem_fun(func),this)); // func is select... see above
747}
748
749void World::selectMoleculeOfAtom(const atom *_atom){
750 OBSERVE;
751 NOTIFY(SelectionChanged);
752 ASSERT(_atom,"Invalid atom pointer in selection of MoleculeOfAtom");
753 molecule *mol=_atom->getMolecule();
754 // the atom might not be part of a molecule
755 if(mol){
756 selectMolecule(mol);
757 }
758}
759
760void World::selectMoleculeOfAtom(const atomId_t id){
761 OBSERVE;
762 NOTIFY(SelectionChanged);
763 ASSERT(atoms.count(id),"No such atom with given ID in selection of Molecules of Atom");\
764 selectMoleculeOfAtom(atoms[id]);
765}
766
767void World::unselectMolecule(const molecule *_mol){
768 OBSERVE;
769 NOTIFY(SelectionChanged);
770 ASSERT(_mol,"invalid pointer in unselection of molecule");
771 unselectMolecule(_mol->getId());
772}
773
774void World::unselectMolecule(const moleculeId_t id){
775 OBSERVE;
776 NOTIFY(SelectionChanged);
777 ASSERT(molecules.count(id),"No such molecule with ID in unselection");
778 selectedMolecules.erase(id);
779}
780
781void World::unselectAllMolecules(MoleculeDescriptor descr){
782 OBSERVE;
783 NOTIFY(SelectionChanged);
784 internal_MoleculeIterator begin = getMoleculeIter_internal(descr);
785 internal_MoleculeIterator end = moleculeEnd_internal();
786 void (World::*func)(const molecule*) = &World::unselectMolecule; // needed for type resolution of overloaded function
787 for_each(begin,end,bind1st(mem_fun(func),this)); // func is unselect... see above
788}
789
790void World::unselectMoleculeOfAtom(const atom *_atom){
791 OBSERVE;
792 NOTIFY(SelectionChanged);
793 ASSERT(_atom,"Invalid atom pointer in selection of MoleculeOfAtom");
794 molecule *mol=_atom->getMolecule();
795 // the atom might not be part of a molecule
796 if(mol){
797 unselectMolecule(mol);
798 }
799}
800
801void World::unselectMoleculeOfAtom(const atomId_t id){
802 OBSERVE;
803 NOTIFY(SelectionChanged);
804 ASSERT(atoms.count(id),"No such atom with given ID in selection of Molecules of Atom");\
805 unselectMoleculeOfAtom(atoms[id]);
806}
807
808size_t World::countSelectedMolecules() const {
809 size_t count = 0;
810 for (MoleculeSet::const_iterator iter = selectedMolecules.begin(); iter != selectedMolecules.end(); ++iter)
811 count++;
812 return count;
813}
814
815bool World::isSelected(const molecule *_mol) const {
816 return isMoleculeSelected(_mol->getId());
817}
818
819bool World::isMoleculeSelected(const moleculeId_t no) const {
820 return selectedMolecules.find(no) != selectedMolecules.end();
821}
822
823const std::vector<molecule *> World::getSelectedMolecules() const {
824 std::vector<molecule *> returnMolecules;
825 returnMolecules.resize(countSelectedMolecules());
826 int count = 0;
827 for (MoleculeSet::const_iterator iter = selectedMolecules.begin(); iter != selectedMolecules.end(); ++iter)
828 returnMolecules[count++] = iter->second;
829 return returnMolecules;
830}
831
832/******************* Iterators over Selection *****************************/
833World::AtomSelectionIterator World::beginAtomSelection(){
834 return selectedAtoms.begin();
835}
836
837World::AtomSelectionIterator World::endAtomSelection(){
838 return selectedAtoms.end();
839}
840
841World::AtomSelectionConstIterator World::beginAtomSelection() const{
842 return selectedAtoms.begin();
843}
844
845World::AtomSelectionConstIterator World::endAtomSelection() const{
846 return selectedAtoms.end();
847}
848
849
850World::MoleculeSelectionIterator World::beginMoleculeSelection(){
851 return selectedMolecules.begin();
852}
853
854World::MoleculeSelectionIterator World::endMoleculeSelection(){
855 return selectedMolecules.end();
856}
857
858World::MoleculeSelectionConstIterator World::beginMoleculeSelection() const{
859 return selectedMolecules.begin();
860}
861
862World::MoleculeSelectionConstIterator World::endMoleculeSelection() const{
863 return selectedMolecules.end();
864}
865
866/******************************* Singleton Stuff **************************/
867
868World::World() :
869 Observable("World"),
870 BG(new BondGraph(true)), // assume Angstroem for the moment
871 periode(new periodentafel(true)),
872 configuration(new config),
873 homologies(new HomologyContainer()),
874 Thermostats(new ThermoStatContainer),
875 ExitFlag(0),
876 atoms(this),
877 selectedAtoms(this),
878 atomIdPool(0, 20, 100),
879 molecules(this),
880 selectedMolecules(this),
881 moleculeIdPool(0, 20,100),
882 molecules_deprecated(new MoleculeListClass(this))
883{
884 cell_size = new Box;
885 RealSpaceMatrix domain;
886 domain.at(0,0) = 20;
887 domain.at(1,1) = 20;
888 domain.at(2,2) = 20;
889 cell_size->setM(domain);
890 LCcontroller = new LinkedCell::LinkedCell_Controller(*cell_size);
891 defaultName = "none";
892 Channels *OurChannel = new Channels;
893 NotificationChannels.insert( std::make_pair( static_cast<Observable *>(this), OurChannel) );
894 for (size_t type = 0; type < (size_t)NotificationType_MAX; ++type)
895 OurChannel->addChannel(type);
896 molecules_deprecated->signOn(this);
897}
898
899World::~World()
900{
901 molecules_deprecated->signOff(this);
902 delete LCcontroller;
903 delete cell_size;
904 delete molecules_deprecated;
905 MoleculeSet::iterator molIter;
906 for(molIter=molecules.begin();molIter!=molecules.end();++molIter){
907 DeleteMolecule((*molIter).second);
908 }
909 molecules.clear();
910 AtomSet::iterator atIter;
911 for(atIter=atoms.begin();atIter!=atoms.end();++atIter){
912 DeleteAtom((*atIter).second);
913 }
914 atoms.clear();
915
916 delete BG;
917 delete periode;
918 delete configuration;
919 delete Thermostats;
920 delete homologies;
921}
922
923// Explicit instantiation of the singleton mechanism at this point
924
925// moleculeId_t und atomId_t sind gleicher Basistyp, deswegen nur einen von beiden konstruieren
926CONSTRUCT_IDPOOL(atomId_t, uniqueId)
927CONSTRUCT_IDPOOL(moleculeId_t, continuousId)
928
929CONSTRUCT_SINGLETON(World)
930
931CONSTRUCT_OBSERVEDCONTAINER(World::AtomSTLSet)
932
933CONSTRUCT_OBSERVEDCONTAINER(World::MoleculeSTLSet)
934
935/******************************* deprecated Legacy Stuff ***********************/
936
937MoleculeListClass *&World::getMolecules() {
938 return molecules_deprecated;
939}
Note: See TracBrowser for help on using the repository browser.