source: src/World.cpp@ d93d2c

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

Added recreateAtom() and recreateMolecule() to World.

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