source: src/UIElements/Qt4/InstanceBoard/QtObservedMolecule.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 4e6ffe, checked in by Frederik Heber <heber@…>, 9 years ago

FIX: ObservedValue need to be removed with a bit of delay.

  • Property mode set to 100644
File size: 17.5 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 * QtObservedMolecule.cpp
25 *
26 * Created on: Oct 28, 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 "QtObservedMolecule.hpp"
37
38#include "UIElements/Qt4/InstanceBoard/QtObservedInstanceBoard.hpp"
39
40#include "CodePatterns/MemDebug.hpp"
41#include "CodePatterns/Assert.hpp"
42#include "CodePatterns/Log.hpp"
43
44#include <boost/assign.hpp>
45#include <boost/bind.hpp>
46
47#include "UIElements/Qt4/InstanceBoard/ObservedValue_wCallback.hpp"
48#include "UIElements/Qt4/InstanceBoard/ObservedValue_UpdateAtoms.hpp"
49
50#include "Atom/atom.hpp"
51#include "Descriptors/MoleculeIdDescriptor.hpp"
52#include "World.hpp"
53
54using namespace boost::assign;
55
56static const Observable::channels_t getAllObservedChannels()
57{
58 Observable::channels_t channels;
59 channels +=
60 molecule::AtomInserted,
61 molecule::AtomMoved,
62 molecule::AtomRemoved,
63 molecule::FormulaChanged,
64 molecule::IndexChanged,
65 molecule::MoleculeNameChanged,
66 molecule::BoundingBoxChanged;
67 return channels;
68}
69
70static const Observable::channels_t getAllAtomCountChannels()
71{
72 Observable::channels_t channels;
73 channels +=
74 molecule::AtomInserted,
75 molecule::AtomRemoved;
76 return channels;
77}
78
79static const Observable::channels_t getAllCenterChannels()
80{
81 Observable::channels_t channels;
82 channels +=
83 molecule::AtomInserted,
84 molecule::AtomMoved,
85 molecule::AtomRemoved;
86 return channels;
87}
88
89// static instances
90const Observable::channels_t QtObservedMolecule::AtomCountChannels(getAllAtomCountChannels());
91const Observable::channels_t QtObservedMolecule::BondCountChannels(getAllAtomCountChannels());
92const Observable::channels_t QtObservedMolecule::BoundingBoxChannels(1, molecule::BoundingBoxChanged);
93const Observable::channels_t QtObservedMolecule::FormulaStringChannels(1, molecule::FormulaChanged);
94const Observable::channels_t QtObservedMolecule::CenterChannels(getAllCenterChannels());
95const Observable::channels_t QtObservedMolecule::IndexChannels(1, molecule::IndexChanged);
96const Observable::channels_t QtObservedMolecule::NameChannels(1, molecule::MoleculeNameChanged);
97const Observable::channels_t QtObservedMolecule::NonHydrogenCountChannels(1, molecule::FormulaChanged);
98
99QtObservedMolecule::QtObservedMolecule(
100 const ObservedValues_t &_ObservedValues,
101 QtObservedInstanceBoard &_board,
102 QWidget * _parent) :
103 QWidget(_parent),
104 Observer("QtObservedMolecule"),
105 subjectKilledCount(0),
106 AllsignedOnChannels(getAllObservedChannels().size()),
107 signedOffChannels(0),
108 owner(NULL),
109 board(_board),
110 BoardIsGone(false),
111 ObservedValues(_ObservedValues)
112{
113 // activating Observer is done by ObservedValueContainer when it's prepared
114}
115
116QtObservedMolecule::~QtObservedMolecule()
117{
118 boost::any_cast<ObservedValue_wCallback<moleculeId_t> *>(ObservedValues[MolIndex])->noteCallBackIsGone();
119 boost::any_cast<ObservedValue_wCallback<int, moleculeId_t> *>(ObservedValues[AtomCount])->noteCallBackIsGone();
120 boost::any_cast<ObservedValue_wCallback<int, moleculeId_t> *>(ObservedValues[BondCount])->noteCallBackIsGone();
121 boost::any_cast<ObservedValue_wCallback<molecule::BoundingBoxInfo, moleculeId_t> *>(ObservedValues[BoundingBox])->noteCallBackIsGone();
122 boost::any_cast<ObservedValue_wCallback<std::string, moleculeId_t> *>(ObservedValues[FormulaString])->noteCallBackIsGone();
123 boost::any_cast<ObservedValue_wCallback<Vector, moleculeId_t> *>(ObservedValues[MolCenter])->noteCallBackIsGone();
124 boost::any_cast<ObservedValue_wCallback<std::string, moleculeId_t> *>(ObservedValues[MolName])->noteCallBackIsGone();
125 boost::any_cast<ObservedValue_wCallback<int, moleculeId_t> *>(ObservedValues[NonHydrogenCount])->noteCallBackIsGone();
126
127 deactivateObserver();
128}
129
130void QtObservedMolecule::deactivateObserver()
131{
132 if (owner != NULL) {
133 Observable::channels_t channels = getAllObservedChannels();
134 for (Observable::channels_t::const_iterator iter = channels.begin();
135 iter != channels.end(); ++iter)
136 owner->signOff(this, *iter);
137 owner = NULL;
138 signedOffChannels = AllsignedOnChannels;
139 if (!BoardIsGone)
140 board.markObservedMoleculeAsDisconnected(getMolIndex());
141 }
142}
143
144void QtObservedMolecule::activateObserver()
145{
146 // sign on as observer (obtain non-const instance before)
147 const molecule * const _molecule = getMolecule(getMolIndex());
148 if (_molecule != NULL) {
149 Observable::channels_t channels = getAllObservedChannels();
150 owner = static_cast<const Observable *>(_molecule);
151 for (Observable::channels_t::const_iterator iter = channels.begin();
152 iter != channels.end(); ++iter)
153 owner->signOn(this, *iter);
154 if (!BoardIsGone)
155 board.markObservedMoleculeAsConnected(getMolIndex());
156 } else
157 signedOffChannels = AllsignedOnChannels;
158}
159
160void QtObservedMolecule::update(Observable *publisher)
161{
162 ASSERT(0,
163 "QtObservedMolecule::update() - general update from unexpected source.");
164}
165
166void QtObservedMolecule::subjectKilled(Observable *publisher)
167{
168 ++signedOffChannels;
169
170 if (signedOffChannels == AllsignedOnChannels) {
171 // remove owner: no more signOff needed
172 owner = NULL;
173
174 emit moleculeRemoved();
175
176 if (!BoardIsGone) {
177 board.markObservedMoleculeAsDisconnected(getMolIndex());
178 board.markObservedMoleculeForErase(getMolIndex());
179 }
180 }
181}
182
183void QtObservedMolecule::recieveNotification(Observable *publisher, Notification_ptr notification)
184{
185 const molecule * const _molecule = getMolecule(getMolIndex());
186 // when molecule is NULL we will soon get destroyed anyway
187 if (_molecule == NULL)
188 return;
189 if (publisher == dynamic_cast<const Observable*>(_molecule)){
190 // notification from atom
191#ifdef LOG_OBSERVER
192 observerLog().addMessage() << "++ Update of Observer "<< observerLog().getName(static_cast<Observer *>(this))
193 << " received notification from molecule " << getMolIndex() << " for channel "
194 << notification->getChannelNo() << ".";
195#endif
196 switch (notification->getChannelNo()) {
197 case molecule::AtomInserted:
198 {
199 const atomId_t _id = _molecule->lastChangedAtomId();
200 emit atomcountChanged();
201 emit atomInserted(_id);
202 emit bondcountChanged();
203 emit boundingboxChanged();
204 emit centerChanged();
205 emit tesselationhullChanged();
206 break;
207 }
208 case molecule::AtomMoved:
209 {
210 emit boundingboxChanged();
211 emit centerChanged();
212 emit tesselationhullChanged();
213 break;
214 }
215 case molecule::AtomRemoved:
216 {
217 const atomId_t _id = _molecule->lastChangedAtomId();
218 emit atomcountChanged();
219 emit atomRemoved(_id);
220 emit bondcountChanged();
221 emit boundingboxChanged();
222 emit centerChanged();
223 emit tesselationhullChanged();
224 break;
225 }
226 case molecule::BoundingBoxChanged:
227 {
228 #ifdef LOG_OBSERVER
229 observerLog().addMessage() << "++ Observer " << observerLog().getName(static_cast<Observer *>(this)) << " received notification that bounding box has changed.";
230 #endif
231 emit tesselationhullChanged();
232 emit boundingboxChanged();
233 break;
234 }
235 case molecule::FormulaChanged:
236 {
237 emit formulaChanged();
238 emit nononhydrogenChanged();
239 break;
240 }
241 case molecule::IndexChanged:
242 {
243 #ifdef LOG_OBSERVER
244 const atomId_t _id = _molecule->lastChangedAtomId();
245 observerLog().addMessage() << "++ Observer " << observerLog().getName(static_cast<Observer *>(this)) << " received notification that atom "+toString(_id)+"'s index has changed.";
246 #endif
247 emit indexChanged();
248 break;
249 }
250 case molecule::MoleculeNameChanged:
251 {
252 #ifdef LOG_OBSERVER
253 observerLog().addMessage() << "++ Observer " << observerLog().getName(static_cast<Observer *>(this)) << " received notification that name has changed.";
254 #endif
255 emit nameChanged();
256 break;
257 }
258 default:
259 break;
260 }
261 }
262}
263
264const molecule * const QtObservedMolecule::getMolecule(const moleculeId_t _id)
265{
266 const molecule * const mol = const_cast<const World &>(World::getInstance()).
267 getMolecule(MoleculeById(_id));
268 return mol;
269}
270
271static molecule::BoundingBoxInfo initBoundingBox()
272{
273 molecule::BoundingBoxInfo info;
274 info.position = zeroVec;
275 info.radius = 0.;
276 return info;
277}
278
279void QtObservedMolecule::initObservedValues(
280 ObservedValues_t &_ObservedValues,
281 const moleculeId_t _molid,
282 const molecule * const _molref,
283 const boost::function<void(const moleculeId_t)> &_subjectKilled)
284{
285 /* This is an old note from when the code was still part of cstor's initializer body.
286 * TODO: Probably does not apply anymore but has not yet been tested.
287 *
288 * We must not use boost::cref(this) as "this" has not been properly constructed and seemingly
289 * boost::cref tries to do some magic to grasp the inheritance hierarchy which fails because
290 * the class has not been fully constructed yet. "This" itself seems to be working fine.
291 */
292
293 ASSERT( _ObservedValues.size() == MAX_ObservedTypes,
294 "QtObservedMolecule::initObservedValues() - given ObservedValues has not correct size.");
295
296 // fill ObservedValues: index first
297 const boost::function<moleculeId_t ()> MolIndexUpdater(
298 boost::bind(&QtObservedMolecule::updateIndex));
299
300 ObservedValue_wCallback<moleculeId_t> * const IndexObservable =
301 new ObservedValue_wCallback<moleculeId_t>(
302 _molref,
303 MolIndexUpdater,
304 "MoleculeIndex_"+toString(_molid),
305 _molid,
306 IndexChannels,
307 _subjectKilled);
308 _ObservedValues[MolIndex] = IndexObservable;
309
310 const boost::function<const moleculeId_t ()> MolIndexGetter =
311 boost::bind(&ObservedValue_wCallback<moleculeId_t>::get,
312 IndexObservable);
313
314 // fill ObservedValues: then all the other that need index
315 const boost::function<int ()> AtomCountUpdater(
316 boost::bind(&QtObservedMolecule::updateAtomCount, MolIndexGetter));
317 const boost::function<int ()> BondCountUpdater(
318 boost::bind(&QtObservedMolecule::updateBondCount, MolIndexGetter));
319 const boost::function<Vector ()> MolCenterUpdater(
320 boost::bind(&QtObservedMolecule::updateCenter, MolIndexGetter));
321 const boost::function<std::string ()> MolFormulaUpdater(
322 boost::bind(&QtObservedMolecule::updateFormulaString, MolIndexGetter));
323 const boost::function<std::string ()> MolNameUpdater(
324 boost::bind(&QtObservedMolecule::updateName, MolIndexGetter));
325 const boost::function<int ()> NonHydrogenCountUpdater(
326 boost::bind(&QtObservedMolecule::updateNonHydrogenCount, MolIndexGetter));
327 const boost::function<molecule::BoundingBoxInfo ()> BoundingBoxUpdater(
328 boost::bind(&QtObservedMolecule::updateBoundingBox, MolIndexGetter));
329
330 _ObservedValues[AtomCount] = new ObservedValue_wCallback<int, moleculeId_t>(
331 _molref,
332 AtomCountUpdater,
333 "MoleculeAtomCount_"+toString(_molid),
334 AtomCountUpdater(),
335 AtomCountChannels,
336 _subjectKilled,
337 MolIndexGetter);
338 _ObservedValues[BondCount] = new ObservedValue_wCallback<int, moleculeId_t>(
339 _molref,
340 BondCountUpdater,
341 "MoleculeBondCount_"+toString(_molid),
342 BondCountUpdater(),
343 BondCountChannels,
344 _subjectKilled,
345 MolIndexGetter);
346 _ObservedValues[BoundingBox] = new ObservedValue_wCallback<molecule::BoundingBoxInfo, moleculeId_t>(
347 _molref,
348 BoundingBoxUpdater,
349 "MoleculeBoundingBox_"+toString(_molid),
350 initBoundingBox(),
351 BoundingBoxChannels,
352 _subjectKilled,
353 MolIndexGetter);
354 _ObservedValues[FormulaString] = new ObservedValue_wCallback<std::string, moleculeId_t>(
355 _molref,
356 MolFormulaUpdater,
357 "MoleculeFormula_"+toString(_molid),
358 MolFormulaUpdater(),
359 FormulaStringChannels,
360 _subjectKilled,
361 MolIndexGetter);
362 _ObservedValues[MolCenter] = new ObservedValue_wCallback<Vector, moleculeId_t>(
363 _molref,
364 MolCenterUpdater,
365 "MoleculeCenter_"+toString(_molid),
366 MolCenterUpdater(),
367 CenterChannels,
368 _subjectKilled,
369 MolIndexGetter);
370 _ObservedValues[MolName] = new ObservedValue_wCallback<std::string, moleculeId_t>(
371 _molref,
372 MolNameUpdater,
373 "MoleculeName_"+toString(_molid),
374 MolNameUpdater(),
375 NameChannels,
376 _subjectKilled,
377 MolIndexGetter);
378 _ObservedValues[NonHydrogenCount] = new ObservedValue_wCallback<int, moleculeId_t>(
379 _molref,
380 NonHydrogenCountUpdater,
381 "MoleculeNonHydrogenCount_"+toString(_molid),
382 NonHydrogenCountUpdater(),
383 NonHydrogenCountChannels,
384 _subjectKilled,
385 MolIndexGetter);
386}
387
388void QtObservedMolecule::destroyObservedValues(
389 std::vector<boost::any> &_ObservedValues)
390{
391 delete boost::any_cast<ObservedValue_wCallback<moleculeId_t> *>(_ObservedValues[MolIndex]);
392 delete boost::any_cast<ObservedValue_wCallback<int, moleculeId_t> *>(_ObservedValues[AtomCount]);
393 delete boost::any_cast<ObservedValue_wCallback<int, moleculeId_t> *>(_ObservedValues[BondCount]);
394 delete boost::any_cast<ObservedValue_wCallback<molecule::BoundingBoxInfo, moleculeId_t> *>(_ObservedValues[BoundingBox]);
395 delete boost::any_cast<ObservedValue_wCallback<std::string, moleculeId_t> *>(_ObservedValues[FormulaString]);
396 delete boost::any_cast<ObservedValue_wCallback<Vector, moleculeId_t> *>(_ObservedValues[MolCenter]);
397 delete boost::any_cast<ObservedValue_wCallback<std::string, moleculeId_t> *>(_ObservedValues[MolName]);
398 delete boost::any_cast<ObservedValue_wCallback<int, moleculeId_t> *>(_ObservedValues[NonHydrogenCount]);
399 _ObservedValues.clear();
400}
401
402int QtObservedMolecule::updateAtomCount(
403 const boost::function<const moleculeId_t ()> &_getMolIndex)
404{
405 const molecule * const mol = getMolecule(_getMolIndex());
406 if (mol != NULL)
407 return mol->getAtomCount();
408 else
409 return (int)0;
410}
411
412int QtObservedMolecule::updateBondCount(
413 const boost::function<const moleculeId_t ()> &_getMolIndex)
414{
415 const molecule * const mol = getMolecule(_getMolIndex());
416 if (mol != NULL)
417 return mol->getBondCount();
418 else
419 return (int)0;
420}
421
422molecule::BoundingBoxInfo QtObservedMolecule::updateBoundingBox(
423 const boost::function<const moleculeId_t ()> &_getMolIndex)
424{
425 const molecule * const mol = getMolecule(_getMolIndex());
426 if (mol != NULL)
427 return mol->getBoundingBox();
428 else
429 return molecule::BoundingBoxInfo();
430}
431
432std::string QtObservedMolecule::updateFormulaString(
433 const boost::function<const moleculeId_t ()> &_getMolIndex)
434{
435 const molecule * const mol = getMolecule(_getMolIndex());
436 if (mol != NULL)
437 return mol->getFormula().toString();
438 else
439 return std::string("");
440}
441
442Vector QtObservedMolecule::updateCenter(
443 const boost::function<const moleculeId_t ()> &_getMolIndex)
444{
445 const molecule * const mol = getMolecule(_getMolIndex());
446 if (mol != NULL)
447 return mol->DetermineCenterOfAll();
448 else
449 return zeroVec;
450}
451
452moleculeId_t QtObservedMolecule::updateIndex()
453{
454 return const_cast<const World &>(World::getInstance()).lastChangedMolId();
455}
456
457std::string QtObservedMolecule::updateName(
458 const boost::function<const moleculeId_t ()> &_getMolIndex)
459{
460 const molecule * const mol = getMolecule(_getMolIndex());
461 if (mol != NULL)
462 return mol->getName();
463 else
464 return std::string("");
465}
466
467int QtObservedMolecule::updateNonHydrogenCount(
468 const boost::function<const moleculeId_t ()> &_getMolIndex)
469{
470 const molecule * const mol = getMolecule(_getMolIndex());
471 if (mol != NULL)
472 return mol->getNoNonHydrogen();
473 else
474 return (int)0;
475}
476
477const int& QtObservedMolecule::getAtomCount() const
478{
479 return boost::any_cast<ObservedValue_wCallback<int, moleculeId_t> *>(ObservedValues[AtomCount])->get();
480}
481
482const int& QtObservedMolecule::getBondCount() const
483{
484 return boost::any_cast<ObservedValue_wCallback<int, moleculeId_t> *>(ObservedValues[BondCount])->get();
485}
486
487const std::string& QtObservedMolecule::getMolFormula() const
488{
489 return boost::any_cast<ObservedValue_wCallback<std::string, moleculeId_t> *>(ObservedValues[FormulaString])->get();
490}
491
492const Vector& QtObservedMolecule::getMolCenter() const
493{
494 return boost::any_cast<ObservedValue_wCallback<Vector, moleculeId_t> *>(ObservedValues[MolCenter])->get();
495}
496
497const moleculeId_t& QtObservedMolecule::getMolIndex() const
498{
499 return boost::any_cast<ObservedValue_wCallback<moleculeId_t> *>(ObservedValues[MolIndex])->get();
500}
501
502const std::string& QtObservedMolecule::getMolName() const
503{
504 return boost::any_cast<ObservedValue_wCallback<std::string, moleculeId_t> *>(ObservedValues[MolName])->get();
505}
506
507const int& QtObservedMolecule::getNonHydrogenCount() const
508{
509 return boost::any_cast<ObservedValue_wCallback<int, moleculeId_t> *>(ObservedValues[NonHydrogenCount])->get();
510}
511
512const molecule::BoundingBoxInfo& QtObservedMolecule::getBoundingBox() const
513{
514 return boost::any_cast<ObservedValue_wCallback<molecule::BoundingBoxInfo, moleculeId_t> *>(ObservedValues[BoundingBox])->get();
515}
Note: See TracBrowser for help on using the repository browser.