Line data Source code
1 : #include "DataDescriptor.h" 2 : 3 : #include <algorithm> 4 : 5 : #include "Error.h" 6 : 7 : namespace elsa 8 : { 9 0 : DataDescriptor::DataDescriptor(IndexVector_t numberOfCoefficientsPerDimension) 10 0 : : _numberOfDimensions{numberOfCoefficientsPerDimension.size()}, 11 0 : _numberOfCoefficientsPerDimension{numberOfCoefficientsPerDimension}, 12 0 : _spacingPerDimension{RealVector_t::Ones(_numberOfDimensions)}, 13 0 : _productOfCoefficientsPerDimension{numberOfCoefficientsPerDimension} 14 : { 15 : // sanity checks 16 0 : if ((numberOfCoefficientsPerDimension.array() <= 0).any()) 17 0 : throw InvalidArgumentError( 18 0 : "DataDescriptor: non-positive number of coefficients not allowed"); 19 : 20 : // set the origin at center 21 0 : _locationOfOrigin = static_cast<real_t>(0.5) 22 0 : * (_numberOfCoefficientsPerDimension.cast<real_t>().array() 23 0 : * _spacingPerDimension.array()); 24 : 25 : // pre-compute the partial products for index computations 26 0 : for (index_t i = 0; i < _numberOfDimensions; ++i) 27 0 : _productOfCoefficientsPerDimension(i) = 28 0 : _numberOfCoefficientsPerDimension.head(i).prod(); 29 0 : } 30 : 31 0 : DataDescriptor::DataDescriptor(IndexVector_t numberOfCoefficientsPerDimension, 32 0 : RealVector_t spacingPerDimension) 33 0 : : _numberOfDimensions{numberOfCoefficientsPerDimension.size()}, 34 0 : _numberOfCoefficientsPerDimension{numberOfCoefficientsPerDimension}, 35 0 : _spacingPerDimension{spacingPerDimension}, 36 0 : _productOfCoefficientsPerDimension{numberOfCoefficientsPerDimension} 37 : { 38 : // sanity checks 39 0 : if ((numberOfCoefficientsPerDimension.array() <= 0).any()) 40 0 : throw InvalidArgumentError( 41 0 : "DataDescriptor: non-positive number of coefficients not allowed"); 42 0 : if (numberOfCoefficientsPerDimension.size() != spacingPerDimension.size()) 43 0 : throw InvalidArgumentError("DataDescriptor: mismatch between " 44 0 : "numberOfCoefficientsPerDimension and spacingPerDimension"); 45 0 : if ((spacingPerDimension.array() < 0).any()) 46 0 : throw InvalidArgumentError("DataDescriptor: non-positive spacing not allowed"); 47 : 48 : // set the origin at center 49 0 : _locationOfOrigin = static_cast<real_t>(0.5) 50 0 : * (_numberOfCoefficientsPerDimension.cast<real_t>().array() 51 0 : * _spacingPerDimension.array()); 52 : 53 : // pre-compute the partial products for index computations 54 0 : for (index_t i = 0; i < _numberOfDimensions; ++i) 55 0 : _productOfCoefficientsPerDimension(i) = 56 0 : _numberOfCoefficientsPerDimension.head(i).prod(); 57 0 : } 58 : 59 0 : DataDescriptor::~DataDescriptor() {} 60 : 61 0 : index_t DataDescriptor::getNumberOfDimensions() const { return _numberOfDimensions; } 62 : 63 0 : index_t DataDescriptor::getNumberOfCoefficients() const 64 : { 65 0 : return _numberOfCoefficientsPerDimension.prod(); 66 : } 67 : 68 0 : IndexVector_t DataDescriptor::getNumberOfCoefficientsPerDimension() const 69 : { 70 0 : return _numberOfCoefficientsPerDimension; 71 : } 72 : 73 0 : RealVector_t DataDescriptor::getSpacingPerDimension() const { return _spacingPerDimension; } 74 : 75 0 : RealVector_t DataDescriptor::getLocationOfOrigin() const { return _locationOfOrigin; } 76 : 77 0 : index_t DataDescriptor::getIndexFromCoordinate(const elsa::IndexVector_t& coordinate) const 78 : { 79 : // sanity check 80 0 : if (coordinate.size() != _productOfCoefficientsPerDimension.size()) 81 0 : throw InvalidArgumentError( 82 0 : "DataDescriptor: mismatch of coordinate and descriptor size"); 83 : 84 0 : return _productOfCoefficientsPerDimension.cwiseProduct(coordinate).sum(); 85 : } 86 : 87 0 : IndexVector_t DataDescriptor::getCoordinateFromIndex(elsa::index_t index) const 88 : { 89 : // sanity check 90 0 : if (index < 0 || index >= getNumberOfCoefficients()) 91 0 : throw InvalidArgumentError("DataDescriptor: invalid index"); 92 : 93 0 : IndexVector_t coordinate(_numberOfDimensions); 94 : 95 0 : index_t leftOver = index; 96 0 : for (index_t i = _numberOfDimensions - 1; i >= 1; --i) { 97 0 : coordinate(i) = leftOver / _productOfCoefficientsPerDimension(i); 98 0 : leftOver %= _productOfCoefficientsPerDimension(i); 99 : } 100 0 : coordinate(0) = leftOver; 101 : 102 0 : return coordinate; 103 0 : } 104 : 105 0 : bool DataDescriptor::isEqual(const DataDescriptor& other) const 106 : { 107 0 : if (typeid(other) != typeid(*this)) 108 0 : return false; 109 : 110 0 : return (_numberOfDimensions == other._numberOfDimensions) 111 0 : && (_numberOfCoefficientsPerDimension == other._numberOfCoefficientsPerDimension) 112 0 : && (_spacingPerDimension == other._spacingPerDimension) 113 0 : && (_locationOfOrigin == other._locationOfOrigin); 114 : } 115 : 116 : } // namespace elsa