The rc178 branch continued after #88 was squash-merged; this is its content fromb9ada7914(the tree #88 squashed) to094eee31a, as one change on main. The individual commits stay on the rc178 branch: - still battery: --cold evicts each set's input from the page cache; Alvra pixel masks; manifest fixes - AGIPD: converter to one rigid panel per module, int16 photons, mask folded in; still battery reads the converted sets - DetectorModules: panel look-up by id, plane -> panel, plane bounds and a per-pixel walk; mask size checked - tests: [PanelLayout] equivalence harness, stacked vs assembled panel layout - Dense per-pixel maps through the panel table (panel layout stage 1) - Panel id on spots and the panel table in the start message - Viewer and preview show a panel detector as it lies on the detector plane - Panel layout stage 3: per-panel spot finding (CPU+GPU, CCL) and raster algorithms on the plane raster - Panel layout stage 2: prediction and Bragg integration through the panel table - XTC reader: frames handed up as stored, streams indexed in parallel - XFEL reader: integer frames stay integer, one gain, placement by panel - EXTERNAL_TEST_DATA_STILLS.md: images used vs the entry for every set; drop "Not in the battery" - still battery: EuXFEL sets read the depositors' Cheetah CXI files directly; AGIPD converter removed - float32_to_int16.py: a non-finite pixel becomes -32768, the int16 error marker, not a zero count - CrystFEL geometry: read the pixel masks and bad regions instead of ignoring them - Panel layout stage 5: the XFEL reader hands up the stored frame and its panel table - Panel table persisted in NXmx; modulation grid and pre-scan memo key on the plane - still battery: Alvra sets take their pixel mask from the CrystFEL geometry, not --mask-good - still battery: take the deposited model as mmCIF where the RCSB has no PDB-format file - still battery: dimple gets PDB-format coordinates converted from an mmCIF-only deposition - stills fixed cost: geometry refinement and pre-scan do the same work in less wall time - stills geometry sample and trial spot finding run as many workers as the image pass - Stills integration: background ring reach measured on empty apertures, radial curvature from the whole frame - StillsPartialityRefine: the partiality width is the run's, measured on the crystals, not the prediction window's - MergeOnTheFly: capture term and multiplicative outlier band for the stills merge (both opt-in) - Stills given a cell: the written cell is the mean over the frames that are merged - Stills: the radial curvature correction decided per run on the same empty apertures - StillsPartialityRefine: measure the run width only on shells with signal - Stills pre-scan: report the paired z of the radial-correction comparison - module placement: the five concurrent fits each keep every thread - still battery: score R-free against the deposited data through the same dimple protocol - still battery: the R-free target is the lower of the deposition's dimple and published values - Stills: background clip follows the radial curve; signal disk from the lattice spacing - Stills keep an overloaded observation as a lower bound instead of dropping it - Stills: drop the lattice-spacing signal disk; the correction decision back on the plain clip - battery: R-free against the deposition without refinement only, one protocol for rotation and stills - still battery: EuXFEL sets run on a 2,000-image subset for now - stills geometry refinement: fit the detector distance and the cell together - stills geometry refinement: a distance given with --detector-distance is held in the joint fit - Metal integration engine: back to its panel-s5 kernels; Mac stills keep the old clip, no saturation count - Metal integration test: the CPU comparison runs on a rotation experiment - Stills: kept overloads go back to the drop where they are not concentrated at low resolution - stills distance search: an absolute 30-3000 mm scan, a sample found without d-limits, the fit iterated - battery results: XFEL still battery 20261022-1358 on rc1780cf62452c- 12 sets, cold, R_free unrefined - battery results: still summary gains the resolution of our merge and of the deposition - Pre-scan masks a pixel at the saturation limit on most frames, as one holding the error value - Stills keep an overload as a lower bound only where it has pixels at the limit; run-level gate removed - XFEL reader: a per-frame mask is read the way the frames are, its chunk inflated outside the HDF5 lock - stills distance search: every centre scanned with a wider acceptance, a larger sample where nothing indexes - rugnux usage: --beam-center-check describes the absolute 30-3000 mm stills distance scan, not the old 60-160 % grid - stills: detector tilt refined in the geometry pre-pass, kept where held-out frames agree - CLAUDE.md: the changelog is written once, just before the merge into main - condensed one-liners of what users get - broker: serve the placed model and its maps of the last rugnux live run (/rugnux/model.cif, /rugnux/map.ccp4) - frontend: Mol* viewer of the placed model and its density on the Rugnux live page - writer: _model.cif from rugnux live keeps the input model's metadata, as the served model.cif does - rugnux live maps: one unit cell centred on the model; the viewer opens on all of it - Anomalous difference map: ANOM/PHANOM in _maps.mtz, /rugnux/map.ccp4?type=anom, a magenta mesh in the viewer - Mol* viewer: open with the maps drawn within 10 A of the centre of view - Mol* viewer: aaredb's structure-viewer setup, on a black stage - rugnux: the gain of a stills file that states none is read off its single-photon peak where the background resolves photons - Mol* viewer: in line with AareDB's StructureView at its current head (8ece2c2) - ACKNOWLEDGEMENT: the web frontend's Mol* viewer follows AareDB's setup (G. Gotthard, PSI) - stills tilt decision: the modules stay where the run placed them - still battery: no distance pins and no per-set tuning flags; gain from the data except where a file's baseline hides it - battery results: rc178 6f6f69 - full still battery and full rotation battery with REFMAC - Bragg integration: a CCD rotation sweep's sigmas at the measured gain, intensities in photons - BackgroundGain: the gain of a frame that resolves photons is the spacing of its photon peaks, so a baseline left in the frame no longer hides it - ShadowFinder: measure the background's azimuthal modulation instead of predicting it from the polarization - BackgroundGain: one gain estimate for rotation and stills; the still battery no longer gives EuXFEL 152 its gain - ShadowFinder: measure the modulation robustly under a wide one-sided shadow - ShadowFinderTest: a one-sided shadow is not fitted as part of the background's modulation - ShadowFinder: back to the predicted polarization factor, in the plane the background shows - MXAnalysisAfterFPGA: the Bragg engine's edge mask in the image's layout, so raw / untransformed FPGA runs start again - battery results: still battery on rc178 e54f55 replaces the earlier rc178 still tables - XFELReader: per-frame mask and photon conversion without a library call or a branch per pixel - stills geometry trial: the hypotheses a search asks are indexed side by side - stills tilt decision: the fits start beside the pre-scan and the geometry trial - XFELReader: a deflated frame is inflated and converted a piece at a time, while it is in the cache - XFELReader: a byte-shuffled frame is unshuffled a piece at a time, a whole pixel per step - GeometryRefiner: residuals carry only the blocks a fit moves; beam and distance one block - GeometryRefiner: a spot's residual differentiates its observed and predicted halves apart - docs: EXTERNAL_TEST_DATA lists every open-arm battery set, with corrected values and counts - battery: doc_check.py cross-checks the manifests against the dataset pages - stills module placement: the placement fit gets half the threads, each held-out fit an eighth - still battery: the EuXFEL sets run on all their frames, as the published still runs did - battery results: still battery on rc178 a0ce6c, cold on a quiet machine, replaces the earlier rc178 table - macOS build: explicit size_t in the XFEL reader's row bounds; parentheses in the CPU preprocessor's select Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015CeEGgpKdfkCTJb3YNMJcu
1106 lines
85 KiB
Markdown
1106 lines
85 KiB
Markdown
# The results report
|
||
|
||
```{contents} On this page
|
||
:local:
|
||
:depth: 2
|
||
```
|
||
|
||
`<prefix>_report.txt` records **what the run determined**, next to the reflection files. It is
|
||
written on every `--mode mx` and `--mode scale` run that has an output prefix — there is no option
|
||
to enable or disable it. Two cases follow from that:
|
||
|
||
- An **empty output prefix** (`-o ""`, the "compute the statistics, persist nothing" mode) writes
|
||
nothing, the report included.
|
||
- **`--no-merge`** still writes a report. It determined an indexing and a geometry result, and those
|
||
are recorded; the merging section then says `MERGE= NOT_PERFORMED` rather than being omitted, so
|
||
the absence is a statement and not something a reader has to infer.
|
||
|
||
The report is never allowed to fail a run: if it cannot be written (unwritable path, full disk) the
|
||
failure is logged as a warning and the run finishes normally.
|
||
|
||
**Exit status.** Rugnux exits 0 when the run completed — everything it determined, declined to
|
||
determine (`CANNOT_DETERMINE`) or warned about is in the report — and non-zero when the run
|
||
stopped: unreadable input, no usable lattice, a `-S` group the indexed lattice cannot host, an
|
||
indexer that could not run. The reason goes to the terminal, and the report may not exist in that
|
||
case — so a script branches on the exit status first and greps the report second.
|
||
|
||
## Format
|
||
|
||
The model is XDS's `CORRECT.LP`: prose and tables a crystallographer reads top to bottom, with a
|
||
structure a script can consume without parsing prose. Every line is one of three kinds — a
|
||
`KEY= value` data line, a `#` comment, or blank — so `grep -v '^#'` leaves the data alone
|
||
(since `REPORT_VERSION= 8`; before that, comment lines had no prefix).
|
||
|
||
- **`KEY= value` assignment lines.** Every number worth extracting is one, so a consumer gets it with
|
||
a single `grep '^ISA= '` and never has to read a sentence. Key names are stable.
|
||
- **`#` comment lines** — everything else: the prose, the section banners, and the fixed-width
|
||
tables (stable header row; the resolution shells, the space-group candidates, the sweep-quality
|
||
ranges).
|
||
- **`# WARNING:` lines**, one per finding, in plain English: `# WARNING: Frames 500-600 out of beam
|
||
(10.1 deg, scale 0.12 and CC 0.30 of the run, 2% scaled)`. `grep '^# WARNING:'` finds every one.
|
||
|
||
The worked examples on this page are shown with the leading `#` stripped for readability; in the
|
||
file itself every such line starts with `#`.
|
||
|
||
**A quantity the run did not measure writes no key at all**, and the fixed-width tables print `-` in
|
||
its place. There is one rule and no placeholders — no `nan`, and no `0.0%` that reads as a measured
|
||
total failure — so a consumer must treat an absent key as *not measured* rather than assume every key
|
||
it knows about is present. A measured value always prints, including a negative one. The keys a
|
||
script meets this on first are `SIGANO=` and `CC_ANOM=`: a rotation merge measures them whether or
|
||
not `-A` was given, but where no Bijvoet pair could be split in both hands — a stills merge without
|
||
`-A`, or too few pairs — the quantity does not exist and the key is absent; `COMPLETENESS=`,
|
||
`MULTIPLICITY=`, `I_OVER_SIGMA=`, `R_MEAS=`, `CC_HALF=` and `WILSON_B=` follow the same rule.
|
||
|
||
**`R_MEAS=`** is the ordinary R_meas, every observation counted once, as XDS and AIMLESS count it - the
|
||
one to set beside theirs. **`R_MEAS_WEIGHTED=`** (and `REFRES_R_MEAS_WEIGHTED=`) weights each
|
||
observation as the merge weights it - by 1/sigma^2 under the error model - with each reflection's
|
||
weights normalised to their effective number, so where a reflection's observations share one sigma it
|
||
equals `R_MEAS=`. A stretch the crystal barely diffracted over is in the merge at the small weight its
|
||
scaled-up counting error gives it, and is in `R_MEAS_WEIGHTED=` at that weight too, rather than setting
|
||
the number with its noise; a large gap between the two says weak frames are kept at low weight.
|
||
`MULTIPLICITY=` stays a count of observations.
|
||
|
||
**`R_MERGE=`** and **`R_PIM=`** are the other two merging R-factors over the same observations as
|
||
`R_MEAS=`: R_merge without the multiplicity correction, and the precision-indicating R_pim (Weiss,
|
||
2001), which falls as the multiplicity rises. **`CC_STAR=`** is CC\* = sqrt(2 CC1/2 / (1 + CC1/2))
|
||
(Karplus & Diederichs, 2012), the estimated correlation of the merged data with the true signal; it is
|
||
absent where CC1/2 is not positive. All three are also columns of the shell tables (`R_merge`,
|
||
`R_pim`, `CC*`) and are written per shell into the merged mmCIF.
|
||
|
||
**`R_SPLIT=`** and **`CC_HALF_SPLIT=`** (and their `REFRES_` forms) are written for stills only, with
|
||
a "Serial statistics" table beside the shell table. Every frame's observations go whole into one of two
|
||
half-sets - as CrystFEL's partialator deals out crystals - and R_split = (1/sqrt 2) sum|I_1 - I_2| /
|
||
(1/2 sum (I_1 + I_2)) (White et al., 2012) and CC1/2 are taken over the reflections both halves
|
||
measured, so both compare directly with CrystFEL's `compare_hkl`. `CC_HALF=` deals each reflection's
|
||
observations out evenly instead, as XDS and cctbx do, and is the one the processing decides on; the two
|
||
agree overall and can differ in a single shell. On stills `R_MEAS=` measures the scatter of partial
|
||
observations, not the error of the merged intensity, and is not the number to quote.
|
||
|
||
**`OBSERVATIONS_REJECTED=`** counts the observations the merge's outlier tests removed, and
|
||
**`OBSERVATIONS_REJECTED_WILSON=`** the part of them the Wilson test took (each listed in the developer
|
||
report). **`OBSERVATIONS_REJECTED_OVERLOAD=`** is separate from both: the rotation measurements left
|
||
out because a pixel of the spot was overloaded on one of its frames, as XDS leaves out an overloaded
|
||
reflection. Outlier rejection takes observations out of `R_MEAS=` and `CC_HALF=` too, so a run that
|
||
rejects much scores better on both; read the counts beside them.
|
||
|
||
The last blocks before `END OF REPORT` are the authorship and the acknowledgement: who wrote
|
||
rugnux, its licence (GPLv3 — free to use for academic institutions and commercial companies alike)
|
||
and where releases are published, then the credit to the X-ray research community whose methods
|
||
rugnux implements and the open-source projects it is built on — both credited in
|
||
`ACKNOWLEDGEMENT.md` beside `LICENSE` and `THIRD_PARTY_NOTICES.md` in the installed package.
|
||
rugnux prints the acknowledgement at startup as well.
|
||
|
||
`REPORT_VERSION=` is the format's own version. Key names, table columns and the reason vocabulary
|
||
below are an interface other software may depend on: they do not change without that number moving.
|
||
Adding a key does not move it — a consumer that greps for what it needs is unaffected by one more
|
||
line. It counts releases, not changes: it moves at most once per release, however many format
|
||
changes that release carries, because a reader only ever meets the format that was released.
|
||
|
||
The header block above section 1 records **how the result was produced**: `RUGNUX_VERSION=` and
|
||
`RUGNUX_DOWNLOAD=` (the release page of exactly that version), `DATE=`, `INPUT_FILE=` and
|
||
`OUTPUT_PREFIX=`, plus
|
||
|
||
- **`RUGNUX_GIT=`** — the commit the binary was built from, stamped at build time so it cannot go
|
||
stale in a reconfigured tree; a `-dirty` suffix marks a build from uncommitted changes.
|
||
- **`BUILD_CXX_FLAGS=`** — the compiler flags of the build (`NONE` for a plain configure). The build
|
||
is set up so that the CPU level it targets (`-march`) does not change the results, only the speed;
|
||
where two reports of one commit still disagree, this is the first line to compare.
|
||
- **`COMMAND_LINE=`** — the invocation as one shell-ready line, arguments containing spaces quoted.
|
||
- **`WALL_TIME=`** — the whole invocation in seconds. It covers everything the process did, opening
|
||
the file and setting up included, so it is a little larger than the `Processing time` written to
|
||
`<prefix>_log.txt`, which starts once the analysis does.
|
||
- **`GPU_COUNT=`** and **`GPU=`** — how many GPUs were visible and what they are, e.g.
|
||
`GPU= 4x NVIDIA A100-SXM4-80GB`; several models on one machine are listed as separate groups.
|
||
`GPU_COUNT= 0` appears on its own, with no `GPU=` line, when nothing was visible — which is the
|
||
first thing to check when a run took far longer than expected. Rugnux prints the GPU at startup
|
||
(`Compute`), before the run, so a missing GPU can be caught while there is still time to stop.
|
||
On macOS, where the Apple GPU (Metal) is used only for Bragg integration and parts of model validation and molecular replacement, the report has
|
||
`GPU_COUNT= 0` and the startup line and the log name the Apple GPU instead.
|
||
|
||
Rates, per-image costs and progress remain on stdout only.
|
||
|
||
Sections, in order: the `SUMMARY`, then `1. DATA SET AND GEOMETRY`, `2. CRYSTAL`,
|
||
`3. MERGED DATA`, `4. DIAGNOSTICS` and `5. MODEL VALIDATION` only with `--model` or `--mr` - which
|
||
also holds molecular replacement's keys where it ran ([below](#molecular-replacement))
|
||
(see [The summary](#the-summary-and-what-the-run-decided) below). The numbering is contiguous, and
|
||
the fifth section appearing renumbers nothing; a stage that did not run states that inside its
|
||
section — `MERGE= NOT_PERFORMED` — rather than the section disappearing.
|
||
|
||
**`SPOT_RESOLUTION_ESTIMATE=`** in section 1 is how far the merged data are expected to reach, read
|
||
off the found spots alone — no lattice, no integration, no merge — so it is there on a run that never
|
||
merges, and on a run that does it can be read against `INCLUDE_RESOLUTION_RANGE` in section 3. It is a
|
||
prediction, good to about 0.2 Å on rotation data; nothing is cut on it. It is **not** limited to what
|
||
the detector records: where it reads finer than the high-resolution end of `INCLUDE_RESOLUTION_RANGE`,
|
||
the crystal diffracts past the corner and the run was detector-limited.
|
||
|
||
**`JFJOCH_DATASET_SETTINGS=`** in section 1 is the geometry the run integrated at — on a rotation run
|
||
the post-refined one — written as the object `jfjoch_broker` takes it in: the four required properties
|
||
of `dataset_settings` in `broker/jfjoch_api.yaml`, joined by the three `poni_rot*_rad` angles whenever
|
||
any of them is non-zero (a body without them states a flat detector), on one line of valid JSON, so a refined beam centre
|
||
and distance can go back to the instrument for the next collection without anyone retyping them.
|
||
|
||
```
|
||
JFJOCH_DATASET_SETTINGS= {"beam_x_pxl": 2078.24, "beam_y_pxl": 2233.92, "detector_distance_mm": 190.311, "incident_energy_keV": 12.4000}
|
||
```
|
||
|
||
```bash
|
||
grep '^JFJOCH_DATASET_SETTINGS=' out_report.txt | cut -d' ' -f2- > geometry.json
|
||
```
|
||
|
||
**The beam centre in the file.** Section 1 sets the file's centre beside the two the run measured:
|
||
**`FILE_DIRECT_BEAM=`** is where the input file puts the direct beam (its beam centre, under its own
|
||
detector tilt), **`BACKGROUND_DIRECT_BEAM=`** where the scattered background puts it, with the fit's
|
||
sigma (the pre-scan's beam-centre check), and **`BEAM_CENTRE_SHIFT=`** how far the centre the result was
|
||
integrated at (`DIRECT_BEAM=`, the refined one on a rotation run) lies from the file's, in pixels.
|
||
**`BEAM_CENTRE_TOLERANCE=`** is how far this crystal on this geometry lets the centre be wrong - the
|
||
displacement at which the accumulated reflections of the longest cell axis smear to 70% of their
|
||
height, the number the log's `Beam centre check` line states, here on the run's own cell. Where the
|
||
shift is more than three times that, a **`BEAM_CENTRE_OFF`** warning gives the file's, the refined and the background
|
||
centre, the difference in pixels and millimetres, and the value to correct the beamline (or the
|
||
header) to: the run itself integrated at the refined centre, but every other program given the same
|
||
file starts from the wrong one. A run that refined no centre (stills) is warned on the background
|
||
alone, where its fit resolves the difference (three sigma) and the difference exceeds three times the
|
||
tolerance, worded as a check. Between one and three times the tolerance the summary's `Beam centre`
|
||
line says so and recommends correcting the beamline value, without a warning - most headers are a few
|
||
pixels off, and at one times the tolerance the warning fired on 107 of 250 battery sets.
|
||
|
||
```
|
||
FILE_DIRECT_BEAM= 1564.31 1702.91
|
||
BACKGROUND_DIRECT_BEAM= 1571.30 1699.85 0.62
|
||
BEAM_CENTRE_SHIFT= 7.15
|
||
BEAM_CENTRE_TOLERANCE= 3.49
|
||
```
|
||
|
||
**`XDS GEOMETRY KEYWORDS`**, the section after section 1, is the same geometry as the `XDS.INP`
|
||
keywords that carry it, ready to paste into an XDS run: `ORGX`/`ORGY` (the PONI, numbered from 1 as XDS
|
||
numbers pixels), `DETECTOR_DISTANCE`, the detector axes `DIRECTION_OF_DETECTOR_X-AXIS`/`Y-AXIS` where the
|
||
detector is tilted (they carry the tilt), `INCIDENT_BEAM_DIRECTION` with `X-RAY_WAVELENGTH`, and
|
||
`ROTATION_AXIS` - the axis the run integrated at, **negated**, because XDS turns the crystal the other way
|
||
about the axis it is given (checked with XDS `IDXREF`). Geometry only: XDS determines the cell and the
|
||
space group itself. The lines carry a fixed prefix, so
|
||
|
||
```bash
|
||
sed -n 's/^# XDS.INP> //p' myrun_report.txt
|
||
```
|
||
|
||
prints them as XDS reads them:
|
||
|
||
```
|
||
ORGX= 749.15 ORGY= 817.32
|
||
DETECTOR_DISTANCE= 175.668
|
||
DIRECTION_OF_DETECTOR_X-AXIS= 1.000000 0.000000 0.000444
|
||
DIRECTION_OF_DETECTOR_Y-AXIS= 0.000000 1.000000 -0.000976
|
||
INCIDENT_BEAM_DIRECTION= 0 0 1 X-RAY_WAVELENGTH= 0.918400
|
||
ROTATION_AXIS= 1.000000 0.000000 0.000000
|
||
```
|
||
|
||
The conventions are XDS's own (W. Kabsch, "XDS" (2010), Acta Cryst. D66, 125-132
|
||
[doi:10.1107/S0907444909047337](https://doi.org/10.1107/S0907444909047337)); this section is the one
|
||
place the run states them.
|
||
|
||
**Which pass.** A rotation run integrates twice — once at the geometry in the input file (the first
|
||
half of the sweep but at least 120°, `--prepass-fraction`), then the whole sweep again at the post-refined geometry — and can integrate a third time if a guard rejects the second pass.
|
||
There is **one** report, for the pass that became the canonical output, and `PASS=` /
|
||
`PASS_DECISION=` (`--developer`) in section 1 say which pass that is and on what evidence, so no number in the file
|
||
is ambiguous about which geometry produced it.
|
||
|
||
**Not in the report:** timing, frame rates, thread counts, per-image progress and library banners.
|
||
Those are process, not result, and stay on stdout.
|
||
|
||
## The summary, and what the run decided
|
||
|
||
The file opens with a **`SUMMARY`** section, above everything it summarises. It exists because the
|
||
report used to have no evaluative line anywhere until its last section: a run that produced garbage
|
||
and a run that produced a textbook data set read identically for their first three hundred lines.
|
||
|
||
- **`VERDICT=`** is a closed vocabulary — `OK`, `WARNINGS`, `UNUSABLE`, `FAILED`. `FAILED` means no
|
||
lattice was determined or the run was cancelled (a sample with no crystal in the beam ends here, with
|
||
`NO_LATTICE`, and the run exits with status 1); `UNUSABLE` means the data merged but carry no
|
||
usable signal; `WARNINGS` means something else needs attention; `OK` means nothing did. It is
|
||
decided from the warnings the rest of the report produced, so it introduces no new analysis and
|
||
cannot disagree with the sections below it.
|
||
- **`VERDICT_TEXT=`** is one to three sentences of free text saying the same thing in English.
|
||
- **`PATHOLOGY_FLAGS=`** is the *type* of each condition that fired, from a closed vocabulary, so a
|
||
consumer switches on a code rather than parsing a sentence: `NO_LATTICE`, `INDEXING_AMBIGUITY`,
|
||
`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`, `SCALING_NOT_CONVERGED`, `HARMONIC_CONTAMINATION`,
|
||
`SUPERCELL_POSSIBLE`, `MULTIPLE_LATTICES`, `ICE_RINGS`, `POWDER_RINGS`, `BEAM_CENTRE_OFF`, `OVERLOADS`, `OVERLAPS`. `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. Thresholds are
|
||
deliberately low: a warning is a prompt to check something, not a verdict, and some of them fire on
|
||
data that turn out fine — the closed
|
||
type for machinery, the open sentence for a person.
|
||
- Below them, one line each, the facts a reader needs before reading further: space group, cell,
|
||
mosaicity, the beam centre, the powder and ice rings, overloads, overlapping spots, multiple lattices, resolution, completeness, signal, anomalous
|
||
signal, anisotropy, pseudo-symmetry, twinning, supercell, radiation damage and the sweep. A line
|
||
states a finding that is not a condition too - weak powder rings, a possible supercell no stronger than
|
||
correct cells show, an arbitrary indexing choice (`Indexing choice`, a rotation sweep whose cell
|
||
admits alternative indexing: one sweep is indexed consistently, so it matters only against other data;
|
||
the operators are **`INDEXING_AMBIGUITY_OPERATORS=`** in section 2). On serial stills the same ambiguity
|
||
mixes the hands in the merge, and is an `INDEXING_AMBIGUITY` warning. `INDEXING_RATE=` - the share of
|
||
frames the per-image indexer took - is a stills measure: a rotation run indexes the sweep as a whole, so
|
||
there it is written only with `--developer`, and `NO_LATTICE` rests on whether the sweep was indexed.
|
||
- **`WARNING_COUNT=`** and the **`WARNING:`** lines follow, in the same section. They are what they
|
||
always were; they have moved from the bottom of the file to the top.
|
||
|
||
Then the numbered sections: **1. DATA SET AND GEOMETRY**, **2. CRYSTAL**,
|
||
**3. MERGED DATA**, **4. DIAGNOSTICS**, and **5. MODEL VALIDATION** only with `--model`.
|
||
|
||
## The reference-range table
|
||
|
||
`--report-resolution <dmin>[,<dmax>]` adds a second block of merging statistics to section 3, the
|
||
`REFRES_*` keys and a second shell table, over the resolution range it is given rather than the range
|
||
the run chose. It exists for comparison: another program's table is at that program's range, and
|
||
running rugnux *at* that range (`--scaling-high-resolution`) is not the same run — the cut moves, and
|
||
with it the symmetry decision and everything downstream of it. The reference table is instead the
|
||
same merged reflections binned again, so nothing is processed differently whether or not it is
|
||
asked for; the merged files and every decision are byte-for-byte the run's own.
|
||
|
||
- **`REFRES_RANGE=`** is the requested range (`dmax dmin`, as `INCLUDE_RESOLUTION_RANGE`; `INF` when
|
||
the run has no low-resolution limit and none was given). **`REFRES_MEASURED_RANGE=`** is the
|
||
coarsest and finest merged reflection that actually landed in it.
|
||
- **`REFRES_COMPLETENESS=`**, **`REFRES_MULTIPLICITY=`**, **`REFRES_I_OVER_SIGMA=`**,
|
||
**`REFRES_R_MEAS=`**, **`REFRES_CC_HALF=`**, **`REFRES_SIGANO=`**, **`REFRES_CC_ANOM=`**,
|
||
**`REFRES_UNIQUE_REFLECTIONS=`** and **`REFRES_TOTAL_OBSERVATIONS=`** are the overall numbers over
|
||
that range, under the same absent-when-unmeasured rule as their section-3 namesakes.
|
||
**`REFRES_ISA=`** is the error model refitted on the reflections of this table alone, in XDS's
|
||
convention, so it reads against an `ISa` produced at that range; the table itself is merged under
|
||
the run's own model.
|
||
- **The table holds only what the run kept.** Where the reference range is finer than the run's own
|
||
limit, the shells past that limit are empty by the run's decision — it judged them to carry no
|
||
signal and did not merge them — and are printed as `past the run's own limit of X A: not merged
|
||
(N possible)` rather than as zeros; the shell the limit falls inside is marked. **`REFRES_SHELLS_PAST_LIMIT=`**
|
||
counts those shells (0 when the range lies within the run's own), so a consumer can tell *not
|
||
merged* from a measured zero. `REFRES_COMPLETENESS` counts their reflections as missing; every
|
||
other overall number is over the shells the run reached.
|
||
|
||
The shells are equal steps in 1/d² between the two bounds, as XDS's are, so at XDS's
|
||
`INCLUDE_RESOLUTION_RANGE` the two tables read row for row.
|
||
|
||
## The developer report
|
||
|
||
`--developer` renders the same report in full. The default report carries what a person deciding
|
||
*keep or recollect* acts on; `--developer` adds the pipeline's own internals — the anisotropy
|
||
detection gate's parameters, the space-group operator and candidate tables, the model-fit null, the
|
||
sweep-quality internals, the twinning statistics measured before the search, and the long
|
||
explanatory passages — plus advisories about the cut's own behaviour that no user can act on.
|
||
|
||
Nothing is computed differently and nothing is lost by leaving the flag off: the report is built
|
||
once, in full, and the flag selects how much of it is written. Every key the default report writes,
|
||
`--developer` writes too.
|
||
|
||
## The space group, and the Sohncke answer beside it
|
||
|
||
The space group lives in section 2: `SPACE_GROUP_NAME=` / `SPACE_GROUP_NUMBER=`, with
|
||
`SPACE_GROUP_ALTERNATIVES=` naming the candidates the data could not separate — an enantiomorphic
|
||
partner among them — and, on a group that has such a partner, `SPACE_GROUP_ENANTIOMORPH=` saying
|
||
whether the hand is open (`UNDETERMINED`), asserted by the user (`GIVEN`), or taken from an accepted
|
||
model (`ASSUMED_FROM_MODEL`).
|
||
|
||
`SPACE_GROUP_SCREW_UNDETERMINED=` names the **axes whose screw these data could not decide at all**,
|
||
as one or more of `a`, `b`, `c`; when every screw the data could show was judged it reads `NONE`
|
||
and, like the other keys whose answer is "nothing to report", is written only with `--developer`. It
|
||
fires when the axial row a screw lives on was never recorded — it lay in the spindle's blind cone,
|
||
or outside the resolution range — so nothing was measured that could confirm or refuse the screw.
|
||
On such an axis `SPACE_GROUP_NAME=` is not an answer: the answer is that group **or** any of
|
||
`SPACE_GROUP_ALTERNATIVES`, and no measurement in the run chooses between them. What is written to
|
||
the `.mtz`/`.cif`/`.hkl` is unchanged — the member claiming no screw, because a reflection file must
|
||
carry one group — and the report prints the axis, why the row could not be judged, and what the
|
||
alternatives are. To settle it, record the missing row: a different crystal orientation, or a sweep
|
||
that reaches it. With `--developer` the space-group section names the same axes in prose beside the
|
||
per-zone screw table.
|
||
|
||
`SETTING_OPERATOR=` and `SETTING_SOURCE=` in section 2 say which axes the files are on: the
|
||
reindexing operator from the axes the space group was determined on (CCP4 style, `h,k,l` where
|
||
nothing moved) and what chose the setting - `STANDARD`, `CELL` (`-C`), `SPACE_GROUP` (a non-standard
|
||
`-S`), `MODEL` (a `--model` that fits) or `REFERENCE` (`-z`). `SPACE_GROUP_NAME`, the cell and every
|
||
file the run writes are in that setting (see RUGNUX_ADVANCED.md, "The setting the files are written
|
||
in").
|
||
|
||
`SOHNCKE_SPACE_GROUP=` in section 2 is written on every run whose space group was determined by the
|
||
search; a run given its group with `-S` has no Sohncke candidate to name and omits the key. Where the
|
||
search found a glide plane, `SPACE_GROUP_NAME=` names the group with it and this names the best group
|
||
without - a crystal of chiral molecules, which is any protein, cannot have a glide plane or an
|
||
inversion centre, so a reader who knows their sample is a protein reads this key and needs no second
|
||
run. Where no glide was found the two keys read the same, deliberately: greppability is the point, and
|
||
a key that appears only sometimes has to be tested for before it can be read.
|
||
|
||
`SPACE_GROUP_CENTRE=` says how the **centre of symmetry** of a glide group was settled; it is written
|
||
only where a non-Sohncke group was adopted. `IMPLIED_BY_ABSENCES` - the group is centrosymmetric and no
|
||
group without a centre predicts its absences (P2_1/c, Pbca, Ia-3d), so the screws and glides found
|
||
imply the centre. `ABSENT_BY_ABSENCES` - the reverse (I-42d, Fdd2): no centrosymmetric group predicts
|
||
these absences. `NOT_DETERMINED` - a group with exactly the same absences and the other answer exists
|
||
(C2/c and Cc, Pnma and Pna2_1), and it is in `SPACE_GROUP_ALTERNATIVES`. Friedel's law hides the centre
|
||
from the symmetry of merged intensities, so the centrosymmetric group is written by default: a missed
|
||
centre is the common error in small-molecule space-group assignment. `ABSENT_BY_STATISTICS` - the
|
||
same situation, but the intensity distribution read acentric and the lattice ruled twinning out, so the
|
||
group without a centre was written; `CENTRE_TWINNING_EXCLUDED=` says, for these two, whether the
|
||
lattice ruled twinning out. Two non-centrosymmetric groups can also share absences (I-42d and
|
||
I4_1md); the lowest-numbered is written and the other listed as the alternative.
|
||
|
||
`CENTRE_STATISTICS_*` are the intensity statistics behind that, read on every searched run on the
|
||
general reflections - those no operator of the Laue class but the identity maps to themselves, which
|
||
are centric exactly when the crystal is centrosymmetric; `CENTRE_STATISTICS_REFLECTIONS=` is how many
|
||
there were. `CENTRE_STATISTICS_L=` is <|L|> (Padilla & Yeates; 0.5 acentric, 2/pi centric),
|
||
`CENTRE_STATISTICS_E2_MINUS_1=` <|E^2-1|> (0.736 / 0.968) and `CENTRE_STATISTICS_NZ01=` N(0.1), the
|
||
fraction with E^2 < 0.1 (0.095 / 0.248). Each has an `_F` beside it (`CENTRE_STATISTICS_L_F=`,
|
||
`_E2_MINUS_1_F=`, `_NZ01_F=`) that places the statistic between the values the same reflections read
|
||
when simulated acentric (0) and centric (1) with their own shell means and sigmas;
|
||
`CENTRE_STATISTICS_CONTROL_F=` does the same for the reflections centric in every candidate, which
|
||
must read centric. The statistics are written only where L-test pairs and control reflections were
|
||
found. `CENTRE_STATISTICS_VERDICT=` is `ACENTRIC` when <|L|> reads `_F` <= 0.3 and the other two
|
||
<= 0.5, `NOT_APPLICABLE` when any of the three falls outside -0.3..1.3 (a structure with a few heavy
|
||
atoms on special positions reads beyond centric) or the control reads below 0.5, and `INCONCLUSIVE`
|
||
otherwise. A twinned crystal reads acentric whether
|
||
or not it has a centre, which is why the verdict decides only with twinning excluded by the lattice.
|
||
|
||
`SPACE_GROUP_ENANTIOMORPH=` in section 2 reads **`ASSUMED_FROM_MODEL`** when the hand written in the
|
||
files is the model's. Assumed, not determined: merged intensities cannot see the hand at all — |F| is
|
||
invariant under the change of hand — so an accepted model asserts it out of prior chemical knowledge.
|
||
It is only ever written where `MODEL_FIT= ACCEPTED`, and the anomalous difference map vetoes it
|
||
outright where the map says the model and the data are in opposite hands. (Before `REPORT_VERSION= 6`
|
||
this value was spelled `DETERMINED_FROM_MODEL` and was emitted whenever a model file merely parsed.)
|
||
|
||
## Sweep quality, the disposition, and their vocabularies
|
||
|
||
Section 4 lists the stretches of the sweep over which the crystal delivered much less than the rest
|
||
of the run — the feedback a beamline control system needs to tell an operator that a crystal should
|
||
be recentred or recollected — says what became of each of them, measures what keeping each one
|
||
costs the merged intensities, and drops the stretches that cost too much.
|
||
|
||
```
|
||
SWEEP_QUALITY_STATUS= COMPUTED
|
||
SWEEP_QUALITY_COUNT= 2
|
||
SWEEP_QUALITY_REASONS= no_diffraction crystal_out_of_beam weak_diffraction loss_of_centring radiation_damage inconsistent_with_merge
|
||
SWEEP_DISPOSITIONS= merged downgraded rejected
|
||
FRAMES_MERGED= 1663
|
||
FRAMES_DOWNGRADED= 101
|
||
FRAMES_REJECTED= 36
|
||
FRAMES_REJECTED_PCT= 2.00
|
||
ROTATION_REJECTED_DEG= 3.6
|
||
FRAMES_BLANK_START= 0
|
||
FRAMES_BLANK_END= 0
|
||
SWEEP_ROTATION= 180.0
|
||
FLUX_PEAK_TO_TROUGH= 1.03
|
||
SCALE_MODULATION_PEAK_TO_TROUGH= 1.00
|
||
|
||
FIRST_IMAGE LAST_IMAGE N_IMAGES ROTATION REASON SEVERITY SCALE CC INDEXED DISPOSITION DELTA_CC_HALF DELTA_CC_HALF_SE
|
||
----------- ----------- --------- -------- ----------------------- -------- ------ ------ -------- ----------- ------------- ----------------
|
||
500 600 101 10.1 crystal_out_of_beam 0.83 0.12 0.30 0.02 downgraded +0.0004 0.0031
|
||
612 630 19 1.9 no_diffraction 0.98 0.02 0.00 0.00 rejected -0.0481 0.0110
|
||
----------- ----------- --------- -------- ----------------------- -------- ------ ------ -------- ----------- ------------- ----------------
|
||
```
|
||
|
||
Of those keys, `SWEEP_QUALITY_COUNT` and the five disposition keys (`FRAMES_MERGED`,
|
||
`FRAMES_DOWNGRADED`, `FRAMES_REJECTED`, `FRAMES_REJECTED_PCT`, `ROTATION_REJECTED_DEG`) and the two
|
||
blank-end counts (`FRAMES_BLANK_START`, `FRAMES_BLANK_END`) are in the default report; `SWEEP_QUALITY_STATUS`, `SWEEP_QUALITY_REASONS`, `SWEEP_DISPOSITIONS`,
|
||
`SWEEP_ROTATION`, `FLUX_PEAK_TO_TROUGH` and `SCALE_MODULATION_PEAK_TO_TROUGH` appear with
|
||
`--developer` (the default report states in prose whether the diagnostic ran).
|
||
|
||
The three frame counts **partition the sweep** — every processed image is exactly one of them and
|
||
they add up to the frame count — so `FRAMES_REJECTED_PCT` is the answer to "how much of this
|
||
experiment was useless". It is reported beside `ROTATION_REJECTED_DEG` on purpose: a percentage of
|
||
*frames* moves when the same experiment is re-sliced, and a percentage of the *rotation* does not.
|
||
The prose headline above the table states both.
|
||
|
||
Frames at either **end** of a rotation sweep that recorded no diffraction at all - a shutter that
|
||
opened late or closed early, or a beam that went off - are left out before scaling and are not a
|
||
degraded range: they raise no `SWEEP_GAPS` warning. `FRAMES_BLANK_START` and `FRAMES_BLANK_END` count
|
||
them (they are also among `FRAMES_REJECTED`), and a prose line names them. A frame is blank when its
|
||
reflections show no diffraction - as many stand more than 3 sigma above zero as below it, and that
|
||
count is clearly below the run's typical frame - and its background says the beam was off (nearer to
|
||
none than to the run's typical frame). A partly exposed frame recorded something and stays in; a
|
||
crystal that has left the beam still scatters the beam into the background, so its frames stay too
|
||
and are reported in the table above.
|
||
|
||
A `SWEEP_GAPS` warning is given, one per range, where the degraded ranges together cover at least 1 %
|
||
of the sweep's rotation; below that - a frame or two - they are in the table and the summary's `Sweep`
|
||
line, and the warning lines in `--developer`.
|
||
|
||
`SWEEP_QUALITY_STATUS` distinguishes **`COMPUTED`** (the diagnostic ran; a count of 0 means the sweep
|
||
was clean throughout) from **`NOT_COMPUTED`** (it did not run — no scaling and merging, or stills
|
||
data). A consumer must not read a missing table or a zero count as "clean" without checking it.
|
||
`SWEEP_QUALITY_REASONS` lists the whole vocabulary this version can emit, so an unknown code is
|
||
distinguishable from a missing one.
|
||
|
||
| Reason code | Meaning |
|
||
|-------------|---------|
|
||
| `no_diffraction` | The range recorded essentially no diffraction from the indexed lattice. |
|
||
| `crystal_out_of_beam` | Frames were lost: over the range a per-image scale could be fitted far less often than over the run. |
|
||
| `weak_diffraction` | The frames all still index, but with much less intensity — the cause was not determined. |
|
||
| `loss_of_centring` | One cycle of modulation per revolution: the crystal is off the rotation axis. |
|
||
| `radiation_damage` | The range runs to the end of a sweep whose quality was already decaying. |
|
||
| `inconsistent_with_merge` | The frames diffract as the run does, but their intensities do not agree with it — the only evidence is `DELTA_CC_HALF`, so the cause is not named. |
|
||
|
||
The vocabulary is **closed and stable**: a code is never renamed, and never reused for a different
|
||
meaning. New codes are only ever added, and adding one moves `REPORT_VERSION` at the next release.
|
||
|
||
The columns are: `FIRST_IMAGE`/`LAST_IMAGE` — inclusive, in processed-image ordinals (the numbering
|
||
of `<prefix>_plot.txt` and of every other per-image array `rugnux` writes; with `-s`/`--stride` the
|
||
source image is `start + ordinal * stride`); `ROTATION` — the width of the range in degrees;
|
||
`SEVERITY` — the fraction of the run's typical diffracting power missing over the range, 0 (as good
|
||
as the run) to 1 (nothing at all); `SCALE` and `CC` — the range's mean per-image scale and
|
||
CC-to-merge relative to the run median; `INDEXED` — the fraction of the range's frames that were
|
||
scaled at all; `DISPOSITION` — what became of it; `DELTA_CC_HALF` and `DELTA_CC_HALF_SE` — what
|
||
keeping it costs the merged intensities, and how precisely that is known. Every range also appears as
|
||
a `WARNING:` sentence in the SUMMARY, with the same cost in words. A range is split where its
|
||
disposition changes, so each row is wholly kept or wholly rejected.
|
||
|
||
### What the disposition means, and what decides it
|
||
|
||
| Disposition | Meaning |
|
||
|-------------|---------|
|
||
| `merged` | The frame's observations are in the merged data at their own weight. |
|
||
| `downgraded` | They are in the merged data, but over a stretch the run itself flagged, carried at the reduced weight the frame's own scale and sigmas give it. Nothing extra is subtracted: for weak-but-consistent data that reduced weight *is* the honest weight, and a second, invented per-frame weight would double-count with the σ's. |
|
||
| `rejected` | Nothing of the frame reached the merge — because ΔCC1/2 convicted it, because an earlier guard dropped a frame whose scale had collapsed to an unusable number, or because the frame recorded nothing to drop in the first place. To a user asking how much of the experiment was useless these are the same answer, and the `REASON` column separates them. |
|
||
|
||
`DELTA_CC_HALF` is **ΔCC1/2**: the overall CC1/2 of the merged data **with** the range minus the
|
||
CC1/2 **without** it, evaluated over the reflections the range touches. Negative means keeping the
|
||
range makes the merged intensities worse. It is computed in the σ-τ form — no random half-dataset
|
||
split, so the same input gives the same answer every run — with each reflection's error variance taken
|
||
from the observed scatter of its own observations, not from the error model's σ's (a bad stretch claims
|
||
the same σ's as a good one, so an error-model estimate would read a stretch that adds noise as one that
|
||
adds precision). It is a CC1/2 over **the range's own reflections**, not over the whole dataset — a
|
||
range that touches a few hundred reflections can carry a large ΔCC1/2 without the dataset's headline
|
||
CC1/2 moving by anything like as much. `DELTA_CC_HALF_SE` is the standard error of a CC1/2 on that
|
||
many reflections, in the same units, and a ΔCC1/2 smaller than it says nothing.
|
||
|
||
A range is rejected only where ΔCC1/2 is **both well below the rest of this run's own batches and
|
||
several standard errors below zero**, and only where **every frame in it is one the per-image channels
|
||
call worse than the run's typical frame** — the scale and the CC to the merge, frame by frame and never
|
||
as an average over the stretch, because an average cannot tell a uniformly bad stretch from a healthy
|
||
arc lying beside a dead one. All three are needed: a healthy crystal merges at
|
||
CC1/2 ≈ 0.999, where a harm of 0.001 in CC is already many standard errors, so significance alone
|
||
convicts frames on clean data whose removal moves nothing; and ΔCC1/2 is itself measured against
|
||
the merge, so removing whichever frames disagree with it most improves every agreement statistic
|
||
whether or not anything was wrong with them — the decision has to be triggered by a channel that owes
|
||
nothing to the merge, and only then confirmed by what the merge does. The test runs last, after the per-frame scale, the
|
||
decay slope and the per-batch relative-*B* have been fitted, so it judges corrected data. The decision
|
||
is taken over 10° batches — the same batches as the radiation-damage curve — and over those batches
|
||
doubled, and doubled again, up to a quarter of the sweep: a defect much longer than a batch is
|
||
invisible one batch at a time, because each batch inside it is judged against a merge that still
|
||
contains the rest of the defect. Where the harm lies is then settled finely: each edge of the
|
||
convicted stretch is slid frame by frame with the *whole* stretch re-measured at every position, so
|
||
the range is reported where it actually lies rather than at the batch grid, and the reflection count
|
||
the verdict rests on never shrinks with the edge. Each edge is then pulled back off any frame the
|
||
per-image channels call normal, and what is left has to carry the verdict again on its own: a stretch
|
||
that cannot be taken without healthy frames holds more than one thing and is not removed at all. A rejected
|
||
stretch is never narrower than one rocking event, because the partials of one event are combined into
|
||
the same intensities and inside it no frame can be judged apart from its neighbours. Never more than
|
||
a quarter of the sweep is removed.
|
||
|
||
**What ΔCC1/2 cannot do**, because the report must not imply otherwise:
|
||
|
||
- it says nothing about the **cause**: a shutter fault and a crystal that slipped have the identical
|
||
signature, both integrating background, so the cause comes from the `REASON` column and never from
|
||
the ΔCC1/2 itself;
|
||
- a **second lattice entering** is invisible to it: those spots were never integrated, so they are not
|
||
in the merged intensities it measures;
|
||
- a **centring drift that is pure attenuation** reads ≈ 0. That is the right answer, not a blind spot:
|
||
the data are weak but consistent, the σ's already say so, and their ΔCC1/2 is the evidence that
|
||
discarding them would cost completeness for nothing;
|
||
- it is attributed to the frame carrying a rocking event's **peak** partial, so it cannot resolve a
|
||
single frame: a stretch narrower than one rocking event is never rejected, and the edges of a
|
||
rejected stretch are soft to within half an event;
|
||
- `loss_of_centring` needs ≥ 350° of sweep to be named at all. On a 90° sweep the same drift is still
|
||
*detected*, only as `crystal_out_of_beam` or `weak_diffraction` — "cause not determined" here means
|
||
this sweep cannot determine it, not that it is undeterminable.
|
||
|
||
The same finding is written **per image** into the `_process.h5` as `/entry/MX/sweepQuality` and
|
||
`/entry/MX/frameDisposition`, when one is written — see
|
||
[HDF5](HDF5.md#41-entrymx--spot-finding-and-indexing-cxi-style).
|
||
|
||
`SPINDLE_SYMMETRY_AXIS_ANGLE_DEG=` and `SPINDLE_SYMMETRY_AXIS_ORDER=` (`--developer`) in section 4 say how the crystal
|
||
sat on the goniometer: the angle between the spindle and the nearest symmetry axis, and that axis's
|
||
order. They are descriptive: neither convicts nor clears the mounting on its own, because an aligned
|
||
axis of any order maps the sweep's blind cone onto itself while an axis near perpendicular does the
|
||
same only when it is a lone 2-fold, and only the nearest axis is reported. (New in
|
||
`REPORT_VERSION= 7`.)
|
||
|
||
`SPINDLE_LOST_UNIQUE_FRACTION=` in section 4 is the exact verdict the angle cannot give: the fraction
|
||
(0-1, so 0.0300 means 3%) of unique reflections, to this run's resolution limit, that the mounting
|
||
made unmeasurable - the part of the sweep's blind double cone that no operator of the measured point
|
||
group maps onto measured territory, computed in the crystal's actual indexed orientation. 0.0000
|
||
means the mounting cost nothing; the run warns when the group recovers less than half of the cone's
|
||
content. The same number is written to the master file as `/entry/MX/spindleLostUniqueFraction`, so a
|
||
pipeline can read it from either output without parsing prose. Written on every rotation run that
|
||
determined a space group and merged reflections.
|
||
|
||
## Powder contamination
|
||
|
||
A crystalline phase other than the crystal, diffracting as rings among its reflections — hexagonal
|
||
ice, a shower of microcrystals, a salt out of the cryoprotectant. It is measured on **every** run, in
|
||
the pre-scan, from the spots found there, and reported whether or not anything acted on it: a user
|
||
whose crystal sat in a powder is told so even where the run indexed perfectly well. Only hexagonal ice
|
||
has rings that can be named in advance, so `POWDER_RINGS_A` is what *this* sample showed.
|
||
|
||
```
|
||
POWDER_RINGS_DETECTED= TRUE
|
||
POWDER_RING_COUNT= 24
|
||
POWDER_SPOT_FRACTION= 0.412
|
||
POWDER_RINGS_SEPARABLE_TO= 2.31
|
||
POWDER_RINGS_A= 3.897 3.671 3.447 ...
|
||
POWDER_EXCLUDED_FROM_INDEXING= TRUE
|
||
POWDER_INDEXING_D_MIN= 4.91
|
||
```
|
||
|
||
`POWDER_RINGS_DETECTED` is written on every merging run and is `FALSE` on nearly all of them; the
|
||
rest of the keys appear only where rings were found. `POWDER_SPOT_FRACTION` is the share of the
|
||
pre-scan's spots the rings hold *over* the smooth fall-off around them — what the contaminant
|
||
contributes, not what happens to lie in a ring band. `POWDER_RINGS_SEPARABLE_TO` is the resolution
|
||
past which the rings crowd together too tightly to be told apart, and so the finest an indexing pass
|
||
can be asked to trust on such a pattern; it is absent where they stay separable over the whole range,
|
||
which is the ordinary case. `POWDER_EXCLUDED_FROM_INDEXING` says whether the run needed them
|
||
left out to index at all (with `POWDER_INDEXING_D_MIN` the resolution the retried first pass used).
|
||
Rings are detected far more often than they are excluded: exclusion happens only where a first pass
|
||
found no usable lattice. The rings are split between those on a hexagonal-ice position
|
||
(**`POWDER_ICE_RING_COUNT=`**, **`POWDER_ICE_SPOT_FRACTION=`**) and the rest - a salt, microcrystals, another
|
||
phase (**`POWDER_NON_ICE_SPOT_FRACTION=`**); the two fractions add up to `POWDER_SPOT_FRACTION=`. The
|
||
summary's `Powder` line gives both. A warning under the `ICE_RINGS` flag is given where the ice rings hold
|
||
at least 5 % of the spots, and one under `POWDER_RINGS` where the other rings do.
|
||
|
||
Hexagonal ice is also measured by the merge itself, which leaves reflections on the ice rings out of
|
||
scaling (and keeps them in the merge) where it finds ice:
|
||
|
||
```
|
||
ICE_RINGS_DETECTED= TRUE
|
||
ICE_RING_SCORE= 2.69
|
||
ICE_SPOT_RATIO= 1.08
|
||
ICE_REFLECTIONS_ON_RINGS_PCT= 25.7
|
||
```
|
||
|
||
**`ICE_RING_SCORE=`** is the strongest ice ring over the smooth radial background (fine-grained ice
|
||
that makes a smooth ring), **`ICE_SPOT_RATIO=`** the pile-up of found spots on the ring positions
|
||
against the ice-free flanks beside them (ice in large crystallites); 1 is no ice on either.
|
||
**`ICE_RINGS_DETECTED=`** is `TRUE` where either passes its gate (1.5 and 2.0), and
|
||
**`ICE_REFLECTIONS_ON_RINGS_PCT=`** is then the share of the integrated reflections set aside from
|
||
scaling. The summary has an `Ice` line, and where the merge found ice an `ICE_RINGS` warning prompts a
|
||
look at the ice-ring shells (one warning line, whichever of the two measurements raised it). The measurement is described in
|
||
[CPU/GPU data analysis ▸ Resolution and ice-ring handling](CPU_DATA_ANALYSIS_IMAGE.md#33-resolution-and-ice-ring-handling).
|
||
|
||
## Overloads and overlapping spots
|
||
|
||
Two ways the measurement, rather than the crystal, cost reflections - each with what to change at the
|
||
next collection. Both are in section 4, both have a summary line, and both warn at a low threshold.
|
||
|
||
```
|
||
OVERLOADED_REFLECTIONS= 1740
|
||
OVERLOADED_REFLECTIONS_PCT= 0.017
|
||
OVERLOADED_REFLECTIONS_LOW_RES_PCT= 0.418
|
||
OVERLAPPED_REFLECTIONS_PCT= 11.10
|
||
OVERLAPPED_REFLECTIONS_MAJOR_PCT= 0.44
|
||
```
|
||
|
||
(a strongly diffracting lysozyme sweep: an `OVERLOADS` warning, no `OVERLAPS` one)
|
||
|
||
**`OVERLOADED_REFLECTIONS=`** counts the integrated reflections - every frame's partial, before the
|
||
merge - with a saturated pixel in the signal disk (or one the detector could not count on that frame),
|
||
and **`OVERLOADED_REFLECTIONS_PCT=`** their share. They are not measurements: the merge leaves them out
|
||
(a rotation merge drops the whole rocking event, `OBSERVATIONS_REJECTED_OVERLOAD=` in section 3), and
|
||
they are the strongest reflections the crystal gave, so they concentrate at low resolution;
|
||
**`OVERLOADED_REFLECTIONS_LOW_RES_PCT=`** is their share among the reflections coarser than 4 Å. An
|
||
**`OVERLOADS`** warning fires from 0.05% of all integrated reflections or 0.25% of those coarser than 4 Å,
|
||
and recommends attenuating the beam or shortening the exposure (or a second, attenuated low-resolution
|
||
sweep).
|
||
|
||
Stills are different: a still has no rocking event, and its overloaded observations are the fully
|
||
recorded ones of the strongest reflections, so they are kept in the merge as a lower bound - the box sum
|
||
with every saturated pixel at the saturation limit - and are not counted above.
|
||
**`OVERLOADED_REFLECTIONS_KEPT=`** counts them and **`OVERLOADED_REFLECTIONS_KEPT_PCT=`** gives their share
|
||
of the integrated reflections; the `OVERLOADS` warning fires from 0.05%.
|
||
|
||
**`OVERLAPPED_REFLECTIONS_PCT=`** is the share of the predicted reflections whose signal disk a nearer
|
||
neighbour's prediction takes pixels from, as the integrator's overlap treatment (`--overlap`, default
|
||
`exclude`) assigns them, and **`OVERLAPPED_REFLECTIONS_MAJOR_PCT=`** the share left with less than
|
||
`--overlap-minpk` (default 75%) of the disk its own - the ones XDS's MINPK would reject. Under
|
||
`exclude` the shared pixels are left out of the profile fit, which keeps the reflection at a cost in
|
||
precision. An **`OVERLAPS`** warning fires from 1% in the second number and recommends a longer
|
||
detector distance, finer rotation slicing or a smaller beam. Neither key is written with
|
||
`--overlap off`, which assigns no pixel to anyone.
|
||
|
||
## Index-2 superstructure
|
||
|
||
On rotation data, section 4 reports whether the lattice the run adopted has intensity at half-integer
|
||
positions it does not index. On 60 frames spread over the sweep, after each frame's own integration, the
|
||
lattice is predicted doubled along all three primitive axes and integrated to 3 Å; the reflections split
|
||
into eight parity classes of h, k and l, of which `0 0 0` is the lattice itself and each of the other
|
||
seven is one index-2 superstructure. The class read there is also followed out to the run's own limit,
|
||
counting only half-integer reflections that no lattice reflection on the same frame lies within the
|
||
background radius of, each resolution shell against the median of the six other classes - which a single
|
||
doubling leaves empty, so they measure what sits at a half-integer node without being a reflection. The
|
||
log prints that table (`Supercell probe to the limit`).
|
||
|
||
**`SUPERCELL_CLASS=`** is the parity class with the most intensity over 20–3 Å.
|
||
**`SUPERCELL_OCCUPANCY_PCT=`** is its mean intensity against the lattice's own reflections on the same
|
||
frames, and **`SUPERCELL_ROCK_PCT=`** (± **`SUPERCELL_ROCK_SE_PCT=`**) the part of it that follows the
|
||
partiality the way a Bragg reflection does, from a fit I = a + b p over the class, on the same scale.
|
||
**`SUPERCELL_I_OVER_SIGMA=`** is its mean I/σ. A class near zero on both is empty. One that is occupied
|
||
and rocks holds reflections of a superstructure this cell does not index; **`SUPERCELL_DOUBLED_CELL=`**
|
||
is the Niggli-reduced cell the lattice doubles to. One that is occupied but hardly rocks is diffuse or
|
||
disordered intensity rather than Bragg reflections.
|
||
|
||
**`SUPERCELL_POSSIBLE=`** is `TRUE` 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 says the doubled cell is there in the data, not that it is the cell to refine
|
||
in: a crystal whose two halves are nearly alike (a pseudo-translation) is described by either cell, and
|
||
spots of further lattice domains can land on the half-integer positions too. A `TRUE` is also a warning
|
||
under the `SUPERCELL_POSSIBLE` flag, and the summary's `Supercell` line carries the same advice.
|
||
|
||
**Both cells merged.** Where the class stands clear of the six empty ones out to the limit (in at least
|
||
three shells where it is measured above its noise and most of its reflections are resolved from the
|
||
lattice's, at more than twice the strongest of them in standard errors) and
|
||
grows significantly with resolution to a quarter of the lattice's intensity or more in the finest shell
|
||
both are measured in - the half cell holds at low resolution and not at high, the shape of a
|
||
pseudo-translation breaking down - the run integrates and merges the doubled cell as well, on the same
|
||
orientation and geometry, and decides with both merges in hand. The size of the class does not decide
|
||
it - crystals deposited in the half cell carry classes as strong as one deposited in the doubled cell.
|
||
The doubled cell is the answer only where, in the doubled merge, one translation - half a cell plus a
|
||
small offset, fitted over the class - modulates at least half of the added class in every resolution
|
||
shell, so the two halves of the cell are one content displaced - and where the doubled merge is not more
|
||
symmetric than the half cell's, which a superstructure of it cannot be. A class that is there whatever the
|
||
direction (copies that differ in content, twin domains, neighbouring reflections) keeps the half cell.
|
||
**`DOUBLED_CELL_ADOPTED=`** says which was written as the answer and **`DOUBLED_CELL_DECISION=`** why;
|
||
**`DOUBLED_CELL_OTHER_FILE=`** names the other hypothesis's merged file (`<prefix>_doubled.mtz`, or
|
||
`<prefix>_halfcell.mtz` where the doubled cell was adopted, with the rest of its files under the same
|
||
prefix), and **`DOUBLED_CELL_OTHER_CELL=`**, **`DOUBLED_CELL_OTHER_SPACE_GROUP=`**,
|
||
**`DOUBLED_CELL_OTHER_D_MIN=`**, **`DOUBLED_CELL_OTHER_CC_HALF=`** and, with `--model`,
|
||
**`DOUBLED_CELL_OTHER_R_FREE=`** describe it. Compare the two in refinement.
|
||
|
||
## 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_<n>_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_<n>_KIND=`** — `DOMAIN`: the same cell, misoriented, over the whole sweep (a split
|
||
crystal; more than 10° from the main lattice, the report calls it a second 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_<n>_LATTICE=`** and **`EXTRA_LATTICE_<n>_CELL=`** — its crystal system, centring and
|
||
conventional cell.
|
||
- **`EXTRA_LATTICE_<n>_VOLUME_RATIO=`** — its reduced cell volume over the main one's.
|
||
- **`EXTRA_LATTICE_<n>_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_<n>_SPOTS_PCT=`**, **`EXTRA_LATTICE_<n>_INTENSITY_PCT=`** — its share of the non-ice
|
||
spots and of their intensity.
|
||
- **`EXTRA_LATTICE_<n>_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 the domains (`DOMAIN`, `TWIN_DOMAIN`, `SEGMENTED`);
|
||
a `RELATED_CELL` or `FOREIGN` lattice is listed but not counted, since it is as often a wrong main lattice or tNCS
|
||
as a second crystal,
|
||
and **`MULTIPLE_LATTICES=`** is `TRUE`, with a warning under the `MULTIPLE_LATTICES` flag, where that
|
||
sum is at least 10 % - the domains together, not the strongest alone. 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.`: the value under *SUGGESTED VALUES FOR INPUT PARAMETERS* at the
|
||
end of `INTEGRATE.LP`, which `CORRECT.LP` repeats. On in-house rotation data it reads 0.90× that value
|
||
(median over 34 data sets). XDS's per-image `SIGMAR` column and the per-block *CRYSTAL MOSAICITY* in
|
||
`INTEGRATE.LP` are a different number - they run about 1.35× higher - and are not the comparison. 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
|
||
vector. It is the pathology that most reliably breaks molecular replacement, because the modulation it
|
||
puts on the intensities is not in the search model. Section 4 reports it beside twinning, because the
|
||
two interact. The algorithm is in
|
||
[CPU/GPU data analysis ▸ Twinning and translational pseudo-symmetry](CPU_DATA_ANALYSIS_DECISIONS.md#132-twinning-check-and-translational-pseudo-symmetry).
|
||
|
||
**`TNCS_DETECTED=`** is `TRUE`, `FALSE`, `INCONCLUSIVE` or `NOT_MEASURED`. The last two are not
|
||
`FALSE`: `NOT_MEASURED` means the merge has too few reflections in 20–5 Å to compute the statistic at
|
||
all, `INCONCLUSIVE` means the Patterson was measured but too few acentric reflections remain to test
|
||
whether the vector it names modulates the intensities. Neither is a statement that the crystal has no
|
||
pseudo-symmetry.
|
||
|
||
A warning under the `PSEUDO_TRANSLATION` flag is given wherever `TNCS_DETECTED= TRUE`. Below a Patterson
|
||
peak of 20 % of the origin (the height phenix.xtriage flags) the detection is significant but its
|
||
modulation is small; the warning and the summary call it weak and ask to check whether molecular
|
||
replacement needs it.
|
||
|
||
`TRUE` requires **both** of two tests, because either alone over-calls by about a factor of two:
|
||
|
||
- **`TNCS_PATTERSON_PEAK_PCT=`** — the largest off-origin peak of the native Patterson, as a
|
||
percentage of the origin peak, counting only peaks farther than 15 Å from any origin-equivalent
|
||
lattice point. **`TNCS_PATTERSON_PEAK_Z=`** scores it against **`TNCS_PATTERSON_NULL_PCT=`**, the
|
||
same map recomputed with the intensities permuted within resolution shells. The null is per dataset
|
||
and not a table: the noise floor of this statistic runs from about 1% on a large merge to about 18%
|
||
on a small one, so no fixed percentage separates the two populations.
|
||
- **`TNCS_MODULATION=`** — the ratio of the strongest to the weakest bin mean of ⟨E²⟩ over the phase
|
||
frac(**h**·**u**), with **u** the refined peak vector (**`TNCS_VECTOR=`**, fractional, and
|
||
**`TNCS_VECTOR_LENGTH=`** in Å). **`TNCS_MODULATION_NULL=`** is the same search started from random
|
||
vectors, so the contrast the search itself can manufacture is measured rather than assumed.
|
||
|
||
The vector is good to about 0.05 fractional. It is a starting point for a program that refines it,
|
||
not a refined result: the refinement maximises the modulation, not the accuracy of the vector.
|
||
|
||
**`TNCS_PSEUDO_CENTRED=`** and **`TNCS_SUBLATTICE=`** are separate claims and are deliberately not
|
||
merged. A vector that is a rational translation `1/q` of the cell means the crystal is pseudo-centred;
|
||
the cell itself is not in question, because the suppressed class is weak rather than absent and a
|
||
smaller cell would contradict it. Only `TNCS_SUBLATTICE= NEAR_EXTINCT_CLASS` — the suppressed class
|
||
almost gone — says the reported cell may be a supercell.
|
||
|
||
**`UNDECLARED_LATTICE_TRANSLATION=`** is a different finding, and is reported instead of a
|
||
pseudo-symmetry rather than as one: a translation at which the Patterson reaches at least 75 % of the
|
||
origin, **`UNDECLARED_LATTICE_TRANSLATION_PCT=`**. Near 100 % the merged data are invariant under it, and
|
||
a translation the data are invariant under is a lattice vector by definition — so the centring or the
|
||
cell is wrong, not the packing; an undeclared centring reads 83-102 %. Every one is a warning under the
|
||
`LATTICE_TRANSLATION` flag, asking to check the centring and the cell; below 90 % the warning also names
|
||
the other reading, a very strong pseudo-translation that molecular replacement needs declared, which
|
||
refinement in the cell tells apart. It is what a centred lattice merged in P1 looks like, which
|
||
`--mode scale` on a file with no space group produces by design. The pseudo-symmetry search continues
|
||
underneath it, so a real pseudo-translation sitting under an undeclared centring is still found.
|
||
|
||
**`L_TEST_VS_TNCS=`** says how the twinning L-test beside it coped. A pseudo-translation **u** biases
|
||
⟨|L|⟩ upwards unless the partner reflection at **h** + **s** shares its class, which happens exactly
|
||
when **s**·**u** is an integer; a half-integer **u** — a pseudo-centering — is preserved by the
|
||
ordinary axis step of 2 and reads `UNAFFECTED`. Where it is not, the steps are restricted to those
|
||
that do preserve the class (`REPAIRED`), and where no step does, `UNREADABLE` says the statistic was
|
||
dropped from the twin verdict **in both directions**: it can no longer indicate a twin, and it can no
|
||
longer be read as proof that there is none. The second moment then decides alone.
|
||
|
||
**`TWINNING_VERDICT=`** is `NO_INDICATION`, `INDICATED` (⟨|L|⟩ below 0.44, the phenix.xtriage convention,
|
||
or the second moment low, where the lattice admits a twin law for the group), `SYMMETRY_SUSPECT`
|
||
(⟨|L|⟩ below 0.42 where the lattice admits no twin law - a false adopted operator gives the same
|
||
distribution), `NO_TWIN_LAW` (⟨|L|⟩ between 0.42 and 0.44 where the lattice admits no twin law: not a
|
||
twin in this group, so the group may be too high, or something other than twinning narrowed the
|
||
distribution) or `NOT_READABLE`. Whether a twin law is possible is read off the cell - a rotation of
|
||
the lattice's metric, within 3° obliquity, that the group lacks - not off the Laue class, so a
|
||
pseudo-merohedral monoclinic or orthorhombic lattice admits one and a general one does not. ⟨|L|⟩ has a physical range: 0.5 untwinned, 0.375 a perfect twin,
|
||
whatever the law. Where it reads below 0.375, or above 0.55 (on this merge or on the one before the
|
||
space-group search), no twin fraction explains it - the statistic is distorted, by tNCS, anisotropy,
|
||
overlapping reflections of a very long cell, or too few reflections - and the verdict is
|
||
`NOT_READABLE`, with no warning: it says nothing about twinning, nor about the space group.
|
||
|
||
### The twin hypothesis (`TWIN_SUBGROUP_*`)
|
||
|
||
Where the adopted space group may have absorbed a twin law - a twin gate of the space-group search
|
||
refused it and was overruled, or a group above P1 was adopted on data that read twin-like before the
|
||
search (`L_TEST_MEAN_ABS_L_BEFORE_SEARCH`) - the run also writes the same observations merged in a
|
||
subgroup, as `<prefix>_twin_<SG>.mtz` and `.cif` in the subgroup's standard setting, to the same
|
||
resolution and with the same free set as `<prefix>.mtz`, the twin law in the mmCIF's
|
||
`_pdbx_reflns_twin`. A near-perfect twin of the subgroup predicts the same intensities as the higher
|
||
group, and a refinement program can only twin-refine data merged in the lower group, so the file is
|
||
there to refine against with the law where a model prefers it. The answer's files and keys do not
|
||
depend on it. At most one is written.
|
||
|
||
| key | meaning |
|
||
|---|---|
|
||
| `TWIN_SUBGROUP_FILE` | The file written, `<prefix>_twin_<SG>.mtz` (and `.cif` beside it) |
|
||
| `TWIN_SUBGROUP_SPACE_GROUP` | The subgroup, as written |
|
||
| `TWIN_SUBGROUP_LAW` | The twin law on that file's axes, as an hkl triplet |
|
||
| `TWIN_SUBGROUP_FRACTION` | The law's fraction from the disagreement of the pairs it relates (1/2 − median H, Yeates' H test): a lower bound |
|
||
| `TWIN_SUBGROUP_ALTERNATIVES` | Other confirmed subgroups that qualified; `-S` merges in one |
|
||
|
||
## Diffraction anisotropy
|
||
|
||
Section 4 also reports how much the fall-off with resolution depends on **direction**, and whether that is
|
||
established above the data set's own systematic error. It runs automatically on every merging run —
|
||
there is no flag — and it is a **description only**: no intensity is corrected, no reflection is
|
||
removed on a directional criterion, and the merged data and the written reflection files do not
|
||
depend on direction at all. The algorithm is in
|
||
[CPU/GPU data analysis ▸ Diffraction anisotropy](CPU_DATA_ANALYSIS_DECISIONS.md#135-diffraction-anisotropy).
|
||
|
||
Two different quantities are reported and they are not interchangeable. `ANISOTROPY_DELTA_B` is a
|
||
*rate* — the range of the principal components of the anisotropy tensor, on the ordinary
|
||
crystallographic *B* scale, so it is directly comparable with phenix.xtriage's `B_cart`, ctruncate's
|
||
anisotropic *B* and AIMLESS's anisotropic Δ*B*. `ANISOTROPY_D_MIN_PRINCIPAL` is where the signal
|
||
actually *runs out* along each principal direction. A crystal can have a large Δ*B* and almost no
|
||
spread in directional limit, or the reverse.
|
||
|
||
| key | meaning |
|
||
|---|---|
|
||
| `ANISOTROPY_VERDICT` | `DETECTED` \| `NOT_DETECTED` \| `CANNOT_DETERMINE` |
|
||
| `ANISOTROPY_FREE_DIRECTIONS` | Deviatoric directions the Laue class allows — 5 triclinic, 3 monoclinic, 2 orthorhombic, 1 tetragonal/trigonal/hexagonal, **0 cubic** |
|
||
| `ANISOTROPY_DELTA_B` | The anisotropic Δ*B* (Ų), fitted on intensities with nothing dropped |
|
||
| `ANISOTROPY_DELTA_B_LINEAR` | The part of it that follows exp(−½ **s**ᵀ*B***s**). **This is the number the verdict is gated on**, and the report says which of the two it is quoting |
|
||
| `ANISOTROPY_PRINCIPAL_B` | The three principal components, relative to the weakest |
|
||
| `ANISOTROPY_D_MIN_PRINCIPAL` | Diffraction limit (Å) along each principal direction — where ⟨I/σ(I)⟩ in a 20° cone about it falls through 2 |
|
||
| `ANISOTROPY_D_MIN_CENSORED` | One flag per direction. `1` means ⟨I/σ(I)⟩ never fell through 2, so the limit is the **edge of the measured data**, a bound and not a measurement. The prose marks it with a `<` |
|
||
| `ANISOTROPY_D_MIN_SPREAD` | Range of the three limits — itself a lower bound if any is censored |
|
||
| `ANISOTROPY_SHAPE` | `LINEAR` (a real Debye–Waller *B*) \| `FLAT` (the deficit does not follow a *B* at all, so Δ*B* may be an **under**-estimate) \| `CONVEX` (grows faster than a *B* can) \| `UNDETERMINED` (the verdict moved on rebinning) |
|
||
| `ANISOTROPY_FLOOR`, `ANISOTROPY_SIGNIFICANCE` | The data set's own systematic-error floor (Ų) and Δ*B*<sub>linear</sub> over it. Banded: below 2 not established, 2–3.5 marginal, above 3.5 established, above 5 strong |
|
||
| `ANISOTROPY_DETECTION_LIMIT` | The smallest Δ*B* that could have been established on these data. It is set by systematic error, not by counting, so it does **not** improve with more reflections or a longer exposure |
|
||
| `ANISOTROPY_N_OBSERVATIONS`, `ANISOTROPY_FORBIDDEN_Z`, `ANISOTROPY_SIGMA_SYSTEMATIC` | The unmerged observations the floor was measured on, that measurement against its own counting noise, and the floor before the counting part is added back |
|
||
|
||
The default report carries `ANISOTROPY_VERDICT`, `ANISOTROPY_DELTA_B`, `ANISOTROPY_D_MIN_PRINCIPAL`
|
||
and `ANISOTROPY_D_MIN_SPREAD`; the rest of this table — the detection gate's own parameters — is
|
||
written with `--developer`.
|
||
|
||
**`CANNOT_DETERMINE` is a real answer, not an evasion.** The verdict is not measured against counting
|
||
statistics — real data carry systematic error far larger than that, and gating on counting error
|
||
reports anisotropy on data sets that have none. Instead the data set measures its own systematic
|
||
error in the tensor directions its Laue class *forbids*, where the true value is exactly zero
|
||
whatever the crystal is. Where that measurement cannot be made, the run says so and gives the
|
||
reason: a **triclinic** Laue class (no forbidden direction exists), an observed rotation under about
|
||
90°, merged data at the noise floor, a scale model carrying no dose term
|
||
(`--no-scaling-corrections`), or no unmerged observations. A **cubic** Laue class is different again
|
||
— symmetry forces Δ*B* to be exactly zero, and the run says that rather than reporting a measurement.
|
||
|
||
Where anisotropy is detected and the directional limits differ by more than 0.5 Å, a `WARNING:` line
|
||
says so, since refinement and map interpretation should allow for it.
|
||
|
||
|
||
## Model validation
|
||
|
||
Section 5 appears only with `--model`. It reports the supplied model against the merged data —
|
||
R-factors, maps, anomalous sites — and, separately, whether the data accepted the model at all.
|
||
|
||
The two are not the same question, and the report keeps them apart. **The R-factors, the maps and the
|
||
rigid-body placement describe the model**: they are computed and reported whatever the answer, because
|
||
a model that does not belong to this crystal still has an R against it, and that is the negative
|
||
result. **`MODEL_FIT=` is the answer**, and it is what governs whether the model was allowed to change
|
||
anything about the written reflections.
|
||
|
||
There is no threshold on R behind it. What a model that explains nothing reaches against a given data
|
||
set depends on its atom count and B-factors as much as on the data, so the same model is refitted —
|
||
and re-placed as a rigid body, exactly as the real one is — from `MODEL_FIT_NULL_REPLICATES` random
|
||
orientations about its own centroid, and `MODEL_FIT_SIGMA` is how far the real fit sits above that
|
||
distribution. The statistic is R-work, not R-free - not because nothing is refined against the working
|
||
set (the placement's six parameters are), but because every null replicate is placed the same way, so
|
||
what they buy is bought on both sides and cancels; and it is decided on an order of magnitude more
|
||
reflections than R-free.
|
||
|
||
That null is built for **every** model the rigid body is tried on, whether or not it claims anything
|
||
about the written reflections, because its answer is also whether the model was placed at all
|
||
(`MODEL_PLACEMENT=`): a model the rigid body does not place against its null - in the answer's merge or
|
||
in the twin hypothesis' one - is searched for by [molecular replacement](#molecular-replacement)
|
||
instead. `MODEL_FIT` is the rigid body's verdict and only ever that; it is absent where no rigid body was
|
||
tried (a prediction, `--mr`) or its null could not be built.
|
||
|
||
| key | meaning |
|
||
|---|---|
|
||
| `MODEL_VALIDATION` | `PERFORMED` \| `NOT_PERFORMED` (with `MODEL_VALIDATION_REASON`, and no R-factors) |
|
||
| `MODEL_PLACEMENT` | `RIGID_BODY` (the model fits against its null in the answer's merge or the twin hypothesis' one) \| `MR` (placed by molecular replacement) \| `NOT_PLACED` |
|
||
| `MODEL_FIT` | `ACCEPTED` \| `REJECTED` — the rigid body's verdict: whether the model may decide anything. Absent where no rigid body was tried |
|
||
| `MODEL_FIT_STATISTIC` | What the verdict was taken on; `R_WORK` |
|
||
| `MODEL_FIT_VALUE`, `MODEL_FIT_NULL_MEAN`, `MODEL_FIT_NULL_SD`, `MODEL_FIT_NULL_REPLICATES` | The real fit, and the null of the same model in random orientations. Absent with `MODEL_FIT` |
|
||
| `MODEL_FIT_SIGMA` | The real fit above that null, in its sample standard deviations. Signed. `ACCEPTED` from +4.51: 3 σ of the null, allowing for its mean and spread being estimated from nine draws (Student's t). Absent with `MODEL_FIT` |
|
||
| `MODEL_DECISIONS_TAKEN` | `NONE` \| `ENANTIOMORPH` \| `INDEXING` \| `ENANTIOMORPH+INDEXING` (the rigid body) \| `MR_ENANTIOMORPH` (molecular replacement, which never reindexes) |
|
||
| `MODEL_ENANTIOMORPH_ADOPTED`, `MODEL_INDEXING_OPERATOR` | The two decisions individually; `x,y,z` is no reindexing |
|
||
| `MODEL_CHANGE_OF_BASIS`, `MODEL_SETTING_AS_READ` | Present only where the model was written in another description of the lattice (other axes, other centring, or another point group) and was put into the data's to be scored. Where such a model fits, the data are then written in the model's setting instead (`SETTING_SOURCE=MODEL`) and these keys are absent, since the model no longer moves. An alternative indexing of the same point group is settled here only where a reference MTZ (`-z`) has already fixed the data's indexing; otherwise the data are reindexed into the model's, and that is `MODEL_INDEXING_OPERATOR` |
|
||
| `MODEL_INDEXING_MARGIN`, `MODEL_INDEXING_MARGIN_NULL`, `MODEL_INDEXING_MARGIN_SIGMA` | Present only where a merohedral ambiguity was probed. The winner's lead over the runner-up in R-free, against the lead a random placement of the same model produces |
|
||
|
||
Where a twin hypothesis was written (above), the model is scored against that merge too - as merged,
|
||
and as twinned by its law at a fraction scanned on the working set - and **the maps and the placed model
|
||
come from whichever merge the model fits better on R-free**. `MAPS_FROM=` says which (`MERGE` or
|
||
`TWIN_SUBGROUP_MERGE`), beside `TWIN_SUBGROUP_R_WORK`, `TWIN_SUBGROUP_R_FREE`, and, as twinned,
|
||
`TWIN_SUBGROUP_R_WORK_TWINNED`, `TWIN_SUBGROUP_R_FREE_TWINNED` and `TWIN_SUBGROUP_MODEL_TWIN_FRACTION`.
|
||
`R_WORK`/`R_FREE` above stay the answer's merge's. The model chooses the maps only: it never changes
|
||
the space group or `<prefix>.mtz`. Where it also fits there against its null, it has chosen the subgroup,
|
||
and that merge is written once more as `<prefix>_mr.mtz`/`.cif` with the model as placed there
|
||
(`MODEL_CHOICE_FILE_PREFIX=` and `MODEL_CHOICE_SPACE_GROUP=`, by either route). With a model, the
|
||
twin hypothesis' merge is also made where a metric re-ask promoted the indexed lattice's group, or where
|
||
the model's group has fewer rotations than the adopted one; made for that reason alone, it is written and
|
||
reported only where the model chooses it.
|
||
|
||
The null's own numbers — `MODEL_FIT_STATISTIC`, `MODEL_FIT_VALUE`, the `MODEL_FIT_NULL_*` keys and
|
||
the `MODEL_INDEXING_MARGIN*` keys — are written with `--developer`; the default report carries the
|
||
verdict (`MODEL_FIT`, `MODEL_FIT_SIGMA`, `MODEL_DECISIONS_TAKEN` and the two decisions).
|
||
|
||
### Comparing two runs: `R_MODEL_SHELL_SCALED`
|
||
|
||
`R_WORK` and `R_FREE` describe *this* dataset against *this* model, and that is all they describe.
|
||
They are **not comparable with another run's**. The model is scaled to the data by an overall factor
|
||
and a symmetry-constrained anisotropic *B* — a shape that can only bend one way with resolution, kept
|
||
that way on purpose so that a batch of maps stays on one scale (see
|
||
[CPU_DATA_ANALYSIS_DECISIONS](CPU_DATA_ANALYSIS_DECISIONS.md)). Whatever the amplitudes' own radial
|
||
profile does that this shape cannot follow is then reported as R. Two reductions of one crystal whose
|
||
merged amplitudes have different radial profiles therefore differ in `R_FREE` for a reason that has
|
||
nothing to do with either fitting the model better, and by more than a real change in the data moves it.
|
||
|
||
`R_MODEL_SHELL_SCALED` is the same sum with that taken out: one free scale per resolution shell — the
|
||
merge table's own shells — fitted on the shell's reflections, so only the agreement *inside* each
|
||
shell is left. `R_MODEL` is the same sum without the per-shell scale, so the gap between the two is
|
||
what the radial profile cost, and `MODEL_RADIAL_MISFIT` is the size of the rescale that closed it
|
||
(the RMS of ln *k*<sub>shell</sub> about its mean). When the misfit moves between two runs, `R_FREE`
|
||
between those two runs cannot be read; `R_MODEL_SHELL_SCALED` can.
|
||
|
||
Both R values are over **all** the reflections, not the free 5%. Nothing here is refined — the
|
||
coordinates, the B-factors and the occupancies are the model's own, and only the scale and the
|
||
placement are fitted — so work and free estimate the same quantity (they differ by a median 0.001
|
||
over our corpus) and the split buys no cross-validation while costing a factor of √20 in precision.
|
||
|
||
None of this touches the maps: the map coefficients and `R_WORK` / `R_FREE` are
|
||
computed from the scale described above and are unchanged by these keys.
|
||
|
||
| key | meaning |
|
||
|---|---|
|
||
| `R_MODEL`, `R_MODEL_REFLECTIONS` | R over every reflection, on the scale the maps use |
|
||
| `R_MODEL_SHELL_SCALED` | The same, with one free scale per resolution shell — **the number to compare between runs** |
|
||
| `MODEL_RADIAL_MISFIT` | How large that per-shell rescale had to be: RMS of its logarithm. Near zero means the maps' own scale already described the radial profile, and then the two R values agree |
|
||
|
||
### CC(model, data)
|
||
|
||
Beside the R-factors, section 5 carries the **correlation of the merged intensities with the placed,
|
||
scaled model**, |*F*<sub>model</sub>|², by resolution shell. The shells are the merge table's own, so
|
||
a row here can be read straight across from that shell's CC1/2 and R<sub>meas</sub> in
|
||
section 3. It is a correlation of *intensities*, like CC1/2 and CCref beside it, and the
|
||
observed value is the merged intensity itself rather than the French–Wilson |*F*|² the R-factors use —
|
||
that amplitude is a posterior mean under a Wilson prior, which pulls a weak reflection towards its
|
||
shell mean and would show up as correlation in exactly the outer shells this number is read in.
|
||
|
||
The model is placed and scaled with eleven parameters, so there is no work/free distinction to draw:
|
||
the correlation is formed on **all** the reflections of a shell, not only the few hundred free ones.
|
||
Both sides are divided by the reflection's symmetry enhancement ε, which they share whatever the model.
|
||
|
||
| key | meaning |
|
||
|---|---|
|
||
| `CC_MODEL_OVERALL`, `CC_MODEL_REFLECTIONS` | The correlation over every reflection in the table, and how many — the `N` column sums to it. Like any overall correlation it is shell-weighted and can take any value between the best shell and the worst; the table is what to read |
|
||
| `CC_MODEL_CONFIRMED_TO_D_MIN` | The finest shell that, together with the shell coarser than it, reaches 3 σ, or `NONE`. A **lower bound** on the useful resolution |
|
||
| the `D_MIN / CC_MODEL / N / CC_NULL / SIGMA` table | Per shell: the correlation, the reflections it was formed on, its null, and how far above the null it sits |
|
||
|
||
**The null.** A correlation above zero is not evidence on its own. The data and a scaled model share
|
||
everything that is smooth in reciprocal space — the falloff across a shell, the anisotropic B (fitted
|
||
to these very data) and the bulk solvent — whatever the model is, so the deposited model of an
|
||
unrelated protein correlates with the data at 10–15 σ by Fisher's transform in most shells. `CC_NULL`
|
||
is the correlation of the data at *h* with the model at *h* + *d*, averaged over the 26 nearest lattice
|
||
offsets *d*: it keeps what is smooth and loses what the model knows of *h* itself. `SIGMA` is
|
||
(atanh `CC_MODEL` − mean atanh) / sd over those 26, the sd never narrower than Fisher's 1/√(N−3). A
|
||
shell confirms only beside a coarser shell that does as well: one shell alone clears 3 σ by chance
|
||
among a dozen, while signal runs on over neighbouring shells.
|
||
|
||
**Read it in one direction only.** A shell whose correlation is significantly above its null carries
|
||
signal the model accounts for reflection by reflection, so `CC_MODEL_CONFIRMED_TO_D_MIN` is evidence
|
||
for keeping *more* data. A shell whose correlation is near
|
||
zero says nothing about the data: the model may be incomplete, in the wrong hand, or simply wrong for
|
||
this crystal, and cutting on it would be cutting because the model is poor. Nothing in the pipeline
|
||
acts on these numbers; they are reported and no more. This is the same asymmetry cryo-EM works under,
|
||
where the half-map FSC sets the resolution and the model–map FSC only validates it.
|
||
|
||
A *significantly negative* correlation in a shell is worth chasing rather than ignoring: it cannot be
|
||
signal, so it points at a systematic error — an indexing the model disagrees with, or an outer shell
|
||
the scaling has mistreated.
|
||
|
||
`MODEL_DECISIONS_TAKEN= NONE` means the reflection
|
||
files are **byte for byte** what a run with no model would have written — same space group, same indexing, same `.mtz`, `.cif`, `.hkl` and
|
||
`_unmerged.mtz`. A rejected model is therefore safe to try: it costs the null's compute and changes
|
||
nothing else.
|
||
|
||
## Molecular replacement
|
||
|
||
A `--model` is placed by molecular replacement where it has no placement of its own - a prediction - or
|
||
where the rigid body did not place it (`MODEL_PLACEMENT=` above), and `--mr <file>` takes a model there
|
||
straight away, without trying the rigid body first. It runs in a full `--mode mx` run, rotation and
|
||
serial stills alike; `--mode scale` places a model by the rigid body only. The search's keys (`MR_*`) and its table are in
|
||
`5. MODEL VALIDATION`. Where it places the model, the R-factors, the maps and CC(model, data) of that
|
||
section are of its placement, validated against the merge it was chosen on with nothing left to decide
|
||
(the maps `<prefix>_mr_*` where that merge is `<prefix>_mr`); `MODEL_FIT` stays the rigid body's. Where
|
||
it does not, they stay the rigid body's. Not placing a model is a result, never a warning. What kind of
|
||
model it is is read
|
||
from the file (`MR_MODEL_KIND=`): a prediction - ModelCIF's `_ma_qa_metric`, or no cell and one B value
|
||
per residue from 0 to 100 (an AlphaFold PDB or mmCIF) - has its residues below pLDDT 70 removed and its
|
||
B-factors made from the pLDDT; anything else is an experimental structure, taken as its polymer only (no
|
||
waters, ligands, hydrogens or alternative conformers) with its own B-factors, and a coordinate error of
|
||
0.67 A (a prediction's at pLDDT 90) for sigma_A. A model whose expected log-likelihood gain - the sum of
|
||
sigma_A^4 / 2 over the search's reflections, one copy being the part of the scattering the most probable
|
||
copy number by Matthews makes it - is below 10 is not searched for (`NOT_PLACED`). Then a rotation function over the point group (6 deg sampling, 4-12 A, each of the 50 best
|
||
peaks refined off the sampling), a translation function for those orientations in every space group the
|
||
merge cannot tell apart, and the best three placements per group that pack through the rigid body, bulk
|
||
solvent and R-free (to `SCORE_D_MIN`, 3 A or the data's limit). Further copies follow one at a time, up
|
||
to the largest copy number with a Matthews probability of 1% (`COPIES_LIKELY`: the most probable): the
|
||
translation function again with the copies already placed as a known partial structure, its peaks
|
||
ranked by the likelihood gain of the new copy beside them (peaks that lower the likelihood dropped),
|
||
each new copy refined beside the others held fixed, and kept where it stands out (below), it packs and
|
||
R-free drops by 0.01 (`COPIES`, and `MR_COPIES=` for the group chosen). The groups are searched
|
||
side by side; with tNCS, every group that placed fewer copies than the best one is searched once more
|
||
with the best one's copies' orientations tried first, and the better search kept.
|
||
|
||
The likelihood is the log-likelihood gain of the Rice/Woolfson distributions of E_obs given E_calc, with
|
||
sigma_A falling off with the coordinate error the pLDDTs predict and its scale refined against the data,
|
||
summed to 2.5 A (or the data's limit, or the 20000 lowest-resolution reflections in a large cell). A copy
|
||
stands out where its translation-function Z-score reaches 8, or - only where the copies placed are as
|
||
many as the cell most probably holds - where its likelihood after the rigid body reaches a Z-score of 8
|
||
over the same copy in the same orientation at random positions (`LLG_Z`; taken only where `TF_Z` is
|
||
below 8). That second way in is what places a single copy in a small cell, whose few reflections keep
|
||
the translation function's own Z-score low. In P1 the first copy sits at the origin, which no function
|
||
of its position can single out; it stands out where its rotation-function Z-score (`RF_Z`) reaches 8.
|
||
|
||
Where the AlphaFold DB's predicted-aligned-error file sits beside the model under its own name
|
||
(`AF-<id>-F1-model_v<n>.cif` and `AF-<id>-F1-predicted_aligned_error_v<n>.json`), the prediction is cut
|
||
into rigid domains by average linkage on the PAE (domains a mean 10 A apart, of 40 residues or more;
|
||
`MR_PAE_DOMAINS=`; a prediction only). Where the whole model is placed nowhere, each domain is searched by itself, side by
|
||
side; the domains placed have to agree, and a domain alone can only confirm the answer's group
|
||
(`AGREES`), never change it (`UNDECIDED` otherwise). `MR_SEARCH_MODEL=` names what the decision
|
||
was made with.
|
||
|
||
The table has one row per group and merge. A row is `PLACED` where one of its copies stands out, at most 5% of the C-alpha atoms clash with another
|
||
copy or a symmetry mate (`CLASH`), and one copy fits the cell (`MATTHEWS`: Vm below 1.5 A^3/Da). The
|
||
null - the same model refitted from random orientations, each placed by the translation function as the
|
||
search placed the real one (each copy turned about its own centroid where there are several, so that the
|
||
copies keep their arrangement) -
|
||
is built for the candidate the choice falls on; its R-work has to beat the null's by 4.51 sd
|
||
(`NULL_SIGMA`: 3 sd allowing for the null being nine draws, as `MODEL_FIT_SIGMA`), and one that does not
|
||
is marked `NULL` and the choice falls on the next. A placement clashing over twice the limit is not
|
||
refined. Translational NCS is looked for in the native Patterson (a peak off the lattice of a fifth of
|
||
the origin's): with it, a group whose screw axes the tNCS translation turns into the chosen group's (or
|
||
the chosen group's enantiomorph) and whose search placed fewer copies leaves the choice `UNDECIDED`,
|
||
since one copy beside a translated twin of itself fits the data no better than at random - unless the
|
||
chosen copies, carried into that group as they are and refined there, fit worse by 0.03 in R-free:
|
||
where the translation does make up the difference between the groups, the copies build the same crystal
|
||
in both. The group the merge was made in, searched to fewer copies than the chosen one, leaves the choice
|
||
`UNDECIDED` too, whether it packs or not (its enantiomorph excepted, which the hand check decides). Where
|
||
the tNCS vector v is half a lattice vector, the reflections with h.v half-integral are weak, and a
|
||
placement moved by (v + o) / 2 (o an origin shift of the group) fits the strong ones exactly as well:
|
||
the candidate the choice falls on is compared with every such move of itself, refined and packing, by
|
||
R-work and R-free together over the weak reflections alone; a move better by 0.01 there is taken
|
||
instead, and where the two best are within 0.01 the choice is `UNDECIDED`. The rotation and translation functions, the rigid
|
||
body and the structure factors the R-factors are taken on run on the
|
||
GPU where there is one (`MR_SEARCH_DEVICE=`). `MR_DECISION=` is then:
|
||
|
||
- `AGREES` - the placed group with the lowest R-free is the answer's, ahead of every other group of
|
||
the merge that packs by 0.03 in R-free (with tNCS, see above). A group within 0.03 that placed as
|
||
many copies has as many parameters, so it is compared on every reflection, work and free: it is
|
||
ruled out where the chosen placement's |F_obs - F_calc| is lower by 3 standard errors of the paired
|
||
difference;
|
||
- `ENANTIOMORPH` - it is the answer's enantiomorph, and the answer's files take that label (a label
|
||
only, as with `--model`; no reflection moves). It is taken only by the rule a `--model`'s
|
||
enantiomorph is taken by: the model has to fit against its null (the choice already required that)
|
||
and model validation's anomalous difference map, read at the placed model's atoms, must not be
|
||
inverted (`MR_HAND_CHECK=`,
|
||
`MR_HAND_FIT_SIGMA=`, `MR_ANOMALOUS_INVERTED=`). Where it is not, the decision reads
|
||
`ENANTIOMORPH_VETOED` and the label stays;
|
||
- `SPACE_GROUP` - another group with the answer's rotations; written as `<prefix>_mr.mtz`/`.cif` from
|
||
the answer's merge, the reflections that group extinguishes left out;
|
||
- `TWIN_SUBGROUP` - the twin hypothesis' subgroup: either no group of the answer's merge can hold the
|
||
model at all (`MATTHEWS`/`CLASH` in every row) and a group of the subgroup can, or the twin comparison
|
||
chose it. The comparison runs where the answer's merge chose a group and the twin hypothesis' merge
|
||
is there: on that merge, against its data as twinned by its law (the fraction refined on the working
|
||
set), the chosen placement with all its symmetry images - the group's crystal read in the subgroup -
|
||
is scored against the model searched for afresh in the subgroup; the subgroup is taken where its own
|
||
placement leads by 0.03 in R-free and passes the subgroup's own choice (its null, its lead over the
|
||
subgroup's other groups). Written as `<prefix>_mr.mtz`/`.cif` from the twin hypothesis' merge, with
|
||
its law and fraction. With a model, the twin hypothesis' merge is made wherever a metric re-ask
|
||
promoted the indexed lattice's group, so that the comparison can run - and, where that is the only
|
||
reason it was made, written and reported only where the model chooses it;
|
||
- `UNDECIDED` or `NOT_PLACED` - nothing is written.
|
||
|
||
With `SPACE_GROUP` and `TWIN_SUBGROUP` the placed model is written as `<prefix>_mr_model.pdb`/`.cif`.
|
||
Apart from the enantiomorph label, the answer's own files are never changed by the model.
|
||
|