// SPDX-FileCopyrightText: 2026 Filip Leonarski, Paul Scherrer Institute // SPDX-License-Identifier: GPL-3.0-only #pragma once #include #include #include #include #include "DetectorModules.h" // DetectorModules::ForEachPixel cut to the image rows [row0, row1), so that a dense map can be built a band // of rows per thread. Calls f(panel, index, px, py) for every pixel of those rows that is on a panel, in // index order: row by row, and within a row panel by panel from left to right. Pixels on no panel are not // visited. Empty table: every pixel of the rows, panel -1, plane == image. template void ForEachPixelInRows(const DetectorModules &modules, int64_t width, int64_t row0, int64_t row1, F &&f) { if (modules.empty()) { for (int64_t y = row0; y < row1; y++) for (int64_t x = 0; x < width; x++) f(int64_t(-1), static_cast(y * width + x), static_cast(x), static_cast(y)); return; } const auto &m = modules.Get(); std::vector on_row; for (int64_t y = row0; y < row1; y++) { on_row.clear(); for (size_t p = 0; p < m.size(); p++) if (y >= m[p].y0 && y < m[p].y0 + m[p].height) on_row.push_back(static_cast(p)); std::sort(on_row.begin(), on_row.end(), [&](int64_t a, int64_t b) { return m[a].x0 < m[b].x0; }); for (const int64_t p: on_row) for (int64_t x = m[p].x0; x < m[p].x0 + m[p].width; x++) { const auto [px, py] = m[p].ImageToPlane(static_cast(x), static_cast(y)); f(p, static_cast(y * width + x), px, py); } } }