The per-direction peak search starts at the 10 A floor, so a lattice row shorter than that was reported at a multiple of itself past it and the cell built from such rows was an exact integer supercell. A second first-pass hypothesis at a 5 A floor (the short-axis pass) won the true cell back on frame counts, and could not reach an axis below 5 A at all. On rotation data (a scanning axis) every shortlisted row reported within three times the floor is now asked, by a direct sum over the accumulated spots, at each whole fraction of its length down to 3 A; the shortest fraction that keeps half the row's amplitude replaces it. The cells of those rows are reduced (widened: a small cell's in-plane combinations fill the standard window) and refined beside the standard cells, and ranked with them, so where a cell and its supercell index alike the smaller one is taken. Protein shortlists have no rows that short, so nothing changes for them; stills and grid scans keep the search they had. The short-axis pass, its speculative pool and its live warm-up are removed; the refined-length bound of the cell fit goes from 5 to 2.5 A. The 40 % overlap test of the candidate refinement no longer deletes a cell for its overlap with an integer multiple or sub-cell of it - one lattice contains the other, so that overlap is total by construction. Such candidates are kept after every cell the test accepts, which keep their order, so the first lattice and the extra crystals are what they were. The rotation indexer carries the refined integer supercells of the cell it chooses, and the twin-composite test asks them as well as the standing cell: once the search offers a twin domain's own cell, the coincidence lattice it used to stand on is one of those. Measured (battery subsets vs rc181-b2): a small-molecule crystal with an axis under 5 A, indexed as an index-5 supercell now gives its true cell and group; the 13 sets the short-axis pass rescued keep their verdicts; the sparse reticular twin keeps its domain and overlap. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UqXYdL4qBGYRiSXSGXfCLu
50 KiB
Command-line options
rugnux run with no arguments prints a short usage: how to run each mode and the options most runs
need. This page is the full reference behind it - every option the program accepts, with what it
does. The program's own usage message is the authority on behaviour; this page is kept consistent
with it.
The same pages ship with the release archive, as share/doc/jfjoch_rugnux/html/ beside bin/, so
they can be read without a network; this one is share/doc/jfjoch_rugnux/html/RUGNUX_CLI.html.
rugnux [options] <input> [<input> ...] [<broker URL>]
:local:
:depth: 2
Running each mode
What a run does is chosen with --mode (default mx). Within mx, rotation and stills are not
chosen by an option: a dataset whose goniometer axis turns is processed as a rotation sweep, one
without a goniometer axis - or with an axis that stands still - as serial stills.
Rotation data (--mode mx, the default)
rugnux -o myrun dataset_master.h5 # NXmx / EIGER / Jungfraujoch master file
rugnux -o myrun sweep_00001.cbf # CBF, marCCD or SMV sweep: name one frame
rugnux -o myrun dataset_master.h5 model.cif # with a model (or --model model.cif)
rugnux -o myrun x_master.h5 http://host:5232/ # follow a broker's collection while it is written
rugnux -o myrun a_master.h5 b_master.h5 # several sweeps of one crystal, merged as one
Chosen when the file's goniometer axis turns. Several sweeps can be given (below, Inputs). A model is placed (rigid body, or molecular replacement), refined and validated after merging; it does not change the processing decisions (Models and reference data).
Serial stills (--mode mx)
rugnux -o serial *_master.h5 # several NXmx masters of one setup
rugnux -o serial -C 79,79,38,90,90,90 -S P43212 run*.h5 # SACLA (Cheetah HDF5)
rugnux -o serial -C 79,79,38,90,90,90 -S P43212 *.cxi # Cheetah CXI
rugnux -o serial -C 79,79,38,90,90,90 -S P43212 *.xtc # LCLS-I XTC streams
Chosen when there is no goniometer axis or it does not turn; --force-still processes a rotation
sweep as stills. Giving the known cell (-C) and space group (-S) is recommended for stills. Several inputs are one dataset, read in the order given. Without -C the stills
are indexed de novo; a model is given as for rotation data
(Still / serial data).
Refinement (--mode refine)
rugnux --mode refine -o refined data.mtz model.cif
Refines a model against merged data that already exist - an MTZ or a structure-factor mmCIF - and
reads no images. The model is required, given among the inputs or with --model
(Refining a model against structure factors).
Detector calibration (--mode calibration)
rugnux --mode calibration --calibrant lab6 -o det LaB6_master.h5
The detector geometry from a powder standard's rings, written as det.poni (pyFAI) and det.json
(Detector calibration).
Azimuthal integration (--mode azint)
rugnux --mode azint -o profiles dataset_master.h5
Azimuthal integration only - no spot finding, indexing or merging; writes profiles_process.h5.
The binning is set by the azimuthal-integration options.
Re-merging (--mode scale)
rugnux -o myrun --write-process-h5 dataset_master.h5 # integrate and merge once
rugnux --mode scale -o remerged -A myrun_process.h5 # re-merge, here anomalously
Re-scales and merges the reflections already integrated into a _process.h5, without re-running
spot finding or integration (Re-scaling and re-merging).
Inputs
Inputs are files, never a directory, read in the order given (a shell glob gives them sorted by
name). Several inputs are one stills dataset in --mode mx, or several rotation sweeps (below): all the files of
one dataset - rugnux run*.h5 (SACLA), *.cxi, *.xtc (LCLS) - or several Jungfraujoch/NXmx
masters of stills, read as one run: their images one after another, merged together, with the
indexing rate reported per master as well. Such masters must share the detector, wavelength,
distance and beam centre. Several inputs must be one format; any --mode other than mx, and
following a broker, take one.
Several rotation sweeps are told apart from the files: one sweep per CBF/marCCD/SMV/SFRM file-name
template (the name with its frame number taken out - any frame of a sweep names the whole sweep, so
rugnux a_*.cbf is the one sweep a), one per rotation master. Only the inputs given are processed;
other sweeps beside them are named in the log. A mix of rotation and stills masters is refused, and
so are sweeps at different wavelengths, -s/-e and --force-still with several sweeps.
By default (--sweeps joint) the sweeps are one dataset, merged in two levels as XSCALE merges the
data sets XDS made of each sweep: each sweep is processed on its own first - indexed, integrated, its
partials combined and scaled, its space group determined - writing only its log <prefix>_s<k>_log.txt;
the sweeps are then put on the axes of the best of them (the finest resolution of its own merge, ties: the higher ISa) - the change
of basis, an axis permutation or a twin law of the lattice, under which their merged intensities correlate
best; where the lattice allows more than one indexing, which one each sweep takes is settled over all pairs
of sweeps at once - and each is judged by its isomorphism ratio with it (see RUGNUX_REPORT): clearly
about 1 it joins, clearly below it (another crystal) it is left out, and in between the merge decides - it
joins if it helps - adding it lowers the held-out residual of the others' merge, or it adds at least 1%
to their unique reflections while that residual is not worse beyond its noise (a sweep left out
is named in the log). The crystal has one cell: a joined sweep whose own cell is more than 0.3% off that of
the joined sweep reaching the finest resolution (where the cell is measured rather than the distance) is
processed a second time, from the distance that would make the two cells agree, and that run replaces the
first where its intensities agree better with that sweep's (a lower held-out residual). Their fulls are
scaled and merged together: a per-frame scale within each sweep, the sweeps' dose order read from
their relative B factors (not from the input order or the header times), a decay along that order or
one B per sweep, whichever predicts held-out frames better, then the space-group search, the
resolution cut and everything after it on the joint data, into <prefix>.*. The detector-dependent
corrections (absorption and detector surfaces) are each sweep's own. The unmerged MTZ holds the joint
merge's scaled observations in the batches of their own sweeps (sweep s of the merge: batches
s * base + frame + 1, base the power of ten past the longest sweep), under the batch headers that
sweep's own run wrote; the report names each sweep in section 1b. SWEEPS. --sweeps separate processes each sweep alone instead, as if it were the only
input, into <prefix>_s<k>_* (k = 1, 2, ... in the order given).
What each format needs is in What Rugnux reads; serial XFEL stills are read without a geometry file where their own metadata places the detector (Serial XFEL inputs).
An atomic model and a reference reflection file can be given among the inputs, in any order,
instead of --model and -z. Each file is told by its contents, not its name: an MTZ (the MTZ
magic) or an mmCIF with a _refln or _diffrn_refln loop is reflections (-z; the input itself in
--mode refine), a PDB file or an mmCIF with an _atom_site loop is a model (--model), anything
else is images. An mmCIF holding both coordinates and reflections has to be given with --model or
-z. At most one of each, also counting --model/--mr and -z; gzipped or not.
With a broker URL (http://host:port/) as the last argument and no input on disk yet, rugnux
follows the broker's current collection while it is written: the input must be the path its master
file will have, the data files are read next to it as the broker reports them closed, and the run
ends with the images the collection delivered. Rotation data, --mode mx only. The collection's
token is read from the environment variable JUNGFRAUJOCH_HTTP_TOKEN and sent only to the broker.
With the input already on disk, the URL is ignored.
All options
General
| Option | Description |
|---|---|
-o, --output-prefix <txt> |
Output file prefix (default: output) |
-N, --threads <num> |
Number of worker threads (default, and for any value ≤ 0: every CPU the run may use - its affinity and cgroup quota). Some stages take fewer, because past a point more workers make them slower: the per-image loop of --mode mx uses at most 16 per GPU unless -N was given a positive value, and first-pass spot finding and the beam-stop pre-scan have ceilings of their own that -N does not lift. On a small card the two ceilings, and the per-image loop's 16 where -N was left at its default, come down to as many workers as keep their buffers (about 24 bytes per detector pixel each) within half of the card's total memory. Scaling, merging and the space-group search use the full count |
-s, --start-image <num> |
First image to process (default: 0) |
-e, --end-image <num> |
End image number, exclusive: -s 0 -e 100 processes images 0-99 (default: all) |
-t, --stride <num> |
Process every n-th image (default: 1) |
-v, --verbose |
Show the whole log on the terminal in place of the steps; <prefix>_log.txt is written either way |
--simulate-live <ms> |
Read a stored input as the collection it was while being written: image i becomes readable (i+1)·ms ms after the start (0: all at once). The run takes the live path a broker URL takes, with the same result; for testing the live workflow without a broker. --mode mx only |
--fast-live |
With --simulate-live or a broker URL: run as the broker's rugnux live mode does — every decision stands where it was first taken, nothing is re-checked or run again once the sweep is in, the integration radius is fixed, and SIGINT cuts the run to what it has established. A difficult crystal can come out worse |
--sweeps joint|separate |
Several rotation sweeps (see Inputs): joint (the default) merges them as one dataset into <prefix>.*; separate processes each alone into <prefix>_s<k>_* |
--no-gpu |
Run on the CPU only, as on a machine without a GPU, even where one is present: CUDA is not touched (nor, on macOS, the Apple GPU that Bragg integration, the model density and the molecular-replacement rotation function otherwise run on) and every GPU step takes its CPU path (-X FFT indexes with FFTW and -X FFBIDX with its CPU implementation; -X cuFFT is refused) |
Mode
--mode <name> (default mx):
| Value | Description |
|---|---|
mx |
Full analysis — spot finding, indexing, integration and merging |
azint |
Only azimuthal integration (no spot finding/indexing); writes <prefix>_process.h5 |
scale |
Only re-scale/merge the already-integrated reflections in the input _process.h5 (no re-integration) |
calibration |
Determine the detector geometry from powder rings; writes <prefix>.poni and <prefix>.json |
refine |
Refine the --model against merged structure factors (an MTZ or a structure-factor mmCIF) and process nothing; see Refining a model against structure factors (--refine-score-only, --refine-d-min) |
Refinement (--mode refine)
The columns are found, not named - amplitudes with their sigmas (F/SIGF, FP/SIGFP, ...) where the file has them, else intensities (IMEAN/SIGIMEAN, I/SIGI, ...) made into amplitudes by French-Wilson, else the mean of the anomalous pairs; the free set from a FreeR_flag-like column (0 the test set, or the minority value where 0 is the majority, as phenix writes it), drawn by rugnux where the file has none. The model is taken as placed in the data's cell, and refined in the data's space group.
| Option | Description |
|---|---|
--refine-score-only |
Score the model as given and refine nothing: R-work/R-free, the scale, the bulk solvent, the likelihood and the geometry, each term under REFINE_SCORE_ (--developer prints them all); the twin test is the refinement's (REFINE_TWIN) |
--refine-d-min <num> |
Leave out reflections finer than this (Å) |
Calibration (--mode calibration)
| Option | Description |
|---|---|
--calibrant <name> |
Powder standard: lab6 | agbh | ceo2 | si | ice (default lab6, case-insensitive). A cell given with -C overrides it: that cell is the standard, its rings enumerated from the cell, with the absences of -S where given |
--calibration <txt> |
How the rings are measured: rings | spots (default rings; see Detector calibration). rings defaults --azim-phi-bins to 32 |
--no-refine-tilt |
Do not refine the detector tilt: hold rot1/rot2 at the header value and fit only the beam centre and the distance, for a calibration handed to a program that cannot express a tilted detector (XDS). On stills it holds the tilt in the geometry refinement too |
Detector mask
| Option | Description |
|---|---|
--detect-beam-stop[=N|off] |
Find the beam stop and its holder in a projection of N images and add them to the pixel mask as bit 9, so nothing shadowed by them is integrated. On by default (60 images); =off disables. A reflection whose signal disk reaches into the shadow is not integrated: the rest of such a disk lies in the stop's half-shadow and reads low. Pixels the finder reports that hold the detector's no-data mark (a PILATUS gap) are masked as dead instead |
Beam centre
| Option | Description |
|---|---|
--beam-center-check[=off] |
Measure the beam centre from the isotropy of the scattered background on every run, report how far the file's value is from it (against how right this geometry needs it to be), and on rotation data index a second first pass at the measured centre. The fit reads the projection --detect-beam-stop already builds, so it costs no extra frames. On by default; =off disables it, and with it the measured centre's part in the post-refinement bound. The measured centre is adopted where the file's centre indexes nothing and the measured one indexes a majority; where the two return cells related by an integer volume factor (2 to 4) and the measured centre's cell, larger or smaller, carries materially more of the pooled validation spots against its own chance level; and, on a two-pass run, where the first pass is run at both centres and the measured one merges better — done where the two give the same cell in different metric symmetries, where they agree only once less of each frame is read, and where they agree but lie further apart than the geometry absorbs and the file's centre merges inconsistently in the lowest-resolution shell. Otherwise the file's centre is kept. On stills, where there is no first pass, the file's centre, the measured one and the point-symmetry capture's are each indexed on a sample of frames and the one putting materially more spots on the lattice is taken; with -C the detector distance is searched too (30-3000 mm, the file's value one hypothesis). Still runs when --beam-x/--beam-y are given. See §1.4 |
Spot finding
| Option | Description |
|---|---|
--spot-sigma <num> |
Noise sigma level for spot finding (default: 4.0) |
--spot-threshold <num> |
Photon-count threshold for spot finding (default: 10) |
--adaptive-spots |
Self-calibrating detection (default, stills and rotation alike): the strong-pixel threshold comes from each image's own per-resolution-ring noise instead of the fixed --spot-threshold, so one setting adapts across datasets (no per-dataset --spot-threshold/--spot-sigma tuning) |
--no-adaptive-spots |
Turn adaptive detection off and use the fixed --spot-threshold / --spot-sigma finder |
--spot-false-pixels <num> |
Adaptive-detection operating point: expected noise pixels tolerated per frame (default: 100; implies --adaptive-spots). A run that finds no lattice at it is made again once at ten times it (SPOT_FALSE_PIXELS_LOOSENED in the report) |
--spot-high-resolution <num> |
High-resolution limit for spot finding, Å. Omitted (or 0): no resolution clipping — spot finding extends as far as the detector reaches, for rotation data as well as stills |
--spot-low-resolution <num> |
Low-resolution limit for spot finding, Å (default: 50; lower it, e.g. 24, to exclude the direct-beam halo on weak serial data; 0 removes the limit) |
--min-pix-per-spot <num> |
Minimum connected strong pixels per spot. If omitted, min-pix is chosen per image (stills indexing): the frame is scored at min-pix 2/3/1 (one lattice search per frame, refined on each list) and the one maximising indexed-spot count × indexed fraction is kept. Give an explicit value to force a fixed min-pix instead. |
--max-spots <num> |
Maximum spots kept per image (the strongest ones) and handed to indexing. If omitted, the budget is measured on rotation data: the first pass reads how deep into an image's spot list its spots still lie on the lattice it found, and the run keeps that many (never more than 1000). Give a value to pin it. Stills always use the fixed 1000. |
--detect-ice-rings[=on|off] |
Flag ice-ring spots (de-prioritised in indexing) and exclude ice-ring reflections from scaling; on rotation data the merge then decides ring by ring whether to merge, down-weight or reject them. Default: the master file's detect_ice_rings, or — where the file carries no such key — on for rotation and off for stills |
Azimuthal integration
The radial profile behind the per-image ice-ring score, and what --mode azint writes. Every q here is
q = 2π/d, in Å⁻¹:
| Option | Description |
|---|---|
-q, --azim-q-spacing <num> |
Q bin spacing, 1/Å (default: 0.01; finer resolves the narrow ice rings) |
--azim-min-q <num> |
Minimum Q, 1/Å |
--azim-max-q <num> |
Maximum Q, 1/Å. Omitted: integration extends to the highest Q the detector reaches. The adaptive spot finder shares these Q bins, so this also sets how far self-calibrating detection can see |
--azim-phi-bins <num> |
Number of azimuthal (phi) bins (default: 1) |
--polarization-correction <on|off> |
Enable/disable the azimuthal polarization correction |
--solid-angle-correction <on|off> |
Enable/disable the azimuthal solid-angle correction |
Indexing
A dataset with a rotation goniometer axis is processed as rotation data (two-pass rotation
indexing) by default; a dataset without one is processed as independent stills. --force-still
overrides the former; the -R / --single-pass-rotation / --force-rotation-lattice flags request
rotation explicitly and pick the pass or lattice.
The FFT search looks for cell axes between 10 Å (--fft-min-unit-cell) and a default longest
axis of 500 Å, which has no flag of its own — a reference cell (-C) moves both bounds to cover
the cell it names. On rotation data a lattice row shorter than the floor, down to 3 Å, is found under
the multiple of it the search reports there, so a small-molecule cell below the 10 Å floor is
indexed on its true axes rather than as a supercell of them.
The long end is extended the same way: wherever the detector separates the lattice rows of an axis
longer than 500 Å (distance × wavelength / (pixel × spot width)), a coarse search to that length,
up to 1200 Å, offers its lattices as a further hypothesis, kept only where it puts more of the
pooled validation spots on itself beyond chance. An axis beyond the search's reach is not refused: the run returns a
plausible shorter sub-cell or an axis harmonic and processes it happily, so a cell that comes out
at a half or a third of the expected long axis should be read as this limit, not as the crystal.
For very long axes the direction grid's angular resolution binds well below 500 Å — see the
analysis reference on FFT indexing.
| Option | Description |
|---|---|
--force-still |
Treat a rotation (goniometer) dataset as independent stills instead of rotation |
-X, --indexing-algorithm <txt> |
Auto (default) | FFT | cuFFT | FFTW | FFBIDX | None, case-insensitive. FFT is the de-novo FFT search, on the GPU (cuFFT) where there is one and --no-gpu is not given, otherwise on the CPU (FFTW); cuFFT and FFTW name one implementation each; cuFFT needs a GPU and is refused without one. FFBIDX (known cell, -C) runs on the GPU where there is one and otherwise on the CPU. Auto takes FFBIDX on stills with a known cell, and FFT otherwise; rotation data always use the FFT search |
-F |
Short for -X FFT, kept for old command lines |
-C, --unit-cell <cell> |
Reference unit cell "a,b,c,alpha,beta,gamma" (required by ffbidx). On rotation data it also widens the FFT search to cover the cell given, at both ends: the longest axis looked for is raised to reach it, and --fft-min-unit-cell is lowered to admit it. A candidate that is an integer supercell of the cell given (a twin's coincidence lattice, a row taken at a multiple of its length) is stepped down to it |
--fft-min-unit-cell <num> |
Shortest cell axis the FFT search accepts, Å (default: 10). A candidate with a shorter axis is discarded — but on rotation data a row shorter than the floor, down to 3 Å, is recognised under the multiple of it the search reports past the floor, so a small-molecule cell is indexed without this flag. -C lowers the floor on its own to cover the cell given. On stills a crystal below the floor cannot be indexed unless this is lowered |
--min-indexed-spots <num> |
Spots a frame must have on the lattice before it counts as indexed (default: 6, minimum 4). It sets the reported indexing rate and the count the rotation first pass ranks candidate lattices by; whether the run has a lattice at all is decided on the pooled spots instead (§4.1), and integration is not gated by it |
-S, --space-group <num|symbol> |
Space group number (96) or Hermann-Mauguin symbol (P43212) — for indexing and scaling. On serial stills whose group admits two indexings, it also lets the crystals be put on one from the data (the indexing ambiguity) |
-r, --geom-refine <txt> |
Geometry refinement: none | orientation | beam_and_lattice (default) | flex (try all three per image, keep whichever indexes the most spots; alias multi) |
-R, --two-pass-rotation[=num] |
Two-pass offline rotation indexing (default for goniometer data; optional first-pass image count, default 100) |
--single-pass-rotation[=num] |
Online-like single-pass rotation indexing (optional min angular range, deg) |
--force-rotation-lattice <vec> |
Force rotation lattice (9 floats, Å), skipping the first pass |
--rotation-no-postrefine |
Rotation: disable the default-on two-pass geometry post-refine (see Rotation data) |
--prepass-fraction <f> |
Rotation: the two-pass geometry pre-pass integrates the first fraction f of the sweep, but at least 120° of it (0.05-1, default 0.5; 1 integrates the whole sweep twice). The second pass always integrates every frame. The pre-scan and the first-pass indexing sample the same part of the sweep |
--refine-geometry[=N|off] |
Stills: extra first pass that bundle-adjusts the shared beam/distance/cell from N strongly-indexed frames (default 200) then re-indexes; default ON for stills with a reference cell (-C / -z), a stationary goniometer axis counting as stills, =off disables |
--index-ice-rings[=on|off] |
Index on the spots flagged as sitting on an ice ring too, instead of setting them aside (default: off; no effect without --detect-ice-rings, which does the flagging) |
Indexer choice in brief: ffbidx (GPU or CPU) refines toward a known cell and is best for sparse
serial stills; fft (GPU) / fftw (CPU) index de novo and suit strong rotation data. See the
CPU/GPU data-analysis reference for the algorithms.
Scaling and merging
| Option | Description |
|---|---|
--no-merge |
Skip scaling and merging, which are on by default; the per-image _process.h5 is then written instead of the merged files (_unmerged.mtz and the results report are still written) |
-A, --anomalous |
Anomalous mode: merge each Bijvoet hand as its own unique reflection, so multiplicity, completeness, ⟨I/σ⟩ and the error model are counted anomalously. A default rotation merge already writes I(+)/I(-) (see Reflection-file conventions); -A changes the counting basis, not whether the anomalous signal is in the file |
--scale-fulls / --no-scale-fulls |
rot3d: refit a per-frame scale on the combined fulls (XDS order, Unity model); on by default for rotation data, off for stills |
--smooth-g[=deg] |
rot3d: smooth the per-frame scale G over a degree range before the 3D combine (XDS DELPHI-like; default 5° for rotation, 0 = off) |
--no-scaling-corrections |
rot3d: disable the default-on decay + absorption + modulation correction surfaces fitted on the fulls after scale-fulls |
--relative-b[=deg] |
rot3d: fit a per-batch relative-B beyond the single decay slope over deg-degree batches, cross-validated (default 10° when bare; off otherwise) |
--simple-stills |
Stills: treat every reflection as a full (p = 1, single-pass scale/merge) — disables the default-on physical partiality post-refinement |
--no-expected-variance-merge |
Stills: disable the default expected-variance merge weighting (which rebuilds each weak observation's signal variance at the reflection mean to de-bias the inverse-variance merge); restores observed-sigma weighting |
--capture-uncertainty <num> |
Systematic sigma num·(1−captured fraction)·⟨I⟩: on rot3d fulls the share of the rocking curve not captured, on stills the share of each partial its partiality does not see (default: 1.0 for rotation, 0 otherwise) |
--min-captured-fraction <num> |
rot3d: drop a combined full whose rocking curve was captured below this fraction — edge-of-sweep truncated fulls (default: 0.7 for rotation, 0 otherwise; 0 = off) |
--scaling-high-resolution <num> |
High-resolution limit for scaling, Å — manual override (default: no limit; disables the automatic cutoff below) |
--scaling-low-resolution <num> |
Low-resolution limit of the scale fit, Å (default: 50, which is also XDS's own default; 0 removes the limit). Reflections coarser than it are merged and written but kept out of every fit of the scale model: on a large cell a few dozen of them, measured on a background the beam stop depresses, bent the model enough to move the merged 10–50 Å intensities by tens of percent. Which of them are measured at all is the beam-stop mask's decision - a reflection whose signal disk reaches the shadow is not integrated (--detect-beam-stop) |
--resolution-cutoff <txt> |
Automatic high-resolution cutoff for the written reflections and reported shells: cc-logistic | off (default: cc-logistic; ignored when --scaling-high-resolution is set) |
--resolution-cc-target <num> |
CC1/2 target defining the cc-logistic fall-off (default: 0.30) |
--resolution-shells <num> |
Number of resolution shells in the reported statistics table (default: 9). The bins are equal steps in 1/d² between the lowest- and highest-resolution reflection merged, which is XDS's rule, and 9 is XDS's count — so at the same resolution limits the two tables have the same shells and can be read row for row |
--report-resolution <dmin>[,<dmax>] |
Also report the merging statistics over this resolution range, Å (either order; dmax defaults to the run's own low-resolution limit), as a second table beside the run's own — the REFRES_* keys of the results report — binned from the same merged reflections, so a run can be read against another program's table at that program's range. Report-only: the cut, the scaling, the error model and every decision stay the run's own, and shells finer than the run's own limit are reported as not merged rather than filled from data the run did not keep |
--min-partiality <num> |
Minimum partiality to accept a reflection (default: 0.02 for rotation, 0.5 for stills) |
--ice-min-score <num> |
Ice-presence gate: the measured per-run ice score (1 = no ice) a dataset must reach before any ice handling is applied — the flagging, the exclusion from scaling and the per-ring merge decision (default: 1.5; 0 = no gate). The fixed hexagonal bands cover 16–26 % of the unique reflections whether or not the crystal has ice, so handling ice on a clean crystal only costs completeness |
--ice-min-spot-ratio <num> |
The second ice-presence channel: found spots on the hexagonal rings over the same q width of ice-free flanks beside them (1 = spots spread evenly). Ice in large crystallites diffracts as discrete spots and leaves the radial profile flat, so --ice-min-score alone is blind to it (default: 2.0; 0 disables this channel) |
--reject-outliers <num> |
Per-observation outlier rejection, N σ from the per-reflection median (default: 6 for rotation, 10 for stills; 0 = off) |
--min-image-cc <num> |
Per-image CC limit, percent (default: no limit) |
--search-min-zeta <num> |
De-novo space-group search only: also search a merge of just the observations whose Lorentz geometry |ζ| reaches this, and report both answers (default: 0.85 for rotation, 0 = single search). Reflections crossing the Ewald sphere near-tangentially are measured worst and can make a real symmetry operator look like a twin law. Where the two searches disagree, the merge of all the observations decides — as it always has for the systematic absences |
--mosaicity <num> |
Diagnostic: fix the scaling mosaicity (°) instead of using the per-image seed |
--scaling-iterations <num> |
Cap on the per-frame scaling iterations; the loop stops earlier once the scales settle, and a merge that hits the cap is flagged SCALING_NOT_CONVERGED (default: 100) |
-z, --reference <file> |
Reference data of the same crystal form — an MTZ or a PDB structure-factor mmCIF (-sf.cif), gzipped or not, recognised by content; --reference-mtz is the same option: fixes the space group, its setting and the cell, resolves the indexing ambiguity, hands over the R-free set and reports CCref. Not a scale anchor |
--free-flags <file> |
Take only the R-free test set of this MTZ or structure-factor mmCIF - e.g. the deposited reflections of the --model - for the validation, the refinement and the merged files; nothing else of the file is used, so unlike -z it fixes no space group, cell or frame. Taken on the model's axes where the merge matches the file's intensities (R_FREE_FLAGS=, see Free set and model bias) |
--reference-column <label> |
Reference column to use, by MTZ label — an mmCIF under the labels gemmi cif2mtz gives it (default: auto — F-model, else IMEAN/I/…, else FP/FOBS/F) |
--model <file> |
Validate the merged intensities against this atomic model (PDB or mmCIF, gzipped or not; the format is taken from the file's content) — R-work / R-free and maps (see Validating against a model). An experimental model is placed as a rigid body, and by molecular replacement where the rigid body does not place it; a prediction (AlphaFold or ModelCIF) goes to molecular replacement straight away (MODEL_PLACEMENT=). It also settles the frame the reflections are written in: the enantiomorph, and the indexing ambiguity where no -z did; another space group or the twin hypothesis' subgroup it chooses is written beside the answer as <prefix>_mr.mtz/.cif. It does not change the processing: the merge is the same with and without it. A placed model is then refined against the merge it was placed on (<prefix>_refined_model.cif, <prefix>_refined_maps.mtz, <prefix>_blobs.json, REFINE_ keys) - seconds on a GPU, typically 2-15 minutes on the CPU - which decides nothing about the processing |
--mr <file> |
As --model, but placed by molecular replacement straight away, without trying the rigid body first: as many copies as the cell holds, in every space group the merge cannot tell apart and in the twin hypothesis' subgroup. A prediction is trimmed to the residues of pLDDT 70 and above, and where the AlphaFold DB's predicted-aligned-error JSON sits beside it under its own name it is cut into rigid domains; any other PDB or mmCIF is taken as an experimental structure, its polymer only (no waters, ligands, hydrogens or alternative conformers). It may relabel the enantiomorph of the answer, and a different space group it chooses is written beside the answer as <prefix>_mr.mtz/.cif with the placed model <prefix>_mr_model.pdb. --mode mx only; not with --model |
--no-refine |
Do not refine the placed model (for debugging): by default a model that --model or --mr places is refined |
--refine-solvent |
Also build the solvent of the refined model: waters added at difference-map peaks and removed where the maps no longer hold them, waters and ions relabelled, and each site audited (the REFINE_SOLVENT_ keys and <prefix>_solvent.json). Off by default for now: the model is refined with its solvent as given, and the report says REFINE_SOLVENT=NOT_PERFORMED. Also with --mode refine |
--no-refine-solvent |
The default: no solvent build or audit (turns off an earlier --refine-solvent) |
--write-process-h5 |
Also write the (large) _process.h5 when merging (default: only .mtz/.cif) |
--developer |
Write the full <prefix>_report.txt: the pipeline-internal keys and the long explanations the default report leaves out. Nothing is computed differently — the same report, rendered in full (see The results report) |
--finalist-ledger |
Report the full-resolution evidence for each space group the search considered, not only the one it adopted, and the twin-immune zone evidence of the adopted group's 2-folds (report-only; the decision is unchanged). Both are read on a merge of the observations in P1 that only this option makes, so it costs one extra merge; rotation only, and not with a fixed centred -S |
--export-unmerged |
Write <prefix>_unmerged.mtz, an unmerged MTZ (POINTLESS column layout), for aimless / pointless. On by default whenever there is an output prefix. Rotation partials are summed into one full per reflection, and on a rotation merge I/SIGI are the merge's own scaled fulls, those it rejected left out. Otherwise intensities carry the deterministic per-reflection corrections and nothing else — Lorentz and polarization in LP, sensor efficiency in QE, flight path in FLIGHT — while the partiality is not divided out and the per-image scale is not applied. Written in --mode mx and --mode scale, and with --no-merge. See The unmerged export |
--no-export-unmerged |
Do not write <prefix>_unmerged.mtz. It is the largest file a run produces, so a run whose observations are not going to another scaling program can skip it |
--export-unmerged-partials |
Write <prefix>_unmerged_partials.mtz, the integrated observations unscaled, each partial as its own row (one batch per image), for a reading program that sums and scales them itself (careless). Off by default, and independent of --export-unmerged |
--export-observations |
Stills diagnostic: write <prefix>_obs.mtz, every integrated observation of the written merge as one row - its signed excitation error, partiality, the run's rocking width, raw I/σ and background, corrections, scale, the σ the merge weighted it with, the frame's cell and orientation, and a bit for each merge test it fails (observations the merge drops included). Processing is unchanged |
--dump-observations <file> |
Diagnostic: write the unmerged fulls of every rotation 3D combine to <file> as text, for a comparison with XDS |
Integration
| Option | Description |
|---|---|
--integrator <txt> |
Spot integrator: gaussian (profile-fit, default) | empirical | boxsum (classical fallback) |
--integration-radius <r> |
Signal-box radius r1, or r1,r2,r3 (px). One value ⇒ r2=r1+2, r3=r1+4 |
--adaptive-integration-radius[=on|off] |
Set the signal radius r1 from how wide this crystal's spots actually are (default: on). On stills it measures instead how far the background ring should reach: on empty apertures of the pre-scan frames, the r3 (up to 14) whose ring best predicts the background under the signal disk. r1 is not the integration domain — that is the profile-fit grid — but it is the aperture the profile width is learned over, and a second moment over a disk of radius a saturates at a²/4, so at the shipped r1 = 4 the learned σ can never exceed 2 px and a broader spot is fitted with a profile the model cannot represent. The pre-scan reads r80, the radius holding 80 % of a spot's flux, off isolated strong spots over a fixed 14 px aperture that owes nothing to r1, fits it against 1/d and evaluates it at 5 Å; then r1 = clamp(round(2·r80), 4, 6), r2 = r1 + 2, and r3 is taken so the r2..r3 background ring keeps the area it has at the default 4,6,13. The ceiling of 6 is pattern density: r2 also drives the neighbour-ownership radius and the ring's inner edge, and past it a dense pattern starts losing reflections whose ring falls below six clean pixels. Ignored when --integration-radius is given. The widened radius applies to the final integration pass only — the two-pass geometry pre-pass keeps the radius the run started with, because the post-refinement fits the detector distance and beam to the observed reflection positions and those move with the signal disk (33 µm and 0.02 px between r1 = 4 and r1 = 6 on one crystal, enough for the second pass's de-novo lattice search to settle on a different lattice and index a fifth fewer frames). And where the widened radius leaves more than 1.1 % of the predicted reflections without a background ring — a pattern too dense for it — the final pass is re-integrated at the fixed 4 px radius, and the log says so. Over the rotation regression battery it moves 12 of 38 crystals and leaves the merged intensities of the other 26 unchanged; where it moves them, per-shell ⟨I/σ⟩ improves by up to 31 % and R_meas by up to 24 % |
--integration-stencil <k> |
Push the r2..r3 background ring out by k times the beam's radial streak bandwidth·R_px, per reflection (default 0 = the fixed circular ring). A fixed ring otherwise ends up on a streaked reflection's own tails at high resolution and measures them as background. Only the ring moves, and only radially — the r1 signal box stays a circle — and the growth is capped at 2·r3. The neighbour exclusion grows with it, so on a crowded pattern a few reflections can be left with too little background and dropped. On a monochromatic beam the streak is zero and this does nothing |
--background-clip <n> |
High-side clip of the background ring at mean + n·√mean (default 4, whatever the bandwidth; 0 = off). The default background estimator — it rejects neighbour cores and zingers without the symmetric trim's Poisson skew bias. Ignored by --integrator boxsum |
--background-trim <f> |
Use the old symmetric trimmed mean for the background ring instead of the clip, 0≤f<0.5 (0.10 was the former default). Switches --background-clip off. A symmetric trim is biased low on Poisson data and adds ~5 counts to every partial, so this is for back compatibility only; 0 = plain ring mean. Rings holding more than 512 pixels fall back to the plain mean (the GPU sorts the ring in shared memory and the CPU now matches it), which the default radii never reach but wide ones do |
--background-radial[=on|off|auto] |
Correct the background ring for the curvature of the radial background (default auto). Disk and ring are concentric, so a background linear in position cancels between them and only curvature survives — which on a smooth ice ring reaches +26 counts on a single reflection. auto decides per run in the pre-scan, on empty apertures of the pre-scan frames: on stills it is applied to every image where it makes the ring predict the background of empty apertures better at all; on rotation data to every image where it takes at least 10 % of that error away, and otherwise only to images whose ice score shows a smooth powder ring (ice made of discrete crystallite spots leaves no such ring, and the correction makes the bias worse). Ignored by --integrator boxsum (no clip pass to take the curve from) |
--integration-high-resolution <num> |
High-resolution limit for prediction and integration. Omitted (or 0) means integration extends as far as the detector reaches — which is what the predictor can place on the detector anyway, since it rejects reflections that miss it. Set a value to integrate less than the detector offers |
--max-hkl <n> |
Predict reflections with |h|,|k|,|l| ≤ n (max 511). By default this is derived per crystal from the refined cell as ceil(max(a,b,c)/d_min) + 1, which is the exact bound: the predictor keeps only |q| ≤ 1/d_min and h = a·q, so no reflection can lie outside it and no candidate inside it is wasted on a shorter axis. Set it only to override that |
--bandwidth <num> |
Relative X-ray bandwidth FWHM (e.g. 0.01 for a 1% DMM). Default: the file's value; where the file states none, the one the pre-scan measures from how much longer strong spots are along their radius than across it, used where it is significant; otherwise 0 (monochromatic). --bandwidth 0 forces a monochromatic beam |
--overlap <txt> |
What to do where two predicted reflections share signal pixels: off | reject | exclude (default exclude). A shared pixel belongs to the nearer centre; without this a crowded reflection reads high on a dense pattern. exclude drops the shared pixels from the profile fit, which renormalises itself, and keeps the reflection; reject instead drops the whole reflection when too little of its profile is cleanly its own. --integrator boxsum has no profile to renormalise, so only reject acts there |
--overlap-minpk <f> |
Least fraction of a reflection's expected profile that must be usable for it to be kept (default 0.75, XDS MINPK). Governs both the fraction that must be readable — not masked, untrusted, in a gap or overloaded — in every profile mode, and, under --overlap reject, the fraction that must be cleanly its own. Under --integrator boxsum any unreadable pixel discards the disk outright and the reject fraction goes by disk area, which cuts harder |
--flight-path <txt> |
What the diffracted beam crosses between the sample and the detector: air (default) | helium | vacuum. A reflection arriving at angle α to the detector normal flies D/cos α instead of D, so it crosses more of the medium and reads low; the factor is exp(D/L·(1/cos α − 1)), with L the attenuation length of the medium from the NIST tabulation and D and λ as stated by the file — nothing in it is fitted. Nothing in NXmx, and no field of any master file Rugnux reads, describes the medium, so it cannot be auto-detected and is assumed; the report states which medium was assumed and what it was worth (FLIGHT_PATH, FLIGHT_PATH_WILSON_B). Nor can it be inferred from the implied transmission — in this corpus a confirmed helium station sits at 51 % implied air transmission and a confirmed air station at 63 %. In air the term is +1.5 % at α = 55° for 18 keV over 160 mm and several-fold below 5 keV, where stations use helium precisely because air is unusable; helium attenuates ~1/600 of air, and vacuum leaves intensities untouched |
--stills-window-sigmas <k> |
Stills: half-width of the prediction window in units of the run's measured rocking width - every frame predicts the reflections within k rocking widths of the Ewald sphere (default 2) |
--prediction-mosaicity <num> |
Diagnostic: fix the rocking width (deg) the prediction window opens to, leaving partiality on the per-image σ_M. The two are one number by default, so a σ_M that moves takes the integrated reflection population with it |
Geometry overrides
Defaults are taken from the input file; override them to reprocess with a corrected geometry.
| Option | Description |
|---|---|
--beam-x <num> |
Beam centre X (pixel). --beam-center-check still runs and can adopt its measured centre (§1.4) |
--beam-y <num> |
Beam centre Y (pixel). --beam-center-check still runs and can adopt its measured centre (§1.4) |
--detector-distance <num> |
Detector distance (mm). On stills it is then held: neither searched nor refined. Without it, stills with a reference cell (-C) search the distance and refine it with the cell |
--wavelength <num> |
Wavelength (Å) |
--pixel-size <num> |
Pixel size (µm), for a file that does not state it (an XTC stream of an unknown camera) |
--gain <num> |
Detector units per photon, for input in detector units (SACLA, CXI, XTC, SMV, marCCD and --crystfel-geometry input). Where the background resolves single photons (SACLA, CXI and --crystfel-geometry input) the frames are counted in whole photons as they are read; otherwise they are analysed in their own units and the gain enters where a photon count is assumed. The integrated intensities come out in photons either way. Default: measured on the background of a few frames (Serial XFEL inputs) |
--saturation <num> |
Pixel value from which a pixel is overloaded, in the units the frames are read in. Replaces the file's limit and the one stills read off the frames |
--crystfel-geometry <file> |
Place the panels of an HDF5/CXI input by a CrystFEL geometry file instead of the file's own metadata: module geometry, camera length, mask arrays and bad regions (optional; Serial XFEL inputs). Photon energy, camera length and - where the geometry names no mask array - the masks otherwise come from the data files (Cheetah CXI, SACLA) or the command line; gain and saturation are measured. Tilted panels, dimN layouts, per-panel data and detector shifts are refused |
--module-geometry <file> |
Where the detector's modules are: an NXmx file with one NXdetector_module per module (what a run writes as <prefix>_modules.h5) or a CrystFEL geometry file whose panels are laid on the image. Overrides the input's own |
--module-placement <file.json> |
Place the modules as a module placement file says (<prefix>_module_placement.json of an earlier run, the module_placement fragment of the broker's dataset settings; Module placement file). Entries name modules by their readout pixel 0 and readout axes in the image as stored, after mirror_y (x0, y0, fast_axis, slow_axis: the words of the broker's custom_geometry, which is before mirror_y); one that matches no module, one named twice, or a module left out, is an error |
--panel-refine[=off|diagnose] |
Stills on a detector of several modules: by default the geometry bundle adjustment places each module as a rigid block where that predicts held-out spots better - the whole placement must beat the given one, and each module keeps its move only where its own held-out spots are predicted better, the others staying where they were given. --panel-refine keeps every move the spots support, without these tests; =off keeps the modules as given (a CrystFEL .geom included). A placement used is written to <prefix>_modules.h5; on stills <prefix>_module_placement.json is written unless =off, also where every module was held. =diagnose also runs a set of tests on the placement and writes them to the log |
--mask-good [<file>:]<dataset>[@<bits>] / --mask-bad [<file>:]<dataset>[@<bits>] |
HDF5/CXI stills: a mask array in the frames' stored layout, in <file> or in each data file; usable only where non-zero (or with all <bits>) / unusable where non-zero (or with any <bits>). Repeatable (Serial XFEL inputs) |
--rot1 <num> |
PONI detector rotation 1 (rad). On stills, --rot1 or --rot2 holds the tilt (not refined); without them stills refine the tilt where held-out frames agree |
--rot2 <num> |
PONI detector rotation 2 (rad) |
--rot3 <num> |
PONI detector rotation 3, about the beam (rad) — the one rugnux --mode calibration writes into its .poni, so a refined third rotation can be given straight back |
--detector-mirror-y |
The stored image is mirrored in Y relative to the frame the PONI angles are stated in |
--detector-quarter-turns <0-3> |
The stored image is turned by this many multiples of 90° about the beam relative to that same frame |
--polarization <num> |
Degree of polarization p (XDS FRACTION_OF_POLARIZATION = (1+p)/2), signed: positive for a horizontally polarized source, negative for a vertically polarized one; where the beam-stop pre-scan finds the background clearly suppressed in the other plane, the degree is applied in that plane instead. Default: what a miniCBF # Polarization line or a dTREK SOURCE_POLARZ states (a fraction f, read as p = 2f* − 1, so a laboratory tube's 0.5 is unpolarized), and otherwise 0.99, an undulator value; bending-magnet and wiggler sources are typically lower (0.8–0.95), and neither ADSC SMV, marCCD nor NXmx files state it, so pass the beamline's known value here |
--rotation-scale <k> |
Goniometer rotation scale: the stage turned k times the angle stored in the file (the commanded one). Applied to both passes, and overrides the scale Rugnux fits for itself |