Line data Source code
1 : #pragma once 2 : 3 : #include "BlockLinearOperator.h" 4 : #include "SphericalCoefficientsDescriptor.h" 5 : #include "XGIDetectorDescriptor.h" 6 : #include "LinearOperator.h" 7 : #include "elsaDefines.h" 8 : 9 : namespace elsa 10 : { 11 : /** 12 : * @brief The AXDT operator combines an arbitrary projector with 13 : * a column block linear operator, which represents the forward model 14 : * of the anisotropic dark-field signal 15 : * For details check https://journals.aps.org/prl/abstract/10.1103/PhysRevLett.117.158101 16 : * @author Matthias Wieczorek (wieczore@cs.tum.edu), original implementation 17 : * @author Nikola Dinev (nikola.dinev@tum.de), port to elsa 18 : * @author Shen Hu (shen.hu@tum.de), rewrite, integrate, port to elsa 19 : * @author Cederik Höfs (cederik.hoefs@tum.de) refactor 20 : * 21 : * @tparam real_t real type 22 : * 23 : */ 24 : template <typename data_t> 25 : class AXDTOperator : public LinearOperator<data_t> 26 : { 27 : public: 28 : using OperatorList = typename BlockLinearOperator<data_t>::OperatorList; 29 : using Symmetry = axdt::Symmetry; 30 : 31 : /** 32 : * @brief Construct an AXDTOperator 33 : * 34 : * @param[in] domainDescriptor descriptor of the domain of the operator (the 35 : * reconstructed volume) 36 : * @param[in] rangeDescriptor descriptor of the range of the operator (the XGI Detector 37 : * descriptor) 38 : * @param[in] projector the projector representing the line integral 39 : * @param[in] weights optional pre-computed weighting function for the spherical 40 : * coefficients, shape is (rangeDescriptor) coefficientCount(symmetry, maxL) 41 : * 42 : */ 43 : AXDTOperator(const SphericalCoefficientsDescriptor& domainDescriptor, 44 : const XGIDetectorDescriptor& rangeDescriptor, 45 : const LinearOperator<data_t>& projector, 46 : std::optional<DataContainer<data_t>> weights = std::nullopt); 47 : 48 12 : ~AXDTOperator() override = default; 49 : 50 : protected: 51 : /// protected copy constructor; used for cloning 52 : AXDTOperator(const AXDTOperator& other); 53 : 54 : /// implement the polymorphic clone operation 55 : AXDTOperator<data_t>* cloneImpl() const override; 56 : 57 : /// implement the polymorphic comparison operation 58 : bool isEqual(const LinearOperator<data_t>& other) const override; 59 : 60 : /// apply the AXDT operator 61 : void applyImpl(const DataContainer<data_t>& x, DataContainer<data_t>& Ax) const override; 62 : 63 : /// apply the adjoint of the AXDT operator 64 : void applyAdjointImpl(const DataContainer<data_t>& y, 65 : DataContainer<data_t>& Aty) const override; 66 : 67 : private: 68 : /// Ptr to a BlockLinearOperator, though saved as a ptr to LinearOperator 69 : std::unique_ptr<BlockLinearOperator<data_t>> bl_op; 70 : }; 71 : 72 : } // namespace elsa