source: src/UIElements/Qt4/InstanceBoard/QtObservedMolecule.cpp@ b2c2e4

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 Candidate_v1.7.0 Candidate_v1.7.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 b2c2e4 was 3b9aa1, checked in by Frederik Heber <heber@…>, 10 years ago

FIX: All ObservedValue getters now return const references.

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