source: src/World.cpp@ 7f1b51

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

Merge branch 'GUI_Fixes' into stable

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