source: src/UIElements/Qt4/InstanceBoard/QtObservedBond.cpp@ f1b5ca

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

FIX: QtObservedAtom: getAtomMolecule() -> getMoleculeIndex().

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