Line data Source code
1 : #include "DataDescriptor.h" 2 : 3 : #include <algorithm> 4 : 5 : #include "Complex.h" 6 : #include "Error.h" 7 : #include "DataContainer.h" 8 : 9 : namespace elsa 10 : { 11 : DataDescriptor::DataDescriptor(IndexVector_t numberOfCoefficientsPerDimension) 12 : : _numberOfDimensions{numberOfCoefficientsPerDimension.size()}, 13 : _numberOfCoefficientsPerDimension{numberOfCoefficientsPerDimension}, 14 : _spacingPerDimension{RealVector_t::Ones(_numberOfDimensions)}, 15 : _productOfCoefficientsPerDimension{numberOfCoefficientsPerDimension} 16 17437 : { 17 : // sanity checks 18 17437 : if ((numberOfCoefficientsPerDimension.array() <= 0).any()) 19 4 : throw InvalidArgumentError( 20 4 : "DataDescriptor: non-positive number of coefficients not allowed"); 21 : 22 : // set the origin at center 23 17433 : _locationOfOrigin = 24 17433 : detail::computeOrigin(_numberOfCoefficientsPerDimension, _spacingPerDimension); 25 : 26 : // pre-compute the partial products for index computations 27 53425 : for (index_t i = 0; i < _numberOfDimensions; ++i) 28 35992 : _productOfCoefficientsPerDimension(i) = 29 35992 : _numberOfCoefficientsPerDimension.head(i).prod(); 30 17433 : } 31 : 32 : DataDescriptor::DataDescriptor(IndexVector_t numberOfCoefficientsPerDimension, 33 : RealVector_t spacingPerDimension) 34 : : _numberOfDimensions{numberOfCoefficientsPerDimension.size()}, 35 : _numberOfCoefficientsPerDimension{numberOfCoefficientsPerDimension}, 36 : _spacingPerDimension{spacingPerDimension}, 37 : _productOfCoefficientsPerDimension{numberOfCoefficientsPerDimension} 38 253114 : { 39 : // sanity checks 40 253114 : if ((numberOfCoefficientsPerDimension.array() <= 0).any()) 41 6 : throw InvalidArgumentError( 42 6 : "DataDescriptor: non-positive number of coefficients not allowed"); 43 253108 : if (numberOfCoefficientsPerDimension.size() != spacingPerDimension.size()) 44 7 : throw InvalidArgumentError("DataDescriptor: mismatch between " 45 7 : "numberOfCoefficientsPerDimension and spacingPerDimension"); 46 253101 : if ((spacingPerDimension.array() < 0).any()) 47 3 : throw InvalidArgumentError("DataDescriptor: non-positive spacing not allowed"); 48 : 49 : // set the origin at center 50 253098 : _locationOfOrigin = 51 253098 : detail::computeOrigin(_numberOfCoefficientsPerDimension, _spacingPerDimension); 52 : 53 : // pre-compute the partial products for index computations 54 885640 : for (index_t i = 0; i < _numberOfDimensions; ++i) 55 632542 : _productOfCoefficientsPerDimension(i) = 56 632542 : _numberOfCoefficientsPerDimension.head(i).prod(); 57 253098 : } 58 : 59 343989 : DataDescriptor::~DataDescriptor() {} 60 : 61 : index_t DataDescriptor::getNumberOfDimensions() const 62 1042198 : { 63 1042198 : return _numberOfDimensions; 64 1042198 : } 65 : 66 : index_t DataDescriptor::getNumberOfCoefficients() const 67 32356100 : { 68 32356100 : return _numberOfCoefficientsPerDimension.prod(); 69 32356100 : } 70 : 71 : IndexVector_t DataDescriptor::getNumberOfCoefficientsPerDimension() const 72 573243 : { 73 573243 : return _numberOfCoefficientsPerDimension; 74 573243 : } 75 : 76 : RealVector_t DataDescriptor::getSpacingPerDimension() const 77 95454 : { 78 95454 : return _spacingPerDimension; 79 95454 : } 80 : 81 : RealVector_t DataDescriptor::getLocationOfOrigin() const 82 8745859 : { 83 8745859 : return _locationOfOrigin; 84 8745859 : } 85 : 86 : index_t DataDescriptor::getIndexFromCoordinate(const elsa::IndexVector_t& coordinate) const 87 1672970 : { 88 : // sanity check 89 1672970 : if (coordinate.size() != _productOfCoefficientsPerDimension.size()) 90 3 : throw InvalidArgumentError( 91 3 : "DataDescriptor: mismatch of coordinate and descriptor size"); 92 : 93 1672967 : return detail::coord2Idx(coordinate, _productOfCoefficientsPerDimension); 94 1672967 : } 95 : 96 : IndexVector_t DataDescriptor::getCoordinateFromIndex(elsa::index_t index) const 97 17348287 : { 98 : // sanity check 99 17348429 : if (index < 0 || index >= getNumberOfCoefficients()) 100 6 : throw InvalidArgumentError("DataDescriptor: invalid index"); 101 : 102 17348281 : return detail::idx2Coord(index, _productOfCoefficientsPerDimension); 103 17348281 : } 104 : 105 : template <class data_t> 106 : DataContainer<data_t> DataDescriptor::element() const 107 5 : { 108 5 : return DataContainer<data_t>(*this); 109 5 : } 110 : 111 : bool DataDescriptor::isEqual(const DataDescriptor& other) const 112 15496 : { 113 15496 : if (typeid(other) != typeid(*this)) 114 38 : return false; 115 : 116 15458 : return (_numberOfDimensions == other._numberOfDimensions) 117 15458 : && (_numberOfCoefficientsPerDimension == other._numberOfCoefficientsPerDimension) 118 15458 : && (_spacingPerDimension == other._spacingPerDimension) 119 15458 : && (_locationOfOrigin == other._locationOfOrigin); 120 15458 : } 121 : 122 : IndexVector_t DataDescriptor::getProductOfCoefficientsPerDimension() const 123 57072 : { 124 57072 : return _productOfCoefficientsPerDimension; 125 57072 : } 126 : 127 : // ------------------------------------------ 128 : // explicit template instantiation 129 : template DataContainer<index_t> DataDescriptor::element() const; 130 : template DataContainer<float> DataDescriptor::element() const; 131 : template DataContainer<double> DataDescriptor::element() const; 132 : template DataContainer<complex<float>> DataDescriptor::element() const; 133 : template DataContainer<complex<double>> DataDescriptor::element() const; 134 : } // namespace elsa