diff --git a/src/common/defs.cpp b/src/common/defs.cpp index 81e4065..08e9f70 100644 --- a/src/common/defs.cpp +++ b/src/common/defs.cpp @@ -1,5 +1,21 @@ #include "defs.hpp" +template <> std::string toString(DetectorType type) { + switch (type) { + case DetectorType::Jungfrau: + return "Jungfrau"; + case DetectorType::Eiger: + return "Eiger"; + case DetectorType::Mythen3: + return "Mythen3"; + case DetectorType::Moench: + return "Moench"; + default: + return "Unknown"; + } +} + + template <> DetectorType StringTo(std::string name) { if (name == "Jungfrau") return DetectorType::Jungfrau; diff --git a/src/common/defs.hpp b/src/common/defs.hpp index 826fb80..230452e 100644 --- a/src/common/defs.hpp +++ b/src/common/defs.hpp @@ -42,7 +42,14 @@ T StringTo(std::string sv){ return T(sv); } +template +std::string toString(T sv){ + return T(sv); +} + template <> DetectorType StringTo(std::string); +template <> std::string toString(DetectorType type); + template <> TimingMode StringTo(std::string); diff --git a/src/core/Frame.cpp b/src/core/Frame.cpp index dde8271..d2ca577 100644 --- a/src/core/Frame.cpp +++ b/src/core/Frame.cpp @@ -1,22 +1,23 @@ #include "Frame.hpp" #include +template +Frame::Frame(std::byte* bytes, ssize_t rows, ssize_t cols): + rows(rows), cols(cols) { + data = new DataType[rows*cols]; + std::memcpy(data, bytes, rows*cols*sizeof(DataType)); + } -FrameImpl::FrameImpl(std::byte* bytes, ssize_t rows, ssize_t cols, ssize_t bitdepth) - { - this->rows = rows; - this->cols = cols; - data = new std::byte[rows * cols*bitdepth/8]; - std::memcpy(data, bytes, bitdepth/8 * rows * cols); -} -std::byte* FrameImpl::get(int row, int col) { + +template +DataType Frame::get(int row, int col) { if (row < 0 || row >= rows || col < 0 || col >= cols) { std::cerr << "Invalid row or column index" << std::endl; return 0; } - return data+(row * cols + col)*bitdepth/8; - - + return data[row*cols + col]; } + +template class Frame; diff --git a/src/core/Frame.hpp b/src/core/Frame.hpp index cbd65b2..1aeef3e 100644 --- a/src/core/Frame.hpp +++ b/src/core/Frame.hpp @@ -13,25 +13,21 @@ * model class * should be able to work with streams coming from files or network */ -class FrameImpl { - protected: - std::byte* data{nullptr}; - ssize_t rows{}; - ssize_t cols{}; - ssize_t bitdepth{}; - public: - FrameImpl(std::byte* fp, ssize_t rows, ssize_t cols, ssize_t bitdepth); - std::byte* get(int row, int col); - ~FrameImpl(){ - delete[] data; - } -}; -template class Frame: public FrameImpl { + +template class Frame{ + public: - Frame(std::byte* fp, ssize_t rows, ssize_t cols):FrameImpl(fp, rows, cols, sizeof(DataType)){} - DataType get(int row, int col){ - return *((DataType*) FrameImpl::get(row, col)); + ssize_t rows; + ssize_t cols; + DataType* data; + ssize_t bitdepth = sizeof(DataType)*8; + + Frame(std::byte* fp, ssize_t rows, ssize_t cols); + DataType get(int row, int col); + + ~Frame(){ + delete[] data; } }; diff --git a/src/file_io/file/File.cpp b/src/file_io/file/File.cpp index 944e477..3bcbba0 100644 --- a/src/file_io/file/File.cpp +++ b/src/file_io/file/File.cpp @@ -1,7 +1,9 @@ #include "File.hpp" - -File::~File() { +template +File::~File() { for (auto& subfile : subfiles) { delete subfile; } } + +template class File; diff --git a/src/file_io/file/File.hpp b/src/file_io/file/File.hpp index cdae0d6..42cd5d2 100644 --- a/src/file_io/file/File.hpp +++ b/src/file_io/file/File.hpp @@ -19,11 +19,11 @@ struct RawFileConfig { return true; } }; - +template class File { public: - virtual FrameImpl* get_frame(int frame_number) = 0; + virtual Frame* get_frame(int frame_number) = 0; private: using config = RawFileConfig; diff --git a/src/file_io/file/FileHandler.hpp b/src/file_io/file/FileHandler.hpp index a5cd74d..43be842 100644 --- a/src/file_io/file/FileHandler.hpp +++ b/src/file_io/file/FileHandler.hpp @@ -1,24 +1,23 @@ #include #include "FileFactory.hpp" #include "File.hpp" +template class FileHandler{ private: std::filesystem::path fpath; - FileFactory* fileFactory; - File* f; + FileFactory* fileFactory; + File* f; public: - FileHandler(std::filesystem::path fpath){ + FileHandler(std::filesystem::path fpath){ this->fpath = fpath; - this->fileFactory= FileFactory::get_factory(fpath); + this->fileFactory= FileFactory::get_factory(fpath); this->f= fileFactory->load_file(); delete fileFactory; } - template Frame* get_frame(int index){ - FrameImpl* frame =f->get_frame(index); - return static_cast*>(frame); + return f->get_frame(index); } diff --git a/src/file_io/file/JsonFile.cpp b/src/file_io/file/JsonFile.cpp index c6c424f..64602b2 100644 --- a/src/file_io/file/JsonFile.cpp +++ b/src/file_io/file/JsonFile.cpp @@ -1,17 +1,18 @@ #include "JsonFile.hpp" #include -FrameImpl* JsonFile::get_frame(int frame_number){ - int subfile_id=frame_number/max_frames_per_file; +template +Frame* JsonFile::get_frame(int frame_number){ + int subfile_id=frame_number/this->max_frames_per_file; std::byte* buffer; - size_t frame_size = subfiles[subfile_id]->bytes_per_frame(); + size_t frame_size = this->subfiles[subfile_id]->bytes_per_frame(); buffer = new std::byte[frame_size]; - subfiles[subfile_id]->get_frame(buffer, frame_number%max_frames_per_file); + this->subfiles[subfile_id]->get_frame(buffer, frame_number%this->max_frames_per_file); - auto f = new FrameImpl(buffer, rows, cols, bitdepth); + auto f = new Frame(buffer, this->rows, this->cols); delete[] buffer; return f; @@ -20,4 +21,7 @@ FrameImpl* JsonFile::get_frame(int frame_number){ -} \ No newline at end of file +} + +template class JsonFile; + diff --git a/src/file_io/file/JsonFile.hpp b/src/file_io/file/JsonFile.hpp index 40b8440..a5285c4 100644 --- a/src/file_io/file/JsonFile.hpp +++ b/src/file_io/file/JsonFile.hpp @@ -1,11 +1,9 @@ #pragma once +#include "File.hpp" #include "Frame.hpp" #include "defs.hpp" -#include "File.hpp" +template +class JsonFile : public File { -class JsonFile: public File -{ - - FrameImpl* get_frame(int frame_number); - + Frame *get_frame(int frame_number); }; \ No newline at end of file diff --git a/src/file_io/file_factory/FileFactory.cpp b/src/file_io/file_factory/FileFactory.cpp index 750b75b..51018ab 100644 --- a/src/file_io/file_factory/FileFactory.cpp +++ b/src/file_io/file_factory/FileFactory.cpp @@ -1,35 +1,34 @@ #include "FileFactory.hpp" #include "File.hpp" -#include "RawFileFactory.hpp" #include "JsonFileFactory.hpp" +#include "RawFileFactory.hpp" #include - - - FileFactory* FileFactory::get_factory(std::filesystem::path fpath, uint16_t bitdepth){ +template +FileFactory *FileFactory::get_factory(std::filesystem::path fpath) { // check if file exists - if(!std::filesystem::exists(fpath)){ + if (!std::filesystem::exists(fpath)) { throw std::runtime_error("File does not exist"); } - if(fpath.extension() == ".raw"){ - std::cout<<"Loading raw file"<(fpath); } - else if(fpath.extension() == ".json"){ - std::cout<<"Loading json file"< +void FileFactory::parse_fname(File *file) { file->base_path = fpath.parent_path(); file->base_name = fpath.stem(); file->ext = fpath.extension(); @@ -40,23 +39,22 @@ void FileFactory::parse_fname(File* file) { file->base_name.erase(pos); } -template - Header FileFactory::read_header(const std::filesystem::path &fname) { - Header h{}; +template +sls_detector_header FileFactory::read_header(const std::filesystem::path &fname) { + sls_detector_header h{}; FILE *fp = fopen(fname.c_str(), "r"); if (!fp) - throw std::runtime_error( - fmt::format("Could not open: {} for reading", fname.c_str())); + throw std::runtime_error(fmt::format("Could not open: {} for reading", fname.c_str())); size_t rc = fread(reinterpret_cast(&h), sizeof(h), 1, fp); fclose(fp); if (rc != 1) throw std::runtime_error("Could not read header from file"); return h; - } -void FileFactory::find_geometry(File* file) { +template +void FileFactory::find_geometry(File *file) { uint16_t r{}; uint16_t c{}; for (int i = 0; i != file->n_subfiles; ++i) { @@ -73,4 +71,6 @@ void FileFactory::find_geometry(File* file) { file->cols = c * file->subfile_cols; file->rows += (r - 1) * file->cfg.module_gap_row; -} \ No newline at end of file +} + +template class FileFactory; diff --git a/src/file_io/file_factory/FileFactory.hpp b/src/file_io/file_factory/FileFactory.hpp index 65ad3e5..0826c2a 100644 --- a/src/file_io/file_factory/FileFactory.hpp +++ b/src/file_io/file_factory/FileFactory.hpp @@ -1,25 +1,25 @@ #pragma once #include #include "File.hpp" - +template class FileFactory{ // Class that will be used to create File objects // follows the factory pattern protected: std::filesystem::path fpath; - uint16_t bitdepth; public: - static FileFactory* get_factory(std::filesystem::path,uint16_t bitdepth=16); + 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 File* load_file()=0;//TODO: add option to load all file to memory or keep it on disk + virtual void parse_metadata(File*)=0; - void find_geometry(File*); - void parse_fname(File*); + void find_geometry(File*); + void parse_fname(File*); - template Header read_header(const std::filesystem::path &fname); + sls_detector_header read_header(const std::filesystem::path &fname); }; + diff --git a/src/file_io/file_factory/JsonFileFactory.cpp b/src/file_io/file_factory/JsonFileFactory.cpp index 00be1f7..ce4a1b7 100644 --- a/src/file_io/file_factory/JsonFileFactory.cpp +++ b/src/file_io/file_factory/JsonFileFactory.cpp @@ -9,14 +9,15 @@ using json = nlohmann::json; -JsonFileFactory::JsonFileFactory(std::filesystem::path fpath, uint16_t bitdepth=16) { +template +JsonFileFactory::JsonFileFactory(std::filesystem::path fpath) { if (not is_master_file(fpath)) throw std::runtime_error("Json file is not a master file"); this->fpath = fpath; - this->bitdepth = bitdepth; } -void JsonFileFactory::parse_metadata(File *file) { +template +void JsonFileFactory::parse_metadata(File *file) { std::cout << "Parsing metadata" << std::endl; std::ifstream ifs(file->master_fname()); json j; @@ -25,6 +26,9 @@ void JsonFileFactory::parse_metadata(File *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"]; @@ -36,9 +40,9 @@ void JsonFileFactory::parse_metadata(File *file) { std::cerr << "master file does not have Dynamic Range. Defaulting to 16 bit" << '\n'; file->bitdepth = 16; } - // if (file->bitdepth != this->bitdepth) - // throw std::runtime_error("Bitdepth mismatch: file bitdepth (" + std::to_string(file->bitdepth) + - // ") != specified bitdepth (" + std::to_string(this->bitdepth) + ")"); + 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) { @@ -46,7 +50,8 @@ void JsonFileFactory::parse_metadata(File *file) { } } -void JsonFileFactory::open_subfiles(File *file) { +template +void JsonFileFactory::open_subfiles(File *file) { for (int i = 0; i != file->n_subfiles; ++i) { file->subfiles.push_back( @@ -54,10 +59,11 @@ void JsonFileFactory::open_subfiles(File *file) { } } -File *JsonFileFactory::load_file() { +template +File *JsonFileFactory::load_file() { std::cout << "Loading json file" << std::endl; - JsonFile *file = new JsonFile(); - file->fname = fpath; + JsonFile *file = new JsonFile(); + file->fname = this->fpath; this->parse_fname(file); this->parse_metadata(file); file->find_number_of_subfiles(); @@ -65,4 +71,6 @@ File *JsonFileFactory::load_file() { this->open_subfiles(file); return file; -} \ No newline at end of file +} + +template class JsonFileFactory; \ No newline at end of file diff --git a/src/file_io/file_factory/JsonFileFactory.hpp b/src/file_io/file_factory/JsonFileFactory.hpp index c9bd947..b178a80 100644 --- a/src/file_io/file_factory/JsonFileFactory.hpp +++ b/src/file_io/file_factory/JsonFileFactory.hpp @@ -1,14 +1,14 @@ #include "FileFactory.hpp" - -class JsonFileFactory: public FileFactory +template +class JsonFileFactory: public FileFactory { private: /* data */ public: - File* load_file() override; - void parse_metadata(File*) override; - JsonFileFactory(std::filesystem::path fpath, uint16_t bitdepth); - void open_subfiles(File*); + File* load_file() override; + void parse_metadata(File*) override; + JsonFileFactory(std::filesystem::path fpath); + void open_subfiles(File*); diff --git a/src/file_io/file_factory/RawFileFactory.hpp b/src/file_io/file_factory/RawFileFactory.hpp index 2c0ca8c..89ee537 100644 --- a/src/file_io/file_factory/RawFileFactory.hpp +++ b/src/file_io/file_factory/RawFileFactory.hpp @@ -1,9 +1,9 @@ #include "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/src/main.cpp b/src/main.cpp index d6b4f90..7ca38f8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,9 +1,15 @@ // Your First C++ Program #include #include -void test(FileHandler* f,int frame_number){ + +using JFileHandler = FileHandler; +using JFile = File; +using JFrame = Frame; + + +void test(JFileHandler* f,int frame_number){ std::cout << "frame number: " << frame_number << std::endl; - Frame16* frame = f->get_frame(frame_number); + JFrame* frame = f->get_frame(frame_number); std::cout << frame->get(0,0) << ' '; std::cout << frame->get(0,1) << ' '; std::cout << frame->get(1,0) << ' '; @@ -14,8 +20,7 @@ void test(FileHandler* f,int frame_number){ int main() { std::filesystem::path fpath("/home/l_bechir/github/aare/data/jungfrau_single_master_0.json"); - FileHandler* fileHandler = new FileHandler(fpath); - test(fileHandler,0); + auto fileHandler = new JFileHandler (fpath); delete fileHandler;