diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index c88ec9e35..9e1b51dd0 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -9,7 +9,7 @@ * Rugnux accepts a detector-modulation or absorption correction surface when held-out data support it on Fisher's z, and fits them in the order modulation, time, goniometer frame; this recovers corrections that were wrongly refused. * Rugnux settles a disagreement between the file's and the measured beam centre over an axis harmonic in either direction, so a file centre off along the spindle no longer leaves the run on a doubled axis. * Rugnux commits a post-refined geometry only when the held-out residual falls by more than its own noise, instead of by a fixed 2 %. -* Rugnux reports the strongest index-2 superstructure class of a rotation run (`SUPERCELL_CLASS` and related keys), with the doubled cell to give with `-C`; it does not change the lattice. +* Rugnux reports the strongest index-2 superstructure class of a rotation run (`SUPERCELL_CLASS` and related keys) with the doubled cell to give with `-C`, and warns (`SUPERCELL_POSSIBLE`) where that class looks like Bragg reflections, so both settings can be tried; it does not change the lattice. * Rugnux also reports `R_MEAS_WEIGHTED`, the R_meas with each observation weighted as the merge weights it, so weak frames kept in the merge at low weight can be told from real disagreement; `R_MEAS` is unchanged. * Rugnux no longer stops per-frame scaling as unsettled because of a single frame that is about to be dropped as blank. * `rugnux --polarization` is documented as the polarization degree (XDS `FRACTION_OF_POLARIZATION` = (1 + p)/2); the default 0.99 suits undulators. diff --git a/docs/RUGNUX_REPORT.md b/docs/RUGNUX_REPORT.md index ad966ea99..82f74bf2a 100644 --- a/docs/RUGNUX_REPORT.md +++ b/docs/RUGNUX_REPORT.md @@ -148,7 +148,7 @@ and a run that produced a textbook data set read identically for their first thr `SYMMETRY_AMBIGUITY`, `CENTERING_UNTESTED`, `UNUSABLE_MERGE`, `LOW_COMPLETENESS`, `SWEEP_GAPS`, `GONIO_SCALE`, `SPINDLE_CAP`, `ANISOTROPY`, `TWINNING`, `PSEUDO_TRANSLATION`, `LATTICE_TRANSLATION`, `MODEL_HAND`, `MODEL_NOT_VALIDATED`, `CANCELLED`, `RESOLUTION_FIT`, - `FLIGHT_PATH`, `GEOMETRY_NOT_CONVERGED`. `NONE` when nothing fired. A code appears if and only if its + `FLIGHT_PATH`, `GEOMETRY_NOT_CONVERGED`, `SUPERCELL_POSSIBLE`. `NONE` when nothing fired. A code appears if and only if its warning fired, so the flags and the `WARNING:` lines are two renderings of one list — the closed type for machinery, the open sentence for a person. - **`WARNING_COUNT=`** and the **`WARNING:`** lines follow, in the same section. They are what they @@ -434,6 +434,13 @@ and rocks is a superstructure whose reflections this run did not integrate; **`S is the Niggli-reduced cell the lattice would double to, to give with `-C` to process on it. One that is occupied but hardly rocks is diffuse or disordered intensity rather than Bragg reflections. +**`SUPERCELL_POSSIBLE=`** is `TRUE`, with a warning under the `SUPERCELL_POSSIBLE` flag, where the +class is measured (`SUPERCELL_I_OVER_SIGMA=` at least 0.5) and part of it rocks like Bragg reflections +(`SUPERCELL_ROCK_PCT=` at least 2 %, three standard errors clear of zero). It is advice to check, not a +finding: the same numbers come from a real doubled cell and from a correct cell with weak ordered +intensity between its reflections, and which of the two a structure is decided by refinement. Process +both settings - the run's cell, and `SUPERCELL_DOUBLED_CELL=` given with `-C` - and compare them there. + ## Translational pseudo-symmetry Two copies of the contents of the asymmetric unit related by a pure translation that is not a lattice diff --git a/rugnux/ReportDocument.h b/rugnux/ReportDocument.h index be8690150..3b72acc0f 100644 --- a/rugnux/ReportDocument.h +++ b/rugnux/ReportDocument.h @@ -43,6 +43,7 @@ namespace PathologyCode { // in how exact it is. ANISOTROPY and RESOLUTION_FIT are already shared this way. constexpr const char *LATTICE_TRANSLATION = "LATTICE_TRANSLATION"; // a translation the cell does not declare constexpr const char *HARMONIC_CONTAMINATION = "HARMONIC_CONTAMINATION"; // the beam carries a higher harmonic + constexpr const char *SUPERCELL_POSSIBLE = "SUPERCELL_POSSIBLE"; // Bragg-like intensity at half-integer positions constexpr const char *GEOMETRY_NOT_CONVERGED = "GEOMETRY_NOT_CONVERGED"; // the geometry walk ran out of rounds constexpr const char *SCALING_NOT_CONVERGED = "SCALING_NOT_CONVERGED"; // the per-frame scales hit their cap still moving } diff --git a/rugnux/ResultReport.cpp b/rugnux/ResultReport.cpp index 5ed23090a..2b64d39ad 100644 --- a/rugnux/ResultReport.cpp +++ b/rugnux/ResultReport.cpp @@ -1088,6 +1088,22 @@ ReportDocument BuildReportDocument(const std::string &output_prefix, Add(s, KeyReal("SUPERCELL_ROCK_SE_PCT", sc.rock_se_pct, "{:.1f}")); Add(s, KeyReal("SUPERCELL_I_OVER_SIGMA", sc.i_over_sigma, "{:.2f}")); Add(s, KeyText("SUPERCELL_DOUBLED_CELL", CellString(sc.doubled_cell))); + // Advisory, not a decision: the class is measured ( at least 0.5) and part of it + // rocks like Bragg reflections (at least 2% of the lattice's, three standard errors clear). + // On the battery's 105 rotation sets this names 8 - both crystals whose accepted cell is the + // doubled one, a pseudo-translation whose doubled description is an accepted alternative, + // and five correct sub-cells with real but weak half-integer intensity. + const bool possible = sc.i_over_sigma >= 0.5 && sc.rock_pct >= 2.0 && sc.rock_pct > 3.0 * sc.rock_se_pct; + Add(s, KeyBool("SUPERCELL_POSSIBLE", possible)); + if (possible) + Warn(doc, PathologyCode::SUPERCELL_POSSIBLE, + fmt::format("Half-integer reflections of parity {} {} {} carry Bragg-like intensity ({:.0f}% " + "of the lattice's, rocking part {:.1f}%): the true cell may be twice as large. " + "Check carefully, preferably by processing both settings - this cell and " + "-C \"{:.2f},{:.2f},{:.2f},{:.2f},{:.2f},{:.2f}\" - and comparing them in refinement", + sc.h, sc.k, sc.l, sc.occupancy_pct, sc.rock_pct, + sc.doubled_cell.a, sc.doubled_cell.b, sc.doubled_cell.c, + sc.doubled_cell.alpha, sc.doubled_cell.beta, sc.doubled_cell.gamma)); Add(s, Blank()); Add(s, Prose( " SUPERCELL_CLASS is the half-integer class (parity of h, k, l in the primitive cell of the\n"