diff --git a/DebugHelpers/datetimerange.py b/DebugHelpers/datetimerange.py index 24fed30..b6a781d 100644 --- a/DebugHelpers/datetimerange.py +++ b/DebugHelpers/datetimerange.py @@ -30,3 +30,4 @@ def qdump__DateTimeRange(d , value): d.putValue(tstop) with SubItem(d, "delta"): d.putValue(delta) + diff --git a/external/TimeSeries b/external/TimeSeries index f5f4deb..22e3e45 160000 --- a/external/TimeSeries +++ b/external/TimeSeries @@ -1 +1 @@ -Subproject commit f5f4debc597b41ab1849dfc02b6e092bf58c32d2 +Subproject commit 22e3e4553178230053aac40131b4fdb36c163075 diff --git a/include/Common/cpp_utils.h b/include/Common/cpp_utils.h index 76739ac..201d837 100644 --- a/include/Common/cpp_utils.h +++ b/include/Common/cpp_utils.h @@ -1,29 +1,37 @@ #ifndef CPP_UTILS_H #define CPP_UTILS_H +#include +#include #include -template< class... > -using void_t = void; +template using void_t = void; -#define HAS_METHOD(method)\ -template \ -struct _has_##method : std::false_type{};\ -\ -template \ -struct _has_##method>>\ - : std::true_type{};\ -\ -template< class T>\ -static inline constexpr bool has_##method = _has_##method::value; +#define HAS_METHOD(method) \ + template struct _has_##method : std::false_type \ + {}; \ + \ + template \ + struct _has_##method< \ + T, void_t>> \ + : std::true_type \ + {}; \ + \ + template \ + static inline constexpr bool has_##method = _has_##method::value; -//taken from here https://www.fluentcpp.com/2017/10/27/function-aliases-cpp/ -#define ALIAS_TEMPLATE_FUNCTION(highLevelF, lowLevelF) \ - template \ - inline auto highLevelF(Args &&... args)->decltype(lowLevelF(std::forward(args)...)) \ - { \ - return lowLevelF(std::forward(args)...); \ - } +// taken from here https://www.fluentcpp.com/2017/10/27/function-aliases-cpp/ +#define ALIAS_TEMPLATE_FUNCTION(highLevelF, lowLevelF) \ + template \ + inline auto highLevelF(Args&&... args) \ + ->decltype(lowLevelF(std::forward(args)...)) \ + { \ + return lowLevelF(std::forward(args)...); \ + } +template constexpr T diff(const std::pair& p) +{ + return p.second - p.first; +} #endif // CPP_UTILS_H diff --git a/include/Data/SpectrogramTimeSerie.h b/include/Data/SpectrogramTimeSerie.h index 4dd3c2a..b453f06 100644 --- a/include/Data/SpectrogramTimeSerie.h +++ b/include/Data/SpectrogramTimeSerie.h @@ -18,10 +18,10 @@ public: .begin()); SpectrogramTimeSerie() {} - SpectrogramTimeSerie(SpectrogramTimeSerie::axis_t& t, - SpectrogramTimeSerie::axis_t& y, + SpectrogramTimeSerie(SpectrogramTimeSerie::axis_t&& t, + SpectrogramTimeSerie::axis_t&& y, SpectrogramTimeSerie::container_type< - SpectrogramTimeSerie::raw_value_type>& values, + SpectrogramTimeSerie::raw_value_type>&& values, std::vector& shape) : TimeSeries::TimeSerie(t, values, shape) { diff --git a/include/Data/TimeSeriesUtils.h b/include/Data/TimeSeriesUtils.h index 0d32b8e..daeda64 100644 --- a/include/Data/TimeSeriesUtils.h +++ b/include/Data/TimeSeriesUtils.h @@ -6,6 +6,7 @@ #include "VectorTimeSerie.h" #include +#include #include namespace TimeSeriesUtils @@ -36,6 +37,47 @@ namespace TimeSeriesUtils } return nullptr; } + + struct axis_properties + { + double range; + double max_resolution; + bool is_log; + }; + + constexpr auto IsLog = true; + constexpr auto IsLinear = false; + + constexpr auto CheckMedian = true; + constexpr auto DontCheckMedian = false; + + template + axis_properties axis_analysis( + typename std::conditional&, + const std::vector&>::type axis) + { + std::vector axis_diff(axis.size()); + if constexpr(is_log) + { + std::transform(std::cbegin(axis), std::cend(axis), std::begin(axis), + [](const auto v) { return std::log10(v); }); + } + auto range = *(std::cend(axis) - 1) - *(std::begin(axis)); + std::adjacent_difference(std::cbegin(axis), std::cend(axis), + std::begin(axis_diff)); + auto min_diff = + (*std::min_element(std::cbegin(axis_diff) + 1, std::cend(axis_diff))); + if constexpr(check_median) + { + std::nth_element(std::begin(axis_diff) + 1, + std::begin(axis_diff) + axis_diff.size() / 2, + std::end(axis_diff)); + auto median_diff = *(std::begin(axis_diff) + axis_diff.size() / 2); + if(median_diff > (4 * min_diff)) min_diff = median_diff; + } + return {range, min_diff, is_log}; + } + } // namespace TimeSeriesUtils #endif diff --git a/src/Variable/Variable2.cpp b/src/Variable/Variable2.cpp index 8a1a1aa..0d6c40b 100644 --- a/src/Variable/Variable2.cpp +++ b/src/Variable/Variable2.cpp @@ -193,6 +193,16 @@ _merge(std::vector source, const DateTimeRange& range) std::back_inserter(*std::dynamic_pointer_cast(dest))); } }); + if(source.size()) + { + const auto& first = *source.begin(); + for(std::size_t ax_index = 1; ax_index < first->shape().size(); ax_index++) + { + const auto& ax = first->axis(ax_index); + std::copy(std::cbegin(ax), std::cend(ax), + std::back_inserter(dest->axis(ax_index))); + } + } return dest; } diff --git a/src/pybind11_wrappers/CoreWrappers.cpp b/src/pybind11_wrappers/CoreWrappers.cpp index 40e2b53..0161d2c 100644 --- a/src/pybind11_wrappers/CoreWrappers.cpp +++ b/src/pybind11_wrappers/CoreWrappers.cpp @@ -232,7 +232,10 @@ PYBIND11_MODULE(pysciqlopcore, m) .def(py::init>()) .def(py::init([](py::array_t t, py::array_t y, py::array_t values) { - assert(t.size() < values.size()); // TODO check geometry + auto t_s = t.size(); + auto v_s = values.size(); + assert(t.size() < values.size() or + t.size() == 0); // TODO check geometry assert(y.size() == values.shape(1)); SpectrogramTimeSerie::axis_t _t(t.size()); SpectrogramTimeSerie::axis_t _y(y.size()); @@ -243,7 +246,8 @@ PYBIND11_MODULE(pysciqlopcore, m) std::vector shape; shape.push_back(values.shape(0)); shape.push_back(values.shape(1)); - return SpectrogramTimeSerie(_t, _y, _values, shape); + return SpectrogramTimeSerie(std::move(_t), std::move(_y), + std::move(_values), shape); })) .def("__getitem__", [](SpectrogramTimeSerie& ts,