source: src/World.cpp@ 7f1865d

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

Added template functions to (un)set vector of instances in a row.

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