source: src/World.cpp@ 4464ef

Action_Thermostats Add_AtomRandomPerturbation Add_RotateAroundBondAction Add_SelectAtomByNameAction Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_StructOpt_integration_tests Automaking_mpqc_open AutomationFragmentation_failures Candidate_v1.6.0 Candidate_v1.6.1 ChangeBugEmailaddress ChangingTestPorts ChemicalSpaceEvaluator Combining_Subpackages Debian_Package_split Debian_package_split_molecuildergui_only Disabling_MemDebug Docu_Python_wait EmpiricalPotential_contain_HomologyGraph_documentation Enable_parallel_make_install Enhance_userguide Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Example_ManyWaysToTranslateAtom Exclude_Hydrogens_annealWithBondGraph FitPartialCharges_GlobalError Fix_ChronosMutex Fix_StatusMsg Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns ForceAnnealing_goodresults ForceAnnealing_oldresults ForceAnnealing_tocheck ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion GeometryObjects Gui_displays_atomic_force_velocity IndependentFragmentGrids_IntegrationTest JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool JobMarket_unresolvable_hostname_fix ODR_violation_mpqc_open PartialCharges_OrthogonalSummation PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks RotateToPrincipalAxisSystem_UndoRedo StoppableMakroAction Subpackage_levmar Subpackage_vmg ThirdParty_MPQC_rebuilt_buildsystem TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps Ubuntu_1604_changes stable
Last change on this file since 4464ef was 0249ce, checked in by Frederik Heber <heber@…>, 8 years ago

FIX: Pop..Action need to check whether stack is actually non-empty.

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