rugnux: an R that compares between runs, beside the one that makes the maps
R_WORK and R_FREE score the data against a model scaled by k_overall, a symmetry-constrained anisotropic B and a flat bulk solvent. That scale is deliberate - a free per-shell rescale would reshape each map's radial amplitude profile and a batch of maps would no longer be comparable - but it can only bend one way with resolution, so whatever a dataset's own radial profile does that k*exp(-B s^2) cannot follow is reported as R. Two reductions of one crystal whose amplitudes differ radially therefore differ in R_FREE for a reason that has nothing to do with either fitting the model: measured on one such pair of runs, R_FREE moved a median +0.042 over eleven sets where phenix.model_vs_data, which scales per shell, moved +0.002. Report a second reading of the same fit: R_MODEL_SHELL_SCALED, one free scale per resolution shell of the merge table, with R_MODEL as the same sum without it and MODEL_RADIAL_MISFIT (RMS of ln k_shell) as the size of the rescale, so the reason a comparison is or is not readable is on the page. Over all the reflections, not the free 5%: nothing here is refined, so work and free estimate the same quantity and the split only costs precision. Nothing is written from it. On two sets, every output file - both maps, the anomalous map, the map coefficients, the MTZ, the HKL and the CIF - is byte for byte what the same commit produced without this change, and R_WORK and R_FREE are unchanged. On the pair above, the new R moves a median +0.0005 and holds every set inside 0.0065 except the one that is a real regression, which it puts first at +0.0174 where the old metric ranked it seventh. The battery reports it beside R_free, and scores neither. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013nW6FNRP1bBJJ8pfHiByAT
This commit is contained in:
@@ -421,8 +421,11 @@ TEST_CASE("ResultReport_ModelValidationSection", "[Diagnostics]") {
|
||||
CHECK(dev_text.find("\nMODEL_FIT_NULL_REPLICATES= 5\n") != std::string::npos);
|
||||
}
|
||||
CHECK(text.find("\nMODEL_FIT_SIGMA= +4.12\n") != std::string::npos);
|
||||
// A run that measured no CC(model, data) writes no key for it.
|
||||
// A run that measured no CC(model, data) writes no key for it, and the shell-scaled R shares
|
||||
// its shells, so it is absent too.
|
||||
CHECK(text.find("CC_MODEL_OVERALL=") == std::string::npos);
|
||||
CHECK(text.find("R_MODEL_SHELL_SCALED=") == std::string::npos);
|
||||
CHECK(text.find("MODEL_RADIAL_MISFIT=") == std::string::npos);
|
||||
CHECK(text.find("CC_MODEL_CONFIRMED_TO_D_MIN=") == std::string::npos);
|
||||
CHECK(text.find("\nMODEL_DECISIONS_TAKEN= ENANTIOMORPH\n") != std::string::npos);
|
||||
// The hand is ASSUMED from the model, never determined: merged intensities cannot see it.
|
||||
@@ -473,6 +476,32 @@ TEST_CASE("ResultReport_ModelValidationSection", "[Diagnostics]") {
|
||||
CHECK(cc_text.find(" 1.80 0.0412 2110 +1.9") != std::string::npos);
|
||||
CHECK(cc_text.find("The table reads in ONE direction only") != std::string::npos);
|
||||
|
||||
// The comparable R rides on the same shells. R_WORK and R_FREE are what they always were - the
|
||||
// maps' own scale - and the new keys sit beside them rather than in place of them.
|
||||
ModelValidationResult with_r = with_cc;
|
||||
with_r.r_model = 0.2011;
|
||||
with_r.r_model_shell_scaled = 0.1734;
|
||||
with_r.n_model = 17610;
|
||||
with_r.radial_misfit = 0.312;
|
||||
with_r.shell_scale_bins = 3;
|
||||
result.model_validation = with_r;
|
||||
const auto r_text = RenderResultReport("p", "in.h5", x, result);
|
||||
CHECK(r_text.find("\nR_WORK= 0.1823\n") != std::string::npos);
|
||||
CHECK(r_text.find("\nR_FREE= 0.2145\n") != std::string::npos);
|
||||
CHECK(r_text.find("\nR_MODEL= 0.2011\n") != std::string::npos);
|
||||
CHECK(r_text.find("\nR_MODEL_SHELL_SCALED= 0.1734\n") != std::string::npos);
|
||||
CHECK(r_text.find("\nR_MODEL_REFLECTIONS= 17610\n") != std::string::npos);
|
||||
CHECK(r_text.find("\nMODEL_RADIAL_MISFIT= 0.312\n") != std::string::npos);
|
||||
CHECK(r_text.find("the number to compare between runs") != std::string::npos);
|
||||
// The shell count is a working detail of the rescale, not part of the reading.
|
||||
CHECK(r_text.find("MODEL_RADIAL_SHELLS=") == std::string::npos);
|
||||
{
|
||||
RunProvenance dev;
|
||||
dev.developer = true;
|
||||
CHECK(RenderResultReport("p", "in.h5", x, result, dev)
|
||||
.find("\nMODEL_RADIAL_SHELLS= 3\n") != std::string::npos);
|
||||
}
|
||||
|
||||
// Nothing significant anywhere: the key still has to be written, saying so.
|
||||
ModelValidationResult no_signal = with_cc;
|
||||
for (auto &sh : no_signal.cc_model_shells)
|
||||
|
||||
Reference in New Issue
Block a user