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"
5#include "ui_LockinAmplifierControl.h"
7
8namespace DynExpModule
9{
11 : QModuleWidget(Owner, parent),
12 ui(std::make_unique<Ui::LockinAmplifierControl>())
13 {
14 ui->setupUi(this);
15 }
16
18 {
19 if (!GetUIInitialized())
20 {
21 ui->SBRange->setSuffix(" m" + QString::fromStdString(ModuleData->SensitivityUnitString));
22 ui->LEOscillatorFreq->setFocus();
23
24 UIInitialized = true;
25 }
26 }
27
32
51
52 const char* LockinAmplifierControl::ProgressBarRedStylesheet = "QProgressBar::chunk { background-color: rgb(255, 0, 0); }";
53 const char* LockinAmplifierControl::ProgressBarGreenStylesheet = "QProgressBar::chunk { background-color: rgb(0, 170, 0); }";
54
56 {
57 try
58 {
59 auto ModuleData = DynExp::dynamic_ModuleData_cast<LockinAmplifierControl>(Instance.ModuleDataGetter());
60 auto InstrData = DynExp::dynamic_InstrumentData_cast<DynExpInstr::LockinAmplifier>(ModuleData->GetLockinAmplifier()->GetInstrumentData());
61
62 ModuleData->CurrentSensitivity = InstrData->GetSensitivity();
63 ModuleData->CurrentPhase = InstrData->GetPhase();
64 ModuleData->CurrentTimeConstant = InstrData->GetTimeConstant();
65 ModuleData->CurrentFilterOrder = InstrData->GetFilterOrder();
66 ModuleData->CurrentTriggerMode = InstrData->GetTriggerMode();
67 ModuleData->CurrentTriggerEdge = InstrData->GetTriggerEdge();
68 ModuleData->CurrentSignal = InstrData->GetSignalType();
69 ModuleData->CurrentSamplingRate = InstrData->GetSamplingRate();
70 ModuleData->CurrentEnable = InstrData->IsEnabled();
71 ModuleData->CurrentOverload = InstrData->IsOverloaded();
72 std::tie(ModuleData->CurrentNegInputLoad, ModuleData->CurrentPosInputLoad) = InstrData->GetInputLoad();
73 ModuleData->CurrentOscillatorFrequency = InstrData->GetOscillatorFrequency();
74 ModuleData->CurrentAcquisitionProgress = InstrData->GetAcquisitionProgress();
75
77 } // ModuleData and instruments' data unlocked here.
78 catch (const Util::TimeoutException& e)
79 {
80 if (NumFailedUpdateAttempts++ >= 3)
81 Instance.GetOwner().SetWarning(e);
82 }
83
85 }
86
91
92 std::unique_ptr<DynExp::QModuleWidget> LockinAmplifierControl::MakeUIWidget()
93 {
94 auto Widget = std::make_unique<LockinAmplifierControlWidget>(*this);
95
96 // Connect Qt signals to module events
97 Connect(Widget->GetUI()->SBRange, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &LockinAmplifierControl::OnSensitivityChanged);
98 Connect(Widget->GetUI()->BAutoRange, &QPushButton::clicked, this, &LockinAmplifierControl::OnAutoRangeClicked);
99 Connect(Widget->GetUI()->SBPhase, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &LockinAmplifierControl::OnPhaseChanged);
100 Connect(Widget->GetUI()->BAutoPhase, &QPushButton::clicked, this, &LockinAmplifierControl::OnAutoPhaseClicked);
101 Connect(Widget->GetUI()->SBTimeConstant, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &LockinAmplifierControl::OnTimeConstantChanged);
102 Connect(Widget->GetUI()->SBFilterOrder, QOverload<int>::of(&QSpinBox::valueChanged), this, &LockinAmplifierControl::OnFilterOrderChanged);
103 Connect(Widget->GetUI()->CBTriggerMode, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &LockinAmplifierControl::OnTriggerModeChanged);
104 Connect(Widget->GetUI()->CBTriggerEdge, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &LockinAmplifierControl::OnTriggerEdgeChanged);
105 Connect(Widget->GetUI()->BForceTrigger, &QPushButton::clicked, this, &LockinAmplifierControl::OnForceTriggerClicked);
106 Connect(Widget->GetUI()->CBQuantity, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &LockinAmplifierControl::OnSignalTypeChanged);
107 Connect(Widget->GetUI()->SBSamplingRate, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &LockinAmplifierControl::OnSamplingRateChanged);
108 Connect(Widget->GetUI()->CBEnable, &QCheckBox::checkStateChanged, this, &LockinAmplifierControl::OnEnableClicked);
109 Connect(Widget->GetUI()->BPersist, &QPushButton::clicked, this, &LockinAmplifierControl::OnPersistParamsClicked);
110
111 return Widget;
112 }
113
114 void LockinAmplifierControl::UpdateUIChild(const ModuleBase::ModuleDataGetterType& ModuleDataGetter)
115 {
116 auto Widget = GetWidget<LockinAmplifierControlWidget>();
117 auto ModuleData = DynExp::dynamic_ModuleData_cast<LockinAmplifierControl>(ModuleDataGetter());
118
119 Widget->InitializeUI(ModuleData);
120
121 if (!Widget->GetUI()->SBRange->hasFocus())
122 {
123 const QSignalBlocker Blocker(Widget->GetUI()->SBRange);
124 Widget->GetUI()->SBRange->setValue(ModuleData->CurrentSensitivity * 1e3);
125 }
126
127 if (ModuleData->CurrentNegInputLoad >= 0)
128 {
129 Widget->GetUI()->PBInputNegLoad->setVisible(true);
130 Widget->GetUI()->PBInputNegLoad->setValue(ModuleData->CurrentNegInputLoad * 100);
131 Widget->GetUI()->PBInputNegLoad->setStyleSheet(ModuleData->CurrentNegInputLoad >= 0.95 ? ProgressBarRedStylesheet : ProgressBarGreenStylesheet);
132
133 }
134 else
135 Widget->GetUI()->PBInputNegLoad->setVisible(false);
136
137 if (ModuleData->CurrentPosInputLoad >= 0)
138 {
139 Widget->GetUI()->PBInputPosLoad->setVisible(true);
140 Widget->GetUI()->PBInputPosLoad->setValue(ModuleData->CurrentPosInputLoad * 100);
141 Widget->GetUI()->PBInputPosLoad->setStyleSheet(ModuleData->CurrentPosInputLoad >= 0.95 ? ProgressBarRedStylesheet : ProgressBarGreenStylesheet);
142
143 }
144 else
145 Widget->GetUI()->PBInputPosLoad->setVisible(false);
146
147 Widget->GetUI()->LInputOverload->setText(ModuleData->CurrentOverload ? "Overload" : "");
148
149 Widget->GetUI()->LOscillatorFreq->setVisible(ModuleData->CurrentOscillatorFrequency > 0);
150 Widget->GetUI()->LEOscillatorFreq->setVisible(ModuleData->CurrentOscillatorFrequency > 0);
151 if (ModuleData->CurrentOscillatorFrequency > 0)
152 Widget->GetUI()->LEOscillatorFreq->setText(QString::fromStdString(Util::ToStr(ModuleData->CurrentOscillatorFrequency, 2) + " Hz"));
153
154 if (!Widget->GetUI()->SBPhase->hasFocus())
155 {
156 const QSignalBlocker Blocker(Widget->GetUI()->SBPhase);
157 Widget->GetUI()->SBPhase->setValue(ModuleData->CurrentPhase / std::numbers::pi * 180.0);
158 }
159
160 if (!Widget->GetUI()->SBTimeConstant->hasFocus())
161 {
162 const QSignalBlocker Blocker(Widget->GetUI()->SBTimeConstant);
163 Widget->GetUI()->SBTimeConstant->setValue(ModuleData->CurrentTimeConstant * 1e6);
164 }
165
166 if (!Widget->GetUI()->SBFilterOrder->hasFocus())
167 {
168 const QSignalBlocker Blocker(Widget->GetUI()->SBFilterOrder);
169 Widget->GetUI()->SBFilterOrder->setValue(ModuleData->CurrentFilterOrder);
170 }
171
172 if (!Widget->GetUI()->CBTriggerMode->hasFocus())
173 {
174 const QSignalBlocker Blocker(Widget->GetUI()->CBTriggerMode);
175 Widget->GetUI()->CBTriggerMode->setCurrentIndex(ModuleData->CurrentTriggerMode - 1);
176 }
177
178 if (!Widget->GetUI()->CBTriggerEdge->hasFocus())
179 {
180 const QSignalBlocker Blocker(Widget->GetUI()->CBTriggerEdge);
181 Widget->GetUI()->CBTriggerEdge->setCurrentIndex(ModuleData->CurrentTriggerEdge - 1);
182 }
183
184 if (!Widget->GetUI()->CBQuantity->hasFocus())
185 {
186 const QSignalBlocker Blocker(Widget->GetUI()->CBQuantity);
187 Widget->GetUI()->CBQuantity->setCurrentIndex(ModuleData->CurrentSignal);
188 }
189
190 if (!Widget->GetUI()->SBSamplingRate->hasFocus())
191 {
192 const QSignalBlocker Blocker(Widget->GetUI()->SBSamplingRate);
193 Widget->GetUI()->SBSamplingRate->setValue(ModuleData->CurrentSamplingRate);
194 }
195
196 if (!Widget->GetUI()->CBEnable->hasFocus())
197 {
198 const QSignalBlocker Blocker(Widget->GetUI()->CBEnable);
199 Widget->GetUI()->CBEnable->setChecked(ModuleData->CurrentEnable);
200 }
201
202 Widget->GetUI()->LProgress->setVisible(ModuleData->CurrentAcquisitionProgress >= 0);
203 Widget->GetUI()->PProgress->setVisible(ModuleData->CurrentAcquisitionProgress >= 0);
204 if (ModuleData->CurrentAcquisitionProgress >= 0)
205 Widget->GetUI()->PProgress->setValue(ModuleData->CurrentAcquisitionProgress * 100);
206 }
207
209 {
210 auto ModuleParams = DynExp::dynamic_Params_cast<LockinAmplifierControl>(Instance->ParamsGetter());
211 auto ModuleData = DynExp::dynamic_ModuleData_cast<LockinAmplifierControl>(Instance->ModuleDataGetter());
212
213 Instance->LockObject(ModuleParams->LockinAmplifier, ModuleData->GetLockinAmplifier());
214
215 ModuleData->SensitivityUnitString = ModuleData->GetLockinAmplifier()->GetSensitivityUnitString();
216 }
217
219 {
220 auto ModuleData = DynExp::dynamic_ModuleData_cast<LockinAmplifierControl>(Instance->ModuleDataGetter());
221
222 Instance->UnlockObject(ModuleData->GetLockinAmplifier());
223 }
224
226 {
227 auto ModuleData = DynExp::dynamic_ModuleData_cast<LockinAmplifierControl>(Instance->ModuleDataGetter());
228 ModuleData->GetLockinAmplifier()->SetSensitivity(Value / 1e3);
229 }
230
232 {
233 auto ModuleData = DynExp::dynamic_ModuleData_cast<LockinAmplifierControl>(Instance->ModuleDataGetter());
234 ModuleData->GetLockinAmplifier()->AutoAdjustSensitivity();
235 }
236
238 {
239 auto ModuleData = DynExp::dynamic_ModuleData_cast<LockinAmplifierControl>(Instance->ModuleDataGetter());
240 ModuleData->GetLockinAmplifier()->SetPhase(Value / 180.0 * std::numbers::pi);
241 }
242
244 {
245 auto ModuleData = DynExp::dynamic_ModuleData_cast<LockinAmplifierControl>(Instance->ModuleDataGetter());
246 ModuleData->GetLockinAmplifier()->AutoAdjustPhase();
247 }
248
250 {
251 auto ModuleData = DynExp::dynamic_ModuleData_cast<LockinAmplifierControl>(Instance->ModuleDataGetter());
252 ModuleData->GetLockinAmplifier()->SetTimeConstant(Value / 1e6);
253 }
254
256 {
257 auto ModuleData = DynExp::dynamic_ModuleData_cast<LockinAmplifierControl>(Instance->ModuleDataGetter());
258 ModuleData->GetLockinAmplifier()->SetFilterOrder(Value);
259 }
260
262 {
263 auto ModuleData = DynExp::dynamic_ModuleData_cast<LockinAmplifierControl>(Instance->ModuleDataGetter());
264 ModuleData->GetLockinAmplifier()->SetTriggerMode(static_cast<DynExpInstr::LockinAmplifierDefs::TriggerModeType>(Index + 1));
265 }
266
268 {
269 auto ModuleData = DynExp::dynamic_ModuleData_cast<LockinAmplifierControl>(Instance->ModuleDataGetter());
270 ModuleData->GetLockinAmplifier()->SetTriggerEdge(static_cast<DynExpInstr::LockinAmplifierDefs::TriggerEdgeType>(Index + 1));
271 }
272
274 {
275 auto ModuleData = DynExp::dynamic_ModuleData_cast<LockinAmplifierControl>(Instance->ModuleDataGetter());
276 ModuleData->GetLockinAmplifier()->ForceTrigger();
277 }
278
280 {
281 auto ModuleData = DynExp::dynamic_ModuleData_cast<LockinAmplifierControl>(Instance->ModuleDataGetter());
282 ModuleData->GetLockinAmplifier()->SetSignalType(static_cast<DynExpInstr::LockinAmplifierDefs::SignalType>(Index));
283 }
284
286 {
287 auto ModuleData = DynExp::dynamic_ModuleData_cast<LockinAmplifierControl>(Instance->ModuleDataGetter());
288 ModuleData->GetLockinAmplifier()->SetSamplingRate(Value);
289 }
290
291 void LockinAmplifierControl::OnEnableClicked(DynExp::ModuleInstance* Instance, Qt::CheckState State) const
292 {
293 auto ModuleData = DynExp::dynamic_ModuleData_cast<LockinAmplifierControl>(Instance->ModuleDataGetter());
294 ModuleData->GetLockinAmplifier()->SetEnable(State == Qt::CheckState::Checked);
295 }
296
298 {
299 auto ModuleData = DynExp::dynamic_ModuleData_cast<LockinAmplifierControl>(Instance->ModuleDataGetter());
300 ModuleData->GetLockinAmplifier()->PersistDataToParams();
301 }
302}
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)
std::unique_ptr< Ui::LockinAmplifierControl > ui
LockinAmplifierControlWidget(LockinAmplifierControl &Owner, QModuleWidget *parent=nullptr)
void OnSignalTypeChanged(DynExp::ModuleInstance *Instance, int Index) const
void OnEnableClicked(DynExp::ModuleInstance *Instance, Qt::CheckState State) 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 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:788
Refer to ParamsBase::dispatch_tag.
Definition Module.h:191
Defines data for a thread belonging to a ModuleBase instance. Refer to RunnableInstance.
Definition Module.h:840
const ModuleBase::ModuleDataGetterType ModuleDataGetter
Getter for module's data. Refer to ModuleBase::ModuleDataGetterType.
Definition Module.h:872
Refer to ParamsBase::dispatch_tag.
Definition Object.h:2018
QModuleWidget * Widget
User interface widget belonging to the module.
Definition Module.h:1807
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:1816
const Object::ParamsGetterType ParamsGetter
Invoke to obtain the parameters (derived from ParamsBase) of Owner.
Definition Object.h:3710
void UnlockObject(LinkedObjectWrapperContainer< ObjectT > &ObjectWrapperContainer)
Unlocks an Object instance stored in the LinkedObjectWrapperContainer ObjectWrapperContainer....
Definition Object.h:3609
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:3593
const auto & GetOwner() const noexcept
Returns Owner.
Definition Object.h:3556
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:262
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:688
Accumulates include statements to provide a precompiled header.