15 #ifndef BORNAGAIN_CORE_INTENSITY_ARRAYUTILS_H
16 #define BORNAGAIN_CORE_INTENSITY_ARRAYUTILS_H
28 template <
class T> std::pair<size_t, size_t>
getShape(
const T& data);
34 template <
typename T>
struct nDim {
37 template <
typename T,
typename A>
struct nDim<std::vector<T, A>> {
38 enum { value = 1 + nDim<T>::value };
41 template <
typename T>
struct baseClass {
44 template <
typename T,
typename A>
struct baseClass<std::vector<T, A>> {
45 using value =
typename baseClass<T>::value;
49 using ReturnType = std::unique_ptr<OutputData<typename CreateDataImpl::baseClass<T>::value>>;
51 template <
class T>
friend ReturnType<T>
createData(
const T& vec);
54 static std::unique_ptr<OutputData<T>> createDataImpl(
const std::vector<T>& vec);
57 static std::unique_ptr<OutputData<T>> createDataImpl(
const std::vector<std::vector<T>>& vec);
61 template <
class T> CreateDataImpl::ReturnType<T>
createData(
const T& vec)
63 constexpr
const int size = CreateDataImpl::nDim<T>::value;
65 size == 1 || size == 2,
66 "Error in ArrayUtils::createData: invalid dimensionality or type of the input argument");
67 static_assert(std::is_same<CreateDataImpl::ReturnType<T>,
68 decltype(CreateDataImpl::createDataImpl(vec))>::value,
69 "Error in ArrayUtils::createData: invalid return type.");
70 return CreateDataImpl::createDataImpl(vec);
73 #ifdef BORNAGAIN_PYTHON
74 PyObject* createNumpyArray(
const std::vector<double>& data);
88 auto result = std::make_unique<OutputData<T>>();
89 const size_t length = vec.size();
90 result->addAxis(
FixedBinAxis(
"axis0", length, 0.0,
static_cast<double>(length)));
91 result->setRawDataVector(vec);
96 std::unique_ptr<OutputData<T>>
97 ArrayUtils::CreateDataImpl::createDataImpl(
const std::vector<std::vector<T>>& vec)
99 auto result = std::make_unique<OutputData<T>>();
102 const size_t nrows = shape.first;
103 const size_t ncols = shape.second;
105 if (nrows == 0 || ncols == 0)
106 throw std::runtime_error(
107 "Error in ArrayUtils::createDataImpl: input argument contains empty dimensions");
109 result->addAxis(
FixedBinAxis(
"axis0", ncols, 0.0,
static_cast<double>(ncols)));
110 result->addAxis(
FixedBinAxis(
"axis1", nrows, 0.0,
static_cast<double>(nrows)));
113 for (
size_t row = 0; row < nrows; ++row) {
114 for (
size_t col = 0; col < ncols; ++col) {
115 size_t globalbin = nrows - row - 1 + col * nrows;
116 (*result)[globalbin] = vec[row][col];
125 size_t nrows = data.size();
128 ncols = data[0].size();
129 for (
size_t row = 0; row < nrows; row++)
130 if (data[row].size() != ncols)
131 throw std::runtime_error(
"Util::getShape() -> Error. "
132 "Number of elements is different from row to row.");
133 return std::make_pair(nrows, ncols);
138 if (data.getRank() != 1)
139 throw std::runtime_error(
"ArrayUtils::createVector1D() -> Error. Not 1D data.");
141 using value_type =
typename T::value_type;
142 std::vector<value_type> result = data.getRawDataVector();
148 using value_type =
typename T::value_type;
149 std::vector<std::vector<value_type>> result;
151 const size_t nrows = data.getAxis(1).size();
152 const size_t ncols = data.getAxis(0).size();
154 result.resize(nrows);
156 for (
size_t row = 0; row < nrows; ++row) {
157 result[row].resize(ncols, 0.0);
158 for (
size_t col = 0; col < ncols; ++col) {
159 size_t globalbin = nrows - row - 1 + col * nrows;
160 result[row][col] = data[globalbin];
Defines and implements template class OutputData.
friend ReturnType< T > createData(const T &vec)
Creates OutputData array from input vector.
Axis with fixed bin size.
Template class to store data of any type in multi-dimensional space.
Array and Numpy utility functions getShape, createNumpyArray.
decltype(auto) createVector2D(const T &data)
Creates 2D vector from OutputData.
CreateDataImpl::ReturnType< T > createData(const T &vec)
Creates OutputData array from input vector.
decltype(auto) createVector1D(const T &data)
Creates 1D vector from OutputData.
std::pair< size_t, size_t > getShape(const T &data)
Returns shape nrows, ncols of 2D array.