// SPDX-FileCopyrightText: 2024 Filip Leonarski, Paul Scherrer Institute // SPDX-License-Identifier: GPL-3.0-only #ifndef JUNGFRAUJOCH_RAWTOCONVERTEDGEOMETRY_H #define JUNGFRAUJOCH_RAWTOCONVERTEDGEOMETRY_H #include #include "RawToConvertedGeometryCore.h" #include "Coord.h" #include "DiffractionExperiment.h" // Input coord is column + 1024 * (line + 512 * module) // Copies result over multipixel - can be used for example for mask calculation template void RawToConvertedGeometry(const DiffractionExperiment &experiment, Td *destination, const Ts *source) { for (size_t module_number = 0; module_number < experiment.GetModulesNum(); module_number++) TransferModule(destination + experiment.GetPixel0OfModuleConv(module_number), source + module_number * RAW_MODULE_SIZE, experiment.GetModuleSlowDirectionStep(module_number), experiment.GetModuleFastDirectionStep(module_number)); } inline std::pair RawToConvertedCoordinate(const DiffractionExperiment& experiment, uint32_t module_number, uint32_t pixel_within_module) { int64_t pixel0 = experiment.GetPixel0OfModuleConv(module_number); int64_t line = pixel_within_module / RAW_MODULE_COLS; int64_t col = pixel_within_module % RAW_MODULE_COLS; line += (line / 256) * 2; col += (col / 256) * 2; int64_t pixel = pixel0 + col * experiment.GetModuleFastDirectionStep(module_number) + line * experiment.GetModuleSlowDirectionStep(module_number); return {pixel % experiment.GetXPixelsNumConv() , pixel / experiment.GetXPixelsNumConv()}; } inline Coord RawToConvertedCoordinate(const DiffractionExperiment& experiment, uint32_t module_number, const Coord &c) { int64_t pixel0 = experiment.GetPixel0OfModuleConv(module_number); Coord pixel0_coord(pixel0 % experiment.GetXPixelsNumConv(), pixel0 / experiment.GetXPixelsNumConv(), 0); return pixel0_coord + experiment.GetModuleFastDirection(module_number) * (c.x + (static_cast(c.x) / 256) * 2) + experiment.GetModuleSlowDirection(module_number) * (c.y + (static_cast(c.y) / 256) * 2); } template void ConvertedToRawGeometry(const DiffractionExperiment &experiment, size_t module_number, T *destination, const T *source) { // Ensure that converted geometry is used, even if raw data mode is set const auto &geom = experiment.GetDetectorSetup().GetGeometry(); for (size_t line = 0; line < RAW_MODULE_LINES; line++) LineConvtToRaw(destination + RAW_MODULE_COLS * line, source + geom.GetPixel0(module_number, true) + geom.GetSlowDirectionStep(module_number) * (line + ((line > 255) ? 2 : 0)), experiment.GetModuleFastDirectionStep(module_number)); } template void ConvertedToRawGeometry(const DiffractionExperiment &experiment, T *destination, const T *source) { for (size_t module_number = 0; module_number < experiment.GetModulesNum(); module_number++) ConvertedToRawGeometry(experiment, module_number, destination + module_number * RAW_MODULE_SIZE, source); } // Input coord is column + 1024 * (line + 512 * module) template void RawToConvertedGeometryAdjustMultipixels(const DiffractionExperiment &experiment, Ts *destination, const Ts *source) { Ts min = experiment.GetUnderflow() + 1; if (min > 0) min = 0; Ts max = experiment.GetSaturationLimit() - 1; for (size_t module_number = 0; module_number < experiment.GetModulesNum(); module_number++) { TransferModuleAdjustMultipixels(destination, source + module_number * RAW_MODULE_SIZE, experiment.GetModuleSlowDirectionStep(module_number), min, max, experiment.GetModuleFastDirectionStep(module_number), experiment.GetPixel0OfModuleConv(module_number)); } } template inline void RawToEigerInput(T *dest, const T *source) { int half_lines_per_packet = HALF_LINES_PER_PACKET; int pixels_per_packet = half_lines_per_packet * RAW_MODULE_COLS / 2; int total_packets = 2 * (RAW_MODULE_LINES / half_lines_per_packet); // bottom left corner for (int packet = 0; packet < total_packets / 4; packet++) { for (int i = 0; i < pixels_per_packet; i++) { size_t line = packet * half_lines_per_packet + (half_lines_per_packet - 1 - i / 512); size_t col = i % (RAW_MODULE_COLS / 2); dest[(total_packets / 2 - 1 - (packet * 2 + 1)) * pixels_per_packet + i] = source[line * RAW_MODULE_COLS + col]; dest[(total_packets / 2 - 1 - (packet * 2)) * pixels_per_packet + i] = source[line * RAW_MODULE_COLS + col + RAW_MODULE_COLS / 2]; } } // top left corner for (int packet = 0; packet < total_packets / 4; packet++) { for (int i = 0; i < pixels_per_packet; i++) { size_t line = RAW_MODULE_LINES / 2 + packet * half_lines_per_packet + i / 512; size_t col = i % (RAW_MODULE_COLS / 2); dest[(total_packets / 2 + (packet * 2)) * pixels_per_packet + i] = source[line * RAW_MODULE_COLS + col]; dest[(total_packets / 2 + (packet * 2 + 1)) * pixels_per_packet + i] = source[line * RAW_MODULE_COLS + col + RAW_MODULE_COLS / 2]; } } } inline void RawToEigerInput32(uint32_t *dest, const uint32_t *source) { // bottom left corner for (int packet = 0; packet < 128; packet++) { for (int i = 0; i < 1024; i++) { size_t line = packet * 2 + (1 - i / 512); size_t col = i % 512; dest[(254 - (packet * 2)) * 1024 + i] = source[line * RAW_MODULE_COLS + col]; } } // bottom right corner for (int packet = 0; packet < 128; packet++) { for (int i = 0; i < 1024; i++) { size_t line = packet * 2 + (1 - i / 512); size_t col = 512 + i % 512; dest[(255 - (packet * 2)) * 1024 + i] = source[line * RAW_MODULE_COLS + col]; } } // top left corner for (int packet = 0; packet < 128; packet++) { for (int i = 0; i < 1024; i++) { size_t line = 256 + packet * 2 + i / 512; size_t col = i % 512; dest[(256 + (packet * 2)) * 1024 + i] = source[line * RAW_MODULE_COLS + col]; } } // top right corner for (int packet = 0; packet < 128; packet++) { for (int i = 0; i < 1024; i++) { size_t line = 256 + packet * 2 + i / 512; size_t col = 512 + i % 512; dest[(257 + (packet * 2)) * 1024 + i] = source[line * RAW_MODULE_COLS + col]; } } } #endif