saving work

This commit is contained in:
Bechir Braham 2024-03-04 15:06:52 +01:00
parent 1bffa4a86d
commit f62cc229f9
No known key found for this signature in database
GPG Key ID: 7F511B55FD8E9671
14 changed files with 149 additions and 156 deletions

View File

@ -47,3 +47,4 @@ template <> DetectorType StringTo(std::string);
template <> TimingMode StringTo(std::string); template <> TimingMode StringTo(std::string);
using DataTypeVariants = std::variant<uint16_t, uint32_t>; using DataTypeVariants = std::variant<uint16_t, uint32_t>;

View File

@ -2,7 +2,7 @@
#include <iostream> #include <iostream>
IFrame::IFrame(std::byte* bytes, ssize_t rows, ssize_t cols, ssize_t bitdepth) FrameImpl::FrameImpl(std::byte* bytes, ssize_t rows, ssize_t cols, ssize_t bitdepth)
{ {
this->rows = rows; this->rows = rows;
this->cols = cols; this->cols = cols;
@ -10,7 +10,7 @@ IFrame::IFrame(std::byte* bytes, ssize_t rows, ssize_t cols, ssize_t bitdepth)
std::memcpy(data, bytes, bitdepth/8 * rows * cols); std::memcpy(data, bytes, bitdepth/8 * rows * cols);
} }
std::byte* IFrame::get(int row, int col) { std::byte* FrameImpl::get(int row, int col) {
if (row < 0 || row >= rows || col < 0 || col >= cols) { if (row < 0 || row >= rows || col < 0 || col >= cols) {
std::cerr << "Invalid row or column index" << std::endl; std::cerr << "Invalid row or column index" << std::endl;
return 0; return 0;

View File

@ -13,24 +13,29 @@
* model class * model class
* should be able to work with streams coming from files or network * should be able to work with streams coming from files or network
*/ */
class IFrame { class FrameImpl {
protected:
std::byte* data{nullptr}; std::byte* data{nullptr};
ssize_t rows{}; ssize_t rows{};
ssize_t cols{}; ssize_t cols{};
ssize_t bitdepth{}; ssize_t bitdepth{};
public: public:
IFrame(std::byte* fp, ssize_t rows, ssize_t cols, ssize_t bitdepth); FrameImpl(std::byte* fp, ssize_t rows, ssize_t cols, ssize_t bitdepth);
std::byte* get(int row, int col); std::byte* get(int row, int col);
~IFrame(){ ~FrameImpl(){
delete[] data; delete[] data;
} }
}; };
template <class DataType> class Frame: public IFrame { template <class DataType> class Frame: public FrameImpl {
public: public:
Frame(std::byte* fp, ssize_t rows, ssize_t cols):IFrame(fp, rows, cols, sizeof(DataType)){} Frame(std::byte* fp, ssize_t rows, ssize_t cols):FrameImpl(fp, rows, cols, sizeof(DataType)){}
DataType get(int row, int col){ DataType get(int row, int col){
return *((DataType*) IFrame::get(row, col)); return *((DataType*) FrameImpl::get(row, col));
} }
};
};
typedef Frame<uint16_t> Frame16;
typedef Frame<uint8_t> Frame8;
typedef Frame<uint32_t> Frame32;

View File

@ -1,14 +1,11 @@
#pragma once #pragma once
#include "Frame.hpp"
#include "SubFile.hpp"
#include "defs.hpp" #include "defs.hpp"
#include <filesystem> #include <filesystem>
#include <fmt/core.h> #include <fmt/core.h>
#include "SubFile.hpp"
#include <iostream> #include <iostream>
#include "Frame.hpp"
struct RawFileConfig { struct RawFileConfig {
int module_gap_row{}; int module_gap_row{};
@ -23,13 +20,16 @@ struct RawFileConfig {
} }
}; };
class File { class File {
private:
using config = RawFileConfig;
public: public:
std::vector<SubFileBase*> subfiles; virtual FrameImpl* get_frame(int frame_number) = 0;
private:
using config = RawFileConfig;
public:
std::vector<SubFile*> subfiles;
std::filesystem::path fname; std::filesystem::path fname;
std::filesystem::path base_path; std::filesystem::path base_path;
std::string base_name, ext; std::string base_name, ext;
@ -49,13 +49,13 @@ class File {
using data_type = uint16_t; using data_type = uint16_t;
std::vector<xy> positions; std::vector<xy> positions;
config cfg{0,0}; config cfg{0, 0};
// File(); // File();
~File(); ~File();
inline size_t bytes_per_frame() const { return rows * cols * bitdepth / 8; } inline size_t bytes_per_frame() const { return rows * cols * bitdepth / 8; }
inline size_t pixels() const { return rows * cols; } inline size_t pixels() const { return rows * cols; }
inline void set_config(int row,int col){ inline void set_config(int row, int col) {
cfg.module_gap_row = row; cfg.module_gap_row = row;
cfg.module_gap_col = col; cfg.module_gap_col = col;
} }
@ -63,21 +63,17 @@ class File {
// TODO! Deal with fast quad and missing files // TODO! Deal with fast quad and missing files
void find_number_of_subfiles() { void find_number_of_subfiles() {
int n_mod = 0; int n_mod = 0;
while (std::filesystem::exists(data_fname(++n_mod, 0))); while (std::filesystem::exists(data_fname(++n_mod, 0)))
;
n_subfiles = n_mod; n_subfiles = n_mod;
} }
inline std::filesystem::path master_fname() { inline std::filesystem::path master_fname() {
return base_path / return base_path / fmt::format("{}_master_{}{}", base_name, findex, ext);
fmt::format("{}_master_{}{}", base_name, findex, ext);
} }
inline std::filesystem::path data_fname(int mod_id, int file_id) { inline std::filesystem::path data_fname(int mod_id, int file_id) {
return base_path / fmt::format("{}_d{}_f{}_{}.raw", base_name, file_id, return base_path / fmt::format("{}_d{}_f{}_{}.raw", base_name, file_id, mod_id, findex);
mod_id, findex);
} }
virtual Frame<uint16_t> get_frame(int frame_number)=0;
// size_t total_frames(); // size_t total_frames();
}; };

View File

@ -0,0 +1,29 @@
#include <filesystem>
#include "FileFactory.hpp"
#include "File.hpp"
class FileHandler{
private:
std::filesystem::path fpath;
FileFactory* fileFactory;
File* f;
public:
FileHandler(std::filesystem::path fpath){
this->fpath = fpath;
this->fileFactory= FileFactory::get_factory(fpath);
this->f= fileFactory->load_file();
delete fileFactory;
}
template <typename DataType>
Frame<DataType>* get_frame(int index){
FrameImpl* frame =f->get_frame(index);
return static_cast<Frame<DataType>*>(frame);
}
~FileHandler(){
delete f;
}
};

View File

@ -1,8 +1,7 @@
#include "JsonFile.hpp" #include "JsonFile.hpp"
#include <typeinfo> #include <typeinfo>
template <class T> FrameImpl* JsonFile::get_frame(int frame_number){
Frame<T> JsonFile::get_frame(int frame_number){
int subfile_id=frame_number/max_frames_per_file; int subfile_id=frame_number/max_frames_per_file;
std::byte* buffer; std::byte* buffer;
size_t frame_size = subfiles[subfile_id]->bytes_per_frame(); size_t frame_size = subfiles[subfile_id]->bytes_per_frame();
@ -12,7 +11,7 @@ Frame<T> JsonFile::get_frame(int frame_number){
auto f = Frame<T>(buffer, rows, cols); auto f = new FrameImpl(buffer, rows, cols, bitdepth);
delete[] buffer; delete[] buffer;
return f; return f;

View File

@ -5,9 +5,7 @@
class JsonFile: public File class JsonFile: public File
{ {
template <class T>
Frame<T> get_frame(int frame_number);
IFrame get_frame(int frame_number); FrameImpl* get_frame(int frame_number);
}; };

View File

@ -7,52 +7,42 @@
* *
* *
*/ */
template <class Header, class DataType>
SubFile<Header, DataType>::SubFile(std::filesystem::path fname, ssize_t rows, ssize_t cols) { SubFile::SubFile(std::filesystem::path fname, DetectorType detector, ssize_t rows, ssize_t cols, uint16_t bitdepth) {
this->rows = rows; this->rows = rows;
this->cols = cols; this->cols = cols;
this->fname = fname; this->fname = fname;
this->bitdepth = bitdepth;
fp = fopen(fname.c_str(), "rb"); fp = fopen(fname.c_str(), "rb");
if (fp == nullptr) { if (fp == nullptr) {
throw std::runtime_error("Could not open file " + fname.string()); throw std::runtime_error("Could not open file " + fname.string());
} }
std::cout<<"File opened"<<std::endl; std::cout << "File opened" << std::endl;
n_frames = std::filesystem::file_size(fname) / (sizeof(Header) + rows * cols * sizeof(DataType)); n_frames = std::filesystem::file_size(fname) / (sizeof(sls_detector_header) + rows * cols * bitdepth / 8);
std::cout<<"Number of frames: "<<n_frames<<std::endl; std::cout << "Number of frames: " << n_frames << std::endl;
if (detector == DetectorType::Moench) {
read_impl = &SubFile::read_impl_reorder<uint16_t>;
} 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) {
template <class Header, class DataType>
size_t SubFile<Header, DataType>::get_frame(std::byte *buffer, int frame_number) {
if (frame_number >= n_frames or frame_number < 0) { if (frame_number >= n_frames or frame_number < 0) {
throw std::runtime_error("Frame number out of range"); throw std::runtime_error("Frame number out of range");
} }
fseek(fp, sizeof(Header)+(sizeof(Header) + bytes_per_frame()) *frame_number, SEEK_SET); fseek(fp, sizeof(sls_detector_header) + (sizeof(sls_detector_header) + bytes_per_frame()) * frame_number, SEEK_SET);
return read_impl(buffer); return (this->*read_impl)(buffer);
} }
/** size_t SubFile::read_impl_normal(std::byte *buffer) { return fread(buffer, this->bytes_per_frame(), 1, this->fp); }
* NormalSubFile methods
*/
template <class Header, class DataType>
NormalSubFile<Header, DataType>::NormalSubFile(std::filesystem::path fname, ssize_t rows, ssize_t cols)
: SubFile<Header, DataType>(fname, rows, cols){};
template <class Header, class DataType> size_t NormalSubFile<Header, DataType>::read_impl(std::byte *buffer) { template <typename DataType> size_t SubFile::read_impl_reorder(std::byte *buffer) {
return fread(buffer, this->bytes_per_frame(), 1, this->fp);
};
/**
* ReorderM03SubFile methods
*/
template <class Header, class DataType>
ReorderM03SubFile<Header, DataType>::ReorderM03SubFile(std::filesystem::path fname, ssize_t rows, ssize_t cols)
: SubFile<Header, DataType>(fname, rows, cols){};
template <class Header, class DataType>
size_t ReorderM03SubFile<Header, DataType>::read_impl(std::byte *buffer) {
std::vector<DataType> tmp(this->pixels_per_frame()); std::vector<DataType> tmp(this->pixels_per_frame());
size_t rc = fread(reinterpret_cast<char *>(&tmp[0]), this->bytes_per_frame(), 1, this->fp); size_t rc = fread(reinterpret_cast<char *>(&tmp[0]), this->bytes_per_frame(), 1, this->fp);
@ -79,13 +69,24 @@ size_t ReorderM03SubFile<Header, DataType>::read_impl(std::byte *buffer) {
} }
return rc; return rc;
}; };
template <typename DataType> size_t SubFile::read_impl_flip(std::byte *buffer) {
template class NormalSubFile<sls_detector_header, uint16_t>; // read to temporary buffer
template class NormalSubFile<sls_detector_header, uint32_t>; // TODO! benchmark direct reads
template class ReorderM03SubFile<sls_detector_header, uint16_t>; std::vector<std::byte> tmp(this->bytes_per_frame());
size_t rc = fread(reinterpret_cast<char *>(&tmp[0]), this->bytes_per_frame(), 1, this->fp);
// template size_t ReorderM03SubFile<sls_detector_header, uint16_t>::read_impl(std::byte *buffer); // copy to place
// template size_t ReorderM03SubFile<sls_detector_header, uint32_t>::read_impl(std::byte *buffer); const size_t start = this->cols * (this->rows - 1) * sizeof(DataType);
const size_t row_size = this->cols * sizeof(DataType);
auto dst = buffer + start;
auto src = &tmp[0];
// template size_t NormalSubFile<sls_detector_header, uint32_t>::read_impl(std::byte *buffer); for (int i = 0; i != this->rows; ++i) {
// template size_t NormalSubFile<sls_detector_header, uint16_t>::read_impl(std::byte *buffer); memcpy(dst, src, row_size);
dst -= row_size;
src += row_size;
}
return rc;
};

View File

@ -4,50 +4,29 @@
#include <filesystem> #include <filesystem>
#include <variant> #include <variant>
class SubFileBase { class SubFile {
protected: protected:
FILE *fp = nullptr; FILE *fp = nullptr;
uint16_t bitdepth;
public: public:
virtual inline size_t bytes_per_frame() =0; // pointer to a read_impl function. pointer will be set to the appropriate read_impl function in the constructor
virtual inline size_t pixels_per_frame() =0; size_t (SubFile::*read_impl)(std::byte *buffer) = nullptr;
std::filesystem::path fname; size_t read_impl_normal(std::byte *buffer);
template <typename DataType> size_t read_impl_flip(std::byte *buffer);
template <typename DataType> size_t read_impl_reorder(std::byte *buffer);
SubFile(std::filesystem::path fname,DetectorType detector, ssize_t rows, ssize_t cols, uint16_t bitdepth);
size_t get_frame(std::byte *buffer, int frame_number);
// TODO: define the inlines as variables and assign them in constructor
inline size_t bytes_per_frame() { return (bitdepth / 8) * rows * cols; }
inline size_t pixels_per_frame() { return rows * cols; }
std::filesystem::path fname;
ssize_t rows{}; ssize_t rows{};
ssize_t cols{}; ssize_t cols{};
ssize_t n_frames{}; ssize_t n_frames{};
int sub_file_index_{}; int sub_file_index_{};
virtual size_t read_impl(std::byte *buffer)=0;
virtual size_t get_frame(std::byte *buffer, int frame_number)=0;
}; };
template <class Header, class DataType> class SubFile : public SubFileBase{
public:
SubFile(std::filesystem::path fname, ssize_t rows, ssize_t cols);
inline size_t bytes_per_frame() override { return sizeof(DataType) * rows * cols; }
inline size_t pixels_per_frame() override { return rows * cols; }
virtual size_t read_impl(std::byte *buffer)=0;
size_t get_frame(std::byte *buffer, int frame_number);
};
template <class Header, class DataType> class NormalSubFile : public SubFile<Header, DataType> {
public:
NormalSubFile(std::filesystem::path fname, ssize_t rows, ssize_t cols);
size_t read_impl(std::byte *buffer);
};
template <class Header, class DataType> class ReorderM03SubFile : public SubFile<Header, DataType> {
public:
ReorderM03SubFile(std::filesystem::path fname, ssize_t rows, ssize_t cols);
size_t read_impl(std::byte *buffer);
};
using JungfrauSubFile = NormalSubFile<sls_detector_header, uint16_t>;
using Moench03SubFile = ReorderM03SubFile<sls_detector_header, uint16_t>;
using Mythen3SubFile = NormalSubFile<sls_detector_header, uint32_t>;
// using SubFileVariants = std::variant<JungfrauSubFile, Mythen3SubFile, Moench03SubFile>;

View File

@ -6,7 +6,7 @@
FileFactory* FileFactory::getFactory(std::filesystem::path fpath){ FileFactory* FileFactory::get_factory(std::filesystem::path fpath, uint16_t bitdepth){
// check if file exists // check if file exists
if(!std::filesystem::exists(fpath)){ if(!std::filesystem::exists(fpath)){
throw std::runtime_error("File does not exist"); throw std::runtime_error("File does not exist");
@ -18,7 +18,7 @@
} }
else if(fpath.extension() == ".json"){ else if(fpath.extension() == ".json"){
std::cout<<"Loading json file"<<std::endl; std::cout<<"Loading json file"<<std::endl;
return new JsonFileFactory(fpath); return new JsonFileFactory(fpath, bitdepth);
} }
//check if extension is numpy //check if extension is numpy
else if(fpath.extension() == ".npy"){ else if(fpath.extension() == ".npy"){

View File

@ -7,10 +7,11 @@ class FileFactory{
// follows the factory pattern // follows the factory pattern
protected: protected:
std::filesystem::path fpath; std::filesystem::path fpath;
uint16_t bitdepth;
public: public:
static FileFactory* getFactory(std::filesystem::path); static FileFactory* get_factory(std::filesystem::path,uint16_t bitdepth=16);
// virtual int deleteFile() = 0; // virtual int deleteFile() = 0;
virtual File* loadFile()=0;//TODO: add option to load all file to memory or keep it on disk 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_metadata(File*)=0;

View File

@ -9,13 +9,14 @@
using json = nlohmann::json; using json = nlohmann::json;
JsonFileFactory::JsonFileFactory(std::filesystem::path fpath) { JsonFileFactory::JsonFileFactory(std::filesystem::path fpath, uint16_t bitdepth=16) {
if (not is_master_file(fpath)) if (not is_master_file(fpath))
throw std::runtime_error("Json file is not a master file"); throw std::runtime_error("Json file is not a master file");
this->fpath = fpath; this->fpath = fpath;
this->bitdepth = bitdepth;
} }
void JsonFileFactory::parse_metadata(File* file) { void JsonFileFactory::parse_metadata(File *file) {
std::cout << "Parsing metadata" << std::endl; std::cout << "Parsing metadata" << std::endl;
std::ifstream ifs(file->master_fname()); std::ifstream ifs(file->master_fname());
json j; json j;
@ -35,6 +36,9 @@ void JsonFileFactory::parse_metadata(File* file) {
std::cerr << "master file does not have Dynamic Range. Defaulting to 16 bit" << '\n'; std::cerr << "master file does not have Dynamic Range. Defaulting to 16 bit" << '\n';
file->bitdepth = 16; 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) + ")");
// only Eiger had quad // only Eiger had quad
if (file->type == DetectorType::Eiger) { if (file->type == DetectorType::Eiger) {
@ -42,22 +46,17 @@ void JsonFileFactory::parse_metadata(File* file) {
} }
} }
void JsonFileFactory::open_subfiles(File* file) { void JsonFileFactory::open_subfiles(File *file) {
for (int i = 0; i != file->n_subfiles; ++i) { for (int i = 0; i != file->n_subfiles; ++i) {
if (file->type == DetectorType::Jungfrau) {
file->subfiles.push_back(new JungfrauSubFile(file->data_fname(i, 0), file->subfile_rows, file->subfile_cols)); file->subfiles.push_back(
} else if (file->type == DetectorType::Mythen3) new SubFile(file->data_fname(i, 0), file->type, file->subfile_rows, file->subfile_cols, file->bitdepth));
file->subfiles.push_back(new Mythen3SubFile(file->data_fname(i, 0), file->subfile_rows, file->subfile_cols));
else if (file->type == DetectorType::Moench)
file->subfiles.push_back(new Moench03SubFile(file->data_fname(i, 0), file->subfile_rows, file->subfile_cols));
else
throw std::runtime_error("File not supported");
} }
} }
File* JsonFileFactory::loadFile() { File *JsonFileFactory::load_file() {
std::cout << "Loading json file" << std::endl; std::cout << "Loading json file" << std::endl;
JsonFile* file = new JsonFile(); JsonFile *file = new JsonFile();
file->fname = fpath; file->fname = fpath;
this->parse_fname(file); this->parse_fname(file);
this->parse_metadata(file); this->parse_metadata(file);

View File

@ -5,9 +5,9 @@ class JsonFileFactory: public FileFactory
private: private:
/* data */ /* data */
public: public:
File* loadFile() override; File* load_file() override;
void parse_metadata(File*) override; void parse_metadata(File*) override;
JsonFileFactory(std::filesystem::path fpath); JsonFileFactory(std::filesystem::path fpath, uint16_t bitdepth);
void open_subfiles(File*); void open_subfiles(File*);

View File

@ -1,37 +1,22 @@
// Your First C++ Program // Your First C++ Program
#include <iostream> #include <iostream>
#include "file_io/file_factory/FileFactory.hpp" #include <FileHandler.hpp>
void test(FileHandler* f,int frame_number){
void test(File* f,int frame_number){
std::cout << "frame number: " << frame_number << std::endl; std::cout << "frame number: " << frame_number << std::endl;
auto frame = f->get_frame(frame_number); Frame16* frame = f->get_frame<uint16_t>(frame_number);
std::cout << frame.get(0,0) << ' '; std::cout << frame->get(0,0) << ' ';
std::cout << frame.get(0,1) << ' '; std::cout << frame->get(0,1) << ' ';
std::cout << frame.get(1,0) << ' '; std::cout << frame->get(1,0) << ' ';
std::cout << frame.get(511,1023) << std::endl; std::cout << frame->get(511,1023) << std::endl;
delete frame;
} }
int main() { int main() {
FileFactory* fileFactory=FileFactory::getFactory(std::filesystem::path("/home/l_bechir/github/aare")/"data"/"jungfrau_single_master_0.json"); std::filesystem::path fpath("/home/l_bechir/github/aare/data/jungfrau_single_master_0.json");
File* f = fileFactory->loadFile(); FileHandler* fileHandler = new FileHandler(fpath);
test(fileHandler,0);
test(f,0); delete fileHandler;
test(f,1);
test(f,2);
test(f,3);
test(f,4);
test(f,5);
test(f,6);
test(f,7);
test(f,8);
test(f,9);
delete fileFactory;
delete f;
} }