DynExp
Highly flexible laboratory automation for dynamically changing experiments.
Loading...
Searching...
No Matches
LaserControl.cpp
Go to the documentation of this file.
1// This file is part of DynExp.
2
3#include "stdafx.h"
4#include "moc_LaserControl.cpp"
5#include "ui_LaserControl.h"
6#include "LaserControl.h"
7
8namespace DynExpModule
9{
11 : QModuleWidget(Owner, parent),
12 ui(std::make_unique<Ui::LaserControl>())
13 {
14 ui->setupUi(this);
15
16 // For shortcuts
17 this->addAction(ui->action_Enable);
18 }
19
21 {
22 const QSignalBlocker SBFrequencyBlocker(ui->SBFrequency);
23 ui->SBFrequency->setRange(ModuleData->HardwareMinFrequency * 1e-12, ModuleData->HardwareMaxFrequency * 1e-12);
24 ui->SBFrequency->setValue(ModuleData->HardwareMinFrequency * 1e-12);
25
26 const QSignalBlocker SBWavelengthBlocker(ui->SBWavelength);
27 ui->SBWavelength->setRange(Util::ConvertFrequencyWavelength(ModuleData->HardwareMaxFrequency) * 1e9, Util::ConvertFrequencyWavelength(ModuleData->HardwareMinFrequency) * 1e9);
28 ui->SBWavelength->setValue(Util::ConvertFrequencyWavelength(ModuleData->HardwareMaxFrequency) * 1e9);
29
30 const QSignalBlocker SBIntensityBlocker(ui->SBIntensity);
31 ui->SBIntensity->setRange(ModuleData->HardwareMinIntensity * 1e3, ModuleData->HardwareMaxIntensity * 1e3);
32 ui->SBIntensity->setValue(ModuleData->HardwareMinIntensity * 1e3);
33
34 const QSignalBlocker SBScanRangeBlocker(ui->SBScanRange);
35 ui->SBScanRange->setRange(ModuleData->HardwareMinScanRange * 1e-9, ModuleData->HardwareMaxScanRange * 1e-9);
36
37 const QSignalBlocker SBScanRateBlocker(ui->SBScanRate);
38 ui->SBScanRate->setRange(ModuleData->HardwareMinScanRate * 1e-9, ModuleData->HardwareMaxScanRate * 1e-9);
39
40 ui->GBFrequencyWavelength->setVisible(ModuleData->HardwareMinFrequency != ModuleData->HardwareMaxFrequency);
41 ui->GBIntensity->setVisible(ModuleData->HardwareMinIntensity != ModuleData->HardwareMaxIntensity);
42 ui->GBScanSettings->setVisible(ModuleData->HardwareMinScanRange != ModuleData->HardwareMaxScanRange);
43 ui->action_Scan->setEnabled(ModuleData->HardwareMinScanRange != ModuleData->HardwareMaxScanRange);
44 }
45
47 {
48 if (std::isnan(ModuleData->CurrentFrequency))
49 {
50 ui->LActualFrequency->setText("Output unstable");
51 ui->LActualWavelength->setText("Output unstable");
52 ui->LActualFrequency->setStyleSheet(DynExpUI::StatusBarWarningStyleSheet);
53 ui->LActualWavelength->setStyleSheet(DynExpUI::StatusBarWarningStyleSheet);
54 }
55 else
56 {
57 ui->LActualFrequency->setText(QString::number(ModuleData->CurrentFrequency * 1e-12, 'f', 6) + " THz");
58 ui->LActualWavelength->setText(QString::number(Util::ConvertFrequencyWavelength(ModuleData->CurrentFrequency) * 1e9, 'f', 6) + " nm");
59 ui->LActualFrequency->setStyleSheet("");
60 ui->LActualWavelength->setStyleSheet("");
61 }
62
63 if (ModuleData->CurrentIntensity < ModuleData->HardwareMinIntensity)
64 {
65 ui->LActualIntensity->setText(QString::number(ModuleData->CurrentIntensity * 1e3, 'f', 3) + " mW (Power low)");
66 ui->LActualIntensity->setStyleSheet(DynExpUI::StatusBarWarningStyleSheet);
67 }
68 else
69 {
70 ui->LActualIntensity->setText(QString::number(ModuleData->CurrentIntensity * 1e3, 'f', 3) + " mW");
71 ui->LActualIntensity->setStyleSheet("");
72 }
73
74 if (!ui->SBScanRange->hasFocus())
75 {
76 const QSignalBlocker Blocker(ui->SBScanRange);
77 ui->SBScanRange->setValue(ModuleData->CurrentScanRange * 1e-9);
78 }
79
80 if (!ui->SBScanRate->hasFocus())
81 {
82 const QSignalBlocker Blocker(ui->SBScanRate);
83 ui->SBScanRate->setValue(ModuleData->CurrentScanRate * 1e-9);
84 }
85
86 switch (ModuleData->LaserState)
87 {
89 ui->LState->setText(" Startup...");
90 ui->LState->setStyleSheet(DynExpUI::StatusBarReadyStyleSheetBright);
91 break;
93 ui->LState->setText(" Emitting in constant mode.");
94 ui->LState->setStyleSheet(DynExpUI::StatusBarBusyStyleSheet);
95 break;
97 ui->LState->setText(" Emitting in scanning mode.");
98 ui->LState->setStyleSheet(DynExpUI::StatusBarBusyStyleSheet);
99 break;
101 ui->LState->setText(" The Laser is in an error state.");
102 ui->LState->setStyleSheet(DynExpUI::StatusBarErrorStyleSheet);
103 break;
104 default:
105 ui->LState->setText(" Laser is ready for emission.");
106 ui->LState->setStyleSheet(DynExpUI::StatusBarReadyStyleSheetBright);
107 }
108 }
109
111 {
112 switch (FrequencyUnit)
113 {
115 return Value;
117 return Util::ConvertFrequencyWavelength(Value) * 1e9;
118 default:
119 throw Util::NotImplementedException("Cannot convert frequency in Hz to the unit required by the laser instrument.");
120 }
121 }
122
124 {
125 switch (FrequencyUnit)
126 {
128 return Value;
130 return Util::ConvertFrequencyWavelength(Value * 1e-9);
131 default:
132 throw Util::NotImplementedException("Cannot convert frequency in unit required by the laser instrument to Hz.");
133 }
134 }
135
137 {
138 switch (IntensityUnit)
139 {
141 return Value;
142 default:
143 throw Util::NotImplementedException("Cannot convert intensity in W to the unit required by the laser instrument.");
144 }
145 }
146
148 {
149 switch (IntensityUnit)
150 {
152 return Value;
153 default:
154 throw Util::NotImplementedException("Cannot convert intensity in unit required by the laser instrument to W.");
155 }
156 }
157
162
184
186 {
187 try
188 {
189 auto ModuleData = DynExp::dynamic_ModuleData_cast<LaserControl>(Instance.ModuleDataGetter());
190 auto InstrData = DynExp::dynamic_InstrumentData_cast<DynExpInstr::Laser>(ModuleData->GetLaser()->GetInstrumentData());
191
192 ModuleData->CurrentFrequency = ModuleData->FrequencyInLaserUnitToHz(InstrData->GetFrequencyValue());
193 ModuleData->CurrentIntensity = ModuleData->IntensityInLaserUnitToW(InstrData->GetIntensityValue());
194 ModuleData->CurrentScanRange = ModuleData->FrequencyInLaserUnitToHz(InstrData->GetScanRangeValue());
195 ModuleData->CurrentScanRate = ModuleData->FrequencyInLaserUnitToHz(InstrData->GetScanRateValue());
196 ModuleData->LaserState = InstrData->GetLaserState();
197
199 } // ModuleData and instruments' data unlocked here.
200 catch (const Util::TimeoutException& e)
201 {
202 if (NumFailedUpdateAttempts++ >= 3)
203 Instance.GetOwner().SetWarning(e);
204 }
205
207 }
208
213
214 std::unique_ptr<DynExp::QModuleWidget> LaserControl::MakeUIWidget()
215 {
216 auto Widget = std::make_unique<LaserControlWidget>(*this);
217
218 Connect(Widget->GetUI()->action_Enable, &QAction::toggled, this, &LaserControl::OnEnableToggled);
219 Connect(Widget->GetUI()->action_Scan, &QAction::toggled, this, &LaserControl::OnScanToggled);
220 Connect(Widget->GetUI()->SBFrequency, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &LaserControl::OnFrequencyValueChanged);
221 Connect(Widget->GetUI()->SBWavelength, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &LaserControl::OnWavelengthValueChanged);
222 Connect(Widget->GetUI()->SBIntensity, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &LaserControl::OnIntensityValueChanged);
223 Connect(Widget->GetUI()->SBScanRange, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &LaserControl::OnScanRangeValueChanged);
224 Connect(Widget->GetUI()->SBScanRate, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &LaserControl::OnScanRateValueChanged);
225
226 return Widget;
227 }
228
229 void LaserControl::UpdateUIChild(const ModuleBase::ModuleDataGetterType& ModuleDataGetter)
230 {
231 auto Widget = GetWidget<LaserControlWidget>();
232 auto ModuleData = DynExp::dynamic_ModuleData_cast<LaserControl>(ModuleDataGetter());
233
234 if (!ModuleData->IsUIInitialized())
235 {
236 Widget->InitializeUI(ModuleData);
237 ModuleData->SetUIInitialized();
238 }
239
240 Widget->UpdateUI(ModuleData);
241 }
242
244 {
245 auto ModuleParams = DynExp::dynamic_Params_cast<LaserControl>(Instance->ParamsGetter());
246 auto ModuleData = DynExp::dynamic_ModuleData_cast<LaserControl>(Instance->ModuleDataGetter());
247
248 Instance->LockObject(ModuleParams->Laser, ModuleData->GetLaser());
249
250 ModuleData->FrequencyUnit = ModuleData->GetLaser()->GetFrequencyUnit();
251 ModuleData->IntensityUnit = ModuleData->GetLaser()->GetIntensityUnit();
252 ModuleData->HardwareMinFrequency = ModuleData->FrequencyInLaserUnitToHz(ModuleData->GetLaser()->GetMinFrequency());
253 ModuleData->HardwareMaxFrequency = ModuleData->FrequencyInLaserUnitToHz(ModuleData->GetLaser()->GetMaxFrequency());
254 ModuleData->HardwareMinIntensity = ModuleData->IntensityInLaserUnitToW(ModuleData->GetLaser()->GetMinIntensity());
255 ModuleData->HardwareMaxIntensity = ModuleData->IntensityInLaserUnitToW(ModuleData->GetLaser()->GetMaxIntensity());
256 ModuleData->HardwareMinScanRange = ModuleData->FrequencyInLaserUnitToHz(ModuleData->GetLaser()->GetMinScanRange());
257 ModuleData->HardwareMaxScanRange = ModuleData->FrequencyInLaserUnitToHz(ModuleData->GetLaser()->GetMaxScanRange());
258 ModuleData->HardwareMinScanRate = ModuleData->FrequencyInLaserUnitToHz(ModuleData->GetLaser()->GetMinScanRate());
259 ModuleData->HardwareMaxScanRate = ModuleData->FrequencyInLaserUnitToHz(ModuleData->GetLaser()->GetMaxScanRate());
260 ModuleData->HardwareModeHopFreeTuningRange = ModuleData->FrequencyInLaserUnitToHz(ModuleData->GetLaser()->GetModeHopFreeTuningRange());
261 }
262
264 {
265 auto ModuleData = DynExp::dynamic_ModuleData_cast<LaserControl>(Instance->ModuleDataGetter());
266
267 Instance->UnlockObject(ModuleData->GetLaser());
268 }
269
270 void LaserControl::OnEnableToggled(DynExp::ModuleInstance* Instance, bool Checked) const
271 {
272 auto ModuleData = DynExp::dynamic_ModuleData_cast<LaserControl>(Instance->ModuleDataGetter());
273
274 if (Checked)
275 ModuleData->GetLaser()->Enable();
276 else
277 ModuleData->GetLaser()->Disable();
278 }
279
280 void LaserControl::OnScanToggled(DynExp::ModuleInstance* Instance, bool Checked) const
281 {
282 auto ModuleData = DynExp::dynamic_ModuleData_cast<LaserControl>(Instance->ModuleDataGetter());
283
284 if (Checked)
285 ModuleData->GetLaser()->ScanContinuously();
286 else
287 ModuleData->GetLaser()->DisableScan();
288 }
289
291 {
292 auto ModuleData = DynExp::dynamic_ModuleData_cast<LaserControl>(Instance->ModuleDataGetter());
293
294 const double FrequencyInHz = Util::ConvertFrequencyWavelength(Value * 1e-9);
295 if (ModuleData->CurrentFrequency != FrequencyInHz)
296 ModuleData->GetLaser()->SetFrequency(ModuleData->FrequencyInHzToLaserUnit(FrequencyInHz));
297 }
298
300 {
301 auto ModuleData = DynExp::dynamic_ModuleData_cast<LaserControl>(Instance->ModuleDataGetter());
302
303 const double FrequencyInHz = Value * 1e12;
304 if (ModuleData->CurrentFrequency != FrequencyInHz)
305 ModuleData->GetLaser()->SetFrequency(ModuleData->FrequencyInHzToLaserUnit(FrequencyInHz));
306 }
307
309 {
310 auto ModuleData = DynExp::dynamic_ModuleData_cast<LaserControl>(Instance->ModuleDataGetter());
311
312 const double IntensityInW = Value * 1e-3;
313 if (ModuleData->CurrentIntensity != IntensityInW)
314 ModuleData->GetLaser()->SetIntensity(ModuleData->IntensityInWToLaserUnit(IntensityInW));
315 }
316
318 {
319 auto ModuleData = DynExp::dynamic_ModuleData_cast<LaserControl>(Instance->ModuleDataGetter());
320
321 const double FrequencyInHz = Value * 1e9;
322 if (ModuleData->CurrentScanRange != FrequencyInHz)
323 ModuleData->GetLaser()->SetScanRange(ModuleData->FrequencyInHzToLaserUnit(FrequencyInHz));
324 }
325
327 {
328 auto ModuleData = DynExp::dynamic_ModuleData_cast<LaserControl>(Instance->ModuleDataGetter());
329
330 const double FrequencyInHz = Value * 1e9;
331 if (ModuleData->CurrentScanRate != FrequencyInHz)
332 ModuleData->GetLaser()->SetScanRate(ModuleData->FrequencyInHzToLaserUnit(FrequencyInHz));
333 }
334}
Implementation of a module to control a laser source.
@ Startup
The laser is warming up.
@ Error
The laser is in an error state.
@ EmissionEnabledConstant
The laser is emitting in constant mode.
@ EmissionEnabledScanning
The laser is emitting in scan mode.
@ Ready
The laser is ready for emission.
double IntensityInLaserUnitToW(double Value) const
DynExp::Units::UnitType FrequencyUnit
void ResetImpl(dispatch_tag< QModuleDataBase >) override final
double FrequencyInLaserUnitToHz(double Value) const
double FrequencyInHzToLaserUnit(double Value) const
double IntensityInWToLaserUnit(double Value) const
DynExpInstr::LaserData::LaserStateType LaserState
DynExp::Units::UnitType IntensityUnit
void InitializeUI(Util::SynchronizedPointer< LaserControlData > &ModuleData)
void UpdateUI(Util::SynchronizedPointer< LaserControlData > &ModuleData)
LaserControlWidget(LaserControl &Owner, QModuleWidget *parent=nullptr)
std::unique_ptr< Ui::LaserControl > ui
void OnScanToggled(DynExp::ModuleInstance *Instance, bool) const
void OnWavelengthValueChanged(DynExp::ModuleInstance *Instance, double Wavelength) const
void OnIntensityValueChanged(DynExp::ModuleInstance *Instance, double Intensity) 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 OnInit(DynExp::ModuleInstance *Instance) const override final
This event is triggered right before the module thread starts. Override it to lock instruments this m...
void UpdateUIChild(const ModuleBase::ModuleDataGetterType &ModuleDataGetter) override final
void OnScanRangeValueChanged(DynExp::ModuleInstance *Instance, double ScanRange) const
void OnScanRateValueChanged(DynExp::ModuleInstance *Instance, double ScanRate) const
void OnExit(DynExp::ModuleInstance *Instance) const override final
This event is triggered right before the module thread terminates (not due to an exception,...
void ResetImpl(dispatch_tag< QModuleBase >) override final
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 OnFrequencyValueChanged(DynExp::ModuleInstance *Instance, double Frequency) const
void OnEnableToggled(DynExp::ModuleInstance *Instance, bool) const
const std::unique_ptr< ModuleDataType > ModuleData
Module data belonging to this ModuleBase instance.
Definition Module.h:789
Refer to ParamsBase::dispatch_tag.
Definition Module.h:192
Defines data for a thread belonging to a ModuleBase instance. Refer to RunnableInstance.
Definition Module.h:841
const ModuleBase::ModuleDataGetterType ModuleDataGetter
Getter for module's data. Refer to ModuleBase::ModuleDataGetterType.
Definition Module.h:873
Refer to ParamsBase::dispatch_tag.
Definition Object.h:2026
QModuleWidget * Widget
User interface widget belonging to the module.
Definition Module.h:1816
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:1825
const Object::ParamsGetterType ParamsGetter
Invoke to obtain the parameters (derived from ParamsBase) of Owner.
Definition Object.h:3718
void UnlockObject(LinkedObjectWrapperContainer< ObjectT > &ObjectWrapperContainer)
Unlocks an Object instance stored in the LinkedObjectWrapperContainer ObjectWrapperContainer....
Definition Object.h:3617
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:3601
const auto & GetOwner() const noexcept
Returns Owner.
Definition Object.h:3564
Thrown when a requested feature is either under development and thus not implemented yet or when a sp...
Definition Exception.h:300
Pointer to lock a class derived from ISynchronizedPointerLockable for synchronizing between threads....
Definition Util.h:171
Thrown when an operation timed out before it could be completed, especially used for locking shared d...
Definition Exception.h:262
DynExp's module namespace contains the implementation of DynExp modules which extend DynExp's core fu...
constexpr auto StatusBarWarningStyleSheet
constexpr auto StatusBarReadyStyleSheetBright
constexpr auto StatusBarErrorStyleSheet
constexpr auto StatusBarBusyStyleSheet
@ Freq_Hz
Frequency in Hz.
@ Wavelength_nm
Wavelength in nm.
@ Power_W
Power in Watt (W)
DynExpErrorCodes
DynExp's error codes
Definition Exception.h:22
constexpr auto ConvertFrequencyWavelength(double Value) noexcept
Converts the frequency value of an electromagnetic wave in Hz to the corresponding wavelength in m an...
Definition Util.h:631
Accumulates include statements to provide a precompiled header.