source: src/UIElements/Qt4/InstanceBoard/QtObservedBond.cpp@ 2560f1

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

QtObservedBond uses fixed index which it returns.

  • Property mode set to 100644
File size: 12.2 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2016 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 * QtObservedBond.cpp
25 *
26 * Created on: Mar 03, 2016
27 * Author: heber
28 */
29
30
31// include config.h
32#ifdef HAVE_CONFIG_H
33#include <config.h>
34#endif
35
36#include "QtObservedBond.hpp"
37
38#include <QtCore/QMetaType>
39
40#include "UIElements/Qt4/InstanceBoard/QtObservedInstanceBoard.hpp"
41
42#include "CodePatterns/MemDebug.hpp"
43
44#include <boost/assign.hpp>
45
46#include "Atom/atom.hpp"
47#include "Bond/bond.hpp"
48#include "World.hpp"
49
50#include "UIElements/Qt4/InstanceBoard/ObservedValue_wCallback.hpp"
51
52using namespace boost::assign;
53
54template <class T>
55Observable * const getObservable(const T * _ptr)
56{
57 return static_cast<Observable * const>(
58 const_cast<T * const>(_ptr));
59}
60
61static QtObservedBond::ObservableCount_t initAllsignedOnChannels(const bond::ptr _bond)
62{
63 const QtObservedBond::ObservableCount_t returnlist =
64 boost::assign::list_of< QtObservedBond::ObservableCount_t::value_type >
65 ( getObservable(_bond.get()), 1);
66 return returnlist;
67}
68
69// static entities
70const Observable::channels_t
71QtObservedBond::BondDegreeChannels(1, BondObservable::DegreeChanged);
72
73
74QtObservedBond::QtObservedBond(
75 const bondId_t _id,
76 const bond::ptr _bond,
77 const QtObservedAtom::ptr &_leftatom,
78 const QtObservedAtom::ptr &_rightatom,
79 QtObservedInstanceBoard &_board,
80 QWidget * _parent) :
81 QWidget(_parent),
82 Observer("QtObservedBond"),
83 AllsignedOnChannels(initAllsignedOnChannels(_bond)),
84 bondowner(NULL),
85 oldbondId(_id),
86 leftatom(_leftatom),
87 rightatom(_rightatom),
88 index(static_cast<const ObservedValue_Index_t>(_bond.get())),
89 board(_board),
90 BoardIsGone(false),
91 ObservedValues(QtObservedBond::MAX_ObservedTypes)
92{
93 qRegisterMetaType<bondId_t>("bondId_t");
94
95 typedef boost::function<ObservableCount_t::mapped_type& (const ObservableCount_t::key_type&)> map_accessor_t;
96 const map_accessor_t accessor =
97 boost::bind<ObservableCount_t::mapped_type&>(
98 &ObservableCount_t::at,
99 boost::ref(subjectKilledCount), _1);
100
101 const boost::function<void ()> bondSubjectKilled(
102 boost::bind(&QtObservedBond::countValuesSubjectKilled,
103 boost::ref(*this),
104 boost::bind(&QtObservedBond::getIndex, boost::cref(*this)),
105 boost::bind(accessor,
106 getObservable(_bond.get()))));
107 initObservedValues( ObservedValues, _id, _bond, bondSubjectKilled);
108
109 // activating Observer is done by ObservedValueContainer when it's inserted
110}
111
112QtObservedBond::~QtObservedBond()
113{
114 boost::any_cast<ObservedValue_wCallback<int, ObservedValue_Index_t> *>(ObservedValues[BondDegree])->noteCallBackIsGone();
115
116 deactivateObserver();
117
118 destroyObservedValues(ObservedValues);
119}
120
121#ifdef HAVE_INLINE
122inline
123#endif
124int QtObservedBond::updateDegree(const bond &_bond)
125{
126 return _bond.getDegree();
127}
128
129void QtObservedBond::update(Observable *publisher)
130{
131 ASSERT(0, "QtObservedBond::update() - we are not signed on for global updates.");
132}
133
134void QtObservedBond::subjectKilled(Observable *publisher)
135{
136 ++(signedOffChannels[publisher]);
137
138 checkForRemoval(getIndex());
139}
140
141void QtObservedBond::countValuesSubjectKilled(
142 ObservedValue_Index_t _id,
143 unsigned int &_counter)
144{
145 ASSERT( _id == getIndex(),
146 "QtObservedBond::countValuesSubjectKilled() - bond "+toString(getIndex())
147 +" received countValuesSubjectKilled for bond id "+toString(_id)+".");
148
149 ++_counter;
150
151 checkForRemoval(_id);
152}
153
154void QtObservedBond::checkForRemoval(ObservedValue_Index_t _id)
155{
156 if (bondowner != NULL) {
157 // only bond needs to be destroyed to signal removal
158 const ObservableCount_t::const_iterator subjectkillediter =
159 subjectKilledCount.find(const_cast<Observable *>(bondowner));
160 const ObservableCount_t::const_iterator allsignediter =
161 AllsignedOnChannels.find(const_cast<Observable *>(bondowner));
162 const ObservableCount_t::const_iterator signedoffiter =
163 signedOffChannels.find(const_cast<Observable *>(bondowner));
164 ASSERT( (subjectkillediter != subjectKilledCount.end())
165 && (allsignediter != AllsignedOnChannels.end())
166 && (signedoffiter != signedOffChannels.end()),
167 "QtObservedBond::checkForRemoval() - something is wrong here.");
168 if ((signedoffiter->second == allsignediter->second)
169 && (subjectkillediter->second == allsignediter->second)) {
170 // remove owner: no more signOff needed
171 bondowner = NULL;
172
173 emit bondRemoved();
174
175 if (!BoardIsGone) {
176 board.markObservedBondAsDisconnected(_id);
177 board.markObservedBondForErase(_id);
178 }
179 }
180 }
181}
182
183void QtObservedBond::recieveNotification(Observable *publisher, Notification_ptr notification)
184{
185 // ObservedValues have been updated before, hence convert updates to Qt's signals
186 if (publisher == bondowner) {
187 switch (notification->getChannelNo()) {
188 case BondObservable::DegreeChanged:
189 emit degreeChanged();
190 break;
191 default:
192 ASSERT(0, "QtObservedBond::recieveNotification() - we are not signed on to channel "
193 +toString(notification->getChannelNo())+" of the bond "
194 +toString(getBondIndex())+".");
195 break;
196 }
197 } else
198 ASSERT(0,
199 "QtObservedBond::recieveNotification() - received signal from unknown source.");
200}
201
202static QtObservedBond::ObservableCount_t::mapped_type getObservableCountValue(
203 const QtObservedBond::ObservableCount_t &_map,
204 const Observable *_obs)
205{
206 Observable * const obs_const = const_cast<Observable * const>(_obs);
207 QtObservedBond::ObservableCount_t::const_iterator iter = _map.find(obs_const);
208 ASSERT( iter != _map.end(),
209 "getObservableCount_tValue");
210 return iter->second;
211}
212
213static void assignObservableCountValue(
214 QtObservedBond::ObservableCount_t &_map,
215 const Observable *_obs,
216 const QtObservedBond::ObservableCount_t::mapped_type &_value)
217{
218 Observable * const obs_const = const_cast<Observable * const>(_obs);
219 QtObservedBond::ObservableCount_t::iterator iter = _map.find(obs_const);
220 ASSERT( iter != _map.end(),
221 "getObservableCount_tValue");
222 iter->second = _value;
223}
224
225void QtObservedBond::activateObserver()
226{
227 signedOffChannels.clear();
228 subjectKilledCount.clear();
229
230 atom * leftatomref = getAtom(getLeftAtomIndex());
231 atom * rightatomref = getAtom(getRightAtomIndex());
232 bond::ptr bondref = leftatomref->getBond(rightatomref);
233 if (bondref != NULL) {
234 // bond
235 {
236 bondowner = static_cast<const Observable *>(bondref.get());
237 bondowner->signOn(this, BondObservable::DegreeChanged);
238 subjectKilledCount.insert( std::make_pair(const_cast<Observable * const>(bondowner), 0));
239 signedOffChannels.insert( std::make_pair(const_cast<Observable * const>(bondowner), 0));
240 }
241
242 // and mark as connected
243 if (!BoardIsGone)
244 board.markObservedBondAsConnected(getIndex());
245 } else {
246 subjectKilledCount.insert( std::make_pair(const_cast<Observable * const>(bondowner), 1));
247 assignObservableCountValue(signedOffChannels, bondowner,
248 getObservableCountValue(AllsignedOnChannels, bondowner));
249 }
250
251 // pass thru to signals from both atoms
252 connect( leftatom.get(), SIGNAL(indexChanged(const atomId_t, const atomId_t)),
253 this, SIGNAL(leftAtomIndexChanged(atomId_t, atomId_t)));
254 connect( leftatom.get(), SIGNAL(elementChanged()), this, SIGNAL(leftAtomElementChanged()));
255 connect( leftatom.get(), SIGNAL(positionChanged()), this, SIGNAL(leftAtomPositionChanged()));
256 connect( leftatom.get(), SIGNAL(moleculeChanged()), this, SIGNAL(leftmoleculeChanged()));
257 connect( rightatom.get(), SIGNAL(indexChanged(const atomId_t, const atomId_t)),
258 this, SIGNAL(rightAtomIndexChanged(atomId_t, atomId_t)));
259 connect( rightatom.get(), SIGNAL(elementChanged()), this, SIGNAL(rightAtomElementChanged()));
260 connect( rightatom.get(), SIGNAL(positionChanged()), this, SIGNAL(rightAtomPositionChanged()));
261 connect( rightatom.get(), SIGNAL(moleculeChanged()), this, SIGNAL(rightmoleculeChanged()));
262}
263
264void QtObservedBond::deactivateObserver()
265{
266 if (bondowner != NULL) {
267 const ObservableCount_t::iterator subjectkilledbonditer =
268 subjectKilledCount.find(const_cast<Observable *>(bondowner));
269 ASSERT( (subjectkilledbonditer != subjectKilledCount.end()),
270 "QtObservedBond::deactivateObserver() - no entry in subjectKilledCount for bond"
271 +toString(bondowner)+","
272 +" has activateObserver() been called?");
273 if (subjectkilledbonditer->second == 0)
274 bondowner->signOff(this, BondObservable::DegreeChanged);
275 subjectkilledbonditer->second = 1;
276 bondowner = NULL;
277 signedOffChannels.clear();
278 signedOffChannels.insert(AllsignedOnChannels.begin(), AllsignedOnChannels.end());
279
280 if (!BoardIsGone)
281 board.markObservedBondAsDisconnected(getIndex());
282 }
283}
284
285const atom * const QtObservedBond::getAtomConst(const atomId_t _id)
286{
287 const atom * const _atom = const_cast<const World &>(World::getInstance()).
288 getAtom(AtomById(_id));
289 return _atom;
290}
291
292atom * const QtObservedBond::getAtom(const atomId_t _id)
293{
294 atom * const _atom = World::getInstance().getAtom(AtomById(_id));
295 return _atom;
296}
297
298void QtObservedBond::initObservedValues(
299 ObservedValues_t &_ObservedValues,
300 const bondId_t _id,
301 const bond::ptr _bondref,
302 const boost::function<void()> &_bondsubjectKilled)
303{
304 // fill ObservedValues: index first
305 const boost::function<ObservedValue_Index_t ()> BondIndexGetter =
306 boost::bind(&QtObservedBond::getIndex,
307 boost::cref(*this));
308
309 // fill ObservedValues: then all the other that need index
310 const boost::function<int ()> BondDegreeUpdater(
311 boost::bind(&QtObservedBond::updateDegree, boost::cref(*_bondref)));
312
313 _ObservedValues[BondDegree] = new ObservedValue_wCallback<int, ObservedValue_Index_t>(
314 _bondref.get(),
315 BondDegreeUpdater,
316 "BondDegree_bond"+toString(_id),
317 BondDegreeUpdater(),
318 BondDegreeChannels,
319 _bondsubjectKilled);
320}
321
322void QtObservedBond::destroyObservedValues(
323 std::vector<boost::any> &_ObservedValues)
324{
325 delete boost::any_cast<ObservedValue_wCallback<int, ObservedValue_Index_t> *>(_ObservedValues[BondDegree]);
326 _ObservedValues.clear();
327}
328
329ObservedValue_Index_t QtObservedBond::getIndex() const
330{
331 ASSERT( index != NULL,
332 "QtObservedBond::getIndex() - index is NULL");
333 return index;
334}
335
336const QtObservedBond::bondId_t QtObservedBond::getBondIndex() const
337{
338 return QtObservedBond::bondId_t(getLeftAtomIndex(), getRightAtomIndex());
339}
340
341const int& QtObservedBond::getBondDegree() const
342{
343 return boost::any_cast<ObservedValue_wCallback<int, ObservedValue_Index_t> *>(ObservedValues[BondDegree])->get();
344}
345
346const atomId_t& QtObservedBond::getLeftAtomIndex() const
347{
348 return leftatom->getAtomIndex();
349}
350
351const atomicNumber_t& QtObservedBond::getLeftAtomElement() const
352{
353 return leftatom->getAtomElement();
354}
355
356const Vector& QtObservedBond::getLeftAtomPosition() const
357{
358 return leftatom->getAtomPosition();
359}
360
361const moleculeId_t QtObservedBond::getLeftMoleculeIndex() const
362{
363 if (leftatom->getMoleculeRef() != NULL)
364 return leftatom->getMoleculeRef()->getMolIndex();
365 else
366 return (moleculeId_t)-1;
367}
368
369const atomId_t& QtObservedBond::getRightAtomIndex() const
370{
371 return rightatom->getAtomIndex();
372}
373
374const atomicNumber_t& QtObservedBond::getRightAtomElement() const
375{
376 return rightatom->getAtomElement();
377}
378
379const Vector& QtObservedBond::getRightAtomPosition() const
380{
381 return rightatom->getAtomPosition();
382}
383
384const moleculeId_t QtObservedBond::getRightMoleculeIndex() const
385{
386 if (rightatom->getMoleculeRef() != NULL)
387 return rightatom->getMoleculeRef()->getMolIndex();
388 else
389 return (moleculeId_t)-1;
390}
Note: See TracBrowser for help on using the repository browser.