diff --git a/image_analysis/spot_finding/StrongPixelSet.cpp b/image_analysis/spot_finding/StrongPixelSet.cpp index 84160aff..c12e12fc 100644 --- a/image_analysis/spot_finding/StrongPixelSet.cpp +++ b/image_analysis/spot_finding/StrongPixelSet.cpp @@ -10,7 +10,7 @@ #include "StrongPixelSet.h" StrongPixelSet::StrongPixelSet() : strong_pixel_count(0) { - pixels.reserve(max_strong_pixel_per_module); + pixels.reserve(UINT16_MAX); } void StrongPixelSet::AddStrongPixel(uint16_t col, uint16_t line, int32_t photons) { @@ -18,16 +18,18 @@ void StrongPixelSet::AddStrongPixel(uint16_t col, uint16_t line, int32_t photons } bool is_far_enough(strong_pixel pixel0, strong_pixel pixel1) { - return (pixel1.line - pixel0.line) > 1; + auto line_diff = pixel0.line - pixel1.line; + return line_diff > 1 || line_diff < -1; } bool is_adjacent(strong_pixel pixel0, strong_pixel pixel1) { - return (fabs(pixel0.line - pixel1.line) <= 1) and - (fabs(pixel0.col - pixel1.col) <= 1); + auto line_diff = pixel0.line - pixel1.line; + auto col_diff = pixel0.col - pixel1.col; + return line_diff <= 1 && line_diff >= -1 && col_diff <= 1 && col_diff >= -1; } -uint16_t StrongPixelSet::find_root(uint16_t e) { - uint16_t r = e; +uint32_t StrongPixelSet::find_root(uint32_t e) { + uint32_t r = e; //assert(r < L.size()); while (L[r] != r) { r = L[r]; @@ -36,8 +38,8 @@ uint16_t StrongPixelSet::find_root(uint16_t e) { return r; } -uint16_t StrongPixelSet::make_union(uint16_t e1, uint16_t e2) { - uint16_t e; +uint32_t StrongPixelSet::make_union(uint32_t e1, uint32_t e2) { + uint32_t e; if (e1 < e2) { e = e1; //assert(e2 < L.size()); @@ -56,11 +58,11 @@ std::vector StrongPixelSet::sparseccl() { unsigned int labels = 0; // first scan: pixel association - uint16_t start_j = 0; - for (uint16_t i = 0; i < pixels.size(); ++i) { + uint32_t start_j = 0; + for (uint32_t i = 0; i < pixels.size(); ++i) { L[i] = i; - uint16_t ai = i; - for (uint16_t j = start_j; j < i; ++j) { + uint32_t ai = i; + for (uint32_t j = start_j; j < i; ++j) { if (is_adjacent(pixels[i], pixels[j])) { ai = make_union(ai, find_root(j)); } else if (is_far_enough(pixels[j], pixels[i])) { @@ -70,7 +72,7 @@ std::vector StrongPixelSet::sparseccl() { } // second scan: transitive closure - for (unsigned int i = 0; i < L.size(); ++i) { + for (uint32_t i = 0; i < L.size(); ++i) { if (L[i] == i) { L[i] = labels++; } else { @@ -80,7 +82,7 @@ std::vector StrongPixelSet::sparseccl() { std::vector spots(labels); - for (unsigned int i = 0; i < L.size(); i++) + for (uint32_t i = 0; i < L.size(); i++) spots[L[i]].AddPixel(pixels[i].col, pixels[i].line, pixels[i].counts); return spots; @@ -88,7 +90,8 @@ std::vector StrongPixelSet::sparseccl() { void StrongPixelSet::FindSpotsImage(const SpotFindingSettings &settings, std::vector &spots) { - if (!pixels.empty()) { + // Avoid spot finding, when more than 65536 strong pixel count (will be super slow) + if (!pixels.empty() && (strong_pixel_count < UINT16_MAX)) { for (const auto &spot: sparseccl()) { if ((spot.PixelCount() <= settings.max_pix_per_spot) && (spot.PixelCount() >= settings.min_pix_per_spot)) { @@ -100,7 +103,8 @@ void StrongPixelSet::FindSpotsImage(const SpotFindingSettings &settings, std::ve void StrongPixelSet::FindSpots(const DiffractionExperiment &experiment, const SpotFindingSettings &settings, std::vector &spots, uint16_t module_number) { - if (!pixels.empty()) { + // Avoid spot finding, when more than 65536 strong pixel count (will be super slow) + if (!pixels.empty() && (strong_pixel_count < UINT16_MAX)) { for (const auto &spot: sparseccl()) { if ((spot.PixelCount() <= settings.max_pix_per_spot) && (spot.PixelCount() >= settings.min_pix_per_spot)) { @@ -114,13 +118,14 @@ void StrongPixelSet::FindSpots(const DiffractionExperiment &experiment, const Sp void StrongPixelSet::ReadFPGAOutput(const DiffractionExperiment & experiment, const DeviceOutput &output) { - strong_pixel_count += output.spot_finding_result.strong_pixel_count; - // Too many strong pixels will kill performance in data processing, so protection is needed // Also if there are no strong pixels, there is no point in looking for them if ((output.spot_finding_result.strong_pixel_count == 0) || - (output.spot_finding_result.strong_pixel_count > max_strong_pixel_per_module)) + (output.spot_finding_result.strong_pixel_count > max_strong_pixel_per_module)) { + // If max strong pixel per module condition kicks-in, still report correct strong pixel count + strong_pixel_count = output.spot_finding_result.strong_pixel_count; return; + } auto pixel_depth = experiment.GetByteDepthImage(); auto out_ptr = (uint32_t *) output.spot_finding_result.strong_pixel; diff --git a/image_analysis/spot_finding/StrongPixelSet.h b/image_analysis/spot_finding/StrongPixelSet.h index c878f5f4..06e05018 100644 --- a/image_analysis/spot_finding/StrongPixelSet.h +++ b/image_analysis/spot_finding/StrongPixelSet.h @@ -17,7 +17,7 @@ struct strong_pixel { class StrongPixelSet { std::vector pixels; - std::vector L; + std::vector L; static const constexpr size_t max_strong_pixel_per_module = 4000; static const constexpr uint32_t xpixel = RAW_MODULE_COLS; @@ -25,8 +25,8 @@ class StrongPixelSet { uint32_t strong_pixel_count; - uint16_t find_root(uint16_t e); - uint16_t make_union(uint16_t e1, uint16_t e2); + uint32_t find_root(uint32_t e); + uint32_t make_union(uint32_t e1, uint32_t e2); std::vector sparseccl(); public: void ReadFPGAOutput(const DiffractionExperiment& experiment,