Rugnux: build the unmerged MTZ beside the P1 cross-check merge
The unmerged file reads the integration outcomes and the determined group, neither of which the P1 merge changes, except each image's mosaicity, which the batch headers carry and the merge rewrites. UnmergedMtz builds the file without it on a second thread, and SetUnmergedMtzMosaicity fills it in after the merge, so the file is the same bytes as before. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D1G8gJVAy6gp1K5Dz3NE5C
This commit is contained in:
@@ -736,12 +736,11 @@ std::vector<Reflection> SumRockingEvents(const std::vector<IntegrationOutcome> &
|
||||
|
||||
} // namespace
|
||||
|
||||
void WriteUnmergedMtzReflections(const std::vector<IntegrationOutcome> &outcomes,
|
||||
const UnitCell &unitCell,
|
||||
const DiffractionExperiment &experiment,
|
||||
bool sum_partials,
|
||||
const std::string &filename,
|
||||
size_t nthreads) {
|
||||
gemmi::Mtz UnmergedMtz(const std::vector<IntegrationOutcome> &outcomes,
|
||||
const UnitCell &unitCell,
|
||||
const DiffractionExperiment &experiment,
|
||||
bool sum_partials,
|
||||
size_t nthreads) {
|
||||
gemmi::Mtz mtz;
|
||||
mtz.spacegroup = &experiment.GetSpaceGroupOrP1();
|
||||
mtz.set_cell_for_all(unitCell);
|
||||
@@ -885,13 +884,11 @@ void WriteUnmergedMtzReflections(const std::vector<IntegrationOutcome> &outcomes
|
||||
// stood on that image. Turn the first indexed one back by its own angle to get the orientation of
|
||||
// the sweep, which is the one matrix POINTLESS also writes into every batch.
|
||||
std::optional<CrystalLattice> lattice_at_zero;
|
||||
std::optional<float> mosaicity_deg;
|
||||
for (const auto &outcome : outcomes) {
|
||||
if (outcome.reflections.empty() || outcome.latt.CalcVolume() <= 1.0f)
|
||||
continue;
|
||||
const float mid_deg = phi_start_deg(outcome.reflections.front().image_number) + wedge_deg / 2.0f;
|
||||
lattice_at_zero = gon ? outcome.latt.Multiply(gon->GetTransformationAngle(mid_deg)) : outcome.latt;
|
||||
mosaicity_deg = outcome.mosaicity_deg;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -930,7 +927,6 @@ void WriteUnmergedMtzReflections(const std::vector<IntegrationOutcome> &outcomes
|
||||
batch.floats[8 + 3 * i] = u[i] * z_cam;
|
||||
}
|
||||
}
|
||||
batch.floats[21] = mosaicity_deg.value_or(0.0f); // crydat(0), the reflecting range
|
||||
batch.floats[40] = 1.0f; // scanax = [0, 0, 1]: the rotation axis IS z in the Cambridge frame
|
||||
batch.floats[47] = wedge_deg;
|
||||
batch.floats[61] = 1.0f; // e1 = scanax, the only goniostat axis
|
||||
@@ -975,6 +971,30 @@ void WriteUnmergedMtzReflections(const std::vector<IntegrationOutcome> &outcomes
|
||||
mtz.data.swap(sorted);
|
||||
mtz.sort_order = {{1, 2, 3, 4, 5}};
|
||||
}
|
||||
return mtz;
|
||||
}
|
||||
|
||||
void SetUnmergedMtzMosaicity(gemmi::Mtz &mtz, const std::vector<IntegrationOutcome> &outcomes) {
|
||||
// The reflecting range of the same image the orientation matrix is taken from.
|
||||
std::optional<float> mosaicity_deg;
|
||||
for (const auto &outcome : outcomes) {
|
||||
if (outcome.reflections.empty() || outcome.latt.CalcVolume() <= 1.0f)
|
||||
continue;
|
||||
mosaicity_deg = outcome.mosaicity_deg;
|
||||
break;
|
||||
}
|
||||
for (auto &batch : mtz.batches)
|
||||
batch.floats[21] = mosaicity_deg.value_or(0.0f); // crydat(0), the reflecting range
|
||||
}
|
||||
|
||||
void WriteUnmergedMtzReflections(const std::vector<IntegrationOutcome> &outcomes,
|
||||
const UnitCell &unitCell,
|
||||
const DiffractionExperiment &experiment,
|
||||
bool sum_partials,
|
||||
const std::string &filename,
|
||||
size_t nthreads) {
|
||||
gemmi::Mtz mtz = UnmergedMtz(outcomes, unitCell, experiment, sum_partials, nthreads);
|
||||
SetUnmergedMtzMosaicity(mtz, outcomes);
|
||||
mtz.write_to_file(filename);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user