A sweep of docs/ against the code, and a changelog a user can read. The report reference still described the section layout from before the report was rewritten, claimed anomalous keys were withheld from Friedel-merged runs when 144 of 148 stored reports carry them, and listed as default a set of keys that --developer now selects. The tutorial described an enantiomorph message that no longer exists; the option tables were missing --developer and --finalist-ledger and carried a short option the program does not have; the integration page's unmerged-MTZ column list predated the two new columns and asserted the absence of one of them. The analysis pages had the efficiency and flight-path corrections but none of the symmetry work: the pseudo-translation detector, the absence test that divides it out, the glide test, the evidence-keyed alternatives and the metric re-ask are now written up where the methods are described. The usage message omitted FLIGHT from the formula that turns a written intensity back into a raw count, while the writer has been emitting the column. The usage message is the authority on what the program does, so it says so now. The changelog had thirty-one entries filed under the previous release, most of them written from the inside: what a change did to the code rather than what it does for a reader. This release gets its own section with sixteen, each one capability. Every key, flag and column a user could grep for survives; what goes is the seam between one person's work and the next's, which is not something a user can act on. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EFEJG6WBQv8th4UJFNe53N
4.1 KiB
What a rugnux run does
The map of a run, in the order it happens — one paragraph per stage, each linking into the data-analysis reference where the algorithm lives. The walk-through is a rotation run with the defaults; stills differences are at the end.
Open the dataset. The geometry, wavelength and goniometer come from the file (What rugnux reads). A goniometer axis makes it a rotation run, none makes it serial stills — nothing is asked of the user.
Pre-scan. A projection of the first frames (60 by default) finds the beam-stop shadow and masks it (§1.5), measures the beam centre from the isotropy of the scattered background and compares it with the file's (§1.4), and reads how wide this crystal's spots are, which sets the integration radius (§9.5).
Spots. Every image is decoded — on the GPU straight from the compressed chunk (§0) — and one fused pass computes the azimuthal profile and finds the spots against each image's own per-resolution-ring noise (§2–§3). The ice-ring score is read off the same profile.
Indexing. The spots of a sample of frames are rotated back to a common crystal frame and the FFT search looks for periodicity over thousands of directions; candidate cells are Niggli-reduced, classified by Bravais lattice, refined both constrained and triclinic, and decided on how many validation frames each actually indexes (§4–§7). A failed pass triggers the discrete rescues — the rotation-axis sign, the beam-centre search — before anything is given up on.
First integration pass. At the geometry in the file, every frame is predicted (§8) and profile-fit integrated (§9); partials are combined into fulls, scaled and merged (§10).
Geometry post-refinement. From those reflections the detector distance, beam centre and the cell scale / rotation axis are refined over all frames at once, each step committed only if it improves a held-out residual (§7.5).
Second pass. The sweep is re-indexed de novo and re-integrated at the refined geometry; this
pass is the canonical output, and a guard compares the two passes and keeps the better one
(reported as PASS= / PASS_DECISION= in the report).
Space group. On the P1 merge of the final pass, the point group is scored operator by operator
on resolution-normalised intensities and the screw axes, glide planes and centring are read from the
systematic absences (§13.1); twinning and translational
pseudo-symmetry are checked beside it (§13.2). CANNOT_DETERMINE and an enantiomorphic pair are real
answers here, not evasions.
Scale and merge. In the determined group: per-frame scales, the cross-validated correction surfaces (decay, absorption, modulation), the error model and ISa, outlier rejection, the CC½-based resolution cut, the anisotropy description, French–Wilson amplitudes and the R-free flags (§10, §13.3–§13.5).
Write. The merged .mtz / .cif / .hkl, the unmerged MTZ, the P1 cross-check and the
results report land next to each other (Output files); with
--model, validation runs first and the maps and the placed model are written too
(§14).
Stills instead. Serial data skip the two-pass machinery: each image is indexed independently
(with the known-cell ffbidx indexer where a cell is given), partiality comes from a per-crystal
orientation-tilt post-refinement rather than a rocking curve, and a merohedral indexing ambiguity
has to be broken per image, at integration time, against a reference or a model
(Advanced ▸ the indexing ambiguity).