Commit c8e5b1e2 authored by Alejandro Homs Puron's avatar Alejandro Homs Puron
Browse files

[PROC][SIM] Update and use gauss & diffraction generators in lima::processing

parent a83cf488
......@@ -6,147 +6,12 @@
#pragma once
#include <cmath>
#include <vector>
#include <lima/core/image/typedefs.hpp>
#include <lima/detectors/simulator/hw/params.hpp>
#include <lima/processing/serial/generator.hpp>
namespace lima
{
namespace detectors::simulator::hw
{
/// Calculates Gauss(x,y) for a given peak
///
/// \param[in] x X-coord
/// \param[in] y Y-coord
/// \param[in] x0 X-coord of the center
/// \param[in] y0 Y-coord of the center
/// \param[in] fwhm Full Width at Half Maximum
/// \param[in] max the central maximum value
/// \return Gauss(x,y)
inline double gauss_2d(std::ptrdiff_t x, std::ptrdiff_t y, double x0, double y0, double fwhm, double max)
{
const double SGM_FWHM = 0.42466090014400952136075141705144; // 1/(2*sqrt(2*ln(2)))
double sigma = SGM_FWHM * std::fabs(fwhm);
return max * std::exp(-((x - x0) * (x - x0) + (y - y0) * (y - y0)) / (2 * sigma * sigma));
}
/// Calculates the summary intensity at certain point
///
/// \param[in] x X-coord
/// \param[in] y Y-coord
/// \return intensity
///
inline double diffract(boost::gil::point<std::ptrdiff_t> dim, double x, double y)
{
const double pi = 3.14159265358979323846;
x -= dim.x / 2;
y -= dim.y / 2;
double r = std::sqrt(x * x + y * y);
double w = (2 * pi / 100 * (0.5 + r / 500));
double ar = (r >= 300) ? (r - 300) : 0;
double a = std::exp(-std::pow(ar / 500, 4.0)) / (r / 5000 + 0.1);
return a * std::pow(std::cos(r * w), 20.0);
}
struct generate_gauss
{
using point_t = boost::gil::point<std::ptrdiff_t>;
using const_t = generate_gauss;
using value_type = boost::gil::pixel<float, boost::gil::gray_layout_t>;
using reference = value_type;
using const_reference = value_type;
using argument_type = point_t;
using result_type = reference;
static const bool is_mutable = false;
generate_gauss(int frame_nr, double grow_factor) : m_frame_nr(frame_nr), m_grow_factor(grow_factor) {}
result_type operator()(const point_t& p) const
{
double res = 0.0;
// For each peaks
for (auto&& peak : m_peaks)
// Add gaussian
res += gauss_2d(p.x, p.y, peak.x0, peak.y0, peak.fwhm, peak.max);
// Apply grow factor
res *= (1.0 + m_grow_factor * m_frame_nr);
return value_type(res);
}
std::vector<gauss_peak> m_peaks;
int m_frame_nr = 0;
double m_grow_factor = 0.0;
};
typedef generate_gauss::point_t point_t;
typedef boost::gil::virtual_2d_locator<generate_gauss, false> generate_gauss_locator_t;
typedef boost::gil::image_view<generate_gauss_locator_t> generate_gauss_view_t;
struct generate_diffraction
{
using point_t = boost::gil::point<std::ptrdiff_t>;
using const_t = generate_diffraction;
using value_type = boost::gil::pixel<float, boost::gil::gray_layout_t>;
using reference = value_type;
using const_reference = value_type;
using argument_type = point_t;
using result_type = reference;
static const bool is_mutable = false;
generate_diffraction(int frame_nr, double grow_factor, double diffract_x, double diffract_y,
double diffract_sx = 0.0, double diffract_sy = 0.0) :
m_frame_nr(frame_nr),
m_grow_factor(grow_factor),
m_diffract_x(diffract_x),
m_diffract_y(diffract_y),
m_diffract_sx(diffract_sx),
m_diffract_sy(diffract_sy)
{
}
result_type operator()(const point_t& p) const
{
double res = 0.0;
double gx = m_diffract_x + m_frame_nr * m_diffract_sx;
double gy = m_diffract_y + m_frame_nr * m_diffract_sy;
// For each peaks
for (auto&& peak : m_peaks)
// Add gaussian
res += gauss_2d(gx, gy, peak.x0, peak.y0, peak.fwhm, peak.max);
// Apply grow factor
res *= (1 + m_grow_factor * m_frame_nr);
res *= diffract(m_dim, p.x, p.y);
return value_type(res);
}
point_t m_dim;
std::vector<gauss_peak> m_peaks;
int m_frame_nr = 0;
double m_grow_factor = 0.0;
double m_diffract_x;
double m_diffract_y;
double m_diffract_sx;
double m_diffract_sy;
};
using point_t = generate_gauss::point_t;
using generate_diffraction_locator_t = boost::gil::virtual_2d_locator<generate_diffraction, false>;
using generate_diffraction_view_t = boost::gil::image_view<generate_diffraction_locator_t>;
using namespace lima::processing;
} // namespace detectors::simulator::hw
} // namespace lima
......@@ -11,6 +11,8 @@
#include <lima/hw/params.describe.hpp>
#include <lima/processing/serial/generator/params.describe.hpp>
#include <lima/detectors/simulator/hw/enums.describe.hpp>
#include <lima/detectors/simulator/hw/params.hpp>
......@@ -30,26 +32,6 @@ namespace detectors::simulator::hw
(doc, "The height of the frame in pixel"))
// clang-format on
BOOST_DESCRIBE_STRUCT(gauss_peak, (), (x0, y0, fwhm, max))
// clang-format off
BOOST_ANNOTATE_MEMBER(gauss_peak, x0,
(desc, "x0"),
(doc, "The x coordinate of the center of the peak"))
BOOST_ANNOTATE_MEMBER(gauss_peak, y0,
(desc, "y0"),
(doc, "The y coordinate of the center of the peak"))
BOOST_ANNOTATE_MEMBER(gauss_peak, fwhm,
(desc, "full width hald maximum"),
(doc, "The full Width at Half Maximum of the peak"))
BOOST_ANNOTATE_MEMBER(gauss_peak, max,
(desc, "max value"),
(doc, "The maximum value at the center of the peak"))
// clang-format on
BOOST_DESCRIBE_STRUCT(detector_params, (), (generator_type, peaks, pixel_type, nb_prefetch_frames, grow_factor))
// clang-format off
......
......@@ -11,6 +11,8 @@
#include <lima/core/enums.hpp>
#include <lima/core/rectangle.hpp>
#include <lima/processing/serial/generator/params.hpp>
#include <lima/hw/params.hpp>
#include <lima/detectors/simulator/hw/enums.hpp>
......@@ -26,21 +28,11 @@ namespace detectors::simulator::hw
int height = 2048;
};
struct gauss_peak
{
double x0, y0; //<! The center of the peak
double fwhm; //<! Full Width at Half Maximum
double max; //<! The maximum value
gauss_peak() : x0(0), y0(0), fwhm(0), max(0) {}
gauss_peak(double x, double y, double w, double m) : x0(x), y0(y), fwhm(w), max(m) {}
};
/// Acquisition parameters specific to the detector
struct detector_params
{
generator_type_enum generator_type = generator_type_enum::gauss; //!< The type of generator
std::vector<gauss_peak> peaks = {{1024, 1024, 128.0, 100.0}}; //!< A vector of peaks
std::vector<lima::processing::gauss_peak> peaks = {{1024, 1024, 128.0, 100.0}}; //!< A vector of peaks
pixel_enum pixel_type = pixel_enum::gray8; //!< The pixel type (layout, bitdepth)
std::size_t nb_prefetch_frames = 1; //!< The number of frames pre-computed (ring buffer)
double grow_factor = 0.0; //!< The grow factor of the diffraction pattern
......
......@@ -13,20 +13,12 @@
#include <lima/core/point.hpp>
#include <lima/core/image/typedefs.hpp>
#include <lima/processing/serial/generator/params.hpp>
namespace lima
{
namespace processing
{
struct gauss_peak
{
double x0, y0; //<! The center of the peak
double fwhm; //<! Full Width at Half Maximum
double max; //<! The maximum value
gauss_peak() : x0(0), y0(0), fwhm(0), max(0) {}
gauss_peak(double x, double y, double w, double m) : x0(x), y0(y), fwhm(w), max(m) {}
};
/// Calculates Gauss(x,y) for a given peak
///
/// \param[in] x X-coord
......@@ -74,6 +66,9 @@ namespace processing
static const bool is_mutable = false;
generate_gauss() = default;
generate_gauss(int frame_nr, double grow_factor) : m_frame_nr(frame_nr), m_grow_factor(grow_factor) {}
result_type operator()(point_t const& p) const
{
double res = 0.0;
......@@ -108,8 +103,14 @@ namespace processing
static const bool is_mutable = false;
generate_diffraction(double diffract_x, double diffract_y, double diffract_sx = 0.0, double diffract_sy = 0.0) :
m_diffract_x(diffract_x), m_diffract_y(diffract_y), m_diffract_sx(diffract_sx), m_diffract_sy(diffract_sy)
generate_diffraction(int frame_nr, double grow_factor, double diffract_x, double diffract_y,
double diffract_sx = 0.0, double diffract_sy = 0.0) :
m_frame_nr(frame_nr),
m_grow_factor(grow_factor),
m_diffract_x(diffract_x),
m_diffract_y(diffract_y),
m_diffract_sx(diffract_sx),
m_diffract_sy(diffract_sy)
{
}
......
// Copyright (C) 2020 Alejandro Homs Puron, ESRF.
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#pragma once
#include <boost/describe/annotations.hpp>
#include <boost/describe/io_structs.hpp>
#include <lima/processing/serial/generator/params.hpp>
namespace lima
{
namespace processing
{
BOOST_DESCRIBE_STRUCT(gauss_peak, (), (x0, y0, fwhm, max))
// clang-format off
BOOST_ANNOTATE_MEMBER(gauss_peak, x0,
(desc, "x0"),
(doc, "The x coordinate of the center of the peak"))
BOOST_ANNOTATE_MEMBER(gauss_peak, y0,
(desc, "y0"),
(doc, "The y coordinate of the center of the peak"))
BOOST_ANNOTATE_MEMBER(gauss_peak, fwhm,
(desc, "full width hald maximum"),
(doc, "The full Width at Half Maximum of the peak"))
BOOST_ANNOTATE_MEMBER(gauss_peak, max,
(desc, "max value"),
(doc, "The maximum value at the center of the peak"))
// clang-format on
} // namespace processing
} // namespace lima
// Copyright (C) 2020 Alejandro Homs Puron, ESRF.
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#pragma once
namespace lima
{
namespace processing
{
struct gauss_peak
{
double x0, y0; //<! The center of the peak
double fwhm; //<! Full Width at Half Maximum
double max; //<! The maximum value
gauss_peak() : x0(0), y0(0), fwhm(0), max(0) {}
gauss_peak(double x, double y, double w, double m) : x0(x), y0(y), fwhm(w), max(m) {}
};
} // namespace processing
} // namespace lima
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment