source: src/World.cpp@ 97445f

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

World::getMolecules..() now has const versions as well.

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