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);
using DataTypeVariants = std::variant<uint16_t, uint32_t>;

View File

@ -2,7 +2,7 @@
#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->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::byte* IFrame::get(int row, int col) {
std::byte* FrameImpl::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;

View File

@ -13,24 +13,29 @@
* model class
* should be able to work with streams coming from files or network
*/
class IFrame {
class FrameImpl {
protected:
std::byte* data{nullptr};
ssize_t rows{};
ssize_t cols{};
ssize_t bitdepth{};
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);
~IFrame(){
~FrameImpl(){
delete[] data;
}
};
template <class DataType> class Frame: public IFrame {
template <class DataType> class Frame: public FrameImpl {
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){
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
#include "Frame.hpp"
#include "SubFile.hpp"
#include "defs.hpp"
#include <filesystem>
#include <fmt/core.h>
#include "SubFile.hpp"
#include <iostream>
#include "Frame.hpp"
struct RawFileConfig {
int module_gap_row{};
@ -23,13 +20,16 @@ struct RawFileConfig {
}
};
class File {
private:
using config = RawFileConfig;
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 base_path;
std::string base_name, ext;
@ -49,13 +49,13 @@ class File {
using data_type = uint16_t;
std::vector<xy> positions;
config cfg{0,0};
config cfg{0, 0};
// File();
~File();
inline size_t bytes_per_frame() const { return rows * cols * bitdepth / 8; }
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_col = col;
}
@ -63,21 +63,17 @@ class File {
// TODO! Deal with fast quad and missing files
void find_number_of_subfiles() {
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;
}
inline std::filesystem::path master_fname() {
return base_path /
fmt::format("{}_master_{}{}", base_name, findex, ext);
return base_path / fmt::format("{}_master_{}{}", base_name, findex, ext);
}
inline std::filesystem::path data_fname(int mod_id, int file_id) {
return base_path / fmt::format("{}_d{}_f{}_{}.raw", base_name, file_id,
mod_id, findex);
return base_path / fmt::format("{}_d{}_f{}_{}.raw", base_name, file_id, mod_id, findex);
}
virtual Frame<uint16_t> get_frame(int frame_number)=0;
// 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 <typeinfo>
template <class T>
Frame<T> JsonFile::get_frame(int frame_number){
FrameImpl* JsonFile::get_frame(int frame_number){
int subfile_id=frame_number/max_frames_per_file;
std::byte* buffer;
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;
return f;

View File

@ -5,9 +5,7 @@
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->cols = cols;
this->fname = fname;
this->bitdepth = bitdepth;
fp = fopen(fname.c_str(), "rb");
if (fp == nullptr) {
throw std::runtime_error("Could not open file " + fname.string());
}
std::cout<<"File opened"<<std::endl;
n_frames = std::filesystem::file_size(fname) / (sizeof(Header) + rows * cols * sizeof(DataType));
std::cout<<"Number of frames: "<<n_frames<<std::endl;
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 (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");
}
}
template <class Header, class DataType>
size_t SubFile<Header, DataType>::get_frame(std::byte *buffer, int frame_number) {
size_t SubFile::get_frame(std::byte *buffer, int frame_number) {
if (frame_number >= n_frames or frame_number < 0) {
throw std::runtime_error("Frame number out of range");
}
fseek(fp, sizeof(Header)+(sizeof(Header) + bytes_per_frame()) *frame_number, SEEK_SET);
return read_impl(buffer);
fseek(fp, sizeof(sls_detector_header) + (sizeof(sls_detector_header) + bytes_per_frame()) * frame_number, SEEK_SET);
return (this->*read_impl)(buffer);
}
/**
* 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){};
size_t SubFile::read_impl_normal(std::byte *buffer) { return fread(buffer, this->bytes_per_frame(), 1, this->fp); }
template <class Header, class DataType> size_t NormalSubFile<Header, DataType>::read_impl(std::byte *buffer) {
return fread(buffer, this->bytes_per_frame(), 1, this->fp);
};
template <typename DataType> size_t SubFile::read_impl_reorder(std::byte *buffer) {
/**
* 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());
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;
};
template <typename DataType> size_t SubFile::read_impl_flip(std::byte *buffer) {
template class NormalSubFile<sls_detector_header, uint16_t>;
template class NormalSubFile<sls_detector_header, uint32_t>;
template class ReorderM03SubFile<sls_detector_header, uint16_t>;
// read to temporary buffer
// TODO! benchmark direct reads
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);
// template size_t ReorderM03SubFile<sls_detector_header, uint32_t>::read_impl(std::byte *buffer);
// copy to place
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);
// template size_t NormalSubFile<sls_detector_header, uint16_t>::read_impl(std::byte *buffer);
for (int i = 0; i != this->rows; ++i) {
memcpy(dst, src, row_size);
dst -= row_size;
src += row_size;
}
return rc;
};

View File

@ -4,50 +4,29 @@
#include <filesystem>
#include <variant>
class SubFileBase {
class SubFile {
protected:
FILE *fp = nullptr;
uint16_t bitdepth;
public:
virtual inline size_t bytes_per_frame() =0;
virtual inline size_t pixels_per_frame() =0;
std::filesystem::path fname;
// 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;
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 cols{};
ssize_t n_frames{};
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
if(!std::filesystem::exists(fpath)){
throw std::runtime_error("File does not exist");
@ -18,7 +18,7 @@
}
else if(fpath.extension() == ".json"){
std::cout<<"Loading json file"<<std::endl;
return new JsonFileFactory(fpath);
return new JsonFileFactory(fpath, bitdepth);
}
//check if extension is numpy
else if(fpath.extension() == ".npy"){

View File

@ -7,10 +7,11 @@ class FileFactory{
// follows the factory pattern
protected:
std::filesystem::path fpath;
uint16_t bitdepth;
public:
static FileFactory* getFactory(std::filesystem::path);
static FileFactory* get_factory(std::filesystem::path,uint16_t bitdepth=16);
// 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;

View File

@ -9,13 +9,14 @@
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))
throw std::runtime_error("Json file is not a master file");
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::ifstream ifs(file->master_fname());
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';
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
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) {
if (file->type == DetectorType::Jungfrau) {
file->subfiles.push_back(new JungfrauSubFile(file->data_fname(i, 0), file->subfile_rows, file->subfile_cols));
} else if (file->type == DetectorType::Mythen3)
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->subfiles.push_back(
new SubFile(file->data_fname(i, 0), file->type, file->subfile_rows, file->subfile_cols, file->bitdepth));
}
}
File* JsonFileFactory::loadFile() {
File *JsonFileFactory::load_file() {
std::cout << "Loading json file" << std::endl;
JsonFile* file = new JsonFile();
JsonFile *file = new JsonFile();
file->fname = fpath;
this->parse_fname(file);
this->parse_metadata(file);

View File

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

View File

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