Line data Source code
1 : #include "PhaseContrastProjector.h"
2 :
3 : namespace elsa
4 : {
5 : template <typename data_t>
6 : PhaseContrastBlobVoxelProjector<data_t>::PhaseContrastBlobVoxelProjector(
7 : const VolumeDescriptor& domainDescriptor, const DetectorDescriptor& rangeDescriptor,
8 : data_t radius, data_t alpha, index_t order)
9 : : LinearOperator<data_t>(domainDescriptor, rangeDescriptor),
10 : blob(radius, alpha, order),
11 : _dim(domainDescriptor.getNumberOfDimensions())
12 780 : {
13 : // sanity checks
14 780 : if (_dim < 2 || _dim > 3) {
15 0 : throw InvalidArgumentError(
16 0 : "PhaseContrastBlobVoxelProjector: only supporting 2d/3d operations");
17 0 : }
18 :
19 780 : if (_dim != rangeDescriptor.getNumberOfDimensions()) {
20 0 : throw InvalidArgumentError(
21 0 : "PhaseContrastBlobVoxelProjector: domain and range dimension need to match");
22 0 : }
23 :
24 780 : if (rangeDescriptor.getNumberOfGeometryPoses() == 0) {
25 0 : throw InvalidArgumentError(
26 0 : "PhaseContrastBlobVoxelProjector: rangeDescriptor without any geometry");
27 0 : }
28 780 : }
29 :
30 : template <typename data_t>
31 : void PhaseContrastBlobVoxelProjector<data_t>::applyImpl(const elsa::DataContainer<data_t>& x,
32 : elsa::DataContainer<data_t>& Ax) const
33 492 : {
34 492 : if (_dim == 2)
35 492 : voxel::forwardVoxel<2>(x, Ax, blob.get_derivative_lut(),
36 492 : voxel::differential_weight_function_2D<data_t>);
37 0 : else
38 0 : voxel::forwardVoxel<3>(x, Ax, blob.get_normalized_gradient_lut(),
39 0 : voxel::differential_weight_function_3D<data_t>);
40 492 : }
41 :
42 : template <typename data_t>
43 : void PhaseContrastBlobVoxelProjector<data_t>::applyAdjointImpl(
44 : const elsa::DataContainer<data_t>& y, elsa::DataContainer<data_t>& Aty) const
45 0 : {
46 0 : if (_dim == 2)
47 0 : voxel::backwardVoxel<2>(y, Aty, blob.get_derivative_lut(),
48 0 : voxel::differential_weight_function_2D<data_t>);
49 0 : else
50 0 : voxel::backwardVoxel<3>(y, Aty, blob.get_normalized_gradient_lut(),
51 0 : voxel::differential_weight_function_3D<data_t>);
52 0 : }
53 :
54 : template <typename data_t>
55 : PhaseContrastBlobVoxelProjector<data_t>*
56 : PhaseContrastBlobVoxelProjector<data_t>::cloneImpl() const
57 0 : {
58 0 : return new PhaseContrastBlobVoxelProjector(
59 0 : downcast<VolumeDescriptor>(*this->_domainDescriptor),
60 0 : downcast<DetectorDescriptor>(*this->_rangeDescriptor), blob.radius(), blob.alpha(),
61 0 : blob.order());
62 0 : }
63 :
64 : template <typename data_t>
65 : bool PhaseContrastBlobVoxelProjector<data_t>::isEqual(
66 : const elsa::LinearOperator<data_t>& other) const
67 0 : {
68 0 : return LinearOperator<data_t>::isEqual(other);
69 0 : }
70 :
71 : template <typename data_t>
72 : PhaseContrastBSplineVoxelProjector<data_t>::PhaseContrastBSplineVoxelProjector(
73 : const VolumeDescriptor& domainDescriptor, const DetectorDescriptor& rangeDescriptor,
74 : const index_t order)
75 : : LinearOperator<data_t>(domainDescriptor, rangeDescriptor),
76 : _dim(domainDescriptor.getNumberOfDimensions()),
77 : bspline(_dim, order)
78 0 : {
79 : // sanity checks
80 0 : if (_dim < 2 || _dim > 3) {
81 0 : throw InvalidArgumentError(
82 0 : "PhaseContrastBSplineVoxelProjector: only supporting 2d/3d operations");
83 0 : }
84 :
85 0 : if (_dim != rangeDescriptor.getNumberOfDimensions()) {
86 0 : throw InvalidArgumentError(
87 0 : "PhaseContrastBSplineVoxelProjector: domain and range dimension need to match");
88 0 : }
89 :
90 0 : if (rangeDescriptor.getNumberOfGeometryPoses() == 0) {
91 0 : throw InvalidArgumentError(
92 0 : "PhaseContrastBSplineVoxelProjector: rangeDescriptor without any geometry");
93 0 : }
94 0 : }
95 :
96 : template <typename data_t>
97 : void
98 : PhaseContrastBSplineVoxelProjector<data_t>::applyImpl(const elsa::DataContainer<data_t>& x,
99 : elsa::DataContainer<data_t>& Ax) const
100 0 : {
101 0 : if (_dim == 2)
102 0 : voxel::forwardVoxel<2>(x, Ax, bspline.get_derivative_lut(),
103 0 : voxel::differential_weight_function_2D<data_t>);
104 0 : else
105 0 : voxel::forwardVoxel<3>(x, Ax, bspline.get_normalized_gradient_lut(),
106 0 : voxel::differential_weight_function_3D<data_t>);
107 0 : }
108 :
109 : template <typename data_t>
110 : void PhaseContrastBSplineVoxelProjector<data_t>::applyAdjointImpl(
111 : const elsa::DataContainer<data_t>& y, elsa::DataContainer<data_t>& Aty) const
112 0 : {
113 0 : if (_dim == 2)
114 0 : voxel::backwardVoxel<2>(y, Aty, bspline.get_derivative_lut(),
115 0 : voxel::differential_weight_function_2D<data_t>);
116 0 : else
117 0 : voxel::backwardVoxel<3>(y, Aty, bspline.get_normalized_gradient_lut(),
118 0 : voxel::differential_weight_function_3D<data_t>);
119 0 : }
120 :
121 : template <typename data_t>
122 : PhaseContrastBSplineVoxelProjector<data_t>*
123 : PhaseContrastBSplineVoxelProjector<data_t>::cloneImpl() const
124 0 : {
125 0 : return new PhaseContrastBSplineVoxelProjector(
126 0 : downcast<VolumeDescriptor>(*this->_domainDescriptor),
127 0 : downcast<DetectorDescriptor>(*this->_rangeDescriptor), bspline.order());
128 0 : }
129 :
130 : template <typename data_t>
131 : bool PhaseContrastBSplineVoxelProjector<data_t>::isEqual(
132 : const elsa::LinearOperator<data_t>& other) const
133 0 : {
134 0 : return LinearOperator<data_t>::isEqual(other);
135 0 : }
136 :
137 : template class PhaseContrastBSplineVoxelProjector<float>;
138 : template class PhaseContrastBSplineVoxelProjector<double>;
139 : template class PhaseContrastBlobVoxelProjector<float>;
140 : template class PhaseContrastBlobVoxelProjector<double>;
141 : }; // namespace elsa
|