DynExp
Highly flexible laboratory automation for dynamically changing experiments.
Loading...
Searching...
No Matches
ODMRWidget.cpp
Go to the documentation of this file.
1// This file is part of DynExp.
2
3#include "stdafx.h"
4#include "ODMR.h"
5#include "moc_ODMRWidget.cpp"
6#include "ui_ODMR.h"
7#include "ODMRWidget.h"
8
9namespace DynExpModule::ODMR
10{
12 : CurrentState(nullptr),
13 StateLabel(new QLabel(Owner)), SweepStateLabel(new QLabel(Owner)), AcquisitionTimeLabel(new QLabel(Owner))
14 {
15 }
16
18 {
19 StateLabel->setText(CurrentState ? (QString(" ") + CurrentState->GetDescription()) : "< Unknown >");
20 if (CurrentState && CurrentState->GetState() != StateType::Ready)
21 StateLabel->setStyleSheet(DynExpUI::StatusBarBusyStyleSheet);
22 else
23 StateLabel->setStyleSheet("");
24 }
25
27 : QModuleWidget(Owner, parent),
28 ui(std::make_unique<Ui::ODMR>()), StatusBar(this),
29 ODMRDataSeries(nullptr), ODMRFitSeries(nullptr), ODMRDataChart(nullptr), ODMRXAxis(new QValueAxis(this)), ODMRYAxis(new QValueAxis(this)),
30 SensitivityDataSeries(nullptr), SensitivityDataChart(nullptr), SensitivityXAxis(new QLogValueAxis(this)), SensitivityYAxis(new QLogValueAxis(this))
31 {
32 ui->setupUi(this);
33
34 // Status bar
35 ui->MainStatusBar->addWidget(StatusBar.StateLabel, 5);
36 ui->MainStatusBar->addWidget(StatusBar.SweepStateLabel, 2);
37 ui->MainStatusBar->addWidget(StatusBar.AcquisitionTimeLabel, 3);
38
39 // Graph to display a single ODMR trace
40 ODMRDataChart = new QChart();
41 ui->ODMRChartView->setChart(ODMRDataChart); // Takes ownership of ODMRDataChart.
42 ui->ODMRChartView->setRenderHint(QPainter::Antialiasing);
44 ODMRDataChart->legend()->setVisible(false);
45 ODMRXAxis->setTitleText("frequency in GHz");
46
47 // Graph to display a single sensitivity measurement
48 SensitivityDataChart = new QChart();
49 ui->SensitivityChartView->setChart(SensitivityDataChart); // Takes ownership of SensitivityDataChart.
50 ui->SensitivityChartView->setRenderHint(QPainter::Antialiasing);
52 SensitivityDataChart->legend()->setVisible(false);
53 SensitivityXAxis->setBase(10);
54 SensitivityXAxis->setTitleText("frequency in Hz");
55 SensitivityYAxis->setBase(10);
56 SensitivityYAxis->setTitleText("sensitivity ASD in T/sqrt(Hz)");
57
58 // Chart takes ownership of axes.
59 ODMRDataChart->addAxis(ODMRXAxis, Qt::AlignBottom);
60 ODMRDataChart->addAxis(ODMRYAxis, Qt::AlignLeft);
61 SensitivityDataChart->addAxis(SensitivityXAxis, Qt::AlignBottom);
62 SensitivityDataChart->addAxis(SensitivityYAxis, Qt::AlignLeft);
63
64 connect(ui->CBParamSweepType, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &ODMRWidget::OnSweepSeriesParamChanged);
65 }
66
68 {
69 if (!GetUIInitialized())
70 {
71 ui->SBRFPower->setValue(ModuleData->RFPower);
72 ui->SBRFCenter->setValue(ModuleData->RFCenterFreq / 1e6);
73 ui->SBRFSpan->setValue(ModuleData->RFFreqSpan / 1e6);
74 ui->SBRFFreqSpacing->setValue(ModuleData->RFFreqSpacing / 1e3);
75 ui->SBRFDwellTime->setValue(ModuleData->RFDwellTime / 1e-3);
76 ui->RBRFModulationTypeNone->setChecked(true); // Emits signal to update module data accordingly.
77 ui->SBRFModulationFreq->setValue(ModuleData->RFModulationFreq / 1e3);
78 ui->SBRFModulationDepth->setValue(ModuleData->RFModulationDepth / 1e3);
79 ui->SBDataAcquisitionODMRSamplingRate->setValue(ModuleData->ODMRSamplingRate);
80 ui->LESaveDataPath->setText(QString::fromStdString(ModuleData->SaveDataPath));
81 ui->SBSaveDataCurrentIndex->setValue(ModuleData->CurrentSaveIndex);
82 ui->CBSaveDataEnable->setChecked(ModuleData->AutosaveEnabled);
83 ui->CBSensitivityEnable->setChecked(ModuleData->SensitivityEnabled);
84 ui->CBSensitivityOncePerSweep->setChecked(ModuleData->SensitivityOncePerSweep);
85 ui->CBSensitivityOffResEnable->setChecked(ModuleData->SensitivityOffResonanceEnabled);
86 ui->SBSensitivityFreq->setValue(ModuleData->SensitivityResonanceFreq / 1e6);
87 ui->SBSensitivityOffResFreq->setValue(ModuleData->SensitivityOffResonanceFreq / 1e6);
88 ui->SBSensitivitySpan->setValue(ModuleData->SensitivityResonanceSpan / 1e6);
89 ui->SBSensitivitySamplingRate->setValue(ModuleData->SensitivitySamplingRate);
90 ui->SBSensitivityDuration->setValue(ModuleData->SensitivityDuration);
91 ui->GBSensitivityAnalysis->setChecked(ModuleData->SensitivityAnalysisEnabled);
92 ui->SBGyromagneticRatio->setValue(ModuleData->GyromagneticRatio / 1e6);
93 ui->CBParamSweepEnable->setChecked(ModuleData->SweepSeriesEnabled);
94 if (ModuleData->TestFeature(ODMRData::FeatureType::AuxAnalogOut))
95 ui->CBParamSweepType->insertItem(ui->CBParamSweepType->count(), "Auxiliary analog out");
96 ui->CBParamSweepType->setCurrentIndex(0); // Emits signal to update module data accordingly, but see below.
97 ui->SBParamSweepStart->setValue(ModuleData->SweepSeriesStart);
98 ui->SBParamSweepStop->setValue(ModuleData->SweepSeriesStop);
99 ui->SBParamSweepStep->setValue(ModuleData->SweepSeriesStep);
100 ui->CBParamSweepRetrace->setChecked(ModuleData->SweepSeriesRetrace);
101 ui->CBParamSweepAdvanceLastValue->setChecked(ModuleData->SweepSeriesAdvanceLastValue);
102
103 ui->SBRFPower->setMinimum(ModuleData->RFGeneratorMinFuncDesc.Amplitude);
104 ui->SBRFPower->setMaximum(ModuleData->RFGeneratorMaxFuncDesc.Amplitude);
105 ui->SBRFPower->setValue(ModuleData->RFGeneratorDefaultFuncDesc.Amplitude);
106 ui->SBRFPower->setSuffix(QString(" ") + ModuleData->GetRFGenerator()->GetValueUnitStr());
107 ui->SBRFCenter->setMinimum(ModuleData->RFGeneratorMinFuncDesc.FrequencyInHz / 1e6);
108 ui->SBRFCenter->setMaximum(ModuleData->RFGeneratorMaxFuncDesc.FrequencyInHz / 1e6);
109 ui->SBRFCenter->setValue(ModuleData->RFGeneratorDefaultFuncDesc.FrequencyInHz / 1e6);
110 ui->SBSensitivityFreq->setMinimum(ModuleData->RFGeneratorMinFuncDesc.FrequencyInHz / 1e6);
111 ui->SBSensitivityFreq->setMaximum(ModuleData->RFGeneratorMaxFuncDesc.FrequencyInHz / 1e6);
112 ui->SBSensitivityFreq->setValue(ModuleData->RFGeneratorDefaultFuncDesc.FrequencyInHz / 1e6);
113
114 ui->SBDataAcquisitionODMRSamplingRate->setEnabled(ModuleData->TestFeature(ODMRData::FeatureType::LockinDetection));
115 ui->SBSensitivitySamplingRate->setEnabled(ModuleData->TestFeature(ODMRData::FeatureType::LockinDetection));
116 ui->SBSensitivityDuration->setEnabled(ModuleData->TestFeature(ODMRData::FeatureType::LockinDetection));
117
118 ODMRYAxis->setTitleText(QString("ODMR signal in ") + ModuleData->GetSignalDetector()->GetValueUnitStr());
119
120 // This is not emitted if setCurrentIndex() does not change the index (because it already is the desired value).
121 // So, do it manually.
122 OnSweepSeriesParamChanged(ui->CBParamSweepType->currentIndex());
123
124 AuxAnalogOutValueUnit = ModuleData->AuxAnalogOutValueUnit;
125 AuxAnalogOutMinValue = ModuleData->AuxAnalogOutMinValue;
126 AuxAnalogOutMaxValue = ModuleData->AuxAnalogOutMaxValue;
127
128 UIInitialized = true;
129 }
130 }
131
133 {
134 bool IsReady = State->GetState() == StateType::Ready;
135 StatusBar.CurrentState = State;
136
137 StatusBar.AcquisitionTimeLabel->setText((IsReady || ModuleData->AcquisitionTime <= 0) ? "" : QString::fromStdString("Acquisition time: " + Util::ToStr(ModuleData->AcquisitionTime, 2) + " s"));
138 StatusBar.SweepStateLabel->setText(IsReady ? "" : (!ModuleData->GetSweepNumberSteps() ? "single run" :
139 (QString("Sweep ") + QString::number(ModuleData->CurrentSweepIndex + 1) + " / " + QString::number(ModuleData->GetSweepNumberSteps()))));
140
141 ui->GBRFSweep->setEnabled(IsReady);
142 ui->GBRFModulation->setEnabled(IsReady);
143 ui->GBDataAcquisition->setEnabled(IsReady);
144 ui->GBSaveData->setEnabled(IsReady);
145 ui->GBSensitivity->setEnabled(IsReady);
146 ui->GBSensitivityAnalysis->setEnabled(IsReady);
147 ui->GBParamSweep->setEnabled(IsReady);
148 ui->BStart->setEnabled(IsReady);
149 ui->BStartSensitivity->setEnabled(IsReady);
150 ui->BStop->setEnabled(!IsReady);
151 }
152
154 {
155 ui->LERFNumSamples->setText(QString::number(ModuleData->GetNumSamples()));
156 ui->LODMRCurrentSelection->setText(ModuleData->ODMRPlot.SelectedPoint.isNull() ? QString() : (QString::number(ModuleData->ODMRPlot.SelectedPoint.x() * 1e3, 'f', 3) + " MHz"));
157 ui->LEODMRFitSlope->setText(QString::number(std::get<1>(ModuleData->ODMRPlot.FitParams) * 1e6) + " [y]/MHz");
158 ui->LEODMRFitOffset->setText(QString::number(std::get<0>(ModuleData->ODMRPlot.FitParams)) + " [y]");
159
160 if (!ui->SBSaveDataCurrentIndex->hasFocus())
161 ui->SBSaveDataCurrentIndex->setValue(ModuleData->CurrentSaveIndex);
162
164 }
165
167 {
168 ODMRDataChart->removeAllSeries();
169 ODMRDataSeries = new QLineSeries(this);
170 ODMRDataSeries->append(ODMRPlot.DataPoints);
171 ODMRDataSeries->setPointsVisible(false);
172 ODMRFitSeries = new QLineSeries(this);
173 ODMRFitSeries->append(ODMRPlot.FitPoints);
174 ODMRFitSeries->setPointsVisible(false);
175
176 ODMRXAxis->setRange(ODMRPlot.DataPointsMinValues.x(), ODMRPlot.DataPointsMaxValues.x());
177 ODMRYAxis->setRange(ODMRPlot.DataPointsMinValues.y(), ODMRPlot.DataPointsMaxValues.y());
178
179 ODMRDataChart->addSeries(ODMRDataSeries);
180 ODMRDataChart->addSeries(ODMRFitSeries);
181 ODMRDataSeries->attachAxis(ODMRDataChart->axes()[0]);
182 ODMRDataSeries->attachAxis(ODMRDataChart->axes()[1]);
183 ODMRFitSeries->attachAxis(ODMRDataChart->axes()[0]);
184 ODMRFitSeries->attachAxis(ODMRDataChart->axes()[1]);
185 }
186
188 {
189 SensitivityDataChart->removeAllSeries();
190 SensitivityDataSeries = new QLineSeries(this);
191 SensitivityDataSeries->append(SensitivityPlot.DataPoints);
192 SensitivityDataSeries->setPointsVisible(false);
193
194 SensitivityYAxis->setRange(SensitivityPlot.DataPointsMinValues.y(), SensitivityPlot.DataPointsMaxValues.y());
195 SensitivityXAxis->setRange(SensitivityPlot.DataPointsMinValues.x(), SensitivityPlot.DataPointsMaxValues.x());
196
198 SensitivityDataSeries->attachAxis(SensitivityDataChart->axes()[0]);
199 SensitivityDataSeries->attachAxis(SensitivityDataChart->axes()[1]);
200 }
201
203 {
204 auto Filename = Util::PromptSaveFilePathModule(this, "Select file for saving ODMR data",
205 ".csv", " Comma-separated values file (*.csv)");
206 if (Filename.isEmpty())
207 return;
208
209 // Emits signal to update module data accordingly.
210 ui->LESaveDataPath->setText(Filename);
211 }
212
214 {
215 QDoubleSpinBox* Destiny = nullptr;
216
217 if (Index != 2) // != ODMRData::SweepSeriesType::AnalogOut
218 {
219 switch (Index)
220 {
221 case 0: // ODMRData::SweepSeriesType::RFModulationDepth
222 Destiny = ui->SBRFModulationDepth;
223 break;
224 case 1: // ODMRData::SweepSeriesType::RFPower
225 Destiny = ui->SBRFPower;
226 break;
227 }
228
229 if (Destiny)
230 {
231 ui->SBParamSweepStart->setMinimum(Destiny->minimum());
232 ui->SBParamSweepStart->setMaximum(Destiny->maximum());
233 ui->SBParamSweepStart->setSuffix(Destiny->suffix());
234 ui->SBParamSweepStop->setMinimum(Destiny->minimum());
235 ui->SBParamSweepStop->setMaximum(Destiny->maximum());
236 ui->SBParamSweepStop->setSuffix(Destiny->suffix());
237 ui->SBParamSweepStep->setMinimum(Destiny->minimum());
238 ui->SBParamSweepStep->setMaximum(Destiny->maximum());
239 ui->SBParamSweepStep->setSuffix(Destiny->suffix());
240 }
241 }
242 else
243 {
244 ui->SBParamSweepStart->setMinimum(AuxAnalogOutMinValue);
245 ui->SBParamSweepStart->setMaximum(AuxAnalogOutMaxValue);
246 ui->SBParamSweepStart->setSuffix(QString(" ") + DynExpInstr::DataStreamInstrumentData::UnitTypeToStr(AuxAnalogOutValueUnit));
247 ui->SBParamSweepStop->setMinimum(AuxAnalogOutMinValue);
248 ui->SBParamSweepStop->setMaximum(AuxAnalogOutMaxValue);
249 ui->SBParamSweepStop->setSuffix(ui->SBParamSweepStart->suffix());
250 ui->SBParamSweepStep->setMinimum(AuxAnalogOutMinValue);
251 ui->SBParamSweepStep->setMaximum(AuxAnalogOutMaxValue);
252 ui->SBParamSweepStep->setSuffix(ui->SBParamSweepStart->suffix());
253 }
254 }
255}
User interface belonging to the DynExpModule::ODMR::ODMR module.
Implementation of a module to perform optically detected magnetic resonance (ODMR) measurements.
static const char * UnitTypeToStr(const UnitType &Unit)
Returns a descriptive string of a respective unit to be e.g. used in plots.
QLogValueAxis * SensitivityXAxis
Definition ODMRWidget.h:107
void OnSweepSeriesParamChanged(int Index)
ODMRWidget(ODMR &Owner, QModuleWidget *parent=nullptr)
void UpdateUIData(Util::SynchronizedPointer< ODMRData > &ModuleData)
void InitializeUI(Util::SynchronizedPointer< ODMRData > &ModuleData)
void UpdateSensitivityPlot(const SensitivityPlotType &SensitivityPlot)
void UpdateODMRPlot(const ODMRPlotType &ODMRPlot)
QLogValueAxis * SensitivityYAxis
Definition ODMRWidget.h:108
void SetUIState(const StateMachineStateType *State, Util::SynchronizedPointer< ODMRData > &ModuleData)
std::unique_ptr< Ui::ODMR > ui
Definition ODMRWidget.h:96
DynExpInstr::DataStreamInstrumentData::UnitType AuxAnalogOutValueUnit
Definition ODMRWidget.h:110
DynExpInstr::DataStreamInstrumentData::ValueType AuxAnalogOutMinValue
Definition ODMRWidget.h:111
DynExpInstr::DataStreamInstrumentData::ValueType AuxAnalogOutMaxValue
Definition ODMRWidget.h:112
bool GetUIInitialized() const noexcept
Definition ODMRWidget.h:92
QModuleBase & Owner
Module owning this user interface window (reference, because it should never change nor be nullptr).
Definition Module.h:1478
QModuleWidget(QModuleBase &Owner, QWidget *Parent=nullptr)
Constructs a QModuleWidget instance.
Definition Module.cpp:451
State machine state as used by class StateMachine. A state mainly wraps a state function of the membe...
Definition Util.h:1367
constexpr StateEnumType GetState() const noexcept
Returns the state's unique identifier.
Definition Util.h:1383
Pointer to lock a class derived from ISynchronizedPointerLockable for synchronizing between threads....
Definition Util.h:170
constexpr auto DefaultQChartTheme
constexpr auto StatusBarBusyStyleSheet
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
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....
Definition QtUtil.cpp:143
Accumulates include statements to provide a precompiled header.
const StateMachineStateType * CurrentState
Definition ODMRWidget.h:72