##// END OF EJS Templates
Merge branch 'feature/MockSpectrogram3' into develop
Alexandre Leroux -
r925:7a5278caab29 merge
parent child
Show More
@@ -0,0 +1,34
1 #ifndef SCIQLOP_AXISRENDERINGUTILS_H
2 #define SCIQLOP_AXISRENDERINGUTILS_H
3
4 #include <memory>
5
6 #include <QtCore/QString>
7
8 class IDataSeries;
9 class QCPAxis;
10 class QCPColorScale;
11 class QCustomPlot;
12
13 /// Formats a data value according to the axis on which it is present
14 QString formatValue(double value, const QCPAxis &axis);
15
16 /**
17 * Helper used to handle axes rendering
18 */
19 struct IAxisHelper {
20 virtual ~IAxisHelper() noexcept = default;
21
22 /// Set properties of the plot's axes and the color scale associated to plot passed as
23 /// parameters
24 /// @param plot the plot for which to set axe properties
25 /// @param colorScale the color scale for which to set properties
26 virtual void setProperties(QCustomPlot &plot, QCPColorScale &colorScale) = 0;
27 };
28
29 struct IAxisHelperFactory {
30 /// Creates IAxisHelper according to a data series
31 static std::unique_ptr<IAxisHelper> create(std::shared_ptr<IDataSeries> dataSeries) noexcept;
32 };
33
34 #endif // SCIQLOP_AXISRENDERINGUTILS_H
@@ -0,0 +1,29
1 #ifndef SCIQLOP_PLOTTABLESRENDERINGUTILS_H
2 #define SCIQLOP_PLOTTABLESRENDERINGUTILS_H
3
4 #include <Visualization/VisualizationDefs.h>
5
6 #include <memory>
7
8 class IDataSeries;
9 class QCPColorScale;
10 class QCustomPlot;
11
12 /**
13 * Helper used to handle plottables rendering
14 */
15 struct IPlottablesHelper {
16 virtual ~IPlottablesHelper() noexcept = default;
17
18 /// Set properties of the plottables passed as parameter
19 /// @param plottables the plottables for which to set properties
20 virtual void setProperties(PlottablesMap &plottables) = 0;
21 };
22
23 struct IPlottablesHelperFactory {
24 /// Creates IPlottablesHelper according to a data series
25 static std::unique_ptr<IPlottablesHelper>
26 create(std::shared_ptr<IDataSeries> dataSeries) noexcept;
27 };
28
29 #endif // SCIQLOP_PLOTTABLESRENDERINGUTILS_H
@@ -0,0 +1,163
1 #include "Visualization/AxisRenderingUtils.h"
2
3 #include <Data/ScalarSeries.h>
4 #include <Data/SpectrogramSeries.h>
5 #include <Data/VectorSeries.h>
6
7 #include <Visualization/qcustomplot.h>
8
9 namespace {
10
11 const auto DATETIME_FORMAT = QStringLiteral("yyyy/MM/dd hh:mm:ss:zzz");
12
13 /// Format for datetimes on a axis
14 const auto DATETIME_TICKER_FORMAT = QStringLiteral("yyyy/MM/dd \nhh:mm:ss");
15
16 /// Generates the appropriate ticker for an axis, depending on whether the axis displays time or
17 /// non-time data
18 QSharedPointer<QCPAxisTicker> axisTicker(bool isTimeAxis)
19 {
20 if (isTimeAxis) {
21 auto dateTicker = QSharedPointer<QCPAxisTickerDateTime>::create();
22 dateTicker->setDateTimeFormat(DATETIME_TICKER_FORMAT);
23 dateTicker->setDateTimeSpec(Qt::UTC);
24
25 return dateTicker;
26 }
27 else {
28 // default ticker
29 return QSharedPointer<QCPAxisTicker>::create();
30 }
31 }
32
33 /**
34 * Sets properties of the axis passed as parameter
35 * @param axis the axis to set
36 * @param unit the unit to set for the axis
37 * @param scaleType the scale type to set for the axis
38 */
39 void setAxisProperties(QCPAxis &axis, const Unit &unit,
40 QCPAxis::ScaleType scaleType = QCPAxis::stLinear)
41 {
42 // label (unit name)
43 axis.setLabel(unit.m_Name);
44
45 // scale type
46 axis.setScaleType(scaleType);
47
48 // ticker (depending on the type of unit)
49 axis.setTicker(axisTicker(unit.m_TimeUnit));
50 }
51
52 /**
53 * Delegate used to set axes properties
54 */
55 template <typename T, typename Enabled = void>
56 struct AxisSetter {
57 static void setProperties(T &, QCustomPlot &, QCPColorScale &)
58 {
59 // Default implementation does nothing
60 }
61 };
62
63 /**
64 * Specialization of AxisSetter for scalars and vectors
65 * @sa ScalarSeries
66 * @sa VectorSeries
67 */
68 template <typename T>
69 struct AxisSetter<T, typename std::enable_if_t<std::is_base_of<ScalarSeries, T>::value
70 or std::is_base_of<VectorSeries, T>::value> > {
71 static void setProperties(T &dataSeries, QCustomPlot &plot, QCPColorScale &)
72 {
73 dataSeries.lockRead();
74 auto xAxisUnit = dataSeries.xAxisUnit();
75 auto valuesUnit = dataSeries.valuesUnit();
76 dataSeries.unlock();
77
78 setAxisProperties(*plot.xAxis, xAxisUnit);
79 setAxisProperties(*plot.yAxis, valuesUnit);
80 }
81 };
82
83 /**
84 * Specialization of AxisSetter for spectrograms
85 * @sa SpectrogramSeries
86 */
87 template <typename T>
88 struct AxisSetter<T, typename std::enable_if_t<std::is_base_of<SpectrogramSeries, T>::value> > {
89 static void setProperties(T &dataSeries, QCustomPlot &plot, QCPColorScale &colorScale)
90 {
91 dataSeries.lockRead();
92 auto xAxisUnit = dataSeries.xAxisUnit();
93 /// @todo ALX: use iterators here
94 auto yAxisUnit = dataSeries.yAxis().unit();
95 auto valuesUnit = dataSeries.valuesUnit();
96 dataSeries.unlock();
97
98 setAxisProperties(*plot.xAxis, xAxisUnit);
99 setAxisProperties(*plot.yAxis, yAxisUnit);
100
101 // Displays color scale in plot
102 plot.plotLayout()->insertRow(0);
103 plot.plotLayout()->addElement(0, 0, &colorScale);
104 colorScale.setType(QCPAxis::atTop);
105 colorScale.setMinimumMargins(QMargins{0, 0, 0, 0});
106
107 // Aligns color scale with axes
108 auto marginGroups = plot.axisRect()->marginGroups();
109 for (auto it = marginGroups.begin(), end = marginGroups.end(); it != end; ++it) {
110 colorScale.setMarginGroup(it.key(), it.value());
111 }
112
113 // Set color scale properties
114 colorScale.setLabel(valuesUnit.m_Name);
115 colorScale.setDataScaleType(QCPAxis::stLogarithmic); // Logarithmic scale
116 }
117 };
118
119 /**
120 * Default implementation of IAxisHelper, which takes data series to set axes properties
121 * @tparam T the data series' type
122 */
123 template <typename T>
124 struct AxisHelper : public IAxisHelper {
125 explicit AxisHelper(T &dataSeries) : m_DataSeries{dataSeries} {}
126
127 void setProperties(QCustomPlot &plot, QCPColorScale &colorScale) override
128 {
129 AxisSetter<T>::setProperties(m_DataSeries, plot, colorScale);
130 }
131
132 T &m_DataSeries;
133 };
134
135 } // namespace
136
137 QString formatValue(double value, const QCPAxis &axis)
138 {
139 // If the axis is a time axis, formats the value as a date
140 if (auto axisTicker = qSharedPointerDynamicCast<QCPAxisTickerDateTime>(axis.ticker())) {
141 return DateUtils::dateTime(value, axisTicker->dateTimeSpec()).toString(DATETIME_FORMAT);
142 }
143 else {
144 return QString::number(value);
145 }
146 }
147
148 std::unique_ptr<IAxisHelper>
149 IAxisHelperFactory::create(std::shared_ptr<IDataSeries> dataSeries) noexcept
150 {
151 if (auto scalarSeries = std::dynamic_pointer_cast<ScalarSeries>(dataSeries)) {
152 return std::make_unique<AxisHelper<ScalarSeries> >(*scalarSeries);
153 }
154 else if (auto spectrogramSeries = std::dynamic_pointer_cast<SpectrogramSeries>(dataSeries)) {
155 return std::make_unique<AxisHelper<SpectrogramSeries> >(*spectrogramSeries);
156 }
157 else if (auto vectorSeries = std::dynamic_pointer_cast<VectorSeries>(dataSeries)) {
158 return std::make_unique<AxisHelper<VectorSeries> >(*vectorSeries);
159 }
160 else {
161 return std::make_unique<AxisHelper<IDataSeries> >(*dataSeries);
162 }
163 }
@@ -0,0 +1,120
1 #include "Visualization/PlottablesRenderingUtils.h"
2
3 #include <Common/ColorUtils.h>
4
5 #include <Data/ScalarSeries.h>
6 #include <Data/SpectrogramSeries.h>
7 #include <Data/VectorSeries.h>
8
9 #include <Visualization/qcustomplot.h>
10
11 namespace {
12
13 /// Default gradient used for colormap
14 const auto DEFAULT_COLORMAP_GRADIENT = QCPColorGradient::gpJet;
15
16 /**
17 * Delegate used to set plottables properties
18 */
19 template <typename T, typename Enabled = void>
20 struct PlottablesSetter {
21 static void setProperties(T &, PlottablesMap &)
22 {
23 // Default implementation does nothing
24 }
25 };
26
27 /**
28 * Specialization of PlottablesSetter for scalars and vectors
29 * @sa ScalarSeries
30 * @sa VectorSeries
31 */
32 template <typename T>
33 struct PlottablesSetter<T, typename std::enable_if_t<std::is_base_of<ScalarSeries, T>::value
34 or std::is_base_of<VectorSeries, T>::value> > {
35 static void setProperties(T &dataSeries, PlottablesMap &plottables)
36 {
37 // Gets the number of components of the data series
38 dataSeries.lockRead();
39 auto componentCount = dataSeries.valuesData()->componentCount();
40 dataSeries.unlock();
41
42 // Generates colors for each component
43 auto colors = ColorUtils::colors(Qt::blue, Qt::red, componentCount);
44
45 // For each component of the data series, creates a QCPGraph to add to the plot
46 for (auto i = 0; i < componentCount; ++i) {
47 auto graph = plottables.at(i);
48 graph->setPen(QPen{colors.at(i)});
49 }
50 }
51 };
52
53 /**
54 * Specialization of PlottablesSetter for spectrograms
55 * @sa SpectrogramSeries
56 */
57 template <typename T>
58 struct PlottablesSetter<T,
59 typename std::enable_if_t<std::is_base_of<SpectrogramSeries, T>::value> > {
60 static void setProperties(T &, PlottablesMap &plottables)
61 {
62 // Checks that for a spectrogram there is only one plottable, that is a colormap
63 if (plottables.size() != 1) {
64 return;
65 }
66
67 if (auto colormap = dynamic_cast<QCPColorMap *>(plottables.begin()->second)) {
68 colormap->setInterpolate(false); // No value interpolation
69 colormap->setTightBoundary(true);
70
71 // Finds color scale in the colormap's plot to associate with it
72 auto plot = colormap->parentPlot();
73 auto plotElements = plot->plotLayout()->elements(false);
74 for (auto plotElement : plotElements) {
75 if (auto colorScale = dynamic_cast<QCPColorScale *>(plotElement)) {
76 colormap->setColorScale(colorScale);
77 }
78 }
79
80 // Sets gradient used for color scale
81 colormap->setGradient(DEFAULT_COLORMAP_GRADIENT);
82 colormap->rescaleDataRange();
83 }
84 }
85 };
86
87 /**
88 * Default implementation of IPlottablesHelper, which takes data series to set plottables properties
89 * @tparam T the data series' type
90 */
91 template <typename T>
92 struct PlottablesHelper : public IPlottablesHelper {
93 explicit PlottablesHelper(T &dataSeries) : m_DataSeries{dataSeries} {}
94
95 void setProperties(PlottablesMap &plottables) override
96 {
97 PlottablesSetter<T>::setProperties(m_DataSeries, plottables);
98 }
99
100 T &m_DataSeries;
101 };
102
103 } // namespace
104
105 std::unique_ptr<IPlottablesHelper>
106 IPlottablesHelperFactory::create(std::shared_ptr<IDataSeries> dataSeries) noexcept
107 {
108 if (auto scalarSeries = std::dynamic_pointer_cast<ScalarSeries>(dataSeries)) {
109 return std::make_unique<PlottablesHelper<ScalarSeries> >(*scalarSeries);
110 }
111 else if (auto spectrogramSeries = std::dynamic_pointer_cast<SpectrogramSeries>(dataSeries)) {
112 return std::make_unique<PlottablesHelper<SpectrogramSeries> >(*spectrogramSeries);
113 }
114 else if (auto vectorSeries = std::dynamic_pointer_cast<VectorSeries>(dataSeries)) {
115 return std::make_unique<PlottablesHelper<VectorSeries> >(*vectorSeries);
116 }
117 else {
118 return std::make_unique<PlottablesHelper<IDataSeries> >(*dataSeries);
119 }
120 }
@@ -26,6 +26,8 OptionalAxis &OptionalAxis::operator=(OptionalAxis other)
26 26 std::swap(m_Defined, other.m_Defined);
27 27 std::swap(m_Data, other.m_Data);
28 28 std::swap(m_Unit, other.m_Unit);
29
30 return *this;
29 31 }
30 32
31 33 bool OptionalAxis::isDefined() const
@@ -3,6 +3,9
3 3
4 4 #include <Common/spimpl.h>
5 5
6 #include <Visualization/VisualizationDefs.h>
7
8 class IDataSeries;
6 9 class QCustomPlot;
7 10 class QMouseEvent;
8 11 class Unit;
@@ -17,8 +20,13 public:
17 20
18 21 void onMouseMove(QMouseEvent *event) noexcept;
19 22
20 /// Sets properties of the plot's axes
21 void setAxesProperties(const Unit &xAxisUnit, const Unit &valuesUnit) noexcept;
23 /// Sets properties of the plot's axes from the data series passed as parameter
24 void setAxesProperties(std::shared_ptr<IDataSeries> dataSeries) noexcept;
25
26 /// Sets rendering properties of the plottables passed as parameter, from the data series that
27 /// generated these
28 void setPlottablesProperties(std::shared_ptr<IDataSeries> dataSeries,
29 PlottablesMap &plottables) noexcept;
22 30
23 31 /// Shows or hides graph overlay (name, close button, etc.)
24 32 void showGraphOverlay(bool show) noexcept;
@@ -77,6 +77,8 gui_sources = [
77 77 'src/Visualization/operations/RescaleAxeOperation.cpp',
78 78 'src/Visualization/VisualizationDragDropContainer.cpp',
79 79 'src/Visualization/VisualizationDragWidget.cpp'
80 'src/Visualization/AxisRenderingUtils.cpp',
81 'src/Visualization/PlottablesRenderingUtils.cpp'
80 82 ]
81 83
82 84 gui_inc = include_directories(['include'])
@@ -1,8 +1,6
1 1 #include "Visualization/VisualizationGraphHelper.h"
2 2 #include "Visualization/qcustomplot.h"
3 3
4 #include <Common/ColorUtils.h>
5
6 4 #include <Data/ScalarSeries.h>
7 5 #include <Data/SpectrogramSeries.h>
8 6 #include <Data/VectorSeries.h>
@@ -52,13 +50,9 struct PlottablesCreator<T,
52 50 auto componentCount = dataSeries.valuesData()->componentCount();
53 51 dataSeries.unlock();
54 52
55 auto colors = ColorUtils::colors(Qt::blue, Qt::red, componentCount);
56
57 53 // For each component of the data series, creates a QCPGraph to add to the plot
58 54 for (auto i = 0; i < componentCount; ++i) {
59 55 auto graph = plot.addGraph();
60 graph->setPen(QPen{colors.at(i)});
61
62 56 result.insert({i, graph});
63 57 }
64 58
@@ -232,7 +226,16 struct PlottablesUpdater<T,
232 226 auto xIndex = 0;
233 227 for (auto it = its.first; it != its.second; ++it, ++xIndex) {
234 228 for (auto yIndex = 0; yIndex < nbY; ++yIndex) {
235 colormap->data()->setCell(xIndex, yIndex, it->value(yIndex));
229 auto value = it->value(yIndex);
230
231 colormap->data()->setCell(xIndex, yIndex, value);
232
233 // Processing spectrogram data for display in QCustomPlot
234 /// For the moment, we just make the NaN values to be transparent in the colormap
235 /// @todo ALX: complete treatments (mesh generation, etc.)
236 if (std::isnan(value)) {
237 colormap->data()->setAlpha(xIndex, yIndex, 0);
238 }
236 239 }
237 240 }
238 241
@@ -1,4 +1,6
1 1 #include "Visualization/VisualizationGraphRenderingDelegate.h"
2 #include "Visualization/AxisRenderingUtils.h"
3 #include "Visualization/PlottablesRenderingUtils.h"
2 4 #include "Visualization/VisualizationGraphWidget.h"
3 5 #include "Visualization/qcustomplot.h"
4 6
@@ -13,11 +15,6 namespace {
13 15 /// Name of the axes layer in QCustomPlot
14 16 const auto AXES_LAYER = QStringLiteral("axes");
15 17
16 const auto DATETIME_FORMAT = QStringLiteral("yyyy/MM/dd hh:mm:ss:zzz");
17
18 /// Format for datetimes on a axis
19 const auto DATETIME_TICKER_FORMAT = QStringLiteral("yyyy/MM/dd \nhh:mm:ss");
20
21 18 /// Icon used to show x-axis properties
22 19 const auto HIDE_AXIS_ICON_PATH = QStringLiteral(":/icones/down.png");
23 20
@@ -38,35 +35,6 const auto TOOLTIP_RECT = QRect{10, 10, 10, 10};
38 35 /// Timeout after which the tooltip is displayed
39 36 const auto TOOLTIP_TIMEOUT = 500;
40 37
41 /// Generates the appropriate ticker for an axis, depending on whether the axis displays time or
42 /// non-time data
43 QSharedPointer<QCPAxisTicker> axisTicker(bool isTimeAxis)
44 {
45 if (isTimeAxis) {
46 auto dateTicker = QSharedPointer<QCPAxisTickerDateTime>::create();
47 dateTicker->setDateTimeFormat(DATETIME_TICKER_FORMAT);
48 dateTicker->setDateTimeSpec(Qt::UTC);
49
50 return dateTicker;
51 }
52 else {
53 // default ticker
54 return QSharedPointer<QCPAxisTicker>::create();
55 }
56 }
57
58 /// Formats a data value according to the axis on which it is present
59 QString formatValue(double value, const QCPAxis &axis)
60 {
61 // If the axis is a time axis, formats the value as a date
62 if (auto axisTicker = qSharedPointerDynamicCast<QCPAxisTickerDateTime>(axis.ticker())) {
63 return DateUtils::dateTime(value, axisTicker->dateTimeSpec()).toString(DATETIME_FORMAT);
64 }
65 else {
66 return QString::number(value);
67 }
68 }
69
70 38 void initPointTracerStyle(QCPItemTracer &tracer) noexcept
71 39 {
72 40 tracer.setInterpolating(false);
@@ -133,7 +101,8 struct VisualizationGraphRenderingDelegate::VisualizationGraphRenderingDelegateP
133 101 m_TitleText{new QCPItemText{&m_Plot}},
134 102 m_XAxisPixmap{new QCPItemPixmap{&m_Plot}},
135 103 m_ShowXAxis{true},
136 m_XAxisLabel{}
104 m_XAxisLabel{},
105 m_ColorScale{new QCPColorScale{&m_Plot}}
137 106 {
138 107 initPointTracerStyle(*m_PointTracer);
139 108
@@ -194,6 +163,7 struct VisualizationGraphRenderingDelegate::VisualizationGraphRenderingDelegateP
194 163 QCPItemPixmap *m_XAxisPixmap;
195 164 bool m_ShowXAxis; /// X-axis properties are shown or hidden
196 165 QString m_XAxisLabel;
166 QCPColorScale *m_ColorScale; /// Color scale used for some types of graphs (as spectrograms)
197 167 };
198 168
199 169 VisualizationGraphRenderingDelegate::VisualizationGraphRenderingDelegate(
@@ -245,21 +215,14 void VisualizationGraphRenderingDelegate::onMouseMove(QMouseEvent *event) noexce
245 215 }
246 216 }
247 217
248 void VisualizationGraphRenderingDelegate::setAxesProperties(const Unit &xAxisUnit,
249 const Unit &valuesUnit) noexcept
218 void VisualizationGraphRenderingDelegate::setAxesProperties(
219 std::shared_ptr<IDataSeries> dataSeries) noexcept
250 220 {
251 221 // Stores x-axis label to be able to retrieve it when x-axis pixmap is unselected
252 impl->m_XAxisLabel = xAxisUnit.m_Name;
222 impl->m_XAxisLabel = dataSeries->xAxisUnit().m_Name;
253 223
254 auto setAxisProperties = [](auto axis, const auto &unit) {
255 // label (unit name)
256 axis->setLabel(unit.m_Name);
257
258 // ticker (depending on the type of unit)
259 axis->setTicker(axisTicker(unit.m_TimeUnit));
260 };
261 setAxisProperties(impl->m_Plot.xAxis, xAxisUnit);
262 setAxisProperties(impl->m_Plot.yAxis, valuesUnit);
224 auto axisHelper = IAxisHelperFactory::create(dataSeries);
225 axisHelper->setProperties(impl->m_Plot, *impl->m_ColorScale);
263 226
264 227 // Updates x-axis state
265 228 impl->updateXAxisState();
@@ -267,6 +230,13 void VisualizationGraphRenderingDelegate::setAxesProperties(const Unit &xAxisUni
267 230 impl->m_Plot.layer(AXES_LAYER)->replot();
268 231 }
269 232
233 void VisualizationGraphRenderingDelegate::setPlottablesProperties(
234 std::shared_ptr<IDataSeries> dataSeries, PlottablesMap &plottables) noexcept
235 {
236 auto plottablesHelper = IPlottablesHelperFactory::create(dataSeries);
237 plottablesHelper->setProperties(plottables);
238 }
239
270 240 void VisualizationGraphRenderingDelegate::showGraphOverlay(bool show) noexcept
271 241 {
272 242 auto overlay = impl->m_Plot.layer(OVERLAY_LAYER);
@@ -114,21 +114,18 void VisualizationGraphWidget::addVariable(std::shared_ptr<Variable> variable, S
114 114 {
115 115 // Uses delegate to create the qcpplot components according to the variable
116 116 auto createdPlottables = VisualizationGraphHelper::create(variable, *ui->widget);
117 impl->m_VariableToPlotMultiMap.insert({variable, std::move(createdPlottables)});
118
119 // Set axes properties according to the units of the data series
120 /// @todo : for the moment, no control is performed on the axes: the units and the tickers
121 /// are fixed for the default x-axis and y-axis of the plot, and according to the new graph
122 auto xAxisUnit = Unit{};
123 auto valuesUnit = Unit{};
124 117
125 118 if (auto dataSeries = variable->dataSeries()) {
126 dataSeries->lockRead();
127 xAxisUnit = dataSeries->xAxisUnit();
128 valuesUnit = dataSeries->valuesUnit();
129 dataSeries->unlock();
119 // Set axes properties according to the units of the data series
120 impl->m_RenderingDelegate->setAxesProperties(dataSeries);
121
122 // Sets rendering properties for the new plottables
123 // Warning: this method must be called after setAxesProperties(), as it can access to some
124 // axes properties that have to be initialized
125 impl->m_RenderingDelegate->setPlottablesProperties(dataSeries, createdPlottables);
130 126 }
131 impl->m_RenderingDelegate->setAxesProperties(xAxisUnit, valuesUnit);
127
128 impl->m_VariableToPlotMultiMap.insert({variable, std::move(createdPlottables)});
132 129
133 130 connect(variable.get(), SIGNAL(updated()), this, SLOT(onDataCacheVariableUpdated()));
134 131
@@ -7,6 +7,7
7 7 #include <Data/VectorSeries.h>
8 8
9 9 #include <cmath>
10 #include <set>
10 11
11 12 #include <QFuture>
12 13 #include <QThread>
@@ -19,6 +20,12 namespace {
19 20 /// Number of bands generated for a spectrogram
20 21 const auto SPECTROGRAM_NUMBER_BANDS = 30;
21 22
23 /// Bands for which to generate NaN values for a spectrogram
24 const auto SPECTROGRAM_NAN_BANDS = std::set<int>{1, 3, 10, 20};
25
26 /// Bands for which to generate zeros for a spectrogram
27 const auto SPECTROGRAM_ZERO_BANDS = std::set<int>{2, 15, 19, 29};
28
22 29 /// Abstract cosinus type
23 30 struct ICosinusType {
24 31 virtual ~ICosinusType() = default;
@@ -26,9 +33,7 struct ICosinusType {
26 33 virtual int componentCount() const = 0;
27 34 /// @return the data series created for the type
28 35 virtual std::shared_ptr<IDataSeries> createDataSeries(std::vector<double> xAxisData,
29 std::vector<double> valuesData,
30 Unit xAxisUnit,
31 Unit valuesUnit) const = 0;
36 std::vector<double> valuesData) const = 0;
32 37 /// Generates values (one value per component)
33 38 /// @param x the x-axis data used to generate values
34 39 /// @param values the vector in which to insert the generated values
@@ -41,11 +46,10 struct ScalarCosinus : public ICosinusType {
41 46 int componentCount() const override { return 1; }
42 47
43 48 std::shared_ptr<IDataSeries> createDataSeries(std::vector<double> xAxisData,
44 std::vector<double> valuesData, Unit xAxisUnit,
45 Unit valuesUnit) const override
49 std::vector<double> valuesData) const override
46 50 {
47 51 return std::make_shared<ScalarSeries>(std::move(xAxisData), std::move(valuesData),
48 xAxisUnit, valuesUnit);
52 Unit{QStringLiteral("t"), true}, Unit{});
49 53 }
50 54
51 55 void generateValues(double x, std::vector<double> &values, int dataIndex) const override
@@ -56,20 +60,21 struct ScalarCosinus : public ICosinusType {
56 60
57 61 struct SpectrogramCosinus : public ICosinusType {
58 62 /// Ctor with y-axis
59 explicit SpectrogramCosinus(std::vector<double> yAxisData, Unit yAxisUnit)
60 : m_YAxisData{std::move(yAxisData)}, m_YAxisUnit{std::move(yAxisUnit)}
63 explicit SpectrogramCosinus(std::vector<double> yAxisData, Unit yAxisUnit, Unit valuesUnit)
64 : m_YAxisData{std::move(yAxisData)},
65 m_YAxisUnit{std::move(yAxisUnit)},
66 m_ValuesUnit{std::move(valuesUnit)}
61 67 {
62 68 }
63 69
64 70 int componentCount() const override { return m_YAxisData.size(); }
65 71
66 72 std::shared_ptr<IDataSeries> createDataSeries(std::vector<double> xAxisData,
67 std::vector<double> valuesData, Unit xAxisUnit,
68 Unit valuesUnit) const override
73 std::vector<double> valuesData) const override
69 74 {
70 return std::make_shared<SpectrogramSeries>(std::move(xAxisData), m_YAxisData,
71 std::move(valuesData), xAxisUnit, m_YAxisUnit,
72 valuesUnit);
75 return std::make_shared<SpectrogramSeries>(
76 std::move(xAxisData), m_YAxisData, std::move(valuesData),
77 Unit{QStringLiteral("t"), true}, m_YAxisUnit, m_ValuesUnit);
73 78 }
74 79
75 80 void generateValues(double x, std::vector<double> &values, int dataIndex) const override
@@ -77,8 +82,20 struct SpectrogramCosinus : public ICosinusType {
77 82 auto componentCount = this->componentCount();
78 83 for (int i = 0; i < componentCount; ++i) {
79 84 auto y = m_YAxisData[i];
80 auto r = 3 * std::sqrt(x * x + y * y) + 1e-2;
81 auto value = 2 * x * (std::cos(r + 2) / r - std::sin(r + 2) / r);
85
86 double value;
87
88 if (SPECTROGRAM_ZERO_BANDS.find(y) != SPECTROGRAM_ZERO_BANDS.end()) {
89 value = 0.;
90 }
91 else if (SPECTROGRAM_NAN_BANDS.find(y) != SPECTROGRAM_NAN_BANDS.end()) {
92 value = std::numeric_limits<double>::quiet_NaN();
93 }
94 else {
95 // Generates value for non NaN/zero bands
96 auto r = 3 * std::sqrt(x * x + y * y) + 1e-2;
97 value = 2 * x * (std::cos(r + 2) / r - std::sin(r + 2) / r);
98 }
82 99
83 100 values[componentCount * dataIndex + i] = value;
84 101 }
@@ -86,17 +103,17 struct SpectrogramCosinus : public ICosinusType {
86 103
87 104 std::vector<double> m_YAxisData;
88 105 Unit m_YAxisUnit;
106 Unit m_ValuesUnit;
89 107 };
90 108
91 109 struct VectorCosinus : public ICosinusType {
92 110 int componentCount() const override { return 3; }
93 111
94 112 std::shared_ptr<IDataSeries> createDataSeries(std::vector<double> xAxisData,
95 std::vector<double> valuesData, Unit xAxisUnit,
96 Unit valuesUnit) const override
113 std::vector<double> valuesData) const override
97 114 {
98 115 return std::make_shared<VectorSeries>(std::move(xAxisData), std::move(valuesData),
99 xAxisUnit, valuesUnit);
116 Unit{QStringLiteral("t"), true}, Unit{});
100 117 }
101 118
102 119 void generateValues(double x, std::vector<double> &values, int dataIndex) const override
@@ -122,7 +139,8 std::unique_ptr<ICosinusType> cosinusType(const QString &type) noexcept
122 139 std::vector<double> yAxisData(SPECTROGRAM_NUMBER_BANDS);
123 140 std::iota(yAxisData.begin(), yAxisData.end(), 0.);
124 141
125 return std::make_unique<SpectrogramCosinus>(std::move(yAxisData), Unit{"eV"});
142 return std::make_unique<SpectrogramCosinus>(std::move(yAxisData), Unit{"eV"},
143 Unit{"eV/(cm^2-s-sr-eV)"});
126 144 }
127 145 else if (type.compare(QStringLiteral("vector"), Qt::CaseInsensitive) == 0) {
128 146 return std::make_unique<VectorCosinus>();
@@ -226,8 +244,7 std::shared_ptr<IDataSeries> CosinusProvider::retrieveData(QUuid acqIdentifier,
226 244 // We can close progression beacause all data has been retrieved
227 245 emit dataProvidedProgress(acqIdentifier, 100);
228 246 }
229 return type->createDataSeries(std::move(xAxisData), std::move(valuesData),
230 Unit{QStringLiteral("t"), true}, Unit{});
247 return type->createDataSeries(std::move(xAxisData), std::move(valuesData));
231 248 }
232 249
233 250 void CosinusProvider::requestDataLoading(QUuid acqIdentifier,
General Comments 0
You need to be logged in to leave comments. Login now