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