// SPDX-FileCopyrightText: 2026 Filip Leonarski, Paul Scherrer Institute // SPDX-License-Identifier: GPL-3.0-only #pragma once #include #include "gemmi/unitcell.hpp" // One reflection as the sigma_A estimate sees it: an observed and a calculated amplitude, already on // a common scale, plus what the likelihood needs to know about the reflection itself. struct SigmaAReflection { double f_obs = 0; double f_calc = 0; double inv_d2 = 0; int epsilon = 1; bool centric = false; bool free = false; }; // The weights of one reflection's map coefficients: 2mFo - DFc and mFo - DFc. struct SigmaAWeight { double m = 1.0; // figure of merit double d = 1.0; // D, carried on the observed amplitudes' scale }; struct SigmaAResult { std::vector weight; // one per input reflection, in the input order int shells = 0; int free_reflections = 0; double mean_fom = 1.0; double sigma_a_lowest_shell = 0.0; // for a log line: sigma_A at the low- and high-resolution ends double sigma_a_highest_shell = 0.0; }; // Per-resolution-shell sigma_A by maximum likelihood, and from it the figure of merit m and the // scale D of each reflection. Estimated on the FREE reflections only - on the working set the model // has been fitted to the data, so sigma_A would come out too high and the weighting would under-state // the model's error where the map is meant to reveal it. // // Following Read (1986) Acta Cryst. A42, 140-149 SigmaAResult EstimateSigmaA(const std::vector &refl, const gemmi::UnitCell &cell);