Commit 6041c2c4 authored by Alejandro Homs Puron's avatar Alejandro Homs Puron
Browse files

[PROC][SIM] Formalize Gauss & Diffraction generator parameters

parent 51cf6b15
......@@ -32,13 +32,6 @@ namespace detectors::simulator::hw::generator
generator(init_params const& init_pars, exec_params const& exec_pars) :
m_init_params(init_pars), m_exec_params(exec_pars)
{
auto center = dimensions() / 2; // The center of the full frame
// If no peak specified, add one peak in the center
if (m_exec_params.peaks.empty())
m_exec_params.peaks.emplace_back(center.x, center.y, 128.0, 100.0);
m_diffract_pos = center;
}
point_t dimensions() { return {m_init_params.width, m_init_params.height}; }
......@@ -49,8 +42,6 @@ namespace detectors::simulator::hw::generator
template <typename Visitor>
void frame_getter_visit(int frame_nr, Visitor&& visitor)
{
using namespace lima::processing;
auto pixel_visitor = [&](auto pixel) {
auto image_dims = dimensions();
......@@ -62,16 +53,13 @@ namespace detectors::simulator::hw::generator
switch (m_exec_params.generator_type) {
case generator_type_enum::gauss: {
generate_gauss func(frame_nr, m_exec_params.grow_factor);
func.m_peaks = m_exec_params.peaks;
generate_gauss func(frame_nr, m_exec_params.gauss);
visitor(converter(func));
break;
}
case generator_type_enum::diffraction: {
generate_diffraction func(frame_nr, m_exec_params.grow_factor, m_diffract_pos.x, m_diffract_pos.y,
m_diffract_speed.x, m_diffract_speed.y);
func.m_peaks = m_exec_params.peaks;
generate_diffraction func(frame_nr, m_exec_params.diffraction);
visitor(converter(func));
break;
}
......@@ -87,8 +75,6 @@ namespace detectors::simulator::hw::generator
init_params m_init_params;
exec_params m_exec_params;
point_t m_diffract_pos;
point_t m_diffract_speed{0, 0};
};
} // namespace detectors::simulator::hw::generator
} // namespace lima
......@@ -30,24 +30,24 @@ namespace detectors::simulator::hw::generator
(doc, "The height of the frame in pixel"))
// clang-format on
BOOST_DESCRIBE_STRUCT(exec_params, (), (generator_type, peaks, pixel_type, grow_factor))
BOOST_DESCRIBE_STRUCT(exec_params, (), (generator_type, gauss, diffraction, pixel_type))
// clang-format off
BOOST_ANNOTATE_MEMBER(exec_params, generator_type,
(desc, "type of generator"),
(doc, "The type of generator [gauss, diffraction]"))
BOOST_ANNOTATE_MEMBER(exec_params, peaks,
(desc, "vector of peak"),
(doc, "A vector of peaks"))
BOOST_ANNOTATE_MEMBER(exec_params, gauss,
(desc, "Gauss generator params"),
(doc, "The configuration of the Gauss generator"))
BOOST_ANNOTATE_MEMBER(exec_params, diffraction,
(desc, "Diffraction generator params"),
(doc, "The configuration of the Diffraction generator"))
BOOST_ANNOTATE_MEMBER(exec_params, pixel_type,
(desc, "pixel type"),
(doc, "The pixel type (channel, color space and layout) [gray8, gray16, gray32, gray32f]"))
BOOST_ANNOTATE_MEMBER(exec_params, grow_factor,
(desc, "grow factor"),
(doc, "The grow factor for gauss peaks"))
// clang-format on
using boost::describe::operator<<;
......
......@@ -18,6 +18,8 @@ namespace lima
{
namespace detectors::simulator::hw::generator
{
using namespace lima::processing::generator;
/// Initialization parameters: defined once in the application
struct init_params
{
......@@ -28,10 +30,10 @@ namespace detectors::simulator::hw::generator
/// Execution parameters: defined each time the generator is instantiated
struct exec_params
{
generator_type_enum generator_type = generator_type_enum::gauss; //!< The type of generator
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)
double grow_factor = 0.0; //!< The grow factor of the diffraction pattern
generator_type_enum generator_type = generator_type_enum::gauss; //!< The type of generator
gauss_params gauss = {2048, 2048}; //!< The Gauss generator parameters
diffraction_params diffraction = {2048, 2048}; //!< The Diffraction generator parameters
pixel_enum pixel_type = pixel_enum::gray8; //!< The pixel type (layout, bitdepth)
};
} // namespace detectors::simulator::hw::generator
......
......@@ -46,7 +46,9 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_generator, T, image_types)
auto pixel_type = lima::pixel_fromtype(lima::type_c<Channel>);
init_params init_pars{dims.x, dims.y};
exec_params exec_pars{generator_type_enum::gauss, {{512, 512, 128., 100.}}, pixel_type, 1.0};
gauss_params gauss_pars{dims.x, dims.y};
diffraction_params diffraction_pars{dims.x, dims.y};
exec_params exec_pars{generator_type_enum::gauss, gauss_pars, diffraction_pars, pixel_type};
generator gauss_gen(init_pars, exec_pars);
exec_pars.generator_type = generator_type_enum::diffraction;
generator diffraction_gen(init_pars, exec_pars);
......
......@@ -17,7 +17,7 @@
namespace lima
{
namespace processing
namespace processing::generator
{
/// Calculates Gauss(x,y) for a given peak
///
......@@ -33,22 +33,23 @@ namespace processing
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));
double r2 = (x - x0) * (x - x0) + (y - y0) * (y - y0);
return max * std::exp(-r2 / (2 * sigma * sigma));
}
/// Calculates the summary intensity at certain point
///
/// \param[in] x X-coord
/// \param[in] y Y-coord
/// \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
/// \return intensity
///
inline double diffract(point_t dim, double x, double y)
inline double diffract(double x, double y, double x0, double y0)
{
const double pi = 3.14159265358979323846;
x -= dim.x / 2;
y -= dim.y / 2;
double r = std::sqrt(x * x + y * y);
double r = std::sqrt((x - x0) * (x - x0) + (y - y0) * (y - y0));
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);
......@@ -66,27 +67,27 @@ 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) {}
generate_gauss(int frame_nr, gauss_params const& params) : m_frame_nr(frame_nr), m_params(params) {}
generate_gauss(int frame_nr, double width, double height) : m_frame_nr(frame_nr), m_params(width, height) {}
result_type operator()(point_t const& p) const
{
double res = 0.0;
// For each peaks
for (auto&& peak : m_peaks)
for (auto&& peak : m_params.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);
res *= (1.0 + m_params.grow_factor * m_frame_nr);
return result_type(res);
}
std::vector<gauss_peak> m_peaks;
int m_frame_nr = 0;
double m_grow_factor = 0.0;
int m_frame_nr;
gauss_params m_params;
};
typedef boost::gil::virtual_2d_locator<generate_gauss, false> generate_gauss_locator_t;
......@@ -103,46 +104,32 @@ namespace processing
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)
generate_diffraction(int frame_nr, diffraction_params const& params) :
m_params(params), m_gauss(frame_nr, m_params.gauss)
{
}
result_type operator()(point_t const& p) const
generate_diffraction(int frame_nr, double width, double height) :
m_params(width, height), m_gauss(frame_nr, m_params.gauss)
{
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);
result_type operator()(point_t const& p) const
{
using gauss_coord = std::ptrdiff_t;
gauss_coord gx = m_params.source_pos_x + m_frame_nr * m_params.source_speed_x;
gauss_coord gy = m_params.source_pos_y + m_frame_nr * m_params.source_speed_y;
double res = m_gauss({gx, gy});
res *= diffract(m_dim, p.x, p.y);
// Apply diffraction pattern
res *= diffract(p.x, p.y, m_params.x0, m_params.y0);
return result_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;
diffraction_params m_params;
generate_gauss m_gauss;
int m_frame_nr;
};
using generate_diffraction_locator_t = boost::gil::virtual_2d_locator<generate_diffraction, false>;
......@@ -205,5 +192,5 @@ namespace processing
return view;
}
} // namespace processing
} // namespace processing::generator
} // namespace lima
......@@ -13,7 +13,7 @@
namespace lima
{
namespace processing
namespace processing::generator
{
BOOST_DESCRIBE_STRUCT(gauss_peak, (), (x0, y0, fwhm, max))
......@@ -35,5 +35,49 @@ namespace processing
(doc, "The maximum value at the center of the peak"))
// clang-format on
} // namespace processing
BOOST_DESCRIBE_STRUCT(gauss_params, (), (peaks, grow_factor))
// clang-format off
BOOST_ANNOTATE_MEMBER(gauss_params, peaks,
(desc, "vector of gauss_peak"),
(doc, "A vector of Gaussian peaks"))
BOOST_ANNOTATE_MEMBER(gauss_params, grow_factor,
(desc, "grow factor"),
(doc, "The grow factor for gauss peaks (per frame)"))
// clang-format on
BOOST_DESCRIBE_STRUCT(diffraction_params, (),
(gauss, x0, y0, source_pos_x, source_pos_y, source_speed_x, source_speed_y))
// clang-format off
BOOST_ANNOTATE_MEMBER(diffraction_params, gauss,
(desc, "Gauss generator params"),
(doc, "The configuration of the gauss generator"))
BOOST_ANNOTATE_MEMBER(diffraction_params, x0,
(desc, "x0"),
(doc, "The x coordinate of the center of the diffraction pattern"))
BOOST_ANNOTATE_MEMBER(diffraction_params, y0,
(desc, "y0"),
(doc, "The y coordinate of the center of the diffraction pattern"))
BOOST_ANNOTATE_MEMBER(diffraction_params, source_pos_x,
(desc, "source position x"),
(doc, "The x coordinate of the source position (relative to the Gauss reference frame)"))
BOOST_ANNOTATE_MEMBER(diffraction_params, source_pos_y,
(desc, "source position y"),
(doc, "The y coordinate of the source position (relative to the Gauss reference frame)"))
BOOST_ANNOTATE_MEMBER(diffraction_params, source_speed_x,
(desc, "source speed x"),
(doc, "The x coordinate of the source speed (in time units of a frame)"))
BOOST_ANNOTATE_MEMBER(diffraction_params, source_speed_y,
(desc, "source speed y"),
(doc, "The y coordinate of the source speed (in time units of a frame)"))
} // namespace processing::generator
} // namespace lima
......@@ -8,8 +8,9 @@
namespace lima
{
namespace processing
namespace processing::generator
{
/// Single peak for Gauss generator
struct gauss_peak
{
double x0, y0; //<! The center of the peak
......@@ -20,5 +21,28 @@ namespace processing
gauss_peak(double x, double y, double w, double m) : x0(x), y0(y), fwhm(w), max(m) {}
};
} // namespace processing
/// Gauss generator params
struct gauss_params
{
std::vector<gauss_peak> peaks; //!< A vector of peaks
double grow_factor{0.0}; //!< The grow factor of the diffraction pattern
gauss_params() = default;
gauss_params(std::vector<gauss_peak> const& p, double f = 0.0) : peaks(p), grow_factor(f) {}
gauss_params(double width, double height) : peaks({{width / 2, height / 2, 128.0, 100}}) {}
};
/// Diffraction generator params
struct diffraction_params
{
double x0, y0; //!< The center of the diffraction pattern
gauss_params gauss{{{5, 5, 0.5, 100}}}; //!< Gauss generator params
double source_pos_x{5}, source_pos_y{5}; //!< The source position, relative to the gauss reference frame
double source_speed_x{0}, source_speed_y{0}; //!< The source speed (in time units of a frame)
diffraction_params() = default;
diffraction_params(double width, double height) : x0(width / 2), y0(height / 2) {}
};
} // namespace processing::generator
} // namespace lima
......@@ -18,14 +18,15 @@ struct frame_fixture
{
frame_fixture() : input_frame(2048, 2048, lima::pixel_enum::gray32f)
{
using namespace lima::processing::generator;
BOOST_TEST_MESSAGE("setup frame fixture");
auto center = input_frame.dimensions() / 2;
lima::processing::generate_gauss func;
func.m_peaks.emplace_back(center.x, center.y, 128, 0.1);
auto dims = input_frame.dimensions();
generate_gauss func(0, dims.x, dims.y);
lima::processing::generate_gauss_locator_t loc(lima::point_t(0, 0), lima::point_t(1, 1), func);
lima::processing::generate_gauss_view_t src(input_frame.dimensions(), loc);
generate_gauss_locator_t loc(lima::point_t(0, 0), lima::point_t(1, 1), func);
generate_gauss_view_t src(input_frame.dimensions(), loc);
boost::gil::copy_and_convert_pixels(src, lima::view(input_frame));
}
......
......@@ -17,14 +17,15 @@ struct frame_fixture
{
frame_fixture() : input_frame(2048, 2048, lima::pixel_enum::gray32f)
{
using namespace lima::processing::generator;
BOOST_TEST_MESSAGE("setup frame fixture");
auto center = input_frame.dimensions() / 2;
lima::processing::generate_gauss func;
func.m_peaks.emplace_back(center.x, center.y, 128, 0.1);
auto dims = input_frame.dimensions();
generate_gauss func(0, dims.x, dims.y);
lima::processing::generate_gauss_locator_t loc(lima::point_t(0, 0), lima::point_t(1, 1), func);
lima::processing::generate_gauss_view_t src(input_frame.dimensions(), loc);
generate_gauss_locator_t loc(lima::point_t(0, 0), lima::point_t(1, 1), func);
generate_gauss_view_t src(input_frame.dimensions(), loc);
boost::gil::copy_and_convert_pixels(src, lima::view(input_frame));
}
......
......@@ -50,11 +50,11 @@ BOOST_AUTO_TEST_CASE(test_generator)
int nb_peaks = std::atoi(framework::master_test_suite().argv[5]);
lima::frame input_frame(2048, 2048, lima::pixel_enum::gray32f);
auto center = input_frame.dimensions() / 2;
// Background diffraction
lima::processing::generate_gauss func;
func.m_peaks.emplace_back(center.x, center.y, gauss_fwhm, gauss_max);
using namespace lima::processing::generator;
auto dims = input_frame.dimensions();
generate_gauss func(0, dims.x, dims.y);
// Background noise
std::normal_distribution distribution(noise_mean, noise_std);
......@@ -69,8 +69,8 @@ BOOST_AUTO_TEST_CASE(test_generator)
unique_random_generate_n(std::back_inserter(peak_linear_idx), nb_peaks, min, max, gen);
for (auto&& idx : peak_linear_idx) {
auto nb_rows = input_frame.dimensions().x;
lima::point_t center{idx % nb_rows, idx / nb_rows};
func.m_peaks.emplace_back(center.x, center.y, 3.0, 1000.0);
lima::point_t center{long(idx % nb_rows), long(idx / nb_rows)};
func.m_params.peaks.emplace_back(center.x, center.y, 3.0, 1000.0);
}
// Generate images
......
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