Api extra (#166)

Changes to be able to run the example notebooks: 

- Invert gain map on setting (multiplication is faster but user supplies
ADU/energy)
- Cast after applying gain map not to loose precision (Important for
int32 clusters)
- "factor" for ClusterFileSink 
- Cluster size available to be able to create the right file sink
This commit is contained in:
Erik Fröjdh 2025-04-25 10:31:16 +02:00 committed by GitHub
parent 86d343f5f5
commit 7b5e32a824
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 42 additions and 15 deletions

View File

@ -16,10 +16,18 @@ class GainMap {
public: public:
explicit GainMap(const NDArray<double, 2> &gain_map) explicit GainMap(const NDArray<double, 2> &gain_map)
: m_gain_map(gain_map) {}; : m_gain_map(gain_map) {
for (auto &item : m_gain_map) {
item = 1.0 / item;
}
};
explicit GainMap(const NDView<double, 2> gain_map) { explicit GainMap(const NDView<double, 2> gain_map) {
m_gain_map = NDArray<double, 2>(gain_map); m_gain_map = NDArray<double, 2>(gain_map);
for (auto &item : m_gain_map) {
item = 1.0 / item;
}
} }
template <typename ClusterType, template <typename ClusterType,
@ -41,7 +49,7 @@ class GainMap {
for (size_t j = 0; j < ClusterSizeX * ClusterSizeY; j++) { for (size_t j = 0; j < ClusterSizeX * ClusterSizeY; j++) {
size_t x = cl.x + j % ClusterSizeX - index_cluster_center_x; size_t x = cl.x + j % ClusterSizeX - index_cluster_center_x;
size_t y = cl.y + j / ClusterSizeX - index_cluster_center_y; size_t y = cl.y + j / ClusterSizeX - index_cluster_center_y;
cl.data[j] = cl.data[j] * static_cast<T>(m_gain_map(y, x)); cl.data[j] = static_cast<T>(cl.data[j] * m_gain_map(y, x)); //cast after conversion to keep precision
} }
} else { } else {
// clear edge clusters // clear edge clusters

View File

@ -1,5 +1,8 @@
from ._aare import ClusterFinder_Cluster3x3i, ClusterFinder_Cluster2x2i, ClusterFinderMT_Cluster3x3i, ClusterFinderMT_Cluster2x2i, ClusterCollector_Cluster3x3i, ClusterCollector_Cluster2x2i from ._aare import ClusterFinder_Cluster3x3i, ClusterFinder_Cluster2x2i, ClusterFinderMT_Cluster3x3i, ClusterFinderMT_Cluster2x2i, ClusterCollector_Cluster3x3i, ClusterCollector_Cluster2x2i
from ._aare import ClusterFileSink_Cluster3x3i, ClusterFileSink_Cluster2x2i
import numpy as np import numpy as np
def ClusterFinder(image_size, cluster_size, n_sigma=5, dtype = np.int32, capacity = 1024): def ClusterFinder(image_size, cluster_size, n_sigma=5, dtype = np.int32, capacity = 1024):
@ -48,3 +51,17 @@ def ClusterCollector(clusterfindermt, cluster_size = (3,3), dtype=np.int32):
#TODO! add the other formats #TODO! add the other formats
raise ValueError(f"Unsupported dtype: {dtype}. Only np.int32 is supported.") raise ValueError(f"Unsupported dtype: {dtype}. Only np.int32 is supported.")
def ClusterFileSink(clusterfindermt, cluster_file, dtype=np.int32):
"""
Factory function to create a ClusterCollector object. Provides a cleaner syntax for
the templated ClusterCollector in C++.
"""
if dtype == np.int32 and clusterfindermt.cluster_size == (3,3):
return ClusterFileSink_Cluster3x3i(clusterfindermt, cluster_file)
elif dtype == np.int32 and clusterfindermt.cluster_size == (2,2):
return ClusterFileSink_Cluster2x2i(clusterfindermt, cluster_file)
else:
#TODO! add the other formats
raise ValueError(f"Unsupported dtype: {dtype}. Only np.int32 is supported.")

View File

@ -11,7 +11,7 @@ from ._aare import ROI
# from ._aare import ClusterFinderMT, ClusterCollector, ClusterFileSink, ClusterVector_i # from ._aare import ClusterFinderMT, ClusterCollector, ClusterFileSink, ClusterVector_i
from .ClusterFinder import ClusterFinder, ClusterCollector, ClusterFinderMT from .ClusterFinder import ClusterFinder, ClusterCollector, ClusterFinderMT, ClusterFileSink
from .ClusterVector import ClusterVector from .ClusterVector import ClusterVector

View File

@ -44,11 +44,10 @@ void define_ClusterVector(py::module &m, const std::string &typestr) {
auto *vec = new std::vector<Type>(self.sum()); auto *vec = new std::vector<Type>(self.sum());
return return_vector(vec); return return_vector(vec);
}) })
.def("sum_2x2", .def("sum_2x2", [](ClusterVector<ClusterType> &self){
[](ClusterVector<ClusterType> &self) { auto *vec = new std::vector<Type>(self.sum_2x2());
auto *vec = new std::vector<Type>(self.sum_2x2()); return return_vector(vec);
return return_vector(vec); })
})
.def_property_readonly("size", &ClusterVector<ClusterType>::size) .def_property_readonly("size", &ClusterVector<ClusterType>::size)
.def("item_size", &ClusterVector<ClusterType>::item_size) .def("item_size", &ClusterVector<ClusterType>::item_size)
.def_property_readonly("fmt", .def_property_readonly("fmt",

View File

@ -93,6 +93,9 @@ void define_cluster_finder_mt_bindings(py::module &m,
return; return;
}, },
py::arg(), py::arg("frame_number") = 0) py::arg(), py::arg("frame_number") = 0)
.def_property_readonly("cluster_size", [](ClusterFinderMT<ClusterType, uint16_t, pd_type> &self){
return py::make_tuple(ClusterSizeX, ClusterSizeY);
})
.def("clear_pedestal", .def("clear_pedestal",
&ClusterFinderMT<ClusterType, uint16_t, pd_type>::clear_pedestal) &ClusterFinderMT<ClusterType, uint16_t, pd_type>::clear_pedestal)
.def("sync", &ClusterFinderMT<ClusterType, uint16_t, pd_type>::sync) .def("sync", &ClusterFinderMT<ClusterType, uint16_t, pd_type>::sync)

View File

@ -10,13 +10,12 @@
#include "file.hpp" #include "file.hpp"
#include "fit.hpp" #include "fit.hpp"
#include "interpolation.hpp" #include "interpolation.hpp"
#include "pedestal.hpp"
#include "pixel_map.hpp"
#include "raw_file.hpp"
#include "raw_master_file.hpp"
#include "var_cluster.hpp"
#include "raw_sub_file.hpp" #include "raw_sub_file.hpp"
#include "raw_master_file.hpp"
#include "raw_file.hpp"
#include "pixel_map.hpp"
#include "var_cluster.hpp"
#include "pedestal.hpp"
#include "jungfrau_data_file.hpp" #include "jungfrau_data_file.hpp"
// Pybind stuff // Pybind stuff

View File

@ -10,8 +10,9 @@ using aare::Cluster;
using aare::ClusterFile; using aare::ClusterFile;
using aare::ClusterVector; using aare::ClusterVector;
TEST_CASE("Read one frame from a cluster file", "[.files]") { TEST_CASE("Read one frame from a cluster file", "[.files]") {
// We know that the frame has 97 clusters //We know that the frame has 97 clusters
auto fpath = test_data_path() / "clust" / "single_frame_97_clustrers.clust"; auto fpath = test_data_path() / "clust" / "single_frame_97_clustrers.clust";
REQUIRE(std::filesystem::exists(fpath)); REQUIRE(std::filesystem::exists(fpath));