Skip to content

Dev/strixels/remap_simple#286

Draft
vhinger182 wants to merge 48 commits into
mainfrom
dev/strixels/remap_simple
Draft

Dev/strixels/remap_simple#286
vhinger182 wants to merge 48 commits into
mainfrom
dev/strixels/remap_simple

Conversation

@vhinger182

Copy link
Copy Markdown
Contributor

Refactor of PR #275, branching off dev/strixels/remap
The structure has been simplified.

Basic structure:

  • defs -> pure data structures (geometry, config structs, placement, remapping result)
  • config -> hardcoded sensor definitions (e.g. Jungfrau iLGAD multipitch, 25um pitch group, ...)
  • algo -> generic remapping algorithms
  • generate -> user-facing convenience functions (i.e. generate a map for Jungfrau iLGAD multipitch sensor 25um pitch group)

So far, only a few basic sensor configurations are implemented. But in principle, it should be straight forward to implement a new one by

  1. Adding geometry definitions in config
  2. Adding generate function

We could also discuss a further simplification making the sensor definitions types, i.e. instead of

auto map = jungfrau_ilgad_singlechip_25um_strixel_map(roi, sensor_placement);

we template on the sensor type

auto map = generate_maps<Jungfrau_iLGAD_MP25>(roi, sensor_placement);

Then adding a new sensor just requires a new type definition.

Comment thread include/aare/RemapConfig.hpp Outdated
inline constexpr defs::SensorGroupConfig SingleChipMP_iLGAD_P25{
.pixel = SingleChipMP_iLGAD_pix,
.strixel = StrxP25,
.placement_on_sensor = {SingleChipMP_iLGAD_pix.guardring.x + 1,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure does indexing always start at zero? e.g. guardring of 9 pixels then roi starts at pixel 9 for zero indexing? Maybe I misunderstand something.

(SingleChipMP_iLGAD_pix.num_pix_y / 4) * 2 - 1}};

inline constexpr defs::SensorGroupConfig SingleChipMP_iLGAD_P18{
.pixel = SingleChipMP_iLGAD_pix,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this pixel grid information should belong to struct SensorConfig?


/**************************************
* Legacy for reference, to be deleted
**************************************/

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes delete all of this

static inline std::string toString(defs::Rotation);
static inline std::string toString(defs::SensorPixelGeometry const &g);
static inline std::string toString(defs::SensorStrixelGeometry const &g);
static inline std::string toString(defs::SensorGroupConfig const &c);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are the conversions every used? Or only used for debugging? You could easily use , It doesnt hurt to keep it but I would move everything to to_string.hpp and maybe use lower case to_string to keep consistent with the rest of the code.

InclusiveROI const &user_roi, defs::BondShift bond_shift = {0, 0});

std::vector<defs::StrixelGroupToPixelMap> strixel_to_pixel_maps(
defs::SensorConfig const &, std::vector<defs::SensorPlacement> const &,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are there multiple sensorplacements? I thought SensorConfig is unique for one sensor and thus only one placement on the module?

std::vector<SensorGroupConfig> group_configs;
};

// Define location and orientation of a sensor on the module

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe SensorModulePlacement is more explicit?

output(row, col) = value;
// output(row, col) = static_cast<T>(input[flat_index]);
} else {
output(row, col) = static_cast<T>(0); // or nan?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would throw a runtime error?

* \param output Remapped array
*/
template <typename T>
void ApplyRemap(NDView<T, 2> const &input, NDArray<ssize_t, 2> const &order_map,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would pass a view instead of reference to NDArray

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe its better to directly return the remapped array than passing?

*
* \param input Original array
* \param order_map Rule for remapping
* \param output Remapped array

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could move this function to PixelMap.hpp

template <typename T>
void ApplyRemap(NDView<T, 2> const &input, NDArray<ssize_t, 2> const &order_map,
NDArray<T, 2> &output) {
for (size_t row = 0; row < order_map.shape(0); ++row) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

compiler warning: use ssize_t

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also for col

Comment thread src/RemapAlgorithm.cpp

// Is it better to pass defs::SensorGroupConfig const& and return a copy?
void apply_rotation_shift(defs::SensorGroupConfig &cfg,
defs::BondShift bond_shift, defs::Rotation rot) {

@AliceMazzoleni99 AliceMazzoleni99 Apr 9, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes everything should be const here

Comment thread src/RemapAlgorithm.cpp

// Define mod ordering (Normal or Inverse)
std::vector<int> mods(multiplicity);
for (int i = 0; i < multiplicity; i++)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe use std::iota

Comment thread src/RemapAlgorithm.cpp
// -- 1) Transform user roi (rx_roi) into sensor-local coordinates
InclusiveROI roi_user_local =
inclusiveroi::geom::alignROIs(roi_user, placement.placement_on_module);
std::cout << "Transformed user ROI: " << roi_user_local << std::endl;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove std::cout or add LOG(logDEBUG) <<

Comment thread src/RemapAlgorithm.cpp
std::cout << "Transformed user ROI: " << roi_user_local << std::endl;

// DEBUG
std::cout << "DEBUG: Group ROI before transformation (as in global config)"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also replace by LOG(logDEBUG)

// Possibly, this may need to be moved to a dedicated "remapping" class
struct StrixelGroupToPixelMap {
int multiplicity;
double pitch_um;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes I would remove these things. Is placement_on_sensor the same ans in SensorGroupConfig?

Comment thread src/RemapAlgorithm.cpp
std::vector<int> const &gaps) {

if (maps.size() != gaps.size()) {
throw std::logic_error("Gaps provided are inclompatible with "

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: incompatible

Comment thread src/RemapAlgorithm.cpp

auto [temp_rows, temp_cols] = maps[i].map.shape();
global_cols = std::max(global_cols, temp_cols);
global_rows = global_rows + temp_rows + gaps[i];

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure what gaps[i] should be due to placement on sensor?

Comment thread src/RemapAlgorithm.cpp
auto [rows, cols] = maps[i].map.shape();

// DEBUG
std::cout << "DEBUG: Row offset: i = " << i

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

again LOG(logDEBUG) <<

Comment thread src/RemapAlgorithm.cpp
global_rows = global_rows + temp_rows + gaps[i];
}

NDArray<ssize_t, 2> map({global_rows, global_cols}, -1);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

skip -1 in Applyremap?

@@ -0,0 +1,87 @@
#pragma once

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe better to remap the file to StrixelPixelMap.hpp

@AliceMazzoleni99 AliceMazzoleni99 Apr 9, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe its better to rename all files to StrixelPixelRemap... makes it more explicit what it is

};

inline std::vector<defs::StrixelGroupToPixelMap>
jungfrau_ilgad_singlechip_multipitch_strixel_maps(InclusiveROI rx_roi,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would make this independant of chip_id and have a constexpr SensorConfig jungfrau_ilgad{{config::jungfrau::SingleChipMP_iLGAD_P25,
config::jungfrau::SingleChipMP_iLGAD_P15,
config::jungfrau::SingleChipMP_iLGAD_P18}}

std::vector<defs::SensorPlacement> placements(configs.group_configs.size(),
placement);

placements[1].rotation = algo::flip(placement.rotation);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does flip do?


return algo::strixel_to_pixel_maps(configs, placements, rx_roi);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

functions definitly need to be commented. Maybe we only need to define one jungfrau pixel map with the combined maps? If someone wants the sensor group map one has still the freedom to calculate it.

@AliceMazzoleni99 AliceMazzoleni99 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a few minor comments. But it needs to be documented more precisely. Every function in particular the functions in RemapAlgorithm and RemapGenerate need to have a proper docstring e.g.
`
/** @brief short explanation

  • @param define all parameters
  • @return what does it return
  • /
    `
    and all the struct members should also have a /// @brief short member explanation
    Otherwise it looks very good.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants