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