mirror of
https://github.com/slsdetectorgroup/aare.git
synced 2025-06-12 07:17:13 +02:00
Added fitting, fixed roi etc (#129)
Co-authored-by: Patrick <patrick.sieberer@psi.ch> Co-authored-by: JulianHeymes <julian.heymes@psi.ch>
This commit is contained in:
@ -1,4 +1,7 @@
|
||||
#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"
|
||||
@ -8,9 +11,10 @@
|
||||
#include <filesystem>
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/stl_bind.h>
|
||||
|
||||
namespace py = pybind11;
|
||||
using pd_type = float;
|
||||
using pd_type = double;
|
||||
|
||||
template <typename T>
|
||||
void define_cluster_vector(py::module &m, const std::string &typestr) {
|
||||
@ -18,93 +22,166 @@ void define_cluster_vector(py::module &m, const std::string &typestr) {
|
||||
py::class_<ClusterVector<T>>(m, class_name.c_str(), py::buffer_protocol())
|
||||
.def(py::init<int, int>())
|
||||
.def_property_readonly("size", &ClusterVector<T>::size)
|
||||
.def("element_offset",
|
||||
py::overload_cast<>(&ClusterVector<T>::element_offset, py::const_))
|
||||
.def("item_size", &ClusterVector<T>::item_size)
|
||||
.def_property_readonly("fmt",
|
||||
[typestr](ClusterVector<T> &self) {
|
||||
return fmt::format(
|
||||
self.fmt_base(), self.cluster_size_x(),
|
||||
self.cluster_size_y(), typestr);
|
||||
[typestr](ClusterVector<T> &self) {
|
||||
return fmt::format(
|
||||
self.fmt_base(), self.cluster_size_x(),
|
||||
self.cluster_size_y(), typestr);
|
||||
})
|
||||
.def("sum",
|
||||
[](ClusterVector<T> &self) {
|
||||
auto *vec = new std::vector<T>(self.sum());
|
||||
return return_vector(vec);
|
||||
})
|
||||
.def("sum", [](ClusterVector<T> &self) {
|
||||
auto *vec = new std::vector<T>(self.sum());
|
||||
.def("sum_2x2", [](ClusterVector<T> &self) {
|
||||
auto *vec = new std::vector<T>(self.sum_2x2());
|
||||
return return_vector(vec);
|
||||
})
|
||||
.def_property_readonly("capacity", &ClusterVector<T>::capacity)
|
||||
.def_property("frame_number", &ClusterVector<T>::frame_number,
|
||||
&ClusterVector<T>::set_frame_number)
|
||||
.def_buffer([typestr](ClusterVector<T> &self) -> py::buffer_info {
|
||||
return py::buffer_info(
|
||||
self.data(), /* Pointer to buffer */
|
||||
self.element_offset(), /* Size of one scalar */
|
||||
self.data(), /* Pointer to buffer */
|
||||
self.item_size(), /* Size of one scalar */
|
||||
fmt::format(self.fmt_base(), self.cluster_size_x(),
|
||||
self.cluster_size_y(),
|
||||
typestr), /* Format descriptor */
|
||||
1, /* Number of dimensions */
|
||||
{self.size()}, /* Buffer dimensions */
|
||||
{self.element_offset()} /* Strides (in bytes) for each index */
|
||||
{self.size()}, /* Buffer dimensions */
|
||||
{self.item_size()} /* Strides (in bytes) for each index */
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
void define_cluster_finder_mt_bindings(py::module &m) {
|
||||
py::class_<ClusterFinderMT<uint16_t, pd_type>>(m, "ClusterFinderMT")
|
||||
.def(py::init<Shape<2>, Shape<2>, pd_type, size_t, size_t>(),
|
||||
py::arg("image_size"), py::arg("cluster_size"),
|
||||
py::arg("n_sigma") = 5.0, py::arg("capacity") = 2048,
|
||||
py::arg("n_threads") = 3)
|
||||
.def("push_pedestal_frame",
|
||||
[](ClusterFinderMT<uint16_t, pd_type> &self,
|
||||
py::array_t<uint16_t> frame) {
|
||||
auto view = make_view_2d(frame);
|
||||
self.push_pedestal_frame(view);
|
||||
})
|
||||
.def(
|
||||
"find_clusters",
|
||||
[](ClusterFinderMT<uint16_t, pd_type> &self,
|
||||
py::array_t<uint16_t> frame, uint64_t frame_number) {
|
||||
auto view = make_view_2d(frame);
|
||||
self.find_clusters(view, frame_number);
|
||||
return;
|
||||
},
|
||||
py::arg(), py::arg("frame_number") = 0)
|
||||
.def("clear_pedestal", &ClusterFinderMT<uint16_t, pd_type>::clear_pedestal)
|
||||
.def("sync", &ClusterFinderMT<uint16_t, pd_type>::sync)
|
||||
.def("stop", &ClusterFinderMT<uint16_t, pd_type>::stop)
|
||||
.def("start", &ClusterFinderMT<uint16_t, pd_type>::start)
|
||||
.def("pedestal",
|
||||
[](ClusterFinderMT<uint16_t, pd_type> &self, size_t thread_index) {
|
||||
auto pd = new NDArray<pd_type, 2>{};
|
||||
*pd = self.pedestal(thread_index);
|
||||
return return_image_data(pd);
|
||||
},py::arg("thread_index") = 0)
|
||||
.def("noise",
|
||||
[](ClusterFinderMT<uint16_t, pd_type> &self, size_t thread_index) {
|
||||
auto arr = new NDArray<pd_type, 2>{};
|
||||
*arr = self.noise(thread_index);
|
||||
return return_image_data(arr);
|
||||
},py::arg("thread_index") = 0);
|
||||
}
|
||||
|
||||
void define_cluster_collector_bindings(py::module &m) {
|
||||
py::class_<ClusterCollector>(m, "ClusterCollector")
|
||||
.def(py::init<ClusterFinderMT<uint16_t, double, int32_t> *>())
|
||||
.def("stop", &ClusterCollector::stop)
|
||||
.def(
|
||||
"steal_clusters",
|
||||
[](ClusterCollector &self) {
|
||||
auto v =
|
||||
new std::vector<ClusterVector<int>>(self.steal_clusters());
|
||||
return v;
|
||||
},
|
||||
py::return_value_policy::take_ownership);
|
||||
}
|
||||
|
||||
void define_cluster_file_sink_bindings(py::module &m) {
|
||||
py::class_<ClusterFileSink>(m, "ClusterFileSink")
|
||||
.def(py::init<ClusterFinderMT<uint16_t, double, int32_t> *,
|
||||
const std::filesystem::path &>())
|
||||
.def("stop", &ClusterFileSink::stop);
|
||||
}
|
||||
|
||||
void define_cluster_finder_bindings(py::module &m) {
|
||||
py::class_<ClusterFinder<uint16_t, pd_type>>(m, "ClusterFinder")
|
||||
.def(py::init<Shape<2>, Shape<2>, pd_type, size_t>(), py::arg("image_size"),
|
||||
py::arg("cluster_size"), py::arg("n_sigma") = 5.0,
|
||||
py::arg("capacity") = 1'000'000)
|
||||
.def(py::init<Shape<2>, Shape<2>, pd_type, size_t>(),
|
||||
py::arg("image_size"), py::arg("cluster_size"),
|
||||
py::arg("n_sigma") = 5.0, py::arg("capacity") = 1'000'000)
|
||||
.def("push_pedestal_frame",
|
||||
[](ClusterFinder<uint16_t, pd_type> &self,
|
||||
py::array_t<uint16_t> frame) {
|
||||
auto view = make_view_2d(frame);
|
||||
self.push_pedestal_frame(view);
|
||||
})
|
||||
.def("pedestal",
|
||||
[](ClusterFinder<uint16_t, pd_type> &self) {
|
||||
auto pd = new NDArray<pd_type, 2>{};
|
||||
*pd = self.pedestal();
|
||||
return return_image_data(pd);
|
||||
})
|
||||
.def("noise",
|
||||
[](ClusterFinder<uint16_t, pd_type> &self) {
|
||||
auto arr = new NDArray<pd_type, 2>{};
|
||||
*arr = self.noise();
|
||||
return return_image_data(arr);
|
||||
})
|
||||
.def("steal_clusters",
|
||||
[](ClusterFinder<uint16_t, pd_type> &self, bool realloc_same_capacity) {
|
||||
auto v = new ClusterVector<int>(self.steal_clusters(realloc_same_capacity));
|
||||
return v;
|
||||
}, py::arg("realloc_same_capacity") = false)
|
||||
.def("find_clusters",
|
||||
[](ClusterFinder<uint16_t, pd_type> &self,
|
||||
py::array_t<uint16_t> frame) {
|
||||
auto view = make_view_2d(frame);
|
||||
self.find_clusters(view);
|
||||
return;
|
||||
});
|
||||
.def("clear_pedestal", &ClusterFinder<uint16_t, pd_type>::clear_pedestal)
|
||||
.def_property_readonly("pedestal",
|
||||
[](ClusterFinder<uint16_t, pd_type> &self) {
|
||||
auto pd = new NDArray<pd_type, 2>{};
|
||||
*pd = self.pedestal();
|
||||
return return_image_data(pd);
|
||||
})
|
||||
.def_property_readonly("noise",
|
||||
[](ClusterFinder<uint16_t, pd_type> &self) {
|
||||
auto arr = new NDArray<pd_type, 2>{};
|
||||
*arr = self.noise();
|
||||
return return_image_data(arr);
|
||||
})
|
||||
.def(
|
||||
"steal_clusters",
|
||||
[](ClusterFinder<uint16_t, pd_type> &self,
|
||||
bool realloc_same_capacity) {
|
||||
auto v = new ClusterVector<int>(
|
||||
self.steal_clusters(realloc_same_capacity));
|
||||
return v;
|
||||
},
|
||||
py::arg("realloc_same_capacity") = false)
|
||||
.def(
|
||||
"find_clusters",
|
||||
[](ClusterFinder<uint16_t, pd_type> &self,
|
||||
py::array_t<uint16_t> frame, uint64_t frame_number) {
|
||||
auto view = make_view_2d(frame);
|
||||
self.find_clusters(view, frame_number);
|
||||
return;
|
||||
},
|
||||
py::arg(), py::arg("frame_number") = 0);
|
||||
|
||||
m.def("hitmap", [](std::array<size_t, 2> image_size, ClusterVector<int32_t>& cv){
|
||||
|
||||
py::array_t<int32_t> hitmap(image_size);
|
||||
auto r = hitmap.mutable_unchecked<2>();
|
||||
m.def("hitmap",
|
||||
[](std::array<size_t, 2> image_size, ClusterVector<int32_t> &cv) {
|
||||
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;
|
||||
// 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;
|
||||
|
||||
size_t stride = cv.element_offset();
|
||||
auto ptr = cv.data();
|
||||
for(size_t i=0; i<cv.size(); i++){
|
||||
auto x = *reinterpret_cast<int16_t*>(ptr);
|
||||
auto y = *reinterpret_cast<int16_t*>(ptr+sizeof(int16_t));
|
||||
r(y, x) += 1;
|
||||
ptr += stride;
|
||||
}
|
||||
return hitmap;
|
||||
});
|
||||
size_t stride = cv.item_size();
|
||||
auto ptr = cv.data();
|
||||
for (size_t i = 0; i < cv.size(); i++) {
|
||||
auto x = *reinterpret_cast<int16_t *>(ptr);
|
||||
auto y = *reinterpret_cast<int16_t *>(ptr + sizeof(int16_t));
|
||||
r(y, x) += 1;
|
||||
ptr += stride;
|
||||
}
|
||||
return hitmap;
|
||||
});
|
||||
define_cluster_vector<int>(m, "i");
|
||||
define_cluster_vector<double>(m, "d");
|
||||
define_cluster_vector<float>(m, "f");
|
||||
|
||||
|
||||
py::class_<DynamicCluster>(m, "DynamicCluster", py::buffer_protocol())
|
||||
.def(py::init<int, int, Dtype>())
|
||||
.def("size", &DynamicCluster::size)
|
||||
|
@ -28,27 +28,24 @@ void define_cluster_file_io_bindings(py::module &m) {
|
||||
py::arg(), py::arg("chunk_size") = 1000, py::arg("mode") = "r")
|
||||
.def("read_clusters",
|
||||
[](ClusterFile &self, size_t n_clusters) {
|
||||
auto *vec =
|
||||
new std::vector<Cluster3x3>(self.read_clusters(n_clusters));
|
||||
return return_vector(vec);
|
||||
})
|
||||
auto v = new ClusterVector<int32_t>(self.read_clusters(n_clusters));
|
||||
return v;
|
||||
},py::return_value_policy::take_ownership)
|
||||
.def("read_frame",
|
||||
[](ClusterFile &self) {
|
||||
int32_t frame_number;
|
||||
auto *vec =
|
||||
new std::vector<Cluster3x3>(self.read_frame(frame_number));
|
||||
return py::make_tuple(frame_number, return_vector(vec));
|
||||
auto v = new ClusterVector<int32_t>(self.read_frame());
|
||||
return v;
|
||||
})
|
||||
.def("write_frame", &ClusterFile::write_frame)
|
||||
.def("read_cluster_with_cut",
|
||||
[](ClusterFile &self, size_t n_clusters,
|
||||
py::array_t<double> noise_map, int nx, int ny) {
|
||||
auto view = make_view_2d(noise_map);
|
||||
auto *vec =
|
||||
new std::vector<Cluster3x3>(self.read_cluster_with_cut(
|
||||
n_clusters, view.data(), nx, ny));
|
||||
return return_vector(vec);
|
||||
})
|
||||
// .def("read_cluster_with_cut",
|
||||
// [](ClusterFile &self, size_t n_clusters,
|
||||
// py::array_t<double> noise_map, int nx, int ny) {
|
||||
// auto view = make_view_2d(noise_map);
|
||||
// auto *vec =
|
||||
// new std::vector<Cluster3x3>(self.read_cluster_with_cut(
|
||||
// n_clusters, view.data(), nx, ny));
|
||||
// return return_vector(vec);
|
||||
// })
|
||||
.def("__enter__", [](ClusterFile &self) { return &self; })
|
||||
.def("__exit__",
|
||||
[](ClusterFile &self,
|
||||
@ -59,12 +56,11 @@ void define_cluster_file_io_bindings(py::module &m) {
|
||||
})
|
||||
.def("__iter__", [](ClusterFile &self) { return &self; })
|
||||
.def("__next__", [](ClusterFile &self) {
|
||||
auto vec =
|
||||
new std::vector<Cluster3x3>(self.read_clusters(self.chunk_size()));
|
||||
if (vec->size() == 0) {
|
||||
auto v = new ClusterVector<int32_t>(self.read_clusters(self.chunk_size()));
|
||||
if (v->size() == 0) {
|
||||
throw py::stop_iteration();
|
||||
}
|
||||
return return_vector(vec);
|
||||
return v;
|
||||
});
|
||||
|
||||
m.def("calculate_eta2", []( aare::ClusterVector<int32_t> &clusters) {
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "aare/RawSubFile.hpp"
|
||||
|
||||
#include "aare/defs.hpp"
|
||||
#include "aare/decode.hpp"
|
||||
// #include "aare/fClusterFileV2.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
@ -23,6 +24,47 @@ using namespace ::aare;
|
||||
|
||||
void define_ctb_raw_file_io_bindings(py::module &m) {
|
||||
|
||||
m.def("adc_sar_05_decode64to16", [](py::array_t<uint8_t> input) {
|
||||
|
||||
|
||||
if(input.ndim() != 2){
|
||||
throw std::runtime_error("Only 2D arrays are supported at this moment");
|
||||
}
|
||||
|
||||
//Create a 2D output array with the same shape as the input
|
||||
std::vector<ssize_t> shape{input.shape(0), input.shape(1)/8};
|
||||
py::array_t<uint16_t> output(shape);
|
||||
|
||||
//Create a view of the input and output arrays
|
||||
NDView<uint64_t, 2> input_view(reinterpret_cast<uint64_t*>(input.mutable_data()), {output.shape(0), output.shape(1)});
|
||||
NDView<uint16_t, 2> output_view(output.mutable_data(), {output.shape(0), output.shape(1)});
|
||||
|
||||
adc_sar_05_decode64to16(input_view, output_view);
|
||||
|
||||
return output;
|
||||
});
|
||||
|
||||
|
||||
m.def("adc_sar_04_decode64to16", [](py::array_t<uint8_t> input) {
|
||||
|
||||
|
||||
if(input.ndim() != 2){
|
||||
throw std::runtime_error("Only 2D arrays are supported at this moment");
|
||||
}
|
||||
|
||||
//Create a 2D output array with the same shape as the input
|
||||
std::vector<ssize_t> shape{input.shape(0), input.shape(1)/8};
|
||||
py::array_t<uint16_t> output(shape);
|
||||
|
||||
//Create a view of the input and output arrays
|
||||
NDView<uint64_t, 2> input_view(reinterpret_cast<uint64_t*>(input.mutable_data()), {output.shape(0), output.shape(1)});
|
||||
NDView<uint16_t, 2> output_view(output.mutable_data(), {output.shape(0), output.shape(1)});
|
||||
|
||||
adc_sar_04_decode64to16(input_view, output_view);
|
||||
|
||||
return output;
|
||||
});
|
||||
|
||||
py::class_<CtbRawFile>(m, "CtbRawFile")
|
||||
.def(py::init<const std::filesystem::path &>())
|
||||
.def("read_frame",
|
||||
|
@ -20,6 +20,11 @@
|
||||
namespace py = pybind11;
|
||||
using namespace ::aare;
|
||||
|
||||
//Disable warnings for unused parameters, as we ignore some
|
||||
//in the __exit__ method
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||
|
||||
void define_file_io_bindings(py::module &m) {
|
||||
|
||||
|
||||
@ -124,8 +129,41 @@ void define_file_io_bindings(py::module &m) {
|
||||
self.read_into(reinterpret_cast<std::byte *>(image.mutable_data()),
|
||||
n_frames);
|
||||
return image;
|
||||
})
|
||||
.def("__enter__", [](File &self) { return &self; })
|
||||
.def("__exit__",
|
||||
[](File &self,
|
||||
const std::optional<pybind11::type> &exc_type,
|
||||
const std::optional<pybind11::object> &exc_value,
|
||||
const std::optional<pybind11::object> &traceback) {
|
||||
// self.close();
|
||||
})
|
||||
.def("__iter__", [](File &self) { return &self; })
|
||||
.def("__next__", [](File &self) {
|
||||
|
||||
try{
|
||||
const uint8_t item_size = self.bytes_per_pixel();
|
||||
py::array image;
|
||||
std::vector<ssize_t> shape;
|
||||
shape.reserve(2);
|
||||
shape.push_back(self.rows());
|
||||
shape.push_back(self.cols());
|
||||
if (item_size == 1) {
|
||||
image = py::array_t<uint8_t>(shape);
|
||||
} else if (item_size == 2) {
|
||||
image = py::array_t<uint16_t>(shape);
|
||||
} else if (item_size == 4) {
|
||||
image = py::array_t<uint32_t>(shape);
|
||||
}
|
||||
self.read_into(
|
||||
reinterpret_cast<std::byte *>(image.mutable_data()));
|
||||
return image;
|
||||
}catch(std::runtime_error &e){
|
||||
throw py::stop_iteration();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
py::class_<FileConfig>(m, "FileConfig")
|
||||
.def(py::init<>())
|
||||
.def_readwrite("rows", &FileConfig::rows)
|
||||
@ -205,7 +243,7 @@ void define_file_io_bindings(py::module &m) {
|
||||
return image;
|
||||
});
|
||||
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
// py::class_<ClusterHeader>(m, "ClusterHeader")
|
||||
// .def(py::init<>())
|
||||
// .def_readwrite("frame_number", &ClusterHeader::frame_number)
|
||||
|
223
python/src/fit.hpp
Normal file
223
python/src/fit.hpp
Normal file
@ -0,0 +1,223 @@
|
||||
#include <cstdint>
|
||||
#include <filesystem>
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/stl_bind.h>
|
||||
|
||||
#include "aare/Fit.hpp"
|
||||
|
||||
namespace py = pybind11;
|
||||
|
||||
void define_fit_bindings(py::module &m) {
|
||||
|
||||
// TODO! Evaluate without converting to double
|
||||
m.def(
|
||||
"gaus",
|
||||
[](py::array_t<double, py::array::c_style | py::array::forcecast> x,
|
||||
py::array_t<double, py::array::c_style | py::array::forcecast> par) {
|
||||
auto x_view = make_view_1d(x);
|
||||
auto par_view = make_view_1d(par);
|
||||
auto y = new NDArray<double, 1>{aare::func::gaus(x_view, par_view)};
|
||||
return return_image_data(y);
|
||||
},
|
||||
R"(
|
||||
Evaluate a 1D Gaussian function for all points in x using parameters par.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
x : array_like
|
||||
The points at which to evaluate the Gaussian function.
|
||||
par : array_like
|
||||
The parameters of the Gaussian function. The first element is the amplitude, the second element is the mean, and the third element is the standard deviation.
|
||||
)", py::arg("x"), py::arg("par"));
|
||||
|
||||
m.def(
|
||||
"pol1",
|
||||
[](py::array_t<double, py::array::c_style | py::array::forcecast> x,
|
||||
py::array_t<double, py::array::c_style | py::array::forcecast> par) {
|
||||
auto x_view = make_view_1d(x);
|
||||
auto par_view = make_view_1d(par);
|
||||
auto y = new NDArray<double, 1>{aare::func::pol1(x_view, par_view)};
|
||||
return return_image_data(y);
|
||||
},
|
||||
R"(
|
||||
Evaluate a 1D polynomial function for all points in x using parameters par. (p0+p1*x)
|
||||
|
||||
Parameters
|
||||
----------
|
||||
x : array_like
|
||||
The points at which to evaluate the polynomial function.
|
||||
par : array_like
|
||||
The parameters of the polynomial function. The first element is the intercept, and the second element is the slope.
|
||||
)", py::arg("x"), py::arg("par"));
|
||||
|
||||
m.def(
|
||||
"fit_gaus",
|
||||
[](py::array_t<double, py::array::c_style | py::array::forcecast> x,
|
||||
py::array_t<double, py::array::c_style | py::array::forcecast> y,
|
||||
int n_threads) {
|
||||
if (y.ndim() == 3) {
|
||||
auto par = new NDArray<double, 3>{};
|
||||
auto y_view = make_view_3d(y);
|
||||
auto x_view = make_view_1d(x);
|
||||
*par = aare::fit_gaus(x_view, y_view, n_threads);
|
||||
return return_image_data(par);
|
||||
} else if (y.ndim() == 1) {
|
||||
auto par = new NDArray<double, 1>{};
|
||||
auto y_view = make_view_1d(y);
|
||||
auto x_view = make_view_1d(x);
|
||||
*par = aare::fit_gaus(x_view, y_view);
|
||||
return return_image_data(par);
|
||||
} else {
|
||||
throw std::runtime_error("Data must be 1D or 3D");
|
||||
}
|
||||
},
|
||||
R"(
|
||||
Fit a 1D Gaussian to data.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
x : array_like
|
||||
The x values.
|
||||
y : array_like
|
||||
The y values.
|
||||
n_threads : int, optional
|
||||
The number of threads to use. Default is 4.
|
||||
)",
|
||||
py::arg("x"), py::arg("y"), py::arg("n_threads") = 4);
|
||||
|
||||
m.def(
|
||||
"fit_gaus",
|
||||
[](py::array_t<double, py::array::c_style | py::array::forcecast> x,
|
||||
py::array_t<double, py::array::c_style | py::array::forcecast> y,
|
||||
py::array_t<double, py::array::c_style | py::array::forcecast>
|
||||
y_err, int n_threads) {
|
||||
if (y.ndim() == 3) {
|
||||
// Allocate memory for the output
|
||||
// Need to have pointers to allow python to manage
|
||||
// the memory
|
||||
auto par = new NDArray<double, 3>({y.shape(0), y.shape(1), 3});
|
||||
auto par_err =
|
||||
new NDArray<double, 3>({y.shape(0), y.shape(1), 3});
|
||||
|
||||
auto y_view = make_view_3d(y);
|
||||
auto y_view_err = make_view_3d(y_err);
|
||||
auto x_view = make_view_1d(x);
|
||||
aare::fit_gaus(x_view, y_view, y_view_err, par->view(),
|
||||
par_err->view(), n_threads);
|
||||
// return return_image_data(par);
|
||||
return py::make_tuple(return_image_data(par),
|
||||
return_image_data(par_err));
|
||||
} else if (y.ndim() == 1) {
|
||||
// Allocate memory for the output
|
||||
// Need to have pointers to allow python to manage
|
||||
// the memory
|
||||
auto par = new NDArray<double, 1>({3});
|
||||
auto par_err = new NDArray<double, 1>({3});
|
||||
|
||||
// Decode the numpy arrays
|
||||
auto y_view = make_view_1d(y);
|
||||
auto y_view_err = make_view_1d(y_err);
|
||||
auto x_view = make_view_1d(x);
|
||||
|
||||
aare::fit_gaus(x_view, y_view, y_view_err, par->view(),
|
||||
par_err->view());
|
||||
return py::make_tuple(return_image_data(par),
|
||||
return_image_data(par_err));
|
||||
} else {
|
||||
throw std::runtime_error("Data must be 1D or 3D");
|
||||
}
|
||||
},
|
||||
R"(
|
||||
Fit a 1D Gaussian to data with error estimates.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
x : array_like
|
||||
The x values.
|
||||
y : array_like
|
||||
The y values.
|
||||
y_err : array_like
|
||||
The error in the y values.
|
||||
n_threads : int, optional
|
||||
The number of threads to use. Default is 4.
|
||||
)",
|
||||
py::arg("x"), py::arg("y"), py::arg("y_err"), py::arg("n_threads") = 4);
|
||||
|
||||
m.def(
|
||||
"fit_pol1",
|
||||
[](py::array_t<double, py::array::c_style | py::array::forcecast> x,
|
||||
py::array_t<double, py::array::c_style | py::array::forcecast> y,
|
||||
int n_threads) {
|
||||
if (y.ndim() == 3) {
|
||||
auto par = new NDArray<double, 3>{};
|
||||
|
||||
auto x_view = make_view_1d(x);
|
||||
auto y_view = make_view_3d(y);
|
||||
*par = aare::fit_pol1(x_view, y_view, n_threads);
|
||||
return return_image_data(par);
|
||||
} else if (y.ndim() == 1) {
|
||||
auto par = new NDArray<double, 1>{};
|
||||
auto x_view = make_view_1d(x);
|
||||
auto y_view = make_view_1d(y);
|
||||
*par = aare::fit_pol1(x_view, y_view);
|
||||
return return_image_data(par);
|
||||
} else {
|
||||
throw std::runtime_error("Data must be 1D or 3D");
|
||||
}
|
||||
},
|
||||
py::arg("x"), py::arg("y"), py::arg("n_threads") = 4);
|
||||
|
||||
m.def(
|
||||
"fit_pol1",
|
||||
[](py::array_t<double, py::array::c_style | py::array::forcecast> x,
|
||||
py::array_t<double, py::array::c_style | py::array::forcecast> y,
|
||||
py::array_t<double, py::array::c_style | py::array::forcecast>
|
||||
y_err, int n_threads) {
|
||||
if (y.ndim() == 3) {
|
||||
auto par =
|
||||
new NDArray<double, 3>({y.shape(0), y.shape(1), 2});
|
||||
auto par_err =
|
||||
new NDArray<double, 3>({y.shape(0), y.shape(1), 2});
|
||||
|
||||
auto y_view = make_view_3d(y);
|
||||
auto y_view_err = make_view_3d(y_err);
|
||||
auto x_view = make_view_1d(x);
|
||||
|
||||
aare::fit_pol1(x_view, y_view,y_view_err, par->view(),
|
||||
par_err->view(), n_threads);
|
||||
return py::make_tuple(return_image_data(par),
|
||||
return_image_data(par_err));
|
||||
|
||||
} else if (y.ndim() == 1) {
|
||||
auto par = new NDArray<double, 1>({2});
|
||||
auto par_err = new NDArray<double, 1>({2});
|
||||
|
||||
auto y_view = make_view_1d(y);
|
||||
auto y_view_err = make_view_1d(y_err);
|
||||
auto x_view = make_view_1d(x);
|
||||
|
||||
aare::fit_pol1(x_view, y_view, y_view_err, par->view(),
|
||||
par_err->view());
|
||||
return py::make_tuple(return_image_data(par),
|
||||
return_image_data(par_err));
|
||||
} else {
|
||||
throw std::runtime_error("Data must be 1D or 3D");
|
||||
}
|
||||
},
|
||||
R"(
|
||||
Fit a 1D polynomial to data with error estimates.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
x : array_like
|
||||
The x values.
|
||||
y : array_like
|
||||
The y values.
|
||||
y_err : array_like
|
||||
The error in the y values.
|
||||
n_threads : int, optional
|
||||
The number of threads to use. Default is 4.
|
||||
)",
|
||||
py::arg("x"), py::arg("y"), py::arg("y_err"), py::arg("n_threads") = 4);
|
||||
}
|
@ -8,6 +8,7 @@
|
||||
#include "pedestal.hpp"
|
||||
#include "cluster.hpp"
|
||||
#include "cluster_file.hpp"
|
||||
#include "fit.hpp"
|
||||
|
||||
//Pybind stuff
|
||||
#include <pybind11/pybind11.h>
|
||||
@ -25,5 +26,10 @@ PYBIND11_MODULE(_aare, m) {
|
||||
define_pedestal_bindings<double>(m, "Pedestal_d");
|
||||
define_pedestal_bindings<float>(m, "Pedestal_f");
|
||||
define_cluster_finder_bindings(m);
|
||||
define_cluster_finder_mt_bindings(m);
|
||||
define_cluster_file_io_bindings(m);
|
||||
define_cluster_collector_bindings(m);
|
||||
define_cluster_file_sink_bindings(m);
|
||||
define_fit_bindings(m);
|
||||
|
||||
}
|
@ -39,65 +39,6 @@ template <typename T> py::array return_vector(std::vector<T> *vec) {
|
||||
free_when_done); // numpy array references this parent
|
||||
}
|
||||
|
||||
// template <typename Reader> py::array do_read(Reader &r, size_t n_frames) {
|
||||
// py::array image;
|
||||
// if (n_frames == 0)
|
||||
// n_frames = r.total_frames();
|
||||
|
||||
// std::array<ssize_t, 3> shape{static_cast<ssize_t>(n_frames), r.rows(),
|
||||
// r.cols()};
|
||||
// const uint8_t item_size = r.bytes_per_pixel();
|
||||
// if (item_size == 1) {
|
||||
// image = py::array_t<uint8_t, py::array::c_style | py::array::forcecast>(
|
||||
// shape);
|
||||
// } else if (item_size == 2) {
|
||||
// image =
|
||||
// py::array_t<uint16_t, py::array::c_style | py::array::forcecast>(
|
||||
// shape);
|
||||
// } else if (item_size == 4) {
|
||||
// image =
|
||||
// py::array_t<uint32_t, py::array::c_style | py::array::forcecast>(
|
||||
// shape);
|
||||
// }
|
||||
// r.read_into(reinterpret_cast<std::byte *>(image.mutable_data()), n_frames);
|
||||
// return image;
|
||||
// }
|
||||
|
||||
// py::array return_frame(pl::Frame *ptr) {
|
||||
// py::capsule free_when_done(ptr, [](void *f) {
|
||||
// pl::Frame *foo = reinterpret_cast<pl::Frame *>(f);
|
||||
// delete foo;
|
||||
// });
|
||||
|
||||
// const uint8_t item_size = ptr->bytes_per_pixel();
|
||||
// std::vector<ssize_t> shape;
|
||||
// for (auto val : ptr->shape())
|
||||
// if (val > 1)
|
||||
// shape.push_back(val);
|
||||
|
||||
// std::vector<ssize_t> strides;
|
||||
// if (shape.size() == 1)
|
||||
// strides.push_back(item_size);
|
||||
// else if (shape.size() == 2) {
|
||||
// strides.push_back(item_size * shape[1]);
|
||||
// strides.push_back(item_size);
|
||||
// }
|
||||
|
||||
// if (item_size == 1)
|
||||
// return py::array_t<uint8_t>(
|
||||
// shape, strides,
|
||||
// reinterpret_cast<uint8_t *>(ptr->data()), free_when_done);
|
||||
// else if (item_size == 2)
|
||||
// return py::array_t<uint16_t>(shape, strides,
|
||||
// reinterpret_cast<uint16_t *>(ptr->data()),
|
||||
// free_when_done);
|
||||
// else if (item_size == 4)
|
||||
// return py::array_t<uint32_t>(shape, strides,
|
||||
// reinterpret_cast<uint32_t *>(ptr->data()),
|
||||
// free_when_done);
|
||||
// return {};
|
||||
// }
|
||||
|
||||
// todo rewrite generic
|
||||
template <class T, int Flags> auto get_shape_3d(py::array_t<T, Flags> arr) {
|
||||
return aare::Shape<3>{arr.shape(0), arr.shape(1), arr.shape(2)};
|
||||
@ -111,6 +52,13 @@ template <class T, int Flags> auto get_shape_2d(py::array_t<T, Flags> arr) {
|
||||
return aare::Shape<2>{arr.shape(0), arr.shape(1)};
|
||||
}
|
||||
|
||||
template <class T, int Flags> auto get_shape_1d(py::array_t<T, Flags> arr) {
|
||||
return aare::Shape<1>{arr.shape(0)};
|
||||
}
|
||||
|
||||
template <class T, int Flags> auto make_view_2d(py::array_t<T, Flags> arr) {
|
||||
return aare::NDView<T, 2>(arr.mutable_data(), get_shape_2d<T, Flags>(arr));
|
||||
}
|
||||
template <class T, int Flags> auto make_view_1d(py::array_t<T, Flags> arr) {
|
||||
return aare::NDView<T, 1>(arr.mutable_data(), get_shape_1d<T, Flags>(arr));
|
||||
}
|
Reference in New Issue
Block a user