DynExp
Highly flexible laboratory automation for dynamically changing experiments.
Loading...
Searching...
No Matches
LockinAmplifierControl.cpp
Go to the documentation of this file.
1// This file is part of DynExp.
2
3#include "stdafx.h"
4#include "moc_LockinAmplifierControl.cpp"
6
7namespace DynExpModule
8{
9 LockinAmplifierControlWidget::LockinAmplifierControlWidget(LockinAmplifierControl& Owner, QModuleWidget* parent) : QModuleWidget(Owner, parent)
10 {
11 ui.setupUi(this);
12 }
13
15 {
16 if (!GetUIInitialized())
17 {
18 ui.SBRange->setSuffix(" m" + QString::fromStdString(ModuleData->SensitivityUnitString));
19 ui.LEOscillatorFreq->setFocus();
20
21 UIInitialized = true;
22 }
23 }
24
29
48
49 const char* LockinAmplifierControl::ProgressBarRedStylesheet = "QProgressBar::chunk { background-color: rgb(255, 0, 0); }";
50 const char* LockinAmplifierControl::ProgressBarGreenStylesheet = "QProgressBar::chunk { background-color: rgb(0, 170, 0); }";
51
53 {
54 try
55 {
56 auto ModuleData = DynExp::dynamic_ModuleData_cast<LockinAmplifierControl>(Instance.ModuleDataGetter());
57 auto InstrData = DynExp::dynamic_InstrumentData_cast<DynExpInstr::LockinAmplifier>(ModuleData->GetLockinAmplifier()->GetInstrumentData());
58
59 ModuleData->CurrentSensitivity = InstrData->GetSensitivity();
60 ModuleData->CurrentPhase = InstrData->GetPhase();
61 ModuleData->CurrentTimeConstant = InstrData->GetTimeConstant();
62 ModuleData->CurrentFilterOrder = InstrData->GetFilterOrder();
63 ModuleData->CurrentTriggerMode = InstrData->GetTriggerMode();
64 ModuleData->CurrentTriggerEdge = InstrData->GetTriggerEdge();
65 ModuleData->CurrentSignal = InstrData->GetSignalType();
66 ModuleData->CurrentSamplingRate = InstrData->GetSamplingRate();
67 ModuleData->CurrentEnable = InstrData->IsEnabled();
68 ModuleData->CurrentOverload = InstrData->IsOverloaded();
69 std::tie(ModuleData->CurrentNegInputLoad, ModuleData->CurrentPosInputLoad) = InstrData->GetInputLoad();
70 ModuleData->CurrentOscillatorFrequency = InstrData->GetOscillatorFrequency();
71 ModuleData->CurrentAcquisitionProgress = InstrData->GetAcquisitionProgress();
72
74 } // ModuleData and instruments' data unlocked here.
75 catch (const Util::TimeoutException& e)
76 {
77 if (NumFailedUpdateAttempts++ >= 3)
78 Instance.GetOwner().SetWarning(e);
79 }
80
82 }
83
88
89 std::unique_ptr<DynExp::QModuleWidget> LockinAmplifierControl::MakeUIWidget()
90 {
91 auto Widget = std::make_unique<LockinAmplifierControlWidget>(*this);
92
93 // Connect Qt signals to module events
94 Connect(Widget->GetUI().SBRange, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &LockinAmplifierControl::OnSensitivityChanged);
95 Connect(Widget->GetUI().BAutoRange, &QPushButton::clicked, this, &LockinAmplifierControl::OnAutoRangeClicked);
96 Connect(Widget->GetUI().SBPhase, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &LockinAmplifierControl::OnPhaseChanged);
97 Connect(Widget->GetUI().BAutoPhase, &QPushButton::clicked, this, &LockinAmplifierControl::OnAutoPhaseClicked);
98 Connect(Widget->GetUI().SBTimeConstant, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &LockinAmplifierControl::OnTimeConstantChanged);
99 Connect(Widget->GetUI().SBFilterOrder, QOverload<int>::of(&QSpinBox::valueChanged), this, &LockinAmplifierControl::OnFilterOrderChanged);
100 Connect(Widget->GetUI().CBTriggerMode, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &LockinAmplifierControl::OnTriggerModeChanged);
101 Connect(Widget->GetUI().CBTriggerEdge, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &LockinAmplifierControl::OnTriggerEdgeChanged);
102 Connect(Widget->GetUI().BForceTrigger, &QPushButton::clicked, this, &LockinAmplifierControl::OnForceTriggerClicked);
103 Connect(Widget->GetUI().CBQuantity, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &LockinAmplifierControl::OnSignalTypeChanged);
104 Connect(Widget->GetUI().SBSamplingRate, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &LockinAmplifierControl::OnSamplingRateChanged);
105 Connect(Widget->GetUI().CBEnable, &QCheckBox::stateChanged, this, &LockinAmplifierControl::OnEnableClicked);
106 Connect(Widget->GetUI().BPersist, &QPushButton::clicked, this, &LockinAmplifierControl::OnPersistParamsClicked);
107
108 return Widget;
109 }
110
111 void LockinAmplifierControl::UpdateUIChild(const ModuleBase::ModuleDataGetterType& ModuleDataGetter)
112 {
113 auto Widget = GetWidget<LockinAmplifierControlWidget>();
114 auto ModuleData = DynExp::dynamic_ModuleData_cast<LockinAmplifierControl>(ModuleDataGetter());
115
116 Widget->InitializeUI(ModuleData);
117
118 if (!Widget->GetUI().SBRange->hasFocus())
119 {
120 const QSignalBlocker Blocker(Widget->GetUI().SBRange);
121 Widget->GetUI().SBRange->setValue(ModuleData->CurrentSensitivity * 1e3);
122 }
123
124 if (ModuleData->CurrentNegInputLoad >= 0)
125 {
126 Widget->GetUI().PBInputNegLoad->setVisible(true);
127 Widget->GetUI().PBInputNegLoad->setValue(ModuleData->CurrentNegInputLoad * 100);
128 Widget->GetUI().PBInputNegLoad->setStyleSheet(ModuleData->CurrentNegInputLoad >= 0.95 ? ProgressBarRedStylesheet : ProgressBarGreenStylesheet);
129
130 }
131 else
132 Widget->GetUI().PBInputNegLoad->setVisible(false);
133
134 if (ModuleData->CurrentPosInputLoad >= 0)
135 {
136 Widget->GetUI().PBInputPosLoad->setVisible(true);
137 Widget->GetUI().PBInputPosLoad->setValue(ModuleData->CurrentPosInputLoad * 100);
138 Widget->GetUI().PBInputPosLoad->setStyleSheet(ModuleData->CurrentPosInputLoad >= 0.95 ? ProgressBarRedStylesheet : ProgressBarGreenStylesheet);
139
140 }
141 else
142 Widget->GetUI().PBInputPosLoad->setVisible(false);
143
144 Widget->GetUI().LInputOverload->setText(ModuleData->CurrentOverload ? "Overload" : "");
145
146 Widget->GetUI().LOscillatorFreq->setVisible(ModuleData->CurrentOscillatorFrequency > 0);
147 Widget->GetUI().LEOscillatorFreq->setVisible(ModuleData->CurrentOscillatorFrequency > 0);
148 if (ModuleData->CurrentOscillatorFrequency > 0)
149 Widget->GetUI().LEOscillatorFreq->setText(QString::fromStdString(Util::ToStr(ModuleData->CurrentOscillatorFrequency, 2) + " Hz"));
150
151 if (!Widget->GetUI().SBPhase->hasFocus())
152 {
153 const QSignalBlocker Blocker(Widget->GetUI().SBPhase);
154 Widget->GetUI().SBPhase->setValue(ModuleData->CurrentPhase / std::numbers::pi * 180.0);
155 }
156
157 if (!Widget->GetUI().SBTimeConstant->hasFocus())
158 {
159 const QSignalBlocker Blocker(Widget->GetUI().SBTimeConstant);
160 Widget->GetUI().SBTimeConstant->setValue(ModuleData->CurrentTimeConstant * 1e6);
161 }
162
163 if (!Widget->GetUI().SBFilterOrder->hasFocus())
164 {
165 const QSignalBlocker Blocker(Widget->GetUI().SBFilterOrder);
166 Widget->GetUI().SBFilterOrder->setValue(ModuleData->CurrentFilterOrder);
167 }
168
169 if (!Widget->GetUI().CBTriggerMode->hasFocus())
170 {
171 const QSignalBlocker Blocker(Widget->GetUI().CBTriggerMode);
172 Widget->GetUI().CBTriggerMode->setCurrentIndex(ModuleData->CurrentTriggerMode - 1);
173 }
174
175 if (!Widget->GetUI().CBTriggerEdge->hasFocus())
176 {
177 const QSignalBlocker Blocker(Widget->GetUI().CBTriggerEdge);
178 Widget->GetUI().CBTriggerEdge->setCurrentIndex(ModuleData->CurrentTriggerEdge - 1);
179 }
180
181 if (!Widget->GetUI().CBQuantity->hasFocus())
182 {
183 const QSignalBlocker Blocker(Widget->GetUI().CBQuantity);
184 Widget->GetUI().CBQuantity->setCurrentIndex(ModuleData->CurrentSignal);
185 }
186
187 if (!Widget->GetUI().SBSamplingRate->hasFocus())
188 {
189 const QSignalBlocker Blocker(Widget->GetUI().SBSamplingRate);
190 Widget->GetUI().SBSamplingRate->setValue(ModuleData->CurrentSamplingRate);
191 }
192
193 if (!Widget->GetUI().CBEnable->hasFocus())
194 {
195 const QSignalBlocker Blocker(Widget->GetUI().CBEnable);
196 Widget->GetUI().CBEnable->setChecked(ModuleData->CurrentEnable);
197 }
198
199 Widget->GetUI().LProgress->setVisible(ModuleData->CurrentAcquisitionProgress >= 0);
200 Widget->GetUI().PProgress->setVisible(ModuleData->CurrentAcquisitionProgress >= 0);
201 if (ModuleData->CurrentAcquisitionProgress >= 0)
202 Widget->GetUI().PProgress->setValue(ModuleData->CurrentAcquisitionProgress * 100);
203 }
204
206 {
207 auto ModuleParams = DynExp::dynamic_Params_cast<LockinAmplifierControl>(Instance->ParamsGetter());
208 auto ModuleData = DynExp::dynamic_ModuleData_cast<LockinAmplifierControl>(Instance->ModuleDataGetter());
209
210 Instance->LockObject(ModuleParams->LockinAmplifier, ModuleData->GetLockinAmplifier());
211
212 ModuleData->SensitivityUnitString = ModuleData->GetLockinAmplifier()->GetSensitivityUnitString();
213 }
214
216 {
217 auto ModuleData = DynExp::dynamic_ModuleData_cast<LockinAmplifierControl>(Instance->ModuleDataGetter());
218
219 Instance->UnlockObject(ModuleData->GetLockinAmplifier());
220 }
221
223 {
224 auto ModuleData = DynExp::dynamic_ModuleData_cast<LockinAmplifierControl>(Instance->ModuleDataGetter());
225 ModuleData->GetLockinAmplifier()->SetSensitivity(Value / 1e3);
226 }
227
229 {
230 auto ModuleData = DynExp::dynamic_ModuleData_cast<LockinAmplifierControl>(Instance->ModuleDataGetter());
231 ModuleData->GetLockinAmplifier()->AutoAdjustSensitivity();
232 }
233
235 {
236 auto ModuleData = DynExp::dynamic_ModuleData_cast<LockinAmplifierControl>(Instance->ModuleDataGetter());
237 ModuleData->GetLockinAmplifier()->SetPhase(Value / 180.0 * std::numbers::pi);
238 }
239
241 {
242 auto ModuleData = DynExp::dynamic_ModuleData_cast<LockinAmplifierControl>(Instance->ModuleDataGetter());
243 ModuleData->GetLockinAmplifier()->AutoAdjustPhase();
244 }
245
247 {
248 auto ModuleData = DynExp::dynamic_ModuleData_cast<LockinAmplifierControl>(Instance->ModuleDataGetter());
249 ModuleData->GetLockinAmplifier()->SetTimeConstant(Value / 1e6);
250 }
251
253 {
254 auto ModuleData = DynExp::dynamic_ModuleData_cast<LockinAmplifierControl>(Instance->ModuleDataGetter());
255 ModuleData->GetLockinAmplifier()->SetFilterOrder(Value);
256 }
257
259 {
260 auto ModuleData = DynExp::dynamic_ModuleData_cast<LockinAmplifierControl>(Instance->ModuleDataGetter());
261 ModuleData->GetLockinAmplifier()->SetTriggerMode(static_cast<DynExpInstr::LockinAmplifierDefs::TriggerModeType>(Index + 1));
262 }
263
265 {
266 auto ModuleData = DynExp::dynamic_ModuleData_cast<LockinAmplifierControl>(Instance->ModuleDataGetter());
267 ModuleData->GetLockinAmplifier()->SetTriggerEdge(static_cast<DynExpInstr::LockinAmplifierDefs::TriggerEdgeType>(Index + 1));
268 }
269
271 {
272 auto ModuleData = DynExp::dynamic_ModuleData_cast<LockinAmplifierControl>(Instance->ModuleDataGetter());
273 ModuleData->GetLockinAmplifier()->ForceTrigger();
274 }
275
277 {
278 auto ModuleData = DynExp::dynamic_ModuleData_cast<LockinAmplifierControl>(Instance->ModuleDataGetter());
279 ModuleData->GetLockinAmplifier()->SetSignalType(static_cast<DynExpInstr::LockinAmplifierDefs::SignalType>(Index));
280 }
281
283 {
284 auto ModuleData = DynExp::dynamic_ModuleData_cast<LockinAmplifierControl>(Instance->ModuleDataGetter());
285 ModuleData->GetLockinAmplifier()->SetSamplingRate(Value);
286 }
287
289 {
290 auto ModuleData = DynExp::dynamic_ModuleData_cast<LockinAmplifierControl>(Instance->ModuleDataGetter());
291 ModuleData->GetLockinAmplifier()->SetEnable(Value);
292 }
293
295 {
296 auto ModuleData = DynExp::dynamic_ModuleData_cast<LockinAmplifierControl>(Instance->ModuleDataGetter());
297 ModuleData->GetLockinAmplifier()->PersistDataToParams();
298 }
299}
Implementation of a module to control a lock-in amplifier.
void ResetImpl(dispatch_tag< QModuleDataBase >) override final
DynExpInstr::LockinAmplifierDefs::TriggerEdgeType CurrentTriggerEdge
DynExpInstr::LockinAmplifierDefs::TriggerModeType CurrentTriggerMode
DynExpInstr::LockinAmplifierDefs::SignalType CurrentSignal
void InitializeUI(Util::SynchronizedPointer< LockinAmplifierControlData > &ModuleData)
LockinAmplifierControlWidget(LockinAmplifierControl &Owner, QModuleWidget *parent=nullptr)
void OnSignalTypeChanged(DynExp::ModuleInstance *Instance, int Index) const
void OnAutoPhaseClicked(DynExp::ModuleInstance *Instance, bool) const
void OnTimeConstantChanged(DynExp::ModuleInstance *Instance, double Value) const
void OnPersistParamsClicked(DynExp::ModuleInstance *Instance, bool) const
void OnFilterOrderChanged(DynExp::ModuleInstance *Instance, int Value) const
void OnPhaseChanged(DynExp::ModuleInstance *Instance, double Value) const
void UpdateUIChild(const ModuleBase::ModuleDataGetterType &ModuleDataGetter) override final
void OnInit(DynExp::ModuleInstance *Instance) const override final
This event is triggered right before the module thread starts. Override it to lock instruments this m...
Util::DynExpErrorCodes::DynExpErrorCodes ModuleMainLoop(DynExp::ModuleInstance &Instance) override final
Module main loop. The function is executed periodically by the module thread. Also refer to GetMainLo...
void OnTriggerModeChanged(DynExp::ModuleInstance *Instance, int Index) const
void ResetImpl(dispatch_tag< QModuleBase >) override final
void OnForceTriggerClicked(DynExp::ModuleInstance *Instance, bool) const
void OnAutoRangeClicked(DynExp::ModuleInstance *Instance, bool) const
std::unique_ptr< DynExp::QModuleWidget > MakeUIWidget() override final
Used by InitUI() as a factory function for the module's user interface widget. Create the widget here...
void OnExit(DynExp::ModuleInstance *Instance) const override final
This event is triggered right before the module thread terminates (not due to an exception,...
void OnEnableClicked(DynExp::ModuleInstance *Instance, int Value) const
void OnTriggerEdgeChanged(DynExp::ModuleInstance *Instance, int Index) const
void OnSamplingRateChanged(DynExp::ModuleInstance *Instance, double Value) const
void OnSensitivityChanged(DynExp::ModuleInstance *Instance, double Value) const
const std::unique_ptr< ModuleDataType > ModuleData
Module data belonging to this ModuleBase instance.
Definition Module.h:743
Refer to ParamsBase::dispatch_tag.
Definition Module.h:189
Defines data for a thread belonging to a ModuleBase instance. Refer to RunnableInstance.
Definition Module.h:793
const ModuleBase::ModuleDataGetterType ModuleDataGetter
Getter for module's data. Refer to ModuleBase::ModuleDataGetterType.
Definition Module.h:825
Refer to ParamsBase::dispatch_tag.
Definition Object.h:2018
QModuleWidget * Widget
User interface widget belonging to the module.
Definition Module.h:1491
void Connect(SenderType *Sender, SignalType Signal, ReceiverType *Receiver, EventType Event)
Uses Qt's connect mechanism to connect a QObject's signal to a DynExp module's event....
Definition Module.h:1500
const Object::ParamsGetterType ParamsGetter
Invoke to obtain the parameters (derived from ParamsBase) of Owner.
Definition Object.h:3671
void UnlockObject(LinkedObjectWrapperContainer< ObjectT > &ObjectWrapperContainer)
Unlocks an Object instance stored in the LinkedObjectWrapperContainer ObjectWrapperContainer....
Definition Object.h:3570
void LockObject(const ParamsBase::Param< ObjectLink< ObjectT > > &LinkParam, LinkedObjectWrapperContainer< ObjectT > &ObjectWrapperContainer, std::chrono::milliseconds Timeout=ObjectLinkBase::LockObjectTimeoutDefault)
Locks an Object instance referenced by a parameter LinkParam of type ParamsBase::Param< ObjectLink< O...
Definition Object.h:3554
const auto & GetOwner() const noexcept
Returns Owner.
Definition Object.h:3524
Pointer to lock a class derived from ISynchronizedPointerLockable for synchronizing between threads....
Definition Util.h:170
Thrown when an operation timed out before it could be completed, especially used for locking shared d...
Definition Exception.h:261
TriggerEdgeType
Type to determine at which edge of a trigger signal to trigger. Not a strongly-typed enum to allow us...
@ Fall
Trigger on falling edge.
SignalType
Type specifying different signal coordinates a lock-in amplifier can record. Not a strongly-typed enu...
@ R
Radial component of the signal in polar coordinates.
TriggerModeType
Type to determine the trigger mode. Not a strongly-typed enum to allow using the enumeration in a Dyn...
@ ExternSingle
Run once after an external trigger signal has been detected.
DynExp's module namespace contains the implementation of DynExp modules which extend DynExp's core fu...
DynExpErrorCodes
DynExp's error codes
Definition Exception.h:22
std::string ToStr(const T &Value, int Precision=-1)
Converts a (numeric) value of type T to a std::string using operator<< of std::stringstream.
Definition Util.h:625
Accumulates include statements to provide a precompiled header.