24 , m_res_function_1d(res_function_1d)
31 , m_res_function_1d(nullptr)
60 throw std::runtime_error(
61 "ConvolutionDetectorResolution::applyDetectorResolution() -> Error! "
62 "Intensity map must have same dimension as detector resolution function.");
72 throw std::runtime_error(
73 "ConvolutionDetectorResolution::applyDetectorResolution() -> Error! "
74 "Class ConvolutionDetectorResolution must be initialized with dimension 1 or 2.");
86 if (p_intensity_map->
rank() != 1)
87 throw std::runtime_error(
88 "ConvolutionDetectorResolution::apply1dConvolution() -> Error! "
89 "Number of axes for intensity map does not correspond to the dimension of the map.");
90 const IAxis& axis = p_intensity_map->
axis(0);
92 std::vector<double> source_vector = p_intensity_map->
flatVector();
93 size_t data_size = source_vector.size();
97 if (axis.
size() != data_size)
98 throw std::runtime_error(
99 "ConvolutionDetectorResolution::apply1dConvolution() -> Error! "
100 "Size of axis for intensity map does not correspond to size of data in the map.");
101 double step_size = std::abs(axis[0] - axis[axis.
size() - 1]) / (data_size - 1);
102 double mid_value = axis[axis.
size() / 2];
103 std::vector<double> kernel;
104 for (
size_t index = 0; index < data_size; ++index)
107 std::vector<double> result;
110 for (
double& e : result)
111 e = std::max(0.0, e);
119 if (p_intensity_map->
rank() != 2)
120 throw std::runtime_error(
121 "ConvolutionDetectorResolution::apply2dConvolution() -> Error! "
122 "Number of axes for intensity map does not correspond to the dimension of the map.");
123 const IAxis& axis_1 = p_intensity_map->
axis(0);
124 const IAxis& axis_2 = p_intensity_map->
axis(1);
125 size_t axis_size_1 = axis_1.
size();
126 size_t axis_size_2 = axis_2.
size();
127 if (axis_size_1 < 2 || axis_size_2 < 2)
130 std::vector<double> raw_source_vector = p_intensity_map->
flatVector();
131 std::vector<std::vector<double>> source;
132 size_t raw_data_size = raw_source_vector.size();
133 if (raw_data_size != axis_size_1 * axis_size_2)
134 throw std::runtime_error(
135 "ConvolutionDetectorResolution::apply2dConvolution() -> Error! "
136 "Intensity map data size does not match the product of its axes' sizes");
137 for (
auto it = raw_source_vector.begin(); it != raw_source_vector.end(); it += axis_size_2) {
138 std::vector<double> row_vector(it, it + axis_size_2);
139 source.push_back(row_vector);
142 std::vector<std::vector<double>> kernel;
143 kernel.resize(axis_size_1);
144 double mid_value_1 = axis_1[axis_size_1 / 2];
145 double mid_value_2 = axis_2[axis_size_2 / 2];
146 double step_size_1 = std::abs(axis_1[0] - axis_1[axis_size_1 - 1]) / (axis_size_1 - 1);
147 double step_size_2 = std::abs(axis_2[0] - axis_2[axis_size_2 - 1]) / (axis_size_2 - 1);
148 for (
size_t index_1 = 0; index_1 < axis_size_1; ++index_1) {
149 double value_1 = axis_1[index_1] - mid_value_1;
150 std::vector<double> row_vector;
151 row_vector.resize(axis_size_2, 0.0);
152 for (
size_t index_2 = 0; index_2 < axis_size_2; ++index_2) {
153 double value_2 = axis_2[index_2] - mid_value_2;
155 row_vector[index_2] = z_value;
157 kernel[index_1] = row_vector;
160 std::vector<std::vector<double>> result;
163 std::vector<double> result_vector;
164 for (
size_t index_1 = 0; index_1 < axis_size_1; ++index_1) {
165 for (
size_t index_2 = 0; index_2 < axis_size_2; ++index_2) {
166 double value = result[index_1][index_2];
167 result_vector.push_back(value);
170 ASSERT(axis_size_1 * axis_size_2 == p_intensity_map->
size());
171 for (
size_t i = 0; i < p_intensity_map->
size(); ++i) {
174 (*p_intensity_map)[i] = std::max(0.0, result[i0][i1]);
180 double halfstep = step / 2.0;
181 double xmin = x - halfstep;
182 double xmax = x + halfstep;
190 double halfstepx = step_x / 2.0;
191 double halfstepy = step_y / 2.0;
192 double xmin = x - halfstepx;
193 double xmax = x + halfstepx;
194 double ymin = y - halfstepy;
195 double ymax = y + halfstepy;
Defines the macro ASSERT.
#define ASSERT(condition)
Defines class ConvolutionDetectorResolution.
Defines class Math::Convolve.
Defines class FixedBinAxis.
Defines and implements templated class Frame.
Convolutes the intensity in 1 or 2 dimensions with a resolution function.
double getIntegratedPDF1d(double x, double step) const
void setResolutionFunction(const IResolutionFunction2D &resFunc)
double(*)(double) cumulative_DF_1d
std::vector< const INode * > nodeChildren() const override
Returns all children.
~ConvolutionDetectorResolution() override
cumulative_DF_1d m_res_function_1d
std::unique_ptr< IResolutionFunction2D > m_res_function_2d
ConvolutionDetectorResolution(cumulative_DF_1d res_function_1d)
Constructor taking a 1 dimensional resolution function as argument.
void apply1dConvolution(Datafield *p_intensity_map) const
void applyDetectorResolution(Datafield *p_intensity_map) const override
Convolve given intensities with the encapsulated resolution.
ConvolutionDetectorResolution * clone() const override
void apply2dConvolution(Datafield *p_intensity_map) const
double getIntegratedPDF2d(double x, double step_x, double y, double step_y) 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
Stores radiation power per bin.
const IAxis & axis(size_t k) const
void setVector(const std::vector< double > &data_vector)
Sets new values to raw data vector.
std::vector< double > flatVector() const
Returns copy of raw data vector.
size_t size() const
Returns total size of data buffer (product of bin number in every dimension).
const Frame & frame() const
size_t projectedIndex(size_t i_flat, size_t k_axis) const
Returns axis bin index for given global index.
Abstract base class for one-dimensional axes.
virtual size_t size() const =0
Returns the number of bins.
Interface providing two-dimensional resolution function.
IResolutionFunction2D * clone() const override=0