##// END OF EJS Templates
Wait for the end of an acquisition to validate an operation (2)...
Wait for the end of an acquisition to validate an operation (2) Creates signal in VariableController emitted when there is no pending acquisition

File last commit:

r858:551a1137cf04
r1214:feac825a443e
Show More
ArrayData.h
373 lines | 11.6 KiB | text/x-c | CLexer
Alexandre Leroux
Creates ArrayData (struct that holds data as a vector of double)
r124 #ifndef SCIQLOP_ARRAYDATA_H
#define SCIQLOP_ARRAYDATA_H
Alexandre Leroux
Replaces current iterator of ArrayData by the previous iterator created
r641 #include "Data/ArrayDataIterator.h"
Alexandre Leroux
Adapts sort() method to 2-dim array data (1)...
r504 #include <Common/SortUtils.h>
Add current progression for thread fix
r364 #include <QReadLocker>
#include <QReadWriteLock>
Alexandre Leroux
Creates ArrayData (struct that holds data as a vector of double)
r124 #include <QVector>
Alexandre Leroux
Makes a Data series be sorted (2)...
r450
#include <memory>
Alexandre Leroux
Adapts sort() method to 2-dim array data (2)...
r505 template <int Dim>
class ArrayData;
Alexandre Leroux
Uses std::vector instead of QVector in ArrayData (1)...
r694 using DataContainer = std::vector<double>;
Alexandre Leroux
Adapts sort() method to 2-dim array data (2)...
r505
namespace arraydata_detail {
/// Struct used to sort ArrayData
template <int Dim>
struct Sort {
Alexandre Leroux
Updates sort() method to be compatible with a single vector
r643 static std::shared_ptr<ArrayData<Dim> > sort(const DataContainer &data, int nbComponents,
Alexandre Leroux
Adapts sort() method to 2-dim array data (2)...
r505 const std::vector<int> &sortPermutation)
{
Alexandre Leroux
Updates sort() method to be compatible with a single vector
r643 return std::make_shared<ArrayData<Dim> >(
SortUtils::sort(data, nbComponents, sortPermutation), nbComponents);
Alexandre Leroux
Adapts sort() method to 2-dim array data (2)...
r505 }
};
/// Specialization for uni-dimensional ArrayData
template <>
struct Sort<1> {
Alexandre Leroux
Updates sort() method to be compatible with a single vector
r643 static std::shared_ptr<ArrayData<1> > sort(const DataContainer &data, int nbComponents,
Alexandre Leroux
Adapts sort() method to 2-dim array data (2)...
r505 const std::vector<int> &sortPermutation)
{
Alexandre Leroux
Updates sort() method to be compatible with a single vector
r643 Q_UNUSED(nbComponents)
return std::make_shared<ArrayData<1> >(SortUtils::sort(data, 1, sortPermutation));
Alexandre Leroux
Adapts sort() method to 2-dim array data (2)...
r505 }
};
Alexandre Leroux
Adapts SqpIterator to make non-const iterators
r673 template <int Dim, bool IsConst>
class IteratorValue;
template <int Dim, bool IsConst>
struct IteratorValueBuilder {
};
template <int Dim>
struct IteratorValueBuilder<Dim, true> {
using DataContainerIterator = DataContainer::const_iterator;
Alexandre Leroux
Adapts iterator to be MoveAssignable...
r674
static void swap(IteratorValue<Dim, true> &o1, IteratorValue<Dim, true> &o2) {}
Alexandre Leroux
Adapts SqpIterator to make non-const iterators
r673 };
Alexandre Leroux
Replaces current iterator of ArrayData by the previous iterator created
r641 template <int Dim>
Alexandre Leroux
Adapts SqpIterator to make non-const iterators
r673 struct IteratorValueBuilder<Dim, false> {
using DataContainerIterator = DataContainer::iterator;
Alexandre Leroux
Adapts iterator to be MoveAssignable...
r674
static void swap(IteratorValue<Dim, false> &o1, IteratorValue<Dim, false> &o2)
{
for (auto i = 0; i < o1.m_NbComponents; ++i) {
std::iter_swap(o1.m_It + i, o2.m_It + i);
}
}
Alexandre Leroux
Adapts SqpIterator to make non-const iterators
r673 };
template <int Dim, bool IsConst>
Alexandre Leroux
Replaces current iterator of ArrayData by the previous iterator created
r641 class IteratorValue : public ArrayDataIteratorValue::Impl {
public:
Alexandre Leroux
Adapts SqpIterator to make non-const iterators
r673 friend class ArrayData<Dim>;
friend class IteratorValueBuilder<Dim, IsConst>;
using DataContainerIterator =
typename IteratorValueBuilder<Dim, IsConst>::DataContainerIterator;
template <bool IC = IsConst, typename = std::enable_if_t<IC == true> >
Alexandre Leroux
Updates ArrayData iterator to be use single QVector
r644 explicit IteratorValue(const DataContainer &container, int nbComponents, bool begin)
: m_It{begin ? container.cbegin() : container.cend()}, m_NbComponents{nbComponents}
Alexandre Leroux
Replaces current iterator of ArrayData by the previous iterator created
r641 {
}
Alexandre Leroux
Adapts SqpIterator to make non-const iterators
r673 template <bool IC = IsConst, typename = std::enable_if_t<IC == false> >
explicit IteratorValue(DataContainer &container, int nbComponents, bool begin)
: m_It{begin ? container.begin() : container.end()}, m_NbComponents{nbComponents}
{
}
Alexandre Leroux
Replaces current iterator of ArrayData by the previous iterator created
r641 IteratorValue(const IteratorValue &other) = default;
std::unique_ptr<ArrayDataIteratorValue::Impl> clone() const override
{
Alexandre Leroux
Adapts SqpIterator to make non-const iterators
r673 return std::make_unique<IteratorValue<Dim, IsConst> >(*this);
Alexandre Leroux
Replaces current iterator of ArrayData by the previous iterator created
r641 }
Alexandre Leroux
Makes random access iterators...
r689 int distance(const ArrayDataIteratorValue::Impl &other) const override try {
const auto &otherImpl = dynamic_cast<const IteratorValue &>(other);
return std::distance(otherImpl.m_It, m_It) / m_NbComponents;
}
catch (const std::bad_cast &) {
return 0;
}
Alexandre Leroux
Replaces current iterator of ArrayData by the previous iterator created
r641 bool equals(const ArrayDataIteratorValue::Impl &other) const override try {
const auto &otherImpl = dynamic_cast<const IteratorValue &>(other);
Alexandre Leroux
Updates ArrayData iterator to be use single QVector
r644 return std::tie(m_It, m_NbComponents) == std::tie(otherImpl.m_It, otherImpl.m_NbComponents);
Alexandre Leroux
Replaces current iterator of ArrayData by the previous iterator created
r641 }
catch (const std::bad_cast &) {
return false;
}
Alexandre Leroux
Makes random access iterators...
r689 bool lowerThan(const ArrayDataIteratorValue::Impl &other) const override try {
const auto &otherImpl = dynamic_cast<const IteratorValue &>(other);
return m_It < otherImpl.m_It;
}
catch (const std::bad_cast &) {
return false;
}
std::unique_ptr<ArrayDataIteratorValue::Impl> advance(int offset) const override
{
auto result = clone();
Alexandre Leroux
Improves random access iterator performance
r697 result->next(offset);
Alexandre Leroux
Makes random access iterators...
r689 return result;
}
Alexandre Leroux
Improves random access iterator performance
r697 void next(int offset) override { std::advance(m_It, offset * m_NbComponents); }
Alexandre Leroux
Updates ArrayData iterator to be use single QVector
r644 void prev() override { std::advance(m_It, -m_NbComponents); }
Alexandre Leroux
Replaces current iterator of ArrayData by the previous iterator created
r641
Alexandre Leroux
Updates ArrayData iterator to be use single QVector
r644 double at(int componentIndex) const override { return *(m_It + componentIndex); }
double first() const override { return *m_It; }
Alexandre Leroux
Replaces current iterator of ArrayData by the previous iterator created
r641 double min() const override
{
Alexandre Leroux
Updates ArrayData iterator to be use single QVector
r644 auto values = this->values();
auto end = values.cend();
auto it = std::min_element(values.cbegin(), end, [](const auto &v1, const auto &v2) {
return SortUtils::minCompareWithNaN(v1, v2);
Alexandre Leroux
Replaces current iterator of ArrayData by the previous iterator created
r641 });
Alexandre Leroux
Updates ArrayData iterator to be use single QVector
r644
return it != end ? *it : std::numeric_limits<double>::quiet_NaN();
Alexandre Leroux
Replaces current iterator of ArrayData by the previous iterator created
r641 }
double max() const override
{
Alexandre Leroux
Updates ArrayData iterator to be use single QVector
r644 auto values = this->values();
auto end = values.cend();
auto it = std::max_element(values.cbegin(), end, [](const auto &v1, const auto &v2) {
return SortUtils::maxCompareWithNaN(v1, v2);
Alexandre Leroux
Replaces current iterator of ArrayData by the previous iterator created
r641 });
Alexandre Leroux
Updates ArrayData iterator to be use single QVector
r644 return it != end ? *it : std::numeric_limits<double>::quiet_NaN();
Alexandre Leroux
Replaces current iterator of ArrayData by the previous iterator created
r641 }
Alexandre Leroux
Adds method into ArrayData and DataSeries iterator to get all values
r667 QVector<double> values() const override
Alexandre Leroux
Updates ArrayData iterator to be use single QVector
r644 {
Alexandre Leroux
Adds method into ArrayData and DataSeries iterator to get all values
r667 auto result = QVector<double>{};
Alexandre Leroux
Updates ArrayData iterator to be use single QVector
r644 for (auto i = 0; i < m_NbComponents; ++i) {
result.push_back(*(m_It + i));
}
return result;
}
Alexandre Leroux
Adapts iterator to be MoveAssignable...
r674 void swap(ArrayDataIteratorValue::Impl &other) override
{
auto &otherImpl = dynamic_cast<IteratorValue &>(other);
IteratorValueBuilder<Dim, IsConst>::swap(*this, otherImpl);
}
Alexandre Leroux
Adds method into ArrayData and DataSeries iterator to get all values
r667 private:
Alexandre Leroux
Adapts SqpIterator to make non-const iterators
r673 DataContainerIterator m_It;
Alexandre Leroux
Updates ArrayData iterator to be use single QVector
r644 int m_NbComponents;
Alexandre Leroux
Replaces current iterator of ArrayData by the previous iterator created
r641 };
Alexandre Leroux
Adapts sort() method to 2-dim array data (2)...
r505 } // namespace arraydata_detail
Alexandre Leroux
Creates ArrayData (struct that holds data as a vector of double)
r124 /**
* @brief The ArrayData class represents a dataset for a data series.
*
* A dataset can be unidimensional or two-dimensional. This property is determined by the Dim
Alexandre Leroux
Creates ctor for two-dimensional ArrayData
r501 * template-parameter. In a case of a two-dimensional dataset, each dataset component has the same
* number of values
Alexandre Leroux
Creates ArrayData (struct that holds data as a vector of double)
r124 *
* @tparam Dim the dimension of the ArrayData (one or two)
* @sa IDataSeries
*/
template <int Dim>
class ArrayData {
public:
Alexandre Leroux
Reorganizes methods in ArrayData...
r507 // ///// //
// Ctors //
// ///// //
Alexandre Leroux
Creates constructor for ScalarSeries that directly takes vectors...
r392 /**
* Ctor for a unidimensional ArrayData
* @param data the data the ArrayData will hold
*/
template <int D = Dim, typename = std::enable_if_t<D == 1> >
Alexandre Leroux
Updates ArrayData to hold a single QVector
r642 explicit ArrayData(DataContainer data) : m_Data{std::move(data)}, m_NbComponents{1}
Alexandre Leroux
Creates constructor for ScalarSeries that directly takes vectors...
r392 {
}
Alexandre Leroux
Creates ctor for two-dimensional ArrayData
r501 /**
Alexandre Leroux
Updates ArrayData to hold a single QVector
r642 * Ctor for a two-dimensional ArrayData. The number of components (number of lines) must be
* greater than 2 and must be a divisor of the total number of data in the vector
Alexandre Leroux
Creates ctor for two-dimensional ArrayData
r501 * @param data the data the ArrayData will hold
Alexandre Leroux
Updates ArrayData to hold a single QVector
r642 * @param nbComponents the number of components
* @throws std::invalid_argument if the number of components is less than 2 or is not a divisor
* of the size of the data
Alexandre Leroux
Creates ctor for two-dimensional ArrayData
r501 */
template <int D = Dim, typename = std::enable_if_t<D == 2> >
Alexandre Leroux
Updates ArrayData to hold a single QVector
r642 explicit ArrayData(DataContainer data, int nbComponents)
: m_Data{std::move(data)}, m_NbComponents{nbComponents}
Alexandre Leroux
Creates ctor for two-dimensional ArrayData
r501 {
if (nbComponents < 2) {
throw std::invalid_argument{
Alexandre Leroux
Updates ArrayData to hold a single QVector
r642 QString{"A multidimensional ArrayData must have at least 2 components (found: %1)"}
.arg(nbComponents)
Alexandre Leroux
Creates ctor for two-dimensional ArrayData
r501 .toStdString()};
}
Alexandre Leroux
Updates ArrayData to hold a single QVector
r642 if (m_Data.size() % m_NbComponents != 0) {
throw std::invalid_argument{QString{
"The number of components (%1) is inconsistent with the total number of data (%2)"}
.arg(m_Data.size(), nbComponents)
.toStdString()};
Alexandre Leroux
Creates ctor for two-dimensional ArrayData
r501 }
}
Alexandre Leroux
Review fixes
r372 /// Copy ctor
Add current progression for thread fix
r364 explicit ArrayData(const ArrayData &other)
{
Alexandre Leroux
Review fixes
r372 QReadLocker otherLocker{&other.m_Lock};
Add current progression for thread fix
r364 m_Data = other.m_Data;
Alexandre Leroux
Updates ArrayData to hold a single QVector
r642 m_NbComponents = other.m_NbComponents;
Add current progression for thread fix
r364 }
Alexandre Leroux
Reorganizes methods in ArrayData...
r507 // /////////////// //
// General methods //
// /////////////// //
Add merge API and implement it for the DataSeries
r233
Alexandre Leroux
Handles merge of two data series
r451 /**
Alexandre Leroux
Adapts add() method to 2-dim array data
r506 * Merges into the array data an other array data. The two array datas must have the same number
* of components so the merge can be done
Alexandre Leroux
Handles merge of two data series
r451 * @param other the array data to merge with
* @param prepend if true, the other array data is inserted at the beginning, otherwise it is
* inserted at the end
*/
Alexandre Leroux
Adapts add() method to 2-dim array data
r506 void add(const ArrayData<Dim> &other, bool prepend = false)
Add merge API and implement it for the DataSeries
r233 {
Alexandre Leroux
Review fixes
r372 QWriteLocker locker{&m_Lock};
Alexandre Leroux
Adapts add() method to 2-dim array data
r506 QReadLocker otherLocker{&other.m_Lock};
Alexandre Leroux
Updates ArrayData to hold a single QVector
r642 if (m_NbComponents != other.componentCount()) {
Alexandre Leroux
Adapts add() method to 2-dim array data
r506 return;
}
Alexandre Leroux
Handles merge of two data series
r451
Alexandre Leroux
Updates merge method...
r696 insert(other.cbegin(), other.cend(), prepend);
Add merge API and implement it for the DataSeries
r233 }
Alexandre Leroux
Reorganizes methods in ArrayData...
r507 void clear()
{
QWriteLocker locker{&m_Lock};
Alexandre Leroux
Updates ArrayData to hold a single QVector
r642 m_Data.clear();
Alexandre Leroux
Reorganizes methods in ArrayData...
r507 }
Alexandre Leroux
Updates ArrayData to hold a single QVector
r642 int componentCount() const noexcept { return m_NbComponents; }
Alexandre Leroux
Reorganizes methods in ArrayData...
r507
Alexandre Leroux
Makes clear() and size() methods compatible with two-dimensional ArrayData
r502 /// @return the size (i.e. number of values) of a single component
/// @remarks in a case of a two-dimensional ArrayData, each component has the same size
Add current progression for thread fix
r364 int size() const
Add merge API and implement it for the DataSeries
r233 {
Alexandre Leroux
Review fixes
r372 QReadLocker locker{&m_Lock};
Alexandre Leroux
Updates ArrayData to hold a single QVector
r642 return m_Data.size() / m_NbComponents;
Add merge API and implement it for the DataSeries
r233 }
Alexandre Leroux
Creates method to retrieve nb points of a data series
r717 /// @return the total size (i.e. number of values) of the array data
int totalSize() const
{
QReadLocker locker{&m_Lock};
return m_Data.size();
}
Alexandre Leroux
Adapts sort() method to 2-dim array data (1)...
r504 std::shared_ptr<ArrayData<Dim> > sort(const std::vector<int> &sortPermutation)
Alexandre Leroux
Makes a Data series be sorted (2)...
r450 {
QReadLocker locker{&m_Lock};
Alexandre Leroux
Updates ArrayData to hold a single QVector
r642 return arraydata_detail::Sort<Dim>::sort(m_Data, m_NbComponents, sortPermutation);
Alexandre Leroux
Makes a Data series be sorted (2)...
r450 }
Alexandre Leroux
Correction on ArrayData::clear() method
r454
Alexandre Leroux
Creates iterator for ArrayData
r555 // ///////// //
// Iterators //
// ///////// //
Alexandre Leroux
Adapts SqpIterator to make non-const iterators
r673 ArrayDataIterator begin()
{
return ArrayDataIterator{
ArrayDataIteratorValue{std::make_unique<arraydata_detail::IteratorValue<Dim, false> >(
m_Data, m_NbComponents, true)}};
}
ArrayDataIterator end()
{
return ArrayDataIterator{
ArrayDataIteratorValue{std::make_unique<arraydata_detail::IteratorValue<Dim, false> >(
m_Data, m_NbComponents, false)}};
}
Alexandre Leroux
Replaces current iterator of ArrayData by the previous iterator created
r641 ArrayDataIterator cbegin() const
{
Alexandre Leroux
Adapts SqpIterator to make non-const iterators
r673 return ArrayDataIterator{
ArrayDataIteratorValue{std::make_unique<arraydata_detail::IteratorValue<Dim, true> >(
m_Data, m_NbComponents, true)}};
Alexandre Leroux
Replaces current iterator of ArrayData by the previous iterator created
r641 }
Alexandre Leroux
Adapts SqpIterator to make non-const iterators
r673
Alexandre Leroux
Replaces current iterator of ArrayData by the previous iterator created
r641 ArrayDataIterator cend() const
{
Alexandre Leroux
Updates ArrayData iterator to be use single QVector
r644 return ArrayDataIterator{
Alexandre Leroux
Adapts SqpIterator to make non-const iterators
r673 ArrayDataIteratorValue{std::make_unique<arraydata_detail::IteratorValue<Dim, true> >(
Alexandre Leroux
Updates ArrayData iterator to be use single QVector
r644 m_Data, m_NbComponents, false)}};
Alexandre Leroux
Replaces current iterator of ArrayData by the previous iterator created
r641 }
Alexandre Leroux
Creates iterator for ArrayData
r555
Alexandre Leroux
Adds erase() method for ArrayData and DataSeries
r675 void erase(ArrayDataIterator first, ArrayDataIterator last)
{
auto firstImpl = dynamic_cast<arraydata_detail::IteratorValue<Dim, false> *>(first->impl());
auto lastImpl = dynamic_cast<arraydata_detail::IteratorValue<Dim, false> *>(last->impl());
if (firstImpl && lastImpl) {
m_Data.erase(firstImpl->m_It, lastImpl->m_It);
}
}
Alexandre Leroux
Updates merge method...
r696 void insert(ArrayDataIterator first, ArrayDataIterator last, bool prepend = false)
Alexandre Leroux
Updates merge() method (2)...
r669 {
Alexandre Leroux
Updates merge method...
r696 auto firstImpl = dynamic_cast<arraydata_detail::IteratorValue<Dim, true> *>(first->impl());
auto lastImpl = dynamic_cast<arraydata_detail::IteratorValue<Dim, true> *>(last->impl());
if (firstImpl && lastImpl) {
auto insertIt = prepend ? m_Data.begin() : m_Data.end();
m_Data.insert(insertIt, firstImpl->m_It, lastImpl->m_It);
}
Alexandre Leroux
Updates merge() method (2)...
r669 }
Alexandre Leroux
Reorganizes methods in ArrayData...
r507
/**
* @return the data at a specified index
* @remarks index must be a valid position
*/
double at(int index) const noexcept
Add current progression for thread fix
r364 {
Alexandre Leroux
Reorganizes methods in ArrayData...
r507 QReadLocker locker{&m_Lock};
Alexandre Leroux
Updates ArrayData to hold a single QVector
r642 return m_Data.at(index);
Alexandre Leroux
Reorganizes methods in ArrayData...
r507 }
Add current progression for thread fix
r364
Alexandre Leroux
Removes unused methods
r645 // ///////////// //
// 1-dim methods //
// ///////////// //
Alexandre Leroux
Reorganizes methods in ArrayData...
r507 /**
* @return the data as a vector, as a const reference
* @remarks this method is only available for a unidimensional ArrayData
*/
template <int D = Dim, typename = std::enable_if_t<D == 1> >
Alexandre Leroux
Uses std::vector instead of QVector in ArrayData (1)...
r694 DataContainer cdata() const noexcept
Alexandre Leroux
Adds unit tests for reading vectors in AMDA
r568 {
return m_Data;
}
Alexandre Leroux
Creates ArrayData (struct that holds data as a vector of double)
r124 private:
Alexandre Leroux
Adapts sort() method to 2-dim array data (2)...
r505 DataContainer m_Data;
Alexandre Leroux
Updates ArrayData to hold a single QVector
r642 /// Number of components (lines). Is always 1 in a 1-dim ArrayData
int m_NbComponents;
Add current progression for thread fix
r364 mutable QReadWriteLock m_Lock;
Alexandre Leroux
Creates ArrayData (struct that holds data as a vector of double)
r124 };
#endif // SCIQLOP_ARRAYDATA_H