##// END OF EJS Templates
Reads variable metadata to get the data type...
Reads variable metadata to get the data type The data type is then parsed to determine the value type expected when reading result file

File last commit:

r555:03bab5615207
r566:a6f250cc335f
Show More
ArrayData.h
298 lines | 8.9 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
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;
using DataContainer = QVector<QVector<double> >;
namespace arraydata_detail {
/// Struct used to sort ArrayData
template <int Dim>
struct Sort {
static std::shared_ptr<ArrayData<Dim> > sort(const DataContainer &data,
const std::vector<int> &sortPermutation)
{
auto nbComponents = data.size();
auto sortedData = DataContainer(nbComponents);
for (auto i = 0; i < nbComponents; ++i) {
sortedData[i] = SortUtils::sort(data.at(i), sortPermutation);
}
return std::make_shared<ArrayData<Dim> >(std::move(sortedData));
}
};
/// Specialization for uni-dimensional ArrayData
template <>
struct Sort<1> {
static std::shared_ptr<ArrayData<1> > sort(const DataContainer &data,
const std::vector<int> &sortPermutation)
{
return std::make_shared<ArrayData<1> >(SortUtils::sort(data.at(0), sortPermutation));
}
};
} // 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
Creates iterator for ArrayData
r555 class IteratorValue {
public:
explicit IteratorValue(const DataContainer &container, bool begin) : m_Its{}
{
for (auto i = 0; i < container.size(); ++i) {
m_Its.push_back(begin ? container.at(i).cbegin() : container.at(i).cend());
}
}
double at(int index) const { return *m_Its.at(index); }
double first() const { return *m_Its.front(); }
void next()
{
for (auto &it : m_Its) {
++it;
}
}
bool operator==(const IteratorValue &other) const { return m_Its == other.m_Its; }
private:
std::vector<DataContainer::value_type::const_iterator> m_Its;
};
class Iterator {
public:
using iterator_category = std::forward_iterator_tag;
using value_type = const IteratorValue;
using difference_type = std::ptrdiff_t;
using pointer = value_type *;
using reference = value_type &;
Iterator(const DataContainer &container, bool begin) : m_CurrentValue{container, begin} {}
virtual ~Iterator() noexcept = default;
Iterator(const Iterator &) = default;
Iterator(Iterator &&) = default;
Iterator &operator=(const Iterator &) = default;
Iterator &operator=(Iterator &&) = default;
Iterator &operator++()
{
m_CurrentValue.next();
return *this;
}
pointer operator->() const { return &m_CurrentValue; }
reference operator*() const { return m_CurrentValue; }
bool operator==(const Iterator &other) const
{
return m_CurrentValue == other.m_CurrentValue;
}
bool operator!=(const Iterator &other) const { return !(*this == other); }
private:
IteratorValue m_CurrentValue;
};
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> >
explicit ArrayData(QVector<double> data) : m_Data{1, QVector<double>{}}
{
m_Data[0] = std::move(data);
}
Alexandre Leroux
Creates ctor for two-dimensional ArrayData
r501 /**
* Ctor for a two-dimensional ArrayData. The number of components (number of vectors) must be
* greater than 2 and each component must have the same number of values
* @param data the data the ArrayData will hold
* @throws std::invalid_argument if the number of components is less than 2
* @remarks if the number of values is not the same for each component, no value is set
*/
template <int D = Dim, typename = std::enable_if_t<D == 2> >
Alexandre Leroux
Adapts sort() method to 2-dim array data (2)...
r505 explicit ArrayData(DataContainer data)
Alexandre Leroux
Creates ctor for two-dimensional ArrayData
r501 {
auto nbComponents = data.size();
if (nbComponents < 2) {
throw std::invalid_argument{
QString{"A multidimensional ArrayData must have at least 2 components (found: %1"}
.arg(data.size())
.toStdString()};
}
auto nbValues = data.front().size();
if (std::all_of(data.cbegin(), data.cend(), [nbValues](const auto &component) {
return component.size() == nbValues;
})) {
m_Data = std::move(data);
}
else {
Alexandre Leroux
Adapts sort() method to 2-dim array data (2)...
r505 m_Data = DataContainer{nbComponents, QVector<double>{}};
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
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};
auto nbComponents = m_Data.size();
if (nbComponents != other.m_Data.size()) {
return;
}
Alexandre Leroux
Handles merge of two data series
r451
Alexandre Leroux
Adapts add() method to 2-dim array data
r506 for (auto componentIndex = 0; componentIndex < nbComponents; ++componentIndex) {
Alexandre Leroux
Handles merge of two data series
r451 if (prepend) {
Alexandre Leroux
Adapts add() method to 2-dim array data
r506 const auto &otherData = other.data(componentIndex);
Alexandre Leroux
Handles merge of two data series
r451 const auto otherDataSize = otherData.size();
Alexandre Leroux
Adapts add() method to 2-dim array data
r506 auto &data = m_Data[componentIndex];
Alexandre Leroux
Handles merge of two data series
r451 data.insert(data.begin(), otherDataSize, 0.);
for (auto i = 0; i < otherDataSize; ++i) {
data.replace(i, otherData.at(i));
}
}
else {
Alexandre Leroux
Adapts add() method to 2-dim array data
r506 m_Data[componentIndex] += other.data(componentIndex);
Alexandre Leroux
Handles merge of two data series
r451 }
Add merge API and implement it for the DataSeries
r233 }
}
Alexandre Leroux
Reorganizes methods in ArrayData...
r507 void clear()
{
QWriteLocker locker{&m_Lock};
auto nbComponents = m_Data.size();
for (auto i = 0; i < nbComponents; ++i) {
m_Data[i].clear();
}
}
/**
* @return the data of a component
* @param componentIndex the index of the component to retrieve the data
* @return the component's data, empty vector if the index is invalid
*/
QVector<double> data(int componentIndex) const noexcept
{
QReadLocker locker{&m_Lock};
return (componentIndex >= 0 && componentIndex < m_Data.size()) ? m_Data.at(componentIndex)
: QVector<double>{};
}
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};
Add merge API and implement it for the DataSeries
r233 return m_Data[0].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
Adapts sort() method to 2-dim array data (2)...
r505 return arraydata_detail::Sort<Dim>::sort(m_Data, 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 //
// ///////// //
Iterator cbegin() const { return Iterator{m_Data, true}; }
Iterator cend() const { return Iterator{m_Data, false}; }
Alexandre Leroux
Reorganizes methods in ArrayData...
r507 // ///////////// //
// 1-dim methods //
// ///////////// //
/**
* @return the data at a specified index
* @remarks index must be a valid position
* @remarks this method is only available for a unidimensional ArrayData
*/
template <int D = Dim, typename = std::enable_if_t<D == 1> >
double at(int index) const noexcept
Add current progression for thread fix
r364 {
Alexandre Leroux
Reorganizes methods in ArrayData...
r507 QReadLocker locker{&m_Lock};
return m_Data[0].at(index);
}
Add current progression for thread fix
r364
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> >
const QVector<double> &cdata() const noexcept
{
QReadLocker locker{&m_Lock};
return m_Data.at(0);
}
/**
* @return the data as a vector
* @remarks this method is only available for a unidimensional ArrayData
*/
template <int D = Dim, typename = std::enable_if_t<D == 1> >
QVector<double> data() const noexcept
{
QReadLocker locker{&m_Lock};
return m_Data[0];
Alexandre Leroux
Makes clear() and size() methods compatible with two-dimensional ArrayData
r502 }
Add merge API and implement it for the DataSeries
r233
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;
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