4 #include "moc_SpectrumViewer.cpp"
10 : QModuleWidget(Owner, parent),
11 DataSeries(nullptr), DataChart(nullptr), XAxis(nullptr), YAxis(nullptr)
16 this->addAction(
ui.action_Run);
17 this->addAction(
ui.action_Stop);
21 ui.Spectrum->setRenderHint(QPainter::Antialiasing);
28 ui.SBExposureTime->setRange(ModuleData->MinExposureTime.count(), ModuleData->MaxExposureTime.count());
29 ui.SBExposureTime->setSuffix(
" " + QString::fromStdString(Util::ToUnitStr<DynExpInstr::SpectrometerData::TimeType>()));
30 ui.SBLowerFrequency->setRange(ModuleData->MinFrequency, ModuleData->MaxFrequency);
32 ui.SBUpperFrequency->setRange(ModuleData->MinFrequency, ModuleData->MaxFrequency);
46 XAxis =
new QValueAxis(
this);
47 YAxis =
new QValueAxis(
this);
49 XAxis->setLabelFormat(
"%d");
51 YAxis->setLabelFormat(
"%d");
68 const QSignalBlocker Blocker(
ui.action_SilentMode);
69 ui.action_SilentMode->setChecked(ModuleData->SilentModeEnabled);
72 if (!
ui.SBExposureTime->hasFocus())
74 const QSignalBlocker Blocker(
ui.SBExposureTime);
75 ui.SBExposureTime->setValue(ModuleData->CurrentExposureTime.count());
78 if (!
ui.SBLowerFrequency->hasFocus())
80 const QSignalBlocker Blocker(
ui.SBLowerFrequency);
81 ui.SBLowerFrequency->setValue(ModuleData->CurrentLowerFrequency);
84 if (!
ui.SBUpperFrequency->hasFocus())
86 const QSignalBlocker Blocker(
ui.SBUpperFrequency);
87 ui.SBUpperFrequency->setValue(ModuleData->CurrentUpperFrequency);
90 switch (ModuleData->CapturingState)
93 ui.LState->setText(
" Acquiring spectrum...");
97 ui.LState->setText(
" The spectrometer is in a warning state.");
101 ui.LState->setText(
" The spectrometer is in an error state.");
105 ui.LState->setText(
" Ready");
106 ui.LState->setStyleSheet(
"");
110 && ModuleData->CapturingProgress > 0);
111 ui.PBProgress->setValue(ModuleData->CapturingProgress > 0 ? Util::NumToT<int>(ModuleData->CapturingProgress) : 0);
153 if (Filename.isEmpty())
157 QMessageBox::warning(
this,
"DynExp - Error",
"Error writing data to file.");
173 std::stringstream CSVData;
174 CSVData << std::setprecision(6);
175 CSVData <<
"ExposureTime = " << ExposureTime.count() <<
" " << Util::ToUnitStr<DynExpInstr::SpectrometerData::TimeType>() <<
"\n";
176 CSVData <<
"HEADER_END\n";
180 for (
const auto& Sample : Points)
181 CSVData << Sample.x() <<
";" << Sample.y() <<
"\n";
183 return CSVData.str();
201 CurrentLowerFrequency = 0.0;
202 CurrentUpperFrequency = 0.0;
203 SilentModeEnabled =
false;
205 CapturingProgress = 0.0;
206 AutoSaveFilename.clear();
208 SpectrumRecordingPaused =
false;
210 UIInitialized =
false;
217 auto ModuleData = DynExp::dynamic_ModuleData_cast<SpectrumViewer>(Instance.
ModuleDataGetter());
218 auto InstrData = DynExp::dynamic_InstrumentData_cast<DynExpInstr::Spectrometer>(ModuleData->GetSpectrometer()->GetInstrumentData());
220 ModuleData->CurrentExposureTime = InstrData->GetCurrentExposureTime();
221 ModuleData->CurrentLowerFrequency = InstrData->GetCurrentLowerFrequency();
222 ModuleData->CurrentUpperFrequency = InstrData->GetCurrentUpperFrequency();
223 ModuleData->SilentModeEnabled = InstrData->GetSilentModeEnabled();
224 ModuleData->CapturingState = InstrData->GetCapturingState();
225 ModuleData->CapturingProgress = InstrData->GetCapturingProgress();
227 if (InstrData->HasSpectrum() && !ModuleData->SpectrumRecordingPaused)
229 ModuleData->CurrentSpectrum = ProcessSpectrum(InstrData->GetSpectrum(), ModuleData);
231 if (!ModuleData->CurrentSpectrum.Points.empty())
233 if (ModuleData->GetCommunicator().valid() && !ModuleData->AutoSaveFilename.empty())
236 ModuleData->AutoSaveFilename.clear();
240 NumFailedUpdateAttempts = 0;
244 if (NumFailedUpdateAttempts++ >= 3)
253 NumFailedUpdateAttempts = 0;
258 auto Widget = std::make_unique<SpectrumViewerWidget>(*
this);
272 auto Widget = GetWidget<SpectrumViewerWidget>();
273 auto ModuleData = DynExp::dynamic_ModuleData_cast<SpectrumViewer>(ModuleDataGetter());
275 if (!ModuleData->IsUIInitialized())
277 Widget->InitializeUI(ModuleData);
278 ModuleData->SetUIInitialized();
281 Widget->UpdateUI(ModuleData);
283 if (!ModuleData->CurrentSpectrum.Points.empty())
284 Widget->SetData(std::move(ModuleData->CurrentSpectrum), ModuleData->AcquisitionExposureTime);
291 TransformedSpectrum.
FrequencyUnit = Spectrum.GetFrequencyUnit();
292 TransformedSpectrum.
IntensityUnit = Spectrum.GetIntensityUnit();
294 if (!Spectrum.HasSpectrum())
295 return TransformedSpectrum;
297 double YMin(std::numeric_limits<double>::max()), YMax(std::numeric_limits<double>::lowest());
298 for (
const auto& Sample : Spectrum.GetSpectrum())
300 TransformedSpectrum.
Points.append({ Sample.first, Sample.second });
302 YMin = std::min(YMin, Sample.second);
303 YMax = std::max(YMax, Sample.second);
306 TransformedSpectrum.
MinValues = { Spectrum.GetSpectrum().begin()->first, YMin};
307 TransformedSpectrum.
MaxValues = { Spectrum.GetSpectrum().rbegin()->first, YMax};
309 if (!ModuleData->AutoSaveFilename.empty())
310 SaveSpectrum(TransformedSpectrum, ModuleData);
312 return TransformedSpectrum;
318 if (!
Util::SaveToFile(QString::fromStdString(ModuleData->AutoSaveFilename), Spectrum.
ToStr(ModuleData->CurrentExposureTime)))
331 auto ModuleParams = DynExp::dynamic_Params_cast<SpectrumViewer>(Instance->
ParamsGetter());
332 auto ModuleData = DynExp::dynamic_ModuleData_cast<SpectrumViewer>(Instance->
ModuleDataGetter());
334 Instance->
LockObject(ModuleParams->Spectrometer, ModuleData->GetSpectrometer());
335 if (ModuleParams->Communicator.ContainsID())
336 Instance->
LockObject(ModuleParams->Communicator, ModuleData->GetCommunicator());
338 ModuleData->FrequencyUnit = ModuleData->GetSpectrometer()->GetFrequencyUnit();
339 ModuleData->IntensityUnit = ModuleData->GetSpectrometer()->GetIntensityUnit();
340 ModuleData->MinFrequency = ModuleData->GetSpectrometer()->GetMinFrequency();
341 ModuleData->MaxFrequency = ModuleData->GetSpectrometer()->GetMaxFrequency();
343 auto InstrData = DynExp::dynamic_InstrumentData_cast<DynExpInstr::Spectrometer>(ModuleData->GetSpectrometer()->GetInstrumentData());
344 ModuleData->MinExposureTime = InstrData->GetMinExposureTime();
345 ModuleData->MaxExposureTime = InstrData->GetMaxExposureTime();
350 auto ModuleData = DynExp::dynamic_ModuleData_cast<SpectrumViewer>(Instance->
ModuleDataGetter());
363 auto ModuleData = DynExp::dynamic_ModuleData_cast<SpectrumViewer>(Instance->
ModuleDataGetter());
365 ModuleData->SpectrumRecordingPaused =
false;
366 ModuleData->AcquisitionExposureTime = ModuleData->CurrentExposureTime;
367 ModuleData->GetSpectrometer()->Record();
372 auto ModuleData = DynExp::dynamic_ModuleData_cast<SpectrumViewer>(Instance->
ModuleDataGetter());
374 ModuleData->SpectrumRecordingPaused =
false;
375 ModuleData->AutoSaveFilename.clear();
376 ModuleData->GetSpectrometer()->Abort();
381 auto ModuleData = DynExp::dynamic_ModuleData_cast<SpectrumViewer>(Instance->
ModuleDataGetter());
383 ModuleData->GetSpectrometer()->SetSilentMode(Checked);
388 auto ModuleData = DynExp::dynamic_ModuleData_cast<SpectrumViewer>(Instance->
ModuleDataGetter());
395 auto ModuleData = DynExp::dynamic_ModuleData_cast<SpectrumViewer>(Instance->
ModuleDataGetter());
396 auto InstrData = DynExp::dynamic_InstrumentData_cast<DynExpInstr::Spectrometer>(ModuleData->GetSpectrometer()->GetInstrumentData());
398 if (Value < InstrData->GetCurrentUpperFrequency())
399 ModuleData->GetSpectrometer()->SetFrequencyRange(Value, InstrData->GetCurrentUpperFrequency());
404 auto ModuleData = DynExp::dynamic_ModuleData_cast<SpectrumViewer>(Instance->
ModuleDataGetter());
405 auto InstrData = DynExp::dynamic_InstrumentData_cast<DynExpInstr::Spectrometer>(ModuleData->GetSpectrometer()->GetInstrumentData());
407 if (Value > InstrData->GetCurrentLowerFrequency())
408 ModuleData->GetSpectrometer()->SetFrequencyRange(InstrData->GetCurrentLowerFrequency(), Value);
414 auto ModuleData = DynExp::dynamic_ModuleData_cast<SpectrumViewer>(Instance->
ModuleDataGetter());
419 ModuleData->SpectrumRecordingPaused =
false;
420 ModuleData->AutoSaveFilename = SaveDataFilename;
423 OnRunClicked(Instance,
false);
428 auto ModuleData = DynExp::dynamic_ModuleData_cast<SpectrumViewer>(Instance->
ModuleDataGetter());
429 ModuleData->SpectrumRecordingPaused =
true;
434 auto ModuleData = DynExp::dynamic_ModuleData_cast<SpectrumViewer>(Instance->
ModuleDataGetter());
435 ModuleData->SpectrumRecordingPaused =
false;
Implementation of a module to plot the spectrum stored in a spectrometer instrument.
Type describing a spectrum as acquired by the Spectrometer instrument.
@ Warning
The spectrometer is in a warning state, but still ready to acquire a spectrum.
@ Capturing
The spectrometer is currently acquiring a spectrum.
@ Error
The spectrometer is in an error state.
@ Ready
The spectrometer is ready to acquire a spectrum.
static const char * IntensityUnitTypeToStr(const IntensityUnitType &Unit)
Returns a descriptive string of a respective intensity unit to be e.g. used in plots.
std::chrono::milliseconds TimeType
Time type describing the spectrometer's times like its exposure time.
static const char * FrequencyUnitTypeToStr(const FrequencyUnitType &Unit)
Returns a descriptive string of a respective frequency unit to be e.g. used in plots.
@ Counts
Number of counts (arbitrary unit)
void ResetImpl(dispatch_tag< QModuleDataBase >) override final
void OnRunClicked(DynExp::ModuleInstance *Instance, bool) 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 OnUpperLimitChanged(DynExp::ModuleInstance *Instance, double Value) const
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 OnStopClicked(DynExp::ModuleInstance *Instance, bool) 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...
void OnPauseSpectrumRecording(DynExp::ModuleInstance *Instance) const
void ResetImpl(dispatch_tag< QModuleBase >) override final
void OnLowerLimitChanged(DynExp::ModuleInstance *Instance, double Value) 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 UpdateUIChild(const ModuleBase::ModuleDataGetterType &ModuleDataGetter) override final
void SaveSpectrum(const SpectrumViewerWidget::SampleDataType &Spectrum, Util::SynchronizedPointer< SpectrumViewerData > &ModuleData)
SpectrumViewerWidget::SampleDataType ProcessSpectrum(DynExpInstr::SpectrometerData::SpectrumType &&Spectrum, Util::SynchronizedPointer< SpectrumViewerData > &ModuleData)
void OnSilentModeToggled(DynExp::ModuleInstance *Instance, bool Checked) const
void OnResumeSpectrumRecording(DynExp::ModuleInstance *Instance) const
void OnRecordAndSaveSpectrum(DynExp::ModuleInstance *Instance, std::string SaveDataFilename) const
void OnExposureTimeChanged(DynExp::ModuleInstance *Instance, int Value) const
static void Register(const ModuleBase &Listener, CallableT EventFunc)
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. Indirectly calls ModuleBase::RemoveRegistere...
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.
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.
Logs events like errors and writes them immediately to a HTML file in a human-readable format....
void Log(const std::string &Message, const ErrorType Type=ErrorType::Info, const size_t Line=0, const std::string &Function="", const std::string &File="", const int ErrorCode=0, const std::stacktrace &Trace={}) noexcept
Logs an event from information specified manually.
Holds a CallableMemberWrapper and invokes its callable when being destroyed.
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...
constexpr auto DefaultQChartTheme
constexpr auto StatusBarWarningStyleSheet
constexpr auto StatusBarErrorStyleSheet
constexpr auto StatusBarBusyStyleSheet
DynExpErrorCodes
DynExp's error codes
bool SaveToFile(const QString &Filename, std::string_view Text)
Saves a std::string_view to a file (using QFile). Creates a new file or truncates an existing file's ...
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.