diff --git a/.github/workflows/build_pkg.yml b/.github/workflows/build_pkg.yml
index c0cd9be..60baffa 100644
--- a/.github/workflows/build_pkg.yml
+++ b/.github/workflows/build_pkg.yml
@@ -13,7 +13,7 @@ jobs:
fail-fast: false
matrix:
platform: [ubuntu-latest, ] # macos-12, windows-2019]
- python-version: ["3.11", "3.12", "3.13",]
+ python-version: ["3.11", "3.12",]
runs-on: ${{ matrix.platform }}
diff --git a/CMakeLists.txt b/CMakeLists.txt
index fd7c3fb..905816c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -59,7 +59,8 @@ if(AARE_FETCH_ZMQ)
# Fetchcontent_Declare is deprecated need to find a way to update this
# for now setting the policy to old is enough
if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.30")
- cmake_policy(SET CMP0169 OLD)
+ cmake_policy(SET CMP0169 OLD)
+ endif()
FetchContent_Declare(
libzmq
GIT_REPOSITORY https://github.com/zeromq/libzmq.git
diff --git a/conda-recipe/meta.yaml b/conda-recipe/meta.yaml
index 7ba00f5..c221757 100644
--- a/conda-recipe/meta.yaml
+++ b/conda-recipe/meta.yaml
@@ -1,6 +1,6 @@
package:
name: aare
- version: 2024.10.29.dev0 #TODO! how to not duplicate this?
+ version: 2024.10.30.dev0 #TODO! how to not duplicate this?
source:
path: ..
diff --git a/include/aare/File.hpp b/include/aare/File.hpp
index 958460c..a12f64f 100644
--- a/include/aare/File.hpp
+++ b/include/aare/File.hpp
@@ -12,7 +12,6 @@ namespace aare {
class File {
private:
FileInterface *file_impl;
- bool is_npy;
public:
/**
@@ -24,14 +23,16 @@ class File {
* @throws std::invalid_argument if the file mode is not supported
*
*/
- File(const std::filesystem::path &fname, const std::string &mode, const FileConfig &cfg = {});
- void write(Frame &frame, sls_detector_header header = {});
- Frame read();
- Frame iread(size_t frame_number);
- std::vector read(size_t n_frames);
+ File(const std::filesystem::path &fname, const std::string &mode="r", const FileConfig &cfg = {});
+
+ Frame read_frame(); //!< read one frame from the file at the current position
+ Frame read_frame(size_t frame_number); //!< read the frame at the position given by frame number
+ std::vector read_n(size_t n_frames); //!< read n_frames from the file at the current position
+
void read_into(std::byte *image_buf);
void read_into(std::byte *image_buf, size_t n_frames);
- size_t frame_number(size_t frame_index);
+
+ size_t frame_number(size_t frame_index); //!< get the frame number at the given frame index
size_t bytes_per_frame();
size_t pixels_per_frame();
void seek(size_t frame_number);
@@ -43,17 +44,8 @@ class File {
size_t bytes_per_pixel() const;
void set_total_frames(size_t total_frames);
DetectorType detector_type() const;
- xy geometry() const;
- /**
- * @brief Move constructor
- * @param other File object to move from
- */
File(File &&other) noexcept;
-
- /**
- * @brief destructor: will only delete the FileInterface object
- */
~File();
};
diff --git a/include/aare/FileInterface.hpp b/include/aare/FileInterface.hpp
index 97e0d19..d917678 100644
--- a/include/aare/FileInterface.hpp
+++ b/include/aare/FileInterface.hpp
@@ -47,32 +47,24 @@ struct FileConfig {
class FileInterface {
public:
/**
- * @brief write a frame to the file
- * @param frame frame to write
- * @return void
- * @throws std::runtime_error if the function is not implemented
- */
- // virtual void write(Frame &frame) = 0;
-
- /**
- * @brief write a vector of frames to the file
- * @param frames vector of frames to write
- * @return void
- */
- // virtual void write(std::vector &frames) = 0;
-
- /**
- * @brief read one frame from the file at the current position
+ * @brief one frame from the file at the current position
* @return Frame
*/
- virtual Frame read() = 0;
+ virtual Frame read_frame() = 0;
+
+ /**
+ * @brief read one frame from the file at the given frame number
+ * @param frame_number frame number to read
+ * @return frame
+ */
+ virtual Frame read_frame(size_t frame_number) = 0;
/**
* @brief read n_frames from the file at the current position
* @param n_frames number of frames to read
* @return vector of frames
*/
- virtual std::vector read(size_t n_frames) = 0; // Is this the right interface?
+ virtual std::vector read_n(size_t n_frames) = 0; // Is this the right interface?
/**
* @brief read one frame from the file at the current position and store it in the provided buffer
@@ -142,32 +134,7 @@ class FileInterface {
*/
virtual size_t bitdepth() const = 0;
- /**
- * @brief read one frame from the file at the given frame number
- * @param frame_number frame number to read
- * @return frame
- */
- Frame iread(size_t frame_number) {
- auto old_pos = tell();
- seek(frame_number);
- Frame tmp = read();
- seek(old_pos);
- return tmp;
- };
- /**
- * @brief read n_frames from the file starting at the given frame number
- * @param frame_number frame number to start reading from
- * @param n_frames number of frames to read
- * @return vector of frames
- */
- std::vector iread(size_t frame_number, size_t n_frames) {
- auto old_pos = tell();
- seek(frame_number);
- std::vector tmp = read(n_frames);
- seek(old_pos);
- return tmp;
- }
DetectorType detector_type() const { return m_type; }
// function to query the data type of the file
@@ -175,8 +142,6 @@ class FileInterface {
virtual ~FileInterface() = default;
- void set_total_frames(size_t total_frames) { m_total_frames = total_frames; }
-
protected:
std::string m_mode{};
std::filesystem::path m_fname{};
diff --git a/include/aare/NumpyFile.hpp b/include/aare/NumpyFile.hpp
index 0e4ea41..745850b 100644
--- a/include/aare/NumpyFile.hpp
+++ b/include/aare/NumpyFile.hpp
@@ -31,9 +31,10 @@ class NumpyFile : public FileInterface {
explicit NumpyFile(const std::filesystem::path &fname, const std::string &mode = "r", FileConfig cfg = {});
void write(Frame &frame);
- Frame read() override { return get_frame(this->current_frame++); }
+ Frame read_frame() override { return get_frame(this->current_frame++); }
+ Frame read_frame(size_t frame_number) override { return get_frame(frame_number); }
- std::vector read(size_t n_frames) override;
+ std::vector read_n(size_t n_frames) override;
void read_into(std::byte *image_buf) override { return get_frame_into(this->current_frame++, image_buf); }
void read_into(std::byte *image_buf, size_t n_frames) override;
size_t frame_number(size_t frame_index) override { return frame_index; };
diff --git a/include/aare/RawFile.hpp b/include/aare/RawFile.hpp
index 7de4aef..d9b7c1c 100644
--- a/include/aare/RawFile.hpp
+++ b/include/aare/RawFile.hpp
@@ -39,8 +39,12 @@ class RawFile : public FileInterface {
* @param frame frame to write
*/
void write(Frame &frame, sls_detector_header header);
- Frame read() override { return get_frame(this->current_frame++); };
- std::vector read(size_t n_frames) override;
+ Frame read_frame() override { return get_frame(this->current_frame++); };
+ Frame read_frame(size_t frame_number) override{
+ seek(frame_number);
+ return read_frame();
+ }
+ std::vector read_n(size_t n_frames) override;
void read_into(std::byte *image_buf) override { return get_frame_into(this->current_frame++, image_buf); };
void read_into(std::byte *image_buf, size_t n_frames) override;
size_t frame_number(size_t frame_index) override;
diff --git a/pyproject.toml b/pyproject.toml
index 090203a..e303327 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -4,7 +4,7 @@ build-backend = "scikit_build_core.build"
[project]
name = "aare"
-version = "2024.10.29.dev0"
+version = "2024.10.30.dev0"
[tool.scikit-build]
cmake.verbose = true
diff --git a/python/src/file.hpp b/python/src/file.hpp
index 9324890..ded90bf 100644
--- a/python/src/file.hpp
+++ b/python/src/file.hpp
@@ -16,25 +16,12 @@ namespace py = pybind11;
using namespace::aare;
void define_file_io_bindings(py::module &m) {
- py::class_(m, "xy")
- .def(py::init<>())
- .def(py::init())
- .def_readwrite("row", &xy::row)
- .def_readwrite("col", &xy::col)
- .def("__eq__", &xy::operator==)
- .def("__ne__", &xy::operator!=)
- .def("__repr__",
- [](const xy &a) { return ""; });
-
-
py::class_(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())
- // .def("read", py::overload_cast<>(&File::read))
- // .def("read", py::overload_cast(&File::read))
- .def("iread", py::overload_cast(&File::iread),py::call_guard())
+
.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)
@@ -44,10 +31,8 @@ void define_file_io_bindings(py::module &m) {
.def_property_readonly("rows", &File::rows)
.def_property_readonly("cols", &File::cols)
.def_property_readonly("bitdepth", &File::bitdepth)
+ .def_property_readonly("bytes_per_pixel", &File::bytes_per_pixel)
.def_property_readonly("detector_type", &File::detector_type)
- .def_property_readonly("geometry", &File::geometry,
- py::call_guard())
- // .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;
@@ -64,6 +49,42 @@ void define_file_io_bindings(py::module &m) {
}
self.read_into(reinterpret_cast(image.mutable_data()));
return image;
+ })
+ .def("read_frame", [](File &self, size_t frame_number) {
+ self.seek(frame_number);
+ const uint8_t item_size = self.bytes_per_pixel();
+ py::array image;
+ std::vector shape;
+ shape.reserve(2);
+ shape.push_back(self.rows());
+ shape.push_back(self.cols());
+ if (item_size == 1) {
+ image = py::array_t(shape);
+ } else if (item_size == 2) {
+ image = py::array_t(shape);
+ } else if (item_size == 4) {
+ image = py::array_t(shape);
+ }
+ self.read_into(reinterpret_cast(image.mutable_data()));
+ return image;
+ })
+ .def("read_n", [](File &self, size_t n_frames) {
+ const uint8_t item_size = self.bytes_per_pixel();
+ py::array image;
+ std::vector shape;
+ shape.reserve(3);
+ shape.push_back(n_frames);
+ shape.push_back(self.rows());
+ shape.push_back(self.cols());
+ if (item_size == 1) {
+ image = py::array_t(shape);
+ } else if (item_size == 2) {
+ image = py::array_t(shape);
+ } else if (item_size == 4) {
+ image = py::array_t(shape);
+ }
+ self.read_into(reinterpret_cast(image.mutable_data()), n_frames);
+ return image;
});
py::class_(m, "FileConfig")
diff --git a/src/File.cpp b/src/File.cpp
index 190b838..2e2a1a3 100644
--- a/src/File.cpp
+++ b/src/File.cpp
@@ -7,7 +7,7 @@
namespace aare {
File::File(const std::filesystem::path &fname, const std::string &mode, const FileConfig &cfg)
- : file_impl(nullptr), is_npy(true) {
+ : file_impl(nullptr){
if (mode != "r" && mode != "w" && mode != "a") {
throw std::invalid_argument("Unsupported file mode");
}
@@ -19,7 +19,6 @@ File::File(const std::filesystem::path &fname, const std::string &mode, const Fi
if (fname.extension() == ".raw" || fname.extension() == ".json") {
// aare::logger::debug("Loading raw file");
file_impl = new RawFile(fname, mode, cfg);
- is_npy = false;
}
// check if extension is numpy
else if (fname.extension() == ".npy") {
@@ -30,17 +29,10 @@ File::File(const std::filesystem::path &fname, const std::string &mode, const Fi
}
}
-void File::write(Frame &frame, sls_detector_header header) {
- if (is_npy) {
- // aare::logger::info("ignoring header for npy file");
- dynamic_cast(file_impl)->write(frame);
- } else {
- dynamic_cast(file_impl)->write(frame, header);
- }
-}
-Frame File::read() { return file_impl->read(); }
+
+Frame File::read_frame() { return file_impl->read_frame(); }
size_t File::total_frames() const { return file_impl->total_frames(); }
-std::vector File::read(size_t n_frames) { return file_impl->read(n_frames); }
+std::vector File::read_n(size_t n_frames) { return file_impl->read_n(n_frames); }
void File::read_into(std::byte *image_buf) { file_impl->read_into(image_buf); }
void File::read_into(std::byte *image_buf, size_t n_frames) { file_impl->read_into(image_buf, n_frames); }
size_t File::frame_number(size_t frame_index) { return file_impl->frame_number(frame_index); }
@@ -52,19 +44,13 @@ 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(); }
-xy File::geometry() const {
- if (is_npy) {
- return {1, 1};
- }
- return reinterpret_cast(file_impl)->geometry();
-}
-Frame File::iread(size_t frame_number) { return file_impl->iread(frame_number); }
-File::File(File &&other) noexcept : file_impl(other.file_impl), is_npy(other.is_npy) { other.file_impl = nullptr; }
+Frame File::read_frame(size_t frame_number) { return file_impl->read_frame(frame_number); }
+
+File::File(File &&other) noexcept : file_impl(other.file_impl) { other.file_impl = nullptr; }
// write move assignment operator
diff --git a/src/NumpyFile.cpp b/src/NumpyFile.cpp
index 8ec9fd5..f6bd0e7 100644
--- a/src/NumpyFile.cpp
+++ b/src/NumpyFile.cpp
@@ -75,7 +75,7 @@ void NumpyFile::get_frame_into(size_t frame_number, std::byte *image_buf) {
size_t NumpyFile::pixels_per_frame() { return m_pixels_per_frame; };
size_t NumpyFile::bytes_per_frame() { return m_bytes_per_frame; };
-std::vector NumpyFile::read(size_t n_frames) {
+std::vector NumpyFile::read_n(size_t n_frames) {
// TODO: implement this in a more efficient way
std::vector frames;
for (size_t i = 0; i < n_frames; i++) {
diff --git a/src/RawFile.cpp b/src/RawFile.cpp
index 2472f05..f7ca21c 100644
--- a/src/RawFile.cpp
+++ b/src/RawFile.cpp
@@ -382,7 +382,7 @@ void RawFile::write(Frame &frame, sls_detector_header header) {
this->current_frame++;
}
-std::vector RawFile::read(size_t n_frames) {
+std::vector RawFile::read_n(size_t n_frames) {
// TODO: implement this in a more efficient way
std::vector frames;
for (size_t i = 0; i < n_frames; i++) {
diff --git a/src/RawFile.test.cpp b/src/RawFile.test.cpp
index 9e99ce7..295747e 100644
--- a/src/RawFile.test.cpp
+++ b/src/RawFile.test.cpp
@@ -41,7 +41,7 @@ TEST_CASE("Read data from a jungfrau 500k single port raw file") {
// we know this file has 10 frames with pixel 0,0 being: 2123, 2051, 2109, 2117, 2089, 2095, 2072, 2126, 2097, 2102
std::vector pixel_0_0 = {2123, 2051, 2109, 2117, 2089, 2095, 2072, 2126, 2097, 2102};
for (size_t i = 0; i < 10; i++) {
- auto frame = f.read();
+ auto frame = f.read_frame();
CHECK(frame.rows() == 512);
CHECK(frame.cols() == 1024);
CHECK(frame.view()(0, 0) == pixel_0_0[i]);
@@ -75,8 +75,8 @@ TEST_CASE("Compare reading from a numpy file with a raw file") {
CHECK(npy.total_frames() == 10);
for (size_t i = 0; i < 10; ++i) {
- auto raw_frame = raw.read();
- auto npy_frame = npy.read();
+ auto raw_frame = raw.read_frame();
+ auto npy_frame = npy.read_frame();
CHECK((raw_frame.view() == npy_frame.view()));
}
}
@@ -95,7 +95,7 @@ TEST_CASE("Read multipart files") {
std::vector pixel_1_0 = {2748, 2614, 2665, 2629, 2618, 2630, 2631, 2634, 2577, 2598};
for (size_t i = 0; i < 10; i++) {
- auto frame = f.read();
+ auto frame = f.read_frame();
CHECK(frame.rows() == 512);
CHECK(frame.cols() == 1024);
CHECK(frame.view()(0, 0) == pixel_0_0[i]);
@@ -110,5 +110,5 @@ TEST_CASE("Read file with unordered frames") {
auto fpath = test_data_path() / "mythen" / "scan242_master_3.raw";
REQUIRE(std::filesystem::exists(fpath));
File f(fpath, "r");
- REQUIRE_THROWS((f.read()));
+ REQUIRE_THROWS((f.read_frame()));
}