mirror of
https://github.com/slsdetectorgroup/aare.git
synced 2026-02-21 04:58:41 +01:00
clang-format
This commit is contained in:
@@ -378,7 +378,9 @@ ClusterFile<ClusterType, Enable>::read_frame_without_cut() {
|
||||
else if (ferror(fp))
|
||||
throw std::runtime_error(LOCATION + "Error reading from file");
|
||||
|
||||
throw std::runtime_error(LOCATION + "Unexpected error (not feof or ferror) when reading frame number");
|
||||
throw std::runtime_error(
|
||||
LOCATION +
|
||||
"Unexpected error (not feof or ferror) when reading frame number");
|
||||
}
|
||||
|
||||
int32_t n_clusters; // Saved as 32bit integer in the cluster file
|
||||
|
||||
@@ -40,7 +40,8 @@ struct FileConfig {
|
||||
// ", cols: " + std::to_string(cols) +
|
||||
// ", geometry: " + geometry.to_string() +
|
||||
// ", detector_type: " + ToString(detector_type) +
|
||||
// ", max_frames_per_file: " + std::to_string(max_frames_per_file) +
|
||||
// ", max_frames_per_file: " +
|
||||
// std::to_string(max_frames_per_file) +
|
||||
// ", total_frames: " + std::to_string(total_frames) + " }";
|
||||
// }
|
||||
};
|
||||
|
||||
@@ -36,7 +36,7 @@ class NDArray : public ArrayExpr<NDArray<T, Ndim>, Ndim> {
|
||||
* @brief Default constructor. Constructs an empty NDArray.
|
||||
*
|
||||
*/
|
||||
NDArray() : shape_(), strides_(c_strides<Ndim>(shape_)), data_(nullptr) {};
|
||||
NDArray() : shape_(), strides_(c_strides<Ndim>(shape_)), data_(nullptr){};
|
||||
|
||||
/**
|
||||
* @brief Construct a new NDArray object with a given shape.
|
||||
|
||||
@@ -27,15 +27,14 @@ Shape<Ndim> make_shape(const std::vector<size_t> &shape) {
|
||||
return arr;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Helper function to drop the first dimension of a shape.
|
||||
* This is useful when you want to create a 2D view from a 3D array.
|
||||
* @param shape The shape to drop the first dimension from.
|
||||
* @return A new shape with the first dimension dropped.
|
||||
*/
|
||||
template<size_t Ndim>
|
||||
Shape<Ndim-1> drop_first_dim(const Shape<Ndim> &shape) {
|
||||
template <size_t Ndim>
|
||||
Shape<Ndim - 1> drop_first_dim(const Shape<Ndim> &shape) {
|
||||
static_assert(Ndim > 1, "Cannot drop first dimension from a 1D shape");
|
||||
Shape<Ndim - 1> new_shape;
|
||||
std::copy(shape.begin() + 1, shape.end(), new_shape.begin());
|
||||
@@ -43,13 +42,12 @@ Shape<Ndim-1> drop_first_dim(const Shape<Ndim> &shape) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Helper function when constructing NDArray/NDView. Calculates the number
|
||||
* of elements in the resulting array from a shape.
|
||||
* @brief Helper function when constructing NDArray/NDView. Calculates the
|
||||
* number of elements in the resulting array from a shape.
|
||||
* @param shape The shape to calculate the number of elements for.
|
||||
* @return The number of elements in and NDArray/NDView of that shape.
|
||||
*/
|
||||
template <size_t Ndim>
|
||||
size_t num_elements(const Shape<Ndim> &shape) {
|
||||
template <size_t Ndim> size_t num_elements(const Shape<Ndim> &shape) {
|
||||
return std::accumulate(shape.begin(), shape.end(), 1,
|
||||
std::multiplies<size_t>());
|
||||
}
|
||||
@@ -94,28 +92,28 @@ class NDView : public ArrayExpr<NDView<T, Ndim>, Ndim> {
|
||||
: buffer_(buffer), strides_(c_strides<Ndim>(shape)), shape_(shape),
|
||||
size_(std::accumulate(std::begin(shape), std::end(shape), 1,
|
||||
std::multiplies<>())) {}
|
||||
|
||||
|
||||
template <typename... Ix>
|
||||
std::enable_if_t<sizeof...(Ix) == Ndim, T &> operator()(Ix... index) {
|
||||
return buffer_[element_offset(strides_, index...)];
|
||||
}
|
||||
|
||||
template <typename... Ix>
|
||||
std::enable_if_t<sizeof...(Ix) == 1 && (Ndim > 1), NDView<T, Ndim - 1>> operator()(Ix... index) {
|
||||
std::enable_if_t<sizeof...(Ix) == 1 && (Ndim > 1), NDView<T, Ndim - 1>>
|
||||
operator()(Ix... index) {
|
||||
// return a view of the next dimension
|
||||
std::array<ssize_t, Ndim - 1> new_shape{};
|
||||
std::copy_n(shape_.begin() + 1, Ndim - 1, new_shape.begin());
|
||||
return NDView<T, Ndim - 1>(&buffer_[element_offset(strides_, index...)],
|
||||
new_shape);
|
||||
|
||||
}
|
||||
|
||||
template <typename... Ix>
|
||||
std::enable_if_t<sizeof...(Ix) == Ndim, const T &> operator()(Ix... index) const {
|
||||
std::enable_if_t<sizeof...(Ix) == Ndim, const T &>
|
||||
operator()(Ix... index) const {
|
||||
return buffer_[element_offset(strides_, index...)];
|
||||
}
|
||||
|
||||
|
||||
ssize_t size() const { return static_cast<ssize_t>(size_); }
|
||||
size_t total_bytes() const { return size_ * sizeof(T); }
|
||||
std::array<ssize_t, Ndim> strides() const noexcept { return strides_; }
|
||||
@@ -124,15 +122,11 @@ class NDView : public ArrayExpr<NDView<T, Ndim>, Ndim> {
|
||||
T *end() { return buffer_ + size_; }
|
||||
T const *begin() const { return buffer_; }
|
||||
T const *end() const { return buffer_ + size_; }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Access element at index i.
|
||||
*/
|
||||
T &operator[](ssize_t i) { return buffer_[i]; }
|
||||
T &operator[](ssize_t i) { return buffer_[i]; }
|
||||
|
||||
/**
|
||||
* @brief Access element at index i.
|
||||
@@ -207,7 +201,7 @@ class NDView : public ArrayExpr<NDView<T, Ndim>, Ndim> {
|
||||
void print_all() const;
|
||||
|
||||
/**
|
||||
* @brief Create a subview of a range of the first dimension.
|
||||
* @brief Create a subview of a range of the first dimension.
|
||||
* This is useful for splitting a batches of frames in parallel processing.
|
||||
* @param first The first index of the subview (inclusive).
|
||||
* @param last The last index of the subview (exclusive).
|
||||
|
||||
@@ -27,8 +27,8 @@
|
||||
|
||||
#include <atomic>
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <type_traits>
|
||||
|
||||
@@ -49,7 +49,6 @@ class RawFile : public FileInterface {
|
||||
Frame read_frame(size_t frame_number) override;
|
||||
std::vector<Frame> read_n(size_t n_frames) override;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Read one ROI defined in the master file
|
||||
* @param roi_index index of the ROI to read
|
||||
@@ -63,7 +62,7 @@ class RawFile : public FileInterface {
|
||||
* @brief Read all ROIs defined in the master file
|
||||
* @return vector of Frames (one Frame per ROI)
|
||||
*/
|
||||
std::vector<Frame>read_rois();
|
||||
std::vector<Frame> read_rois();
|
||||
|
||||
/**
|
||||
* @brief Read n frames for the given ROI index
|
||||
@@ -72,7 +71,7 @@ class RawFile : public FileInterface {
|
||||
* @return vector of Frames
|
||||
*/
|
||||
std::vector<Frame> read_n_with_roi(const size_t n_frames,
|
||||
const size_t roi_index);
|
||||
const size_t roi_index);
|
||||
|
||||
void read_into(std::byte *image_buf) override;
|
||||
void read_into(std::byte *image_buf, size_t n_frames) override;
|
||||
|
||||
@@ -175,11 +175,9 @@ calculate_pedestal(NDView<uint16_t, 3> raw_data, ssize_t n_threads) {
|
||||
count += cnt;
|
||||
}
|
||||
|
||||
|
||||
// Will move to a NDArray<T, 3 - static_cast<ssize_t>(only_gain0)>
|
||||
// if only_gain0 is true
|
||||
return safe_divide<T>(accumulator, count);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,12 +6,11 @@
|
||||
#include <vector>
|
||||
namespace aare {
|
||||
|
||||
|
||||
uint16_t adc_sar_05_06_07_08decode64to16(uint64_t input);
|
||||
uint16_t adc_sar_05_decode64to16(uint64_t input);
|
||||
uint16_t adc_sar_04_decode64to16(uint64_t input);
|
||||
void adc_sar_05_06_07_08decode64to16(NDView<uint64_t, 2> input,
|
||||
NDView<uint16_t, 2> output);
|
||||
NDView<uint16_t, 2> output);
|
||||
void adc_sar_05_decode64to16(NDView<uint64_t, 2> input,
|
||||
NDView<uint16_t, 2> output);
|
||||
void adc_sar_04_decode64to16(NDView<uint64_t, 2> input,
|
||||
@@ -22,19 +21,22 @@ void adc_sar_04_decode64to16(NDView<uint64_t, 2> input,
|
||||
* and then return the lower 24 bits as an 32 bit integer
|
||||
* @param input 32-ibt input value
|
||||
* @param offset (should be in range 0-7 to allow for full 24 bits)
|
||||
* @return uint32_t
|
||||
* @return uint32_t
|
||||
*/
|
||||
uint32_t mask32to24bits(uint32_t input, BitOffset offset={});
|
||||
uint32_t mask32to24bits(uint32_t input, BitOffset offset = {});
|
||||
|
||||
/**
|
||||
* @brief Expand 24 bit values in a 8bit buffer to 32bit unsigned integers
|
||||
* Used for detectors with 24bit counters in combination with CTB
|
||||
*
|
||||
* @param input View of the 24 bit data as uint8_t (no 24bit native data type exists)
|
||||
* @param output Destination of the expanded data (32bit, unsigned)
|
||||
* @param offset Offset within the first byte to where the data starts (0-7 bits)
|
||||
*
|
||||
* @param input View of the 24 bit data as uint8_t (no 24bit native data type
|
||||
* exists)
|
||||
* @param output Destination of the expanded data (32bit, unsigned)
|
||||
* @param offset Offset within the first byte to where the data starts (0-7
|
||||
* bits)
|
||||
*/
|
||||
void expand24to32bit(NDView<uint8_t,1> input, NDView<uint32_t,1> output, BitOffset offset={});
|
||||
void expand24to32bit(NDView<uint8_t, 1> input, NDView<uint32_t, 1> output,
|
||||
BitOffset offset = {});
|
||||
|
||||
/**
|
||||
* @brief Apply custom weights to a 16-bit input value. Will sum up
|
||||
|
||||
@@ -353,16 +353,15 @@ using DataTypeVariants = std::variant<uint16_t, uint32_t>;
|
||||
constexpr uint16_t ADC_MASK =
|
||||
0x3FFF; // used to mask out the gain bits in Jungfrau
|
||||
|
||||
|
||||
class BitOffset{
|
||||
class BitOffset {
|
||||
uint8_t m_offset{};
|
||||
public:
|
||||
|
||||
public:
|
||||
BitOffset() = default;
|
||||
explicit BitOffset(uint32_t offset);
|
||||
uint8_t value() const {return m_offset;}
|
||||
bool operator==(const BitOffset& other) const;
|
||||
bool operator<(const BitOffset& other) const;
|
||||
|
||||
uint8_t value() const { return m_offset; }
|
||||
bool operator==(const BitOffset &other) const;
|
||||
bool operator<(const BitOffset &other) const;
|
||||
};
|
||||
|
||||
} // namespace aare
|
||||
@@ -106,8 +106,8 @@ class Logger {
|
||||
}
|
||||
|
||||
std::ostringstream &Get() {
|
||||
os << Color(m_level) << "- " << Timestamp() << " " << Logger::ToString(m_level)
|
||||
<< ": ";
|
||||
os << Color(m_level) << "- " << Timestamp() << " "
|
||||
<< Logger::ToString(m_level) << ": ";
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,9 +20,8 @@ void RunInParallel(F func, const std::vector<std::pair<int, int>> &tasks) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
std::vector<NDView<T,3>> make_subviews(NDView<T, 3> &data, ssize_t n_threads) {
|
||||
std::vector<NDView<T, 3>> make_subviews(NDView<T, 3> &data, ssize_t n_threads) {
|
||||
std::vector<NDView<T, 3>> subviews;
|
||||
subviews.reserve(n_threads);
|
||||
auto limits = split_task(0, data.shape(0), n_threads);
|
||||
|
||||
@@ -39,7 +39,8 @@ void define_raw_file_io_bindings(py::module &m) {
|
||||
// return headers from all subfiles
|
||||
py::array_t<DetectorHeader> header(self.n_modules());
|
||||
|
||||
py::array image = allocate_image_data(self.bytes_per_pixel(), shape);
|
||||
py::array image =
|
||||
allocate_image_data(self.bytes_per_pixel(), shape);
|
||||
self.read_into(
|
||||
reinterpret_cast<std::byte *>(image.mutable_data()),
|
||||
header.mutable_data());
|
||||
@@ -72,7 +73,8 @@ void define_raw_file_io_bindings(py::module &m) {
|
||||
{self.n_modules_in_roi()[0], n_frames});
|
||||
}
|
||||
|
||||
py::array images = allocate_image_data(self.bytes_per_pixel(), shape);
|
||||
py::array images =
|
||||
allocate_image_data(self.bytes_per_pixel(), shape);
|
||||
self.read_into(
|
||||
reinterpret_cast<std::byte *>(images.mutable_data()),
|
||||
n_frames, header.mutable_data());
|
||||
@@ -85,33 +87,32 @@ void define_raw_file_io_bindings(py::module &m) {
|
||||
|
||||
.def(
|
||||
"read_roi",
|
||||
[](RawFile &self,
|
||||
const size_t roi_index) {
|
||||
[](RawFile &self, const size_t roi_index) {
|
||||
if (self.num_rois() == 0) {
|
||||
throw std::runtime_error(LOCATION + "No ROIs defined.");
|
||||
}
|
||||
|
||||
if ( roi_index >= self.num_rois()) {
|
||||
if (roi_index >= self.num_rois()) {
|
||||
throw std::runtime_error(LOCATION +
|
||||
"ROI index out of range.");
|
||||
}
|
||||
|
||||
// return headers from all subfiles
|
||||
py::array_t<DetectorHeader> header(self.n_modules_in_roi()[roi_index]);
|
||||
py::array_t<DetectorHeader> header(
|
||||
self.n_modules_in_roi()[roi_index]);
|
||||
|
||||
|
||||
std::vector<size_t> shape;
|
||||
shape.reserve(2);
|
||||
shape.push_back(self.roi_geometries(roi_index).pixels_y());
|
||||
shape.push_back(self.roi_geometries(roi_index).pixels_x());
|
||||
|
||||
py::array image = allocate_image_data(self.bytes_per_pixel(), shape);
|
||||
|
||||
py::array image =
|
||||
allocate_image_data(self.bytes_per_pixel(), shape);
|
||||
|
||||
self.read_roi_into(
|
||||
reinterpret_cast<std::byte *>(image.mutable_data()),
|
||||
roi_index, self.tell(), header.mutable_data());
|
||||
|
||||
|
||||
self.seek(self.tell() + 1); // advance frame number so the
|
||||
return py::make_tuple(header, image);
|
||||
},
|
||||
@@ -143,8 +144,6 @@ void define_raw_file_io_bindings(py::module &m) {
|
||||
throw std::runtime_error(LOCATION + "No ROIs defined.");
|
||||
}
|
||||
|
||||
|
||||
|
||||
size_t number_of_ROIs = self.num_rois();
|
||||
|
||||
// const uint8_t item_size = self.bytes_per_pixel();
|
||||
@@ -152,25 +151,25 @@ void define_raw_file_io_bindings(py::module &m) {
|
||||
std::vector<py::array> images(number_of_ROIs);
|
||||
|
||||
// return headers from all subfiles
|
||||
std::vector<py::array_t<DetectorHeader>> headers(number_of_ROIs);
|
||||
std::vector<py::array_t<DetectorHeader>> headers(
|
||||
number_of_ROIs);
|
||||
for (size_t r = 0; r < number_of_ROIs; r++) {
|
||||
headers[r] =
|
||||
py::array_t<DetectorHeader>(self.n_modules_in_roi()[r]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
for (size_t r = 0; r < number_of_ROIs; r++) {
|
||||
std::vector<size_t> shape;
|
||||
shape.reserve(2);
|
||||
shape.push_back(self.roi_geometries(r).pixels_y());
|
||||
shape.push_back(self.roi_geometries(r).pixels_x());
|
||||
|
||||
images[r] = allocate_image_data(self.bytes_per_pixel(), shape);
|
||||
images[r] =
|
||||
allocate_image_data(self.bytes_per_pixel(), shape);
|
||||
|
||||
self.read_roi_into(
|
||||
reinterpret_cast<std::byte *>(images[r].mutable_data()),
|
||||
r, self.tell(),headers[r].mutable_data());
|
||||
r, self.tell(), headers[r].mutable_data());
|
||||
}
|
||||
self.seek(self.tell() + 1); // advance frame number so the
|
||||
return py::make_tuple(headers, images);
|
||||
@@ -217,12 +216,10 @@ void define_raw_file_io_bindings(py::module &m) {
|
||||
|
||||
// return headers from all subfiles
|
||||
auto n_mod = self.n_modules_in_roi()[roi_index];
|
||||
py::array_t<DetectorHeader> header({
|
||||
n_frames, n_mod}
|
||||
);
|
||||
py::array_t<DetectorHeader> header({n_frames, n_mod});
|
||||
|
||||
|
||||
py::array images = allocate_image_data(self.bytes_per_pixel(), shape);
|
||||
py::array images =
|
||||
allocate_image_data(self.bytes_per_pixel(), shape);
|
||||
|
||||
auto image_buffer =
|
||||
reinterpret_cast<std::byte *>(images.mutable_data());
|
||||
|
||||
@@ -50,7 +50,7 @@ void define_ctb_raw_file_io_bindings(py::module &m) {
|
||||
|
||||
return output;
|
||||
});
|
||||
|
||||
|
||||
m.def("adc_sar_05_decode64to16", [](py::array_t<uint8_t> input) {
|
||||
if (input.ndim() != 2) {
|
||||
throw std::runtime_error(
|
||||
@@ -121,67 +121,65 @@ void define_ctb_raw_file_io_bindings(py::module &m) {
|
||||
});
|
||||
|
||||
m.def("expand24to32bit",
|
||||
[](py::array_t<uint8_t, py::array::c_style | py::array::forcecast>
|
||||
&input, uint32_t offset){
|
||||
[](py::array_t<uint8_t, py::array::c_style | py::array::forcecast>
|
||||
&input,
|
||||
uint32_t offset) {
|
||||
aare::BitOffset bitoff(offset);
|
||||
py::buffer_info buf = input.request();
|
||||
|
||||
aare::BitOffset bitoff(offset);
|
||||
py::buffer_info buf = input.request();
|
||||
constexpr uint32_t bytes_per_channel = 3; // 24 bit
|
||||
py::array_t<uint32_t> output(buf.size / bytes_per_channel);
|
||||
|
||||
constexpr uint32_t bytes_per_channel = 3; //24 bit
|
||||
py::array_t<uint32_t> output(buf.size/bytes_per_channel);
|
||||
NDView<uint8_t, 1> input_view(input.mutable_data(),
|
||||
{input.size()});
|
||||
NDView<uint32_t, 1> output_view(output.mutable_data(),
|
||||
{output.size()});
|
||||
|
||||
NDView<uint8_t, 1> input_view(input.mutable_data(),
|
||||
{input.size()});
|
||||
NDView<uint32_t, 1> output_view(output.mutable_data(),
|
||||
{output.size()});
|
||||
|
||||
aare::expand24to32bit(input_view, output_view, bitoff);
|
||||
return output;
|
||||
|
||||
});
|
||||
aare::expand24to32bit(input_view, output_view, bitoff);
|
||||
return output;
|
||||
});
|
||||
|
||||
m.def("decode_my302",
|
||||
[](py::array_t<uint8_t, py::array::c_style | py::array::forcecast>
|
||||
&input, uint32_t offset){
|
||||
[](py::array_t<uint8_t, py::array::c_style | py::array::forcecast>
|
||||
&input,
|
||||
uint32_t offset) {
|
||||
// Physical layout of the chip
|
||||
constexpr size_t channels = 64;
|
||||
constexpr size_t counters = 3;
|
||||
constexpr size_t bytes_per_channel = 3; // 24 bit
|
||||
constexpr int n_outputs = 2;
|
||||
|
||||
// Physical layout of the chip
|
||||
constexpr size_t channels = 64;
|
||||
constexpr size_t counters = 3;
|
||||
constexpr size_t bytes_per_channel = 3; //24 bit
|
||||
constexpr int n_outputs = 2;
|
||||
ssize_t expected_size = channels * counters * bytes_per_channel;
|
||||
|
||||
ssize_t expected_size = channels*counters*bytes_per_channel;
|
||||
// If whe have an offset we need one extra byte per output
|
||||
aare::BitOffset bitoff(offset);
|
||||
if (bitoff.value())
|
||||
expected_size += n_outputs;
|
||||
|
||||
//If whe have an offset we need one extra byte per output
|
||||
aare::BitOffset bitoff(offset);
|
||||
if(bitoff.value())
|
||||
expected_size += n_outputs;
|
||||
if (input.size() != expected_size) {
|
||||
throw std::runtime_error(fmt::format(
|
||||
"{} Expected an input size of {} bytes. Called "
|
||||
"with input size of {}",
|
||||
LOCATION, expected_size, input.size()));
|
||||
}
|
||||
|
||||
if (input.size() != expected_size) {
|
||||
throw std::runtime_error(
|
||||
fmt::format("{} Expected an input size of {} bytes. Called "
|
||||
"with input size of {}",
|
||||
LOCATION, expected_size, input.size()));
|
||||
}
|
||||
py::buffer_info buf = input.request();
|
||||
py::array_t<uint32_t> output(channels * counters);
|
||||
|
||||
py::buffer_info buf = input.request();
|
||||
py::array_t<uint32_t> output(channels * counters);
|
||||
for (int i = 0; i != n_outputs; ++i) {
|
||||
auto step = input.size() / n_outputs;
|
||||
auto out_step = output.size() / n_outputs;
|
||||
NDView<uint8_t, 1> input_view(input.mutable_data() + step * i,
|
||||
{input.size() / n_outputs});
|
||||
NDView<uint32_t, 1> output_view(output.mutable_data() +
|
||||
out_step * i,
|
||||
{output.size() / n_outputs});
|
||||
|
||||
for (int i = 0; i!=n_outputs; ++i){
|
||||
auto step = input.size()/n_outputs;
|
||||
auto out_step = output.size()/n_outputs;
|
||||
NDView<uint8_t, 1> input_view(input.mutable_data()+step*i,
|
||||
{input.size()/n_outputs});
|
||||
NDView<uint32_t, 1> output_view(output.mutable_data()+out_step*i,
|
||||
{output.size()/n_outputs});
|
||||
aare::expand24to32bit(input_view, output_view, bitoff);
|
||||
}
|
||||
|
||||
aare::expand24to32bit(input_view, output_view, bitoff);
|
||||
|
||||
}
|
||||
|
||||
return output;
|
||||
|
||||
});
|
||||
return output;
|
||||
});
|
||||
|
||||
py::class_<CtbRawFile>(m, "CtbRawFile")
|
||||
.def(py::init<const std::filesystem::path &>())
|
||||
|
||||
@@ -64,9 +64,8 @@ void define_file_io_bindings(py::module &m) {
|
||||
.def_property_readonly("cols", &File::cols)
|
||||
.def_property_readonly("bitdepth", &File::bitdepth)
|
||||
.def_property_readonly("bytes_per_pixel", &File::bytes_per_pixel)
|
||||
.def_property_readonly(
|
||||
"detector_type",
|
||||
[](File &self) { return self.detector_type(); })
|
||||
.def_property_readonly("detector_type",
|
||||
[](File &self) { return self.detector_type(); })
|
||||
.def("read_frame",
|
||||
[](File &self) {
|
||||
const uint8_t item_size = self.bytes_per_pixel();
|
||||
@@ -161,7 +160,6 @@ void define_file_io_bindings(py::module &m) {
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
py::class_<ScanParameters>(m, "ScanParameters")
|
||||
.def(py::init<const std::string &>())
|
||||
.def(py::init<const ScanParameters &>())
|
||||
|
||||
@@ -86,17 +86,17 @@ struct fmt_format_trait<Cluster<T, ClusterSizeX, ClusterSizeY, CoordType>> {
|
||||
template <typename ClusterType>
|
||||
auto fmt_format = fmt_format_trait<ClusterType>::value();
|
||||
|
||||
/**
|
||||
* Helper function to allocate image data given item size and shape
|
||||
* used when we want to fill a numpy array and return to python
|
||||
*/
|
||||
/**
|
||||
* Helper function to allocate image data given item size and shape
|
||||
* used when we want to fill a numpy array and return to python
|
||||
*/
|
||||
py::array allocate_image_data(size_t item_size,
|
||||
const std::vector<size_t> &shape) {
|
||||
py::array image_data;
|
||||
if (item_size == 1) {
|
||||
image_data = py::array_t<uint8_t>(shape);
|
||||
} else if (item_size == 2) {
|
||||
image_data = py::array_t<uint16_t>(shape);
|
||||
image_data = py::array_t<uint16_t>(shape);
|
||||
} else if (item_size == 4) {
|
||||
image_data = py::array_t<uint32_t>(shape);
|
||||
}
|
||||
|
||||
@@ -58,10 +58,8 @@ class ClusterFinderMTWrapper
|
||||
size_t m_sink_size() const { return this->m_sink.sizeGuess(); }
|
||||
};
|
||||
|
||||
|
||||
TEST_CASE("multithreaded cluster finder", "[.with-data]") {
|
||||
auto fpath =
|
||||
test_data_path() / "raw/moench03/cu_half_speed_master_4.json";
|
||||
auto fpath = test_data_path() / "raw/moench03/cu_half_speed_master_4.json";
|
||||
|
||||
REQUIRE(std::filesystem::exists(fpath));
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ using aare::Cluster;
|
||||
using aare::ClusterVector;
|
||||
using C1 = Cluster<int32_t, 2, 2>;
|
||||
|
||||
|
||||
TEST_CASE("A newly created ClusterVector is empty") {
|
||||
ClusterVector<C1> cv(4);
|
||||
REQUIRE(cv.empty());
|
||||
@@ -174,7 +173,8 @@ TEST_CASE("Push back more than initial capacity") {
|
||||
REQUIRE(initial_data != cv.data());
|
||||
}
|
||||
|
||||
TEST_CASE("Concatenate two cluster vectors where the first has enough capacity") {
|
||||
TEST_CASE(
|
||||
"Concatenate two cluster vectors where the first has enough capacity") {
|
||||
ClusterVector<Cluster<int32_t, 2, 2>> cv1(12);
|
||||
Cluster<int32_t, 2, 2> c1 = {1, 2, {3, 4, 5, 6}};
|
||||
cv1.push_back(c1);
|
||||
|
||||
@@ -5,9 +5,8 @@
|
||||
namespace aare {
|
||||
|
||||
CtbRawFile::CtbRawFile(const std::filesystem::path &fname) : m_master(fname) {
|
||||
if( (m_master.detector_type() != DetectorType::ChipTestBoard) &&
|
||||
(m_master.detector_type() != DetectorType::Xilinx_ChipTestBoard) )
|
||||
{
|
||||
if ((m_master.detector_type() != DetectorType::ChipTestBoard) &&
|
||||
(m_master.detector_type() != DetectorType::Xilinx_ChipTestBoard)) {
|
||||
throw std::runtime_error(LOCATION + "Not a Ctb file");
|
||||
}
|
||||
|
||||
@@ -15,8 +14,9 @@ CtbRawFile::CtbRawFile(const std::filesystem::path &fname) : m_master(fname) {
|
||||
|
||||
// open the first subfile
|
||||
m_file.open(m_master.data_fname(0, 0), std::ios::binary);
|
||||
if(!m_file)
|
||||
throw std::runtime_error(LOCATION + "Could not open: " + m_master.data_fname(0, 0).string());
|
||||
if (!m_file)
|
||||
throw std::runtime_error(
|
||||
LOCATION + "Could not open: " + m_master.data_fname(0, 0).string());
|
||||
}
|
||||
|
||||
void CtbRawFile::read_into(std::byte *image_buf, DetectorHeader *header) {
|
||||
@@ -63,7 +63,6 @@ void CtbRawFile::find_subfiles() {
|
||||
// we can semi safely assume that there is only one module for CTB
|
||||
while (std::filesystem::exists(m_master.data_fname(0, m_num_subfiles)))
|
||||
m_num_subfiles++;
|
||||
|
||||
}
|
||||
|
||||
void CtbRawFile::open_data_file(size_t subfile_index) {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
|
||||
#include "aare/Dtype.hpp"
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
|
||||
@@ -71,7 +71,8 @@ TEST_CASE("Seek in a JungfrauDataFile", "[.with-data]") {
|
||||
REQUIRE_THROWS(f.seek(86356)); // out of range
|
||||
}
|
||||
|
||||
TEST_CASE("Open a Jungfrau data file with non zero file index", "[.with-data]") {
|
||||
TEST_CASE("Open a Jungfrau data file with non zero file index",
|
||||
"[.with-data]") {
|
||||
|
||||
auto fpath = test_data_path() / "dat" / "AldoJF65k_000003.dat";
|
||||
REQUIRE(std::filesystem::exists(fpath));
|
||||
|
||||
@@ -105,43 +105,43 @@ TEST_CASE("Indexing of a 3D image") {
|
||||
REQUIRE(img(2, 3, 1) == 23);
|
||||
}
|
||||
|
||||
TEST_CASE("Access to data using a pointer"){
|
||||
TEST_CASE("Access to data using a pointer") {
|
||||
// This pattern is discouraged but sometimes useful
|
||||
NDArray<int,2> img{{4,5},0};
|
||||
int* data_ptr = img.data();
|
||||
for(int i=0; i < img.size(); ++i){
|
||||
data_ptr[i] = i*2;
|
||||
NDArray<int, 2> img{{4, 5}, 0};
|
||||
int *data_ptr = img.data();
|
||||
for (int i = 0; i < img.size(); ++i) {
|
||||
data_ptr[i] = i * 2;
|
||||
}
|
||||
|
||||
// Cross check using operator[]
|
||||
for(int i=0; i < img.size(); ++i){
|
||||
REQUIRE(img[i] == i*2);
|
||||
for (int i = 0; i < img.size(); ++i) {
|
||||
REQUIRE(img[i] == i * 2);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Access to data using a pointer for a const NDArray"){
|
||||
TEST_CASE("Access to data using a pointer for a const NDArray") {
|
||||
// This pattern is discouraged but sometimes useful
|
||||
|
||||
// Using a lambda to create a const NDArray with known data
|
||||
const NDArray<int,2> arr = [](){
|
||||
NDArray<int,2> img{{4,5},0};
|
||||
int* data_ptr = img.data();
|
||||
for(int i=0; i < img.size(); ++i){
|
||||
data_ptr[i] = i*3;
|
||||
const NDArray<int, 2> arr = []() {
|
||||
NDArray<int, 2> img{{4, 5}, 0};
|
||||
int *data_ptr = img.data();
|
||||
for (int i = 0; i < img.size(); ++i) {
|
||||
data_ptr[i] = i * 3;
|
||||
}
|
||||
return img;
|
||||
}();
|
||||
|
||||
// Cross check using data() pointer, if compiles we can get a const pointer
|
||||
const int* const_data_ptr = arr.data();
|
||||
for(int i=0; i < arr.size(); ++i){
|
||||
REQUIRE(const_data_ptr[i] == i*3);
|
||||
const int *const_data_ptr = arr.data();
|
||||
for (int i = 0; i < arr.size(); ++i) {
|
||||
REQUIRE(const_data_ptr[i] == i * 3);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Use *buffer"){
|
||||
// Another useful but discouraged pattern. But can be useful when getting data
|
||||
// from external sources
|
||||
TEST_CASE("Use *buffer") {
|
||||
// Another useful but discouraged pattern. But can be useful when getting
|
||||
// data from external sources
|
||||
Shape<2> shape{{4, 5}};
|
||||
NDArray<int, 2> src(shape);
|
||||
NDArray<int, 2> dst(shape);
|
||||
@@ -491,64 +491,60 @@ TEST_CASE("Construct an NDArray from an std::array") {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Copy construct an NDArray"){
|
||||
NDArray<int,2> a({{3,4}},0);
|
||||
a(1,1) = 42;
|
||||
a(2,3) = 84;
|
||||
TEST_CASE("Copy construct an NDArray") {
|
||||
NDArray<int, 2> a({{3, 4}}, 0);
|
||||
a(1, 1) = 42;
|
||||
a(2, 3) = 84;
|
||||
|
||||
NDArray<int,2> b(a);
|
||||
REQUIRE(b.shape() == Shape<2>{3,4});
|
||||
NDArray<int, 2> b(a);
|
||||
REQUIRE(b.shape() == Shape<2>{3, 4});
|
||||
REQUIRE(b.size() == 12);
|
||||
REQUIRE(b(1,1) == 42);
|
||||
REQUIRE(b(2,3) == 84);
|
||||
REQUIRE(b(1, 1) == 42);
|
||||
REQUIRE(b(2, 3) == 84);
|
||||
|
||||
// Modifying b should not affect a
|
||||
b(1,1) = 7;
|
||||
REQUIRE(a(1,1) == 42);
|
||||
b(1, 1) = 7;
|
||||
REQUIRE(a(1, 1) == 42);
|
||||
|
||||
REQUIRE(a.data() != b.data());
|
||||
}
|
||||
|
||||
TEST_CASE("Move construct an NDArray") {
|
||||
NDArray<int, 2> a({{3, 4}}, 0);
|
||||
a(1, 1) = 42;
|
||||
a(2, 3) = 84;
|
||||
|
||||
TEST_CASE("Move construct an NDArray"){
|
||||
NDArray<int,2> a({{3,4}},0);
|
||||
a(1,1) = 42;
|
||||
a(2,3) = 84;
|
||||
|
||||
NDArray<int,2> b(std::move(a));
|
||||
REQUIRE(b.shape() == Shape<2>{3,4});
|
||||
NDArray<int, 2> b(std::move(a));
|
||||
REQUIRE(b.shape() == Shape<2>{3, 4});
|
||||
REQUIRE(b.size() == 12);
|
||||
REQUIRE(b(1,1) == 42);
|
||||
REQUIRE(b(2,3) == 84);
|
||||
REQUIRE(b(1, 1) == 42);
|
||||
REQUIRE(b(2, 3) == 84);
|
||||
|
||||
// The moved from object should be in a unspecified but valid state.
|
||||
// This means original array pointer should be null, and size zero
|
||||
REQUIRE(a.size() == 0);
|
||||
REQUIRE(a.shape() == Shape<2>{0,0});
|
||||
REQUIRE(a.shape() == Shape<2>{0, 0});
|
||||
REQUIRE(a.data() == nullptr);
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("Move construct from an array with Ndim + 1") {
|
||||
NDArray<int, 3> a({{1,2,2}}, 0);
|
||||
NDArray<int, 3> a({{1, 2, 2}}, 0);
|
||||
a(0, 0, 0) = 1;
|
||||
a(0, 0, 1) = 2;
|
||||
a(0, 1, 0) = 3;
|
||||
a(0, 1, 1) = 4;
|
||||
|
||||
|
||||
NDArray<int, 2> b(std::move(a));
|
||||
REQUIRE(b.shape() == Shape<2>{2,2});
|
||||
REQUIRE(b.shape() == Shape<2>{2, 2});
|
||||
REQUIRE(b.size() == 4);
|
||||
REQUIRE(b(0, 0) == 1);
|
||||
REQUIRE(b(0, 1) == 2);
|
||||
REQUIRE(b(1, 0) == 3);
|
||||
REQUIRE(b(1, 1) == 4);
|
||||
|
||||
}
|
||||
|
||||
TEST_CASE("Move construct from an array with Ndim + 1 throws on size mismatch") {
|
||||
NDArray<int, 3> a({{2,2,2}}, 0);
|
||||
TEST_CASE(
|
||||
"Move construct from an array with Ndim + 1 throws on size mismatch") {
|
||||
NDArray<int, 3> a({{2, 2, 2}}, 0);
|
||||
REQUIRE_THROWS(NDArray<int, 2>(std::move(a)));
|
||||
}
|
||||
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
#include "aare/NDView.hpp"
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <iostream>
|
||||
#include <numeric>
|
||||
#include <vector>
|
||||
#include <cstddef>
|
||||
|
||||
using aare::NDView;
|
||||
using aare::Shape;
|
||||
@@ -23,7 +23,6 @@ TEST_CASE("Element reference 1D") {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("Assign elements through () and []") {
|
||||
std::vector<int> vec;
|
||||
for (int i = 0; i != 10; ++i) {
|
||||
@@ -31,11 +30,10 @@ TEST_CASE("Assign elements through () and []") {
|
||||
}
|
||||
NDView<int, 1> data(vec.data(), Shape<1>{10});
|
||||
REQUIRE(vec.size() == static_cast<size_t>(data.size()));
|
||||
|
||||
|
||||
data[3] = 187;
|
||||
data(4) = 512;
|
||||
|
||||
|
||||
REQUIRE(data(0) == 0);
|
||||
REQUIRE(data[0] == 0);
|
||||
REQUIRE(data(1) == 1);
|
||||
@@ -56,8 +54,6 @@ TEST_CASE("Assign elements through () and []") {
|
||||
REQUIRE(data[8] == 8);
|
||||
REQUIRE(data(9) == 9);
|
||||
REQUIRE(data[9] == 9);
|
||||
|
||||
|
||||
}
|
||||
|
||||
TEST_CASE("Element reference 1D with a const NDView") {
|
||||
@@ -73,7 +69,6 @@ TEST_CASE("Element reference 1D with a const NDView") {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("Element reference 2D") {
|
||||
std::vector<int> vec(12);
|
||||
std::iota(vec.begin(), vec.end(), 0);
|
||||
@@ -190,8 +185,6 @@ TEST_CASE("iterators") {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
TEST_CASE("divide with another NDView") {
|
||||
std::vector<int> vec0{9, 12, 3};
|
||||
std::vector<int> vec1{3, 2, 1};
|
||||
@@ -229,7 +222,7 @@ TEST_CASE("compare two views") {
|
||||
REQUIRE((view1 == view2));
|
||||
}
|
||||
|
||||
TEST_CASE("Compare two views with different size"){
|
||||
TEST_CASE("Compare two views with different size") {
|
||||
std::vector<int> vec1(12);
|
||||
std::iota(vec1.begin(), vec1.end(), 0);
|
||||
NDView<int, 2> view1(vec1.data(), Shape<2>{3, 4});
|
||||
@@ -241,7 +234,7 @@ TEST_CASE("Compare two views with different size"){
|
||||
REQUIRE_FALSE(view1 == view2);
|
||||
}
|
||||
|
||||
TEST_CASE("Compare two views with same size but different shape"){
|
||||
TEST_CASE("Compare two views with same size but different shape") {
|
||||
std::vector<int> vec1(12);
|
||||
std::iota(vec1.begin(), vec1.end(), 0);
|
||||
NDView<int, 2> view1(vec1.data(), Shape<2>{3, 4});
|
||||
@@ -262,10 +255,9 @@ TEST_CASE("Create a view over a vector") {
|
||||
REQUIRE(v[11] == 11);
|
||||
}
|
||||
|
||||
TEST_CASE("NDView over byte"){
|
||||
TEST_CASE("NDView over byte") {
|
||||
std::vector<std::byte> buf(5);
|
||||
auto v = aare::make_view(buf);
|
||||
REQUIRE(v.shape()[0] == 5);
|
||||
REQUIRE(v[0] == std::byte{0});
|
||||
|
||||
}
|
||||
@@ -105,8 +105,8 @@ NDArray<ssize_t, 2> GenerateEigerFlipRowsPixelMap() {
|
||||
}
|
||||
|
||||
NDArray<ssize_t, 2> GenerateMH02SingleCounterPixelMap() {
|
||||
// This is the pixel map for a single counter Matterhorn02, i.e. 48x48 pixels.
|
||||
// Data is read from two transceivers in blocks of 4 pixels.
|
||||
// This is the pixel map for a single counter Matterhorn02, i.e. 48x48
|
||||
// pixels. Data is read from two transceivers in blocks of 4 pixels.
|
||||
NDArray<ssize_t, 2> order_map({48, 48});
|
||||
size_t offset = 0;
|
||||
size_t nSamples = 4;
|
||||
@@ -131,8 +131,7 @@ NDArray<ssize_t, 3> GenerateMH02FourCounterPixelMap() {
|
||||
for (int row = 0; row < 48; row++) {
|
||||
for (int col = 0; col < 48; col++) {
|
||||
order_map(counter, row, col) =
|
||||
single_counter_map(row, col) +
|
||||
counter * 48 * 48;
|
||||
single_counter_map(row, col) + counter * 48 * 48;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +62,6 @@ Frame RawFile::read_roi(const size_t roi_index) {
|
||||
return get_frame(m_current_frame++, roi_index);
|
||||
}
|
||||
|
||||
|
||||
std::vector<Frame> RawFile::read_rois() {
|
||||
|
||||
if (!m_master.rois()) {
|
||||
@@ -83,8 +82,6 @@ std::vector<Frame> RawFile::read_rois() {
|
||||
return frames;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Frame RawFile::read_frame() {
|
||||
if (m_master.rois().has_value() && m_master.rois()->size() > 1) {
|
||||
throw std::runtime_error(LOCATION +
|
||||
@@ -473,7 +470,7 @@ std::vector<Frame> RawFile::read_n(size_t n_frames) {
|
||||
}
|
||||
|
||||
std::vector<Frame> RawFile::read_n_with_roi(const size_t n_frames,
|
||||
const size_t roi_index) {
|
||||
const size_t roi_index) {
|
||||
if (roi_index >= num_rois()) {
|
||||
throw std::runtime_error(LOCATION + "ROI index out of range.");
|
||||
}
|
||||
|
||||
@@ -255,7 +255,7 @@ void RawMasterFile::parse_json(std::istream &is) {
|
||||
// TODO! Not valid for CTB but not changing api right now!
|
||||
// Not all detectors write the bitdepth but in case
|
||||
// its not there it is 16
|
||||
if(j.contains("Dynamic Range") && j["Dynamic Range"].is_number()){
|
||||
if (j.contains("Dynamic Range") && j["Dynamic Range"].is_number()) {
|
||||
m_bitdepth = j["Dynamic Range"];
|
||||
} else {
|
||||
m_bitdepth = 16;
|
||||
|
||||
@@ -398,7 +398,7 @@ TEST_CASE("Parse EIGER 7.2 master from string stream") {
|
||||
REQUIRE(f.timing_mode() == TimingMode::Auto);
|
||||
REQUIRE(f.geometry().col == 2);
|
||||
REQUIRE(f.geometry().row == 2);
|
||||
|
||||
|
||||
REQUIRE(f.image_size_in_bytes() == 524288);
|
||||
REQUIRE(f.pixels_x() == 512);
|
||||
REQUIRE(f.pixels_y() == 256);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
|
||||
#include <aare/algorithm.hpp>
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
#include "aare/decode.hpp"
|
||||
#include <fmt/format.h>
|
||||
#include <cmath>
|
||||
#include <fmt/format.h>
|
||||
namespace aare {
|
||||
|
||||
uint16_t adc_sar_05_06_07_08decode64to16(uint64_t input) {
|
||||
@@ -24,7 +24,7 @@ uint16_t adc_sar_05_06_07_08decode64to16(uint64_t input) {
|
||||
}
|
||||
|
||||
void adc_sar_05_06_07_08decode64to16(NDView<uint64_t, 2> input,
|
||||
NDView<uint16_t, 2> output) {
|
||||
NDView<uint16_t, 2> output) {
|
||||
if (input.shape() != output.shape()) {
|
||||
throw std::invalid_argument(LOCATION +
|
||||
" input and output shapes must match");
|
||||
@@ -139,49 +139,50 @@ void apply_custom_weights(NDView<uint16_t, 1> input, NDView<double, 1> output,
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t mask32to24bits(uint32_t input, BitOffset offset){
|
||||
uint32_t mask32to24bits(uint32_t input, BitOffset offset) {
|
||||
constexpr uint32_t mask24bits{0xFFFFFF};
|
||||
return (input >> offset.value()) & mask24bits;
|
||||
}
|
||||
|
||||
void expand24to32bit(NDView<uint8_t,1> input, NDView<uint32_t,1> output, BitOffset bit_offset){
|
||||
void expand24to32bit(NDView<uint8_t, 1> input, NDView<uint32_t, 1> output,
|
||||
BitOffset bit_offset) {
|
||||
|
||||
ssize_t bytes_per_channel = 3; //24bit
|
||||
ssize_t min_input_size = output.size()*bytes_per_channel;
|
||||
ssize_t bytes_per_channel = 3; // 24bit
|
||||
ssize_t min_input_size = output.size() * bytes_per_channel;
|
||||
|
||||
//if we have an offset we need one more byte in the input data
|
||||
// if we have an offset we need one more byte in the input data
|
||||
if (bit_offset.value())
|
||||
min_input_size += 1;
|
||||
min_input_size += 1;
|
||||
|
||||
if (input.size() < min_input_size)
|
||||
throw std::runtime_error(fmt::format(
|
||||
"{} Mismatch between input and output size. Output "
|
||||
"size of {} with bit offset {} requires an input of at least {} "
|
||||
"bytes. Called with input size: {} output size: {}",
|
||||
LOCATION, output.size(), bit_offset.value(), min_input_size, input.size(), output.size()));
|
||||
LOCATION, output.size(), bit_offset.value(), min_input_size,
|
||||
input.size(), output.size()));
|
||||
|
||||
auto* in = input.data();
|
||||
auto *in = input.data();
|
||||
|
||||
if(bit_offset.value()){
|
||||
//If there is a bit_offset we copy 4 bytes and then
|
||||
//mask out the correct ones.
|
||||
for (auto& v : output){
|
||||
if (bit_offset.value()) {
|
||||
// If there is a bit_offset we copy 4 bytes and then
|
||||
// mask out the correct ones.
|
||||
for (auto &v : output) {
|
||||
uint32_t val{};
|
||||
std::memcpy(&val, in, sizeof(val));
|
||||
v = mask32to24bits(val, bit_offset);
|
||||
in += bytes_per_channel;
|
||||
}
|
||||
}else{
|
||||
//If there is no offset we can directly copy the bits
|
||||
//without masking
|
||||
for (auto& v : output){
|
||||
}
|
||||
} else {
|
||||
// If there is no offset we can directly copy the bits
|
||||
// without masking
|
||||
for (auto &v : output) {
|
||||
uint32_t val{};
|
||||
std::memcpy(&val, in, 3);
|
||||
v = val;
|
||||
in += bytes_per_channel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // namespace aare
|
||||
|
||||
@@ -75,35 +75,32 @@ TEST_CASE("test_apply_custom_weights") {
|
||||
CHECK_THAT(output, WithinAbs(6.34, 0.001));
|
||||
}
|
||||
|
||||
TEST_CASE("Mask 32 bit unsigned integer to 24 bit"){
|
||||
//any number less than 2**24 (16777216) should be the same
|
||||
CHECK(aare::mask32to24bits(0)==0);
|
||||
CHECK(aare::mask32to24bits(19)==19);
|
||||
CHECK(aare::mask32to24bits(29875)==29875);
|
||||
CHECK(aare::mask32to24bits(1092177)==1092177);
|
||||
CHECK(aare::mask32to24bits(0xFFFF)==0xFFFF);
|
||||
CHECK(aare::mask32to24bits(0xFFFFFFFF)==0xFFFFFF);
|
||||
TEST_CASE("Mask 32 bit unsigned integer to 24 bit") {
|
||||
// any number less than 2**24 (16777216) should be the same
|
||||
CHECK(aare::mask32to24bits(0) == 0);
|
||||
CHECK(aare::mask32to24bits(19) == 19);
|
||||
CHECK(aare::mask32to24bits(29875) == 29875);
|
||||
CHECK(aare::mask32to24bits(1092177) == 1092177);
|
||||
CHECK(aare::mask32to24bits(0xFFFF) == 0xFFFF);
|
||||
CHECK(aare::mask32to24bits(0xFFFFFFFF) == 0xFFFFFF);
|
||||
|
||||
// Offset specifies that the should ignore 0-7 bits
|
||||
// at the start
|
||||
CHECK(aare::mask32to24bits(0xFFFF, BitOffset(4))==0xFFF);
|
||||
CHECK(aare::mask32to24bits(0xFF0000d9)==0xd9);
|
||||
CHECK(aare::mask32to24bits(0xFF000d9F, BitOffset(4))==0xF000d9);
|
||||
CHECK(aare::mask32to24bits(16777217)==1);
|
||||
CHECK(aare::mask32to24bits(15,BitOffset(7))==0);
|
||||
|
||||
//Highest bit set to 1 should just be excluded
|
||||
//lowest 4 bits set to 1
|
||||
CHECK(aare::mask32to24bits(0x8000000f,BitOffset(7))==0);
|
||||
|
||||
CHECK(aare::mask32to24bits(0xFFFF, BitOffset(4)) == 0xFFF);
|
||||
CHECK(aare::mask32to24bits(0xFF0000d9) == 0xd9);
|
||||
CHECK(aare::mask32to24bits(0xFF000d9F, BitOffset(4)) == 0xF000d9);
|
||||
CHECK(aare::mask32to24bits(16777217) == 1);
|
||||
CHECK(aare::mask32to24bits(15, BitOffset(7)) == 0);
|
||||
|
||||
// Highest bit set to 1 should just be excluded
|
||||
// lowest 4 bits set to 1
|
||||
CHECK(aare::mask32to24bits(0x8000000f, BitOffset(7)) == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("Expand container with 24 bit data to 32"){
|
||||
TEST_CASE("Expand container with 24 bit data to 32") {
|
||||
{
|
||||
uint8_t buffer[] = {
|
||||
0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
aare::NDView<uint8_t, 1> input(&buffer[0], {9});
|
||||
@@ -116,9 +113,7 @@ TEST_CASE("Expand container with 24 bit data to 32"){
|
||||
}
|
||||
{
|
||||
uint8_t buffer[] = {
|
||||
0x0F, 0x00, 0x00,
|
||||
0xFF, 0x00, 0x00,
|
||||
0xFF, 0xFF, 0xFF,
|
||||
0x0F, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF,
|
||||
};
|
||||
|
||||
aare::NDView<uint8_t, 1> input(&buffer[0], {9});
|
||||
@@ -131,9 +126,7 @@ TEST_CASE("Expand container with 24 bit data to 32"){
|
||||
}
|
||||
{
|
||||
uint8_t buffer[] = {
|
||||
0x00, 0x00, 0xFF,
|
||||
0xFF, 0xFF, 0x00,
|
||||
0x00, 0xFF, 0x00,
|
||||
0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00,
|
||||
};
|
||||
|
||||
aare::NDView<uint8_t, 1> input(&buffer[0], {9});
|
||||
@@ -147,20 +140,16 @@ TEST_CASE("Expand container with 24 bit data to 32"){
|
||||
REQUIRE_THROWS(aare::expand24to32bit(input, out.view(), BitOffset(4)));
|
||||
}
|
||||
{
|
||||
//For use with offset we need an extra byte
|
||||
uint8_t buffer[] = {
|
||||
0x00, 0x00, 0xFF,
|
||||
0xFF, 0xFF, 0x00,
|
||||
0x00, 0xFF, 0x00, 0x00
|
||||
};
|
||||
// For use with offset we need an extra byte
|
||||
uint8_t buffer[] = {0x00, 0x00, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0xFF, 0x00, 0x00};
|
||||
|
||||
aare::NDView<uint8_t, 1> input(&buffer[0], {10});
|
||||
aare::NDArray<uint32_t, 1> out({3}); //still output.size == 3
|
||||
aare::NDArray<uint32_t, 1> out({3}); // still output.size == 3
|
||||
aare::expand24to32bit(input, out.view(), BitOffset(4));
|
||||
|
||||
CHECK(out(0) == 0xFFF000);
|
||||
CHECK(out(1) == 0xFFF);
|
||||
CHECK(out(2) == 0xFF0);
|
||||
}
|
||||
|
||||
}
|
||||
23
src/defs.cpp
23
src/defs.cpp
@@ -51,23 +51,20 @@ void assert_failed(const std::string &msg) {
|
||||
// throw std::runtime_error("Could not decode detector to string");
|
||||
// }
|
||||
|
||||
|
||||
BitOffset::BitOffset(uint32_t offset){
|
||||
if (offset>7)
|
||||
throw std::runtime_error(fmt::format("{} BitOffset needs to be <8: Called with {}", LOCATION, offset));
|
||||
BitOffset::BitOffset(uint32_t offset) {
|
||||
if (offset > 7)
|
||||
throw std::runtime_error(fmt::format(
|
||||
"{} BitOffset needs to be <8: Called with {}", LOCATION, offset));
|
||||
|
||||
m_offset = static_cast<uint8_t>(offset);
|
||||
|
||||
}
|
||||
|
||||
bool BitOffset::operator==(const BitOffset& other) const {
|
||||
return m_offset == other.m_offset;
|
||||
}
|
||||
|
||||
bool BitOffset::operator<(const BitOffset& other) const {
|
||||
return m_offset < other.m_offset;
|
||||
}
|
||||
|
||||
bool BitOffset::operator==(const BitOffset &other) const {
|
||||
return m_offset == other.m_offset;
|
||||
}
|
||||
|
||||
bool BitOffset::operator<(const BitOffset &other) const {
|
||||
return m_offset < other.m_offset;
|
||||
}
|
||||
|
||||
} // namespace aare
|
||||
@@ -4,8 +4,6 @@
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <string>
|
||||
|
||||
|
||||
|
||||
TEST_CASE("Enum values") {
|
||||
// Since some of the enums are written to file we need to make sure
|
||||
// they match the value in the slsDetectorPackage
|
||||
@@ -38,23 +36,22 @@ TEST_CASE("DynamicCluster creation") {
|
||||
REQUIRE(c2.data() != nullptr);
|
||||
}
|
||||
|
||||
TEST_CASE("Basic ops on BitOffset"){
|
||||
TEST_CASE("Basic ops on BitOffset") {
|
||||
REQUIRE_THROWS(aare::BitOffset(10));
|
||||
|
||||
aare::BitOffset offset(5);
|
||||
REQUIRE(offset.value()==5);
|
||||
REQUIRE(offset.value() == 5);
|
||||
|
||||
aare::BitOffset offset2;
|
||||
REQUIRE(offset2.value()==0);
|
||||
REQUIRE(offset2.value() == 0);
|
||||
|
||||
aare::BitOffset offset3(offset);
|
||||
REQUIRE(offset3.value()==5);
|
||||
REQUIRE(offset3.value() == 5);
|
||||
|
||||
REQUIRE(offset==offset3);
|
||||
REQUIRE(offset == offset3);
|
||||
|
||||
//Now assign offset to offset2 which should get the value 5
|
||||
// Now assign offset to offset2 which should get the value 5
|
||||
offset2 = offset;
|
||||
REQUIRE(offset2.value()==5);
|
||||
REQUIRE(offset2==offset);
|
||||
REQUIRE(offset2.value() == 5);
|
||||
REQUIRE(offset2 == offset);
|
||||
}
|
||||
|
||||
|
||||
@@ -53,7 +53,6 @@ template <> FrameDiscardPolicy string_to(const std::string &arg) {
|
||||
arg + "\"");
|
||||
}
|
||||
|
||||
|
||||
template <> DACIndex string_to(const std::string &arg) {
|
||||
if (arg == "dac 0")
|
||||
return DACIndex::DAC_0;
|
||||
@@ -236,12 +235,12 @@ template <> DACIndex string_to(const std::string &arg) {
|
||||
"\"");
|
||||
}
|
||||
|
||||
|
||||
std::string remove_unit(std::string &str) {
|
||||
auto it = str.begin();
|
||||
while (it != str.end()) {
|
||||
if (std::isalpha(*it)) {
|
||||
// Check if this is scientific notation (e or E followed by optional sign and digits)
|
||||
// Check if this is scientific notation (e or E followed by optional
|
||||
// sign and digits)
|
||||
if (((*it == 'e' || *it == 'E') && (it + 1) != str.end())) {
|
||||
auto next = it + 1;
|
||||
// Skip optional sign
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
|
||||
namespace aare {
|
||||
|
||||
|
||||
std::string remove_unit(std::string &str);
|
||||
|
||||
template <typename T>
|
||||
@@ -40,7 +39,6 @@ T string_to(const std::string &t, const std::string &unit) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// if T has a constructor that takes a string, lets use it.
|
||||
// template <class T> T string_to(const std::string &arg) { return T{arg}; }
|
||||
template <typename T> T string_to(const std::string &arg) {
|
||||
@@ -81,10 +79,4 @@ template <> FrameDiscardPolicy string_to(const std::string &arg);
|
||||
*/
|
||||
template <> DACIndex string_to(const std::string &arg);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace aare
|
||||
@@ -10,7 +10,8 @@ using aare::string_to;
|
||||
TEST_CASE("DetectorType string to enum") {
|
||||
REQUIRE(string_to<aare::DetectorType>("Generic") ==
|
||||
aare::DetectorType::Generic);
|
||||
REQUIRE(string_to<aare::DetectorType>("Eiger") == aare::DetectorType::Eiger);
|
||||
REQUIRE(string_to<aare::DetectorType>("Eiger") ==
|
||||
aare::DetectorType::Eiger);
|
||||
REQUIRE(string_to<aare::DetectorType>("Gotthard") ==
|
||||
aare::DetectorType::Gotthard);
|
||||
REQUIRE(string_to<aare::DetectorType>("Jungfrau") ==
|
||||
@@ -36,7 +37,8 @@ TEST_CASE("DetectorType string to enum") {
|
||||
|
||||
TEST_CASE("TimingMode string to enum") {
|
||||
REQUIRE(string_to<aare::TimingMode>("auto") == aare::TimingMode::Auto);
|
||||
REQUIRE(string_to<aare::TimingMode>("trigger") == aare::TimingMode::Trigger);
|
||||
REQUIRE(string_to<aare::TimingMode>("trigger") ==
|
||||
aare::TimingMode::Trigger);
|
||||
REQUIRE_THROWS(string_to<aare::TimingMode>("invalid_mode"));
|
||||
}
|
||||
|
||||
@@ -88,34 +90,50 @@ TEST_CASE("DACIndex string to enum") {
|
||||
REQUIRE(string_to<aare::DACIndex>("vcp") == aare::DACIndex::VCP);
|
||||
REQUIRE(string_to<aare::DACIndex>("vcn") == aare::DACIndex::VCN);
|
||||
REQUIRE(string_to<aare::DACIndex>("vishaper") == aare::DACIndex::VISHAPER);
|
||||
REQUIRE(string_to<aare::DACIndex>("vthreshold") == aare::DACIndex::VTHRESHOLD);
|
||||
REQUIRE(string_to<aare::DACIndex>("vthreshold") ==
|
||||
aare::DACIndex::VTHRESHOLD);
|
||||
REQUIRE(string_to<aare::DACIndex>("vref_ds") == aare::DACIndex::VREF_DS);
|
||||
REQUIRE(string_to<aare::DACIndex>("vout_cm") == aare::DACIndex::VOUT_CM);
|
||||
REQUIRE(string_to<aare::DACIndex>("vin_cm") == aare::DACIndex::VIN_CM);
|
||||
REQUIRE(string_to<aare::DACIndex>("vref_comp") == aare::DACIndex::VREF_COMP);
|
||||
REQUIRE(string_to<aare::DACIndex>("vref_comp") ==
|
||||
aare::DACIndex::VREF_COMP);
|
||||
REQUIRE(string_to<aare::DACIndex>("vb_comp") == aare::DACIndex::VB_COMP);
|
||||
REQUIRE(string_to<aare::DACIndex>("vdd_prot") == aare::DACIndex::VDD_PROT);
|
||||
REQUIRE(string_to<aare::DACIndex>("vin_com") == aare::DACIndex::VIN_COM);
|
||||
REQUIRE(string_to<aare::DACIndex>("vref_prech") == aare::DACIndex::VREF_PRECH);
|
||||
REQUIRE(string_to<aare::DACIndex>("vb_pixbuf") == aare::DACIndex::VB_PIXBUF);
|
||||
REQUIRE(string_to<aare::DACIndex>("vref_prech") ==
|
||||
aare::DACIndex::VREF_PRECH);
|
||||
REQUIRE(string_to<aare::DACIndex>("vb_pixbuf") ==
|
||||
aare::DACIndex::VB_PIXBUF);
|
||||
REQUIRE(string_to<aare::DACIndex>("vb_ds") == aare::DACIndex::VB_DS);
|
||||
REQUIRE(string_to<aare::DACIndex>("vref_h_adc") == aare::DACIndex::VREF_H_ADC);
|
||||
REQUIRE(string_to<aare::DACIndex>("vb_comp_fe") == aare::DACIndex::VB_COMP_FE);
|
||||
REQUIRE(string_to<aare::DACIndex>("vb_comp_adc") == aare::DACIndex::VB_COMP_ADC);
|
||||
REQUIRE(string_to<aare::DACIndex>("vref_h_adc") ==
|
||||
aare::DACIndex::VREF_H_ADC);
|
||||
REQUIRE(string_to<aare::DACIndex>("vb_comp_fe") ==
|
||||
aare::DACIndex::VB_COMP_FE);
|
||||
REQUIRE(string_to<aare::DACIndex>("vb_comp_adc") ==
|
||||
aare::DACIndex::VB_COMP_ADC);
|
||||
REQUIRE(string_to<aare::DACIndex>("vcom_cds") == aare::DACIndex::VCOM_CDS);
|
||||
REQUIRE(string_to<aare::DACIndex>("vref_rstore") == aare::DACIndex::VREF_RSTORE);
|
||||
REQUIRE(string_to<aare::DACIndex>("vb_opa_1st") == aare::DACIndex::VB_OPA_1ST);
|
||||
REQUIRE(string_to<aare::DACIndex>("vref_comp_fe") == aare::DACIndex::VREF_COMP_FE);
|
||||
REQUIRE(string_to<aare::DACIndex>("vcom_adc1") == aare::DACIndex::VCOM_ADC1);
|
||||
REQUIRE(string_to<aare::DACIndex>("vref_l_adc") == aare::DACIndex::VREF_L_ADC);
|
||||
REQUIRE(string_to<aare::DACIndex>("vref_rstore") ==
|
||||
aare::DACIndex::VREF_RSTORE);
|
||||
REQUIRE(string_to<aare::DACIndex>("vb_opa_1st") ==
|
||||
aare::DACIndex::VB_OPA_1ST);
|
||||
REQUIRE(string_to<aare::DACIndex>("vref_comp_fe") ==
|
||||
aare::DACIndex::VREF_COMP_FE);
|
||||
REQUIRE(string_to<aare::DACIndex>("vcom_adc1") ==
|
||||
aare::DACIndex::VCOM_ADC1);
|
||||
REQUIRE(string_to<aare::DACIndex>("vref_l_adc") ==
|
||||
aare::DACIndex::VREF_L_ADC);
|
||||
REQUIRE(string_to<aare::DACIndex>("vref_cds") == aare::DACIndex::VREF_CDS);
|
||||
REQUIRE(string_to<aare::DACIndex>("vb_cs") == aare::DACIndex::VB_CS);
|
||||
REQUIRE(string_to<aare::DACIndex>("vb_opa_fd") == aare::DACIndex::VB_OPA_FD);
|
||||
REQUIRE(string_to<aare::DACIndex>("vcom_adc2") == aare::DACIndex::VCOM_ADC2);
|
||||
REQUIRE(string_to<aare::DACIndex>("vb_opa_fd") ==
|
||||
aare::DACIndex::VB_OPA_FD);
|
||||
REQUIRE(string_to<aare::DACIndex>("vcom_adc2") ==
|
||||
aare::DACIndex::VCOM_ADC2);
|
||||
REQUIRE(string_to<aare::DACIndex>("vcassh") == aare::DACIndex::VCASSH);
|
||||
REQUIRE(string_to<aare::DACIndex>("vth2") == aare::DACIndex::VTH2);
|
||||
REQUIRE(string_to<aare::DACIndex>("vrshaper_n") == aare::DACIndex::VRSHAPER_N);
|
||||
REQUIRE(string_to<aare::DACIndex>("vipre_out") == aare::DACIndex::VIPRE_OUT);
|
||||
REQUIRE(string_to<aare::DACIndex>("vrshaper_n") ==
|
||||
aare::DACIndex::VRSHAPER_N);
|
||||
REQUIRE(string_to<aare::DACIndex>("vipre_out") ==
|
||||
aare::DACIndex::VIPRE_OUT);
|
||||
REQUIRE(string_to<aare::DACIndex>("vth3") == aare::DACIndex::VTH3);
|
||||
REQUIRE(string_to<aare::DACIndex>("vth1") == aare::DACIndex::VTH1);
|
||||
REQUIRE(string_to<aare::DACIndex>("vicin") == aare::DACIndex::VICIN);
|
||||
@@ -124,31 +142,47 @@ TEST_CASE("DACIndex string to enum") {
|
||||
REQUIRE(string_to<aare::DACIndex>("vipre") == aare::DACIndex::VIPRE);
|
||||
REQUIRE(string_to<aare::DACIndex>("vcal_p") == aare::DACIndex::VCAL_P);
|
||||
REQUIRE(string_to<aare::DACIndex>("vdcsh") == aare::DACIndex::VDCSH);
|
||||
REQUIRE(string_to<aare::DACIndex>("vbp_colbuf") == aare::DACIndex::VBP_COLBUF);
|
||||
REQUIRE(string_to<aare::DACIndex>("vbp_colbuf") ==
|
||||
aare::DACIndex::VBP_COLBUF);
|
||||
REQUIRE(string_to<aare::DACIndex>("vb_sda") == aare::DACIndex::VB_SDA);
|
||||
REQUIRE(string_to<aare::DACIndex>("vcasc_sfp") == aare::DACIndex::VCASC_SFP);
|
||||
REQUIRE(string_to<aare::DACIndex>("vipre_cds") == aare::DACIndex::VIPRE_CDS);
|
||||
REQUIRE(string_to<aare::DACIndex>("ibias_sfp") == aare::DACIndex::IBIAS_SFP);
|
||||
REQUIRE(string_to<aare::DACIndex>("trimbits") == aare::DACIndex::TRIMBIT_SCAN);
|
||||
REQUIRE(string_to<aare::DACIndex>("highvoltage") == aare::DACIndex::HIGH_VOLTAGE);
|
||||
REQUIRE(string_to<aare::DACIndex>("vcasc_sfp") ==
|
||||
aare::DACIndex::VCASC_SFP);
|
||||
REQUIRE(string_to<aare::DACIndex>("vipre_cds") ==
|
||||
aare::DACIndex::VIPRE_CDS);
|
||||
REQUIRE(string_to<aare::DACIndex>("ibias_sfp") ==
|
||||
aare::DACIndex::IBIAS_SFP);
|
||||
REQUIRE(string_to<aare::DACIndex>("trimbits") ==
|
||||
aare::DACIndex::TRIMBIT_SCAN);
|
||||
REQUIRE(string_to<aare::DACIndex>("highvoltage") ==
|
||||
aare::DACIndex::HIGH_VOLTAGE);
|
||||
REQUIRE(string_to<aare::DACIndex>("iodelay") == aare::DACIndex::IO_DELAY);
|
||||
REQUIRE(string_to<aare::DACIndex>("temp_adc") == aare::DACIndex::TEMPERATURE_ADC);
|
||||
REQUIRE(string_to<aare::DACIndex>("temp_fpga") == aare::DACIndex::TEMPERATURE_FPGA);
|
||||
REQUIRE(string_to<aare::DACIndex>("temp_fpgaext") == aare::DACIndex::TEMPERATURE_FPGAEXT);
|
||||
REQUIRE(string_to<aare::DACIndex>("temp_10ge") == aare::DACIndex::TEMPERATURE_10GE);
|
||||
REQUIRE(string_to<aare::DACIndex>("temp_dcdc") == aare::DACIndex::TEMPERATURE_DCDC);
|
||||
REQUIRE(string_to<aare::DACIndex>("temp_sodl") == aare::DACIndex::TEMPERATURE_SODL);
|
||||
REQUIRE(string_to<aare::DACIndex>("temp_sodr") == aare::DACIndex::TEMPERATURE_SODR);
|
||||
REQUIRE(string_to<aare::DACIndex>("temp_fpgafl") == aare::DACIndex::TEMPERATURE_FPGA2);
|
||||
REQUIRE(string_to<aare::DACIndex>("temp_fpgafr") == aare::DACIndex::TEMPERATURE_FPGA3);
|
||||
REQUIRE(string_to<aare::DACIndex>("temp_slowadc") == aare::DACIndex::SLOW_ADC_TEMP);
|
||||
|
||||
REQUIRE(string_to<aare::DACIndex>("temp_adc") ==
|
||||
aare::DACIndex::TEMPERATURE_ADC);
|
||||
REQUIRE(string_to<aare::DACIndex>("temp_fpga") ==
|
||||
aare::DACIndex::TEMPERATURE_FPGA);
|
||||
REQUIRE(string_to<aare::DACIndex>("temp_fpgaext") ==
|
||||
aare::DACIndex::TEMPERATURE_FPGAEXT);
|
||||
REQUIRE(string_to<aare::DACIndex>("temp_10ge") ==
|
||||
aare::DACIndex::TEMPERATURE_10GE);
|
||||
REQUIRE(string_to<aare::DACIndex>("temp_dcdc") ==
|
||||
aare::DACIndex::TEMPERATURE_DCDC);
|
||||
REQUIRE(string_to<aare::DACIndex>("temp_sodl") ==
|
||||
aare::DACIndex::TEMPERATURE_SODL);
|
||||
REQUIRE(string_to<aare::DACIndex>("temp_sodr") ==
|
||||
aare::DACIndex::TEMPERATURE_SODR);
|
||||
REQUIRE(string_to<aare::DACIndex>("temp_fpgafl") ==
|
||||
aare::DACIndex::TEMPERATURE_FPGA2);
|
||||
REQUIRE(string_to<aare::DACIndex>("temp_fpgafr") ==
|
||||
aare::DACIndex::TEMPERATURE_FPGA3);
|
||||
REQUIRE(string_to<aare::DACIndex>("temp_slowadc") ==
|
||||
aare::DACIndex::SLOW_ADC_TEMP);
|
||||
|
||||
REQUIRE_THROWS(string_to<aare::DACIndex>("invalid_dac"));
|
||||
}
|
||||
|
||||
TEST_CASE("Remove unit from string") {
|
||||
using aare::remove_unit;
|
||||
|
||||
|
||||
// Test basic numeric value with unit
|
||||
{
|
||||
std::string input = "123.45 V";
|
||||
@@ -156,7 +190,7 @@ TEST_CASE("Remove unit from string") {
|
||||
REQUIRE(unit == "V");
|
||||
REQUIRE(input == "123.45");
|
||||
}
|
||||
|
||||
|
||||
// Test integer value with unit
|
||||
{
|
||||
std::string input = "42 Hz";
|
||||
@@ -164,7 +198,7 @@ TEST_CASE("Remove unit from string") {
|
||||
REQUIRE(unit == "Hz");
|
||||
REQUIRE(input == "42");
|
||||
}
|
||||
|
||||
|
||||
// Test negative value with unit
|
||||
{
|
||||
std::string input = "-50.5 mV";
|
||||
@@ -172,7 +206,7 @@ TEST_CASE("Remove unit from string") {
|
||||
REQUIRE(unit == "mV");
|
||||
REQUIRE(input == "-50.5");
|
||||
}
|
||||
|
||||
|
||||
// Test value with no unit (only numbers)
|
||||
{
|
||||
std::string input = "123.45";
|
||||
@@ -180,7 +214,7 @@ TEST_CASE("Remove unit from string") {
|
||||
REQUIRE(unit == "");
|
||||
REQUIRE(input == "123.45");
|
||||
}
|
||||
|
||||
|
||||
// Test value with only unit (letters at start)
|
||||
{
|
||||
std::string input = "kHz";
|
||||
@@ -188,7 +222,7 @@ TEST_CASE("Remove unit from string") {
|
||||
REQUIRE(unit == "kHz");
|
||||
REQUIRE(input == "");
|
||||
}
|
||||
|
||||
|
||||
// Test with multiple word units
|
||||
{
|
||||
std::string input = "100 degrees Celsius";
|
||||
@@ -196,7 +230,7 @@ TEST_CASE("Remove unit from string") {
|
||||
REQUIRE(unit == "degrees Celsius");
|
||||
REQUIRE(input == "100");
|
||||
}
|
||||
|
||||
|
||||
// Test with scientific notation
|
||||
{
|
||||
std::string input = "1.23e-5 A";
|
||||
@@ -212,7 +246,7 @@ TEST_CASE("Remove unit from string") {
|
||||
REQUIRE(unit == "m/s");
|
||||
REQUIRE(input == "-4.56E6");
|
||||
}
|
||||
|
||||
|
||||
// Test with scientific notation uppercase
|
||||
{
|
||||
std::string input = "5.67E+3 Hz";
|
||||
@@ -220,7 +254,7 @@ TEST_CASE("Remove unit from string") {
|
||||
REQUIRE(unit == "Hz");
|
||||
REQUIRE(input == "5.67E+3");
|
||||
}
|
||||
|
||||
|
||||
// Test with leading zeros
|
||||
{
|
||||
std::string input = "00123 ohm";
|
||||
@@ -236,7 +270,7 @@ TEST_CASE("Remove unit from string") {
|
||||
REQUIRE(unit == "ohm");
|
||||
REQUIRE(input == "00123");
|
||||
}
|
||||
|
||||
|
||||
// Test empty string
|
||||
{
|
||||
std::string input = "";
|
||||
@@ -260,7 +294,8 @@ TEST_CASE("Conversions from time string to chrono durations") {
|
||||
REQUIRE(string_to<microseconds>("2.5 ms") == microseconds(2500));
|
||||
REQUIRE(string_to<milliseconds>("3.5 s") == milliseconds(3500));
|
||||
|
||||
REQUIRE(string_to<seconds>("2") == seconds(2)); // No unit defaults to seconds
|
||||
REQUIRE(string_to<seconds>("2") ==
|
||||
seconds(2)); // No unit defaults to seconds
|
||||
|
||||
REQUIRE_THROWS(string_to<seconds>("10 min")); // Unsupported unit
|
||||
}
|
||||
Reference in New Issue
Block a user