##// END OF EJS Templates
Merge branch 'feature/ImprovePerfs3' into develop
Alexandre Leroux -
r648:cdcfd45a9b91 merge
parent child
Show More
@@ -77,7 +77,7 struct SortUtils {
77 for (auto i = 0, componentIndex = 0, permutationIndex = 0; i < containerSize;
77 for (auto i = 0, componentIndex = 0, permutationIndex = 0; i < containerSize;
78 ++i, componentIndex = i % nbValues, permutationIndex = i / nbValues) {
78 ++i, componentIndex = i % nbValues, permutationIndex = i / nbValues) {
79 auto insertIndex = sortPermutation.at(permutationIndex) * nbValues + componentIndex;
79 auto insertIndex = sortPermutation.at(permutationIndex) * nbValues + componentIndex;
80 sortedData.append(container.at(insertIndex));
80 sortedData.push_back(container.at(insertIndex));
81 }
81 }
82
82
83 return sortedData;
83 return sortedData;
@@ -13,7 +13,7
13 template <int Dim>
13 template <int Dim>
14 class ArrayData;
14 class ArrayData;
15
15
16 using DataContainer = QVector<double>;
16 using DataContainer = std::vector<double>;
17
17
18 namespace arraydata_detail {
18 namespace arraydata_detail {
19
19
@@ -121,13 +121,11 public:
121 std::unique_ptr<ArrayDataIteratorValue::Impl> advance(int offset) const override
121 std::unique_ptr<ArrayDataIteratorValue::Impl> advance(int offset) const override
122 {
122 {
123 auto result = clone();
123 auto result = clone();
124 while (offset--) {
124 result->next(offset);
125 result->next();
126 }
127 return result;
125 return result;
128 }
126 }
129
127
130 void next() override { std::advance(m_It, m_NbComponents); }
128 void next(int offset) override { std::advance(m_It, offset * m_NbComponents); }
131 void prev() override { std::advance(m_It, -m_NbComponents); }
129 void prev() override { std::advance(m_It, -m_NbComponents); }
132
130
133 double at(int componentIndex) const override { return *(m_It + componentIndex); }
131 double at(int componentIndex) const override { return *(m_It + componentIndex); }
@@ -256,16 +254,7 public:
256 return;
254 return;
257 }
255 }
258
256
259 if (prepend) {
257 insert(other.cbegin(), other.cend(), prepend);
260 auto otherDataSize = other.m_Data.size();
261 m_Data.insert(m_Data.begin(), otherDataSize, 0.);
262 for (auto i = 0; i < otherDataSize; ++i) {
263 m_Data.replace(i, other.m_Data.at(i));
264 }
265 }
266 else {
267 m_Data.append(other.m_Data);
268 }
269 }
258 }
270
259
271 void clear()
260 void clear()
@@ -332,16 +321,16 public:
332 }
321 }
333 }
322 }
334
323
335 /// Inserts at the end of the array data the values passed as a parameter. This
324 void insert(ArrayDataIterator first, ArrayDataIterator last, bool prepend = false)
336 /// method is intended to be used in the context of generating a back insert iterator, or only
337 /// if it's ensured that the total size of the vector is consistent with the number of
338 /// components of the array data
339 /// @param values the values to insert
340 /// @sa http://en.cppreference.com/w/cpp/iterator/back_inserter
341 void push_back(const QVector<double> &values)
342 {
325 {
343 Q_ASSERT(values.size() % m_NbComponents == 0);
326 auto firstImpl = dynamic_cast<arraydata_detail::IteratorValue<Dim, true> *>(first->impl());
344 m_Data.append(values);
327 auto lastImpl = dynamic_cast<arraydata_detail::IteratorValue<Dim, true> *>(last->impl());
328
329 if (firstImpl && lastImpl) {
330 auto insertIt = prepend ? m_Data.begin() : m_Data.end();
331
332 m_Data.insert(insertIt, firstImpl->m_It, lastImpl->m_It);
333 }
345 }
334 }
346
335
347 /**
336 /**
@@ -363,9 +352,8 public:
363 * @remarks this method is only available for a unidimensional ArrayData
352 * @remarks this method is only available for a unidimensional ArrayData
364 */
353 */
365 template <int D = Dim, typename = std::enable_if_t<D == 1> >
354 template <int D = Dim, typename = std::enable_if_t<D == 1> >
366 const QVector<double> &cdata() const noexcept
355 DataContainer cdata() const noexcept
367 {
356 {
368 QReadLocker locker{&m_Lock};
369 return m_Data;
357 return m_Data;
370 }
358 }
371
359
@@ -23,7 +23,7 public:
23 virtual bool equals(const Impl &other) const = 0;
23 virtual bool equals(const Impl &other) const = 0;
24 virtual bool lowerThan(const Impl &other) const = 0;
24 virtual bool lowerThan(const Impl &other) const = 0;
25 virtual std::unique_ptr<Impl> advance(int offset) const = 0;
25 virtual std::unique_ptr<Impl> advance(int offset) const = 0;
26 virtual void next() = 0;
26 virtual void next(int offset) = 0;
27 virtual void prev() = 0;
27 virtual void prev() = 0;
28 virtual double at(int componentIndex) const = 0;
28 virtual double at(int componentIndex) const = 0;
29 virtual double first() const = 0;
29 virtual double first() const = 0;
@@ -44,7 +44,7 public:
44
44
45 ArrayDataIteratorValue advance(int offset) const;
45 ArrayDataIteratorValue advance(int offset) const;
46 /// Advances to the next value
46 /// Advances to the next value
47 void next();
47 void next(int offset = 1);
48 /// Moves back to the previous value
48 /// Moves back to the previous value
49 void prev();
49 void prev();
50 /// Gets value of a specified component
50 /// Gets value of a specified component
@@ -81,16 +81,14 public:
81 std::unique_ptr<DataSeriesIteratorValue::Impl> advance(int offset) const override
81 std::unique_ptr<DataSeriesIteratorValue::Impl> advance(int offset) const override
82 {
82 {
83 auto result = clone();
83 auto result = clone();
84 while (offset--) {
84 result->next(offset);
85 result->next();
86 }
87 return result;
85 return result;
88 }
86 }
89
87
90 void next() override
88 void next(int offset) override
91 {
89 {
92 ++m_XIt;
90 m_XIt->next(offset);
93 ++m_ValuesIt;
91 m_ValuesIt->next(offset);
94 }
92 }
95
93
96 void prev() override
94 void prev() override
@@ -134,10 +132,6 class SCIQLOP_CORE_EXPORT DataSeries : public IDataSeries {
134 friend class DataSeriesMergeHelper;
132 friend class DataSeriesMergeHelper;
135
133
136 public:
134 public:
137 /// Tag needed to define the push_back() method
138 /// @sa push_back()
139 using value_type = DataSeriesIteratorValue;
140
141 /// @sa IDataSeries::xAxisData()
135 /// @sa IDataSeries::xAxisData()
142 std::shared_ptr<ArrayData<1> > xAxisData() override { return m_XAxisData; }
136 std::shared_ptr<ArrayData<1> > xAxisData() override { return m_XAxisData; }
143 const std::shared_ptr<ArrayData<1> > xAxisData() const { return m_XAxisData; }
137 const std::shared_ptr<ArrayData<1> > xAxisData() const { return m_XAxisData; }
@@ -155,8 +149,8 public:
155
149
156 SqpRange range() const override
150 SqpRange range() const override
157 {
151 {
158 if (!m_XAxisData->cdata().isEmpty()) {
152 if (!m_XAxisData->cdata().empty()) {
159 return SqpRange{m_XAxisData->cdata().first(), m_XAxisData->cdata().last()};
153 return SqpRange{m_XAxisData->cdata().front(), m_XAxisData->cdata().back()};
160 }
154 }
161
155
162 return SqpRange{};
156 return SqpRange{};
@@ -254,6 +248,17 public:
254 }
248 }
255 }
249 }
256
250
251 void insert(DataSeriesIterator first, DataSeriesIterator last, bool prepend = false)
252 {
253 auto firstImpl = dynamic_cast<dataseries_detail::IteratorValue<Dim, true> *>(first->impl());
254 auto lastImpl = dynamic_cast<dataseries_detail::IteratorValue<Dim, true> *>(last->impl());
255
256 if (firstImpl && lastImpl) {
257 m_XAxisData->insert(firstImpl->m_XIt, lastImpl->m_XIt, prepend);
258 m_ValuesData->insert(firstImpl->m_ValuesIt, lastImpl->m_ValuesIt, prepend);
259 }
260 }
261
257 /// @sa IDataSeries::minXAxisData()
262 /// @sa IDataSeries::minXAxisData()
258 DataSeriesIterator minXAxisData(double minXAxisData) const override
263 DataSeriesIterator minXAxisData(double minXAxisData) const override
259 {
264 {
@@ -287,7 +292,7 public:
287 begin, end, minXAxisData,
292 begin, end, minXAxisData,
288 [](const auto &itValue, const auto &value) { return itValue.x() < value; });
293 [](const auto &itValue, const auto &value) { return itValue.x() < value; });
289 auto upperIt = std::upper_bound(
294 auto upperIt = std::upper_bound(
290 begin, end, maxXAxisData,
295 lowerIt, end, maxXAxisData,
291 [](const auto &value, const auto &itValue) { return value < itValue.x(); });
296 [](const auto &value, const auto &itValue) { return value < itValue.x(); });
292
297
293 return std::make_pair(lowerIt, upperIt);
298 return std::make_pair(lowerIt, upperIt);
@@ -327,22 +332,6 public:
327 virtual void lockWrite() { m_Lock.lockForWrite(); }
332 virtual void lockWrite() { m_Lock.lockForWrite(); }
328 virtual void unlock() { m_Lock.unlock(); }
333 virtual void unlock() { m_Lock.unlock(); }
329
334
330 // ///// //
331 // Other //
332 // ///// //
333
334 /// Inserts at the end of the data series the value of the iterator passed as a parameter. This
335 /// method is intended to be used in the context of generating a back insert iterator
336 /// @param iteratorValue the iterator value containing the values to insert
337 /// @sa http://en.cppreference.com/w/cpp/iterator/back_inserter
338 /// @sa merge()
339 /// @sa value_type
340 void push_back(const value_type &iteratorValue)
341 {
342 m_XAxisData->push_back(QVector<double>{iteratorValue.x()});
343 m_ValuesData->push_back(iteratorValue.values());
344 }
345
346 protected:
335 protected:
347 /// Protected ctor (DataSeries is abstract). The vectors must have the same size, otherwise a
336 /// Protected ctor (DataSeries is abstract). The vectors must have the same size, otherwise a
348 /// DataSeries with no values will be created.
337 /// DataSeries with no values will be created.
@@ -24,7 +24,7 public:
24 virtual bool equals(const Impl &other) const = 0;
24 virtual bool equals(const Impl &other) const = 0;
25 virtual bool lowerThan(const Impl &other) const = 0;
25 virtual bool lowerThan(const Impl &other) const = 0;
26 virtual std::unique_ptr<Impl> advance(int offset) const = 0;
26 virtual std::unique_ptr<Impl> advance(int offset) const = 0;
27 virtual void next() = 0;
27 virtual void next(int offset) = 0;
28 virtual void prev() = 0;
28 virtual void prev() = 0;
29 virtual double x() const = 0;
29 virtual double x() const = 0;
30 virtual double value() const = 0;
30 virtual double value() const = 0;
@@ -46,7 +46,7 public:
46
46
47 DataSeriesIteratorValue advance(int offset) const;
47 DataSeriesIteratorValue advance(int offset) const;
48 /// Advances to the next value
48 /// Advances to the next value
49 void next();
49 void next(int offset = 1);
50 /// Moves back to the previous value
50 /// Moves back to the previous value
51 void prev();
51 void prev();
52 /// Gets x-axis data
52 /// Gets x-axis data
@@ -27,45 +27,6 MergeScope<FEnd> scope(FEnd end)
27 return MergeScope<FEnd>{end};
27 return MergeScope<FEnd>{end};
28 }
28 }
29
29
30 /**
31 * Enum used to position a data series relative to another during a merge operation
32 */
33 enum class MergePosition { LOWER_THAN, GREATER_THAN, EQUAL, OVERLAP };
34
35 /**
36 * Computes the position of the first data series relative to the second data series
37 * @param lhs the first data series
38 * @param rhs the second data series
39 * @return the merge position computed
40 * @remarks the data series must not be empty
41 */
42 template <int Dim>
43 MergePosition mergePosition(DataSeries<Dim> &lhs, DataSeries<Dim> &rhs)
44 {
45 Q_ASSERT(!lhs.isEmpty() && !rhs.isEmpty());
46
47 // Case lhs < rhs
48 auto lhsLast = --lhs.cend();
49 auto rhsFirst = rhs.cbegin();
50 if (lhsLast->x() < rhsFirst->x()) {
51 return MergePosition::LOWER_THAN;
52 }
53
54 // Case lhs > rhs
55 auto lhsFirst = lhs.cbegin();
56 auto rhsLast = --rhs.cend();
57 if (lhsFirst->x() > rhsLast->x()) {
58 return MergePosition::GREATER_THAN;
59 }
60
61 // Other cases
62 auto equal = std::equal(lhs.cbegin(), lhs.cend(), rhs.cbegin(), rhs.cend(),
63 [](const auto &it1, const auto &it2) {
64 return it1.x() == it2.x() && it1.values() == it2.values();
65 });
66 return equal ? MergePosition::EQUAL : MergePosition::OVERLAP;
67 }
68
69 } // namespace detail
30 } // namespace detail
70
31
71
32
@@ -92,40 +53,30 struct DataSeriesMergeHelper {
92 return;
53 return;
93 }
54 }
94
55
95 // Gets the position of the source in relation to the destination
56 auto destMin = dest.cbegin()->x();
96 auto sourcePosition = detail::mergePosition(source, dest);
57 auto destMax = (--dest.cend())->x();
58
59 auto sourceBegin = source.cbegin();
60 auto sourceEnd = source.cend();
61 auto sourceMin = sourceBegin->x();
62 auto sourceMax = (--source.cend())->x();
97
63
98 switch (sourcePosition) {
64 // Case : source bounds are inside dest bounds -> no merge is made
99 case detail::MergePosition::LOWER_THAN:
65 if (sourceMin >= destMin && sourceMax <= destMax) {
100 case detail::MergePosition::GREATER_THAN: {
66 return;
101 auto prepend = sourcePosition == detail::MergePosition::LOWER_THAN;
102 dest.m_XAxisData->add(*source.m_XAxisData, prepend);
103 dest.m_ValuesData->add(*source.m_ValuesData, prepend);
104 break;
105 }
106 case detail::MergePosition::EQUAL:
107 // the data series equal each other : no merge made
108 break;
109 case detail::MergePosition::OVERLAP: {
110 // the two data series overlap : merge is made
111 auto temp = dest.clone();
112 if (auto tempSeries = dynamic_cast<DataSeries<Dim> *>(temp.get())) {
113 // Makes the merge :
114 // - Data are sorted by x-axis values
115 // - If two entries are in the source range and the other range, only one entry
116 // is retained as result
117 // - The results are stored directly in the data series
118 dest.clear();
119 std::set_union(
120 tempSeries->cbegin(), tempSeries->cend(), source.cbegin(), source.cend(),
121 std::back_inserter(dest),
122 [](const auto &it1, const auto &it2) { return it1.x() < it2.x(); });
123 }
124 break;
125 }
126 default:
127 Q_ASSERT(false);
128 }
67 }
68
69 // Default case :
70 // - prepend to dest the values of source that are lower than min value of dest
71 // - append to dest the values of source that are greater than max value of dest
72 auto lowerIt
73 = std::lower_bound(sourceBegin, sourceEnd, destMin,
74 [](const auto &it, const auto &val) { return it.x() < val; });
75 auto upperIt
76 = std::upper_bound(lowerIt, sourceEnd, destMax,
77 [](const auto &val, const auto &it) { return val < it.x(); });
78 dest.insert(sourceBegin, lowerIt, true);
79 dest.insert(upperIt, sourceEnd);
129 }
80 }
130 };
81 };
131
82
@@ -16,7 +16,7 public:
16 * @param xAxisData x-axis data
16 * @param xAxisData x-axis data
17 * @param valuesData values data
17 * @param valuesData values data
18 */
18 */
19 explicit ScalarSeries(QVector<double> xAxisData, QVector<double> valuesData,
19 explicit ScalarSeries(std::vector<double> xAxisData, std::vector<double> valuesData,
20 const Unit &xAxisUnit, const Unit &valuesUnit);
20 const Unit &xAxisUnit, const Unit &valuesUnit);
21
21
22 std::unique_ptr<IDataSeries> clone() const override;
22 std::unique_ptr<IDataSeries> clone() const override;
@@ -52,9 +52,7 public:
52 SqpIterator &operator+=(int offset)
52 SqpIterator &operator+=(int offset)
53 {
53 {
54 if (offset >= 0) {
54 if (offset >= 0) {
55 while (offset--) {
55 m_CurrentValue.next(offset);
56 m_CurrentValue.next();
57 }
58 }
56 }
59 else {
57 else {
60 while (offset++) {
58 while (offset++) {
@@ -18,12 +18,12 public:
18 * @param yvaluesData y-values data
18 * @param yvaluesData y-values data
19 * @param zvaluesData z-values data
19 * @param zvaluesData z-values data
20 */
20 */
21 explicit VectorSeries(QVector<double> xAxisData, QVector<double> xValuesData,
21 explicit VectorSeries(std::vector<double> xAxisData, std::vector<double> xValuesData,
22 QVector<double> yValuesData, QVector<double> zValuesData,
22 std::vector<double> yValuesData, std::vector<double> zValuesData,
23 const Unit &xAxisUnit, const Unit &valuesUnit);
23 const Unit &xAxisUnit, const Unit &valuesUnit);
24
24
25 /// Default Ctor
25 /// Default Ctor
26 explicit VectorSeries(QVector<double> xAxisData, QVector<double> valuesData,
26 explicit VectorSeries(std::vector<double> xAxisData, std::vector<double> valuesData,
27 const Unit &xAxisUnit, const Unit &valuesUnit);
27 const Unit &xAxisUnit, const Unit &valuesUnit);
28
28
29 std::unique_ptr<IDataSeries> clone() const;
29 std::unique_ptr<IDataSeries> clone() const;
@@ -36,9 +36,9 ArrayDataIteratorValue ArrayDataIteratorValue::advance(int offset) const
36 return ArrayDataIteratorValue{m_Impl->advance(offset)};
36 return ArrayDataIteratorValue{m_Impl->advance(offset)};
37 }
37 }
38
38
39 void ArrayDataIteratorValue::next()
39 void ArrayDataIteratorValue::next(int offset)
40 {
40 {
41 m_Impl->next();
41 m_Impl->next(offset);
42 }
42 }
43
43
44 void ArrayDataIteratorValue::prev()
44 void ArrayDataIteratorValue::prev()
@@ -38,9 +38,9 DataSeriesIteratorValue DataSeriesIteratorValue::advance(int offset) const
38 return DataSeriesIteratorValue{m_Impl->advance(offset)};
38 return DataSeriesIteratorValue{m_Impl->advance(offset)};
39 }
39 }
40
40
41 void DataSeriesIteratorValue::next()
41 void DataSeriesIteratorValue::next(int offset)
42 {
42 {
43 m_Impl->next();
43 m_Impl->next(offset);
44 }
44 }
45
45
46 void DataSeriesIteratorValue::prev()
46 void DataSeriesIteratorValue::prev()
@@ -1,6 +1,6
1 #include <Data/ScalarSeries.h>
1 #include <Data/ScalarSeries.h>
2
2
3 ScalarSeries::ScalarSeries(QVector<double> xAxisData, QVector<double> valuesData,
3 ScalarSeries::ScalarSeries(std::vector<double> xAxisData, std::vector<double> valuesData,
4 const Unit &xAxisUnit, const Unit &valuesUnit)
4 const Unit &xAxisUnit, const Unit &valuesUnit)
5 : DataSeries{std::make_shared<ArrayData<1> >(std::move(xAxisData)), xAxisUnit,
5 : DataSeries{std::make_shared<ArrayData<1> >(std::move(xAxisData)), xAxisUnit,
6 std::make_shared<ArrayData<1> >(std::move(valuesData)), valuesUnit}
6 std::make_shared<ArrayData<1> >(std::move(valuesData)), valuesUnit}
@@ -14,18 +14,18 std::unique_ptr<IDataSeries> ScalarSeries::clone() const
14
14
15 std::shared_ptr<IDataSeries> ScalarSeries::subDataSeries(const SqpRange &range)
15 std::shared_ptr<IDataSeries> ScalarSeries::subDataSeries(const SqpRange &range)
16 {
16 {
17 auto subXAxisData = QVector<double>();
17 auto subXAxisData = std::vector<double>();
18 auto subValuesData = QVector<double>();
18 auto subValuesData = std::vector<double>();
19 this->lockRead();
19 this->lockRead();
20 {
20 {
21 auto bounds = xAxisRange(range.m_TStart, range.m_TEnd);
21 auto bounds = xAxisRange(range.m_TStart, range.m_TEnd);
22 for (auto it = bounds.first; it != bounds.second; ++it) {
22 for (auto it = bounds.first; it != bounds.second; ++it) {
23 subXAxisData.append(it->x());
23 subXAxisData.push_back(it->x());
24 subValuesData.append(it->value());
24 subValuesData.push_back(it->value());
25 }
25 }
26 }
26 }
27 this->unlock();
27 this->unlock();
28
28
29 return std::make_shared<ScalarSeries>(subXAxisData, subValuesData, this->xAxisUnit(),
29 return std::make_shared<ScalarSeries>(std::move(subXAxisData), std::move(subValuesData),
30 this->valuesUnit());
30 this->xAxisUnit(), this->valuesUnit());
31 }
31 }
@@ -19,18 +19,22 namespace {
19 * @remarks the three components are consumed
19 * @remarks the three components are consumed
20 * @sa ArrayData
20 * @sa ArrayData
21 */
21 */
22 QVector<double> flatten(QVector<double> xValues, QVector<double> yValues, QVector<double> zValues)
22 std::vector<double> flatten(std::vector<double> xValues, std::vector<double> yValues,
23 std::vector<double> zValues)
23 {
24 {
24 if (xValues.size() != yValues.size() || xValues.size() != zValues.size()) {
25 if (xValues.size() != yValues.size() || xValues.size() != zValues.size()) {
25 /// @todo ALX : log
26 /// @todo ALX : log
26 return {};
27 return {};
27 }
28 }
28
29
29 auto result = QVector<double>{};
30 auto result = std::vector<double>();
30 result.reserve(xValues.size() * 3);
31 result.reserve(xValues.size() * 3);
31
32
32 while (!xValues.isEmpty()) {
33 while (!xValues.empty()) {
33 result.append({xValues.takeFirst(), yValues.takeFirst(), zValues.takeFirst()});
34 result.insert(result.cend(), {xValues.front(), yValues.front(), zValues.front()});
35 xValues.erase(xValues.begin());
36 yValues.erase(yValues.begin());
37 zValues.erase(zValues.begin());
34 }
38 }
35
39
36 return result;
40 return result;
@@ -38,8 +42,8 QVector<double> flatten(QVector<double> xValues, QVector<double> yValues, QVecto
38
42
39 } // namespace
43 } // namespace
40
44
41 VectorSeries::VectorSeries(QVector<double> xAxisData, QVector<double> xValuesData,
45 VectorSeries::VectorSeries(std::vector<double> xAxisData, std::vector<double> xValuesData,
42 QVector<double> yValuesData, QVector<double> zValuesData,
46 std::vector<double> yValuesData, std::vector<double> zValuesData,
43 const Unit &xAxisUnit, const Unit &valuesUnit)
47 const Unit &xAxisUnit, const Unit &valuesUnit)
44 : VectorSeries{std::move(xAxisData), flatten(std::move(xValuesData), std::move(yValuesData),
48 : VectorSeries{std::move(xAxisData), flatten(std::move(xValuesData), std::move(yValuesData),
45 std::move(zValuesData)),
49 std::move(zValuesData)),
@@ -47,7 +51,7 VectorSeries::VectorSeries(QVector<double> xAxisData, QVector<double> xValuesDat
47 {
51 {
48 }
52 }
49
53
50 VectorSeries::VectorSeries(QVector<double> xAxisData, QVector<double> valuesData,
54 VectorSeries::VectorSeries(std::vector<double> xAxisData, std::vector<double> valuesData,
51 const Unit &xAxisUnit, const Unit &valuesUnit)
55 const Unit &xAxisUnit, const Unit &valuesUnit)
52 : DataSeries{std::make_shared<ArrayData<1> >(std::move(xAxisData)), xAxisUnit,
56 : DataSeries{std::make_shared<ArrayData<1> >(std::move(xAxisData)), xAxisUnit,
53 std::make_shared<ArrayData<2> >(std::move(valuesData), 3), valuesUnit}
57 std::make_shared<ArrayData<2> >(std::move(valuesData), 3), valuesUnit}
@@ -61,23 +65,24 std::unique_ptr<IDataSeries> VectorSeries::clone() const
61
65
62 std::shared_ptr<IDataSeries> VectorSeries::subDataSeries(const SqpRange &range)
66 std::shared_ptr<IDataSeries> VectorSeries::subDataSeries(const SqpRange &range)
63 {
67 {
64 auto subXAxisData = QVector<double>();
68 auto subXAxisData = std::vector<double>();
65 auto subXValuesData = QVector<double>();
69 auto subXValuesData = std::vector<double>();
66 auto subYValuesData = QVector<double>();
70 auto subYValuesData = std::vector<double>();
67 auto subZValuesData = QVector<double>();
71 auto subZValuesData = std::vector<double>();
68
72
69 this->lockRead();
73 this->lockRead();
70 {
74 {
71 auto bounds = xAxisRange(range.m_TStart, range.m_TEnd);
75 auto bounds = xAxisRange(range.m_TStart, range.m_TEnd);
72 for (auto it = bounds.first; it != bounds.second; ++it) {
76 for (auto it = bounds.first; it != bounds.second; ++it) {
73 subXAxisData.append(it->x());
77 subXAxisData.push_back(it->x());
74 subXValuesData.append(it->value(0));
78 subXValuesData.push_back(it->value(0));
75 subYValuesData.append(it->value(1));
79 subYValuesData.push_back(it->value(1));
76 subZValuesData.append(it->value(2));
80 subZValuesData.push_back(it->value(2));
77 }
81 }
78 }
82 }
79 this->unlock();
83 this->unlock();
80
84
81 return std::make_shared<VectorSeries>(subXAxisData, subXValuesData, subYValuesData,
85 return std::make_shared<VectorSeries>(std::move(subXAxisData), std::move(subXValuesData),
82 subZValuesData, this->xAxisUnit(), this->valuesUnit());
86 std::move(subYValuesData), std::move(subZValuesData),
87 this->xAxisUnit(), this->valuesUnit());
83 }
88 }
@@ -12,8 +12,10 Q_DECLARE_METATYPE(std::shared_ptr<VectorSeries>)
12
12
13 namespace {
13 namespace {
14
14
15 void validateRange(DataSeriesIterator first, DataSeriesIterator last, const QVector<double> &xData,
15 using DataContainer = std::vector<double>;
16 const QVector<double> &valuesData)
16
17 void validateRange(DataSeriesIterator first, DataSeriesIterator last, const DataContainer &xData,
18 const DataContainer &valuesData)
17 {
19 {
18 QVERIFY(std::equal(first, last, xData.cbegin(), xData.cend(),
20 QVERIFY(std::equal(first, last, xData.cbegin(), xData.cend(),
19 [](const auto &it, const auto &expectedX) { return it.x() == expectedX; }));
21 [](const auto &it, const auto &expectedX) { return it.x() == expectedX; }));
@@ -22,8 +24,8 void validateRange(DataSeriesIterator first, DataSeriesIterator last, const QVec
22 [](const auto &it, const auto &expectedVal) { return it.value() == expectedVal; }));
24 [](const auto &it, const auto &expectedVal) { return it.value() == expectedVal; }));
23 }
25 }
24
26
25 void validateRange(DataSeriesIterator first, DataSeriesIterator last, const QVector<double> &xData,
27 void validateRange(DataSeriesIterator first, DataSeriesIterator last, const DataContainer &xData,
26 const QVector<QVector<double> > &valuesData)
28 const std::vector<DataContainer> &valuesData)
27 {
29 {
28 QVERIFY(std::equal(first, last, xData.cbegin(), xData.cend(),
30 QVERIFY(std::equal(first, last, xData.cbegin(), xData.cend(),
29 [](const auto &it, const auto &expectedX) { return it.x() == expectedX; }));
31 [](const auto &it, const auto &expectedX) { return it.x() == expectedX; }));
@@ -102,8 +104,8 private:
102 QTest::addColumn<double>("max");
104 QTest::addColumn<double>("max");
103
105
104 // Expected values after purge
106 // Expected values after purge
105 QTest::addColumn<QVector<double> >("expectedXAxisData");
107 QTest::addColumn<DataContainer>("expectedXAxisData");
106 QTest::addColumn<QVector<QVector<double> > >("expectedValuesData");
108 QTest::addColumn<std::vector<DataContainer> >("expectedValuesData");
107 }
109 }
108
110
109 template <typename T>
111 template <typename T>
@@ -116,8 +118,8 private:
116 dataSeries->purge(min, max);
118 dataSeries->purge(min, max);
117
119
118 // Validates results
120 // Validates results
119 QFETCH(QVector<double>, expectedXAxisData);
121 QFETCH(DataContainer, expectedXAxisData);
120 QFETCH(QVector<QVector<double> >, expectedValuesData);
122 QFETCH(std::vector<DataContainer>, expectedValuesData);
121
123
122 validateRange(dataSeries->cbegin(), dataSeries->cend(), expectedXAxisData,
124 validateRange(dataSeries->cbegin(), dataSeries->cend(), expectedXAxisData,
123 expectedValuesData);
125 expectedValuesData);
@@ -196,67 +198,65 void TestDataSeries::testCtor_data()
196 // ////////////// //
198 // ////////////// //
197
199
198 // x-axis data
200 // x-axis data
199 QTest::addColumn<QVector<double> >("xAxisData");
201 QTest::addColumn<DataContainer>("xAxisData");
200 // values data
202 // values data
201 QTest::addColumn<QVector<double> >("valuesData");
203 QTest::addColumn<DataContainer>("valuesData");
202
204
203 // expected x-axis data
205 // expected x-axis data
204 QTest::addColumn<QVector<double> >("expectedXAxisData");
206 QTest::addColumn<DataContainer>("expectedXAxisData");
205 // expected values data
207 // expected values data
206 QTest::addColumn<QVector<double> >("expectedValuesData");
208 QTest::addColumn<DataContainer>("expectedValuesData");
207
209
208 // ////////// //
210 // ////////// //
209 // Test cases //
211 // Test cases //
210 // ////////// //
212 // ////////// //
211
213
212 QTest::newRow("invalidData (different sizes of vectors)")
214 QTest::newRow("invalidData (different sizes of vectors)")
213 << QVector<double>{1., 2., 3., 4., 5.} << QVector<double>{100., 200., 300.}
215 << DataContainer{1., 2., 3., 4., 5.} << DataContainer{100., 200., 300.} << DataContainer{}
214 << QVector<double>{} << QVector<double>{};
216 << DataContainer{};
215
217
216 QTest::newRow("sortedData") << QVector<double>{1., 2., 3., 4., 5.}
218 QTest::newRow("sortedData") << DataContainer{1., 2., 3., 4., 5.}
217 << QVector<double>{100., 200., 300., 400., 500.}
219 << DataContainer{100., 200., 300., 400., 500.}
218 << QVector<double>{1., 2., 3., 4., 5.}
220 << DataContainer{1., 2., 3., 4., 5.}
219 << QVector<double>{100., 200., 300., 400., 500.};
221 << DataContainer{100., 200., 300., 400., 500.};
220
222
221 QTest::newRow("unsortedData") << QVector<double>{5., 4., 3., 2., 1.}
223 QTest::newRow("unsortedData") << DataContainer{5., 4., 3., 2., 1.}
222 << QVector<double>{100., 200., 300., 400., 500.}
224 << DataContainer{100., 200., 300., 400., 500.}
223 << QVector<double>{1., 2., 3., 4., 5.}
225 << DataContainer{1., 2., 3., 4., 5.}
224 << QVector<double>{500., 400., 300., 200., 100.};
226 << DataContainer{500., 400., 300., 200., 100.};
225
227
226 QTest::newRow("unsortedData2")
228 QTest::newRow("unsortedData2")
227 << QVector<double>{1., 4., 3., 5., 2.} << QVector<double>{100., 200., 300., 400., 500.}
229 << DataContainer{1., 4., 3., 5., 2.} << DataContainer{100., 200., 300., 400., 500.}
228 << QVector<double>{1., 2., 3., 4., 5.} << QVector<double>{100., 500., 300., 200., 400.};
230 << DataContainer{1., 2., 3., 4., 5.} << DataContainer{100., 500., 300., 200., 400.};
229 }
231 }
230
232
231 void TestDataSeries::testCtor()
233 void TestDataSeries::testCtor()
232 {
234 {
233 // Creates series
235 // Creates series
234 QFETCH(QVector<double>, xAxisData);
236 QFETCH(DataContainer, xAxisData);
235 QFETCH(QVector<double>, valuesData);
237 QFETCH(DataContainer, valuesData);
236
238
237 auto series = std::make_shared<ScalarSeries>(std::move(xAxisData), std::move(valuesData),
239 auto series = std::make_shared<ScalarSeries>(std::move(xAxisData), std::move(valuesData),
238 Unit{}, Unit{});
240 Unit{}, Unit{});
239
241
240 // Validates results : we check that the data series is sorted on its x-axis data
242 // Validates results : we check that the data series is sorted on its x-axis data
241 QFETCH(QVector<double>, expectedXAxisData);
243 QFETCH(DataContainer, expectedXAxisData);
242 QFETCH(QVector<double>, expectedValuesData);
244 QFETCH(DataContainer, expectedValuesData);
243
245
244 validateRange(series->cbegin(), series->cend(), expectedXAxisData, expectedValuesData);
246 validateRange(series->cbegin(), series->cend(), expectedXAxisData, expectedValuesData);
245 }
247 }
246
248
247 namespace {
249 namespace {
248
250
249 std::shared_ptr<ScalarSeries> createScalarSeries(QVector<double> xAxisData,
251 std::shared_ptr<ScalarSeries> createScalarSeries(DataContainer xAxisData, DataContainer valuesData)
250 QVector<double> valuesData)
251 {
252 {
252 return std::make_shared<ScalarSeries>(std::move(xAxisData), std::move(valuesData), Unit{},
253 return std::make_shared<ScalarSeries>(std::move(xAxisData), std::move(valuesData), Unit{},
253 Unit{});
254 Unit{});
254 }
255 }
255
256
256 std::shared_ptr<VectorSeries> createVectorSeries(QVector<double> xAxisData,
257 std::shared_ptr<VectorSeries> createVectorSeries(DataContainer xAxisData, DataContainer xValuesData,
257 QVector<double> xValuesData,
258 DataContainer yValuesData,
258 QVector<double> yValuesData,
259 DataContainer zValuesData)
259 QVector<double> zValuesData)
260 {
260 {
261 return std::make_shared<VectorSeries>(std::move(xAxisData), std::move(xValuesData),
261 return std::make_shared<VectorSeries>(std::move(xAxisData), std::move(xValuesData),
262 std::move(yValuesData), std::move(zValuesData), Unit{},
262 std::move(yValuesData), std::move(zValuesData), Unit{},
@@ -276,8 +276,8 void TestDataSeries::testMerge_data()
276 QTest::addColumn<std::shared_ptr<ScalarSeries> >("dataSeries2");
276 QTest::addColumn<std::shared_ptr<ScalarSeries> >("dataSeries2");
277
277
278 // Expected values in the first data series after merge
278 // Expected values in the first data series after merge
279 QTest::addColumn<QVector<double> >("expectedXAxisData");
279 QTest::addColumn<DataContainer>("expectedXAxisData");
280 QTest::addColumn<QVector<double> >("expectedValuesData");
280 QTest::addColumn<DataContainer>("expectedValuesData");
281
281
282 // ////////// //
282 // ////////// //
283 // Test cases //
283 // Test cases //
@@ -286,26 +286,25 void TestDataSeries::testMerge_data()
286 QTest::newRow("sortedMerge")
286 QTest::newRow("sortedMerge")
287 << createScalarSeries({1., 2., 3., 4., 5.}, {100., 200., 300., 400., 500.})
287 << createScalarSeries({1., 2., 3., 4., 5.}, {100., 200., 300., 400., 500.})
288 << createScalarSeries({6., 7., 8., 9., 10.}, {600., 700., 800., 900., 1000.})
288 << createScalarSeries({6., 7., 8., 9., 10.}, {600., 700., 800., 900., 1000.})
289 << QVector<double>{1., 2., 3., 4., 5., 6., 7., 8., 9., 10.}
289 << DataContainer{1., 2., 3., 4., 5., 6., 7., 8., 9., 10.}
290 << QVector<double>{100., 200., 300., 400., 500., 600., 700., 800., 900., 1000.};
290 << DataContainer{100., 200., 300., 400., 500., 600., 700., 800., 900., 1000.};
291
291
292 QTest::newRow("unsortedMerge")
292 QTest::newRow("unsortedMerge")
293 << createScalarSeries({6., 7., 8., 9., 10.}, {600., 700., 800., 900., 1000.})
293 << createScalarSeries({6., 7., 8., 9., 10.}, {600., 700., 800., 900., 1000.})
294 << createScalarSeries({1., 2., 3., 4., 5.}, {100., 200., 300., 400., 500.})
294 << createScalarSeries({1., 2., 3., 4., 5.}, {100., 200., 300., 400., 500.})
295 << QVector<double>{1., 2., 3., 4., 5., 6., 7., 8., 9., 10.}
295 << DataContainer{1., 2., 3., 4., 5., 6., 7., 8., 9., 10.}
296 << QVector<double>{100., 200., 300., 400., 500., 600., 700., 800., 900., 1000.};
296 << DataContainer{100., 200., 300., 400., 500., 600., 700., 800., 900., 1000.};
297
297
298 QTest::newRow("unsortedMerge2")
298 QTest::newRow("unsortedMerge2 (merge not made because source is in the bounds of dest)")
299 << createScalarSeries({1., 2., 8., 9., 10}, {100., 200., 300., 400., 500.})
299 << createScalarSeries({1., 2., 8., 9., 10}, {100., 200., 800., 900., 1000.})
300 << createScalarSeries({3., 4., 5., 6., 7.}, {600., 700., 800., 900., 1000.})
300 << createScalarSeries({3., 4., 5., 6., 7.}, {300., 400., 500., 600., 700.})
301 << QVector<double>{1., 2., 3., 4., 5., 6., 7., 8., 9., 10.}
301 << DataContainer{1., 2., 8., 9., 10.} << DataContainer{100., 200., 800., 900., 1000.};
302 << QVector<double>{100., 200., 600., 700., 800., 900., 1000., 300., 400., 500.};
303
302
304 QTest::newRow("unsortedMerge3")
303 QTest::newRow("unsortedMerge3")
305 << createScalarSeries({3., 5., 8., 7., 2}, {100., 200., 300., 400., 500.})
304 << createScalarSeries({3., 4., 5., 7., 8}, {300., 400., 500., 700., 800.})
306 << createScalarSeries({6., 4., 9., 10., 1.}, {600., 700., 800., 900., 1000.})
305 << createScalarSeries({1., 2., 3., 7., 10.}, {100., 200., 333., 777., 1000.})
307 << QVector<double>{1., 2., 3., 4., 5., 6., 7., 8., 9., 10.}
306 << DataContainer{1., 2., 3., 4., 5., 7., 8., 10.}
308 << QVector<double>{1000., 500., 100., 700., 200., 600., 400., 300., 800., 900.};
307 << DataContainer{100., 200., 300., 400., 500., 700., 800., 1000.};
309 }
308 }
310
309
311 void TestDataSeries::testMerge()
310 void TestDataSeries::testMerge()
@@ -318,8 +317,8 void TestDataSeries::testMerge()
318
317
319 // Validates results : we check that the merge is valid and the data series is sorted on its
318 // Validates results : we check that the merge is valid and the data series is sorted on its
320 // x-axis data
319 // x-axis data
321 QFETCH(QVector<double>, expectedXAxisData);
320 QFETCH(DataContainer, expectedXAxisData);
322 QFETCH(QVector<double>, expectedValuesData);
321 QFETCH(DataContainer, expectedValuesData);
323
322
324 validateRange(dataSeries->cbegin(), dataSeries->cend(), expectedXAxisData, expectedValuesData);
323 validateRange(dataSeries->cbegin(), dataSeries->cend(), expectedXAxisData, expectedValuesData);
325 }
324 }
@@ -334,24 +333,23 void TestDataSeries::testPurgeScalar_data()
334
333
335 QTest::newRow("purgeScalar") << createScalarSeries({1., 2., 3., 4., 5.},
334 QTest::newRow("purgeScalar") << createScalarSeries({1., 2., 3., 4., 5.},
336 {100., 200., 300., 400., 500.})
335 {100., 200., 300., 400., 500.})
337 << 2. << 4. << QVector<double>{2., 3., 4.}
336 << 2. << 4. << DataContainer{2., 3., 4.}
338 << QVector<QVector<double> >{{200., 300., 400.}};
337 << std::vector<DataContainer>{{200., 300., 400.}};
339 QTest::newRow("purgeScalar2") << createScalarSeries({1., 2., 3., 4., 5.},
338 QTest::newRow("purgeScalar2") << createScalarSeries({1., 2., 3., 4., 5.},
340 {100., 200., 300., 400., 500.})
339 {100., 200., 300., 400., 500.})
341 << 0. << 2.5 << QVector<double>{1., 2.}
340 << 0. << 2.5 << DataContainer{1., 2.}
342 << QVector<QVector<double> >{{100., 200.}};
341 << std::vector<DataContainer>{{100., 200.}};
343 QTest::newRow("purgeScalar3") << createScalarSeries({1., 2., 3., 4., 5.},
342 QTest::newRow("purgeScalar3") << createScalarSeries({1., 2., 3., 4., 5.},
344 {100., 200., 300., 400., 500.})
343 {100., 200., 300., 400., 500.})
345 << 3.5 << 7. << QVector<double>{4., 5.}
344 << 3.5 << 7. << DataContainer{4., 5.}
346 << QVector<QVector<double> >{{400., 500.}};
345 << std::vector<DataContainer>{{400., 500.}};
347 QTest::newRow("purgeScalar4") << createScalarSeries({1., 2., 3., 4., 5.},
346 QTest::newRow("purgeScalar4") << createScalarSeries({1., 2., 3., 4., 5.},
348 {100., 200., 300., 400., 500.})
347 {100., 200., 300., 400., 500.})
349 << 0. << 7. << QVector<double>{1., 2., 3., 4., 5.}
348 << 0. << 7. << DataContainer{1., 2., 3., 4., 5.}
350 << QVector<QVector<double> >{{100., 200., 300., 400., 500.}};
349 << std::vector<DataContainer>{{100., 200., 300., 400., 500.}};
351 QTest::newRow("purgeScalar5") << createScalarSeries({1., 2., 3., 4., 5.},
350 QTest::newRow("purgeScalar5") << createScalarSeries({1., 2., 3., 4., 5.},
352 {100., 200., 300., 400., 500.})
351 {100., 200., 300., 400., 500.})
353 << 5.5 << 7. << QVector<double>{}
352 << 5.5 << 7. << DataContainer{} << std::vector<DataContainer>{{}};
354 << QVector<QVector<double> >{{}};
355 }
353 }
356
354
357 void TestDataSeries::testPurgeScalar()
355 void TestDataSeries::testPurgeScalar()
@@ -370,8 +368,8 void TestDataSeries::testPurgeVector_data()
370 QTest::newRow("purgeVector") << createVectorSeries({1., 2., 3., 4., 5.}, {6., 7., 8., 9., 10.},
368 QTest::newRow("purgeVector") << createVectorSeries({1., 2., 3., 4., 5.}, {6., 7., 8., 9., 10.},
371 {11., 12., 13., 14., 15.},
369 {11., 12., 13., 14., 15.},
372 {16., 17., 18., 19., 20.})
370 {16., 17., 18., 19., 20.})
373 << 2. << 4. << QVector<double>{2., 3., 4.}
371 << 2. << 4. << DataContainer{2., 3., 4.}
374 << QVector<QVector<double> >{
372 << std::vector<DataContainer>{
375 {7., 8., 9.}, {12., 13., 14.}, {17., 18., 19.}};
373 {7., 8., 9.}, {12., 13., 14.}, {17., 18., 19.}};
376 }
374 }
377
375
@@ -512,8 +510,8 void TestDataSeries::testXAxisRange_data()
512 QTest::addColumn<double>("max");
510 QTest::addColumn<double>("max");
513
511
514 // Expected values
512 // Expected values
515 QTest::addColumn<QVector<double> >("expectedXAxisData");
513 QTest::addColumn<DataContainer>("expectedXAxisData");
516 QTest::addColumn<QVector<double> >("expectedValuesData");
514 QTest::addColumn<DataContainer>("expectedValuesData");
517
515
518 // ////////// //
516 // ////////// //
519 // Test cases //
517 // Test cases //
@@ -521,32 +519,32 void TestDataSeries::testXAxisRange_data()
521
519
522 QTest::newRow("xAxisRange1") << createScalarSeries({1., 2., 3., 4., 5.},
520 QTest::newRow("xAxisRange1") << createScalarSeries({1., 2., 3., 4., 5.},
523 {100., 200., 300., 400., 500.})
521 {100., 200., 300., 400., 500.})
524 << -1. << 3.2 << QVector<double>{1., 2., 3.}
522 << -1. << 3.2 << DataContainer{1., 2., 3.}
525 << QVector<double>{100., 200., 300.};
523 << DataContainer{100., 200., 300.};
526 QTest::newRow("xAxisRange2") << createScalarSeries({1., 2., 3., 4., 5.},
524 QTest::newRow("xAxisRange2") << createScalarSeries({1., 2., 3., 4., 5.},
527 {100., 200., 300., 400., 500.})
525 {100., 200., 300., 400., 500.})
528 << 1. << 4. << QVector<double>{1., 2., 3., 4.}
526 << 1. << 4. << DataContainer{1., 2., 3., 4.}
529 << QVector<double>{100., 200., 300., 400.};
527 << DataContainer{100., 200., 300., 400.};
530 QTest::newRow("xAxisRange3") << createScalarSeries({1., 2., 3., 4., 5.},
528 QTest::newRow("xAxisRange3") << createScalarSeries({1., 2., 3., 4., 5.},
531 {100., 200., 300., 400., 500.})
529 {100., 200., 300., 400., 500.})
532 << 1. << 3.9 << QVector<double>{1., 2., 3.}
530 << 1. << 3.9 << DataContainer{1., 2., 3.}
533 << QVector<double>{100., 200., 300.};
531 << DataContainer{100., 200., 300.};
534 QTest::newRow("xAxisRange4") << createScalarSeries({1., 2., 3., 4., 5.},
532 QTest::newRow("xAxisRange4") << createScalarSeries({1., 2., 3., 4., 5.},
535 {100., 200., 300., 400., 500.})
533 {100., 200., 300., 400., 500.})
536 << 0. << 0.9 << QVector<double>{} << QVector<double>{};
534 << 0. << 0.9 << DataContainer{} << DataContainer{};
537 QTest::newRow("xAxisRange5") << createScalarSeries({1., 2., 3., 4., 5.},
535 QTest::newRow("xAxisRange5") << createScalarSeries({1., 2., 3., 4., 5.},
538 {100., 200., 300., 400., 500.})
536 {100., 200., 300., 400., 500.})
539 << 0. << 1. << QVector<double>{1.} << QVector<double>{100.};
537 << 0. << 1. << DataContainer{1.} << DataContainer{100.};
540 QTest::newRow("xAxisRange6") << createScalarSeries({1., 2., 3., 4., 5.},
538 QTest::newRow("xAxisRange6") << createScalarSeries({1., 2., 3., 4., 5.},
541 {100., 200., 300., 400., 500.})
539 {100., 200., 300., 400., 500.})
542 << 2.1 << 6. << QVector<double>{3., 4., 5.}
540 << 2.1 << 6. << DataContainer{3., 4., 5.}
543 << QVector<double>{300., 400., 500.};
541 << DataContainer{300., 400., 500.};
544 QTest::newRow("xAxisRange7") << createScalarSeries({1., 2., 3., 4., 5.},
542 QTest::newRow("xAxisRange7") << createScalarSeries({1., 2., 3., 4., 5.},
545 {100., 200., 300., 400., 500.})
543 {100., 200., 300., 400., 500.})
546 << 6. << 9. << QVector<double>{} << QVector<double>{};
544 << 6. << 9. << DataContainer{} << DataContainer{};
547 QTest::newRow("xAxisRange8") << createScalarSeries({1., 2., 3., 4., 5.},
545 QTest::newRow("xAxisRange8") << createScalarSeries({1., 2., 3., 4., 5.},
548 {100., 200., 300., 400., 500.})
546 {100., 200., 300., 400., 500.})
549 << 5. << 9. << QVector<double>{5.} << QVector<double>{500.};
547 << 5. << 9. << DataContainer{5.} << DataContainer{500.};
550 }
548 }
551
549
552 void TestDataSeries::testXAxisRange()
550 void TestDataSeries::testXAxisRange()
@@ -555,8 +553,8 void TestDataSeries::testXAxisRange()
555 QFETCH(double, min);
553 QFETCH(double, min);
556 QFETCH(double, max);
554 QFETCH(double, max);
557
555
558 QFETCH(QVector<double>, expectedXAxisData);
556 QFETCH(DataContainer, expectedXAxisData);
559 QFETCH(QVector<double>, expectedValuesData);
557 QFETCH(DataContainer, expectedValuesData);
560
558
561 auto bounds = dataSeries->xAxisRange(min, max);
559 auto bounds = dataSeries->xAxisRange(min, max);
562 validateRange(bounds.first, bounds.second, expectedXAxisData, expectedValuesData);
560 validateRange(bounds.first, bounds.second, expectedXAxisData, expectedValuesData);
@@ -4,7 +4,9
4
4
5 namespace {
5 namespace {
6
6
7 void verifyArrayData(const ArrayData<1> &arrayData, const QVector<double> &expectedData)
7 using DataContainer = std::vector<double>;
8
9 void verifyArrayData(const ArrayData<1> &arrayData, const DataContainer &expectedData)
8 {
10 {
9 QVERIFY(std::equal(
11 QVERIFY(std::equal(
10 arrayData.cbegin(), arrayData.cend(), expectedData.cbegin(), expectedData.cend(),
12 arrayData.cbegin(), arrayData.cend(), expectedData.cbegin(), expectedData.cend(),
@@ -44,18 +46,18 private slots:
44 void TestOneDimArrayData::testData_data()
46 void TestOneDimArrayData::testData_data()
45 {
47 {
46 // Test structure
48 // Test structure
47 QTest::addColumn<QVector<double> >("inputData"); // array's data input
49 QTest::addColumn<DataContainer>("inputData"); // array's data input
48 QTest::addColumn<QVector<double> >("expectedData"); // expected data
50 QTest::addColumn<DataContainer>("expectedData"); // expected data
49
51
50 // Test cases
52 // Test cases
51 QTest::newRow("data1") << QVector<double>{1., 2., 3., 4., 5.}
53 QTest::newRow("data1") << DataContainer{1., 2., 3., 4., 5.}
52 << QVector<double>{1., 2., 3., 4., 5.};
54 << DataContainer{1., 2., 3., 4., 5.};
53 }
55 }
54
56
55 void TestOneDimArrayData::testData()
57 void TestOneDimArrayData::testData()
56 {
58 {
57 QFETCH(QVector<double>, inputData);
59 QFETCH(DataContainer, inputData);
58 QFETCH(QVector<double>, expectedData);
60 QFETCH(DataContainer, expectedData);
59
61
60 ArrayData<1> arrayData{inputData};
62 ArrayData<1> arrayData{inputData};
61 verifyArrayData(arrayData, expectedData);
63 verifyArrayData(arrayData, expectedData);
@@ -64,26 +66,24 void TestOneDimArrayData::testData()
64 void TestOneDimArrayData::testAdd_data()
66 void TestOneDimArrayData::testAdd_data()
65 {
67 {
66 // Test structure
68 // Test structure
67 QTest::addColumn<QVector<double> >("inputData"); // array's data input
69 QTest::addColumn<DataContainer>("inputData"); // array's data input
68 QTest::addColumn<QVector<double> >("otherData"); // array data's input to merge with
70 QTest::addColumn<DataContainer>("otherData"); // array data's input to merge with
69 QTest::addColumn<bool>("prepend"); // prepend or append merge
71 QTest::addColumn<bool>("prepend"); // prepend or append merge
70 QTest::addColumn<QVector<double> >("expectedData"); // expected data after merge
72 QTest::addColumn<DataContainer>("expectedData"); // expected data after merge
71
73
72 // Test cases
74 // Test cases
73 QTest::newRow("appendMerge") << QVector<double>{1., 2., 3., 4., 5.}
75 QTest::newRow("appendMerge") << DataContainer{1., 2., 3., 4., 5.} << DataContainer{6., 7., 8.}
74 << QVector<double>{6., 7., 8.} << false
76 << false << DataContainer{1., 2., 3., 4., 5., 6., 7., 8.};
75 << QVector<double>{1., 2., 3., 4., 5., 6., 7., 8.};
77 QTest::newRow("prependMerge") << DataContainer{1., 2., 3., 4., 5.} << DataContainer{6., 7., 8.}
76 QTest::newRow("prependMerge") << QVector<double>{1., 2., 3., 4., 5.}
78 << true << DataContainer{6., 7., 8., 1., 2., 3., 4., 5.};
77 << QVector<double>{6., 7., 8.} << true
78 << QVector<double>{6., 7., 8., 1., 2., 3., 4., 5.};
79 }
79 }
80
80
81 void TestOneDimArrayData::testAdd()
81 void TestOneDimArrayData::testAdd()
82 {
82 {
83 QFETCH(QVector<double>, inputData);
83 QFETCH(DataContainer, inputData);
84 QFETCH(QVector<double>, otherData);
84 QFETCH(DataContainer, otherData);
85 QFETCH(bool, prepend);
85 QFETCH(bool, prepend);
86 QFETCH(QVector<double>, expectedData);
86 QFETCH(DataContainer, expectedData);
87
87
88 ArrayData<1> arrayData{inputData};
88 ArrayData<1> arrayData{inputData};
89 ArrayData<1> other{otherData};
89 ArrayData<1> other{otherData};
@@ -95,18 +95,18 void TestOneDimArrayData::testAdd()
95 void TestOneDimArrayData::testAt_data()
95 void TestOneDimArrayData::testAt_data()
96 {
96 {
97 // Test structure
97 // Test structure
98 QTest::addColumn<QVector<double> >("inputData"); // array data's input
98 QTest::addColumn<DataContainer>("inputData"); // array data's input
99 QTest::addColumn<int>("index"); // index to retrieve data
99 QTest::addColumn<int>("index"); // index to retrieve data
100 QTest::addColumn<double>("expectedData"); // expected data at index
100 QTest::addColumn<double>("expectedData"); // expected data at index
101
101
102 // Test cases
102 // Test cases
103 QTest::newRow("data1") << QVector<double>{1., 2., 3., 4., 5.} << 0 << 1.;
103 QTest::newRow("data1") << DataContainer{1., 2., 3., 4., 5.} << 0 << 1.;
104 QTest::newRow("data2") << QVector<double>{1., 2., 3., 4., 5.} << 3 << 4.;
104 QTest::newRow("data2") << DataContainer{1., 2., 3., 4., 5.} << 3 << 4.;
105 }
105 }
106
106
107 void TestOneDimArrayData::testAt()
107 void TestOneDimArrayData::testAt()
108 {
108 {
109 QFETCH(QVector<double>, inputData);
109 QFETCH(DataContainer, inputData);
110 QFETCH(int, index);
110 QFETCH(int, index);
111 QFETCH(double, expectedData);
111 QFETCH(double, expectedData);
112
112
@@ -117,34 +117,34 void TestOneDimArrayData::testAt()
117 void TestOneDimArrayData::testClear_data()
117 void TestOneDimArrayData::testClear_data()
118 {
118 {
119 // Test structure
119 // Test structure
120 QTest::addColumn<QVector<double> >("inputData"); // array data's input
120 QTest::addColumn<DataContainer>("inputData"); // array data's input
121
121
122 // Test cases
122 // Test cases
123 QTest::newRow("data1") << QVector<double>{1., 2., 3., 4., 5.};
123 QTest::newRow("data1") << DataContainer{1., 2., 3., 4., 5.};
124 }
124 }
125
125
126 void TestOneDimArrayData::testClear()
126 void TestOneDimArrayData::testClear()
127 {
127 {
128 QFETCH(QVector<double>, inputData);
128 QFETCH(DataContainer, inputData);
129
129
130 ArrayData<1> arrayData{inputData};
130 ArrayData<1> arrayData{inputData};
131 arrayData.clear();
131 arrayData.clear();
132 verifyArrayData(arrayData, QVector<double>{});
132 verifyArrayData(arrayData, DataContainer{});
133 }
133 }
134
134
135 void TestOneDimArrayData::testSize_data()
135 void TestOneDimArrayData::testSize_data()
136 {
136 {
137 // Test structure
137 // Test structure
138 QTest::addColumn<QVector<double> >("inputData"); // array data's input
138 QTest::addColumn<DataContainer>("inputData"); // array data's input
139 QTest::addColumn<int>("expectedSize"); // expected array data size
139 QTest::addColumn<int>("expectedSize"); // expected array data size
140
140
141 // Test cases
141 // Test cases
142 QTest::newRow("data1") << QVector<double>{1., 2., 3., 4., 5.} << 5;
142 QTest::newRow("data1") << DataContainer{1., 2., 3., 4., 5.} << 5;
143 }
143 }
144
144
145 void TestOneDimArrayData::testSize()
145 void TestOneDimArrayData::testSize()
146 {
146 {
147 QFETCH(QVector<double>, inputData);
147 QFETCH(DataContainer, inputData);
148 QFETCH(int, expectedSize);
148 QFETCH(int, expectedSize);
149
149
150 ArrayData<1> arrayData{inputData};
150 ArrayData<1> arrayData{inputData};
@@ -154,22 +154,22 void TestOneDimArrayData::testSize()
154 void TestOneDimArrayData::testSort_data()
154 void TestOneDimArrayData::testSort_data()
155 {
155 {
156 // Test structure
156 // Test structure
157 QTest::addColumn<QVector<double> >("inputData"); // array data's input
157 QTest::addColumn<DataContainer>("inputData"); // array data's input
158 QTest::addColumn<std::vector<int> >("sortPermutation"); // permutation used to sort data
158 QTest::addColumn<std::vector<int> >("sortPermutation"); // permutation used to sort data
159 QTest::addColumn<QVector<double> >("expectedData"); // expected data after sorting
159 QTest::addColumn<DataContainer>("expectedData"); // expected data after sorting
160
160
161 // Test cases
161 // Test cases
162 QTest::newRow("data1") << QVector<double>{1., 2., 3., 4., 5.} << std::vector<int>{0, 2, 3, 1, 4}
162 QTest::newRow("data1") << DataContainer{1., 2., 3., 4., 5.} << std::vector<int>{0, 2, 3, 1, 4}
163 << QVector<double>{1., 3., 4., 2., 5.};
163 << DataContainer{1., 3., 4., 2., 5.};
164 QTest::newRow("data2") << QVector<double>{1., 2., 3., 4., 5.} << std::vector<int>{4, 1, 2, 3, 0}
164 QTest::newRow("data2") << DataContainer{1., 2., 3., 4., 5.} << std::vector<int>{4, 1, 2, 3, 0}
165 << QVector<double>{5., 2., 3., 4., 1.};
165 << DataContainer{5., 2., 3., 4., 1.};
166 }
166 }
167
167
168 void TestOneDimArrayData::testSort()
168 void TestOneDimArrayData::testSort()
169 {
169 {
170 QFETCH(QVector<double>, inputData);
170 QFETCH(DataContainer, inputData);
171 QFETCH(std::vector<int>, sortPermutation);
171 QFETCH(std::vector<int>, sortPermutation);
172 QFETCH(QVector<double>, expectedData);
172 QFETCH(DataContainer, expectedData);
173
173
174 ArrayData<1> arrayData{inputData};
174 ArrayData<1> arrayData{inputData};
175 auto sortedArrayData = arrayData.sort(sortPermutation);
175 auto sortedArrayData = arrayData.sort(sortPermutation);
@@ -2,31 +2,32
2 #include <QObject>
2 #include <QObject>
3 #include <QtTest>
3 #include <QtTest>
4
4
5 using Container = QVector<QVector<double> >;
5 using DataContainer = std::vector<double>;
6 using InputData = QPair<QVector<double>, int>;
6 using Container = std::vector<DataContainer>;
7 using InputData = QPair<DataContainer, int>;
7
8
8 namespace {
9 namespace {
9
10
10 InputData flatten(const Container &container)
11 InputData flatten(const Container &container)
11 {
12 {
12 if (container.isEmpty()) {
13 if (container.empty()) {
13 return {};
14 return {};
14 }
15 }
15
16
16 // We assume here that each component of the container have the same size
17 // We assume here that each component of the container have the same size
17 auto containerSize = container.size();
18 auto containerSize = container.size();
18 auto componentSize = container.first().size();
19 auto componentSize = container.front().size();
19
20
20 auto result = QVector<double>{};
21 auto result = DataContainer{};
21 result.reserve(componentSize * containerSize);
22 result.reserve(componentSize * containerSize);
22
23
23 for (auto i = 0; i < componentSize; ++i) {
24 for (auto i = 0; i < componentSize; ++i) {
24 for (auto j = 0; j < containerSize; ++j) {
25 for (auto j = 0; j < containerSize; ++j) {
25 result.append(container.at(j).at(i));
26 result.push_back(container.at(j).at(i));
26 }
27 }
27 }
28 }
28
29
29 return {result, containerSize};
30 return {result, static_cast<int>(containerSize)};
30 }
31 }
31
32
32 void verifyArrayData(const ArrayData<2> &arrayData, const Container &expectedData)
33 void verifyArrayData(const ArrayData<2> &arrayData, const Container &expectedData)
@@ -175,7 +176,7 void TestTwoDimArrayData::testClear()
175 ArrayData<2> arrayData{inputData.first, inputData.second};
176 ArrayData<2> arrayData{inputData.first, inputData.second};
176 arrayData.clear();
177 arrayData.clear();
177
178
178 auto emptyData = Container(inputData.second, QVector<double>{});
179 auto emptyData = Container(inputData.second, DataContainer{});
179 verifyArrayData(arrayData, emptyData);
180 verifyArrayData(arrayData, emptyData);
180 }
181 }
181
182
@@ -194,15 +194,16 std::shared_ptr<IDataSeries> AmdaResultParser::readTxt(const QString &filePath,
194 case ValueType::SCALAR:
194 case ValueType::SCALAR:
195 Q_ASSERT(results.second.size() == 1);
195 Q_ASSERT(results.second.size() == 1);
196 return std::make_shared<ScalarSeries>(
196 return std::make_shared<ScalarSeries>(
197 std::move(results.first), std::move(results.second.takeFirst()), xAxisUnit, Unit{});
197 std::move(results.first.toStdVector()),
198 std::move(results.second.takeFirst().toStdVector()), xAxisUnit, Unit{});
198 case ValueType::VECTOR: {
199 case ValueType::VECTOR: {
199 Q_ASSERT(results.second.size() == 3);
200 Q_ASSERT(results.second.size() == 3);
200 auto xValues = results.second.takeFirst();
201 auto xValues = results.second.takeFirst().toStdVector();
201 auto yValues = results.second.takeFirst();
202 auto yValues = results.second.takeFirst().toStdVector();
202 auto zValues = results.second.takeFirst();
203 auto zValues = results.second.takeFirst().toStdVector();
203 return std::make_shared<VectorSeries>(std::move(results.first), std::move(xValues),
204 return std::make_shared<VectorSeries>(std::move(results.first.toStdVector()),
204 std::move(yValues), std::move(zValues), xAxisUnit,
205 std::move(xValues), std::move(yValues),
205 Unit{});
206 std::move(zValues), xAxisUnit, Unit{});
206 }
207 }
207 case ValueType::UNKNOWN:
208 case ValueType::UNKNOWN:
208 // Invalid case
209 // Invalid case
@@ -18,7 +18,7 std::shared_ptr<IDataSeries> CosinusProvider::retrieveData(QUuid acqIdentifier,
18 auto dataIndex = 0;
18 auto dataIndex = 0;
19
19
20 // Gets the timerange from the parameters
20 // Gets the timerange from the parameters
21 double freq = 1.0;
21 double freq = 100.0;
22 double start = std::ceil(dataRangeRequested.m_TStart * freq); // 100 htz
22 double start = std::ceil(dataRangeRequested.m_TStart * freq); // 100 htz
23 double end = std::floor(dataRangeRequested.m_TEnd * freq); // 100 htz
23 double end = std::floor(dataRangeRequested.m_TEnd * freq); // 100 htz
24
24
@@ -30,10 +30,10 std::shared_ptr<IDataSeries> CosinusProvider::retrieveData(QUuid acqIdentifier,
30 // Generates scalar series containing cosinus values (one value per second)
30 // Generates scalar series containing cosinus values (one value per second)
31 auto dataCount = end - start;
31 auto dataCount = end - start;
32
32
33 auto xAxisData = QVector<double>{};
33 auto xAxisData = std::vector<double>{};
34 xAxisData.resize(dataCount);
34 xAxisData.resize(dataCount);
35
35
36 auto valuesData = QVector<double>{};
36 auto valuesData = std::vector<double>{};
37 valuesData.resize(dataCount);
37 valuesData.resize(dataCount);
38
38
39 int progress = 0;
39 int progress = 0;
@@ -43,8 +43,8 std::shared_ptr<IDataSeries> CosinusProvider::retrieveData(QUuid acqIdentifier,
43 if (it != m_VariableToEnableProvider.end() && it.value()) {
43 if (it != m_VariableToEnableProvider.end() && it.value()) {
44 const auto timeOnFreq = time / freq;
44 const auto timeOnFreq = time / freq;
45
45
46 xAxisData.replace(dataIndex, timeOnFreq);
46 xAxisData[dataIndex] = timeOnFreq;
47 valuesData.replace(dataIndex, std::cos(timeOnFreq));
47 valuesData[dataIndex] = std::cos(timeOnFreq);
48
48
49 // progression
49 // progression
50 int currentProgress = (time - start) * 100.0 / progressEnd;
50 int currentProgress = (time - start) * 100.0 / progressEnd;
General Comments 0
You need to be logged in to leave comments. Login now