Files
Jungfraujoch/docs/RUGNUX_ADVANCED.md
T
leonarski_f 8edd0e5f3e docs: rugnux options, model and export pages brought in line with the usage text
RUGNUX_ADVANCED: --simulate-live/--fast-live rows, -e exclusive, stills
behaviour of --beam-center-check, -S, --min-partiality (0.5),
--capture-uncertainty, --adaptive-integration-radius (on for stills too),
--detector-distance/--rot1/--rot2/--no-refine-tilt; --background-radial
auto as it decides now; --refine-modules syntax; _cell.*_esd.
MODEL_AND_REFERENCE: the default refinement of a placed model in the
summary, the decision table and the step list; --mode scale does not refine.
INTEGRATION: the .ins written beside every .hkl (ZERR on rotation).
VIEWER: rugnux writes _process.h5 only with --no-merge/--write-process-h5.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015CeEGgpKdfkCTJb3YNMJcu
(cherry picked from commit 51d2564356ba46bda8730c855ff8d3ee7c23d605)
2026-10-26 14:50:42 +01:00

64 KiB
Raw Blame History

Advanced Rugnux

The machinery behind a run that needs more than the defaults: external reference data, model validation, re-merging without re-integration, and the full option tables.

:local:
:depth: 2

Reference data and the indexing ambiguity

What a reference does (-z)

-z reference.mtz supplies known intensities of the same crystal form — a previously merged dataset, or F-model amplitudes computed from a structure. The reference can equally be a PDB structure-factor file (-z 1abc-sf.cif, SF-mmCIF), gzipped or not; the format is taken from the file's content. From an mmCIF the first merged reflection block with a usable column is read (the log names it), its columns under the MTZ labels gemmi cif2mtz gives them (IMEAN, FP, FC, …), and its R-free set from _refln.status (f free, o working), or from _refln.pdbx_r_free_flag where the status marks no test set. It is read once, before processing starts, and used for five things:

  • It fixes the space group and the unit cell the run works in, unless -S / -C override them. The cell is a soft reference: indexing may still drift within tolerance, so a small mismatch between reference and data is absorbed rather than rejected.
  • It fixes the axes the files are written on. The group is taken in the setting the reference is written in (P 2 21 21 stays P 2 21 21, not only "number 18"), and once the run has merged, every description of its lattice on the reference's axes - axis permutations, sign flips, I- against C-centred - and every alternative indexing on top is correlated with the reference; the best one is re-merged and written. REFERENCE_OPERATOR= names the operator (h,k,l where the data were already on the reference's axes), REFERENCE_CC= and REFERENCE_MATCHED_FRACTION= how well the result matches.
  • It resolves the indexing ambiguity (below) — the one thing the data cannot settle for themselves: which of the equivalent indexings is the reference's own.
  • It hands over its R-free test set, where the file carries one, so every dataset of a campaign is scored on the same free reflections - in the reference's frame, and only where the merge matches the reference (CC at least 0.5 over at least half of the merged reflections in its resolution range). A reference that does not is reported (REFERENCE_MISMATCH), and the merge keeps its own test set; REFERENCE_FREE_FLAGS_INHERITED= says which happened.
  • It reports CCref, the correlation of the merged intensities against the reference, in the statistics table. Stills only — the rotation merge never scores itself against the reference, and its table shows - in that column.

A reference is not a scale anchor. Both workflows scale against their own data — scaling images against a foreign dataset injects that dataset's systematics — so -z never puts the reference's errors into the intensities. --reference-column picks the column to read where the automatic choice (F-model, else IMEAN/I, else FP/FOBS/F) is not the right one.

For the indexing ambiguity an atomic model does as well: --model computes the intensities it needs from the structure (a model that fits also sets the hand label and the setting, see Validating against a model). Where a reference dataset exists, prefer it; where only a model does, it resolves the ambiguity just the same.

The indexing ambiguity

Some crystals can be indexed in more than one way, each equally valid geometrically, and each giving different merged intensities. This happens whenever the lattice is more symmetric than the crystal: in P3, P4, P6, P31, C2 and their relatives (merohedral), and also where the cell is metrically more symmetric than the Laue class by accident (pseudo-merohedral, up to 2° of obliquity). The alternatives are related by the crystal's twin laws — reindexing operators such as k,h,-l.

Nothing in the data says which solution is the true one: the merge is equally self-consistent either way, so which comes out is arbitrary. What that costs depends on the workflow:

  • Rotation. The whole sweep is one lattice, so the whole dataset lands in one indexing, picked at random. The merge itself is sound; it may simply be the other solution from an earlier dataset of the same crystal form, and the two cannot be combined, compared or phased against the same model.
  • Serial stills. Every crystal is indexed independently, so a run mixes both indexings into one merge. That is not a labelling matter — reflections that are not symmetry mates get averaged together, and CC1/2, Rmeas and the anomalous signal all degrade. The data can say which crystals are in the same indexing, though, and that is what a merge needs: with the space group given (-S) and no reference, Rugnux puts each crystal into the indexing in which it agrees best with all the others, before anything is scaled. This takes seconds for tens of thousands of crystals, and the report says how clearly the crystals separated (AMBIGUITY_SEPARATION_SIGMA=, AMBIGUITY_DECIDED_FRACTION=) and how many were moved (AMBIGUITY_REINDEXED=). The indexing the whole merge ends up in is still arbitrary against other data sets, exactly as on rotation data. On a pseudo-merohedral cell whose axes differ by a few per cent, each crystal's own refined cell already says which axis is which; there only the crystals whose cell does not are decided by the intensities, and the others keep their indexing.

Every run that merges tests for the ambiguity, and where it exists and nothing resolves it (serial stills whose space group was determined by the run rather than given), says so in the log and in the report's warnings:

Indexing ambiguity: this cell / space group admits alternative indexing (reindex operator(s):
-h,-k,l). Serial-stills crystals are indexed in one hand at random, and rugnux makes them consistent
from the data only where the space group is given: here it was determined by the run, so the merge
mixes the hands and CC1/2 is degraded. Giving the space group (-S) resolves it from the data; a
reference MTZ (-z) or a model (--model, which needs -C and -S here) resolves it against them.

Where something does resolve it, the run says so instead — Indexing ambiguity present (reindex operator(s): -h,-k,l); resolved against the supplied reference or ...; resolved from the data.

How to resolve it:

Situation What to do
Rotation, a reference dataset exists -z reference.mtz. Once the space group is settled, each candidate reindexing of the merged intensities is correlated with the reference and the best-correlating one is re-merged. Only the hkl labels change; the cell does not
Serial stills, a reference dataset exists -z reference.mtz. Resolved per image, at integration time, by correlating each crystal's intensities with the reference — so the merge never mixes hands in the first place. Where the crystals' own cells tell the indexings apart (pseudo-merohedry), a crystal its cell decides keeps that indexing and the reference decides the rest. The data-only resolution below runs as a check: AMBIGUITY_DATA_DISAGREES=
Rotation, only a model --model model.pdb. The merged data are fitted to the model in each candidate indexing and the lowest R-free wins — provided the model first beats its random-orientation null (MODEL_FIT= ACCEPTED) and its lead over the runner-up beats the lead a random placement of the same model takes; the written reflections are then reindexed into it, so the file, the R-factors and the maps agree. Where either bar is missed the data keep the indexing they were merged in, and the report says by how much (MODEL_INDEXING_MARGIN_SIGMA). It is the data that are relabelled, never the model: every dataset of one crystal form processed against the same model comes out in that model's indexing, so the reflection files and maps of a screening campaign compare directly. The relabelling is a proper rotation of the lattice, so the merging statistics are unchanged and I(+)/I(-) keep their hand
Serial stills, only a model --model model.pdb, with the cell and space group given (-C / -S). Structure factors are computed from the model up front and used as the reference for the per-image test, exactly as a reference MTZ would be, the crystals their own cell decides again excepted. The data-only resolution below is then run only as a check: AMBIGUITY_DATA_DISAGREES= counts the crystals on which it would have chosen otherwise
Serial stills, neither, space group given (-S) Nothing to do: the crystals are made consistent with each other from the data alone (INDEXING_AMBIGUITY_RESOLVED= data), in an indexing that is arbitrary against other data sets. A model or reference still settles the weakest crystals more reliably than the other crystals can, and puts the merge in its own indexing
Neither The run warns and merges in whichever indexing it found: for rotation data a usable dataset in an arbitrary frame; for stills whose space group the run determined, a merge of mixed indexings, which looks like a perfect twin and can pass for higher symmetry than the crystal has. Run again with -S

Two things to know about where the choice lands:

  • --mode scale cannot repair a stills run after the fact. The per-image test happens at integration time, so a _process.h5 whose images were integrated without a reference — an MTZ or a model — has already lost the distinction, and no re-merge brings it back; the data-only resolution runs in the full pipeline, not in --mode scale. On rotation data, where the ambiguity is one choice for the whole dataset, --mode scale --model model.pdb does resolve it.
  • The choice reaches the written reflections, not only the R-factors and the maps: the merged .mtz / .cif / .hkl (and _unmerged.mtz, where it is asked for) are written in the indexing the model or the reference settled on, so the file can be refined against that model as it stands.

Two things the indexing ambiguity is not:

  • Not the enantiomorph. P41212 versus P43212 (or P31 versus P32) leaves the merged intensities unchanged, so no amount of data can choose between them and Rugnux never tries — the run reports the pair it cannot separate. A model the data accept names it (MODEL_FIT= ACCEPTED in the report), and the naming is a label only: the written reflections take the model's space group, no reflection moves, and I(+)/I(-) stay exactly as measured — reindexing by the change of hand would flip every anomalous difference, so it is never done. Whether the model and the data really agree about the hand is answered afterwards by the anomalous difference map, which warns when the density at the model's atoms comes out inverted. The _process.h5, whose per-image reflections were written as they were integrated, keeps the group the run determined and is left alone.
  • Not twinning. The twin laws are the same operators, but twinning is a property of the crystal — two orientations diffracting at once — and is reported separately in the report's twinning section. A crystal can have an indexing ambiguity without being twinned, and usually is not.

The algorithms behind both are in CPU/GPU data analysis ▸ Reference data.

The setting the files are written in

The space-group search decides which axes carry the screws and the centring on the cell as it was indexed, whose axes are ordered by length. The files are then written in the standard setting, as XDS and POINTLESS write it (SETTING_SOURCE=STANDARD): P2221 and P21212 with the unique axis on c and a<b; the other orthorhombic groups a<=b<=c; C222 and C2221 with a<b; monoclinic b-unique, C-centred (never I2), least oblique with beta >= 90; triclinic keeps the reduced cell. So a crystal indexed as 52.51 87.87 137.72 in P 2 21 21 is written as 87.87 137.72 52.51 in P 21 21 2.

What the user gives takes precedence, in this order: a reference MTZ (-z, its own setting), a model that fits (--model, its setting), the axis order of a cell given with -C (SETTING_SOURCE=CELL), and the setting of a group given with -S by a non-standard symbol (-S "P 2 21 21", SETTING_SOURCE=SPACE_GROUP). A group given with -S is also placed on the axes its absences name before anything is merged, so -S 18 on a cell whose pure two-fold is its shortest axis puts the screws on the right rows.

The change is a relabelling made after every decision - nothing measured, and no decision, depends on it - and it is applied to everything the run writes: the merged .mtz/.cif/.hkl, _unmerged.mtz and the _process.h5 (whose per-image reflections carry the reindex matrix). SETTING_OPERATOR= gives it as a reindexing operator on the indices the space group was determined on, CCP4 style (k,l,h is h'=k, k'=l, l'=h); h,k,l where nothing moved.

Validating against a model (rugnux --model)

Which decisions a model can influence, and which it cannot, is set out decision by decision in Models and reference data.

Given an atomic model of the same structure, --model model.pdb scales the model structure factors to the merged amplitudes — fitting a flat bulk-solvent contribution and an overall anisotropic B — and reports R-work / R-free and the mean 2mFo−DFc density at the atom centres. It also writes the map-coefficient MTZ <prefix>_maps.mtz next to the merged reflections: the σA-weighted 2mFo−DFc and mFo−DFc coefficients, which Coot and PyMOL open directly as maps. Where the merge kept the Bijvoet split (a rotation merge always does), an anomalous difference map is made too and read, not written: the report names its strongest sites (ANOMALOUS_SITE_01…10) and the map's mean height at the model's anomalous scatterers - every atom from phosphorus up - as one number for the anomalous signal (ANOMALOUS_SCATTERER_MEAN_SIGMA). The model is not refined for these numbers (a placed model is refined afterwards, on the side - see Refinement); it is re-fractionalized into the data cell and then placed as one rigid body, so a deposited model from a crystal that is not quite isomorphous still sits where the density is. The placement runs on the GPU where there is one and on the CPU otherwise, with nothing to set; the two agree to rounding, not bit for bit.

The rigid body only moves a model that already sits near its place, so its placement is checked: the model counts as placed where its fit beats the same model refitted from random orientations (the null behind MODEL_FIT, below), in the answer's merge or in the twin hypothesis' one. An experimental model the rigid body does not place — a deposited structure of another crystal form, a model of a subgroup the data were merged above, a file with no crystal cell — is then searched for by molecular replacement: as many copies as the cell holds, in every space group the merge cannot tell apart and in the twin hypothesis' subgroup (the search and its keys are in Molecular replacement). A predicted model — AlphaFold or ModelCIF, recognised from the file's content (pLDDT in the B column) — has no placement of its own and goes to molecular replacement straight away, 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, cut into rigid domains. --mr <file> is --model with the rigid body skipped: molecular replacement straight away, whatever the model. The report says which way the model was placed, MODEL_PLACEMENT= RIGID_BODY, MR or NOT_PLACED; a model placed nowhere is a result, not a warning, and the reflection files are then what a run without a model writes. Where molecular replacement placed it, the R-factors, the maps and the placed model below are those of its placement. Molecular replacement is part of the full --mode mx run, rotation and serial stills alike; --mode scale (below) places the model by the rigid body alone.

A placed model changes two things in <prefix>.mtz/.cif/.hkl and nothing else: the enantiomorph label and, placed by the rigid body, the indexing ambiguity (molecular replacement relabels the hand, past the same anomalous check, and never reindexes). Where the model chooses another space group with the answer's rotations, or the twin hypothesis' subgroup, the answer's files stay the run's own and that merge is written beside them as <prefix>_mr.mtz/.cif — from the merge it was chosen on, with the twin law and fraction where it is the subgroup — together with the model as placed there, <prefix>_mr_model.pdb/.cif; the report names them (MODEL_CHOICE_FILE_PREFIX=, MODEL_CHOICE_SPACE_GROUP=).

Because the model moves, the input file no longer describes these maps, so the model as placed is written as <prefix>_model.cif — the input's chains, residues, ligands, waters, B-factors, occupancies and anisotropic Us, at the coordinates the maps were computed from, in the same unit cell and space group as <prefix>.mtz beside it. The same coordinates are written as <prefix>_model.pdb as well, because the fragment-screening tools this file exists to feed take a PDB: PanDDA's per-dataset input is <name>.pdb beside <name>.mtz, and dimple produces that same pair. (The PDB is skipped, with a log line, for a cell its fixed-width format cannot hold; the mmCIF is unconditional.) That is the file to open with the maps, and the one to hand to REFMAC5 or phenix.refine; its starting R-free is the R_FREE= the report quotes. Rugnux's own refinement of it is written beside it as <prefix>_refined_model.cif with <prefix>_refined_maps.mtz (Refinement). (<prefix>.cif is the merged reflections — hence the separate name.)

Where the run also wrote a twin hypothesis — <prefix>_twin_<SG>.mtz/.cif, the same data merged in a subgroup with a twin law, written when the adopted space group may have absorbed one (see the twin hypothesis) — the model is scored against that merge as well, plainly and as twinned by the law, and the maps and <prefix>_model.cif come from whichever of the two merges the model fits better on R-free. The report says which (MAPS_FROM=) and gives the R-free of both. <prefix>.mtz and the space group are the run's own either way; where the model also fits that merge against its null, it has chosen the subgroup, and the merge is written once more as <prefix>_mr.mtz/.cif (above). Both are written whenever the maps are, including for a model the data rejected: the rejection is a result, and it is exactly the case where someone wants to look at the model in the density.

The model may be PDB or mmCIF, gzipped or not, and the format is taken from the file's own content rather than from its name — a model downloaded as .cif, .pdb, .ent or with no useful extension at all is read the same way. A model that cannot be read, or that has no atoms, no unit cell or no usable space group, does not fail the run: it is logged, and the results report carries a WARNING: Model validation did not run: … line, so a run that silently produced no R-free and no maps cannot be mistaken for one that was never given --model.

Either way the results report carries a 5. MODEL VALIDATION section: R_WORK= / R_FREE= with their reflection counts, R_MODEL_SHELL_SCALED= and MODEL_RADIAL_MISFIT= beside them (the R that compares between two runs, and why the other two do not — see RUGNUX_REPORT), the bulk-solvent and overall scale parameters, the mean 2mFo−DFc density at the atom centres, the reindexing operators the written reflections were brought into the model's frame with, and MAPS_PREFIX=; or MODEL_VALIDATION= NOT_PERFORMED with MODEL_VALIDATION_REASON= when the model could not be used. A run given no --model has no such section at all.

It is a data-quality lens, independent of the internal statistics: R-free measures the merged intensities against external truth, where CC1/2 and Rmeas only measure them against themselves. It also settles the two things merged intensities alone cannot, in two different ways — though only where the data accept the model first: the same model is refitted, and re-placed, from random orientations about its own centroid, and the real fit has to beat that null (MODEL_FIT= in the report; §14.5). A model that fits no better than its own random placements decides nothing, and the reflection files are byte for byte what a run with no model would have written. The enantiomorph is a relabelling: data merged in P41212 against a P43212 model take the model's space group as the label they are written under, with no reflection moved and I(+)/I(-) exactly as measured. A merohedral indexing ambiguity — when no reference MTZ has already fixed it — is a reindexing: the candidate with the lowest R-free is kept — where its lead over the runner-up beats the lead a random placement of the same model takes — and applied to the written reflections as well as to the R-factors and the maps; otherwise the data keep the indexing they were merged in. This is distinct from a model written in another description of the lattice — other axes, a different unique axis, I-centred where the run indexed C-centred — or in another point group: there the model is first put into the data's description (MODEL_CHANGE_OF_BASIS=) to be scored. A model that asserts such a setting is then tested against its random placements like any other claim, and where it fits, the data move instead: the files are written in the model's setting (SETTING_SOURCE=MODEL), and the validation is made once more on those axes so the maps and _model.pdb match them. Where it does not fit, the files stay in the standard setting. Validation runs before the reflection files, so the .mtz / .cif / .hkl come out in the model's frame either way — reindexed where the ambiguity decided, and carrying the model's space group where the hand was adopted. The log names the operator in each case, and for the indexing choice gives the winning R-free together with the runner-up.

Re-scaling and re-merging (rugnux --mode scale)

The scale mode re-scales and merges the already-integrated reflections stored in a _process.h5 file, without re-running spot finding or integration. Use it to re-merge quickly with a different space group, resolution limit, anomalous setting or outlier rejection. It reuses the same -o/-N/-s/-e/-S/-A/-z/--scaling-* options as the full run, and (unlike the full pipeline) does not run a space-group search: it merges in the space group and unit cell the file records, and -S / -C override them. A _process.h5 written before the group was stored carries none, and merges in P1 unless -S says otherwise.

A reference MTZ (-z) is accepted here on stills data, where it fixes the space group and cell, reports CCref and hands over its R-free flags; on rotation data the rotation scaler declines it and the run stops with a message saying so. --model works here as in a full run, except that the model is placed by the rigid body only: a model it does not place, or a prediction, is not searched for by molecular replacement, --mr is refused, and the placed model is not refined. On rotation data, where the indexing ambiguity is one choice for the whole dataset, it can settle the enantiomorph label and the indexing — under the same fit test as always — and the re-merged reflections are written in what it settled. What no re-merge can repair is a stills _process.h5 integrated without a reference: there the ambiguity was decided per image, at integration time, and the distinction is gone from the stored reflections.

Where the full run re-seated the lattice — the space group it settled on is in a different setting from the one each image was indexed in — the file records the change of basis as /entry/MX/reindexMatrix, and rugnux applies it on read, so the reflections and the stored cell describe the same frame. An older file that was affected by this cannot be repaired (the matrix is not recoverable after the fact); such a file now stops with a message naming both cells and the exact -S/-C override to merge it in its own setting, instead of failing inside the merge.

The merged mmCIF (<prefix>.cif)

The .cif follows the PDBx/mmCIF dictionary and holds one data block, data_sample: the merged reflections (_refln: I, F and the Bijvoet mates, with the free set in _refln.status) and what describes them - the cell and space group; _software with Rugnux named twice, once for data reduction and once for data scaling; the experiment as the input file states it (_diffrn.ambient_temp from the sample temperature, the wavelength, the source's facility and beamline and its general class, the detector's make and model in _diffrn_detector.type and its class in _diffrn_detector.detector, and the collection date from the NXmx start time); and the merging statistics overall (_reflns) and per shell (_reflns_shell): completeness, multiplicity, <I/σ(I)>, R_merge, R_meas, R_pim, CC1/2 and CC*, and SigAno where an anomalous split was made; on rotation data the cell carries its e.s.d.s (_cell.length_a_esd, …). A quantity the input does not state is left out rather than guessed. The unmerged observations are in the _unmerged.mtz (unscaled) and the .hkl (scaled), not in the .cif.

Items PDBx does not define — ISa, the error model, the twinning and anisotropy diagnostics, the refined distance and beam centre — are written under the jfjoch_ local prefix, which a dictionary check reports as unknown and a deposition ignores.

Provenance

Every reflection file says where it came from, so that it can be traced back without the report beside it:

  • the .cif names the Rugnux version in _software.version and the commit it was built from in _software.description, and the command line, the input file (absolute path) and the input's identity under _jfjoch_provenance.command_line, .input_file and .input_identity;
  • the .mtz and the _unmerged.mtz carry the same in their HISTORY records (mtzdump prints them), each run on over further records where it is longer than the 80 characters of one.

The identity is the input file's size and modification time — for an HDF5 data set, the master file's — which tells two files of one name apart without reading the data. A collection followed from the broker is not a file here, and has none.

Command-line 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
--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)
--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 above). 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

Geometry:

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)
--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. 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). 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. A de-novo rotation run also tries a second first-pass hypothesis with the short end lowered to 5 Å, so a small-molecule cell below the 10 Å floor is indexed on its true axes rather than as a supercell of them; the standard pass's answer stands unless that evidence takes it. 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
-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
--fft-min-unit-cell <num> Shortest cell axis the FFT search accepts, Å (default: 10). A candidate with a shorter axis is discarded — but a de-novo rotation run also runs a second first-pass hypothesis with the floor lowered to 5 Å by default, adopted when the standing cell turns out to be an integer supercell of what it finds, so a small-molecule cell is indexed without this flag. -C lowers the floor on its own to cover the cell given (and the second hypothesis then stays out of the way). On stills, where neither applies, 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 the rotation section)
--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 (see below)
--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 and the exclusion from scaling (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
--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. For serial stills given -C / -S, the model's structure factors become the per-image reference. 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. --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
--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) of the integrated observations, for aimless / pointless / careless. On by default whenever there is an output prefix. Rotation partials are summed into one full per reflection. 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 same observations with each partial as its own row (one batch per image) for the reading program to sum. Off by default, and independent of --export-unmerged

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
--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)
--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
--refine-modules[=on|off|diagnose] Stills: place each module as a rigid block in the geometry bundle adjustment, where that predicts held-out spots better (default: on). Used for a foreign multi-panel detector, measured and reported only for a JUNGFRAU; the placement is written to <prefix>_modules.h5
--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