Files
Jungfraujoch/docs/RUGNUX_OVERVIEW.md
T
leonarski_fandClaude Opus 5 2538f5a956 docs: the manual describes the program this branch actually built
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
2026-09-06 22:44:09 +02:00

4.1 KiB
Raw Blame History

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, FrenchWilson 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).