##// END OF EJS Templates
Makes a Data series be sorted (1)
Alexandre Leroux -
r449:9b2f73ab0183
parent child
Show More
@@ -1,116 +1,116
1 1 #ifndef SCIQLOP_ARRAYDATA_H
2 2 #define SCIQLOP_ARRAYDATA_H
3 3
4 4 #include <QReadLocker>
5 5 #include <QReadWriteLock>
6 6 #include <QVector>
7 7 /**
8 8 * @brief The ArrayData class represents a dataset for a data series.
9 9 *
10 10 * A dataset can be unidimensional or two-dimensional. This property is determined by the Dim
11 11 * template-parameter.
12 12 *
13 13 * @tparam Dim the dimension of the ArrayData (one or two)
14 14 * @sa IDataSeries
15 15 */
16 16 template <int Dim>
17 17 class ArrayData {
18 18 public:
19 19 /**
20 20 * Ctor for a unidimensional ArrayData
21 21 * @param nbColumns the number of values the ArrayData will hold
22 22 */
23 23 template <int D = Dim, typename = std::enable_if_t<D == 1> >
24 24 explicit ArrayData(int nbColumns) : m_Data{1, QVector<double>{}}
25 25 {
26 26 QWriteLocker locker{&m_Lock};
27 27 m_Data[0].resize(nbColumns);
28 28 }
29 29
30 30 /**
31 31 * Ctor for a unidimensional ArrayData
32 32 * @param data the data the ArrayData will hold
33 33 */
34 34 template <int D = Dim, typename = std::enable_if_t<D == 1> >
35 35 explicit ArrayData(QVector<double> data) : m_Data{1, QVector<double>{}}
36 36 {
37 37 QWriteLocker locker{&m_Lock};
38 38 m_Data[0] = std::move(data);
39 39 }
40 40
41 41 /// Copy ctor
42 42 explicit ArrayData(const ArrayData &other)
43 43 {
44 44 QReadLocker otherLocker{&other.m_Lock};
45 45 QWriteLocker locker{&m_Lock};
46 46 m_Data = other.m_Data;
47 47 }
48 48
49 49 /**
50 50 * Sets a data at a specified index. The index has to be valid to be effective
51 51 * @param index the index to which the data will be set
52 52 * @param data the data to set
53 53 * @remarks this method is only available for a unidimensional ArrayData
54 54 */
55 55 template <int D = Dim, typename = std::enable_if_t<D == 1> >
56 56 void setData(int index, double data) noexcept
57 57 {
58 58 QWriteLocker locker{&m_Lock};
59 59 if (index >= 0 && index < m_Data.at(0).size()) {
60 60 m_Data[0].replace(index, data);
61 61 }
62 62 }
63 63
64 64 /**
65 65 * @return the data as a vector
66 66 * @remarks this method is only available for a unidimensional ArrayData
67 67 */
68 68 template <int D = Dim, typename = std::enable_if_t<D == 1> >
69 69 QVector<double> data() const noexcept
70 70 {
71 71 QReadLocker locker{&m_Lock};
72 72 return m_Data[0];
73 73 }
74 74
75 75 /**
76 * @return the data as a vector
76 * @return the data as a vector, as a const reference
77 77 * @remarks this method is only available for a unidimensional ArrayData
78 78 */
79 79 template <int D = Dim, typename = std::enable_if_t<D == 1> >
80 QVector<double> data(double tStart, double tEnd) const noexcept
80 const QVector<double> &cdata() const noexcept
81 81 {
82 82 QReadLocker locker{&m_Lock};
83 return m_Data.at(tStart);
83 return m_Data.at(0);
84 84 }
85 85
86 86 // TODO Comment
87 87 template <int D = Dim, typename = std::enable_if_t<D == 1> >
88 88 void merge(const ArrayData<1> &arrayData)
89 89 {
90 90 QWriteLocker locker{&m_Lock};
91 91 if (!m_Data.empty()) {
92 92 QReadLocker otherLocker{&arrayData.m_Lock};
93 93 m_Data[0] += arrayData.data();
94 94 }
95 95 }
96 96
97 97 template <int D = Dim, typename = std::enable_if_t<D == 1> >
98 98 int size() const
99 99 {
100 100 QReadLocker locker{&m_Lock};
101 101 return m_Data[0].size();
102 102 }
103 103
104 104 void clear()
105 105 {
106 106 QWriteLocker locker{&m_Lock};
107 107 m_Data.clear();
108 108 }
109 109
110 110
111 111 private:
112 112 QVector<QVector<double> > m_Data;
113 113 mutable QReadWriteLock m_Lock;
114 114 };
115 115
116 116 #endif // SCIQLOP_ARRAYDATA_H
@@ -1,107 +1,130
1 1 #ifndef SCIQLOP_DATASERIES_H
2 2 #define SCIQLOP_DATASERIES_H
3 3
4 4 #include <Data/ArrayData.h>
5 5 #include <Data/IDataSeries.h>
6 6
7 7 #include <QLoggingCategory>
8 8
9 9 #include <QReadLocker>
10 10 #include <QReadWriteLock>
11 11 #include <memory>
12 12
13 13 Q_DECLARE_LOGGING_CATEGORY(LOG_DataSeries)
14 14 Q_LOGGING_CATEGORY(LOG_DataSeries, "DataSeries")
15 15
16 16
17 17 /**
18 18 * @brief The DataSeries class is the base (abstract) implementation of IDataSeries.
19 19 *
20 * It proposes to set a dimension for the values ​​data
20 * It proposes to set a dimension for the values ​​data.
21 *
22 * A DataSeries is always sorted on its x-axis data.
21 23 *
22 24 * @tparam Dim The dimension of the values data
23 25 *
24 26 */
25 27 template <int Dim>
26 28 class DataSeries : public IDataSeries {
27 29 public:
28 30 /// @sa IDataSeries::xAxisData()
29 31 std::shared_ptr<ArrayData<1> > xAxisData() override { return m_XAxisData; }
30 32 const std::shared_ptr<ArrayData<1> > xAxisData() const { return m_XAxisData; }
31 33
32 34 /// @sa IDataSeries::xAxisUnit()
33 35 Unit xAxisUnit() const override { return m_XAxisUnit; }
34 36
35 37 /// @return the values dataset
36 38 std::shared_ptr<ArrayData<Dim> > valuesData() { return m_ValuesData; }
37 39 const std::shared_ptr<ArrayData<Dim> > valuesData() const { return m_ValuesData; }
38 40
39 41 /// @sa IDataSeries::valuesUnit()
40 42 Unit valuesUnit() const override { return m_ValuesUnit; }
41 43
42 44 void clear()
43 45 {
44 46 m_XAxisData->clear();
45 47 m_ValuesData->clear();
46 48 }
47 49
48 50 /// @sa IDataSeries::merge()
49 51 void merge(IDataSeries *dataSeries) override
50 52 {
51 53 if (auto dimDataSeries = dynamic_cast<DataSeries<Dim> *>(dataSeries)) {
52 54 m_XAxisData->merge(*dimDataSeries->xAxisData());
53 55 m_ValuesData->merge(*dimDataSeries->valuesData());
54 56 dimDataSeries->clear();
55 57 }
56 58 else {
57 59 qCWarning(LOG_DataSeries())
58 60 << QObject::tr("Dection of a type of IDataSeries we cannot merge with !");
59 61 }
60 62 }
61 63
62 64 virtual void lockRead() { m_Lock.lockForRead(); }
63 65 virtual void lockWrite() { m_Lock.lockForWrite(); }
64 66 virtual void unlock() { m_Lock.unlock(); }
65 67
66 68 protected:
67 /// Protected ctor (DataSeries is abstract)
69 /// Protected ctor (DataSeries is abstract). The vectors must have the same size, otherwise a
70 /// DataSeries with no values will be created.
71 /// @remarks data series is automatically sorted on its x-axis data
68 72 explicit DataSeries(std::shared_ptr<ArrayData<1> > xAxisData, const Unit &xAxisUnit,
69 73 std::shared_ptr<ArrayData<Dim> > valuesData, const Unit &valuesUnit)
70 74 : m_XAxisData{xAxisData},
71 75 m_XAxisUnit{xAxisUnit},
72 76 m_ValuesData{valuesData},
73 77 m_ValuesUnit{valuesUnit}
74 78 {
79 if (m_XAxisData->size() != m_ValuesData->size()) {
80 clear();
81 }
82
83 // Sorts data if it's not the case
84 const auto &xAxisCData = m_XAxisData->cdata();
85 if (!std::is_sorted(xAxisCData.cbegin(), xAxisCData.cend())) {
86 sort();
87 }
75 88 }
76 89
77 90 /// Copy ctor
78 91 explicit DataSeries(const DataSeries<Dim> &other)
79 92 : m_XAxisData{std::make_shared<ArrayData<1> >(*other.m_XAxisData)},
80 93 m_XAxisUnit{other.m_XAxisUnit},
81 94 m_ValuesData{std::make_shared<ArrayData<Dim> >(*other.m_ValuesData)},
82 95 m_ValuesUnit{other.m_ValuesUnit}
83 96 {
97 // Since a series is ordered from its construction and is always ordered, it is not
98 // necessary to call the sort method here ('other' is sorted)
84 99 }
85 100
86 101 /// Assignment operator
87 102 template <int D>
88 103 DataSeries &operator=(DataSeries<D> other)
89 104 {
90 105 std::swap(m_XAxisData, other.m_XAxisData);
91 106 std::swap(m_XAxisUnit, other.m_XAxisUnit);
92 107 std::swap(m_ValuesData, other.m_ValuesData);
93 108 std::swap(m_ValuesUnit, other.m_ValuesUnit);
94 109
95 110 return *this;
96 111 }
97 112
98 113 private:
114 /**
115 * Sorts data series on its x-axis data
116 */
117 void sort() noexcept
118 {
119 /// @todo ALX
120 }
121
99 122 std::shared_ptr<ArrayData<1> > m_XAxisData;
100 123 Unit m_XAxisUnit;
101 124 std::shared_ptr<ArrayData<Dim> > m_ValuesData;
102 125 Unit m_ValuesUnit;
103 126
104 127 QReadWriteLock m_Lock;
105 128 };
106 129
107 130 #endif // SCIQLOP_DATASERIES_H
General Comments 0
You need to be logged in to leave comments. Login now