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.