19 : m_dimension(1), m_res_function_1d(res_function_1d)
21 setName(
"ConvolutionDetectorResolution");
26 : m_dimension(2), m_res_function_1d(0)
28 setName(
"ConvolutionDetectorResolution");
29 setResolutionFunction(p_res_function_2d);
32 ConvolutionDetectorResolution::~ConvolutionDetectorResolution() =
default;
37 m_dimension = other.m_dimension;
38 m_res_function_1d = other.m_res_function_1d;
39 if (other.mp_res_function_2d)
40 setResolutionFunction(*other.mp_res_function_2d);
41 setName(other.getName());
51 return std::vector<const INode*>() << mp_res_function_2d;
57 if (p_intensity_map->
getRank() != m_dimension) {
59 "ConvolutionDetectorResolution::applyDetectorResolution() -> Error! "
60 "Intensity map must have same dimension as detector resolution function.");
62 switch (m_dimension) {
64 apply1dConvolution(p_intensity_map);
67 apply2dConvolution(p_intensity_map);
71 "ConvolutionDetectorResolution::applyDetectorResolution() -> Error! "
72 "Class ConvolutionDetectorResolution must be initialized with dimension 1 or 2.");
78 mp_res_function_2d.reset(resFunc.clone());
79 registerChild(mp_res_function_2d.get());
82 void ConvolutionDetectorResolution::apply1dConvolution(
OutputData<double>* p_intensity_map)
const
84 if (m_res_function_1d == 0)
86 "ConvolutionDetectorResolution::apply1dConvolution() -> Error! "
87 "No 1d resolution function present for convolution of 1d data.");
88 if (p_intensity_map->
getRank() != 1)
90 "ConvolutionDetectorResolution::apply1dConvolution() -> Error! "
91 "Number of axes for intensity map does not correspond to the dimension of the map.");
95 size_t data_size = source_vector.size();
99 if (axis.
size() != data_size)
101 "ConvolutionDetectorResolution::apply1dConvolution() -> Error! "
102 "Size of axis for intensity map does not correspond to size of data in the map.");
103 double step_size = std::abs(axis[0] - axis[axis.
size() - 1]) / (data_size - 1);
104 double mid_value = axis[axis.
size() / 2];
105 std::vector<double> kernel;
106 for (
size_t index = 0; index < data_size; ++index) {
107 kernel.push_back(getIntegratedPDF1d(axis[index] - mid_value, step_size));
110 std::vector<double> result;
113 std::for_each(result.begin(), result.end(), [](
double& val) { val = std::max(0.0, val); });
118 void ConvolutionDetectorResolution::apply2dConvolution(
OutputData<double>* p_intensity_map)
const
120 if (mp_res_function_2d == 0)
122 "ConvolutionDetectorResolution::apply2dConvolution() -> Error! "
123 "No 2d resolution function present for convolution of 2d data.");
124 if (p_intensity_map->
getRank() != 2)
126 "ConvolutionDetectorResolution::apply2dConvolution() -> Error! "
127 "Number of axes for intensity map does not correspond to the dimension of the map.");
130 size_t axis_size_1 = axis_1.
size();
131 size_t axis_size_2 = axis_2.
size();
132 if (axis_size_1 < 2 || axis_size_2 < 2)
135 std::vector<double> raw_source_vector = p_intensity_map->
getRawDataVector();
136 std::vector<std::vector<double>> source;
137 size_t raw_data_size = raw_source_vector.size();
138 if (raw_data_size != axis_size_1 * axis_size_2)
140 "ConvolutionDetectorResolution::apply2dConvolution() -> Error! "
141 "Intensity map data size does not match the product of its axes' sizes");
142 for (
auto it = raw_source_vector.begin(); it != raw_source_vector.end(); it += axis_size_2) {
143 std::vector<double> row_vector(it, it + axis_size_2);
144 source.push_back(row_vector);
147 std::vector<std::vector<double>> kernel;
148 kernel.resize(axis_size_1);
149 double mid_value_1 = axis_1[axis_size_1 / 2];
150 double mid_value_2 = axis_2[axis_size_2 / 2];
151 double step_size_1 = std::abs(axis_1[0] - axis_1[axis_size_1 - 1]) / (axis_size_1 - 1);
152 double step_size_2 = std::abs(axis_2[0] - axis_2[axis_size_2 - 1]) / (axis_size_2 - 1);
153 for (
size_t index_1 = 0; index_1 < axis_size_1; ++index_1) {
154 double value_1 = axis_1[index_1] - mid_value_1;
155 std::vector<double> row_vector;
156 row_vector.resize(axis_size_2, 0.0);
157 for (
size_t index_2 = 0; index_2 < axis_size_2; ++index_2) {
158 double value_2 = axis_2[index_2] - mid_value_2;
159 double z_value = getIntegratedPDF2d(value_1, step_size_1, value_2, step_size_2);
160 row_vector[index_2] = z_value;
162 kernel[index_1] = row_vector;
165 std::vector<std::vector<double>> result;
168 std::vector<double> result_vector;
169 for (
size_t index_1 = 0; index_1 < axis_size_1; ++index_1) {
170 for (
size_t index_2 = 0; index_2 < axis_size_2; ++index_2) {
171 double value = result[index_1][index_2];
172 result_vector.push_back(value);
176 std::for_each(result_vector.begin(), result_vector.end(),
177 [](
double& val) { val = std::max(0.0, val); });
178 for (
auto it = p_intensity_map->
begin(); it != p_intensity_map->
end(); ++it)
179 (*it) = result_vector[it.getIndex()];
182 double ConvolutionDetectorResolution::getIntegratedPDF1d(
double x,
double step)
const
184 double halfstep = step / 2.0;
185 double xmin = x - halfstep;
186 double xmax = x + halfstep;
187 ASSERT(m_res_function_1d !=
nullptr);
188 return m_res_function_1d(xmax) - m_res_function_1d(xmin);
191 double ConvolutionDetectorResolution::getIntegratedPDF2d(
double x,
double step_x,
double y,
194 double halfstepx = step_x / 2.0;
195 double halfstepy = step_y / 2.0;
196 double xmin = x - halfstepx;
197 double xmax = x + halfstepx;
198 double ymin = y - halfstepy;
199 double ymax = y + halfstepy;
201 mp_res_function_2d->evaluateCDF(xmax, ymax) - mp_res_function_2d->evaluateCDF(xmax, ymin)
202 - mp_res_function_2d->evaluateCDF(xmin, ymax) + mp_res_function_2d->evaluateCDF(xmin, ymin);
Defines class ConvolutionDetectorResolution.
Defines class MathFunctions::Convolve.
Convolutes the intensity in 1 or 2 dimensions with a resolution function.
ConvolutionDetectorResolution(cumulative_DF_1d res_function_1d)
Constructor taking a 1 dimensional resolution function as argument.
virtual void applyDetectorResolution(OutputData< double > *p_intensity_map) const
Convolve given intensities with the encapsulated resolution.
std::vector< const INode * > getChildren() const
Returns a vector of children (const).
Convolution of two real vectors (in 1D or 2D) using Fast Fourier Transform.
void fftconvolve(const double1d_t &source, const double1d_t &kernel, double1d_t &result)
convolution in 1D
Interface for one-dimensional axes.
virtual size_t size() const =0
retrieve the number of bins
Interface providing two-dimensional resolution function.
iterator end()
Returns read/write iterator that points to the one past last element.
std::vector< T > getRawDataVector() const
Returns copy of raw data vector.
size_t getRank() const
Returns number of dimensions.
const IAxis & getAxis(size_t serial_number) const
returns axis with given serial number
void setRawDataVector(const std::vector< T > &data_vector)
Sets new values to raw data vector.
iterator begin()
Returns read/write iterator that points to the first element.