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