##// END OF EJS Templates
Closed
Pull request !290 Created on Thu, 21 Sep 2017 11:04:20, by
- Merge branch 'feature/ProgressAndCancel' into develop
- Fix progression bug when aborting a request for Amda plugin
- See last commit
- Fix bug when creating two variables crash the app.
- Update networkcontroller for abort mechanism
Pull request versions not available.
ver Time Author Commit Description
12 commits hidden, click expand to show them.
@@ -0,0 +1,52
1 #include "Variable/VariableCacheStrategy.h"
2
3 #include "Settings/SqpSettingsDefs.h"
4
5 #include "Variable/Variable.h"
6 #include "Variable/VariableController.h"
7
8 Q_LOGGING_CATEGORY(LOG_VariableCacheStrategy, "VariableCacheStrategy")
9
10 struct VariableCacheStrategy::VariableCacheStrategyPrivate {
11 VariableCacheStrategyPrivate() : m_CacheStrategy{CacheStrategy::FixedTolerance} {}
12
13 CacheStrategy m_CacheStrategy;
14 };
15
16
17 VariableCacheStrategy::VariableCacheStrategy(QObject *parent)
18 : QObject{parent}, impl{spimpl::make_unique_impl<VariableCacheStrategyPrivate>()}
19 {
20 }
21
22 std::pair<SqpRange, SqpRange>
23 VariableCacheStrategy::computeStrategyRanges(const SqpRange &vRange, const SqpRange &rangeRequested)
24 {
25
26 auto varRanges = std::pair<SqpRange, SqpRange>{};
27
28 auto toleranceFactor = SqpSettings::toleranceValue(GENERAL_TOLERANCE_AT_UPDATE_KEY,
29 GENERAL_TOLERANCE_AT_UPDATE_DEFAULT_VALUE);
30 auto tolerance = toleranceFactor * (rangeRequested.m_TEnd - rangeRequested.m_TStart);
31
32 switch (impl->m_CacheStrategy) {
33 case CacheStrategy::FixedTolerance: {
34 varRanges.first = rangeRequested;
35 varRanges.second
36 = SqpRange{rangeRequested.m_TStart - tolerance, rangeRequested.m_TEnd + tolerance};
37 break;
38 }
39
40 case CacheStrategy::TwoThreashold: {
41 // TODO Implement
42 break;
43 }
44 default:
45 qCCritical(LOG_VariableCacheStrategy())
46 << tr("Impossible to use compute the cache range with an unknow cache strategy");
47 // No action
48 break;
49 }
50
51 return varRanges;
52 }
@@ -1,12 +1,11
1 #!/bin/bash
1 #!/bin/bash
2
2
3 mkdir -p ${MESON_INSTALL_PREFIX}/Contents/Frameworks
3 mkdir -p ${MESON_INSTALL_PREFIX}/Contents/Frameworks
4 mv ${MESON_INSTALL_PREFIX}/lib/*plugin* ${MESON_INSTALL_PREFIX}/Contents/MacOS
4 mv ${MESON_INSTALL_PREFIX}/lib/*plugin* ${MESON_INSTALL_PREFIX}/Contents/MacOS
5 macdeployqt ${MESON_INSTALL_PREFIX} -verbose=3
5 macdeployqt ${MESON_INSTALL_PREFIX} -verbose=3
6 install_name_tool -change @rpath/QtCore.framework/Versions/5/QtCore @executable_path/../Frameworks/QtCore.framework/Versions/5/QtCore /tmp/SciQLOP.app/Contents/MacOS/sciqlop
6 install_name_tool -change @rpath/QtCore.framework/Versions/5/QtCore @executable_path/../Frameworks/QtCore.framework/Versions/5/QtCore /tmp/SciQLOP.app/Contents/MacOS/sciqlop
7 install_name_tool -change @rpath/QtPrintSupport.framework/Versions/5/QtPrintSupport @executable_path/../Frameworks/QtPrintSupport.framework/Versions/5/QtPrintSupport /tmp/SciQLOP.app/Contents/MacOS/sciqlop
7 install_name_tool -change @rpath/QtPrintSupport.framework/Versions/5/QtPrintSupport @executable_path/../Frameworks/QtPrintSupport.framework/Versions/5/QtPrintSupport /tmp/SciQLOP.app/Contents/MacOS/sciqlop
8 install_name_tool -change @rpath/QtGui.framework/Versions/5/QtGui @executable_path/../Frameworks/QtGui.framework/Versions/5/QtGui /tmp/SciQLOP.app/Contents/MacOS/sciqlop
8 install_name_tool -change @rpath/QtGui.framework/Versions/5/QtGui @executable_path/../Frameworks/QtGui.framework/Versions/5/QtGui /tmp/SciQLOP.app/Contents/MacOS/sciqlop
9 install_name_tool -change @rpath/QtWidgets.framework/Versions/5/QtWidgets @executable_path/../Frameworks/QtWidgets.framework/Versions/5/QtWidgets /tmp/SciQLOP.app/Contents/MacOS/sciqlop
9 install_name_tool -change @rpath/QtWidgets.framework/Versions/5/QtWidgets @executable_path/../Frameworks/QtWidgets.framework/Versions/5/QtWidgets /tmp/SciQLOP.app/Contents/MacOS/sciqlop
10 install_name_tool -change @rpath/QtNetwork.framework/Versions/5/QtNetwork @executable_path/../Frameworks/QtNetwork.framework/Versions/5/QtNetwork /tmp/SciQLOP.app/Contents/MacOS/sciqlop
10 install_name_tool -change @rpath/QtNetwork.framework/Versions/5/QtNetwork @executable_path/../Frameworks/QtNetwork.framework/Versions/5/QtNetwork /tmp/SciQLOP.app/Contents/MacOS/sciqlop
11 install_name_tool -change @rpath/QtSvg.framework/Versions/5/QtSvg @executable_path/../Frameworks/QtSvg.framework/Versions/5/QtSvg /tmp/SciQLOP.app/Contents/MacOS/sciqlop
12
11
@@ -1,112 +1,108
1 #ifndef SCIQLOP_SQPITERATOR_H
1 #ifndef SCIQLOP_SQPITERATOR_H
2 #define SCIQLOP_SQPITERATOR_H
2 #define SCIQLOP_SQPITERATOR_H
3
3
4 #include "CoreGlobal.h"
4 #include "CoreGlobal.h"
5
5
6 /**
6 /**
7 * @brief The SqpIterator class represents an iterator used in SciQlop. It defines all operators
7 * @brief The SqpIterator class represents an iterator used in SciQlop. It defines all operators
8 * needed for a standard forward iterator
8 * needed for a standard forward iterator
9 * @tparam T the type of object handled in iterator
9 * @tparam T the type of object handled in iterator
10 * @sa http://www.cplusplus.com/reference/iterator/
10 * @sa http://www.cplusplus.com/reference/iterator/
11 */
11 */
12 template <typename T>
12 template <typename T>
13 class SCIQLOP_CORE_EXPORT SqpIterator {
13 class SCIQLOP_CORE_EXPORT SqpIterator {
14 public:
14 public:
15 using iterator_category = std::random_access_iterator_tag;
15 using iterator_category = std::random_access_iterator_tag;
16 using value_type = const T;
16 using value_type = const T;
17 using difference_type = std::ptrdiff_t;
17 using difference_type = std::ptrdiff_t;
18 using pointer = value_type *;
18 using pointer = value_type *;
19 using reference = value_type &;
19 using reference = value_type &;
20
20
21 explicit SqpIterator(T value) : m_CurrentValue{std::move(value)} {}
21 explicit SqpIterator(T value) : m_CurrentValue{std::move(value)} {}
22
22
23 virtual ~SqpIterator() noexcept = default;
23 virtual ~SqpIterator() noexcept = default;
24 SqpIterator(const SqpIterator &) = default;
24 SqpIterator(const SqpIterator &) = default;
25 SqpIterator &operator=(SqpIterator other)
25 SqpIterator &operator=(SqpIterator other) { swap(m_CurrentValue, other.m_CurrentValue); }
26 {
27 swap(m_CurrentValue, other.m_CurrentValue);
28 return *this;
29 }
30
26
31 SqpIterator &operator++()
27 SqpIterator &operator++()
32 {
28 {
33 m_CurrentValue.next();
29 m_CurrentValue.next();
34 return *this;
30 return *this;
35 }
31 }
36
32
37 SqpIterator &operator--()
33 SqpIterator &operator--()
38 {
34 {
39 m_CurrentValue.prev();
35 m_CurrentValue.prev();
40 return *this;
36 return *this;
41 }
37 }
42
38
43 SqpIterator operator++(int)const
39 SqpIterator operator++(int)const
44 {
40 {
45 auto result = *this;
41 auto result = *this;
46 this->operator++();
42 this->operator++();
47 return result;
43 return result;
48 }
44 }
49 SqpIterator operator--(int)const
45 SqpIterator operator--(int)const
50 {
46 {
51 auto result = *this;
47 auto result = *this;
52 this->operator--();
48 this->operator--();
53 return result;
49 return result;
54 }
50 }
55
51
56 SqpIterator &operator+=(int offset)
52 SqpIterator &operator+=(int offset)
57 {
53 {
58 if (offset >= 0) {
54 if (offset >= 0) {
59 m_CurrentValue.next(offset);
55 m_CurrentValue.next(offset);
60 }
56 }
61 else {
57 else {
62 while (offset++) {
58 while (offset++) {
63 m_CurrentValue.prev();
59 m_CurrentValue.prev();
64 }
60 }
65 }
61 }
66
62
67 return *this;
63 return *this;
68 }
64 }
69 SqpIterator &operator-=(int offset) { return *this += -offset; }
65 SqpIterator &operator-=(int offset) { return *this += -offset; }
70
66
71 SqpIterator operator+(int offset) const
67 SqpIterator operator+(int offset) const
72 {
68 {
73 auto result = *this;
69 auto result = *this;
74 result += offset;
70 result += offset;
75 return result;
71 return result;
76 }
72 }
77 SqpIterator operator-(int offset) const
73 SqpIterator operator-(int offset) const
78 {
74 {
79 auto result = *this;
75 auto result = *this;
80 result -= offset;
76 result -= offset;
81 return result;
77 return result;
82 }
78 }
83
79
84 int operator-(const SqpIterator &other) const
80 int operator-(const SqpIterator &other) const
85 {
81 {
86 return m_CurrentValue.distance(other.m_CurrentValue);
82 return m_CurrentValue.distance(other.m_CurrentValue);
87 }
83 }
88
84
89 const T *operator->() const { return &m_CurrentValue; }
85 const T *operator->() const { return &m_CurrentValue; }
90 const T &operator*() const { return m_CurrentValue; }
86 const T &operator*() const { return m_CurrentValue; }
91 T *operator->() { return &m_CurrentValue; }
87 T *operator->() { return &m_CurrentValue; }
92 T &operator*() { return m_CurrentValue; }
88 T &operator*() { return m_CurrentValue; }
93 T &operator[](int offset) const { return m_CurrentValue.advance(offset); }
89 T &operator[](int offset) const { return m_CurrentValue.advance(offset); }
94
90
95 bool operator==(const SqpIterator &other) const
91 bool operator==(const SqpIterator &other) const
96 {
92 {
97 return m_CurrentValue.equals(other.m_CurrentValue);
93 return m_CurrentValue.equals(other.m_CurrentValue);
98 }
94 }
99 bool operator!=(const SqpIterator &other) const { return !(*this == other); }
95 bool operator!=(const SqpIterator &other) const { return !(*this == other); }
100 bool operator>(const SqpIterator &other) const { return other.m_CurrentValue.lowerThan(*this); }
96 bool operator>(const SqpIterator &other) const { return other.m_CurrentValue.lowerThan(*this); }
101 bool operator<(const SqpIterator &other) const
97 bool operator<(const SqpIterator &other) const
102 {
98 {
103 return m_CurrentValue.lowerThan(other.m_CurrentValue);
99 return m_CurrentValue.lowerThan(other.m_CurrentValue);
104 }
100 }
105 bool operator>=(const SqpIterator &other) const { return !(*this < other); }
101 bool operator>=(const SqpIterator &other) const { return !(*this < other); }
106 bool operator<=(const SqpIterator &other) const { return !(*this > other); }
102 bool operator<=(const SqpIterator &other) const { return !(*this > other); }
107
103
108 private:
104 private:
109 T m_CurrentValue;
105 T m_CurrentValue;
110 };
106 };
111
107
112 #endif // SCIQLOP_SQPITERATOR_H
108 #endif // SCIQLOP_SQPITERATOR_H
@@ -1,37 +1,40
1 #ifndef SCIQLOP_VARIABLECACHESTRATEGY_H
1 #ifndef SCIQLOP_VARIABLECACHESTRATEGY_H
2 #define SCIQLOP_VARIABLECACHESTRATEGY_H
2 #define SCIQLOP_VARIABLECACHESTRATEGY_H
3
3
4 #include "CoreGlobal.h"
4 #include "CoreGlobal.h"
5
5
6 #include <QLoggingCategory>
6 #include <QLoggingCategory>
7 #include <QObject>
7 #include <QObject>
8
8
9 #include <Data/SqpRange.h>
9 #include <Data/SqpRange.h>
10
10
11 #include <QLoggingCategory>
11 #include <QLoggingCategory>
12
12
13 #include <Common/spimpl.h>
13 #include <Common/spimpl.h>
14 #include <utility>
14 #include <utility>
15
15
16
16
17 Q_DECLARE_LOGGING_CATEGORY(LOG_VariableCacheStrategy)
17 Q_DECLARE_LOGGING_CATEGORY(LOG_VariableCacheStrategy)
18
18
19 class Variable;
19 class Variable;
20
20
21 /**
21 /**
22 * Possible types of zoom operation
22 * Possible types of zoom operation
23 */
23 */
24 // enum class CacheStrategy { FixedTolerance, TwoThreashold };
24 enum class CacheStrategy { FixedTolerance, TwoThreashold };
25
26
25
27 /// This class aims to hande the cache strategy.
26 /// This class aims to hande the cache strategy.
28 class SCIQLOP_CORE_EXPORT VariableCacheStrategy {
27 class SCIQLOP_CORE_EXPORT VariableCacheStrategy : public QObject {
29
28 Q_OBJECT
30 public:
29 public:
31 virtual std::pair<SqpRange, SqpRange> computeRange(const SqpRange &vRange,
30 explicit VariableCacheStrategy(QObject *parent = 0);
32 const SqpRange &rangeRequested)
33 = 0;
34 };
35
31
32 std::pair<SqpRange, SqpRange> computeStrategyRanges(const SqpRange &vRange,
33 const SqpRange &rangeRequested);
34
35 private:
36 class VariableCacheStrategyPrivate;
37 spimpl::unique_impl_ptr<VariableCacheStrategyPrivate> impl;
38 };
36
39
37 #endif // SCIQLOP_VARIABLECACHESTRATEGY_H
40 #endif // SCIQLOP_VARIABLECACHESTRATEGY_H
@@ -1,83 +1,84
1 #include "Data/DataSeriesIterator.h"
1 #include "Data/DataSeriesIterator.h"
2
2
3 DataSeriesIteratorValue::DataSeriesIteratorValue(
3 DataSeriesIteratorValue::DataSeriesIteratorValue(
4 std::unique_ptr<DataSeriesIteratorValue::Impl> impl)
4 std::unique_ptr<DataSeriesIteratorValue::Impl> impl)
5 : m_Impl{std::move(impl)}
5 : m_Impl{std::move(impl)}
6 {
6 {
7 }
7 }
8
8
9 DataSeriesIteratorValue::DataSeriesIteratorValue(const DataSeriesIteratorValue &other)
9 DataSeriesIteratorValue::DataSeriesIteratorValue(const DataSeriesIteratorValue &other)
10 : m_Impl{other.m_Impl->clone()}
10 : m_Impl{other.m_Impl->clone()}
11 {
11 {
12 }
12 }
13
13
14 DataSeriesIteratorValue &DataSeriesIteratorValue::operator=(DataSeriesIteratorValue other)
14 DataSeriesIteratorValue &DataSeriesIteratorValue::operator=(DataSeriesIteratorValue other)
15 {
15 {
16 m_Impl->swap(*other.m_Impl);
16 m_Impl->swap(*other.m_Impl);
17 return *this;
17 return *this;
18 }
18 }
19
19
20 int DataSeriesIteratorValue::distance(const DataSeriesIteratorValue &other) const
20 int DataSeriesIteratorValue::distance(const DataSeriesIteratorValue &other) const
21 {
21 {
22 auto dist = m_Impl->distance(*other.m_Impl);
22 return m_Impl->distance(*other.m_Impl);
23 return m_Impl->distance(*other.m_Impl);
23 }
24 }
24
25
25 bool DataSeriesIteratorValue::equals(const DataSeriesIteratorValue &other) const
26 bool DataSeriesIteratorValue::equals(const DataSeriesIteratorValue &other) const
26 {
27 {
27 return m_Impl->equals(*other.m_Impl);
28 return m_Impl->equals(*other.m_Impl);
28 }
29 }
29
30
30 bool DataSeriesIteratorValue::lowerThan(const DataSeriesIteratorValue &other) const
31 bool DataSeriesIteratorValue::lowerThan(const DataSeriesIteratorValue &other) const
31 {
32 {
32 return m_Impl->lowerThan(*other.m_Impl);
33 return m_Impl->lowerThan(*other.m_Impl);
33 }
34 }
34
35
35 DataSeriesIteratorValue DataSeriesIteratorValue::advance(int offset) const
36 DataSeriesIteratorValue DataSeriesIteratorValue::advance(int offset) const
36 {
37 {
37 return DataSeriesIteratorValue{m_Impl->advance(offset)};
38 return DataSeriesIteratorValue{m_Impl->advance(offset)};
38 }
39 }
39
40
40 void DataSeriesIteratorValue::next(int offset)
41 void DataSeriesIteratorValue::next(int offset)
41 {
42 {
42 m_Impl->next(offset);
43 m_Impl->next(offset);
43 }
44 }
44
45
45 void DataSeriesIteratorValue::prev()
46 void DataSeriesIteratorValue::prev()
46 {
47 {
47 m_Impl->prev();
48 m_Impl->prev();
48 }
49 }
49
50
50 double DataSeriesIteratorValue::x() const
51 double DataSeriesIteratorValue::x() const
51 {
52 {
52 return m_Impl->x();
53 return m_Impl->x();
53 }
54 }
54
55
55 double DataSeriesIteratorValue::value() const
56 double DataSeriesIteratorValue::value() const
56 {
57 {
57 return m_Impl->value();
58 return m_Impl->value();
58 }
59 }
59
60
60 double DataSeriesIteratorValue::value(int componentIndex) const
61 double DataSeriesIteratorValue::value(int componentIndex) const
61 {
62 {
62 return m_Impl->value(componentIndex);
63 return m_Impl->value(componentIndex);
63 }
64 }
64
65
65 double DataSeriesIteratorValue::minValue() const
66 double DataSeriesIteratorValue::minValue() const
66 {
67 {
67 return m_Impl->minValue();
68 return m_Impl->minValue();
68 }
69 }
69
70
70 double DataSeriesIteratorValue::maxValue() const
71 double DataSeriesIteratorValue::maxValue() const
71 {
72 {
72 return m_Impl->maxValue();
73 return m_Impl->maxValue();
73 }
74 }
74
75
75 QVector<double> DataSeriesIteratorValue::values() const
76 QVector<double> DataSeriesIteratorValue::values() const
76 {
77 {
77 return m_Impl->values();
78 return m_Impl->values();
78 }
79 }
79
80
80 DataSeriesIteratorValue::Impl *DataSeriesIteratorValue::impl()
81 DataSeriesIteratorValue::Impl *DataSeriesIteratorValue::impl()
81 {
82 {
82 return m_Impl.get();
83 return m_Impl.get();
83 }
84 }
@@ -1,85 +1,88
1 #include "Data/VectorSeries.h"
1 #include "Data/VectorSeries.h"
2
2
3 namespace {
3 namespace {
4
4
5 /**
5 /**
6 * Flatten the three components of a vector to a single QVector that can be passed to an ArrayData
6 * Flatten the three components of a vector to a single QVector that can be passed to an ArrayData
7 *
7 *
8 * Example:
8 * Example:
9 * xValues = {1, 2, 3}
9 * xValues = {1, 2, 3}
10 * yValues = {4, 5, 6}
10 * yValues = {4, 5, 6}
11 * zValues = {7, 8, 9}
11 * zValues = {7, 8, 9}
12 *
12 *
13 * result = {1, 4, 7, 2, 5, 8, 3, 6, 9}
13 * result = {1, 4, 7, 2, 5, 8, 3, 6, 9}
14 *
14 *
15 * @param xValues the x-component values of the vector
15 * @param xValues the x-component values of the vector
16 * @param yValues the y-component values of the vector
16 * @param yValues the y-component values of the vector
17 * @param zValues the z-component values of the vector
17 * @param zValues the z-component values of the vector
18 * @return the single QVector
18 * @return the single QVector
19 * @remarks the three components are consumed
19 * @remarks the three components are consumed
20 * @sa ArrayData
20 * @sa ArrayData
21 */
21 */
22 std::vector<double> flatten(std::vector<double> xValues, std::vector<double> yValues,
22 std::vector<double> flatten(std::vector<double> xValues, std::vector<double> yValues,
23 std::vector<double> zValues)
23 std::vector<double> zValues)
24 {
24 {
25 if (xValues.size() != yValues.size() || xValues.size() != zValues.size()) {
25 if (xValues.size() != yValues.size() || xValues.size() != zValues.size()) {
26 /// @todo ALX : log
26 /// @todo ALX : log
27 return {};
27 return {};
28 }
28 }
29
29
30 auto result = std::vector<double>();
30 auto result = std::vector<double>();
31 result.reserve(xValues.size() * 3);
31 result.reserve(xValues.size() * 3);
32
32
33 while (!xValues.empty()) {
33 while (!xValues.empty()) {
34 result.insert(result.cend(), {xValues.front(), yValues.front(), zValues.front()});
34 result.insert(result.cend(), {xValues.front(), yValues.front(), zValues.front()});
35 xValues.erase(xValues.begin());
35 xValues.erase(xValues.begin());
36 yValues.erase(yValues.begin());
36 yValues.erase(yValues.begin());
37 zValues.erase(zValues.begin());
37 zValues.erase(zValues.begin());
38 }
38 }
39
39
40 return result;
40 return result;
41 }
41 }
42
42
43 } // namespace
43 } // namespace
44
44
45 VectorSeries::VectorSeries(std::vector<double> xAxisData, std::vector<double> xValuesData,
45 VectorSeries::VectorSeries(std::vector<double> xAxisData, std::vector<double> xValuesData,
46 std::vector<double> yValuesData, std::vector<double> zValuesData,
46 std::vector<double> yValuesData, std::vector<double> zValuesData,
47 const Unit &xAxisUnit, const Unit &valuesUnit)
47 const Unit &xAxisUnit, const Unit &valuesUnit)
48 : VectorSeries{std::move(xAxisData), flatten(std::move(xValuesData), std::move(yValuesData),
48 : VectorSeries{std::move(xAxisData), flatten(std::move(xValuesData), std::move(yValuesData),
49 std::move(zValuesData)),
49 std::move(zValuesData)),
50 xAxisUnit, valuesUnit}
50 xAxisUnit, valuesUnit}
51 {
51 {
52 }
52 }
53
53
54 VectorSeries::VectorSeries(std::vector<double> xAxisData, std::vector<double> valuesData,
54 VectorSeries::VectorSeries(std::vector<double> xAxisData, std::vector<double> valuesData,
55 const Unit &xAxisUnit, const Unit &valuesUnit)
55 const Unit &xAxisUnit, const Unit &valuesUnit)
56 : DataSeries{std::make_shared<ArrayData<1> >(std::move(xAxisData)), xAxisUnit,
56 : DataSeries{std::make_shared<ArrayData<1> >(std::move(xAxisData)), xAxisUnit,
57 std::make_shared<ArrayData<2> >(std::move(valuesData), 3), valuesUnit}
57 std::make_shared<ArrayData<2> >(std::move(valuesData), 3), valuesUnit}
58 {
58 {
59 }
59 }
60
60
61 std::unique_ptr<IDataSeries> VectorSeries::clone() const
61 std::unique_ptr<IDataSeries> VectorSeries::clone() const
62 {
62 {
63 return std::make_unique<VectorSeries>(*this);
63 return std::make_unique<VectorSeries>(*this);
64 }
64 }
65
65
66 std::shared_ptr<IDataSeries> VectorSeries::subDataSeries(const SqpRange &range)
66 std::shared_ptr<IDataSeries> VectorSeries::subDataSeries(const SqpRange &range)
67 {
67 {
68 auto subXAxisData = std::vector<double>();
68 auto subXAxisData = std::vector<double>();
69 auto subValuesData = std::vector<double>();
69 auto subXValuesData = std::vector<double>();
70 auto subYValuesData = std::vector<double>();
71 auto subZValuesData = std::vector<double>();
70
72
71 this->lockRead();
73 this->lockRead();
72 {
74 {
73 auto bounds = xAxisRange(range.m_TStart, range.m_TEnd);
75 auto bounds = xAxisRange(range.m_TStart, range.m_TEnd);
74 for (auto it = bounds.first; it != bounds.second; ++it) {
76 for (auto it = bounds.first; it != bounds.second; ++it) {
75 subXAxisData.push_back(it->x());
77 subXAxisData.push_back(it->x());
76 subValuesData.push_back(it->value(0));
78 subXValuesData.push_back(it->value(0));
77 subValuesData.push_back(it->value(1));
79 subYValuesData.push_back(it->value(1));
78 subValuesData.push_back(it->value(2));
80 subZValuesData.push_back(it->value(2));
79 }
81 }
80 }
82 }
81 this->unlock();
83 this->unlock();
82
84
83 return std::make_shared<VectorSeries>(std::move(subXAxisData), std::move(subValuesData),
85 return std::make_shared<VectorSeries>(std::move(subXAxisData), std::move(subXValuesData),
86 std::move(subYValuesData), std::move(subZValuesData),
84 this->xAxisUnit(), this->valuesUnit());
87 this->xAxisUnit(), this->valuesUnit());
85 }
88 }
@@ -1,842 +1,834
1 #include <Variable/Variable.h>
1 #include <Variable/Variable.h>
2 #include <Variable/VariableAcquisitionWorker.h>
2 #include <Variable/VariableAcquisitionWorker.h>
3 #include <Variable/VariableCacheStrategy.h>
3 #include <Variable/VariableCacheStrategy.h>
4 #include <Variable/VariableCacheStrategyFactory.h>
5 #include <Variable/VariableController.h>
4 #include <Variable/VariableController.h>
6 #include <Variable/VariableModel.h>
5 #include <Variable/VariableModel.h>
7 #include <Variable/VariableSynchronizationGroup.h>
6 #include <Variable/VariableSynchronizationGroup.h>
8
7
9 #include <Data/DataProviderParameters.h>
8 #include <Data/DataProviderParameters.h>
10 #include <Data/IDataProvider.h>
9 #include <Data/IDataProvider.h>
11 #include <Data/IDataSeries.h>
10 #include <Data/IDataSeries.h>
12 #include <Data/VariableRequest.h>
11 #include <Data/VariableRequest.h>
13 #include <Time/TimeController.h>
12 #include <Time/TimeController.h>
14
13
15 #include <QMutex>
14 #include <QMutex>
16 #include <QThread>
15 #include <QThread>
17 #include <QUuid>
16 #include <QUuid>
18 #include <QtCore/QItemSelectionModel>
17 #include <QtCore/QItemSelectionModel>
19
18
20 #include <deque>
19 #include <deque>
21 #include <set>
20 #include <set>
22 #include <unordered_map>
21 #include <unordered_map>
23
22
24 Q_LOGGING_CATEGORY(LOG_VariableController, "VariableController")
23 Q_LOGGING_CATEGORY(LOG_VariableController, "VariableController")
25
24
26 namespace {
25 namespace {
27
26
28 SqpRange computeSynchroRangeRequested(const SqpRange &varRange, const SqpRange &graphRange,
27 SqpRange computeSynchroRangeRequested(const SqpRange &varRange, const SqpRange &graphRange,
29 const SqpRange &oldGraphRange)
28 const SqpRange &oldGraphRange)
30 {
29 {
31 auto zoomType = VariableController::getZoomType(graphRange, oldGraphRange);
30 auto zoomType = VariableController::getZoomType(graphRange, oldGraphRange);
32
31
33 auto varRangeRequested = varRange;
32 auto varRangeRequested = varRange;
34 switch (zoomType) {
33 switch (zoomType) {
35 case AcquisitionZoomType::ZoomIn: {
34 case AcquisitionZoomType::ZoomIn: {
36 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
35 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
37 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
36 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
38 varRangeRequested.m_TStart += deltaLeft;
37 varRangeRequested.m_TStart += deltaLeft;
39 varRangeRequested.m_TEnd -= deltaRight;
38 varRangeRequested.m_TEnd -= deltaRight;
40 break;
39 break;
41 }
40 }
42
41
43 case AcquisitionZoomType::ZoomOut: {
42 case AcquisitionZoomType::ZoomOut: {
44 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
43 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
45 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
44 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
46 varRangeRequested.m_TStart -= deltaLeft;
45 varRangeRequested.m_TStart -= deltaLeft;
47 varRangeRequested.m_TEnd += deltaRight;
46 varRangeRequested.m_TEnd += deltaRight;
48 break;
47 break;
49 }
48 }
50 case AcquisitionZoomType::PanRight: {
49 case AcquisitionZoomType::PanRight: {
51 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
50 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
52 varRangeRequested.m_TStart += deltaRight;
51 varRangeRequested.m_TStart += deltaRight;
53 varRangeRequested.m_TEnd += deltaRight;
52 varRangeRequested.m_TEnd += deltaRight;
54 break;
53 break;
55 }
54 }
56 case AcquisitionZoomType::PanLeft: {
55 case AcquisitionZoomType::PanLeft: {
57 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
56 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
58 varRangeRequested.m_TStart -= deltaLeft;
57 varRangeRequested.m_TStart -= deltaLeft;
59 varRangeRequested.m_TEnd -= deltaLeft;
58 varRangeRequested.m_TEnd -= deltaLeft;
60 break;
59 break;
61 }
60 }
62 case AcquisitionZoomType::Unknown: {
61 case AcquisitionZoomType::Unknown: {
63 qCCritical(LOG_VariableController())
62 qCCritical(LOG_VariableController())
64 << VariableController::tr("Impossible to synchronize: zoom type unknown");
63 << VariableController::tr("Impossible to synchronize: zoom type unknown");
65 break;
64 break;
66 }
65 }
67 default:
66 default:
68 qCCritical(LOG_VariableController()) << VariableController::tr(
67 qCCritical(LOG_VariableController()) << VariableController::tr(
69 "Impossible to synchronize: zoom type not take into account");
68 "Impossible to synchronize: zoom type not take into account");
70 // No action
69 // No action
71 break;
70 break;
72 }
71 }
73
72
74 return varRangeRequested;
73 return varRangeRequested;
75 }
74 }
76 }
75 }
77
76
78 struct VariableController::VariableControllerPrivate {
77 struct VariableController::VariableControllerPrivate {
79 explicit VariableControllerPrivate(VariableController *parent)
78 explicit VariableControllerPrivate(VariableController *parent)
80 : m_WorkingMutex{},
79 : m_WorkingMutex{},
81 m_VariableModel{new VariableModel{parent}},
80 m_VariableModel{new VariableModel{parent}},
82 m_VariableSelectionModel{new QItemSelectionModel{m_VariableModel, parent}},
81 m_VariableSelectionModel{new QItemSelectionModel{m_VariableModel, parent}},
83 // m_VariableCacheStrategy{std::make_unique<VariableCacheStrategy>()},
82 m_VariableCacheStrategy{std::make_unique<VariableCacheStrategy>()},
84 m_VariableCacheStrategy{VariableCacheStrategyFactory::createCacheStrategy(
85 CacheStrategy::SingleThreshold)},
86 m_VariableAcquisitionWorker{std::make_unique<VariableAcquisitionWorker>()},
83 m_VariableAcquisitionWorker{std::make_unique<VariableAcquisitionWorker>()},
87 q{parent}
84 q{parent}
88 {
85 {
89
86
90 m_VariableAcquisitionWorker->moveToThread(&m_VariableAcquisitionWorkerThread);
87 m_VariableAcquisitionWorker->moveToThread(&m_VariableAcquisitionWorkerThread);
91 m_VariableAcquisitionWorkerThread.setObjectName("VariableAcquisitionWorkerThread");
88 m_VariableAcquisitionWorkerThread.setObjectName("VariableAcquisitionWorkerThread");
92 }
89 }
93
90
94
91
95 virtual ~VariableControllerPrivate()
92 virtual ~VariableControllerPrivate()
96 {
93 {
97 qCDebug(LOG_VariableController()) << tr("VariableControllerPrivate destruction");
94 qCDebug(LOG_VariableController()) << tr("VariableControllerPrivate destruction");
98 m_VariableAcquisitionWorkerThread.quit();
95 m_VariableAcquisitionWorkerThread.quit();
99 m_VariableAcquisitionWorkerThread.wait();
96 m_VariableAcquisitionWorkerThread.wait();
100 }
97 }
101
98
102
99
103 void processRequest(std::shared_ptr<Variable> var, const SqpRange &rangeRequested,
100 void processRequest(std::shared_ptr<Variable> var, const SqpRange &rangeRequested,
104 QUuid varRequestId);
101 QUuid varRequestId);
105
102
106 QVector<SqpRange> provideNotInCacheDateTimeList(std::shared_ptr<Variable> variable,
103 QVector<SqpRange> provideNotInCacheDateTimeList(std::shared_ptr<Variable> variable,
107 const SqpRange &dateTime);
104 const SqpRange &dateTime);
108
105
109 std::shared_ptr<Variable> findVariable(QUuid vIdentifier);
106 std::shared_ptr<Variable> findVariable(QUuid vIdentifier);
110 std::shared_ptr<IDataSeries>
107 std::shared_ptr<IDataSeries>
111 retrieveDataSeries(const QVector<AcquisitionDataPacket> acqDataPacketVector);
108 retrieveDataSeries(const QVector<AcquisitionDataPacket> acqDataPacketVector);
112
109
113 void registerProvider(std::shared_ptr<IDataProvider> provider);
110 void registerProvider(std::shared_ptr<IDataProvider> provider);
114
111
115 void storeVariableRequest(QUuid varId, QUuid varRequestId, const VariableRequest &varRequest);
112 void storeVariableRequest(QUuid varId, QUuid varRequestId, const VariableRequest &varRequest);
116 QUuid acceptVariableRequest(QUuid varId, std::shared_ptr<IDataSeries> dataSeries);
113 QUuid acceptVariableRequest(QUuid varId, std::shared_ptr<IDataSeries> dataSeries);
117 void updateVariableRequest(QUuid varRequestId);
114 void updateVariableRequest(QUuid varRequestId);
118 void cancelVariableRequest(QUuid varRequestId);
115 void cancelVariableRequest(QUuid varRequestId);
119
116
120 QMutex m_WorkingMutex;
117 QMutex m_WorkingMutex;
121 /// Variable model. The VariableController has the ownership
118 /// Variable model. The VariableController has the ownership
122 VariableModel *m_VariableModel;
119 VariableModel *m_VariableModel;
123 QItemSelectionModel *m_VariableSelectionModel;
120 QItemSelectionModel *m_VariableSelectionModel;
124
121
125
122
126 TimeController *m_TimeController{nullptr};
123 TimeController *m_TimeController{nullptr};
127 std::unique_ptr<VariableCacheStrategy> m_VariableCacheStrategy;
124 std::unique_ptr<VariableCacheStrategy> m_VariableCacheStrategy;
128 std::unique_ptr<VariableAcquisitionWorker> m_VariableAcquisitionWorker;
125 std::unique_ptr<VariableAcquisitionWorker> m_VariableAcquisitionWorker;
129 QThread m_VariableAcquisitionWorkerThread;
126 QThread m_VariableAcquisitionWorkerThread;
130
127
131 std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> >
128 std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> >
132 m_VariableToProviderMap;
129 m_VariableToProviderMap;
133 std::unordered_map<std::shared_ptr<Variable>, QUuid> m_VariableToIdentifierMap;
130 std::unordered_map<std::shared_ptr<Variable>, QUuid> m_VariableToIdentifierMap;
134 std::map<QUuid, std::shared_ptr<VariableSynchronizationGroup> >
131 std::map<QUuid, std::shared_ptr<VariableSynchronizationGroup> >
135 m_GroupIdToVariableSynchronizationGroupMap;
132 m_GroupIdToVariableSynchronizationGroupMap;
136 std::map<QUuid, QUuid> m_VariableIdGroupIdMap;
133 std::map<QUuid, QUuid> m_VariableIdGroupIdMap;
137 std::set<std::shared_ptr<IDataProvider> > m_ProviderSet;
134 std::set<std::shared_ptr<IDataProvider> > m_ProviderSet;
138
135
139 std::map<QUuid, std::map<QUuid, VariableRequest> > m_VarRequestIdToVarIdVarRequestMap;
136 std::map<QUuid, std::map<QUuid, VariableRequest> > m_VarRequestIdToVarIdVarRequestMap;
140
137
141 std::map<QUuid, std::deque<QUuid> > m_VarIdToVarRequestIdQueueMap;
138 std::map<QUuid, std::deque<QUuid> > m_VarIdToVarRequestIdQueueMap;
142
139
143
140
144 VariableController *q;
141 VariableController *q;
145 };
142 };
146
143
147
144
148 VariableController::VariableController(QObject *parent)
145 VariableController::VariableController(QObject *parent)
149 : QObject{parent}, impl{spimpl::make_unique_impl<VariableControllerPrivate>(this)}
146 : QObject{parent}, impl{spimpl::make_unique_impl<VariableControllerPrivate>(this)}
150 {
147 {
151 qCDebug(LOG_VariableController()) << tr("VariableController construction")
148 qCDebug(LOG_VariableController()) << tr("VariableController construction")
152 << QThread::currentThread();
149 << QThread::currentThread();
153
150
154 connect(impl->m_VariableModel, &VariableModel::abortProgessRequested, this,
151 connect(impl->m_VariableModel, &VariableModel::abortProgessRequested, this,
155 &VariableController::onAbortProgressRequested);
152 &VariableController::onAbortProgressRequested);
156
153
157 connect(impl->m_VariableAcquisitionWorker.get(),
154 connect(impl->m_VariableAcquisitionWorker.get(),
158 &VariableAcquisitionWorker::variableCanceledRequested, this,
155 &VariableAcquisitionWorker::variableCanceledRequested, this,
159 &VariableController::onAbortAcquisitionRequested);
156 &VariableController::onAbortAcquisitionRequested);
160
157
161 connect(impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::dataProvided, this,
158 connect(impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::dataProvided, this,
162 &VariableController::onDataProvided);
159 &VariableController::onDataProvided);
163 connect(impl->m_VariableAcquisitionWorker.get(),
160 connect(impl->m_VariableAcquisitionWorker.get(),
164 &VariableAcquisitionWorker::variableRequestInProgress, this,
161 &VariableAcquisitionWorker::variableRequestInProgress, this,
165 &VariableController::onVariableRetrieveDataInProgress);
162 &VariableController::onVariableRetrieveDataInProgress);
166
163
167
164
168 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::started,
165 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::started,
169 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::initialize);
166 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::initialize);
170 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::finished,
167 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::finished,
171 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::finalize);
168 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::finalize);
172
169
173
170
174 impl->m_VariableAcquisitionWorkerThread.start();
171 impl->m_VariableAcquisitionWorkerThread.start();
175 }
172 }
176
173
177 VariableController::~VariableController()
174 VariableController::~VariableController()
178 {
175 {
179 qCDebug(LOG_VariableController()) << tr("VariableController destruction")
176 qCDebug(LOG_VariableController()) << tr("VariableController destruction")
180 << QThread::currentThread();
177 << QThread::currentThread();
181 this->waitForFinish();
178 this->waitForFinish();
182 }
179 }
183
180
184 VariableModel *VariableController::variableModel() noexcept
181 VariableModel *VariableController::variableModel() noexcept
185 {
182 {
186 return impl->m_VariableModel;
183 return impl->m_VariableModel;
187 }
184 }
188
185
189 QItemSelectionModel *VariableController::variableSelectionModel() noexcept
186 QItemSelectionModel *VariableController::variableSelectionModel() noexcept
190 {
187 {
191 return impl->m_VariableSelectionModel;
188 return impl->m_VariableSelectionModel;
192 }
189 }
193
190
194 void VariableController::setTimeController(TimeController *timeController) noexcept
191 void VariableController::setTimeController(TimeController *timeController) noexcept
195 {
192 {
196 impl->m_TimeController = timeController;
193 impl->m_TimeController = timeController;
197 }
194 }
198
195
199 std::shared_ptr<Variable>
196 std::shared_ptr<Variable>
200 VariableController::cloneVariable(std::shared_ptr<Variable> variable) noexcept
197 VariableController::cloneVariable(std::shared_ptr<Variable> variable) noexcept
201 {
198 {
202 if (impl->m_VariableModel->containsVariable(variable)) {
199 if (impl->m_VariableModel->containsVariable(variable)) {
203 // Clones variable
200 // Clones variable
204 auto duplicate = variable->clone();
201 auto duplicate = variable->clone();
205
202
206 // Adds clone to model
203 // Adds clone to model
207 impl->m_VariableModel->addVariable(duplicate);
204 impl->m_VariableModel->addVariable(duplicate);
208
205
209 // Generates clone identifier
206 // Generates clone identifier
210 impl->m_VariableToIdentifierMap[duplicate] = QUuid::createUuid();
207 impl->m_VariableToIdentifierMap[duplicate] = QUuid::createUuid();
211
208
212 // Registers provider
209 // Registers provider
213 auto variableProvider = impl->m_VariableToProviderMap.at(variable);
210 auto variableProvider = impl->m_VariableToProviderMap.at(variable);
214 auto duplicateProvider = variableProvider != nullptr ? variableProvider->clone() : nullptr;
211 auto duplicateProvider = variableProvider != nullptr ? variableProvider->clone() : nullptr;
215
212
216 impl->m_VariableToProviderMap[duplicate] = duplicateProvider;
213 impl->m_VariableToProviderMap[duplicate] = duplicateProvider;
217 if (duplicateProvider) {
214 if (duplicateProvider) {
218 impl->registerProvider(duplicateProvider);
215 impl->registerProvider(duplicateProvider);
219 }
216 }
220
217
221 return duplicate;
218 return duplicate;
222 }
219 }
223 else {
220 else {
224 qCCritical(LOG_VariableController())
221 qCCritical(LOG_VariableController())
225 << tr("Can't create duplicate of variable %1: variable not registered in the model")
222 << tr("Can't create duplicate of variable %1: variable not registered in the model")
226 .arg(variable->name());
223 .arg(variable->name());
227 return nullptr;
224 return nullptr;
228 }
225 }
229 }
226 }
230
227
231 void VariableController::deleteVariable(std::shared_ptr<Variable> variable) noexcept
228 void VariableController::deleteVariable(std::shared_ptr<Variable> variable) noexcept
232 {
229 {
233 if (!variable) {
230 if (!variable) {
234 qCCritical(LOG_VariableController()) << "Can't delete variable: variable is null";
231 qCCritical(LOG_VariableController()) << "Can't delete variable: variable is null";
235 return;
232 return;
236 }
233 }
237
234
238 // Spreads in SciQlop that the variable will be deleted, so that potential receivers can
235 // Spreads in SciQlop that the variable will be deleted, so that potential receivers can
239 // make some treatments before the deletion
236 // make some treatments before the deletion
240 emit variableAboutToBeDeleted(variable);
237 emit variableAboutToBeDeleted(variable);
241
238
242 // Deletes identifier
239 // Deletes identifier
243 impl->m_VariableToIdentifierMap.erase(variable);
240 impl->m_VariableToIdentifierMap.erase(variable);
244
241
245 // Deletes provider
242 // Deletes provider
246 auto nbProvidersDeleted = impl->m_VariableToProviderMap.erase(variable);
243 auto nbProvidersDeleted = impl->m_VariableToProviderMap.erase(variable);
247 qCDebug(LOG_VariableController())
244 qCDebug(LOG_VariableController())
248 << tr("Number of providers deleted for variable %1: %2")
245 << tr("Number of providers deleted for variable %1: %2")
249 .arg(variable->name(), QString::number(nbProvidersDeleted));
246 .arg(variable->name(), QString::number(nbProvidersDeleted));
250
247
251
248
252 // Deletes from model
249 // Deletes from model
253 impl->m_VariableModel->deleteVariable(variable);
250 impl->m_VariableModel->deleteVariable(variable);
254 }
251 }
255
252
256 void VariableController::deleteVariables(
253 void VariableController::deleteVariables(
257 const QVector<std::shared_ptr<Variable> > &variables) noexcept
254 const QVector<std::shared_ptr<Variable> > &variables) noexcept
258 {
255 {
259 for (auto variable : qAsConst(variables)) {
256 for (auto variable : qAsConst(variables)) {
260 deleteVariable(variable);
257 deleteVariable(variable);
261 }
258 }
262 }
259 }
263
260
264 std::shared_ptr<Variable>
261 std::shared_ptr<Variable>
265 VariableController::createVariable(const QString &name, const QVariantHash &metadata,
262 VariableController::createVariable(const QString &name, const QVariantHash &metadata,
266 std::shared_ptr<IDataProvider> provider) noexcept
263 std::shared_ptr<IDataProvider> provider) noexcept
267 {
264 {
268 if (!impl->m_TimeController) {
265 if (!impl->m_TimeController) {
269 qCCritical(LOG_VariableController())
266 qCCritical(LOG_VariableController())
270 << tr("Impossible to create variable: The time controller is null");
267 << tr("Impossible to create variable: The time controller is null");
271 return nullptr;
268 return nullptr;
272 }
269 }
273
270
274 auto range = impl->m_TimeController->dateTime();
271 auto range = impl->m_TimeController->dateTime();
275
272
276 if (auto newVariable = impl->m_VariableModel->createVariable(name, metadata)) {
273 if (auto newVariable = impl->m_VariableModel->createVariable(name, metadata)) {
277 auto identifier = QUuid::createUuid();
274 auto identifier = QUuid::createUuid();
278
275
279 // store the provider
276 // store the provider
280 impl->registerProvider(provider);
277 impl->registerProvider(provider);
281
278
282 // Associate the provider
279 // Associate the provider
283 impl->m_VariableToProviderMap[newVariable] = provider;
280 impl->m_VariableToProviderMap[newVariable] = provider;
284 qCInfo(LOG_VariableController()) << "createVariable: " << identifier;
281 qCInfo(LOG_VariableController()) << "createVariable: " << identifier;
285 impl->m_VariableToIdentifierMap[newVariable] = identifier;
282 impl->m_VariableToIdentifierMap[newVariable] = identifier;
286
283
287
284
288 auto varRequestId = QUuid::createUuid();
285 auto varRequestId = QUuid::createUuid();
289 impl->processRequest(newVariable, range, varRequestId);
286 impl->processRequest(newVariable, range, varRequestId);
290 impl->updateVariableRequest(varRequestId);
287 impl->updateVariableRequest(varRequestId);
291
288
292 return newVariable;
289 return newVariable;
293 }
290 }
294 }
291 }
295
292
296 void VariableController::onDateTimeOnSelection(const SqpRange &dateTime)
293 void VariableController::onDateTimeOnSelection(const SqpRange &dateTime)
297 {
294 {
298 // TODO check synchronisation and Rescale
295 // TODO check synchronisation and Rescale
299 qCDebug(LOG_VariableController()) << "VariableController::onDateTimeOnSelection"
296 qCDebug(LOG_VariableController()) << "VariableController::onDateTimeOnSelection"
300 << QThread::currentThread()->objectName();
297 << QThread::currentThread()->objectName();
301 auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
298 auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
302 auto varRequestId = QUuid::createUuid();
299 auto varRequestId = QUuid::createUuid();
303
300
304 for (const auto &selectedRow : qAsConst(selectedRows)) {
301 for (const auto &selectedRow : qAsConst(selectedRows)) {
305 if (auto selectedVariable = impl->m_VariableModel->variable(selectedRow.row())) {
302 if (auto selectedVariable = impl->m_VariableModel->variable(selectedRow.row())) {
306 selectedVariable->setRange(dateTime);
303 selectedVariable->setRange(dateTime);
307 impl->processRequest(selectedVariable, dateTime, varRequestId);
304 impl->processRequest(selectedVariable, dateTime, varRequestId);
308
305
309 // notify that rescale operation has to be done
306 // notify that rescale operation has to be done
310 emit rangeChanged(selectedVariable, dateTime);
307 emit rangeChanged(selectedVariable, dateTime);
311 }
308 }
312 }
309 }
313 impl->updateVariableRequest(varRequestId);
310 impl->updateVariableRequest(varRequestId);
314 }
311 }
315
312
316 void VariableController::onDataProvided(QUuid vIdentifier, const SqpRange &rangeRequested,
313 void VariableController::onDataProvided(QUuid vIdentifier, const SqpRange &rangeRequested,
317 const SqpRange &cacheRangeRequested,
314 const SqpRange &cacheRangeRequested,
318 QVector<AcquisitionDataPacket> dataAcquired)
315 QVector<AcquisitionDataPacket> dataAcquired)
319 {
316 {
320 auto retrievedDataSeries = impl->retrieveDataSeries(dataAcquired);
317 auto retrievedDataSeries = impl->retrieveDataSeries(dataAcquired);
321 auto varRequestId = impl->acceptVariableRequest(vIdentifier, retrievedDataSeries);
318 auto varRequestId = impl->acceptVariableRequest(vIdentifier, retrievedDataSeries);
322 if (!varRequestId.isNull()) {
319 if (!varRequestId.isNull()) {
323 impl->updateVariableRequest(varRequestId);
320 impl->updateVariableRequest(varRequestId);
324 }
321 }
325 }
322 }
326
323
327 void VariableController::onVariableRetrieveDataInProgress(QUuid identifier, double progress)
324 void VariableController::onVariableRetrieveDataInProgress(QUuid identifier, double progress)
328 {
325 {
329 qCDebug(LOG_VariableController())
326 qCDebug(LOG_VariableController())
330 << "TORM: variableController::onVariableRetrieveDataInProgress"
327 << "TORM: variableController::onVariableRetrieveDataInProgress"
331 << QThread::currentThread()->objectName() << progress;
328 << QThread::currentThread()->objectName() << progress;
332 if (auto var = impl->findVariable(identifier)) {
329 if (auto var = impl->findVariable(identifier)) {
333 impl->m_VariableModel->setDataProgress(var, progress);
330 impl->m_VariableModel->setDataProgress(var, progress);
334 }
331 }
335 else {
332 else {
336 qCCritical(LOG_VariableController())
333 qCCritical(LOG_VariableController())
337 << tr("Impossible to notify progression of a null variable");
334 << tr("Impossible to notify progression of a null variable");
338 }
335 }
339 }
336 }
340
337
341 void VariableController::onAbortProgressRequested(std::shared_ptr<Variable> variable)
338 void VariableController::onAbortProgressRequested(std::shared_ptr<Variable> variable)
342 {
339 {
343 auto it = impl->m_VariableToIdentifierMap.find(variable);
340 auto it = impl->m_VariableToIdentifierMap.find(variable);
344 if (it != impl->m_VariableToIdentifierMap.cend()) {
341 if (it != impl->m_VariableToIdentifierMap.cend()) {
345 impl->m_VariableAcquisitionWorker->abortProgressRequested(it->second);
342 impl->m_VariableAcquisitionWorker->abortProgressRequested(it->second);
346
343
347 QUuid varRequestId;
344 QUuid varRequestId;
348 auto varIdToVarRequestIdQueueMapIt = impl->m_VarIdToVarRequestIdQueueMap.find(it->second);
345 auto varIdToVarRequestIdQueueMapIt = impl->m_VarIdToVarRequestIdQueueMap.find(it->second);
349 if (varIdToVarRequestIdQueueMapIt != impl->m_VarIdToVarRequestIdQueueMap.cend()) {
346 if (varIdToVarRequestIdQueueMapIt != impl->m_VarIdToVarRequestIdQueueMap.cend()) {
350 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
347 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
351 varRequestId = varRequestIdQueue.front();
348 varRequestId = varRequestIdQueue.front();
352 impl->cancelVariableRequest(varRequestId);
349 impl->cancelVariableRequest(varRequestId);
353
350
354 // Finish the progression for the request
351 // Finish the progression for the request
355 impl->m_VariableModel->setDataProgress(variable, 0.0);
352 impl->m_VariableModel->setDataProgress(variable, 0.0);
356 }
353 }
357 else {
354 else {
358 qCWarning(LOG_VariableController())
355 qCWarning(LOG_VariableController())
359 << tr("Aborting progression of inexistant variable request detected !!!")
356 << tr("Aborting progression of inexistant variable request detected !!!")
360 << QThread::currentThread()->objectName();
357 << QThread::currentThread()->objectName();
361 }
358 }
362 }
359 }
363 else {
360 else {
364 qCWarning(LOG_VariableController())
361 qCWarning(LOG_VariableController())
365 << tr("Aborting progression of inexistant variable detected !!!")
362 << tr("Aborting progression of inexistant variable detected !!!")
366 << QThread::currentThread()->objectName();
363 << QThread::currentThread()->objectName();
367 }
364 }
368 }
365 }
369
366
370 void VariableController::onAbortAcquisitionRequested(QUuid vIdentifier)
367 void VariableController::onAbortAcquisitionRequested(QUuid vIdentifier)
371 {
368 {
372 qCDebug(LOG_VariableController()) << "TORM: variableController::onAbortAcquisitionRequested"
369 qCDebug(LOG_VariableController()) << "TORM: variableController::onAbortAcquisitionRequested"
373 << QThread::currentThread()->objectName() << vIdentifier;
370 << QThread::currentThread()->objectName() << vIdentifier;
374
371
375 if (auto var = impl->findVariable(vIdentifier)) {
372 if (auto var = impl->findVariable(vIdentifier)) {
376 this->onAbortProgressRequested(var);
373 this->onAbortProgressRequested(var);
377 }
374 }
378 else {
375 else {
379 qCCritical(LOG_VariableController())
376 qCCritical(LOG_VariableController())
380 << tr("Impossible to abort Acquisition Requestof a null variable");
377 << tr("Impossible to abort Acquisition Requestof a null variable");
381 }
378 }
382 }
379 }
383
380
384 void VariableController::onAddSynchronizationGroupId(QUuid synchronizationGroupId)
381 void VariableController::onAddSynchronizationGroupId(QUuid synchronizationGroupId)
385 {
382 {
386 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronizationGroupId"
383 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronizationGroupId"
387 << QThread::currentThread()->objectName()
384 << QThread::currentThread()->objectName()
388 << synchronizationGroupId;
385 << synchronizationGroupId;
389 auto vSynchroGroup = std::make_shared<VariableSynchronizationGroup>();
386 auto vSynchroGroup = std::make_shared<VariableSynchronizationGroup>();
390 impl->m_GroupIdToVariableSynchronizationGroupMap.insert(
387 impl->m_GroupIdToVariableSynchronizationGroupMap.insert(
391 std::make_pair(synchronizationGroupId, vSynchroGroup));
388 std::make_pair(synchronizationGroupId, vSynchroGroup));
392 }
389 }
393
390
394 void VariableController::onRemoveSynchronizationGroupId(QUuid synchronizationGroupId)
391 void VariableController::onRemoveSynchronizationGroupId(QUuid synchronizationGroupId)
395 {
392 {
396 impl->m_GroupIdToVariableSynchronizationGroupMap.erase(synchronizationGroupId);
393 impl->m_GroupIdToVariableSynchronizationGroupMap.erase(synchronizationGroupId);
397 }
394 }
398
395
399 void VariableController::onAddSynchronized(std::shared_ptr<Variable> variable,
396 void VariableController::onAddSynchronized(std::shared_ptr<Variable> variable,
400 QUuid synchronizationGroupId)
397 QUuid synchronizationGroupId)
401
398
402 {
399 {
403 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronized"
400 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronized"
404 << synchronizationGroupId;
401 << synchronizationGroupId;
405 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(variable);
402 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(variable);
406 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
403 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
407 auto groupIdToVSGIt
404 auto groupIdToVSGIt
408 = impl->m_GroupIdToVariableSynchronizationGroupMap.find(synchronizationGroupId);
405 = impl->m_GroupIdToVariableSynchronizationGroupMap.find(synchronizationGroupId);
409 if (groupIdToVSGIt != impl->m_GroupIdToVariableSynchronizationGroupMap.cend()) {
406 if (groupIdToVSGIt != impl->m_GroupIdToVariableSynchronizationGroupMap.cend()) {
410 impl->m_VariableIdGroupIdMap.insert(
407 impl->m_VariableIdGroupIdMap.insert(
411 std::make_pair(varToVarIdIt->second, synchronizationGroupId));
408 std::make_pair(varToVarIdIt->second, synchronizationGroupId));
412 groupIdToVSGIt->second->addVariableId(varToVarIdIt->second);
409 groupIdToVSGIt->second->addVariableId(varToVarIdIt->second);
413 }
410 }
414 else {
411 else {
415 qCCritical(LOG_VariableController())
412 qCCritical(LOG_VariableController())
416 << tr("Impossible to synchronize a variable with an unknown sycnhronization group")
413 << tr("Impossible to synchronize a variable with an unknown sycnhronization group")
417 << variable->name();
414 << variable->name();
418 }
415 }
419 }
416 }
420 else {
417 else {
421 qCCritical(LOG_VariableController())
418 qCCritical(LOG_VariableController())
422 << tr("Impossible to synchronize a variable with no identifier") << variable->name();
419 << tr("Impossible to synchronize a variable with no identifier") << variable->name();
423 }
420 }
424 }
421 }
425
422
426 void VariableController::desynchronize(std::shared_ptr<Variable> variable,
423 void VariableController::desynchronize(std::shared_ptr<Variable> variable,
427 QUuid synchronizationGroupId)
424 QUuid synchronizationGroupId)
428 {
425 {
429 // Gets variable id
426 // Gets variable id
430 auto variableIt = impl->m_VariableToIdentifierMap.find(variable);
427 auto variableIt = impl->m_VariableToIdentifierMap.find(variable);
431 if (variableIt == impl->m_VariableToIdentifierMap.cend()) {
428 if (variableIt == impl->m_VariableToIdentifierMap.cend()) {
432 qCCritical(LOG_VariableController())
429 qCCritical(LOG_VariableController())
433 << tr("Can't desynchronize variable %1: variable identifier not found")
430 << tr("Can't desynchronize variable %1: variable identifier not found")
434 .arg(variable->name());
431 .arg(variable->name());
435 return;
432 return;
436 }
433 }
437
434
438 // Gets synchronization group
435 // Gets synchronization group
439 auto groupIt = impl->m_GroupIdToVariableSynchronizationGroupMap.find(synchronizationGroupId);
436 auto groupIt = impl->m_GroupIdToVariableSynchronizationGroupMap.find(synchronizationGroupId);
440 if (groupIt == impl->m_GroupIdToVariableSynchronizationGroupMap.cend()) {
437 if (groupIt == impl->m_GroupIdToVariableSynchronizationGroupMap.cend()) {
441 qCCritical(LOG_VariableController())
438 qCCritical(LOG_VariableController())
442 << tr("Can't desynchronize variable %1: unknown synchronization group")
439 << tr("Can't desynchronize variable %1: unknown synchronization group")
443 .arg(variable->name());
440 .arg(variable->name());
444 return;
441 return;
445 }
442 }
446
443
447 auto variableId = variableIt->second;
444 auto variableId = variableIt->second;
448
445
449 // Removes variable from synchronization group
446 // Removes variable from synchronization group
450 auto synchronizationGroup = groupIt->second;
447 auto synchronizationGroup = groupIt->second;
451 synchronizationGroup->removeVariableId(variableId);
448 synchronizationGroup->removeVariableId(variableId);
452
449
453 // Removes link between variable and synchronization group
450 // Removes link between variable and synchronization group
454 impl->m_VariableIdGroupIdMap.erase(variableId);
451 impl->m_VariableIdGroupIdMap.erase(variableId);
455 }
452 }
456
453
457 void VariableController::onRequestDataLoading(QVector<std::shared_ptr<Variable> > variables,
454 void VariableController::onRequestDataLoading(QVector<std::shared_ptr<Variable> > variables,
458 const SqpRange &range, const SqpRange &oldRange,
455 const SqpRange &range, const SqpRange &oldRange,
459 bool synchronise)
456 bool synchronise)
460 {
457 {
461 // NOTE: oldRange isn't really necessary since oldRange == variable->range().
458 // NOTE: oldRange isn't really necessary since oldRange == variable->range().
462
459
463 // we want to load data of the variable for the dateTime.
460 // we want to load data of the variable for the dateTime.
464 // First we check if the cache contains some of them.
461 // First we check if the cache contains some of them.
465 // For the other, we ask the provider to give them.
462 // For the other, we ask the provider to give them.
466
463
467 auto varRequestId = QUuid::createUuid();
464 auto varRequestId = QUuid::createUuid();
468 qCDebug(LOG_VariableController()) << "VariableController::onRequestDataLoading"
465 qCDebug(LOG_VariableController()) << "VariableController::onRequestDataLoading"
469 << QThread::currentThread()->objectName() << varRequestId;
466 << QThread::currentThread()->objectName() << varRequestId;
470
467
471 for (const auto &var : variables) {
468 for (const auto &var : variables) {
472 qCDebug(LOG_VariableController()) << "processRequest for" << var->name() << varRequestId;
469 qCDebug(LOG_VariableController()) << "processRequest for" << var->name() << varRequestId;
473 impl->processRequest(var, range, varRequestId);
470 impl->processRequest(var, range, varRequestId);
474 }
471 }
475
472
476 if (synchronise) {
473 if (synchronise) {
477 // Get the group ids
474 // Get the group ids
478 qCDebug(LOG_VariableController())
475 qCDebug(LOG_VariableController())
479 << "TORM VariableController::onRequestDataLoading for synchro var ENABLE";
476 << "TORM VariableController::onRequestDataLoading for synchro var ENABLE";
480 auto groupIds = std::set<QUuid>{};
477 auto groupIds = std::set<QUuid>{};
481 auto groupIdToOldRangeMap = std::map<QUuid, SqpRange>{};
478 auto groupIdToOldRangeMap = std::map<QUuid, SqpRange>{};
482 for (const auto &var : variables) {
479 for (const auto &var : variables) {
483 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(var);
480 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(var);
484 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
481 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
485 auto vId = varToVarIdIt->second;
482 auto vId = varToVarIdIt->second;
486 auto varIdToGroupIdIt = impl->m_VariableIdGroupIdMap.find(vId);
483 auto varIdToGroupIdIt = impl->m_VariableIdGroupIdMap.find(vId);
487 if (varIdToGroupIdIt != impl->m_VariableIdGroupIdMap.cend()) {
484 if (varIdToGroupIdIt != impl->m_VariableIdGroupIdMap.cend()) {
488 auto gId = varIdToGroupIdIt->second;
485 auto gId = varIdToGroupIdIt->second;
489 groupIdToOldRangeMap.insert(std::make_pair(gId, var->range()));
486 groupIdToOldRangeMap.insert(std::make_pair(gId, var->range()));
490 if (groupIds.find(gId) == groupIds.cend()) {
487 if (groupIds.find(gId) == groupIds.cend()) {
491 qCDebug(LOG_VariableController()) << "Synchro detect group " << gId;
488 qCDebug(LOG_VariableController()) << "Synchro detect group " << gId;
492 groupIds.insert(gId);
489 groupIds.insert(gId);
493 }
490 }
494 }
491 }
495 }
492 }
496 }
493 }
497
494
498 // We assume here all group ids exist
495 // We assume here all group ids exist
499 for (const auto &gId : groupIds) {
496 for (const auto &gId : groupIds) {
500 auto vSynchronizationGroup = impl->m_GroupIdToVariableSynchronizationGroupMap.at(gId);
497 auto vSynchronizationGroup = impl->m_GroupIdToVariableSynchronizationGroupMap.at(gId);
501 auto vSyncIds = vSynchronizationGroup->getIds();
498 auto vSyncIds = vSynchronizationGroup->getIds();
502 qCDebug(LOG_VariableController()) << "Var in synchro group ";
499 qCDebug(LOG_VariableController()) << "Var in synchro group ";
503 for (auto vId : vSyncIds) {
500 for (auto vId : vSyncIds) {
504 auto var = impl->findVariable(vId);
501 auto var = impl->findVariable(vId);
505
502
506 // Don't process already processed var
503 // Don't process already processed var
507 if (!variables.contains(var)) {
504 if (!variables.contains(var)) {
508 if (var != nullptr) {
505 if (var != nullptr) {
509 qCDebug(LOG_VariableController()) << "processRequest synchro for"
506 qCDebug(LOG_VariableController()) << "processRequest synchro for"
510 << var->name();
507 << var->name();
511 auto vSyncRangeRequested = computeSynchroRangeRequested(
508 auto vSyncRangeRequested = computeSynchroRangeRequested(
512 var->range(), range, groupIdToOldRangeMap.at(gId));
509 var->range(), range, groupIdToOldRangeMap.at(gId));
513 qCDebug(LOG_VariableController()) << "synchro RR" << vSyncRangeRequested;
510 qCDebug(LOG_VariableController()) << "synchro RR" << vSyncRangeRequested;
514 impl->processRequest(var, vSyncRangeRequested, varRequestId);
511 impl->processRequest(var, vSyncRangeRequested, varRequestId);
515 }
512 }
516 else {
513 else {
517 qCCritical(LOG_VariableController())
514 qCCritical(LOG_VariableController())
518
515
519 << tr("Impossible to synchronize a null variable");
516 << tr("Impossible to synchronize a null variable");
520 }
517 }
521 }
518 }
522 }
519 }
523 }
520 }
524 }
521 }
525
522
526 impl->updateVariableRequest(varRequestId);
523 impl->updateVariableRequest(varRequestId);
527 }
524 }
528
525
529
526
530 void VariableController::initialize()
527 void VariableController::initialize()
531 {
528 {
532 qCDebug(LOG_VariableController()) << tr("VariableController init") << QThread::currentThread();
529 qCDebug(LOG_VariableController()) << tr("VariableController init") << QThread::currentThread();
533 impl->m_WorkingMutex.lock();
530 impl->m_WorkingMutex.lock();
534 qCDebug(LOG_VariableController()) << tr("VariableController init END");
531 qCDebug(LOG_VariableController()) << tr("VariableController init END");
535 }
532 }
536
533
537 void VariableController::finalize()
534 void VariableController::finalize()
538 {
535 {
539 impl->m_WorkingMutex.unlock();
536 impl->m_WorkingMutex.unlock();
540 }
537 }
541
538
542 void VariableController::waitForFinish()
539 void VariableController::waitForFinish()
543 {
540 {
544 QMutexLocker locker{&impl->m_WorkingMutex};
541 QMutexLocker locker{&impl->m_WorkingMutex};
545 }
542 }
546
543
547 AcquisitionZoomType VariableController::getZoomType(const SqpRange &range, const SqpRange &oldRange)
544 AcquisitionZoomType VariableController::getZoomType(const SqpRange &range, const SqpRange &oldRange)
548 {
545 {
549 // t1.m_TStart <= t2.m_TStart && t2.m_TEnd <= t1.m_TEnd
546 // t1.m_TStart <= t2.m_TStart && t2.m_TEnd <= t1.m_TEnd
550 auto zoomType = AcquisitionZoomType::Unknown;
547 auto zoomType = AcquisitionZoomType::Unknown;
551 if (range.m_TStart <= oldRange.m_TStart && oldRange.m_TEnd <= range.m_TEnd) {
548 if (range.m_TStart <= oldRange.m_TStart && oldRange.m_TEnd <= range.m_TEnd) {
552 zoomType = AcquisitionZoomType::ZoomOut;
549 zoomType = AcquisitionZoomType::ZoomOut;
553 }
550 }
554 else if (range.m_TStart > oldRange.m_TStart && range.m_TEnd > oldRange.m_TEnd) {
551 else if (range.m_TStart > oldRange.m_TStart && range.m_TEnd > oldRange.m_TEnd) {
555 zoomType = AcquisitionZoomType::PanRight;
552 zoomType = AcquisitionZoomType::PanRight;
556 }
553 }
557 else if (range.m_TStart < oldRange.m_TStart && range.m_TEnd < oldRange.m_TEnd) {
554 else if (range.m_TStart < oldRange.m_TStart && range.m_TEnd < oldRange.m_TEnd) {
558 zoomType = AcquisitionZoomType::PanLeft;
555 zoomType = AcquisitionZoomType::PanLeft;
559 }
556 }
560 else if (range.m_TStart > oldRange.m_TStart && oldRange.m_TEnd > range.m_TEnd) {
557 else if (range.m_TStart > oldRange.m_TStart && oldRange.m_TEnd > range.m_TEnd) {
561 zoomType = AcquisitionZoomType::ZoomIn;
558 zoomType = AcquisitionZoomType::ZoomIn;
562 }
559 }
563 else {
560 else {
564 qCCritical(LOG_VariableController()) << "getZoomType: Unknown type detected";
561 qCCritical(LOG_VariableController()) << "getZoomType: Unknown type detected";
565 }
562 }
566 return zoomType;
563 return zoomType;
567 }
564 }
568
565
569 void VariableController::VariableControllerPrivate::processRequest(std::shared_ptr<Variable> var,
566 void VariableController::VariableControllerPrivate::processRequest(std::shared_ptr<Variable> var,
570 const SqpRange &rangeRequested,
567 const SqpRange &rangeRequested,
571 QUuid varRequestId)
568 QUuid varRequestId)
572 {
569 {
573
570
574 // TODO: protect at
571 // TODO: protect at
575 auto varRequest = VariableRequest{};
572 auto varRequest = VariableRequest{};
576 auto varId = m_VariableToIdentifierMap.at(var);
573 auto varId = m_VariableToIdentifierMap.at(var);
577
574
578 auto varStrategyRangesRequested
575 auto varStrategyRangesRequested
579 = m_VariableCacheStrategy->computeRange(var->range(), rangeRequested);
576 = m_VariableCacheStrategy->computeStrategyRanges(var->range(), rangeRequested);
580
577 auto notInCacheRangeList = var->provideNotInCacheRangeList(varStrategyRangesRequested.second);
581 auto notInCacheRangeList = QVector<SqpRange>{varStrategyRangesRequested.second};
578 auto inCacheRangeList = var->provideInCacheRangeList(varStrategyRangesRequested.second);
582 auto inCacheRangeList = QVector<SqpRange>{};
583 if (m_VarIdToVarRequestIdQueueMap.find(varId) == m_VarIdToVarRequestIdQueueMap.cend()) {
584 notInCacheRangeList = var->provideNotInCacheRangeList(varStrategyRangesRequested.second);
585 inCacheRangeList = var->provideInCacheRangeList(varStrategyRangesRequested.second);
586 }
587
579
588 if (!notInCacheRangeList.empty()) {
580 if (!notInCacheRangeList.empty()) {
589 varRequest.m_RangeRequested = varStrategyRangesRequested.first;
581 varRequest.m_RangeRequested = varStrategyRangesRequested.first;
590 varRequest.m_CacheRangeRequested = varStrategyRangesRequested.second;
582 varRequest.m_CacheRangeRequested = varStrategyRangesRequested.second;
591
583
592 // store VarRequest
584 // store VarRequest
593 storeVariableRequest(varId, varRequestId, varRequest);
585 storeVariableRequest(varId, varRequestId, varRequest);
594
586
595 auto varProvider = m_VariableToProviderMap.at(var);
587 auto varProvider = m_VariableToProviderMap.at(var);
596 if (varProvider != nullptr) {
588 if (varProvider != nullptr) {
597 auto varRequestIdCanceled = m_VariableAcquisitionWorker->pushVariableRequest(
589 auto varRequestIdCanceled = m_VariableAcquisitionWorker->pushVariableRequest(
598 varRequestId, varId, varStrategyRangesRequested.first,
590 varRequestId, varId, varStrategyRangesRequested.first,
599 varStrategyRangesRequested.second,
591 varStrategyRangesRequested.second,
600 DataProviderParameters{std::move(notInCacheRangeList), var->metadata()},
592 DataProviderParameters{std::move(notInCacheRangeList), var->metadata()},
601 varProvider);
593 varProvider);
602
594
603 if (!varRequestIdCanceled.isNull()) {
595 if (!varRequestIdCanceled.isNull()) {
604 qCDebug(LOG_VariableAcquisitionWorker()) << tr("vsarRequestIdCanceled: ")
596 qCDebug(LOG_VariableAcquisitionWorker()) << tr("vsarRequestIdCanceled: ")
605 << varRequestIdCanceled;
597 << varRequestIdCanceled;
606 cancelVariableRequest(varRequestIdCanceled);
598 cancelVariableRequest(varRequestIdCanceled);
607 }
599 }
608 }
600 }
609 else {
601 else {
610 qCCritical(LOG_VariableController())
602 qCCritical(LOG_VariableController())
611 << "Impossible to provide data with a null provider";
603 << "Impossible to provide data with a null provider";
612 }
604 }
613
605
614 if (!inCacheRangeList.empty()) {
606 if (!inCacheRangeList.empty()) {
615 emit q->updateVarDisplaying(var, inCacheRangeList.first());
607 emit q->updateVarDisplaying(var, inCacheRangeList.first());
616 }
608 }
617 }
609 }
618 else {
610 else {
619 varRequest.m_RangeRequested = varStrategyRangesRequested.first;
611 varRequest.m_RangeRequested = varStrategyRangesRequested.first;
620 varRequest.m_CacheRangeRequested = varStrategyRangesRequested.second;
612 varRequest.m_CacheRangeRequested = varStrategyRangesRequested.second;
621 // store VarRequest
613 // store VarRequest
622 storeVariableRequest(varId, varRequestId, varRequest);
614 storeVariableRequest(varId, varRequestId, varRequest);
623 acceptVariableRequest(varId,
615 acceptVariableRequest(varId,
624 var->dataSeries()->subDataSeries(varStrategyRangesRequested.second));
616 var->dataSeries()->subDataSeries(varStrategyRangesRequested.second));
625 }
617 }
626 }
618 }
627
619
628 std::shared_ptr<Variable>
620 std::shared_ptr<Variable>
629 VariableController::VariableControllerPrivate::findVariable(QUuid vIdentifier)
621 VariableController::VariableControllerPrivate::findVariable(QUuid vIdentifier)
630 {
622 {
631 std::shared_ptr<Variable> var;
623 std::shared_ptr<Variable> var;
632 auto findReply = [vIdentifier](const auto &entry) { return vIdentifier == entry.second; };
624 auto findReply = [vIdentifier](const auto &entry) { return vIdentifier == entry.second; };
633
625
634 auto end = m_VariableToIdentifierMap.cend();
626 auto end = m_VariableToIdentifierMap.cend();
635 auto it = std::find_if(m_VariableToIdentifierMap.cbegin(), end, findReply);
627 auto it = std::find_if(m_VariableToIdentifierMap.cbegin(), end, findReply);
636 if (it != end) {
628 if (it != end) {
637 var = it->first;
629 var = it->first;
638 }
630 }
639 else {
631 else {
640 qCCritical(LOG_VariableController())
632 qCCritical(LOG_VariableController())
641 << tr("Impossible to find the variable with the identifier: ") << vIdentifier;
633 << tr("Impossible to find the variable with the identifier: ") << vIdentifier;
642 }
634 }
643
635
644 return var;
636 return var;
645 }
637 }
646
638
647 std::shared_ptr<IDataSeries> VariableController::VariableControllerPrivate::retrieveDataSeries(
639 std::shared_ptr<IDataSeries> VariableController::VariableControllerPrivate::retrieveDataSeries(
648 const QVector<AcquisitionDataPacket> acqDataPacketVector)
640 const QVector<AcquisitionDataPacket> acqDataPacketVector)
649 {
641 {
650 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size")
642 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size")
651 << acqDataPacketVector.size();
643 << acqDataPacketVector.size();
652 std::shared_ptr<IDataSeries> dataSeries;
644 std::shared_ptr<IDataSeries> dataSeries;
653 if (!acqDataPacketVector.isEmpty()) {
645 if (!acqDataPacketVector.isEmpty()) {
654 dataSeries = acqDataPacketVector[0].m_DateSeries;
646 dataSeries = acqDataPacketVector[0].m_DateSeries;
655 for (int i = 1; i < acqDataPacketVector.size(); ++i) {
647 for (int i = 1; i < acqDataPacketVector.size(); ++i) {
656 dataSeries->merge(acqDataPacketVector[i].m_DateSeries.get());
648 dataSeries->merge(acqDataPacketVector[i].m_DateSeries.get());
657 }
649 }
658 }
650 }
659 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size END")
651 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size END")
660 << acqDataPacketVector.size();
652 << acqDataPacketVector.size();
661 return dataSeries;
653 return dataSeries;
662 }
654 }
663
655
664 void VariableController::VariableControllerPrivate::registerProvider(
656 void VariableController::VariableControllerPrivate::registerProvider(
665 std::shared_ptr<IDataProvider> provider)
657 std::shared_ptr<IDataProvider> provider)
666 {
658 {
667 if (m_ProviderSet.find(provider) == m_ProviderSet.end()) {
659 if (m_ProviderSet.find(provider) == m_ProviderSet.end()) {
668 qCDebug(LOG_VariableController()) << tr("Registering of a new provider")
660 qCDebug(LOG_VariableController()) << tr("Registering of a new provider")
669 << provider->objectName();
661 << provider->objectName();
670 m_ProviderSet.insert(provider);
662 m_ProviderSet.insert(provider);
671 connect(provider.get(), &IDataProvider::dataProvided, m_VariableAcquisitionWorker.get(),
663 connect(provider.get(), &IDataProvider::dataProvided, m_VariableAcquisitionWorker.get(),
672 &VariableAcquisitionWorker::onVariableDataAcquired);
664 &VariableAcquisitionWorker::onVariableDataAcquired);
673 connect(provider.get(), &IDataProvider::dataProvidedProgress,
665 connect(provider.get(), &IDataProvider::dataProvidedProgress,
674 m_VariableAcquisitionWorker.get(),
666 m_VariableAcquisitionWorker.get(),
675 &VariableAcquisitionWorker::onVariableRetrieveDataInProgress);
667 &VariableAcquisitionWorker::onVariableRetrieveDataInProgress);
676 connect(provider.get(), &IDataProvider::dataProvidedFailed,
668 connect(provider.get(), &IDataProvider::dataProvidedFailed,
677 m_VariableAcquisitionWorker.get(),
669 m_VariableAcquisitionWorker.get(),
678 &VariableAcquisitionWorker::onVariableAcquisitionFailed);
670 &VariableAcquisitionWorker::onVariableAcquisitionFailed);
679 }
671 }
680 else {
672 else {
681 qCDebug(LOG_VariableController()) << tr("Cannot register provider, it already exists ");
673 qCDebug(LOG_VariableController()) << tr("Cannot register provider, it already exists ");
682 }
674 }
683 }
675 }
684
676
685 void VariableController::VariableControllerPrivate::storeVariableRequest(
677 void VariableController::VariableControllerPrivate::storeVariableRequest(
686 QUuid varId, QUuid varRequestId, const VariableRequest &varRequest)
678 QUuid varId, QUuid varRequestId, const VariableRequest &varRequest)
687 {
679 {
688 // First request for the variable. we can create an entry for it
680 // First request for the variable. we can create an entry for it
689 auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.find(varId);
681 auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.find(varId);
690 if (varIdToVarRequestIdQueueMapIt == m_VarIdToVarRequestIdQueueMap.cend()) {
682 if (varIdToVarRequestIdQueueMapIt == m_VarIdToVarRequestIdQueueMap.cend()) {
691 auto varRequestIdQueue = std::deque<QUuid>{};
683 auto varRequestIdQueue = std::deque<QUuid>{};
692 qCDebug(LOG_VariableController()) << tr("Store REQUEST in QUEUE");
684 qCDebug(LOG_VariableController()) << tr("Store REQUEST in QUEUE");
693 varRequestIdQueue.push_back(varRequestId);
685 varRequestIdQueue.push_back(varRequestId);
694 m_VarIdToVarRequestIdQueueMap.insert(std::make_pair(varId, std::move(varRequestIdQueue)));
686 m_VarIdToVarRequestIdQueueMap.insert(std::make_pair(varId, std::move(varRequestIdQueue)));
695 }
687 }
696 else {
688 else {
697 qCDebug(LOG_VariableController()) << tr("Store REQUEST in EXISTING QUEUE");
689 qCDebug(LOG_VariableController()) << tr("Store REQUEST in EXISTING QUEUE");
698 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
690 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
699 varRequestIdQueue.push_back(varRequestId);
691 varRequestIdQueue.push_back(varRequestId);
700 }
692 }
701
693
702 auto varRequestIdToVarIdVarRequestMapIt = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
694 auto varRequestIdToVarIdVarRequestMapIt = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
703 if (varRequestIdToVarIdVarRequestMapIt == m_VarRequestIdToVarIdVarRequestMap.cend()) {
695 if (varRequestIdToVarIdVarRequestMapIt == m_VarRequestIdToVarIdVarRequestMap.cend()) {
704 auto varIdToVarRequestMap = std::map<QUuid, VariableRequest>{};
696 auto varIdToVarRequestMap = std::map<QUuid, VariableRequest>{};
705 varIdToVarRequestMap.insert(std::make_pair(varId, varRequest));
697 varIdToVarRequestMap.insert(std::make_pair(varId, varRequest));
706 qCDebug(LOG_VariableController()) << tr("Store REQUESTID in MAP");
698 qCDebug(LOG_VariableController()) << tr("Store REQUESTID in MAP");
707 m_VarRequestIdToVarIdVarRequestMap.insert(
699 m_VarRequestIdToVarIdVarRequestMap.insert(
708 std::make_pair(varRequestId, std::move(varIdToVarRequestMap)));
700 std::make_pair(varRequestId, std::move(varIdToVarRequestMap)));
709 }
701 }
710 else {
702 else {
711 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
703 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
712 qCDebug(LOG_VariableController()) << tr("Store REQUESTID in EXISTING MAP");
704 qCDebug(LOG_VariableController()) << tr("Store REQUESTID in EXISTING MAP");
713 varIdToVarRequestMap.insert(std::make_pair(varId, varRequest));
705 varIdToVarRequestMap.insert(std::make_pair(varId, varRequest));
714 }
706 }
715 }
707 }
716
708
717 QUuid VariableController::VariableControllerPrivate::acceptVariableRequest(
709 QUuid VariableController::VariableControllerPrivate::acceptVariableRequest(
718 QUuid varId, std::shared_ptr<IDataSeries> dataSeries)
710 QUuid varId, std::shared_ptr<IDataSeries> dataSeries)
719 {
711 {
720 QUuid varRequestId;
712 QUuid varRequestId;
721 auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.find(varId);
713 auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.find(varId);
722 if (varIdToVarRequestIdQueueMapIt != m_VarIdToVarRequestIdQueueMap.cend()) {
714 if (varIdToVarRequestIdQueueMapIt != m_VarIdToVarRequestIdQueueMap.cend()) {
723 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
715 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
724 varRequestId = varRequestIdQueue.front();
716 varRequestId = varRequestIdQueue.front();
725 auto varRequestIdToVarIdVarRequestMapIt
717 auto varRequestIdToVarIdVarRequestMapIt
726 = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
718 = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
727 if (varRequestIdToVarIdVarRequestMapIt != m_VarRequestIdToVarIdVarRequestMap.cend()) {
719 if (varRequestIdToVarIdVarRequestMapIt != m_VarRequestIdToVarIdVarRequestMap.cend()) {
728 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
720 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
729 auto varIdToVarRequestMapIt = varIdToVarRequestMap.find(varId);
721 auto varIdToVarRequestMapIt = varIdToVarRequestMap.find(varId);
730 if (varIdToVarRequestMapIt != varIdToVarRequestMap.cend()) {
722 if (varIdToVarRequestMapIt != varIdToVarRequestMap.cend()) {
731 qCDebug(LOG_VariableController()) << tr("acceptVariableRequest");
723 qCDebug(LOG_VariableController()) << tr("acceptVariableRequest");
732 auto &varRequest = varIdToVarRequestMapIt->second;
724 auto &varRequest = varIdToVarRequestMapIt->second;
733 varRequest.m_DataSeries = dataSeries;
725 varRequest.m_DataSeries = dataSeries;
734 varRequest.m_CanUpdate = true;
726 varRequest.m_CanUpdate = true;
735 }
727 }
736 else {
728 else {
737 qCDebug(LOG_VariableController())
729 qCDebug(LOG_VariableController())
738 << tr("Impossible to acceptVariableRequest of a unknown variable id attached "
730 << tr("Impossible to acceptVariableRequest of a unknown variable id attached "
739 "to a variableRequestId")
731 "to a variableRequestId")
740 << varRequestId << varId;
732 << varRequestId << varId;
741 }
733 }
742 }
734 }
743 else {
735 else {
744 qCCritical(LOG_VariableController())
736 qCCritical(LOG_VariableController())
745 << tr("Impossible to acceptVariableRequest of a unknown variableRequestId")
737 << tr("Impossible to acceptVariableRequest of a unknown variableRequestId")
746 << varRequestId;
738 << varRequestId;
747 }
739 }
748
740
749 varRequestIdQueue.pop_front();
741 varRequestIdQueue.pop_front();
750 if (varRequestIdQueue.empty()) {
742 if (varRequestIdQueue.empty()) {
751 qCDebug(LOG_VariableController())
743 qCDebug(LOG_VariableController())
752 << tr("TORM Erase REQUEST because it has been accepted") << varId;
744 << tr("TORM Erase REQUEST because it has been accepted") << varId;
753 m_VarIdToVarRequestIdQueueMap.erase(varId);
745 m_VarIdToVarRequestIdQueueMap.erase(varId);
754 }
746 }
755 }
747 }
756 else {
748 else {
757 qCCritical(LOG_VariableController())
749 qCCritical(LOG_VariableController())
758 << tr("Impossible to acceptVariableRequest of a unknown variable id") << varId;
750 << tr("Impossible to acceptVariableRequest of a unknown variable id") << varId;
759 }
751 }
760
752
761 return varRequestId;
753 return varRequestId;
762 }
754 }
763
755
764 void VariableController::VariableControllerPrivate::updateVariableRequest(QUuid varRequestId)
756 void VariableController::VariableControllerPrivate::updateVariableRequest(QUuid varRequestId)
765 {
757 {
766
758
767 auto varRequestIdToVarIdVarRequestMapIt = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
759 auto varRequestIdToVarIdVarRequestMapIt = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
768 if (varRequestIdToVarIdVarRequestMapIt != m_VarRequestIdToVarIdVarRequestMap.cend()) {
760 if (varRequestIdToVarIdVarRequestMapIt != m_VarRequestIdToVarIdVarRequestMap.cend()) {
769 bool processVariableUpdate = true;
761 bool processVariableUpdate = true;
770 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
762 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
771 for (auto varIdToVarRequestMapIt = varIdToVarRequestMap.cbegin();
763 for (auto varIdToVarRequestMapIt = varIdToVarRequestMap.cbegin();
772 (varIdToVarRequestMapIt != varIdToVarRequestMap.cend()) && processVariableUpdate;
764 (varIdToVarRequestMapIt != varIdToVarRequestMap.cend()) && processVariableUpdate;
773 ++varIdToVarRequestMapIt) {
765 ++varIdToVarRequestMapIt) {
774 processVariableUpdate &= varIdToVarRequestMapIt->second.m_CanUpdate;
766 processVariableUpdate &= varIdToVarRequestMapIt->second.m_CanUpdate;
775 qCDebug(LOG_VariableController()) << tr("updateVariableRequest")
767 qCDebug(LOG_VariableController()) << tr("updateVariableRequest")
776 << processVariableUpdate;
768 << processVariableUpdate;
777 }
769 }
778
770
779 if (processVariableUpdate) {
771 if (processVariableUpdate) {
780 for (auto varIdToVarRequestMapIt = varIdToVarRequestMap.cbegin();
772 for (auto varIdToVarRequestMapIt = varIdToVarRequestMap.cbegin();
781 varIdToVarRequestMapIt != varIdToVarRequestMap.cend(); ++varIdToVarRequestMapIt) {
773 varIdToVarRequestMapIt != varIdToVarRequestMap.cend(); ++varIdToVarRequestMapIt) {
782 if (auto var = findVariable(varIdToVarRequestMapIt->first)) {
774 if (auto var = findVariable(varIdToVarRequestMapIt->first)) {
783 auto &varRequest = varIdToVarRequestMapIt->second;
775 auto &varRequest = varIdToVarRequestMapIt->second;
784 var->setRange(varRequest.m_RangeRequested);
776 var->setRange(varRequest.m_RangeRequested);
785 var->setCacheRange(varRequest.m_CacheRangeRequested);
777 var->setCacheRange(varRequest.m_CacheRangeRequested);
786 qCDebug(LOG_VariableController()) << tr("1: onDataProvided")
778 qCDebug(LOG_VariableController()) << tr("1: onDataProvided")
787 << varRequest.m_RangeRequested;
779 << varRequest.m_RangeRequested;
788 qCDebug(LOG_VariableController()) << tr("2: onDataProvided")
780 qCDebug(LOG_VariableController()) << tr("2: onDataProvided")
789 << varRequest.m_CacheRangeRequested;
781 << varRequest.m_CacheRangeRequested;
790 var->mergeDataSeries(varRequest.m_DataSeries);
782 var->mergeDataSeries(varRequest.m_DataSeries);
791 qCDebug(LOG_VariableController()) << tr("3: onDataProvided")
783 qCDebug(LOG_VariableController()) << tr("3: onDataProvided")
792 << varRequest.m_DataSeries->range();
784 << varRequest.m_DataSeries->range();
793 qCDebug(LOG_VariableController()) << tr("4: onDataProvided");
785 qCDebug(LOG_VariableController()) << tr("4: onDataProvided");
794
786
795 /// @todo MPL: confirm
787 /// @todo MPL: confirm
796 // Variable update is notified only if there is no pending request for it
788 // Variable update is notified only if there is no pending request for it
797 // if
789 // if
798 // (m_VarIdToVarRequestIdQueueMap.count(varIdToVarRequestMapIt->first)
790 // (m_VarIdToVarRequestIdQueueMap.count(varIdToVarRequestMapIt->first)
799 // == 0) {
791 // == 0) {
800 emit var->updated();
792 emit var->updated();
801 // }
793 // }
802 }
794 }
803 else {
795 else {
804 qCCritical(LOG_VariableController())
796 qCCritical(LOG_VariableController())
805 << tr("Impossible to update data to a null variable");
797 << tr("Impossible to update data to a null variable");
806 }
798 }
807 }
799 }
808
800
809 // cleaning varRequestId
801 // cleaning varRequestId
810 qCDebug(LOG_VariableController()) << tr("0: erase REQUEST in MAP ?")
802 qCDebug(LOG_VariableController()) << tr("0: erase REQUEST in MAP ?")
811 << m_VarRequestIdToVarIdVarRequestMap.size();
803 << m_VarRequestIdToVarIdVarRequestMap.size();
812 m_VarRequestIdToVarIdVarRequestMap.erase(varRequestId);
804 m_VarRequestIdToVarIdVarRequestMap.erase(varRequestId);
813 qCDebug(LOG_VariableController()) << tr("1: erase REQUEST in MAP ?")
805 qCDebug(LOG_VariableController()) << tr("1: erase REQUEST in MAP ?")
814 << m_VarRequestIdToVarIdVarRequestMap.size();
806 << m_VarRequestIdToVarIdVarRequestMap.size();
815 }
807 }
816 }
808 }
817 else {
809 else {
818 qCCritical(LOG_VariableController())
810 qCCritical(LOG_VariableController())
819 << tr("Cannot updateVariableRequest for a unknow varRequestId") << varRequestId;
811 << tr("Cannot updateVariableRequest for a unknow varRequestId") << varRequestId;
820 }
812 }
821 }
813 }
822
814
823 void VariableController::VariableControllerPrivate::cancelVariableRequest(QUuid varRequestId)
815 void VariableController::VariableControllerPrivate::cancelVariableRequest(QUuid varRequestId)
824 {
816 {
825 // cleaning varRequestId
817 // cleaning varRequestId
826 m_VarRequestIdToVarIdVarRequestMap.erase(varRequestId);
818 m_VarRequestIdToVarIdVarRequestMap.erase(varRequestId);
827
819
828 for (auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.begin();
820 for (auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.begin();
829 varIdToVarRequestIdQueueMapIt != m_VarIdToVarRequestIdQueueMap.end();) {
821 varIdToVarRequestIdQueueMapIt != m_VarIdToVarRequestIdQueueMap.end();) {
830 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
822 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
831 varRequestIdQueue.erase(
823 varRequestIdQueue.erase(
832 std::remove(varRequestIdQueue.begin(), varRequestIdQueue.end(), varRequestId),
824 std::remove(varRequestIdQueue.begin(), varRequestIdQueue.end(), varRequestId),
833 varRequestIdQueue.end());
825 varRequestIdQueue.end());
834 if (varRequestIdQueue.empty()) {
826 if (varRequestIdQueue.empty()) {
835 varIdToVarRequestIdQueueMapIt
827 varIdToVarRequestIdQueueMapIt
836 = m_VarIdToVarRequestIdQueueMap.erase(varIdToVarRequestIdQueueMapIt);
828 = m_VarIdToVarRequestIdQueueMap.erase(varIdToVarRequestIdQueueMapIt);
837 }
829 }
838 else {
830 else {
839 ++varIdToVarRequestIdQueueMapIt;
831 ++varIdToVarRequestIdQueueMapIt;
840 }
832 }
841 }
833 }
842 }
834 }
@@ -1,20 +1,19
1
1
2
2
3 tests = [
3 tests = [
4 [['Common/TestStringUtils.cpp'],'test_string_utils','StringUtils test'],
4 [['Common/TestStringUtils.cpp'],'test_string_utils','StringUtils test'],
5 [['Data/TestDataSeries.cpp'],'test_data','DataSeries test'],
5 [['Data/TestDataSeries.cpp'],'test_data','DataSeries test'],
6 [['Data/TestOneDimArrayData.cpp'],'test_1d','One Dim Array test'],
6 [['Data/TestOneDimArrayData.cpp'],'test_1d','One Dim Array test'],
7 [['Data/TestTwoDimArrayData.cpp'],'test_2d','Two Dim Array test'],
7 [['Data/TestTwoDimArrayData.cpp'],'test_2d','Two Dim Array test'],
8 [['DataSource/TestDataSourceController.cpp'],'test_data_source','DataSourceController test'],
8 [['DataSource/TestDataSourceController.cpp'],'test_data_source','DataSourceController test'],
9 [['Variable/TestVariableCacheController.cpp'],'test_variable_cache','VariableCacheController test'],
9 [['Variable/TestVariableCacheController.cpp'],'test_variable_cache','VariableCacheController test'],
10 [['Variable/TestVariable.cpp'],'test_variable','Variable test'],
10 [['Variable/TestVariable.cpp'],'test_variable','Variable test']
11 [['Variable/TestVariableSync.cpp'],'test_variable_sync','Variable synchronization test']
12 ]
11 ]
13
12
14 foreach unit_test : tests
13 foreach unit_test : tests
15 test_moc_files = qt5.preprocess(moc_sources : unit_test[0])
14 test_moc_files = qt5.preprocess(moc_sources : unit_test[0])
16 test_exe = executable(unit_test[1],unit_test[0] , test_moc_files,
15 test_exe = executable(unit_test[1],unit_test[0] , test_moc_files,
17 dependencies : [sciqlop_core, qt5test])
16 dependencies : [sciqlop_core, qt5test])
18 test(unit_test[2], test_exe, args: ['-teamcity', '-o', '@0@.teamcity.txt'.format(unit_test[1])])
17 test(unit_test[2], test_exe, args: ['-teamcity', '-o', '@0@.teamcity.txt'.format(unit_test[1])])
19 endforeach
18 endforeach
20
19
@@ -1,32 +1,31
1 #ifndef SCIQLOP_RENAMEVARIABLEDIALOG_H
1 #ifndef SCIQLOP_RENAMEVARIABLEDIALOG_H
2 #define SCIQLOP_RENAMEVARIABLEDIALOG_H
2 #define SCIQLOP_RENAMEVARIABLEDIALOG_H
3
3
4 #include <QDialog>
4 #include <QDialog>
5
5
6 namespace Ui {
6 namespace Ui {
7 class RenameVariableDialog;
7 class RenameVariableDialog;
8 } // Ui
8 } // Ui
9
9
10 /**
10 /**
11 * @brief The RenameVariableDialog class represents the dialog to rename a variable
11 * @brief The RenameVariableDialog class represents the dialog to rename a variable
12 */
12 */
13 class RenameVariableDialog : public QDialog {
13 class RenameVariableDialog : public QDialog {
14 Q_OBJECT
15 public:
14 public:
16 explicit RenameVariableDialog(const QString &defaultName,
15 explicit RenameVariableDialog(const QString &defaultName,
17 const QVector<QString> &forbiddenNames,
16 const QVector<QString> &forbiddenNames,
18 QWidget *parent = nullptr);
17 QWidget *parent = nullptr);
19 virtual ~RenameVariableDialog() noexcept;
18 virtual ~RenameVariableDialog() noexcept;
20
19
21 QString name() const noexcept;
20 QString name() const noexcept;
22
21
23 public slots:
22 public slots:
24 void accept() override;
23 void accept() override;
25
24
26 private:
25 private:
27 Ui::RenameVariableDialog *ui;
26 Ui::RenameVariableDialog *ui;
28 QString m_DefaultName;
27 QString m_DefaultName;
29 QVector<QString> m_ForbiddenNames;
28 QVector<QString> m_ForbiddenNames;
30 };
29 };
31
30
32 #endif // SCIQLOP_RENAMEVARIABLEDIALOG_H
31 #endif // SCIQLOP_RENAMEVARIABLEDIALOG_H
@@ -1,80 +1,77
1
1
2 gui_moc_headers = [
2 gui_moc_headers = [
3 'include/DataSource/DataSourceWidget.h',
3 'include/DataSource/DataSourceWidget.h',
4 'include/Settings/SqpSettingsDialog.h',
4 'include/Settings/SqpSettingsDialog.h',
5 'include/Settings/SqpSettingsGeneralWidget.h',
5 'include/Settings/SqpSettingsGeneralWidget.h',
6 'include/SidePane/SqpSidePane.h',
6 'include/SidePane/SqpSidePane.h',
7 'include/SqpApplication.h',
7 'include/SqpApplication.h',
8 'include/TimeWidget/TimeWidget.h',
8 'include/TimeWidget/TimeWidget.h',
9 'include/Variable/VariableInspectorWidget.h',
9 'include/Variable/VariableInspectorWidget.h',
10 'include/Variable/RenameVariableDialog.h',
11 'include/Visualization/qcustomplot.h',
10 'include/Visualization/qcustomplot.h',
12 'include/Visualization/VisualizationGraphWidget.h',
11 'include/Visualization/VisualizationGraphWidget.h',
13 'include/Visualization/VisualizationTabWidget.h',
12 'include/Visualization/VisualizationTabWidget.h',
14 'include/Visualization/VisualizationWidget.h',
13 'include/Visualization/VisualizationWidget.h',
15 'include/Visualization/VisualizationZoneWidget.h'
14 'include/Visualization/VisualizationZoneWidget.h'
16 ]
15 ]
17
16
18 gui_ui_files = [
17 gui_ui_files = [
19 'ui/DataSource/DataSourceWidget.ui',
18 'ui/DataSource/DataSourceWidget.ui',
20 'ui/Settings/SqpSettingsDialog.ui',
19 'ui/Settings/SqpSettingsDialog.ui',
21 'ui/Settings/SqpSettingsGeneralWidget.ui',
20 'ui/Settings/SqpSettingsGeneralWidget.ui',
22 'ui/SidePane/SqpSidePane.ui',
21 'ui/SidePane/SqpSidePane.ui',
23 'ui/TimeWidget/TimeWidget.ui',
22 'ui/TimeWidget/TimeWidget.ui',
24 'ui/Variable/VariableInspectorWidget.ui',
23 'ui/Variable/VariableInspectorWidget.ui',
25 'ui/Variable/RenameVariableDialog.ui',
26 'ui/Variable/VariableMenuHeaderWidget.ui',
24 'ui/Variable/VariableMenuHeaderWidget.ui',
27 'ui/Visualization/VisualizationGraphWidget.ui',
25 'ui/Visualization/VisualizationGraphWidget.ui',
28 'ui/Visualization/VisualizationTabWidget.ui',
26 'ui/Visualization/VisualizationTabWidget.ui',
29 'ui/Visualization/VisualizationWidget.ui',
27 'ui/Visualization/VisualizationWidget.ui',
30 'ui/Visualization/VisualizationZoneWidget.ui'
28 'ui/Visualization/VisualizationZoneWidget.ui'
31 ]
29 ]
32
30
33 gui_qresources = ['resources/sqpguiresources.qrc']
31 gui_qresources = ['resources/sqpguiresources.qrc']
34
32
35 gui_moc_files = qt5.preprocess(moc_headers : gui_moc_headers,
33 gui_moc_files = qt5.preprocess(moc_headers : gui_moc_headers,
36 ui_files : gui_ui_files,
34 ui_files : gui_ui_files,
37 qresources : gui_qresources)
35 qresources : gui_qresources)
38
36
39 gui_sources = [
37 gui_sources = [
40 'src/SqpApplication.cpp',
38 'src/SqpApplication.cpp',
41 'src/Common/ColorUtils.cpp',
39 'src/Common/ColorUtils.cpp',
42 'src/DataSource/DataSourceTreeWidgetItem.cpp',
40 'src/DataSource/DataSourceTreeWidgetItem.cpp',
43 'src/DataSource/DataSourceTreeWidgetHelper.cpp',
41 'src/DataSource/DataSourceTreeWidgetHelper.cpp',
44 'src/DataSource/DataSourceWidget.cpp',
42 'src/DataSource/DataSourceWidget.cpp',
45 'src/Settings/SqpSettingsDialog.cpp',
43 'src/Settings/SqpSettingsDialog.cpp',
46 'src/Settings/SqpSettingsGeneralWidget.cpp',
44 'src/Settings/SqpSettingsGeneralWidget.cpp',
47 'src/SidePane/SqpSidePane.cpp',
45 'src/SidePane/SqpSidePane.cpp',
48 'src/TimeWidget/TimeWidget.cpp',
46 'src/TimeWidget/TimeWidget.cpp',
49 'src/Variable/VariableInspectorWidget.cpp',
47 'src/Variable/VariableInspectorWidget.cpp',
50 'src/Variable/VariableMenuHeaderWidget.cpp',
48 'src/Variable/VariableMenuHeaderWidget.cpp',
51 'src/Variable/RenameVariableDialog.cpp',
52 'src/Visualization/VisualizationGraphHelper.cpp',
49 'src/Visualization/VisualizationGraphHelper.cpp',
53 'src/Visualization/VisualizationGraphRenderingDelegate.cpp',
50 'src/Visualization/VisualizationGraphRenderingDelegate.cpp',
54 'src/Visualization/VisualizationGraphWidget.cpp',
51 'src/Visualization/VisualizationGraphWidget.cpp',
55 'src/Visualization/VisualizationTabWidget.cpp',
52 'src/Visualization/VisualizationTabWidget.cpp',
56 'src/Visualization/VisualizationWidget.cpp',
53 'src/Visualization/VisualizationWidget.cpp',
57 'src/Visualization/VisualizationZoneWidget.cpp',
54 'src/Visualization/VisualizationZoneWidget.cpp',
58 'src/Visualization/qcustomplot.cpp',
55 'src/Visualization/qcustomplot.cpp',
59 'src/Visualization/QCustomPlotSynchronizer.cpp',
56 'src/Visualization/QCustomPlotSynchronizer.cpp',
60 'src/Visualization/operations/FindVariableOperation.cpp',
57 'src/Visualization/operations/FindVariableOperation.cpp',
61 'src/Visualization/operations/GenerateVariableMenuOperation.cpp',
58 'src/Visualization/operations/GenerateVariableMenuOperation.cpp',
62 'src/Visualization/operations/MenuBuilder.cpp',
59 'src/Visualization/operations/MenuBuilder.cpp',
63 'src/Visualization/operations/RemoveVariableOperation.cpp',
60 'src/Visualization/operations/RemoveVariableOperation.cpp',
64 'src/Visualization/operations/RescaleAxeOperation.cpp'
61 'src/Visualization/operations/RescaleAxeOperation.cpp'
65 ]
62 ]
66
63
67 gui_inc = include_directories(['include'])
64 gui_inc = include_directories(['include'])
68
65
69 sciqlop_gui_lib = library('sciqlopgui',
66 sciqlop_gui_lib = library('sciqlopgui',
70 gui_sources,
67 gui_sources,
71 gui_moc_files,
68 gui_moc_files,
72 include_directories : [gui_inc],
69 include_directories : [gui_inc],
73 dependencies : [ qt5printsupport, qt5gui, qt5widgets, qt5svg, sciqlop_core],
70 dependencies : [ qt5printsupport, qt5gui, qt5widgets, qt5svg, sciqlop_core],
74 install : true
71 install : true
75 )
72 )
76
73
77 sciqlop_gui = declare_dependency(link_with : sciqlop_gui_lib,
74 sciqlop_gui = declare_dependency(link_with : sciqlop_gui_lib,
78 include_directories : gui_inc,
75 include_directories : gui_inc,
79 dependencies : [qt5printsupport, qt5gui, qt5widgets, qt5svg, sciqlop_core])
76 dependencies : [qt5printsupport, qt5gui, qt5widgets, qt5svg, sciqlop_core])
80
77
@@ -1,239 +1,228
1 #include <Variable/RenameVariableDialog.h>
1 #include <Variable/RenameVariableDialog.h>
2 #include <Variable/Variable.h>
2 #include <Variable/Variable.h>
3 #include <Variable/VariableController.h>
3 #include <Variable/VariableController.h>
4 #include <Variable/VariableInspectorWidget.h>
4 #include <Variable/VariableInspectorWidget.h>
5 #include <Variable/VariableMenuHeaderWidget.h>
5 #include <Variable/VariableMenuHeaderWidget.h>
6 #include <Variable/VariableModel.h>
6 #include <Variable/VariableModel.h>
7
7
8 #include <ui_VariableInspectorWidget.h>
8 #include <ui_VariableInspectorWidget.h>
9
9
10 #include <QMouseEvent>
10 #include <QMouseEvent>
11 #include <QSortFilterProxyModel>
11 #include <QSortFilterProxyModel>
12 #include <QStyledItemDelegate>
12 #include <QStyledItemDelegate>
13 #include <QWidgetAction>
13 #include <QWidgetAction>
14
14
15 #include <SqpApplication.h>
15 #include <SqpApplication.h>
16
16
17 Q_LOGGING_CATEGORY(LOG_VariableInspectorWidget, "VariableInspectorWidget")
17 Q_LOGGING_CATEGORY(LOG_VariableInspectorWidget, "VariableInspectorWidget")
18
18
19
19
20 class QProgressBarItemDelegate : public QStyledItemDelegate {
20 class QProgressBarItemDelegate : public QStyledItemDelegate {
21
21
22 public:
22 public:
23 QProgressBarItemDelegate(QObject *parent) : QStyledItemDelegate{parent} {}
23 QProgressBarItemDelegate(QObject *parent) : QStyledItemDelegate{parent} {}
24
24
25 void paint(QPainter *painter, const QStyleOptionViewItem &option,
25 void paint(QPainter *painter, const QStyleOptionViewItem &option,
26 const QModelIndex &index) const
26 const QModelIndex &index) const
27 {
27 {
28 auto data = index.data(Qt::DisplayRole);
28 auto data = index.data(Qt::DisplayRole);
29 auto progressData = index.data(VariableRoles::ProgressRole);
29 auto progressData = index.data(VariableRoles::ProgressRole);
30 if (data.isValid() && progressData.isValid()) {
30 if (data.isValid() && progressData.isValid()) {
31 auto name = data.value<QString>();
31 auto name = data.value<QString>();
32 auto progress = progressData.value<double>();
32 auto progress = progressData.value<double>();
33 if (progress > 0) {
33 if (progress > 0) {
34 auto cancelButtonWidth = 20;
34 auto cancelButtonWidth = 20;
35 auto progressBarOption = QStyleOptionProgressBar{};
35 auto progressBarOption = QStyleOptionProgressBar{};
36 auto progressRect = option.rect;
36 auto progressRect = option.rect;
37 progressRect.setWidth(progressRect.width() - cancelButtonWidth);
37 progressRect.setWidth(progressRect.width() - cancelButtonWidth);
38 progressBarOption.rect = progressRect;
38 progressBarOption.rect = progressRect;
39 progressBarOption.minimum = 0;
39 progressBarOption.minimum = 0;
40 progressBarOption.maximum = 100;
40 progressBarOption.maximum = 100;
41 progressBarOption.progress = progress;
41 progressBarOption.progress = progress;
42 progressBarOption.text
42 progressBarOption.text
43 = QString("%1 %2").arg(name).arg(QString::number(progress, 'f', 2) + "%");
43 = QString("%1 %2").arg(name).arg(QString::number(progress, 'f', 2) + "%");
44 progressBarOption.textVisible = true;
44 progressBarOption.textVisible = true;
45 progressBarOption.textAlignment = Qt::AlignCenter;
45 progressBarOption.textAlignment = Qt::AlignCenter;
46
46
47
47
48 QApplication::style()->drawControl(QStyle::CE_ProgressBar, &progressBarOption,
48 QApplication::style()->drawControl(QStyle::CE_ProgressBar, &progressBarOption,
49 painter);
49 painter);
50
50
51 // Cancel button
51 // Cancel button
52 auto buttonRect = QRect(progressRect.right(), option.rect.top(), cancelButtonWidth,
52 auto buttonRect = QRect(progressRect.right(), option.rect.top(), cancelButtonWidth,
53 option.rect.height());
53 option.rect.height());
54 auto buttonOption = QStyleOptionButton{};
54 auto buttonOption = QStyleOptionButton{};
55 buttonOption.rect = buttonRect;
55 buttonOption.rect = buttonRect;
56 buttonOption.text = "X";
56 buttonOption.text = "X";
57
57
58 QApplication::style()->drawControl(QStyle::CE_PushButton, &buttonOption, painter);
58 QApplication::style()->drawControl(QStyle::CE_PushButton, &buttonOption, painter);
59 }
59 }
60 else {
60 else {
61 QStyledItemDelegate::paint(painter, option, index);
61 QStyledItemDelegate::paint(painter, option, index);
62 }
62 }
63 }
63 }
64 else {
64 else {
65 QStyledItemDelegate::paint(painter, option, index);
65 QStyledItemDelegate::paint(painter, option, index);
66 }
66 }
67 }
67 }
68
68
69 bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option,
69 bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option,
70 const QModelIndex &index)
70 const QModelIndex &index)
71 {
71 {
72 if (event->type() == QEvent::MouseButtonRelease) {
72 if (event->type() == QEvent::MouseButtonRelease) {
73 auto data = index.data(Qt::DisplayRole);
73 auto data = index.data(Qt::DisplayRole);
74 auto progressData = index.data(VariableRoles::ProgressRole);
74 auto progressData = index.data(VariableRoles::ProgressRole);
75 if (data.isValid() && progressData.isValid()) {
75 if (data.isValid() && progressData.isValid()) {
76 auto cancelButtonWidth = 20;
76 auto cancelButtonWidth = 20;
77 auto progressRect = option.rect;
77 auto progressRect = option.rect;
78 progressRect.setWidth(progressRect.width() - cancelButtonWidth);
78 progressRect.setWidth(progressRect.width() - cancelButtonWidth);
79 // Cancel button
79 // Cancel button
80 auto buttonRect = QRect(progressRect.right(), option.rect.top(), cancelButtonWidth,
80 auto buttonRect = QRect(progressRect.right(), option.rect.top(), cancelButtonWidth,
81 option.rect.height());
81 option.rect.height());
82
82
83 auto e = (QMouseEvent *)event;
83 auto e = (QMouseEvent *)event;
84 auto clickX = e->x();
84 auto clickX = e->x();
85 auto clickY = e->y();
85 auto clickY = e->y();
86
86
87 auto x = buttonRect.left(); // the X coordinate
87 auto x = buttonRect.left(); // the X coordinate
88 auto y = buttonRect.top(); // the Y coordinate
88 auto y = buttonRect.top(); // the Y coordinate
89 auto w = buttonRect.width(); // button width
89 auto w = buttonRect.width(); // button width
90 auto h = buttonRect.height(); // button height
90 auto h = buttonRect.height(); // button height
91
91
92 if (clickX > x && clickX < x + w) {
92 if (clickX > x && clickX < x + w) {
93 if (clickY > y && clickY < y + h) {
93 if (clickY > y && clickY < y + h) {
94 auto variableModel = sqpApp->variableController().variableModel();
94 auto variableModel = sqpApp->variableController().variableModel();
95 variableModel->abortProgress(index);
95 variableModel->abortProgress(index);
96 }
96 }
97 return true;
98 }
97 }
99 else {
98 else {
100 return QStyledItemDelegate::editorEvent(event, model, option, index);
99 QStyledItemDelegate::editorEvent(event, model, option, index);
101 }
100 }
102 }
101 }
103 else {
102 else {
104 return QStyledItemDelegate::editorEvent(event, model, option, index);
103 QStyledItemDelegate::editorEvent(event, model, option, index);
105 }
104 }
106 }
105 }
107 else {
106 else {
108 return QStyledItemDelegate::editorEvent(event, model, option, index);
107 QStyledItemDelegate::editorEvent(event, model, option, index);
109 }
108 }
110
111
112 return QStyledItemDelegate::editorEvent(event, model, option, index);
113 }
109 }
114 };
110 };
115
111
116 VariableInspectorWidget::VariableInspectorWidget(QWidget *parent)
112 VariableInspectorWidget::VariableInspectorWidget(QWidget *parent)
117 : QWidget{parent},
113 : QWidget{parent},
118 ui{new Ui::VariableInspectorWidget},
114 ui{new Ui::VariableInspectorWidget},
119 m_ProgressBarItemDelegate{new QProgressBarItemDelegate{this}}
115 m_ProgressBarItemDelegate{new QProgressBarItemDelegate{this}}
120 {
116 {
121 ui->setupUi(this);
117 ui->setupUi(this);
122
118
123 // Sets model for table
119 // Sets model for table
124 // auto sortFilterModel = new QSortFilterProxyModel{this};
120 // auto sortFilterModel = new QSortFilterProxyModel{this};
125 // sortFilterModel->setSourceModel(sqpApp->variableController().variableModel());
121 // sortFilterModel->setSourceModel(sqpApp->variableController().variableModel());
126
122
127 auto variableModel = sqpApp->variableController().variableModel();
123 auto variableModel = sqpApp->variableController().variableModel();
128 ui->tableView->setModel(variableModel);
124 ui->tableView->setModel(variableModel);
129
125
130 // Adds extra signal/slot between view and model, so the view can be updated instantly when
126 // Adds extra signal/slot between view and model, so the view can be updated instantly when
131 // there is a change of data in the model
127 // there is a change of data in the model
132 connect(variableModel, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), this,
128 connect(variableModel, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), this,
133 SLOT(refresh()));
129 SLOT(refresh()));
134
130
135 ui->tableView->setSelectionModel(sqpApp->variableController().variableSelectionModel());
131 ui->tableView->setSelectionModel(sqpApp->variableController().variableSelectionModel());
136 ui->tableView->setItemDelegateForColumn(0, m_ProgressBarItemDelegate);
132 ui->tableView->setItemDelegateForColumn(0, m_ProgressBarItemDelegate);
137
133
138 // Fixes column sizes
134 // Fixes column sizes
139 auto model = ui->tableView->model();
135 auto model = ui->tableView->model();
140 const auto count = model->columnCount();
136 const auto count = model->columnCount();
141 for (auto i = 0; i < count; ++i) {
137 for (auto i = 0; i < count; ++i) {
142 ui->tableView->setColumnWidth(
138 ui->tableView->setColumnWidth(
143 i, model->headerData(i, Qt::Horizontal, Qt::SizeHintRole).toSize().width());
139 i, model->headerData(i, Qt::Horizontal, Qt::SizeHintRole).toSize().width());
144 }
140 }
145
141
146 // Sets selection options
142 // Sets selection options
147 ui->tableView->setSelectionBehavior(QTableView::SelectRows);
143 ui->tableView->setSelectionBehavior(QTableView::SelectRows);
148 ui->tableView->setSelectionMode(QTableView::ExtendedSelection);
144 ui->tableView->setSelectionMode(QTableView::ExtendedSelection);
149
145
150 // Connection to show a menu when right clicking on the tree
146 // Connection to show a menu when right clicking on the tree
151 ui->tableView->setContextMenuPolicy(Qt::CustomContextMenu);
147 ui->tableView->setContextMenuPolicy(Qt::CustomContextMenu);
152 connect(ui->tableView, &QTableView::customContextMenuRequested, this,
148 connect(ui->tableView, &QTableView::customContextMenuRequested, this,
153 &VariableInspectorWidget::onTableMenuRequested);
149 &VariableInspectorWidget::onTableMenuRequested);
154 }
150 }
155
151
156 VariableInspectorWidget::~VariableInspectorWidget()
152 VariableInspectorWidget::~VariableInspectorWidget()
157 {
153 {
158 delete ui;
154 delete ui;
159 }
155 }
160
156
161 void VariableInspectorWidget::onTableMenuRequested(const QPoint &pos) noexcept
157 void VariableInspectorWidget::onTableMenuRequested(const QPoint &pos) noexcept
162 {
158 {
163 auto selectedRows = ui->tableView->selectionModel()->selectedRows();
159 auto selectedRows = ui->tableView->selectionModel()->selectedRows();
164
160
165 // Gets the model to retrieve the underlying selected variables
161 // Gets the model to retrieve the underlying selected variables
166 auto model = sqpApp->variableController().variableModel();
162 auto model = sqpApp->variableController().variableModel();
167 auto selectedVariables = QVector<std::shared_ptr<Variable> >{};
163 auto selectedVariables = QVector<std::shared_ptr<Variable> >{};
168 for (const auto &selectedRow : qAsConst(selectedRows)) {
164 for (const auto &selectedRow : qAsConst(selectedRows)) {
169 if (auto selectedVariable = model->variable(selectedRow.row())) {
165 if (auto selectedVariable = model->variable(selectedRow.row())) {
170 selectedVariables.push_back(selectedVariable);
166 selectedVariables.push_back(selectedVariable);
171 }
167 }
172 }
168 }
173
169
174 QMenu tableMenu{};
170 QMenu tableMenu{};
175
171
176 // Emits a signal so that potential receivers can populate the menu before displaying it
172 // Emits a signal so that potential receivers can populate the menu before displaying it
177 emit tableMenuAboutToBeDisplayed(&tableMenu, selectedVariables);
173 emit tableMenuAboutToBeDisplayed(&tableMenu, selectedVariables);
178
174
179 // Adds menu-specific actions
175 // Adds menu-specific actions
180 if (!selectedVariables.isEmpty()) {
176 if (!selectedVariables.isEmpty()) {
181 tableMenu.addSeparator();
177 tableMenu.addSeparator();
182
178
183 // 'Rename' and 'Duplicate' actions (only if one variable selected)
179 // 'Rename' and 'Duplicate' actions (only if one variable selected)
184 if (selectedVariables.size() == 1) {
180 if (selectedVariables.size() == 1) {
185 auto selectedVariable = selectedVariables.front();
181 auto selectedVariable = selectedVariables.front();
186
182
187 auto duplicateFun = [varW = std::weak_ptr<Variable>(selectedVariable)]()
183 auto duplicateFun = [&selectedVariable]() {
188 {
184 sqpApp->variableController().cloneVariable(selectedVariable);
189 if (auto var = varW.lock()) {
190 sqpApp->variableController().cloneVariable(var);
191 }
192 };
185 };
193
186
194 tableMenu.addAction(tr("Duplicate"), duplicateFun);
187 tableMenu.addAction(tr("Duplicate"), duplicateFun);
195
188
196 auto renameFun = [ varW = std::weak_ptr<Variable>(selectedVariable), &model, this ]()
189 auto renameFun = [&selectedVariable, &model, this]() {
197 {
190 // Generates forbidden names (names associated to existing variables)
198 if (auto var = varW.lock()) {
191 auto allVariables = model->variables();
199 // Generates forbidden names (names associated to existing variables)
192 auto forbiddenNames = QVector<QString>(allVariables.size());
200 auto allVariables = model->variables();
193 std::transform(allVariables.cbegin(), allVariables.cend(), forbiddenNames.begin(),
201 auto forbiddenNames = QVector<QString>(allVariables.size());
194 [](const auto &variable) { return variable->name(); });
202 std::transform(allVariables.cbegin(), allVariables.cend(),
195
203 forbiddenNames.begin(),
196 RenameVariableDialog dialog{selectedVariable->name(), forbiddenNames, this};
204 [](const auto &variable) { return variable->name(); });
197 if (dialog.exec() == QDialog::Accepted) {
205
198 selectedVariable->setName(dialog.name());
206 RenameVariableDialog dialog{var->name(), forbiddenNames, this};
207 if (dialog.exec() == QDialog::Accepted) {
208 var->setName(dialog.name());
209 }
210 }
199 }
211 };
200 };
212
201
213 tableMenu.addAction(tr("Rename..."), renameFun);
202 tableMenu.addAction(tr("Rename..."), renameFun);
214 }
203 }
215
204
216 // 'Delete' action
205 // 'Delete' action
217 auto deleteFun = [&selectedVariables]() {
206 auto deleteFun = [&selectedVariables]() {
218 sqpApp->variableController().deleteVariables(selectedVariables);
207 sqpApp->variableController().deleteVariables(selectedVariables);
219 };
208 };
220
209
221 tableMenu.addAction(QIcon{":/icones/delete.png"}, tr("Delete"), deleteFun);
210 tableMenu.addAction(QIcon{":/icones/delete.png"}, tr("Delete"), deleteFun);
222 }
211 }
223
212
224 if (!tableMenu.isEmpty()) {
213 if (!tableMenu.isEmpty()) {
225 // Generates menu header (inserted before first action)
214 // Generates menu header (inserted before first action)
226 auto firstAction = tableMenu.actions().first();
215 auto firstAction = tableMenu.actions().first();
227 auto headerAction = new QWidgetAction{&tableMenu};
216 auto headerAction = new QWidgetAction{&tableMenu};
228 headerAction->setDefaultWidget(new VariableMenuHeaderWidget{selectedVariables, &tableMenu});
217 headerAction->setDefaultWidget(new VariableMenuHeaderWidget{selectedVariables, &tableMenu});
229 tableMenu.insertAction(firstAction, headerAction);
218 tableMenu.insertAction(firstAction, headerAction);
230
219
231 // Displays menu
220 // Displays menu
232 tableMenu.exec(QCursor::pos());
221 tableMenu.exec(QCursor::pos());
233 }
222 }
234 }
223 }
235
224
236 void VariableInspectorWidget::refresh() noexcept
225 void VariableInspectorWidget::refresh() noexcept
237 {
226 {
238 ui->tableView->viewport()->update();
227 ui->tableView->viewport()->update();
239 }
228 }
@@ -1,73 +1,72
1
1
2 amdaplugin_moc_headers = [
2 amdaplugin_moc_headers = [
3 'include/AmdaPlugin.h',
3 'include/AmdaPlugin.h'
4 'include/AmdaProvider.h'
5 ]
4 ]
6
5
7 amdaplugin_sources = [
6 amdaplugin_sources = [
8 'src/AmdaDefs.cpp',
7 'src/AmdaDefs.cpp',
9 'src/AmdaParser.cpp',
8 'src/AmdaParser.cpp',
10 'src/AmdaPlugin.cpp',
9 'src/AmdaPlugin.cpp',
11 'src/AmdaProvider.cpp',
10 'src/AmdaProvider.cpp',
12 'src/AmdaResultParser.cpp'
11 'src/AmdaResultParser.cpp'
13 ]
12 ]
14
13
15 amdaplugin_ui_files = []
14 amdaplugin_ui_files = []
16 amdaplugin_resources_files = [
15 amdaplugin_resources_files = [
17 'resources/amdaresources.qrc'
16 'resources/amdaresources.qrc'
18 ]
17 ]
19
18
20 amdaplugin_inc = include_directories(['include', '../../plugin/include'])
19 amdaplugin_inc = include_directories(['include', '../../plugin/include'])
21
20
22 moc_gen = generator(moc,
21 moc_gen = generator(moc,
23 output : 'moc_@BASENAME@.cpp',
22 output : 'moc_@BASENAME@.cpp',
24 arguments : ['@INPUT@',
23 arguments : ['@INPUT@',
25 '-DPLUGIN_JSON_FILE_PATH="'+meson.source_root()+'/plugins/amda/resources/amda.json"',
24 '-DPLUGIN_JSON_FILE_PATH="'+meson.source_root()+'/plugins/amda/resources/amda.json"',
26 '-I', meson.current_source_dir()+'/include',
25 '-I', meson.current_source_dir()+'/include',
27 '-I', meson.current_source_dir()+'/../../plugin/include',
26 '-I', meson.current_source_dir()+'/../../plugin/include',
28 '-o', '@OUTPUT@'])
27 '-o', '@OUTPUT@'])
29
28
30 rcc_gen = generator(rcc,
29 rcc_gen = generator(rcc,
31 output : 'qrc_@BASENAME@.cpp',
30 output : 'qrc_@BASENAME@.cpp',
32 arguments : ['--name=@BASENAME@"',
31 arguments : ['--name=@BASENAME@"',
33 '--output',
32 '--output',
34 '@OUTPUT@',
33 '@OUTPUT@',
35 '@INPUT@'])
34 '@INPUT@'])
36
35
37 amdaplugin_moc_plugin_files = moc_gen.process(amdaplugin_moc_headers)
36 amdaplugin_moc_plugin_files = moc_gen.process(amdaplugin_moc_headers)
38
37
39 amdaplugin_rcc_plugin_files = rcc_gen.process(amdaplugin_resources_files)
38 amdaplugin_rcc_plugin_files = rcc_gen.process(amdaplugin_resources_files)
40
39
41 #amdaplugin_rcc_plugin_files = qt5.preprocess(
40 #amdaplugin_rcc_plugin_files = qt5.preprocess(
42 # qresources : amdaplugin_resources_files)
41 # qresources : amdaplugin_resources_files)
43
42
44 amdaplugin_moc_files = qt5.preprocess(
43 amdaplugin_moc_files = qt5.preprocess(
45 ui_files : amdaplugin_ui_files)
44 ui_files : amdaplugin_ui_files)
46
45
47 sciqlop_amdaplugin = library('amdaplugin',
46 sciqlop_amdaplugin = library('amdaplugin',
48 amdaplugin_sources,
47 amdaplugin_sources,
49 amdaplugin_moc_files,
48 amdaplugin_moc_files,
50 amdaplugin_rcc_plugin_files,
49 amdaplugin_rcc_plugin_files,
51 amdaplugin_moc_plugin_files,
50 amdaplugin_moc_plugin_files,
52 cpp_args : ['-DAMDA_LIB','-DQT_PLUGIN'],
51 cpp_args : ['-DAMDA_LIB','-DQT_PLUGIN'],
53 include_directories : [amdaplugin_inc],
52 include_directories : [amdaplugin_inc],
54 dependencies : [sciqlop_core, sciqlop_gui],
53 dependencies : [sciqlop_core, sciqlop_gui],
55 install : true
54 install : true
56 )
55 )
57
56
58
57
59 tests = [
58 tests = [
60 [['tests/TestAmdaParser.cpp'],'test_amda_parser','AMDA parser test'],
59 [['tests/TestAmdaParser.cpp'],'test_amda_parser','AMDA parser test'],
61 [['tests/TestAmdaResultParser.cpp'],'test_amda_result_parser','AMDA result parser test'],
60 [['tests/TestAmdaResultParser.cpp'],'test_amda_result_parser','AMDA result parser test'],
62 [['tests/TestAmdaAcquisition.cpp'],'test_amda_acquisition','AMDA Acquisition test']
61 [['tests/TestAmdaAcquisition.cpp'],'test_amda_acquisition','AMDA Acquisition test']
63 ]
62 ]
64
63
65 foreach unit_test : tests
64 foreach unit_test : tests
66 test_moc_files = qt5.preprocess(moc_sources : unit_test[0])
65 test_moc_files = qt5.preprocess(moc_sources : unit_test[0])
67 test_exe = executable(unit_test[1],unit_test[0] , test_moc_files,
66 test_exe = executable(unit_test[1],unit_test[0] , test_moc_files,
68 link_with : [sciqlop_amdaplugin],
67 link_with : [sciqlop_amdaplugin],
69 include_directories : [amdaplugin_inc],
68 include_directories : [amdaplugin_inc],
70 cpp_args : ['-DAMDA_TESTS_RESOURCES_DIR="'+meson.current_source_dir()+'/tests-resources"'],
69 cpp_args : ['-DAMDA_TESTS_RESOURCES_DIR="'+meson.current_source_dir()+'/tests-resources"'],
71 dependencies : [sciqlop_core, sciqlop_gui, qt5test])
70 dependencies : [sciqlop_core, sciqlop_gui, qt5test])
72 test(unit_test[2], test_exe, args: ['-teamcity', '-o', '@0@.teamcity.txt'.format(unit_test[1])], timeout: 3 * 60)
71 test(unit_test[2], test_exe, args: ['-teamcity', '-o', '@0@.teamcity.txt'.format(unit_test[1])], timeout: 3 * 60)
73 endforeach
72 endforeach
@@ -1,284 +1,283
1 #include "AmdaProvider.h"
1 #include "AmdaProvider.h"
2 #include "AmdaDefs.h"
2 #include "AmdaDefs.h"
3 #include "AmdaResultParser.h"
3 #include "AmdaResultParser.h"
4
4
5 #include <Common/DateUtils.h>
5 #include <Common/DateUtils.h>
6 #include <Data/DataProviderParameters.h>
6 #include <Data/DataProviderParameters.h>
7 #include <Network/NetworkController.h>
7 #include <Network/NetworkController.h>
8 #include <SqpApplication.h>
8 #include <SqpApplication.h>
9 #include <Variable/Variable.h>
9 #include <Variable/Variable.h>
10
10
11 #include <QNetworkAccessManager>
11 #include <QNetworkAccessManager>
12 #include <QNetworkReply>
12 #include <QNetworkReply>
13 #include <QTemporaryFile>
13 #include <QTemporaryFile>
14 #include <QThread>
14 #include <QThread>
15
15
16 Q_LOGGING_CATEGORY(LOG_AmdaProvider, "AmdaProvider")
16 Q_LOGGING_CATEGORY(LOG_AmdaProvider, "AmdaProvider")
17
17
18 namespace {
18 namespace {
19
19
20 /// URL format for a request on AMDA server. The parameters are as follows:
20 /// URL format for a request on AMDA server. The parameters are as follows:
21 /// - %1: start date
21 /// - %1: start date
22 /// - %2: end date
22 /// - %2: end date
23 /// - %3: parameter id
23 /// - %3: parameter id
24 /// Old url: http://amda.irap.omp.eu/php/rest/
25 const auto AMDA_URL_FORMAT = QStringLiteral(
24 const auto AMDA_URL_FORMAT = QStringLiteral(
26 "http://amdatest.irap.omp.eu/php/rest/"
25 "http://amda.irap.omp.eu/php/rest/"
27 "getParameter.php?startTime=%1&stopTime=%2&parameterID=%3&outputFormat=ASCII&"
26 "getParameter.php?startTime=%1&stopTime=%2&parameterID=%3&outputFormat=ASCII&"
28 "timeFormat=ISO8601&gzip=0");
27 "timeFormat=ISO8601&gzip=0");
29
28
30 /// Dates format passed in the URL (e.g 2013-09-23T09:00)
29 /// Dates format passed in the URL (e.g 2013-09-23T09:00)
31 const auto AMDA_TIME_FORMAT = QStringLiteral("yyyy-MM-ddThh:mm:ss");
30 const auto AMDA_TIME_FORMAT = QStringLiteral("yyyy-MM-ddThh:mm:ss");
32
31
33 /// Formats a time to a date that can be passed in URL
32 /// Formats a time to a date that can be passed in URL
34 QString dateFormat(double sqpRange) noexcept
33 QString dateFormat(double sqpRange) noexcept
35 {
34 {
36 auto dateTime = DateUtils::dateTime(sqpRange);
35 auto dateTime = DateUtils::dateTime(sqpRange);
37 return dateTime.toString(AMDA_TIME_FORMAT);
36 return dateTime.toString(AMDA_TIME_FORMAT);
38 }
37 }
39
38
40 AmdaResultParser::ValueType valueType(const QString &valueType)
39 AmdaResultParser::ValueType valueType(const QString &valueType)
41 {
40 {
42 if (valueType == QStringLiteral("scalar")) {
41 if (valueType == QStringLiteral("scalar")) {
43 return AmdaResultParser::ValueType::SCALAR;
42 return AmdaResultParser::ValueType::SCALAR;
44 }
43 }
45 else if (valueType == QStringLiteral("vector")) {
44 else if (valueType == QStringLiteral("vector")) {
46 return AmdaResultParser::ValueType::VECTOR;
45 return AmdaResultParser::ValueType::VECTOR;
47 }
46 }
48 else {
47 else {
49 return AmdaResultParser::ValueType::UNKNOWN;
48 return AmdaResultParser::ValueType::UNKNOWN;
50 }
49 }
51 }
50 }
52
51
53 } // namespace
52 } // namespace
54
53
55 AmdaProvider::AmdaProvider()
54 AmdaProvider::AmdaProvider()
56 {
55 {
57 qCDebug(LOG_AmdaProvider()) << tr("AmdaProvider::AmdaProvider") << QThread::currentThread();
56 qCDebug(LOG_AmdaProvider()) << tr("AmdaProvider::AmdaProvider") << QThread::currentThread();
58 if (auto app = sqpApp) {
57 if (auto app = sqpApp) {
59 auto &networkController = app->networkController();
58 auto &networkController = app->networkController();
60 connect(this, SIGNAL(requestConstructed(std::shared_ptr<QNetworkRequest>, QUuid,
59 connect(this, SIGNAL(requestConstructed(std::shared_ptr<QNetworkRequest>, QUuid,
61 std::function<void(QNetworkReply *, QUuid)>)),
60 std::function<void(QNetworkReply *, QUuid)>)),
62 &networkController,
61 &networkController,
63 SLOT(onProcessRequested(std::shared_ptr<QNetworkRequest>, QUuid,
62 SLOT(onProcessRequested(std::shared_ptr<QNetworkRequest>, QUuid,
64 std::function<void(QNetworkReply *, QUuid)>)));
63 std::function<void(QNetworkReply *, QUuid)>)));
65
64
66
65
67 connect(&sqpApp->networkController(),
66 connect(&sqpApp->networkController(),
68 SIGNAL(replyDownloadProgress(QUuid, std::shared_ptr<QNetworkRequest>, double)),
67 SIGNAL(replyDownloadProgress(QUuid, std::shared_ptr<QNetworkRequest>, double)),
69 this,
68 this,
70 SLOT(onReplyDownloadProgress(QUuid, std::shared_ptr<QNetworkRequest>, double)));
69 SLOT(onReplyDownloadProgress(QUuid, std::shared_ptr<QNetworkRequest>, double)));
71 }
70 }
72 }
71 }
73
72
74 std::shared_ptr<IDataProvider> AmdaProvider::clone() const
73 std::shared_ptr<IDataProvider> AmdaProvider::clone() const
75 {
74 {
76 // No copy is made in the clone
75 // No copy is made in the clone
77 return std::make_shared<AmdaProvider>();
76 return std::make_shared<AmdaProvider>();
78 }
77 }
79
78
80 void AmdaProvider::requestDataLoading(QUuid acqIdentifier, const DataProviderParameters &parameters)
79 void AmdaProvider::requestDataLoading(QUuid acqIdentifier, const DataProviderParameters &parameters)
81 {
80 {
82 // NOTE: Try to use multithread if possible
81 // NOTE: Try to use multithread if possible
83 const auto times = parameters.m_Times;
82 const auto times = parameters.m_Times;
84 const auto data = parameters.m_Data;
83 const auto data = parameters.m_Data;
85 for (const auto &dateTime : qAsConst(times)) {
84 for (const auto &dateTime : qAsConst(times)) {
86 qCDebug(LOG_AmdaProvider()) << tr("TORM AmdaProvider::requestDataLoading ") << acqIdentifier
85 qCDebug(LOG_AmdaProvider()) << tr("TORM AmdaProvider::requestDataLoading ") << acqIdentifier
87 << dateTime;
86 << dateTime;
88 this->retrieveData(acqIdentifier, dateTime, data);
87 this->retrieveData(acqIdentifier, dateTime, data);
89
88
90
89
91 // TORM when AMDA will support quick asynchrone request
90 // TORM when AMDA will support quick asynchrone request
92 QThread::msleep(1000);
91 QThread::msleep(1000);
93 }
92 }
94 }
93 }
95
94
96 void AmdaProvider::requestDataAborting(QUuid acqIdentifier)
95 void AmdaProvider::requestDataAborting(QUuid acqIdentifier)
97 {
96 {
98 if (auto app = sqpApp) {
97 if (auto app = sqpApp) {
99 auto &networkController = app->networkController();
98 auto &networkController = app->networkController();
100 networkController.onReplyCanceled(acqIdentifier);
99 networkController.onReplyCanceled(acqIdentifier);
101 }
100 }
102 }
101 }
103
102
104 void AmdaProvider::onReplyDownloadProgress(QUuid acqIdentifier,
103 void AmdaProvider::onReplyDownloadProgress(QUuid acqIdentifier,
105 std::shared_ptr<QNetworkRequest> networkRequest,
104 std::shared_ptr<QNetworkRequest> networkRequest,
106 double progress)
105 double progress)
107 {
106 {
108 qCDebug(LOG_AmdaProvider()) << tr("onReplyDownloadProgress") << acqIdentifier
107 qCDebug(LOG_AmdaProvider()) << tr("onReplyDownloadProgress") << acqIdentifier
109 << networkRequest.get() << progress;
108 << networkRequest.get() << progress;
110 auto acqIdToRequestProgressMapIt = m_AcqIdToRequestProgressMap.find(acqIdentifier);
109 auto acqIdToRequestProgressMapIt = m_AcqIdToRequestProgressMap.find(acqIdentifier);
111 if (acqIdToRequestProgressMapIt != m_AcqIdToRequestProgressMap.end()) {
110 if (acqIdToRequestProgressMapIt != m_AcqIdToRequestProgressMap.end()) {
112
111
113 // Update the progression for the current request
112 // Update the progression for the current request
114 auto requestPtr = networkRequest;
113 auto requestPtr = networkRequest;
115 auto findRequest = [requestPtr](const auto &entry) { return requestPtr == entry.first; };
114 auto findRequest = [requestPtr](const auto &entry) { return requestPtr == entry.first; };
116
115
117 auto &requestProgressMap = acqIdToRequestProgressMapIt->second;
116 auto &requestProgressMap = acqIdToRequestProgressMapIt->second;
118 auto requestProgressMapEnd = requestProgressMap.end();
117 auto requestProgressMapEnd = requestProgressMap.end();
119 auto requestProgressMapIt
118 auto requestProgressMapIt
120 = std::find_if(requestProgressMap.begin(), requestProgressMapEnd, findRequest);
119 = std::find_if(requestProgressMap.begin(), requestProgressMapEnd, findRequest);
121
120
122 if (requestProgressMapIt != requestProgressMapEnd) {
121 if (requestProgressMapIt != requestProgressMapEnd) {
123 requestProgressMapIt->second = progress;
122 requestProgressMapIt->second = progress;
124 }
123 }
125 else {
124 else {
126 // This case can happened when a progression is send after the request has been
125 // This case can happened when a progression is send after the request has been
127 // finished.
126 // finished.
128 // Generaly the case when aborting a request
127 // Generaly the case when aborting a request
129 qCDebug(LOG_AmdaProvider()) << tr("Can't retrieve Request in progress") << acqIdentifier
128 qCDebug(LOG_AmdaProvider()) << tr("Can't retrieve Request in progress") << acqIdentifier
130 << networkRequest.get() << progress;
129 << networkRequest.get() << progress;
131 }
130 }
132
131
133 // Compute the current final progress and notify it
132 // Compute the current final progress and notify it
134 double finalProgress = 0.0;
133 double finalProgress = 0.0;
135
134
136 auto fraq = requestProgressMap.size();
135 auto fraq = requestProgressMap.size();
137
136
138 for (auto requestProgress : requestProgressMap) {
137 for (auto requestProgress : requestProgressMap) {
139 finalProgress += requestProgress.second;
138 finalProgress += requestProgress.second;
140 qCDebug(LOG_AmdaProvider()) << tr("Current final progress without fraq:")
139 qCDebug(LOG_AmdaProvider()) << tr("Current final progress without fraq:")
141 << finalProgress << requestProgress.second;
140 << finalProgress << requestProgress.second;
142 }
141 }
143
142
144 if (fraq > 0) {
143 if (fraq > 0) {
145 finalProgress = finalProgress / fraq;
144 finalProgress = finalProgress / fraq;
146 }
145 }
147
146
148 qCDebug(LOG_AmdaProvider()) << tr("Current final progress: ") << fraq << finalProgress;
147 qCDebug(LOG_AmdaProvider()) << tr("Current final progress: ") << fraq << finalProgress;
149 emit dataProvidedProgress(acqIdentifier, finalProgress);
148 emit dataProvidedProgress(acqIdentifier, finalProgress);
150 }
149 }
151 else {
150 else {
152 // This case can happened when a progression is send after the request has been finished.
151 // This case can happened when a progression is send after the request has been finished.
153 // Generaly the case when aborting a request
152 // Generaly the case when aborting a request
154 emit dataProvidedProgress(acqIdentifier, 100.0);
153 emit dataProvidedProgress(acqIdentifier, 100.0);
155 }
154 }
156 }
155 }
157
156
158 void AmdaProvider::retrieveData(QUuid token, const SqpRange &dateTime, const QVariantHash &data)
157 void AmdaProvider::retrieveData(QUuid token, const SqpRange &dateTime, const QVariantHash &data)
159 {
158 {
160 // Retrieves product ID from data: if the value is invalid, no request is made
159 // Retrieves product ID from data: if the value is invalid, no request is made
161 auto productId = data.value(AMDA_XML_ID_KEY).toString();
160 auto productId = data.value(AMDA_XML_ID_KEY).toString();
162 if (productId.isNull()) {
161 if (productId.isNull()) {
163 qCCritical(LOG_AmdaProvider()) << tr("Can't retrieve data: unknown product id");
162 qCCritical(LOG_AmdaProvider()) << tr("Can't retrieve data: unknown product id");
164 return;
163 return;
165 }
164 }
166
165
167 // Retrieves the data type that determines whether the expected format for the result file is
166 // Retrieves the data type that determines whether the expected format for the result file is
168 // scalar, vector...
167 // scalar, vector...
169 auto productValueType = valueType(data.value(AMDA_DATA_TYPE_KEY).toString());
168 auto productValueType = valueType(data.value(AMDA_DATA_TYPE_KEY).toString());
170
169
171 // /////////// //
170 // /////////// //
172 // Creates URL //
171 // Creates URL //
173 // /////////// //
172 // /////////// //
174
173
175 auto startDate = dateFormat(dateTime.m_TStart);
174 auto startDate = dateFormat(dateTime.m_TStart);
176 auto endDate = dateFormat(dateTime.m_TEnd);
175 auto endDate = dateFormat(dateTime.m_TEnd);
177
176
178 auto url = QUrl{QString{AMDA_URL_FORMAT}.arg(startDate, endDate, productId)};
177 auto url = QUrl{QString{AMDA_URL_FORMAT}.arg(startDate, endDate, productId)};
179 qCInfo(LOG_AmdaProvider()) << tr("TORM AmdaProvider::retrieveData url:") << url;
178 qCInfo(LOG_AmdaProvider()) << tr("TORM AmdaProvider::retrieveData url:") << url;
180 auto tempFile = std::make_shared<QTemporaryFile>();
179 auto tempFile = std::make_shared<QTemporaryFile>();
181
180
182 // LAMBDA
181 // LAMBDA
183 auto httpDownloadFinished = [this, dateTime, tempFile,
182 auto httpDownloadFinished = [this, dateTime, tempFile,
184 productValueType](QNetworkReply *reply, QUuid dataId) noexcept {
183 productValueType](QNetworkReply *reply, QUuid dataId) noexcept {
185
184
186 // Don't do anything if the reply was abort
185 // Don't do anything if the reply was abort
187 if (reply->error() == QNetworkReply::NoError) {
186 if (reply->error() == QNetworkReply::NoError) {
188
187
189 if (tempFile) {
188 if (tempFile) {
190 auto replyReadAll = reply->readAll();
189 auto replyReadAll = reply->readAll();
191 if (!replyReadAll.isEmpty()) {
190 if (!replyReadAll.isEmpty()) {
192 tempFile->write(replyReadAll);
191 tempFile->write(replyReadAll);
193 }
192 }
194 tempFile->close();
193 tempFile->close();
195
194
196 // Parse results file
195 // Parse results file
197 if (auto dataSeries
196 if (auto dataSeries
198 = AmdaResultParser::readTxt(tempFile->fileName(), productValueType)) {
197 = AmdaResultParser::readTxt(tempFile->fileName(), productValueType)) {
199 emit dataProvided(dataId, dataSeries, dateTime);
198 emit dataProvided(dataId, dataSeries, dateTime);
200 }
199 }
201 else {
200 else {
202 /// @todo ALX : debug
201 /// @todo ALX : debug
203 emit dataProvidedFailed(dataId);
202 emit dataProvidedFailed(dataId);
204 }
203 }
205 }
204 }
206 qCDebug(LOG_AmdaProvider()) << tr("acquisition requests erase because of finishing")
205 qCDebug(LOG_AmdaProvider()) << tr("acquisition requests erase because of finishing")
207 << dataId;
206 << dataId;
208 m_AcqIdToRequestProgressMap.erase(dataId);
207 m_AcqIdToRequestProgressMap.erase(dataId);
209 }
208 }
210 else {
209 else {
211 qCCritical(LOG_AmdaProvider()) << tr("httpDownloadFinished ERROR");
210 qCCritical(LOG_AmdaProvider()) << tr("httpDownloadFinished ERROR");
212 emit dataProvidedFailed(dataId);
211 emit dataProvidedFailed(dataId);
213 }
212 }
214
213
215 };
214 };
216 auto httpFinishedLambda
215 auto httpFinishedLambda
217 = [this, httpDownloadFinished, tempFile](QNetworkReply *reply, QUuid dataId) noexcept {
216 = [this, httpDownloadFinished, tempFile](QNetworkReply *reply, QUuid dataId) noexcept {
218
217
219 // Don't do anything if the reply was abort
218 // Don't do anything if the reply was abort
220 if (reply->error() == QNetworkReply::NoError) {
219 if (reply->error() == QNetworkReply::NoError) {
221 auto downloadFileUrl = QUrl{QString{reply->readAll()}.trimmed()};
220 auto downloadFileUrl = QUrl{QString{reply->readAll()}};
222
221
223 qCInfo(LOG_AmdaProvider())
222 qCInfo(LOG_AmdaProvider())
224 << tr("TORM AmdaProvider::retrieveData downloadFileUrl:") << downloadFileUrl;
223 << tr("TORM AmdaProvider::retrieveData downloadFileUrl:") << downloadFileUrl;
225 // Executes request for downloading file //
224 // Executes request for downloading file //
226
225
227 // Creates destination file
226 // Creates destination file
228 if (tempFile->open()) {
227 if (tempFile->open()) {
229 // Executes request and store the request for progression
228 // Executes request and store the request for progression
230 auto request = std::make_shared<QNetworkRequest>(downloadFileUrl);
229 auto request = std::make_shared<QNetworkRequest>(downloadFileUrl);
231 updateRequestProgress(dataId, request, 0.0);
230 updateRequestProgress(dataId, request, 0.0);
232 emit requestConstructed(request, dataId, httpDownloadFinished);
231 emit requestConstructed(request, dataId, httpDownloadFinished);
233 }
232 }
234 else {
233 else {
235 emit dataProvidedFailed(dataId);
234 emit dataProvidedFailed(dataId);
236 }
235 }
237 }
236 }
238 else {
237 else {
239 qCDebug(LOG_AmdaProvider())
238 qCDebug(LOG_AmdaProvider())
240 << tr("acquisition requests erase because of aborting") << dataId;
239 << tr("acquisition requests erase because of aborting") << dataId;
241 qCCritical(LOG_AmdaProvider()) << tr("httpFinishedLambda ERROR");
240 qCCritical(LOG_AmdaProvider()) << tr("httpFinishedLambda ERROR");
242 m_AcqIdToRequestProgressMap.erase(dataId);
241 m_AcqIdToRequestProgressMap.erase(dataId);
243 emit dataProvidedFailed(dataId);
242 emit dataProvidedFailed(dataId);
244 }
243 }
245 };
244 };
246
245
247 // //////////////// //
246 // //////////////// //
248 // Executes request //
247 // Executes request //
249 // //////////////// //
248 // //////////////// //
250
249
251 auto request = std::make_shared<QNetworkRequest>(url);
250 auto request = std::make_shared<QNetworkRequest>(url);
252 qCDebug(LOG_AmdaProvider()) << tr("First Request creation") << request.get();
251 qCDebug(LOG_AmdaProvider()) << tr("First Request creation") << request.get();
253 updateRequestProgress(token, request, 0.0);
252 updateRequestProgress(token, request, 0.0);
254
253
255 emit requestConstructed(request, token, httpFinishedLambda);
254 emit requestConstructed(request, token, httpFinishedLambda);
256 }
255 }
257
256
258 void AmdaProvider::updateRequestProgress(QUuid acqIdentifier,
257 void AmdaProvider::updateRequestProgress(QUuid acqIdentifier,
259 std::shared_ptr<QNetworkRequest> request, double progress)
258 std::shared_ptr<QNetworkRequest> request, double progress)
260 {
259 {
261 auto acqIdToRequestProgressMapIt = m_AcqIdToRequestProgressMap.find(acqIdentifier);
260 auto acqIdToRequestProgressMapIt = m_AcqIdToRequestProgressMap.find(acqIdentifier);
262 if (acqIdToRequestProgressMapIt != m_AcqIdToRequestProgressMap.end()) {
261 if (acqIdToRequestProgressMapIt != m_AcqIdToRequestProgressMap.end()) {
263 auto &requestProgressMap = acqIdToRequestProgressMapIt->second;
262 auto &requestProgressMap = acqIdToRequestProgressMapIt->second;
264 auto requestProgressMapIt = requestProgressMap.find(request);
263 auto requestProgressMapIt = requestProgressMap.find(request);
265 if (requestProgressMapIt != requestProgressMap.end()) {
264 if (requestProgressMapIt != requestProgressMap.end()) {
266 requestProgressMapIt->second = progress;
265 requestProgressMapIt->second = progress;
267 qCDebug(LOG_AmdaProvider()) << tr("updateRequestProgress new progress for request")
266 qCDebug(LOG_AmdaProvider()) << tr("updateRequestProgress new progress for request")
268 << acqIdentifier << request.get() << progress;
267 << acqIdentifier << request.get() << progress;
269 }
268 }
270 else {
269 else {
271 qCDebug(LOG_AmdaProvider()) << tr("updateRequestProgress new request") << acqIdentifier
270 qCDebug(LOG_AmdaProvider()) << tr("updateRequestProgress new request") << acqIdentifier
272 << request.get() << progress;
271 << request.get() << progress;
273 acqIdToRequestProgressMapIt->second.insert(std::make_pair(request, progress));
272 acqIdToRequestProgressMapIt->second.insert(std::make_pair(request, progress));
274 }
273 }
275 }
274 }
276 else {
275 else {
277 qCDebug(LOG_AmdaProvider()) << tr("updateRequestProgress new acqIdentifier")
276 qCDebug(LOG_AmdaProvider()) << tr("updateRequestProgress new acqIdentifier")
278 << acqIdentifier << request.get() << progress;
277 << acqIdentifier << request.get() << progress;
279 auto requestProgressMap = std::map<std::shared_ptr<QNetworkRequest>, double>{};
278 auto requestProgressMap = std::map<std::shared_ptr<QNetworkRequest>, double>{};
280 requestProgressMap.insert(std::make_pair(request, progress));
279 requestProgressMap.insert(std::make_pair(request, progress));
281 m_AcqIdToRequestProgressMap.insert(
280 m_AcqIdToRequestProgressMap.insert(
282 std::make_pair(acqIdentifier, std::move(requestProgressMap)));
281 std::make_pair(acqIdentifier, std::move(requestProgressMap)));
283 }
282 }
284 }
283 }
@@ -1,225 +1,209
1 #include "AmdaResultParser.h"
1 #include "AmdaResultParser.h"
2
2
3 #include <Common/DateUtils.h>
3 #include <Common/DateUtils.h>
4 #include <Data/ScalarSeries.h>
4 #include <Data/ScalarSeries.h>
5 #include <Data/VectorSeries.h>
5 #include <Data/VectorSeries.h>
6
6
7 #include <QDateTime>
7 #include <QDateTime>
8 #include <QFile>
8 #include <QFile>
9 #include <QRegularExpression>
9 #include <QRegularExpression>
10
10
11 #include <cmath>
11 #include <cmath>
12
12
13 Q_LOGGING_CATEGORY(LOG_AmdaResultParser, "AmdaResultParser")
13 Q_LOGGING_CATEGORY(LOG_AmdaResultParser, "AmdaResultParser")
14
14
15 namespace {
15 namespace {
16
16
17 /// Message in result file when the file was not found on server
17 /// Message in result file when the file was not found on server
18 const auto FILE_NOT_FOUND_MESSAGE = QStringLiteral("Not Found");
18 const auto FILE_NOT_FOUND_MESSAGE = QStringLiteral("Not Found");
19
19
20 /// Separator between values in a result line
21 const auto RESULT_LINE_SEPARATOR = QRegularExpression{QStringLiteral("\\s+")};
22
23 /// Regex to find the header of the data in the file. This header indicates the end of comments in
24 /// the file
25 const auto DATA_HEADER_REGEX = QRegularExpression{QStringLiteral("#\\s*DATA\\s*:")};
26
27 /// Format for dates in result files
20 /// Format for dates in result files
28 const auto DATE_FORMAT = QStringLiteral("yyyy-MM-ddThh:mm:ss.zzz");
21 const auto DATE_FORMAT = QStringLiteral("yyyy-MM-ddThh:mm:ss.zzz");
29
22
30 /// Regex to find unit in a line. Examples of valid lines:
23 /// Separator between values in a result line
31 /// ... PARAMETER_UNITS : nT ...
24 const auto RESULT_LINE_SEPARATOR = QRegularExpression{QStringLiteral("\\s+")};
32 /// ... PARAMETER_UNITS:nT ...
33 /// ... PARAMETER_UNITS: m² ...
34 /// ... PARAMETER_UNITS : m/s ...
35 const auto UNIT_REGEX = QRegularExpression{QStringLiteral("\\s*PARAMETER_UNITS\\s*:\\s*(.+)")};
36
25
37 QDateTime dateTimeFromString(const QString &stringDate) noexcept
26 /// Regex to find unit in a line. Examples of valid lines:
38 {
27 /// ... - Units : nT - ...
39 #if QT_VERSION >= QT_VERSION_CHECK(5, 8, 0)
28 /// ... -Units:nT- ...
40 return QDateTime::fromString(stringDate, Qt::ISODateWithMs);
29 /// ... -Units: m²- ...
41 #else
30 /// ... - Units : m/s - ...
42 return QDateTime::fromString(stringDate, DATE_FORMAT);
31 const auto UNIT_REGEX = QRegularExpression{QStringLiteral("-\\s*Units\\s*:\\s*(.+?)\\s*-")};
43 #endif
44 }
45
32
46 /// Converts a string date to a double date
33 /// Converts a string date to a double date
47 /// @return a double that represents the date in seconds, NaN if the string date can't be converted
34 /// @return a double that represents the date in seconds, NaN if the string date can't be converted
48 double doubleDate(const QString &stringDate) noexcept
35 double doubleDate(const QString &stringDate) noexcept
49 {
36 {
50 // Format: yyyy-MM-ddThh:mm:ss.zzz
37 auto dateTime = QDateTime::fromString(stringDate, DATE_FORMAT);
51 auto dateTime = dateTimeFromString(stringDate);
52 dateTime.setTimeSpec(Qt::UTC);
38 dateTime.setTimeSpec(Qt::UTC);
53 return dateTime.isValid() ? DateUtils::secondsSinceEpoch(dateTime)
39 return dateTime.isValid() ? DateUtils::secondsSinceEpoch(dateTime)
54 : std::numeric_limits<double>::quiet_NaN();
40 : std::numeric_limits<double>::quiet_NaN();
55 }
41 }
56
42
57 /// Checks if a line is a comment line
43 /// Checks if a line is a comment line
58 bool isCommentLine(const QString &line)
44 bool isCommentLine(const QString &line)
59 {
45 {
60 return line.startsWith("#");
46 return line.startsWith("#");
61 }
47 }
62
48
63 /// @return the number of lines to be read depending on the type of value passed in parameter
49 /// @return the number of lines to be read depending on the type of value passed in parameter
64 int nbValues(AmdaResultParser::ValueType valueType) noexcept
50 int nbValues(AmdaResultParser::ValueType valueType) noexcept
65 {
51 {
66 switch (valueType) {
52 switch (valueType) {
67 case AmdaResultParser::ValueType::SCALAR:
53 case AmdaResultParser::ValueType::SCALAR:
68 return 1;
54 return 1;
69 case AmdaResultParser::ValueType::VECTOR:
55 case AmdaResultParser::ValueType::VECTOR:
70 return 3;
56 return 3;
71 case AmdaResultParser::ValueType::UNKNOWN:
57 case AmdaResultParser::ValueType::UNKNOWN:
72 // Invalid case
58 // Invalid case
73 break;
59 break;
74 }
60 }
75
61
76 // Invalid cases
62 // Invalid cases
77 qCCritical(LOG_AmdaResultParser())
63 qCCritical(LOG_AmdaResultParser())
78 << QObject::tr("Can't get the number of values to read: unsupported type");
64 << QObject::tr("Can't get the number of values to read: unsupported type");
79 return 0;
65 return 0;
80 }
66 }
81
67
82 /**
68 /**
83 * Reads stream to retrieve x-axis unit
69 * Reads stream to retrieve x-axis unit
84 * @param stream the stream to read
70 * @param stream the stream to read
85 * @return the unit that has been read in the stream, a default unit (time unit with no label) if an
71 * @return the unit that has been read in the stream, a default unit (time unit with no label) if an
86 * error occured during reading
72 * error occured during reading
87 */
73 */
88 Unit readXAxisUnit(QTextStream &stream)
74 Unit readXAxisUnit(QTextStream &stream)
89 {
75 {
90 QString line{};
76 QString line{};
91
77
92 // Searches unit in the comment lines (as long as the reading has not reached the data header)
78 // Searches unit in the comment lines
93 while (stream.readLineInto(&line) && !line.contains(DATA_HEADER_REGEX)) {
79 while (stream.readLineInto(&line) && isCommentLine(line)) {
94 auto match = UNIT_REGEX.match(line);
80 auto match = UNIT_REGEX.match(line);
95 if (match.hasMatch()) {
81 if (match.hasMatch()) {
96 return Unit{match.captured(1), true};
82 return Unit{match.captured(1), true};
97 }
83 }
98 }
84 }
99
85
100 qCWarning(LOG_AmdaResultParser()) << QObject::tr("The unit could not be found in the file");
86 qCWarning(LOG_AmdaResultParser()) << QObject::tr("The unit could not be found in the file");
101
87
102 // Error cases
88 // Error cases
103 return Unit{{}, true};
89 return Unit{{}, true};
104 }
90 }
105
91
106 /**
92 /**
107 * Reads stream to retrieve results
93 * Reads stream to retrieve results
108 * @param stream the stream to read
94 * @param stream the stream to read
109 * @return the pair of vectors x-axis data/values data that has been read in the stream
95 * @return the pair of vectors x-axis data/values data that has been read in the stream
110 */
96 */
111 std::pair<std::vector<double>, std::vector<double> >
97 std::pair<std::vector<double>, std::vector<double> >
112 readResults(QTextStream &stream, AmdaResultParser::ValueType valueType)
98 readResults(QTextStream &stream, AmdaResultParser::ValueType valueType)
113 {
99 {
114 auto expectedNbValues = nbValues(valueType) + 1;
100 auto expectedNbValues = nbValues(valueType);
115
101
116 auto xData = std::vector<double>{};
102 auto xData = std::vector<double>{};
117 auto valuesData = std::vector<double>{};
103 auto valuesData = std::vector<double>{};
118
104
119 QString line{};
105 QString line{};
120
106
121 // Skip comment lines
107 while (stream.readLineInto(&line)) {
122 while (stream.readLineInto(&line) && isCommentLine(line)) {
108 // Ignore comment lines
123 }
109 if (!isCommentLine(line)) {
124
125 if (!stream.atEnd()) {
126 do {
127 auto lineData = line.split(RESULT_LINE_SEPARATOR, QString::SkipEmptyParts);
110 auto lineData = line.split(RESULT_LINE_SEPARATOR, QString::SkipEmptyParts);
128 if (lineData.size() == expectedNbValues) {
111 if (lineData.size() == expectedNbValues + 1) {
129 // X : the data is converted from date to double (in secs)
112 // X : the data is converted from date to double (in secs)
130 auto x = doubleDate(lineData.at(0));
113 auto x = doubleDate(lineData.at(0));
131
114
132 // Adds result only if x is valid. Then, if value is invalid, it is set to NaN
115 // Adds result only if x is valid. Then, if value is invalid, it is set to NaN
133 if (!std::isnan(x)) {
116 if (!std::isnan(x)) {
134 xData.push_back(x);
117 xData.push_back(x);
135
118
136 // Values
119 // Values
137 for (auto valueIndex = 1; valueIndex < expectedNbValues; ++valueIndex) {
120 for (auto valueIndex = 0; valueIndex < expectedNbValues; ++valueIndex) {
138 auto column = valueIndex;
121 auto column = valueIndex + 1;
139
122
140 bool valueOk;
123 bool valueOk;
141 auto value = lineData.at(column).toDouble(&valueOk);
124 auto value = lineData.at(column).toDouble(&valueOk);
142
125
143 if (!valueOk) {
126 if (!valueOk) {
144 qCWarning(LOG_AmdaResultParser())
127 qCWarning(LOG_AmdaResultParser())
145 << QObject::tr(
128 << QObject::tr(
146 "Value from (line %1, column %2) is invalid and will be "
129 "Value from (line %1, column %2) is invalid and will be "
147 "converted to NaN")
130 "converted to NaN")
148 .arg(line, column);
131 .arg(line, column);
149 value = std::numeric_limits<double>::quiet_NaN();
132 value = std::numeric_limits<double>::quiet_NaN();
150 }
133 }
151 valuesData.push_back(value);
134 valuesData.push_back(value);
152 }
135 }
153 }
136 }
154 else {
137 else {
155 qCWarning(LOG_AmdaResultParser())
138 qCWarning(LOG_AmdaResultParser())
156 << QObject::tr("Can't retrieve results from line %1: x is invalid")
139 << QObject::tr("Can't retrieve results from line %1: x is invalid")
157 .arg(line);
140 .arg(line);
158 }
141 }
159 }
142 }
160 else {
143 else {
161 qCWarning(LOG_AmdaResultParser())
144 qCWarning(LOG_AmdaResultParser())
162 << QObject::tr("Can't retrieve results from line %1: invalid line").arg(line);
145 << QObject::tr("Can't retrieve results from line %1: invalid line").arg(line);
163 }
146 }
164 } while (stream.readLineInto(&line));
147 }
165 }
148 }
166
149
167 return std::make_pair(std::move(xData), std::move(valuesData));
150 return std::make_pair(std::move(xData), std::move(valuesData));
168 }
151 }
169
152
170 } // namespace
153 } // namespace
171
154
172 std::shared_ptr<IDataSeries> AmdaResultParser::readTxt(const QString &filePath,
155 std::shared_ptr<IDataSeries> AmdaResultParser::readTxt(const QString &filePath,
173 ValueType valueType) noexcept
156 ValueType valueType) noexcept
174 {
157 {
175 if (valueType == ValueType::UNKNOWN) {
158 if (valueType == ValueType::UNKNOWN) {
176 qCCritical(LOG_AmdaResultParser())
159 qCCritical(LOG_AmdaResultParser())
177 << QObject::tr("Can't retrieve AMDA data: the type of values to be read is unknown");
160 << QObject::tr("Can't retrieve AMDA data: the type of values to be read is unknown");
178 return nullptr;
161 return nullptr;
179 }
162 }
180
163
181 QFile file{filePath};
164 QFile file{filePath};
182
165
183 if (!file.open(QFile::ReadOnly | QIODevice::Text)) {
166 if (!file.open(QFile::ReadOnly | QIODevice::Text)) {
184 qCCritical(LOG_AmdaResultParser())
167 qCCritical(LOG_AmdaResultParser())
185 << QObject::tr("Can't retrieve AMDA data from file %1: %2")
168 << QObject::tr("Can't retrieve AMDA data from file %1: %2")
186 .arg(filePath, file.errorString());
169 .arg(filePath, file.errorString());
187 return nullptr;
170 return nullptr;
188 }
171 }
189
172
190 QTextStream stream{&file};
173 QTextStream stream{&file};
191
174
192 // Checks if the file was found on the server
175 // Checks if the file was found on the server
193 auto firstLine = stream.readLine();
176 auto firstLine = stream.readLine();
194 if (firstLine.compare(FILE_NOT_FOUND_MESSAGE) == 0) {
177 if (firstLine.compare(FILE_NOT_FOUND_MESSAGE) == 0) {
195 qCCritical(LOG_AmdaResultParser())
178 qCCritical(LOG_AmdaResultParser())
196 << QObject::tr("Can't retrieve AMDA data from file %1: file was not found on server")
179 << QObject::tr("Can't retrieve AMDA data from file %1: file was not found on server")
197 .arg(filePath);
180 .arg(filePath);
198 return nullptr;
181 return nullptr;
199 }
182 }
200
183
201 // Reads x-axis unit
184 // Reads x-axis unit
202 stream.seek(0); // returns to the beginning of the file
185 stream.seek(0); // returns to the beginning of the file
203 auto xAxisUnit = readXAxisUnit(stream);
186 auto xAxisUnit = readXAxisUnit(stream);
204
187
205 // Reads results
188 // Reads results
189 stream.seek(0); // returns to the beginning of the file
206 auto results = readResults(stream, valueType);
190 auto results = readResults(stream, valueType);
207
191
208 // Creates data series
192 // Creates data series
209 switch (valueType) {
193 switch (valueType) {
210 case ValueType::SCALAR:
194 case ValueType::SCALAR:
211 return std::make_shared<ScalarSeries>(std::move(results.first),
195 return std::make_shared<ScalarSeries>(std::move(results.first),
212 std::move(results.second), xAxisUnit, Unit{});
196 std::move(results.second), xAxisUnit, Unit{});
213 case ValueType::VECTOR:
197 case ValueType::VECTOR:
214 return std::make_shared<VectorSeries>(std::move(results.first),
198 return std::make_shared<VectorSeries>(std::move(results.first),
215 std::move(results.second), xAxisUnit, Unit{});
199 std::move(results.second), xAxisUnit, Unit{});
216 case ValueType::UNKNOWN:
200 case ValueType::UNKNOWN:
217 // Invalid case
201 // Invalid case
218 break;
202 break;
219 }
203 }
220
204
221 // Invalid cases
205 // Invalid cases
222 qCCritical(LOG_AmdaResultParser())
206 qCCritical(LOG_AmdaResultParser())
223 << QObject::tr("Can't create data series: unsupported value type");
207 << QObject::tr("Can't create data series: unsupported value type");
224 return nullptr;
208 return nullptr;
225 }
209 }
@@ -1,64 +1,6
1 # -----------
1 #Sampling Time : 60
2 # AMDA INFO :
2 #Time Format : YYYY-MM-DDThh:mm:ss.mls
3 # -----------
3 #imf(0) - Type : Local Parameter @ CDPP/AMDA - Name : bx_gse - Units : nT - Size : 1 - Frame : GSE - Mission : ACE - Instrument : MFI - Dataset : mfi_final-prelim
4 # AMDA_ABOUT : Created by CDPP/AMDA(c)
5 # AMDA_VERSION : 3.5.0
6 # AMDA_ACKNOWLEDGEMENT : CDPP/AMDA Team
7 #
8 # --------------
9 # REQUEST INFO :
10 # --------------
11 # REQUEST_STRUCTURE : one-file-per-parameter-per-interval
12 # REQUEST_TIME_FORMAT : ISO 8601
13 # REQUEST_OUTPUT_PARAMS : imf
14 #
15 # -----------------
16 # BASE PARAMETERS :
17 # -----------------
18 #
19 # MISSION_ID : NONE
20 #
21 # INSTRUMENT_ID : NONE
22 #
23 # DATASET_ID : ace-imf-all
24 # DATASET_NAME : final / prelim
25 # DATASET_DESCRIPTION : Interplanetary Magnetic Field 16-sec Level2/PRELIM Data
26 # DATASET_SOURCE : CDPP/DDServer
27 # DATASET_GLOBAL_START : 1997-09-02T00:00:12.000
28 # DATASET_GLOBAL_STOP : 2017-09-16T23:59:57.000
29 # DATASET_MIN_SAMPLING : 16
30 # DATASET_MAX_SAMPLING : 16
31 # DATASET_CAVEATS :
32 The quality of ACE level 2 data is such that it is suitable for serious scientific study. However, to avoid confusion and misunderstanding, it is recommended that users consult with the appropriate ACE team members before publishing work derived from the data. The ACE team has worked hard to ensure that the level 2 data are free from errors, but the team cannot accept responsibility for erroneous data, or for misunderstandings about how the data may be used. This is especially true if the appropriate ACE team members are not consulted before publication. At the very least, preprints should be forwarded to the ACE team before publication.
33
34 # DATASET_ACKNOWLEDGEMENT :
35 Please acknowledge the ACE/MAG instrument team and the ACE Science Center
36
37 #
38 # PARAMETER_ID : imf
39 # PARAMETER_NAME : imf
40 # PARAMETER_SHORT_NAME : b_gse
41 # PARAMETER_COMPONENTS : bx,by,bz
42 # PARAMETER_UNITS : nT
43 # PARAMETER_COORDINATE_SYSTEM : GSE
44 # PARAMETER_TENSOR_ORDER : 0
45 # PARAMETER_SI_CONVERSION : 1e-9>T
46 # PARAMETER_TABLE : None
47 # PARAMETER_FILL_VALUE : nan
48 # PARAMETER_UCD : phys.magField
49 #
50 #
51 # ---------------
52 # INTERVAL INFO :
53 # ---------------
54 # INTERVAL_START : 2013-09-23T08:58:12.000
55 # INTERVAL_STOP : 2013-09-23T09:11:48.000
56 #
57 # ------
58 # DATA :
59 # ------
60 # DATA_COLUMNS : AMDA_TIME, imf[0]
61 #
62 2013-09-23T09:00:30.000 NaN
4 2013-09-23T09:00:30.000 NaN
63 2013-09-23T09:01:30.000 -2.71850
5 2013-09-23T09:01:30.000 -2.71850
64 2013-09-23T09:02:30.000 -2.52150 No newline at end of file
6 2013-09-23T09:02:30.000 -2.52150
@@ -1,64 +1,6
1 # -----------
1 #Sampling Time : 60
2 # AMDA INFO :
2 #Time Format : YYYY-MM-DDThh:mm:ss.mls
3 # -----------
3 #imf(0) - Type : Local Parameter @ CDPP/AMDA - Name : bx_gse - Units : nT - Size : 1 - Frame : GSE - Mission : ACE - Instrument : MFI - Dataset : mfi_final-prelim
4 # AMDA_ABOUT : Created by CDPP/AMDA(c)
5 # AMDA_VERSION : 3.5.0
6 # AMDA_ACKNOWLEDGEMENT : CDPP/AMDA Team
7 #
8 # --------------
9 # REQUEST INFO :
10 # --------------
11 # REQUEST_STRUCTURE : one-file-per-parameter-per-interval
12 # REQUEST_TIME_FORMAT : ISO 8601
13 # REQUEST_OUTPUT_PARAMS : imf
14 #
15 # -----------------
16 # BASE PARAMETERS :
17 # -----------------
18 #
19 # MISSION_ID : NONE
20 #
21 # INSTRUMENT_ID : NONE
22 #
23 # DATASET_ID : ace-imf-all
24 # DATASET_NAME : final / prelim
25 # DATASET_DESCRIPTION : Interplanetary Magnetic Field 16-sec Level2/PRELIM Data
26 # DATASET_SOURCE : CDPP/DDServer
27 # DATASET_GLOBAL_START : 1997-09-02T00:00:12.000
28 # DATASET_GLOBAL_STOP : 2017-09-16T23:59:57.000
29 # DATASET_MIN_SAMPLING : 16
30 # DATASET_MAX_SAMPLING : 16
31 # DATASET_CAVEATS :
32 The quality of ACE level 2 data is such that it is suitable for serious scientific study. However, to avoid confusion and misunderstanding, it is recommended that users consult with the appropriate ACE team members before publishing work derived from the data. The ACE team has worked hard to ensure that the level 2 data are free from errors, but the team cannot accept responsibility for erroneous data, or for misunderstandings about how the data may be used. This is especially true if the appropriate ACE team members are not consulted before publication. At the very least, preprints should be forwarded to the ACE team before publication.
33
34 # DATASET_ACKNOWLEDGEMENT :
35 Please acknowledge the ACE/MAG instrument team and the ACE Science Center
36
37 #
38 # PARAMETER_ID : imf
39 # PARAMETER_NAME : imf
40 # PARAMETER_SHORT_NAME : b_gse
41 # PARAMETER_COMPONENTS : bx,by,bz
42 # PARAMETER_UNITS : nT
43 # PARAMETER_COORDINATE_SYSTEM : GSE
44 # PARAMETER_TENSOR_ORDER : 0
45 # PARAMETER_SI_CONVERSION : 1e-9>T
46 # PARAMETER_TABLE : None
47 # PARAMETER_FILL_VALUE : nan
48 # PARAMETER_UCD : phys.magField
49 #
50 #
51 # ---------------
52 # INTERVAL INFO :
53 # ---------------
54 # INTERVAL_START : 2013-09-23T08:58:12.000
55 # INTERVAL_STOP : 2013-09-23T09:11:48.000
56 #
57 # ------
58 # DATA :
59 # ------
60 # DATA_COLUMNS : AMDA_TIME, imf[0]
61 #
62 NaN -3.01425
4 NaN -3.01425
63 2013-09-23T09:01:30.000 -2.71850
5 2013-09-23T09:01:30.000 -2.71850
64 2013-09-23T09:02:30.000 -2.52150 No newline at end of file
6 2013-09-23T09:02:30.000 -2.52150
@@ -1,60 +1,2
1 # -----------
1 #Sampling Time : 60
2 # AMDA INFO :
2 #Time Format : YYYY-MM-DDThh:mm:ss.mls No newline at end of file
3 # -----------
4 # AMDA_ABOUT : Created by CDPP/AMDA(c)
5 # AMDA_VERSION : 3.5.0
6 # AMDA_ACKNOWLEDGEMENT : CDPP/AMDA Team
7 #
8 # --------------
9 # REQUEST INFO :
10 # --------------
11 # REQUEST_STRUCTURE : one-file-per-parameter-per-interval
12 # REQUEST_TIME_FORMAT : ISO 8601
13 # REQUEST_OUTPUT_PARAMS : imf
14 #
15 # -----------------
16 # BASE PARAMETERS :
17 # -----------------
18 #
19 # MISSION_ID : NONE
20 #
21 # INSTRUMENT_ID : NONE
22 #
23 # DATASET_ID : ace-imf-all
24 # DATASET_NAME : final / prelim
25 # DATASET_DESCRIPTION : Interplanetary Magnetic Field 16-sec Level2/PRELIM Data
26 # DATASET_SOURCE : CDPP/DDServer
27 # DATASET_GLOBAL_START : 1997-09-02T00:00:12.000
28 # DATASET_GLOBAL_STOP : 2017-09-16T23:59:57.000
29 # DATASET_MIN_SAMPLING : 16
30 # DATASET_MAX_SAMPLING : 16
31 # DATASET_CAVEATS :
32 The quality of ACE level 2 data is such that it is suitable for serious scientific study. However, to avoid confusion and misunderstanding, it is recommended that users consult with the appropriate ACE team members before publishing work derived from the data. The ACE team has worked hard to ensure that the level 2 data are free from errors, but the team cannot accept responsibility for erroneous data, or for misunderstandings about how the data may be used. This is especially true if the appropriate ACE team members are not consulted before publication. At the very least, preprints should be forwarded to the ACE team before publication.
33
34 # DATASET_ACKNOWLEDGEMENT :
35 Please acknowledge the ACE/MAG instrument team and the ACE Science Center
36
37 #
38 # PARAMETER_ID : imf
39 # PARAMETER_NAME : imf
40 # PARAMETER_SHORT_NAME : b_gse
41 # PARAMETER_COMPONENTS : bx,by,bz
42 # PARAMETER_COORDINATE_SYSTEM : GSE
43 # PARAMETER_TENSOR_ORDER : 0
44 # PARAMETER_SI_CONVERSION : 1e-9>T
45 # PARAMETER_TABLE : None
46 # PARAMETER_FILL_VALUE : nan
47 # PARAMETER_UCD : phys.magField
48 #
49 #
50 # ---------------
51 # INTERVAL INFO :
52 # ---------------
53 # INTERVAL_START : 2013-09-23T08:58:12.000
54 # INTERVAL_STOP : 2013-09-23T09:11:48.000
55 #
56 # ------
57 # DATA :
58 # ------
59 # DATA_COLUMNS : AMDA_TIME, imf[0]
60 # No newline at end of file
@@ -1,64 +1,6
1 # -----------
1 #Sampling Time : 60
2 # AMDA INFO :
2 #Time Format : YYYY-MM-DDThh:mm:ss.mls
3 # -----------
3 #imf(0) - Type : Local Parameter @ CDPP/AMDA - Name : bx_gse - Units : nT - Size : 1 - Frame : GSE - Mission : ACE - Instrument : MFI - Dataset : mfi_final-prelim
4 # AMDA_ABOUT : Created by CDPP/AMDA(c)
5 # AMDA_VERSION : 3.5.0
6 # AMDA_ACKNOWLEDGEMENT : CDPP/AMDA Team
7 #
8 # --------------
9 # REQUEST INFO :
10 # --------------
11 # REQUEST_STRUCTURE : one-file-per-parameter-per-interval
12 # REQUEST_TIME_FORMAT : ISO 8601
13 # REQUEST_OUTPUT_PARAMS : imf
14 #
15 # -----------------
16 # BASE PARAMETERS :
17 # -----------------
18 #
19 # MISSION_ID : NONE
20 #
21 # INSTRUMENT_ID : NONE
22 #
23 # DATASET_ID : ace-imf-all
24 # DATASET_NAME : final / prelim
25 # DATASET_DESCRIPTION : Interplanetary Magnetic Field 16-sec Level2/PRELIM Data
26 # DATASET_SOURCE : CDPP/DDServer
27 # DATASET_GLOBAL_START : 1997-09-02T00:00:12.000
28 # DATASET_GLOBAL_STOP : 2017-09-16T23:59:57.000
29 # DATASET_MIN_SAMPLING : 16
30 # DATASET_MAX_SAMPLING : 16
31 # DATASET_CAVEATS :
32 The quality of ACE level 2 data is such that it is suitable for serious scientific study. However, to avoid confusion and misunderstanding, it is recommended that users consult with the appropriate ACE team members before publishing work derived from the data. The ACE team has worked hard to ensure that the level 2 data are free from errors, but the team cannot accept responsibility for erroneous data, or for misunderstandings about how the data may be used. This is especially true if the appropriate ACE team members are not consulted before publication. At the very least, preprints should be forwarded to the ACE team before publication.
33
34 # DATASET_ACKNOWLEDGEMENT :
35 Please acknowledge the ACE/MAG instrument team and the ACE Science Center
36
37 #
38 # PARAMETER_ID : imf
39 # PARAMETER_NAME : imf
40 # PARAMETER_SHORT_NAME : b_gse
41 # PARAMETER_COMPONENTS : bx,by,bz
42 # PARAMETER_UNITS : nT
43 # PARAMETER_COORDINATE_SYSTEM : GSE
44 # PARAMETER_TENSOR_ORDER : 0
45 # PARAMETER_SI_CONVERSION : 1e-9>T
46 # PARAMETER_TABLE : None
47 # PARAMETER_FILL_VALUE : nan
48 # PARAMETER_UCD : phys.magField
49 #
50 #
51 # ---------------
52 # INTERVAL INFO :
53 # ---------------
54 # INTERVAL_START : 2013-09-23T08:58:12.000
55 # INTERVAL_STOP : 2013-09-23T09:11:48.000
56 #
57 # ------
58 # DATA :
59 # ------
60 # DATA_COLUMNS : AMDA_TIME, imf[0]
61 #
62 2013-09-23T09:00:30.000 -2.83950 1.05141 3.01547
4 2013-09-23T09:00:30.000 -2.83950 1.05141 3.01547
63 2013-09-23T09:01:30.000 -2.71850
5 2013-09-23T09:01:30.000 -2.71850
64 2013-09-23T09:02:30.000 -2.52150 No newline at end of file
6 2013-09-23T09:02:30.000 -2.52150
@@ -1,71 +1,13
1 # -----------
1 #Sampling Time : 60
2 # AMDA INFO :
2 #Time Format : YYYY-MM-DDThh:mm:ss.mls
3 # -----------
3 #imf(0) - Type : Local Parameter @ CDPP/AMDA - Name : bx_gse - Units : nT - Size : 1 - Frame : GSE - Mission : ACE - Instrument : MFI - Dataset : mfi_final-prelim
4 # AMDA_ABOUT : Created by CDPP/AMDA(c)
5 # AMDA_VERSION : 3.5.0
6 # AMDA_ACKNOWLEDGEMENT : CDPP/AMDA Team
7 #
8 # --------------
9 # REQUEST INFO :
10 # --------------
11 # REQUEST_STRUCTURE : one-file-per-parameter-per-interval
12 # REQUEST_TIME_FORMAT : ISO 8601
13 # REQUEST_OUTPUT_PARAMS : imf
14 #
15 # -----------------
16 # BASE PARAMETERS :
17 # -----------------
18 #
19 # MISSION_ID : NONE
20 #
21 # INSTRUMENT_ID : NONE
22 #
23 # DATASET_ID : ace-imf-all
24 # DATASET_NAME : final / prelim
25 # DATASET_DESCRIPTION : Interplanetary Magnetic Field 16-sec Level2/PRELIM Data
26 # DATASET_SOURCE : CDPP/DDServer
27 # DATASET_GLOBAL_START : 1997-09-02T00:00:12.000
28 # DATASET_GLOBAL_STOP : 2017-09-16T23:59:57.000
29 # DATASET_MIN_SAMPLING : 16
30 # DATASET_MAX_SAMPLING : 16
31 # DATASET_CAVEATS :
32 The quality of ACE level 2 data is such that it is suitable for serious scientific study. However, to avoid confusion and misunderstanding, it is recommended that users consult with the appropriate ACE team members before publishing work derived from the data. The ACE team has worked hard to ensure that the level 2 data are free from errors, but the team cannot accept responsibility for erroneous data, or for misunderstandings about how the data may be used. This is especially true if the appropriate ACE team members are not consulted before publication. At the very least, preprints should be forwarded to the ACE team before publication.
33
34 # DATASET_ACKNOWLEDGEMENT :
35 Please acknowledge the ACE/MAG instrument team and the ACE Science Center
36
37 #
38 # PARAMETER_ID : imf
39 # PARAMETER_NAME : imf
40 # PARAMETER_SHORT_NAME : b_gse
41 # PARAMETER_COMPONENTS : bx,by,bz
42 # PARAMETER_UNITS : nT
43 # PARAMETER_COORDINATE_SYSTEM : GSE
44 # PARAMETER_TENSOR_ORDER : 0
45 # PARAMETER_SI_CONVERSION : 1e-9>T
46 # PARAMETER_TABLE : None
47 # PARAMETER_FILL_VALUE : nan
48 # PARAMETER_UCD : phys.magField
49 #
50 #
51 # ---------------
52 # INTERVAL INFO :
53 # ---------------
54 # INTERVAL_START : 2013-09-23T08:58:12.000
55 # INTERVAL_STOP : 2013-09-23T09:11:48.000
56 #
57 # ------
58 # DATA :
59 # ------
60 # DATA_COLUMNS : AMDA_TIME, imf[0]
61 #
62 2013-09-23T09:00:30.000 -2.83950
4 2013-09-23T09:00:30.000 -2.83950
63 2013-09-23T09:01:30.000 -2.71850
5 2013-09-23T09:01:30.000 -2.71850
64 2013-09-23T09:02:30.000 -2.52150
6 2013-09-23T09:02:30.000 -2.52150
65 2013-09-23T09:03:30.000 -2.57633
7 2013-09-23T09:03:30.000 -2.57633
66 2013-09-23T09:04:30.000 -2.58050
8 2013-09-23T09:04:30.000 -2.58050
67 2013-09-23T09:05:30.000 -2.48325
9 2013-09-23T09:05:30.000 -2.48325
68 2013-09-23T09:06:30.000 -2.63025
10 2013-09-23T09:06:30.000 -2.63025
69 2013-09-23T09:07:30.000 -2.55800
11 2013-09-23T09:07:30.000 -2.55800
70 2013-09-23T09:08:30.000 -2.43250
12 2013-09-23T09:08:30.000 -2.43250
71 2013-09-23T09:09:30.000 -2.42200 No newline at end of file
13 2013-09-23T09:09:30.000 -2.42200
@@ -1,71 +1,12
1 # -----------
1 #Time Format : YYYY-MM-DDThh:mm:ss.mls
2 # AMDA INFO :
2 #imf - Type : Local Parameter @ CDPP/AMDA - Name : imf_gse - Units : nT - Size : 3 - Frame : GSE - Mission : ACE - Instrument : MFI - Dataset : mfi_final-prelim
3 # -----------
4 # AMDA_ABOUT : Created by CDPP/AMDA(c)
5 # AMDA_VERSION : 3.5.0
6 # AMDA_ACKNOWLEDGEMENT : CDPP/AMDA Team
7 #
8 # --------------
9 # REQUEST INFO :
10 # --------------
11 # REQUEST_STRUCTURE : one-file-per-parameter-per-interval
12 # REQUEST_TIME_FORMAT : ISO 8601
13 # REQUEST_OUTPUT_PARAMS : imf
14 #
15 # -----------------
16 # BASE PARAMETERS :
17 # -----------------
18 #
19 # MISSION_ID : NONE
20 #
21 # INSTRUMENT_ID : NONE
22 #
23 # DATASET_ID : ace-imf-all
24 # DATASET_NAME : final / prelim
25 # DATASET_DESCRIPTION : Interplanetary Magnetic Field 16-sec Level2/PRELIM Data
26 # DATASET_SOURCE : CDPP/DDServer
27 # DATASET_GLOBAL_START : 1997-09-02T00:00:12.000
28 # DATASET_GLOBAL_STOP : 2017-09-16T23:59:57.000
29 # DATASET_MIN_SAMPLING : 16
30 # DATASET_MAX_SAMPLING : 16
31 # DATASET_CAVEATS :
32 The quality of ACE level 2 data is such that it is suitable for serious scientific study. However, to avoid confusion and misunderstanding, it is recommended that users consult with the appropriate ACE team members before publishing work derived from the data. The ACE team has worked hard to ensure that the level 2 data are free from errors, but the team cannot accept responsibility for erroneous data, or for misunderstandings about how the data may be used. This is especially true if the appropriate ACE team members are not consulted before publication. At the very least, preprints should be forwarded to the ACE team before publication.
33
34 # DATASET_ACKNOWLEDGEMENT :
35 Please acknowledge the ACE/MAG instrument team and the ACE Science Center
36
37 #
38 # PARAMETER_ID : imf
39 # PARAMETER_NAME : imf
40 # PARAMETER_SHORT_NAME : b_gse
41 # PARAMETER_COMPONENTS : bx,by,bz
42 # PARAMETER_UNITS : nT
43 # PARAMETER_COORDINATE_SYSTEM : GSE
44 # PARAMETER_TENSOR_ORDER : 0
45 # PARAMETER_SI_CONVERSION : 1e-9>T
46 # PARAMETER_TABLE : None
47 # PARAMETER_FILL_VALUE : nan
48 # PARAMETER_UCD : phys.magField
49 #
50 #
51 # ---------------
52 # INTERVAL INFO :
53 # ---------------
54 # INTERVAL_START : 2012-09-27T06:47:56.000
55 # INTERVAL_STOP : 2012-09-27T08:09:32.000
56 #
57 # ------
58 # DATA :
59 # ------
60 # DATA_COLUMNS : AMDA_TIME, imf[0], imf[1], imf[2]
61 #
62 2013-07-02T09:13:50.000 -0.332000 3.20600 0.0580000
3 2013-07-02T09:13:50.000 -0.332000 3.20600 0.0580000
63 2013-07-02T09:14:06.000 -1.01100 2.99900 0.496000
4 2013-07-02T09:14:06.000 -1.01100 2.99900 0.496000
64 2013-07-02T09:14:22.000 -1.45700 2.78500 1.01800
5 2013-07-02T09:14:22.000 -1.45700 2.78500 1.01800
65 2013-07-02T09:14:38.000 -1.29300 2.73600 1.48500
6 2013-07-02T09:14:38.000 -1.29300 2.73600 1.48500
66 2013-07-02T09:14:54.000 -1.21700 2.61200 1.66200
7 2013-07-02T09:14:54.000 -1.21700 2.61200 1.66200
67 2013-07-02T09:15:10.000 -1.44300 2.56400 1.50500
8 2013-07-02T09:15:10.000 -1.44300 2.56400 1.50500
68 2013-07-02T09:15:26.000 -1.27800 2.89200 1.16800
9 2013-07-02T09:15:26.000 -1.27800 2.89200 1.16800
69 2013-07-02T09:15:42.000 -1.20200 2.86200 1.24400
10 2013-07-02T09:15:42.000 -1.20200 2.86200 1.24400
70 2013-07-02T09:15:58.000 -1.22000 2.85900 1.15000
11 2013-07-02T09:15:58.000 -1.22000 2.85900 1.15000
71 2013-07-02T09:16:14.000 -1.25900 2.76400 1.35800 No newline at end of file
12 2013-07-02T09:16:14.000 -1.25900 2.76400 1.35800
@@ -1,64 +1,6
1 # -----------
1 #Sampling Time : 60
2 # AMDA INFO :
2 #Time Format : YYYY-MM-DDThh:mm:ss.mls
3 # -----------
3 #imf(0) - Type : Local Parameter @ CDPP/AMDA - Name : bx_gse - Units : nT - Size : 1 - Frame : GSE - Mission : ACE - Instrument : MFI - Dataset : mfi_final-prelim
4 # AMDA_ABOUT : Created by CDPP/AMDA(c)
5 # AMDA_VERSION : 3.5.0
6 # AMDA_ACKNOWLEDGEMENT : CDPP/AMDA Team
7 #
8 # --------------
9 # REQUEST INFO :
10 # --------------
11 # REQUEST_STRUCTURE : one-file-per-parameter-per-interval
12 # REQUEST_TIME_FORMAT : ISO 8601
13 # REQUEST_OUTPUT_PARAMS : imf
14 #
15 # -----------------
16 # BASE PARAMETERS :
17 # -----------------
18 #
19 # MISSION_ID : NONE
20 #
21 # INSTRUMENT_ID : NONE
22 #
23 # DATASET_ID : ace-imf-all
24 # DATASET_NAME : final / prelim
25 # DATASET_DESCRIPTION : Interplanetary Magnetic Field 16-sec Level2/PRELIM Data
26 # DATASET_SOURCE : CDPP/DDServer
27 # DATASET_GLOBAL_START : 1997-09-02T00:00:12.000
28 # DATASET_GLOBAL_STOP : 2017-09-16T23:59:57.000
29 # DATASET_MIN_SAMPLING : 16
30 # DATASET_MAX_SAMPLING : 16
31 # DATASET_CAVEATS :
32 The quality of ACE level 2 data is such that it is suitable for serious scientific study. However, to avoid confusion and misunderstanding, it is recommended that users consult with the appropriate ACE team members before publishing work derived from the data. The ACE team has worked hard to ensure that the level 2 data are free from errors, but the team cannot accept responsibility for erroneous data, or for misunderstandings about how the data may be used. This is especially true if the appropriate ACE team members are not consulted before publication. At the very least, preprints should be forwarded to the ACE team before publication.
33
34 # DATASET_ACKNOWLEDGEMENT :
35 Please acknowledge the ACE/MAG instrument team and the ACE Science Center
36
37 #
38 # PARAMETER_ID : imf
39 # PARAMETER_NAME : imf
40 # PARAMETER_SHORT_NAME : b_gse
41 # PARAMETER_COMPONENTS : bx,by,bz
42 # PARAMETER_UNITS : nT
43 # PARAMETER_COORDINATE_SYSTEM : GSE
44 # PARAMETER_TENSOR_ORDER : 0
45 # PARAMETER_SI_CONVERSION : 1e-9>T
46 # PARAMETER_TABLE : None
47 # PARAMETER_FILL_VALUE : nan
48 # PARAMETER_UCD : phys.magField
49 #
50 #
51 # ---------------
52 # INTERVAL INFO :
53 # ---------------
54 # INTERVAL_START : 2013-09-23T08:58:12.000
55 # INTERVAL_STOP : 2013-09-23T09:11:48.000
56 #
57 # ------
58 # DATA :
59 # ------
60 # DATA_COLUMNS : AMDA_TIME, imf[0]
61 #
62 23/09/2013 07:50:30 -2.83950
4 23/09/2013 07:50:30 -2.83950
63 2013-09-23T09:01:30.000 -2.71850
5 2013-09-23T09:01:30.000 -2.71850
64 2013-09-23T09:02:30.000 -2.52150 No newline at end of file
6 2013-09-23T09:02:30.000 -2.52150
@@ -1,64 +1,6
1 # -----------
1 #Sampling Time : 60
2 # AMDA INFO :
2 #Time Format : YYYY-MM-DDThh:mm:ss.mls
3 # -----------
3 #Wrong unit comment
4 # AMDA_ABOUT : Created by CDPP/AMDA(c)
5 # AMDA_VERSION : 3.5.0
6 # AMDA_ACKNOWLEDGEMENT : CDPP/AMDA Team
7 #
8 # --------------
9 # REQUEST INFO :
10 # --------------
11 # REQUEST_STRUCTURE : one-file-per-parameter-per-interval
12 # REQUEST_TIME_FORMAT : ISO 8601
13 # REQUEST_OUTPUT_PARAMS : imf
14 #
15 # -----------------
16 # BASE PARAMETERS :
17 # -----------------
18 #
19 # MISSION_ID : NONE
20 #
21 # INSTRUMENT_ID : NONE
22 #
23 # DATASET_ID : ace-imf-all
24 # DATASET_NAME : final / prelim
25 # DATASET_DESCRIPTION : Interplanetary Magnetic Field 16-sec Level2/PRELIM Data
26 # DATASET_SOURCE : CDPP/DDServer
27 # DATASET_GLOBAL_START : 1997-09-02T00:00:12.000
28 # DATASET_GLOBAL_STOP : 2017-09-16T23:59:57.000
29 # DATASET_MIN_SAMPLING : 16
30 # DATASET_MAX_SAMPLING : 16
31 # DATASET_CAVEATS :
32 The quality of ACE level 2 data is such that it is suitable for serious scientific study. However, to avoid confusion and misunderstanding, it is recommended that users consult with the appropriate ACE team members before publishing work derived from the data. The ACE team has worked hard to ensure that the level 2 data are free from errors, but the team cannot accept responsibility for erroneous data, or for misunderstandings about how the data may be used. This is especially true if the appropriate ACE team members are not consulted before publication. At the very least, preprints should be forwarded to the ACE team before publication.
33
34 # DATASET_ACKNOWLEDGEMENT :
35 Please acknowledge the ACE/MAG instrument team and the ACE Science Center
36
37 #
38 # PARAMETER_ID : imf
39 # PARAMETER_NAME : imf
40 # PARAMETER_SHORT_NAME : b_gse
41 # PARAMETER_COMPONENTS : bx,by,bz
42 # PARAM_UNITS : wrong unit line
43 # PARAMETER_COORDINATE_SYSTEM : GSE
44 # PARAMETER_TENSOR_ORDER : 0
45 # PARAMETER_SI_CONVERSION : 1e-9>T
46 # PARAMETER_TABLE : None
47 # PARAMETER_FILL_VALUE : nan
48 # PARAMETER_UCD : phys.magField
49 #
50 #
51 # ---------------
52 # INTERVAL INFO :
53 # ---------------
54 # INTERVAL_START : 2013-09-23T08:58:12.000
55 # INTERVAL_STOP : 2013-09-23T09:11:48.000
56 #
57 # ------
58 # DATA :
59 # ------
60 # DATA_COLUMNS : AMDA_TIME, imf[0]
61 #
62 2013-09-23T09:00:30.000 -2.83950
4 2013-09-23T09:00:30.000 -2.83950
63 2013-09-23T09:01:30.000 -2.71850
5 2013-09-23T09:01:30.000 -2.71850
64 2013-09-23T09:02:30.000 -2.52150 No newline at end of file
6 2013-09-23T09:02:30.000 -2.52150
@@ -1,64 +1,6
1 # -----------
1 #Sampling Time : 60
2 # AMDA INFO :
2 #Time Format : YYYY-MM-DDThh:mm:ss.mls
3 # -----------
3 #imf(0) - Type : Local Parameter @ CDPP/AMDA - Name : bx_gse - Units : nT - Size : 1 - Frame : GSE - Mission : ACE - Instrument : MFI - Dataset : mfi_final-prelim
4 # AMDA_ABOUT : Created by CDPP/AMDA(c)
5 # AMDA_VERSION : 3.5.0
6 # AMDA_ACKNOWLEDGEMENT : CDPP/AMDA Team
7 #
8 # --------------
9 # REQUEST INFO :
10 # --------------
11 # REQUEST_STRUCTURE : one-file-per-parameter-per-interval
12 # REQUEST_TIME_FORMAT : ISO 8601
13 # REQUEST_OUTPUT_PARAMS : imf
14 #
15 # -----------------
16 # BASE PARAMETERS :
17 # -----------------
18 #
19 # MISSION_ID : NONE
20 #
21 # INSTRUMENT_ID : NONE
22 #
23 # DATASET_ID : ace-imf-all
24 # DATASET_NAME : final / prelim
25 # DATASET_DESCRIPTION : Interplanetary Magnetic Field 16-sec Level2/PRELIM Data
26 # DATASET_SOURCE : CDPP/DDServer
27 # DATASET_GLOBAL_START : 1997-09-02T00:00:12.000
28 # DATASET_GLOBAL_STOP : 2017-09-16T23:59:57.000
29 # DATASET_MIN_SAMPLING : 16
30 # DATASET_MAX_SAMPLING : 16
31 # DATASET_CAVEATS :
32 The quality of ACE level 2 data is such that it is suitable for serious scientific study. However, to avoid confusion and misunderstanding, it is recommended that users consult with the appropriate ACE team members before publishing work derived from the data. The ACE team has worked hard to ensure that the level 2 data are free from errors, but the team cannot accept responsibility for erroneous data, or for misunderstandings about how the data may be used. This is especially true if the appropriate ACE team members are not consulted before publication. At the very least, preprints should be forwarded to the ACE team before publication.
33
34 # DATASET_ACKNOWLEDGEMENT :
35 Please acknowledge the ACE/MAG instrument team and the ACE Science Center
36
37 #
38 # PARAMETER_ID : imf
39 # PARAMETER_NAME : imf
40 # PARAMETER_SHORT_NAME : b_gse
41 # PARAMETER_COMPONENTS : bx,by,bz
42 # PARAMETER_UNITS : nT
43 # PARAMETER_COORDINATE_SYSTEM : GSE
44 # PARAMETER_TENSOR_ORDER : 0
45 # PARAMETER_SI_CONVERSION : 1e-9>T
46 # PARAMETER_TABLE : None
47 # PARAMETER_FILL_VALUE : nan
48 # PARAMETER_UCD : phys.magField
49 #
50 #
51 # ---------------
52 # INTERVAL INFO :
53 # ---------------
54 # INTERVAL_START : 2013-09-23T08:58:12.000
55 # INTERVAL_STOP : 2013-09-23T09:11:48.000
56 #
57 # ------
58 # DATA :
59 # ------
60 # DATA_COLUMNS : AMDA_TIME, imf[0]
61 #
62 2013-09-23T09:00:30.000 abc
4 2013-09-23T09:00:30.000 abc
63 2013-09-23T09:01:30.000 -2.71850
5 2013-09-23T09:01:30.000 -2.71850
64 2013-09-23T09:02:30.000 -2.52150 No newline at end of file
6 2013-09-23T09:02:30.000 -2.52150
@@ -1,197 +1,195
1 #include "AmdaProvider.h"
1 #include "AmdaProvider.h"
2 #include "AmdaResultParser.h"
2 #include "AmdaResultParser.h"
3
3
4 #include "SqpApplication.h"
4 #include "SqpApplication.h"
5 #include <Data/DataSeries.h>
5 #include <Data/DataSeries.h>
6 #include <Data/IDataSeries.h>
6 #include <Data/IDataSeries.h>
7 #include <Data/ScalarSeries.h>
7 #include <Data/ScalarSeries.h>
8 #include <Time/TimeController.h>
8 #include <Time/TimeController.h>
9 #include <Variable/Variable.h>
9 #include <Variable/Variable.h>
10 #include <Variable/VariableController.h>
10 #include <Variable/VariableController.h>
11
11
12 #include <QObject>
12 #include <QObject>
13 #include <QtTest>
13 #include <QtTest>
14
14
15 #include <memory>
15 #include <memory>
16
16
17 // TEST with REF:
17 // TEST with REF:
18 // AmdaData-2012-01-01-12-00-00_2012-01-03-12-00-00
18 // AmdaData-2012-01-01-12-00-00_2012-01-03-12-00-00
19 // imf(0) - Type : Local Parameter @ CDPP/AMDA -
19 // imf(0) - Type : Local Parameter @ CDPP/AMDA -
20 // Name : bx_gse - Units : nT - Size : 1 -
20 // Name : bx_gse - Units : nT - Size : 1 -
21 // Frame : GSE - Mission : ACE -
21 // Frame : GSE - Mission : ACE -
22 // Instrument : MFI - Dataset : mfi_final-prelim
22 // Instrument : MFI - Dataset : mfi_final-prelim
23 // REFERENCE DOWNLOAD FILE =
23 // REFERENCE DOWNLOAD FILE =
24 // http://amda.irap.omp.eu/php/rest/getParameter.php?startTime=2012-01-01T12:00:00&stopTime=2012-01-03T12:00:00&parameterID=imf(0)&outputFormat=ASCII&timeFormat=ISO8601&gzip=0
24 // http://amda.irap.omp.eu/php/rest/getParameter.php?startTime=2012-01-01T12:00:00&stopTime=2012-01-03T12:00:00&parameterID=imf(0)&outputFormat=ASCII&timeFormat=ISO8601&gzip=0
25
25
26 namespace {
26 namespace {
27
27
28 /// Path for the tests
28 /// Path for the tests
29 const auto TESTS_RESOURCES_PATH
29 const auto TESTS_RESOURCES_PATH
30 = QFileInfo{QString{AMDA_TESTS_RESOURCES_DIR}, "TestAmdaAcquisition"}.absoluteFilePath();
30 = QFileInfo{QString{AMDA_TESTS_RESOURCES_DIR}, "TestAmdaAcquisition"}.absoluteFilePath();
31
31
32 const auto TESTS_AMDA_REF_FILE = QString{"AmdaData-2012-01-01-12-00-00_2012-01-03-12-00-00.txt"};
32 const auto TESTS_AMDA_REF_FILE = QString{"AmdaData-2012-01-01-12-00-00_2012-01-03-12-00-00.txt"};
33
33
34 template <typename T>
34 template <typename T>
35 bool compareDataSeries(std::shared_ptr<IDataSeries> candidate, SqpRange candidateCacheRange,
35 bool compareDataSeries(std::shared_ptr<IDataSeries> candidate, SqpRange candidateCacheRange,
36 std::shared_ptr<IDataSeries> reference)
36 std::shared_ptr<IDataSeries> reference)
37 {
37 {
38 auto compareLambda = [](const auto &it1, const auto &it2) {
38 auto compareLambda = [](const auto &it1, const auto &it2) {
39 return (it1.x() == it2.x()) && (it1.value() == it2.value());
39 return (it1.x() == it2.x()) && (it1.value() == it2.value());
40 };
40 };
41
41
42 auto candidateDS = std::dynamic_pointer_cast<T>(candidate);
42 auto candidateDS = std::dynamic_pointer_cast<T>(candidate);
43 auto referenceDS = std::dynamic_pointer_cast<T>(reference);
43 auto referenceDS = std::dynamic_pointer_cast<T>(reference);
44
44
45 if (candidateDS && referenceDS) {
45 if (candidateDS && referenceDS) {
46
46
47 auto itRefs
47 auto itRefs
48 = referenceDS->xAxisRange(candidateCacheRange.m_TStart, candidateCacheRange.m_TEnd);
48 = referenceDS->xAxisRange(candidateCacheRange.m_TStart, candidateCacheRange.m_TEnd);
49 qDebug() << " DISTANCE" << std::distance(candidateDS->cbegin(), candidateDS->cend())
49 qDebug() << " DISTANCE" << std::distance(candidateDS->cbegin(), candidateDS->cend())
50 << std::distance(itRefs.first, itRefs.second);
50 << std::distance(itRefs.first, itRefs.second);
51
51
52 // auto xcValue = candidateDS->valuesData()->data();
52 // auto xcValue = candidateDS->valuesData()->data();
53 // auto dist = std::distance(itRefs.first, itRefs.second);
53 // auto dist = std::distance(itRefs.first, itRefs.second);
54 // auto it = itRefs.first;
54 // auto it = itRefs.first;
55 // for (auto i = 0; i < dist - 1; ++i) {
55 // for (auto i = 0; i < dist - 1; ++i) {
56 // ++it;
56 // ++it;
57 // qInfo() << "END:" << it->value();
57 // qInfo() << "END:" << it->value();
58 // }
58 // }
59 // qDebug() << "END:" << it->value() << xcValue.last();
59 // qDebug() << "END:" << it->value() << xcValue.last();
60
60
61 return std::equal(candidateDS->cbegin(), candidateDS->cend(), itRefs.first, itRefs.second,
61 return std::equal(candidateDS->cbegin(), candidateDS->cend(), itRefs.first, itRefs.second,
62 compareLambda);
62 compareLambda);
63 }
63 }
64 else {
64 else {
65 return false;
65 return false;
66 }
66 }
67 }
67 }
68 }
68 }
69
69
70 class TestAmdaAcquisition : public QObject {
70 class TestAmdaAcquisition : public QObject {
71 Q_OBJECT
71 Q_OBJECT
72
72
73 private slots:
73 private slots:
74 void testAcquisition();
74 void testAcquisition();
75 };
75 };
76
76
77 void TestAmdaAcquisition::testAcquisition()
77 void TestAmdaAcquisition::testAcquisition()
78 {
78 {
79 /// @todo: update test to be compatible with AMDA v2
80
81 // READ the ref file:
79 // READ the ref file:
82 auto filePath = QFileInfo{TESTS_RESOURCES_PATH, TESTS_AMDA_REF_FILE}.absoluteFilePath();
80 auto filePath = QFileInfo{TESTS_RESOURCES_PATH, TESTS_AMDA_REF_FILE}.absoluteFilePath();
83 auto results = AmdaResultParser::readTxt(filePath, AmdaResultParser::ValueType::SCALAR);
81 auto results = AmdaResultParser::readTxt(filePath, AmdaResultParser::ValueType::SCALAR);
84
82
85 auto provider = std::make_shared<AmdaProvider>();
83 auto provider = std::make_shared<AmdaProvider>();
86 auto timeController = std::make_unique<TimeController>();
84 auto timeController = std::make_unique<TimeController>();
87
85
88 auto varRS = QDateTime{QDate{2012, 01, 02}, QTime{2, 3, 0, 0}};
86 auto varRS = QDateTime{QDate{2012, 01, 02}, QTime{2, 3, 0, 0}};
89 auto varRE = QDateTime{QDate{2012, 01, 02}, QTime{2, 4, 0, 0}};
87 auto varRE = QDateTime{QDate{2012, 01, 02}, QTime{2, 4, 0, 0}};
90
88
91 auto sqpR = SqpRange{DateUtils::secondsSinceEpoch(varRS), DateUtils::secondsSinceEpoch(varRE)};
89 auto sqpR = SqpRange{DateUtils::secondsSinceEpoch(varRS), DateUtils::secondsSinceEpoch(varRE)};
92
90
93 timeController->onTimeToUpdate(sqpR);
91 timeController->onTimeToUpdate(sqpR);
94
92
95 QVariantHash metaData;
93 QVariantHash metaData;
96 metaData.insert("dataType", "scalar");
94 metaData.insert("dataType", "scalar");
97 metaData.insert("xml:id", "imf(0)");
95 metaData.insert("xml:id", "imf(0)");
98
96
99 VariableController vc;
97 VariableController vc;
100 vc.setTimeController(timeController.get());
98 vc.setTimeController(timeController.get());
101
99
102 auto var = vc.createVariable("bx_gse", metaData, provider);
100 auto var = vc.createVariable("bx_gse", metaData, provider);
103
101
104 // 1 : Variable creation
102 // 1 : Variable creation
105
103
106 qDebug() << " 1: TIMECONTROLLER" << timeController->dateTime();
104 qDebug() << " 1: TIMECONTROLLER" << timeController->dateTime();
107 qDebug() << " 1: RANGE " << var->range();
105 qDebug() << " 1: RANGE " << var->range();
108 qDebug() << " 1: CACHERANGE" << var->cacheRange();
106 qDebug() << " 1: CACHERANGE" << var->cacheRange();
109
107
110 // wait for 10 sec before asking next request toi permit asynchrone process to finish.
108 // wait for 10 sec before asking next request toi permit asynchrone process to finish.
111 auto timeToWaitMs = 10000;
109 auto timeToWaitMs = 10000;
112
110
113 QEventLoop loop;
111 QEventLoop loop;
114 QTimer::singleShot(timeToWaitMs, &loop, &QEventLoop::quit);
112 QTimer::singleShot(timeToWaitMs, &loop, &QEventLoop::quit);
115 loop.exec();
113 loop.exec();
116
114
117 // Tests on acquisition operation
115 // Tests on acquisition operation
118
116
119 int count = 1;
117 int count = 1;
120
118
121 auto requestDataLoading = [&vc, var, timeToWaitMs, results, &count](auto tStart, auto tEnd) {
119 auto requestDataLoading = [&vc, var, timeToWaitMs, results, &count](auto tStart, auto tEnd) {
122 ++count;
120 ++count;
123
121
124 auto nextSqpR
122 auto nextSqpR
125 = SqpRange{DateUtils::secondsSinceEpoch(tStart), DateUtils::secondsSinceEpoch(tEnd)};
123 = SqpRange{DateUtils::secondsSinceEpoch(tStart), DateUtils::secondsSinceEpoch(tEnd)};
126 vc.onRequestDataLoading(QVector<std::shared_ptr<Variable> >{} << var, nextSqpR,
124 vc.onRequestDataLoading(QVector<std::shared_ptr<Variable> >{} << var, nextSqpR,
127 var->range(), true);
125 var->range(), true);
128
126
129 QEventLoop loop;
127 QEventLoop loop;
130 QTimer::singleShot(timeToWaitMs, &loop, &QEventLoop::quit);
128 QTimer::singleShot(timeToWaitMs, &loop, &QEventLoop::quit);
131 loop.exec();
129 loop.exec();
132
130
133 qInfo() << count << "RANGE " << var->range();
131 qInfo() << count << "RANGE " << var->range();
134 qInfo() << count << "CACHERANGE" << var->cacheRange();
132 qInfo() << count << "CACHERANGE" << var->cacheRange();
135
133
136 QCOMPARE(var->range().m_TStart, nextSqpR.m_TStart);
134 QCOMPARE(var->range().m_TStart, nextSqpR.m_TStart);
137 QCOMPARE(var->range().m_TEnd, nextSqpR.m_TEnd);
135 QCOMPARE(var->range().m_TEnd, nextSqpR.m_TEnd);
138
136
139 // Verify dataserie
137 // Verify dataserie
140 QVERIFY(compareDataSeries<ScalarSeries>(var->dataSeries(), var->cacheRange(), results));
138 QVERIFY(compareDataSeries<ScalarSeries>(var->dataSeries(), var->cacheRange(), results));
141
139
142 };
140 };
143
141
144 // 2 : pan (jump) left for one hour
142 // 2 : pan (jump) left for one hour
145 auto nextVarRS = QDateTime{QDate{2012, 01, 02}, QTime{2, 1, 0, 0}};
143 auto nextVarRS = QDateTime{QDate{2012, 01, 02}, QTime{2, 1, 0, 0}};
146 auto nextVarRE = QDateTime{QDate{2012, 01, 02}, QTime{2, 2, 0, 0}};
144 auto nextVarRE = QDateTime{QDate{2012, 01, 02}, QTime{2, 2, 0, 0}};
147 // requestDataLoading(nextVarRS, nextVarRE);
145 requestDataLoading(nextVarRS, nextVarRE);
148
146
149
147
150 // 3 : pan (jump) right for one hour
148 // 3 : pan (jump) right for one hour
151 nextVarRS = QDateTime{QDate{2012, 01, 02}, QTime{2, 5, 0, 0}};
149 nextVarRS = QDateTime{QDate{2012, 01, 02}, QTime{2, 5, 0, 0}};
152 nextVarRE = QDateTime{QDate{2012, 01, 02}, QTime{2, 6, 0, 0}};
150 nextVarRE = QDateTime{QDate{2012, 01, 02}, QTime{2, 6, 0, 0}};
153 // requestDataLoading(nextVarRS, nextVarRE);
151 requestDataLoading(nextVarRS, nextVarRE);
154
152
155 // 4 : pan (overlay) right for 30 min
153 // 4 : pan (overlay) right for 30 min
156 nextVarRS = QDateTime{QDate{2012, 01, 02}, QTime{2, 5, 30, 0}};
154 nextVarRS = QDateTime{QDate{2012, 01, 02}, QTime{2, 5, 30, 0}};
157 nextVarRE = QDateTime{QDate{2012, 01, 02}, QTime{2, 6, 30, 0}};
155 nextVarRE = QDateTime{QDate{2012, 01, 02}, QTime{2, 6, 30, 0}};
158 // requestDataLoading(nextVarRS, nextVarRE);
156 // requestDataLoading(nextVarRS, nextVarRE);
159
157
160 // 5 : pan (overlay) left for 30 min
158 // 5 : pan (overlay) left for 30 min
161 nextVarRS = QDateTime{QDate{2012, 01, 02}, QTime{2, 5, 0, 0}};
159 nextVarRS = QDateTime{QDate{2012, 01, 02}, QTime{2, 5, 0, 0}};
162 nextVarRE = QDateTime{QDate{2012, 01, 02}, QTime{2, 6, 0, 0}};
160 nextVarRE = QDateTime{QDate{2012, 01, 02}, QTime{2, 6, 0, 0}};
163 // requestDataLoading(nextVarRS, nextVarRE);
161 // requestDataLoading(nextVarRS, nextVarRE);
164
162
165 // 6 : pan (overlay) left for 30 min - BIS
163 // 6 : pan (overlay) left for 30 min - BIS
166 nextVarRS = QDateTime{QDate{2012, 01, 02}, QTime{2, 4, 30, 0}};
164 nextVarRS = QDateTime{QDate{2012, 01, 02}, QTime{2, 4, 30, 0}};
167 nextVarRE = QDateTime{QDate{2012, 01, 02}, QTime{2, 5, 30, 0}};
165 nextVarRE = QDateTime{QDate{2012, 01, 02}, QTime{2, 5, 30, 0}};
168 // requestDataLoading(nextVarRS, nextVarRE);
166 // requestDataLoading(nextVarRS, nextVarRE);
169
167
170 // 7 : Zoom in Inside 20 min range
168 // 7 : Zoom in Inside 20 min range
171 nextVarRS = QDateTime{QDate{2012, 01, 02}, QTime{2, 4, 50, 0}};
169 nextVarRS = QDateTime{QDate{2012, 01, 02}, QTime{2, 4, 50, 0}};
172 nextVarRE = QDateTime{QDate{2012, 01, 02}, QTime{2, 5, 10, 0}};
170 nextVarRE = QDateTime{QDate{2012, 01, 02}, QTime{2, 5, 10, 0}};
173 // requestDataLoading(nextVarRS, nextVarRE);
171 // requestDataLoading(nextVarRS, nextVarRE);
174
172
175 // 8 : Zoom out Inside 2 hours range
173 // 8 : Zoom out Inside 2 hours range
176 nextVarRS = QDateTime{QDate{2012, 01, 02}, QTime{2, 4, 0, 0}};
174 nextVarRS = QDateTime{QDate{2012, 01, 02}, QTime{2, 4, 0, 0}};
177 nextVarRE = QDateTime{QDate{2012, 01, 02}, QTime{2, 6, 0, 0}};
175 nextVarRE = QDateTime{QDate{2012, 01, 02}, QTime{2, 6, 0, 0}};
178 // requestDataLoading(nextVarRS, nextVarRE);
176 // requestDataLoading(nextVarRS, nextVarRE);
179
177
180
178
181 // Close the app after 10 sec
179 // Close the app after 10 sec
182 QTimer::singleShot(timeToWaitMs, &loop, &QEventLoop::quit);
180 QTimer::singleShot(timeToWaitMs, &loop, &QEventLoop::quit);
183 loop.exec();
181 loop.exec();
184 }
182 }
185
183
186 int main(int argc, char *argv[])
184 int main(int argc, char *argv[])
187 {
185 {
188 SqpApplication app(argc, argv);
186 SqpApplication app(argc, argv);
189 app.setAttribute(Qt::AA_Use96Dpi, true);
187 app.setAttribute(Qt::AA_Use96Dpi, true);
190 TestAmdaAcquisition tc;
188 TestAmdaAcquisition tc;
191 QTEST_SET_MAIN_SOURCE_PATH
189 QTEST_SET_MAIN_SOURCE_PATH
192 return QTest::qExec(&tc, argc, argv);
190 return QTest::qExec(&tc, argc, argv);
193 }
191 }
194
192
195 // QTEST_MAIN(TestAmdaAcquisition)
193 // QTEST_MAIN(TestAmdaAcquisition)
196
194
197 #include "TestAmdaAcquisition.moc"
195 #include "TestAmdaAcquisition.moc"
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
General Comments 2
there is 1 general comment from older versions, show it