mirror of
https://github.com/slsdetectorgroup/aare.git
synced 2026-02-19 16:48:42 +01:00
Dev/rosenblatttransform (#241)
- added rosenblatttransform - added 3x3 eta methods - interpolation can be used with various eta functions - added documentation for interpolation, eta calculation - exposed full eta struct in python - disable ClusterFinder for 2x2 clusters - factory function for ClusterVector --------- Co-authored-by: Dhanya Thattil <dhanya.thattil@psi.ch> Co-authored-by: Erik Fröjdh <erik.frojdh@psi.ch>
This commit is contained in:
@@ -80,9 +80,7 @@ void reduce_to_3x3(py::module &m) {
|
||||
[](const Cluster<T, ClusterSizeX, ClusterSizeY, CoordType> &cl) {
|
||||
return reduce_to_3x3(cl);
|
||||
},
|
||||
py::return_value_policy::move,
|
||||
"Reduce cluster to 3x3 subcluster by taking the 3x3 subcluster with "
|
||||
"the highest photon energy.");
|
||||
py::return_value_policy::move, R"(Reduce cluster to 3x3 subcluster)");
|
||||
}
|
||||
|
||||
template <typename T, uint8_t ClusterSizeX, uint8_t ClusterSizeY,
|
||||
@@ -95,8 +93,15 @@ void reduce_to_2x2(py::module &m) {
|
||||
return reduce_to_2x2(cl);
|
||||
},
|
||||
py::return_value_policy::move,
|
||||
"Reduce cluster to 2x2 subcluster by taking the 2x2 subcluster with "
|
||||
"the highest photon energy.");
|
||||
R"(
|
||||
Reduce cluster to 2x2 subcluster by taking the 2x2 subcluster with
|
||||
the highest photon energy.
|
||||
|
||||
RETURN:
|
||||
|
||||
reduced cluster (cluster is 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.)
|
||||
|
||||
)");
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
@@ -81,23 +81,4 @@ void define_ClusterFile(py::module &m, const std::string &typestr) {
|
||||
});
|
||||
}
|
||||
|
||||
template <typename Type, uint8_t CoordSizeX, uint8_t CoordSizeY,
|
||||
typename CoordType = uint16_t>
|
||||
void register_calculate_eta(py::module &m) {
|
||||
using ClusterType = Cluster<Type, CoordSizeX, CoordSizeY, CoordType>;
|
||||
|
||||
m.def("calculate_eta2",
|
||||
[](const aare::ClusterVector<ClusterType> &clusters) {
|
||||
auto eta2 = new NDArray<double, 2>(calculate_eta2(clusters));
|
||||
return return_image_data(eta2);
|
||||
});
|
||||
|
||||
m.def("calculate_eta2", [](const aare::Cluster<Type, CoordSizeX, CoordSizeY,
|
||||
CoordType> &cluster) {
|
||||
auto eta2 = calculate_eta2(cluster);
|
||||
// TODO return proper eta class
|
||||
return py::make_tuple(eta2.x, eta2.y, eta2.sum);
|
||||
});
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
@@ -120,12 +120,13 @@ void define_2x2_reduction(py::module &m) {
|
||||
reduce_to_2x2(cv));
|
||||
},
|
||||
R"(
|
||||
|
||||
Reduce cluster to 2x2 subcluster by taking the 2x2 subcluster with
|
||||
the highest photon energy."
|
||||
the highest photon energy.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
cv : ClusterVector
|
||||
|
||||
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"));
|
||||
}
|
||||
@@ -142,11 +143,10 @@ void define_3x3_reduction(py::module &m) {
|
||||
reduce_to_3x3(cv));
|
||||
},
|
||||
R"(
|
||||
|
||||
Reduce cluster to 3x3 subcluster by taking the 3x3 subcluster with
|
||||
the highest photon energy."
|
||||
Reduce cluster to 3x3 subcluster
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
cv : ClusterVector
|
||||
)",
|
||||
py::arg("clustervector"));
|
||||
|
||||
104
python/src/bind_Eta.hpp
Normal file
104
python/src/bind_Eta.hpp
Normal file
@@ -0,0 +1,104 @@
|
||||
#include "aare/CalculateEta.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
// #include <pybind11/native_enum.h> only for version 3
|
||||
#include <pybind11/pybind11.h>
|
||||
|
||||
namespace py = pybind11;
|
||||
using namespace ::aare;
|
||||
|
||||
template <typename T>
|
||||
void define_eta(py::module &m, const std::string &typestr) {
|
||||
auto class_name = fmt::format("Eta{}", typestr);
|
||||
|
||||
py::class_<Eta2<T>>(m, class_name.c_str())
|
||||
.def(py::init<>())
|
||||
.def_readonly("x", &Eta2<T>::x, "eta x value")
|
||||
.def_readonly("y", &Eta2<T>::y, "eta y value")
|
||||
.def_readonly("c", &Eta2<T>::c,
|
||||
"eta corner value cTopLeft, cTopRight, "
|
||||
"cBottomLeft, cBottomRight")
|
||||
.def_readonly("sum", &Eta2<T>::sum, "photon energy of cluster");
|
||||
}
|
||||
|
||||
void define_corner_enum(py::module &m) {
|
||||
py::enum_<corner>(m, "corner", "enum.Enum")
|
||||
.value("cTopLeft", corner::cTopLeft)
|
||||
.value("cTopRight", corner::cTopRight)
|
||||
.value("cBottomLeft", corner::cBottomLeft)
|
||||
.value("cBottomRight", corner::cBottomRight)
|
||||
.export_values();
|
||||
}
|
||||
|
||||
template <typename Type, uint8_t CoordSizeX, uint8_t CoordSizeY,
|
||||
typename CoordType = uint16_t>
|
||||
void register_calculate_2x2eta(py::module &m) {
|
||||
using ClusterType = Cluster<Type, CoordSizeX, CoordSizeY, CoordType>;
|
||||
|
||||
m.def(
|
||||
"calculate_eta2",
|
||||
[](const aare::ClusterVector<ClusterType> &clusters) {
|
||||
auto eta2 = new std::vector<Eta2<typename ClusterType::value_type>>(
|
||||
calculate_eta2(clusters));
|
||||
return return_vector(eta2);
|
||||
},
|
||||
R"(calculates eta2x2)", py::arg("clusters"));
|
||||
|
||||
m.def(
|
||||
"calculate_eta2",
|
||||
[](const aare::Cluster<Type, CoordSizeX, CoordSizeY, CoordType>
|
||||
&cluster) { return calculate_eta2(cluster); },
|
||||
R"(calculates eta2x2)", py::arg("cluster"));
|
||||
|
||||
m.def(
|
||||
"calculate_full_eta2",
|
||||
[](const aare::Cluster<Type, CoordSizeX, CoordSizeY, CoordType>
|
||||
&cluster) { return calculate_full_eta2(cluster); },
|
||||
R"(calculates full eta2x2)", py::arg("cluster"));
|
||||
|
||||
m.def(
|
||||
"calculate_full_eta2",
|
||||
[](const aare::ClusterVector<ClusterType> &clusters) {
|
||||
auto eta2 = new std::vector<Eta2<typename ClusterType::value_type>>(
|
||||
calculate_full_eta2(clusters));
|
||||
return return_vector(eta2);
|
||||
},
|
||||
R"(calculates full eta2x2)", py::arg("clusters"));
|
||||
}
|
||||
|
||||
template <typename Type, uint8_t ClusterSizeX, uint8_t ClusterSizeY,
|
||||
typename CoordType = uint16_t>
|
||||
void register_calculate_3x3eta(py::module &m) {
|
||||
using ClusterType = Cluster<Type, ClusterSizeX, ClusterSizeY, CoordType>;
|
||||
|
||||
m.def(
|
||||
"calculate_eta3",
|
||||
[](const aare::ClusterVector<ClusterType> &clusters) {
|
||||
auto eta = new std::vector<Eta2<Type>>(calculate_eta3(clusters));
|
||||
return return_vector(eta);
|
||||
},
|
||||
R"(calculates eta3x3 using entire cluster)", py::arg("clusters"));
|
||||
|
||||
m.def(
|
||||
"calculate_cross_eta3",
|
||||
[](const aare::ClusterVector<ClusterType> &clusters) {
|
||||
auto eta =
|
||||
new std::vector<Eta2<Type>>(calculate_cross_eta3(clusters));
|
||||
return return_vector(eta);
|
||||
},
|
||||
R"(calculates eta3x3 taking into account cross pixels in cluster)",
|
||||
py::arg("clusters"));
|
||||
|
||||
m.def(
|
||||
"calculate_eta3",
|
||||
[](const ClusterType &cluster) { return calculate_eta3(cluster); },
|
||||
R"(calculates eta3x3 using entire cluster)", py::arg("cluster"));
|
||||
|
||||
m.def(
|
||||
"calculate_cross_eta3",
|
||||
[](const ClusterType &cluster) {
|
||||
return calculate_cross_eta3(cluster);
|
||||
},
|
||||
R"(calculates eta3x3 taking into account cross pixels in cluster)",
|
||||
py::arg("cluster"));
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
#include "aare/CalculateEta.hpp"
|
||||
#include "aare/Interpolator.hpp"
|
||||
#include "aare/NDArray.hpp"
|
||||
#include "aare/NDView.hpp"
|
||||
@@ -9,19 +10,41 @@
|
||||
|
||||
namespace py = pybind11;
|
||||
|
||||
#define REGISTER_INTERPOLATOR_ETA2(T, N, M, U) \
|
||||
register_interpolate<T, N, M, U, aare::calculate_full_eta2<T, N, M, U>>( \
|
||||
interpolator, "_full_eta2", "full eta2"); \
|
||||
register_interpolate<T, N, M, U, aare::calculate_eta2<T, N, M, U>>( \
|
||||
interpolator, "", "eta2");
|
||||
|
||||
#define REGISTER_INTERPOLATOR_ETA3(T, N, M, U) \
|
||||
register_interpolate<T, N, M, U, aare::calculate_eta3<T, N, M, U>>( \
|
||||
interpolator, "_eta3", "full eta3"); \
|
||||
register_interpolate<T, N, M, U, aare::calculate_cross_eta3<T, N, M, U>>( \
|
||||
interpolator, "_cross_eta3", "cross eta3");
|
||||
|
||||
template <typename Type, uint8_t CoordSizeX, uint8_t CoordSizeY,
|
||||
typename CoordType = uint16_t>
|
||||
void register_interpolate(py::class_<aare::Interpolator> &interpolator) {
|
||||
typename CoordType = uint16_t, auto EtaFunction>
|
||||
void register_interpolate(py::class_<aare::Interpolator> &interpolator,
|
||||
const std::string &typestr = "",
|
||||
const std::string &doc_string_etatype = "eta2x2") {
|
||||
|
||||
using ClusterType = Cluster<Type, CoordSizeX, CoordSizeY, CoordType>;
|
||||
|
||||
interpolator.def("interpolate",
|
||||
[](aare::Interpolator &self,
|
||||
const ClusterVector<ClusterType> &clusters) {
|
||||
auto photons = self.interpolate<ClusterType>(clusters);
|
||||
auto *ptr = new std::vector<Photon>{photons};
|
||||
return return_vector(ptr);
|
||||
});
|
||||
const std::string docstring = "interpolation based on " +
|
||||
doc_string_etatype +
|
||||
"\n\nReturns:\n interpolated photons";
|
||||
|
||||
auto function_name = fmt::format("interpolate{}", typestr);
|
||||
|
||||
interpolator.def(
|
||||
function_name.c_str(),
|
||||
[](aare::Interpolator &self,
|
||||
const ClusterVector<ClusterType> &clusters) {
|
||||
auto photons = self.interpolate<EtaFunction, ClusterType>(clusters);
|
||||
auto *ptr = new std::vector<Photon>{photons};
|
||||
return return_vector(ptr);
|
||||
},
|
||||
docstring.c_str(), py::arg("cluster_vector"));
|
||||
}
|
||||
|
||||
void define_interpolation_bindings(py::module &m) {
|
||||
@@ -30,33 +53,91 @@ void define_interpolation_bindings(py::module &m) {
|
||||
|
||||
auto interpolator =
|
||||
py::class_<aare::Interpolator>(m, "Interpolator")
|
||||
.def(py::init([](py::array_t<double, py::array::c_style |
|
||||
py::array::forcecast>
|
||||
etacube,
|
||||
py::array_t<double> xbins,
|
||||
py::array_t<double> ybins,
|
||||
py::array_t<double> ebins) {
|
||||
return Interpolator(make_view_3d(etacube), make_view_1d(xbins),
|
||||
make_view_1d(ybins), make_view_1d(ebins));
|
||||
}))
|
||||
.def(py::init(
|
||||
[](py::array_t<double,
|
||||
py::array::c_style | py::array::forcecast>
|
||||
etacube,
|
||||
py::array_t<double> xbins, py::array_t<double> ybins,
|
||||
py::array_t<double> ebins) {
|
||||
return Interpolator(
|
||||
make_view_3d(etacube), make_view_1d(xbins),
|
||||
make_view_1d(ybins), make_view_1d(ebins));
|
||||
}),
|
||||
R"doc(
|
||||
Constructor
|
||||
|
||||
Args:
|
||||
|
||||
etacube:
|
||||
joint distribution of eta_x, eta_y and photon energy (**Note:** for the joint distribution first dimension is eta_x, second: eta_y, third: energy bins.)
|
||||
xbins:
|
||||
bin edges of etax
|
||||
ybins:
|
||||
bin edges of etay
|
||||
ebins:
|
||||
bin edges of photon energy
|
||||
)doc",
|
||||
py::arg("etacube"),
|
||||
py::arg("xbins"), py::arg("ybins"),
|
||||
py::arg("ebins"))
|
||||
|
||||
.def(py::init(
|
||||
[](py::array_t<double> xbins, py::array_t<double> ybins,
|
||||
py::array_t<double> ebins) {
|
||||
return Interpolator(make_view_1d(xbins),
|
||||
make_view_1d(ybins),
|
||||
make_view_1d(ebins));
|
||||
}),
|
||||
R"(
|
||||
Constructor
|
||||
|
||||
Args:
|
||||
|
||||
xbins:
|
||||
bin edges of etax
|
||||
ybins:
|
||||
bin edges of etay
|
||||
ebins:
|
||||
bin edges of photon energy
|
||||
)", py::arg("xbins"),
|
||||
py::arg("ybins"), py::arg("ebins"))
|
||||
.def(
|
||||
"rosenblatttransform",
|
||||
[](Interpolator &self,
|
||||
py::array_t<double,
|
||||
py::array::c_style | py::array::forcecast>
|
||||
etacube) {
|
||||
return self.rosenblatttransform(make_view_3d(etacube));
|
||||
},
|
||||
R"(
|
||||
calculated the rosenblatttransform for the given distribution
|
||||
|
||||
etacube:
|
||||
joint distribution of eta_x, eta_y and photon energy (**Note:** for the joint distribution first dimension is eta_x, second: eta_y, third: energy bins.)
|
||||
)",
|
||||
py::arg("etacube"))
|
||||
.def("get_ietax",
|
||||
[](Interpolator &self) {
|
||||
auto *ptr = new NDArray<double, 3>{};
|
||||
*ptr = self.get_ietax();
|
||||
return return_image_data(ptr);
|
||||
})
|
||||
}, R"(conditional CDF of etax conditioned on etay, marginal CDF of etax (if rosenblatt transform applied))")
|
||||
.def("get_ietay", [](Interpolator &self) {
|
||||
auto *ptr = new NDArray<double, 3>{};
|
||||
*ptr = self.get_ietay();
|
||||
return return_image_data(ptr);
|
||||
});
|
||||
}, R"(conditional CDF of etay conditioned on etax)");
|
||||
|
||||
register_interpolate<int, 3, 3, uint16_t>(interpolator);
|
||||
register_interpolate<float, 3, 3, uint16_t>(interpolator);
|
||||
register_interpolate<double, 3, 3, uint16_t>(interpolator);
|
||||
register_interpolate<int, 2, 2, uint16_t>(interpolator);
|
||||
register_interpolate<float, 2, 2, uint16_t>(interpolator);
|
||||
register_interpolate<double, 2, 2, uint16_t>(interpolator);
|
||||
REGISTER_INTERPOLATOR_ETA3(int, 3, 3, uint16_t);
|
||||
REGISTER_INTERPOLATOR_ETA3(float, 3, 3, uint16_t);
|
||||
REGISTER_INTERPOLATOR_ETA3(double, 3, 3, uint16_t);
|
||||
|
||||
REGISTER_INTERPOLATOR_ETA2(int, 3, 3, uint16_t);
|
||||
REGISTER_INTERPOLATOR_ETA2(float, 3, 3, uint16_t);
|
||||
REGISTER_INTERPOLATOR_ETA2(double, 3, 3, uint16_t);
|
||||
REGISTER_INTERPOLATOR_ETA2(int, 2, 2, uint16_t);
|
||||
REGISTER_INTERPOLATOR_ETA2(float, 2, 2, uint16_t);
|
||||
REGISTER_INTERPOLATOR_ETA2(double, 2, 2, uint16_t);
|
||||
|
||||
// TODO! Evaluate without converting to double
|
||||
m.def(
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "bind_ClusterFinder.hpp"
|
||||
#include "bind_ClusterFinderMT.hpp"
|
||||
#include "bind_ClusterVector.hpp"
|
||||
#include "bind_Eta.hpp"
|
||||
#include "bind_calibration.hpp"
|
||||
|
||||
// TODO! migrate the other names
|
||||
@@ -42,14 +43,16 @@ double, 'f' for float)
|
||||
#define DEFINE_CLUSTER_BINDINGS(T, N, M, U, TYPE_CODE) \
|
||||
define_ClusterFile<T, N, M, U>(m, "Cluster" #N "x" #M #TYPE_CODE); \
|
||||
define_ClusterVector<T, N, M, U>(m, "Cluster" #N "x" #M #TYPE_CODE); \
|
||||
define_Cluster<T, N, M, U>(m, #N "x" #M #TYPE_CODE); \
|
||||
register_calculate_2x2eta<T, N, M, U>(m); \
|
||||
define_2x2_reduction<T, N, M, U>(m); \
|
||||
reduce_to_2x2<T, N, M, U>(m);
|
||||
|
||||
#define DEFINE_BINDINGS_CLUSTERFINDER(T, N, M, U, TYPE_CODE) \
|
||||
define_ClusterFinder<T, N, M, U>(m, "Cluster" #N "x" #M #TYPE_CODE); \
|
||||
define_ClusterFinderMT<T, N, M, U>(m, "Cluster" #N "x" #M #TYPE_CODE); \
|
||||
define_ClusterFileSink<T, N, M, U>(m, "Cluster" #N "x" #M #TYPE_CODE); \
|
||||
define_ClusterCollector<T, N, M, U>(m, "Cluster" #N "x" #M #TYPE_CODE); \
|
||||
define_Cluster<T, N, M, U>(m, #N "x" #M #TYPE_CODE); \
|
||||
register_calculate_eta<T, N, M, U>(m); \
|
||||
define_2x2_reduction<T, N, M, U>(m); \
|
||||
reduce_to_2x2<T, N, M, U>(m);
|
||||
define_ClusterCollector<T, N, M, U>(m, "Cluster" #N "x" #M #TYPE_CODE);
|
||||
|
||||
PYBIND11_MODULE(_aare, m) {
|
||||
define_file_io_bindings(m);
|
||||
@@ -87,7 +90,23 @@ PYBIND11_MODULE(_aare, m) {
|
||||
DEFINE_CLUSTER_BINDINGS(double, 9, 9, uint16_t, d);
|
||||
DEFINE_CLUSTER_BINDINGS(float, 9, 9, uint16_t, f);
|
||||
|
||||
// DEFINE_CLUSTER_BINDINGS(double, 2, 1, uint16_t, d);
|
||||
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(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<int, 3, 3, uint16_t>(m);
|
||||
define_3x3_reduction<double, 3, 3, uint16_t>(m);
|
||||
@@ -115,10 +134,30 @@ PYBIND11_MODULE(_aare, m) {
|
||||
reduce_to_3x3<double, 9, 9, uint16_t>(m);
|
||||
reduce_to_3x3<float, 9, 9, uint16_t>(m);
|
||||
|
||||
register_calculate_3x3eta<int, 3, 3, uint16_t>(m);
|
||||
register_calculate_3x3eta<double, 3, 3, uint16_t>(m);
|
||||
register_calculate_3x3eta<float, 3, 3, uint16_t>(m);
|
||||
register_calculate_3x3eta<int16_t, 3, 3, uint16_t>(m);
|
||||
|
||||
using Sum_index_pair_d = Sum_index_pair<double, corner>;
|
||||
PYBIND11_NUMPY_DTYPE(Sum_index_pair_d, sum, index);
|
||||
using Sum_index_pair_f = Sum_index_pair<float, corner>;
|
||||
PYBIND11_NUMPY_DTYPE(Sum_index_pair_f, sum, index);
|
||||
using Sum_index_pair_i = Sum_index_pair<int, corner>;
|
||||
PYBIND11_NUMPY_DTYPE(Sum_index_pair_i, sum, index);
|
||||
|
||||
using eta_d = Eta2<double>;
|
||||
PYBIND11_NUMPY_DTYPE(eta_d, x, y, c, sum);
|
||||
using eta_i = Eta2<int>;
|
||||
PYBIND11_NUMPY_DTYPE(eta_i, x, y, c, sum);
|
||||
using eta_f = Eta2<float>;
|
||||
PYBIND11_NUMPY_DTYPE(eta_f, x, y, c, sum);
|
||||
using eta_i16 = Eta2<int16_t>;
|
||||
PYBIND11_NUMPY_DTYPE(eta_i16, x, y, c, sum);
|
||||
|
||||
define_corner_enum(m);
|
||||
define_eta<float>(m, "f");
|
||||
define_eta<double>(m, "d");
|
||||
define_eta<int>(m, "i");
|
||||
define_eta<int16_t>(m, "i16");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user