diff --git a/include/aare/ClusterFinder.hpp b/include/aare/ClusterFinder.hpp index 4b5c98d..74c5baa 100644 --- a/include/aare/ClusterFinder.hpp +++ b/include/aare/ClusterFinder.hpp @@ -113,6 +113,8 @@ class ClusterFinder { m_clusters.set_frame_number(frame_number); m_pd_corrected_frame = frame - m_pedestal.view(); + + for (int iy = 0; iy < frame.shape(0); iy++) { for (int ix = 0; ix < frame.shape(1); ix++) { @@ -152,8 +154,8 @@ class ClusterFinder { m_pedestal.push( iy, ix, frame(iy, - ix)); // Assume we have reached n_samples in the - // pedestal, slight performance improvement + ix)); + continue; // It was a pedestal value nothing to store } diff --git a/include/aare/FastPedestal.hpp b/include/aare/FastPedestal.hpp index 0d245e8..1c17c48 100644 --- a/include/aare/FastPedestal.hpp +++ b/include/aare/FastPedestal.hpp @@ -9,11 +9,12 @@ namespace aare { /** * @brief Calculate the pedestal of a series of frames. Can be used as - * standalone but mostly used in the ClusterFinder. + * standalone but mostly used in the ClusterFinder. Internal calculations are + * performed using double precision. * - * @tparam SUM_TYPE type of the sum + * @tparam PEDESTAL_TYPE type of the exposed mean and std */ -template class FastPedestal { +template class FastPedestal { // TODO! Force floating point sum type? // how does the internal calculation work with integers? @@ -23,13 +24,13 @@ template class FastPedestal { uint32_t m_cols; uint32_t m_samples; - SUM_TYPE m_inv_samples; // precompute 1/m_samples for faster division + double m_inv_samples; // precompute 1/m_samples for faster division uint32_t m_cur_samples = 0; // TODO! do we need this when we have m_samples? // for cache we want to keep sum and sum2 close struct Entry { - SUM_TYPE sum; - SUM_TYPE sum2; + double sum; + double sum2; }; // TODO! in case of int needs to be changed to uint64_t NDArray m_sum; @@ -37,47 +38,45 @@ template class FastPedestal { // Cache mean since it is used over and over in the ClusterFinder // This optimization is related to the access pattern of the ClusterFinder // Relies on having more reads than pushes to the pedestal - NDArray m_mean; + NDArray m_mean; // Cache std. Only refreshed via update_std() to keep push() cheap. - NDArray m_std; + // This gives a measureable speedup in the ClusterFinder. + NDArray m_std; public: FastPedestal(uint32_t rows, uint32_t cols, uint32_t n_samples = 1000) : m_rows(rows), m_cols(cols), m_samples(n_samples), m_inv_samples(1.0 / n_samples), - m_sum(NDArray({rows, cols})), - m_mean(NDArray({rows, cols})), - m_std(NDArray({rows, cols})) { + m_sum({rows, cols}, Entry{0, 0}), + m_mean({rows, cols}), + m_std({rows, cols}, 0) { assert(rows > 0 && cols > 0 && n_samples > 0); - m_sum = Entry{SUM_TYPE(0), SUM_TYPE(0)}; - m_mean = SUM_TYPE(0); - m_std = SUM_TYPE(0); } ~FastPedestal() = default; - NDArray mean() { return m_mean; } + NDArray mean() { return m_mean; } - const NDView view() const { return m_mean.view(); } + const NDView view() const { return m_mean.view(); } - SUM_TYPE mean(const uint32_t row, const uint32_t col) const { + PEDESTAL_TYPE mean(const uint32_t row, const uint32_t col) const { return m_mean(row, col); } - NDArray cached_std() { return m_std; } + NDArray cached_std() { return m_std; } - SUM_TYPE cached_std(const uint32_t row, const uint32_t col) const { + PEDESTAL_TYPE cached_std(const uint32_t row, const uint32_t col) const { return m_std(row, col); } - SUM_TYPE variance(const uint32_t row, const uint32_t col) const { + PEDESTAL_TYPE variance(const uint32_t row, const uint32_t col) const { auto &entry = m_sum(row, col); auto m2 = entry.sum * m_inv_samples * entry.sum * m_inv_samples; return entry.sum2 * m_inv_samples - m2; } - NDArray variance() { - NDArray res({m_rows, m_cols}); + NDArray variance() { + NDArray res({m_rows, m_cols}); for (ssize_t row = 0; row < m_rows; ++row) { for (ssize_t col = 0; col < m_cols; ++col) { res(row, col) = variance(row, col); @@ -86,12 +85,12 @@ template class FastPedestal { return res; } - SUM_TYPE std(const uint32_t row, const uint32_t col) const { + PEDESTAL_TYPE std(const uint32_t row, const uint32_t col) const { return std::sqrt(variance(row, col)); } - NDArray std() { - NDArray res({m_rows, m_cols}); + NDArray std() { + NDArray res({m_rows, m_cols}); for (ssize_t row = 0; row < m_rows; ++row) { for (ssize_t col = 0; col < m_cols; ++col) { res(row, col) = std(row, col); @@ -105,9 +104,9 @@ template class FastPedestal { uint32_t cur_samples() { return m_cur_samples; } void clear() { - m_sum = Entry{SUM_TYPE(0), SUM_TYPE(0)}; - m_mean = SUM_TYPE(0); - m_std = SUM_TYPE(0); + m_sum = Entry{double(0), double(0)}; + m_mean = PEDESTAL_TYPE(0); + m_std = PEDESTAL_TYPE(0); m_ready = false; } @@ -143,7 +142,7 @@ template class FastPedestal { for (size_t row = 0; row < m_rows; row++) { for (size_t col = 0; col < m_cols; col++) { - const auto val = static_cast(frame(row, col)); + const auto val = static_cast(frame(row, col)); auto &entry = m_sum(row, col); entry.sum += val; entry.sum2 += val * val; @@ -176,7 +175,7 @@ template class FastPedestal { if (!ready()) { throw std::runtime_error("Pedestal is not ready, cannot push"); } - SUM_TYPE val = static_cast(val_); + auto val = static_cast(val_); auto &entry = m_sum(row, col); entry.sum += val - entry.sum * m_inv_samples; entry.sum2 += val * val - entry.sum2 * m_inv_samples; @@ -188,7 +187,7 @@ template class FastPedestal { if (!ready()) { throw std::runtime_error("Pedestal is not ready, cannot push"); } - SUM_TYPE val = static_cast(val_); + auto val = static_cast(val_); auto &entry = m_sum(row, col); entry.sum += val - entry.sum * m_inv_samples; entry.sum2 += val * val - entry.sum2 * m_inv_samples; diff --git a/python/src/bind_Cluster.hpp b/python/src/bind_Cluster.hpp index eca0881..2349b17 100644 --- a/python/src/bind_Cluster.hpp +++ b/python/src/bind_Cluster.hpp @@ -10,7 +10,7 @@ #include namespace py = pybind11; -using pd_type = double; + using namespace aare; diff --git a/python/src/bind_ClusterCollector.hpp b/python/src/bind_ClusterCollector.hpp index 2e621ed..bdbe76b 100644 --- a/python/src/bind_ClusterCollector.hpp +++ b/python/src/bind_ClusterCollector.hpp @@ -6,6 +6,8 @@ #include "aare/ClusterVector.hpp" #include "aare/NDView.hpp" #include "aare/Pedestal.hpp" + +#include "module_config.hpp" #include "np_helper.hpp" #include @@ -15,7 +17,7 @@ #include namespace py = pybind11; -using pd_type = double; + using namespace aare; @@ -30,7 +32,7 @@ void define_ClusterCollector(py::module &m, const std::string &typestr) { using ClusterType = Cluster; py::class_>(m, class_name.c_str()) - .def(py::init *>()) + .def(py::init *>()) .def("stop", &ClusterCollector::stop) .def( "steal_clusters", diff --git a/python/src/bind_ClusterFileSink.hpp b/python/src/bind_ClusterFileSink.hpp index ade574d..6caf7a2 100644 --- a/python/src/bind_ClusterFileSink.hpp +++ b/python/src/bind_ClusterFileSink.hpp @@ -15,8 +15,6 @@ #include namespace py = pybind11; -using pd_type = double; - using namespace aare; #pragma GCC diagnostic push @@ -29,6 +27,8 @@ void define_ClusterFileSink(py::module &m, const std::string &typestr) { using ClusterType = Cluster; + //TODO! adapt to set pedestal type (needs templating of ClusterFileSink) + //or maybe access through base class? py::class_>(m, class_name.c_str()) .def(py::init *, const std::filesystem::path &>()) diff --git a/python/src/bind_ClusterFinder.hpp b/python/src/bind_ClusterFinder.hpp index 4a72db7..564e0cf 100644 --- a/python/src/bind_ClusterFinder.hpp +++ b/python/src/bind_ClusterFinder.hpp @@ -6,6 +6,8 @@ #include "aare/ClusterVector.hpp" #include "aare/NDView.hpp" #include "aare/Pedestal.hpp" + +#include "module_config.hpp" #include "np_helper.hpp" #include @@ -15,7 +17,7 @@ #include namespace py = pybind11; -using pd_type = double; + using namespace aare; diff --git a/python/src/bind_ClusterFinderMT.hpp b/python/src/bind_ClusterFinderMT.hpp index 1a303ba..2484d98 100644 --- a/python/src/bind_ClusterFinderMT.hpp +++ b/python/src/bind_ClusterFinderMT.hpp @@ -6,6 +6,8 @@ #include "aare/ClusterVector.hpp" #include "aare/NDView.hpp" #include "aare/Pedestal.hpp" + +#include "module_config.hpp" #include "np_helper.hpp" #include @@ -15,7 +17,7 @@ #include namespace py = pybind11; -using pd_type = double; + using namespace aare; diff --git a/python/src/bind_ClusterVector.hpp b/python/src/bind_ClusterVector.hpp index 254f96a..08faf49 100644 --- a/python/src/bind_ClusterVector.hpp +++ b/python/src/bind_ClusterVector.hpp @@ -15,7 +15,7 @@ #include namespace py = pybind11; -using pd_type = double; + using namespace aare; diff --git a/python/src/module.cpp b/python/src/module.cpp index 8d9e1a9..26f9fc6 100644 --- a/python/src/module.cpp +++ b/python/src/module.cpp @@ -1,6 +1,8 @@ // SPDX-License-Identifier: MPL-2.0 // Files with bindings to the different classes +#include "module_config.hpp" + // New style file naming #include "bind_Cluster.hpp" #include "bind_ClusterCollector.hpp" diff --git a/python/src/module_config.hpp b/python/src/module_config.hpp new file mode 100644 index 0000000..369140c --- /dev/null +++ b/python/src/module_config.hpp @@ -0,0 +1,4 @@ +#pragma once + +//Configure module wide pedestal type for cluster finding +using pd_type = double; \ No newline at end of file