source: src/World.cpp@ 7eec64

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

FIX: World needs to first destroy the molecule, then release its ids.

  • this is similar to the change for the atom.
  • Property mode set to 100644
File size: 30.0 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 NOTIFY(SelectionChanged);
346 }
347 DeleteMolecule(mol);
348 molecules.erase(id);
349 moleculeIdPool.releaseId(id);
350}
351
352atom *World::createAtom(){
353 OBSERVE;
354 atomId_t id = atomIdPool.getNextId();
355 ASSERT(!atoms.count(id),"proposed id did not specify an unused ID");
356 atom *res = NewAtom(id);
357 res->setWorld(this);
358 // store the atom by ID
359 atoms[res->getId()] = res;
360 _lastchangedatom = res;
361 _lastchangedatomid = res->getId();
362 NOTIFY(AtomInserted);
363 return res;
364}
365
366
367int World::registerAtom(atom *atom){
368 OBSERVE;
369 atomId_t id = atomIdPool.getNextId();
370 atom->setId(id);
371 atom->setWorld(this);
372 atoms[atom->getId()] = atom;
373 _lastchangedatom = atom;
374 _lastchangedatomid = atom->getId();
375 NOTIFY(AtomInserted);
376 return atom->getId();
377}
378
379void World::destroyAtom(atom* atom){
380 int id = atom->getId();
381 destroyAtom(id);
382}
383
384void World::destroyAtom(atomId_t id) {
385 atom *atom = atoms[id];
386 ASSERT(atom,"Atom ID that was meant to be destroyed did not exist");
387 // give notice about immediate removal
388 {
389 OBSERVE;
390 _lastchangedatom = atom;
391 _lastchangedatomid = atom->getId();
392 NOTIFY(AtomRemoved);
393 }
394 // check if it's the last atom
395 molecule *_mol = const_cast<molecule *>(atom->getMolecule());
396 if ((_mol == NULL) || (_mol->getAtomCount() > 1))
397 _mol = NULL;
398 if (isAtomSelected(id)) {
399 selectedAtoms.erase(id);
400 NOTIFY(SelectionChanged);
401 }
402 DeleteAtom(atom);
403 atoms.erase(id);
404 atomIdPool.releaseId(id);
405 // remove molecule if empty
406 if (_mol != NULL)
407 destroyMolecule(_mol);
408}
409
410bool World::changeAtomId(atomId_t oldId, atomId_t newId, atom* target){
411 OBSERVE;
412 // in case this call did not originate from inside the atom, we redirect it,
413 // to also let it know that it has changed
414 if(!target){
415 target = atoms[oldId];
416 ASSERT(target,"Atom with that ID not found");
417 return target->changeId(newId);
418 }
419 else{
420 if(atomIdPool.reserveId(newId)){
421 atoms.erase(oldId);
422 atoms.insert(pair<atomId_t,atom*>(newId,target));
423 return true;
424 }
425 else{
426 return false;
427 }
428 }
429}
430
431bool World::changeMoleculeId(moleculeId_t oldId, moleculeId_t newId, molecule* target){
432 OBSERVE;
433 // in case this call did not originate from inside the atom, we redirect it,
434 // to also let it know that it has changed
435 if(!target){
436 target = molecules[oldId];
437 ASSERT(target,"Molecule with that ID not found");
438 return target->changeId(newId);
439 }
440 else{
441 if(moleculeIdPool.reserveId(newId)){
442 molecules.erase(oldId);
443 molecules.insert(pair<moleculeId_t,molecule*>(newId,target));
444 return true;
445 }
446 else{
447 return false;
448 }
449 }
450}
451
452ManipulateAtomsProcess* World::manipulateAtoms(boost::function<void(atom*)> op,std::string name,AtomDescriptor descr){
453 ActionTrait manipulateTrait(name);
454 return new ManipulateAtomsProcess(op, descr,manipulateTrait);
455}
456
457ManipulateAtomsProcess* World::manipulateAtoms(boost::function<void(atom*)> op,std::string name){
458 return manipulateAtoms(op,name,AllAtoms());
459}
460
461/********************* Internal Change methods for double Callback and Observer mechanism ********/
462
463void World::doManipulate(ManipulateAtomsProcess *proc){
464 proc->signOn(this);
465 {
466 OBSERVE;
467 proc->doManipulate(this);
468 }
469 proc->signOff(this);
470}
471/******************************* Iterators ********************************/
472
473// external parts with observers
474
475CONSTRUCT_SELECTIVE_ITERATOR(atom*,World::AtomSet,AtomDescriptor)
476
477CONSTRUCT_SELECTIVE_CONST_ITERATOR(atom*,World::AtomSet,AtomDescriptor)
478
479World::AtomIterator
480World::getAtomIter(AtomDescriptor descr){
481 return AtomIterator(descr,atoms);
482}
483
484World::AtomConstIterator
485World::getAtomIter(AtomDescriptor descr) const{
486 return AtomConstIterator(descr,atoms);
487}
488
489World::AtomIterator
490World::getAtomIter(){
491 return AtomIterator(AllAtoms(),atoms);
492}
493
494World::AtomConstIterator
495World::getAtomIter() const{
496 return AtomConstIterator(AllAtoms(),atoms);
497}
498
499World::AtomIterator
500World::atomEnd(){
501 return AtomIterator(AllAtoms(),atoms,atoms.end());
502}
503
504World::AtomConstIterator
505World::atomEnd() const{
506 return AtomConstIterator(AllAtoms(),atoms,atoms.end());
507}
508
509CONSTRUCT_SELECTIVE_ITERATOR(molecule*,World::MoleculeSet,MoleculeDescriptor)
510
511CONSTRUCT_SELECTIVE_CONST_ITERATOR(molecule*,World::MoleculeSet,MoleculeDescriptor)
512
513World::MoleculeIterator
514World::getMoleculeIter(MoleculeDescriptor descr){
515 return MoleculeIterator(descr,molecules);
516}
517
518World::MoleculeConstIterator
519World::getMoleculeIter(MoleculeDescriptor descr) const{
520 return MoleculeConstIterator(descr,molecules);
521}
522
523World::MoleculeIterator
524World::getMoleculeIter(){
525 return MoleculeIterator(AllMolecules(),molecules);
526}
527
528World::MoleculeConstIterator
529World::getMoleculeIter() const{
530 return MoleculeConstIterator(AllMolecules(),molecules);
531}
532
533World::MoleculeIterator
534World::moleculeEnd(){
535 return MoleculeIterator(AllMolecules(),molecules,molecules.end());
536}
537
538World::MoleculeConstIterator
539World::moleculeEnd() const{
540 return MoleculeConstIterator(AllMolecules(),molecules,molecules.end());
541}
542
543// Internal parts, without observers
544
545// Build the AtomIterator from template
546CONSTRUCT_SELECTIVE_ITERATOR(atom*,World::AtomSet::set_t,AtomDescriptor);
547
548
549World::internal_AtomIterator
550World::getAtomIter_internal(AtomDescriptor descr){
551 return internal_AtomIterator(descr,atoms.getContent());
552}
553
554World::internal_AtomIterator
555World::atomEnd_internal(){
556 return internal_AtomIterator(AllAtoms(),atoms.getContent(),atoms.end_internal());
557}
558
559// build the MoleculeIterator from template
560CONSTRUCT_SELECTIVE_ITERATOR(molecule*,World::MoleculeSet::set_t,MoleculeDescriptor);
561
562World::internal_MoleculeIterator World::getMoleculeIter_internal(MoleculeDescriptor descr){
563 return internal_MoleculeIterator(descr,molecules.getContent());
564}
565
566World::internal_MoleculeIterator World::moleculeEnd_internal(){
567 return internal_MoleculeIterator(AllMolecules(),molecules.getContent(),molecules.end_internal());
568}
569
570/************************** Selection of Atoms and molecules ******************/
571
572// Atoms
573
574void World::clearAtomSelection(){
575 OBSERVE;
576 NOTIFY(SelectionChanged);
577 selectedAtoms.clear();
578}
579
580void World::invertAtomSelection(){
581 // get all atoms not selected
582 AtomComposite invertedSelection(getAllAtoms());
583 bool (World::*predicate)(const atom*) const = &World::isSelected; // needed for type resolution of overloaded function
584 AtomComposite::iterator iter =
585 std::remove_if(invertedSelection.begin(), invertedSelection.end(),
586 std::bind1st(std::mem_fun(predicate), this));
587 invertedSelection.erase(iter, invertedSelection.end());
588 // apply new selection
589 selectedAtoms.clear();
590 void (World::*selector)(const atom*) = &World::selectAtom; // needed for type resolution of overloaded function
591 std::for_each(invertedSelection.begin(),invertedSelection.end(),
592 std::bind1st(std::mem_fun(selector),this)); // func is select... see above
593}
594
595void World::popAtomSelection(){
596 OBSERVE;
597 NOTIFY(SelectionChanged);
598 const atomIdsVector_t atomids = selectedAtoms_Stack.top();
599 boost::function<void (const atomId_t)> IdSelector =
600 boost::bind(static_cast<void (World::*)(const atomId_t)>(&World::selectAtom), this, _1);
601 selectedAtoms.clear();
602 std::for_each(atomids.begin(),atomids.end(), IdSelector);
603 selectedAtoms_Stack.pop();
604}
605
606void World::pushAtomSelection(){
607 OBSERVE;
608 NOTIFY(SelectionChanged);
609 atomIdsVector_t atomids(countSelectedAtoms(), (atomId_t)-1);
610 std::copy(
611 MapKeyIterator<AtomSelectionConstIterator>(beginAtomSelection()),
612 MapKeyIterator<AtomSelectionConstIterator>(endAtomSelection()),
613 atomids.begin());
614 selectedAtoms_Stack.push( atomids );
615 selectedAtoms.clear();
616}
617
618void World::selectAtom(const atom *_atom){
619 OBSERVE;
620 NOTIFY(SelectionChanged);
621 // atom * is unchanged in this function, but we do store entity as changeable
622 ASSERT(_atom,"Invalid pointer in selection of atom");
623 selectedAtoms[_atom->getId()]=const_cast<atom *>(_atom);
624}
625
626void World::selectAtom(const atomId_t id){
627 OBSERVE;
628 NOTIFY(SelectionChanged);
629 ASSERT(atoms.count(id),"Atom Id selected that was not in the world");
630 selectedAtoms[id]=atoms[id];
631}
632
633void World::selectAllAtoms(AtomDescriptor descr){
634 OBSERVE;
635 NOTIFY(SelectionChanged);
636 internal_AtomIterator begin = getAtomIter_internal(descr);
637 internal_AtomIterator end = atomEnd_internal();
638 void (World::*func)(const atom*) = &World::selectAtom; // needed for type resolution of overloaded function
639 for_each(begin,end,bind1st(mem_fun(func),this)); // func is select... see above
640}
641
642void World::selectAtomsOfMolecule(const molecule *_mol){
643 OBSERVE;
644 NOTIFY(SelectionChanged);
645 ASSERT(_mol,"Invalid pointer to molecule in selection of Atoms of Molecule");
646 // need to make it const to get the fast iterators
647 const molecule *mol = _mol;
648 void (World::*func)(const atom*) = &World::selectAtom; // needed for type resolution of overloaded function
649 for_each(mol->begin(),mol->end(),bind1st(mem_fun(func),this)); // func is select... see above
650}
651
652void World::selectAtomsOfMolecule(const moleculeId_t id){
653 OBSERVE;
654 NOTIFY(SelectionChanged);
655 ASSERT(molecules.count(id),"No molecule with the given id upon Selection of atoms from molecule");
656 selectAtomsOfMolecule(molecules[id]);
657}
658
659void World::unselectAtom(const atom *_atom){
660 OBSERVE;
661 NOTIFY(SelectionChanged);
662 ASSERT(_atom,"Invalid pointer in unselection of atom");
663 unselectAtom(_atom->getId());
664}
665
666void World::unselectAtom(const atomId_t id){
667 OBSERVE;
668 NOTIFY(SelectionChanged);
669 ASSERT(atoms.count(id),"Atom Id unselected that was not in the world");
670 selectedAtoms.erase(id);
671}
672
673void World::unselectAllAtoms(AtomDescriptor descr){
674 OBSERVE;
675 NOTIFY(SelectionChanged);
676 internal_AtomIterator begin = getAtomIter_internal(descr);
677 internal_AtomIterator end = atomEnd_internal();
678 void (World::*func)(const atom*) = &World::unselectAtom; // needed for type resolution of overloaded function
679 for_each(begin,end,bind1st(mem_fun(func),this)); // func is unselect... see above
680}
681
682void World::unselectAtomsOfMolecule(const molecule *_mol){
683 OBSERVE;
684 NOTIFY(SelectionChanged);
685 ASSERT(_mol,"Invalid pointer to molecule in selection of Atoms of Molecule");
686 // need to make it const to get the fast iterators
687 const molecule *mol = _mol;
688 void (World::*func)(const atom*) = &World::unselectAtom; // needed for type resolution of overloaded function
689 for_each(mol->begin(),mol->end(),bind1st(mem_fun(func),this)); // func is unselect... see above
690}
691
692void World::unselectAtomsOfMolecule(const moleculeId_t id){
693 OBSERVE;
694 NOTIFY(SelectionChanged);
695 ASSERT(molecules.count(id),"No molecule with the given id upon Selection of atoms from molecule");
696 unselectAtomsOfMolecule(molecules[id]);
697}
698
699size_t World::countSelectedAtoms() const {
700 size_t count = 0;
701 for (AtomSet::const_iterator iter = selectedAtoms.begin(); iter != selectedAtoms.end(); ++iter)
702 count++;
703 return count;
704}
705
706bool World::isSelected(const atom *_atom) const {
707 return isAtomSelected(_atom->getId());
708}
709
710bool World::isAtomSelected(const atomId_t no) const {
711 return selectedAtoms.find(no) != selectedAtoms.end();
712}
713
714std::vector<atom *> World::getSelectedAtoms() {
715 std::vector<atom *> returnAtoms;
716 std::transform(
717 selectedAtoms.begin(),
718 selectedAtoms.end(),
719 back_inserter(returnAtoms),
720 _take<atom*,World::AtomSet::value_type>::get);
721 return returnAtoms;
722}
723
724std::vector<const atom *> World::getSelectedAtoms() const {
725 std::vector<const atom *> returnAtoms;
726 std::transform(
727 selectedAtoms.begin(),
728 selectedAtoms.end(),
729 back_inserter(returnAtoms),
730 _take<atom*,World::AtomSet::value_type>::get);
731 return returnAtoms;
732}
733
734std::vector<atomId_t> World::getSelectedAtomIds() const {
735 std::vector<atomId_t> returnAtomIds;
736 std::transform(
737 selectedAtoms.begin(),
738 selectedAtoms.end(),
739 back_inserter(returnAtomIds),
740 _take<atom*,World::AtomSet::value_type>::getKey);
741 return returnAtomIds;
742}
743
744// Molecules
745
746void World::clearMoleculeSelection(){
747 OBSERVE;
748 NOTIFY(SelectionChanged);
749 selectedMolecules.clear();
750}
751
752void World::invertMoleculeSelection(){
753 // get all molecules not selected
754 typedef std::vector<molecule *> MoleculeVector_t;
755 MoleculeVector_t invertedSelection(getAllMolecules());
756 bool (World::*predicate)(const molecule*) const = &World::isSelected; // needed for type resolution of overloaded function
757 MoleculeVector_t::iterator iter =
758 std::remove_if(invertedSelection.begin(), invertedSelection.end(),
759 std::bind1st(std::mem_fun(predicate), this));
760 invertedSelection.erase(iter, invertedSelection.end());
761 // apply new selection
762 selectedMolecules.clear();
763 void (World::*selector)(const molecule*) = &World::selectMolecule; // needed for type resolution of overloaded function
764 std::for_each(invertedSelection.begin(),invertedSelection.end(),
765 std::bind1st(std::mem_fun(selector),this)); // func is select... see above
766}
767
768void World::popMoleculeSelection(){
769 OBSERVE;
770 NOTIFY(SelectionChanged);
771 const moleculeIdsVector_t moleculeids = selectedMolecules_Stack.top();
772 boost::function<void (const moleculeId_t)> IdSelector =
773 boost::bind(static_cast<void (World::*)(const moleculeId_t)>(&World::selectMolecule), this, _1);
774 selectedMolecules.clear();
775 std::for_each(moleculeids.begin(),moleculeids.end(), IdSelector);
776 selectedMolecules_Stack.pop();
777}
778
779void World::pushMoleculeSelection(){
780 OBSERVE;
781 NOTIFY(SelectionChanged);
782 moleculeIdsVector_t moleculeids(countSelectedMolecules(), (moleculeId_t)-1);
783 boost::function<moleculeId_t (const molecule*)> IdRetriever =
784 boost::bind(&molecule::getId, _1);
785 std::copy(
786 MapKeyIterator<MoleculeSelectionConstIterator>(beginMoleculeSelection()),
787 MapKeyIterator<MoleculeSelectionConstIterator>(endMoleculeSelection()),
788 moleculeids.begin());
789 selectedMolecules_Stack.push( moleculeids );
790 selectedMolecules.clear();
791}
792
793void World::selectMolecule(const molecule *_mol){
794 OBSERVE;
795 NOTIFY(SelectionChanged);
796 // molecule * is unchanged in this function, but we do store entity as changeable
797 ASSERT(_mol,"Invalid pointer to molecule in selection");
798 selectedMolecules[_mol->getId()]=const_cast<molecule *>(_mol);
799}
800
801void World::selectMolecule(const moleculeId_t id){
802 OBSERVE;
803 NOTIFY(SelectionChanged);
804 ASSERT(molecules.count(id),"Molecule Id selected that was not in the world");
805 selectedMolecules[id]=molecules[id];
806}
807
808void World::selectAllMolecules(MoleculeDescriptor descr){
809 OBSERVE;
810 NOTIFY(SelectionChanged);
811 internal_MoleculeIterator begin = getMoleculeIter_internal(descr);
812 internal_MoleculeIterator end = moleculeEnd_internal();
813 void (World::*func)(const molecule*) = &World::selectMolecule; // needed for type resolution of overloaded function
814 for_each(begin,end,bind1st(mem_fun(func),this)); // func is select... see above
815}
816
817void World::selectMoleculeOfAtom(const atom *_atom){
818 OBSERVE;
819 NOTIFY(SelectionChanged);
820 ASSERT(_atom,"Invalid atom pointer in selection of MoleculeOfAtom");
821 const molecule *mol=_atom->getMolecule();
822 // the atom might not be part of a molecule
823 if(mol){
824 selectMolecule(mol);
825 }
826}
827
828void World::selectMoleculeOfAtom(const atomId_t id){
829 OBSERVE;
830 NOTIFY(SelectionChanged);
831 ASSERT(atoms.count(id),"No such atom with given ID in selection of Molecules of Atom");\
832 selectMoleculeOfAtom(atoms[id]);
833}
834
835void World::unselectMolecule(const molecule *_mol){
836 OBSERVE;
837 NOTIFY(SelectionChanged);
838 ASSERT(_mol,"invalid pointer in unselection of molecule");
839 unselectMolecule(_mol->getId());
840}
841
842void World::unselectMolecule(const moleculeId_t id){
843 OBSERVE;
844 NOTIFY(SelectionChanged);
845 ASSERT(molecules.count(id),"No such molecule with ID in unselection");
846 selectedMolecules.erase(id);
847}
848
849void World::unselectAllMolecules(MoleculeDescriptor descr){
850 OBSERVE;
851 NOTIFY(SelectionChanged);
852 internal_MoleculeIterator begin = getMoleculeIter_internal(descr);
853 internal_MoleculeIterator end = moleculeEnd_internal();
854 void (World::*func)(const molecule*) = &World::unselectMolecule; // needed for type resolution of overloaded function
855 for_each(begin,end,bind1st(mem_fun(func),this)); // func is unselect... see above
856}
857
858void World::unselectMoleculeOfAtom(const atom *_atom){
859 OBSERVE;
860 NOTIFY(SelectionChanged);
861 ASSERT(_atom,"Invalid atom pointer in selection of MoleculeOfAtom");
862 const molecule *mol=_atom->getMolecule();
863 // the atom might not be part of a molecule
864 if(mol){
865 unselectMolecule(mol);
866 }
867}
868
869void World::unselectMoleculeOfAtom(const atomId_t id){
870 OBSERVE;
871 NOTIFY(SelectionChanged);
872 ASSERT(atoms.count(id),"No such atom with given ID in selection of Molecules of Atom");\
873 unselectMoleculeOfAtom(atoms[id]);
874}
875
876size_t World::countSelectedMolecules() const {
877 size_t count = 0;
878 for (MoleculeSet::const_iterator iter = selectedMolecules.begin(); iter != selectedMolecules.end(); ++iter)
879 count++;
880 return count;
881}
882
883bool World::isSelected(const molecule *_mol) const {
884 return isMoleculeSelected(_mol->getId());
885}
886
887bool World::isMoleculeSelected(const moleculeId_t no) const {
888 return selectedMolecules.find(no) != selectedMolecules.end();
889}
890
891std::vector<molecule *> World::getSelectedMolecules() {
892 std::vector<molecule *> returnMolecules;
893 std::transform(
894 selectedMolecules.begin(),
895 selectedMolecules.end(),
896 back_inserter(returnMolecules),
897 _take<molecule*,World::MoleculeSet::value_type>::get);
898 return returnMolecules;
899}
900
901std::vector<const molecule *> World::getSelectedMolecules() const {
902 std::vector<const molecule *> returnMolecules;
903 std::transform(
904 selectedMolecules.begin(),
905 selectedMolecules.end(),
906 back_inserter(returnMolecules),
907 _take<molecule*,World::MoleculeSet::value_type>::get);
908 return returnMolecules;
909}
910
911std::vector<moleculeId_t> World::getSelectedMoleculeIds() const {
912 std::vector<moleculeId_t> returnMoleculeIds;
913 std::transform(
914 selectedMolecules.begin(),
915 selectedMolecules.end(),
916 back_inserter(returnMoleculeIds),
917 _take<molecule*,World::MoleculeSet::value_type>::getKey);
918 return returnMoleculeIds;
919}
920
921/******************* Iterators over Selection *****************************/
922World::AtomSelectionIterator World::beginAtomSelection(){
923 return selectedAtoms.begin();
924}
925
926World::AtomSelectionIterator World::endAtomSelection(){
927 return selectedAtoms.end();
928}
929
930World::AtomSelectionConstIterator World::beginAtomSelection() const{
931 return selectedAtoms.begin();
932}
933
934World::AtomSelectionConstIterator World::endAtomSelection() const{
935 return selectedAtoms.end();
936}
937
938
939World::MoleculeSelectionIterator World::beginMoleculeSelection(){
940 return selectedMolecules.begin();
941}
942
943World::MoleculeSelectionIterator World::endMoleculeSelection(){
944 return selectedMolecules.end();
945}
946
947World::MoleculeSelectionConstIterator World::beginMoleculeSelection() const{
948 return selectedMolecules.begin();
949}
950
951World::MoleculeSelectionConstIterator World::endMoleculeSelection() const{
952 return selectedMolecules.end();
953}
954
955/******************************* Singleton Stuff **************************/
956
957World::World() :
958 Observable("World"),
959 BG(new BondGraph(true)), // assume Angstroem for the moment
960 periode(new periodentafel(true)),
961 configuration(new config),
962 homologies(new HomologyContainer()),
963 Thermostats(new ThermoStatContainer),
964 ExitFlag(0),
965 atoms(this),
966 selectedAtoms(this),
967 atomIdPool(0, 20, 100),
968 molecules(this),
969 selectedMolecules(this),
970 moleculeIdPool(0, 20,100),
971 molecules_deprecated(new MoleculeListClass(this))
972{
973 cell_size = new Box;
974 RealSpaceMatrix domain;
975 domain.at(0,0) = 20;
976 domain.at(1,1) = 20;
977 domain.at(2,2) = 20;
978 cell_size->setM(domain);
979 LCcontroller = new LinkedCell::LinkedCell_Controller(*cell_size);
980 defaultName = "none";
981 Channels *OurChannel = new Channels;
982 Observable::insertNotificationChannel( std::make_pair( static_cast<Observable *>(this), OurChannel) );
983 for (size_t type = 0; type < (size_t)NotificationType_MAX; ++type)
984 OurChannel->addChannel(type);
985}
986
987World::~World()
988{
989 delete LCcontroller;
990 delete cell_size;
991 delete molecules_deprecated;
992 MoleculeSet::iterator molIter;
993 for(molIter=molecules.begin();molIter!=molecules.end();++molIter){
994 DeleteMolecule((*molIter).second);
995 }
996 molecules.clear();
997 AtomSet::iterator atIter;
998 for(atIter=atoms.begin();atIter!=atoms.end();++atIter){
999 DeleteAtom((*atIter).second);
1000 }
1001 atoms.clear();
1002
1003 delete BG;
1004 delete periode;
1005 delete configuration;
1006 delete Thermostats;
1007 delete homologies;
1008}
1009
1010// Explicit instantiation of the singleton mechanism at this point
1011
1012// moleculeId_t und atomId_t sind gleicher Basistyp, deswegen nur einen von beiden konstruieren
1013CONSTRUCT_IDPOOL(atomId_t, uniqueId)
1014CONSTRUCT_IDPOOL(moleculeId_t, continuousId)
1015
1016CONSTRUCT_SINGLETON(World)
1017
1018CONSTRUCT_OBSERVEDCONTAINER(World::AtomSTLSet, UnobservedIterator<World::AtomSTLSet> )
1019
1020CONSTRUCT_OBSERVEDCONTAINER(World::MoleculeSTLSet, UnobservedIterator<World::MoleculeSTLSet> )
1021
1022/******************************* deprecated Legacy Stuff ***********************/
1023
1024MoleculeListClass *&World::getMolecules() {
1025 return molecules_deprecated;
1026}
Note: See TracBrowser for help on using the repository browser.