source: src/World.cpp@ f02b53

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

World now first releases id and then destroys the atom/molecule.

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