CalcGlobalWilsonB fits ln<I> against 1/d^2 from 4 A to d_min. With d_min just under 4 A that window is a sliver, and after the shells past the signal limit are dropped it held 0-2 shells, so the estimate was NaN (or a fit over almost no range); and any B above 200 A^2 was discarded, which is every crystal diffracting to 4-7 A. Now the window is never narrower in 1/d^2 than the 4-3 A window a 3 A data set gets: a narrower one is widened towards low resolution (d_min 3.15 A -> from 4.39 A, 3.61 A -> 5.96 A, 3.87 A -> 7.40 A; data coarser than ~4.4 A use everything, as before). The 200 A^2 cap is dropped for the dataset-wide estimate (kept for the per-image one). The window is logged, printed with the statistics and reported (WILSON_B_RANGE_A, developer key); the correlation is reported as before. Data with d_min <= 3 A are unchanged. Report only: the value feeds the statistics text, the log, the report and the mmCIF _reflns.B_iso_Wilson_estimate; nothing in scaling, merging or the MTZ reads it. Measured on the open arm (replica on thea897b08merged data, confirmed by rugnux runs): 12 sets change, 7 previously NaN now finite - 5nw5 315, 9z44 493, 6r72 302 A^2 (were above the cap; model mean B 328/310/114, deposited Wilson 388/322/179), 9yzk 210 (model 383, ctruncate 243, xtriage 104), 7qij 104 (model 194, ctruncate 150), 9yl4 78 (model 146), 8qq7 35 at 4 shells (model 197; its signal ends well inside the written 3.15 A). 6yqf 132 (corr 0.51) -> 96 (corr 0.69; model 57, ctruncate 145, xtriage 114); 9rcs 69 -> 148 (model 74, ctruncate 131). At 3-4 A the estimators themselves disagree by 1.5-3x, so these are better-defined numbers, not exact ones. p.hkl and MTZ data identical to the base (e34a5fb88) on every set compared (ci tier, private arm, the Wilson sets). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
34 lines
1.8 KiB
C++
34 lines
1.8 KiB
C++
// SPDX-FileCopyrightText: 2025 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
|
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
|
|
#pragma once
|
|
|
|
#include <limits>
|
|
#include <vector>
|
|
|
|
#include "../../common/JFJochMessages.h"
|
|
#include "../../common/Reflection.h"
|
|
|
|
void CalcISigma(DataMessage &msg);
|
|
void CalcWilsonBFactor(DataMessage &msg, bool replace_b = true);
|
|
|
|
void CalcISigma(DataMessage &msg, const std::vector<Reflection> &reflections);
|
|
void CalcWilsonBFactor(DataMessage &msg, const std::vector<Reflection> &reflections, bool replace_b = true);
|
|
// The two above in one pass over the reflections, for the per-image path that wants both.
|
|
void CalcISigmaAndWilsonBFactor(DataMessage &msg, const std::vector<Reflection> &reflections,
|
|
bool replace_b = true);
|
|
|
|
// Dataset-wide isotropic Wilson B-factor estimate from a log-linear fit of the shell-averaged merged
|
|
// intensity against 1/d^2 (B = -2*slope). Robust because it averages over the whole dataset - the
|
|
// per-image CalcWilsonBFactor above is a per-frame estimate and much noisier. Diagnostic only (like
|
|
// XDS's "WILSON LINE ... B="), not used in scaling. Returns b = NaN when it cannot be determined.
|
|
struct GlobalWilsonB {
|
|
double b = std::numeric_limits<double>::quiet_NaN(); // Wilson B-factor estimate (A^2)
|
|
double correlation = std::numeric_limits<double>::quiet_NaN(); // |correlation| of the log-linear fit
|
|
int n_shells = 0; // resolution shells actually used
|
|
double d_low_A = std::numeric_limits<double>::quiet_NaN(); // the fit window, low-resolution end
|
|
double d_high_A = std::numeric_limits<double>::quiet_NaN(); // and high-resolution end (A)
|
|
};
|
|
GlobalWilsonB CalcGlobalWilsonB(const std::vector<MergedReflection> &merged);
|
|
|