From 81dbf9a385f6093aed62323a68608c223717cd03 Mon Sep 17 00:00:00 2001 From: Filip Leonarski Date: Tue, 21 Jul 2026 09:53:33 +0200 Subject: [PATCH] Fix empty spot-plot and resolution percentile in SpotAnalyze GenerateSpotPlot iterated msg.spots, but SpotAnalyze called it before assigning output.spots. In the online path the DataMessage is fresh per frame, so the plot was built from an empty list and spot_plot_intensity / spot_plot_count came out all zeros. Pass the finished spots vector explicitly instead of relying on the field being set: the live path passes the full pre-truncation list, the HDF5 read-back path passes message.spots. GetResolution scaled the 5th-percentile index by spots.size() (which includes ice-ring spots) while indexing the ice-filtered resolutions vector, biasing the estimate and reading out of bounds on ice-heavy frames. Index by resolutions.size() instead. Co-Authored-By: Claude Opus 4.8 (1M context) --- image_analysis/spot_finding/SpotUtils.cpp | 9 ++++----- image_analysis/spot_finding/SpotUtils.h | 2 +- reader/HDF5MetadataSource.cpp | 2 +- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/image_analysis/spot_finding/SpotUtils.cpp b/image_analysis/spot_finding/SpotUtils.cpp index 8dcf3254..d272fb3f 100644 --- a/image_analysis/spot_finding/SpotUtils.cpp +++ b/image_analysis/spot_finding/SpotUtils.cpp @@ -94,17 +94,17 @@ std::optional GetResolution(const std::vector &spots) { return std::nullopt; if (resolutions.size() < 20) return resolutions[2]; - return resolutions[static_cast(spots.size() * 0.05)]; + return resolutions[static_cast(resolutions.size() * 0.05)]; } -void GenerateSpotPlot(DataMessage &msg, float d_min_A) { +void GenerateSpotPlot(DataMessage &msg, const std::vector &spots, float d_min_A) { const int nshells = 20; ResolutionShells shells(d_min_A, 50.0, nshells); std::vector intensity(nshells); std::vector count(nshells); - for (const auto &s: msg.spots) { + for (const auto &s: spots) { if (s.ice_ring) continue; @@ -140,7 +140,6 @@ void SpotAnalyze(const DiffractionExperiment &experiment, spots_out.push_back(s.value()); } - if (spot_finding_settings.high_res_gap_Q_recipA.has_value()) FilterSpuriousHighResolutionSpots(spots_out, spot_finding_settings.high_res_gap_Q_recipA.value()); @@ -149,7 +148,7 @@ void SpotAnalyze(const DiffractionExperiment &experiment, CountSpots(output, spots_out, spot_finding_settings.cutoff_spot_count_low_res); - GenerateSpotPlot(output, spot_finding_settings.high_resolution_limit); + GenerateSpotPlot(output, spots_out, spot_finding_settings.high_resolution_limit); output.resolution_estimate = GetResolution(spots_out); diff --git a/image_analysis/spot_finding/SpotUtils.h b/image_analysis/spot_finding/SpotUtils.h index 05d183c8..9ba458be 100644 --- a/image_analysis/spot_finding/SpotUtils.h +++ b/image_analysis/spot_finding/SpotUtils.h @@ -5,7 +5,7 @@ #include "../../common/DiffractionSpot.h" -void GenerateSpotPlot(DataMessage &msg, float d_min_A); +void GenerateSpotPlot(DataMessage &msg, const std::vector &spots, float d_min_A); void CountSpots(DataMessage &msg, const DiffractionExperiment& experiment, diff --git a/reader/HDF5MetadataSource.cpp b/reader/HDF5MetadataSource.cpp index 40469725..4a0cb2f3 100644 --- a/reader/HDF5MetadataSource.cpp +++ b/reader/HDF5MetadataSource.cpp @@ -889,7 +889,7 @@ static void ReadSpotsFromFiles(HDF5Object &master_file, message.spot_count_indexed = ReadElementMasterFirst( master_file, source_file, "/entry/MX/peakCountIndexed", master_image, source_image); - GenerateSpotPlot(message, 1.5); + GenerateSpotPlot(message, message.spots, 1.5); } void HDF5MetadataSource::FillPerImage(DataMessage &message, int64_t requested_image,