15 #ifndef BORNAGAIN_DEVICE_DATA_OUTPUTDATA_H
16 #define BORNAGAIN_DEVICE_DATA_OUTPUTDATA_H
48 void addAxis(
const std::string&
name,
size_t size,
double start,
double end);
131 double getAxisValue(
size_t global_index,
size_t i_selected_axis)
const;
137 double getAxisValue(
size_t global_index,
const std::string& axis_name)
const;
214 #ifdef BORNAGAIN_PYTHON
241 m_value_axes = std::move(other.m_value_axes);
242 m_ll_data = other.m_ll_data;
244 other.m_ll_data =
nullptr;
280 size_t rank = other.
rank();
281 for (
size_t i = 0; i < rank; ++i)
282 addAxis(other.
axis(i));
288 ret->copyShapeFrom(*
this);
290 for (
size_t i = 0; i < m_ll_data->getTotalSize(); ++i)
291 (*ret)[i] = getValue(i);
297 if (axisNameExists(new_axis.
getName()))
298 throw std::runtime_error(
"OutputData<T>::addAxis(const IAxis& new_axis) -> "
299 "Error! Attempt to add axis with already existing name '"
301 if (new_axis.
size() > 0) {
302 m_value_axes.push_back(new_axis.
clone());
310 if (axisNameExists(
name))
311 throw std::runtime_error(
"OutputData<T>::addAxis(std::string name) -> "
312 "Error! Attempt to add axis with already existing name '"
320 return *m_value_axes[serial_number];
326 std::vector<size_t> result;
327 for (
size_t i = 0; i < rank(); ++i) {
328 int dim = m_ll_data->dimensions()[i];
329 result.push_back(dim);
337 std::vector<T> result;
338 for (
size_t i = 0; i < getAllocatedSize(); ++i)
339 result.push_back((*m_ll_data)[i]);
358 size_t remainder = global_index;
359 std::vector<int> result;
360 result.resize(m_ll_data->rank());
361 for (
size_t i = 0; i < m_ll_data->rank(); ++i) {
362 result[m_ll_data->rank() - 1 - i] =
363 (int)(remainder % m_value_axes[m_ll_data->rank() - 1 - i]->size());
364 remainder /= m_value_axes[m_ll_data->rank() - 1 - i]->size();
373 size_t remainder(global_index);
374 for (
size_t i = 0; i < m_ll_data->rank(); ++i) {
375 size_t i_axis = m_ll_data->rank() - 1 - i;
376 size_t result = remainder % m_value_axes[i_axis]->size();
377 if (i_selected_axis == i_axis)
379 remainder /= m_value_axes[i_axis]->size();
381 throw std::runtime_error(
"OutputData<T>::getAxisBinIndex() -> "
382 "Error! No axis with given number");
388 return getAxisBinIndex(global_index, getAxisIndex(axis_name));
395 if (axes_indices.size() != m_ll_data->rank())
396 throw std::runtime_error(
"size_t OutputData<T>::toGlobalIndex() -> "
397 "Error! Number of coordinates must match rank of data structure");
399 size_t step_size = 1;
400 for (
size_t i = m_ll_data->rank(); i > 0; --i) {
401 if (axes_indices[i - 1] >= m_value_axes[i - 1]->size()) {
402 std::ostringstream message;
403 message <<
"size_t OutputData<T>::toGlobalIndex() -> Error. Index ";
404 message << axes_indices[i - 1] <<
" is out of range. Axis ";
405 message << m_value_axes[i - 1]->getName();
406 message <<
" size " << m_value_axes[i - 1]->size() <<
".\n";
407 throw std::runtime_error(message.str());
409 result += axes_indices[i - 1] * step_size;
410 step_size *= m_value_axes[i - 1]->size();
419 if (coordinates.size() != m_ll_data->rank())
420 throw std::runtime_error(
"OutputData<T>::findClosestIndex() -> "
421 "Error! Number of coordinates must match rank of data structure");
422 std::vector<unsigned> axes_indexes;
423 axes_indexes.resize(m_ll_data->rank());
424 for (
size_t i = 0; i < m_ll_data->rank(); ++i)
425 axes_indexes[i] =
static_cast<unsigned>(m_value_axes[i]->findClosestIndex(coordinates[i]));
426 return toGlobalIndex(axes_indexes);
432 auto axis_index = getAxisBinIndex(global_index, i_selected_axis);
433 return (*m_value_axes[i_selected_axis])[axis_index];
439 return getAxisValue(global_index, getAxisIndex(axis_name));
444 std::vector<int> indices = getAxesBinIndices(global_index);
445 std::vector<double> result;
446 for (
size_t i_axis = 0; i_axis < indices.size(); ++i_axis)
447 result.push_back((*m_value_axes[i_axis])[indices[i_axis]]);
454 auto axis_index = getAxisBinIndex(global_index, i_selected_axis);
455 return m_value_axes[i_selected_axis]->bin(axis_index);
461 return getAxisBin(global_index, getAxisIndex(axis_name));
467 return m_ll_data->getTotalSum();
472 m_value_axes.clear();
479 throw std::runtime_error(
480 "OutputData::setAllTo() -> Error! Low-level data object was not yet initialized.");
481 m_ll_data->setAll(value);
487 throw std::runtime_error(
488 "OutputData::scaleAll() -> Error! Low-level data object was not yet initialized.");
489 m_ll_data->scaleAll(factor);
495 std::string basename(
"axis");
496 for (
size_t i = 0; i < rank; ++i) {
497 std::ostringstream
name;
498 name << basename << i;
499 addAxis(
name.str(), n_dims[i], 0.0, (
double)(n_dims[i] - 1));
528 if (rank() != m_ll_data->rank())
545 size_t rank = m_value_axes.size();
546 int* dims =
new int[rank];
547 for (
size_t i = 0; i < rank; ++i) {
548 dims[i] = (int)axis(i).size();
551 T default_value = {};
552 m_ll_data->setAll(default_value);
558 if (data_vector.size() != getAllocatedSize())
559 throw std::runtime_error(
560 "OutputData<T>::setRawDataVector() -> Error! "
561 "setRawDataVector can only be called with a data vector of the correct size.");
562 for (
size_t i = 0; i < getAllocatedSize(); ++i)
563 (*m_ll_data)[i] = data_vector[i];
568 for (
size_t i = 0; i < getAllocatedSize(); ++i)
569 (*m_ll_data)[i] = source[i];
577 if (!isInitialized())
581 if (rank() != right.
rank())
583 for (
size_t i_axis = 0; i_axis < rank(); ++i_axis)
584 if (axis(i_axis).size() != right.
axis(i_axis).
size())
594 if (!hasSameDimensions(right))
597 for (
size_t i = 0; i < m_value_axes.size(); ++i)
604 #ifdef BORNAGAIN_PYTHON
611 for (
size_t i = 0; i < m_value_axes.size(); ++i)
612 if (m_value_axes[i]->getName() == axis_name)
614 throw std::runtime_error(
"OutputData<T>::getAxisIndex() -> "
615 "Error! Axis with given name not found '"
621 for (
size_t i = 0; i < m_value_axes.size(); ++i)
622 if (m_value_axes[i]->getName() == axis_name)
Defines the macro ASSERT.
#define ASSERT(condition)
Defines class FixedBinAxis.
bool HaveSameNameAndShape(const IAxis &left, const IAxis &right)
global helper function for comparison of axes
Defines and implements template class OutputDataIterator.
PyObvject forward declaration.
Defines and implements template class SafePointerVector.
Defines struct ThreadInfo.
Axis with fixed bin size.
Interface for one-dimensional axes.
virtual IAxis * clone() const =0
clone function
virtual size_t size() const =0
retrieve the number of bins
std::string getName() const
retrieve the label of the axis
Template class to store data of any type in multi-dimensional space (low-level).
Iterator for underlying OutputData container.
Templated class to store data of type double or CumulativeValue in multi-dimensional space.
double getValue(size_t index) const
Returns value or summed value, depending on T.
void setAxisSizes(size_t rank, int *n_dims)
Adds 'rank' axes with indicated sizes.
void copyFrom(const OutputData< T > &x)
OutputData< double > * meanValues() const
void allocate()
memory allocation for current dimensions configuration
OutputData(OutputData &&)
T & operator[](size_t index)
indexed accessor
size_t getAxisBinIndex(size_t global_index, size_t i_selected_axis) const
Returns axis bin index for given global index.
iterator end()
Returns read/write iterator that points to the one past last element.
size_t toGlobalIndex(const std::vector< unsigned > &axes_indices) const
Returns global index for specified indices of axes.
const OutputData< T > & operator+=(const OutputData< T > &right)
addition-assignment operator for two output data
bool hasSameShape(const OutputData< U > &right) const
Returns true if objects a) have same dimensions b) bin boundaries of axes coincide.
OutputData(const OutputData &)=delete
size_t rank() const
Returns number of dimensions.
void setRawDataArray(const T *source)
Sets new values to raw data array.
OutputDataIterator< const T, const OutputData< T > > const_iterator
Read-only iterator type.
std::vector< T > getRawDataVector() const
Returns copy of raw data vector.
void setAllTo(const T &value)
Sets content of output data to specific value.
std::vector< double > getAxesValues(size_t global_index) const
Returns values on all defined axes for given globalbin number.
size_t findGlobalIndex(const std::vector< double > &coordinates) const
Returns global index for specified axes values.
OutputDataIterator< T, OutputData< T > > iterator
Read/write iterator type.
const OutputData & operator=(const OutputData &)=delete
T totalSum() const
Returns sum of all values in the data structure.
const IAxis & axis(size_t serial_number) const
returns axis with given serial number
std::vector< int > getAxesBinIndices(size_t global_index) const
Returns vector of axes indices for given global index.
const OutputData< T > & operator-=(const OutputData< T > &right)
substraction-assignment operator for two output data
void copyShapeFrom(const OutputData< U > &other)
Bin1D getAxisBin(size_t global_index, const std::string &axis_name) const
Returns bin of selected axis for given global_index.
void addAxis(const IAxis &new_axis)
bool isInitialized() const
returns true if object is correctly initialized
Bin1D getAxisBin(size_t global_index, size_t i_selected_axis) const
Returns bin of selected axis for given global_index.
const OutputData< T > & operator*=(const OutputData< T > &right)
multiplication-assignment operator for two output data
const OutputData< T > & operator/=(const OutputData< T > &right)
division-assignment operator for two output data
SafePointerVector< IAxis > m_value_axes
void setRawDataVector(const std::vector< T > &data_vector)
Sets new values to raw data vector.
bool axisNameExists(const std::string &axis_name) const
checks if given axis name exists
double getAxisValue(size_t global_index, const std::string &axis_name) const
Returns the value of selected axis for given global_index.
bool hasSameDimensions(const OutputData< U > &right) const
Returns true if object have same dimensions and number of axes bins.
const_iterator begin() const
Returns read-only iterator that points to the first element.
void scaleAll(const T &factor)
multiply every item of this output data by value
void addAxis(const std::string &name, size_t size, double start, double end)
iterator begin()
Returns read/write iterator that points to the first element.
size_t getAxisBinIndex(size_t global_index, const std::string &axis_name) const
Returns axis bin index for given global index.
std::vector< size_t > getAllSizes() const
Returns all sizes of its axes.
size_t getAllocatedSize() const
Returns total size of data buffer (product of bin number in every dimension).
const_iterator end() const
Returns read-only iterator that points to the one past last element.
const T & operator[](size_t index) const
indexed accessor (const)
size_t getAxisIndex(const std::string &axis_name) const
returns serial number of axis with given name
OutputData * clone() const
PyObject * getArray() const
returns data as Python numpy array
double getAxisValue(size_t global_index, size_t i_selected_axis) const
Returns the value of selected axis for given global_index.
void clear()
Sets object into initial state (no dimensions, data)
QString const & name(EShape k)