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