15 #ifndef BORNAGAIN_CORE_INTENSITY_OUTPUTDATA_H
16 #define BORNAGAIN_CORE_INTENSITY_OUTPUTDATA_H
48 void addAxis(
const std::string& name,
size_t size,
double start,
double end);
134 double getAxisValue(
size_t global_index,
size_t i_selected_axis)
const;
140 double getAxisValue(
size_t global_index,
const std::string& axis_name)
const;
217 #ifdef BORNAGAIN_PYTHON
275 for (
size_t i = 0; i < rank; ++i)
282 ret->copyShapeFrom(*
this);
284 for (
size_t i = 0; i < mp_ll_data->getTotalSize(); ++i)
285 (*ret)[i] = getValue(i);
291 if (axisNameExists(new_axis.
getName()))
293 "OutputData<T>::addAxis(const IAxis& new_axis) -> "
294 "Error! Attempt to add axis with already existing name '"
296 if (new_axis.
size() > 0) {
297 m_value_axes.push_back(new_axis.
clone());
305 if (axisNameExists(name))
307 "OutputData<T>::addAxis(std::string name) -> "
308 "Error! Attempt to add axis with already existing name '"
316 return *m_value_axes[serial_number];
321 return getAxis(getAxisIndex(axis_name));
327 std::vector<size_t> result;
328 for (
size_t i = 0; i < getRank(); ++i) {
329 int dim = mp_ll_data->getDimensions()[i];
330 result.push_back(dim);
338 std::vector<T> result;
339 for (
size_t i = 0; i < getAllocatedSize(); ++i)
340 result.push_back((*mp_ll_data)[i]);
359 size_t remainder = global_index;
360 std::vector<int> result;
361 result.resize(mp_ll_data->getRank());
362 for (
size_t i = 0; i < mp_ll_data->getRank(); ++i) {
363 result[mp_ll_data->getRank() - 1 - i] =
364 (int)(remainder % m_value_axes[mp_ll_data->getRank() - 1 - i]->size());
365 remainder /= m_value_axes[mp_ll_data->getRank() - 1 - i]->size();
374 size_t remainder(global_index);
375 for (
size_t i = 0; i < mp_ll_data->getRank(); ++i) {
376 size_t i_axis = mp_ll_data->getRank() - 1 - i;
377 size_t result = remainder % m_value_axes[i_axis]->size();
378 if (i_selected_axis == i_axis)
380 remainder /= m_value_axes[i_axis]->size();
383 "Error! No axis with given number");
389 return getAxisBinIndex(global_index, getAxisIndex(axis_name));
396 if (axes_indices.size() != mp_ll_data->getRank())
398 "size_t OutputData<T>::toGlobalIndex() -> "
399 "Error! Number of coordinates must match rank of data structure");
401 size_t step_size = 1;
402 for (
size_t i = mp_ll_data->getRank(); i > 0; --i) {
403 if (axes_indices[i - 1] >= m_value_axes[i - 1]->size()) {
404 std::ostringstream message;
405 message <<
"size_t OutputData<T>::toGlobalIndex() -> Error. Index ";
406 message << axes_indices[i - 1] <<
" is out of range. Axis ";
407 message << m_value_axes[i - 1]->getName();
408 message <<
" size " << m_value_axes[i - 1]->size() <<
".\n";
411 result += axes_indices[i - 1] * step_size;
412 step_size *= m_value_axes[i - 1]->size();
421 if (coordinates.size() != mp_ll_data->getRank())
423 "OutputData<T>::findClosestIndex() -> "
424 "Error! Number of coordinates must match rank of data structure");
425 std::vector<unsigned> axes_indexes;
426 axes_indexes.resize(mp_ll_data->getRank());
427 for (
size_t i = 0; i < mp_ll_data->getRank(); ++i)
428 axes_indexes[i] =
static_cast<unsigned>(m_value_axes[i]->findClosestIndex(coordinates[i]));
429 return toGlobalIndex(axes_indexes);
435 auto axis_index = getAxisBinIndex(global_index, i_selected_axis);
436 return (*m_value_axes[i_selected_axis])[axis_index];
442 return getAxisValue(global_index, getAxisIndex(axis_name));
447 std::vector<int> indices = getAxesBinIndices(global_index);
448 std::vector<double> result;
449 for (
size_t i_axis = 0; i_axis < indices.size(); ++i_axis)
450 result.push_back((*m_value_axes[i_axis])[indices[i_axis]]);
457 auto axis_index = getAxisBinIndex(global_index, i_selected_axis);
458 return m_value_axes[i_selected_axis]->getBin(axis_index);
464 return getAxisBin(global_index, getAxisIndex(axis_name));
470 return mp_ll_data->getTotalSum();
475 m_value_axes.clear();
483 "OutputData::setAllTo() -> Error! Low-level data object was not yet initialized.");
484 mp_ll_data->setAll(value);
491 "OutputData::scaleAll() -> Error! Low-level data object was not yet initialized.");
492 mp_ll_data->scaleAll(factor);
498 std::string basename(
"axis");
499 for (
size_t i = 0; i < rank; ++i) {
500 std::ostringstream name;
501 name << basename << i;
502 addAxis(name.str(), n_dims[i], 0.0, (
double)(n_dims[i] - 1));
531 if (getRank() != mp_ll_data->getRank())
548 size_t rank = m_value_axes.size();
549 int* dims =
new int[rank];
550 for (
size_t i = 0; i < rank; ++i) {
551 dims[i] = (int)getAxis(i).size();
554 T default_value = {};
555 mp_ll_data->setAll(default_value);
561 if (data_vector.size() != getAllocatedSize())
563 "OutputData<T>::setRawDataVector() -> Error! "
564 "setRawDataVector can only be called with a data vector of the correct size.");
565 for (
size_t i = 0; i < getAllocatedSize(); ++i)
566 (*mp_ll_data)[i] = data_vector[i];
571 for (
size_t i = 0; i < getAllocatedSize(); ++i)
572 (*mp_ll_data)[i] = source[i];
580 if (!isInitialized())
584 if (getRank() != right.
getRank())
586 for (
size_t i_axis = 0; i_axis < getRank(); ++i_axis)
587 if (getAxis(i_axis).size() != right.
getAxis(i_axis).
size())
597 if (!hasSameDimensions(right))
600 for (
size_t i = 0; i < m_value_axes.size(); ++i)
607 #ifdef BORNAGAIN_PYTHON
614 for (
size_t i = 0; i < m_value_axes.size(); ++i)
615 if (m_value_axes[i]->getName() == axis_name)
618 "Error! Axis with given name not found '"
624 for (
size_t i = 0; i < m_value_axes.size(); ++i)
625 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.
Template class to store data of any type 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
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
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 & getAxis(const std::string &axis_name) const
returns axis with given name
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)
size_t getRank() const
Returns number of dimensions.
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 IAxis & getAxis(size_t serial_number) const
returns axis with given serial number
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)