diff --git a/AGENTS.md b/AGENTS.md index 3468a879..d2d6bb06 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -170,13 +170,24 @@ agree; run them when changing any solver. ### Python layer -- `python/src/module.cpp` registers everything. Templated classes are +- `python/src/module.cpp` only calls the registration entry points declared + in `bindings.hpp`, in a fixed order (overload docstrings follow it). The + bindings themselves are compiled in parallel translation units: + `bind_io.cpp` (files, geometry, pixel maps, calibration, test probes), + `bind_hist.cpp`, `bind_pedestal.cpp`, `bind_fit.cpp`, `bind_eta.cpp`, and + one `bind_cluster_NxN.cpp` per cluster size. Templated classes are instantiated per value type and cluster size through the - `DEFINE_CLUSTER_BINDINGS` and `DEFINE_BINDINGS_CLUSTERFINDER` macros, - producing names such as `ClusterFinder_Cluster3x3i`, `Pedestal_d`, and - `FastPedestal_i16`. Supported cluster sizes are 2x2, 3x3, 5x5, 7x7, and - 9x9; value types are `i`, `f`, `d`, and `i16` (3x3 only). - `module_config.hpp` fixes the module-wide pedestal type (`pd_type`). + `DEFINE_CLUSTER_BINDINGS` and `DEFINE_BINDINGS_CLUSTERFINDER` macros in + `bind_cluster_common.hpp`, producing names such as + `ClusterFinder_Cluster3x3i`, `Pedestal_d`, and `FastPedestal_i16`. + Supported cluster sizes are 2x2, 3x3, 5x5, 7x7, and 9x9; value types are + `i`, `f`, `d`, and `i16` (3x3 only). `module_config.hpp` fixes the + module-wide pedestal type (`pd_type`). Each `bind_*.hpp` header is included + by exactly one translation unit, so a header must include everything it + uses itself, including the pybind11 casters (`pybind11/stl.h`, + `pybind11/stl/filesystem.h`) for the types its bindings take or return. + Non-template functions defined in a header that several units include + must be `inline`. - `python/aare/factory.py` maps NumPy dtypes to those suffixes. The facades in `python/aare/*.py` are thin factory functions or subclasses that select the right binding and add Pythonic conveniences (iteration, context @@ -224,7 +235,10 @@ A Python-facing feature can require coordinated changes in several layers: 1. Update the C++ public API and implementation. 2. Add or update its binding in `python/src/`. -3. Register new bindings in `python/src/module.cpp`. +3. Register new bindings: add the entry point to `python/src/bindings.hpp`, + call it from `python/src/module.cpp`, and include the header from the + matching `python/src/bind_*.cpp` (or add a new one to + `python/CMakeLists.txt`). 4. Update the facade or public exports in `python/aare/`. 5. If adding a Python module, add it to `PYTHON_FILES` in `python/CMakeLists.txt` so it is copied and installed. diff --git a/RELEASE.md b/RELEASE.md index 1a6df702..fbefc6b7 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -19,6 +19,10 @@ - Minuit2, and libzmq when enabled, are compiled as unity builds (about 5x less compile time), and the fetched dependencies are shallow clones, which makes a first configure faster and the build directory smaller. +- The Python extension is compiled from one translation unit per binding + area instead of a single file, so the bindings build in parallel and + editing one binding header recompiles only its unit. The module's + contents and registration order are unchanged. ## 2026.9.30 diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index db7974f3..9510a5ab 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -18,11 +18,21 @@ else() find_package(pybind11 3.0.3 REQUIRED) endif() -# Add the compiled python extension +# The compiled python extension: one translation unit per binding area so they +# compile in parallel; see src/module.cpp for the registration order. pybind11_add_module( _aare # name of the module - src/module.cpp # source file -) + src/module.cpp + src/bind_io.cpp + src/bind_hist.cpp + src/bind_pedestal.cpp + src/bind_fit.cpp + src/bind_eta.cpp + src/bind_cluster_2x2.cpp + src/bind_cluster_3x3.cpp + src/bind_cluster_5x5.cpp + src/bind_cluster_7x7.cpp + src/bind_cluster_9x9.cpp) set_target_properties(_aare PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) diff --git a/python/src/bind_ClusterFileSink.hpp b/python/src/bind_ClusterFileSink.hpp index 50600fcb..32a690c6 100644 --- a/python/src/bind_ClusterFileSink.hpp +++ b/python/src/bind_ClusterFileSink.hpp @@ -12,6 +12,7 @@ #include #include #include +#include #include namespace py = pybind11; diff --git a/python/src/bind_Defs.hpp b/python/src/bind_Defs.hpp index e5f3cc3d..b5f90a8d 100644 --- a/python/src/bind_Defs.hpp +++ b/python/src/bind_Defs.hpp @@ -3,8 +3,11 @@ #include #include +#include "aare/ROI.hpp" #include "aare/defs.hpp" +#include + namespace py = pybind11; using namespace aare; diff --git a/python/src/bind_Eta.hpp b/python/src/bind_Eta.hpp index e2b9302e..9e3eac1e 100644 --- a/python/src/bind_Eta.hpp +++ b/python/src/bind_Eta.hpp @@ -28,7 +28,7 @@ void define_eta(py::module &m, const std::string &typestr) { }); } -void define_corner_enum(py::module &m) { +inline void define_corner_enum(py::module &m) { py::enum_(m, "corner", "enum.Enum") .value("cTopLeft", corner::cTopLeft) .value("cTopRight", corner::cTopRight) diff --git a/python/src/bind_FastPedestal.hpp b/python/src/bind_FastPedestal.hpp index 5c278490..75bef9ec 100644 --- a/python/src/bind_FastPedestal.hpp +++ b/python/src/bind_FastPedestal.hpp @@ -7,6 +7,7 @@ #include #include #include +#include namespace py = pybind11; diff --git a/python/src/bind_MultiThreadedFileReader.hpp b/python/src/bind_MultiThreadedFileReader.hpp index 0f39cb6c..a4fbb011 100644 --- a/python/src/bind_MultiThreadedFileReader.hpp +++ b/python/src/bind_MultiThreadedFileReader.hpp @@ -71,7 +71,7 @@ multi_threaded_reader_read(aare::experimental::MultiThreadedFileReader &reader, return image; } -inline void define_multi_threaded_file_reader_bindings(py::module_ &m) { +void define_multi_threaded_file_reader_bindings(py::module_ &m) { using aare::experimental::MultiThreadedFileReader; auto reader = diff --git a/python/src/bind_PedestalTrackingPixelHistogram.hpp b/python/src/bind_PedestalTrackingPixelHistogram.hpp index 139b58a1..fe4a3c09 100644 --- a/python/src/bind_PedestalTrackingPixelHistogram.hpp +++ b/python/src/bind_PedestalTrackingPixelHistogram.hpp @@ -6,6 +6,7 @@ #include #include #include +#include namespace py = pybind11; using namespace ::aare; diff --git a/python/src/bind_cluster_2x2.cpp b/python/src/bind_cluster_2x2.cpp new file mode 100644 index 00000000..0ff9c660 --- /dev/null +++ b/python/src/bind_cluster_2x2.cpp @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: MPL-2.0 +#include "bind_cluster_common.hpp" + +void bind_cluster_types_2x2(py::module &m) { + DEFINE_CLUSTER_BINDINGS(int, 2, 2, uint16_t, i); + DEFINE_CLUSTER_BINDINGS(double, 2, 2, uint16_t, d); + DEFINE_CLUSTER_BINDINGS(float, 2, 2, uint16_t, f); +} diff --git a/python/src/bind_cluster_3x3.cpp b/python/src/bind_cluster_3x3.cpp new file mode 100644 index 00000000..7b30a378 --- /dev/null +++ b/python/src/bind_cluster_3x3.cpp @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: MPL-2.0 +#include "bind_cluster_common.hpp" + +void bind_cluster_types_3x3(py::module &m) { + DEFINE_CLUSTER_BINDINGS(int, 3, 3, uint16_t, i); + DEFINE_CLUSTER_BINDINGS(double, 3, 3, uint16_t, d); + DEFINE_CLUSTER_BINDINGS(float, 3, 3, uint16_t, f); +} + +void bind_cluster_types_3x3_i16(py::module &m) { + DEFINE_CLUSTER_BINDINGS(int16_t, 3, 3, uint16_t, i16); +} + +void bind_cluster_finders_3x3(py::module &m) { + DEFINE_BINDINGS_CLUSTERFINDER(int, 3, 3, uint16_t, i); + DEFINE_BINDINGS_CLUSTERFINDER(double, 3, 3, uint16_t, d); + DEFINE_BINDINGS_CLUSTERFINDER(float, 3, 3, uint16_t, f); + DEFINE_BINDINGS_CLUSTERFINDER(int16_t, 3, 3, uint16_t, i16); +} + +void bind_eta_3x3(py::module &m) { + register_calculate_3x3eta(m); + register_calculate_3x3eta(m); + register_calculate_3x3eta(m); + register_calculate_3x3eta(m); +} diff --git a/python/src/bind_cluster_5x5.cpp b/python/src/bind_cluster_5x5.cpp new file mode 100644 index 00000000..fbd3b9af --- /dev/null +++ b/python/src/bind_cluster_5x5.cpp @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: MPL-2.0 +#include "bind_cluster_common.hpp" + +void bind_cluster_types_5x5(py::module &m) { + DEFINE_CLUSTER_BINDINGS(int, 5, 5, uint16_t, i); + DEFINE_CLUSTER_BINDINGS(double, 5, 5, uint16_t, d); + DEFINE_CLUSTER_BINDINGS(float, 5, 5, uint16_t, f); +} + +void bind_cluster_finders_5x5(py::module &m) { + DEFINE_BINDINGS_CLUSTERFINDER(int, 5, 5, uint16_t, i); + DEFINE_BINDINGS_CLUSTERFINDER(double, 5, 5, uint16_t, d); + DEFINE_BINDINGS_CLUSTERFINDER(float, 5, 5, uint16_t, f); +} + +void bind_cluster_vector_reductions_5x5(py::module &m) { + define_3x3_reduction(m); + define_3x3_reduction(m); + define_3x3_reduction(m); +} + +void bind_cluster_reductions_5x5(py::module &m) { + reduce_to_3x3(m); + reduce_to_3x3(m); + reduce_to_3x3(m); +} diff --git a/python/src/bind_cluster_7x7.cpp b/python/src/bind_cluster_7x7.cpp new file mode 100644 index 00000000..33341c2a --- /dev/null +++ b/python/src/bind_cluster_7x7.cpp @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: MPL-2.0 +#include "bind_cluster_common.hpp" + +void bind_cluster_types_7x7(py::module &m) { + DEFINE_CLUSTER_BINDINGS(int, 7, 7, uint16_t, i); + DEFINE_CLUSTER_BINDINGS(double, 7, 7, uint16_t, d); + DEFINE_CLUSTER_BINDINGS(float, 7, 7, uint16_t, f); +} + +void bind_cluster_finders_7x7(py::module &m) { + DEFINE_BINDINGS_CLUSTERFINDER(int, 7, 7, uint16_t, i); + DEFINE_BINDINGS_CLUSTERFINDER(double, 7, 7, uint16_t, d); + DEFINE_BINDINGS_CLUSTERFINDER(float, 7, 7, uint16_t, f); +} + +void bind_cluster_vector_reductions_7x7(py::module &m) { + define_3x3_reduction(m); + define_3x3_reduction(m); + define_3x3_reduction(m); +} + +void bind_cluster_reductions_7x7(py::module &m) { + reduce_to_3x3(m); + reduce_to_3x3(m); + reduce_to_3x3(m); +} diff --git a/python/src/bind_cluster_9x9.cpp b/python/src/bind_cluster_9x9.cpp new file mode 100644 index 00000000..ecbf9375 --- /dev/null +++ b/python/src/bind_cluster_9x9.cpp @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: MPL-2.0 +#include "bind_cluster_common.hpp" + +void bind_cluster_types_9x9(py::module &m) { + DEFINE_CLUSTER_BINDINGS(int, 9, 9, uint16_t, i); + DEFINE_CLUSTER_BINDINGS(double, 9, 9, uint16_t, d); + DEFINE_CLUSTER_BINDINGS(float, 9, 9, uint16_t, f); +} + +void bind_cluster_finders_9x9(py::module &m) { + DEFINE_BINDINGS_CLUSTERFINDER(int, 9, 9, uint16_t, i); + DEFINE_BINDINGS_CLUSTERFINDER(double, 9, 9, uint16_t, d); + DEFINE_BINDINGS_CLUSTERFINDER(float, 9, 9, uint16_t, f); +} + +void bind_cluster_vector_reductions_9x9(py::module &m) { + define_3x3_reduction(m); + define_3x3_reduction(m); + define_3x3_reduction(m); +} + +void bind_cluster_reductions_9x9(py::module &m) { + reduce_to_3x3(m); + reduce_to_3x3(m); + reduce_to_3x3(m); +} diff --git a/python/src/bind_cluster_common.hpp b/python/src/bind_cluster_common.hpp new file mode 100644 index 00000000..809a58b8 --- /dev/null +++ b/python/src/bind_cluster_common.hpp @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: MPL-2.0 +// Shared by the per-cluster-size translation units bind_cluster_NxN.cpp. +#pragma once + +#include "module_config.hpp" + +#include "bind_Cluster.hpp" +#include "bind_ClusterCollector.hpp" +#include "bind_ClusterFile.hpp" +#include "bind_ClusterFileSink.hpp" +#include "bind_ClusterFinder.hpp" +#include "bind_ClusterFinderMT.hpp" +#include "bind_ClusterVector.hpp" +#include "bind_Eta.hpp" + +/* MACRO that defines Cluster bindings for a specific size and type + +T - Storage type of the cluster data (int, float, double) +N - Number of rows in the cluster +M - Number of columns in the cluster +U - Type of the pixel data (e.g., uint16_t) +TYPE_CODE - A character representing the type code (e.g., 'i' for int, 'd' for +double, 'f' for float) + +*/ +#define DEFINE_CLUSTER_BINDINGS(T, N, M, U, TYPE_CODE) \ + define_ClusterFile(m, "Cluster" #N "x" #M #TYPE_CODE); \ + define_ClusterVector(m, "Cluster" #N "x" #M #TYPE_CODE); \ + define_Cluster(m, #N "x" #M #TYPE_CODE); \ + register_calculate_2x2eta(m); \ + define_2x2_reduction(m); \ + reduce_to_2x2(m); + +#define DEFINE_BINDINGS_CLUSTERFINDER(T, N, M, U, TYPE_CODE) \ + define_ClusterFinder(m, "Cluster" #N "x" #M #TYPE_CODE); \ + define_ClusterFinderMT(m, "Cluster" #N "x" #M #TYPE_CODE); \ + define_ClusterFileSink(m, "Cluster" #N "x" #M #TYPE_CODE); \ + define_ClusterCollector(m, "Cluster" #N "x" #M #TYPE_CODE); diff --git a/python/src/bind_eta.cpp b/python/src/bind_eta.cpp new file mode 100644 index 00000000..8cebfda0 --- /dev/null +++ b/python/src/bind_eta.cpp @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: MPL-2.0 +#include "module_config.hpp" + +#include "bind_Eta.hpp" + +#include +#include + +void bind_eta_types(py::module &m) { + using Sum_index_pair_d = Sum_index_pair; + PYBIND11_NUMPY_DTYPE(Sum_index_pair_d, sum, index); + using Sum_index_pair_f = Sum_index_pair; + PYBIND11_NUMPY_DTYPE(Sum_index_pair_f, sum, index); + using Sum_index_pair_i = Sum_index_pair; + PYBIND11_NUMPY_DTYPE(Sum_index_pair_i, sum, index); + + using eta_d = Eta2; + PYBIND11_NUMPY_DTYPE(eta_d, x, y, c, sum); + using eta_i = Eta2; + PYBIND11_NUMPY_DTYPE(eta_i, x, y, c, sum); + using eta_f = Eta2; + PYBIND11_NUMPY_DTYPE(eta_f, x, y, c, sum); + using eta_i16 = Eta2; + PYBIND11_NUMPY_DTYPE(eta_i16, x, y, c, sum); + + define_corner_enum(m); + define_eta(m, "f"); + define_eta(m, "d"); + define_eta(m, "i"); + define_eta(m, "i16"); +} diff --git a/python/src/bind_fit.cpp b/python/src/bind_fit.cpp new file mode 100644 index 00000000..5104c154 --- /dev/null +++ b/python/src/bind_fit.cpp @@ -0,0 +1,5 @@ +// SPDX-License-Identifier: MPL-2.0 +#include "module_config.hpp" + +#include "bind_Interpolator.hpp" +#include "fit.hpp" diff --git a/python/src/bind_hist.cpp b/python/src/bind_hist.cpp new file mode 100644 index 00000000..8a8d1305 --- /dev/null +++ b/python/src/bind_hist.cpp @@ -0,0 +1,5 @@ +// SPDX-License-Identifier: MPL-2.0 +#include "module_config.hpp" + +#include "bind_PedestalTrackingPixelHistogram.hpp" +#include "bind_PixelHistogram.hpp" diff --git a/python/src/bind_io.cpp b/python/src/bind_io.cpp new file mode 100644 index 00000000..10f840dd --- /dev/null +++ b/python/src/bind_io.cpp @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: MPL-2.0 +// File readers, geometry, pixel maps, calibration and test probes. +#include "module_config.hpp" + +#include "bind_Defs.hpp" +#include "bind_MultiThreadedFileReader.hpp" +#include "bind_PixelMap.hpp" +#include "bind_RawFile.hpp" +#include "bind_calibration.hpp" +#include "bind_testing.hpp" +#include "ctb_raw_file.hpp" +#include "file.hpp" +#include "jungfrau_data_file.hpp" +#include "raw_master_file.hpp" +#include "raw_sub_file.hpp" +#include "var_cluster.hpp" diff --git a/python/src/bind_pedestal.cpp b/python/src/bind_pedestal.cpp new file mode 100644 index 00000000..994a41ae --- /dev/null +++ b/python/src/bind_pedestal.cpp @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: MPL-2.0 +#include "module_config.hpp" + +#include "bind_FastPedestal.hpp" +#include "bind_Pedestal.hpp" + +void bind_pedestals(py::module &m) { + define_pedestal_bindings(m, "Pedestal_d"); + define_pedestal_bindings(m, "Pedestal_f"); + define_pedestal_bindings(m, "Pedestal_i16"); + define_fast_pedestal_bindings(m, "FastPedestal_d"); + define_fast_pedestal_bindings(m, "FastPedestal_f"); + define_fast_pedestal_bindings(m, "FastPedestal_i16"); +} diff --git a/python/src/bindings.hpp b/python/src/bindings.hpp new file mode 100644 index 00000000..d2cddecb --- /dev/null +++ b/python/src/bindings.hpp @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: MPL-2.0 +// Entry points of the binding translation units. Each function registers one +// area of the module; module.cpp calls them in a fixed order. +#pragma once + +#include +#include + +namespace py = pybind11; + +// bind_io.cpp (functions defined in the individual bind_*.hpp headers) +void define_file_io_bindings(py::module &m); +void define_multi_threaded_file_reader_bindings(py::module &m); +void define_raw_file_io_bindings(py::module &m); +void define_raw_sub_file_io_bindings(py::module &m); +void define_ctb_raw_file_io_bindings(py::module &m); +void define_raw_master_file_bindings(py::module &m); +void define_var_cluster_finder_bindings(py::module &m); +void define_pixel_map_bindings(py::module &m); +void define_jungfrau_data_file_io_bindings(py::module &m); +void bind_calibration(py::module &m); +void define_testing_bindings(py::module &m); +void define_defs_bindings(py::module &m); + +// bind_hist.cpp +void define_pixel_histogram_bindings(py::module &m); +void define_pedestal_tracking_pixel_histogram_bindings(py::module &m); + +// bind_pedestal.cpp +void bind_pedestals(py::module &m); + +// bind_fit.cpp +void define_fit_bindings(py::module &m); +void define_interpolation_bindings(py::module &m); + +// bind_cluster_NxN.cpp +void bind_cluster_types_3x3(py::module &m); +void bind_cluster_types_3x3_i16(py::module &m); +void bind_cluster_types_2x2(py::module &m); +void bind_cluster_types_5x5(py::module &m); +void bind_cluster_types_7x7(py::module &m); +void bind_cluster_types_9x9(py::module &m); +void bind_cluster_finders_3x3(py::module &m); +void bind_cluster_finders_5x5(py::module &m); +void bind_cluster_finders_7x7(py::module &m); +void bind_cluster_finders_9x9(py::module &m); +void bind_cluster_vector_reductions_5x5(py::module &m); +void bind_cluster_vector_reductions_7x7(py::module &m); +void bind_cluster_vector_reductions_9x9(py::module &m); +void bind_cluster_reductions_5x5(py::module &m); +void bind_cluster_reductions_7x7(py::module &m); +void bind_cluster_reductions_9x9(py::module &m); +void bind_eta_3x3(py::module &m); + +// bind_eta.cpp +void bind_eta_types(py::module &m); diff --git a/python/src/module.cpp b/python/src/module.cpp index b83deaca..2eb89d0e 100644 --- a/python/src/module.cpp +++ b/python/src/module.cpp @@ -1,68 +1,10 @@ // SPDX-License-Identifier: MPL-2.0 -// Files with bindings to the different classes +// Module registration. The bindings live in bind_*.cpp translation units so +// they compile in parallel; the call order below is kept as before. -#include "module_config.hpp" +#include "bindings.hpp" -// New style file naming -#include "bind_Cluster.hpp" -#include "bind_ClusterCollector.hpp" -#include "bind_ClusterFile.hpp" -#include "bind_ClusterFileSink.hpp" -#include "bind_ClusterFinder.hpp" -#include "bind_ClusterFinderMT.hpp" -#include "bind_ClusterVector.hpp" -#include "bind_Defs.hpp" -#include "bind_Eta.hpp" -#include "bind_FastPedestal.hpp" -#include "bind_Interpolator.hpp" -#include "bind_MultiThreadedFileReader.hpp" -#include "bind_Pedestal.hpp" -#include "bind_PedestalTrackingPixelHistogram.hpp" -#include "bind_PixelHistogram.hpp" -#include "bind_PixelMap.hpp" -#include "bind_RawFile.hpp" -#include "bind_calibration.hpp" -#include "bind_testing.hpp" - -// TODO! migrate the other names -#include "ctb_raw_file.hpp" -#include "file.hpp" -#include "fit.hpp" -#include "jungfrau_data_file.hpp" -#include "raw_master_file.hpp" -#include "raw_sub_file.hpp" -#include "var_cluster.hpp" - -// Pybind stuff -#include #include -#include - -namespace py = pybind11; - -/* MACRO that defines Cluster bindings for a specific size and type - -T - Storage type of the cluster data (int, float, double) -N - Number of rows in the cluster -M - Number of columns in the cluster -U - Type of the pixel data (e.g., uint16_t) -TYPE_CODE - A character representing the type code (e.g., 'i' for int, 'd' for -double, 'f' for float) - -*/ -#define DEFINE_CLUSTER_BINDINGS(T, N, M, U, TYPE_CODE) \ - define_ClusterFile(m, "Cluster" #N "x" #M #TYPE_CODE); \ - define_ClusterVector(m, "Cluster" #N "x" #M #TYPE_CODE); \ - define_Cluster(m, #N "x" #M #TYPE_CODE); \ - register_calculate_2x2eta(m); \ - define_2x2_reduction(m); \ - reduce_to_2x2(m); - -#define DEFINE_BINDINGS_CLUSTERFINDER(T, N, M, U, TYPE_CODE) \ - define_ClusterFinder(m, "Cluster" #N "x" #M #TYPE_CODE); \ - define_ClusterFinderMT(m, "Cluster" #N "x" #M #TYPE_CODE); \ - define_ClusterFileSink(m, "Cluster" #N "x" #M #TYPE_CODE); \ - define_ClusterCollector(m, "Cluster" #N "x" #M #TYPE_CODE); PYBIND11_MODULE(_aare, m) { auto experimental = m.def_submodule( @@ -78,12 +20,7 @@ PYBIND11_MODULE(_aare, m) { define_pixel_map_bindings(m); define_pixel_histogram_bindings(m); define_pedestal_tracking_pixel_histogram_bindings(m); - define_pedestal_bindings(m, "Pedestal_d"); - define_pedestal_bindings(m, "Pedestal_f"); - define_pedestal_bindings(m, "Pedestal_i16"); - define_fast_pedestal_bindings(m, "FastPedestal_d"); - define_fast_pedestal_bindings(m, "FastPedestal_f"); - define_fast_pedestal_bindings(m, "FastPedestal_i16"); + bind_pedestals(m); define_fit_bindings(m); define_interpolation_bindings(m); define_jungfrau_data_file_io_bindings(m); @@ -91,91 +28,29 @@ PYBIND11_MODULE(_aare, m) { bind_calibration(m); define_testing_bindings(m); - DEFINE_CLUSTER_BINDINGS(int, 3, 3, uint16_t, i); - DEFINE_CLUSTER_BINDINGS(double, 3, 3, uint16_t, d); - DEFINE_CLUSTER_BINDINGS(float, 3, 3, uint16_t, f); + bind_cluster_types_3x3(m); + bind_cluster_types_2x2(m); + bind_cluster_types_5x5(m); + bind_cluster_types_7x7(m); + bind_cluster_types_9x9(m); + bind_cluster_types_3x3_i16(m); - DEFINE_CLUSTER_BINDINGS(int, 2, 2, uint16_t, i); - DEFINE_CLUSTER_BINDINGS(double, 2, 2, uint16_t, d); - DEFINE_CLUSTER_BINDINGS(float, 2, 2, uint16_t, f); + bind_cluster_finders_3x3(m); + bind_cluster_finders_5x5(m); + bind_cluster_finders_7x7(m); + bind_cluster_finders_9x9(m); - DEFINE_CLUSTER_BINDINGS(int, 5, 5, uint16_t, i); - DEFINE_CLUSTER_BINDINGS(double, 5, 5, uint16_t, d); - DEFINE_CLUSTER_BINDINGS(float, 5, 5, uint16_t, f); + bind_cluster_vector_reductions_5x5(m); + bind_cluster_vector_reductions_7x7(m); + bind_cluster_vector_reductions_9x9(m); - DEFINE_CLUSTER_BINDINGS(int, 7, 7, uint16_t, i); - DEFINE_CLUSTER_BINDINGS(double, 7, 7, uint16_t, d); - DEFINE_CLUSTER_BINDINGS(float, 7, 7, uint16_t, f); + bind_cluster_reductions_5x5(m); + bind_cluster_reductions_7x7(m); + bind_cluster_reductions_9x9(m); - DEFINE_CLUSTER_BINDINGS(int, 9, 9, uint16_t, i); - DEFINE_CLUSTER_BINDINGS(double, 9, 9, uint16_t, d); - DEFINE_CLUSTER_BINDINGS(float, 9, 9, uint16_t, f); - - DEFINE_CLUSTER_BINDINGS(int16_t, 3, 3, uint16_t, i16); - - DEFINE_BINDINGS_CLUSTERFINDER(int, 3, 3, uint16_t, i); - DEFINE_BINDINGS_CLUSTERFINDER(double, 3, 3, uint16_t, d); - DEFINE_BINDINGS_CLUSTERFINDER(float, 3, 3, uint16_t, f); - DEFINE_BINDINGS_CLUSTERFINDER(int16_t, 3, 3, uint16_t, i16); - - DEFINE_BINDINGS_CLUSTERFINDER(int, 5, 5, uint16_t, i); - DEFINE_BINDINGS_CLUSTERFINDER(double, 5, 5, uint16_t, d); - DEFINE_BINDINGS_CLUSTERFINDER(float, 5, 5, uint16_t, f); - - DEFINE_BINDINGS_CLUSTERFINDER(int, 7, 7, uint16_t, i); - DEFINE_BINDINGS_CLUSTERFINDER(double, 7, 7, uint16_t, d); - DEFINE_BINDINGS_CLUSTERFINDER(float, 7, 7, uint16_t, f); - - DEFINE_BINDINGS_CLUSTERFINDER(int, 9, 9, uint16_t, i); - DEFINE_BINDINGS_CLUSTERFINDER(double, 9, 9, uint16_t, d); - DEFINE_BINDINGS_CLUSTERFINDER(float, 9, 9, uint16_t, f); - - define_3x3_reduction(m); - define_3x3_reduction(m); - define_3x3_reduction(m); - define_3x3_reduction(m); - define_3x3_reduction(m); - define_3x3_reduction(m); - define_3x3_reduction(m); - define_3x3_reduction(m); - define_3x3_reduction(m); - - reduce_to_3x3(m); - reduce_to_3x3(m); - reduce_to_3x3(m); - reduce_to_3x3(m); - reduce_to_3x3(m); - reduce_to_3x3(m); - reduce_to_3x3(m); - reduce_to_3x3(m); - reduce_to_3x3(m); - - register_calculate_3x3eta(m); - register_calculate_3x3eta(m); - register_calculate_3x3eta(m); - register_calculate_3x3eta(m); + bind_eta_3x3(m); define_defs_bindings(m); - using Sum_index_pair_d = Sum_index_pair; - PYBIND11_NUMPY_DTYPE(Sum_index_pair_d, sum, index); - using Sum_index_pair_f = Sum_index_pair; - PYBIND11_NUMPY_DTYPE(Sum_index_pair_f, sum, index); - using Sum_index_pair_i = Sum_index_pair; - PYBIND11_NUMPY_DTYPE(Sum_index_pair_i, sum, index); - - using eta_d = Eta2; - PYBIND11_NUMPY_DTYPE(eta_d, x, y, c, sum); - using eta_i = Eta2; - PYBIND11_NUMPY_DTYPE(eta_i, x, y, c, sum); - using eta_f = Eta2; - PYBIND11_NUMPY_DTYPE(eta_f, x, y, c, sum); - using eta_i16 = Eta2; - PYBIND11_NUMPY_DTYPE(eta_i16, x, y, c, sum); - - define_corner_enum(m); - define_eta(m, "f"); - define_eta(m, "d"); - define_eta(m, "i"); - define_eta(m, "i16"); + bind_eta_types(m); } diff --git a/python/src/np_helper.hpp b/python/src/np_helper.hpp index 83880470..6beb7318 100644 --- a/python/src/np_helper.hpp +++ b/python/src/np_helper.hpp @@ -1,11 +1,13 @@ // SPDX-License-Identifier: MPL-2.0 #pragma once +#include #include #include #include #include +#include "aare/Cluster.hpp" #include "aare/Frame.hpp" #include "aare/NDArray.hpp" #include "aare/NDView.hpp" @@ -124,8 +126,8 @@ template const std::string &fmt_format() { * Helper function to allocate image data given item size and shape * used when we want to fill a numpy array and return to python */ -py::array allocate_image_data(size_t item_size, - const std::vector &shape) { +inline py::array allocate_image_data(size_t item_size, + const std::vector &shape) { py::array image_data; if (item_size == 1) { image_data = py::array_t(shape);