mirror of
https://github.com/slsdetectorgroup/aare.git
synced 2025-06-05 12:30:39 +02:00
template pedestal (#71)
template the type of m_sum and m_sum2 in pedestal
This commit is contained in:
parent
fed362e843
commit
1dd361a343
@ -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)
|
||||
|
@ -5,7 +5,8 @@
|
||||
#include <cstddef>
|
||||
|
||||
namespace aare {
|
||||
class Pedestal {
|
||||
|
||||
template <typename SUM_TYPE = double> 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<T>(index % m_cols, index / m_cols, frame(index));
|
||||
push<T>(index / m_cols, index % m_cols, frame(index));
|
||||
}
|
||||
}
|
||||
template <typename T> void push(Frame &frame) {
|
||||
assert(frame.rows() == static_cast<size_t>(m_rows) && frame.cols() == static_cast<size_t>(m_cols));
|
||||
push<T>(frame.view<T>());
|
||||
}
|
||||
NDArray<double> mean();
|
||||
NDArray<double> variance();
|
||||
NDArray<double> standard_deviation();
|
||||
NDArray<SUM_TYPE> mean();
|
||||
NDArray<SUM_TYPE> variance();
|
||||
NDArray<SUM_TYPE> 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<SUM_TYPE, 2> get_sum() const { return m_sum; }
|
||||
inline NDArray<SUM_TYPE, 2> get_sum2() const { return m_sum2; }
|
||||
|
||||
// pixel level operations (should be refactored to allow users to implement their own pixel level operations)
|
||||
template <typename T> 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<SUM_TYPE, 2> m_sum;
|
||||
NDArray<SUM_TYPE, 2> m_sum2;
|
||||
};
|
||||
} // namespace aare
|
@ -3,68 +3,74 @@
|
||||
#include <cstddef>
|
||||
|
||||
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 <typename SUM_TYPE>
|
||||
Pedestal<SUM_TYPE>::Pedestal(int rows, int cols, int n_samples)
|
||||
: m_rows(rows), m_cols(cols), m_samples(n_samples), m_sum(NDArray<SUM_TYPE, 2>({cols, rows})),
|
||||
m_sum2(NDArray<SUM_TYPE, 2>({cols, rows})), m_cur_samples(new uint32_t[static_cast<uint64_t>(rows) * cols]{}) {
|
||||
assert(rows > 0 && cols > 0 && n_samples > 0);
|
||||
m_sum = 0;
|
||||
m_sum2 = 0;
|
||||
}
|
||||
|
||||
NDArray<double, 2> Pedestal::mean() {
|
||||
NDArray<double, 2> mean_array({m_rows, m_cols});
|
||||
template <typename SUM_TYPE> NDArray<SUM_TYPE, 2> Pedestal<SUM_TYPE>::mean() {
|
||||
NDArray<SUM_TYPE, 2> 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<double, 2> Pedestal::variance() {
|
||||
NDArray<double, 2> variance_array({m_rows, m_cols});
|
||||
template <typename SUM_TYPE> NDArray<SUM_TYPE, 2> Pedestal<SUM_TYPE>::variance() {
|
||||
NDArray<SUM_TYPE, 2> 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<double, 2> Pedestal::standard_deviation() {
|
||||
NDArray<double, 2> standard_deviation_array({m_rows, m_cols});
|
||||
template <typename SUM_TYPE> NDArray<SUM_TYPE, 2> Pedestal<SUM_TYPE>::standard_deviation() {
|
||||
NDArray<SUM_TYPE, 2> 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 <typename SUM_TYPE> void Pedestal<SUM_TYPE>::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 <typename SUM_TYPE> SUM_TYPE Pedestal<SUM_TYPE>::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 <typename SUM_TYPE> SUM_TYPE Pedestal<SUM_TYPE>::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 <typename SUM_TYPE> SUM_TYPE Pedestal<SUM_TYPE>::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 <typename SUM_TYPE> void Pedestal<SUM_TYPE>::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 <typename SUM_TYPE> Pedestal<SUM_TYPE>::~Pedestal() { delete[] m_cur_samples; }
|
||||
|
||||
template class Pedestal<double>;
|
||||
template class Pedestal<float>;
|
||||
template class Pedestal<long double>;
|
||||
|
||||
} // namespace aare
|
@ -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<uint16_t>(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<double> 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<double>(j, k, distribution(generator));
|
||||
}
|
||||
}
|
||||
pedestal.push<double>(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<double>(mean(i, j), MEAN, MEAN * TOLERANCE));
|
||||
REQUIRE(compare_floats<double>(variance(i, j), VAR, VAR * TOLERANCE));
|
||||
REQUIRE(compare_floats<double>(standard_deviation(i, j), STD, STD * TOLERANCE)); // maybe sqrt of tolerance?
|
||||
|
@ -1,9 +1,9 @@
|
||||
#include "test_config.hpp"
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <climits>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
|
||||
#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);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user