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