source: src/World.cpp@ 270bdf

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

atom::getMolecule() now returns ptr to const molecule.

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