diff --git a/image_analysis/scale_merge/SearchSpaceGroup.cpp b/image_analysis/scale_merge/SearchSpaceGroup.cpp index de71f6a7..cc1535a8 100644 --- a/image_analysis/scale_merge/SearchSpaceGroup.cpp +++ b/image_analysis/scale_merge/SearchSpaceGroup.cpp @@ -296,11 +296,6 @@ SearchSpaceGroupResult SearchSpaceGroup( for (const auto& sg : gemmi::spacegroup_tables::main) { if (!sg.is_sohncke() || !sg.is_reference_setting() || RotationSetOf(sg) != best_pg->rotation_set) continue; - // Centering is a metric property: when the lattice centering is known, only weigh P against - // that centering, never a different one. - if (opt.lattice_centering != '\0' && - sg.centring_type() != 'P' && sg.centring_type() != opt.lattice_centering) - continue; const gemmi::GroupOps gops = sg.operations(); SpaceGroupCandidateScore s{.space_group = sg}; @@ -361,13 +356,7 @@ SearchSpaceGroupResult SearchSpaceGroup( return eligible(a); if (a.absent_observed != b.absent_observed) return a.absent_observed > b.absent_observed; - // Tie: prefer the metric centering, then the lower space-group number. - if (opt.lattice_centering != '\0') { - const bool am = a.space_group.centring_type() == opt.lattice_centering; - const bool bm = b.space_group.centring_type() == opt.lattice_centering; - if (am != bm) - return am; - } + // Tie (e.g. I23 vs I2_13, indistinguishable by absences): lower space-group number. return a.space_group.number < b.space_group.number; }); diff --git a/image_analysis/scale_merge/SearchSpaceGroup.h b/image_analysis/scale_merge/SearchSpaceGroup.h index e65c7e24..acdb0286 100644 --- a/image_analysis/scale_merge/SearchSpaceGroup.h +++ b/image_analysis/scale_merge/SearchSpaceGroup.h @@ -50,10 +50,10 @@ struct SearchSpaceGroupOptions { // symmetry than the intensities support. Unset = search every Sohncke system. std::optional lattice_system; - // Lattice centering from LatticeSearch ('P','C','I','F','R'; '\0' = unknown). Centering is a - // metric property of the lattice, so when known the space-group search only weighs P vs this - // centering and prefers the metric one when the data cannot decide between them. - char lattice_centering = '\0'; + // Centering is NOT taken from the lattice metric: an indexer that returns the conventional cell + // (e.g. cubic 'P'-looking axes for a body-centered lattice) hides the centering, which lives only + // in the systematic absences. Stage B therefore tests every centering allowed by the point group + // and confirms it from the data (h+k+l etc. absent), rather than trusting a geometric hint. // Friedel mates are treated as equivalent when matching HKLs (i.e. anomalous signal ignored). bool merge_friedel = true; diff --git a/process/JFJochProcess.cpp b/process/JFJochProcess.cpp index 60188557..8b2c46c9 100644 --- a/process/JFJochProcess.cpp +++ b/process/JFJochProcess.cpp @@ -481,11 +481,9 @@ ProcessResult JFJochProcess::Run(JFJochProcessObserver *observer) { sg_opts.merge_friedel = experiment_.GetScalingSettings().GetMergeFriedel(); sg_opts.d_min_limit_A = experiment_.GetScalingSettings().GetHighResolutionLimit_A().value_or(0.0); // Constrain the search to subgroups of the lattice (metric) symmetry found by rotation - // indexing, and weigh centering only against the metric one. - if (end_msg.rotation_lattice_type.has_value()) { + // indexing. Centering is not constrained here - it is determined from the absences. + if (end_msg.rotation_lattice_type.has_value()) sg_opts.lattice_system = end_msg.rotation_lattice_type->crystal_system; - sg_opts.lattice_centering = end_msg.rotation_lattice_type->centering; - } const auto sg_search = SearchSpaceGroup(sm.merged, sg_opts); stats_text << SearchSpaceGroupResultToText(sg_search) << "\n\n"; diff --git a/tools/jfjoch_process.cpp b/tools/jfjoch_process.cpp index 9a1001f9..38c4085e 100644 --- a/tools/jfjoch_process.cpp +++ b/tools/jfjoch_process.cpp @@ -679,8 +679,11 @@ int main(int argc, char **argv) { experiment.ImagesPerTrigger(images_to_process); experiment.NumTriggers(1); - if (fixed_reference_unit_cell.has_value()) - experiment.SetUnitCell(*fixed_reference_unit_cell); + // Re-determine the unit cell from scratch: discard any cell stored in the input file so + // indexing is not biased by it. A stale or wrong stored cell otherwise resolves the indexing + // algorithm to FFBIDX and drives it to the wrong lattice (e.g. a non-cubic cell for cubic + // insulin). A user-supplied -C cell still takes effect (clears to nullopt when absent). + experiment.SetUnitCell(fixed_reference_unit_cell); if (max_spot_count_override.has_value()) { experiment.MaxSpotCount(max_spot_count_override.value());