ModelValidation: score the candidate changes of basis at the same time
Each candidate setting of the model was scored one after another on the coarse shell (a density, an FFT and an isotropic scale fit, 0.2-0.5 s each), and a run with a model in another setting scores them in both of its validations. They share nothing but what they read, so they now run on ParallelFor, each on its own copy of the model, and are read back in their own order: the log lines, the ranking and the tie-break (first of equal R wins) are those of the serial loop. Measured (16-core workstation, loaded): 8sa8 3 candidates 0.64 s -> 0.22 s; 9ea5 3 candidates 1.47 s -> 0.50 s; 8xtg 1.45 s -> 0.40 s. p.mtz, the maps, the map MTZ and the placed model md5-identical. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SVmAWnzCmRKAXVUCdc4iNi
This commit is contained in:
@@ -32,6 +32,7 @@
|
||||
#include "../../common/CorrelationCoefficient.h"
|
||||
#include "../../common/JFJochMath.h" // PI (M_PI is not standard, and MSVC does not define it)
|
||||
#include "../../common/Logger.h"
|
||||
#include "../../common/ParallelFor.h"
|
||||
#include "../scale_merge/ReindexAmbiguity.h" // ReindexReflections
|
||||
#include "../scale_merge/CrystalSetting.h" // CellMappingOperators
|
||||
#include "ModelFFT.h"
|
||||
@@ -481,13 +482,15 @@ ModelValidationResult Validate(const std::vector<MergedReflection> &merged,
|
||||
"is not how the data describe this lattice; scoring {} change(s) of basis",
|
||||
st.cell.a, st.cell.b, st.cell.c, st.cell.alpha, st.cell.beta, st.cell.gamma,
|
||||
sg->xhm(), frames.size() - 1);
|
||||
size_t best = 0;
|
||||
double best_r = 0;
|
||||
for (size_t i = 0; i < frames.size(); i++) {
|
||||
// The candidates are scored at the same time, each on its own copy of the model, and read
|
||||
// in their own order below, so the ranking and its tie-break are those of one after another.
|
||||
std::vector<double> frame_r(frames.size(), 0.0);
|
||||
std::vector<const gemmi::SpaceGroup *> frame_sg(frames.size(), nullptr);
|
||||
ParallelFor(static_cast<int>(frames.size()), nthreads, [&](int i) {
|
||||
gemmi::Structure trial = st;
|
||||
const gemmi::SpaceGroup *trial_sg = sg;
|
||||
if (i > 0 && !change_model_basis(trial, trial_sg, frames[i]))
|
||||
continue; // no origin shift names the transformed group; not a basis we can take
|
||||
return; // no origin shift names the transformed group; not a basis we can take
|
||||
refractionalize_into(trial, data_cell);
|
||||
trial.setup_cell_images();
|
||||
// Each frame at the data's best indexing: the alternative indexings are only probed
|
||||
@@ -499,8 +502,17 @@ ModelValidationResult Validate(const std::vector<MergedReflection> &merged,
|
||||
if (same_point_group)
|
||||
for (const gemmi::Op &law : reindex_ops)
|
||||
r = std::min(r, frame_probe_r(trial, trial_sg, ReindexReflections(obs, law), d_min));
|
||||
frame_r[i] = r;
|
||||
frame_sg[i] = trial_sg;
|
||||
});
|
||||
size_t best = 0;
|
||||
double best_r = 0;
|
||||
for (size_t i = 0; i < frames.size(); i++) {
|
||||
if (frame_sg[i] == nullptr)
|
||||
continue;
|
||||
const double r = frame_r[i];
|
||||
logger.Info("Model validation: {:<12} -> {:<12} R {:.4f} on the coarse shell",
|
||||
frames[i].triplet(), trial_sg->xhm(), r);
|
||||
frames[i].triplet(), frame_sg[i]->xhm(), r);
|
||||
if (i == 0 || r < best_r) {
|
||||
best_r = r;
|
||||
best = i;
|
||||
|
||||
Reference in New Issue
Block a user