From cd905e96f38f383f6310c721958d0b2ca903139d Mon Sep 17 00:00:00 2001 From: Bechir Braham Date: Wed, 20 Mar 2024 13:14:14 +0100 Subject: [PATCH] remove templates --- CMakeLists.txt | 30 ++++++++++++++++- core/CMakeLists.txt | 4 ++- core/include/aare/Frame.hpp | 29 +++++++++------- core/src/Frame.cpp | 41 ++++++++++------------- examples/CMakeLists.txt | 11 ++++-- examples/json_file_read.cpp | 30 +++++++++++++++++ examples/main.cpp | 35 ------------------- examples/numpy_file_read.cpp | 30 +++++++++++++++++ file_io/CMakeLists.txt | 11 +++--- file_io/include/aare/File.hpp | 5 ++- file_io/include/aare/FileFactory.hpp | 9 +++-- file_io/include/aare/FileHandler.hpp | 11 +++--- file_io/include/aare/JsonFile.hpp | 4 +-- file_io/include/aare/JsonFileFactory.hpp | 13 ++++--- file_io/include/aare/NumpyFile.hpp | 4 +-- file_io/include/aare/NumpyFileFactory.hpp | 10 +++--- file_io/include/aare/RawFileFactory.hpp | 3 +- file_io/include/aare/SubFile.hpp | 12 +++++-- file_io/src/FileFactory.cpp | 8 ++--- file_io/src/JsonFile.cpp | 10 ++---- file_io/src/JsonFileFactory.cpp | 39 ++++++--------------- file_io/src/NumpyFile.cpp | 11 +++--- file_io/src/NumpyFileFactory.cpp | 24 ++++--------- file_io/src/SubFile.cpp | 22 +++++------- python/src/bindings.cpp | 17 +++++----- 25 files changed, 223 insertions(+), 200 deletions(-) create mode 100644 examples/json_file_read.cpp delete mode 100644 examples/main.cpp create mode 100644 examples/numpy_file_read.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 80deac7..f112f6a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -64,6 +64,35 @@ if(AARE_USE_WARNINGS) ) endif() +if (NOT AARE_PYTHON_BINDINGS) + target_compile_options( + aare_compiler_flags + INTERFACE + -fsanitize=address + -fdiagnostics-parseable-fixits + -fdiagnostics-generate-patch + -fdiagnostics-show-template-tree + -fsanitize=address,undefined,pointer-compare + -fno-sanitize-recover + -D_FORTIFY_SOURCE=2 + -fstack-protector + -fno-omit-frame-pointer + ) + + target_link_libraries( + aare_compiler_flags + INTERFACE + -fsanitize=address + -fdiagnostics-parseable-fixits + -fdiagnostics-generate-patch + -fdiagnostics-show-template-tree + -fsanitize=address,undefined,pointer-compare + -fno-sanitize-recover + -D_FORTIFY_SOURCE=2 + -fstack-protector + -fno-omit-frame-pointer + ) +endif() if(AARE_TESTS) add_subdirectory(tests) endif() @@ -81,7 +110,6 @@ target_include_directories(aare INTERFACE ) add_subdirectory(examples) -target_link_libraries(example PUBLIC aare) if(AARE_PYTHON_BINDINGS) diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 58dbd38..fd5e4e4 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -10,8 +10,10 @@ target_include_directories(core PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) target_link_libraries(core PUBLIC fmt::fmt PRIVATE aare_compiler_flags) -set_property(TARGET core PROPERTY POSITION_INDEPENDENT_CODE ON) +if (AARE_PYTHON_BINDINGS) +set_property(TARGET core PROPERTY POSITION_INDEPENDENT_CODE ON) +endif() if(AARE_TESTS) set(TestSources diff --git a/core/include/aare/Frame.hpp b/core/include/aare/Frame.hpp index b447773..abf9150 100644 --- a/core/include/aare/Frame.hpp +++ b/core/include/aare/Frame.hpp @@ -12,17 +12,18 @@ * should be able to work with streams coming from files or network */ -template class Frame { +class Frame { ssize_t m_rows; ssize_t m_cols; - DataType *m_data; - ssize_t m_bitdepth = sizeof(DataType) * 8; + ssize_t m_bitdepth; + std::byte* m_data; + public: - Frame(ssize_t rows, ssize_t cols); - Frame(std::byte *fp, ssize_t rows, ssize_t cols); - DataType get(int row, int col); - std::vector> get_array(); + Frame(ssize_t rows, ssize_t cols,ssize_t m_bitdepth); + Frame(std::byte *fp, ssize_t rows, ssize_t cols,ssize_t m_bitdepth); + std::byte* get(int row, int col); + // std::vector> get_array(); ssize_t rows() const{ return m_rows; } @@ -32,13 +33,17 @@ template class Frame { ssize_t bitdepth() const{ return m_bitdepth; } - DataType* _get_data(){ + std::byte* _get_data(){ return m_data; } + Frame& operator=(Frame& other){ + m_rows = other.rows(); + m_cols = other.cols(); + m_bitdepth = other.bitdepth(); + m_data = new std::byte[m_rows*m_cols*m_bitdepth/8]; + std::memcpy(m_data, other.m_data, m_rows*m_cols*m_bitdepth/8); + return *this; + } ~Frame() { delete[] m_data; } }; - -typedef Frame Frame16; -typedef Frame Frame8; -typedef Frame Frame32; \ No newline at end of file diff --git a/core/src/Frame.cpp b/core/src/Frame.cpp index 3d4e940..7974b5c 100644 --- a/core/src/Frame.cpp +++ b/core/src/Frame.cpp @@ -1,41 +1,36 @@ #include "aare/Frame.hpp" #include -template -Frame::Frame(std::byte* bytes, ssize_t rows, ssize_t cols): - m_rows(rows), m_cols(cols) { - m_data = new DataType[rows*cols]; - std::memcpy(m_data, bytes, m_rows*m_cols*sizeof(DataType)); +Frame::Frame(std::byte* bytes, ssize_t rows, ssize_t cols, ssize_t bitdepth): + m_rows(rows), m_cols(cols), m_bitdepth(bitdepth) { + m_data = new std::byte[rows*cols*bitdepth/8]; + std::memcpy(m_data, bytes, rows*cols*bitdepth/8); } -template -Frame::Frame(ssize_t rows, ssize_t cols): - m_rows(rows), m_cols(cols) { - m_data = new DataType[m_rows*m_cols]; +Frame::Frame(ssize_t rows, ssize_t cols, ssize_t bitdepth): + m_rows(rows), m_cols(cols), m_bitdepth(bitdepth) { + m_data = new std::byte[rows*cols*bitdepth/8]; } -template -DataType Frame::get(int row, int col) { +std::byte* Frame::get(int row, int col) { if (row < 0 || row >= m_rows || col < 0 || col >= m_cols) { std::cerr << "Invalid row or column index" << std::endl; return 0; } - return m_data[row*m_cols + col]; + return m_data+(row*m_cols + col)*(m_bitdepth/8); } -template -std::vector> Frame::get_array() { - std::vector> array; - for (int i = 0; i < m_rows; i++) { - std::vector row; - row.assign(m_data + i*m_cols, m_data + (i+1)*m_cols); - array.push_back(row); - } +// std::vector> Frame::get_array() { +// std::vector> array; +// for (int i = 0; i < m_rows; i++) { +// std::vector row; +// row.assign(m_data + i*m_cols, m_data + (i+1)*m_cols); +// array.push_back(row); +// } - return array; -} +// return array; +// } -template class Frame; diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 23b1284..003a556 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,8 +1,13 @@ -add_executable(example "${CMAKE_CURRENT_SOURCE_DIR}/main.cpp") +add_executable(json_example json_file_read.cpp) +add_executable(numpy_example numpy_file_read.cpp) -target_include_directories(example PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}") -target_link_libraries(example PRIVATE aare_compiler_flags) +target_link_libraries(json_example PRIVATE aare_compiler_flags) +target_link_libraries(numpy_example PRIVATE aare_compiler_flags) + +target_link_libraries(json_example PUBLIC aare) +target_link_libraries(numpy_example PUBLIC aare) + diff --git a/examples/json_file_read.cpp b/examples/json_file_read.cpp new file mode 100644 index 0000000..d8ac8bd --- /dev/null +++ b/examples/json_file_read.cpp @@ -0,0 +1,30 @@ +// Your First C++ Program +#include "aare/FileHandler.hpp" +#include + +#define AARE_ROOT_DIR_VAR "PROJECT_ROOT_DIR" + +void test(FileHandler *f, int frame_number) { + std::cout << "frame number: " << frame_number << std::endl; + Frame *frame = f->get_frame(frame_number); + std::cout << *((uint16_t *)frame->get(0, 0)) << std::endl; + std::cout << *((uint16_t *)frame->get(0, 1)) << std::endl; + std::cout << *((uint16_t *)frame->get(1, 0)) << std::endl; + std::cout << *((uint16_t *)frame->get(511, 1023)) << std::endl; + + delete frame; +} + +int main() { + auto PROJECT_ROOT_DIR = std::filesystem::path(getenv(AARE_ROOT_DIR_VAR)); + std::filesystem::path fpath(PROJECT_ROOT_DIR / "data" / "jungfrau_single_master_0.json"); + // std::filesystem::path fpath(PROJECT_ROOT_DIR / "data" / "test_numpy_file.npy"); + std::cout << fpath << std::endl; + + auto fileHandler = new FileHandler(fpath); + test(fileHandler, 0); + test(fileHandler, 2); + test(fileHandler, 9); + + delete fileHandler; +} diff --git a/examples/main.cpp b/examples/main.cpp deleted file mode 100644 index a1464e0..0000000 --- a/examples/main.cpp +++ /dev/null @@ -1,35 +0,0 @@ -// Your First C++ Program -#include "aare/FileHandler.hpp" -#include - -#define AARE_ROOT_DIR_VAR "PROJECT_ROOT_DIR" - -using JFileHandler = FileHandler; -using JFile = File; -using JFrame = Frame; - -void test(JFileHandler *f, int frame_number) { - std::cout << "frame number: " << frame_number << std::endl; - JFrame *frame = f->get_frame(frame_number); - std::cout << frame->get(0, 0) << std::endl; - std::cout << frame->get(0, 1) << std::endl; - std::cout << frame->get(1, 0) << std::endl; - std::cout << frame->get(49, 49) << std::endl; - - delete frame; -} - -int main() { - auto PROJECT_ROOT_DIR = std::filesystem::path(getenv(AARE_ROOT_DIR_VAR)); - // std::filesystem::path fpath("/home/bb/github/aare/data/jungfrau_single_master_0.json"); - std::filesystem::path fpath(PROJECT_ROOT_DIR / "data" / "test_numpy_file.npy"); - std::cout< + +#define AARE_ROOT_DIR_VAR "PROJECT_ROOT_DIR" + +void test(FileHandler *f, int frame_number) { + std::cout << "frame number: " << frame_number << std::endl; + Frame *frame = f->get_frame(frame_number); + std::cout << *((uint16_t *)frame->get(0, 0)) << std::endl; + std::cout << *((uint16_t *)frame->get(0, 1)) << std::endl; + std::cout << *((uint16_t *)frame->get(1, 0)) << std::endl; + std::cout << *((uint16_t *)frame->get(49, 49)) << std::endl; + + delete frame; +} + +int main() { + auto PROJECT_ROOT_DIR = std::filesystem::path(getenv(AARE_ROOT_DIR_VAR)); + // std::filesystem::path fpath(PROJECT_ROOT_DIR / "data" / "jungfrau_single_master_0.json"); + std::filesystem::path fpath(PROJECT_ROOT_DIR / "data" / "test_numpy_file.npy"); + std::cout << fpath << std::endl; + + auto fileHandler = new FileHandler(fpath); + test(fileHandler, 0); + test(fileHandler, 2); + test(fileHandler, 24); + + delete fileHandler; +} diff --git a/file_io/CMakeLists.txt b/file_io/CMakeLists.txt index 5452079..8d65baa 100644 --- a/file_io/CMakeLists.txt +++ b/file_io/CMakeLists.txt @@ -1,8 +1,5 @@ -FetchContent_Declare(json - GIT_REPOSITORY https://github.com/nlohmann/json - GIT_TAG v3.11.3 -) -FetchContent_MakeAvailable(json) +find_package(nlohmann_json 3.2.0 REQUIRED) + set(SourceFiles ${CMAKE_CURRENT_SOURCE_DIR}/src/File.cpp @@ -19,7 +16,11 @@ set(SourceFiles add_library(file_io STATIC ${SourceFiles}) target_include_directories(file_io PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) target_link_libraries(file_io PRIVATE fmt::fmt core nlohmann_json::nlohmann_json aare_compiler_flags) + +if(AARE_PYTHON_BINDINGS) set_property(TARGET file_io PROPERTY POSITION_INDEPENDENT_CODE ON) +endif() + if(AARE_TESTS) set(TestSources diff --git a/file_io/include/aare/File.hpp b/file_io/include/aare/File.hpp index a490598..eff33ca 100644 --- a/file_io/include/aare/File.hpp +++ b/file_io/include/aare/File.hpp @@ -8,11 +8,10 @@ #include -template class File { public: - virtual Frame* get_frame(size_t frame_number) = 0; + virtual Frame* get_frame(size_t frame_number) = 0; private: //comment @@ -34,7 +33,7 @@ class File { ssize_t rows{}; ssize_t cols{}; - uint8_t bitdepth{}; + ssize_t bitdepth{}; // File(); diff --git a/file_io/include/aare/FileFactory.hpp b/file_io/include/aare/FileFactory.hpp index b11bc8c..0841b35 100644 --- a/file_io/include/aare/FileFactory.hpp +++ b/file_io/include/aare/FileFactory.hpp @@ -1,18 +1,17 @@ #pragma once #include #include "aare/File.hpp" -template class FileFactory{ // Class that will be used to create File objects // follows the factory pattern protected: std::filesystem::path m_fpath; public: - static FileFactory* get_factory(std::filesystem::path); + static FileFactory* get_factory(std::filesystem::path); // virtual int deleteFile() = 0; - virtual File* load_file()=0;//TODO: add option to load all file to memory or keep it on disk - virtual void parse_metadata(File*)=0; - virtual void parse_fname(File*)=0; + virtual File* load_file()=0;//TODO: add option to load all file to memory or keep it on disk + virtual void parse_metadata(File*)=0; + virtual void parse_fname(File*)=0; virtual ~FileFactory() = default; diff --git a/file_io/include/aare/FileHandler.hpp b/file_io/include/aare/FileHandler.hpp index 709d0e4..18900d5 100644 --- a/file_io/include/aare/FileHandler.hpp +++ b/file_io/include/aare/FileHandler.hpp @@ -2,22 +2,21 @@ #include "aare/FileFactory.hpp" #include "aare/File.hpp" -template class FileHandler{ private: std::filesystem::path fpath; - FileFactory* fileFactory; - File* f; + FileFactory* fileFactory; + File* f; public: - FileHandler(std::filesystem::path fname){ + FileHandler(std::filesystem::path fname){ this->fpath = fname; - this->fileFactory= FileFactory::get_factory(fname); + this->fileFactory= FileFactory::get_factory(fname); this->f= fileFactory->load_file(); delete fileFactory; } - Frame* get_frame(int index){ + Frame* get_frame(int index){ return f->get_frame(index); } diff --git a/file_io/include/aare/JsonFile.hpp b/file_io/include/aare/JsonFile.hpp index 9dc0565..e632121 100644 --- a/file_io/include/aare/JsonFile.hpp +++ b/file_io/include/aare/JsonFile.hpp @@ -4,12 +4,12 @@ #include "aare/File.hpp" -template class JsonFile : public File { +class JsonFile : public File { using config = RawFileConfig; public: - Frame *get_frame(size_t frame_number); + Frame *get_frame(size_t frame_number); int n_subfiles; std::vector subfiles; int subfile_rows, subfile_cols; diff --git a/file_io/include/aare/JsonFileFactory.hpp b/file_io/include/aare/JsonFileFactory.hpp index 4c0ffac..1aa5d86 100644 --- a/file_io/include/aare/JsonFileFactory.hpp +++ b/file_io/include/aare/JsonFileFactory.hpp @@ -1,17 +1,16 @@ #include "aare/FileFactory.hpp" -template -class JsonFileFactory: public FileFactory +class JsonFileFactory: public FileFactory { private: /* data */ public: JsonFileFactory(std::filesystem::path fpath); - File* load_file() override; - void parse_metadata(File*) override; - void parse_fname(File*) override; - void open_subfiles(File*); + File* load_file() override; + void parse_metadata(File*) override; + void parse_fname(File*) override; + void open_subfiles(File*); sls_detector_header read_header(const std::filesystem::path &fname); - void find_geometry(File*); + void find_geometry(File*); diff --git a/file_io/include/aare/NumpyFile.hpp b/file_io/include/aare/NumpyFile.hpp index 80c8d62..bd62d2d 100644 --- a/file_io/include/aare/NumpyFile.hpp +++ b/file_io/include/aare/NumpyFile.hpp @@ -6,12 +6,12 @@ #include -template class NumpyFile : public File { +class NumpyFile : public File { FILE *fp = nullptr; public: NumpyFile(std::filesystem::path fname); - Frame *get_frame(size_t frame_number) override; + Frame *get_frame(size_t frame_number) override; header_t header{}; static constexpr std::array magic_str{'\x93', 'N', 'U', 'M', 'P', 'Y'}; uint8_t major_ver_{}; diff --git a/file_io/include/aare/NumpyFileFactory.hpp b/file_io/include/aare/NumpyFileFactory.hpp index 45e55da..6dbac55 100644 --- a/file_io/include/aare/NumpyFileFactory.hpp +++ b/file_io/include/aare/NumpyFileFactory.hpp @@ -6,15 +6,15 @@ -template class NumpyFileFactory : public FileFactory { +class NumpyFileFactory : public FileFactory { private: std::ifstream f; - void read_data(File *_file); + void read_data(File *_file); public: NumpyFileFactory(std::filesystem::path fpath); - void parse_metadata(File *_file) override; - File *load_file() override; - void parse_fname(File *){}; + void parse_metadata(File *_file) override; + File *load_file() override; + void parse_fname(File*){}; }; \ No newline at end of file diff --git a/file_io/include/aare/RawFileFactory.hpp b/file_io/include/aare/RawFileFactory.hpp index 66a3f59..4f40b3d 100644 --- a/file_io/include/aare/RawFileFactory.hpp +++ b/file_io/include/aare/RawFileFactory.hpp @@ -1,9 +1,8 @@ #include "aare/File.hpp" #include -template class RawFileFactory{ public: // RawFileFactory(); // ~RawFileFactory(); - File loadFile(std::filesystem::path fpath); + File loadFile(std::filesystem::path fpath); }; \ No newline at end of file diff --git a/file_io/include/aare/SubFile.hpp b/file_io/include/aare/SubFile.hpp index c747e9c..d297178 100644 --- a/file_io/include/aare/SubFile.hpp +++ b/file_io/include/aare/SubFile.hpp @@ -3,20 +3,28 @@ #include #include #include +#include class SubFile { protected: FILE *fp = nullptr; - uint16_t m_bitdepth; + ssize_t m_bitdepth; std::filesystem::path m_fname; ssize_t m_rows{}; ssize_t m_cols{}; ssize_t n_frames{}; int m_sub_file_index_{}; + // pointer to functions that will read frames + using pfunc = size_t (SubFile::*)(std::byte *); + std::map, pfunc> read_impl_map = { + {{DetectorType::Moench, 16}, &SubFile::read_impl_reorder}, + {{DetectorType::Jungfrau, 16}, &SubFile::read_impl_normal}, + }; + public: // pointer to a read_impl function. pointer will be set to the appropriate read_impl function in the constructor - size_t (SubFile::*read_impl)(std::byte *buffer) = nullptr; + pfunc read_impl = nullptr; size_t read_impl_normal(std::byte *buffer); template size_t read_impl_flip(std::byte *buffer); template size_t read_impl_reorder(std::byte *buffer); diff --git a/file_io/src/FileFactory.cpp b/file_io/src/FileFactory.cpp index 37eaf0c..5323341 100644 --- a/file_io/src/FileFactory.cpp +++ b/file_io/src/FileFactory.cpp @@ -4,8 +4,7 @@ #include "aare/NumpyFileFactory.hpp" #include -template -FileFactory *FileFactory::get_factory(std::filesystem::path fpath) { +FileFactory *FileFactory::get_factory(std::filesystem::path fpath) { // check if file exists if (!std::filesystem::exists(fpath)) { throw std::runtime_error("File does not exist"); @@ -16,12 +15,12 @@ FileFactory *FileFactory::get_factory(st throw std::runtime_error("Raw file not implemented"); } else if (fpath.extension() == ".json") { std::cout << "Loading json file" << std::endl; - return new JsonFileFactory(fpath); + return new JsonFileFactory(fpath); } // check if extension is numpy else if (fpath.extension() == ".npy") { std::cout << "Loading numpy file" << std::endl; - return new NumpyFileFactory(fpath); + return new NumpyFileFactory(fpath); } throw std::runtime_error("Unsupported file type"); @@ -29,4 +28,3 @@ FileFactory *FileFactory::get_factory(st -template class FileFactory; \ No newline at end of file diff --git a/file_io/src/JsonFile.cpp b/file_io/src/JsonFile.cpp index 0b7844d..0ba0f25 100644 --- a/file_io/src/JsonFile.cpp +++ b/file_io/src/JsonFile.cpp @@ -1,7 +1,6 @@ #include "aare/JsonFile.hpp" -template -Frame *JsonFile::get_frame(size_t frame_number) { +Frame *JsonFile::get_frame(size_t frame_number) { if (frame_number > this->total_frames) { throw std::runtime_error("Frame number out of range"); } @@ -9,21 +8,18 @@ Frame *JsonFile::get_frame(size_t frame_number) { std::byte *buffer; size_t frame_size = this->subfiles[subfile_id]->bytes_per_frame(); buffer = new std::byte[frame_size]; - this->subfiles[subfile_id]->get_frame(buffer, frame_number % this->max_frames_per_file); + auto f = new Frame(buffer, this->rows, this->cols, this->bitdepth ); - auto f = new Frame(buffer, this->rows, this->cols); delete[] buffer; return f; } -template -JsonFile::~JsonFile() { +JsonFile::~JsonFile() { for (auto& subfile : subfiles) { delete subfile; } } -template class JsonFile; \ No newline at end of file diff --git a/file_io/src/JsonFileFactory.cpp b/file_io/src/JsonFileFactory.cpp index 41c2d46..60885ce 100644 --- a/file_io/src/JsonFileFactory.cpp +++ b/file_io/src/JsonFileFactory.cpp @@ -9,16 +9,14 @@ using json = nlohmann::json; -template -JsonFileFactory::JsonFileFactory(std::filesystem::path fpath) { +JsonFileFactory::JsonFileFactory(std::filesystem::path fpath) { if (not is_master_file(fpath)) throw std::runtime_error("Json file is not a master file"); this->m_fpath = fpath; } -template -void JsonFileFactory::parse_metadata(File *_file) { - auto file = dynamic_cast *>(_file); +void JsonFileFactory::parse_metadata(File*_file) { + auto file = dynamic_cast(_file); std::ifstream ifs(file->master_fname()); json j; ifs >> j; @@ -26,9 +24,6 @@ void JsonFileFactory::parse_metadata(File std::cout << "Version: " << v << std::endl; file->version = fmt::format("{:.1f}", v); file->type = StringTo(j["Detector Type"].get()); - if (file->type != detector) - throw std::runtime_error("Detector type mismatch: file type (" + toString(file->type) + - ") != specified type (" + toString(detector) + ")"); file->timing_mode = StringTo(j["Timing Mode"].get()); file->total_frames = j["Frames in File"]; file->subfile_cols = j["Pixels"]["x"]; @@ -37,22 +32,16 @@ void JsonFileFactory::parse_metadata(File try { file->bitdepth = j.at("Dynamic Range"); } catch (const json::out_of_range &e) { - std::cerr << "master file does not have Dynamic Range. Defaulting to 16 bit" << '\n'; file->bitdepth = 16; } - if (file->bitdepth != sizeof(DataType) * 8) - throw std::runtime_error("Bitdepth mismatch: file bitdepth (" + std::to_string(file->bitdepth) + - ") != specified bitdepth (" + std::to_string(sizeof(DataType) * 8) + ")"); - // only Eiger had quad if (file->type == DetectorType::Eiger) { file->quad = (j["Quad"] == 1); } } -template -void JsonFileFactory::open_subfiles(File *_file) { - auto file = dynamic_cast *>(_file); +void JsonFileFactory::open_subfiles(File*_file) { + auto file = dynamic_cast(_file); for (int i = 0; i != file->n_subfiles; ++i) { file->subfiles.push_back( @@ -60,22 +49,19 @@ void JsonFileFactory::open_subfiles(File * } } -template -File *JsonFileFactory::load_file() { - JsonFile *file = new JsonFile(); +File* JsonFileFactory::load_file() { + JsonFile *file = new JsonFile(); file->fname = this->m_fpath; this->parse_fname(file); this->parse_metadata(file); file->find_number_of_subfiles(); this->find_geometry(file); this->open_subfiles(file); - return file; } -template -sls_detector_header JsonFileFactory::read_header(const std::filesystem::path &fname) { +sls_detector_header JsonFileFactory::read_header(const std::filesystem::path &fname) { sls_detector_header h{}; FILE *fp = fopen(fname.c_str(), "r"); if (!fp) @@ -89,9 +75,8 @@ sls_detector_header JsonFileFactory::read_header(const std:: } -template -void JsonFileFactory::find_geometry(File *_file) { - auto file = dynamic_cast *>(_file); +void JsonFileFactory::find_geometry(File* _file) { + auto file = dynamic_cast(_file); uint16_t r{}; uint16_t c{}; for (int i = 0; i != file->n_subfiles; ++i) { @@ -110,8 +95,7 @@ void JsonFileFactory::find_geometry(File file->rows += (r - 1) * file->cfg.module_gap_row; } -template -void JsonFileFactory::parse_fname(File *file) { +void JsonFileFactory::parse_fname(File* file) { file->base_path = this->m_fpath.parent_path(); file->base_name = this->m_fpath.stem(); @@ -124,4 +108,3 @@ void JsonFileFactory::parse_fname(File * } -template class JsonFileFactory; \ No newline at end of file diff --git a/file_io/src/NumpyFile.cpp b/file_io/src/NumpyFile.cpp index 15f06ff..90c1d8d 100644 --- a/file_io/src/NumpyFile.cpp +++ b/file_io/src/NumpyFile.cpp @@ -1,24 +1,21 @@ #include "aare/NumpyFile.hpp" -template -NumpyFile::NumpyFile(std::filesystem::path fname_){ +NumpyFile::NumpyFile(std::filesystem::path fname_){ this->fname = fname_; fp = fopen(this->fname.c_str(), "rb"); } -template -Frame *NumpyFile::get_frame(size_t frame_number) { +Frame* NumpyFile::get_frame(size_t frame_number) { if (fp == nullptr) { throw std::runtime_error("File not open"); } if (frame_number > header.shape[0]) { throw std::runtime_error("Frame number out of range"); } - Frame *frame = new Frame(header.shape[1], header.shape[2]); + Frame *frame = new Frame(header.shape[1], header.shape[2], header.dtype.itemsize*8); fseek(fp, header_size + frame_number * bytes_per_frame(), SEEK_SET); - fread(frame->_get_data(), sizeof(DataType), pixels_per_frame(), fp); + fread(frame->_get_data(), bytes_per_frame(), 1, fp); return frame; } -template class NumpyFile; \ No newline at end of file diff --git a/file_io/src/NumpyFileFactory.cpp b/file_io/src/NumpyFileFactory.cpp index 1f912eb..893c90e 100644 --- a/file_io/src/NumpyFileFactory.cpp +++ b/file_io/src/NumpyFileFactory.cpp @@ -1,12 +1,10 @@ #include "aare/NumpyFileFactory.hpp" #include "aare/NumpyHelpers.hpp" -template -NumpyFileFactory::NumpyFileFactory(std::filesystem::path fpath) { +NumpyFileFactory::NumpyFileFactory(std::filesystem::path fpath) { this->m_fpath = fpath; } -template -void NumpyFileFactory::parse_metadata(File *_file) { - auto file = dynamic_cast *>(_file); +void NumpyFileFactory::parse_metadata(File *_file) { + auto file = dynamic_cast(_file); // open ifsteam to file f = std::ifstream(file->fname, std::ios::binary); // check if file exists @@ -16,7 +14,7 @@ void NumpyFileFactory::parse_metadata(File tmp{}; f.read(tmp.data(), tmp.size()); - if (tmp != NumpyFile::magic_str) { + if (tmp != NumpyFile::magic_str) { for (auto item : tmp) fmt::print("{}, ", int(item)); fmt::print("\n"); @@ -74,19 +72,11 @@ void NumpyFileFactory::parse_metadata(Fileheader = {dtype, fortran_order, shape}; } -template - File* NumpyFileFactory::load_file() { - NumpyFile *file = new NumpyFile(this->m_fpath); + File* NumpyFileFactory::load_file() { + NumpyFile *file = new NumpyFile(this->m_fpath); parse_metadata(file); - std::cout << "parsed header: " << file->header.to_string() << std::endl; - - if(sizeof(DataType) != file->header.dtype.itemsize){ - std::stringstream s; - s << "Data type size mismatch: " << sizeof(DataType) << " != " << file->header.dtype.itemsize; - throw std::runtime_error(s.str()); - } + std::cout << "parsed header: " << file->header.to_string() << std::endl; return file; }; -template class NumpyFileFactory; diff --git a/file_io/src/SubFile.cpp b/file_io/src/SubFile.cpp index 133ce99..af523ea 100644 --- a/file_io/src/SubFile.cpp +++ b/file_io/src/SubFile.cpp @@ -2,11 +2,7 @@ #include // #include -/** - * SubFile methods - * - * - */ + SubFile::SubFile(std::filesystem::path fname, DetectorType detector, ssize_t rows, ssize_t cols, uint16_t bitdepth) { this->m_rows = rows; @@ -20,15 +16,15 @@ SubFile::SubFile(std::filesystem::path fname, DetectorType detector, ssize_t row std::cout << "File opened" << std::endl; n_frames = std::filesystem::file_size(fname) / (sizeof(sls_detector_header) + rows * cols * bitdepth / 8); std::cout << "Number of frames: " << n_frames << std::endl; + + if (read_impl_map.find({detector, bitdepth}) == read_impl_map.end()) { + throw std::runtime_error("Unsupported detector/bitdepth combination"); + } + read_impl = read_impl_map.at({detector, bitdepth}); + + - if (detector == DetectorType::Moench) { - read_impl = &SubFile::read_impl_reorder; - } else if (detector == DetectorType::Jungfrau) { - read_impl = &SubFile::read_impl_normal; - } - else { - throw std::runtime_error("Detector type not implemented"); - } + } size_t SubFile::get_frame(std::byte *buffer, int frame_number) { diff --git a/python/src/bindings.cpp b/python/src/bindings.cpp index d14b0ee..ceba72b 100644 --- a/python/src/bindings.cpp +++ b/python/src/bindings.cpp @@ -18,20 +18,19 @@ PYBIND11_MODULE(_aare, m) { py::implicitly_convertible(); //TODO: find a solution to avoid code duplication and include other detectors - py::class_>(m, "_FileHandler_Jungfrau_16") + py::class_(m, "_FileHandler") .def(py::init()) - .def("get_frame", &FileHandler::get_frame); + .def("get_frame", &FileHandler::get_frame); py::enum_(m, "DetectorType"); - py::class_>(m, "_Frame16") - .def(py::init()) - .def("get", &Frame::get) - .def("get_array", &Frame::get_array) - .def_property_readonly("rows", &Frame::rows) - .def_property_readonly("cols", &Frame::cols) - .def_property_readonly("bitdepth", &Frame::bitdepth); + py::class_(m, "_Frame") + .def(py::init()) + .def("get", &Frame::get) + .def_property_readonly("rows", &Frame::rows) + .def_property_readonly("cols", &Frame::cols) + .def_property_readonly("bitdepth", &Frame::bitdepth);