The Q bins can now be laid out in equal steps of log10(Q) between low and high Q, dense at low Q and coarse at high Q, as small-angle work needs; such binning is given by its number of bins. Linear binning takes either its spacing (as before) or its number of bins, not both. Linear binning by spacing bins every pixel and reports every bin centre exactly as before. The Q axis (bin_to_q, written to CBOR and HDF5) holds each bin's centre on its binning scale: the geometric mean of the edges for log10 bins. The ring background of the Bragg radial correction and the ice-ring score read the bin centres instead of assuming a constant spacing. A q rounding onto the far edge of the last bin now stays in that bin instead of spilling into the next azimuthal row. rugnux: --azim-q-binning linear|log10 and --azim-q-bins; --mode calibration refuses log10 bins, as its ring search works in equal Q steps. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HVeDQsU5a8AJUdJPgWevAK
35 lines
1.1 KiB
C++
35 lines
1.1 KiB
C++
// SPDX-FileCopyrightText: 2026 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
|
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
|
|
#include "RingBackground.h"
|
|
|
|
#include <algorithm>
|
|
#include <cmath>
|
|
|
|
RingBackground::RingBackground(const std::vector<float> &ring_bkg, const std::vector<double> &q_centre) {
|
|
const size_t q_bins = q_centre.size();
|
|
if (q_bins == 0)
|
|
return;
|
|
std::vector<double> sum(q_bins, 0.0);
|
|
std::vector<int> cnt(q_bins, 0);
|
|
for (size_t i = 0; i < ring_bkg.size(); ++i)
|
|
if (std::isfinite(ring_bkg[i])) {
|
|
sum[i % q_bins] += ring_bkg[i];
|
|
++cnt[i % q_bins];
|
|
}
|
|
for (size_t i = 0; i < q_bins; ++i)
|
|
if (cnt[i] > 0) {
|
|
q.push_back(q_centre[i]);
|
|
b.push_back(sum[i] / cnt[i]);
|
|
}
|
|
}
|
|
|
|
double RingBackground::At(double q_recipA) const {
|
|
if (q_recipA <= q.front())
|
|
return b.front();
|
|
if (q_recipA >= q.back())
|
|
return b.back();
|
|
const size_t j = std::upper_bound(q.begin(), q.end(), q_recipA) - q.begin() - 1;
|
|
return b[j] + (b[j + 1] - b[j]) * (q_recipA - q[j]) / (q[j + 1] - q[j]);
|
|
}
|