Merge branch 'dq-reg4' into rc174-all3
# Conflicts: # docs/CHANGELOG.md
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
* Rugnux drops a rotation reflection whose spot held a saturated (overloaded) pixel, as XDS does, and reports the count as `OBSERVATIONS_REJECTED_OVERLOAD=`.
|
||||
* Rugnux fits a rotation sweep's per-frame scale on the partial reflections, even with few reflections per frame, when scaling from the fulls alone leaves no measurable error model.
|
||||
* Rugnux no longer refuses a genuine high-symmetry point group because one of its operators agrees with the data unusually well; it refuses a group whose operators split into an agreeing subgroup and a disagreeing rest.
|
||||
* Rugnux no longer adopts an intermediate space group (e.g. C222_1 for a twinned P2_1 on a hexagonal metric) when the higher group was refused and the twin-immune reflections show the added two-folds to be a twin law.
|
||||
* Rugnux names glide planes in groups without a centre of symmetry (e.g. I-42d, Fdd2), reports a group with the same absences (C2/c and Cc) as an alternative, and states how the centre was decided (`SPACE_GROUP_CENTRE`, `CENTRE_STATISTICS_*`).
|
||||
|
||||
### 1.0.0-rc.173
|
||||
|
||||
+48
-2
@@ -7828,8 +7828,53 @@ ProcessResult Rugnux::RunPipeline(RugnuxObserver *observer, bool write_output, b
|
||||
if (alt.centring_type() == cand.centering) { chosen = alt; break; }
|
||||
const bool point_group_higher = s2.best_space_group.has_value()
|
||||
&& s2.point_group_order > sg_search.point_group_order;
|
||||
const bool higher = point_group_higher
|
||||
&& chosen->centring_type() == cand.centering;
|
||||
bool higher = point_group_higher
|
||||
&& chosen->centring_type() == cand.centering;
|
||||
// A promotion over a refusal is arbitrated by the twin-immune zone of the added
|
||||
// operators (TwinZoneVerdict), here as where the two arms disagree: where a twin
|
||||
// gate of the search in hand refused a higher group, this ask reopens the question
|
||||
// that gate answered, for whichever of the refused group's operators the new
|
||||
// lattice holds, and its own search cannot answer it - the gates there are relative
|
||||
// too, and a twin law or a pseudo-symmetry the refused group's other operators
|
||||
// diluted passes them alone. Measured on a monoclinic crystal on a hexagonal metric,
|
||||
// a pseudo-merohedral twin: 622 refused on the added-operator R, the C-centred
|
||||
// orthorhombic sub-lattice then asked, its two in-plane two-folds at R 0.061 against
|
||||
// 0.045 for the genuine screw, and C 2 2 21 adopted with the zone of those two-folds
|
||||
// reading acentric. The group in hand is carried into the candidate's setting for
|
||||
// it: h -> Q h with Q the reindex from the basis it was found in (read where GEMMI's
|
||||
// table names the result, as every setting the search enumerates is).
|
||||
std::string zone_refusal;
|
||||
if (higher && sg_search.refused_by_twin_gate && sg_search.point_group_representative) {
|
||||
gemmi::Mat33 q = reindex;
|
||||
if (commit_reindex)
|
||||
q = reindex.multiply(commit_reindex->inverse());
|
||||
const gemmi::Mat33 q_inv = q.inverse();
|
||||
gemmi::GroupOps lower_ops;
|
||||
lower_ops.cen_ops = gemmi::centring_vectors(cand.centering);
|
||||
for (const auto &op : sg_search.point_group_representative->operations().sym_ops) {
|
||||
// apply_to_hkl uses rot^T, so the Miller-index matrix of op is rot^T / DEN.
|
||||
gemmi::Mat33 m;
|
||||
for (int i = 0; i < 3; ++i)
|
||||
for (int j = 0; j < 3; ++j)
|
||||
m.a[i][j] = static_cast<double>(op.rot[j][i]) / gemmi::Op::DEN;
|
||||
const gemmi::Mat33 m_new = q.multiply(m).multiply(q_inv);
|
||||
gemmi::Op op_new = gemmi::Op::identity();
|
||||
for (int i = 0; i < 3; ++i)
|
||||
for (int j = 0; j < 3; ++j)
|
||||
op_new.rot[i][j] = static_cast<int>(std::lround(m_new[j][i])) * gemmi::Op::DEN;
|
||||
lower_ops.sym_ops.push_back(op_new);
|
||||
}
|
||||
if (const gemmi::SpaceGroup *lower_sg = gemmi::find_spacegroup_by_ops(lower_ops)) {
|
||||
SearchSpaceGroupResult lower = sg_search;
|
||||
lower.point_group_representative = *lower_sg;
|
||||
if (TwinZoneVerdict(merged_all, *o2.cell, s2, lower, result) < 0) {
|
||||
zone_refusal = sg_search.refused_point_group_hm + " was refused (" +
|
||||
sg_search.refused_reason + "), and the twin-immune zone of the "
|
||||
"operators this group adds reads acentric";
|
||||
higher = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
const auto &uc = cand.conventional.GetUnitCell();
|
||||
// The two asks are told apart by what they were asked against: the class a search
|
||||
// has already been given, or the rotations the intensities have actually confirmed.
|
||||
@@ -7853,6 +7898,7 @@ ProcessResult Rugnux::RunPipeline(RugnuxObserver *observer, bool write_output, b
|
||||
s2.best_space_group.has_value() ? s2.best_space_group->xhm() : "nothing",
|
||||
s2.point_group_order, sg_search.point_group_order,
|
||||
higher ? " - adopted"
|
||||
: !zone_refusal.empty() ? " - keeping the group already found; " + zone_refusal
|
||||
: (point_group_higher
|
||||
? " - keeping the group already found; the point group IS "
|
||||
"higher, but no candidate of it carries the centring the "
|
||||
|
||||
Reference in New Issue
Block a user