mirror of
https://github.com/slsdetectorgroup/aare.git
synced 2025-06-04 03:50:41 +02:00
WIP
This commit is contained in:
parent
a4fb217e3f
commit
abb1d20ca3
@ -40,6 +40,7 @@ class File {
|
||||
size_t rows() const;
|
||||
size_t cols() const;
|
||||
size_t bitdepth() const;
|
||||
size_t bytes_per_pixel() const;
|
||||
void set_total_frames(size_t total_frames);
|
||||
DetectorType detector_type() const;
|
||||
xy geometry() const;
|
||||
|
@ -10,8 +10,25 @@ else()
|
||||
endif()
|
||||
|
||||
|
||||
pybind11_add_module(_aare src/module.cpp)
|
||||
pybind11_add_module(
|
||||
_aare
|
||||
src/module.cpp
|
||||
)
|
||||
set_target_properties(_aare PROPERTIES
|
||||
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
)
|
||||
target_link_libraries(_aare PRIVATE aare_core aare_compiler_flags)
|
||||
|
||||
set( PYTHON_FILES
|
||||
aare/__init__.py
|
||||
)
|
||||
|
||||
foreach(FILE ${PYTHON_FILES})
|
||||
configure_file( ${FILE}
|
||||
${CMAKE_BINARY_DIR}/${FILE} )
|
||||
endforeach(FILE ${PYTHON_FILES})
|
||||
|
||||
|
||||
configure_file( examples/play.py
|
||||
${CMAKE_BINARY_DIR}/play.py
|
||||
)
|
3
python/aare/__init__.py
Normal file
3
python/aare/__init__.py
Normal file
@ -0,0 +1,3 @@
|
||||
|
||||
|
||||
from _aare import File
|
14
python/examples/play.py
Normal file
14
python/examples/play.py
Normal file
@ -0,0 +1,14 @@
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
plt.ion()
|
||||
|
||||
import aare
|
||||
from pathlib import Path
|
||||
|
||||
p = Path('/Users/erik/data/aare_test_data/jungfrau/jungfrau_single_master_0.json')
|
||||
|
||||
f = aare.File(p)
|
||||
frame = f.read_frame()
|
||||
|
||||
fig, ax = plt.subplots()
|
||||
im = ax.imshow(frame, cmap='viridis')
|
126
python/src/file.hpp
Normal file
126
python/src/file.hpp
Normal file
@ -0,0 +1,126 @@
|
||||
#include "aare/Frame.hpp"
|
||||
#include "aare/File.hpp"
|
||||
#include "aare/defs.hpp"
|
||||
// #include "aare/fClusterFileV2.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <filesystem>
|
||||
#include <pybind11/numpy.h>
|
||||
#include <pybind11/iostream.h>
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/stl/filesystem.h>
|
||||
#include <string>
|
||||
|
||||
namespace py = pybind11;
|
||||
using namespace::aare;
|
||||
|
||||
void define_file_io_bindings(py::module &m) {
|
||||
py::class_<xy>(m, "xy")
|
||||
.def(py::init<>())
|
||||
.def(py::init<uint32_t, uint32_t>())
|
||||
.def_readwrite("row", &xy::row)
|
||||
.def_readwrite("col", &xy::col)
|
||||
.def("__eq__", &xy::operator==)
|
||||
.def("__ne__", &xy::operator!=)
|
||||
.def("__repr__",
|
||||
[](const xy &a) { return "<xy: row=" + std::to_string(a.row) + ", col=" + std::to_string(a.col) + ">"; });
|
||||
|
||||
|
||||
py::class_<File>(m, "File")
|
||||
.def(py::init([](const std::filesystem::path &fname) { return File(fname, "r", {}); }))
|
||||
.def(
|
||||
py::init([](const std::filesystem::path &fname, const std::string &mode) { return File(fname, mode, {}); }))
|
||||
.def(py::init<const std::filesystem::path &, const std::string &, const FileConfig &>())
|
||||
// .def("read", py::overload_cast<>(&File::read))
|
||||
// .def("read", py::overload_cast<size_t>(&File::read))
|
||||
.def("iread", py::overload_cast<size_t>(&File::iread),py::call_guard<py::gil_scoped_release>())
|
||||
.def("frame_number", &File::frame_number)
|
||||
.def_property_readonly("bytes_per_frame", &File::bytes_per_frame)
|
||||
.def_property_readonly("pixels_per_frame", &File::pixels_per_frame)
|
||||
.def("seek", &File::seek)
|
||||
.def("tell", &File::tell)
|
||||
.def_property_readonly("total_frames", &File::total_frames)
|
||||
.def_property_readonly("rows", &File::rows)
|
||||
.def_property_readonly("cols", &File::cols)
|
||||
.def_property_readonly("bitdepth", &File::bitdepth)
|
||||
.def_property_readonly("detector_type", &File::detector_type)
|
||||
.def_property_readonly("geometry", &File::geometry,
|
||||
py::call_guard<py::scoped_ostream_redirect, py::scoped_estream_redirect>())
|
||||
// .def("set_total_frames", &File::set_total_frames)
|
||||
.def("read_frame", [](File &self) {
|
||||
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;
|
||||
});
|
||||
|
||||
py::class_<FileConfig>(m, "FileConfig")
|
||||
.def(py::init<>())
|
||||
.def_readwrite("rows", &FileConfig::rows)
|
||||
.def_readwrite("cols", &FileConfig::cols)
|
||||
.def_readwrite("version", &FileConfig::version)
|
||||
.def_readwrite("geometry", &FileConfig::geometry)
|
||||
.def_readwrite("detector_type", &FileConfig::detector_type)
|
||||
.def_readwrite("max_frames_per_file", &FileConfig::max_frames_per_file)
|
||||
.def_readwrite("total_frames", &FileConfig::total_frames)
|
||||
.def_readwrite("dtype", &FileConfig::dtype)
|
||||
.def("__eq__", &FileConfig::operator==)
|
||||
.def("__ne__", &FileConfig::operator!=)
|
||||
.def("__repr__", [](const FileConfig &a) { return "<FileConfig: " + a.to_string() + ">"; });
|
||||
|
||||
// py::class_<ClusterHeader>(m, "ClusterHeader")
|
||||
// .def(py::init<>())
|
||||
// .def_readwrite("frame_number", &ClusterHeader::frame_number)
|
||||
// .def_readwrite("n_clusters", &ClusterHeader::n_clusters)
|
||||
// .def("__repr__", [](const ClusterHeader &a) { return "<ClusterHeader: " + a.to_string() + ">"; });
|
||||
|
||||
// py::class_<ClusterV2_>(m, "ClusterV2_")
|
||||
// .def(py::init<>())
|
||||
// .def_readwrite("x", &ClusterV2_::x)
|
||||
// .def_readwrite("y", &ClusterV2_::y)
|
||||
// .def_readwrite("data", &ClusterV2_::data)
|
||||
// .def("__repr__", [](const ClusterV2_ &a) { return "<ClusterV2_: " + a.to_string(false) + ">"; });
|
||||
|
||||
// py::class_<ClusterV2>(m, "ClusterV2")
|
||||
// .def(py::init<>())
|
||||
// .def_readwrite("cluster", &ClusterV2::cluster)
|
||||
// .def_readwrite("frame_number", &ClusterV2::frame_number)
|
||||
// .def("__repr__", [](const ClusterV2 &a) { return "<ClusterV2: " + a.to_string() + ">"; });
|
||||
|
||||
// py::class_<ClusterFileV2>(m, "ClusterFileV2")
|
||||
// .def(py::init<const std::filesystem::path &, const std::string &>())
|
||||
// .def("read", py::overload_cast<>(&ClusterFileV2::read))
|
||||
// .def("read", py::overload_cast<int>(&ClusterFileV2::read))
|
||||
// .def("frame_number", &ClusterFileV2::frame_number)
|
||||
// .def("write", py::overload_cast<std::vector<ClusterV2> const &>(&ClusterFileV2::write))
|
||||
|
||||
// .def("close", &ClusterFileV2::close);
|
||||
|
||||
// m.def("to_clustV2", [](std::vector<Cluster> &clusters, const int frame_number) {
|
||||
// std::vector<ClusterV2> clusters_;
|
||||
// for (auto &c : clusters) {
|
||||
// ClusterV2 cluster;
|
||||
// cluster.cluster.x = c.x;
|
||||
// cluster.cluster.y = c.y;
|
||||
// int i=0;
|
||||
// for(auto &d : cluster.cluster.data) {
|
||||
// d=c.get<double>(i++);
|
||||
// }
|
||||
// cluster.frame_number = frame_number;
|
||||
// clusters_.push_back(cluster);
|
||||
// }
|
||||
// return clusters_;
|
||||
// });
|
||||
}
|
@ -1,9 +1,14 @@
|
||||
|
||||
|
||||
#include "file.hpp"
|
||||
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
|
||||
namespace py = pybind11;
|
||||
|
||||
PYBIND11_MODULE(_aare, m) {
|
||||
|
||||
|
||||
|
||||
define_file_io_bindings(m);
|
||||
}
|
115
python/src/np_helper.hpp
Normal file
115
python/src/np_helper.hpp
Normal file
@ -0,0 +1,115 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <pybind11/numpy.h>
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
|
||||
#include "aare/Frame.hpp"
|
||||
#include "aare/NDArray.hpp"
|
||||
|
||||
namespace py = pybind11;
|
||||
|
||||
// Pass image data back to python as a numpy array
|
||||
// template <typename T, ssize_t Ndim>
|
||||
// py::array return_image_data(pl::ImageData<T, Ndim> *image) {
|
||||
|
||||
// py::capsule free_when_done(image, [](void *f) {
|
||||
// pl::ImageData<T, Ndim> *foo =
|
||||
// reinterpret_cast<pl::ImageData<T, Ndim> *>(f);
|
||||
// delete foo;
|
||||
// });
|
||||
|
||||
// return py::array_t<T>(
|
||||
// image->shape(), // shape
|
||||
// image->byte_strides(), // C-style contiguous strides for double
|
||||
// image->data(), // the data pointer
|
||||
// free_when_done); // numpy array references this parent
|
||||
// }
|
||||
|
||||
// template <typename T> py::array return_vector(std::vector<T> *vec) {
|
||||
// py::capsule free_when_done(vec, [](void *f) {
|
||||
// std::vector<T> *foo = reinterpret_cast<std::vector<T> *>(f);
|
||||
// delete foo;
|
||||
// });
|
||||
// return py::array_t<T>({vec->size()}, // shape
|
||||
// {sizeof(T)}, // C-style contiguous strides for double
|
||||
// vec->data(), // the data pointer
|
||||
// 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 pl::Shape<3>{arr.shape(0), arr.shape(1), arr.shape(2)};
|
||||
}
|
||||
|
||||
template <class T, int Flags> auto make_span_3d(py::array_t<T, Flags> arr) {
|
||||
return pl::DataSpan<T, 3>(arr.mutable_data(), get_shape_3d<T, Flags>(arr));
|
||||
}
|
||||
|
||||
template <class T, int Flags> auto get_shape_2d(py::array_t<T, Flags> arr) {
|
||||
return pl::Shape<2>{arr.shape(0), arr.shape(1)};
|
||||
}
|
||||
|
||||
template <class T, int Flags> auto make_span_2d(py::array_t<T, Flags> arr) {
|
||||
return pl::DataSpan<T, 2>(arr.mutable_data(), get_shape_2d<T, Flags>(arr));
|
||||
}
|
@ -51,6 +51,7 @@ size_t File::tell() const { return file_impl->tell(); }
|
||||
size_t File::rows() const { return file_impl->rows(); }
|
||||
size_t File::cols() const { return file_impl->cols(); }
|
||||
size_t File::bitdepth() const { return file_impl->bitdepth(); }
|
||||
size_t File::bytes_per_pixel() const { return file_impl->bitdepth()/8; }
|
||||
void File::set_total_frames(size_t total_frames) { return file_impl->set_total_frames(total_frames); }
|
||||
File::~File() { delete file_impl; }
|
||||
DetectorType File::detector_type() const { return file_impl->detector_type(); }
|
||||
|
Loading…
x
Reference in New Issue
Block a user