mirror of
https://github.com/slsdetectorgroup/aare.git
synced 2025-12-27 15:31:24 +01:00
156 lines
5.8 KiB
C++
156 lines
5.8 KiB
C++
// SPDX-License-Identifier: MPL-2.0
|
|
#include "aare/ClusterCollector.hpp"
|
|
#include "aare/ClusterFileSink.hpp"
|
|
#include "aare/ClusterFinder.hpp"
|
|
#include "aare/ClusterFinderMT.hpp"
|
|
#include "aare/ClusterVector.hpp"
|
|
#include "aare/NDView.hpp"
|
|
#include "aare/Pedestal.hpp"
|
|
#include "np_helper.hpp"
|
|
|
|
#include <cstdint>
|
|
#include <filesystem>
|
|
#include <pybind11/pybind11.h>
|
|
#include <pybind11/stl.h>
|
|
#include <pybind11/stl_bind.h>
|
|
|
|
namespace py = pybind11;
|
|
using pd_type = double;
|
|
|
|
using namespace aare;
|
|
|
|
#pragma GCC diagnostic push
|
|
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
|
|
|
template <typename Type, uint8_t ClusterSizeX, uint8_t ClusterSizeY,
|
|
typename CoordType = uint16_t>
|
|
void define_ClusterVector(py::module &m, const std::string &typestr) {
|
|
using ClusterType = Cluster<Type, ClusterSizeX, ClusterSizeY, CoordType>;
|
|
auto class_name = fmt::format("ClusterVector_{}", typestr);
|
|
|
|
py::class_<ClusterVector<
|
|
Cluster<Type, ClusterSizeX, ClusterSizeY, CoordType>, void>>(
|
|
m, class_name.c_str(),
|
|
py::buffer_protocol())
|
|
|
|
.def(py::init()) // TODO change!!!
|
|
|
|
.def("push_back",
|
|
[](ClusterVector<ClusterType> &self, const ClusterType &cluster) {
|
|
self.push_back(cluster);
|
|
})
|
|
|
|
.def("sum",
|
|
[](ClusterVector<ClusterType> &self) {
|
|
auto *vec = new std::vector<Type>(self.sum());
|
|
return return_vector(vec);
|
|
})
|
|
.def(
|
|
"sum_2x2",
|
|
[](ClusterVector<ClusterType> &self) {
|
|
auto *vec = new std::vector<Sum_index_pair<Type, corner>>(
|
|
self.sum_2x2());
|
|
|
|
return return_vector(vec);
|
|
},
|
|
R"(calculates sum of 2x2 subcluster with highest energy and index relative to cluster center 0: top_left, 1: top_right, 2: bottom_left, 3: bottom_right
|
|
)")
|
|
.def_property_readonly("size", &ClusterVector<ClusterType>::size)
|
|
.def("item_size", &ClusterVector<ClusterType>::item_size)
|
|
.def_property_readonly("fmt",
|
|
[typestr](ClusterVector<ClusterType> &self) {
|
|
return fmt_format<ClusterType>;
|
|
})
|
|
|
|
.def_property_readonly("cluster_size_x",
|
|
&ClusterVector<ClusterType>::cluster_size_x)
|
|
.def_property_readonly("cluster_size_y",
|
|
&ClusterVector<ClusterType>::cluster_size_y)
|
|
.def_property_readonly("capacity",
|
|
&ClusterVector<ClusterType>::capacity)
|
|
.def_property("frame_number", &ClusterVector<ClusterType>::frame_number,
|
|
&ClusterVector<ClusterType>::set_frame_number)
|
|
.def_buffer(
|
|
[typestr](ClusterVector<ClusterType> &self) -> py::buffer_info {
|
|
return py::buffer_info(
|
|
self.data(), /* Pointer to buffer */
|
|
self.item_size(), /* Size of one scalar */
|
|
fmt_format<ClusterType>, /* Format descriptor */
|
|
1, /* Number of dimensions */
|
|
{self.size()}, /* Buffer dimensions */
|
|
{self.item_size()} /* Strides (in bytes) for each index */
|
|
);
|
|
});
|
|
|
|
// Free functions using ClusterVector
|
|
m.def("hitmap",
|
|
[](std::array<size_t, 2> image_size, ClusterVector<ClusterType> &cv) {
|
|
// Create a numpy array to hold the hitmap
|
|
// The shape of the array is (image_size[0], image_size[1])
|
|
// note that the python array is passed as [row, col] which
|
|
// is the opposite of the clusters [x,y]
|
|
py::array_t<int32_t> hitmap(image_size);
|
|
auto r = hitmap.mutable_unchecked<2>();
|
|
|
|
// Initialize hitmap to 0
|
|
for (py::ssize_t i = 0; i < r.shape(0); i++)
|
|
for (py::ssize_t j = 0; j < r.shape(1); j++)
|
|
r(i, j) = 0;
|
|
|
|
// Loop over the clusters and increment the hitmap
|
|
// Skip out of bound clusters
|
|
for (const auto &cluster : cv) {
|
|
auto x = cluster.x;
|
|
auto y = cluster.y;
|
|
if (x < image_size[1] && y < image_size[0])
|
|
r(cluster.y, cluster.x) += 1;
|
|
}
|
|
|
|
return hitmap;
|
|
});
|
|
}
|
|
|
|
template <typename Type, uint8_t ClusterSizeX, uint8_t ClusterSizeY,
|
|
typename CoordType = uint16_t>
|
|
void define_2x2_reduction(py::module &m) {
|
|
m.def(
|
|
"reduce_to_2x2",
|
|
[](const ClusterVector<
|
|
Cluster<Type, ClusterSizeX, ClusterSizeY, CoordType>> &cv) {
|
|
return new ClusterVector<Cluster<Type, 2, 2, CoordType>>(
|
|
reduce_to_2x2(cv));
|
|
},
|
|
R"(
|
|
Reduce cluster to 2x2 subcluster by taking the 2x2 subcluster with
|
|
the highest photon energy.
|
|
|
|
Parameters
|
|
|
|
cv : ClusterVector (clusters are filled in row-major ordering starting at the top left. Thus for a max subcluster in the top left corner the photon hit is at the fourth position.)
|
|
|
|
)",
|
|
py::arg("clustervector"));
|
|
}
|
|
|
|
template <typename Type, uint8_t ClusterSizeX, uint8_t ClusterSizeY,
|
|
typename CoordType = uint16_t>
|
|
void define_3x3_reduction(py::module &m) {
|
|
|
|
m.def(
|
|
"reduce_to_3x3",
|
|
[](const ClusterVector<
|
|
Cluster<Type, ClusterSizeX, ClusterSizeY, CoordType>> &cv) {
|
|
return new ClusterVector<Cluster<Type, 3, 3, CoordType>>(
|
|
reduce_to_3x3(cv));
|
|
},
|
|
R"(
|
|
Reduce cluster to 3x3 subcluster
|
|
|
|
Parameters
|
|
|
|
cv : ClusterVector
|
|
)",
|
|
py::arg("clustervector"));
|
|
}
|
|
|
|
#pragma GCC diagnostic pop |