mirror of
https://github.com/slsdetectorgroup/aare.git
synced 2025-06-13 07:47:13 +02:00
new folder structure
This commit is contained in:
10
file_io/src/File.cpp
Normal file
10
file_io/src/File.cpp
Normal file
@ -0,0 +1,10 @@
|
||||
#include "aare/File.hpp"
|
||||
|
||||
template <DetectorType detector, typename DataType>
|
||||
File<detector,DataType>::~File<detector,DataType>() {
|
||||
for (auto& subfile : subfiles) {
|
||||
delete subfile;
|
||||
}
|
||||
}
|
||||
|
||||
template class File<DetectorType::Jungfrau, uint16_t>;
|
75
file_io/src/FileFactory.cpp
Normal file
75
file_io/src/FileFactory.cpp
Normal file
@ -0,0 +1,75 @@
|
||||
#include "aare/FileFactory.hpp"
|
||||
#include "aare/File.hpp"
|
||||
#include "aare/JsonFileFactory.hpp"
|
||||
#include <iostream>
|
||||
|
||||
template <DetectorType detector, typename DataType>
|
||||
FileFactory<detector, DataType> *FileFactory<detector, DataType>::get_factory(std::filesystem::path fpath) {
|
||||
// check if file exists
|
||||
if (!std::filesystem::exists(fpath)) {
|
||||
throw std::runtime_error("File does not exist");
|
||||
}
|
||||
|
||||
if (fpath.extension() == ".raw") {
|
||||
std::cout << "Loading raw file" << std::endl;
|
||||
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);
|
||||
}
|
||||
// check if extension is numpy
|
||||
else if (fpath.extension() == ".npy") {
|
||||
std::cout << "Loading numpy file" << std::endl;
|
||||
throw std::runtime_error("Numpy file not implemented");
|
||||
}
|
||||
|
||||
throw std::runtime_error("Unsupported file type");
|
||||
}
|
||||
|
||||
template <DetectorType detector, typename DataType>
|
||||
void FileFactory<detector, DataType>::parse_fname(File<detector, DataType> *file) {
|
||||
file->base_path = fpath.parent_path();
|
||||
file->base_name = fpath.stem();
|
||||
file->ext = fpath.extension();
|
||||
|
||||
auto pos = file->base_name.rfind("_");
|
||||
file->findex = std::stoi(file->base_name.substr(pos + 1));
|
||||
pos = file->base_name.find("_master_");
|
||||
file->base_name.erase(pos);
|
||||
}
|
||||
|
||||
template <DetectorType detector, typename DataType>
|
||||
sls_detector_header FileFactory<detector, DataType>::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()));
|
||||
|
||||
size_t rc = fread(reinterpret_cast<char *>(&h), sizeof(h), 1, fp);
|
||||
fclose(fp);
|
||||
if (rc != 1)
|
||||
throw std::runtime_error("Could not read header from file");
|
||||
return h;
|
||||
}
|
||||
|
||||
template <DetectorType detector, typename DataType>
|
||||
void FileFactory<detector, DataType>::find_geometry(File<detector, DataType> *file) {
|
||||
uint16_t r{};
|
||||
uint16_t c{};
|
||||
for (int i = 0; i != file->n_subfiles; ++i) {
|
||||
auto h = this->read_header(file->data_fname(i, 0));
|
||||
r = std::max(r, h.row);
|
||||
c = std::max(c, h.column);
|
||||
|
||||
file->positions.push_back({h.row, h.column});
|
||||
}
|
||||
r++;
|
||||
c++;
|
||||
|
||||
file->rows = r * file->subfile_rows;
|
||||
file->cols = c * file->subfile_cols;
|
||||
|
||||
file->rows += (r - 1) * file->cfg.module_gap_row;
|
||||
}
|
||||
|
||||
template class FileFactory<DetectorType::Jungfrau, uint16_t>;
|
19
file_io/src/JsonFile.cpp
Normal file
19
file_io/src/JsonFile.cpp
Normal file
@ -0,0 +1,19 @@
|
||||
#include "aare/JsonFile.hpp"
|
||||
#include <typeinfo>
|
||||
|
||||
template <DetectorType detector, typename DataType>
|
||||
Frame<DataType> *JsonFile<detector, DataType>::get_frame(int frame_number) {
|
||||
int subfile_id = frame_number / this->max_frames_per_file;
|
||||
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<DataType>(buffer, this->rows, this->cols);
|
||||
|
||||
delete[] buffer;
|
||||
return f;
|
||||
}
|
||||
|
||||
template class JsonFile<DetectorType::Jungfrau, uint16_t>;
|
76
file_io/src/JsonFileFactory.cpp
Normal file
76
file_io/src/JsonFileFactory.cpp
Normal file
@ -0,0 +1,76 @@
|
||||
#include "aare/JsonFileFactory.hpp"
|
||||
#include "aare/JsonFile.hpp"
|
||||
#include "aare/SubFile.hpp"
|
||||
#include "aare/defs.hpp"
|
||||
#include "aare/helpers.hpp"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
template <DetectorType detector,typename DataType>
|
||||
JsonFileFactory<detector,DataType>::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;
|
||||
}
|
||||
|
||||
template <DetectorType detector,typename DataType>
|
||||
void JsonFileFactory<detector,DataType>::parse_metadata(File<detector,DataType> *file) {
|
||||
std::cout << "Parsing metadata" << std::endl;
|
||||
std::ifstream ifs(file->master_fname());
|
||||
json j;
|
||||
ifs >> j;
|
||||
double v = j["Version"];
|
||||
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"];
|
||||
file->subfile_rows = j["Pixels"]["y"];
|
||||
file->max_frames_per_file = j["Max Frames Per 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 <DetectorType detector,typename DataType>
|
||||
void JsonFileFactory<detector,DataType>::open_subfiles(File<detector,DataType> *file) {
|
||||
for (int i = 0; i != file->n_subfiles; ++i) {
|
||||
|
||||
file->subfiles.push_back(
|
||||
new SubFile(file->data_fname(i, 0), file->type, file->subfile_rows, file->subfile_cols, file->bitdepth));
|
||||
}
|
||||
}
|
||||
|
||||
template <DetectorType detector,typename DataType>
|
||||
File<detector,DataType> *JsonFileFactory<detector,DataType>::load_file() {
|
||||
std::cout << "Loading json file" << std::endl;
|
||||
JsonFile<detector,DataType> *file = new JsonFile<detector,DataType>();
|
||||
file->fname = this->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 class JsonFileFactory<DetectorType::Jungfrau, uint16_t>;
|
92
file_io/src/SubFile.cpp
Normal file
92
file_io/src/SubFile.cpp
Normal file
@ -0,0 +1,92 @@
|
||||
#include "aare/SubFile.hpp"
|
||||
#include <iostream>
|
||||
// #include <filesystem>
|
||||
|
||||
/**
|
||||
* SubFile methods
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
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(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");
|
||||
}
|
||||
}
|
||||
|
||||
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(sls_detector_header) + (sizeof(sls_detector_header) + bytes_per_frame()) * frame_number, SEEK_SET);
|
||||
return (this->*read_impl)(buffer);
|
||||
}
|
||||
|
||||
size_t SubFile::read_impl_normal(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) {
|
||||
|
||||
std::vector<DataType> tmp(this->pixels_per_frame());
|
||||
size_t rc = fread(reinterpret_cast<char *>(&tmp[0]), this->bytes_per_frame(), 1, this->fp);
|
||||
|
||||
int adc_nr[32] = {300, 325, 350, 375, 300, 325, 350, 375, 200, 225, 250, 275, 200, 225, 250, 275,
|
||||
100, 125, 150, 175, 100, 125, 150, 175, 0, 25, 50, 75, 0, 25, 50, 75};
|
||||
int sc_width = 25;
|
||||
int nadc = 32;
|
||||
int pixels_per_sc = 5000;
|
||||
|
||||
auto dst = reinterpret_cast<DataType *>(buffer);
|
||||
int pixel = 0;
|
||||
for (int i = 0; i != pixels_per_sc; ++i) {
|
||||
for (int i_adc = 0; i_adc != nadc; ++i_adc) {
|
||||
int col = adc_nr[i_adc] + (i % sc_width);
|
||||
int row;
|
||||
if ((i_adc / 4) % 2 == 0)
|
||||
row = 199 - int(i / sc_width);
|
||||
else
|
||||
row = 200 + int(i / sc_width);
|
||||
|
||||
dst[col + row * 400] = tmp[pixel];
|
||||
pixel++;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
};
|
||||
template <typename DataType> size_t SubFile::read_impl_flip(std::byte *buffer) {
|
||||
|
||||
// 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);
|
||||
|
||||
// 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];
|
||||
|
||||
for (int i = 0; i != this->rows; ++i) {
|
||||
memcpy(dst, src, row_size);
|
||||
dst -= row_size;
|
||||
src += row_size;
|
||||
}
|
||||
|
||||
return rc;
|
||||
};
|
11
file_io/src/helpers.cpp
Normal file
11
file_io/src/helpers.cpp
Normal file
@ -0,0 +1,11 @@
|
||||
#include "aare/helpers.hpp"
|
||||
|
||||
|
||||
bool is_master_file(std::filesystem::path fpath) {
|
||||
std::string stem = fpath.stem();
|
||||
if (stem.find("_master_") != std::string::npos)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
Reference in New Issue
Block a user