mirror of
https://github.com/slsdetectorgroup/aare.git
synced 2025-06-07 21:20:40 +02:00
added minimum mythen file reader
This commit is contained in:
parent
bd0ff3d7da
commit
e04bf6be30
@ -1,5 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <bitset>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <filesystem>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
@ -8,6 +11,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "Hdf5FileReader.hpp"
|
||||||
#include "NDArray.hpp"
|
#include "NDArray.hpp"
|
||||||
|
|
||||||
namespace aare {
|
namespace aare {
|
||||||
@ -224,6 +228,69 @@ class FlatField {
|
|||||||
std::shared_ptr<MythenDetectorSpecifications> mythen_detector;
|
std::shared_ptr<MythenDetectorSpecifications> mythen_detector;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct MythenFrame {
|
||||||
|
NDArray<uint32_t, 1> photon_counts;
|
||||||
|
double detector_angle{};
|
||||||
|
// double reference_intensity{}; not needed
|
||||||
|
std::array<bool, 3> channel_mask{};
|
||||||
|
};
|
||||||
|
|
||||||
|
/** minimal version for a mythen file reader */
|
||||||
|
class MythenFileReader : public HDF5FileReader {
|
||||||
|
|
||||||
|
public:
|
||||||
|
MythenFileReader(const std::filesystem::path &file_path_,
|
||||||
|
const std::string &file_prefix_)
|
||||||
|
: m_base_path(file_path_), file_prefix(file_prefix_) {};
|
||||||
|
|
||||||
|
MythenFrame read_frame(ssize_t frame_index) {
|
||||||
|
std::string current_file_name = m_base_path.string() + file_prefix +
|
||||||
|
std::to_string(frame_index) + ".h5";
|
||||||
|
|
||||||
|
open_file(current_file_name);
|
||||||
|
|
||||||
|
auto dataset_photon_count =
|
||||||
|
get_dataset("/entry/instrument/detector/data");
|
||||||
|
|
||||||
|
NDArray photon_counts =
|
||||||
|
dataset_photon_count.store_as_ndarray<uint32_t, 1>();
|
||||||
|
|
||||||
|
auto dataset_detector_angle =
|
||||||
|
get_dataset("/entry/instrument/NDAttributes/DetectorAngle");
|
||||||
|
|
||||||
|
double detector_angle;
|
||||||
|
|
||||||
|
dataset_detector_angle.read_into_buffer(
|
||||||
|
reinterpret_cast<std::byte *>(&detector_angle));
|
||||||
|
|
||||||
|
auto dataset_channel_number =
|
||||||
|
get_dataset("/entry/instrument/NDAttributes/CounterMask");
|
||||||
|
|
||||||
|
uint8_t channel_number;
|
||||||
|
|
||||||
|
dataset_channel_number.read_into_buffer(
|
||||||
|
reinterpret_cast<std::byte *>(&channel_number));
|
||||||
|
|
||||||
|
std::bitset<3> binary_channel_numbers(channel_number); // 1 0 0
|
||||||
|
|
||||||
|
// binary_channel_numbers.flip(); // TODO not sure where most
|
||||||
|
// significant
|
||||||
|
// bit is ask Anna again
|
||||||
|
|
||||||
|
std::array<bool, 3> channel_mask{binary_channel_numbers[2],
|
||||||
|
binary_channel_numbers[1],
|
||||||
|
binary_channel_numbers[0]};
|
||||||
|
|
||||||
|
close_file();
|
||||||
|
|
||||||
|
return MythenFrame{photon_counts, detector_angle, channel_mask};
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::filesystem::path m_base_path{};
|
||||||
|
std::string file_prefix{};
|
||||||
|
};
|
||||||
|
|
||||||
class AngleCalibration {
|
class AngleCalibration {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -300,18 +367,26 @@ class AngleCalibration {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* calculates new histogram with fixed sized angle bins
|
* calculates new histogram with fixed sized angle bins
|
||||||
* for several acquisitions at different detector angles
|
* for several acquisitions at different detector angles for given frame
|
||||||
|
* indices
|
||||||
|
* @param start_frame_index, end_frame_index gives range of frames
|
||||||
*/
|
*/
|
||||||
void calculate_fixed_bin_angle_width_histogram();
|
void
|
||||||
|
calculate_fixed_bin_angle_width_histogram(const size_t start_frame_index,
|
||||||
|
const size_t end_frame_index);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* redistributes photon counts with of histogram using one bin per strip to
|
* redistributes photon counts with of histogram using one bin per strip to
|
||||||
* histogram with fixed size angle bins
|
* histogram with fixed size angle bins
|
||||||
* @param filename where histogram is stored
|
* @param frame MythenFrame storing data from image
|
||||||
|
* @param bin_counts accumulate new photon counts
|
||||||
|
* @param new_statistical_weights accumulate new statistical weights
|
||||||
|
* @param new_errors accumulate new_errors
|
||||||
*/
|
*/
|
||||||
// TODO: pass frame or filename?
|
|
||||||
void redistribute_photon_counts_to_fixed_angle_bins(
|
void redistribute_photon_counts_to_fixed_angle_bins(
|
||||||
const std::string &filename, NDView<double, 2> new_photon_counts);
|
const MythenFrame &frame, NDView<double, 1> bin_counts,
|
||||||
|
NDView<double, 1> new_statistical_weights,
|
||||||
|
NDView<double, 1> new_errors);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// TODO: Design maybe have a struct with three vectors, store all three
|
// TODO: Design maybe have a struct with three vectors, store all three
|
||||||
@ -334,11 +409,16 @@ class AngleCalibration {
|
|||||||
|
|
||||||
std::shared_ptr<FlatField> flat_field;
|
std::shared_ptr<FlatField> flat_field;
|
||||||
|
|
||||||
NDArray<double, 2> new_photon_count_histogram;
|
NDArray<double, 1> new_photon_counts;
|
||||||
|
NDArray<double, 1> new_photon_count_errors;
|
||||||
|
|
||||||
double histogram_bin_width = 0.0036; // [degrees]
|
double histogram_bin_width = 0.0036; // [degrees]
|
||||||
|
|
||||||
double exposure_rate = 1. / MythenDetectorSpecifications::exposure_time();
|
double exposure_rate =
|
||||||
|
1. / MythenDetectorSpecifications::exposure_time(); // TODO change
|
||||||
|
|
||||||
|
std::shared_ptr<MythenFileReader>
|
||||||
|
mythen_file_reader; // TODO replace by FileInterface ptr
|
||||||
};
|
};
|
||||||
|
|
||||||
void AngleCalibration::read_initial_calibration_from_file(
|
void AngleCalibration::read_initial_calibration_from_file(
|
||||||
@ -469,41 +549,45 @@ double AngleCalibration::angular_strip_width(const size_t strip_index) {
|
|||||||
// TODO: again not sure about division order - taking abs anyway
|
// TODO: again not sure about division order - taking abs anyway
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
void AngleCalibration::calculate_fixed_bin_angle_width_histogram(
|
||||||
void AngleCalibration::calculate_fixed_bin_angle_width_histogram() {
|
const size_t start_frame_index, const size_t end_frame_index) {
|
||||||
|
|
||||||
ssize_t num_bins = mythen_detector->max_angle() / histogram_bin_width -
|
ssize_t num_bins = mythen_detector->max_angle() / histogram_bin_width -
|
||||||
mythen_detector->min_angle() /
|
mythen_detector->min_angle() /
|
||||||
histogram_bin_width; // TODO only works if negative
|
histogram_bin_width; // TODO only works if negative
|
||||||
// and positive angle
|
// and positive angle
|
||||||
new_photon_count_histogram =
|
new_photon_counts = NDArray<double, 1>(std::array<ssize_t, 1>{num_bins});
|
||||||
NDArray<double, 2>(std::array<ssize_t, 2>{num_bins, 2});
|
|
||||||
|
|
||||||
NDArray<double, 2> new_photon_counts(std::array<ssize_t, 2>(num_bins, 3),
|
new_photon_count_errors =
|
||||||
0.0);
|
NDArray<double, 1>(std::array<ssize_t, 1>{num_bins});
|
||||||
|
|
||||||
|
NDArray<double, 1> bin_counts(std::array<ssize_t, 1>{num_bins}, 0.0);
|
||||||
|
NDArray<double, 1> new_statistical_weights(std::array<ssize_t, 1>{num_bins},
|
||||||
|
1.0);
|
||||||
|
|
||||||
|
NDArray<double, 1> new_errors(std::array<ssize_t, 1>{num_bins}, 0.0);
|
||||||
|
|
||||||
|
for (size_t frame_index = start_frame_index; frame_index < end_frame_index;
|
||||||
|
++frame_index) {
|
||||||
|
MythenFrame frame = mythen_file_reader->read_frame(frame_index);
|
||||||
|
redistribute_photon_counts_to_fixed_angle_bins(
|
||||||
|
frame, new_photon_counts.view(), new_statistical_weights.view(),
|
||||||
|
new_errors.view());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ssize_t i = 0; i < new_photon_counts.size(); ++i) {
|
||||||
|
new_photon_counts[i] = bin_counts[i] / new_statistical_weights[i];
|
||||||
|
new_photon_count_errors[i] = 1.0 / sqrt(bin_counts[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
void AngleCalibration::redistribute_photon_counts_to_fixed_angle_bins(
|
void AngleCalibration::redistribute_photon_counts_to_fixed_angle_bins(
|
||||||
const std::string &filename, NDView<double, 2> new_photon_counts) {
|
const MythenFrame &frame, NDView<double, 1> bin_counts,
|
||||||
|
NDView<double, 1> new_statistical_weights, NDView<double, 1> new_errors) {
|
||||||
|
|
||||||
// TODO: do i want to have a MythenReader that reads everything e.g. angle
|
ssize_t channel = 0; // TODO handle mask - FlatField still 1d
|
||||||
// in read_frame()
|
|
||||||
double detector_angle; // read from file
|
|
||||||
double reference_intensity; // read from file - Whats the difference between
|
|
||||||
// this and flatfield
|
|
||||||
|
|
||||||
NDArray<uint32_t, 2> photon_counts; // read from file e.g read frame - maybe
|
if (frame.photon_counts.shape()[0] != mythen_detector->num_strips()) {
|
||||||
// keep it as a frame and not an NDArray
|
|
||||||
|
|
||||||
ssize_t channel = 0; // read from file photon_counts is 2d do we have to
|
|
||||||
// loop over all strategies as well - probably
|
|
||||||
|
|
||||||
if (photon_counts.shape()[0] != mythen_detector->num_strips()) {
|
|
||||||
throw std::runtime_error("wrong number of strips read");
|
throw std::runtime_error("wrong number of strips read");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -523,11 +607,11 @@ void AngleCalibration::redistribute_photon_counts_to_fixed_angle_bins(
|
|||||||
!mythen_detector->get_connected_modules()[module_index])
|
!mythen_detector->get_connected_modules()[module_index])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
double poisson_error = sqrt(photon_counts(strip_index, channel)) *
|
double poisson_error = sqrt(frame.photon_counts(strip_index)) *
|
||||||
inverse_normalized_flatfield(strip_index) *
|
inverse_normalized_flatfield(strip_index) *
|
||||||
exposure_rate; // not sure what this is
|
exposure_rate; // not sure what this is
|
||||||
double corrected_photon_count =
|
double corrected_photon_count =
|
||||||
photon_counts(strip_index, channel) *
|
frame.photon_counts(strip_index) *
|
||||||
inverse_normalized_flatfield(strip_index) * exposure_rate;
|
inverse_normalized_flatfield(strip_index) * exposure_rate;
|
||||||
|
|
||||||
size_t local_strip_index =
|
size_t local_strip_index =
|
||||||
@ -537,7 +621,7 @@ void AngleCalibration::redistribute_photon_counts_to_fixed_angle_bins(
|
|||||||
centers[module_index], conversions[module_index],
|
centers[module_index], conversions[module_index],
|
||||||
offsets[module_index], local_strip_index);
|
offsets[module_index], local_strip_index);
|
||||||
|
|
||||||
diffraction_angle += (detector_angle + mythen_detector->dtt0() +
|
diffraction_angle += (frame.detector_angle + mythen_detector->dtt0() +
|
||||||
mythen_detector->bloffset());
|
mythen_detector->bloffset());
|
||||||
|
|
||||||
if (diffraction_angle < mythen_detector->min_angle() ||
|
if (diffraction_angle < mythen_detector->min_angle() ||
|
||||||
@ -580,14 +664,15 @@ void AngleCalibration::redistribute_photon_counts_to_fixed_angle_bins(
|
|||||||
|
|
||||||
ssize_t bin_index = bin - num_bins1;
|
ssize_t bin_index = bin - num_bins1;
|
||||||
if (bin_coverage > 0.0001) {
|
if (bin_coverage > 0.0001) {
|
||||||
new_photon_counts(bin_index, 0) +=
|
new_statistical_weights(bin_index) +=
|
||||||
statistical_weights * bin_coverage_factor;
|
statistical_weights * bin_coverage_factor -
|
||||||
new_photon_counts(bin_index, 1) += statistical_weights *
|
1.0; //- 1 to avoid division by zero - initiallized with 1.
|
||||||
bin_coverage_factor *
|
bin_counts(bin_index) += statistical_weights *
|
||||||
photon_count_per_bin;
|
bin_coverage_factor *
|
||||||
new_photon_counts(bin_index, 2) += statistical_weights *
|
photon_count_per_bin;
|
||||||
bin_coverage_factor *
|
new_errors(bin_index) += statistical_weights *
|
||||||
pow(photon_count_per_bin, 2);
|
bin_coverage_factor *
|
||||||
|
pow(photon_count_per_bin, 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
* @short HDF5FileReader based on H5File object
|
* @short HDF5FileReader based on H5File object
|
||||||
***********************************************/
|
***********************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#include "Frame.hpp"
|
#include "Frame.hpp"
|
||||||
#include "NDArray.hpp"
|
#include "NDArray.hpp"
|
||||||
#include <H5Cpp.h>
|
#include <H5Cpp.h>
|
||||||
@ -13,7 +15,7 @@
|
|||||||
namespace aare {
|
namespace aare {
|
||||||
|
|
||||||
// return std::type_info
|
// return std::type_info
|
||||||
const std::type_info &deduce_cpp_type(const H5::DataType datatype) {
|
inline const std::type_info &deduce_cpp_type(const H5::DataType datatype) {
|
||||||
if (H5Tequal(datatype.getId(), H5::PredType::NATIVE_UINT8.getId())) {
|
if (H5Tequal(datatype.getId(), H5::PredType::NATIVE_UINT8.getId())) {
|
||||||
return typeid(uint8_t);
|
return typeid(uint8_t);
|
||||||
} else if (H5Tequal(datatype.getId(),
|
} else if (H5Tequal(datatype.getId(),
|
||||||
@ -175,7 +177,10 @@ class HDF5Dataset {
|
|||||||
class HDF5FileReader {
|
class HDF5FileReader {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
HDF5FileReader(const std::string &filename_) : filename(filename_) {
|
HDF5FileReader() = default;
|
||||||
|
|
||||||
|
void open_file(const std::string &filename_) {
|
||||||
|
filename = filename_;
|
||||||
try {
|
try {
|
||||||
file = H5::H5File(filename, H5F_ACC_RDONLY);
|
file = H5::H5File(filename, H5F_ACC_RDONLY);
|
||||||
} catch (H5::Exception &e) {
|
} catch (H5::Exception &e) {
|
||||||
@ -183,6 +188,8 @@ class HDF5FileReader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void close_file() { file.close(); }
|
||||||
|
|
||||||
HDF5Dataset get_dataset(const std::string &dataset_name) {
|
HDF5Dataset get_dataset(const std::string &dataset_name) {
|
||||||
H5::DataSet dataset;
|
H5::DataSet dataset;
|
||||||
try {
|
try {
|
||||||
|
@ -21,7 +21,6 @@ TODO! Add expression templates for operators
|
|||||||
|
|
||||||
namespace aare {
|
namespace aare {
|
||||||
|
|
||||||
|
|
||||||
template <typename T, ssize_t Ndim = 2>
|
template <typename T, ssize_t Ndim = 2>
|
||||||
class NDArray : public ArrayExpr<NDArray<T, Ndim>, Ndim> {
|
class NDArray : public ArrayExpr<NDArray<T, Ndim>, Ndim> {
|
||||||
std::array<ssize_t, Ndim> shape_;
|
std::array<ssize_t, Ndim> shape_;
|
||||||
@ -48,7 +47,6 @@ class NDArray : public ArrayExpr<NDArray<T, Ndim>, Ndim> {
|
|||||||
std::multiplies<>())),
|
std::multiplies<>())),
|
||||||
data_(new T[size_]) {}
|
data_(new T[size_]) {}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Construct a new NDArray object with a shape and value.
|
* @brief Construct a new NDArray object with a shape and value.
|
||||||
*
|
*
|
||||||
@ -69,8 +67,8 @@ class NDArray : public ArrayExpr<NDArray<T, Ndim>, Ndim> {
|
|||||||
std::copy(v.begin(), v.end(), begin());
|
std::copy(v.begin(), v.end(), begin());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t Size>
|
template <size_t Size>
|
||||||
NDArray(const std::array<T, Size>& arr) : NDArray<T,1>({Size}) {
|
NDArray(const std::array<T, Size> &arr) : NDArray<T, 1>({Size}) {
|
||||||
std::copy(arr.begin(), arr.end(), begin());
|
std::copy(arr.begin(), arr.end(), begin());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,7 +77,6 @@ class NDArray : public ArrayExpr<NDArray<T, Ndim>, Ndim> {
|
|||||||
: shape_(other.shape_), strides_(c_strides<Ndim>(shape_)),
|
: shape_(other.shape_), strides_(c_strides<Ndim>(shape_)),
|
||||||
size_(other.size_), data_(other.data_) {
|
size_(other.size_), data_(other.data_) {
|
||||||
other.reset(); // TODO! is this necessary?
|
other.reset(); // TODO! is this necessary?
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy constructor
|
// Copy constructor
|
||||||
@ -113,10 +110,10 @@ class NDArray : public ArrayExpr<NDArray<T, Ndim>, Ndim> {
|
|||||||
NDArray &operator-=(const NDArray &other);
|
NDArray &operator-=(const NDArray &other);
|
||||||
NDArray &operator*=(const NDArray &other);
|
NDArray &operator*=(const NDArray &other);
|
||||||
|
|
||||||
//Write directly to the data array, or create a new one
|
// Write directly to the data array, or create a new one
|
||||||
template<size_t Size>
|
template <size_t Size>
|
||||||
NDArray<T,1>& operator=(const std::array<T,Size> &other){
|
NDArray<T, 1> &operator=(const std::array<T, Size> &other) {
|
||||||
if(Size != size_){
|
if (Size != size_) {
|
||||||
delete[] data_;
|
delete[] data_;
|
||||||
size_ = Size;
|
size_ = Size;
|
||||||
data_ = new T[size_];
|
data_ = new T[size_];
|
||||||
@ -157,11 +154,6 @@ class NDArray : public ArrayExpr<NDArray<T, Ndim>, Ndim> {
|
|||||||
|
|
||||||
NDArray &operator&=(const T & /*mask*/);
|
NDArray &operator&=(const T & /*mask*/);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void sqrt() {
|
void sqrt() {
|
||||||
for (int i = 0; i < size_; ++i) {
|
for (int i = 0; i < size_; ++i) {
|
||||||
data_[i] = std::sqrt(data_[i]);
|
data_[i] = std::sqrt(data_[i]);
|
||||||
@ -345,9 +337,6 @@ NDArray<T, Ndim> &NDArray<T, Ndim>::operator+=(const T &value) {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T, ssize_t Ndim>
|
template <typename T, ssize_t Ndim>
|
||||||
NDArray<T, Ndim> NDArray<T, Ndim>::operator+(const T &value) {
|
NDArray<T, Ndim> NDArray<T, Ndim>::operator+(const T &value) {
|
||||||
NDArray result = *this;
|
NDArray result = *this;
|
||||||
@ -391,6 +380,7 @@ NDArray<T, Ndim> NDArray<T, Ndim>::operator*(const T &value) {
|
|||||||
result *= value;
|
result *= value;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// template <typename T, ssize_t Ndim> void NDArray<T, Ndim>::Print() {
|
// template <typename T, ssize_t Ndim> void NDArray<T, Ndim>::Print() {
|
||||||
// if (shape_[0] < 20 && shape_[1] < 20)
|
// if (shape_[0] < 20 && shape_[1] < 20)
|
||||||
// Print_all();
|
// Print_all();
|
||||||
@ -448,6 +438,4 @@ NDArray<T, Ndim> load(const std::string &pathname,
|
|||||||
return img;
|
return img;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace aare
|
} // namespace aare
|
@ -24,9 +24,11 @@ TEST_CASE("read hdf5 file", "[.hdf5file]") {
|
|||||||
|
|
||||||
REQUIRE(std::filesystem::exists(filename));
|
REQUIRE(std::filesystem::exists(filename));
|
||||||
|
|
||||||
HDF5FileReader file(filename);
|
HDF5FileReader file_reader;
|
||||||
|
|
||||||
auto dataset = file.get_dataset("/entry/data/data");
|
file_reader.open_file(filename);
|
||||||
|
|
||||||
|
auto dataset = file_reader.get_dataset("/entry/data/data");
|
||||||
|
|
||||||
auto shape = dataset.get_shape();
|
auto shape = dataset.get_shape();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user