remove templates

This commit is contained in:
Bechir Braham
2024-03-20 13:14:14 +01:00
parent 4da9bc0813
commit cd905e96f3
25 changed files with 223 additions and 200 deletions

View File

@ -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

View File

@ -8,11 +8,10 @@
#include <iostream>
template <DetectorType detector, typename DataType>
class File {
public:
virtual Frame<DataType>* 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();

View File

@ -1,18 +1,17 @@
#pragma once
#include <filesystem>
#include "aare/File.hpp"
template <DetectorType detector,typename DataType>
class FileFactory{
// Class that will be used to create File objects
// follows the factory pattern
protected:
std::filesystem::path m_fpath;
public:
static FileFactory<detector,DataType>* get_factory(std::filesystem::path);
static FileFactory* get_factory(std::filesystem::path);
// virtual int deleteFile() = 0;
virtual File<detector,DataType>* load_file()=0;//TODO: add option to load all file to memory or keep it on disk
virtual void parse_metadata(File<detector,DataType>*)=0;
virtual void parse_fname(File<detector,DataType>*)=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;

View File

@ -2,22 +2,21 @@
#include "aare/FileFactory.hpp"
#include "aare/File.hpp"
template <DetectorType detector,typename DataType>
class FileHandler{
private:
std::filesystem::path fpath;
FileFactory<detector,DataType>* fileFactory;
File<detector,DataType>* f;
FileFactory* fileFactory;
File* f;
public:
FileHandler<detector,DataType>(std::filesystem::path fname){
FileHandler(std::filesystem::path fname){
this->fpath = fname;
this->fileFactory= FileFactory<detector,DataType>::get_factory(fname);
this->fileFactory= FileFactory::get_factory(fname);
this->f= fileFactory->load_file();
delete fileFactory;
}
Frame<DataType>* get_frame(int index){
Frame* get_frame(int index){
return f->get_frame(index);
}

View File

@ -4,12 +4,12 @@
#include "aare/File.hpp"
template <DetectorType detector, typename DataType> class JsonFile : public File<detector, DataType> {
class JsonFile : public File {
using config = RawFileConfig;
public:
Frame<DataType> *get_frame(size_t frame_number);
Frame *get_frame(size_t frame_number);
int n_subfiles;
std::vector<SubFile *> subfiles;
int subfile_rows, subfile_cols;

View File

@ -1,17 +1,16 @@
#include "aare/FileFactory.hpp"
template <DetectorType detector,typename DataType>
class JsonFileFactory: public FileFactory<detector,DataType>
class JsonFileFactory: public FileFactory
{
private:
/* data */
public:
JsonFileFactory(std::filesystem::path fpath);
File<detector,DataType>* load_file() override;
void parse_metadata(File<detector,DataType>*) override;
void parse_fname(File<detector,DataType>*) override;
void open_subfiles(File<detector,DataType>*);
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<detector,DataType>*);
void find_geometry(File*);

View File

@ -6,12 +6,12 @@
#include <numeric>
template <DetectorType detector, typename DataType> class NumpyFile : public File<detector, DataType> {
class NumpyFile : public File {
FILE *fp = nullptr;
public:
NumpyFile(std::filesystem::path fname);
Frame<DataType> *get_frame(size_t frame_number) override;
Frame *get_frame(size_t frame_number) override;
header_t header{};
static constexpr std::array<char, 6> magic_str{'\x93', 'N', 'U', 'M', 'P', 'Y'};
uint8_t major_ver_{};

View File

@ -6,15 +6,15 @@
template <DetectorType detector, typename DataType> class NumpyFileFactory : public FileFactory<detector, DataType> {
class NumpyFileFactory : public FileFactory {
private:
std::ifstream f;
void read_data(File<detector, DataType> *_file);
void read_data(File *_file);
public:
NumpyFileFactory(std::filesystem::path fpath);
void parse_metadata(File<detector, DataType> *_file) override;
File<detector, DataType> *load_file() override;
void parse_fname(File<detector, DataType> *){};
void parse_metadata(File *_file) override;
File *load_file() override;
void parse_fname(File*){};
};

View File

@ -1,9 +1,8 @@
#include "aare/File.hpp"
#include <filesystem>
template<DetectorType detector,typename DataType>
class RawFileFactory{
public:
// RawFileFactory();
// ~RawFileFactory();
File<detector,DataType> loadFile(std::filesystem::path fpath);
File loadFile(std::filesystem::path fpath);
};

View File

@ -3,20 +3,28 @@
#include <cstdint>
#include <filesystem>
#include <variant>
#include <map>
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<std::pair<DetectorType, int>, pfunc> read_impl_map = {
{{DetectorType::Moench, 16}, &SubFile::read_impl_reorder<uint16_t>},
{{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 <typename DataType> size_t read_impl_flip(std::byte *buffer);
template <typename DataType> size_t read_impl_reorder(std::byte *buffer);

View File

@ -4,8 +4,7 @@
#include "aare/NumpyFileFactory.hpp"
#include <iostream>
template <DetectorType detector, typename DataType>
FileFactory<detector, DataType> *FileFactory<detector, DataType>::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<detector, DataType> *FileFactory<detector, DataType>::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<detector, DataType>(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<detector, DataType>(fpath);
return new NumpyFileFactory(fpath);
}
throw std::runtime_error("Unsupported file type");
@ -29,4 +28,3 @@ FileFactory<detector, DataType> *FileFactory<detector, DataType>::get_factory(st
template class FileFactory<DetectorType::Jungfrau, uint16_t>;

View File

@ -1,7 +1,6 @@
#include "aare/JsonFile.hpp"
template <DetectorType detector, typename DataType>
Frame<DataType> *JsonFile<detector, DataType>::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<DataType> *JsonFile<detector, DataType>::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<DataType>(buffer, this->rows, this->cols);
delete[] buffer;
return f;
}
template <DetectorType detector, typename DataType>
JsonFile<detector,DataType>::~JsonFile<detector,DataType>() {
JsonFile::~JsonFile() {
for (auto& subfile : subfiles) {
delete subfile;
}
}
template class JsonFile<DetectorType::Jungfrau, uint16_t>;

View File

@ -9,16 +9,14 @@
using json = nlohmann::json;
template <DetectorType detector,typename DataType>
JsonFileFactory<detector,DataType>::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 <DetectorType detector,typename DataType>
void JsonFileFactory<detector,DataType>::parse_metadata(File<detector,DataType> *_file) {
auto file = dynamic_cast<JsonFile<detector,DataType> *>(_file);
void JsonFileFactory::parse_metadata(File*_file) {
auto file = dynamic_cast<JsonFile*>(_file);
std::ifstream ifs(file->master_fname());
json j;
ifs >> j;
@ -26,9 +24,6 @@ void JsonFileFactory<detector,DataType>::parse_metadata(File<detector,DataType>
std::cout << "Version: " << v << std::endl;
file->version = fmt::format("{:.1f}", v);
file->type = StringTo<DetectorType>(j["Detector Type"].get<std::string>());
if (file->type != detector)
throw std::runtime_error("Detector type mismatch: file type (" + toString<DetectorType>(file->type) +
") != specified type (" + toString<DetectorType>(detector) + ")");
file->timing_mode = StringTo<TimingMode>(j["Timing Mode"].get<std::string>());
file->total_frames = j["Frames in File"];
file->subfile_cols = j["Pixels"]["x"];
@ -37,22 +32,16 @@ void JsonFileFactory<detector,DataType>::parse_metadata(File<detector,DataType>
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 <DetectorType detector,typename DataType>
void JsonFileFactory<detector,DataType>::open_subfiles(File<detector,DataType> *_file) {
auto file = dynamic_cast<JsonFile<detector,DataType> *>(_file);
void JsonFileFactory::open_subfiles(File*_file) {
auto file = dynamic_cast<JsonFile*>(_file);
for (int i = 0; i != file->n_subfiles; ++i) {
file->subfiles.push_back(
@ -60,22 +49,19 @@ void JsonFileFactory<detector,DataType>::open_subfiles(File<detector,DataType> *
}
}
template <DetectorType detector,typename DataType>
File<detector,DataType> *JsonFileFactory<detector,DataType>::load_file() {
JsonFile<detector,DataType> *file = new JsonFile<detector,DataType>();
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 <DetectorType detector, typename DataType>
sls_detector_header JsonFileFactory<detector, DataType>::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<detector, DataType>::read_header(const std::
}
template <DetectorType detector, typename DataType>
void JsonFileFactory<detector, DataType>::find_geometry(File<detector, DataType> *_file) {
auto file = dynamic_cast<JsonFile<detector, DataType> *>(_file);
void JsonFileFactory::find_geometry(File* _file) {
auto file = dynamic_cast<JsonFile*>(_file);
uint16_t r{};
uint16_t c{};
for (int i = 0; i != file->n_subfiles; ++i) {
@ -110,8 +95,7 @@ void JsonFileFactory<detector, DataType>::find_geometry(File<detector, DataType>
file->rows += (r - 1) * file->cfg.module_gap_row;
}
template <DetectorType detector, typename DataType>
void JsonFileFactory<detector, DataType>::parse_fname(File<detector, DataType> *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<detector, DataType>::parse_fname(File<detector, DataType> *
}
template class JsonFileFactory<DetectorType::Jungfrau, uint16_t>;

View File

@ -1,24 +1,21 @@
#include "aare/NumpyFile.hpp"
template <DetectorType detector, typename DataType>
NumpyFile<detector, DataType>::NumpyFile(std::filesystem::path fname_){
NumpyFile::NumpyFile(std::filesystem::path fname_){
this->fname = fname_;
fp = fopen(this->fname.c_str(), "rb");
}
template <DetectorType detector, typename DataType>
Frame<DataType> *NumpyFile<detector, DataType>::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<DataType> *frame = new Frame<DataType>(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<DetectorType::Jungfrau, uint16_t>;

View File

@ -1,12 +1,10 @@
#include "aare/NumpyFileFactory.hpp"
#include "aare/NumpyHelpers.hpp"
template <DetectorType detector, typename DataType>
NumpyFileFactory<detector, DataType>::NumpyFileFactory(std::filesystem::path fpath) {
NumpyFileFactory::NumpyFileFactory(std::filesystem::path fpath) {
this->m_fpath = fpath;
}
template <DetectorType detector, typename DataType>
void NumpyFileFactory<detector, DataType>::parse_metadata(File<detector, DataType> *_file) {
auto file = dynamic_cast<NumpyFile<detector, DataType> *>(_file);
void NumpyFileFactory::parse_metadata(File *_file) {
auto file = dynamic_cast<NumpyFile*>(_file);
// open ifsteam to file
f = std::ifstream(file->fname, std::ios::binary);
// check if file exists
@ -16,7 +14,7 @@ void NumpyFileFactory<detector, DataType>::parse_metadata(File<detector, DataTyp
// read magic number
std::array<char, 6> tmp{};
f.read(tmp.data(), tmp.size());
if (tmp != NumpyFile<detector, DataType>::magic_str) {
if (tmp != NumpyFile::magic_str) {
for (auto item : tmp)
fmt::print("{}, ", int(item));
fmt::print("\n");
@ -74,19 +72,11 @@ void NumpyFileFactory<detector, DataType>::parse_metadata(File<detector, DataTyp
file->header = {dtype, fortran_order, shape};
}
template <DetectorType detector, typename DataType>
File<detector, DataType>* NumpyFileFactory<detector, DataType>::load_file() {
NumpyFile<detector, DataType> *file = new NumpyFile<detector, DataType>(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<DetectorType::Jungfrau, uint16_t>;

View File

@ -2,11 +2,7 @@
#include <iostream>
// #include <filesystem>
/**
* 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<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) {