12 std::stringstream CSVData;
13 CSVData << std::setprecision(6);
14 CSVData <<
"ExposureTime = " << ExposureTime.count() <<
" " << Util::ToUnitStr<DynExpInstr::SpectrometerData::TimeType>() <<
"\n";
15 CSVData <<
"HEADER_END\n";
18 for (
const auto& Sample :
Samples)
19 CSVData << Sample.x() <<
";" << Sample.y() <<
"\n";
58 auto ModuleData = DynExp::dynamic_ModuleData_cast<SpectrumViewer>(Instance.
ModuleDataGetter());
59 auto InstrData = DynExp::dynamic_InstrumentData_cast<DynExpInstr::Spectrometer>(ModuleData->GetSpectrometer()->GetInstrumentData());
63 ModuleData->CurrentExposureTime = InstrData->GetCurrentExposureTime();
64 ModuleData->CurrentLowerFrequency = InstrData->GetCurrentLowerFrequency();
65 ModuleData->CurrentUpperFrequency = InstrData->GetCurrentUpperFrequency();
66 ModuleData->SilentModeEnabled = InstrData->GetSilentModeEnabled();
67 ModuleData->CapturingState = InstrData->GetCapturingState();
68 ModuleData->CapturingProgress = InstrData->GetCapturingProgress();
70 if (InstrData->HasSpectrum() && !ModuleData->SpectrumRecordingPaused)
73 NumFailedUpdateAttempts = 0;
77 if (NumFailedUpdateAttempts++ >= 3)
88 auto ModuleData = DynExp::dynamic_ModuleData_cast<SpectrumViewer>(Instance.
ModuleDataGetter());
90 ModuleData->CurrentSpectrum = std::move(ProcessedSamples);
91 ModuleData->PlotInfo = std::move(
PlotInfo);
93 if (!ModuleData->AutoSaveFilename.empty())
95 SaveSpectrum(ModuleData);
96 ModuleData->AutoSaveFilename.clear();
98 if (ModuleData->GetCommunicator().valid())
99 ModuleData->GetCommunicator()->PostEvent(*
this,
FinishedEvent{});
105 auto ModuleData = DynExp::dynamic_ModuleData_cast<SpectrumViewer>(Instance.
ModuleDataGetter());
110 ModuleData->PlotInfo = std::move(
PlotInfo);
118 IsSavingData =
false;
119 NumFailedUpdateAttempts = 0;
136 auto Backend = GetBackend<SpectrumViewerBackend>();
137 auto ModuleData = DynExp::dynamic_ModuleData_cast<SpectrumViewer>(ModuleDataGetter());
139 if (!ModuleData->IsUIInitialized())
141 Backend->SetExposureTimeRange({ Util::NumToT<int>(ModuleData->MinExposureTime.count()), Util::NumToT<int>(ModuleData->MaxExposureTime.count()) });
142 Backend->SetExposureTimeUnit(QString::fromStdString(Util::ToUnitStr<DynExpInstr::SpectrometerData::TimeType>()));
143 Backend->SetLimitRange({ ModuleData->MinFrequency, ModuleData->MaxFrequency });
146 Backend->GetGraph()->InsertSeries(
"Spectrum");
148 ModuleData->SetUIInitialized();
151 switch (ModuleData->CapturingState)
159 if (!Backend->IsSilentFocused())
160 Backend->SetSilent(ModuleData->SilentModeEnabled);
161 if (!Backend->IsExposureTimeFocused())
162 Backend->SetExposureTime(Util::NumToT<int>(ModuleData->CurrentExposureTime.count()));
163 if (!Backend->IsLowerLimitFocused())
164 Backend->SetLowerLimit(ModuleData->CurrentLowerFrequency);
165 if (!Backend->IsUpperLimitFocused())
166 Backend->SetUpperLimit(ModuleData->CurrentUpperFrequency);
167 Backend->SetProgress(ModuleData->CapturingProgress > 0. && ModuleData->CapturingProgress <= 100. ? ModuleData->CapturingProgress / 100. : 0.);
169 Backend->GetGraph()->UpdateSeries(0, ModuleData->CurrentSpectrum.Samples, ModuleData->PlotInfo);
170 Backend->GetGraph()->UpdateData(ModuleData->PlotInfo);
175 if (!
Util::SaveToFile(QString::fromStdString(ModuleData->AutoSaveFilename), ModuleData->CurrentSpectrum.ToStr(ModuleData->CurrentExposureTime, ModuleData->PlotInfo)))
188 auto ModuleParams = DynExp::dynamic_Params_cast<SpectrumViewer>(Instance->
ParamsGetter());
189 auto ModuleData = DynExp::dynamic_ModuleData_cast<SpectrumViewer>(Instance->
ModuleDataGetter());
191 Instance->
LockObject(ModuleParams->Spectrometer, ModuleData->GetSpectrometer());
192 if (ModuleParams->Communicator.ContainsID())
193 Instance->
LockObject(ModuleParams->Communicator, ModuleData->GetCommunicator());
195 ModuleData->PlotInfo.XUnit = ModuleData->GetSpectrometer()->GetFrequencyUnit();
196 ModuleData->PlotInfo.YUnit = ModuleData->GetSpectrometer()->GetIntensityUnit();
197 ModuleData->MinFrequency = ModuleData->GetSpectrometer()->GetMinFrequency();
198 ModuleData->MaxFrequency = ModuleData->GetSpectrometer()->GetMaxFrequency();
200 auto InstrData = DynExp::dynamic_InstrumentData_cast<DynExpInstr::Spectrometer>(ModuleData->GetSpectrometer()->GetInstrumentData());
201 ModuleData->MinExposureTime = InstrData->GetMinExposureTime();
202 ModuleData->MaxExposureTime = InstrData->GetMaxExposureTime();
207 auto ModuleData = DynExp::dynamic_ModuleData_cast<SpectrumViewer>(Instance->
ModuleDataGetter());
222 auto ModuleData = DynExp::dynamic_ModuleData_cast<SpectrumViewer>(Instance->
ModuleDataGetter());
227 ModuleData->SpectrumRecordingPaused =
false;
228 ModuleData->GetSpectrometer()->Record();
233 auto ModuleData = DynExp::dynamic_ModuleData_cast<SpectrumViewer>(Instance->
ModuleDataGetter());
235 ModuleData->SpectrumRecordingPaused =
false;
236 ModuleData->AutoSaveFilename.clear();
237 ModuleData->GetSpectrometer()->Abort();
242 auto ModuleData = DynExp::dynamic_ModuleData_cast<SpectrumViewer>(Instance->
ModuleDataGetter());
244 ModuleData->GetSpectrometer()->SetSilentMode(Checked);
249 auto ModuleData = DynExp::dynamic_ModuleData_cast<SpectrumViewer>(Instance->
ModuleDataGetter());
256 auto ModuleData = DynExp::dynamic_ModuleData_cast<SpectrumViewer>(Instance->
ModuleDataGetter());
257 auto InstrData = DynExp::dynamic_InstrumentData_cast<DynExpInstr::Spectrometer>(ModuleData->GetSpectrometer()->GetInstrumentData());
259 if (Value < InstrData->GetCurrentUpperFrequency())
260 ModuleData->GetSpectrometer()->SetFrequencyRange(Value, InstrData->GetCurrentUpperFrequency());
265 auto ModuleData = DynExp::dynamic_ModuleData_cast<SpectrumViewer>(Instance->
ModuleDataGetter());
266 auto InstrData = DynExp::dynamic_InstrumentData_cast<DynExpInstr::Spectrometer>(ModuleData->GetSpectrometer()->GetInstrumentData());
268 if (Value > InstrData->GetCurrentLowerFrequency())
269 ModuleData->GetSpectrometer()->SetFrequencyRange(InstrData->GetCurrentLowerFrequency(), Value);
274 auto ModuleData = DynExp::dynamic_ModuleData_cast<SpectrumViewer>(Instance->
ModuleDataGetter());
277 ModuleData->AutoSaveFilename = SaveFilename +
".csv";
282 OnRunClicked(Instance);
287 OnStopClicked(Instance);
292 auto ModuleData = DynExp::dynamic_ModuleData_cast<SpectrumViewer>(Instance->
ModuleDataGetter());
293 ModuleData->SpectrumRecordingPaused =
true;
298 auto ModuleData = DynExp::dynamic_ModuleData_cast<SpectrumViewer>(Instance->
ModuleDataGetter());
299 ModuleData->SpectrumRecordingPaused =
false;
304 EnsureCallFromOwningThread();
311 if (Filename.isEmpty())
314 auto ModuleData = DynExp::dynamic_ModuleData_cast<SpectrumViewer>(GetModuleData());
315 if (!
Util::SaveToFile(Filename, ModuleData->CurrentSpectrum.ToStr(ModuleData->CurrentExposureTime, ModuleData->PlotInfo)))
316 QMessageBox::warning(GetWidget(),
"DynExp - Error",
"Error writing data to file.");
C++ backend of the SpectrumViewer QML module.
Implementation of a module to plot the spectrum stored in a spectrometer instrument.
Type describing a spectrum as acquired by the Spectrometer instrument.
bool HasSpectrum() const noexcept
Indicates whether the spectrum is empty.
auto & GetSpectrum() const noexcept
Getter for Samples.
@ 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.
std::chrono::milliseconds TimeType
Time type describing the spectrometer's times like its exposure time.
This event signals that an action (like a measurement) started by a TriggerEvent has been completed.
void lowerLimitChanged(double)
void upperLimitChanged(double)
void exposureTimeChanged(int)
DynExpInstr::SpectrometerData::TimeType CurrentExposureTime
DynExpInstr::SpectrometerData::CapturingStateType CapturingState
std::string AutoSaveFilename
SampleDataType CurrentSpectrum
DynExpInstr::SpectrometerData::TimeType MinExposureTime
double CurrentLowerFrequency
DynExpInstr::SpectrometerData::TimeType MaxExposureTime
Graph::LineGraphPlotInfo PlotInfo
bool SpectrumRecordingPaused
void ResetImpl(dispatch_tag< QMLModuleDataBase >) override final
double CurrentUpperFrequency
void OnExit(DynExp::ModuleInstance *Instance) const override final
This event is triggered right before the module thread terminates (not due to an exception,...
void SaveSpectrum(Util::SynchronizedPointer< SpectrumViewerData > &ModuleData)
void OnUpperLimitChanged(DynExp::ModuleInstance *Instance, double Value) const
void MakeConnections(QObject *Backend) override final
Use QModuleBase::Connect() to connect Qt QML signals to the module's event functions.
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 OnRunClicked(DynExp::ModuleInstance *Instance) 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 OnLowerLimitChanged(DynExp::ModuleInstance *Instance, double Value) const
void OnTrigger(DynExp::ModuleInstance *Instance) const
void OnSetFilename(DynExp::ModuleInstance *Instance, const std::string &SaveFilename) const
void UpdateUIChild(const ModuleBase::ModuleDataGetterType &ModuleDataGetter) override final
void OnSaveSpectrum() const
void OnSilentModeToggled(DynExp::ModuleInstance *Instance, bool Checked) const
void OnStop(DynExp::ModuleInstance *Instance) const
void FinishedSavingData() const noexcept
void OnResumeSpectrumRecording(DynExp::ModuleInstance *Instance) const
void OnStopClicked(DynExp::ModuleInstance *Instance) const
void ResetImpl(dispatch_tag< QMLModuleBase >) override final
void OnExposureTimeChanged(DynExp::ModuleInstance *Instance, int Value) const
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 ...
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.
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...
const char * UnitTypeToStr(UnitType Unit)
Returns a descriptive string of the given unit's type (e.g. 'dBm').
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 ...
EventLogger & EventLog()
This function holds a static EventLogger instance and returns a reference to it. DynExp uses only one...
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.
DynExp::Units::UnitType XUnit
Joint unit of the plot's x axis.
void AdjustAxesLimits()
Adjusts MinValues and MaxValues to best display all data series.
bool ProcessSpectrum(DynExpInstr::SpectrometerData::SpectrumType Spectrum, QList< QPointF > &Samples, const size_t SeriesIndex)
Converts Spectrum to displayable format and stores its minimal and maximal values in this DynExpLineG...
void ReprocessSamples(const QList< QPointF > &Samples, const size_t SeriesIndex)
If data plotting is not enabled (running), the available and already plotted samples have to be repro...
void ResetHoveredSample()
Removes the stored hovered sample.
void Reset()
Resets the instance to generate information from new sample series.
DynExp::Units::UnitType YUnit
Joint unit of the plot's y axis.
std::string ToStr(DynExpInstr::SpectrometerData::TimeType ExposureTime, const DynExpModule::Graph::LineGraphPlotInfo &PlotInfo) const