// SPDX-FileCopyrightText: 2025 Filip Leonarski, Paul Scherrer Institute // SPDX-License-Identifier: GPL-3.0-only #include "SpotUtils.h" void CountSpots(DataMessage &msg, const std::vector &spots, float d_min_A) { int64_t low_res = 0; int64_t ice_ring = 0; for (auto &s: spots) { if (s.ice_ring) ice_ring++; if (s.d_A > d_min_A) low_res++; } msg.spot_count = spots.size(); msg.spot_count_low_res = low_res; msg.spot_count_ice_rings = ice_ring; } void MarkIceRings(std::vector &spots, float tolerance_q_recipA) { std::vector ice_rings_q; for (const auto &i: ICE_RING_RES_A) ice_rings_q.push_back(2 * M_PI / i); for (auto &s: spots) { auto spot_q = 2 * M_PI / s.d_A; bool tmp = false; for (const auto &q: ice_rings_q) tmp |= (fabs(spot_q - q) < tolerance_q_recipA); s.ice_ring = tmp; } } void FilterSpotsByCount(std::vector &input, int64_t count) { size_t output_size = std::min(input.size(), count); std::ranges::partial_sort(input, input.begin() + output_size, std::ranges::less{}, // comparator on the projected key [](const SpotToSave &s) { // projection: key to compare by return std::tuple{s.ice_ring, -s.intensity}; // false < true → non-ice first; negate intensity → higher first }); input.resize(output_size); }