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