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 int length =
sizeof(Type);
71 std::string
name = std::string(
typeid(Type).
name());
72 if ((
name.find(
'i') != std::string::npos) || (
name.find(
'l') != std::string::npos) ||
73 (
name.find(
'x') != std::string::npos)) {
78 this->m_type =
"int64";
81 if (
name.find(
'f') != std::string::npos) {
82 this->m_type =
"float";
84 if (
name.find(
'd') != std::string::npos) {
85 this->m_type =
"double";
87 if (
name.find(
'u') != std::string::npos) {
89 this->m_type =
"uint32_t";
92 this->m_type =
"uint64_t";
95 if (this->m_type.empty()) {
104 const std::type_info &
get_type_info()
const override {
return typeid(Type); }
110 void read(
size_t index,
const std::string &text)
override;
112 void read(
const size_t index, std::istringstream &in)
override;
115 bool isNumber()
const override {
return std::is_convertible<Type, double>::value; }
117 long int sizeOfData()
const override {
return static_cast<long int>(
m_data.size() *
sizeof(Type)); }
132 return boost::numeric_cast<double, DoubleType>(
value);
160 m_data[i] =
static_cast<Type
>(boost::numeric_cast<DoubleType, double>(
value));
174 return convertToDouble(
m_data[i]);
176 return std::numeric_limits<double>::quiet_NaN();
182 void sortIndex(
bool ascending,
size_t start,
size_t end, std::vector<size_t> &indexVec,
183 std::vector<std::pair<size_t, size_t>> &equalRanges)
const override;
186 void sortValues(
const std::vector<size_t> &indexVec)
override;
189 if (!possibleToCompare(otherColumn)) {
192 const auto &otherColumnTyped =
static_cast<const TableColumn<Type> &
>(otherColumn);
193 const auto &otherData = otherColumnTyped.
data();
194 return compareVectors(otherData,
tolerance, nanEqual);
198 if (!possibleToCompare(otherColumn)) {
201 const auto &otherColumnTyped =
static_cast<const TableColumn<Type> &
>(otherColumn);
202 const auto &otherData = otherColumnTyped.
data();
203 return compareVectorsRelError(otherData,
tolerance, nanEqual);
230 return compareVectors(newVector,
tolerance, nanEqual, std::is_integral<Type>());
234 for (
size_t i = 0; i <
m_data.size(); i++) {
235 if (!Kernel::withinAbsoluteDifference<Type, double>(
m_data[i], newVector[i],
tolerance)) {
243 std::false_type)
const {
244 for (
size_t i = 0; i <
m_data.size(); i++) {
245 if (nanEqual && std::isnan(
m_data[i]) && std::isnan(newVector[i])) {
247 }
else if (!Kernel::withinAbsoluteDifference<Type, double>(
m_data[i], newVector[i],
tolerance)) {
256 return compareVectorsRelError(newVector,
tolerance, nanEqual, std::is_integral<Type>());
260 for (
size_t i = 0; i <
m_data.size(); i++) {
261 if (!Kernel::withinRelativeDifference<Type, double>(
m_data[i], newVector[i],
tolerance)) {
269 std::false_type)
const {
270 for (
size_t i = 0; i <
m_data.size(); i++) {
271 if (nanEqual && std::isnan(
m_data[i]) && std::isnan(newVector[i])) {
273 }
else if (!Kernel::withinRelativeDifference<Type, double>(
m_data[i], newVector[i],
tolerance)) {
285 for (
size_t i = 0; i <
m_data.size(); i++) {
286 if (
m_data[i] != newVector[i]) {
297 for (
size_t i = 0; i <
m_data.size(); i++) {
298 if (!(
m_data[i] == newVector[i])) {
308 bool const nanEqual)
const {
310 for (std::size_t i = 0; i <
m_data.size(); i++) {
337 double tolerance,
bool const nanEqual)
const {
339 for (
size_t i = 0; i <
m_data.size(); i++) {
369 std::istringstream istr(text);
382template <
typename Type>
class CompareValues {
387 CompareValues(
const TableColumn<Type> &column,
bool ascending) :
m_data(column.data()),
m_ascending(ascending) {}
388 bool operator()(
size_t i,
size_t j) {
396template <
typename Type>
398 std::vector<std::pair<size_t, size_t>> &equalRanges)
const {
401 const size_t n =
m_data.size();
406 auto iBegin = indexVec.begin() + start;
407 auto iEnd = indexVec.begin() + end;
409 std::stable_sort(iBegin,
iEnd, CompareValues<Type>(*
this, ascending));
413 for (
auto i = iBegin + 1; i !=
iEnd; ++i) {
416 eqStart =
static_cast<size_t>(std::distance(indexVec.begin(), i - 1));
421 auto p = std::make_pair(eqStart,
static_cast<size_t>(std::distance(indexVec.begin(), i)));
422 equalRanges.emplace_back(p);
430 auto p = std::make_pair(eqStart,
static_cast<size_t>(std::distance(indexVec.begin(),
iEnd)));
431 equalRanges.emplace_back(p);
437 assert(
m_data.size() == indexVec.size());
438 std::vector<Type> sortedData(
m_data.size());
440 auto sortedIt = sortedData.begin();
441 for (
auto idx = indexVec.begin(); idx != indexVec.end(); ++idx, ++sortedIt) {
445 std::swap(
m_data, sortedData);
462 std::string str =
"Data type of column " + c->
name() +
" does not match " +
typeid(T).
name();
463 throw std::runtime_error(str);
476 std::string str =
"Data type of column " + c->name() +
" does not match " +
typeid(
API::Boolean).
name();
477 throw std::runtime_error(str);
491#define DECLARE_TABLECOLUMN(DataType, TypeName) \
493 Mantid::Kernel::RegistrationHelper register_column_##TypeName( \
494 (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.