diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index ac267c892..07efaa35b 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -23,6 +23,8 @@ * Rugnux puts the merge onto a reference MTZ's axes before inheriting its free-R flags, and does not inherit them where the merge does not match the reference (`REFERENCE_MISMATCH`); `REFERENCE_OPERATOR=`, `REFERENCE_CC=` and `REFERENCE_MATCHED_FRACTION=` report the match. * Rugnux places a space group given with `-S` on the axes its systematic absences name, so `-S 18` on a cell whose pure two-fold is not its longest axis no longer merges with the screw absences on the wrong rows. * `rugnux -z` also takes a PDB structure-factor mmCIF (`-sf.cif`, gzipped or not) as the reference, with its R-free set; `--reference` is a new name for `--reference-mtz`. +* Rugnux reports further lattices found in the spots the main lattice leaves over on rotation data - split-crystal and twin domains, a crystal that changes along the sweep, a related or an unrelated cell (`EXTRA_LATTICE_*` keys, a `Multiple lattices` summary line) - and warns (`MULTIPLE_LATTICES`) where they hold at least 10 % of the spot intensity; processing is unchanged. +* Rugnux reports the mosaicity the merge used (`MOSAICITY_DEG=` with `MOSAICITY_DEG_P10=`/`_P90=` over the frames, and a summary line), as XDS's sigma_M (`REFLECTING_RANGE_E.S.D.`). * `rugnux --polarization` is documented as the polarization degree (XDS `FRACTION_OF_POLARIZATION` = (1 + p)/2); the default 0.99 suits undulators. ### 1.0.0-rc.172 diff --git a/docs/RUGNUX_REPORT.md b/docs/RUGNUX_REPORT.md index d4139a9e2..42cf2b0f8 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`, `REFERENCE_MISMATCH`, `CANCELLED`, `RESOLUTION_FIT`, - `FLIGHT_PATH`, `GEOMETRY_NOT_CONVERGED`, `SUPERCELL_POSSIBLE`. `NONE` when nothing fired. A code appears if and only if its + `FLIGHT_PATH`, `GEOMETRY_NOT_CONVERGED`, `SUPERCELL_POSSIBLE`, `MULTIPLE_LATTICES`. `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 @@ -450,6 +450,58 @@ both settings - the run's cell, and `SUPERCELL_DOUBLED_CELL=` given with `-C` - summary at the top of the report carries the same advice on its `Supercell` line, beside pseudo-symmetry and twinning. +## Further lattices + +On rotation data, once the first pass has its lattice, section 4 reports what the spots that lattice +leaves over index to. Every spot of the spread and validation frames the main lattice takes is set +aside; the rest, ice left out, go to a fresh rotation indexer. A lattice it finds is kept when the +leftover validation spots sit on it far more often than they do with each frame's spots displaced to +another frame's spindle angle - the null the first pass judges its own lattice against - by at least +five standard deviations (**`EXTRA_LATTICE__Z=`**). Its spots are set aside in turn and the search +goes on, up to three lattices. A lattice of the same cell within 1° of the main one is the main +lattice's own spots its tolerance missed, and is not listed. Nothing is decided on any of this: only +the main lattice is integrated, whatever is found. + +**`MAIN_LATTICE_SPOTS_PCT=`** and **`MAIN_LATTICE_INTENSITY_PCT=`** are the main lattice's share of the +non-ice spots of those frames and of their summed intensity; **`EXTRA_LATTICE_COUNT=`** is the number of +lattices listed. For each, numbered from 1 in the order found: + +- **`EXTRA_LATTICE__KIND=`** — `DOMAIN`: the same cell, misoriented, over the whole sweep (a split + crystal); `TWIN_DOMAIN`: the same, turned by 180° (within 3°) — a non-merohedral twin domain; + `SEGMENTED`: the same cell, with at least 60 % of its spots in 2 of 8 equal blocks of the sweep — the + crystal in the beam changes along the rotation; `RELATED_CELL`: a cell whose volume is 1 to 8 times, + or a 1/2 to 1/8 of, the main one's — a question about the main cell (see the supercell keys above and + the harmonic) rather than a second crystal; `FOREIGN`: an unrelated cell — a second crystal, or a + main lattice that is not the crystal's. +- **`EXTRA_LATTICE__LATTICE=`** and **`EXTRA_LATTICE__CELL=`** — its crystal system, centring and + conventional cell. +- **`EXTRA_LATTICE__VOLUME_RATIO=`** — its reduced cell volume over the main one's. +- **`EXTRA_LATTICE__MISORIENTATION_DEG=`** — for the same cell only: the smallest rotation taking the + main lattice onto it, over every basis whose metric matches, so a symmetry of the lattice is not read + as a misorientation. +- **`EXTRA_LATTICE__SPOTS_PCT=`**, **`EXTRA_LATTICE__INTENSITY_PCT=`** — its share of the non-ice + spots and of their intensity. +- **`EXTRA_LATTICE__SWEEP_CONCENTRATION=`** — the share of its spots in the 2 densest of 8 blocks of the + sweep; 0.25 is uniform. + +**`EXTRA_LATTICE_INTENSITY_PCT=`** sums the intensity share of every listed lattice except `RELATED_CELL`, +and **`MULTIPLE_LATTICES=`** is `TRUE`, with a warning under the `MULTIPLE_LATTICES` flag, where that is +at least 10 %. It is information, not a failure: a split crystal whose second domain is half as strong +as the main one can still give data as good as XDS's, since the domains' reflections are only a problem +where they overlap the main lattice's. Look at the crystal, and at the result. The summary at the top of +the report has a `Multiple lattices` line, `none found` where nothing was listed. + +## Mosaicity + +**`MOSAICITY_DEG=`** (section 2, and a `Mosaicity` line in the summary) is the mosaic spread the merge +computed partiality from, on rotation data: Kabsch's σ_M, the standard deviation (not the FWHM) of a +reflection's rocking curve in degrees, in the same partiality model as XDS - so it is the number to set +beside XDS's `REFLECTING_RANGE_E.S.D.`. It is fitted on every frame by maximum likelihood from the +rocking offsets of that frame's 250 strongest indexed spots, with the energy bandwidth taken out where +the beam has one (XDS keeps it in), and smoothed in frame order; the value is the median over the frames, +with **`MOSAICITY_DEG_P10=`** and **`MOSAICITY_DEG_P90=`** for its spread. The per-frame values are the +`sigma_M_deg` column of `_plot.txt`. + ## 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/tools/battery/README.md b/tools/battery/README.md index 599ddb53e..a5b180217 100644 --- a/tools/battery/README.md +++ b/tools/battery/README.md @@ -385,6 +385,7 @@ was run `--unforced`), so its forced XDS-arm rows are left out the same way. | `d_min`, `d_min_ref`, `res_gain_pct` | our high-resolution limit, the reference's, and (ref - ours) / ref in % | | `d_min_ref_rule`, `d_min_xds` | XDS arms: how `d_min_ref` was derived (below), and the range XDS merged | | `r_meas`, `cc_half`, `isa`, `completeness`, `multiplicity`, `i_over_sigma`, `indexing_rate`, `images` | from rugnux's `_report.txt`, over its own range | +| `mosaicity_deg`, `extra_lattice_intensity_pct` | from the same report: `MOSAICITY_DEG=` (sigma_M as XDS) and `EXTRA_LATTICE_INTENSITY_PCT=` (spot intensity on further lattices); null in reports without them | | `r_meas_ref`, `cc_half_ref`, `isa_ref`, `completeness_ref`, `multiplicity_ref` | XDS's overall values, over XDS's own range | | `refres_range`, `refres_shells_past_limit`, `refres_unique_reflections`, `refres_completeness`, `refres_multiplicity`, `refres_i_over_sigma`, `refres_r_meas`, `refres_cc_half`, `refres_isa` | XDS arms: the REFRES_* keys, the same merge over the reference range | | `isa_ratio`, `r_meas_ratio` | refres_isa / isa_ref and refres_r_meas / r_meas_ref | diff --git a/tools/battery/score.py b/tools/battery/score.py index 1c7e96685..64cfc94dd 100644 --- a/tools/battery/score.py +++ b/tools/battery/score.py @@ -190,6 +190,7 @@ def judge(entry, rep, run_note): # merge does (absent from reports before the weighting) "r_meas_weighted": fnum(rep.get("R_MEAS_WEIGHTED")), "isa": fnum(rep.get("ISA")), "completeness": fnum(rep.get("COMPLETENESS")), + "mosaicity_deg": fnum(rep.get("MOSAICITY_DEG")), "extra_lattice_intensity_pct": fnum(rep.get("EXTRA_LATTICE_INTENSITY_PCT")), "multiplicity": fnum(rep.get("MULTIPLICITY")), "i_over_sigma": fnum(rep.get("I_OVER_SIGMA")), "indexing_rate": fnum(rep.get("INDEXING_RATE")), "images": fnum(rep.get("IMAGES_PROCESSED")), "rugnux_wall_s": fnum(rep.get("WALL_TIME")), "rugnux_verdict": rep.get("VERDICT_TEXT"),