Files
Jungfraujoch/common/TopPixels.h
T
leonarski_f cc3eb8352c
Build Packages / Unit tests (push) Skipped
Build Packages / build:rpm (rocky8_nocuda) (push) Successful in 9m28s
Build Packages / build:rpm (rocky9_nocuda) (push) Successful in 10m9s
Build Packages / build:rpm (ubuntu2404_nocuda) (push) Successful in 9m47s
Build Packages / build:rpm (ubuntu2204_nocuda) (push) Successful in 10m58s
Build Packages / build:rpm (rocky8_sls9) (push) Successful in 11m39s
Build Packages / build:rpm (rocky8) (push) Successful in 11m43s
Build Packages / build:rpm (rocky9_sls9) (push) Successful in 12m59s
Build Packages / Generate python client (push) Successful in 35s
Build Packages / Build documentation (push) Successful in 59s
Build Packages / Create release (push) Skipped
Build Packages / build:rpm (ubuntu2204) (push) Successful in 11m48s
Build Packages / build:rpm (rocky9) (push) Successful in 12m32s
Build Packages / build:rpm (ubuntu2404) (push) Successful in 10m24s
Build Packages / XDS test (durin plugin) (push) Successful in 7m35s
Build Packages / XDS test (neggia plugin) (push) Successful in 6m50s
Build Packages / XDS test (JFJoch plugin) (push) Successful in 7m40s
Build Packages / DIALS test (push) Successful in 11m19s
v1.0.0-rc.148 (#58)
This is an UNSTABLE release. The release has significant modifications for data processing - in case of troubles go back to 1.0.0-rc.144.

* jfjoch_broker: Improve azimuthal integration (add <I^2> calculation)
* jfjoch_broker: Fixes around indexing, aiming to handle multi-lattice crystals (work in progress, it is not fully integrated)
* jfjoch_writer: Save mean(I), stddev(I), and count(I) for each azimuthal bin

Reviewed-on: #58
2026-06-08 08:30:35 +02:00

85 lines
2.4 KiB
C++

// SPDX-FileCopyrightText: 2025 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
// SPDX-License-Identifier: GPL-3.0-only
#pragma once
#include <array>
#include <algorithm>
#include <cstdint>
#include <stdexcept>
#include <vector>
class TopPixels {
public:
struct Entry {
int32_t value = 0;
int32_t index = 0;
};
explicit TopPixels(int capacity = 20)
: capacity_(std::clamp(capacity, 1, kMaxCapacity)) {}
void Clear() noexcept { size_ = 0; }
void Add(int32_t value, int32_t index) noexcept {
const Entry e{value, index};
if (size_ < capacity_) {
InsertSorted_(e);
return;
}
// Quick reject: if not better than the current smallest in top-K
if (value <= top_[capacity_ - 1].value)
return;
ReplaceSmallestAndFixOrder_(e);
}
[[nodiscard]] int Capacity() const noexcept { return capacity_; }
[[nodiscard]] int Size() const noexcept { return size_; }
[[nodiscard]] bool Empty() const noexcept { return size_ == 0; }
// Sorted descending by value; valid for i in [0, Size()).
[[nodiscard]] const Entry& At(int i) const {
if (i < 0 || i >= size_)
throw std::out_of_range("TopPixels::At index out of range");
return top_[i];
}
[[nodiscard]] const Entry& operator[](int i) const { return At(i); }
// Convenience: copy results to a std::vector (still sorted descending).
[[nodiscard]] std::vector<Entry> ToVector() const {
return std::vector<Entry>(top_.begin(), top_.begin() + size_);
}
private:
static constexpr int kMaxCapacity = 64; // hard cap for stack-friendly storage
std::array<Entry, kMaxCapacity> top_{};
int size_ = 0;
int capacity_ = 20;
void InsertSorted_(Entry e) noexcept {
top_[size_] = e;
++size_;
// Bubble up to keep descending order by value
for (int i = size_ - 1; i > 0 && top_[i].value > top_[i - 1].value; --i)
std::swap(top_[i], top_[i - 1]);
}
void ReplaceSmallestAndFixOrder_(Entry e) noexcept {
// Replace the smallest (last, because sorted descending)
top_[capacity_ - 1] = e;
// Bubble up to restore descending order
for (int i = capacity_ - 1; i > 0 && top_[i].value > top_[i - 1].value; --i)
std::swap(top_[i], top_[i - 1]);
size_ = capacity_;
}
};