source: src/World.cpp@ cd5aa0

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

FIX: [push/pop][Atom/Molecule]Selection would store ptrs instead of ids.

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