source: src/UIElements/Qt4/InstanceBoard/QtObservedAtom.cpp@ 50246c

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 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 50246c was 273c8a, checked in by Frederik Heber <heber@…>, 10 years ago

QtObservedAtom only offers direct access to associated const QtObservedMolecule ref.

  • the molecule index is not part of the atom's state, hence cannot be directly observed. The only thing we observe is the association to the molecule. For this a O/O-signal is available and we may actively change the ref when getting this signal without breaking anything as it occurs in the same thread, hence the board can be safely accessed.
  • QtObservedBond now needs to access mol index through the molecule ref.
  • QtInfoBox may now conveniently access atom'smol ref directly.
  • FIX: Removed static QtObservedBond::getMolecule().
  • Property mode set to 100644
File size: 14.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 * QtObservedAtom.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 "QtObservedAtom.hpp"
37
38#include "UIElements/Qt4/InstanceBoard/QtObservedInstanceBoard.hpp"
39
40#include "CodePatterns/MemDebug.hpp"
41
42#include <boost/assign.hpp>
43
44#include "Atom/atom.hpp"
45#include "Bond/bond.hpp"
46#include "Descriptors/AtomIdDescriptor.hpp"
47#include "Element/element.hpp"
48#include "World.hpp"
49
50#include "UIElements/Qt4/InstanceBoard/ObservedValue_wCallback.hpp"
51
52using namespace boost::assign;
53
54static const Observable::channels_t getAtomBondsChannels()
55{
56 Observable::channels_t channels;
57 channels += AtomObservable::BondsAdded, AtomObservable::BondsRemoved;
58 return channels;
59}
60
61static const Observable::channels_t getAllObservedChannels()
62{
63 Observable::channels_t channels;
64 channels +=
65 AtomObservable::IndexChanged,
66 AtomObservable::BondsAdded,
67 AtomObservable::BondsRemoved,
68 AtomObservable::MoleculeChanged,
69 AtomObservable::NameChanged,
70 AtomObservable::ElementChanged,
71 AtomObservable::PositionChanged,
72 AtomObservable::SelectionChanged;
73 return channels;
74}
75
76// static entities
77const Observable::channels_t
78QtObservedAtom::AtomIndexChannels(1, AtomObservable::IndexChanged);
79const Observable::channels_t
80QtObservedAtom::AtomBondsChannels(getAtomBondsChannels());
81const Observable::channels_t
82QtObservedAtom::AtomElementChannels(1, AtomObservable::ElementChanged);
83const Observable::channels_t
84QtObservedAtom::MoleculeChangedChannels(1, AtomObservable::MoleculeChanged);
85const Observable::channels_t
86QtObservedAtom::AtomNameChannels(1, AtomObservable::NameChanged);
87const Observable::channels_t
88QtObservedAtom::AtomPositionChannels(1, AtomObservable::PositionChanged);
89const Observable::channels_t
90QtObservedAtom::AtomSelectedChannels(1, AtomObservable::SelectionChanged);
91
92QtObservedAtom::QtObservedAtom(
93 const atomId_t _id,
94 const atom * const _atom,
95 QtObservedInstanceBoard &_board,
96 QWidget * _parent) :
97 QWidget(_parent),
98 Observer("QtObservedAtom"),
99 subjectKilledCount(0),
100 AllsignedOnChannels(getAllObservedChannels().size()),
101 signedOffChannels(0),
102 owner(NULL),
103 oldId(_id),
104 board(_board),
105 BoardIsGone(false),
106 ObservedValues(QtObservedAtom::MAX_ObservedTypes)
107{
108 boost::function<void ()> atomSubjectKilled(
109 boost::bind(&QtObservedAtom::countValuesSubjectKilled,
110 boost::ref(*this),
111 boost::bind(&QtObservedAtom::getIndex, boost::ref(*this))));
112 initObservedValues( ObservedValues, _id, _atom, atomSubjectKilled);
113
114 // activating Observer is done by ObservedValueContainer when it's inserted
115}
116
117QtObservedAtom::~QtObservedAtom()
118{
119 boost::any_cast<ObservedValue_wCallback<atomId_t, ObservedValue_Index_t> *>(ObservedValues[AtomIndex])->noteCallBackIsGone();
120 boost::any_cast<ObservedValue_wCallback<ListOfBonds_t, ObservedValue_Index_t> *>(ObservedValues[AtomBonds])->noteCallBackIsGone();
121 boost::any_cast<ObservedValue_wCallback<atomicNumber_t, ObservedValue_Index_t> *>(ObservedValues[AtomElement])->noteCallBackIsGone();
122 boost::any_cast<ObservedValue_wCallback<QtObservedMolecule*, ObservedValue_Index_t> *>(ObservedValues[MoleculeRef])->noteCallBackIsGone();
123 boost::any_cast<ObservedValue_wCallback<std::string, ObservedValue_Index_t> *>(ObservedValues[AtomName])->noteCallBackIsGone();
124 boost::any_cast<ObservedValue_wCallback<Vector, ObservedValue_Index_t> *>(ObservedValues[AtomPosition])->noteCallBackIsGone();
125 boost::any_cast<ObservedValue_wCallback<bool, ObservedValue_Index_t> *>(ObservedValues[AtomSelected])->noteCallBackIsGone();
126
127 deactivateObserver();
128
129 destroyObservedValues(ObservedValues);
130}
131
132const atom * const QtObservedAtom::getAtomConst(const atomId_t _id)
133{
134 const atom * const _atom = const_cast<const World &>(World::getInstance()).
135 getAtom(AtomById(_id));
136 return _atom;
137}
138
139atom * const QtObservedAtom::getAtom(const atomId_t _id)
140{
141 atom * const _atom = World::getInstance().getAtom(AtomById(_id));
142 return _atom;
143}
144
145#ifdef HAVE_INLINE
146inline
147#endif
148atomId_t QtObservedAtom::updateIndex(const atom &_atomref)
149{
150 return _atomref.getId();
151}
152
153QtObservedAtom::ListOfBonds_t QtObservedAtom::updateBonds(
154 const atom &_atom)
155{
156 ListOfBonds_t ListOfBonds;
157 // make sure bonds is up-to-date
158 const BondList ListBonds = _atom.getListOfBonds();
159 for (BondList::const_iterator iter = ListBonds.begin();
160 iter != ListBonds.end();
161 ++iter)
162 ListOfBonds.insert( ListOfBonds.end(), std::make_pair(
163 (*iter)->leftatom->getId(),
164 (*iter)->rightatom->getId()) );
165 return ListOfBonds;
166}
167
168#ifdef HAVE_INLINE
169inline
170#endif
171atomicNumber_t QtObservedAtom::updateElement(
172 const atom &_atom)
173{
174 return _atom.getElementNo();
175}
176
177#ifdef HAVE_INLINE
178inline
179#endif
180QtObservedMolecule* QtObservedAtom::updateMoleculeRef(
181 const atom &_atom)
182{
183 if (_atom.getMolecule() != NULL) {
184 const moleculeId_t molid = _atom.getMolecule()->getId();
185 const QtObservedMolecule::ptr mol = board.getObservedMolecule(molid);
186 ASSERT(mol,
187 "QtObservedAtom::updateMoleculeRef() - could not update the ref, "
188 +toString(molid)+" unknown to Instance board?");
189 return mol.get();
190 } else {
191 return (QtObservedMolecule*)NULL;
192 }
193}
194
195#ifdef HAVE_INLINE
196inline
197#endif
198std::string QtObservedAtom::updateName(
199 const atom &_atom)
200{
201 return _atom.getName();
202}
203
204#ifdef HAVE_INLINE
205inline
206#endif
207Vector QtObservedAtom::updatePosition(
208 const atom &_atom)
209{
210 return _atom.getPosition();
211}
212
213#ifdef HAVE_INLINE
214inline
215#endif
216bool QtObservedAtom::updateSelected(
217 const atom &_atom)
218{
219 return _atom.getSelected();
220}
221
222void QtObservedAtom::update(Observable *publisher)
223{
224 ASSERT(0, "QtObservedAtom::update() - we are not signed on for global updates.");
225}
226
227void QtObservedAtom::subjectKilled(Observable *publisher)
228{
229 ++signedOffChannels;
230
231 checkForRemoval(getIndex());
232}
233
234void QtObservedAtom::countValuesSubjectKilled(ObservedValue_Index_t _id)
235{
236 ASSERT( _id == getIndex(),
237 "QtObservedAtom::countValuesSubjectKilled() - atom "+toString(getIndex())
238 +" received countValuesSubjectKilled for atom id "+toString(_id)+".");
239
240 ++subjectKilledCount;
241
242 checkForRemoval(_id);
243}
244
245#ifdef HAVE_INLINE
246inline
247#endif
248void QtObservedAtom::checkForRemoval(ObservedValue_Index_t _id)
249{
250 if ((signedOffChannels == AllsignedOnChannels) && (subjectKilledCount == MAX_ObservedTypes)) {
251 // remove owner: no more signOff needed
252 owner = NULL;
253
254 emit atomRemoved();
255
256 if (!BoardIsGone) {
257 board.markObservedAtomAsDisconnected(_id);
258 board.markObservedAtomForErase(_id);
259 }
260 }
261}
262
263void QtObservedAtom::recieveNotification(Observable *publisher, Notification_ptr notification)
264{
265 // ObservedValues have been updated before, hence convert updates to Qt's signals
266 switch (notification->getChannelNo()) {
267 case AtomObservable::IndexChanged:
268 {
269 const atomId_t newId = getAtomIndex();
270 emit indexChanged(oldId, newId);
271 oldId = newId;
272 break;
273 }
274 case AtomObservable::BondsAdded:
275 case AtomObservable::BondsRemoved:
276 emit bondsChanged();
277 break;
278 case AtomObservable::ElementChanged:
279 emit elementChanged();
280 break;
281 case AtomObservable::MoleculeChanged:
282 emit moleculeChanged();
283 break;
284 case AtomObservable::NameChanged:
285 emit nameChanged();
286 break;
287 case AtomObservable::PositionChanged:
288 emit positionChanged();
289 break;
290 case AtomObservable::SelectionChanged:
291 emit selectedChanged();
292 break;
293 default:
294 ASSERT(0, "QtObservedAtom::recieveNotification() - we are not signed on to channel "
295 +toString(notification->getChannelNo())+" of the atom.");
296 break;
297 }
298}
299
300void QtObservedAtom::activateObserver()
301{
302 atom * atomref = getAtom(getAtomIndex());
303 if (atomref != NULL) {
304 Observable::channels_t channels = getAllObservedChannels();
305 owner = static_cast<const Observable *>(atomref);
306 for (Observable::channels_t::const_iterator iter = channels.begin();
307 iter != channels.end(); ++iter)
308 owner->signOn(this, *iter);
309 if (!BoardIsGone)
310 board.markObservedAtomAsConnected(getIndex());
311 } else
312 signedOffChannels = AllsignedOnChannels;
313}
314
315void QtObservedAtom::deactivateObserver()
316{
317 // sign Off
318 if (owner != NULL) {
319 Observable::channels_t channels = getAllObservedChannels();
320 for (Observable::channels_t::const_iterator iter = channels.begin();
321 iter != channels.end(); ++iter)
322 owner->signOff(this, *iter);
323 owner = NULL;
324 signedOffChannels = AllsignedOnChannels;
325 if (!BoardIsGone)
326 board.markObservedAtomAsDisconnected(getIndex());
327 }
328}
329
330void QtObservedAtom::initObservedValues(
331 ObservedValues_t &_ObservedValues,
332 const atomId_t _id,
333 const atom * const _atomref,
334 const boost::function<void()> &_subjectKilled)
335{
336 ASSERT( _ObservedValues.size() == MAX_ObservedTypes,
337 "QtObservedAtom::initObservedValues() - given ObservedValues has not correct size.");
338
339 // fill ObservedValues: then all the other that need index
340 const boost::function<atomId_t ()> AtomIndexUpdater(
341 boost::bind(&QtObservedAtom::updateIndex, boost::cref(*_atomref)));
342 const boost::function<ListOfBonds_t ()> AtomBondsUpdater(
343 boost::bind(&QtObservedAtom::updateBonds, boost::cref(*_atomref)));
344 const boost::function<atomicNumber_t ()> AtomElementUpdater(
345 boost::bind(&QtObservedAtom::updateElement, boost::cref(*_atomref)));
346 const boost::function<std::string ()> AtomNameUpdater(
347 boost::bind(&QtObservedAtom::updateName, boost::cref(*_atomref)));
348 const boost::function<Vector ()> AtomPositionUpdater(
349 boost::bind(&QtObservedAtom::updatePosition, boost::cref(*_atomref)));
350 const boost::function<bool ()> AtomSelectedUpdater(
351 boost::bind(&QtObservedAtom::updateSelected, boost::cref(*_atomref)));
352 const boost::function<QtObservedMolecule* ()> MoleculeRefUpdater(
353 boost::bind(&QtObservedAtom::updateMoleculeRef, this, boost::cref(*_atomref)));
354
355 _ObservedValues[AtomIndex] = new ObservedValue_wCallback<atomId_t, ObservedValue_Index_t>(
356 _atomref,
357 AtomIndexUpdater,
358 "AtomIndex_"+toString(_id),
359 _id,
360 AtomIndexChannels,
361 _subjectKilled);
362 _ObservedValues[AtomBonds] = new ObservedValue_wCallback<ListOfBonds_t, ObservedValue_Index_t>(
363 _atomref,
364 AtomBondsUpdater,
365 "AtomBonds_"+toString(_id),
366 AtomBondsUpdater(),
367 AtomBondsChannels,
368 _subjectKilled);
369 _ObservedValues[AtomElement] = new ObservedValue_wCallback<atomicNumber_t, ObservedValue_Index_t>(
370 _atomref,
371 AtomElementUpdater,
372 "AtomElement"+toString(_id),
373 AtomElementUpdater(),
374 AtomElementChannels,
375 _subjectKilled);
376 _ObservedValues[AtomName] = new ObservedValue_wCallback<std::string, ObservedValue_Index_t>(
377 _atomref,
378 AtomNameUpdater,
379 "AtomName"+toString(_id),
380 AtomNameUpdater(),
381 AtomNameChannels,
382 _subjectKilled);
383 _ObservedValues[AtomPosition] = new ObservedValue_wCallback<Vector, ObservedValue_Index_t>(
384 _atomref,
385 AtomPositionUpdater,
386 "AtomPosition_"+toString(_id),
387 AtomPositionUpdater(),
388 AtomPositionChannels,
389 _subjectKilled);
390 _ObservedValues[AtomSelected] = new ObservedValue_wCallback<bool, ObservedValue_Index_t>(
391 _atomref,
392 AtomSelectedUpdater,
393 "AtomSelected_"+toString(_id),
394 AtomSelectedUpdater(),
395 AtomSelectedChannels,
396 _subjectKilled);
397 _ObservedValues[MoleculeRef] = new ObservedValue_wCallback<QtObservedMolecule*, ObservedValue_Index_t>(
398 _atomref,
399 MoleculeRefUpdater,
400 "AtomMoleculeIndex"+toString(_id),
401 MoleculeRefUpdater(),
402 MoleculeChangedChannels,
403 _subjectKilled);
404}
405
406void QtObservedAtom::destroyObservedValues(
407 std::vector<boost::any> &_ObservedValues)
408{
409 delete boost::any_cast<ObservedValue_wCallback<atomId_t, ObservedValue_Index_t> *>(_ObservedValues[AtomIndex]);
410 delete boost::any_cast<ObservedValue_wCallback<ListOfBonds_t, ObservedValue_Index_t> *>(_ObservedValues[AtomBonds]);
411 delete boost::any_cast<ObservedValue_wCallback<atomicNumber_t, ObservedValue_Index_t> *>(_ObservedValues[AtomElement]);
412 delete boost::any_cast<ObservedValue_wCallback<std::string, ObservedValue_Index_t> *>(_ObservedValues[AtomName]);
413 delete boost::any_cast<ObservedValue_wCallback<Vector, ObservedValue_Index_t> *>(_ObservedValues[AtomPosition]);
414 delete boost::any_cast<ObservedValue_wCallback<bool, ObservedValue_Index_t> *>(_ObservedValues[AtomSelected]);
415 delete boost::any_cast<ObservedValue_wCallback<QtObservedMolecule*, ObservedValue_Index_t> *>(_ObservedValues[MoleculeRef]);
416 _ObservedValues.clear();
417}
418
419ObservedValue_Index_t QtObservedAtom::getIndex() const
420{
421 ASSERT( owner != NULL,
422 "QtObservedAtom::getIndex() - index is NULL");
423 return owner;
424}
425
426const atomId_t& QtObservedAtom::getAtomIndex() const
427{
428 return boost::any_cast<ObservedValue_wCallback<atomId_t, ObservedValue_Index_t> *>(ObservedValues[AtomIndex])->get();
429}
430
431const QtObservedAtom::ListOfBonds_t& QtObservedAtom::getAtomBonds() const
432{
433 return boost::any_cast<ObservedValue_wCallback<ListOfBonds_t, ObservedValue_Index_t> *>(ObservedValues[AtomBonds])->get();
434}
435
436const atomicNumber_t& QtObservedAtom::getAtomElement() const
437{
438 return boost::any_cast<ObservedValue_wCallback<atomicNumber_t, ObservedValue_Index_t> *>(ObservedValues[AtomElement])->get();
439}
440
441const std::string& QtObservedAtom::getAtomName() const
442{
443 return boost::any_cast<ObservedValue_wCallback<std::string, ObservedValue_Index_t> *>(ObservedValues[AtomName])->get();
444}
445
446const Vector& QtObservedAtom::getAtomPosition() const
447{
448 return boost::any_cast<ObservedValue_wCallback<Vector, ObservedValue_Index_t> *>(ObservedValues[AtomPosition])->get();
449}
450
451const bool QtObservedAtom::getAtomSelected() const
452{
453 return boost::any_cast<ObservedValue_wCallback<bool, ObservedValue_Index_t> *>(ObservedValues[AtomSelected])->get();
454}
455
456const QtObservedMolecule* const QtObservedAtom::getMoleculeRef() const
457{
458 return boost::any_cast<ObservedValue_wCallback<QtObservedMolecule*, ObservedValue_Index_t> *>(ObservedValues[MoleculeRef])->get();
459}
Note: See TracBrowser for help on using the repository browser.