##// END OF EJS Templates
New TimeSeries integration WIP...
jeandet -
r62:7315812f3839
parent child
Show More
@@ -0,0 +1,187
1 #ifndef VARIANTWITHBASE_H
2 #define VARIANTWITHBASE_H
3 // stolen without any shame from
4 // https://tower120.github.io/2018/05/18/variant_with_base.html (•_•) (
5 // •_•)>⌐■-■ (⌐■_■)
6 #include <cassert>
7 #include <tuple>
8 #include <type_traits>
9 #include <variant>
10
11 template<class Base, class Variant> class variant_w_base
12 {
13 using Self = variant_w_base<Base, Variant>;
14
15 auto& self_mut() const { return *const_cast<Self*>(this); }
16
17 Base* m_base;
18 Variant m_variant;
19
20 void update_base()
21 {
22 m_base = std::visit(
23 [](auto&& arg) -> Base* {
24 using Arg = std::decay_t<decltype(arg)>;
25 if constexpr(std::is_same_v<Arg, std::monostate>) { return nullptr; }
26 else
27 {
28 return static_cast<Base*>(&arg);
29 }
30 },
31 m_variant);
32 }
33 template<class T> void update_base()
34 {
35 using Arg = std::decay_t<T>;
36 if constexpr(std::is_same_v<Arg, std::monostate>) { m_base = nullptr; }
37 else
38 {
39 m_base = std::get_if<Arg>(&m_variant);
40 assert(m_base);
41 }
42 }
43
44 template<class T>
45 using is_not_self = std::enable_if_t<!std::is_same_v<std::decay_t<T>, Self>>;
46
47 public:
48 variant_w_base() { update_base(); }
49 variant_w_base(const variant_w_base& other) : m_variant(other.m_variant)
50 {
51 update_base();
52 }
53 variant_w_base(variant_w_base&& other) : m_variant(std::move(other.m_variant))
54 {
55 update_base();
56 }
57 variant_w_base(const Variant& var) : m_variant(var) { update_base(); }
58 variant_w_base(Variant&& var) : m_variant(std::move(var)) { update_base(); }
59 template<class T, typename = is_not_self<T>>
60 variant_w_base(T&& value) : m_variant(std::forward<T>(value))
61 {
62 update_base<T>();
63 }
64 template<class T, class... Args>
65 explicit variant_w_base(std::in_place_type_t<T>, Args&&... args)
66 : m_variant(std::in_place_type_t<T>(), std::forward<Args>(args)...)
67 {
68 update_base<T>();
69 }
70
71 variant_w_base& operator=(const variant_w_base& other)
72 {
73 m_variant = other.m_variant;
74 update_base();
75 return *this;
76 }
77 variant_w_base& operator=(variant_w_base&& other)
78 {
79 m_variant = std::move(other.m_variant);
80 update_base();
81 return *this;
82 }
83
84 template<class T, typename = is_not_self<T>>
85 variant_w_base& operator=(T&& value)
86 {
87 m_variant = std::forward<T>(value);
88 update_base<T>();
89 return *this;
90 }
91 variant_w_base& operator=(const Variant& var)
92 {
93 m_variant = var;
94 update_base();
95 return *this;
96 }
97 variant_w_base& operator=(Variant&& var)
98 {
99 m_variant = std::move(var);
100 update_base();
101 return *this;
102 }
103 constexpr std::size_t index() const noexcept { return m_variant.index(); }
104 constexpr bool operator==(const variant_w_base& other) const
105 {
106 return m_variant == other.m_variant;
107 }
108 constexpr bool operator!=(const variant_w_base& other) const
109 {
110 return m_variant != other.m_variant;
111 }
112
113 // free functions from std::variant
114 template<class T> constexpr T* get_if()
115 {
116 if constexpr(std::is_same_v<T, Base>) { return base(); }
117 else
118 {
119 return std::get_if<T>(variant());
120 }
121 }
122 template<class T> constexpr const T* get_if() const
123 {
124 return self_mut().template get<T>();
125 }
126
127 template<std::size_t I> constexpr decltype(auto) get_if()
128 {
129 return std::get_if<I>(variant());
130 }
131 template<std::size_t I> constexpr decltype(auto) get_if() const
132 {
133 return std::get_if<I>(variant());
134 }
135
136 template<class T> constexpr T& get()
137 {
138 if constexpr(std::is_same_v<T, Base>)
139 {
140 if(base() == nullptr) { throw std::bad_variant_access(); }
141 return *base();
142 }
143 else
144 {
145 return std::get<T>(variant());
146 }
147 }
148 template<class T> constexpr const T& get() const
149 {
150 return self_mut().template get<T>();
151 }
152
153 template<std::size_t I> constexpr decltype(auto) get()
154 {
155 return std::get<I>(variant());
156 }
157 template<std::size_t I> constexpr decltype(auto) get() const
158 {
159 return std::get<I>(variant());
160 }
161
162 template<class Visitor> constexpr decltype(auto) visit(Visitor&& vis)
163 {
164 return std::visit(std::forward<Visitor>(vis), variant());
165 }
166 template<class Visitor> constexpr decltype(auto) visit(Visitor&& vis) const
167 {
168 return std::visit(std::forward<Visitor>(vis), variant());
169 }
170
171 Base* base() noexcept { return m_base; }
172 const Base* base() const noexcept { return m_base; }
173 operator Base&() noexcept { return *m_base; }
174 operator const Base&() const noexcept { return *m_base; }
175 Base* operator->() noexcept { return m_base; }
176 const Base* operator->() const noexcept { return m_base; }
177 Base& operator*() noexcept { return m_base; }
178 const Base& operator*() const noexcept { return m_base; }
179
180 constexpr const Variant& variant() const noexcept { return m_variant; }
181
182 private:
183 // hide, to keep variant type change tracked.
184 constexpr Variant& variant() noexcept { return m_variant; }
185 };
186
187 #endif // VARIANTWITHBASE_H
@@ -0,0 +1,97
1 #ifndef SCIQLOP_VARIABLE2_H
2 #define SCIQLOP_VARIABLE2_H
3
4 #include "CoreGlobal.h"
5
6 #include <Common/MetaTypes.h>
7 #include <Common/deprecate.h>
8 #include <Common/spimpl.h>
9 #include <Common/variant_with_base.h>
10 #include <Data/DataSeriesType.h>
11 #include <Data/DateTimeRange.h>
12 #include <Data/ScalarTimeSerie.h>
13 #include <Data/VectorTimeSerie.h>
14 #include <QDataStream>
15 #include <QObject>
16 #include <QReadWriteLock>
17 #include <QUuid>
18 #include <TimeSeries.h>
19 #include <optional>
20
21 using AnyTimeSerie = variant_w_base<
22 TimeSeries::ITimeSerie,
23 std::variant<std::monostate, ScalarTimeSerie, VectorTimeSerie>>;
24
25 class SCIQLOP_CORE_EXPORT Variable2 : public QObject
26 {
27 Q_OBJECT
28
29 public:
30 explicit Variable2(const QString& name, const QVariantHash& metadata = {});
31
32 /// Copy ctor
33 explicit Variable2(const Variable2& other);
34
35 std::shared_ptr<Variable2> clone() const;
36
37 QString name() const noexcept;
38 void setName(const QString& name) noexcept;
39 DateTimeRange range() const noexcept;
40 std::optional<DateTimeRange> realRange() const noexcept;
41
42 std::size_t nbPoints() const noexcept;
43
44 /// @return the data of the variable, nullptr if there is no data
45 AnyTimeSerie* data() const noexcept;
46
47 /// @return the type of data that the variable holds
48 DataSeriesType type() const noexcept;
49
50 QVariantHash metadata() const noexcept;
51
52 void setData(const std::vector<AnyTimeSerie*>& dataSeries,
53 const DateTimeRange& range, bool notify = true);
54
55 static QByteArray
56 mimeData(const std::vector<std::shared_ptr<Variable2>>& variables)
57 {
58 auto encodedData = QByteArray{};
59 QDataStream stream{&encodedData, QIODevice::WriteOnly};
60 for(auto& var : variables)
61 {
62 stream << var->ID().toByteArray();
63 }
64 return encodedData;
65 }
66
67 static std::vector<QUuid> IDs(QByteArray mimeData)
68 {
69 std::vector<QUuid> variables;
70 QDataStream stream{mimeData};
71
72 QVariantList ids;
73 stream >> ids;
74 std::transform(std::cbegin(ids), std::cend(ids),
75 std::back_inserter(variables),
76 [](const auto& id) { return id.toByteArray(); });
77 return variables;
78 }
79
80 operator QUuid() { return _uuid; }
81 QUuid ID() { return _uuid; }
82 signals:
83 void updated(QUuid ID);
84
85 private:
86 struct VariablePrivate;
87 spimpl::unique_impl_ptr<VariablePrivate> impl;
88 QUuid _uuid;
89 QReadWriteLock m_lock;
90 };
91
92 // Required for using shared_ptr in signals/slots
93 // SCIQLOP_REGISTER_META_TYPE(VARIABLE_PTR_REGISTRY, std::shared_ptr<Variable2>)
94 // SCIQLOP_REGISTER_META_TYPE(VARIABLE_PTR_VECTOR_REGISTRY,
95 // QVector<std::shared_ptr<Variable2>>)
96
97 #endif // SCIQLOP_VARIABLE2_H
@@ -0,0 +1,123
1 #include "Variable/Variable2.h"
2
3 #define PROPERTY_(property, getter, setter, type) \
4 type getter() noexcept \
5 { \
6 QReadLocker lock{&m_Lock}; \
7 return property; \
8 } \
9 void setter(const type& getter) noexcept \
10 { \
11 QWriteLocker lock{&m_Lock}; \
12 property = getter; \
13 } \
14 type property;
15
16 #define V_FW_GETTER_SETTER(getter, setter, type) \
17 type Variable2::getter() const noexcept { return impl->getter(); } \
18 void Variable2::setter(const type& value) noexcept \
19 { \
20 impl->setter(value); \
21 emit updated(this->ID()); \
22 }
23
24 struct Variable2::VariablePrivate
25 {
26 VariablePrivate(const QString& name, const QVariantHash& metadata)
27 : m_Name{name}, m_Range{INVALID_RANGE}, m_Metadata{metadata}, m_TimeSerie{
28 nullptr}
29 {}
30 VariablePrivate(const VariablePrivate& other) {}
31 std::size_t nbPoints()
32 {
33 if(m_TimeSerie) return m_TimeSerie->base()->size();
34 return 0;
35 }
36 DataSeriesType type() const
37 {
38 if(m_TimeSerie) return DataSeriesType(m_TimeSerie->index());
39 return DataSeriesType::NONE;
40 }
41
42 PROPERTY_(m_Name, name, setName, QString)
43 PROPERTY_(m_Range, range, setRange, DateTimeRange)
44 PROPERTY_(m_Metadata, metadata, setMetadata, QVariantHash)
45 AnyTimeSerie& dataSeries() { return *m_TimeSerie.get(); }
46 void setDataSeries(std::unique_ptr<AnyTimeSerie>&& timeSerie)
47 {
48 QWriteLocker lock{&m_Lock};
49 m_TimeSerie = std::move(timeSerie);
50 }
51 std::unique_ptr<AnyTimeSerie> m_TimeSerie;
52 QReadWriteLock m_Lock;
53 };
54
55 Variable2::Variable2(const QString& name, const QVariantHash& metadata)
56 : impl{spimpl::make_unique_impl<VariablePrivate>(name, metadata)},
57 _uuid{QUuid::createUuid()}
58 {}
59
60 Variable2::Variable2(const Variable2& other)
61 : impl{spimpl::make_unique_impl<VariablePrivate>(*other.impl)},
62 _uuid{QUuid::createUuid()} // is a clone but must have a != uuid
63 {}
64
65 std::shared_ptr<Variable2> Variable2::clone() const
66 {
67 return std::make_shared<Variable2>(*this);
68 }
69
70 V_FW_GETTER_SETTER(name, setName, QString)
71
72 DateTimeRange Variable2::range() const noexcept { return impl->range(); }
73
74 std::size_t Variable2::nbPoints() const noexcept { return impl->nbPoints(); }
75
76 AnyTimeSerie* Variable2::data() const noexcept {}
77
78 DataSeriesType Variable2::type() const noexcept { return impl->type(); }
79
80 QVariantHash Variable2::metadata() const noexcept {}
81
82 template<typename T>
83 void _merge(const std::vector<AnyTimeSerie*>& source, AnyTimeSerie* dest)
84 {
85 // std::for_each(
86 // std::cbegin(source) + 1, std::cend(source), [dest](AnyTimeSerie*
87 // serie) {
88 // std::copy(std::begin(serie->get<T>()), std::end(serie->get<T>()),
89 // std::back_inserter(dest->get<T>()));
90 // });
91 }
92
93 std::unique_ptr<AnyTimeSerie>
94 merge(const std::vector<AnyTimeSerie*>& dataSeries)
95 {
96 std::unique_ptr<AnyTimeSerie> ts;
97 *ts = *dataSeries.front();
98 switch(DataSeriesType(ts->index()))
99 {
100 case DataSeriesType::NONE: break;
101 case DataSeriesType::SCALAR:
102 _merge<ScalarTimeSerie>(dataSeries, ts.get());
103 break;
104 case DataSeriesType::VECTOR:
105 _merge<VectorTimeSerie>(dataSeries, ts.get());
106 break;
107 case DataSeriesType::SPECTROGRAM:
108 // merge<Spe>(dataSeries, ts.get());
109 break;
110 }
111 return ts;
112 }
113
114 void Variable2::setData(const std::vector<AnyTimeSerie*>& dataSeries,
115 const DateTimeRange& range, bool notify)
116 {
117 if(dataSeries.size())
118 {
119 impl->setDataSeries(merge(dataSeries));
120 impl->setRange(range);
121 if(notify) emit this->updated(this->ID());
122 }
123 }
@@ -78,6 +78,7 FILE (GLOB_RECURSE core_SRCS
78 ./include/Common/containers.h
78 ./include/Common/containers.h
79 ./include/Common/debug.h
79 ./include/Common/debug.h
80 ./include/Common/cpp_utils.h
80 ./include/Common/cpp_utils.h
81 ./include/Common/variant_with_base.h
81 ./include/Plugin/IPlugin.h
82 ./include/Plugin/IPlugin.h
82 ./include/Data/ArrayDataIterator.h
83 ./include/Data/ArrayDataIterator.h
83 ./include/Data/VectorSeries.h
84 ./include/Data/VectorSeries.h
@@ -112,6 +113,7 FILE (GLOB_RECURSE core_SRCS
112 ./include/Variable/SingleThresholdCacheStrategy.h
113 ./include/Variable/SingleThresholdCacheStrategy.h
113 ./include/Variable/VariableCacheStrategyFactory.h
114 ./include/Variable/VariableCacheStrategyFactory.h
114 ./include/Variable/Variable.h
115 ./include/Variable/Variable.h
116 ./include/Variable/Variable2.h
115 ./include/Variable/VariableController2.h
117 ./include/Variable/VariableController2.h
116 ./include/Variable/private/VCTransaction.h
118 ./include/Variable/private/VCTransaction.h
117 ./include/Time/TimeController.h
119 ./include/Time/TimeController.h
@@ -143,6 +145,7 FILE (GLOB_RECURSE core_SRCS
143 ./src/Variable/VariableModel2.cpp
145 ./src/Variable/VariableModel2.cpp
144 ./src/Variable/VariableSynchronizationGroup2.cpp
146 ./src/Variable/VariableSynchronizationGroup2.cpp
145 ./src/Variable/Variable.cpp
147 ./src/Variable/Variable.cpp
148 ./src/Variable/Variable2.cpp
146 ./src/Version.cpp
149 ./src/Version.cpp
147 ./src/Time/TimeController.cpp
150 ./src/Time/TimeController.cpp
148 ./src/Settings/SqpSettingsDefs.cpp
151 ./src/Settings/SqpSettingsDefs.cpp
@@ -1,1 +1,1
1 Subproject commit f76d1333ff1b2a9e1629a5a79226424a8fe84f00
1 Subproject commit ce006cf8df2b0bb3d433f901b6e80ce69119a430
@@ -1,1 +1,1
1 Subproject commit 9e6d585db2d3bea47c864622ee9f67d496aa7251
1 Subproject commit 9c518f27796798fda36a1495b329808177c4c150
@@ -5,10 +5,10
5
5
6 enum class DataSeriesType
6 enum class DataSeriesType
7 {
7 {
8 NONE,
8 SCALAR,
9 SCALAR,
9 SPECTROGRAM,
10 VECTOR,
10 VECTOR,
11 UNKNOWN
11 SPECTROGRAM
12 };
12 };
13
13
14 struct DataSeriesTypeUtils
14 struct DataSeriesTypeUtils
@@ -27,7 +27,7 struct DataSeriesTypeUtils
27 }
27 }
28 else
28 else
29 {
29 {
30 return DataSeriesType::UNKNOWN;
30 return DataSeriesType::NONE;
31 }
31 }
32 }
32 }
33 };
33 };
@@ -1,23 +1,21
1 #ifndef SCIQLOP_VARIABLE_H
1 #ifndef SCIQLOP_VARIABLE_H
2 #define SCIQLOP_VARIABLE_H
2 #define SCIQLOP_VARIABLE_H
3
3
4 #include <optional>
5
6 #include <QLoggingCategory>
7 #include <QObject>
8 #include <QUuid>
9 #include <QReadWriteLock>
10 #include <QDataStream>
11
12 #include "CoreGlobal.h"
4 #include "CoreGlobal.h"
13 #include <Data/DataSeriesIterator.h>
14 #include <Data/DataSeriesType.h>
15 #include <Data/DateTimeRange.h>
16
17
5
18 #include <Common/deprecate.h>
19 #include <Common/MetaTypes.h>
6 #include <Common/MetaTypes.h>
7 #include <Common/deprecate.h>
20 #include <Common/spimpl.h>
8 #include <Common/spimpl.h>
9 #include <Data/DataSeriesIterator.h>
10 #include <Data/DataSeriesType.h>
11 #include <Data/DateTimeRange.h>
12 #include <QDataStream>
13 #include <QLoggingCategory>
14 #include <QObject>
15 #include <QReadWriteLock>
16 #include <QUuid>
17 #include <TimeSeries.h>
18 #include <optional>
21
19
22 Q_DECLARE_LOGGING_CATEGORY(LOG_Variable)
20 Q_DECLARE_LOGGING_CATEGORY(LOG_Variable)
23
21
@@ -27,91 +25,95 class QString;
27 /**
25 /**
28 * @brief The Variable class represents a variable in SciQlop.
26 * @brief The Variable class represents a variable in SciQlop.
29 */
27 */
30 class SCIQLOP_CORE_EXPORT Variable : public QObject {
28 class SCIQLOP_CORE_EXPORT Variable : public QObject
31
29 {
32 Q_OBJECT
30 Q_OBJECT
33
31
34 public:
32 public:
35 explicit Variable(const QString &name, const QVariantHash &metadata = {});
33 explicit Variable(const QString& name, const QVariantHash& metadata = {});
36
34
37 /// Copy ctor
35 /// Copy ctor
38 explicit Variable(const Variable &other);
36 explicit Variable(const Variable& other);
39
37
40 std::shared_ptr<Variable> clone() const;
38 std::shared_ptr<Variable> clone() const;
41
39
42 QString name() const noexcept;
40 QString name() const noexcept;
43 void setName(const QString &name) noexcept;
41 void setName(const QString& name) noexcept;
44 DateTimeRange range() const noexcept;
42 DateTimeRange range() const noexcept;
45 void setRange(const DateTimeRange &range, bool notify=false) noexcept;
43 void setRange(const DateTimeRange& range, bool notify = false) noexcept;
46 DateTimeRange cacheRange() const noexcept;
44 DateTimeRange cacheRange() const noexcept;
47 void setCacheRange(const DateTimeRange &cacheRange) noexcept;
45 void setCacheRange(const DateTimeRange& cacheRange) noexcept;
48
46
49 /// @return the number of points hold by the variable. The number of points is updated each time
47 /// @return the number of points hold by the variable. The number of points is
50 /// the data series changes
48 /// updated each time the data series changes
51 unsigned int nbPoints() const noexcept;
49 unsigned int nbPoints() const noexcept;
52
50
53 /// Returns the real range of the variable, i.e. the min and max x-axis values of the data
51 /// Returns the real range of the variable, i.e. the min and max x-axis values
54 /// series between the range of the variable. The real range is updated each time the variable
52 /// of the data series between the range of the variable. The real range is
55 /// range or the data series changed
53 /// updated each time the variable range or the data series changed
56 /// @return the real range, invalid range if the data series is null or empty
54 /// @return the real range, invalid range if the data series is null or empty
57 /// @sa setDataSeries()
55 /// @sa setDataSeries()
58 /// @sa setRange()
56 /// @sa setRange()
59 std::optional<DateTimeRange> realRange() const noexcept;
57 std::optional<DateTimeRange> realRange() const noexcept;
60
58
61 /// @return the data of the variable, nullptr if there is no data
59 /// @return the data of the variable, nullptr if there is no data
62 std::shared_ptr<IDataSeries> dataSeries() const noexcept;
60 std::shared_ptr<IDataSeries> dataSeries() const noexcept;
63
61
64 /// @return the type of data that the variable holds
62 /// @return the type of data that the variable holds
65 DataSeriesType type() const noexcept;
63 DataSeriesType type() const noexcept;
66
64
67 QVariantHash metadata() const noexcept;
65 QVariantHash metadata() const noexcept;
68
66
69 void updateData(const std::vector<IDataSeries*>& dataSeries,
67 void updateData(const std::vector<IDataSeries*>& dataSeries,
70 const DateTimeRange& newRange, const DateTimeRange& newCacheRange,
68 const DateTimeRange& newRange,
71 bool notify=true);
69 const DateTimeRange& newCacheRange, bool notify = true);
72
70
73 void setData(const std::vector<IDataSeries*>& dataSeries,
71 void setData(const std::vector<IDataSeries*>& dataSeries,
74 const DateTimeRange& newRange, const DateTimeRange& newCacheRange,
72 const DateTimeRange& newRange,
75 bool notify=true);
73 const DateTimeRange& newCacheRange, bool notify = true);
76
74
77 static QByteArray mimeData(const std::vector<std::shared_ptr<Variable> > &variables)
75 static QByteArray
76 mimeData(const std::vector<std::shared_ptr<Variable>>& variables)
77 {
78 auto encodedData = QByteArray{};
79 QDataStream stream{&encodedData, QIODevice::WriteOnly};
80 for(auto& var : variables)
78 {
81 {
79 auto encodedData = QByteArray{};
82 stream << var->ID().toByteArray();
80 QDataStream stream{&encodedData, QIODevice::WriteOnly};
81 for (auto &var : variables) {
82 stream << var->ID().toByteArray();
83 }
84 return encodedData;
85 }
83 }
84 return encodedData;
85 }
86
86
87 static std::vector<QUuid> variablesIDs(QByteArray mimeData)
87 static std::vector<QUuid> variablesIDs(QByteArray mimeData)
88 {
88 {
89 std::vector<QUuid> variables;
89 std::vector<QUuid> variables;
90 QDataStream stream{mimeData};
90 QDataStream stream{mimeData};
91
91
92 QVariantList ids;
92 QVariantList ids;
93 stream >> ids;
93 stream >> ids;
94
94
95 for (const auto& id : ids) {
95 for(const auto& id : ids)
96 variables.emplace_back (id.toByteArray());
96 {
97 }
97 variables.emplace_back(id.toByteArray());
98 return variables;
99 }
98 }
99 return variables;
100 }
100
101
101 operator QUuid() {return _uuid;}
102 operator QUuid() { return _uuid; }
102 QUuid ID(){return _uuid;}
103 QUuid ID() { return _uuid; }
103 signals:
104 signals:
104 void updated(QUuid ID);
105 void updated(QUuid ID);
105
106
106 private:
107 private:
107 class VariablePrivate;
108 class VariablePrivate;
108 spimpl::unique_impl_ptr<VariablePrivate> impl;
109 spimpl::unique_impl_ptr<VariablePrivate> impl;
109 QUuid _uuid;
110 QUuid _uuid;
110 QReadWriteLock m_lock;
111 QReadWriteLock m_lock;
111 };
112 };
112
113
113 // Required for using shared_ptr in signals/slots
114 // Required for using shared_ptr in signals/slots
114 SCIQLOP_REGISTER_META_TYPE(VARIABLE_PTR_REGISTRY, std::shared_ptr<Variable>)
115 SCIQLOP_REGISTER_META_TYPE(VARIABLE_PTR_REGISTRY, std::shared_ptr<Variable>)
115 SCIQLOP_REGISTER_META_TYPE(VARIABLE_PTR_VECTOR_REGISTRY, QVector<std::shared_ptr<Variable> >)
116 SCIQLOP_REGISTER_META_TYPE(VARIABLE_PTR_VECTOR_REGISTRY,
117 QVector<std::shared_ptr<Variable>>)
116
118
117 #endif // SCIQLOP_VARIABLE_H
119 #endif // SCIQLOP_VARIABLE_H
@@ -1,13 +1,18
1 #include "Common/DateUtils.h"
1 #include "Common/DateUtils.h"
2
2
3 #include <cmath>
4
3 QDateTime DateUtils::dateTime(double secs, Qt::TimeSpec timeSpec) noexcept
5 QDateTime DateUtils::dateTime(double secs, Qt::TimeSpec timeSpec) noexcept
4 {
6 {
5 // Uses msecs to be Qt 4 compatible
7 // Uses msecs to be Qt 4 compatible
6 return QDateTime::fromMSecsSinceEpoch(secs * 1000., timeSpec);
8 if(!std::isnan(secs))
9 return QDateTime::fromMSecsSinceEpoch(static_cast<qint64>(secs * 1000.),
10 timeSpec);
11 return QDateTime();
7 }
12 }
8
13
9 double DateUtils::secondsSinceEpoch(const QDateTime &dateTime) noexcept
14 double DateUtils::secondsSinceEpoch(const QDateTime& dateTime) noexcept
10 {
15 {
11 // Uses msecs to be Qt 4 compatible
16 // Uses msecs to be Qt 4 compatible
12 return dateTime.toMSecsSinceEpoch() / 1000.;
17 return dateTime.toMSecsSinceEpoch() / 1000.;
13 }
18 }
@@ -1,225 +1,211
1 #include <optional>
2 #include <QMutex>
3 #include <QReadWriteLock>
4 #include <QThread>
5
6 #include "Variable/Variable.h"
1 #include "Variable/Variable.h"
7
2
8 #include <Data/IDataSeries.h>
9 #include <Data/DateTimeRange.h>
10
11 #include <Common/debug.h>
3 #include <Common/debug.h>
4 #include <Data/DateTimeRange.h>
5 #include <Data/IDataSeries.h>
6 #include <QMutex>
7 #include <QReadWriteLock>
8 #include <QThread>
9 #include <optional>
12
10
13 Q_LOGGING_CATEGORY(LOG_Variable, "Variable")
11 Q_LOGGING_CATEGORY(LOG_Variable, "Variable")
14
12
15
16 /**
13 /**
17 * Searches in metadata for a value that can be converted to DataSeriesType
14 * Searches in metadata for a value that can be converted to DataSeriesType
18 * @param metadata the metadata where to search
15 * @param metadata the metadata where to search
19 * @return the value converted to a DataSeriesType if it was found, UNKNOWN type otherwise
16 * @return the value converted to a DataSeriesType if it was found, UNKNOWN type
17 * otherwise
20 * @sa DataSeriesType
18 * @sa DataSeriesType
21 */
19 */
22 static DataSeriesType findDataSeriesType(const QVariantHash &metadata)
20 static DataSeriesType findDataSeriesType(const QVariantHash& metadata)
23 {
21 {
24 auto dataSeriesType = DataSeriesType::UNKNOWN;
22 auto dataSeriesType = DataSeriesType::NONE;
25
23
26 // Go through the metadata and stop at the first value that could be converted to DataSeriesType
24 // Go through the metadata and stop at the first value that could be converted
27 for (auto it = metadata.cbegin(), end = metadata.cend();
25 // to DataSeriesType
28 it != end && dataSeriesType == DataSeriesType::UNKNOWN; ++it) {
26 for(auto it = metadata.cbegin(), end = metadata.cend();
29 dataSeriesType = DataSeriesTypeUtils::fromString(it.value().toString());
27 it != end && dataSeriesType == DataSeriesType::NONE; ++it)
30 }
28 {
29 dataSeriesType = DataSeriesTypeUtils::fromString(it.value().toString());
30 }
31
31
32 return dataSeriesType;
32 return dataSeriesType;
33 }
33 }
34
34
35
35 #define VP_PROPERTY(property, getter, setter, type) \
36 #define VP_PROPERTY(property,getter,setter,type) \
36 type getter() noexcept \
37 type getter() noexcept\
37 { \
38 {\
38 QReadLocker lock{&m_Lock}; \
39 QReadLocker lock{&m_Lock};\
39 return property; \
40 return property;\
40 } \
41 }\
41 void setter(const type& getter) noexcept \
42 void setter(const type& getter) noexcept\
42 { \
43 {\
43 QWriteLocker lock{&m_Lock}; \
44 QWriteLocker lock{&m_Lock};\
44 property = getter; \
45 property = getter;\
45 } \
46 }\
46 type property;
47 type property;\
47
48
48 #define V_FW_GETTER_SETTER(getter, setter, type) \
49 #define V_FW_GETTER_SETTER(getter,setter, type)\
49 type Variable::getter() const noexcept { return impl->getter(); } \
50 type Variable::getter() const noexcept \
50 void Variable::setter(const type& getter) noexcept \
51 {\
51 { \
52 return impl->getter();\
52 impl->setter(getter); \
53 }\
53 emit updated(this->ID()); \
54 void Variable::setter(const type& getter) noexcept \
54 }
55 {\
55
56 impl->setter(getter);\
56 struct Variable::VariablePrivate
57 emit updated(this->ID());\
57 {
58 }\
58 explicit VariablePrivate(const QString& name, const QVariantHash& metadata)
59
59 : m_Name{name}, m_Range{INVALID_RANGE}, m_CacheRange{INVALID_RANGE},
60 struct Variable::VariablePrivate {
60 m_Metadata{metadata}, m_DataSeries{nullptr}, m_RealRange{INVALID_RANGE},
61 explicit VariablePrivate(const QString &name, const QVariantHash &metadata)
61 m_NbPoints{0}, m_Type{findDataSeriesType(m_Metadata)}
62 : m_Name{name},
62 {}
63 m_Range{INVALID_RANGE},
63
64 m_CacheRange{INVALID_RANGE},
64 VariablePrivate(const VariablePrivate& other)
65 m_Metadata{metadata},
65 : m_Name{other.m_Name}, m_Range{other.m_Range},
66 m_DataSeries{nullptr},
66 m_CacheRange{other.m_CacheRange}, m_Metadata{other.m_Metadata},
67 m_RealRange{INVALID_RANGE},
67 m_DataSeries{other.m_DataSeries != nullptr ? other.m_DataSeries->clone()
68 m_NbPoints{0},
68 : nullptr},
69 m_Type{findDataSeriesType(m_Metadata)}
69 m_RealRange{other.m_RealRange},
70 {
70 m_NbPoints{other.m_NbPoints}, m_Type{findDataSeriesType(m_Metadata)}
71 }
71 {}
72
72
73 VariablePrivate(const VariablePrivate &other)
73 void lockRead() { m_Lock.lockForRead(); }
74 : m_Name{other.m_Name},
74 void lockWrite() { m_Lock.lockForWrite(); }
75 m_Range{other.m_Range},
75 void unlock() { m_Lock.unlock(); }
76 m_CacheRange{other.m_CacheRange},
76
77 m_Metadata{other.m_Metadata},
77 void purgeDataSeries()
78 m_DataSeries{other.m_DataSeries != nullptr ? other.m_DataSeries->clone() : nullptr},
78 {
79 m_RealRange{other.m_RealRange},
79 if(m_DataSeries)
80 m_NbPoints{other.m_NbPoints},
80 { m_DataSeries->purge(m_CacheRange.m_TStart, m_CacheRange.m_TEnd); }
81 m_Type{findDataSeriesType(m_Metadata)}
81 updateRealRange();
82 {
82 updateNbPoints();
83 }
83 }
84
84 void mergeDataSeries(const std::vector<IDataSeries*>& dataseries,
85 void lockRead() { m_Lock.lockForRead(); }
85 bool overwrite = false)
86 void lockWrite() { m_Lock.lockForWrite(); }
86 {
87 void unlock() { m_Lock.unlock(); }
87 QWriteLocker lock{&m_Lock};
88
88 for(auto ds : dataseries)
89 void purgeDataSeries()
90 {
89 {
91 if (m_DataSeries) {
90 if(!overwrite & bool(m_DataSeries))
92 m_DataSeries->purge(m_CacheRange.m_TStart, m_CacheRange.m_TEnd);
91 m_DataSeries->merge(ds);
93 }
92 else
94 updateRealRange();
93 m_DataSeries = ds->clone();
95 updateNbPoints();
96 }
94 }
97 void mergeDataSeries(const std::vector<IDataSeries*>& dataseries, bool overwrite=false)
95 }
96 void updateNbPoints()
97 {
98 m_NbPoints = m_DataSeries ? m_DataSeries->nbPoints() : 0;
99 }
100
101 /// Updates real range according to current variable range and data series
102 void updateRealRange()
103 {
104 if(m_DataSeries)
98 {
105 {
99 QWriteLocker lock{&m_Lock};
106 auto lock = m_DataSeries->getReadLock();
100 for(auto ds:dataseries)
107 auto end = m_DataSeries->cend();
101 {
108 auto minXAxisIt = m_DataSeries->minXAxisData(m_Range.m_TStart);
102 if(!overwrite & bool(m_DataSeries))
109 auto maxXAxisIt = m_DataSeries->maxXAxisData(m_Range.m_TEnd);
103 m_DataSeries->merge(ds);
110 if(minXAxisIt != end && maxXAxisIt != end &&
104 else
111 minXAxisIt->x() <= maxXAxisIt->x())
105 m_DataSeries = ds->clone();
112 m_RealRange = DateTimeRange{minXAxisIt->x(), maxXAxisIt->x()};
106 }
113 else
114 m_RealRange = std::nullopt;
107 }
115 }
108 void updateNbPoints() { m_NbPoints = m_DataSeries ? m_DataSeries->nbPoints() : 0; }
116 else
109
110 /// Updates real range according to current variable range and data series
111 void updateRealRange()
112 {
117 {
113 if (m_DataSeries) {
118 m_RealRange = std::nullopt;
114 auto lock = m_DataSeries->getReadLock();
115 auto end = m_DataSeries->cend();
116 auto minXAxisIt = m_DataSeries->minXAxisData(m_Range.m_TStart);
117 auto maxXAxisIt = m_DataSeries->maxXAxisData(m_Range.m_TEnd);
118 if(minXAxisIt != end && maxXAxisIt != end && minXAxisIt->x() <= maxXAxisIt->x())
119 m_RealRange = DateTimeRange{minXAxisIt->x(), maxXAxisIt->x()};
120 else
121 m_RealRange = std::nullopt;
122 }
123 else {
124 m_RealRange = std::nullopt;
125 }
126 }
119 }
127
120 }
128 VP_PROPERTY(m_Name, name, setName, QString)
121
129 VP_PROPERTY(m_Range, range, setRange, DateTimeRange)
122 VP_PROPERTY(m_Name, name, setName, QString)
130 VP_PROPERTY(m_CacheRange, cacheRange, setCacheRange, DateTimeRange)
123 VP_PROPERTY(m_Range, range, setRange, DateTimeRange)
131 VP_PROPERTY(m_Metadata, metadata, setMetadata, QVariantHash)
124 VP_PROPERTY(m_CacheRange, cacheRange, setCacheRange, DateTimeRange)
132 VP_PROPERTY(m_DataSeries, dataSeries, setDataSeries, std::shared_ptr<IDataSeries>)
125 VP_PROPERTY(m_Metadata, metadata, setMetadata, QVariantHash)
133 VP_PROPERTY(m_RealRange, realRange, setRealRange, std::optional<DateTimeRange>)
126 VP_PROPERTY(m_DataSeries, dataSeries, setDataSeries,
134 unsigned int m_NbPoints;
127 std::shared_ptr<IDataSeries>)
135 VP_PROPERTY(m_Type, type, setType, DataSeriesType)
128 VP_PROPERTY(m_RealRange, realRange, setRealRange,
136 QReadWriteLock m_Lock;
129 std::optional<DateTimeRange>)
130 unsigned int m_NbPoints;
131 VP_PROPERTY(m_Type, type, setType, DataSeriesType)
132 QReadWriteLock m_Lock;
137 };
133 };
138
134
139 Variable::Variable(const QString &name, const QVariantHash &metadata)
135 Variable::Variable(const QString& name, const QVariantHash& metadata)
140 : impl{spimpl::make_unique_impl<VariablePrivate>(name, metadata)},
136 : impl{spimpl::make_unique_impl<VariablePrivate>(name, metadata)},
141 _uuid{QUuid::createUuid()}
137 _uuid{QUuid::createUuid()}
142 {
138 {}
143 }
144
139
145 Variable::Variable(const Variable &other)
140 Variable::Variable(const Variable& other)
146 : impl{spimpl::make_unique_impl<VariablePrivate>(*other.impl)},
141 : impl{spimpl::make_unique_impl<VariablePrivate>(*other.impl)},
147 _uuid{QUuid::createUuid()} //is a clone but must have a != uuid
142 _uuid{QUuid::createUuid()} // is a clone but must have a != uuid
148 {
143 {}
149 }
150
144
151 std::shared_ptr<Variable> Variable::clone() const
145 std::shared_ptr<Variable> Variable::clone() const
152 {
146 {
153 return std::make_shared<Variable>(*this);
147 return std::make_shared<Variable>(*this);
154 }
148 }
155
149
156 V_FW_GETTER_SETTER(name,setName,QString)
150 V_FW_GETTER_SETTER(name, setName, QString)
157
151
158 DateTimeRange Variable::range() const noexcept
152 DateTimeRange Variable::range() const noexcept { return impl->range(); }
159 {
160 return impl->range();
161 }
162
153
163 void Variable::setRange(const DateTimeRange &range, bool notify) noexcept
154 void Variable::setRange(const DateTimeRange& range, bool notify) noexcept
164 {
155 {
165 impl->setRange(range);
156 impl->setRange(range);
166 impl->updateRealRange();
157 impl->updateRealRange();
167 if(notify)
158 if(notify) emit this->updated(this->ID());
168 emit this->updated(this->ID());
169 }
159 }
170
160
171 V_FW_GETTER_SETTER(cacheRange, setCacheRange, DateTimeRange)
161 V_FW_GETTER_SETTER(cacheRange, setCacheRange, DateTimeRange)
172
162
173 unsigned int Variable::nbPoints() const noexcept
163 unsigned int Variable::nbPoints() const noexcept { return impl->m_NbPoints; }
174 {
175 return impl->m_NbPoints;
176 }
177
164
178 std::optional<DateTimeRange> Variable::realRange() const noexcept
165 std::optional<DateTimeRange> Variable::realRange() const noexcept
179 {
166 {
180 return impl->realRange();
167 return impl->realRange();
181 }
168 }
182
169
183 void Variable::updateData(const std::vector<IDataSeries *> &dataSeries, const DateTimeRange &newRange, const DateTimeRange &newCacheRange, bool notify)
170 void Variable::updateData(const std::vector<IDataSeries*>& dataSeries,
171 const DateTimeRange& newRange,
172 const DateTimeRange& newCacheRange, bool notify)
184 {
173 {
185 {
174 {
186 QWriteLocker lock{&m_lock};
175 QWriteLocker lock{&m_lock};
187 impl->mergeDataSeries(dataSeries);
176 impl->mergeDataSeries(dataSeries);
188 impl->setRange(newRange);
177 impl->setRange(newRange);
189 impl->setCacheRange(newCacheRange);
178 impl->setCacheRange(newCacheRange);
190 impl->purgeDataSeries();
179 impl->purgeDataSeries();
191 }
180 }
192 if(notify)
181 if(notify) emit updated(this->ID());
193 emit updated(this->ID());
194 }
182 }
195
183
196 void Variable::setData(const std::vector<IDataSeries *> &dataSeries, const DateTimeRange &newRange, const DateTimeRange &newCacheRange, bool notify)
184 void Variable::setData(const std::vector<IDataSeries*>& dataSeries,
185 const DateTimeRange& newRange,
186 const DateTimeRange& newCacheRange, bool notify)
197 {
187 {
198 {
188 {
199 QWriteLocker lock{&m_lock};
189 QWriteLocker lock{&m_lock};
200 impl->mergeDataSeries(dataSeries, true);
190 impl->mergeDataSeries(dataSeries, true);
201 impl->setRange(newRange);
191 impl->setRange(newRange);
202 impl->setCacheRange(newCacheRange);
192 impl->setCacheRange(newCacheRange);
203 impl->purgeDataSeries();
193 impl->purgeDataSeries();
204 }
194 }
205 if(notify)
195 if(notify) emit updated(this->ID());
206 emit updated(this->ID());
207 }
196 }
208
197
209 std::shared_ptr<IDataSeries> Variable::dataSeries() const noexcept
198 std::shared_ptr<IDataSeries> Variable::dataSeries() const noexcept
210 {
199 {
211 return impl->dataSeries();
200 return impl->dataSeries();
212 }
201 }
213
202
214 DataSeriesType Variable::type() const noexcept
203 DataSeriesType Variable::type() const noexcept { return impl->type(); }
215 {
216 return impl->type();
217 }
218
204
219 QVariantHash Variable::metadata() const noexcept
205 QVariantHash Variable::metadata() const noexcept
220 {
206 {
221 impl->lockRead();
207 impl->lockRead();
222 auto metadata = impl->m_Metadata;
208 auto metadata = impl->m_Metadata;
223 impl->unlock();
209 impl->unlock();
224 return metadata;
210 return metadata;
225 }
211 }
@@ -62,7 +62,10 class VariableController2::VariableController2Private
62 {
62 {
63 QReadLocker lock{&_lock};
63 QReadLocker lock{&_lock};
64 auto it = _variables.find(variable);
64 auto it = _variables.find(variable);
65 [[unlikely]] if(it == _variables.end())
65 #if __cplusplus > 201703L
66 [[unlikely]]
67 #endif
68 if(it == _variables.end())
66 SCIQLOP_ERROR(threadSafeVaraiblesMaps, "Unknown Variable");
69 SCIQLOP_ERROR(threadSafeVaraiblesMaps, "Unknown Variable");
67 return (*it).second;
70 return (*it).second;
68 }
71 }
@@ -70,7 +73,10 class VariableController2::VariableController2Private
70 inline std::shared_ptr<Variable> variable(int index)
73 inline std::shared_ptr<Variable> variable(int index)
71 {
74 {
72 QReadLocker lock{&_lock};
75 QReadLocker lock{&_lock};
73 [[unlikely]] if(!_variables.size() > index)
76 #if __cplusplus > 201703L
77 [[unlikely]]
78 #endif
79 if(!_variables.size() > index)
74 SCIQLOP_ERROR(threadSafeVaraiblesMaps, "Index is out of bounds");
80 SCIQLOP_ERROR(threadSafeVaraiblesMaps, "Index is out of bounds");
75 auto it = _variables.cbegin();
81 auto it = _variables.cbegin();
76 while(index != 0)
82 while(index != 0)
@@ -95,7 +101,10 class VariableController2::VariableController2Private
95 inline std::shared_ptr<IDataProvider> provider(QUuid variable)
101 inline std::shared_ptr<IDataProvider> provider(QUuid variable)
96 {
102 {
97 QReadLocker lock{&_lock};
103 QReadLocker lock{&_lock};
98 [[unlikely]] if(!_providers.contains(variable))
104 #if __cplusplus > 201703L
105 [[unlikely]]
106 #endif
107 if(!_providers.contains(variable))
99 SCIQLOP_ERROR(threadSafeVaraiblesMaps, "Unknown Variable");
108 SCIQLOP_ERROR(threadSafeVaraiblesMaps, "Unknown Variable");
100 return _providers[variable];
109 return _providers[variable];
101 }
110 }
@@ -103,7 +112,10 class VariableController2::VariableController2Private
103 inline std::shared_ptr<VariableSynchronizationGroup2> group(QUuid variable)
112 inline std::shared_ptr<VariableSynchronizationGroup2> group(QUuid variable)
104 {
113 {
105 QReadLocker lock{&_lock};
114 QReadLocker lock{&_lock};
106 [[unlikely]] if(!_synchronizationGroups.contains(variable))
115 #if __cplusplus > 201703L
116 [[unlikely]]
117 #endif
118 if(!_synchronizationGroups.contains(variable))
107 SCIQLOP_ERROR(threadSafeVaraiblesMaps, "Unknown Variable");
119 SCIQLOP_ERROR(threadSafeVaraiblesMaps, "Unknown Variable");
108 return _synchronizationGroups[variable];
120 return _synchronizationGroups[variable];
109 }
121 }
@@ -11,6 +11,7
11 #include <Data/VectorSeries.h>
11 #include <Data/VectorSeries.h>
12 #include <Network/Downloader.h>
12 #include <Network/Downloader.h>
13 #include <Time/TimeController.h>
13 #include <Time/TimeController.h>
14 #include <Variable/Variable2.h>
14 #include <Variable/VariableController2.h>
15 #include <Variable/VariableController2.h>
15 #include <pybind11/chrono.h>
16 #include <pybind11/chrono.h>
16 #include <pybind11/embed.h>
17 #include <pybind11/embed.h>
@@ -19,6 +20,7
19 #include <pybind11/operators.h>
20 #include <pybind11/operators.h>
20 #include <pybind11/pybind11.h>
21 #include <pybind11/pybind11.h>
21 #include <pybind11/stl.h>
22 #include <pybind11/stl.h>
23 #include <pybind11/stl_bind.h>
22 #include <sstream>
24 #include <sstream>
23 #include <string>
25 #include <string>
24
26
@@ -27,11 +29,13 using namespace std::chrono;
27
29
28 PYBIND11_MODULE(pysciqlopcore, m)
30 PYBIND11_MODULE(pysciqlopcore, m)
29 {
31 {
32 pybind11::bind_vector<std::vector<double>>(m, "VectorDouble");
33
30 py::enum_<DataSeriesType>(m, "DataSeriesType")
34 py::enum_<DataSeriesType>(m, "DataSeriesType")
31 .value("SCALAR", DataSeriesType::SCALAR)
35 .value("SCALAR", DataSeriesType::SCALAR)
32 .value("SPECTROGRAM", DataSeriesType::SPECTROGRAM)
36 .value("SPECTROGRAM", DataSeriesType::SPECTROGRAM)
33 .value("VECTOR", DataSeriesType::VECTOR)
37 .value("VECTOR", DataSeriesType::VECTOR)
34 .value("UNKNOWN", DataSeriesType::UNKNOWN)
38 .value("NONE", DataSeriesType::NONE)
35 .export_values();
39 .export_values();
36
40
37 py::class_<Unit>(m, "Unit")
41 py::class_<Unit>(m, "Unit")
@@ -149,9 +153,58 PYBIND11_MODULE(pysciqlopcore, m)
149 })
153 })
150 .def("__repr__", __repr__<Variable>);
154 .def("__repr__", __repr__<Variable>);
151
155
156 py::class_<TimeSeries::ITimeSerie>(m, "ITimeSerie")
157 .def_property_readonly(
158 "size", [](const TimeSeries::ITimeSerie& ts) { return ts.size(); })
159 .def_property_readonly(
160 "t",
161 [](TimeSeries::ITimeSerie& ts) -> decltype(ts.axis(0))& {
162 return ts.axis(0);
163 },
164 py::return_value_policy::reference);
165
166 py::class_<ScalarTimeSerie, TimeSeries::ITimeSerie>(m, "ScalarTimeSerie")
167 .def(py::init<>())
168 .def(py::init<std::size_t>())
169 .def("__getitem__",
170 [](ScalarTimeSerie& ts, std::size_t key) { return ts[key]; })
171 .def("__setitem__", [](ScalarTimeSerie& ts, std::size_t key,
172 double value) { *(ts.begin() + key) = value; });
173
174 py::class_<VectorTimeSerie::raw_value_type>(m, "vector")
175 .def(py::init<>())
176 .def(py::init<double, double, double>())
177 .def("__repr__", __repr__<VectorTimeSerie::raw_value_type>)
178 .def_readwrite("x", &VectorTimeSerie::raw_value_type::x)
179 .def_readwrite("y", &VectorTimeSerie::raw_value_type::y)
180 .def_readwrite("z", &VectorTimeSerie::raw_value_type::z);
181
182 py::class_<VectorTimeSerie, TimeSeries::ITimeSerie>(m, "VectorTimeSerie")
183 .def(py::init<>())
184 .def(py::init<std::size_t>())
185 .def("__getitem__",
186 [](VectorTimeSerie& ts, std::size_t key)
187 -> VectorTimeSerie::raw_value_type& { return ts[key]; },
188 py::return_value_policy::reference)
189 .def("__setitem__", [](VectorTimeSerie& ts, std::size_t key,
190 VectorTimeSerie::raw_value_type value) {
191 *(ts.begin() + key) = value;
192 });
193
194 py::class_<Variable2, std::shared_ptr<Variable2>>(m, "Variable2")
195 .def(py::init<const QString&>())
196 .def_property("name", &Variable2::name, &Variable2::setName)
197 .def_property_readonly("range", &Variable2::range)
198 .def_property_readonly("nbPoints", &Variable2::nbPoints)
199 .def_property_readonly(
200 "dataSeries", [](const Variable2& var) { return var.data()->base(); })
201 .def("set_data", &Variable2::setData)
202 .def("__len__", &Variable2::nbPoints)
203 .def("__repr__", __repr__<Variable2>);
204
152 py::class_<DateTimeRange>(m, "SqpRange")
205 py::class_<DateTimeRange>(m, "SqpRange")
153 //.def("fromDateTime", &DateTimeRange::fromDateTime,
206 //.def("fromDateTime", &DateTimeRange::fromDateTime,
154 //py::return_value_policy::move)
207 // py::return_value_policy::move)
155 .def(py::init([](double start, double stop) {
208 .def(py::init([](double start, double stop) {
156 return DateTimeRange{start, stop};
209 return DateTimeRange{start, stop};
157 }))
210 }))
@@ -1,54 +1,79
1 #pragma once
1 #pragma once
2 #include <pybind11/pybind11.h>
3 #include <pybind11/operators.h>
4
5 #include <string>
6 #include <sstream>
7 #include "pywrappers_common.h"
8 #include "QtWrappers.h"
2 #include "QtWrappers.h"
3 #include "pywrappers_common.h"
4
9 #include <Data/DataSeriesType.h>
5 #include <Data/DataSeriesType.h>
10 #include <Data/Unit.h>
6 #include <Data/DateTimeRange.h>
11 #include <Data/IDataSeries.h>
7 #include <Data/IDataSeries.h>
8 #include <Data/Unit.h>
12 #include <Variable/Variable.h>
9 #include <Variable/Variable.h>
13 #include <Data/DateTimeRange.h>
10 #include <Variable/Variable2.h>
11 #include <pybind11/pybind11.h>
12 #include <sstream>
13 #include <string>
14
14
15 PYBIND11_MAKE_OPAQUE(std::vector<double>);
15
16
16 std::ostream &operator <<(std::ostream& os, const Unit& u)
17 std::ostream& operator<<(std::ostream& os, const Unit& u)
17 {
18 {
18 os << "=========================" << std::endl
19 os << "=========================" << std::endl
19 << "Unit:" << std::endl
20 << "Unit:" << std::endl
20 << " Name: " << u.m_Name << std::endl
21 << " Name: " << u.m_Name << std::endl
21 << " Is_TimeUnit: " << u.m_TimeUnit << std::endl;
22 << " Is_TimeUnit: " << u.m_TimeUnit << std::endl;
22 return os;
23 return os;
23 }
24 }
24
25
26 std::ostream& operator<<(std::ostream& os, const IDataSeries& ds)
27 {
28 os << "=========================" << std::endl
29 << "DataSerie:" << std::endl
30 << " Number of points:" << ds.nbPoints() << std::endl
31 << " X Axis Unit:" << std::endl
32 << ds.xAxisUnit() << std::endl
33 << " Y Axis Unit:" << std::endl
34 << ds.yAxisUnit() << std::endl
35 << " Values Axis Unit:" << std::endl
36 << ds.valuesUnit() << std::endl;
37 return os;
38 }
39
40 std::ostream& operator<<(std::ostream& os, const DateTimeRange& range)
41 {
42 os << "=========================" << std::endl
43 << "SqpRange:" << std::endl
44 << " Start date: " << DateUtils::dateTime(range.m_TStart).toString()
45 << std::endl
46 << " Stop date: " << DateUtils::dateTime(range.m_TEnd).toString()
47 << std::endl;
48 return os;
49 }
25
50
26 std::ostream &operator <<(std::ostream& os, const IDataSeries& ds)
51 std::ostream& operator<<(std::ostream& os, const Variable& variable)
27 {
52 {
28 os << "=========================" << std::endl
53 os << "=========================" << std::endl
29 << "DataSerie:" << std::endl
54 << "Variable:" << std::endl
30 << " Number of points:" << ds.nbPoints() << std::endl
55 << " Name: " << variable.name() << std::endl
31 << " X Axis Unit:" << std::endl << ds.xAxisUnit() << std::endl
56 << " range: " << std::endl
32 << " Y Axis Unit:" << std::endl << ds.yAxisUnit()<< std::endl
57 << variable.range() << std::endl
33 << " Values Axis Unit:" << std::endl << ds.valuesUnit()<< std::endl;
58 << " cache range: " << std::endl
34 return os;
59 << variable.cacheRange() << std::endl;
60 return os;
35 }
61 }
36
62
37 std::ostream &operator <<(std::ostream& os, const DateTimeRange& range)
63 std::ostream& operator<<(std::ostream& os, const Variable2& variable)
38 {
64 {
39 os << "=========================" << std::endl
65 os << "=========================" << std::endl
40 << "SqpRange:" << std::endl
66 << "Variable:" << std::endl
41 << " Start date: " << DateUtils::dateTime(range.m_TStart).toString() << std::endl
67 << " Name: " << variable.name() << std::endl
42 << " Stop date: " << DateUtils::dateTime(range.m_TEnd).toString() << std::endl;
68 << " range: " << std::endl
43 return os;
69 << variable.range() << std::endl;
70 return os;
44 }
71 }
45
72
46 std::ostream &operator <<(std::ostream& os, const Variable& variable)
73 std::ostream& operator<<(std::ostream& os,
74 const VectorTimeSerie::raw_value_type& value)
47 {
75 {
48 os << "=========================" << std::endl
76 os << "[" << value.x << ", " << value.y << ", " << value.z << "]"
49 << "Variable:" << std::endl
77 << std::endl;
50 << " Name: " << variable.name() << std::endl
78 return os;
51 << " range: " << std::endl << variable.range() << std::endl
52 << " cache range: " << std::endl << variable.cacheRange() << std::endl;
53 return os;
54 }
79 }
@@ -1,23 +1,20
1 #include <Variable/Variable.h>
2
3 #include <Data/ScalarSeries.h>
4
5 #include <QObject>
1 #include <QObject>
6 #include <QtTest>
2 #include <QtTest>
7
3 #include <Variable/Variable2.h>
8 #include <memory>
4 #include <memory>
9
5
10
6 class TestVariable : public QObject
11
7 {
12 class TestVariable : public QObject {
8 Q_OBJECT
13 Q_OBJECT
14
9
15 private slots:
10 private slots:
16 void initTestCase() { QSKIP("Please Write me! .·´¯`(>▂<)´¯`·. "); }
11 void initTestCase() {}
12 void type_matches_TS_type()
13 {
14 Variable2 v("none", {});
15 QVERIFY(v.type() == DataSeriesType::NONE);
16 }
17 };
17 };
18
18
19
20
21
22 QTEST_MAIN(TestVariable)
19 QTEST_MAIN(TestVariable)
23 #include "TestVariable.moc"
20 #include "TestVariable.moc"
General Comments 0
You need to be logged in to leave comments. Login now