French-Wilson once, on the written merge; none for the P1 cross-check

Every full-statistics rotation merge computed French-Wilson amplitudes - the
search candidates, the pinned low/high pair, the final, and the P1
cross-check - although only the written merge's amplitudes are used, and those
were recomputed anyway with the anisotropic prior. RotationScaleMerge gets
SetFrenchWilson(); Rugnux turns it off for its merges and makes the amplitudes
once after the anisotropy analysis (anisotropic prior when a tensor was
fitted, isotropic otherwise). --mode scale keeps the engine's own amplitudes.

p_P1.mtz is now intensities only (owner decision): the F/SIGF/F(+)/F(-)
columns are omitted; every intensity column is bit-identical to before.

French-Wilson was 29% of the CPU samples in the large-cell tail (8tyy P1
cross-check window, ~84 core-s). p.mtz md5 unchanged on myob, cytc, thau,
kdp, 8tyy (GPU build). Wall: 8tyy 173.9 -> 150.9 s; cytc/thau -0.2..-0.3 s,
myob unchanged (3 interleaved repeats).

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:
2026-10-06 23:10:26 +02:00
co-authored by Claude Opus 5.5
parent fc61700c95
commit 76b3956e11
7 changed files with 40 additions and 16 deletions
+13 -8
View File
@@ -460,7 +460,8 @@ void WriteMmcifReflections(const std::vector<MergedReflection> &reflections,
void WriteMtzReflections(const std::vector<MergedReflection> &reflections,
const UnitCell &unitCell,
const DiffractionExperiment &experiment,
const std::string &filename) {
const std::string &filename,
bool amplitudes) {
gemmi::Mtz mtz;
// Optional but recommended metadata
@@ -495,9 +496,11 @@ void WriteMtzReflections(const std::vector<MergedReflection> &reflections,
mtz.add_column("I(-)", 'K', dataset_id, -1, false);
mtz.add_column("SIGI(-)", 'M', dataset_id, -1, false);
}
mtz.add_column("F", 'F', dataset_id, -1, false); // French-Wilson amplitude
mtz.add_column("SIGF", 'Q', dataset_id, -1, false);
if (has_anom) {
if (amplitudes) {
mtz.add_column("F", 'F', dataset_id, -1, false); // French-Wilson amplitude
mtz.add_column("SIGF", 'Q', dataset_id, -1, false);
}
if (amplitudes && has_anom) {
mtz.add_column("F(+)", 'G', dataset_id, -1, false);
mtz.add_column("SIGF(+)", 'L', dataset_id, -1, false);
mtz.add_column("F(-)", 'G', dataset_id, -1, false);
@@ -506,7 +509,7 @@ void WriteMtzReflections(const std::vector<MergedReflection> &reflections,
mtz.add_column("FreeR_flag", 'I', dataset_id, -1, false);
mtz.nreflections = static_cast<int>(out_rows.size());
mtz.data.reserve(out_rows.size() * (has_anom ? 16 : 8));
mtz.data.reserve(out_rows.size() * 16);
for (const auto& row : out_rows) {
mtz.data.push_back(static_cast<float>(row.h));
mtz.data.push_back(static_cast<float>(row.k));
@@ -519,9 +522,11 @@ void WriteMtzReflections(const std::vector<MergedReflection> &reflections,
mtz.data.push_back(row.Im);
mtz.data.push_back(row.sIm);
}
mtz.data.push_back(row.Fmean);
mtz.data.push_back(row.sFmean);
if (has_anom) {
if (amplitudes) {
mtz.data.push_back(row.Fmean);
mtz.data.push_back(row.sFmean);
}
if (amplitudes && has_anom) {
mtz.data.push_back(row.Fp);
mtz.data.push_back(row.sFp);
mtz.data.push_back(row.Fm);