Line data Source code
1 : #pragma once 2 : 3 : #include "elsaDefines.h" 4 : #include "Cloneable.h" 5 : 6 : #include <vector> 7 : 8 : namespace elsa 9 : { 10 : namespace detail 11 : { 12 : template <typename Derived> 13 : index_t coord2Idx(const Eigen::MatrixBase<Derived>& coord, 14 : const Eigen::MatrixBase<Derived>& strideProduct) 15 1689195 : { 16 1689195 : return strideProduct.cwiseProduct(coord).sum(); 17 1689195 : } 18 : 19 : template <typename Derived> 20 : Eigen::Matrix<index_t, Derived::RowsAtCompileTime, 1> 21 : idx2Coord(index_t idx, const Eigen::MatrixBase<Derived>& strideProduct) 22 30815579 : { 23 30815579 : Eigen::Matrix<index_t, Derived::RowsAtCompileTime, 1> coordinate; 24 : 25 30815579 : index_t leftOver = idx; 26 : 27 30815579 : if constexpr (Derived::RowsAtCompileTime == Eigen::Dynamic) { 28 13467055 : auto size = strideProduct.size(); 29 13467055 : coordinate.resize(size); 30 : 31 34714368 : for (index_t i = size - 1; i >= 1; --i) { 32 17364009 : coordinate[i] = leftOver / strideProduct[i]; 33 17364009 : leftOver %= strideProduct[i]; 34 17364009 : } 35 17350359 : } else { 36 27069023 : for (index_t i = Derived::RowsAtCompileTime - 1; i >= 1; --i) { 37 13601968 : coordinate[i] = leftOver / strideProduct[i]; 38 13601968 : leftOver %= strideProduct[i]; 39 13601968 : } 40 13467055 : } 41 : 42 30815579 : coordinate[0] = leftOver; 43 : 44 30815579 : return coordinate; 45 30815579 : } 46 : 47 : inline RealVector_t computeOrigin(const IndexVector_t& shape, const RealVector_t& spacing) 48 271117 : { 49 271117 : return real_t{0.5} * (shape.cast<real_t>().array() * spacing.array()).matrix(); 50 271117 : } 51 : } // namespace detail 52 : 53 : // declare DataContainer 54 : template <typename data_t> 55 : class DataContainer; 56 : 57 : /** 58 : * @brief Base class for representing metadata for linearized n-dimensional signal stored in 59 : * memory 60 : * 61 : * @author Matthias Wieczorek - initial code 62 : * @author Tobias Lasser - modularization, modernization 63 : * @author Maximilian Hornung - various enhancements 64 : * @author David Frank - inheritance restructuring 65 : * 66 : * This class provides an interface for metadata about a signal that is stored in memory. This 67 : * base class provides other descriptor subclasses with a fundamental interface to access the 68 : * important parameters (i.e. dimensionality, size and spacing) of the metadata. 69 : * 70 : */ 71 : class DataDescriptor : public Cloneable<DataDescriptor> 72 : { 73 : public: 74 : /// delete default constructor (having no metadata is invalid) 75 : DataDescriptor() = delete; 76 : 77 : /// Pure virtual destructor 78 : virtual ~DataDescriptor() = 0; 79 : 80 : /** 81 : * @brief Constructor for DataDescriptor, accepts dimension and size 82 : * 83 : * @param[in] numberOfCoefficientsPerDimension vector containing the number of coefficients 84 : * per dimension, (dimension is set implicitly from the size of the vector) 85 : * 86 : * @throw InvalidArgumentError if any number of coefficients is non-positive 87 : */ 88 : explicit DataDescriptor(IndexVector_t numberOfCoefficientsPerDimension); 89 : 90 : /** 91 : * @brief Constructor for DataDescriptor, accepts dimension, size and spacing 92 : * 93 : * @param[in] numberOfCoefficientsPerDimension vector containing the number of coefficients 94 : * per dimension, (dimension is set implicitly from the size of the vector) 95 : * @param[in] spacingPerDimension vector containing the spacing per dimension 96 : * 97 : * @throw InvalidArgumentError if any number of coefficients is non-positive, 98 : * or sizes of numberOfCoefficientsPerDimension and spacingPerDimension do not match 99 : */ 100 : explicit DataDescriptor(IndexVector_t numberOfCoefficientsPerDimension, 101 : RealVector_t spacingPerDimension); 102 : 103 : /// return the number of dimensions 104 : index_t getNumberOfDimensions() const; 105 : 106 : /// return the total number of coefficients 107 : index_t getNumberOfCoefficients() const; 108 : 109 : /// return the number of coefficients per dimension 110 : IndexVector_t getNumberOfCoefficientsPerDimension() const; 111 : 112 : /// return the product of coefficients per dimension 113 : IndexVector_t getProductOfCoefficientsPerDimension() const; 114 : 115 : /// return the spacing per dimension 116 : RealVector_t getSpacingPerDimension() const; 117 : 118 : /// return the location of the origin (typically the center) 119 : RealVector_t getLocationOfOrigin() const; 120 : 121 : /** 122 : * @brief computes the linearized index in the data vector from local coordinates 123 : * 124 : * @param[in] coordinate vector containing the local coordinate 125 : * @return the index into the linearized data vector 126 : * 127 : * The local coordinates are integers, running from 0 to 128 : * _numberOfCoefficientsPerDimension[i]-1 for every dimension i = 0,...,_numberOfDimensions. 129 : * Linearization is assumed to be done in order of the dimensions. 130 : */ 131 : index_t getIndexFromCoordinate(const elsa::IndexVector_t& coordinate) const; 132 : 133 : /** 134 : * @brief computes the local coordinates from a linearized index 135 : * 136 : * @param[in] index into the linearized data vector 137 : * @return the local coordinate corresponding to the index 138 : * 139 : * The local coordinates are integers, running from 0 to 140 : * _numberOfCoefficientsPerDimension[i]-1 for every dimension i = 141 : * 0,...,_numberOfDimensions. Linearization is assumed to be done in order of the 142 : * dimensions. 143 : */ 144 : IndexVector_t getCoordinateFromIndex(index_t index) const; 145 : 146 : /// @brief create a DataContainer for the given DataDescriptor. By 147 : /// default an uninitialized element is returned, and the caller 148 : /// is responsible to properly initialize the element 149 : template <class data_t> 150 : DataContainer<data_t> element() const; 151 : 152 : protected: 153 : /// Number of dimensions 154 : index_t _numberOfDimensions; 155 : 156 : /// vector containing the number of coefficients per dimension 157 : IndexVector_t _numberOfCoefficientsPerDimension; 158 : 159 : /// vector containing the spacing per dimension 160 : RealVector_t _spacingPerDimension; 161 : 162 : /// vector containing precomputed partial products of coefficients per dimension for index 163 : /// computations 164 : IndexVector_t _productOfCoefficientsPerDimension; 165 : 166 : /// vector containing the origin of the described volume (typically the center) 167 : RealVector_t _locationOfOrigin; 168 : 169 : /// default copy constructor, hidden from non-derived classes to prevent potential slicing 170 71558 : DataDescriptor(const DataDescriptor&) = default; 171 : 172 : /// default move constructor, hidden from non-derived classes to prevent potential slicing 173 2369 : DataDescriptor(DataDescriptor&&) = default; 174 : 175 : /// implement the polymorphic comparison operation 176 : bool isEqual(const DataDescriptor& other) const override; 177 : }; 178 : 179 : } // namespace elsa