moved DetectorGeometry, vector of ROIGeometry to master file

This commit is contained in:
2026-09-01 17:11:02 +02:00
parent 4ba2185bf6
commit 2a77674adf
11 changed files with 384 additions and 411 deletions
+4
View File
@@ -16,6 +16,10 @@
- ``NDView<T, Ndim>`` now converts to ``NDView<const T, Ndim>``;
``expand4to8bit`` and ``expand24to32bit`` accept const input views.
- ``RawMasterFile::geometry()`` is deprecetad and returns full detector geometry information including module geometry. Use
``RawMasterFile::module_layout()`` to get num_modules in x an y
- ``RawMasterFile::rois()`` always returns a list of rois (no optional). Per default it returns a list of one ROI element spawing the entire detector
### Bugfixes:
- Fixed broken reading of old (pre reordering) Moench03
+2 -1
View File
@@ -2,7 +2,6 @@
#pragma once
#include "aare/ROI.hpp"
#include "aare/ROIGeometry.hpp"
#include "aare/RawMasterFile.hpp" //ROI refactor away
#include <iostream>
namespace aare {
@@ -97,6 +96,8 @@ class DetectorGeometry {
const xy udp_interfaces_per_module = xy{1, 1},
const bool quad = false);
DetectorGeometry() = default;
~DetectorGeometry() = default;
/**
-5
View File
@@ -19,11 +19,6 @@ class ROIGeometry {
*/
ROIGeometry(const ROI &roi, DetectorGeometry &geometry);
/** @brief Constructor for ROI geometry expanding over full detector
* @param geometry general detector geometry
*/
ROIGeometry(DetectorGeometry &geometry);
/// @brief Get number of modules in the ROI
size_t num_modules_in_roi() const;
-11
View File
@@ -1,6 +1,5 @@
// SPDX-License-Identifier: MPL-2.0
#pragma once
#include "aare/DetectorGeometry.hpp"
#include "aare/FileInterface.hpp"
#include "aare/Frame.hpp"
#include "aare/NDArray.hpp" //for pixel map
@@ -30,9 +29,6 @@ class RawFile : public FileInterface {
RawMasterFile m_master;
size_t m_current_frame{};
DetectorGeometry m_geometry;
/// @brief Geometries e.g. number of modules, size etc. for each ROI
std::vector<ROIGeometry> m_ROI_geometries;
/// @brief total number of frames in file
@@ -43,7 +39,6 @@ class RawFile : public FileInterface {
* @brief RawFile constructor
* @param fname path to the master file (.json)
* @param mode file mode (only "r" is supported at the moment)
*/
RawFile(const std::filesystem::path &fname, const std::string &mode = "r");
virtual ~RawFile() override = default;
@@ -172,12 +167,6 @@ class RawFile : public FileInterface {
Frame get_frame(size_t frame_index, const size_t roi_index = 0);
void open_subfiles(const size_t roi_index);
/**
* @brief set the ROIs in master file.
* @param rois vector of ROIs to set in the RawMasterFile.
*/
void set_ROIs(const std::vector<ROI> &rois);
};
} // namespace aare
+21 -9
View File
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: MPL-2.0
#pragma once
#include "aare/DetectorGeometry.hpp"
#include "aare/ROI.hpp"
#include <algorithm>
#include <chrono>
@@ -13,8 +14,6 @@ using json = nlohmann::json;
namespace aare {
class RawFile; // forward declaration
/**
* @brief Implementation used in RawMasterFile to parse the file name
*/
@@ -90,7 +89,8 @@ class RawMasterFile {
std::optional<std::chrono::nanoseconds> m_exptime;
std::chrono::nanoseconds m_period{0};
xy m_geometry{};
/// @brief modules in x and y direction
xy m_detector_layout{};
xy m_udp_interfaces_per_module{1, 1};
size_t m_max_frames_per_file{};
@@ -118,7 +118,14 @@ class RawMasterFile {
std::optional<std::vector<std::string>>
m_udp_port_types{}; // TODO: UDPPortType? - string_to conversion?
std::optional<std::vector<ROI>> m_rois;
/// @brief ROIs defined in master file or derived from disabled UDP ports
std::vector<ROI> m_rois;
/// @brief Detector geometry - geometry for each module
DetectorGeometry m_geometry{};
/// @brief ROI geometries
std::vector<ROIGeometry> m_ROI_geometries;
public:
RawMasterFile(const std::filesystem::path &fpath);
@@ -140,10 +147,14 @@ class RawMasterFile {
const FrameDiscardPolicy &frame_discard_policy() const;
size_t total_frames_expected() const;
xy geometry() const;
xy detector_layout() const;
size_t n_modules() const;
uint8_t quad() const;
const DetectorGeometry &geometry() const;
const std::vector<ROIGeometry> &roi_geometries() const;
ReadoutMode get_reading_mode() const;
std::optional<size_t> analog_samples() const;
@@ -162,9 +173,11 @@ class RawMasterFile {
/// for masterfile version >= 8.1)
std::optional<std::vector<size_t>> disabled_udp_ports() const;
std::optional<std::vector<ROI>> rois() const;
std::vector<ROI> rois() const;
std::optional<ROI> roi() const;
/// @brief get roi for the case of a single ROI
/// @return ROI object (complete ROI if no roi present in master file)
ROI roi() const;
ScanParameters scan_parameters() const;
@@ -176,9 +189,8 @@ class RawMasterFile {
private:
void parse_json(std::istream &is);
void parse_raw(std::istream &is);
void update_rois_from_disabled_udp_ports();
void retrieve_geometry();
friend class RawFile;
};
} // namespace aare
+4 -3
View File
@@ -66,7 +66,8 @@ void define_raw_master_file_bindings(py::module &m) {
.def_property_readonly("total_frames_expected",
&RawMasterFile::total_frames_expected)
.def_property_readonly("geometry", &RawMasterFile::geometry)
.def_property_readonly("detector_layout",
&RawMasterFile::detector_layout)
.def_property_readonly("udp_interfaces_per_module",
&RawMasterFile::udp_interfaces_per_module)
.def_property_readonly("analog_samples", &RawMasterFile::analog_samples,
@@ -112,8 +113,8 @@ void define_raw_master_file_bindings(py::module &m) {
Returns
----------
Optional[List[ROI]]
Optional vector of ROIs (only present for masterfile version >= 8.1)
List[ROI]
List of ROIs (default complete ROI)
)")
.def_property_readonly("udp_port_types", &RawMasterFile::udp_port_types,
R"(
+14 -15
View File
@@ -5,25 +5,24 @@ namespace aare {
ROIGeometry::ROIGeometry(const ROI &roi, DetectorGeometry &geometry)
: m_pixels_x(roi.width()), m_pixels_y(roi.height()), m_geometry(geometry) {
m_module_indices_in_roi.reserve(m_geometry.n_modules());
// determine which modules are in the roi
for (size_t i = 0; i < m_geometry.n_modules(); ++i) {
auto &module_geometry = m_geometry.get_module_geometries(i);
if (module_geometry.module_in_roi(roi)) {
module_geometry.update_geometry_with_roi(roi);
m_module_indices_in_roi.push_back(i);
if (complete_ROI({roi}, geometry)) {
m_module_indices_in_roi.resize(m_geometry.n_modules());
std::iota(m_module_indices_in_roi.begin(),
m_module_indices_in_roi.end(), 0);
} else {
m_module_indices_in_roi.reserve(m_geometry.n_modules());
// determine which modules are in the roi
for (size_t i = 0; i < m_geometry.n_modules(); ++i) {
auto &module_geometry = m_geometry.get_module_geometries(i);
if (module_geometry.module_in_roi(roi)) {
module_geometry.update_geometry_with_roi(roi);
m_module_indices_in_roi.push_back(i);
}
}
}
}
ROIGeometry::ROIGeometry(DetectorGeometry &geometry)
: m_pixels_x(geometry.pixels_x()), m_pixels_y(geometry.pixels_y()),
m_geometry(geometry) {
m_module_indices_in_roi.resize(m_geometry.n_modules());
std::iota(m_module_indices_in_roi.begin(), m_module_indices_in_roi.end(),
0);
}
size_t ROIGeometry::num_modules_in_roi() const {
return m_module_indices_in_roi.size();
}
+73 -275
View File
@@ -16,212 +16,25 @@ using json = nlohmann::json;
namespace aare {
/**
* @brief Get ROIs from disabled UDP ports
* @param disabled_ports vector of disabled UDP ports
* @param udp_port_types vector of UDP port types (e.g. "left", "right", "top",
* "bottom")
* @param pixels_per_module_x number of pixels per module in x direction
* @param pixels_per_module_y number of pixels per module in y direction
* @param modules_x number of modules in x direction
* @param modules_y number of modules in y direction
* @return vector of ROIs corresponding to the disabled UDP ports
*/
std::vector<ROI>
get_rois_from_disabled_udp_ports(std::vector<size_t> &disabled_ports,
std::vector<std::string> &udp_port_types,
const DetectorGeometry &geometry) {
const size_t num_udp_port_types = udp_port_types.size();
size_t first_port = disabled_ports[0] % num_udp_port_types;
bool all_ports_equal =
std::all_of(disabled_ports.begin(), disabled_ports.end(),
[&num_udp_port_types, first_port](size_t &port) {
return port % num_udp_port_types == first_port;
});
std::vector<ROI> rois;
const ssize_t udp_ports_per_module =
geometry.udp_interfaces_per_module().col *
geometry.udp_interfaces_per_module().row;
bool port_disabled_for_all_modules =
disabled_ports.size() ==
geometry.modules_x() * geometry.modules_y() / udp_ports_per_module;
if (all_ports_equal && port_disabled_for_all_modules) {
if (udp_port_types[first_port] == "left") {
const size_t num_rois = geometry.modules_x() / udp_ports_per_module;
rois.resize(num_rois);
const ssize_t pixels_per_module_x =
geometry.pixels_x() / geometry.modules_x();
std::generate(
rois.begin(), rois.end(),
[n = 0, &geometry, pixels_per_module_x,
udp_ports_per_module]() mutable {
ssize_t idx = n++;
return ROI{
idx * udp_ports_per_module * pixels_per_module_x +
pixels_per_module_x,
idx * udp_ports_per_module * pixels_per_module_x +
2 * pixels_per_module_x,
0, static_cast<ssize_t>(geometry.pixels_y())};
});
}
if (udp_port_types[first_port] == "right") {
const size_t num_rois = geometry.modules_x() / udp_ports_per_module;
rois.resize(num_rois);
const ssize_t pixels_per_module_x =
geometry.pixels_x() / geometry.modules_x();
std::generate(
rois.begin(), rois.end(),
[n = 0, geometry, pixels_per_module_x,
udp_ports_per_module]() mutable {
ssize_t idx = n++;
return ROI{idx * udp_ports_per_module * pixels_per_module_x,
idx * udp_ports_per_module *
pixels_per_module_x +
pixels_per_module_x,
0, static_cast<ssize_t>(geometry.pixels_y())};
});
}
if (udp_port_types[first_port] == "top") {
size_t num_rois = geometry.modules_y() / udp_ports_per_module;
rois.resize(num_rois);
// assumes euclidean coordinate system with origin at bottom
// left corner of the detector
const ssize_t pixels_per_module_y =
geometry.pixels_y() / geometry.modules_y();
std::generate(
rois.begin(), rois.end(),
[n = 0, &geometry, pixels_per_module_y,
udp_ports_per_module]() mutable {
ssize_t idx = n++;
return ROI{0, static_cast<ssize_t>(geometry.pixels_x()),
idx * udp_ports_per_module * pixels_per_module_y,
idx * udp_ports_per_module *
pixels_per_module_y +
pixels_per_module_y};
});
}
if (udp_port_types[first_port] == "bottom") {
size_t num_rois = geometry.modules_y() / udp_ports_per_module;
rois.resize(num_rois);
const ssize_t pixels_per_module_y =
geometry.pixels_y() / geometry.modules_y();
std::generate(
rois.begin(), rois.end(),
[n = 0, &geometry, pixels_per_module_y,
udp_ports_per_module]() mutable {
ssize_t idx = n++;
return ROI{
0, static_cast<ssize_t>(geometry.pixels_x()),
idx * udp_ports_per_module * pixels_per_module_y +
pixels_per_module_y,
idx * udp_ports_per_module * pixels_per_module_y +
2 * pixels_per_module_y};
});
}
} else {
// iterate over all ports and create ROIs for each disabled port
LOG(logDEBUG) << "Creating ROIs from disabled UDP ports";
// get the enabled ones:
std::vector<size_t> enabled_ports(geometry.n_modules());
std::iota(enabled_ports.begin(), enabled_ports.end(), 0);
std::for_each(disabled_ports.begin(), disabled_ports.end(),
[&enabled_ports](size_t &port) {
enabled_ports.erase(std::remove(enabled_ports.begin(),
enabled_ports.end(),
port),
enabled_ports.end());
});
rois.reserve(enabled_ports.size());
for (const auto enabled_port : enabled_ports) {
auto module_geometry = geometry.get_module_geometries(enabled_port);
rois.push_back(
ROI{module_geometry.origin_x,
module_geometry.origin_x + module_geometry.width,
module_geometry.origin_y,
module_geometry.origin_y + module_geometry.height});
}
if (udp_port_types == std::vector<std::string>{"left", "right"}) {
rois = merge_consecutive_rois<false, true>(rois);
} else if (udp_port_types ==
std::vector<std::string>{"bottom", "top"} ||
udp_port_types ==
std::vector<std::string>{"top", "bottom"}) {
rois = merge_consecutive_rois<true, false>(rois);
} else {
throw std::runtime_error(LOCATION + "Unsupported UDP port types");
}
}
return rois;
}
RawFile::RawFile(const std::filesystem::path &fname, const std::string &mode)
: m_master(fname),
m_geometry(m_master.geometry(), m_master.pixels_x(), m_master.pixels_y(),
m_master.udp_interfaces_per_module(), m_master.quad()),
m_frames_in_file(m_master.frames_in_file()) {
: m_master(fname), m_frames_in_file(m_master.frames_in_file()) {
m_mode = mode;
if (mode == "r") {
if (m_master.rois().has_value() &&
!complete_ROI(m_master.rois().value(), m_geometry)) {
LOG(logDEBUG)
<< "ROIs defined in master file. Creating subfiles for "
"each ROI.";
m_ROI_geometries.reserve(m_master.rois()->size());
m_subfiles.resize(m_master.roi_geometries().size());
// iterate over all ROIS
const size_t num_rois = m_master.roi_geometries().size();
m_subfiles.resize(m_master.rois()->size());
// iterate over all ROIS
size_t roi_index = 0;
const auto rois = m_master.rois().value();
for (const auto &roi : rois) {
m_ROI_geometries.push_back(ROIGeometry(roi, m_geometry));
// open subfiles
open_subfiles(roi_index);
++roi_index;
}
} else if (m_master.disabled_udp_ports().has_value() &&
m_master.disabled_udp_ports().value().size() > 0) {
LOG(logDEBUG) << "Disabled UDP ports defined in master file. "
"Creating ROIs from disabled UDP ports.";
auto disabled_ports = m_master.disabled_udp_ports().value();
auto udp_port_types = m_master.udp_port_types().value();
std::vector<ROI> rois = get_rois_from_disabled_udp_ports(
disabled_ports, udp_port_types, m_geometry);
set_ROIs(rois);
m_subfiles.resize(rois.size());
m_ROI_geometries.reserve(rois.size());
for (size_t roi_index = 0; roi_index < rois.size(); ++roi_index) {
m_ROI_geometries.push_back(
ROIGeometry(rois[roi_index], m_geometry));
open_subfiles(roi_index);
}
for (size_t roi_index = 0; roi_index < num_rois; ++roi_index) {
// open subfiles
open_subfiles(roi_index);
}
// TODO: work around for now - retrieve num_frames from subfiles
if (m_master.disabled_udp_ports().has_value() &&
m_master.disabled_udp_ports().value().size() > 0) {
// TODO: remove frames_from_file from master file?
// retrieve the frame numbers from subfile as frames per file in
// master file 0 if dataprocessor 0 was disabled
@@ -243,12 +56,6 @@ RawFile::RawFile(const std::filesystem::path &fname, const std::string &mode)
min_subfiles_per_roi.end());
LOG(logDEBUG) << "Frames in file: " << m_frames_in_file;
} else {
// no ROI use full detector
m_subfiles.resize(1);
m_ROI_geometries.reserve(1);
m_ROI_geometries.push_back(ROIGeometry(m_geometry));
open_subfiles(0);
}
} else {
throw std::runtime_error(LOCATION +
@@ -258,24 +65,14 @@ RawFile::RawFile(const std::filesystem::path &fname, const std::string &mode)
Frame RawFile::read_roi(const size_t roi_index) {
if (!m_master.rois()) {
throw std::runtime_error(LOCATION +
"No ROIs defined in the master file.");
}
if (roi_index >= m_ROI_geometries.size()) {
if (roi_index >= m_master.roi_geometries().size()) {
throw std::runtime_error(LOCATION + "ROI index out of range.");
}
return get_frame(m_current_frame++, roi_index);
}
std::vector<Frame> RawFile::read_rois() {
if (!m_master.rois()) {
throw std::runtime_error(LOCATION +
"No ROIs defined in the master file.");
}
const size_t num_rois = m_ROI_geometries.size();
const size_t num_rois = m_master.roi_geometries().size();
std::vector<Frame> frames;
frames.reserve(num_rois);
@@ -289,7 +86,7 @@ std::vector<Frame> RawFile::read_rois() {
}
Frame RawFile::read_frame() {
if (m_ROI_geometries.size() > 1) {
if (m_master.roi_geometries().size() > 1) {
throw std::runtime_error(LOCATION + "Multiple ROIs present in file. "
"Use read_ROIs() instead.");
}
@@ -297,7 +94,7 @@ Frame RawFile::read_frame() {
}
Frame RawFile::read_frame(size_t frame_number) {
if (m_ROI_geometries.size() > 1) {
if (m_master.roi_geometries().size() > 1) {
throw std::runtime_error(
LOCATION + "Multiple ROIs present in file. "
"Use read_ROIs(const size_t frame_number) instead.");
@@ -308,7 +105,7 @@ Frame RawFile::read_frame(size_t frame_number) {
void RawFile::read_into(std::byte *image_buf, size_t n_frames) {
// TODO: implement this in a more efficient way
if (m_ROI_geometries.size() > 1) {
if (m_master.roi_geometries().size() > 1) {
throw std::runtime_error(LOCATION +
"Cannot use read_into for multiple ROIs.");
}
@@ -320,7 +117,7 @@ void RawFile::read_into(std::byte *image_buf, size_t n_frames) {
}
void RawFile::read_into(std::byte *image_buf) {
if (m_ROI_geometries.size() > 1) {
if (m_master.roi_geometries().size() > 1) {
throw std::runtime_error(LOCATION +
"Cannot use read_into for multiple ROIs. Use "
"read_roi_into() for a single ROI instead.");
@@ -330,10 +127,6 @@ void RawFile::read_into(std::byte *image_buf) {
void RawFile::read_roi_into(std::byte *image_buf, const size_t roi_index,
const size_t frame_number, DetectorHeader *header) {
if (m_ROI_geometries.size() <= 1) {
throw std::runtime_error(LOCATION +
"No ROIs defined in the master file.");
}
if (roi_index >= num_rois()) {
throw std::runtime_error(LOCATION + "ROI index out of range.");
}
@@ -341,7 +134,7 @@ void RawFile::read_roi_into(std::byte *image_buf, const size_t roi_index,
}
void RawFile::read_into(std::byte *image_buf, DetectorHeader *header) {
if (m_ROI_geometries.size() > 1) {
if (m_master.roi_geometries().size() > 1) {
throw std::runtime_error(LOCATION +
"Cannot use read_into for multiple ROIs. Use "
"read_roi_into() for a single ROI instead.");
@@ -353,7 +146,7 @@ void RawFile::read_into(std::byte *image_buf, size_t n_frames,
DetectorHeader *header) {
// return get_frame_into(m_current_frame++, image_buf, header);
if (m_ROI_geometries.size() > 1) {
if (m_master.roi_geometries().size() > 1) {
throw std::runtime_error(
LOCATION +
"Cannot use read_into for multiple ROIs."); // TODO: maybe
@@ -369,12 +162,12 @@ void RawFile::read_into(std::byte *image_buf, size_t n_frames,
this->get_frame_into(m_current_frame++, image_buf, 0, header);
image_buf += bytes_per_frame();
if (header)
header += m_ROI_geometries[0].num_modules_in_roi();
header += m_master.roi_geometries()[0].num_modules_in_roi();
}
}
size_t RawFile::bytes_per_frame() {
if (m_ROI_geometries.size() > 1) {
if (m_master.roi_geometries().size() > 1) {
throw std::runtime_error(
LOCATION + "Pass the desired roi_index to bytes_per_frame to get "
"bytes_per_frame for the specific ROI. ");
@@ -383,13 +176,13 @@ size_t RawFile::bytes_per_frame() {
}
size_t RawFile::bytes_per_frame(const size_t roi_index) {
return m_ROI_geometries.at(roi_index).pixels_x() *
m_ROI_geometries.at(roi_index).pixels_y() * m_master.bitdepth() /
bits_per_byte;
return m_master.roi_geometries().at(roi_index).pixels_x() *
m_master.roi_geometries().at(roi_index).pixels_y() *
m_master.bitdepth() / bits_per_byte;
}
size_t RawFile::pixels_per_frame() {
if (m_ROI_geometries.size() > 1) {
if (m_master.roi_geometries().size() > 1) {
throw std::runtime_error(
LOCATION + "Pass the desired roi_index to pixels_per_frame to get "
"pixels_per_frame for the specific ROI. ");
@@ -398,8 +191,8 @@ size_t RawFile::pixels_per_frame() {
}
size_t RawFile::pixels_per_frame(const size_t roi_index) {
return m_ROI_geometries.at(roi_index).pixels_x() *
m_ROI_geometries.at(roi_index).pixels_y();
return m_master.roi_geometries().at(roi_index).pixels_x() *
m_master.roi_geometries().at(roi_index).pixels_y();
}
DetectorType RawFile::detector_type() const { return m_master.detector_type(); }
@@ -421,7 +214,7 @@ size_t RawFile::tell() { return m_current_frame; }
size_t RawFile::total_frames() const { return m_frames_in_file; }
size_t RawFile::rows() const {
if (m_ROI_geometries.size() > 1) {
if (m_master.roi_geometries().size() > 1) {
throw std::runtime_error(LOCATION +
"Pass the desired roi_index to rows to get "
"rows for the specific ROI. ");
@@ -429,10 +222,10 @@ size_t RawFile::rows() const {
return rows(0);
}
size_t RawFile::rows(const size_t roi_index) const {
return m_ROI_geometries.at(roi_index).pixels_y();
return m_master.roi_geometries().at(roi_index).pixels_y();
}
size_t RawFile::cols() const {
if (m_ROI_geometries.size() > 1) {
if (m_master.roi_geometries().size() > 1) {
throw std::runtime_error(LOCATION +
"Pass the desired roi_index to cols to get "
"cols for the specific ROI. ");
@@ -440,27 +233,26 @@ size_t RawFile::cols() const {
return cols(0);
}
size_t RawFile::cols(const size_t roi_index) const {
return m_ROI_geometries.at(roi_index).pixels_x();
return m_master.roi_geometries().at(roi_index).pixels_x();
}
size_t RawFile::bitdepth() const { return m_master.bitdepth(); }
xy RawFile::geometry() const {
return xy{static_cast<uint32_t>(m_geometry.modules_y()),
static_cast<uint32_t>(m_geometry.modules_x())};
}
size_t RawFile::n_modules() const { return m_geometry.n_modules(); };
xy RawFile::geometry() const { return m_master.detector_layout(); }
size_t RawFile::num_rois() const { return m_ROI_geometries.size(); }
size_t RawFile::n_modules() const { return m_master.n_modules(); };
size_t RawFile::num_rois() const { return m_master.roi_geometries().size(); }
const ROIGeometry &RawFile::roi_geometries(size_t roi_index) const {
return m_ROI_geometries[roi_index];
return m_master.roi_geometries().at(roi_index);
}
std::vector<size_t> RawFile::n_modules_in_roi() const {
std::vector<size_t> results(m_ROI_geometries.size());
std::vector<size_t> results(m_master.roi_geometries().size());
std::transform(
m_ROI_geometries.begin(), m_ROI_geometries.end(), results.begin(),
m_master.roi_geometries().begin(), m_master.roi_geometries().end(),
results.begin(),
[](const ROIGeometry &roi) { return roi.num_modules_in_roi(); });
return results;
}
@@ -469,13 +261,13 @@ void RawFile::open_subfiles(const size_t roi_index) {
if (m_mode == "r") {
m_subfiles[roi_index].reserve(
m_ROI_geometries[roi_index].num_modules_in_roi());
m_master.roi_geometries().at(roi_index).num_modules_in_roi());
auto module_indices =
m_ROI_geometries[roi_index].module_indices_in_roi();
m_master.roi_geometries().at(roi_index).module_indices_in_roi();
for (const size_t i : module_indices) {
const auto pos = m_geometry.get_module_geometries(i);
const auto pos = m_master.geometry().get_module_geometries(i);
m_subfiles[roi_index].emplace_back(std::make_unique<RawSubFile>(
m_master.data_fname(i, 0), m_master.detector_type(), pos.height,
pos.width, m_master.bitdepth(), pos.row_index, pos.col_index));
@@ -506,8 +298,8 @@ DetectorHeader RawFile::read_header(const std::filesystem::path &fname) {
RawMasterFile RawFile::master() const { return m_master; }
Frame RawFile::get_frame(size_t frame_index, const size_t roi_index) {
auto f = Frame(m_ROI_geometries[roi_index].pixels_y(),
m_ROI_geometries[roi_index].pixels_x(),
auto f = Frame(m_master.roi_geometries().at(roi_index).pixels_y(),
m_master.roi_geometries().at(roi_index).pixels_x(),
Dtype::from_bitdepth(m_master.bitdepth()));
std::byte *frame_buffer = f.data();
get_frame_into(frame_index, frame_buffer, roi_index);
@@ -523,16 +315,18 @@ void RawFile::get_frame_into(size_t frame_index, std::byte *frame_buffer,
throw std::runtime_error(LOCATION + "Frame number out of range");
}
std::vector<size_t> frame_numbers(
m_ROI_geometries[roi_index].num_modules_in_roi());
m_master.roi_geometries().at(roi_index).num_modules_in_roi());
std::vector<size_t> frame_indices(
m_ROI_geometries[roi_index].num_modules_in_roi(), frame_index);
m_master.roi_geometries().at(roi_index).num_modules_in_roi(),
frame_index);
// sync the frame numbers
if (m_ROI_geometries[roi_index].num_modules_in_roi() !=
if (m_master.roi_geometries().at(roi_index).num_modules_in_roi() !=
1) { // if we have more than one module
for (size_t part_idx = 0;
part_idx != m_ROI_geometries[roi_index].num_modules_in_roi();
part_idx !=
m_master.roi_geometries().at(roi_index).num_modules_in_roi();
++part_idx) {
frame_numbers[part_idx] =
m_subfiles[roi_index][part_idx]->frame_number(frame_index);
@@ -562,32 +356,35 @@ void RawFile::get_frame_into(size_t frame_index, std::byte *frame_buffer,
}
}
if (m_master.geometry().col == 1) {
if (m_master.detector_layout().col == 1) {
// get the part from each subfile and copy it to the frame
for (size_t part_idx = 0;
part_idx != m_ROI_geometries[roi_index].num_modules_in_roi();
part_idx !=
m_master.roi_geometries().at(roi_index).num_modules_in_roi();
++part_idx) {
auto corrected_idx = frame_indices[part_idx];
// This is where we start writing
auto offset =
(m_geometry
(m_master.geometry()
.get_module_geometries(
m_ROI_geometries[roi_index].module_indices_in_roi(
part_idx))
m_master.roi_geometries()
.at(roi_index)
.module_indices_in_roi(part_idx))
.origin_y *
m_ROI_geometries[roi_index].pixels_x() +
m_geometry
m_master.roi_geometries().at(roi_index).pixels_x() +
m_master.geometry()
.get_module_geometries(
m_ROI_geometries[roi_index].module_indices_in_roi(
part_idx))
m_master.roi_geometries()
.at(roi_index)
.module_indices_in_roi(part_idx))
.origin_x) *
m_master.bitdepth() / 8;
if (m_geometry
.get_module_geometries(
m_ROI_geometries[roi_index].module_indices_in_roi(
part_idx))
if (m_master.geometry()
.get_module_geometries(m_master.roi_geometries()
.at(roi_index)
.module_indices_in_roi(part_idx))
.origin_x != 0)
throw std::runtime_error(
LOCATION +
@@ -620,10 +417,12 @@ void RawFile::get_frame_into(size_t frame_index, std::byte *frame_buffer,
// the module level
for (size_t part_idx = 0;
part_idx != m_ROI_geometries[roi_index].num_modules_in_roi();
part_idx !=
m_master.roi_geometries().at(roi_index).num_modules_in_roi();
++part_idx) {
auto pos = m_geometry.get_module_geometries(
m_ROI_geometries[roi_index].module_indices_in_roi(part_idx));
auto pos = m_master.geometry().get_module_geometries(
m_master.roi_geometries().at(roi_index).module_indices_in_roi(
part_idx));
auto corrected_idx = frame_indices[part_idx];
m_subfiles[roi_index][part_idx]->seek(corrected_idx);
@@ -637,7 +436,8 @@ void RawFile::get_frame_into(size_t frame_index, std::byte *frame_buffer,
auto irow = (pos.origin_y + cur_row);
auto icol = pos.origin_x;
auto dest =
(irow * m_ROI_geometries[roi_index].pixels_x() + icol);
(irow * m_master.roi_geometries().at(roi_index).pixels_x() +
icol);
dest = dest * m_master.bitdepth() / 8;
memcpy(frame_buffer + dest,
part_buffer +
@@ -691,6 +491,4 @@ size_t RawFile::frame_number(size_t frame_index) {
return m_subfiles[0][0]->frame_number(frame_index);
}
void RawFile::set_ROIs(const std::vector<ROI> &rois) { m_master.m_rois = rois; }
} // namespace aare
+37 -36
View File
@@ -264,8 +264,9 @@ TEST_CASE("check find_geometry", "[.with-data][RawFile]") {
RawMasterFile master_file(fpath);
auto geometry = DetectorGeometry(
master_file.geometry(), master_file.pixels_x(), master_file.pixels_y(),
master_file.udp_interfaces_per_module(), master_file.quad());
master_file.detector_layout(), master_file.pixels_x(),
master_file.pixels_y(), master_file.udp_interfaces_per_module(),
master_file.quad());
CHECK(geometry.modules_x() == test_parameters.modules_x);
CHECK(geometry.modules_y() == test_parameters.modules_y);
@@ -309,8 +310,8 @@ TEST_CASE("Open multi module file with ROI",
RawFile f(fpath, "r");
SECTION("read 2 frames") {
REQUIRE(f.master().roi().value().width() == 256);
REQUIRE(f.master().roi().value().height() == 256);
REQUIRE(f.master().roi().width() == 256);
REQUIRE(f.master().roi().height() == 256);
CHECK(f.n_modules() == 2);
@@ -401,8 +402,8 @@ TEST_CASE("Read Mythenframe", "[.with-data][RawFile]") {
auto fpath = test_data_path() / "raw/newmythen03/run_2_master_1.json";
REQUIRE(std::filesystem::exists(fpath));
RawFile f(fpath);
REQUIRE(f.master().roi().value().width() == 2560);
REQUIRE(f.master().roi().value().height() == 1);
REQUIRE(f.master().roi().width() == 2560);
REQUIRE(f.master().roi().height() == 1);
auto frame = f.read_frame();
REQUIRE(frame.cols() == 2560);
}
@@ -424,8 +425,8 @@ TEST_CASE("Read Jungfrau frame with disabled UDP ports",
auto rois = f.master().rois();
REQUIRE(rois.value().size() == 1);
REQUIRE(rois.value()[0] == ROI{0, 1024, 0, 256});
REQUIRE(rois.size() == 1);
REQUIRE(rois[0] == ROI{0, 1024, 0, 256});
}
SECTION("disabled bottom port") {
@@ -441,8 +442,8 @@ TEST_CASE("Read Jungfrau frame with disabled UDP ports",
REQUIRE(frame.cols() == 1024);
REQUIRE(frame.rows() == 256);
auto rois = f.master().rois();
REQUIRE(rois.value().size() == 1);
REQUIRE(rois.value()[0] == ROI{0, 1024, 256, 512});
REQUIRE(rois.size() == 1);
REQUIRE(rois[0] == ROI{0, 1024, 256, 512});
}
SECTION("2 modules - top ports disabled") {
auto fpath = test_data_path() / "raw/jungfrau" /
@@ -468,9 +469,9 @@ TEST_CASE("Read Jungfrau frame with disabled UDP ports",
REQUIRE(frame[1].cols() == 1024);
REQUIRE(frame[1].rows() == 256);
auto rois = f.master().rois();
REQUIRE(rois.value().size() == 2);
REQUIRE(rois.value()[0] == ROI{0, 1024, 0, 256});
REQUIRE(rois.value()[1] == ROI{0, 1024, 512, 768});
REQUIRE(rois.size() == 2);
REQUIRE(rois[0] == ROI{0, 1024, 0, 256});
REQUIRE(rois[1] == ROI{0, 1024, 512, 768});
}
SECTION("2 modules - top ports disabled - bottom port disabled") {
auto fpath = test_data_path() / "raw/jungfrau" /
@@ -485,8 +486,8 @@ TEST_CASE("Read Jungfrau frame with disabled UDP ports",
REQUIRE(frame.cols() == 1024);
REQUIRE(frame.rows() == 512);
auto rois = f.master().rois();
REQUIRE(rois.value().size() == 1);
REQUIRE(rois.value()[0] == ROI{0, 1024, 256, 768});
REQUIRE(rois.size() == 1);
REQUIRE(rois[0] == ROI{0, 1024, 256, 768});
}
SECTION("4 modules- mixed ports disabled") {
auto fpath = test_data_path() / "raw/jungfrau" /
@@ -513,11 +514,11 @@ TEST_CASE("Read Jungfrau frame with disabled UDP ports",
REQUIRE(frames[3].cols() == 1024);
REQUIRE(frames[3].rows() == 256);
auto rois = f.master().rois();
REQUIRE(rois.value().size() == 4);
REQUIRE(rois.value()[0] == ROI{0, 1024, 0, 256});
REQUIRE(rois.value()[1] == ROI{0, 1024, 512, 768});
REQUIRE(rois.value()[2] == ROI{1024, 2048, 256, 512});
REQUIRE(rois.value()[3] == ROI{1024, 2048, 768, 1024});
REQUIRE(rois.size() == 4);
REQUIRE(rois[0] == ROI{0, 1024, 0, 256});
REQUIRE(rois[1] == ROI{0, 1024, 512, 768});
REQUIRE(rois[2] == ROI{1024, 2048, 256, 512});
REQUIRE(rois[3] == ROI{1024, 2048, 768, 1024});
}
}
@@ -537,8 +538,8 @@ TEST_CASE("Read Moench frame with disabled UDP ports",
REQUIRE(frame.rows() == 200);
auto rois = f.master().rois();
REQUIRE(rois.value().size() == 1);
REQUIRE(rois.value()[0] == ROI{0, 400, 0, 200});
REQUIRE(rois.size() == 1);
REQUIRE(rois[0] == ROI{0, 400, 0, 200});
}
SECTION("disabled bottom port") {
@@ -555,8 +556,8 @@ TEST_CASE("Read Moench frame with disabled UDP ports",
REQUIRE(frame.rows() == 200);
auto rois = f.master().rois();
REQUIRE(rois.value().size() == 1);
REQUIRE(rois.value()[0] == ROI{0, 400, 200, 400});
REQUIRE(rois.size() == 1);
REQUIRE(rois[0] == ROI{0, 400, 200, 400});
}
}
@@ -577,8 +578,8 @@ TEST_CASE("Read Eiger frame with disabled UDP ports",
REQUIRE(frame.rows() == 512);
auto rois = f.master().rois();
REQUIRE(rois.value().size() == 1);
REQUIRE(rois.value()[0] == ROI{512, 1024, 0, 512});
REQUIRE(rois.size() == 1);
REQUIRE(rois[0] == ROI{512, 1024, 0, 512});
}
SECTION("disabled right port") {
auto fpath = test_data_path() / "raw/eiger" /
@@ -593,8 +594,8 @@ TEST_CASE("Read Eiger frame with disabled UDP ports",
REQUIRE(frame.cols() == 512);
REQUIRE(frame.rows() == 512);
auto rois = f.master().rois();
REQUIRE(rois.value().size() == 1);
REQUIRE(rois.value()[0] == ROI{0, 512, 0, 512});
REQUIRE(rois.size() == 1);
REQUIRE(rois[0] == ROI{0, 512, 0, 512});
}
SECTION("2 full modules stacked vertically - right ports disabled") {
auto fpath = test_data_path() / "raw/eiger" /
@@ -618,9 +619,9 @@ TEST_CASE("Read Eiger frame with disabled UDP ports",
REQUIRE(frames[1].cols() == 512);
REQUIRE(frames[1].rows() == 512);
auto rois = f.master().rois();
REQUIRE(rois.value().size() == 2);
REQUIRE(rois.value()[0] == ROI{0, 512, 0, 512});
REQUIRE(rois.value()[1] == ROI{1024, 1536, 0, 512});
REQUIRE(rois.size() == 2);
REQUIRE(rois[0] == ROI{0, 512, 0, 512});
REQUIRE(rois[1] == ROI{1024, 1536, 0, 512});
}
SECTION("quad module - bottom port disabled") {
auto fpath = test_data_path() / "raw/eiger" /
@@ -636,8 +637,8 @@ TEST_CASE("Read Eiger frame with disabled UDP ports",
REQUIRE(frame.cols() == 512);
REQUIRE(frame.rows() == 256);
auto rois = f.master().rois();
REQUIRE(rois.value().size() == 1);
REQUIRE(rois.value()[0] == ROI{0, 512, 256, 512});
REQUIRE(rois.size() == 1);
REQUIRE(rois[0] == ROI{0, 512, 256, 512});
}
SECTION("only one port disabled") {
auto fpath = test_data_path() / "raw/eiger" /
@@ -656,9 +657,9 @@ TEST_CASE("Read Eiger frame with disabled UDP ports",
REQUIRE(frame[1].cols() == 1024);
REQUIRE(frame[1].rows() == 256);
auto rois = f.master().rois();
REQUIRE(rois.value().size() == 2);
REQUIRE(rois.size() == 2);
REQUIRE(rois.value()[0] == ROI{512, 1024, 0, 256});
REQUIRE(rois.value()[1] == ROI{0, 1024, 256, 512});
REQUIRE(rois[0] == ROI{512, 1024, 0, 256});
REQUIRE(rois[1] == ROI{0, 1024, 256, 512});
}
}
+203 -30
View File
@@ -116,9 +116,30 @@ RawMasterFile::RawMasterFile(const std::filesystem::path &fpath)
throw std::runtime_error(LOCATION + "Unsupported file type");
}
m_geometry = DetectorGeometry(m_detector_layout, m_pixels_x, m_pixels_y,
m_udp_interfaces_per_module, m_quad);
if (m_quad == 1 && m_udp_port_types.has_value()) {
m_udp_port_types.value() = {"top", "bottom"};
}
if (m_disabled_udp_ports.has_value()) {
// ROI takes precedence over disabled UDP ports, if both are defined in
// the master file
if (!complete_ROI(m_rois, m_geometry)) {
LOG(logWARNING)
<< "ROI and disabled UDP ports defined in master file. ROI "
"will be used and disabled UDP ports will be ignored.";
} else {
update_rois_from_disabled_udp_ports();
}
}
m_ROI_geometries.reserve(m_rois.size());
for (const auto &roi : m_rois) {
m_ROI_geometries.push_back(ROIGeometry(roi, m_geometry));
}
}
RawMasterFile::RawMasterFile(std::istream &is, const std::string &fname)
@@ -168,10 +189,16 @@ std::optional<uint8_t> RawMasterFile::counter_mask() const {
return m_counter_mask;
}
xy RawMasterFile::geometry() const { return m_geometry; }
xy RawMasterFile::detector_layout() const { return m_detector_layout; }
const DetectorGeometry &RawMasterFile::geometry() const { return m_geometry; }
const std::vector<ROIGeometry> &RawMasterFile::roi_geometries() const {
return m_ROI_geometries;
}
size_t RawMasterFile::n_modules() const {
return m_geometry.row * m_geometry.col;
return m_detector_layout.row * m_detector_layout.col;
}
xy RawMasterFile::udp_interfaces_per_module() const {
@@ -205,26 +232,21 @@ std::optional<std::vector<size_t>> RawMasterFile::disabled_udp_ports() const {
return m_disabled_udp_ports;
}
std::optional<ROI> RawMasterFile::roi() const {
if (!m_rois) {
return std::nullopt;
}
ROI RawMasterFile::roi() const {
if (m_rois->empty()) {
if (m_rois.empty()) {
throw std::runtime_error(LOCATION + "Zero ROIs in metadata.");
}
if (m_rois.value().size() > 1) {
if (m_rois.size() > 1) {
throw std::runtime_error(LOCATION +
"Multiple ROIs present, use rois() method.");
} else {
return m_rois.has_value()
? std::optional<ROI>(m_rois.value().at(0))
: std::nullopt; // TODO: maybe throw if no roi exists
return m_rois.at(0);
}
}
std::optional<std::vector<ROI>> RawMasterFile::rois() const { return m_rois; }
std::vector<ROI> RawMasterFile::rois() const { return m_rois; }
ReadoutMode RawMasterFile::get_reading_mode() const {
@@ -260,10 +282,11 @@ void RawMasterFile::parse_json(std::istream &is) {
m_type = string_to<DetectorType>(j["Detector Type"].get<std::string>());
m_timing_mode = string_to<TimingMode>(j["Timing Mode"].get<std::string>());
m_geometry = {j["Geometry"]["y"],
j["Geometry"]["x"]}; // TODO: isnt it only available for
// version > 7.1?
// - try block default should be 1x1
m_detector_layout = {
j["Geometry"]["y"],
j["Geometry"]["x"]}; // TODO: isnt it only available for
// version > 7.1?
// - try block default should be 1x1
m_image_size_in_bytes =
v < 8.0 ? j["Image Size in bytes"] : j["Image Size"];
@@ -426,14 +449,18 @@ void RawMasterFile::parse_json(std::istream &is) {
obj.at("ymin") = 0;
obj.at("ymax") = 0;
}
m_rois.emplace();
m_rois.value().push_back(ROI{
obj.at("xmin"), static_cast<ssize_t>(obj.at("xmax")) + 1,
obj.at("ymin"), static_cast<ssize_t>(obj.at("ymax")) + 1});
m_rois.push_back({static_cast<ssize_t>(obj.at("xmin")),
static_cast<ssize_t>(obj.at("xmax")) + 1,
static_cast<ssize_t>(obj.at("ymin")),
static_cast<ssize_t>(obj.at("ymax")) + 1});
} else {
// fill ROI with full detector size if not present in master
// file
m_rois.push_back({0, static_cast<ssize_t>(m_pixels_x), 0,
static_cast<ssize_t>(m_pixels_y)});
}
} else {
auto obj = j.at("Receiver Rois");
m_rois.emplace();
for (auto &elem : obj) {
// handle Mythen
if (elem.at("ymin") == -1 && elem.at("ymax") == -1) {
@@ -441,15 +468,17 @@ void RawMasterFile::parse_json(std::istream &is) {
elem.at("ymax") = 0;
}
m_rois.value().push_back(ROI{
elem.at("xmin"), static_cast<ssize_t>(elem.at("xmax")) + 1,
elem.at("ymin"),
static_cast<ssize_t>(elem.at("ymax")) + 1});
m_rois.push_back({static_cast<ssize_t>(elem.at("xmin")),
static_cast<ssize_t>(elem.at("xmax")) + 1,
static_cast<ssize_t>(elem.at("ymin")),
static_cast<ssize_t>(elem.at("ymax")) + 1});
}
}
} catch (const json::out_of_range &e) {
// leave the optional empty
// fill ROI with full detector size if not present in master file
m_rois.push_back({0, static_cast<ssize_t>(m_pixels_x), 0,
static_cast<ssize_t>(m_pixels_y)});
}
if (j.contains("Counter Mask")) {
@@ -557,7 +586,7 @@ void RawMasterFile::parse_raw(std::istream &is) {
m_max_frames_per_file = std::stoi(value);
} else if (key == "Geometry") {
pos = value.find(',');
m_geometry = {
m_detector_layout = {
static_cast<uint32_t>(std::stoi(value.substr(1, pos))),
static_cast<uint32_t>(std::stoi(value.substr(pos + 1)))};
} else if (key == "Number of UDP Interfaces") {
@@ -577,11 +606,11 @@ void RawMasterFile::parse_raw(std::istream &is) {
m_type = DetectorType::Moench03_old;
}
if (m_geometry.col == 0 && m_geometry.row == 0) {
if (m_detector_layout.col == 0 && m_detector_layout.row == 0) {
retrieve_geometry();
LOG(TLogLevel::logWARNING)
<< "No geometry found in master file. Retrieved geometry of "
<< m_geometry.row << " x " << m_geometry.col << "\n ";
<< m_detector_layout.row << " x " << m_detector_layout.col << "\n ";
}
// TODO! Read files and find actual frames
@@ -607,7 +636,151 @@ void RawMasterFile::retrieve_geometry() {
++rows;
++cols;
m_geometry = {rows, cols};
m_detector_layout = {rows, cols};
}
/**
* @brief Update ROIs from disabled UDP ports
*/
void RawMasterFile::update_rois_from_disabled_udp_ports() {
const size_t num_udp_port_types = m_udp_port_types.value().size();
auto disabled_ports = m_disabled_udp_ports.value();
size_t first_port = disabled_ports[0] % num_udp_port_types;
bool all_ports_equal =
std::all_of(disabled_ports.begin(), disabled_ports.end(),
[&num_udp_port_types, first_port](size_t &port) {
return port % num_udp_port_types == first_port;
});
m_rois.clear(); // remove global roi
const ssize_t udp_ports_per_module =
m_geometry.udp_interfaces_per_module().col *
m_geometry.udp_interfaces_per_module().row;
bool port_disabled_for_all_modules =
disabled_ports.size() ==
m_geometry.modules_x() * m_geometry.modules_y() / udp_ports_per_module;
if (all_ports_equal && port_disabled_for_all_modules) {
if (m_udp_port_types.value()[first_port] == "left") {
const size_t num_rois =
m_geometry.modules_x() / udp_ports_per_module;
m_rois.resize(num_rois);
const ssize_t pixels_per_module_x =
m_geometry.pixels_x() / m_geometry.modules_x();
std::generate(
m_rois.begin(), m_rois.end(),
[n = 0, this, pixels_per_module_x,
udp_ports_per_module]() mutable {
ssize_t idx = n++;
return ROI{
idx * udp_ports_per_module * pixels_per_module_x +
pixels_per_module_x,
idx * udp_ports_per_module * pixels_per_module_x +
2 * pixels_per_module_x,
0, static_cast<ssize_t>(m_geometry.pixels_y())};
});
}
if (m_udp_port_types.value()[first_port] == "right") {
const size_t num_rois =
m_geometry.modules_x() / udp_ports_per_module;
m_rois.resize(num_rois);
const ssize_t pixels_per_module_x =
m_geometry.pixels_x() / m_geometry.modules_x();
std::generate(
m_rois.begin(), m_rois.end(),
[n = 0, this, pixels_per_module_x,
udp_ports_per_module]() mutable {
ssize_t idx = n++;
return ROI{idx * udp_ports_per_module * pixels_per_module_x,
idx * udp_ports_per_module *
pixels_per_module_x +
pixels_per_module_x,
0, static_cast<ssize_t>(m_geometry.pixels_y())};
});
}
if (m_udp_port_types.value()[first_port] == "top") {
size_t num_rois = m_geometry.modules_y() / udp_ports_per_module;
m_rois.resize(num_rois);
// assumes euclidean coordinate system with origin at bottom
// left corner of the detector
const ssize_t pixels_per_module_y =
m_geometry.pixels_y() / m_geometry.modules_y();
std::generate(
m_rois.begin(), m_rois.end(),
[n = 0, this, pixels_per_module_y,
udp_ports_per_module]() mutable {
ssize_t idx = n++;
return ROI{0, static_cast<ssize_t>(m_geometry.pixels_x()),
idx * udp_ports_per_module * pixels_per_module_y,
idx * udp_ports_per_module *
pixels_per_module_y +
pixels_per_module_y};
});
}
if (m_udp_port_types.value()[first_port] == "bottom") {
size_t num_rois = m_geometry.modules_y() / udp_ports_per_module;
m_rois.resize(num_rois);
const ssize_t pixels_per_module_y =
m_geometry.pixels_y() / m_geometry.modules_y();
std::generate(
m_rois.begin(), m_rois.end(),
[n = 0, this, pixels_per_module_y,
udp_ports_per_module]() mutable {
ssize_t idx = n++;
return ROI{
0, static_cast<ssize_t>(m_geometry.pixels_x()),
idx * udp_ports_per_module * pixels_per_module_y +
pixels_per_module_y,
idx * udp_ports_per_module * pixels_per_module_y +
2 * pixels_per_module_y};
});
}
} else {
// iterate over all ports and create ROIs for each disabled port
LOG(logDEBUG) << "Creating ROIs from disabled UDP ports";
// get the enabled ones:
std::vector<size_t> enabled_ports(m_geometry.n_modules());
std::iota(enabled_ports.begin(), enabled_ports.end(), 0);
std::for_each(disabled_ports.begin(), disabled_ports.end(),
[&enabled_ports](size_t &port) {
enabled_ports.erase(std::remove(enabled_ports.begin(),
enabled_ports.end(),
port),
enabled_ports.end());
});
m_rois.reserve(enabled_ports.size());
for (const auto enabled_port : enabled_ports) {
auto module_geometry =
m_geometry.get_module_geometries(enabled_port);
m_rois.push_back(
ROI{module_geometry.origin_x,
module_geometry.origin_x + module_geometry.width,
module_geometry.origin_y,
module_geometry.origin_y + module_geometry.height});
}
if (m_udp_port_types == std::vector<std::string>{"left", "right"}) {
m_rois = merge_consecutive_rois<false, true>(m_rois);
} else if (m_udp_port_types ==
std::vector<std::string>{"bottom", "top"} ||
m_udp_port_types ==
std::vector<std::string>{"top", "bottom"}) {
m_rois = merge_consecutive_rois<true, false>(m_rois);
} else {
throw std::runtime_error(LOCATION + "Unsupported UDP port types");
}
}
}
} // namespace aare
+26 -26
View File
@@ -86,8 +86,8 @@ TEST_CASE("Parse a master file in .json format", "[.integration]") {
// "x": 1,
// "y": 1
// },
REQUIRE(f.geometry().col == 1);
REQUIRE(f.geometry().row == 1);
REQUIRE(f.detector_layout().col == 1);
REQUIRE(f.detector_layout().row == 1);
// "Image Size in bytes": 1048576,
REQUIRE(f.image_size_in_bytes() == 1048576);
@@ -180,9 +180,9 @@ TEST_CASE("Parse a master file in .raw format", "[.integration]") {
REQUIRE(f.detector_type() == DetectorType::ChipTestBoard);
// Timing Mode : auto
REQUIRE(f.timing_mode() == TimingMode::Auto);
// Geometry : [1, 1]
REQUIRE(f.geometry().col == 1);
REQUIRE(f.geometry().row == 1);
// Detector Layout : [1, 1]
REQUIRE(f.detector_layout().col == 1);
REQUIRE(f.detector_layout().row == 1);
// Image Size : 360000 bytes
REQUIRE(f.image_size_in_bytes() == 360000);
// Pixels : [96, 1]
@@ -247,9 +247,9 @@ TEST_CASE("Parse a master file in new .json format",
REQUIRE(f.detector_type() == DetectorType::Mythen3);
// Timing Mode : auto
REQUIRE(f.timing_mode() == TimingMode::Auto);
// Geometry : [2, 1]
REQUIRE(f.geometry().col == 2);
REQUIRE(f.geometry().row == 1);
// Detector Layout : [2, 1]
REQUIRE(f.detector_layout().col == 2);
REQUIRE(f.detector_layout().row == 1);
// Image Size : 5120 bytes
REQUIRE(f.image_size_in_bytes() == 5120);
@@ -400,8 +400,8 @@ TEST_CASE("Parse EIGER 7.2 master from string stream") {
REQUIRE(f.version() == "7.2");
REQUIRE(f.detector_type() == DetectorType::Eiger);
REQUIRE(f.timing_mode() == TimingMode::Auto);
REQUIRE(f.geometry().col == 2);
REQUIRE(f.geometry().row == 2);
REQUIRE(f.detector_layout().col == 2);
REQUIRE(f.detector_layout().row == 2);
REQUIRE(f.image_size_in_bytes() == 524288);
REQUIRE(f.pixels_x() == 512);
@@ -477,8 +477,8 @@ TEST_CASE("Parse JUNGFRAU 7.2 master from string stream") {
REQUIRE(f.version() == "7.2");
REQUIRE(f.detector_type() == DetectorType::Jungfrau);
REQUIRE(f.timing_mode() == TimingMode::Auto);
REQUIRE(f.geometry().col == 1);
REQUIRE(f.geometry().row == 2);
REQUIRE(f.detector_layout().col == 1);
REQUIRE(f.detector_layout().row == 2);
REQUIRE(f.n_modules() == 2);
REQUIRE(f.image_size_in_bytes() == 524288);
REQUIRE(f.pixels_x() == 1024);
@@ -560,7 +560,7 @@ TEST_CASE(
REQUIRE(f.version() == "7.2");
REQUIRE(f.detector_type() == DetectorType::ChipTestBoard);
REQUIRE(f.timing_mode() == TimingMode::Auto);
REQUIRE(f.geometry() == xy{1, 1});
REQUIRE(f.detector_layout() == xy{1, 1});
REQUIRE(f.image_size_in_bytes() == 192000);
REQUIRE(f.pixels_x() == 32);
REQUIRE(f.pixels_y() == 1);
@@ -638,7 +638,7 @@ TEST_CASE(
REQUIRE(f.version() == "7.2");
REQUIRE(f.detector_type() == DetectorType::ChipTestBoard);
REQUIRE(f.timing_mode() == TimingMode::Auto);
REQUIRE(f.geometry() == xy{1, 1});
REQUIRE(f.detector_layout() == xy{1, 1});
REQUIRE(f.image_size_in_bytes() == 16000);
REQUIRE(f.pixels_x() == 64);
REQUIRE(f.pixels_y() == 1);
@@ -710,7 +710,7 @@ TEST_CASE("Parse Moench 7.2 master (SW 7.0.3) from string stream") {
REQUIRE(f.version() == "7.2");
REQUIRE(f.detector_type() == DetectorType::Moench03_old);
REQUIRE(f.timing_mode() == TimingMode::Auto);
REQUIRE(f.geometry() == xy{1, 1});
REQUIRE(f.detector_layout() == xy{1, 1});
REQUIRE(f.image_size_in_bytes() == 320000);
REQUIRE(f.pixels_x() == 400);
REQUIRE(f.pixels_y() == 400);
@@ -781,7 +781,7 @@ TEST_CASE("Parse Moench 7.2 master (SW 8.0.0) from string stream") {
REQUIRE(f.version() == "7.2");
REQUIRE(f.detector_type() == DetectorType::Moench03);
REQUIRE(f.timing_mode() == TimingMode::Auto);
REQUIRE(f.geometry() == xy{1, 1});
REQUIRE(f.detector_layout() == xy{1, 1});
REQUIRE(f.image_size_in_bytes() == 320000);
REQUIRE(f.pixels_x() == 400);
REQUIRE(f.pixels_y() == 400);
@@ -863,7 +863,7 @@ TEST_CASE("Parse CTB 7.2 master (SW 8.0.0) from string stream") {
REQUIRE(f.version() == "7.2");
REQUIRE(f.detector_type() == DetectorType::ChipTestBoard);
REQUIRE(f.timing_mode() == TimingMode::Auto);
REQUIRE(f.geometry() == xy{1, 1});
REQUIRE(f.detector_layout() == xy{1, 1});
REQUIRE(f.image_size_in_bytes() == 192000);
REQUIRE(f.pixels_x() == 32);
REQUIRE(f.pixels_y() == 1);
@@ -944,7 +944,7 @@ TEST_CASE(
REQUIRE(f.version() == "7.2");
REQUIRE(f.detector_type() == DetectorType::ChipTestBoard);
REQUIRE(f.timing_mode() == TimingMode::Auto);
REQUIRE(f.geometry() == xy{1, 1});
REQUIRE(f.detector_layout() == xy{1, 1});
REQUIRE(f.image_size_in_bytes() == 16000);
REQUIRE(f.pixels_x() == 64);
REQUIRE(f.pixels_y() == 1);
@@ -1011,8 +1011,8 @@ TEST_CASE("Parse a CTB file from stream") {
REQUIRE(f.version() == "8.0");
REQUIRE(f.detector_type() == DetectorType::ChipTestBoard);
REQUIRE(f.timing_mode() == TimingMode::Auto);
REQUIRE(f.geometry().col == 1);
REQUIRE(f.geometry().row == 1);
REQUIRE(f.detector_layout().col == 1);
REQUIRE(f.detector_layout().row == 1);
REQUIRE(f.image_size_in_bytes() == 18432);
REQUIRE(f.pixels_x() == 2);
REQUIRE(f.pixels_y() == 1);
@@ -1101,8 +1101,8 @@ TEST_CASE("Parse v8.0 MYTHEN3 from stream") {
REQUIRE(f.version() == "8.0");
REQUIRE(f.detector_type() == DetectorType::Mythen3);
REQUIRE(f.timing_mode() == TimingMode::Auto);
REQUIRE(f.geometry().col == 2);
REQUIRE(f.geometry().row == 1);
REQUIRE(f.detector_layout().col == 2);
REQUIRE(f.detector_layout().row == 1);
REQUIRE(f.image_size_in_bytes() == 5120);
REQUIRE(f.pixels_x() == 1280);
REQUIRE(f.pixels_y() == 1);
@@ -1186,8 +1186,8 @@ TEST_CASE("Parse a v7.1 Mythen3 from stream") {
REQUIRE(f.version() == "7.1");
REQUIRE(f.detector_type() == DetectorType::Mythen3);
REQUIRE(f.timing_mode() == TimingMode::Auto);
REQUIRE(f.geometry().col == 1);
REQUIRE(f.geometry().row == 1);
REQUIRE(f.detector_layout().col == 1);
REQUIRE(f.detector_layout().row == 1);
REQUIRE(f.image_size_in_bytes() == 15360);
REQUIRE(f.pixels_x() == 3840);
REQUIRE(f.pixels_y() == 1);
@@ -1268,8 +1268,8 @@ TEST_CASE("Parse old Moench03 from stream") {
REQUIRE(f.version() == "7.1");
REQUIRE(f.detector_type() == DetectorType::Moench03_old);
REQUIRE(f.timing_mode() == TimingMode::Auto);
REQUIRE(f.geometry().col == 1);
REQUIRE(f.geometry().row == 1);
REQUIRE(f.detector_layout().col == 1);
REQUIRE(f.detector_layout().row == 1);
REQUIRE(f.image_size_in_bytes() == 320000);
REQUIRE(f.pixels_x() == 400);
REQUIRE(f.pixels_y() == 400);