4#include "moc_LaserScanningSpectroscopy.cpp"
5#include "ui_LaserScanningSpectroscopy.h"
11 : QModuleWidget(Owner, parent),
17 this->addAction(
ui->action_Stop);
24 const QSignalBlocker SBLowerFrequencyLimitBlocker(
ui->SBLowerFrequencyLimit);
25 ui->SBLowerFrequencyLimit->setRange(ModuleData->GetLaser()->GetMinFrequency() * 1e-9, ModuleData->GetLaser()->GetMaxFrequency() * 1e-9);
26 ui->SBLowerFrequencyLimit->setValue(ModuleData->GetLaser()->GetMinFrequency() * 1e-9);
28 const QSignalBlocker SBUpperFrequencyLimitBlocker(
ui->SBUpperFrequencyLimit);
29 ui->SBUpperFrequencyLimit->setRange(ModuleData->GetLaser()->GetMinFrequency() * 1e-9, ModuleData->GetLaser()->GetMaxFrequency() * 1e-9);
30 ui->SBUpperFrequencyLimit->setValue((ModuleData->GetLaser()->GetMinFrequency() + ModuleData->GetLaser()->GetModeHopFreeTuningRange()) * 1e-9);
32 const QSignalBlocker SBFrequencyRangeBlocker(
ui->SBFrequencyRange);
33 ui->SBFrequencyRange->setRange(0.0, ModuleData->GetLaser()->GetModeHopFreeTuningRange() * 1e-9);
34 ui->SBFrequencyRange->setValue(ModuleData->GetLaser()->GetModeHopFreeTuningRange() * 1e-9);
36 const QSignalBlocker SBCenterFrequencyBlocker(
ui->SBCenterFrequency);
37 ui->SBCenterFrequency->setRange(ModuleData->GetLaser()->GetMinFrequency() * 1e-9 + 0.5 * ModuleData->GetLaser()->GetModeHopFreeTuningRange() * 1e-9, ModuleData->GetLaser()->GetMaxFrequency() * 1e-9 - 0.5 * ModuleData->GetLaser()->GetModeHopFreeTuningRange() * 1e-9);
38 ui->SBCenterFrequency->setValue(ModuleData->GetLaser()->GetMinFrequency() * 1e-9 + 0.5 * ModuleData->GetLaser()->GetModeHopFreeTuningRange() * 1e-9);
40 const QSignalBlocker SBStepSizeBlocker(
ui->SBStepSize);
41 ui->SBStepSize->setRange(1, 10000);
42 ui->SBStepSize->setValue(100);
44 const QSignalBlocker SBNumberOfStepsBlocker(
ui->SBNumberOfSteps);
45 ui->SBNumberOfSteps->setRange(1, 10000);
46 ui->SBNumberOfSteps->setValue(
ui->SBFrequencyRange->value() * 1e3 /
ui->SBStepSize->value());
48 const QSignalBlocker SBNumberOfRepetitionsBlocker(
ui->SBNumberOfRepetitions);
49 ui->SBNumberOfRepetitions->setRange(1, 10000);
50 ui->SBNumberOfRepetitions->setValue(1);
52 ModuleData->LowerFrequencyLimit =
ui->SBLowerFrequencyLimit->value() * 1e9;
53 ModuleData->UpperFrequencyLimit =
ui->SBUpperFrequencyLimit->value() * 1e9;
54 ModuleData->FrequencyRange =
ui->SBFrequencyRange->value() * 1e9;
55 ModuleData->CenterFrequency =
ui->SBCenterFrequency->value() * 1e9;
56 ModuleData->StepSize =
ui->SBStepSize->value() * 1e6;
57 ModuleData->NumberOfSteps =
ui->SBNumberOfSteps->value();
58 ModuleData->NumberOfRepetitions =
ui->SBNumberOfRepetitions->value();
59 ModuleData->ScanBackAndForth =
ui->CBScanBackAndForth->isChecked();
61 ModuleData->ScanStartFrequency =
ui->RBStartAtMinimum->isChecked() ? ModuleData->LowerFrequencyLimit : ModuleData->UpperFrequencyLimit;
62 ModuleData->ScanEndFrequency =
ui->RBStartAtMinimum->isChecked() ? ModuleData->UpperFrequencyLimit : ModuleData->LowerFrequencyLimit;
70 auto Filename =
Util::PromptSaveFilePathModule(
this,
"Select directory and filename prefix for saving data",
".csv",
"Comma-separated values file (*.csv)");
71 if (Filename.isEmpty())
75 ui->LEPath->setText(Filename);
111 : QModuleBase(OwnerThreadID, std::move(Params)),
112 StateMachine(ReadyState, WaitForSettingFrequencyState, WaitForCapturingState)
122 ModuleData->LaserState = DynExp::dynamic_InstrumentData_cast<DynExpInstr::Laser>(
ModuleData->GetLaser()->GetInstrumentData())->GetLaserState();
147 auto Widget = std::make_unique<LaserScanningSpectroscopyWidget>(*
this);
170 auto Widget = GetWidget<LaserScanningSpectroscopyWidget>();
174 std::string UIMessage;
177 auto ModuleData = DynExp::dynamic_ModuleData_cast<LaserScanningSpectroscopy>(ModuleDataGetter());
183 Widget->GetUI()->action_StepwiseScan->setEnabled(
Ready);
185 Widget->GetUI()->SBLowerFrequencyLimit->setEnabled(
Ready);
186 Widget->GetUI()->SBUpperFrequencyLimit->setEnabled(
Ready);
187 Widget->GetUI()->SBFrequencyRange->setEnabled(
Ready);
188 Widget->GetUI()->SBCenterFrequency->setEnabled(
Ready);
190 Widget->GetUI()->SBNumberOfSteps->setEnabled(
Ready);
191 Widget->GetUI()->SBNumberOfRepetitions->setEnabled(
Ready);
196 Widget->GetUI()->PBLaserScanningSpectroscopyProgress->setVisible(!
Ready);
197 Widget->GetUI()->PBLaserScanningSpectroscopyProgress->setValue(
static_cast<int>(100.0 *
200 if (SettingFrequency)
201 Widget->GetUI()->LLaserScanningSpectroscopyState->setText(
" Stabilizing");
203 Widget->GetUI()->LLaserScanningSpectroscopyState->setText(
" Capturing");
205 Widget->GetUI()->LLaserScanningSpectroscopyState->setText(
" Ready");
212 const QSignalBlocker LEPathBlocker(
Widget->GetUI()->LEPath);
213 Widget->GetUI()->LEPath->setText(QString::fromStdString(
ModuleData->FileSavePath.string()));
225 if (!UIMessage.empty())
226 QMessageBox::warning(
Widget,
"Laser Control", UIMessage.data());
248 double Frequency = 0.0;
262 ModuleData->GetLaser()->SetFrequency(Frequency);
268 SavePath.replace_filename(SavePath.filename().stem().concat(FilenameSuffix));
269 std::filesystem::create_directories(SavePath.parent_path());
276 auto ModuleParams = DynExp::dynamic_Params_cast<LaserScanningSpectroscopy>(Instance->
ParamsGetter());
279 if (ModuleParams->PLECommunicator.ContainsID())
284 if (ModuleParams->WFCommunicator.ContainsID())
319 ModuleData->LaserScanningSpectroscopyProgress = 0;
323 auto ModuleParams = DynExp::dynamic_Params_cast<LaserScanningSpectroscopy>(Instance->
ParamsGetter());
324 WaitingEndTimePoint = std::chrono::system_clock::now() + std::chrono::milliseconds(ModuleParams->CapturingTimeDifference);
352 auto Widget = GetWidget<LaserScanningSpectroscopyWidget>();
354 double NewFrequencyRange =
ModuleData->UpperFrequencyLimit - LowerFrequencyLimit * 1e9;
355 ModuleData->LowerFrequencyLimit = LowerFrequencyLimit * 1e9;
357 if (NewFrequencyRange < 0)
359 NewFrequencyRange =
ModuleData->FrequencyRange;
360 ModuleData->UpperFrequencyLimit = LowerFrequencyLimit * 1e9 + NewFrequencyRange;
362 else if (NewFrequencyRange >
ModuleData->ModeHopFreeTuningRange)
364 NewFrequencyRange =
ModuleData->ModeHopFreeTuningRange;
365 ModuleData->UpperFrequencyLimit = LowerFrequencyLimit * 1e9 + NewFrequencyRange;
369 ModuleData->CenterFrequency = LowerFrequencyLimit * 1e9 + NewFrequencyRange / 2;
370 ModuleData->FrequencyRange = NewFrequencyRange;
372 ModuleData->GetLaser()->SetScanRange(NewFrequencyRange);
374 const QSignalBlocker SBUpperFrequencyLimitBlocker(
Widget->GetUI()->SBUpperFrequencyLimit);
375 const QSignalBlocker SBFrequencyRangeBlocker(
Widget->GetUI()->SBFrequencyRange);
376 const QSignalBlocker SBCenterFrequencyBlocker(
Widget->GetUI()->SBCenterFrequency);
377 const QSignalBlocker SBNumberOfStepsBlocker(
Widget->GetUI()->SBNumberOfSteps);
378 Widget->GetUI()->SBUpperFrequencyLimit->setValue(
ModuleData->UpperFrequencyLimit / 1e9);
379 Widget->GetUI()->SBFrequencyRange->setValue(
ModuleData->FrequencyRange / 1e9);
380 Widget->GetUI()->SBCenterFrequency->setValue(
ModuleData->CenterFrequency / 1e9);
387 auto Widget = GetWidget<LaserScanningSpectroscopyWidget>();
389 double NewFrequencyRange = UpperFrequencyLimit * 1e9 -
ModuleData->LowerFrequencyLimit;
390 ModuleData->UpperFrequencyLimit = UpperFrequencyLimit * 1e9;
392 if (NewFrequencyRange < 0)
394 NewFrequencyRange =
ModuleData->FrequencyRange;
395 ModuleData->LowerFrequencyLimit = UpperFrequencyLimit * 1e9 - NewFrequencyRange;
397 else if (NewFrequencyRange >
ModuleData->ModeHopFreeTuningRange)
399 NewFrequencyRange =
ModuleData->ModeHopFreeTuningRange;
400 ModuleData->LowerFrequencyLimit = UpperFrequencyLimit * 1e9 - NewFrequencyRange;
404 ModuleData->CenterFrequency = UpperFrequencyLimit * 1e9 - NewFrequencyRange / 2;
405 ModuleData->FrequencyRange = NewFrequencyRange;
407 ModuleData->GetLaser()->SetScanRange(NewFrequencyRange);
409 const QSignalBlocker SBLowerFrequencyLimitBlocker(
Widget->GetUI()->SBLowerFrequencyLimit);
410 const QSignalBlocker SBFrequencyRangeBlocker(
Widget->GetUI()->SBFrequencyRange);
411 const QSignalBlocker SBCenterFrequencyBlocker(
Widget->GetUI()->SBCenterFrequency);
412 const QSignalBlocker SBNumberOfStepsBlocker(
Widget->GetUI()->SBNumberOfSteps);
413 Widget->GetUI()->SBLowerFrequencyLimit->setValue(
ModuleData->LowerFrequencyLimit / 1e9);
414 Widget->GetUI()->SBFrequencyRange->setValue(NewFrequencyRange / 1e9);
415 Widget->GetUI()->SBCenterFrequency->setValue(
ModuleData->CenterFrequency / 1e9);
422 auto Widget = GetWidget<LaserScanningSpectroscopyWidget>();
424 ModuleData->FrequencyRange = FrequencyRange * 1e9;
425 const double NewFrequencyRange = FrequencyRange * 1e9 <=
ModuleData->ModeHopFreeTuningRange ? FrequencyRange * 1e9 :
ModuleData->ModeHopFreeTuningRange;
430 ModuleData->FrequencyRange = NewFrequencyRange;
432 ModuleData->GetLaser()->SetScanRange(NewFrequencyRange);
434 const QSignalBlocker SBUpperFrequencyLimitBlocker(
Widget->GetUI()->SBUpperFrequencyLimit);
435 const QSignalBlocker SBFrequencyRangeBlocker(
Widget->GetUI()->SBFrequencyRange);
436 const QSignalBlocker SBCenterFrequencyBlocker(
Widget->GetUI()->SBCenterFrequency);
437 const QSignalBlocker SBNumberOfStepsBlocker(
Widget->GetUI()->SBNumberOfSteps);
438 Widget->GetUI()->SBUpperFrequencyLimit->setValue(
ModuleData->UpperFrequencyLimit / 1e9);
439 Widget->GetUI()->SBFrequencyRange->setValue(
ModuleData->FrequencyRange / 1e9);
440 Widget->GetUI()->SBCenterFrequency->setValue(
ModuleData->CenterFrequency / 1e9);
446 auto Widget = GetWidget<LaserScanningSpectroscopyWidget>();
449 ModuleData->CenterFrequency = CenterFrequency * 1e9;
455 const QSignalBlocker SBLowerFrequencyLimitBlocker(
Widget->GetUI()->SBLowerFrequencyLimit);
456 const QSignalBlocker SBUpperFrequencyLimitBlocker(
Widget->GetUI()->SBUpperFrequencyLimit);
457 Widget->GetUI()->SBLowerFrequencyLimit->setValue(
ModuleData->LowerFrequencyLimit / 1e9);
458 Widget->GetUI()->SBUpperFrequencyLimit->setValue(
ModuleData->UpperFrequencyLimit / 1e9);
463 auto Widget = GetWidget<LaserScanningSpectroscopyWidget>();
471 const QSignalBlocker SBNumberOfStepsBlocker(
Widget->GetUI()->SBNumberOfSteps);
477 auto Widget = GetWidget<LaserScanningSpectroscopyWidget>();
485 const QSignalBlocker SBStepSizeBlocker(
Widget->GetUI()->SBStepSize);
492 ModuleData->NumberOfRepetitions = NumberOfRepetitions;
503 auto Widget = GetWidget<LaserScanningSpectroscopyWidget>();
506 ModuleData->IsStepwiseScan =
Widget->GetUI()->action_StepwiseScan->isChecked();
527 ModuleData->FileSavePath = std::filesystem::path(SaveFilename);
557 auto ModuleParams = DynExp::dynamic_Params_cast<LaserScanningSpectroscopy>(Instance->
ParamsGetter());
558 WaitingEndTimePoint = std::chrono::system_clock::now() + std::chrono::milliseconds(ModuleParams->CapturingTimeDifference);
571 auto LaserInstrData = DynExp::dynamic_InstrumentData_cast<DynExpInstr::Laser>(
ModuleData->GetLaser()->GetInstrumentData());
583 auto ModuleParams = DynExp::dynamic_Params_cast<LaserScanningSpectroscopy>(Instance.
ParamsGetter());
598 +
"_CurrentFreqHz_" +
Util::ToStr(LaserInstrData->GetFrequencyValue(), 0)
603 ModuleData->LaserScanningSpectroscopyProgress++;
Implementation of a module to perform photoluminescence excitation spectroscopy.
@ Startup
The laser is warming up.
@ EmissionEnabledConstant
The laser is emitting in constant mode.
@ Ready
The laser is ready for emission.
This event signals that an action (like a measurement) started by a TriggerEvent has been completed.
double ScanStartFrequency
void ResetImpl(dispatch_tag< QModuleDataBase >) override final
int LaserScanningSpectroscopyProgress
double LowerFrequencyLimit
StateType LaserScanningSpectroscopyState
std::filesystem::path FileSavePath
double ModeHopFreeTuningRange
DynExpInstr::LaserData::LaserStateType LaserState
double UpperFrequencyLimit
void OnStop(DynExp::ModuleInstance *Instance) const
std::chrono::system_clock::time_point WaitingEndTimePoint
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 OnFinishedCapturing(DynExp::ModuleInstance *Instance) const
StateType WaitForSettingFrequencyStateFunc(DynExp::ModuleInstance &Instance)
void OnStart(DynExp::ModuleInstance *Instance) const
void OnStartAtToggled(DynExp::ModuleInstance *Instance, bool) const
void OnNumberOfRepetitionsChanged(DynExp::ModuleInstance *Instance, int NumberOfRepetitions) const
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 FrequencyStep(DynExp::ModuleInstance *Instance) const
StateType WaitForCapturingStateFunc(DynExp::ModuleInstance &Instance)
std::filesystem::path BuildFilename(Util::SynchronizedPointer< ModuleDataType > &ModuleData, std::string_view FilenameSuffix) const
void OnStepSizeChanged(DynExp::ModuleInstance *Instance, double StepSize) const
Util::StateMachine< StateMachineStateType > StateMachine
bool IsSettingFrequencyState() const noexcept
void OnExit(DynExp::ModuleInstance *Instance) const override final
This event is triggered right before the module thread terminates (not due to an exception,...
bool IsCapturingState() const noexcept
void ResetImpl(dispatch_tag< QModuleBase >) override final
size_t NumFailedUpdateAttempts
bool IsReadyState() const noexcept
StateType ReadyStateFunc(DynExp::ModuleInstance &Instance)
void OnLowerFrequencyLimitChanged(DynExp::ModuleInstance *Instance, double LowerFrequencyLimit) const
void OnPathChanged(DynExp::ModuleInstance *Instance, const std::string &SaveFilename) const
void OnNumberOfStepsChanged(DynExp::ModuleInstance *Instance, int NumberOfSteps) const
void OnStartClicked(DynExp::ModuleInstance *Instance, bool) const
void OnUpperFrequencyLimitChanged(DynExp::ModuleInstance *Instance, double UpperFrequencyLimit) const
void UpdateUIChild(const ModuleBase::ModuleDataGetterType &ModuleDataGetter) override final
void OnScanBackAndForthToggled(DynExp::ModuleInstance *Instance, bool Checked) const
void OnFrequencyRangeChanged(DynExp::ModuleInstance *Instance, double FrequencyRange) const
void OnCenterFrequencyChanged(DynExp::ModuleInstance *Instance, double CenterFrequency) const
void OnStopClicked(DynExp::ModuleInstance *Instance, bool) const
This event tells the receiver where to store e.g. acquired data.
This event is intended to make the receiver prepare an action (like a measurement) that is started wh...
This event is intended to make the receiver stop an action (like a measurement).
This event is intended to make the receiver start an action (like a measurement) after it received a ...
static void Register(const ModuleBase &Listener, CallableT EventFunc, ItemIDType CommunicatorID=ItemIDNotSet)
Registers/Subscribes module Listener to the event with the event function EventFunc....
static void Deregister(const ModuleBase &Listener)
Deregisters/unsubscribes module Listener from the event, regardless of the inter-module communicator ...
const std::unique_ptr< ModuleDataType > ModuleData
Module data belonging to this ModuleBase instance.
Refer to ParamsBase::dispatch_tag.
Defines data for a thread belonging to a ModuleBase instance. Refer to RunnableInstance.
const ModuleBase::ModuleDataGetterType ModuleDataGetter
Getter for module's data. Refer to ModuleBase::ModuleDataGetterType.
Refer to ParamsBase::dispatch_tag.
QModuleWidget * Widget
User interface widget belonging to the module.
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....
const Object::ParamsGetterType ParamsGetter
Invoke to obtain the parameters (derived from ParamsBase) of Owner.
void UnlockObject(LinkedObjectWrapperContainer< ObjectT > &ObjectWrapperContainer)
Unlocks an Object instance stored in the LinkedObjectWrapperContainer ObjectWrapperContainer....
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...
const auto & GetOwner() const noexcept
Returns Owner.
Pointer to lock a class derived from ISynchronizedPointerLockable for synchronizing between threads....
Thrown when an operation timed out before it could be completed, especially used for locking shared d...
@ WaitForSettingFrequency
std::unique_ptr< ParamsBase > ParamsBasePtrType
Alias for a pointer to the parameter system base class ParamsBase.
DynExpErrorCodes
DynExp's error codes
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.
QString PromptSaveFilePathModule(DynExp::QModuleWidget *Parent, const QString &Title, const QString &DefaultSuffix, const QString &NameFilter)
Works as PromptOpenFilePath() but asks the user to select a single file which does not need to exist....
Accumulates include statements to provide a precompiled header.