##// END OF EJS Templates
Creates enum that represents the value types that can be read in AMDA...
Creates enum that represents the value types that can be read in AMDA This enum is passed in parameter of the reading method to parse the result file according to it

File last commit:

r562:d3e47b0fbfb0
r563:a08e6992e146
Show More
DataSeries.h
293 lines | 9.1 KiB | text/x-c | CLexer
Alexandre Leroux
Creates IDataSeries interface and its default implementation
r125 #ifndef SCIQLOP_DATASERIES_H
#define SCIQLOP_DATASERIES_H
Alexandre Leroux
Updates declaration of logger to avoid multiple definitions
r562 #include "CoreGlobal.h"
Alexandre Leroux
Makes a Data series be sorted (2)...
r450 #include <Common/SortUtils.h>
Alexandre Leroux
Creates IDataSeries interface and its default implementation
r125 #include <Data/ArrayData.h>
#include <Data/IDataSeries.h>
Correction for pull request
r243 #include <QLoggingCategory>
Add current progression for thread fix
r364 #include <QReadLocker>
#include <QReadWriteLock>
Alexandre Leroux
Creates IDataSeries interface and its default implementation
r125 #include <memory>
Alexandre Leroux
Updates declaration of logger to avoid multiple definitions
r562 // We don't use the Qt macro since the log is used in the header file, which causes multiple log
// definitions with inheritance. Inline method is used instead
inline const QLoggingCategory &LOG_DataSeries()
{
static const QLoggingCategory category{"DataSeries"};
return category;
}
Correction for pull request
r243
Alexandre Leroux
Creates IDataSeries interface and its default implementation
r125 /**
* @brief The DataSeries class is the base (abstract) implementation of IDataSeries.
*
Alexandre Leroux
Makes a Data series be sorted (1)
r449 * It proposes to set a dimension for the values ​​data.
*
* A DataSeries is always sorted on its x-axis data.
Alexandre Leroux
Creates IDataSeries interface and its default implementation
r125 *
* @tparam Dim The dimension of the values data
*
*/
template <int Dim>
Alexandre Leroux
Updates declaration of logger to avoid multiple definitions
r562 class SCIQLOP_CORE_EXPORT DataSeries : public IDataSeries {
Alexandre Leroux
Creates IDataSeries interface and its default implementation
r125 public:
Alexandre Leroux
Creates iterator for DataSeries
r556 class IteratorValue {
public:
explicit IteratorValue(const DataSeries &dataSeries, bool begin)
: m_XIt(begin ? dataSeries.xAxisData()->cbegin() : dataSeries.xAxisData()->cend()),
m_ValuesIt(begin ? dataSeries.valuesData()->cbegin()
: dataSeries.valuesData()->cend())
{
}
double x() const { return m_XIt->at(0); }
double value() const { return m_ValuesIt->at(0); }
double value(int componentIndex) const { return m_ValuesIt->at(componentIndex); }
void next()
{
++m_XIt;
++m_ValuesIt;
}
bool operator==(const IteratorValue &other) const
{
return std::tie(m_XIt, m_ValuesIt) == std::tie(other.m_XIt, other.m_ValuesIt);
}
private:
ArrayData<1>::Iterator m_XIt;
typename ArrayData<Dim>::Iterator m_ValuesIt;
};
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 DataSeries &dataSeries, bool begin) : m_CurrentValue{dataSeries, 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
Creates IDataSeries interface and its default implementation
r125 /// @sa IDataSeries::xAxisData()
std::shared_ptr<ArrayData<1> > xAxisData() override { return m_XAxisData; }
Alexandre Leroux
Use std::shared_ptr in CosinusProvider
r310 const std::shared_ptr<ArrayData<1> > xAxisData() const { return m_XAxisData; }
Alexandre Leroux
Creates IDataSeries interface and its default implementation
r125
/// @sa IDataSeries::xAxisUnit()
Alexandre Leroux
Replaces QString unit by a new struct...
r177 Unit xAxisUnit() const override { return m_XAxisUnit; }
Alexandre Leroux
Creates IDataSeries interface and its default implementation
r125
/// @return the values dataset
Alexandre Leroux
Use std::shared_ptr in CosinusProvider
r310 std::shared_ptr<ArrayData<Dim> > valuesData() { return m_ValuesData; }
const std::shared_ptr<ArrayData<Dim> > valuesData() const { return m_ValuesData; }
Alexandre Leroux
Creates IDataSeries interface and its default implementation
r125
/// @sa IDataSeries::valuesUnit()
Alexandre Leroux
Replaces QString unit by a new struct...
r177 Unit valuesUnit() const override { return m_ValuesUnit; }
Alexandre Leroux
Creates IDataSeries interface and its default implementation
r125
Implementation of V5 acquisition
r539
SqpRange range() const override
{
if (!m_XAxisData->cdata().isEmpty()) {
return SqpRange{m_XAxisData->cdata().first(), m_XAxisData->cdata().last()};
}
return SqpRange{};
}
Add current progression for thread fix
r364 void clear()
{
m_XAxisData->clear();
m_ValuesData->clear();
}
Alexandre Leroux
Handles merge of two data series
r451 /// Merges into the data series an other data series
/// @remarks the data series to merge with is cleared after the operation
Add merge API and implement it for the DataSeries
r233 void merge(IDataSeries *dataSeries) override
{
Alexandre Leroux
Handles merge of two data series
r451 dataSeries->lockWrite();
lockWrite();
if (auto other = dynamic_cast<DataSeries<Dim> *>(dataSeries)) {
const auto &otherXAxisData = other->xAxisData()->cdata();
const auto &xAxisData = m_XAxisData->cdata();
// As data series are sorted, we can improve performances of merge, by call the sort
// method only if the two data series overlap.
if (!otherXAxisData.empty()) {
auto firstValue = otherXAxisData.front();
auto lastValue = otherXAxisData.back();
auto xAxisDataBegin = xAxisData.cbegin();
auto xAxisDataEnd = xAxisData.cend();
bool prepend;
bool sortNeeded;
if (std::lower_bound(xAxisDataBegin, xAxisDataEnd, firstValue) == xAxisDataEnd) {
// Other data series if after data series
prepend = false;
sortNeeded = false;
}
else if (std::upper_bound(xAxisDataBegin, xAxisDataEnd, lastValue)
== xAxisDataBegin) {
// Other data series if before data series
prepend = true;
sortNeeded = false;
}
else {
// The two data series overlap
prepend = false;
sortNeeded = true;
}
// Makes the merge
m_XAxisData->add(*other->xAxisData(), prepend);
m_ValuesData->add(*other->valuesData(), prepend);
if (sortNeeded) {
sort();
}
}
// Clears the other data series
other->clear();
Add merge API and implement it for the DataSeries
r233 }
Correction for pull request
r243 else {
qCWarning(LOG_DataSeries())
Alexandre Leroux
Handles merge of two data series
r451 << QObject::tr("Detection of a type of IDataSeries we cannot merge with !");
Correction for pull request
r243 }
Alexandre Leroux
Handles merge of two data series
r451 unlock();
dataSeries->unlock();
Add merge API and implement it for the DataSeries
r233 }
Alexandre Leroux
Creates iterator for DataSeries
r556 // ///////// //
// Iterators //
// ///////// //
Iterator cbegin() const { return Iterator{*this, true}; }
Iterator cend() const { return Iterator{*this, false}; }
Alexandre Leroux
Adds subData() method
r557 std::pair<Iterator, Iterator> subData(double min, double max) const
{
if (min > max) {
std::swap(min, max);
}
auto begin = cbegin();
auto end = cend();
auto lowerIt
= std::lower_bound(begin, end, min, [](const auto &itValue, const auto &value) {
return itValue.x() == value;
});
auto upperIt
= std::upper_bound(begin, end, max, [](const auto &value, const auto &itValue) {
return itValue.x() == value;
});
return std::make_pair(lowerIt, upperIt);
}
Alexandre Leroux
Creates iterator for DataSeries
r556 // /////// //
// Mutexes //
// /////// //
Add current progression for thread fix
r364 virtual void lockRead() { m_Lock.lockForRead(); }
virtual void lockWrite() { m_Lock.lockForWrite(); }
virtual void unlock() { m_Lock.unlock(); }
Alexandre Leroux
Creates IDataSeries interface and its default implementation
r125 protected:
Alexandre Leroux
Makes a Data series be sorted (1)
r449 /// Protected ctor (DataSeries is abstract). The vectors must have the same size, otherwise a
/// DataSeries with no values will be created.
/// @remarks data series is automatically sorted on its x-axis data
Alexandre Leroux
Fixes after review
r188 explicit DataSeries(std::shared_ptr<ArrayData<1> > xAxisData, const Unit &xAxisUnit,
std::shared_ptr<ArrayData<Dim> > valuesData, const Unit &valuesUnit)
Alexandre Leroux
Creates IDataSeries interface and its default implementation
r125 : m_XAxisData{xAxisData},
Alexandre Leroux
Fixes after review
r188 m_XAxisUnit{xAxisUnit},
Alexandre Leroux
Creates IDataSeries interface and its default implementation
r125 m_ValuesData{valuesData},
Alexandre Leroux
Fixes after review
r188 m_ValuesUnit{valuesUnit}
Alexandre Leroux
Creates IDataSeries interface and its default implementation
r125 {
Alexandre Leroux
Makes a Data series be sorted (1)
r449 if (m_XAxisData->size() != m_ValuesData->size()) {
clear();
}
// Sorts data if it's not the case
const auto &xAxisCData = m_XAxisData->cdata();
if (!std::is_sorted(xAxisCData.cbegin(), xAxisCData.cend())) {
sort();
}
Alexandre Leroux
Creates IDataSeries interface and its default implementation
r125 }
Alexandre Leroux
Use std::shared_ptr in CosinusProvider
r310 /// Copy ctor
explicit DataSeries(const DataSeries<Dim> &other)
: m_XAxisData{std::make_shared<ArrayData<1> >(*other.m_XAxisData)},
m_XAxisUnit{other.m_XAxisUnit},
m_ValuesData{std::make_shared<ArrayData<Dim> >(*other.m_ValuesData)},
m_ValuesUnit{other.m_ValuesUnit}
{
Alexandre Leroux
Makes a Data series be sorted (1)
r449 // Since a series is ordered from its construction and is always ordered, it is not
// necessary to call the sort method here ('other' is sorted)
Alexandre Leroux
Use std::shared_ptr in CosinusProvider
r310 }
/// Assignment operator
template <int D>
DataSeries &operator=(DataSeries<D> other)
{
std::swap(m_XAxisData, other.m_XAxisData);
std::swap(m_XAxisUnit, other.m_XAxisUnit);
std::swap(m_ValuesData, other.m_ValuesData);
std::swap(m_ValuesUnit, other.m_ValuesUnit);
return *this;
}
Alexandre Leroux
Creates IDataSeries interface and its default implementation
r125 private:
Alexandre Leroux
Makes a Data series be sorted (1)
r449 /**
* Sorts data series on its x-axis data
*/
void sort() noexcept
{
Alexandre Leroux
Makes a Data series be sorted (2)...
r450 auto permutation = SortUtils::sortPermutation(*m_XAxisData, std::less<double>());
m_XAxisData = m_XAxisData->sort(permutation);
m_ValuesData = m_ValuesData->sort(permutation);
Alexandre Leroux
Makes a Data series be sorted (1)
r449 }
Alexandre Leroux
Creates IDataSeries interface and its default implementation
r125 std::shared_ptr<ArrayData<1> > m_XAxisData;
Alexandre Leroux
Replaces QString unit by a new struct...
r177 Unit m_XAxisUnit;
Alexandre Leroux
Creates IDataSeries interface and its default implementation
r125 std::shared_ptr<ArrayData<Dim> > m_ValuesData;
Alexandre Leroux
Replaces QString unit by a new struct...
r177 Unit m_ValuesUnit;
Add current progression for thread fix
r364
QReadWriteLock m_Lock;
Alexandre Leroux
Creates IDataSeries interface and its default implementation
r125 };
#endif // SCIQLOP_DATASERIES_H