source: src/UIElements/Qt4/InstanceBoard/QtObservedInstanceBoard.cpp@ 6d4925

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

FIX: QtObservedInstanceBoard needs to allow delayed atomInserted from World.

  • we may get the notification from molecule before we get the insertion from the World. Hence, we store any ids obtained from molecule insertion if the set of the new atom's observed values have not been generated yet.
  • Property mode set to 100644
File size: 15.8 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 moleculeObservedValues(
65 "molecule",
66 *this,
67 boost::bind(&QtObservedInstanceBoard::moleculecountsubjectKilled, this, _1)),
68 atomSubjectKilled(
69 boost::bind(&ObservedValuesContainer<QtObservedAtom, atomId_t>::countsubjectKilled,
70 boost::ref(atomObservedValues),
71 _1)),
72 moleculeSubjectKilled(
73 boost::bind(&ObservedValuesContainer<QtObservedMolecule, moleculeId_t>::countsubjectKilled,
74 boost::ref(moleculeObservedValues),
75 _1)),
76 lastremovedatom((atomId_t)-1),
77 lastremovedatomsmolecule( std::make_pair((moleculeId_t)-1,(atomId_t)-1) ),
78 lastremovedmolecule((moleculeId_t)-1)
79{
80 qRegisterMetaType<QtObservedAtom::ptr>("QtObservedAtom::ptr");
81 qRegisterMetaType<QtObservedMolecule::ptr>("QtObservedMolecule::ptr");
82
83 // be first (besides ObservedValues to know about new insertions)
84 World::getInstance().signOn(this, World::AtomInserted, GlobalObservableInfo::PriorityLevel(int(-10)));
85 World::getInstance().signOn(this, World::AtomRemoved, GlobalObservableInfo::PriorityLevel(int(-10)));
86 World::getInstance().signOn(this, World::MoleculeInserted, GlobalObservableInfo::PriorityLevel(int(-10)));
87 World::getInstance().signOn(this, World::MoleculeRemoved, GlobalObservableInfo::PriorityLevel(int(-10)));
88 WorldSignedOn = true;
89}
90
91QtObservedInstanceBoard::~QtObservedInstanceBoard()
92{
93 if (WorldSignedOn) {
94 World::getInstance().signOff(this, World::AtomInserted);
95 World::getInstance().signOff(this, World::AtomRemoved);
96 World::getInstance().signOff(this, World::MoleculeInserted);
97 World::getInstance().signOff(this, World::MoleculeRemoved);
98 }
99 // sign off from all remaining molecules and atoms
100 for (SignedOn_t::iterator iter = AtomSignedOn.begin(); !AtomSignedOn.empty();
101 iter = AtomSignedOn.begin()) {
102 (*iter)->signOff(this, atom::IndexChanged);
103 AtomSignedOn.erase(iter);
104 }
105
106 for (SignedOn_t::iterator iter = MoleculeSignedOn.begin(); !MoleculeSignedOn.empty();
107 iter = MoleculeSignedOn.begin()) {
108 (*iter)->signOff(this, molecule::IndexChanged);
109 (*iter)->signOff(this, molecule::AtomInserted);
110 (*iter)->signOff(this, molecule::AtomRemoved);
111 MoleculeSignedOn.erase(*iter); //erase all instances
112 }
113}
114
115void QtObservedInstanceBoard::update(Observable *publisher)
116{
117 ASSERT(0,
118 "QtObservedInstanceBoard::update() - we are not signed on to general updates.");
119}
120
121void QtObservedInstanceBoard::subjectKilled(Observable *publisher)
122{
123 SignedOn_t::iterator iter = AtomSignedOn.find(publisher);
124 if ( iter != AtomSignedOn.end()) {
125 LOG(3, "DEBUG: InstanceBoard got subjectKilled() from atom " << publisher);
126 AtomSignedOn.erase(iter);
127 } else {
128 iter = MoleculeSignedOn.find(publisher);
129 if ( iter != MoleculeSignedOn.end()) {
130 LOG(3, "DEBUG: InstanceBoard got subjectKilled() from molecule " << publisher);
131 MoleculeSignedOn.erase(iter);
132 } else {
133 ASSERT(0,
134 "QtObservedInstanceBoard::subjectKilled() - could not find signedOn for atom/molecule "+toString(publisher));
135 }
136 }
137}
138
139void QtObservedInstanceBoard::recieveNotification(Observable *publisher, Notification_ptr notification)
140{
141 if (static_cast<World *>(publisher) == World::getPointer()) {
142 switch (notification->getChannelNo()) {
143 case World::MoleculeInserted:
144 {
145 const moleculeId_t _id = const_cast<const World &>(World::getInstance()).lastChangedMolId();
146 #ifdef LOG_OBSERVER
147 observerLog().addMessage() << "++ Observer " << observerLog().getName(static_cast<Observer *>(this)) << " received notification that molecule "+toString(_id)+" has been inserted.";
148 #endif
149 LOG(3, "DEBUG: InformationBoard got moleculeInserted signal for molecule " << _id);
150 const molecule * const _molecule = const_cast<const World &>(World::getInstance()).
151 getMolecule(MoleculeById(_id));
152 if (_molecule != NULL) {
153 ObservedValues_t ObservedValues(QtObservedMolecule::MAX_ObservedTypes);
154 LOG(3, "DEBUG: InformationBoard initializes ObservedValues for molecule " << _id);
155 QtObservedMolecule::initObservedValues(
156 ObservedValues,
157 _id,
158 _molecule,
159 moleculeSubjectKilled);
160 QtObservedMolecule::ptr observedmolecule(new QtObservedMolecule(ObservedValues, *this));
161#ifndef NDEBUG
162 bool status =
163#endif
164 moleculeObservedValues.insert(_id, observedmolecule);
165 ASSERT( status,
166 "QtObservedInstanceBoard::recieveNotification() - could not insert ObservedMolecule for"
167 +toString(_id)+".");
168 // we need to check for index changes
169 LOG(3, "DEBUG: InformationBoard signOn()s to molecule " << _id);
170 _molecule->signOn(this, molecule::IndexChanged);
171 MoleculeSignedOn.insert( static_cast<Observable *>(const_cast<molecule *>(_molecule)) );
172 _molecule->signOn(this, molecule::AtomInserted);
173 MoleculeSignedOn.insert( static_cast<Observable *>(const_cast<molecule *>(_molecule)) );
174 _molecule->signOn(this, molecule::AtomRemoved);
175 MoleculeSignedOn.insert( static_cast<Observable *>(const_cast<molecule *>(_molecule)) );
176
177 emit moleculeInserted(_id);
178 } else {
179 ELOG(1, "QtObservedInstanceBoard got MoleculeInserted for unknown molecule id " << _id);
180 }
181 break;
182 }
183 case World::MoleculeRemoved:
184 {
185 const moleculeId_t _id = const_cast<const World &>(World::getInstance()).lastChangedMolId();
186 LOG(3, "DEBUG: InformationBoard got MoleculeRemoved signal for molecule " << _id);
187 // note down such that ObservedValues are simply dropped
188 lastremovedmolecule = _id;
189 break;
190 }
191 case World::AtomInserted:
192 {
193 const atomId_t _id = const_cast<const World &>(World::getInstance()).lastChangedAtomId();
194 #ifdef LOG_OBSERVER
195 observerLog().addMessage() << "++ Observer " << observerLog().getName(static_cast<Observer *>(this)) << " received notification that atom "+toString(_id)+" has been inserted.";
196 #endif
197 LOG(3, "DEBUG: InformationBoard got atomInserted signal for atom " << _id);
198 const atom * const _atom = const_cast<const World &>(World::getInstance()).
199 getAtom(AtomById(_id));
200 if (_atom!= NULL) {
201 ObservedValues_t ObservedValues(QtObservedAtom::MAX_ObservedTypes);
202 LOG(3, "DEBUG: InformationBoard initializes ObservedValues for atom " << _id);
203 QtObservedAtom::initObservedValues(
204 ObservedValues,
205 _id,
206 _atom,
207 atomSubjectKilled);
208 QtObservedAtom::ptr observedatom(new QtObservedAtom(ObservedValues, *this));
209#ifndef NDEBUG
210 bool status =
211#endif
212 atomObservedValues.insert(_id, observedatom);
213 ASSERT( status,
214 "QtObservedInstanceBoard::recieveNotification() - could not insert ObservedValues for"
215 +toString(_id)+".");
216 // we need to check for index changes
217 LOG(3, "DEBUG: InformationBoard signOn()s to atom " << _id);
218 _atom->signOn(this, atom::IndexChanged);
219 AtomSignedOn.insert( static_cast<Observable *>(const_cast<atom *>(_atom)) );
220 emit atomInserted(observedatom->getAtomMoleculeIndex(), observedatom->getAtomIndex());
221 } else {
222 ELOG(1, "QtObservedInstanceBoard got AtomInserted for unknown atom id " << _id);
223 }
224 break;
225 }
226 case World::AtomRemoved:
227 {
228 const atomId_t _id = const_cast<const World &>(World::getInstance()).lastChangedAtomId();
229 LOG(3, "DEBUG: InformationBoard got AtomRemoved signal for atom " << _id);
230 // note down such that ObservedValues are simply dropped
231 lastremovedatom = _id;
232 break;
233 }
234 default:
235 ASSERT(0, "QtObservedInstanceBoard::recieveNotification() - we cannot get here for World.");
236 break;
237 }
238 } else if (dynamic_cast<molecule *>(publisher) != NULL) {
239 const moleculeId_t molid = const_cast<const World &>(World::getInstance()).lastChangedMolId();
240 switch (notification->getChannelNo()) {
241 case molecule::AtomInserted:
242 {
243 const molecule * const _molecule = const_cast<const World &>(World::getInstance()).
244 getMolecule(MoleculeById(molid));
245 if (_molecule != NULL) {
246 const atomId_t atomid = const_cast<const molecule *>(_molecule)->lastChangedAtomId();
247 LOG(3, "DEBUG: InformationBoard got AtomInserted signal for atom "
248 << atomid << " from molecule " << molid);
249 // check whether atom's observedvalues are present
250 ASSERT( atomObservedValues.isPresent(atomid),
251 "QtObservedInstanceBoard::recieveNotification() - ObservedValues for atom "
252 +toString(atomid)+" are not present yet.");
253 // and emit
254 emit atomInserted(molid, atomid);
255 } else {
256 ELOG(2, "QtObservedInstanceBoard::recieveNotification() - molecule "
257 << molid << " has disappeared.");
258 }
259 break;
260 }
261 case molecule::AtomRemoved:
262 {
263 const molecule * const _molecule = const_cast<const World &>(World::getInstance()).
264 getMolecule(MoleculeById(molid));
265 if (_molecule != NULL) {
266 const atomId_t atomid = const_cast<const molecule *>(_molecule)->lastChangedAtomId();
267 LOG(3, "DEBUG: InformationBoard got AtomRemoved signal for atom "
268 << atomid << " from molecule " << molid);
269 lastremovedatomsmolecule = std::make_pair(molid, atomid);
270 }
271 break;
272 }
273 case molecule::IndexChanged:
274 {
275 // molecule has changed its index
276 const moleculeId_t newmoleculeId = dynamic_cast<molecule *>(publisher)->getId();
277 LOG(3, "DEBUG: InformationBoard got IndexChanged from molecule " << molid << " to " << newmoleculeId);
278#ifndef NDEBUG
279 bool status =
280#endif
281 moleculeObservedValues.changeIdentifier(molid, newmoleculeId);
282 ASSERT( status,
283 "QtObservedInstanceBoard::recieveNotification() - cannot change molecule's id "
284 +toString(molid)+" "+toString(newmoleculeId)+" in moleculeObservedValues.");
285 // no need update SignedOn, ref does not change
286 emit moleculeIndexChanged(molid, newmoleculeId);
287 break;
288 }
289 default:
290 ASSERT(0, "QtObservedInstanceBoard::recieveNotification() - we cannot get here.");
291 break;
292 }
293 } else if (dynamic_cast<atom *>(publisher) != NULL) {
294 const atomId_t oldatomId = const_cast<const World &>(World::getInstance()).lastChangedAtomId();
295 switch (notification->getChannelNo()) {
296 case AtomObservable::IndexChanged:
297 {
298 const atomId_t newatomId = dynamic_cast<atom *>(publisher)->getId();
299 LOG(3, "DEBUG: InformationBoard got IndexChanged from atom " << oldatomId << " to " << newatomId);
300#ifndef NDEBUG
301 bool status =
302#endif
303 atomObservedValues.changeIdentifier(oldatomId, newatomId);
304 ASSERT( status,
305 "QtObservedInstanceBoard::recieveNotification() - cannot change atom's id "
306 +toString(oldatomId)+" "+toString(newatomId)+" in atomObservedValues.");
307 // changed insertion delayed
308 atomInsertionDelayed_t::iterator iter = atomInsertionDelayed.find(oldatomId);
309 if (iter != atomInsertionDelayed.end()) {
310 const moleculeId_t molid = iter->second;
311 atomInsertionDelayed.erase(iter);
312#ifndef NDEBUG
313 std::pair<atomInsertionDelayed_t::iterator, bool> inserter =
314#endif
315 atomInsertionDelayed.insert( std::make_pair(newatomId, molid) );
316 ASSERT( inserter.second,
317 "QtObservedInstanceBoard::recieveNotification() - id "
318 +toString(newatomId)+" already present in atomInsertionDelayed.");
319 }
320 // no need update SignedOn, ref does not change
321 emit atomIndexChanged(oldatomId, newatomId);
322 break;
323 }
324 default:
325 ASSERT(0, "QtObservedInstanceBoard::recieveNotification() - we cannot get here.");
326 break;
327 }
328 } else {
329 ASSERT(0, "QtObservedInstanceBoard::recieveNotification() - notification from unknown source.");
330 }
331}
332
333void QtObservedInstanceBoard::atomcountsubjectKilled(const atomId_t _atomid)
334{
335 if ((_atomid == lastremovedatomsmolecule.second) && (_atomid == lastremovedatom)) {
336 LOG(3, "DEBUG: InstanceBoard emits atomRemoved for " << _atomid);
337 emit atomRemoved(lastremovedatomsmolecule.first, lastremovedatomsmolecule.second);
338 } else
339 ELOG(2, "QtObservedInstanceBoard::atomcountsubjectKilled() - id " << _atomid
340 << " not fitting with " << lastremovedatomsmolecule << " or " << lastremovedatom);
341}
342
343void QtObservedInstanceBoard::moleculecountsubjectKilled(const moleculeId_t _molid)
344{
345 if (lastremovedmolecule == _molid) {
346 LOG(3, "DEBUG: InstanceBoard emits moleculeRemoved for " << _molid);
347 emit moleculeRemoved(_molid);
348 } else
349 ELOG(2, "QtObservedInstanceBoard::moleculecountsubjectKilled() - id " << _molid
350 << " not fitting with " << lastremovedmolecule);
351}
352
353QtObservedAtom::ptr QtObservedInstanceBoard::getObservedAtom(const atomId_t _id)
354{
355 return atomObservedValues.get(_id);
356}
357
358QtObservedMolecule::ptr QtObservedInstanceBoard::getObservedMolecule(const moleculeId_t _id)
359{
360 return moleculeObservedValues.get(_id);
361}
362
363void QtObservedInstanceBoard::markObservedAtomAsConnected(const atomId_t _id)
364{
365 atomObservedValues.markObservedValuesAsConnected(_id);
366}
367
368void QtObservedInstanceBoard::markObservedAtomAsDisconnected(const atomId_t _id)
369{
370 atomObservedValues.markObservedValuesAsDisconnected(_id);
371}
372
373void QtObservedInstanceBoard::markObservedAtomForErase(const atomId_t _id)
374{
375 atomObservedValues.eraseObservedValues(_id);
376}
377
378void QtObservedInstanceBoard::markObservedMoleculeAsConnected(const moleculeId_t _id)
379{
380 moleculeObservedValues.markObservedValuesAsConnected(_id);
381}
382
383void QtObservedInstanceBoard::markObservedMoleculeAsDisconnected(const moleculeId_t _id)
384{
385 moleculeObservedValues.markObservedValuesAsDisconnected(_id);
386}
387
388void QtObservedInstanceBoard::markObservedMoleculeForErase(const moleculeId_t _id)
389{
390 moleculeObservedValues.eraseObservedValues(_id);
391}
Note: See TracBrowser for help on using the repository browser.