mirror of
https://github.com/slsdetectorgroup/aare.git
synced 2025-04-19 21:30:02 +02:00
docs and reorder
This commit is contained in:
parent
db936b6357
commit
13b2cb40b6
@ -21,33 +21,62 @@ TODO! Add expression templates for operators
|
||||
namespace aare {
|
||||
|
||||
template <typename T, int64_t Ndim = 2> class NDArray {
|
||||
public:
|
||||
NDArray() : shape_(), strides_(c_strides<Ndim>(shape_)), data_(nullptr){};
|
||||
std::array<int64_t, Ndim> shape_;
|
||||
std::array<int64_t, Ndim> strides_;
|
||||
size_t size_{};
|
||||
T *data_;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Default constructor. Will construct an empty NDArray.
|
||||
*
|
||||
*/
|
||||
NDArray() : shape_(), strides_(c_strides<Ndim>(shape_)), data_(nullptr) {};
|
||||
|
||||
/**
|
||||
* @brief Construct a new NDArray object with a given shape.
|
||||
* @note The data is uninitialized.
|
||||
*
|
||||
* @param shape shape of the new NDArray
|
||||
*/
|
||||
explicit NDArray(std::array<int64_t, Ndim> shape)
|
||||
: shape_(shape), strides_(c_strides<Ndim>(shape_)),
|
||||
size_(std::accumulate(shape_.begin(), shape_.end(), 1, std::multiplies<>())), data_(new T[size_]){};
|
||||
size_(std::accumulate(shape_.begin(), shape_.end(), 1,
|
||||
std::multiplies<>())),
|
||||
data_(new T[size_]) {};
|
||||
|
||||
NDArray(std::array<int64_t, Ndim> shape, T value) : NDArray(shape) { this->operator=(value); }
|
||||
/**
|
||||
* @brief Construct a new NDArray object with a shape and value.
|
||||
*
|
||||
* @param shape shape of the new array
|
||||
* @param value value to initialize the array with
|
||||
*/
|
||||
NDArray(std::array<int64_t, Ndim> shape, T value) : NDArray(shape) {
|
||||
this->operator=(value);
|
||||
}
|
||||
|
||||
/* When constructing from a NDView we need to copy the data since
|
||||
NDArray expect to own its data, and span is just a view*/
|
||||
explicit NDArray(NDView<T, Ndim> span) : NDArray(span.shape()) {
|
||||
std::copy(span.begin(), span.end(), begin());
|
||||
// fmt::print("NDArray(NDView<T, Ndim> span)\n");
|
||||
/**
|
||||
* @brief Construct a new NDArray object from a NDView.
|
||||
* @note The data is copied from the view to the NDArray.
|
||||
*
|
||||
* @param v view of data to initialize the NDArray with
|
||||
*/
|
||||
explicit NDArray(const NDView<T, Ndim> v) : NDArray(v.shape()) {
|
||||
std::copy(v.begin(), v.end(), begin());
|
||||
}
|
||||
|
||||
// Move constructor
|
||||
NDArray(NDArray &&other) noexcept
|
||||
: shape_(other.shape_), strides_(c_strides<Ndim>(shape_)), size_(other.size_), data_(other.data_) {
|
||||
: shape_(other.shape_), strides_(c_strides<Ndim>(shape_)),
|
||||
size_(other.size_), data_(other.data_) {
|
||||
|
||||
other.reset();
|
||||
// fmt::print("NDArray(NDArray &&other)\n");
|
||||
}
|
||||
|
||||
// Copy constructor
|
||||
NDArray(const NDArray &other)
|
||||
: shape_(other.shape_), strides_(c_strides<Ndim>(shape_)), size_(other.size_), data_(new T[size_]) {
|
||||
: shape_(other.shape_), strides_(c_strides<Ndim>(shape_)),
|
||||
size_(other.size_), data_(new T[size_]) {
|
||||
std::copy(other.data_, other.data_ + size_, data_);
|
||||
// fmt::print("NDArray(const NDArray &other)\n");
|
||||
}
|
||||
@ -70,6 +99,7 @@ template <typename T, int64_t Ndim = 2> class NDArray {
|
||||
NDArray &operator*=(const NDArray &other);
|
||||
NDArray operator/(const NDArray &other);
|
||||
// NDArray& operator/=(const NDArray& other);
|
||||
|
||||
template <typename V> NDArray &operator/=(const NDArray<V, Ndim> &other) {
|
||||
// check shape
|
||||
if (shape_ == other.shape()) {
|
||||
@ -106,15 +136,18 @@ template <typename T, int64_t Ndim = 2> class NDArray {
|
||||
|
||||
NDArray &operator++(); // pre inc
|
||||
|
||||
template <typename... Ix> std::enable_if_t<sizeof...(Ix) == Ndim, T &> operator()(Ix... index) {
|
||||
template <typename... Ix>
|
||||
std::enable_if_t<sizeof...(Ix) == Ndim, T &> operator()(Ix... index) {
|
||||
return data_[element_offset(strides_, index...)];
|
||||
}
|
||||
|
||||
template <typename... Ix> std::enable_if_t<sizeof...(Ix) == Ndim, T &> operator()(Ix... index) const {
|
||||
template <typename... Ix>
|
||||
std::enable_if_t<sizeof...(Ix) == Ndim, T &> operator()(Ix... index) const {
|
||||
return data_[element_offset(strides_, index...)];
|
||||
}
|
||||
|
||||
template <typename... Ix> std::enable_if_t<sizeof...(Ix) == Ndim, T> value(Ix... index) {
|
||||
template <typename... Ix>
|
||||
std::enable_if_t<sizeof...(Ix) == Ndim, T> value(Ix... index) {
|
||||
return data_[element_offset(strides_, index...)];
|
||||
}
|
||||
|
||||
@ -129,15 +162,20 @@ template <typename T, int64_t Ndim = 2> class NDArray {
|
||||
int64_t shape(int64_t i) const noexcept { return shape_[i]; }
|
||||
std::array<int64_t, Ndim> strides() const noexcept { return strides_; }
|
||||
size_t bitdepth() const noexcept { return sizeof(T) * 8; }
|
||||
|
||||
std::array<int64_t, Ndim> byte_strides() const noexcept {
|
||||
auto byte_strides = strides_;
|
||||
for (auto &val : byte_strides)
|
||||
val *= sizeof(T);
|
||||
return byte_strides;
|
||||
// return strides_;
|
||||
}
|
||||
|
||||
NDView<T, Ndim> span() const { return NDView<T, Ndim>{data_, shape_}; }
|
||||
/**
|
||||
* @brief Create a view of the NDArray.
|
||||
*
|
||||
* @return NDView<T, Ndim>
|
||||
*/
|
||||
NDView<T, Ndim> view() const { return NDView<T, Ndim>{data_, shape_}; }
|
||||
|
||||
void Print();
|
||||
void Print_all();
|
||||
@ -149,16 +187,12 @@ template <typename T, int64_t Ndim = 2> class NDArray {
|
||||
std::fill(shape_.begin(), shape_.end(), 0);
|
||||
std::fill(strides_.begin(), strides_.end(), 0);
|
||||
}
|
||||
|
||||
private:
|
||||
std::array<int64_t, Ndim> shape_;
|
||||
std::array<int64_t, Ndim> strides_;
|
||||
uint64_t size_{};
|
||||
T *data_;
|
||||
};
|
||||
|
||||
// Move assign
|
||||
template <typename T, int64_t Ndim> NDArray<T, Ndim> &NDArray<T, Ndim>::operator=(NDArray<T, Ndim> &&other) noexcept {
|
||||
template <typename T, int64_t Ndim>
|
||||
NDArray<T, Ndim> &
|
||||
NDArray<T, Ndim>::operator=(NDArray<T, Ndim> &&other) noexcept {
|
||||
if (this != &other) {
|
||||
delete[] data_;
|
||||
data_ = other.data_;
|
||||
@ -170,12 +204,14 @@ template <typename T, int64_t Ndim> NDArray<T, Ndim> &NDArray<T, Ndim>::operator
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, int64_t Ndim> NDArray<T, Ndim> NDArray<T, Ndim>::operator+(const NDArray &other) {
|
||||
template <typename T, int64_t Ndim>
|
||||
NDArray<T, Ndim> NDArray<T, Ndim>::operator+(const NDArray &other) {
|
||||
NDArray result(*this);
|
||||
result += other;
|
||||
return result;
|
||||
}
|
||||
template <typename T, int64_t Ndim> NDArray<T, Ndim> &NDArray<T, Ndim>::operator+=(const NDArray<T, Ndim> &other) {
|
||||
template <typename T, int64_t Ndim>
|
||||
NDArray<T, Ndim> &NDArray<T, Ndim>::operator+=(const NDArray<T, Ndim> &other) {
|
||||
// check shape
|
||||
if (shape_ == other.shape_) {
|
||||
for (uint32_t i = 0; i < size_; ++i) {
|
||||
@ -186,13 +222,15 @@ template <typename T, int64_t Ndim> NDArray<T, Ndim> &NDArray<T, Ndim>::operator
|
||||
throw(std::runtime_error("Shape of ImageDatas must match"));
|
||||
}
|
||||
|
||||
template <typename T, int64_t Ndim> NDArray<T, Ndim> NDArray<T, Ndim>::operator-(const NDArray &other) {
|
||||
template <typename T, int64_t Ndim>
|
||||
NDArray<T, Ndim> NDArray<T, Ndim>::operator-(const NDArray &other) {
|
||||
NDArray result{*this};
|
||||
result -= other;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T, int64_t Ndim> NDArray<T, Ndim> &NDArray<T, Ndim>::operator-=(const NDArray<T, Ndim> &other) {
|
||||
template <typename T, int64_t Ndim>
|
||||
NDArray<T, Ndim> &NDArray<T, Ndim>::operator-=(const NDArray<T, Ndim> &other) {
|
||||
// check shape
|
||||
if (shape_ == other.shape_) {
|
||||
for (uint32_t i = 0; i < size_; ++i) {
|
||||
@ -202,13 +240,15 @@ template <typename T, int64_t Ndim> NDArray<T, Ndim> &NDArray<T, Ndim>::operator
|
||||
}
|
||||
throw(std::runtime_error("Shape of ImageDatas must match"));
|
||||
}
|
||||
template <typename T, int64_t Ndim> NDArray<T, Ndim> NDArray<T, Ndim>::operator*(const NDArray &other) {
|
||||
template <typename T, int64_t Ndim>
|
||||
NDArray<T, Ndim> NDArray<T, Ndim>::operator*(const NDArray &other) {
|
||||
NDArray result = *this;
|
||||
result *= other;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T, int64_t Ndim> NDArray<T, Ndim> &NDArray<T, Ndim>::operator*=(const NDArray<T, Ndim> &other) {
|
||||
template <typename T, int64_t Ndim>
|
||||
NDArray<T, Ndim> &NDArray<T, Ndim>::operator*=(const NDArray<T, Ndim> &other) {
|
||||
// check shape
|
||||
if (shape_ == other.shape_) {
|
||||
for (uint32_t i = 0; i < size_; ++i) {
|
||||
@ -219,34 +259,22 @@ template <typename T, int64_t Ndim> NDArray<T, Ndim> &NDArray<T, Ndim>::operator
|
||||
throw(std::runtime_error("Shape of ImageDatas must match"));
|
||||
}
|
||||
|
||||
template <typename T, int64_t Ndim> NDArray<T, Ndim> NDArray<T, Ndim>::operator/(const NDArray &other) {
|
||||
template <typename T, int64_t Ndim>
|
||||
NDArray<T, Ndim> NDArray<T, Ndim>::operator/(const NDArray &other) {
|
||||
NDArray result = *this;
|
||||
result /= other;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T, int64_t Ndim> NDArray<T, Ndim> &NDArray<T, Ndim>::operator&=(const T &mask) {
|
||||
template <typename T, int64_t Ndim>
|
||||
NDArray<T, Ndim> &NDArray<T, Ndim>::operator&=(const T &mask) {
|
||||
for (auto it = begin(); it != end(); ++it)
|
||||
*it &= mask;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// template <typename T, int64_t Ndim>
|
||||
// NDArray<T, Ndim>& NDArray<T, Ndim>::operator/=(const NDArray<T, Ndim>&
|
||||
// other)
|
||||
// {
|
||||
// //check shape
|
||||
// if (shape_ == other.shape_) {
|
||||
// for (int i = 0; i < size_; ++i) {
|
||||
// data_[i] /= other.data_[i];
|
||||
// }
|
||||
// return *this;
|
||||
// } else {
|
||||
// throw(std::runtime_error("Shape of ImageDatas must match"));
|
||||
// }
|
||||
// }
|
||||
|
||||
template <typename T, int64_t Ndim> NDArray<bool, Ndim> NDArray<T, Ndim>::operator>(const NDArray &other) {
|
||||
template <typename T, int64_t Ndim>
|
||||
NDArray<bool, Ndim> NDArray<T, Ndim>::operator>(const NDArray &other) {
|
||||
if (shape_ == other.shape_) {
|
||||
NDArray<bool> result{shape_};
|
||||
for (int i = 0; i < size_; ++i) {
|
||||
@ -257,7 +285,8 @@ template <typename T, int64_t Ndim> NDArray<bool, Ndim> NDArray<T, Ndim>::operat
|
||||
throw(std::runtime_error("Shape of ImageDatas must match"));
|
||||
}
|
||||
|
||||
template <typename T, int64_t Ndim> NDArray<T, Ndim> &NDArray<T, Ndim>::operator=(const NDArray<T, Ndim> &other) {
|
||||
template <typename T, int64_t Ndim>
|
||||
NDArray<T, Ndim> &NDArray<T, Ndim>::operator=(const NDArray<T, Ndim> &other) {
|
||||
if (this != &other) {
|
||||
delete[] data_;
|
||||
shape_ = other.shape_;
|
||||
@ -269,7 +298,8 @@ template <typename T, int64_t Ndim> NDArray<T, Ndim> &NDArray<T, Ndim>::operator
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, int64_t Ndim> bool NDArray<T, Ndim>::operator==(const NDArray<T, Ndim> &other) const {
|
||||
template <typename T, int64_t Ndim>
|
||||
bool NDArray<T, Ndim>::operator==(const NDArray<T, Ndim> &other) const {
|
||||
if (shape_ != other.shape_)
|
||||
return false;
|
||||
|
||||
@ -280,57 +310,68 @@ template <typename T, int64_t Ndim> bool NDArray<T, Ndim>::operator==(const NDAr
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T, int64_t Ndim> bool NDArray<T, Ndim>::operator!=(const NDArray<T, Ndim> &other) const {
|
||||
template <typename T, int64_t Ndim>
|
||||
bool NDArray<T, Ndim>::operator!=(const NDArray<T, Ndim> &other) const {
|
||||
return !((*this) == other);
|
||||
}
|
||||
template <typename T, int64_t Ndim> NDArray<T, Ndim> &NDArray<T, Ndim>::operator++() {
|
||||
template <typename T, int64_t Ndim>
|
||||
NDArray<T, Ndim> &NDArray<T, Ndim>::operator++() {
|
||||
for (uint32_t i = 0; i < size_; ++i)
|
||||
data_[i] += 1;
|
||||
return *this;
|
||||
}
|
||||
template <typename T, int64_t Ndim> NDArray<T, Ndim> &NDArray<T, Ndim>::operator=(const T &value) {
|
||||
template <typename T, int64_t Ndim>
|
||||
NDArray<T, Ndim> &NDArray<T, Ndim>::operator=(const T &value) {
|
||||
std::fill_n(data_, size_, value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, int64_t Ndim> NDArray<T, Ndim> &NDArray<T, Ndim>::operator+=(const T &value) {
|
||||
template <typename T, int64_t Ndim>
|
||||
NDArray<T, Ndim> &NDArray<T, Ndim>::operator+=(const T &value) {
|
||||
for (uint32_t i = 0; i < size_; ++i)
|
||||
data_[i] += value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, int64_t Ndim> NDArray<T, Ndim> NDArray<T, Ndim>::operator+(const T &value) {
|
||||
template <typename T, int64_t Ndim>
|
||||
NDArray<T, Ndim> NDArray<T, Ndim>::operator+(const T &value) {
|
||||
NDArray result = *this;
|
||||
result += value;
|
||||
return result;
|
||||
}
|
||||
template <typename T, int64_t Ndim> NDArray<T, Ndim> &NDArray<T, Ndim>::operator-=(const T &value) {
|
||||
template <typename T, int64_t Ndim>
|
||||
NDArray<T, Ndim> &NDArray<T, Ndim>::operator-=(const T &value) {
|
||||
for (uint32_t i = 0; i < size_; ++i)
|
||||
data_[i] -= value;
|
||||
return *this;
|
||||
}
|
||||
template <typename T, int64_t Ndim> NDArray<T, Ndim> NDArray<T, Ndim>::operator-(const T &value) {
|
||||
template <typename T, int64_t Ndim>
|
||||
NDArray<T, Ndim> NDArray<T, Ndim>::operator-(const T &value) {
|
||||
NDArray result = *this;
|
||||
result -= value;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T, int64_t Ndim> NDArray<T, Ndim> &NDArray<T, Ndim>::operator/=(const T &value) {
|
||||
template <typename T, int64_t Ndim>
|
||||
NDArray<T, Ndim> &NDArray<T, Ndim>::operator/=(const T &value) {
|
||||
for (uint32_t i = 0; i < size_; ++i)
|
||||
data_[i] /= value;
|
||||
return *this;
|
||||
}
|
||||
template <typename T, int64_t Ndim> NDArray<T, Ndim> NDArray<T, Ndim>::operator/(const T &value) {
|
||||
template <typename T, int64_t Ndim>
|
||||
NDArray<T, Ndim> NDArray<T, Ndim>::operator/(const T &value) {
|
||||
NDArray result = *this;
|
||||
result /= value;
|
||||
return result;
|
||||
}
|
||||
template <typename T, int64_t Ndim> NDArray<T, Ndim> &NDArray<T, Ndim>::operator*=(const T &value) {
|
||||
template <typename T, int64_t Ndim>
|
||||
NDArray<T, Ndim> &NDArray<T, Ndim>::operator*=(const T &value) {
|
||||
for (uint32_t i = 0; i < size_; ++i)
|
||||
data_[i] *= value;
|
||||
return *this;
|
||||
}
|
||||
template <typename T, int64_t Ndim> NDArray<T, Ndim> NDArray<T, Ndim>::operator*(const T &value) {
|
||||
template <typename T, int64_t Ndim>
|
||||
NDArray<T, Ndim> NDArray<T, Ndim>::operator*(const T &value) {
|
||||
NDArray result = *this;
|
||||
result *= value;
|
||||
return result;
|
||||
@ -342,9 +383,8 @@ template <typename T, int64_t Ndim> void NDArray<T, Ndim>::Print() {
|
||||
Print_some();
|
||||
}
|
||||
|
||||
|
||||
template <typename T, int64_t Ndim>
|
||||
std::ostream& operator <<(std::ostream& os, const NDArray<T, Ndim>& arr){
|
||||
std::ostream &operator<<(std::ostream &os, const NDArray<T, Ndim> &arr) {
|
||||
for (auto row = 0; row < arr.shape(0); ++row) {
|
||||
for (auto col = 0; col < arr.shape(1); ++col) {
|
||||
os << std::setw(3);
|
||||
@ -355,7 +395,6 @@ std::ostream& operator <<(std::ostream& os, const NDArray<T, Ndim>& arr){
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
template <typename T, int64_t Ndim> void NDArray<T, Ndim>::Print_all() {
|
||||
for (auto row = 0; row < shape_[0]; ++row) {
|
||||
for (auto col = 0; col < shape_[1]; ++col) {
|
||||
@ -375,7 +414,8 @@ template <typename T, int64_t Ndim> void NDArray<T, Ndim>::Print_some() {
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, int64_t Ndim> void save(NDArray<T, Ndim> &img, std::string &pathname) {
|
||||
template <typename T, int64_t Ndim>
|
||||
void save(NDArray<T, Ndim> &img, std::string &pathname) {
|
||||
std::ofstream f;
|
||||
f.open(pathname, std::ios::binary);
|
||||
f.write(img.buffer(), img.size() * sizeof(T));
|
||||
@ -383,7 +423,8 @@ template <typename T, int64_t Ndim> void save(NDArray<T, Ndim> &img, std::string
|
||||
}
|
||||
|
||||
template <typename T, int64_t Ndim>
|
||||
NDArray<T, Ndim> load(const std::string &pathname, std::array<int64_t, Ndim> shape) {
|
||||
NDArray<T, Ndim> load(const std::string &pathname,
|
||||
std::array<int64_t, Ndim> shape) {
|
||||
NDArray<T, Ndim> img{shape};
|
||||
std::ifstream f;
|
||||
f.open(pathname, std::ios::binary);
|
||||
|
@ -74,6 +74,8 @@ template <typename T, int64_t Ndim = 2> class NDView {
|
||||
|
||||
T *begin() { return buffer_; }
|
||||
T *end() { return buffer_ + size_; }
|
||||
T const *begin() const { return buffer_; }
|
||||
T const *end() const { return buffer_ + size_; }
|
||||
T &operator()(int64_t i) const { return buffer_[i]; }
|
||||
T &operator[](int64_t i) const { return buffer_[i]; }
|
||||
|
||||
@ -121,7 +123,7 @@ template <typename T, int64_t Ndim = 2> class NDView {
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto &shape() { return shape_; }
|
||||
auto &shape() const { return shape_; }
|
||||
auto shape(int64_t i) const { return shape_[i]; }
|
||||
|
||||
T *data() { return buffer_; }
|
||||
|
@ -8,8 +8,11 @@ namespace aare {
|
||||
NDArray<ssize_t, 2> GenerateMoench03PixelMap();
|
||||
NDArray<ssize_t, 2> GenerateMoench05PixelMap();
|
||||
|
||||
//Matterhorn02
|
||||
NDArray<ssize_t, 2>GenerateMH02SingleCounterPixelMap();
|
||||
NDArray<ssize_t, 3> GenerateMH02FourCounterPixelMap();
|
||||
|
||||
//Eiger
|
||||
NDArray<ssize_t, 2>GenerateEigerFlipRowsPixelMap();
|
||||
|
||||
} // namespace aare
|
@ -22,9 +22,11 @@ class RawSubFile {
|
||||
size_t m_cols{};
|
||||
size_t m_bytes_per_frame{};
|
||||
size_t n_frames{};
|
||||
uint32_t m_pos_row{};
|
||||
uint32_t m_pos_col{};
|
||||
|
||||
DetectorType m_detector_type;
|
||||
std::optional<NDArray<ssize_t, 2>> pixel_map;
|
||||
std::optional<NDArray<ssize_t, 2>> m_pixel_map;
|
||||
|
||||
public:
|
||||
/**
|
||||
@ -37,7 +39,7 @@ class RawSubFile {
|
||||
* @throws std::invalid_argument if the detector,type pair is not supported
|
||||
*/
|
||||
RawSubFile(const std::filesystem::path &fname, DetectorType detector,
|
||||
size_t rows, size_t cols, size_t bitdepth);
|
||||
size_t rows, size_t cols, size_t bitdepth, uint32_t pos_row = 0, uint32_t pos_col = 0);
|
||||
|
||||
~RawSubFile() = default;
|
||||
/**
|
||||
|
@ -1,80 +0,0 @@
|
||||
#pragma once
|
||||
#include "aare/Frame.hpp"
|
||||
#include "aare/defs.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <filesystem>
|
||||
#include <map>
|
||||
#include <optional>
|
||||
|
||||
|
||||
namespace aare {
|
||||
|
||||
/**
|
||||
* @brief Class to read a subfile from a RawFile
|
||||
*/
|
||||
class SubFile {
|
||||
public:
|
||||
size_t write_part(std::byte *buffer, DetectorHeader header, size_t frame_index);
|
||||
/**
|
||||
* @brief SubFile constructor
|
||||
* @param fname path to the subfile
|
||||
* @param detector detector type
|
||||
* @param rows number of rows in the subfile
|
||||
* @param cols number of columns in the subfile
|
||||
* @param bitdepth bitdepth of the subfile
|
||||
* @throws std::invalid_argument if the detector,type pair is not supported
|
||||
*/
|
||||
SubFile(const std::filesystem::path &fname, DetectorType detector, size_t rows, size_t cols, size_t bitdepth,
|
||||
const std::string &mode = "r");
|
||||
|
||||
/**
|
||||
* @brief read the subfile into a buffer
|
||||
* @param buffer pointer to the buffer to read the data into
|
||||
* @return number of bytes read
|
||||
*/
|
||||
size_t read_impl_normal(std::byte *buffer);
|
||||
|
||||
/**
|
||||
* @brief read the subfile into a buffer with the bytes flipped
|
||||
* @param buffer pointer to the buffer to read the data into
|
||||
* @return number of bytes read
|
||||
*/
|
||||
template <typename DataType> size_t read_impl_flip(std::byte *buffer);
|
||||
|
||||
/**
|
||||
* @brief read the subfile into a buffer with the bytes reordered
|
||||
* @param buffer pointer to the buffer to read the data into
|
||||
* @return number of bytes read
|
||||
*/
|
||||
template <typename DataType> size_t read_impl_reorder(std::byte *buffer);
|
||||
|
||||
/**
|
||||
* @brief read the subfile into a buffer with the bytes reordered and flipped
|
||||
* @param buffer pointer to the buffer to read the data into
|
||||
* @param frame_number frame number to read
|
||||
* @return number of bytes read
|
||||
*/
|
||||
size_t get_part(std::byte *buffer, size_t frame_index);
|
||||
size_t frame_number(size_t frame_index);
|
||||
|
||||
// TODO: define the inlines as variables and assign them in constructor
|
||||
inline size_t bytes_per_part() const { return (m_bitdepth / 8) * m_rows * m_cols; }
|
||||
inline size_t pixels_per_part() const { return m_rows * m_cols; }
|
||||
|
||||
~SubFile();
|
||||
|
||||
protected:
|
||||
FILE *fp = nullptr;
|
||||
size_t m_bitdepth;
|
||||
std::filesystem::path m_fname;
|
||||
size_t m_rows{};
|
||||
size_t m_cols{};
|
||||
std::string m_mode;
|
||||
size_t n_frames{};
|
||||
int m_sub_file_index_{};
|
||||
DetectorType m_detector_type;
|
||||
std::optional<NDArray<ssize_t, 2>> pixel_map;
|
||||
};
|
||||
|
||||
} // namespace aare
|
@ -12,7 +12,7 @@ TEST_CASE("Initial size is zero if no size is specified") {
|
||||
REQUIRE(a.shape() == Shape<2>{0, 0});
|
||||
}
|
||||
|
||||
TEST_CASE("Construct from a DataSpan") {
|
||||
TEST_CASE("Construct from an NDView") {
|
||||
std::vector<int> some_data(9, 42);
|
||||
NDView<int, 2> view(some_data.data(), Shape<2>{3, 3});
|
||||
|
||||
@ -168,42 +168,8 @@ TEST_CASE("Bitwise and on data") {
|
||||
REQUIRE(a(2) == 384);
|
||||
}
|
||||
|
||||
// TEST_CASE("Benchmarks")
|
||||
// {
|
||||
// NDArray<double> img;
|
||||
// std::array<int64_t, 2> shape{ 512, 1024 };
|
||||
// BENCHMARK("Allocate 500k double image")
|
||||
// {
|
||||
// NDArray<double>im{ shape };
|
||||
// }
|
||||
// BENCHMARK("Allocate 500k double image with initial value")
|
||||
// {
|
||||
// NDArray<double>im{ shape, 3.14 };
|
||||
// }
|
||||
|
||||
// NDArray<double> a{ shape, 1.2 };
|
||||
// NDArray<double> b{ shape, 53. };
|
||||
// auto c = a + b;
|
||||
// c = a * b;
|
||||
// BENCHMARK("Multiply two images")
|
||||
// {
|
||||
// c = a * b;
|
||||
// }
|
||||
// BENCHMARK("Divide two images")
|
||||
// {
|
||||
// c = a / b;
|
||||
// }
|
||||
// BENCHMARK("Add two images")
|
||||
// {
|
||||
// c = a + b;
|
||||
// }
|
||||
// BENCHMARK("Subtract two images")
|
||||
// {
|
||||
// c = a - b;
|
||||
// }
|
||||
// }
|
||||
|
||||
TEST_CASE("Elementwise operatios on images") {
|
||||
TEST_CASE("Elementwise operations on images") {
|
||||
std::array<int64_t, 2> shape{5, 5};
|
||||
double a_val = 3.0;
|
||||
double b_val = 8.0;
|
||||
|
@ -52,6 +52,16 @@ NDArray<ssize_t, 2> GenerateMoench05PixelMap() {
|
||||
return order_map;
|
||||
}
|
||||
|
||||
NDArray<ssize_t, 2>GenerateEigerFlipRowsPixelMap(){
|
||||
NDArray<ssize_t, 2> order_map({256, 512});
|
||||
for(int row = 0; row < 256; row++){
|
||||
for(int col = 0; col < 512; col++){
|
||||
order_map(row, col) = 255*512-row*512 + col;
|
||||
}
|
||||
}
|
||||
return order_map;
|
||||
}
|
||||
|
||||
NDArray<ssize_t, 2>GenerateMH02SingleCounterPixelMap(){
|
||||
NDArray<ssize_t, 2> order_map({48, 48});
|
||||
for(int row = 0; row < 48; row++){
|
||||
|
@ -97,10 +97,14 @@ void RawFile::open_subfiles() {
|
||||
for (size_t i = 0; i != n_subfiles; ++i) {
|
||||
auto v = std::vector<RawSubFile *>(n_subfile_parts);
|
||||
for (size_t j = 0; j != n_subfile_parts; ++j) {
|
||||
fmt::print("{} pos: {},{}\n", j,positions[j].row, positions[j].col);
|
||||
|
||||
auto pos = m_module_pixel_0[j];
|
||||
fmt::print("{} pos: {},{}\n", j,pos.y, pos.x);
|
||||
v[j] = new RawSubFile(m_master.data_fname(j, i),
|
||||
m_master.detector_type(), pos.height,
|
||||
pos.width, m_master.bitdepth());
|
||||
pos.width, m_master.bitdepth(),
|
||||
positions[j].row, positions[j].col);
|
||||
|
||||
}
|
||||
subfiles.push_back(v);
|
||||
|
@ -8,12 +8,15 @@ namespace aare {
|
||||
|
||||
RawSubFile::RawSubFile(const std::filesystem::path &fname,
|
||||
DetectorType detector, size_t rows, size_t cols,
|
||||
size_t bitdepth)
|
||||
size_t bitdepth, uint32_t pos_row, uint32_t pos_col)
|
||||
: m_bitdepth(bitdepth), m_fname(fname), m_rows(rows), m_cols(cols),
|
||||
m_detector_type(detector),
|
||||
m_bytes_per_frame((m_bitdepth / 8) * m_rows * m_cols) {
|
||||
m_bytes_per_frame((m_bitdepth / 8) * m_rows * m_cols), m_pos_row(pos_row), m_pos_col(pos_col) {
|
||||
if (m_detector_type == DetectorType::Moench03_old) {
|
||||
pixel_map = GenerateMoench03PixelMap();
|
||||
m_pixel_map = GenerateMoench03PixelMap();
|
||||
}else if(m_detector_type == DetectorType::Eiger && m_pos_row % 2 == 0){
|
||||
m_pixel_map = GenerateEigerFlipRowsPixelMap();
|
||||
fmt::print("Flipping rows\n");
|
||||
}
|
||||
|
||||
if (std::filesystem::exists(fname)) {
|
||||
@ -59,7 +62,7 @@ void RawSubFile::read_into(std::byte *image_buf, DetectorHeader *header) {
|
||||
}
|
||||
|
||||
//TODO! expand support for different bitdepths
|
||||
if(pixel_map){
|
||||
if(m_pixel_map){
|
||||
// read into a temporary buffer and then copy the data to the buffer
|
||||
// in the correct order
|
||||
// currently this only supports 16 bit data!
|
||||
@ -68,7 +71,7 @@ void RawSubFile::read_into(std::byte *image_buf, DetectorHeader *header) {
|
||||
auto *data = reinterpret_cast<uint16_t *>(image_buf);
|
||||
auto *part_data = reinterpret_cast<uint16_t *>(part_buffer);
|
||||
for (size_t i = 0; i < pixels_per_frame(); i++) {
|
||||
data[i] = part_data[(*pixel_map)(i)];
|
||||
data[i] = part_data[(*m_pixel_map)(i)];
|
||||
}
|
||||
delete[] part_buffer;
|
||||
} else {
|
||||
|
@ -1,91 +0,0 @@
|
||||
#include "aare/SubFile.hpp"
|
||||
#include "aare/PixelMap.hpp"
|
||||
#include <cstring> // memcpy
|
||||
#include <fmt/core.h>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
namespace aare {
|
||||
|
||||
SubFile::SubFile(const std::filesystem::path &fname, DetectorType detector, size_t rows, size_t cols, size_t bitdepth,
|
||||
const std::string &mode)
|
||||
: m_bitdepth(bitdepth), m_fname(fname), m_rows(rows), m_cols(cols), m_mode(mode), m_detector_type(detector) {
|
||||
|
||||
|
||||
if (m_detector_type == DetectorType::Moench03_old) {
|
||||
pixel_map = GenerateMoench03PixelMap();
|
||||
}
|
||||
|
||||
if (std::filesystem::exists(fname)) {
|
||||
n_frames = std::filesystem::file_size(fname) / (sizeof(DetectorHeader) + rows * cols * bitdepth / 8);
|
||||
} else {
|
||||
n_frames = 0;
|
||||
}
|
||||
|
||||
if (mode == "r") {
|
||||
fp = fopen(m_fname.string().c_str(), "rb");
|
||||
} else {
|
||||
throw std::runtime_error(LOCATION + "Unsupported mode. Can only read RawFiles.");
|
||||
}
|
||||
if (fp == nullptr) {
|
||||
throw std::runtime_error(LOCATION + fmt::format("Could not open file {}", m_fname.string()));
|
||||
}
|
||||
#ifdef AARE_VERBOSE
|
||||
fmt::print("Opened file: {} with {} frames\n", m_fname.string(), n_frames);
|
||||
fmt::print("m_rows: {}, m_cols: {}, m_bitdepth: {}\n", m_rows, m_cols, m_bitdepth);
|
||||
#endif
|
||||
}
|
||||
|
||||
size_t SubFile::get_part(std::byte *buffer, size_t frame_index) {
|
||||
if (frame_index >= n_frames) {
|
||||
throw std::runtime_error("Frame number out of range");
|
||||
}
|
||||
fseek(fp, sizeof(DetectorHeader) + (sizeof(DetectorHeader) + bytes_per_part()) * frame_index, // NOLINT
|
||||
SEEK_SET);
|
||||
|
||||
if (pixel_map){
|
||||
// read into a temporary buffer and then copy the data to the buffer
|
||||
// in the correct order
|
||||
auto part_buffer = new std::byte[bytes_per_part()];
|
||||
auto wc = fread(part_buffer, bytes_per_part(), 1, fp);
|
||||
auto *data = reinterpret_cast<uint16_t *>(buffer);
|
||||
auto *part_data = reinterpret_cast<uint16_t *>(part_buffer);
|
||||
for (size_t i = 0; i < pixels_per_part(); i++) {
|
||||
data[i] = part_data[(*pixel_map)(i)];
|
||||
}
|
||||
delete[] part_buffer;
|
||||
return wc;
|
||||
}else{
|
||||
// read directly into the buffer
|
||||
return fread(buffer, this->bytes_per_part(), 1, this->fp);
|
||||
}
|
||||
|
||||
}
|
||||
size_t SubFile::write_part(std::byte *buffer, DetectorHeader header, size_t frame_index) {
|
||||
if (frame_index > n_frames) {
|
||||
throw std::runtime_error("Frame number out of range");
|
||||
}
|
||||
fseek(fp, static_cast<int64_t>((sizeof(DetectorHeader) + bytes_per_part()) * frame_index), SEEK_SET);
|
||||
auto wc = fwrite(reinterpret_cast<char *>(&header), sizeof(header), 1, fp);
|
||||
wc += fwrite(buffer, bytes_per_part(), 1, fp);
|
||||
|
||||
return wc;
|
||||
}
|
||||
|
||||
size_t SubFile::frame_number(size_t frame_index) {
|
||||
DetectorHeader h{};
|
||||
fseek(fp, (sizeof(DetectorHeader) + bytes_per_part()) * frame_index, SEEK_SET); // NOLINT
|
||||
size_t const rc = fread(reinterpret_cast<char *>(&h), sizeof(h), 1, fp);
|
||||
if (rc != 1)
|
||||
throw std::runtime_error(LOCATION + "Could not read header from file");
|
||||
|
||||
return h.frameNumber;
|
||||
}
|
||||
|
||||
SubFile::~SubFile() {
|
||||
if (fp) {
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace aare
|
Loading…
x
Reference in New Issue
Block a user