PreviewImage: Calculate mask in parallel to speed up startup

This commit is contained in:
2026-05-01 14:34:00 +02:00
parent 34d47046ff
commit 03c185c35d
2 changed files with 52 additions and 23 deletions
+49 -21
View File
@@ -1,9 +1,11 @@
// SPDX-FileCopyrightText: 2024 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
// SPDX-License-Identifier: GPL-3.0-only
#include "PreviewImage.h"
#include <thread>
#include <cmath>
#include <future>
#include "PreviewImage.h"
#include "JFJochJPEG.h"
#include "JFJochTIFF.h"
@@ -212,7 +214,32 @@ void PreviewImage::AddResolutionRing(std::vector<rgb> &rgb_image, float d) const
}
}
void PreviewImage::Configure(const DiffractionExperiment &in_experiment, const PixelMask& pixel_mask) {
void PreviewImage::ConfigurePixel(const std::vector<uint32_t> &mask_tmp, size_t pixel_begin, size_t pixel_end) {
constexpr uint32_t gap_bits =
(1u << PixelMask::ModuleGapPixelBit)
| (1u << PixelMask::ChipGapPixelBit)
| (1u << PixelMask::ModuleEdgePixelBit);
constexpr uint32_t det_bits = 0xFEFEu; // bits 1-7 and 9-15
constexpr uint32_t usr_bits = (1u << PixelMask::UserMaskedPixelBit);
for (size_t i = pixel_begin; i < pixel_end; i++) {
const auto pixel_val = mask_tmp[i];
if (pixel_val == 0)
mask[i] = 0;
else if ((pixel_val & gap_bits) != 0)
mask[i] = MaskGap;
else if ((pixel_val & det_bits) != 0)
mask[i] = MaskDet;
else if ((pixel_val & usr_bits) != 0)
mask[i] = MaskUsr;
else
mask[i] = 0;
}
}
void PreviewImage::Configure(const DiffractionExperiment &in_experiment, const PixelMask &pixel_mask, size_t nthreads) {
std::unique_lock ul(m);
experiment = in_experiment;
@@ -225,25 +252,26 @@ void PreviewImage::Configure(const DiffractionExperiment &in_experiment, const P
mask.resize(experiment.GetPixelsNum(), 0);
auto &mask_tmp = pixel_mask.GetMask(experiment);
for (int i = 0; i < experiment.GetPixelsNum(); i++) {
if (((mask_tmp[i] & (1 << PixelMask::ModuleGapPixelBit)) != 0)
|| ((mask_tmp[i] & (1 << PixelMask::ChipGapPixelBit)) != 0)
|| ((mask_tmp[i] & (1 << PixelMask::ModuleEdgePixelBit)) != 0))
mask[i] = MaskGap;
else if (mask_tmp[i] & 0xFEFE) // bits 1-7 and 9-15
mask[i] = MaskDet;
else if ((mask_tmp[i] & (1 << PixelMask::UserMaskedPixelBit)) != 0)
mask[i] = MaskUsr;
else
mask[i] = 0;
}
}
if (nthreads == 0)
nthreads = std::thread::hardware_concurrency();
void PreviewImage::Configure() {
std::unique_lock ul(m);
xpixel = 0;
ypixel = 0;
nthreads = std::clamp<size_t>(nthreads, 1, 8);
auto &mask_tmp = pixel_mask.GetMask(experiment);
std::vector<std::future<void> > futures;
futures.reserve(nthreads);
size_t npixel = experiment.GetPixelsNum();
for (size_t t = 0; t < nthreads; ++t)
futures.emplace_back(std::async(std::launch::async,
&PreviewImage::ConfigurePixel, this, std::cref(mask_tmp),
t * npixel / nthreads,
(t + 1) * npixel / nthreads));
for (auto &f: futures)
f.get();
}
std::vector<rgb> PreviewImage::GenerateRGB(const PreviewImageSettings &settings, const DataMessage &msg) const {
+3 -2
View File
@@ -66,9 +66,10 @@ class PreviewImage {
void spot(std::vector<rgb>& ret, int64_t xpixel, int64_t ypixel, const rgb &color) const;
void roi(std::vector<rgb>& ret, int64_t xpixel, int64_t ypixel, int64_t roi_number) const;
std::string GenerateImage(const PreviewImageSettings& settings, const DataMessage &msg) const;
void ConfigurePixel(const std::vector<uint32_t> &mask, size_t pixel_begin, size_t pixel_end);
public:
void Configure(const DiffractionExperiment& experiment, const PixelMask& mask);
void Configure();
void Configure(const DiffractionExperiment& experiment, const PixelMask& mask, size_t nthreads = 0);
[[nodiscard]] std::string GenerateImage(const PreviewImageSettings& settings, const std::vector<uint8_t>& cbor_format);
[[nodiscard]] static std::string GenerateTIFF(const std::vector<uint8_t>& cbor_format) ;