ImageSpotFinder: Getting ready for abstract class for both CPU and GPU spot finders
This commit is contained in:
@@ -14,7 +14,6 @@ MXAnalysisWithoutFPGA::MXAnalysisWithoutFPGA(const DiffractionExperiment &in_exp
|
||||
IndexerThreadPool *in_indexer)
|
||||
: experiment(in_experiment),
|
||||
integration(in_integration),
|
||||
updated_image(experiment.GetPixelsNum()),
|
||||
roi_count(0),
|
||||
npixels(experiment.GetPixelsNum()),
|
||||
xpixels(experiment.GetXPixelsNum()),
|
||||
@@ -35,6 +34,7 @@ MXAnalysisWithoutFPGA::MXAnalysisWithoutFPGA(const DiffractionExperiment &in_exp
|
||||
mask_1bit[i] = (in_mask.GetMask().at(i) != 0);
|
||||
|
||||
spotFinder = std::make_unique<ImageSpotFinderCPU>(experiment.GetXPixelsNum(), experiment.GetYPixelsNum());
|
||||
updated_image = spotFinder->GetHostBuffer();
|
||||
}
|
||||
|
||||
void MXAnalysisWithoutFPGA::Analyze(DataMessage &output, std::vector<uint8_t> &image, AzimuthalIntegrationProfile &profile,
|
||||
@@ -159,10 +159,12 @@ void MXAnalysisWithoutFPGA::Analyze(DataMessage &output,
|
||||
|| mask_low_res != settings.low_resolution_limit)
|
||||
UpdateMaskResolution(settings);
|
||||
|
||||
const std::vector<DiffractionSpot> spots = spotFinder->Run(updated_image.data(), settings, mask_resolution);
|
||||
const std::vector<DiffractionSpot> spots = spotFinder->Run(settings, mask_resolution);
|
||||
|
||||
SpotAnalyze(experiment, settings, spots,
|
||||
CompressedImage(updated_image, experiment.GetXPixelsNum(), experiment.GetYPixelsNum()),
|
||||
CompressedImage(updated_image, sizeof(int32_t) * experiment.GetPixelsNum(),
|
||||
experiment.GetXPixelsNum(), experiment.GetYPixelsNum(),
|
||||
CompressedImageMode::Int32),
|
||||
indexer, output);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ class MXAnalysisWithoutFPGA {
|
||||
const DiffractionExperiment &experiment;
|
||||
const AzimuthalIntegration &integration;
|
||||
|
||||
std::vector<int32_t> updated_image;
|
||||
int32_t *updated_image;
|
||||
std::vector<uint16_t> roi_map;
|
||||
std::map<std::string, uint16_t> roi_names;
|
||||
size_t roi_count;
|
||||
@@ -28,7 +28,7 @@ class MXAnalysisWithoutFPGA {
|
||||
size_t xpixels;
|
||||
std::vector<bool> mask_1bit;
|
||||
|
||||
std::unique_ptr<ImageSpotFinderCPU> spotFinder;
|
||||
std::unique_ptr<ImageSpotFinder> spotFinder;
|
||||
IndexerThreadPool *indexer;
|
||||
|
||||
uint16_t azint_bins;
|
||||
|
||||
@@ -7,6 +7,8 @@ ADD_LIBRARY(JFJochSpotFinding STATIC
|
||||
StrongPixelSet.cpp
|
||||
StrongPixelSet.h
|
||||
DetModuleSpotFinder_cpu.h
|
||||
ImageSpotFinder.cpp
|
||||
ImageSpotFinder.h
|
||||
)
|
||||
|
||||
TARGET_LINK_LIBRARIES(JFJochSpotFinding JFJochCommon)
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
// SPDX-FileCopyrightText: 2025 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
//
|
||||
// Created by leonarski_f on 04.10.25.
|
||||
//
|
||||
|
||||
#include "ImageSpotFinder.h"
|
||||
@@ -0,0 +1,20 @@
|
||||
// SPDX-FileCopyrightText: 2025 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
#ifndef JFJOCH_IMAGESPOTFINDER_H
|
||||
#define JFJOCH_IMAGESPOTFINDER_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
#include "../../common/DiffractionSpot.h"
|
||||
|
||||
class ImageSpotFinder {
|
||||
public:
|
||||
virtual ~ImageSpotFinder() = default;
|
||||
virtual int32_t *GetHostBuffer() = 0;
|
||||
virtual std::vector<DiffractionSpot> Run(const SpotFindingSettings &settings, const std::vector<bool> &res_mask) = 0;
|
||||
};
|
||||
|
||||
|
||||
#endif //JFJOCH_IMAGESPOTFINDER_H
|
||||
@@ -5,15 +5,19 @@
|
||||
#include "StrongPixelSet.h"
|
||||
|
||||
ImageSpotFinderCPU::ImageSpotFinderCPU(size_t in_width, size_t in_height)
|
||||
: width(in_width), height(in_height) {}
|
||||
: width(in_width), height(in_height), in_buffer(in_width * in_height) {
|
||||
}
|
||||
|
||||
void ImageSpotFinderCPU::nbx(int input) {
|
||||
NBX = input;
|
||||
}
|
||||
|
||||
std::vector<DiffractionSpot> ImageSpotFinderCPU::Run(const int32_t *input,
|
||||
const SpotFindingSettings &settings,
|
||||
const std::vector<bool> &res_mask) {
|
||||
int32_t *ImageSpotFinderCPU::GetHostBuffer() {
|
||||
return in_buffer.data();
|
||||
}
|
||||
|
||||
std::vector<DiffractionSpot> ImageSpotFinderCPU::Run(const SpotFindingSettings &settings,
|
||||
const std::vector<bool> &res_mask) {
|
||||
std::vector<DiffractionSpot> output;
|
||||
StrongPixelSet strong_pixel_set;
|
||||
|
||||
@@ -21,11 +25,11 @@ std::vector<DiffractionSpot> ImageSpotFinderCPU::Run(const int32_t *input,
|
||||
if (settings.photon_count_threshold > 0) {
|
||||
for (int line = 0; line < height; line++) {
|
||||
for (int col = 0; col < width; col++) {
|
||||
int32_t pxl_val = input[line * width + col];
|
||||
int32_t pxl_val = in_buffer[line * width + col];
|
||||
if (pxl_val == INT32_MAX ||
|
||||
(pxl_val > settings.photon_count_threshold
|
||||
&& pxl_val != INT32_MIN
|
||||
&& !res_mask[line * width + col]))
|
||||
&& pxl_val != INT32_MIN
|
||||
&& !res_mask[line * width + col]))
|
||||
strong_pixel_set.AddStrongPixel(col, line, pxl_val);
|
||||
}
|
||||
}
|
||||
@@ -47,8 +51,8 @@ std::vector<DiffractionSpot> ImageSpotFinderCPU::Run(const int32_t *input,
|
||||
for (int col = 0; col < width; col++) {
|
||||
auto pxl = line * width + col;
|
||||
|
||||
if (input[pxl] != INT32_MAX && input[pxl] != INT32_MIN) {
|
||||
int64_t tmp = input[pxl];
|
||||
if (in_buffer[pxl] != INT32_MAX && in_buffer[pxl] != INT32_MIN) {
|
||||
int64_t tmp = in_buffer[pxl];
|
||||
sum_vert[col] += tmp;
|
||||
sum2_vert[col] += tmp * tmp;
|
||||
valid_vert[col] += 1;
|
||||
@@ -62,8 +66,8 @@ std::vector<DiffractionSpot> ImageSpotFinderCPU::Run(const int32_t *input,
|
||||
if (line < height - NBX) {
|
||||
auto pxl = (line + NBX) * width + col;
|
||||
|
||||
if (input[pxl] != INT32_MAX && input[pxl] != INT32_MIN) {
|
||||
int64_t tmp = input[pxl];
|
||||
if (in_buffer[pxl] != INT32_MAX && in_buffer[pxl] != INT32_MIN) {
|
||||
int64_t tmp = in_buffer[pxl];
|
||||
sum_vert[col] += tmp;
|
||||
sum2_vert[col] += tmp * tmp;
|
||||
valid_vert[col] += 1;
|
||||
@@ -72,8 +76,8 @@ std::vector<DiffractionSpot> ImageSpotFinderCPU::Run(const int32_t *input,
|
||||
|
||||
if (line >= NBX + 1) {
|
||||
auto pxl = (line - (NBX + 1)) * width + col;
|
||||
if (input[pxl] != INT32_MAX && input[pxl] != INT32_MIN) {
|
||||
int64_t tmp = input[pxl];
|
||||
if (in_buffer[pxl] != INT32_MAX && in_buffer[pxl] != INT32_MIN) {
|
||||
int64_t tmp = in_buffer[pxl];
|
||||
sum_vert[col] -= tmp;
|
||||
sum2_vert[col] -= tmp * tmp;
|
||||
valid_vert[col] -= 1;
|
||||
@@ -104,7 +108,7 @@ std::vector<DiffractionSpot> ImageSpotFinderCPU::Run(const int32_t *input,
|
||||
valid -= valid_vert[col - NBX - 1];
|
||||
}
|
||||
|
||||
int32_t pxl_val = input[line * width + col];
|
||||
int32_t pxl_val = in_buffer[line * width + col];
|
||||
int64_t var = valid * sum2 - (sum * sum);
|
||||
int64_t in_minus_mean = pxl_val * valid - sum;
|
||||
|
||||
@@ -113,11 +117,8 @@ std::vector<DiffractionSpot> ImageSpotFinderCPU::Run(const int32_t *input,
|
||||
(pxl_val > settings.photon_count_threshold) && // pixel is above count threshold
|
||||
(in_minus_mean > 0) && // pixel value is larger than mean
|
||||
(in_minus_mean * in_minus_mean > std::ceil(var * strong2)) && // pixel is above SNR threshold
|
||||
(res_mask[line * width + col] == 0))) {
|
||||
// pixel is within a valid resolution range
|
||||
std::cout << line << " " << col << std::endl;
|
||||
(res_mask[line * width + col] == 0))) // pixel is within a valid resolution range
|
||||
strong_pixel_set.AddStrongPixel(col, line, pxl_val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
// SPDX-FileCopyrightText: 2025 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
#ifndef JFJOCH_IMAGESPOTFINDER_H
|
||||
#define JFJOCH_IMAGESPOTFINDER_H
|
||||
#ifndef JFJOCH_IMAGESPOTFINDERCPU_H
|
||||
#define JFJOCH_IMAGESPOTFINDERCPU_H
|
||||
|
||||
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
|
||||
#include "ImageSpotFinder.h"
|
||||
#include "SpotFindingSettings.h"
|
||||
#include "../../common/AzimuthalIntegration.h"
|
||||
#include "../../common/DiffractionSpot.h"
|
||||
@@ -17,15 +18,17 @@
|
||||
// This one is expected to be used in cases, where images are already assembled
|
||||
// and it aims for 100 ms execution
|
||||
|
||||
class ImageSpotFinderCPU {
|
||||
class ImageSpotFinderCPU : public ImageSpotFinder {
|
||||
size_t width;
|
||||
size_t height;
|
||||
std::vector<int32_t> in_buffer;
|
||||
|
||||
int NBX = 15;
|
||||
public:
|
||||
int32_t *GetHostBuffer();
|
||||
ImageSpotFinderCPU(size_t width, size_t height);
|
||||
void nbx(int input);
|
||||
std::vector<DiffractionSpot> Run(const int32_t *input, const SpotFindingSettings &settings, const std::vector<bool> &res_mask);
|
||||
std::vector<DiffractionSpot> Run(const SpotFindingSettings &settings, const std::vector<bool> &res_mask);
|
||||
};
|
||||
|
||||
#endif //JFJOCH_IMAGESPOTFINDER_H
|
||||
|
||||
@@ -10,10 +10,11 @@
|
||||
#include <vector>
|
||||
#include "SpotFindingSettings.h"
|
||||
#include "StrongPixelSet.h"
|
||||
#include "ImageSpotFinder.h"
|
||||
|
||||
struct CudaStreamWrapper;
|
||||
|
||||
class ImageSpotFinderGPU {
|
||||
class ImageSpotFinderGPU : public ImageSpotFinder {
|
||||
std::mutex m;
|
||||
CudaStreamWrapper *cudastream;
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ TEST_CASE("ImageSpotFinderCPU_SignalToNoise") {
|
||||
|
||||
ImageSpotFinderCPU s(width, height);
|
||||
|
||||
std::vector<int32_t> input (width * height);
|
||||
int32_t *input = s.GetHostBuffer();
|
||||
for (int i = 0; i < width * height; i++)
|
||||
input[i] = (i % 2) * 5 + 5;
|
||||
|
||||
@@ -29,7 +29,7 @@ TEST_CASE("ImageSpotFinderCPU_SignalToNoise") {
|
||||
};
|
||||
|
||||
std::vector<bool> mask_resolution(width * height, false);
|
||||
auto spots = s.Run(input.data(), settings, mask_resolution);
|
||||
auto spots = s.Run(settings, mask_resolution);
|
||||
|
||||
REQUIRE(spots.size() == 2);
|
||||
REQUIRE(spots[0].RawCoord().y == 25);
|
||||
@@ -42,7 +42,7 @@ TEST_CASE("ImageSpotFinderCPU_SignalToNoise_Resolution") {
|
||||
|
||||
ImageSpotFinderCPU s(width, height);
|
||||
|
||||
std::vector<int32_t> input (width * height);
|
||||
int32_t *input = s.GetHostBuffer();
|
||||
for (int i = 0; i < width * height; i++)
|
||||
input[i] = (i % 2) * 5 + 5;
|
||||
|
||||
@@ -62,7 +62,7 @@ TEST_CASE("ImageSpotFinderCPU_SignalToNoise_Resolution") {
|
||||
|
||||
std::vector<bool> mask_resolution(width * height, false);
|
||||
mask_resolution[width * 50 + 50] = true;
|
||||
auto spots = s.Run(input.data(), settings, mask_resolution);
|
||||
auto spots = s.Run(settings, mask_resolution);
|
||||
|
||||
REQUIRE(spots.size() == 1);
|
||||
REQUIRE(spots[0].RawCoord().x == 26);
|
||||
@@ -75,7 +75,7 @@ TEST_CASE("ImageSpotFinderCPU_CountThreshold_Resolution") {
|
||||
|
||||
ImageSpotFinderCPU s(width, height);
|
||||
|
||||
std::vector<int32_t> input (width * height);
|
||||
int32_t *input = s.GetHostBuffer();
|
||||
for (int i = 0; i < width * height; i++)
|
||||
input[i] = (i % 2) * 5 + 5;
|
||||
|
||||
@@ -95,7 +95,7 @@ TEST_CASE("ImageSpotFinderCPU_CountThreshold_Resolution") {
|
||||
|
||||
std::vector<bool> mask_resolution(width * height, false);
|
||||
mask_resolution[width * 50 + 50] = true;
|
||||
auto spots = s.Run(input.data(), settings, mask_resolution);
|
||||
auto spots = s.Run(settings, mask_resolution);
|
||||
|
||||
REQUIRE(spots.size() == 2);
|
||||
REQUIRE(spots[0].RawCoord().y == 25);
|
||||
@@ -108,7 +108,7 @@ TEST_CASE("ImageSpotFinderCPU_CountThreshold_Mask") {
|
||||
|
||||
ImageSpotFinderCPU s( width, height);
|
||||
|
||||
std::vector<int32_t> input (width * height);
|
||||
int32_t *input = s.GetHostBuffer();
|
||||
for (int i = 0; i < width * height; i++)
|
||||
input[i] = (i % 2) * 5 + 5;
|
||||
|
||||
@@ -128,7 +128,7 @@ TEST_CASE("ImageSpotFinderCPU_CountThreshold_Mask") {
|
||||
};
|
||||
|
||||
std::vector<bool> mask_resolution(width * height, false);
|
||||
auto spots = s.Run(input.data(), settings, mask_resolution);
|
||||
auto spots = s.Run(settings, mask_resolution);
|
||||
|
||||
REQUIRE(spots.size() == 3);
|
||||
REQUIRE(spots[0].RawCoord().x == 26);
|
||||
@@ -144,7 +144,7 @@ TEST_CASE("ImageSpotFinderCPU_SignalToNoise_Mask") {
|
||||
size_t height = 100;
|
||||
ImageSpotFinderCPU s(width, height);
|
||||
|
||||
std::vector<int32_t> input (width * height);
|
||||
int32_t *input = s.GetHostBuffer();
|
||||
for (int i = 0; i < width * height; i++)
|
||||
input[i] = (i % 2) * 5 + 5;
|
||||
|
||||
@@ -166,7 +166,7 @@ TEST_CASE("ImageSpotFinderCPU_SignalToNoise_Mask") {
|
||||
};
|
||||
|
||||
std::vector<bool> mask_resolution(width * height, false);
|
||||
auto spots = s.Run(input.data(), settings, mask_resolution);
|
||||
auto spots = s.Run(settings, mask_resolution);
|
||||
|
||||
REQUIRE(spots.size() == 3);
|
||||
REQUIRE(spots[0].RawCoord().x == 26);
|
||||
|
||||
Reference in New Issue
Block a user