@@ -0,0 +1,23 | |||
|
1 | #ifndef SCIQLOP_MOCKDEFS_H | |
|
2 | #define SCIQLOP_MOCKDEFS_H | |
|
3 | ||
|
4 | #include "MockPluginGlobal.h" | |
|
5 | ||
|
6 | #include <QString> | |
|
7 | #include <QVariant> | |
|
8 | ||
|
9 | // ////////////// // | |
|
10 | // Mock constants // | |
|
11 | // ////////////// // | |
|
12 | ||
|
13 | // Metadata for cosinus provider // | |
|
14 | ||
|
15 | /// Cosinus frequency (Hz) | |
|
16 | extern SCIQLOP_MOCKPLUGIN_EXPORT const QString COSINUS_FREQUENCY_KEY; | |
|
17 | extern SCIQLOP_MOCKPLUGIN_EXPORT const QVariant COSINUS_FREQUENCY_DEFAULT_VALUE; | |
|
18 | ||
|
19 | /// Cosinus type ("scalar" or "vector") | |
|
20 | extern SCIQLOP_MOCKPLUGIN_EXPORT const QString COSINUS_TYPE_KEY; | |
|
21 | extern SCIQLOP_MOCKPLUGIN_EXPORT const QVariant COSINUS_TYPE_DEFAULT_VALUE; | |
|
22 | ||
|
23 | #endif // SCIQLOP_MOCKDEFS_H |
@@ -0,0 +1,7 | |||
|
1 | #include "MockDefs.h" | |
|
2 | ||
|
3 | const QString COSINUS_FREQUENCY_KEY = QStringLiteral("cosinusFrequency"); | |
|
4 | const QVariant COSINUS_FREQUENCY_DEFAULT_VALUE = 60.; | |
|
5 | ||
|
6 | const QString COSINUS_TYPE_KEY = QStringLiteral("cosinusType"); | |
|
7 | const QVariant COSINUS_TYPE_DEFAULT_VALUE = QStringLiteral("scalar"); |
@@ -27,8 +27,8 public: | |||
|
27 | 27 | |
|
28 | 28 | |
|
29 | 29 | private: |
|
30 |
std::shared_ptr<IDataSeries> |
|
|
31 | const SqpRange &dataRangeRequested); | |
|
30 | std::shared_ptr<IDataSeries> | |
|
31 | retrieveData(QUuid acqIdentifier, const SqpRange &dataRangeRequested, const QVariantHash &data); | |
|
32 | 32 | |
|
33 | 33 | QHash<QUuid, bool> m_VariableToEnableProvider; |
|
34 | 34 | }; |
@@ -1,7 +1,9 | |||
|
1 | 1 | #include "CosinusProvider.h" |
|
2 | #include "MockDefs.h" | |
|
2 | 3 | |
|
3 | 4 | #include <Data/DataProviderParameters.h> |
|
4 | 5 | #include <Data/ScalarSeries.h> |
|
6 | #include <Data/VectorSeries.h> | |
|
5 | 7 | |
|
6 | 8 | #include <cmath> |
|
7 | 9 | |
@@ -11,6 +13,60 | |||
|
11 | 13 | |
|
12 | 14 | Q_LOGGING_CATEGORY(LOG_CosinusProvider, "CosinusProvider") |
|
13 | 15 | |
|
16 | namespace { | |
|
17 | ||
|
18 | /// Abstract cosinus type | |
|
19 | struct ICosinusType { | |
|
20 | virtual ~ICosinusType() = default; | |
|
21 | /// @return the number of components generated for the type | |
|
22 | virtual int componentCount() const = 0; | |
|
23 | /// @return the data series created for the type | |
|
24 | virtual std::shared_ptr<IDataSeries> createDataSeries(std::vector<double> xAxisData, | |
|
25 | std::vector<double> valuesData, | |
|
26 | Unit xAxisUnit, | |
|
27 | Unit valuesUnit) const = 0; | |
|
28 | }; | |
|
29 | ||
|
30 | struct ScalarCosinus : public ICosinusType { | |
|
31 | int componentCount() const override { return 1; } | |
|
32 | ||
|
33 | std::shared_ptr<IDataSeries> createDataSeries(std::vector<double> xAxisData, | |
|
34 | std::vector<double> valuesData, Unit xAxisUnit, | |
|
35 | Unit valuesUnit) const override | |
|
36 | { | |
|
37 | return std::make_shared<ScalarSeries>(std::move(xAxisData), std::move(valuesData), | |
|
38 | xAxisUnit, valuesUnit); | |
|
39 | } | |
|
40 | }; | |
|
41 | struct VectorCosinus : public ICosinusType { | |
|
42 | int componentCount() const override { return 3; } | |
|
43 | ||
|
44 | std::shared_ptr<IDataSeries> createDataSeries(std::vector<double> xAxisData, | |
|
45 | std::vector<double> valuesData, Unit xAxisUnit, | |
|
46 | Unit valuesUnit) const override | |
|
47 | { | |
|
48 | return std::make_shared<VectorSeries>(std::move(xAxisData), std::move(valuesData), | |
|
49 | xAxisUnit, valuesUnit); | |
|
50 | } | |
|
51 | }; | |
|
52 | ||
|
53 | /// Converts string to cosinus type | |
|
54 | /// @return the cosinus type if the string could be converted, nullptr otherwise | |
|
55 | std::unique_ptr<ICosinusType> cosinusType(const QString &type) noexcept | |
|
56 | { | |
|
57 | if (type.compare(QStringLiteral("scalar"), Qt::CaseInsensitive) == 0) { | |
|
58 | return std::make_unique<ScalarCosinus>(); | |
|
59 | } | |
|
60 | else if (type.compare(QStringLiteral("vector"), Qt::CaseInsensitive) == 0) { | |
|
61 | return std::make_unique<VectorCosinus>(); | |
|
62 | } | |
|
63 | else { | |
|
64 | return nullptr; | |
|
65 | } | |
|
66 | } | |
|
67 | ||
|
68 | } // namespace | |
|
69 | ||
|
14 | 70 | std::shared_ptr<IDataProvider> CosinusProvider::clone() const |
|
15 | 71 | { |
|
16 | 72 | // No copy is made in clone |
@@ -18,15 +74,36 std::shared_ptr<IDataProvider> CosinusProvider::clone() const | |||
|
18 | 74 | } |
|
19 | 75 | |
|
20 | 76 | std::shared_ptr<IDataSeries> CosinusProvider::retrieveData(QUuid acqIdentifier, |
|
21 |
const SqpRange &dataRangeRequested |
|
|
77 | const SqpRange &dataRangeRequested, | |
|
78 | const QVariantHash &data) | |
|
22 | 79 | { |
|
23 | 80 | // TODO: Add Mutex |
|
24 | 81 | auto dataIndex = 0; |
|
25 | 82 | |
|
83 | // Retrieves cosinus type | |
|
84 | auto typeVariant = data.value(COSINUS_TYPE_KEY, COSINUS_TYPE_DEFAULT_VALUE); | |
|
85 | if (!typeVariant.canConvert<QString>()) { | |
|
86 | qCCritical(LOG_CosinusProvider()) << tr("Can't retrieve data: invalid type"); | |
|
87 | return nullptr; | |
|
88 | } | |
|
89 | ||
|
90 | auto type = cosinusType(typeVariant.toString()); | |
|
91 | if (!type) { | |
|
92 | qCCritical(LOG_CosinusProvider()) << tr("Can't retrieve data: unknown type"); | |
|
93 | return nullptr; | |
|
94 | } | |
|
95 | ||
|
96 | // Retrieves frequency | |
|
97 | auto freqVariant = data.value(COSINUS_FREQUENCY_KEY, COSINUS_FREQUENCY_DEFAULT_VALUE); | |
|
98 | if (!freqVariant.canConvert<double>()) { | |
|
99 | qCCritical(LOG_CosinusProvider()) << tr("Can't retrieve data: invalid frequency"); | |
|
100 | return nullptr; | |
|
101 | } | |
|
102 | ||
|
26 | 103 | // Gets the timerange from the parameters |
|
27 |
double freq = |
|
|
28 |
double start = std::ceil(dataRangeRequested.m_TStart * freq); |
|
|
29 |
double end = std::floor(dataRangeRequested.m_TEnd * freq); |
|
|
104 | double freq = freqVariant.toDouble(); | |
|
105 | double start = std::ceil(dataRangeRequested.m_TStart * freq); | |
|
106 | double end = std::floor(dataRangeRequested.m_TEnd * freq); | |
|
30 | 107 | |
|
31 | 108 | // We assure that timerange is valid |
|
32 | 109 | if (end < start) { |
@@ -37,11 +114,14 std::shared_ptr<IDataSeries> CosinusProvider::retrieveData(QUuid acqIdentifier, | |||
|
37 | 114 | // included) |
|
38 | 115 | auto dataCount = end - start + 1; |
|
39 | 116 | |
|
117 | // Number of components (depending on the cosinus type) | |
|
118 | auto componentCount = type->componentCount(); | |
|
119 | ||
|
40 | 120 | auto xAxisData = std::vector<double>{}; |
|
41 | 121 | xAxisData.resize(dataCount); |
|
42 | 122 | |
|
43 | 123 | auto valuesData = std::vector<double>{}; |
|
44 | valuesData.resize(dataCount); | |
|
124 | valuesData.resize(dataCount * componentCount); | |
|
45 | 125 | |
|
46 | 126 | int progress = 0; |
|
47 | 127 | auto progressEnd = dataCount; |
@@ -51,7 +131,13 std::shared_ptr<IDataSeries> CosinusProvider::retrieveData(QUuid acqIdentifier, | |||
|
51 | 131 | const auto timeOnFreq = time / freq; |
|
52 | 132 | |
|
53 | 133 | xAxisData[dataIndex] = timeOnFreq; |
|
54 | 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 | } | |
|
55 | 141 | |
|
56 | 142 | // progression |
|
57 | 143 | int currentProgress = (time - start) * 100.0 / progressEnd; |
@@ -76,8 +162,8 std::shared_ptr<IDataSeries> CosinusProvider::retrieveData(QUuid acqIdentifier, | |||
|
76 | 162 | // We can close progression beacause all data has been retrieved |
|
77 | 163 | emit dataProvidedProgress(acqIdentifier, 100); |
|
78 | 164 | } |
|
79 |
return |
|
|
80 |
|
|
|
165 | return type->createDataSeries(std::move(xAxisData), std::move(valuesData), | |
|
166 | Unit{QStringLiteral("t"), true}, Unit{}); | |
|
81 | 167 | } |
|
82 | 168 | |
|
83 | 169 | void CosinusProvider::requestDataLoading(QUuid acqIdentifier, |
@@ -92,7 +178,7 void CosinusProvider::requestDataLoading(QUuid acqIdentifier, | |||
|
92 | 178 | |
|
93 | 179 | for (const auto &dateTime : qAsConst(times)) { |
|
94 | 180 | if (m_VariableToEnableProvider[acqIdentifier]) { |
|
95 | auto scalarSeries = this->retrieveData(acqIdentifier, dateTime); | |
|
181 | auto scalarSeries = this->retrieveData(acqIdentifier, dateTime, parameters.m_Data); | |
|
96 | 182 | qCDebug(LOG_CosinusProvider()) << "TORM: CosinusProvider::dataProvided"; |
|
97 | 183 | emit dataProvided(acqIdentifier, scalarSeries, dateTime); |
|
98 | 184 | } |
@@ -1,5 +1,6 | |||
|
1 | 1 | #include "MockPlugin.h" |
|
2 | 2 | #include "CosinusProvider.h" |
|
3 | #include "MockDefs.h" | |
|
3 | 4 | |
|
4 | 5 | #include <DataSource/DataSourceController.h> |
|
5 | 6 | #include <DataSource/DataSourceItem.h> |
@@ -20,10 +21,11 std::unique_ptr<IDataProvider> createDataProvider() noexcept | |||
|
20 | 21 | return std::make_unique<CosinusProvider>(); |
|
21 | 22 | } |
|
22 | 23 | |
|
23 |
std::unique_ptr<DataSourceItem> createProductItem(const Q |
|
|
24 | std::unique_ptr<DataSourceItem> createProductItem(const QVariantHash &data, | |
|
24 | 25 | const QUuid &dataSourceUid) |
|
25 | 26 | { |
|
26 |
auto result = std::make_unique<DataSourceItem>(DataSourceItemType::PRODUCT, |
|
|
27 | auto result = std::make_unique<DataSourceItem>(DataSourceItemType::PRODUCT, data); | |
|
28 | auto productName = data.value(DataSourceItem::NAME_DATA_KEY).toString(); | |
|
27 | 29 | |
|
28 | 30 | // Add action to load product from DataSourceController |
|
29 | 31 | result->addAction(std::make_unique<DataSourceItemAction>( |
@@ -43,8 +45,36 std::unique_ptr<DataSourceItem> createDataSourceItem(const QUuid &dataSourceUid) | |||
|
43 | 45 | // Magnetic field products |
|
44 | 46 | auto magneticFieldFolder = std::make_unique<DataSourceItem>(DataSourceItemType::NODE, |
|
45 | 47 | QStringLiteral("Magnetic field")); |
|
46 | magneticFieldFolder->appendChild(createProductItem(QStringLiteral("FGM"), dataSourceUid)); | |
|
47 | magneticFieldFolder->appendChild(createProductItem(QStringLiteral("SC"), dataSourceUid)); | |
|
48 | magneticFieldFolder->appendChild( | |
|
49 | createProductItem({{DataSourceItem::NAME_DATA_KEY, QStringLiteral("Scalar 10 Hz")}, | |
|
50 | {COSINUS_TYPE_KEY, "scalar"}, | |
|
51 | {COSINUS_FREQUENCY_KEY, 10.}}, | |
|
52 | dataSourceUid)); | |
|
53 | magneticFieldFolder->appendChild( | |
|
54 | createProductItem({{DataSourceItem::NAME_DATA_KEY, QStringLiteral("Scalar 60 Hz")}, | |
|
55 | {COSINUS_TYPE_KEY, "scalar"}, | |
|
56 | {COSINUS_FREQUENCY_KEY, 60.}}, | |
|
57 | dataSourceUid)); | |
|
58 | magneticFieldFolder->appendChild( | |
|
59 | createProductItem({{DataSourceItem::NAME_DATA_KEY, QStringLiteral("Scalar 100 Hz")}, | |
|
60 | {COSINUS_TYPE_KEY, "scalar"}, | |
|
61 | {COSINUS_FREQUENCY_KEY, 100.}}, | |
|
62 | dataSourceUid)); | |
|
63 | magneticFieldFolder->appendChild( | |
|
64 | createProductItem({{DataSourceItem::NAME_DATA_KEY, QStringLiteral("Vector 10 Hz")}, | |
|
65 | {COSINUS_TYPE_KEY, "vector"}, | |
|
66 | {COSINUS_FREQUENCY_KEY, 10.}}, | |
|
67 | dataSourceUid)); | |
|
68 | magneticFieldFolder->appendChild( | |
|
69 | createProductItem({{DataSourceItem::NAME_DATA_KEY, QStringLiteral("Vector 60 Hz")}, | |
|
70 | {COSINUS_TYPE_KEY, "vector"}, | |
|
71 | {COSINUS_FREQUENCY_KEY, 60.}}, | |
|
72 | dataSourceUid)); | |
|
73 | magneticFieldFolder->appendChild( | |
|
74 | createProductItem({{DataSourceItem::NAME_DATA_KEY, QStringLiteral("Vector 100 Hz")}, | |
|
75 | {COSINUS_TYPE_KEY, "vector"}, | |
|
76 | {COSINUS_FREQUENCY_KEY, 100.}}, | |
|
77 | dataSourceUid)); | |
|
48 | 78 | |
|
49 | 79 | // Electric field products |
|
50 | 80 | auto electricFieldFolder = std::make_unique<DataSourceItem>(DataSourceItemType::NODE, |
@@ -1,4 +1,5 | |||
|
1 | 1 | #include "CosinusProvider.h" |
|
2 | #include "MockDefs.h" | |
|
2 | 3 | |
|
3 | 4 | #include <Data/DataProviderParameters.h> |
|
4 | 5 | #include <Data/ScalarSeries.h> |
@@ -158,7 +159,8 void TestCosinusAcquisition::testAcquisition() | |||
|
158 | 159 | QFETCH(SqpRange, initialRange); |
|
159 | 160 | sqpApp->timeController().onTimeToUpdate(initialRange); |
|
160 | 161 | auto provider = std::make_shared<CosinusProvider>(); |
|
161 |
auto variable = sqpApp->variableController().createVariable( |
|
|
162 | auto variable = sqpApp->variableController().createVariable( | |
|
163 | "MMS", {{COSINUS_TYPE_KEY, "scalar"}, {COSINUS_FREQUENCY_KEY, 100.}}, provider); | |
|
162 | 164 | |
|
163 | 165 | QTest::qWait(OPERATION_DELAY); |
|
164 | 166 | validateVariable(variable, initialRange); |
General Comments 0
You need to be logged in to leave comments.
Login now