Mantid
Loading...
Searching...
No Matches
VectorColumn.h
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2013 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
7#pragma once
8
9#include "MantidAPI/Column.h"
10#include "MantidDataObjects/DllConfig.h"
13
14#include <boost/algorithm/string/join.hpp>
15#include <boost/algorithm/string/trim.hpp>
16#include <boost/lexical_cast.hpp>
17
18#include <cmath>
19#include <numeric>
20namespace Mantid {
21namespace DataObjects {
22
31template <class Type> class MANTID_DATAOBJECTS_DLL VectorColumn : public API::Column {
32public:
33 VectorColumn() { m_type = typeName(); }
34
36 size_t size() const override { return m_data.size(); }
37
39 const std::type_info &get_type_info() const override { return typeid(std::vector<Type>); }
40
42 const std::type_info &get_pointer_type_info() const override { return typeid(std::vector<Type> *); }
43
45 void print(size_t index, std::ostream &s) const override {
46 const std::vector<Type> &values = m_data.at(index);
47
48 auto it = values.begin();
49
50 if (it != values.end()) {
51 s << *it;
52 ++it;
53 }
54
55 for (; it != values.end(); ++it) {
56 s << ',';
57 s << *it;
58 }
59 }
60
62 void read(size_t index, const std::string &text) override {
63 std::vector<Type> newValues;
65
66 for (const auto &element : elements) {
67 try {
68 newValues.emplace_back(boost::lexical_cast<Type>(element));
69 } catch (boost::bad_lexical_cast &) {
70 throw std::invalid_argument("Unable to convert one of the elements: " + element);
71 }
72 }
73
74 m_data.at(index) = newValues;
75 }
76
78 void read(const size_t index, std::istringstream &in) override {
79 std::string s;
80 in >> s;
81 read(index, s);
82 }
83
85 bool isBool() const override { return false; }
86
87 bool isNumber() const override { return false; }
88
90 long int sizeOfData() const override {
91 return std::accumulate(m_data.cbegin(), m_data.cend(), 0, [](long int dataSize, const auto &elem) {
92 return dataSize + static_cast<long int>(elem.size() * sizeof(Type));
93 });
94 }
95
97 VectorColumn *clone() const override {
98 auto newColumn = new VectorColumn<Type>();
99 newColumn->m_data = m_data;
100 newColumn->setName(m_name);
101 newColumn->setPlotType(m_plotType);
102 return newColumn;
103 }
104
106 double toDouble(size_t i) const override {
107 UNUSED_ARG(i);
108 throw std::runtime_error("VectorColumn is not convertible to double.");
109 }
110
112 void fromDouble(size_t i, double value) override {
113 UNUSED_ARG(i);
115 throw std::runtime_error("VectorColumn is not assignable from double.");
116 }
117
119 const std::vector<std::vector<Type>> &data() const { return m_data; }
120
121 bool equals(const Column &otherColumn, double tolerance, bool const nanEqual = false) const override {
122 if (!possibleToCompare(otherColumn)) {
123 return false;
124 }
125 const auto &otherColumnTyped = static_cast<const VectorColumn<Type> &>(otherColumn);
126 const auto &otherData = otherColumnTyped.data();
127 for (size_t i = 0; i < m_data.size(); i++) {
128 if (m_data[i].size() != otherData[i].size()) {
129 return false;
130 }
131 for (size_t j = 0; j < m_data[i].size(); j++) {
132 double const left = static_cast<double>(m_data[i][j]);
133 double const right = static_cast<double>(otherData[i][j]);
134 if (nanEqual && std::isnan(left) && std::isnan(right)) {
135 continue;
136 } else if (!Kernel::withinAbsoluteDifference(left, right, tolerance)) {
137 return false;
138 }
139 }
140 }
141 return true;
142 }
143
144 bool equalsRelErr(const Column &otherColumn, double tolerance, bool const nanEqual = false) const override {
145 if (!possibleToCompare(otherColumn)) {
146 return false;
147 }
148 const auto &otherColumnTyped = static_cast<const VectorColumn<Type> &>(otherColumn);
149 const auto &otherData = otherColumnTyped.data();
150 for (size_t i = 0; i < m_data.size(); i++) {
151 if (m_data[i].size() != otherData[i].size()) {
152 return false;
153 }
154 for (size_t j = 0; j < m_data[i].size(); j++) {
155 double const left = static_cast<double>(m_data[i][j]);
156 double const right = static_cast<double>(otherData[i][j]);
157 if (nanEqual && std::isnan(left) && std::isnan(right)) {
158 continue;
159 } else if (!Kernel::withinRelativeDifference(left, right, tolerance)) {
160 return false;
161 }
162 }
163 }
164 return true;
165 }
166
167protected:
169 void resize(size_t count) override { m_data.resize(count); }
170
172 void insert(size_t index) override {
173 // Insert empty vector at the given position
174 m_data.insert(m_data.begin() + index, std::vector<Type>());
175 }
176
178 void remove(size_t index) override { m_data.erase(m_data.begin() + index); }
179
181 void *void_pointer(size_t index) override { return &m_data.at(index); }
182
184 const void *void_pointer(size_t index) const override { return &m_data.at(index); }
185
186private:
188 std::vector<std::vector<Type>> m_data;
189
192 std::string typeName();
193};
194
195} // namespace DataObjects
196} // namespace Mantid
197
198#define DECLARE_VECTORCOLUMN(Type, TypeName) \
199 template <> std::string VectorColumn<Type>::typeName() { return #TypeName; } \
200 Kernel::RegistrationHelper register_column_##TypeName( \
201 (API::ColumnFactory::Instance().subscribe<VectorColumn<Type>>(#TypeName), 0));
double value
The value of the point.
Definition FitMW.cpp:51
std::map< DeltaEMode::Type, std::string > index
double left
double right
int count
counter
Definition Matrix.cpp:37
double tolerance
#define UNUSED_ARG(x)
Function arguments are sometimes unused in certain implmentations but are required for documentation ...
Definition System.h:48
const std::vector< Type > & m_data
Column is the base class for columns of TableWorkspace.
Definition Column.h:35
VectorColumn : table column type capable of storing vectors of primitive types.
bool equalsRelErr(const Column &otherColumn, double tolerance, bool const nanEqual=false) const override
void resize(size_t count) override
Sets the new column size.
const std::type_info & get_pointer_type_info() const override
Returns typeid for the pointer type to the data element in the column.
bool isBool() const override
Specialized type check.
long int sizeOfData() const override
Overall memory size taken by the column (bytes)
void read(const size_t index, std::istringstream &in) override
Set item from a stream.
bool equals(const Column &otherColumn, double tolerance, bool const nanEqual=false) const override
void read(size_t index, const std::string &text) override
Set item from a string value.
void fromDouble(size_t i, double value) override
Assign from double.
const void * void_pointer(size_t index) const override
Pointer to a data element.
void print(size_t index, std::ostream &s) const override
Print specified item to the stream.
void insert(size_t index) override
Inserts an item.
VectorColumn * clone() const override
Create another copy of the column.
std::string typeName()
Returns the name of the column with the given type.
void remove(size_t index) override
Removes an item.
const std::type_info & get_type_info() const override
Returns typeid for the data in the column.
double toDouble(size_t i) const override
Cast to double.
size_t size() const override
Number of individual elements in the column.
bool isNumber() const override
Are elements of the column interpretable as a number?
void * void_pointer(size_t index) override
Pointer to a data element.
const std::vector< std::vector< Type > > & data() const
Reference to the data.
std::vector< std::vector< Type > > m_data
All the vectors stored.
@ TOK_TRIM
remove leading and trailing whitespace from tokens
Helper class which provides the Collimation Length for SANS instruments.