From 1dd361a343bcac123699ee20f0de944eabc8e71f Mon Sep 17 00:00:00 2001 From: Bechir Braham Date: Mon, 27 May 2024 15:24:26 +0200 Subject: [PATCH] template pedestal (#71) template the type of m_sum and m_sum2 in pedestal --- src/core/CMakeLists.txt | 2 +- .../include/aare/processing/Pedestal.hpp | 36 +++++------ src/processing/src/Pedestal.cpp | 60 ++++++++++--------- src/processing/test/pedestal.test.cpp | 36 +++++------ tests/test.cpp | 9 ++- 5 files changed, 76 insertions(+), 67 deletions(-) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 460e0f5..28335ee 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -11,7 +11,7 @@ add_library(core STATIC ${SourceFiles}) target_include_directories(core PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) -target_link_libraries(core PUBLIC fmt::fmt PRIVATE aare_compiler_flags utils ) +target_link_libraries(core PUBLIC utils fmt::fmt PRIVATE aare_compiler_flags ) if (AARE_PYTHON_BINDINGS) set_property(TARGET core PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/src/processing/include/aare/processing/Pedestal.hpp b/src/processing/include/aare/processing/Pedestal.hpp index 3f2a17c..b19a811 100644 --- a/src/processing/include/aare/processing/Pedestal.hpp +++ b/src/processing/include/aare/processing/Pedestal.hpp @@ -5,7 +5,8 @@ #include namespace aare { -class Pedestal { + +template class Pedestal { public: Pedestal(int rows, int cols, int n_samples = 1000); ~Pedestal(); @@ -15,16 +16,16 @@ class Pedestal { assert(frame.size() == m_rows * m_cols); // TODO: test the effect of #pragma omp parallel for for (int index = 0; index < m_rows * m_cols; index++) { - push(index % m_cols, index / m_cols, frame(index)); + push(index / m_cols, index % m_cols, frame(index)); } } template void push(Frame &frame) { assert(frame.rows() == static_cast(m_rows) && frame.cols() == static_cast(m_cols)); push(frame.view()); } - NDArray mean(); - NDArray variance(); - NDArray standard_deviation(); + NDArray mean(); + NDArray variance(); + NDArray standard_deviation(); void clear(); // getter functions @@ -32,33 +33,34 @@ class Pedestal { inline int cols() const { return m_cols; } inline int n_samples() const { return m_samples; } inline uint32_t *cur_samples() const { return m_cur_samples; } - inline double *get_sum() const { return m_sum; } - inline double *get_sum2() const { return m_sum2; } + inline NDArray get_sum() const { return m_sum; } + inline NDArray get_sum2() const { return m_sum2; } // pixel level operations (should be refactored to allow users to implement their own pixel level operations) template inline void push(const int row, const int col, const T val) { const int idx = index(row, col); + if (m_cur_samples[idx] < m_samples) { - m_sum[idx] += val; - m_sum2[idx] += val * val; + m_sum(idx) += val; + m_sum2(idx) += val * val; m_cur_samples[idx]++; } else { - m_sum[idx] += val - m_sum[idx] / m_cur_samples[idx]; - m_sum2[idx] += val * val - m_sum2[idx] / m_cur_samples[idx]; + m_sum(idx) += val - m_sum(idx) / m_cur_samples[idx]; + m_sum2(idx) += val * val - m_sum2(idx) / m_cur_samples[idx]; } } - double mean(const int row, const int col) const; - double variance(const int row, const int col) const; - double standard_deviation(const int row, const int col) const; + SUM_TYPE mean(const int row, const int col) const; + SUM_TYPE variance(const int row, const int col) const; + SUM_TYPE standard_deviation(const int row, const int col) const; inline int index(const int row, const int col) const { return row * m_cols + col; }; void clear(const int row, const int col); private: int m_rows; int m_cols; - int m_samples; + uint32_t m_samples; uint32_t *m_cur_samples{nullptr}; - double *m_sum{nullptr}; - double *m_sum2{nullptr}; + NDArray m_sum; + NDArray m_sum2; }; } // namespace aare \ No newline at end of file diff --git a/src/processing/src/Pedestal.cpp b/src/processing/src/Pedestal.cpp index f93cb4c..bca7487 100644 --- a/src/processing/src/Pedestal.cpp +++ b/src/processing/src/Pedestal.cpp @@ -3,68 +3,74 @@ #include namespace aare { -Pedestal::Pedestal(int rows, int cols, int n_samples) - : m_rows(rows), m_cols(cols), m_samples(n_samples), m_sum(new double[rows * cols]{}), - m_sum2(new double[rows * cols]{}), m_cur_samples(new uint32_t[rows * cols]{}) { +template +Pedestal::Pedestal(int rows, int cols, int n_samples) + : m_rows(rows), m_cols(cols), m_samples(n_samples), m_sum(NDArray({cols, rows})), + m_sum2(NDArray({cols, rows})), m_cur_samples(new uint32_t[static_cast(rows) * cols]{}) { assert(rows > 0 && cols > 0 && n_samples > 0); + m_sum = 0; + m_sum2 = 0; } -NDArray Pedestal::mean() { - NDArray mean_array({m_rows, m_cols}); +template NDArray Pedestal::mean() { + NDArray mean_array({m_rows, m_cols}); for (int i = 0; i < m_rows * m_cols; i++) { - mean_array(i % m_cols, i / m_cols) = mean(i % m_cols, i / m_cols); + mean_array(i / m_cols, i % m_cols) = mean(i / m_cols, i % m_cols); } return mean_array; } -NDArray Pedestal::variance() { - NDArray variance_array({m_rows, m_cols}); +template NDArray Pedestal::variance() { + NDArray variance_array({m_rows, m_cols}); for (int i = 0; i < m_rows * m_cols; i++) { - variance_array(i % m_cols, i / m_cols) = variance(i % m_cols, i / m_cols); + variance_array(i / m_cols, i % m_cols) = variance(i / m_cols, i % m_cols); } return variance_array; } -NDArray Pedestal::standard_deviation() { - NDArray standard_deviation_array({m_rows, m_cols}); +template NDArray Pedestal::standard_deviation() { + NDArray standard_deviation_array({m_rows, m_cols}); for (int i = 0; i < m_rows * m_cols; i++) { - standard_deviation_array(i % m_cols, i / m_cols) = standard_deviation(i % m_cols, i / m_cols); + standard_deviation_array(i / m_cols, i % m_cols) = standard_deviation(i / m_cols, i % m_cols); } + return standard_deviation_array; } -void Pedestal::clear() { +template void Pedestal::clear() { for (int i = 0; i < m_rows * m_cols; i++) { - clear(i % m_cols, i / m_cols); + clear(i / m_cols, i % m_cols); } } /* * index level operations */ -double Pedestal::mean(const int row, const int col) const { +template SUM_TYPE Pedestal::mean(const int row, const int col) const { if (m_cur_samples[index(row, col)] == 0) { return 0.0; } - return m_sum[index(row, col)] / m_cur_samples[index(row, col)]; + return m_sum(row, col) / m_cur_samples[index(row, col)]; } -double Pedestal::variance(const int row, const int col) const { +template SUM_TYPE Pedestal::variance(const int row, const int col) const { if (m_cur_samples[index(row, col)] == 0) { return 0.0; } - return m_sum2[index(row, col)] / m_cur_samples[index(row, col)] - mean(row, col) * mean(row, col); + return m_sum2(row, col) / m_cur_samples[index(row, col)] - mean(row, col) * mean(row, col); +} +template SUM_TYPE Pedestal::standard_deviation(const int row, const int col) const { + return std::sqrt(variance(row, col)); } -double Pedestal::standard_deviation(const int row, const int col) const { return std::sqrt(variance(row, col)); } -void Pedestal::clear(const int row, const int col) { - m_sum[index(row, col)] = 0; - m_sum2[index(row, col)] = 0; +template void Pedestal::clear(const int row, const int col) { + m_sum(row, col) = 0; + m_sum2(row, col) = 0; m_cur_samples[index(row, col)] = 0; } -Pedestal::~Pedestal() { - delete[] m_sum; - delete[] m_sum2; - delete[] m_cur_samples; -} +template Pedestal::~Pedestal() { delete[] m_cur_samples; } + +template class Pedestal; +template class Pedestal; +template class Pedestal; } // namespace aare \ No newline at end of file diff --git a/src/processing/test/pedestal.test.cpp b/src/processing/test/pedestal.test.cpp index a0a9140..9337c26 100644 --- a/src/processing/test/pedestal.test.cpp +++ b/src/processing/test/pedestal.test.cpp @@ -11,12 +11,10 @@ TEST_CASE("test pedestal constructor") { REQUIRE(pedestal.cols() == 10); REQUIRE(pedestal.n_samples() == 5); REQUIRE(pedestal.cur_samples() != nullptr); - REQUIRE(pedestal.get_sum() != nullptr); - REQUIRE(pedestal.get_sum2() != nullptr); for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { - REQUIRE(pedestal.get_sum()[pedestal.index(i, j)] == 0); - REQUIRE(pedestal.get_sum2()[pedestal.index(i, j)] == 0); + REQUIRE(pedestal.get_sum()(i, j) == 0); + REQUIRE(pedestal.get_sum2()(i, j) == 0); REQUIRE(pedestal.cur_samples()[pedestal.index(i, j)] == 0); } } @@ -35,8 +33,8 @@ TEST_CASE("test pedestal push") { pedestal.push(frame); for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { - REQUIRE(pedestal.get_sum()[pedestal.index(i, j)] == i + j); - REQUIRE(pedestal.get_sum2()[pedestal.index(i, j)] == (i + j) * (i + j)); + REQUIRE(pedestal.get_sum()(i, j) == i + j); + REQUIRE(pedestal.get_sum2()(i, j) == (i + j) * (i + j)); REQUIRE(pedestal.cur_samples()[pedestal.index(i, j)] == 1); } } @@ -45,8 +43,8 @@ TEST_CASE("test pedestal push") { pedestal.clear(); for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { - REQUIRE(pedestal.get_sum()[pedestal.index(i, j)] == 0); - REQUIRE(pedestal.get_sum2()[pedestal.index(i, j)] == 0); + REQUIRE(pedestal.get_sum()(i, j) == 0); + REQUIRE(pedestal.get_sum2()(i, j) == 0); REQUIRE(pedestal.cur_samples()[pedestal.index(i, j)] == 0); } } @@ -58,12 +56,12 @@ TEST_CASE("test pedestal push") { for (int j = 0; j < 10; j++) { if (k < 5) { REQUIRE(pedestal.cur_samples()[pedestal.index(i, j)] == k + 1); - REQUIRE(pedestal.get_sum()[pedestal.index(i, j)] == (k + 1) * (i + j)); - REQUIRE(pedestal.get_sum2()[pedestal.index(i, j)] == (k + 1) * (i + j) * (i + j)); + REQUIRE(pedestal.get_sum()(i, j) == (k + 1) * (i + j)); + REQUIRE(pedestal.get_sum2()(i, j) == (k + 1) * (i + j) * (i + j)); } else { REQUIRE(pedestal.cur_samples()[pedestal.index(i, j)] == 5); - REQUIRE(pedestal.get_sum()[pedestal.index(i, j)] == 5 * (i + j)); - REQUIRE(pedestal.get_sum2()[pedestal.index(i, j)] == 5 * (i + j) * (i + j)); + REQUIRE(pedestal.get_sum()(i, j) == 5 * (i + j)); + REQUIRE(pedestal.get_sum2()(i, j) == 5 * (i + j) * (i + j)); } REQUIRE(pedestal.mean(i, j) == (i + j)); REQUIRE(pedestal.variance(i, j) == 0); @@ -80,24 +78,22 @@ TEST_CASE("test pedestal with normal distribution") { std::default_random_engine generator(seed); std::normal_distribution distribution(MEAN, STD); - aare::Pedestal pedestal(4, 4, 10000); + aare::Pedestal pedestal(3, 5, 10000); for (int i = 0; i < 10000; i++) { - aare::Frame frame(4, 4, 64); - for (int j = 0; j < 4; j++) { - for (int k = 0; k < 4; k++) { + aare::Frame frame(3, 5, 64); + for (int j = 0; j < 3; j++) { + for (int k = 0; k < 5; k++) { frame.set(j, k, distribution(generator)); } } pedestal.push(frame); } - auto mean = pedestal.mean(); auto variance = pedestal.variance(); auto standard_deviation = pedestal.standard_deviation(); - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - // 10% tolerance + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 5; j++) { REQUIRE(compare_floats(mean(i, j), MEAN, MEAN * TOLERANCE)); REQUIRE(compare_floats(variance(i, j), VAR, VAR * TOLERANCE)); REQUIRE(compare_floats(standard_deviation(i, j), STD, STD * TOLERANCE)); // maybe sqrt of tolerance? diff --git a/tests/test.cpp b/tests/test.cpp index 1b4f632..1a76f0a 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -1,9 +1,9 @@ +#include "test_config.hpp" #include +#include #include #include -#include "test_config.hpp" - TEST_CASE("Test suite can find data assets") { auto fpath = test_data_path() / "numpy" / "test_numpy_file.npy"; REQUIRE(std::filesystem::exists(fpath)); @@ -13,4 +13,9 @@ TEST_CASE("Test suite can open data assets") { auto fpath = test_data_path() / "numpy" / "test_numpy_file.npy"; auto f = std::ifstream(fpath, std::ios::binary); REQUIRE(f.is_open()); +} + +TEST_CASE("Test float32 and char8") { + REQUIRE(sizeof(float) == 4); + REQUIRE(CHAR_BIT == 8); } \ No newline at end of file