Files
Jungfraujoch/common/RawToConvertedGeometry.h
2025-05-05 19:32:22 +02:00

153 lines
7.0 KiB
C++

// SPDX-FileCopyrightText: 2024 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
// SPDX-License-Identifier: GPL-3.0-only
#ifndef JUNGFRAUJOCH_RAWTOCONVERTEDGEOMETRY_H
#define JUNGFRAUJOCH_RAWTOCONVERTEDGEOMETRY_H
#include <cmath>
#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<class Td, class Ts>
void RawToConvertedGeometry(const DiffractionExperiment &experiment, Td *destination, const Ts *source) {
for (size_t module_number = 0; module_number < experiment.GetModulesNum(); module_number++)
TransferModule<Td, Ts>(destination + experiment.GetPixel0OfModuleConv(module_number),
source + module_number * RAW_MODULE_SIZE,
experiment.GetModuleSlowDirectionStep(module_number),
experiment.GetModuleFastDirectionStep(module_number));
}
inline std::pair<int64_t, int64_t> 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<int32_t>(c.x) / 256) * 2)
+ experiment.GetModuleSlowDirection(module_number) * (c.y + (static_cast<int32_t>(c.y) / 256) * 2);
}
template<class T>
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<T>(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<class T>
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<class Ts>
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<Ts, Ts>(destination,
source + module_number * RAW_MODULE_SIZE,
experiment.GetModuleSlowDirectionStep(module_number),
min, max,
experiment.GetModuleFastDirectionStep(module_number),
experiment.GetPixel0OfModuleConv(module_number));
}
}
template <int HALF_LINES_PER_PACKET = 4, class T>
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