bb9f5c715f
Build Packages / build:rpm (ubuntu2204_nocuda) (push) Successful in 9m55s
Build Packages / build:rpm (rocky8_nocuda) (push) Successful in 10m28s
Build Packages / build:rpm (ubuntu2404_nocuda) (push) Successful in 8m56s
Build Packages / build:rpm (rocky9_nocuda) (push) Successful in 11m47s
Build Packages / build:rpm (rocky8_sls9) (push) Successful in 13m7s
Build Packages / build:rpm (ubuntu2204) (push) Successful in 12m31s
Build Packages / build:rpm (rocky8) (push) Successful in 12m59s
Build Packages / build:rpm (rocky9) (push) Successful in 14m5s
Build Packages / build:rpm (rocky9_sls9) (push) Successful in 15m30s
Build Packages / Generate python client (push) Successful in 1m18s
Build Packages / Build documentation (push) Successful in 1m3s
Build Packages / Create release (push) Has been skipped
Build Packages / build:rpm (ubuntu2404) (push) Successful in 10m8s
Build Packages / XDS test (durin plugin) (push) Successful in 9m16s
Build Packages / XDS test (neggia plugin) (push) Successful in 7m59s
Build Packages / XDS test (JFJoch plugin) (push) Successful in 9m12s
Build Packages / DIALS test (push) Successful in 11m44s
Build Packages / Unit tests (push) Successful in 1h23m8s
This is an UNSTABLE release. The release has significant modifications and bug fixes, if things go wrong, it is better to revert to 1.0.0-rc.132. * Multiple small bug fixes scattered across the whole code base. (detected with GPT-5.4) * jfjoch_viewer: Improve image render performance Reviewed-on: #44 Co-authored-by: Filip Leonarski <filip.leonarski@psi.ch> Co-committed-by: Filip Leonarski <filip.leonarski@psi.ch>
127 lines
4.9 KiB
C++
127 lines
4.9 KiB
C++
// SPDX-FileCopyrightText: 2024 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
|
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
|
|
#include "ModuleSummation.h"
|
|
#include "JFJochException.h"
|
|
|
|
ModuleSummation::ModuleSummation(bool in_pixel_signed, uint32_t in_fpga_depth_bytes) {
|
|
pixel_signed = in_pixel_signed;
|
|
first = true;
|
|
is_empty = false;
|
|
output_depth_bytes = 4;
|
|
fpga_depth_bytes = in_fpga_depth_bytes;
|
|
|
|
if ((fpga_depth_bytes != 4)
|
|
&& (fpga_depth_bytes != 2)
|
|
&& (fpga_depth_bytes != 1))
|
|
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "FPGA byte depth can be only 1, 2 or 4");
|
|
|
|
output = std::make_unique<DeviceOutput>();
|
|
memset(output.get(), 0, sizeof(DeviceOutput));
|
|
}
|
|
|
|
ModuleSummation::ModuleSummation(const DiffractionExperiment &experiment) : ModuleSummation(
|
|
experiment.IsPixelSigned(), experiment.GetByteDepthFPGA()) {
|
|
if (!experiment.IsCPUSummation())
|
|
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
|
|
"CPU summation not turned on");
|
|
if (experiment.GetByteDepthImage() != 4)
|
|
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
|
|
"CPU summation works only for 32-bit output");
|
|
}
|
|
|
|
const DeviceOutput &ModuleSummation::GetOutput() const {
|
|
return *output;
|
|
}
|
|
|
|
DeviceOutput &ModuleSummation::GetOutput() {
|
|
return *output;
|
|
}
|
|
|
|
template<class Tdst, class Tsrc>
|
|
void Add(DeviceOutput &output, const DeviceOutput &input) {
|
|
auto in_pixel = reinterpret_cast<const Tsrc *>(input.pixels);
|
|
auto out_pixel = reinterpret_cast<Tdst *>(output.pixels);
|
|
|
|
Tdst err_val_dst = std::is_signed_v<Tdst> ? std::numeric_limits<Tdst>::min() : std::numeric_limits<Tdst>::max();
|
|
Tsrc err_val_src = std::is_signed_v<Tsrc> ? std::numeric_limits<Tsrc>::min() : std::numeric_limits<Tsrc>::max();
|
|
|
|
for (int i = 0; i < RAW_MODULE_SIZE; i++) {
|
|
if ((in_pixel[i] == err_val_src) || (out_pixel[i] == err_val_dst))
|
|
out_pixel[i] = err_val_dst;
|
|
else if ((in_pixel[i] == std::numeric_limits<Tsrc>::max())
|
|
|| (out_pixel[i] == std::numeric_limits<Tdst>::max())
|
|
|| (static_cast<int64_t>(out_pixel[i]) + static_cast<int64_t>(in_pixel[i]) >= std::numeric_limits<
|
|
Tdst>::max()))
|
|
out_pixel[i] = std::numeric_limits<Tdst>::max();
|
|
else
|
|
out_pixel[i] = out_pixel[i] + in_pixel[i];
|
|
}
|
|
}
|
|
|
|
void ModuleSummation::AddFPGAOutput(const DeviceOutput &input, const std::optional<uint32_t> &in_fpga_depth_bytes) {
|
|
std::unique_lock ul(module_summation_mutex);
|
|
|
|
if (first) {
|
|
output->module_statistics = input.module_statistics;
|
|
first = false;
|
|
} else {
|
|
output->module_statistics.err_pixels += input.module_statistics.err_pixels;
|
|
output->module_statistics.saturated_pixels += input.module_statistics.saturated_pixels;
|
|
output->module_statistics.packet_count += input.module_statistics.packet_count;
|
|
}
|
|
|
|
// The only function not handled is spot finding
|
|
switch (in_fpga_depth_bytes.value_or(fpga_depth_bytes)) {
|
|
case 2:
|
|
if (pixel_signed)
|
|
Add<int32_t, int16_t>(*output, input);
|
|
else
|
|
Add<uint32_t, uint16_t>(*output, input);
|
|
break;
|
|
case 4:
|
|
if (pixel_signed)
|
|
Add<int32_t, int32_t>(*output, input);
|
|
else
|
|
Add<uint32_t, uint32_t>(*output, input);
|
|
break;
|
|
case 1:
|
|
if (pixel_signed)
|
|
Add<int32_t, int8_t>(*output, input);
|
|
else
|
|
Add<uint32_t, uint8_t>(*output, input);
|
|
break;
|
|
default:
|
|
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
|
|
"Unknown bit depth");
|
|
}
|
|
|
|
for (int i = 0; i < FPGA_INTEGRATION_BIN_COUNT; i++) {
|
|
output->integration_result[i].count += input.integration_result[i].count;
|
|
output->integration_result[i].sum += input.integration_result[i].sum;
|
|
}
|
|
|
|
for (int i = 0; i < ADU_HISTO_BIN_COUNT; i++)
|
|
output->adu_histogram[i] += input.adu_histogram[i];
|
|
|
|
for (int i = 0; i < FPGA_ROI_COUNT; i++) {
|
|
output->roi_counts[i].sum += input.roi_counts[i].sum;
|
|
output->roi_counts[i].sum2 += input.roi_counts[i].sum2;
|
|
output->roi_counts[i].good_pixels += input.roi_counts[i].good_pixels;
|
|
output->roi_counts[i].sum_x_weighted += input.roi_counts[i].sum_x_weighted;
|
|
output->roi_counts[i].sum_y_weighted += input.roi_counts[i].sum_y_weighted;
|
|
if (output->roi_counts[i].max_value < input.roi_counts[i].max_value)
|
|
output->roi_counts[i].max_value = input.roi_counts[i].max_value;
|
|
}
|
|
}
|
|
|
|
void ModuleSummation::AddEmptyOutput() {
|
|
std::unique_lock ul(module_summation_mutex);
|
|
is_empty = true;
|
|
}
|
|
|
|
bool ModuleSummation::empty() const {
|
|
std::unique_lock ul(module_summation_mutex);
|
|
return is_empty;
|
|
}
|