source: src/UIElements/Qt4/InstanceBoard/QtObservedInstanceBoard.cpp@ 136842

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

FIX: ObservedValue_Index_t is now the memory address of the Observer instance.

  • the atom, bond, or molecule may be removed before and reinstantiated at the same address. Hence, it is not a good unique index. The only sensible index is the memory address of the QtObserved... instance itself.
  • Property mode set to 100644
File size: 16.6 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2015 Frederik Heber. All rights reserved.
5 *
6 *
7 * This file is part of MoleCuilder.
8 *
9 * MoleCuilder is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * MoleCuilder is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with MoleCuilder. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23/*
24 * QtObservedInstanceBoard.cpp
25 *
26 * Created on: Oct 17, 2015
27 * Author: heber
28 */
29
30
31// include config.h
32#ifdef HAVE_CONFIG_H
33#include <config.h>
34#endif
35
36#include "QtObservedInstanceBoard.hpp"
37
38#include <QtCore/QMetaType>
39
40#include "UIElements/Qt4/InstanceBoard/QtObservedAtom.hpp"
41#include "UIElements/Qt4/InstanceBoard/QtObservedMolecule.hpp"
42
43#include "CodePatterns/MemDebug.hpp"
44
45#include <boost/bind.hpp>
46
47#include "CodePatterns/Log.hpp"
48
49#include "Atom/atom.hpp"
50#include "Descriptors/AtomIdDescriptor.hpp"
51#include "Descriptors/MoleculeIdDescriptor.hpp"
52#include "molecule.hpp"
53#include "UIElements/Qt4/InstanceBoard/ObservedValuesContainer_impl.hpp"
54#include "World.hpp"
55
56QtObservedInstanceBoard::QtObservedInstanceBoard(QWidget * _parent) :
57 QWidget(_parent),
58 Observer("QtObservedInstanceBoard"),
59 WorldSignedOn(false),
60 atomObservedValues(
61 "atom",
62 *this,
63 boost::bind(&QtObservedInstanceBoard::atomcountsubjectKilled, this, _1)),
64 bondObservedValues(
65 "bond",
66 *this,
67 boost::bind(&QtObservedInstanceBoard::bondcountsubjectKilled, this, _1)),
68 moleculeObservedValues(
69 "molecule",
70 *this,
71 boost::bind(&QtObservedInstanceBoard::moleculecountsubjectKilled, this, _1))
72{
73 qRegisterMetaType<ObservedValue_Index_t>("ObservedValue_Index_t");
74 qRegisterMetaType<QtObservedAtom::ptr>("QtObservedAtom::ptr");
75 qRegisterMetaType<QtObservedBond::ptr>("QtObservedBond::ptr");
76 qRegisterMetaType<QtObservedMolecule::ptr>("QtObservedMolecule::ptr");
77
78 // be first (besides ObservedValues to know about new insertions)
79 World::getInstance().signOn(this, World::AtomInserted, GlobalObservableInfo::PriorityLevel(int(-10)));
80 World::getInstance().signOn(this, World::MoleculeInserted, GlobalObservableInfo::PriorityLevel(int(-10)));
81 WorldSignedOn = true;
82}
83
84QtObservedInstanceBoard::~QtObservedInstanceBoard()
85{
86 if (WorldSignedOn) {
87 World::getInstance().signOff(this, World::AtomInserted);
88 World::getInstance().signOff(this, World::MoleculeInserted);
89 }
90 // sign off from all remaining molecules, bonds, and atoms
91 for (SignedOn_t::iterator iter = AtomSignedOn.begin(); !AtomSignedOn.empty();
92 iter = AtomSignedOn.begin()) {
93 (*iter)->signOff(this, atom::IndexChanged);
94 (*iter)->signOff(this, atom::BondsAdded);
95 AtomSignedOn.erase(*iter);
96 }
97
98 for (SignedOn_t::iterator iter = MoleculeSignedOn.begin(); !MoleculeSignedOn.empty();
99 iter = MoleculeSignedOn.begin()) {
100 (*iter)->signOff(this, molecule::IndexChanged);
101 MoleculeSignedOn.erase(iter);
102 }
103}
104
105void QtObservedInstanceBoard::update(Observable *publisher)
106{
107 ASSERT(0,
108 "QtObservedInstanceBoard::update() - we are not signed on to general updates.");
109}
110
111void QtObservedInstanceBoard::subjectKilled(Observable *publisher)
112{
113 SignedOn_t::iterator iter = AtomSignedOn.find(publisher);
114 if ( iter != AtomSignedOn.end()) {
115 LOG(3, "DEBUG: InstanceBoard got subjectKilled() from atom " << publisher);
116 AtomSignedOn.erase(iter); // only remove one
117 } else {
118 iter = MoleculeSignedOn.find(publisher);
119 if ( iter != MoleculeSignedOn.end()) {
120 LOG(3, "DEBUG: InstanceBoard got subjectKilled() from molecule " << publisher);
121 MoleculeSignedOn.erase(iter);
122 } else {
123 ASSERT(0,
124 "QtObservedInstanceBoard::subjectKilled() - could not find signedOn for atom/molecule "+toString(publisher));
125 }
126 }
127}
128
129void QtObservedInstanceBoard::recieveNotification(Observable *publisher, Notification_ptr notification)
130{
131 if (static_cast<World *>(publisher) == World::getPointer()) {
132 switch (notification->getChannelNo()) {
133 case World::MoleculeInserted:
134 {
135 const moleculeId_t _id = const_cast<const World &>(World::getInstance()).lastChangedMolId();
136 #ifdef LOG_OBSERVER
137 observerLog().addMessage() << "++ Observer " << observerLog().getName(static_cast<Observer *>(this)) << " received notification that molecule "+toString(_id)+" has been inserted.";
138 #endif
139 LOG(3, "DEBUG: InformationBoard got moleculeInserted signal for molecule " << _id);
140 const molecule * const _molecule = const_cast<const World &>(World::getInstance()).
141 getMolecule(MoleculeById(_id));
142 if (_molecule != NULL) {
143 LOG(3, "DEBUG: InformationBoard initializes QtObservedMolecule for " << _id);
144 QtObservedMolecule::ptr observedmolecule(
145 new QtObservedMolecule(
146 _id,
147 _molecule,
148 *this));
149 observedmolecule->setSelfRef(observedmolecule);
150 const ObservedValue_Index_t index = observedmolecule->getIndex();
151 moleculeObservedValues.insert(index, observedmolecule);
152 moleculeids_lookup.left.insert( std::make_pair(_id, index) );
153 // we need to check for index changes
154 LOG(3, "DEBUG: InformationBoard signOn()s to molecule " << _id);
155 _molecule->signOn(this, molecule::IndexChanged);
156 MoleculeSignedOn.insert( static_cast<Observable *>(const_cast<molecule *>(_molecule)) );
157
158 emit moleculeInserted(observedmolecule);
159 } else {
160 ELOG(1, "QtObservedInstanceBoard got MoleculeInserted for unknown molecule id " << _id);
161 }
162 break;
163 }
164 case World::AtomInserted:
165 {
166 const atomId_t _id = const_cast<const World &>(World::getInstance()).lastChangedAtomId();
167 #ifdef LOG_OBSERVER
168 observerLog().addMessage() << "++ Observer " << observerLog().getName(static_cast<Observer *>(this)) << " received notification that atom "+toString(_id)+" has been inserted.";
169 #endif
170 LOG(3, "DEBUG: InformationBoard got atomInserted signal for atom " << _id);
171 const atom * const _atom = const_cast<const World &>(World::getInstance()).
172 getAtom(AtomById(_id));
173 if (_atom!= NULL) {
174 LOG(3, "DEBUG: InformationBoard initializes QtObservedAtom for " << _id);
175 QtObservedAtom::ptr observedatom(
176 new QtObservedAtom(_id, _atom, *this));
177 observedatom->setSelfRef(observedatom);
178 const ObservedValue_Index_t index = observedatom->getIndex();
179 atomObservedValues.insert(index, observedatom);
180 atomids_lookup.left.insert( std::make_pair(_id, index) );
181 // we need to check for index changes
182 LOG(3, "DEBUG: InformationBoard signOn()s to atom " << _id);
183 _atom->signOn(this, atom::IndexChanged);
184 _atom->signOn(this, atom::BondsAdded);
185 AtomSignedOn.insert( static_cast<Observable *>(const_cast<atom *>(_atom)) );
186 AtomSignedOn.insert( static_cast<Observable *>(const_cast<atom *>(_atom)) );
187 emit atomInserted(observedatom);
188 } else {
189 ELOG(1, "QtObservedInstanceBoard got AtomInserted for unknown atom id " << _id);
190 }
191 break;
192 }
193 default:
194 ASSERT(0, "QtObservedInstanceBoard::recieveNotification() - we cannot get here for World.");
195 break;
196 }
197 } else if (dynamic_cast<molecule *>(publisher) != NULL) {
198 const moleculeId_t molid = const_cast<const World &>(World::getInstance()).lastChangedMolId();
199 switch (notification->getChannelNo()) {
200 case molecule::IndexChanged:
201 {
202 // molecule has changed its index
203 const moleculeId_t newmoleculeId = dynamic_cast<molecule *>(publisher)->getId();
204 LOG(3, "DEBUG: InformationBoard got IndexChanged from molecule " << molid << " to " << newmoleculeId);
205 {
206 typename IdtoIndex_t<moleculeId_t>::left_iterator iter = moleculeids_lookup.left.find(molid);
207 ASSERT( iter != moleculeids_lookup.left.end(),
208 "QtObservedInstanceBoard::recieveNotification() - mol id "
209 +toString(molid)+" unknown to lookup.");
210 const ObservedValue_Index_t index = iter->second;
211 moleculeids_lookup.left.erase(iter);
212 moleculeids_lookup.left.insert( std::pair<moleculeId_t, ObservedValue_Index_t>(newmoleculeId, index) );
213 }
214 // no need update SignedOn, ref does not change
215 emit moleculeIndexChanged(molid, newmoleculeId);
216 break;
217 }
218 default:
219 ASSERT(0, "QtObservedInstanceBoard::recieveNotification() - we cannot get here.");
220 break;
221 }
222 } else if (dynamic_cast<atom *>(publisher) != NULL) {
223 const atomId_t oldatomId = const_cast<const World &>(World::getInstance()).lastChangedAtomId();
224 switch (notification->getChannelNo()) {
225 case AtomObservable::IndexChanged:
226 {
227 const atomId_t newatomId = dynamic_cast<atom *>(publisher)->getId();
228 LOG(3, "DEBUG: InformationBoard got IndexChanged from atom " << oldatomId << " to " << newatomId);
229 {
230 typename IdtoIndex_t<atomId_t>::left_iterator iter = atomids_lookup.left.find(oldatomId);
231 ASSERT( iter != atomids_lookup.left.end(),
232 "QtObservedInstanceBoard::recieveNotification() - atom id "
233 +toString(oldatomId)+" unknown to lookup.");
234 const ObservedValue_Index_t index = iter->second;
235 atomids_lookup.left.erase(iter);
236 atomids_lookup.left.insert( std::pair<atomId_t, ObservedValue_Index_t>(newatomId, index) );
237 }
238 // no need update SignedOn, ref does not change
239 emit atomIndexChanged(oldatomId, newatomId);
240 break;
241 }
242 case AtomObservable::BondsAdded:
243 {
244 const atom * _atom = dynamic_cast<atom *>(publisher);
245 const atomId_t _id = _atom->getId();
246#ifdef LOG_OBSERVER
247 observerLog().addMessage() << "++ Observer " << observerLog().getName(static_cast<Observer *>(this)) << " received notification that atom "+toString(_id)+" has been inserted.";
248#endif
249 LOG(3, "DEBUG: InformationBoard got bondInserted signal for atom " << _id);
250 if (_atom != NULL) {
251 // find the new bond by simply taking the last added to the list
252 const BondList &ListOfBonds = _atom->getListOfBonds();
253 const bond::ptr bondref = ListOfBonds.back();
254
255 // check whether bond is already present, cause we get BondsAdded from both atoms
256 const bondId_t bondid =
257 std::make_pair( bondref->leftatom->getId(), bondref->rightatom->getId());
258 if (!bondids_lookup.left.count(bondid)) {
259 const QtObservedAtom::ptr leftatom = getObservedAtom(bondref->leftatom->getId());
260 ASSERT( leftatom,
261 "QtObservedInstanceBoard::recieveNotification() - QtObservedAtom leftatom to bond must exist.");
262 const QtObservedAtom::ptr rightatom = getObservedAtom(bondref->rightatom->getId());
263 ASSERT( rightatom,
264 "QtObservedInstanceBoard::recieveNotification() - QtObservedAtom leftatom to bond must exist.");
265 LOG(3, "DEBUG: InformationBoard initializes QtObservedBond for " << bondid);
266 QtObservedBond::ptr observedbond(
267 new QtObservedBond(bondid, bondref, leftatom, rightatom, *this));
268 const ObservedValue_Index_t index = observedbond->getIndex();
269 bondObservedValues.insert(index, observedbond);
270 bondids_lookup.left.insert( std::make_pair(bondid, index) );
271 emit bondInserted(observedbond);
272 }
273 } else {
274 ELOG(1, "QtObservedInstanceBoard got BondsAdded for unknown atom id " << _id);
275 }
276 break;
277 }
278 default:
279 ASSERT(0, "QtObservedInstanceBoard::recieveNotification() - we cannot get here.");
280 break;
281 }
282 } else {
283 ASSERT(0, "QtObservedInstanceBoard::recieveNotification() - notification from unknown source.");
284 }
285}
286
287const atomId_t QtObservedInstanceBoard::getAtomIdToIndex(ObservedValue_Index_t _id) const
288{
289 typename IdtoIndex_t<atomId_t>::right_const_iterator iter = atomids_lookup.right.find(_id);
290 ASSERT( iter != atomids_lookup.right.end(),
291 "QtObservedInstanceBoard::getAtomIdToIndex() - index "
292 +toString(_id)+" is unknown.");
293 return iter->second;
294}
295
296const QtObservedInstanceBoard::bondId_t
297QtObservedInstanceBoard::getBondIdToIndex(ObservedValue_Index_t _id) const
298{
299 typename IdtoIndex_t<bondId_t>::right_const_iterator iter = bondids_lookup.right.find(_id);
300 ASSERT( iter != bondids_lookup.right.end(),
301 "QtObservedInstanceBoard::getBondIdToIndex() - index "
302 +toString(_id)+" is unknown.");
303 return iter->second;
304}
305
306const moleculeId_t QtObservedInstanceBoard::getMoleculeIdToIndex(ObservedValue_Index_t _id) const
307{
308 typename IdtoIndex_t<moleculeId_t>::right_const_iterator iter = moleculeids_lookup.right.find(_id);
309 ASSERT( iter != moleculeids_lookup.right.end(),
310 "QtObservedInstanceBoard::getMoleculeIdToIndex() - index "
311 +toString(_id)+" is unknown.");
312 return iter->second;
313}
314
315void QtObservedInstanceBoard::atomcountsubjectKilled(ObservedValue_Index_t _id)
316{
317 LOG(3, "DEBUG: InstanceBoard emits atomRemoved for " << getAtomIdToIndex(_id));
318 emit atomRemoved(_id);
319}
320
321void QtObservedInstanceBoard::bondcountsubjectKilled(ObservedValue_Index_t _id)
322{
323 LOG(3, "DEBUG: InstanceBoard emits bondRemoved for " << getBondIdToIndex(_id));
324 emit bondRemoved(_id);
325}
326
327void QtObservedInstanceBoard::moleculecountsubjectKilled(ObservedValue_Index_t _id)
328{
329 LOG(3, "DEBUG: InstanceBoard emits moleculeRemoved for " << getMoleculeIdToIndex(_id));
330 emit moleculeRemoved(_id);
331}
332
333QtObservedAtom::ptr QtObservedInstanceBoard::getObservedAtom(const atomId_t _id)
334{
335 typename IdtoIndex_t<atomId_t>::left_iterator iter = atomids_lookup.left.find(_id);
336 if (iter == atomids_lookup.left.end())
337 return QtObservedAtom::ptr();
338 else
339 return atomObservedValues.get(iter->second);
340}
341
342QtObservedAtom::ptr QtObservedInstanceBoard::getObservedAtom(ObservedValue_Index_t _id)
343{
344 return atomObservedValues.get(_id);
345}
346
347QtObservedBond::ptr QtObservedInstanceBoard::getObservedBond(const bondId_t _id)
348{
349 typename IdtoIndex_t<bondId_t>::left_iterator iter = bondids_lookup.left.find(_id);
350 if (iter == bondids_lookup.left.end())
351 return QtObservedBond::ptr();
352 else
353 return bondObservedValues.get(iter->second);
354}
355
356QtObservedBond::ptr QtObservedInstanceBoard::getObservedBond(ObservedValue_Index_t _id)
357{
358 return bondObservedValues.get(_id);
359}
360
361QtObservedMolecule::ptr QtObservedInstanceBoard::getObservedMolecule(const moleculeId_t _id)
362{
363 typename IdtoIndex_t<moleculeId_t>::left_iterator iter = moleculeids_lookup.left.find(_id);
364 if (iter == moleculeids_lookup.left.end())
365 return QtObservedMolecule::ptr();
366 else
367 return moleculeObservedValues.get(iter->second);
368}
369
370QtObservedMolecule::ptr QtObservedInstanceBoard::getObservedMolecule(ObservedValue_Index_t _id)
371{
372 return moleculeObservedValues.get(_id);
373}
374
375void QtObservedInstanceBoard::markObservedAtomAsConnected(ObservedValue_Index_t _id)
376{
377 atomObservedValues.markObservedValuesAsConnected(_id);
378}
379
380void QtObservedInstanceBoard::markObservedAtomAsDisconnected(ObservedValue_Index_t _id)
381{
382 atomObservedValues.markObservedValuesAsDisconnected(_id);
383}
384
385void QtObservedInstanceBoard::markObservedAtomForErase(ObservedValue_Index_t _id)
386{
387 atomObservedValues.eraseObservedValues(_id);
388 atomids_lookup.right.erase(_id);
389}
390
391void QtObservedInstanceBoard::markObservedBondAsConnected(ObservedValue_Index_t _id)
392{
393 bondObservedValues.markObservedValuesAsConnected(_id);
394}
395
396void QtObservedInstanceBoard::markObservedBondAsDisconnected(ObservedValue_Index_t _id)
397{
398 bondObservedValues.markObservedValuesAsDisconnected(_id);
399}
400
401void QtObservedInstanceBoard::markObservedBondForErase(ObservedValue_Index_t _id)
402{
403 bondObservedValues.eraseObservedValues(_id);
404 bondids_lookup.right.erase(_id);
405}
406
407void QtObservedInstanceBoard::markObservedMoleculeAsConnected(ObservedValue_Index_t _id)
408{
409 moleculeObservedValues.markObservedValuesAsConnected(_id);
410}
411
412void QtObservedInstanceBoard::markObservedMoleculeAsDisconnected(ObservedValue_Index_t _id)
413{
414 moleculeObservedValues.markObservedValuesAsDisconnected(_id);
415}
416
417void QtObservedInstanceBoard::markObservedMoleculeForErase(ObservedValue_Index_t _id)
418{
419 moleculeObservedValues.eraseObservedValues(_id);
420 moleculeids_lookup.right.erase(_id);
421}
Note: See TracBrowser for help on using the repository browser.