##// END OF EJS Templates
Updates generation of spectrogram in the mock plugin to set values' unit
Alexandre Leroux -
r914:487930a9dd9f
parent child
Show More
@@ -1,274 +1,272
1 #include "CosinusProvider.h"
1 #include "CosinusProvider.h"
2 #include "MockDefs.h"
2 #include "MockDefs.h"
3
3
4 #include <Data/DataProviderParameters.h>
4 #include <Data/DataProviderParameters.h>
5 #include <Data/ScalarSeries.h>
5 #include <Data/ScalarSeries.h>
6 #include <Data/SpectrogramSeries.h>
6 #include <Data/SpectrogramSeries.h>
7 #include <Data/VectorSeries.h>
7 #include <Data/VectorSeries.h>
8
8
9 #include <cmath>
9 #include <cmath>
10
10
11 #include <QFuture>
11 #include <QFuture>
12 #include <QThread>
12 #include <QThread>
13 #include <QtConcurrent/QtConcurrent>
13 #include <QtConcurrent/QtConcurrent>
14
14
15 Q_LOGGING_CATEGORY(LOG_CosinusProvider, "CosinusProvider")
15 Q_LOGGING_CATEGORY(LOG_CosinusProvider, "CosinusProvider")
16
16
17 namespace {
17 namespace {
18
18
19 /// Number of bands generated for a spectrogram
19 /// Number of bands generated for a spectrogram
20 const auto SPECTROGRAM_NUMBER_BANDS = 30;
20 const auto SPECTROGRAM_NUMBER_BANDS = 30;
21
21
22 /// Abstract cosinus type
22 /// Abstract cosinus type
23 struct ICosinusType {
23 struct ICosinusType {
24 virtual ~ICosinusType() = default;
24 virtual ~ICosinusType() = default;
25 /// @return the number of components generated for the type
25 /// @return the number of components generated for the type
26 virtual int componentCount() const = 0;
26 virtual int componentCount() const = 0;
27 /// @return the data series created for the type
27 /// @return the data series created for the type
28 virtual std::shared_ptr<IDataSeries> createDataSeries(std::vector<double> xAxisData,
28 virtual std::shared_ptr<IDataSeries> createDataSeries(std::vector<double> xAxisData,
29 std::vector<double> valuesData,
29 std::vector<double> valuesData) const = 0;
30 Unit xAxisUnit,
31 Unit valuesUnit) const = 0;
32 /// Generates values (one value per component)
30 /// Generates values (one value per component)
33 /// @param x the x-axis data used to generate values
31 /// @param x the x-axis data used to generate values
34 /// @param values the vector in which to insert the generated values
32 /// @param values the vector in which to insert the generated values
35 /// @param dataIndex the index of insertion of the generated values
33 /// @param dataIndex the index of insertion of the generated values
36 ///
34 ///
37 virtual void generateValues(double x, std::vector<double> &values, int dataIndex) const = 0;
35 virtual void generateValues(double x, std::vector<double> &values, int dataIndex) const = 0;
38 };
36 };
39
37
40 struct ScalarCosinus : public ICosinusType {
38 struct ScalarCosinus : public ICosinusType {
41 int componentCount() const override { return 1; }
39 int componentCount() const override { return 1; }
42
40
43 std::shared_ptr<IDataSeries> createDataSeries(std::vector<double> xAxisData,
41 std::shared_ptr<IDataSeries> createDataSeries(std::vector<double> xAxisData,
44 std::vector<double> valuesData, Unit xAxisUnit,
42 std::vector<double> valuesData) const override
45 Unit valuesUnit) const override
46 {
43 {
47 return std::make_shared<ScalarSeries>(std::move(xAxisData), std::move(valuesData),
44 return std::make_shared<ScalarSeries>(std::move(xAxisData), std::move(valuesData),
48 xAxisUnit, valuesUnit);
45 Unit{QStringLiteral("t"), true}, Unit{});
49 }
46 }
50
47
51 void generateValues(double x, std::vector<double> &values, int dataIndex) const override
48 void generateValues(double x, std::vector<double> &values, int dataIndex) const override
52 {
49 {
53 values[dataIndex] = std::cos(x);
50 values[dataIndex] = std::cos(x);
54 }
51 }
55 };
52 };
56
53
57 struct SpectrogramCosinus : public ICosinusType {
54 struct SpectrogramCosinus : public ICosinusType {
58 /// Ctor with y-axis
55 /// Ctor with y-axis
59 explicit SpectrogramCosinus(std::vector<double> yAxisData, Unit yAxisUnit)
56 explicit SpectrogramCosinus(std::vector<double> yAxisData, Unit yAxisUnit, Unit valuesUnit)
60 : m_YAxisData{std::move(yAxisData)}, m_YAxisUnit{std::move(yAxisUnit)}
57 : m_YAxisData{std::move(yAxisData)},
58 m_YAxisUnit{std::move(yAxisUnit)},
59 m_ValuesUnit{std::move(valuesUnit)}
61 {
60 {
62 }
61 }
63
62
64 int componentCount() const override { return m_YAxisData.size(); }
63 int componentCount() const override { return m_YAxisData.size(); }
65
64
66 std::shared_ptr<IDataSeries> createDataSeries(std::vector<double> xAxisData,
65 std::shared_ptr<IDataSeries> createDataSeries(std::vector<double> xAxisData,
67 std::vector<double> valuesData, Unit xAxisUnit,
66 std::vector<double> valuesData) const override
68 Unit valuesUnit) const override
69 {
67 {
70 return std::make_shared<SpectrogramSeries>(std::move(xAxisData), m_YAxisData,
68 return std::make_shared<SpectrogramSeries>(
71 std::move(valuesData), xAxisUnit, m_YAxisUnit,
69 std::move(xAxisData), m_YAxisData, std::move(valuesData),
72 valuesUnit);
70 Unit{QStringLiteral("t"), true}, m_YAxisUnit, m_ValuesUnit);
73 }
71 }
74
72
75 void generateValues(double x, std::vector<double> &values, int dataIndex) const override
73 void generateValues(double x, std::vector<double> &values, int dataIndex) const override
76 {
74 {
77 auto componentCount = this->componentCount();
75 auto componentCount = this->componentCount();
78 for (int i = 0; i < componentCount; ++i) {
76 for (int i = 0; i < componentCount; ++i) {
79 auto y = m_YAxisData[i];
77 auto y = m_YAxisData[i];
80 auto r = 3 * std::sqrt(x * x + y * y) + 1e-2;
78 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);
79 auto value = 2 * x * (std::cos(r + 2) / r - std::sin(r + 2) / r);
82
80
83 values[componentCount * dataIndex + i] = value;
81 values[componentCount * dataIndex + i] = value;
84 }
82 }
85 }
83 }
86
84
87 std::vector<double> m_YAxisData;
85 std::vector<double> m_YAxisData;
88 Unit m_YAxisUnit;
86 Unit m_YAxisUnit;
87 Unit m_ValuesUnit;
89 };
88 };
90
89
91 struct VectorCosinus : public ICosinusType {
90 struct VectorCosinus : public ICosinusType {
92 int componentCount() const override { return 3; }
91 int componentCount() const override { return 3; }
93
92
94 std::shared_ptr<IDataSeries> createDataSeries(std::vector<double> xAxisData,
93 std::shared_ptr<IDataSeries> createDataSeries(std::vector<double> xAxisData,
95 std::vector<double> valuesData, Unit xAxisUnit,
94 std::vector<double> valuesData) const override
96 Unit valuesUnit) const override
97 {
95 {
98 return std::make_shared<VectorSeries>(std::move(xAxisData), std::move(valuesData),
96 return std::make_shared<VectorSeries>(std::move(xAxisData), std::move(valuesData),
99 xAxisUnit, valuesUnit);
97 Unit{QStringLiteral("t"), true}, Unit{});
100 }
98 }
101
99
102 void generateValues(double x, std::vector<double> &values, int dataIndex) const override
100 void generateValues(double x, std::vector<double> &values, int dataIndex) const override
103 {
101 {
104 // Generates value for each component: cos(x), cos(x)/2, cos(x)/3
102 // Generates value for each component: cos(x), cos(x)/2, cos(x)/3
105 auto xValue = std::cos(x);
103 auto xValue = std::cos(x);
106 auto componentCount = this->componentCount();
104 auto componentCount = this->componentCount();
107 for (auto i = 0; i < componentCount; ++i) {
105 for (auto i = 0; i < componentCount; ++i) {
108 values[componentCount * dataIndex + i] = xValue / (i + 1);
106 values[componentCount * dataIndex + i] = xValue / (i + 1);
109 }
107 }
110 }
108 }
111 };
109 };
112
110
113 /// Converts string to cosinus type
111 /// Converts string to cosinus type
114 /// @return the cosinus type if the string could be converted, nullptr otherwise
112 /// @return the cosinus type if the string could be converted, nullptr otherwise
115 std::unique_ptr<ICosinusType> cosinusType(const QString &type) noexcept
113 std::unique_ptr<ICosinusType> cosinusType(const QString &type) noexcept
116 {
114 {
117 if (type.compare(QStringLiteral("scalar"), Qt::CaseInsensitive) == 0) {
115 if (type.compare(QStringLiteral("scalar"), Qt::CaseInsensitive) == 0) {
118 return std::make_unique<ScalarCosinus>();
116 return std::make_unique<ScalarCosinus>();
119 }
117 }
120 else if (type.compare(QStringLiteral("spectrogram"), Qt::CaseInsensitive) == 0) {
118 else if (type.compare(QStringLiteral("spectrogram"), Qt::CaseInsensitive) == 0) {
121 // Generates default y-axis data for spectrogram [0., 1., 2., ...]
119 // Generates default y-axis data for spectrogram [0., 1., 2., ...]
122 std::vector<double> yAxisData(SPECTROGRAM_NUMBER_BANDS);
120 std::vector<double> yAxisData(SPECTROGRAM_NUMBER_BANDS);
123 std::iota(yAxisData.begin(), yAxisData.end(), 0.);
121 std::iota(yAxisData.begin(), yAxisData.end(), 0.);
124
122
125 return std::make_unique<SpectrogramCosinus>(std::move(yAxisData), Unit{"eV"});
123 return std::make_unique<SpectrogramCosinus>(std::move(yAxisData), Unit{"eV"},
124 Unit{"eV/(cm^2-s-sr-eV)"});
126 }
125 }
127 else if (type.compare(QStringLiteral("vector"), Qt::CaseInsensitive) == 0) {
126 else if (type.compare(QStringLiteral("vector"), Qt::CaseInsensitive) == 0) {
128 return std::make_unique<VectorCosinus>();
127 return std::make_unique<VectorCosinus>();
129 }
128 }
130 else {
129 else {
131 return nullptr;
130 return nullptr;
132 }
131 }
133 }
132 }
134
133
135 } // namespace
134 } // namespace
136
135
137 std::shared_ptr<IDataProvider> CosinusProvider::clone() const
136 std::shared_ptr<IDataProvider> CosinusProvider::clone() const
138 {
137 {
139 // No copy is made in clone
138 // No copy is made in clone
140 return std::make_shared<CosinusProvider>();
139 return std::make_shared<CosinusProvider>();
141 }
140 }
142
141
143 std::shared_ptr<IDataSeries> CosinusProvider::retrieveData(QUuid acqIdentifier,
142 std::shared_ptr<IDataSeries> CosinusProvider::retrieveData(QUuid acqIdentifier,
144 const SqpRange &dataRangeRequested,
143 const SqpRange &dataRangeRequested,
145 const QVariantHash &data)
144 const QVariantHash &data)
146 {
145 {
147 // TODO: Add Mutex
146 // TODO: Add Mutex
148 auto dataIndex = 0;
147 auto dataIndex = 0;
149
148
150 // Retrieves cosinus type
149 // Retrieves cosinus type
151 auto typeVariant = data.value(COSINUS_TYPE_KEY, COSINUS_TYPE_DEFAULT_VALUE);
150 auto typeVariant = data.value(COSINUS_TYPE_KEY, COSINUS_TYPE_DEFAULT_VALUE);
152 if (!typeVariant.canConvert<QString>()) {
151 if (!typeVariant.canConvert<QString>()) {
153 qCCritical(LOG_CosinusProvider()) << tr("Can't retrieve data: invalid type");
152 qCCritical(LOG_CosinusProvider()) << tr("Can't retrieve data: invalid type");
154 return nullptr;
153 return nullptr;
155 }
154 }
156
155
157 auto type = cosinusType(typeVariant.toString());
156 auto type = cosinusType(typeVariant.toString());
158 if (!type) {
157 if (!type) {
159 qCCritical(LOG_CosinusProvider()) << tr("Can't retrieve data: unknown type");
158 qCCritical(LOG_CosinusProvider()) << tr("Can't retrieve data: unknown type");
160 return nullptr;
159 return nullptr;
161 }
160 }
162
161
163 // Retrieves frequency
162 // Retrieves frequency
164 auto freqVariant = data.value(COSINUS_FREQUENCY_KEY, COSINUS_FREQUENCY_DEFAULT_VALUE);
163 auto freqVariant = data.value(COSINUS_FREQUENCY_KEY, COSINUS_FREQUENCY_DEFAULT_VALUE);
165 if (!freqVariant.canConvert<double>()) {
164 if (!freqVariant.canConvert<double>()) {
166 qCCritical(LOG_CosinusProvider()) << tr("Can't retrieve data: invalid frequency");
165 qCCritical(LOG_CosinusProvider()) << tr("Can't retrieve data: invalid frequency");
167 return nullptr;
166 return nullptr;
168 }
167 }
169
168
170 // Gets the timerange from the parameters
169 // Gets the timerange from the parameters
171 double freq = freqVariant.toDouble();
170 double freq = freqVariant.toDouble();
172 double start = std::ceil(dataRangeRequested.m_TStart * freq);
171 double start = std::ceil(dataRangeRequested.m_TStart * freq);
173 double end = std::floor(dataRangeRequested.m_TEnd * freq);
172 double end = std::floor(dataRangeRequested.m_TEnd * freq);
174
173
175 // We assure that timerange is valid
174 // We assure that timerange is valid
176 if (end < start) {
175 if (end < start) {
177 std::swap(start, end);
176 std::swap(start, end);
178 }
177 }
179
178
180 // Generates scalar series containing cosinus values (one value per second, end value is
179 // Generates scalar series containing cosinus values (one value per second, end value is
181 // included)
180 // included)
182 auto dataCount = end - start + 1;
181 auto dataCount = end - start + 1;
183
182
184 // Number of components (depending on the cosinus type)
183 // Number of components (depending on the cosinus type)
185 auto componentCount = type->componentCount();
184 auto componentCount = type->componentCount();
186
185
187 auto xAxisData = std::vector<double>{};
186 auto xAxisData = std::vector<double>{};
188 xAxisData.resize(dataCount);
187 xAxisData.resize(dataCount);
189
188
190 auto valuesData = std::vector<double>{};
189 auto valuesData = std::vector<double>{};
191 valuesData.resize(dataCount * componentCount);
190 valuesData.resize(dataCount * componentCount);
192
191
193 int progress = 0;
192 int progress = 0;
194 auto progressEnd = dataCount;
193 auto progressEnd = dataCount;
195 for (auto time = start; time <= end; ++time, ++dataIndex) {
194 for (auto time = start; time <= end; ++time, ++dataIndex) {
196 auto it = m_VariableToEnableProvider.find(acqIdentifier);
195 auto it = m_VariableToEnableProvider.find(acqIdentifier);
197 if (it != m_VariableToEnableProvider.end() && it.value()) {
196 if (it != m_VariableToEnableProvider.end() && it.value()) {
198 const auto x = time / freq;
197 const auto x = time / freq;
199
198
200 xAxisData[dataIndex] = x;
199 xAxisData[dataIndex] = x;
201
200
202 // Generates values (depending on the type)
201 // Generates values (depending on the type)
203 type->generateValues(x, valuesData, dataIndex);
202 type->generateValues(x, valuesData, dataIndex);
204
203
205 // progression
204 // progression
206 int currentProgress = (time - start) * 100.0 / progressEnd;
205 int currentProgress = (time - start) * 100.0 / progressEnd;
207 if (currentProgress != progress) {
206 if (currentProgress != progress) {
208 progress = currentProgress;
207 progress = currentProgress;
209
208
210 emit dataProvidedProgress(acqIdentifier, progress);
209 emit dataProvidedProgress(acqIdentifier, progress);
211 qCDebug(LOG_CosinusProvider()) << "TORM: CosinusProvider::retrieveData"
210 qCDebug(LOG_CosinusProvider()) << "TORM: CosinusProvider::retrieveData"
212 << QThread::currentThread()->objectName()
211 << QThread::currentThread()->objectName()
213 << progress;
212 << progress;
214 // NOTE: Try to use multithread if possible
213 // NOTE: Try to use multithread if possible
215 }
214 }
216 }
215 }
217 else {
216 else {
218 if (!it.value()) {
217 if (!it.value()) {
219 qCDebug(LOG_CosinusProvider())
218 qCDebug(LOG_CosinusProvider())
220 << "CosinusProvider::retrieveData: ARRET De l'acquisition detectΓ©"
219 << "CosinusProvider::retrieveData: ARRET De l'acquisition detectΓ©"
221 << end - time;
220 << end - time;
222 }
221 }
223 }
222 }
224 }
223 }
225 if (progress != 100) {
224 if (progress != 100) {
226 // We can close progression beacause all data has been retrieved
225 // We can close progression beacause all data has been retrieved
227 emit dataProvidedProgress(acqIdentifier, 100);
226 emit dataProvidedProgress(acqIdentifier, 100);
228 }
227 }
229 return type->createDataSeries(std::move(xAxisData), std::move(valuesData),
228 return type->createDataSeries(std::move(xAxisData), std::move(valuesData));
230 Unit{QStringLiteral("t"), true}, Unit{});
231 }
229 }
232
230
233 void CosinusProvider::requestDataLoading(QUuid acqIdentifier,
231 void CosinusProvider::requestDataLoading(QUuid acqIdentifier,
234 const DataProviderParameters &parameters)
232 const DataProviderParameters &parameters)
235 {
233 {
236 // TODO: Add Mutex
234 // TODO: Add Mutex
237 m_VariableToEnableProvider[acqIdentifier] = true;
235 m_VariableToEnableProvider[acqIdentifier] = true;
238 qCDebug(LOG_CosinusProvider()) << "TORM: CosinusProvider::requestDataLoading"
236 qCDebug(LOG_CosinusProvider()) << "TORM: CosinusProvider::requestDataLoading"
239 << QThread::currentThread()->objectName();
237 << QThread::currentThread()->objectName();
240 // NOTE: Try to use multithread if possible
238 // NOTE: Try to use multithread if possible
241 const auto times = parameters.m_Times;
239 const auto times = parameters.m_Times;
242
240
243 for (const auto &dateTime : qAsConst(times)) {
241 for (const auto &dateTime : qAsConst(times)) {
244 if (m_VariableToEnableProvider[acqIdentifier]) {
242 if (m_VariableToEnableProvider[acqIdentifier]) {
245 auto scalarSeries = this->retrieveData(acqIdentifier, dateTime, parameters.m_Data);
243 auto scalarSeries = this->retrieveData(acqIdentifier, dateTime, parameters.m_Data);
246 emit dataProvided(acqIdentifier, scalarSeries, dateTime);
244 emit dataProvided(acqIdentifier, scalarSeries, dateTime);
247 }
245 }
248 }
246 }
249 }
247 }
250
248
251 void CosinusProvider::requestDataAborting(QUuid acqIdentifier)
249 void CosinusProvider::requestDataAborting(QUuid acqIdentifier)
252 {
250 {
253 qCDebug(LOG_CosinusProvider()) << "CosinusProvider::requestDataAborting" << acqIdentifier
251 qCDebug(LOG_CosinusProvider()) << "CosinusProvider::requestDataAborting" << acqIdentifier
254 << QThread::currentThread()->objectName();
252 << QThread::currentThread()->objectName();
255 auto it = m_VariableToEnableProvider.find(acqIdentifier);
253 auto it = m_VariableToEnableProvider.find(acqIdentifier);
256 if (it != m_VariableToEnableProvider.end()) {
254 if (it != m_VariableToEnableProvider.end()) {
257 it.value() = false;
255 it.value() = false;
258 }
256 }
259 else {
257 else {
260 qCDebug(LOG_CosinusProvider())
258 qCDebug(LOG_CosinusProvider())
261 << tr("Aborting progression of inexistant identifier detected !!!");
259 << tr("Aborting progression of inexistant identifier detected !!!");
262 }
260 }
263 }
261 }
264
262
265 std::shared_ptr<IDataSeries> CosinusProvider::provideDataSeries(const SqpRange &dataRangeRequested,
263 std::shared_ptr<IDataSeries> CosinusProvider::provideDataSeries(const SqpRange &dataRangeRequested,
266 const QVariantHash &data)
264 const QVariantHash &data)
267 {
265 {
268 auto uid = QUuid::createUuid();
266 auto uid = QUuid::createUuid();
269 m_VariableToEnableProvider[uid] = true;
267 m_VariableToEnableProvider[uid] = true;
270 auto dataSeries = this->retrieveData(uid, dataRangeRequested, data);
268 auto dataSeries = this->retrieveData(uid, dataRangeRequested, data);
271
269
272 m_VariableToEnableProvider.remove(uid);
270 m_VariableToEnableProvider.remove(uid);
273 return dataSeries;
271 return dataSeries;
274 }
272 }
General Comments 0
You need to be logged in to leave comments. Login now