Commit 644506fa authored by Alejandro Homs Puron's avatar Alejandro Homs Puron Committed by Generic Bliss account for Control Software
Browse files

[PROC][SMX] Add average of corrected and peak found images

parent ba4f4fe7
......@@ -80,7 +80,7 @@ namespace processing::pipelines
(error_model, variance_path, mask_path, dark_path, dark_variance_path, flat_path,
solid_angle_path, polarization_path, absorption_path, dummy, delta_dummy,
normalization_factor, csr_path, cutoff_clip, cycle, radius2d_path, radius1d_path, noise,
cutoff_pick, cl_source_path))
cutoff_pick, acc_update_freq, cl_source_path))
// clang-format off
BOOST_ANNOTATE_MEMBER(fai_params, error_model,
......@@ -159,12 +159,18 @@ namespace processing::pipelines
(desc, "todo"),
(doc, "TODO"))
BOOST_ANNOTATE_MEMBER(fai_params, acc_update_freq,
(desc, "todo"),
(doc, "TODO"))
BOOST_ANNOTATE_MEMBER(fai_params, cl_source_path,
(desc, "todo"),
(doc, "TODO"))
// clang-format on
BOOST_DESCRIBE_STRUCT(proc_params, (), (fifo, buffers, saving_dense, saving_sparse, gpu, jfrau, fai, counters))
BOOST_DESCRIBE_STRUCT(proc_params, (),
(fifo, buffers, saving_dense, saving_sparse, saving_accumulation_corrected,
saving_accumulation_peak, gpu, jfrau, fai, counters))
// clang-format off
BOOST_ANNOTATE_MEMBER(proc_params, fifo,
......@@ -183,6 +189,14 @@ namespace processing::pipelines
(desc, "saving parameters assembled"),
(doc, "The HDF5 saving parameters for the assembled frame"))
BOOST_ANNOTATE_MEMBER(proc_params, saving_accumulation_corrected,
(desc, "saving parameters accumulation corrected"),
(doc, "The HDF5 saving parameters for the accumulation of corrected frames"))
BOOST_ANNOTATE_MEMBER(proc_params, saving_accumulation_peak,
(desc, "saving parameters accumulation peak"),
(doc, "The HDF5 saving parameters for the accumulation of found peak frames"))
BOOST_ANNOTATE_MEMBER(proc_params, gpu,
(desc, "gpu params"),
(doc, "The GPU (OpenCL) parameters"))
......
......@@ -73,6 +73,7 @@ namespace processing::pipelines
std::filesystem::path radius1d_path; //
float noise = 0.0f; //
float cutoff_pick = 0.0f; //
int acc_update_freq = 0; //
std::filesystem::path cl_source_path = "detectors/processing/psi/src"; // CL source file path
};
......@@ -82,6 +83,8 @@ namespace processing::pipelines
buffer_params buffers;
io::h5::saving_params saving_dense;
io::h5::saving_params saving_sparse;
io::h5::saving_params saving_accumulation_corrected;
io::h5::saving_params saving_accumulation_peak;
gpu_params gpu;
gain_pedestal_params jfrau;
fai_params fai;
......
......@@ -14,6 +14,7 @@
#include <lima/logging.hpp>
#include <lima/core/enums.hpp>
#include <lima/core/image/view.hpp>
#include <lima/processing/pipelines/smx/sparse_frame.hpp>
......@@ -28,9 +29,14 @@ namespace processing::pipelines
{
namespace bcl = boost::compute;
struct peak_finder_node : public tbb::flow::function_node<lima::frame, std::shared_ptr<sparse_frame>>
using accum_result_t = std::tuple<lima::frame, lima::frame>;
struct peak_finder_node
: public tbb::flow::multifunction_node<lima::frame,
std::tuple<std::shared_ptr<sparse_frame>, accum_result_t>>
{
using parent_t = tbb::flow::function_node<lima::frame, std::shared_ptr<sparse_frame>>;
using parent_t =
tbb::flow::multifunction_node<lima::frame, std::tuple<std::shared_ptr<sparse_frame>, accum_result_t>>;
struct peak_finder_body
{
......@@ -41,11 +47,14 @@ namespace processing::pipelines
queue(queue),
nb_pixels(width * height),
nb_bins(params.csr_indptr.size() - 1),
raw_d(nb_pixels, context), // Input
peak_indices_d(nb_pixels, context), // Outputs Peaks
peak_values_d(nb_pixels, context), //
background_avg_d(nb_bins, context), // Background
background_std_d(nb_bins, context), //
raw_d(nb_pixels, context), // Input
peak_indices_d(nb_pixels, context), // Outputs Peaks
peak_values_d(nb_pixels, context), //
background_avg_d(nb_bins, context), // Background
background_std_d(nb_bins, context), //
acc_update_freq(params.acc_update_freq), // Accumulation
acc_corr_d(acc_update_freq ? nb_pixels : 0, context), //
acc_peak_d(acc_update_freq ? nb_pixels : 0, context), //
debug(false),
corrected_d(debug ? nb_pixels : 0), // Corrected
preprocessed_d(debug ? nb_pixels : 0), // Preprocessed
......@@ -63,25 +72,27 @@ namespace processing::pipelines
params.dark_variance, params.flat, params.solid_angle, params.polarization, params.absorption,
params.dummy, params.delta_dummy, params.normalization_factor, params.csr_data,
params.csr_indices, params.csr_indptr, params.cutoff_clip, params.cycle, params.empty,
params.radius2d, params.radius1d, params.noise, params.cutoff_pick, //
params.radius2d, params.radius1d, params.noise, params.cutoff_pick, acc_update_freq, //
cl_source_path, queue);
LIMA_LOG(trace, proc) << "Peak finder created";
}
std::shared_ptr<sparse_frame> operator()(lima::frame const& in) const
void operator()(lima::frame const& in, typename parent_t::output_ports_type& ports) const
{
assert(nb_pixels == in.size());
// Write input to the device (non-blocking)
//copy_async(in.m_data, raw_d, queue);
auto v = boost::variant2::get<gray16c_view_t>(lima::const_view(in));
bcl::copy(v.begin(), v.end(), raw_d.begin(), queue);
auto v_in = lima::const_view<gray16c_view_t>(in);
bcl::copy(v_in.begin(), v_in.end(), raw_d.begin(), queue);
// Run the kernels
std::size_t nb_peaks = pf(queue, raw_d, //
corrected_d, preprocessed_d, cliped_d, found_d, //
peak_indices_d, peak_values_d, background_avg_d, background_std_d);
auto force_acc = in.metadata.is_final;
auto [nb_peaks, nb_acc_frames] = pf(queue, raw_d, //
corrected_d, preprocessed_d, cliped_d, found_d, //
peak_indices_d, peak_values_d, background_avg_d,
background_std_d, acc_corr_d, acc_peak_d, force_acc);
//{
// std::ofstream of("/tmp/preprocessed_" + std::to_string(in.metadata.idx) + ".bin");
// const char* d = reinterpret_cast<const char*>(preprocessed_dbg.data());
......@@ -90,20 +101,43 @@ namespace processing::pipelines
LIMA_LOG(trace, proc) << nb_peaks << " peaks found";
std::shared_ptr<sparse_frame> res =
std::make_shared<sparse_frame>(in.dimensions(), nb_peaks, nb_bins);
auto dims = in.dimensions();
auto pixel_type = in.pixel_type();
auto sparse = std::make_shared<sparse_frame>(dims, nb_peaks, nb_bins);
// Copy metadata
res->metadata = in.metadata;
res->attributes = in.attributes;
sparse->metadata = in.metadata;
sparse->attributes = in.attributes;
// Read result from the device to array (non-blocking)
bcl::copy_n(peak_indices_d.begin(), nb_peaks, res->peak_indices.begin(), queue);
bcl::copy_n(peak_values_d.begin(), nb_peaks, res->peak_values.begin(), queue);
bcl::copy(background_avg_d.begin(), background_avg_d.end(), res->background_avg.begin(), queue);
bcl::copy(background_std_d.begin(), background_std_d.end(), res->background_std.begin(), queue);
return res;
bcl::copy_n(peak_indices_d.begin(), nb_peaks, sparse->peak_indices.begin(), queue);
bcl::copy_n(peak_values_d.begin(), nb_peaks, sparse->peak_values.begin(), queue);
bcl::copy(background_avg_d.begin(), background_avg_d.end(), sparse->background_avg.begin(), queue);
bcl::copy(background_std_d.begin(), background_std_d.end(), sparse->background_std.begin(), queue);
std::get<0>(ports).try_put(sparse);
if (nb_acc_frames) {
LIMA_LOG(trace, proc) << "Accumulation available";
auto acc_pixel = pixel_enum::gray32f;
auto acc = std::make_tuple(lima::frame(dims, acc_pixel), lima::frame(dims, acc_pixel));
auto& [corr, peak] = acc;
auto copy_acc = [&](auto& s, auto& f) {
// Copy metadata - TODO: include nb_acc_frames
f.metadata = in.metadata;
f.metadata.idx = acc_frame_idx;
f.attributes = in.attributes;
// Copy data
auto view = lima::view<lima::gray32f_view_t>(f);
bcl::copy(s.begin(), s.end(), &boost::gil::at_c<0>(view(0, 0)), queue);
};
copy_acc(acc_corr_d, corr);
copy_acc(acc_peak_d, peak);
++acc_frame_idx;
std::get<1>(ports).try_put(acc);
}
}
bcl::context context;
......@@ -111,6 +145,7 @@ namespace processing::pipelines
std::size_t nb_pixels;
std::size_t nb_bins;
std::size_t acc_update_freq;
fai::peak_finder pf;
......@@ -119,6 +154,9 @@ namespace processing::pipelines
mutable fai::vector<float> peak_values_d; //
mutable fai::vector<float> background_avg_d; // Background
mutable fai::vector<float> background_std_d; //
mutable fai::vector<float> acc_corr_d; // Accumulation
mutable fai::vector<float> acc_peak_d; //
mutable std::size_t acc_frame_idx{0}; //
// Following outputs are usually used only for debugging
bool debug;
......
......@@ -19,7 +19,8 @@ namespace processing::pipelines
{
BOOST_DESCRIBE_STRUCT(counters, (),
(nb_frames_source, nb_frames_reconstructed, nb_frames_counters, nb_frames_sparsified,
nb_frames_sparse_saved, nb_frames_dense_saved))
nb_frames_sparse_saved, nb_frames_dense_saved, nb_frames_acc_corrected_saved,
nb_frames_acc_peak_saved))
// clang-format off
BOOST_ANNOTATE_MEMBER(counters, nb_frames_source,
......@@ -45,6 +46,14 @@ namespace processing::pipelines
BOOST_ANNOTATE_MEMBER(counters, nb_frames_dense_saved,
(desc, "nb frames dense saved"),
(doc, "The number of dense frame saved to file"))
BOOST_ANNOTATE_MEMBER(counters, nb_frames_acc_corrected_saved,
(desc, "nb frames accumulation corrected saved"),
(doc, "The number of corrected accumulation frame saved to file"))
BOOST_ANNOTATE_MEMBER(counters, nb_frames_acc_peak_saved,
(desc, "nb frames accumulation peak saved"),
(doc, "The number of peak accumulation frame saved to file"))
// clang-format on
using boost::json::tag_invoke;
......
......@@ -31,6 +31,8 @@ namespace processing::pipelines
int nb_frames_sparsified = 0;
int nb_frames_sparse_saved = 0;
int nb_frames_dense_saved = 0;
int nb_frames_acc_corrected_saved = 0;
int nb_frames_acc_peak_saved = 0;
};
using finished_callback_t = std::function<void(std::exception_ptr)>;
......
......@@ -46,6 +46,8 @@ namespace processing::pipelines
public:
using proc_params_t = proc_params;
using accum_split_node = tbb::flow::split_node<std::tuple<frame_t, frame_t>>;
impl(int rank, hw::frame_info const& frame_info, hw::acq_params const& acq_params,
proc_params_t const& proc_params) :
m_fifo(proc_params.fifo.nb_fifo_frames),
......@@ -129,7 +131,8 @@ namespace processing::pipelines
proc_params.fai.absorption_path, proc_params.fai.dummy, proc_params.fai.delta_dummy,
proc_params.fai.normalization_factor, proc_params.fai.csr_path, proc_params.fai.cutoff_clip,
proc_params.fai.cycle, proc_params.fai.empty, proc_params.fai.radius2d_path,
proc_params.fai.radius1d_path, proc_params.fai.noise, proc_params.fai.cutoff_pick, context, queue);
proc_params.fai.radius1d_path, proc_params.fai.noise, proc_params.fai.cutoff_pick,
proc_params.fai.acc_update_freq, context, queue);
LIMA_LOG(trace, proc) << "Peak finder kernel parameters parsed";
......@@ -156,6 +159,20 @@ namespace processing::pipelines
nb_bins, frame_info.dimensions(), radius, mask);
checkpoint_hdf5_sparse.emplace(m_graph, tbb::flow::unlimited, m_nb_frames_sparse_saved);
// Accumulation HDF5 node
auto do_acc = (proc_params.fai.acc_update_freq > 0);
if (do_acc) {
accum_split.emplace(m_graph);
auto acc_frames = (acq_params.xfer.time_slice.count - 1) / proc_params.fai.acc_update_freq + 1;
acc_saving_corrected.emplace(m_graph, proc_params.saving_accumulation_corrected, rank, acc_frames,
frame_info.dimensions(), pixel_enum::gray32f);
checkpoint_hdf5_acc_corrected.emplace(m_graph, tbb::flow::unlimited,
m_nb_frames_acc_corrected_saved);
acc_saving_peak.emplace(m_graph, proc_params.saving_accumulation_peak, rank, acc_frames,
frame_info.dimensions(), pixel_enum::gray32f);
checkpoint_hdf5_acc_peak.emplace(m_graph, tbb::flow::unlimited, m_nb_frames_acc_peak_saved);
}
// ROI counters node (optional)
if (!proc_params.counters.rois.empty()) {
roi_counters.emplace(m_graph, tbb::flow::unlimited, proc_params.counters.rois);
......@@ -166,12 +183,20 @@ namespace processing::pipelines
// Graph topology
tbb::flow::make_edge(*src, *peak_finder);
tbb::flow::make_edge(*peak_finder, *io_hdf5_sparse);
tbb::flow::make_edge(*peak_finder, *peak_counter);
auto&& [sparse, acc] = peak_finder->output_ports();
tbb::flow::make_edge(sparse, *io_hdf5_sparse);
tbb::flow::make_edge(sparse, *peak_counter);
tbb::flow::make_edge(*peak_counter, *peak_counters_buffer);
tbb::flow::make_edge(*peak_finder, *checkpoint_peak_finder);
tbb::flow::make_edge(sparse, *checkpoint_peak_finder);
tbb::flow::make_edge(*io_hdf5_sparse, *checkpoint_hdf5_sparse);
if (do_acc) {
tbb::flow::make_edge(acc, *accum_split);
auto&& [corr, peak] = accum_split->output_ports();
tbb::flow::make_edge(corr, *acc_saving_corrected);
tbb::flow::make_edge(*acc_saving_corrected, *checkpoint_hdf5_acc_corrected);
tbb::flow::make_edge(peak, *acc_saving_peak);
tbb::flow::make_edge(*acc_saving_peak, *checkpoint_hdf5_acc_peak);
}
tbb::flow::make_edge(*src, *io_hdf5_dense);
tbb::flow::make_edge(*io_hdf5_dense, *checkpoint_hdf5_dense);
......@@ -229,8 +254,14 @@ namespace processing::pipelines
/// Returns the progress counters
counters get_counters() const
{
return {(int) m_nb_frames_source, (int) m_nb_frames_reconstructed, (int) m_nb_frames_counters,
(int) m_nb_frames_sparsified, (int) m_nb_frames_sparse_saved, (int) m_nb_frames_dense_saved};
return {(int) m_nb_frames_source,
(int) m_nb_frames_reconstructed,
(int) m_nb_frames_counters,
(int) m_nb_frames_sparsified,
(int) m_nb_frames_sparse_saved,
(int) m_nb_frames_dense_saved,
(int) m_nb_frames_acc_corrected_saved,
(int) m_nb_frames_acc_peak_saved};
}
/// Pop a given number of ROI counters
......@@ -322,6 +353,12 @@ namespace processing::pipelines
std::optional<io_hdf5_sparse_node> io_hdf5_sparse;
std::optional<checkpoint_node<tbb::flow::continue_msg>> checkpoint_hdf5_sparse;
std::optional<accum_split_node> accum_split;
std::optional<io_hdf5_node<frame_t>> acc_saving_corrected;
std::optional<checkpoint_node<tbb::flow::continue_msg>> checkpoint_hdf5_acc_corrected;
std::optional<io_hdf5_node<frame_t>> acc_saving_peak;
std::optional<checkpoint_node<tbb::flow::continue_msg>> checkpoint_hdf5_acc_peak;
std::optional<roi_counters_node<frame>> roi_counters;
std::optional<circular_buffer_node<roi_counters_result>> roi_counters_buffer;
std::optional<checkpoint_node<tbb::flow::continue_msg>> roi_counters_checkpoint;
......@@ -333,6 +370,8 @@ namespace processing::pipelines
std::atomic_int m_nb_frames_sparsified = 0;
std::atomic_int m_nb_frames_sparse_saved = 0;
std::atomic_int m_nb_frames_dense_saved = 0;
std::atomic_int m_nb_frames_acc_corrected_saved = 0;
std::atomic_int m_nb_frames_acc_peak_saved = 0;
// ROI counters
boost::circular_buffer<roi_counters_result> m_roi_counters_buffer;
......
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