9#include <boost/numeric/conversion/cast.hpp>
17#include "MantidDataObjects/DllConfig.h"
22namespace DataObjects {
49template <
class Type>
class TableColumn :
public API::Column {
60 operator double()
const {
61 throw std::runtime_error(std::string(
"Cannot convert ") +
typeid(Type).
name() +
" to double.");
63 operator Type()
const {
64 throw std::runtime_error(std::string(
"Cannot convert double to ") +
typeid(Type).
name() +
".");
70 std::string
name = std::string(
typeid(Type).
name());
71 if ((
name.find(
'i') != std::string::npos) || (
name.find(
'l') != std::string::npos) ||
72 (
name.find(
'x') != std::string::npos)) {
73 if constexpr (
sizeof(Type) == 4) {
76 if constexpr (
sizeof(Type) == 8) {
77 this->m_type =
"int64";
80 if (
name.find(
'f') != std::string::npos) {
81 this->m_type =
"float";
83 if (
name.find(
'd') != std::string::npos) {
84 this->m_type =
"double";
86 if (
name.find(
'u') != std::string::npos) {
87 if constexpr (
sizeof(Type) == 4) {
88 this->m_type =
"uint32_t";
90 if constexpr (
sizeof(Type) == 8) {
91 this->m_type =
"uint64_t";
94 if (this->m_type.empty()) {
103 const std::type_info &
get_type_info()
const override {
return typeid(Type); }
109 void read(
size_t index,
const std::string &text)
override;
111 void read(
const size_t index, std::istringstream &in)
override;
114 bool isNumber()
const override {
return std::is_convertible<Type, double>::value; }
116 long int sizeOfData()
const override {
return static_cast<long int>(
m_data.size() *
sizeof(Type)); }
131 return boost::numeric_cast<double, DoubleType>(
value);
159 m_data[i] =
static_cast<Type
>(boost::numeric_cast<DoubleType, double>(
value));
173 return convertToDouble(
m_data[i]);
175 return std::numeric_limits<double>::quiet_NaN();
181 void sortIndex(
bool ascending,
size_t start,
size_t end, std::vector<size_t> &indexVec,
182 std::vector<std::pair<size_t, size_t>> &equalRanges)
const override;
185 void sortValues(
const std::vector<size_t> &indexVec)
override;
188 if (!possibleToCompare(otherColumn)) {
191 const auto &otherColumnTyped =
static_cast<const TableColumn<Type> &
>(otherColumn);
192 const auto &otherData = otherColumnTyped.
data();
193 return compareVectors(otherData,
tolerance, nanEqual);
197 if (!possibleToCompare(otherColumn)) {
200 const auto &otherColumnTyped =
static_cast<const TableColumn<Type> &
>(otherColumn);
201 const auto &otherData = otherColumnTyped.
data();
202 return compareVectorsRelError(otherData,
tolerance, nanEqual);
229 return compareVectors(newVector,
tolerance, nanEqual, std::is_integral<Type>());
233 for (
size_t i = 0; i <
m_data.size(); i++) {
234 if (!Kernel::withinAbsoluteDifference<Type, double>(
m_data[i], newVector[i],
tolerance)) {
242 std::false_type)
const {
243 for (
size_t i = 0; i <
m_data.size(); i++) {
244 if (nanEqual && std::isnan(
m_data[i]) && std::isnan(newVector[i])) {
246 }
else if (!Kernel::withinAbsoluteDifference<Type, double>(
m_data[i], newVector[i],
tolerance)) {
255 return compareVectorsRelError(newVector,
tolerance, nanEqual, std::is_integral<Type>());
259 for (
size_t i = 0; i <
m_data.size(); i++) {
260 if (!Kernel::withinRelativeDifference<Type, double>(
m_data[i], newVector[i],
tolerance)) {
268 std::false_type)
const {
269 for (
size_t i = 0; i <
m_data.size(); i++) {
270 if (nanEqual && std::isnan(
m_data[i]) && std::isnan(newVector[i])) {
272 }
else if (!Kernel::withinRelativeDifference<Type, double>(
m_data[i], newVector[i],
tolerance)) {
284 for (
size_t i = 0; i <
m_data.size(); i++) {
285 if (
m_data[i] != newVector[i]) {
296 for (
size_t i = 0; i <
m_data.size(); i++) {
297 if (!(
m_data[i] == newVector[i])) {
307 bool const nanEqual)
const {
309 for (std::size_t i = 0; i <
m_data.size(); i++) {
336 double tolerance,
bool const nanEqual)
const {
338 for (
size_t i = 0; i <
m_data.size(); i++) {
368 std::istringstream istr(text);
381template <
typename Type>
class CompareValues {
386 CompareValues(
const TableColumn<Type> &column,
bool ascending) :
m_data(column.data()),
m_ascending(ascending) {}
387 bool operator()(
size_t i,
size_t j) {
395template <
typename Type>
397 std::vector<std::pair<size_t, size_t>> &equalRanges)
const {
400 const size_t n =
m_data.size();
405 auto iBegin = indexVec.begin() + start;
406 auto iEnd = indexVec.begin() + end;
408 std::stable_sort(iBegin,
iEnd, CompareValues<Type>(*
this, ascending));
412 for (
auto i = iBegin + 1; i !=
iEnd; ++i) {
415 eqStart =
static_cast<size_t>(std::distance(indexVec.begin(), i - 1));
420 auto p = std::make_pair(eqStart,
static_cast<size_t>(std::distance(indexVec.begin(), i)));
421 equalRanges.emplace_back(p);
429 auto p = std::make_pair(eqStart,
static_cast<size_t>(std::distance(indexVec.begin(),
iEnd)));
430 equalRanges.emplace_back(p);
436 assert(
m_data.size() == indexVec.size());
437 std::vector<Type> sortedData(
m_data.size());
439 auto sortedIt = sortedData.begin();
440 for (
auto idx = indexVec.begin(); idx != indexVec.end(); ++idx, ++sortedIt) {
444 std::swap(
m_data, sortedData);
461 std::string str =
"Data type of column " + c->
name() +
" does not match " +
typeid(T).
name();
462 throw std::runtime_error(str);
475 std::string str =
"Data type of column " + c->name() +
" does not match " +
typeid(
API::Boolean).
name();
476 throw std::runtime_error(str);
490#define DECLARE_TABLECOLUMN(DataType, TypeName) \
492 Mantid::Kernel::RegistrationHelper register_column_##TypeName( \
493 (Mantid::API::ColumnFactory::Instance().subscribe<Mantid::DataObjects::TableColumn<DataType>>(#TypeName), 0)); \
double value
The value of the point.
std::map< DeltaEMode::Type, std::string > index
const std::vector< Type > & m_data
Column is the base class for columns of TableWorkspace.
const std::string & name() const
Name (caption) of the column.
TableColumn_ptr(const std::shared_ptr< API::Column > &c)
Constructor.
Shared pointer to a column with automatic type cast and data type check.
TableColumn_ptr(std::shared_ptr< API::Column > c)
Constructor.
Class TableColumn implements abstract class Column for any copyable data type.
bool compareVectors(const std::vector< Type > &newVector, double tolerance, bool const nanEqual=false) const
long int sizeOfData() const override
Memory used by the column.
void read(const size_t index, std::istringstream &in) override
Read in from stream and set the value at the given index.
double operator[](size_t i) const override
return a value casted to double; the users responsibility is to be sure, that the casting is possible
void remove(size_t index) override
Removes an item at index.
void resize(size_t count) override
Resize.
bool isNumber() const override
Are elements of the column interpretable as a number?
void sortValues(const std::vector< size_t > &indexVec) override
Re-arrange values in this column according to indices in indexVec.
const std::vector< Type > & data() const
Const reference to the data.
size_t size() const override
Number of individual elements in the column.
bool compareVectors(const std::vector< Type > &newVector, double tolerance, bool const, std::true_type) const
void print(size_t index, std::ostream &s) const override
Output to an ostream.
bool isBool() const override
Type check.
void read(size_t index, const std::string &text) override
Read in a string and set the value at the given index.
void * void_pointer(size_t index) override
Returns a pointer to the data element.
void insert(size_t index) override
Inserts default value at position index.
Type * dataArray()
Pointer to the data array.
bool equals(const Column &otherColumn, double tolerance, bool const nanEqual=false) const override
TableColumn * clone() const override
Clone.
std::vector< Type > & data()
Reference to the data.
bool compareVectorsRelError(const std::vector< Type > &newVector, double tolerance, bool const nanEqual=false) const
bool equalsRelErr(const Column &otherColumn, double tolerance, bool const nanEqual=false) const override
void fromDouble(size_t i, double value) override
Cast an element to double if possible.
bool compareVectorsRelError(const std::vector< Type > &newVector, double tolerance, bool const nanEqual, std::false_type) const
const void * void_pointer(size_t index) const override
Returns a pointer to the data element.
void sortIndex(bool ascending, size_t start, size_t end, std::vector< size_t > &indexVec, std::vector< std::pair< size_t, size_t > > &equalRanges) const override
Sort a vector of indices according to values in corresponding cells of this column.
const std::type_info & get_pointer_type_info() const override
Type id of the pointer to data in the column.
bool compareVectorsRelError(const std::vector< Type > &newVector, double tolerance, bool const, std::true_type) const
bool compareVectors(const std::vector< Type > &newVector, double tolerance, bool const nanEqual, std::false_type) const
double convertToDouble(const std::string &value) const
Cast an string to double if possible.
const std::type_info & get_type_info() const override
Type id of the data in the column.
double convertToDouble(const T &value) const
Cast an element to double if possible.
std::vector< Type > m_data
Column data.
double toDouble(size_t i) const override
Cast an element to double if possible.
TableWorkspace is an implementation of Workspace in which the data are organised in columns of same s...
static bool isnan(V3D const &vec)
Determine if a V3D can be considered nan.
MANTID_KERNEL_DLL bool withinRelativeDifference(T const x, T const y, S const tolerance)
Test whether x, y are within relative tolerance tol.
MANTID_KERNEL_DLL bool withinAbsoluteDifference(T const x, T const y, S const tolerance)
Test whether x, y are within absolute tolerance tol.
Helper class which provides the Collimation Length for SANS instruments.
As TableColumn stores its data in a std::vector bool type cannot be used in the same way as the other...
Helper struct helping to write a generic casting to double.
InconvertibleToDoubleType(const Type &)
Constructor.
InconvertibleToDoubleType(const double &)
Constructor.