considered num_udp_interafces for jungfrau and quad structure for eiger

This commit is contained in:
2025-06-10 11:35:15 +02:00
parent 87d8682b1e
commit ad7525cd02
6 changed files with 90 additions and 60 deletions

View File

@ -82,8 +82,10 @@ class RawMasterFile {
size_t m_pixels_x{}; size_t m_pixels_x{};
size_t m_bitdepth{}; size_t m_bitdepth{};
size_t m_num_udp_interfaces_per_module = 1; size_t m_num_udp_interfaces_per_module = 1;
uint8_t m_quad = 0;
xy m_geometry{}; xy m_geometry{};
xy m_udp_interfaces_per_module{1, 1};
size_t m_max_frames_per_file{}; size_t m_max_frames_per_file{};
// uint32_t m_adc_mask{}; // TODO! implement reading // uint32_t m_adc_mask{}; // TODO! implement reading
@ -101,7 +103,6 @@ class RawMasterFile {
std::optional<size_t> m_digital_samples; std::optional<size_t> m_digital_samples;
std::optional<size_t> m_transceiver_samples; std::optional<size_t> m_transceiver_samples;
std::optional<size_t> m_number_of_rows; std::optional<size_t> m_number_of_rows;
std::optional<uint8_t> m_quad;
std::optional<ROI> m_roi; std::optional<ROI> m_roi;
@ -120,18 +121,18 @@ class RawMasterFile {
size_t max_frames_per_file() const; size_t max_frames_per_file() const;
size_t bitdepth() const; size_t bitdepth() const;
size_t frame_padding() const; size_t frame_padding() const;
size_t num_udp_interfaces_per_module() const; xy udp_interfaces_per_module() const;
const FrameDiscardPolicy &frame_discard_policy() const; const FrameDiscardPolicy &frame_discard_policy() const;
size_t total_frames_expected() const; size_t total_frames_expected() const;
xy geometry() const; xy geometry() const;
size_t n_modules() const; size_t n_modules() const;
uint8_t quad() const;
std::optional<size_t> analog_samples() const; std::optional<size_t> analog_samples() const;
std::optional<size_t> digital_samples() const; std::optional<size_t> digital_samples() const;
std::optional<size_t> transceiver_samples() const; std::optional<size_t> transceiver_samples() const;
std::optional<size_t> number_of_rows() const; std::optional<size_t> number_of_rows() const;
std::optional<uint8_t> quad() const;
std::optional<ROI> roi() const; std::optional<ROI> roi() const;

View File

@ -3,16 +3,15 @@
#include "aare/Dtype.hpp" #include "aare/Dtype.hpp"
#include <array> #include <array>
#include <stdexcept>
#include <cassert> #include <cassert>
#include <cstdint> #include <cstdint>
#include <cstring> #include <cstring>
#include <stdexcept>
#include <string> #include <string>
#include <string_view> #include <string_view>
#include <variant> #include <variant>
#include <vector> #include <vector>
/** /**
* @brief LOCATION macro to get the current location in the code * @brief LOCATION macro to get the current location in the code
*/ */
@ -20,28 +19,24 @@
std::string(__FILE__) + std::string(":") + std::to_string(__LINE__) + \ std::string(__FILE__) + std::string(":") + std::to_string(__LINE__) + \
":" + std::string(__func__) + ":" ":" + std::string(__func__) + ":"
#ifdef AARE_CUSTOM_ASSERT #ifdef AARE_CUSTOM_ASSERT
#define AARE_ASSERT(expr)\ #define AARE_ASSERT(expr) \
if (expr)\ if (expr) { \
{}\ } else \
else\
aare::assert_failed(LOCATION + " Assertion failed: " + #expr + "\n"); aare::assert_failed(LOCATION + " Assertion failed: " + #expr + "\n");
#else #else
#define AARE_ASSERT(cond)\ #define AARE_ASSERT(cond) \
do { (void)sizeof(cond); } while(0) do { \
(void)sizeof(cond); \
} while (0)
#endif #endif
namespace aare { namespace aare {
inline constexpr size_t bits_per_byte = 8; inline constexpr size_t bits_per_byte = 8;
void assert_failed(const std::string &msg); void assert_failed(const std::string &msg);
class DynamicCluster { class DynamicCluster {
public: public:
int cluster_sizeX; int cluster_sizeX;
@ -55,7 +50,7 @@ class DynamicCluster {
public: public:
DynamicCluster(int cluster_sizeX_, int cluster_sizeY_, DynamicCluster(int cluster_sizeX_, int cluster_sizeY_,
Dtype dt_ = Dtype(typeid(int32_t))) Dtype dt_ = Dtype(typeid(int32_t)))
: cluster_sizeX(cluster_sizeX_), cluster_sizeY(cluster_sizeY_), : cluster_sizeX(cluster_sizeX_), cluster_sizeY(cluster_sizeY_),
dt(dt_) { dt(dt_) {
m_data = new std::byte[cluster_sizeX * cluster_sizeY * dt.bytes()]{}; m_data = new std::byte[cluster_sizeX * cluster_sizeY * dt.bytes()]{};
@ -179,24 +174,24 @@ template <typename T> struct t_xy {
}; };
using xy = t_xy<uint32_t>; using xy = t_xy<uint32_t>;
/** /**
* @brief Class to hold the geometry of a module. Where pixel 0 is located and the size of the module * @brief Class to hold the geometry of a module. Where pixel 0 is located and
* the size of the module
*/ */
struct ModuleGeometry{ struct ModuleGeometry {
int origin_x{}; int origin_x{};
int origin_y{}; int origin_y{};
int height{}; int height{};
int width{}; int width{};
int row_index{}; int row_index{};
int col_index{}; int col_index{};
}; };
/** /**
* @brief Class to hold the geometry of a detector. Number of modules, their size and where pixel 0 * @brief Class to hold the geometry of a detector. Number of modules, their
* for each module is located * size and where pixel 0 for each module is located
*/ */
struct DetectorGeometry{ struct DetectorGeometry {
int modules_x{}; int modules_x{};
int modules_y{}; int modules_y{};
int pixels_x{}; int pixels_x{};
@ -204,35 +199,34 @@ struct DetectorGeometry{
int module_gap_row{}; int module_gap_row{};
int module_gap_col{}; int module_gap_col{};
std::vector<ModuleGeometry> module_pixel_0; std::vector<ModuleGeometry> module_pixel_0;
auto size() const { return module_pixel_0.size(); } auto size() const { return module_pixel_0.size(); }
}; };
struct ROI{ struct ROI {
ssize_t xmin{}; ssize_t xmin{};
ssize_t xmax{}; ssize_t xmax{};
ssize_t ymin{}; ssize_t ymin{};
ssize_t ymax{}; ssize_t ymax{};
ssize_t height() const { return ymax - ymin; } ssize_t height() const { return ymax - ymin; }
ssize_t width() const { return xmax - xmin; } ssize_t width() const { return xmax - xmin; }
bool contains(ssize_t x, ssize_t y) const { bool contains(ssize_t x, ssize_t y) const {
return x >= xmin && x < xmax && y >= ymin && y < ymax; return x >= xmin && x < xmax && y >= ymin && y < ymax;
} }
}; };
using dynamic_shape = std::vector<ssize_t>; using dynamic_shape = std::vector<ssize_t>;
//TODO! Can we uniform enums between the libraries? // TODO! Can we uniform enums between the libraries?
/** /**
* @brief Enum class to identify different detectors. * @brief Enum class to identify different detectors.
* The values are the same as in slsDetectorPackage * The values are the same as in slsDetectorPackage
* Different spelling to avoid confusion with the slsDetectorPackage * Different spelling to avoid confusion with the slsDetectorPackage
*/ */
enum class DetectorType { enum class DetectorType {
//Standard detectors match the enum values from slsDetectorPackage // Standard detectors match the enum values from slsDetectorPackage
Generic, Generic,
Eiger, Eiger,
Gotthard, Gotthard,
@ -243,8 +237,9 @@ enum class DetectorType {
Gotthard2, Gotthard2,
Xilinx_ChipTestBoard, Xilinx_ChipTestBoard,
//Additional detectors used for defining processing. Variants of the standard ones. // Additional detectors used for defining processing. Variants of the
Moench03=100, // standard ones.
Moench03 = 100,
Moench03_old, Moench03_old,
Unknown Unknown
}; };

View File

@ -149,19 +149,27 @@ RawMasterFile RawFile::master() const { return m_master; }
void RawFile::find_geometry() { void RawFile::find_geometry() {
for (size_t col = 0; col < m_master.geometry().col; for (size_t col = 0; col < m_master.geometry().col;
col += m_master.num_udp_interfaces_per_module()) col += m_master.udp_interfaces_per_module().col)
for (size_t row = 0; row < m_master.geometry().row; ++row) { for (size_t row = 0; row < m_master.geometry().row;
for (size_t port = 0; row += m_master.udp_interfaces_per_module().row) {
port < m_master.num_udp_interfaces_per_module(); ++port) { for (size_t port_row = 0;
ModuleGeometry g; port_row < m_master.udp_interfaces_per_module().row;
g.origin_x = (col + port) * m_master.pixels_x(); ++port_row)
g.origin_y = row * m_master.pixels_y(); for (size_t port_col = 0;
g.row_index = row; port_col < m_master.udp_interfaces_per_module().col;
g.col_index = col + port; ++port_col) {
g.width = m_master.pixels_x(); ModuleGeometry g;
g.height = m_master.pixels_y(); g.origin_x = (col + port_col) * m_master.pixels_x();
m_geometry.module_pixel_0.push_back(g); g.origin_y = (row + port_row) *
} m_master.pixels_y(); // TODO: quad doesnt seem
// to have an effect
g.row_index = m_master.quad() ? (row + port_row + 1) % 2
: (row + port_row);
g.col_index = col + port_col;
g.width = m_master.pixels_x();
g.height = m_master.pixels_y();
m_geometry.module_pixel_0.push_back(g);
}
} }
m_geometry.pixels_y = (m_master.geometry().row * m_master.pixels_y()); m_geometry.pixels_y = (m_master.geometry().row * m_master.pixels_y());

View File

@ -200,9 +200,27 @@ TEST_CASE("check find_geometry", "[.integration][.files][.rawfile]") {
ModuleGeometry{0, 0, 256, 512, 0, 0}, ModuleGeometry{0, 0, 256, 512, 0, 0},
ModuleGeometry{512, 0, 256, 512, 0, 1}, ModuleGeometry{512, 0, 256, 512, 0, 1},
ModuleGeometry{0, 256, 256, 512, 1, 0}, ModuleGeometry{0, 256, 256, 512, 1, 0},
ModuleGeometry{512, 256, 256, 512, 1, 1}}}}); ModuleGeometry{512, 256, 256, 512, 1, 1}}}},
TestParameters{
"raw/jungfrau_2modules_2interfaces/run_master_0.json", 4,
DetectorGeometry{1, 4, 1024, 1024, 0, 0,
std::vector<ModuleGeometry>{
ModuleGeometry{0, 0, 256, 1024, 0, 0},
ModuleGeometry{0, 256, 256, 1024, 1, 0},
ModuleGeometry{0, 512, 256, 1024, 2, 0},
ModuleGeometry{0, 768, 256, 1024, 3, 0}}}},
TestParameters{
"raw/W13_230320/"
"W13_vthreshscan_m21C_300V_800eV_vrpre3400_master_0.json",
2,
DetectorGeometry{1, 2, 512, 512, 0, 0,
std::vector<ModuleGeometry>{
ModuleGeometry{0, 0, 256, 512, 0, 0},
ModuleGeometry{0, 256, 256, 512, 1, 0}}}});
auto fpath = test_data_path() / test_parameters.master_filename; auto fpath = test_data_path() / test_parameters.master_filename;
REQUIRE(std::filesystem::exists(fpath)); REQUIRE(std::filesystem::exists(fpath));
RawFileTestWrapper f(fpath, "r"); RawFileTestWrapper f(fpath, "r");
@ -242,7 +260,7 @@ TEST_CASE("check find_geometry", "[.integration][.files][.rawfile]") {
TEST_CASE("Open multi module file with ROI", TEST_CASE("Open multi module file with ROI",
"[.integration][.files][.rawfile]") { "[.integration][.files][.rawfile]") {
auto fpath = test_data_path() / "SingleChipROI/Data_master_0.json"; auto fpath = test_data_path() / "raw/SingleChipROI/Data_master_0.json";
REQUIRE(std::filesystem::exists(fpath)); REQUIRE(std::filesystem::exists(fpath));
RawFile f(fpath, "r"); RawFile f(fpath, "r");

View File

@ -139,11 +139,11 @@ size_t RawMasterFile::n_modules() const {
return m_geometry.row * m_geometry.col; return m_geometry.row * m_geometry.col;
} }
size_t RawMasterFile::num_udp_interfaces_per_module() const { xy RawMasterFile::udp_interfaces_per_module() const {
return m_num_udp_interfaces_per_module; return m_udp_interfaces_per_module;
} }
std::optional<uint8_t> RawMasterFile::quad() const { return m_quad; } uint8_t RawMasterFile::quad() const { return m_quad; }
// optional values, these may or may not be present in the master file // optional values, these may or may not be present in the master file
// and are therefore modeled as std::optional // and are therefore modeled as std::optional
@ -267,10 +267,13 @@ void RawMasterFile::parse_json(const std::filesystem::path &fpath) {
// not a scan // not a scan
} }
try { try {
m_num_udp_interfaces_per_module = j.at("Number of UDP Interfaces"); m_udp_interfaces_per_module = {j.at("Number of UDP Interfaces"), 1};
} catch (const json::out_of_range &e) { } catch (const json::out_of_range &e) {
if (m_type == DetectorType::Eiger) if (m_type == DetectorType::Eiger && m_quad == 1)
m_num_udp_interfaces_per_module = 2; m_udp_interfaces_per_module = {2, 1};
else if (m_type == DetectorType::Eiger) {
m_udp_interfaces_per_module = {1, 2};
}
} }
try { try {
@ -347,9 +350,6 @@ void RawMasterFile::parse_raw(const std::filesystem::path &fpath) {
if (m_type == DetectorType::Moench) { if (m_type == DetectorType::Moench) {
m_type = DetectorType::Moench03_old; m_type = DetectorType::Moench03_old;
} }
if (m_type == DetectorType::Eiger) {
m_num_udp_interfaces_per_module = 2;
}
} else if (key == "Timing Mode") { } else if (key == "Timing Mode") {
m_timing_mode = StringTo<TimingMode>(value); m_timing_mode = StringTo<TimingMode>(value);
} else if (key == "Image Size") { } else if (key == "Image Size") {
@ -407,10 +407,18 @@ void RawMasterFile::parse_raw(const std::filesystem::path &fpath) {
static_cast<uint32_t>(std::stoi(value.substr(1, pos))), static_cast<uint32_t>(std::stoi(value.substr(1, pos))),
static_cast<uint32_t>(std::stoi(value.substr(pos + 1)))}; static_cast<uint32_t>(std::stoi(value.substr(pos + 1)))};
} else if (key == "Number of UDP Interfaces") { } else if (key == "Number of UDP Interfaces") {
m_num_udp_interfaces_per_module = std::stoi(value); m_udp_interfaces_per_module = {
static_cast<uint32_t>(std::stoi(value)), 1};
} }
} }
} }
if (m_type == DetectorType::Eiger && m_quad == 1) {
m_udp_interfaces_per_module = {2, 1};
} else if (m_type == DetectorType::Eiger) {
m_udp_interfaces_per_module = {1, 2};
}
if (m_pixels_x == 400 && m_pixels_y == 400) { if (m_pixels_x == 400 && m_pixels_y == 400) {
m_type = DetectorType::Moench03_old; m_type = DetectorType::Moench03_old;
} }

View File

@ -153,7 +153,7 @@ TEST_CASE("Parse a master file in old .raw format",
REQUIRE(std::filesystem::exists(fpath)); REQUIRE(std::filesystem::exists(fpath));
RawMasterFile f(fpath); RawMasterFile f(fpath);
CHECK(f.num_udp_interfaces_per_module() == 1); CHECK(f.udp_interfaces_per_module() == xy{1, 1});
CHECK(f.n_modules() == 2); CHECK(f.n_modules() == 2);
CHECK(f.geometry().row == 2); CHECK(f.geometry().row == 2);
CHECK(f.geometry().col == 1); CHECK(f.geometry().col == 1);