added to documentation

This commit is contained in:
2026-08-26 17:33:49 +02:00
parent a2f56002f3
commit bffeab15f4
12 changed files with 482 additions and 147 deletions
@@ -0,0 +1,31 @@
Inclusive ROI
================
Class for Region of Interest (ROI) using inclusive bounds.
The class is primarily used in the context of pixel to strixel remapping.
.. doxygenstruct:: aare::InclusiveROI
:members:
:undoc-members:
.. doxygenfunction:: aare::toInclusiveROI
.. doxygenfunction:: aare::toHalfopenROI
.. doxygenfunction:: aare::inclusiveroi::geom::translate
.. doxygenfunction:: aare::inclusiveroi::geom::to_local
.. doxygenfunction:: aare::inclusiveroi::geom::mirror_on_y
.. doxygenfunction:: aare::inclusiveroi::geom::mirror_on_x
.. doxygenfunction:: aare::inclusiveroi::geom::mirrorXY
.. doxygenfunction:: aare::inclusiveroi::geom::intersect
.. doxygenfunction:: aare::inclusiveroi::geom::unite
.. doxygenfunction:: aare::inclusiveroi::geom::rebaseROI
@@ -0,0 +1,45 @@
Predefined Pixel to Strixel Maps
================================
Includes predefined pixel to strixel maps for the sensor configurations introduced in :ref:`predefined_sensor_configs`.
Predefined Maps for 2x2 cm iLGAD sensor
----------------------------------------
.. doxygenfunction:: aare::remap::generate::jungfrau_ilgad_singlechip_25um_strixel_map
.. doxygenfunction:: aare::remap::generate::jungfrau_ilgad_singlechip_15um_strixel_map
.. doxygenfunction:: aare::remap::generate::jungfrau_ilgad_singlechip_18um_strixel_map
.. doxygenfunction:: aare::remap::generate::jungfrau_ilgad_singlechip_multipitch_strixel_maps(InclusiveROI, defs::SensorModulePlacement, defs::BondShift)
.. doxygenfunction:: aare::remap::generate::jungfrau_ilgad_singlechip_multipitch_strixel_maps(InclusiveROI, int, defs::BondShift)
Predefined Maps for 2x2 cm TEW sensor
----------------------------------------
.. doxygenfunction:: aare::remap::generate::jungfrau_tew_singlechip_25um_strixel_map
.. doxygenfunction:: aare::remap::generate::jungfrau_tew_singlechip_15um_strixel_map
.. doxygenfunction:: aare::remap::generate::jungfrau_tew_singlechip_18um_strixel_map
.. doxygenfunction:: aare::remap::generate::jungfrau_tew_singlechip_multipitch_strixel_maps(InclusiveROI, defs::SensorModulePlacement, defs::BondShift)
.. doxygenfunction:: aare::remap::generate::jungfrau_tew_singlechip_multipitch_strixel_maps(InclusiveROI, int, defs::BondShift)
Predefined Maps for 4x4 cm iLGAD sensor
----------------------------------------
.. doxygenfunction:: aare::remap::generate::jungfrau_ilgad_quadbottom_25um_strixel_map
.. doxygenfunction:: aare::remap::generate::jungfrau_ilgad_quadtop_25um_strixel_map
.. doxygenfunction:: aare::remap::generate::jungfrau_ilgad_quad_25um_strixel_maps
.. doxygenfunction:: aare::remap::generate::jungfrau_ilgad_quad_25um_strixel_map
@@ -0,0 +1,107 @@
.. _predefined_sensor_configs:
Predefined Sensor configurations
=================================
Includes all predefined sensor configurations for Jungfrau iLGAD and Jungfrau TEW sensors.
The Photon Detector Group produces Jungfrau modules with three different sensor types: 2x2 cm iLGAD, 2x2 cm TEW and 4x4 cm iLGAD.
Below are the predefined sensor configurations for all three sensor types. Detailed information about the sensor geometry, placement and rotation on the module, strixel types and their placement can be found in the dedicated sensor sections further below.
Predefined sensor configurations
---------------------------------
.. doxygenvariable:: aare::remap::config::jungfrau::SingleChipMP_iLGAD
.. doxygenvariable:: aare::remap::config::jungfrau::SingleChipMP_TEW
.. doxygenvariable:: aare::remap::config::jungfrau::Quad_iLGAD
.. _predefined_strixel_groups:
Predefined strixel groups
---------------------------------
.. doxygenvariable:: aare::remap::config::jungfrau::StrxP25
.. doxygenvariable:: aare::remap::config::jungfrau::StrxP15
.. doxygenvariable:: aare::remap::config::jungfrau::StrxP18
.. doxygenvariable:: aare::remap::config::jungfrau::StrxP37
.. _predefined_sensor_placements:
Predefined sensor placements on Junfrau modules
------------------------------------------------
The Photon Detector Group produces jungfrau modules with a 2x2 cm iLGAD/TEW sensors placed on the second chip (Chip1) and the seventh chip (Chip6) of the module.
The larger 4x4cm iLGAD sensors are typically placed on the module's quad (Chip1+Chip2+Chip5+Chip6).
.. doxygenvariable:: aare::remap::config::jungfrau::Chip1
.. doxygenvariable:: aare::remap::config::jungfrau::Chip6
.. doxygenvariable:: aare::remap::config::jungfrau::Quad
2x2 cm iLGAD sensor:
---------------------
The 2x2 cm iLGAD sensor has a guardring height and width of 9 pixels each and spawns over 256x256 pixels.
.. doxygenvariable:: aare::remap::config::jungfrau::SingleChipMP_iLGAD_pix
The Photon Detector Group produces Jungfrau modules with 2x2 cm iLGAD sensors placed on the second chip (Chip1) ``Chip1`` and the seventh chip (Chip6) ``Chip6`` of the module.
See :ref:`predefined_sensor_placements` for more information.
The sensor is partitioned into three strixel groups ``StrxP25``, ``StrxP15`` and ``StrxP18``. See :ref:`predefined_strixel_groups` for more information.
Strixel group ``StrxP25`` covers roughly the top 25 % of the sensor's pixel area. Strixel Group ``StrxP15`` covers roughly the next 25 % of the sensor's pixel area. Strixel group ``StrxP18`` covers roughly the bottom 50 % of the sensor's pixel area.
.. doxygenvariable:: aare::remap::config::jungfrau::SingleChipMP_iLGAD_P25
.. doxygenvariable:: aare::remap::config::jungfrau::SingleChipMP_iLGAD_P15
.. doxygenvariable:: aare::remap::config::jungfrau::SingleChipMP_iLGAD_P18
2x2 cm TEW sensor:
---------------------
The 2x2 cm TEW sensor has no guardring and spawns over 256x256 pixels.
.. doxygenvariable:: aare::remap::config::jungfrau::SingleChipMP_TEW_pix
The Photon Detector Group produces Jungfrau modules with 2x2 cm TEW sensors placed on the second chip (Chip1) ``Chip1`` and the seventh chip (Chip6) ``Chip6`` of the module.
See :ref:`predefined_sensor_placements` for more information.
The sensor is again partitioned into three pixel groups ``StrxP25``, ``StrxP15`` and ``StrxP18``. See :ref:`predefined_strixel_groups` for more information.
The partition is more or less the same as for the 2x2 cm iLGAD sensor.
.. doxygenvariable:: aare::remap::config::jungfrau::SingleChipMP_TEW_P25
.. doxygenvariable:: aare::remap::config::jungfrau::SingleChipMP_TEW_P15
.. doxygenvariable:: aare::remap::config::jungfrau::SingleChipMP_TEW_P18
4x4 cm iLGAD sensor:
---------------------
The 4x4 cm iLGAD sensor has a guardring height and width of 9 pixels each and spawns over 512x512 pixels.
.. doxygenvariable:: aare::remap::config::jungfrau::Quad_iLGAD_pix
The 4x4 cm iLGAD sensor is typically placed on the module's quad (Chip1+Chip2+Chip5+Chip6) ``Quad``. See :ref:`predefined_sensor_placements` for more information.
The sensor is partitioned into two strixel groups ``StrxP25``. See :ref:`predefined_strixel_groups` for more information. The bottom sensor half uses forward pixel to strixel routing and the top sensor half uses backward pixel to strixel routing.
.. doxygenvariable:: aare::remap::config::jungfrau::Quad_iLGAD_bottomhalf
.. doxygenvariable:: aare::remap::config::jungfrau::Quad_iLGAD_tophalf
@@ -0,0 +1,41 @@
Sensor configurations
=====================
Helper structs to define the sensor configuration, such as sensor pixel geometry, placement and rotation of the sensor on the module, the different strixel types on the sensor and its placement.
.. doxygenenum:: aare::remap::defs::Rotation
.. doxygenenum:: aare::remap::defs::ModuloOrdering
.. doxygenstruct:: aare::remap::defs::BondShift
:members:
.. doxygenstruct:: aare::remap::defs::Guardring
:members:
.. doxygenstruct:: aare::remap::defs::GroupRouting
:members:
.. doxygenstruct:: aare::remap::defs::SensorPixelGeometry
:members:
.. doxygenstruct:: aare::remap::defs::GroupStrixelGeometry
:members:
.. doxygenstruct:: aare::remap::defs::GroupConfig
:members:
.. doxygenstruct:: aare::remap::defs::SensorConfig
:members:
.. doxygenstruct:: aare::remap::defs::SensorModulePlacement
:members:
.. doxygenstruct:: aare::remap::defs::StrixelGroupToPixelMap
:members:
@@ -0,0 +1,15 @@
Strixel to Pixel Remapping
==============================
.. doxygenfunction:: aare::remap::algo::strixel_to_pixel_map
.. doxygenfunction:: aare::remap::algo::strixel_to_pixel_maps
.. doxygenfunction:: aare::remap::algo::ApplyRemap
+18
View File
@@ -0,0 +1,18 @@
Pixel to Strixel Remapping
==============================
..
maybe document what a strixel is in here how the remapping roughly works what types are predefined
.. toctree::
:maxdepth: 1
SensorConfiguration
StrixelPixelRemapAlgorithm
InclusiveROI
PredefinedSensorConfigs
PredefinedMaps
+2 -1
View File
@@ -36,7 +36,7 @@ AARE
.. toctree::
:caption: C++ API
:maxdepth: 1
:maxdepth: 2
algorithm
NDArray
@@ -57,6 +57,7 @@ AARE
RawSubFile
RawMasterFile
VarClusterFinder
StrixelPixelRemapping/index
+111 -59
View File
@@ -9,11 +9,16 @@
namespace aare {
/// @brief Inclusive Region of Interest (ROI) with inclusive bounds.
struct InclusiveROI {
/// @brief start of x-coordinate.
ssize_t xmin;
ssize_t xmax; // inclusive
/// @brief end of x-coordinate (inclusive).
ssize_t xmax;
/// @brief start of y-coordinate.
ssize_t ymin;
ssize_t ymax; // inclusive
/// @brief end of y-coordinate (inclusive).
ssize_t ymax;
constexpr ssize_t width() const noexcept { return xmax - xmin + 1; }
@@ -44,10 +49,20 @@ struct InclusiveROI {
// static InclusiveROI from_shape(ssize_t width, ssize_t height);
};
/**
* @brief transorms a half-open ROI to an inclusive ROI
* @param r half-open ROI
* @return inclusive ROI with same physical extent
*/
inline InclusiveROI toInclusiveROI(ROI const &r) {
return {r.xmin, r.xmax - 1, r.ymin, r.ymax - 1};
}
/** @brief
* @brief Transforms an inclusive ROI to a half-open ROI
* @param r inclusive ROI
* @return half-open ROI with same physical extent
*/
inline ROI toHalfopenROI(InclusiveROI const &r) {
return {r.xmin, r.xmax + 1, r.ymin, r.ymax + 1};
}
@@ -66,35 +81,51 @@ inline std::ostream &operator<<(std::ostream &os, InclusiveROI const &roi) {
namespace aare::inclusiveroi::geom {
// coordinate space transforms
/**
* @brief Coordinate space transforms for InclusiveROI.
* @param r InclusiveROI to be transformed
* @param dx translation in x direction
* @param dy translation in y direction
* @return InclusiveROI translated by (dx, dy)
*/
static inline InclusiveROI translate(InclusiveROI r, ssize_t dx, ssize_t dy) {
return {r.xmin + dx, r.xmax + dx, r.ymin + dy, r.ymax + dy};
}
/**
* @brief Convert an InclusiveROI to a local coordinate system with origin at
* (0,0).
* @param roi InclusiveROI to be converted
* @return InclusiveROI in local coordinates
*/
static inline InclusiveROI to_local(InclusiveROI const &roi) {
return {0, roi.xmax - roi.xmin, 0, roi.ymax - roi.ymin};
}
// Mirror an ROI on a given y-axis (vertical axis), thereby reflecting its
// x-coordinates horizontally
//
// The ROI is translated to the horizontally mirrored position while
// preserving its size.
//
// Example:
//
// yaxis_coord yaxis_coord
// -----------|----------- -----------|-----------
// | | r.xmax | | x0p | x1p |
// | ******|******** | | ********|****** |
// | * | roi * | -> | *mirrored roi * |
// | * | * | | * | * |
// | ******|******** | | ********|****** |
// | | | | | |
// -----------|----------- -----------|-----------
//
// @param r The ROI to be mirrored
// @param yaxis_coord The y-axis coordinate (in x) expressed in pixel
// coordinates
/**
* @brief Mirror an ROI on a given y-axis (vertical axis), thereby reflecting
* its x-coordinates horizontally
*
* The ROI is translated to the horizontally mirrored position while
* preserving its size
*
* Example:
* \verbatim
*
* yaxis_coord yaxis_coord
* -----------|----------- -----------|-----------
* | | r.xmax | | x0p | x1p |
* | ******|******** | | ********|****** |
* | * | roi * | -> | *mirrored roi * |
* | * | * | | * | * |
* | ******|******** | | ********|****** |
* | | | | | |
* -----------|----------- -----------|-----------
*\endverbatim
* @param r The ROI to be mirrored
* @param yaxis_coord The y-axis coordinate (in x) expressed in pixel
* coordinates
*/
static inline InclusiveROI mirror_on_y(InclusiveROI r, ssize_t yaxis_coord) {
// int x0p = (width - 1) - r.xmax;
// int x1p = (width - 1) - r.xmin;
@@ -103,15 +134,17 @@ static inline InclusiveROI mirror_on_y(InclusiveROI r, ssize_t yaxis_coord) {
return {x0p, x1p, r.ymin, r.ymax};
}
// Mirror an ROI on a given x-axis (horizontal axis), thereby reflecting its
// y-coordinates vertically
//
// The ROI is translated to the vertically mirrored position while
// preserving its size.
// @param r The ROI to be mirrored
// @param xaxis_coord The x-axis coordinate (in y) expressed in pixel
// coordinates
/**
* @brief Mirror an ROI on a given x-axis (horizontal axis), thereby reflecting
* its y-coordinates vertically
*
* The ROI is translated to the vertically mirrored position while
* preserving its size
*
* @param r The ROI to be mirrored
* @param xaxis_coord The x-axis coordinate (in y) expressed in pixel
* coordinates
*/
static inline InclusiveROI mirror_on_x(InclusiveROI r, ssize_t xaxis_coord) {
// int y0p = (height - 1) - r.ymax;
// int y1p = (height - 1) - r.ymin;
@@ -120,16 +153,29 @@ static inline InclusiveROI mirror_on_x(InclusiveROI r, ssize_t xaxis_coord) {
return {r.xmin, r.xmax, y0p, y1p};
}
// Mirror both x- and y-coordinates.
//
// This is equivalent to a 180° rotation about the axes intersection.
/**
* @brief Mirror both x- and y-coordinates.
*
* This is equivalent to a 180° rotation about the axes intersection.
* @param r The ROI to be mirrored
* @param xaxis_coord The x-axis coordinate (in y) expressed in pixel
* coordinates
* @param yaxis_coord The y-axis coordinate (in x) expressed in pixel
* coordinates
*/
static inline InclusiveROI mirrorXY(InclusiveROI r, ssize_t xaxis_coord,
ssize_t yaxis_coord) {
// return {mirrorX(mirrorY(r, height), width)};
return {mirror_on_y(mirror_on_x(r, xaxis_coord), yaxis_coord)};
}
// intersection
/**
* @brief Compute the intersection of two InclusiveROIs.
* @param a First InclusiveROI
* @param b Second InclusiveROI
* @return InclusiveROI representing the intersection of a and b or empty ROI if
* they do not intersect
*/
static inline InclusiveROI intersect(InclusiveROI const &a,
InclusiveROI const &b) {
InclusiveROI r;
@@ -139,14 +185,19 @@ static inline InclusiveROI intersect(InclusiveROI const &a,
r.ymax = std::min(a.ymax, b.ymax);
if (r.xmin > r.xmax || r.ymin > r.ymax) {
// std::cout << "WARNING: ROIs do not intersect!" << std::endl;
LOG(TLogLevel::logWARNING) << "ROIs do not intersect!" << std::endl;
return InclusiveROI::emptyROI(); // empty
}
return r;
}
// union
/**
* @brief Compute the union of two InclusiveROIs.
* @param a First InclusiveROI
* @param b Second InclusiveROI
* @return InclusiveROI representing the union of a and b if they are contiguous
* @throws std::runtime_error if the ROIs cannot be united contiguously
*/
static inline InclusiveROI unite(InclusiveROI const &a, InclusiveROI const &b) {
// Horizontal union: same y-range
if (a.ymin == b.ymin && a.ymax == b.ymax) {
@@ -169,26 +220,27 @@ static inline InclusiveROI unite(InclusiveROI const &a, InclusiveROI const &b) {
throw std::runtime_error("ROIs cannot be united contiguously");
}
// Rebase an ROI into the coordinate system of another ROI.
//
// The returned ROI has the same physical extent, but is expressed relative
// to roi_base instead of the original coordinate system.
//
// In other words, roi_base.xmin/ymin become the new origin (0,0).
//
// Example:
//
// Global coordinates:
//
// roi_base = [100..199] x [50..149]
// roi_input = [120..139] x [70..89]
//
// After rebasing:
//
// roi_input = [20..39] x [20..39]
//
// This is equivalent to translating roi_input by
// (-roi_base.xmin, -roi_base.ymin).
/**
* @brief Rebase an ROI into the coordinate system of another ROI.
* @param roi_input The ROI to be rebased
* @param roi_base The base ROI defining the new coordinate system
* @return InclusiveROI expressed in the coordinate system of roi_base
*
* The returned ROI has the same physical extent, but is expressed relative
* to roi_base instead of the original coordinate system.
*
* In other words, roi_base.xmin/ymin become the new origin (0,0).
* Example:
*
* Global coordinates:
*
* roi_base = [100..199] x [50..149] \n
* roi_input = [120..139] x [70..89] \n
*
* After rebasing:
*
* roi_input = [20..39] x [20..39] \n
*/
static inline InclusiveROI rebaseROI(InclusiveROI const &roi_input,
InclusiveROI const &roi_base) {
return translate(roi_input, -roi_base.xmin, -roi_base.ymin);
+38 -4
View File
@@ -4,11 +4,45 @@
namespace aare::remap::algo {
defs::StrixelGroupToPixelMap strixel_to_pixel_map(
defs::GroupConfig const &, defs::SensorPixelGeometry const &,
defs::SensorModulePlacement const &, InclusiveROI const &user_roi,
defs::BondShift bond_shift = {0, 0});
/**
* @brief Build the strixel-to-pixel order map for one strixel group.
* The strixel mapping is determined by the group's multiplicity and
* modulo ordering. A reversed modulo ordering reverses the ordering
* within each multiplicity group; it does not reverse the complete
* strixel column ordering.
*
* @param group_config Configuration of the strixel group to be mapped.
* @param pixel Sensor pixel geometry to which the group
* is connected.
* @param placement Sensor placement and orientation on the module.
* @param roi_user User-specified ROI in the module's native coordinate system.
* @param bond_shift Physical bonding shift in x and y directions.
* @return A StrixelGroupToPixelMap describing the mapping from strixel
* coordinates to pixel indices in the user-provided ROI.
* - map(strixel_row,strixel_col) = pixel_index_in_user_roi
* - Invalid or unmapped strixel positions are initialized to -1.
* @throws std::logic_error For negative or zero strixel multiplicity.
* @throws std::logic_error If the group ROI width is not divisible by
* the strixel multiplicity.
*/
defs::StrixelGroupToPixelMap
strixel_to_pixel_map(defs::GroupConfig const &group_config,
defs::SensorPixelGeometry const &pixel,
defs::SensorModulePlacement const &placement,
InclusiveROI const &user_roi,
defs::BondShift bond_shift = {0, 0});
/**
* @brief Build the strixel-to-pixel order maps for all strixel groups in a
* sensor.
* @param sensor_config Configuration of the sensor, including all
* configurations of the strixel groups.
* @param placement Sensor placement and orientation on the module.
* @param roi_user User-specified ROI in the module's native coordinate system.
* @param bond_shift Bonding shift in x and y directions.
* @return A vector of StrixelGroupToPixelMap containing the mappings for all
* strixel groups.
*/
std::vector<defs::StrixelGroupToPixelMap> strixel_to_pixel_maps(
defs::SensorConfig const &, defs::SensorModulePlacement const &,
InclusiveROI const &user_roi, defs::BondShift bond_shift = {0, 0});
+39 -5
View File
@@ -7,25 +7,44 @@ namespace aare::remap::config::jungfrau {
/************************************
* Default strixel geometries
************************************/
/// @brief Strixel geometry for 25 µm pitch strixels on iLGAD sensors
/// (multiplicity = 3)
inline constexpr defs::GroupStrixelGeometry StrxP25{3, // .multiplicity = 3,
25.0}; //.pitch_um = 25.0};
/// @brief Strixel geometry for 15 µm pitch strixels on iLGAD sensors
/// (multiplicity = 5)
inline constexpr defs::GroupStrixelGeometry StrxP15{5, //.multiplicity = 5,
15.0}; //.pitch_um = 15.0};
/// @brief Strixel geometry for 18.75 µm pitch strixels on iLGAD sensors
/// (multiplicity = 4)
inline constexpr defs::GroupStrixelGeometry StrxP18{
4, //.multiplicity = 4,
18.75}; //.pitch_um = 18.75};
4, //.multiplicity = 4,
18.75}; //.pitch_um = 18.75};
/// @brief Strixel geometry for 37.5 µm pitch strixels on iLGAD sensors
/// (multiplicity = 2)
inline constexpr defs::GroupStrixelGeometry StrxP37{2, //.multiplicity = 2,
37.5}; //.pitch_um = 37.5};
/************************************
* Default sensor placements
************************************/
/// @brief Placement of the 2x2cm iLGAD sensor on the second chip (Chip1) of the
/// Jungfrau module, with no rotation applied.
inline constexpr defs::SensorModulePlacement Chip1{
{256, 511, 0, 255}, //.placement_on_module{256, 511, 0, 255},
defs::Rotation::Identity}; //.rotation = defs::Rotation::Identity};
/// @brief Placement of the 2x2cm iLGAD sensor on the seventh chip (Chip6) of
/// the Jungfrau module, with a 180-degree rotation applied.
inline constexpr defs::SensorModulePlacement Chip6{
{512, 767, 256, 511}, //.placement_on_module{512, 767, 256, 511},
defs::Rotation::Rotate180}; //.rotation = defs::Rotation::Rotate180};
/// @brief Placement of the 4x4cm iLGAD sensor on the quad
/// (Chip1+Chip2+Chip5+Chip6) of the Jungfrau module, with no rotation applied.
inline constexpr defs::SensorModulePlacement Quad{
{256, 767, 0, 511}, //.placement_on_module{256, 767, 0, 511},
defs::Rotation::Identity}; //.rotation = defs::Rotation::Identity};
@@ -33,10 +52,13 @@ inline constexpr defs::SensorModulePlacement Quad{
/************************************
* Single chip, multi-pitch, iLGAD
************************************/
/// @brief Pixel geometry of the 2x2 cm iLGAd sensor
inline constexpr defs::SensorPixelGeometry SingleChipMP_iLGAD_pix{
256, 256, {9, 9}};
// .num_pix_x = 256, .num_pix_y = 256, .guardring = {.x = 9, .y = 9}};
/// @brief Strixel group of 25 µm pitch strixels on the 2x2 cm iLGAD sensor
inline constexpr defs::GroupConfig SingleChipMP_iLGAD_P25{
StrxP25, //.strixel = StrxP25,
{defs::ModuloOrdering::Forward},
@@ -50,6 +72,7 @@ inline constexpr defs::GroupConfig SingleChipMP_iLGAD_P25{
* Number of strixel rows: 165
********************************/
/// @brief Strixel group of 15 µm pitch strixels on the 2x2 cm iLGAD sensor
inline constexpr defs::GroupConfig SingleChipMP_iLGAD_P15{
StrxP15, // .strixel
{defs::ModuloOrdering::Forward},
@@ -63,6 +86,7 @@ inline constexpr defs::GroupConfig SingleChipMP_iLGAD_P15{
* Number of strixel rows: 320
********************************/
/// @brief Strixel group of 18.75 µm pitch strixels on the 2x2 cm iLGAD sensor
inline constexpr defs::GroupConfig SingleChipMP_iLGAD_P18{
StrxP18, // .strixel =
{defs::ModuloOrdering::Forward},
@@ -77,7 +101,7 @@ inline constexpr defs::GroupConfig SingleChipMP_iLGAD_P18{
* Number of strixel rows: 476
********************************/
// Complete SensorConfig with all groups
/// @brief Sensor configuration of the 2x2 cm iLGAD sensor
inline const defs::SensorConfig SingleChipMP_iLGAD{
// NOTE: Vector cannot be constexpr
SingleChipMP_iLGAD_pix, //.pixel =
@@ -87,10 +111,12 @@ inline const defs::SensorConfig SingleChipMP_iLGAD{
/************************************
* Single chip, multi-pitch, Thin Entrance Window (TEW)
************************************/
/// @brief Pixel geometry of the 2x2 cm TEW sensors with no guard ring.
inline constexpr defs::SensorPixelGeometry SingleChipMP_TEW_pix{
256, 256, {0, 0}};
// .num_pix_x = 256, .num_pix_y = 256, .guardring = {.x = 0, .y = 0}};
/// @brief Strixel group of 25 µm pitch strixels on the 2x2 cm TEW sensor
inline constexpr defs::GroupConfig SingleChipMP_TEW_P25{
StrxP25, //.strixel =
{defs::ModuloOrdering::Forward},
@@ -104,6 +130,7 @@ inline constexpr defs::GroupConfig SingleChipMP_TEW_P25{
* Number of strixel rows: 192
********************************/
/// @brief Strixel group of 15 µm pitch strixels on the 2x2 cm TEW sensor
inline constexpr defs::GroupConfig SingleChipMP_TEW_P15{
StrxP15, //.strixel =
{defs::ModuloOrdering::Forward},
@@ -117,6 +144,7 @@ inline constexpr defs::GroupConfig SingleChipMP_TEW_P15{
* Number of strixel rows: 320
********************************/
/// @brief Strixel group of 18.75 µm pitch strixels on the 2x2 cm TEW sensor
inline constexpr defs::GroupConfig SingleChipMP_TEW_P18{
StrxP18, //.strixel =
{defs::ModuloOrdering::Forward},
@@ -131,7 +159,7 @@ inline constexpr defs::GroupConfig SingleChipMP_TEW_P18{
* Number of strixel rows: 512
********************************/
// Complete SensorConfig with all groups
/// @brief Sensor configuration of the 2x2 cm TEW sensor
inline const defs::SensorConfig SingleChipMP_TEW{
// NOTE: Vector cannot be constexpr
SingleChipMP_TEW_pix, //.pixel =
@@ -141,11 +169,15 @@ inline const defs::SensorConfig SingleChipMP_TEW{
/************************************
* Quad, 25 um, iLGAD
************************************/
/// @brief Pixel geometry of the 4x4 cm iLGAd sensor
inline constexpr defs::SensorPixelGeometry Quad_iLGAD_pix{512, 512, {9, 9}};
// .num_pix_x = 512, .num_pix_y = 512, .guardring = {.x = 9, .y = 9}};
inline constexpr size_t Quad_iLGAD_strixel_gap_rows = 12;
/// @brief Strixel group of 25 µm pitch strixels located on the bottom half of
/// 4x4 cm iLGAD sensor
inline constexpr defs::GroupConfig Quad_iLGAD_bottomhalf{
StrxP25, //.strixel
{defs::ModuloOrdering::Forward},
@@ -155,6 +187,8 @@ inline constexpr defs::GroupConfig Quad_iLGAD_bottomhalf{
Quad_iLGAD_pix.guardring.y, // 9
(Quad_iLGAD_pix.num_pix_y / 2) - 2}}; // 254
/// @brief Strixel group of 25 µm pitch strixels located on the top half of 4x4
/// cm iLGAD sensor
inline constexpr defs::GroupConfig Quad_iLGAD_tophalf{
StrxP25, //.strixel =
{defs::ModuloOrdering::Reverse}, //.routing =
@@ -164,7 +198,7 @@ inline constexpr defs::GroupConfig Quad_iLGAD_tophalf{
Quad_iLGAD_pix.num_pix_y / 2 + 1, // 257
Quad_iLGAD_pix.num_pix_y - Quad_iLGAD_pix.guardring.y - 1}}; // 502
// Complete SensorConfig with all groups
/// @brief Sensor configuration of the 4x4 cm iLGAD sensor
inline const defs::SensorConfig Quad_iLGAD{
// NOTE: Vector cannot be constexpr
Quad_iLGAD_pix, //.pixel =
+32 -28
View File
@@ -43,14 +43,20 @@ enum class Rotation : int { Identity = 0, Rotate180 = 1 };
*/
enum class ModuloOrdering { Forward, Reverse };
/// @brief Describes the physical guardring around a sensor to protect the ASIC
/// from high fluxes.
struct Guardring {
int x;
int y;
/// @brief ring width.
int x{};
/// @brief ring height.
int y{};
};
struct BondShift {
int x = 0;
int y = 0;
/// @brief Bonding shift in x direction
int x{};
/// @brief Bonding shift in y direction
int y{};
};
/**
@@ -60,20 +66,21 @@ struct BondShift {
* the coordinate system in which remapping is performed.
*/
struct SensorPixelGeometry {
/// @brief Number of pixels in x direction (columns)
int num_pix_x;
/// @brief Number of pixels in y direction (rows)
int num_pix_y;
/// @brief guardring around sensor
Guardring guardring;
};
/**
* @brief Describes the strixel geometry of a single remapping group.
*
* Pixel rows are multiplied by `multiplicity`, resulting
* in an effective strixel pitch of `pitch_um`, and pixel columns are divided by
* `multiplicity`.
*/
struct GroupStrixelGeometry {
/// @brief Number of pixels a strixel covers.
int multiplicity;
/// @brief Effective strixel pitch [µm]
double pitch_um;
};
@@ -90,43 +97,39 @@ struct GroupRouting {
/**
* @brief Configuration of a single contiguous strixel group on a sensor.
*
* A group is characterized by
* - its strixel geometry,
* - its routing pattern, and
* - its location within the native sensor pixel grid.
*/
struct GroupConfig {
/// @brief strixel geometry
GroupStrixelGeometry strixel;
/// @brief pixel-to-strixel routing pattern
GroupRouting routing;
/// Group bounds in native sensor pixel coordinates.
/// @brief location on sensor (given in sensor's native coordinates)
InclusiveROI placement_on_sensor;
};
/**
* @brief Complete description of a sensor.
*
* A sensor consists of a single native pixel geometry together with one or
* more remapping groups that partition the sensor into regions with different
* strixel geometries and/or routing.
*/
struct SensorConfig {
/// @brief pixel geometry of the sensor
SensorPixelGeometry pixel;
/// @brief strixel group configurations partitions the sensor into regions
/// with different strixel geometries and/or routing
std::vector<GroupConfig> group_configs;
};
/**
* @brief Describes the placement of a sensor within the module.
*
* Specifies where the sensor is located in module coordinates and how it is
* physically oriented with respect to the module reference frame.
*/
struct SensorModulePlacement {
/// Sensor bounds in module coordinates.
/// @brief Sensor bounds in module coordinates.
InclusiveROI placement_on_module;
/// Physical orientation of the mounted sensor.
/// @brief Physical orientation of the mounted sensor with respect to the
/// module reference frame.
Rotation rotation;
};
@@ -135,7 +138,8 @@ struct SensorModulePlacement {
*
* The order map defines a local strixel-grid coordinate system. For each
* map position (row, col), map(row, col) contains the flattened pixel index
* of the corresponding source pixel in the user-provided input ROI.
* of the corresponding source pixel in the user-provided input ROI for strixel
* defined at (row, col).
*
* For a valid entry:
*
@@ -144,11 +148,11 @@ struct SensorModulePlacement {
* where (dx, dy) is the pixel position in the coordinate system of the
* original user-provided ROI.
*
* NOTE: The map coordinates (row, col) are local to this strixel group and are
* geometrically associated with effective_roi. The stored pixel index,
* NOTE: The map coordinates (row, col) are local to this strixel group and
* are geometrically associated with effective_roi. The stored pixel index,
* however, is flattened with respect to the original user-provided ROI,
* not effective_roi. (I.e.: The map provides a local strixel grid mapped to the
* correct corresponding pixel indices in the original user grid, and
* not effective_roi. (I.e.: The map provides a local strixel grid mapped to
* the correct corresponding pixel indices in the original user grid, and
* effective_roi is the ROI the algorithm used for remapping.)
*
* An entry of -1 indicates that the corresponding strixel position has no
+3 -50
View File
@@ -13,10 +13,9 @@ namespace aare::remap::algo {
* The order is intentional because bond shifts are defined in the
* sensor's native coordinate system.
*/
inline InclusiveROI
update_pixel_group_placement(InclusiveROI roi,
defs::SensorPixelGeometry const &pixel,
defs::BondShift bond_shift, defs::Rotation rot) {
InclusiveROI inline update_pixel_group_placement(
InclusiveROI roi, defs::SensorPixelGeometry const &pixel,
defs::BondShift bond_shift, defs::Rotation rot) {
// If there is a bond shift, translate the roi
if (bond_shift.x != 0 || bond_shift.y != 0)
roi = aare::inclusiveroi::geom::translate(roi, bond_shift.x,
@@ -30,52 +29,6 @@ update_pixel_group_placement(InclusiveROI roi,
return roi;
}
/**
* @brief Build the strixel-to-pixel order map for one strixel group.
*
* The returned map describes how pixels from the user-provided ROI (normally
* rx_roi from input file) are rearranged into the local strixel coordinate
* system of the group.
*
* Coordinate systems:
*
* - @p roi_user is expressed in full-module coordinates.
* - @p group_config.placement_on_sensor is expressed in the sensor-local
* coordinate system before applying the bond shift and sensor rotation.
* - The group ROI is transformed by applying the bond shift first and the
* sensor rotation second.
* - The returned @c effective_roi is the intersection of the user ROI
* (rebased into sensor-local coordinates) and the transformed group ROI.
* - The returned @c map uses its own local strixel coordinate system.
* - Each valid map entry contains a flattened index into the ORIGINAL
* user ROI, not into @c effective_roi.
*
* Thus:
*
* map(strixel_row, strixel_col) = pixel_index_in_user_roi
*
* Invalid or unmapped strixel positions are initialized to -1.
*
* The strixel mapping is determined by the group's multiplicity and
* modulo ordering. A reversed modulo ordering reverses the ordering
* within each multiplicity group; it does not reverse the complete
* strixel column ordering.
*
* @param group_config Configuration of the strixel group to be mapped.
* @param pixel Native pixel geometry of the sensor to which the group
* is connected. Used when transforming the group ROI.
* @param placement Location and orientation of the sensor on the module.
* @param roi_user User-requested ROI in full-module coordinates.
* @param bond_shift Physical bonding shift, applied before the rotation.
*
* @return A @c StrixelGroupToPixelMap containing:
* - the generated strixel-to-user-pixel order map;
* - the effective pixel ROI covered by the map.
*
* @throws std::logic_error For negative or zero strixel multiplicity.
* @throws std::logic_error If the group ROI width is not divisible by
* the strixel multiplicity.
*/
defs::StrixelGroupToPixelMap
strixel_to_pixel_map(defs::GroupConfig const &group_config,
defs::SensorPixelGeometry const &pixel,