10ef6fa643cf16eb263cf8bc7ee8285a3c218fde
201
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
7922b0a7fa |
SECURITY.md: describe the token swap semantics; drop the single-sign-on paragraph
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
7f884f67c7 |
Per-dataset bearer tokens in the broker; viewer token, model option, grid-scan plot, dark theme, tutorial
jfjoch_broker: /start takes an optional `tokens` list (any number, all equivalent; writeOnly in the
API). While the current dataset has any, the endpoints that expose it - /statistics/data_collection,
/result/scan, /image_buffer/{start.cbor,image.cbor,image.jpeg,image.tiff}, /preview/plot{,.bin} -
answer 401 unless the request carries `Authorization: Bearer <token>`; /statistics keeps serving
the instrument view and only omits its `measurement` block. Enforcement is one pre-routing hook
over a named path set (the same set carries `bearerAuth` in jfjoch_api.yaml); tokens are compared
in constant time and never read back or logged. The tokens are replaced only by an accepted start,
and atomically with clearing the previous run's status, plots and image buffer, in this order:
clear, swap, import the new settings - so no moment serves the old run under the new tokens or the
new run's name under the old ones. Settings are validated on a copy first so a refused start
changes nothing.
jfjoch_viewer: a Token field (password echo) next to the http/https scheme in Open HTTP Connection,
JUNGFRAUJOCH_HTTP_TOKEN, and D-Bus LoadFile(..., token) / SetHttpToken; the dialog overrides the
others, nothing is persisted. A 401 clears the display, stops following and puts a line on the
status bar - no dialog, since a dataset changing hands is the normal cause.
Web frontend: key button in the top bar (token in sessionStorage, applied to the bearerAuth
operations by the generated client, and to the raw preview fetch), a tokens field in the start
form, and a "token required" hint on the plots. Python client: Configuration(access_token=...)
after regeneration.
Viewer: reference dataset accepts a structure-factor mmCIF (already read by content; the dialog
now offers it) and a model file can be chosen next to it (ProcessConfig::model_path, as
rugnux --model); the job also carries the reference's free-R flags, cell and setting, and the
copied command line states -z / --reference-column / --model. A grid scan keeps its own preferred
dataset-info plot and "Spots + background" means the spot count there. Dark theme: the navy hero
buttons, checked segments, warning texts and chart guide lines follow the theme instead of their
light-theme colours.
Docs: SECURITY.md section 3 is now the implemented scheme; a guided tour with four screenshots
in JFJOCH_VIEWER.md; broker, OpenAPI, Python client and frontend pages mention the token.
Tests: BearerTokens unit test and an HTTP round trip over the real broker HTTP layer (jfjoch_test
now compiles JFJochBrokerHttp.cpp and links httplib).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
||
|
|
e07667726e |
Viewer: Shift + wheel on macOS, Mac keys in the mouse-shortcut help
Build Packages / Create release (push) Successful in 28s
Build Packages / build:viewer:macos-arm64:nocuda (push) Successful in 2m54s
Build Packages / build:rugnux:macos-arm64:nocuda (push) Successful in 2m25s
Build Packages / build:viewer:linux-x86_64:nocuda (push) Successful in 11m31s
Build Packages / build:viewer:linux-x86_64:cuda (push) Successful in 12m3s
Build Packages / build:rugnux:linux-x86_64:cuda (push) Successful in 8m18s
Build Packages / build:rugnux:linux-aarch64:cuda (push) Successful in 6m19s
Build Packages / build:viewer:windows-x86_64:nocuda (push) Successful in 17m31s
Build Packages / build:viewer:windows-x86_64:cuda (push) Successful in 20m8s
Build Packages / HDF5 consumer tests (DIALS, XDS) (push) Successful in 23m21s
Build Packages / build:jfjoch:rocky8:nocuda (push) Successful in 14m5s
Build Packages / build:jfjoch:rocky9:nocuda (push) Successful in 15m27s
Build Packages / build:jfjoch:ubuntu2204:nocuda (push) Successful in 14m45s
Build Packages / build:jfjoch:ubuntu2404:nocuda (push) Successful in 13m42s
Build Packages / build:rugnux:windows-x86_64:cuda (push) Successful in 11m13s
Build Packages / build:jfjoch:rocky8:cuda-sls9 (push) Successful in 15m11s
Build Packages / Generate python client (push) Successful in 27s
Build Packages / Build documentation (push) Successful in 1m17s
Build Packages / build:jfjoch:rocky9:cuda-sls9 (push) Successful in 16m20s
Build Packages / build:jfjoch:rocky8:cuda (push) Successful in 17m55s
Build Packages / build:jfjoch:ubuntu2404:cuda (push) Successful in 16m34s
Build Packages / build:jfjoch:ubuntu2204:cuda (push) Successful in 17m34s
Build Packages / build:jfjoch:rocky9:cuda (push) Successful in 18m4s
Build Packages / Unit tests (push) Successful in 1h20m54s
macOS turns Shift + a vertical mouse wheel into horizontal scrolling, so the notch arrives in angleDelta().x() and y() is 0; the contrast step read only y and did nothing. The wheel handler now takes whichever axis carries the notch, for zoom, foreground and background alike. Help > Mouse Shortcuts names Cmd for Ctrl on macOS (Qt maps Command to Ctrl), Ctrl-click for right click and Fn + arrows for Home/End/Page Up/Down, and lists B held + wheel, which was missing. The magnifier's tooltip says how to drive it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
48ce0dd570 |
Docs: macOS artefacts - requirements, first open, building from source
RELEASE_CONTENTS gains the macOS .dmg and rugnux .tgz in the artefact table, the CPU floor (any Apple Silicon Mac), the OS floor (macOS 13), the CPU-only note in the CUDA/GPU tables, and a macOS section: Apple Silicon only (Rosetta does not run arm64 code on Intel), drag-to-Applications, notices inside the bundle, and how to open the not-yet-notarized release (Open Anyway on macOS 15+, Control-click Open on 13/14, or xattr). JFJOCH_VIEWER states the platforms and requirements, that the Mac build is CPU-only, that D-Bus is Linux-only, and adds Building from source on macOS. RUGNUX_INSTALL adds the macOS archive and the quarantine note - checked: a browser-downloaded .tgz hands its quarantine flag to everything tar extracts, Gatekeeper rejects rugnux, and xattr -dr clears it. DEPLOYMENT points to the pre-built Windows/macOS viewers and the macOS rugnux archive. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
e9da892790 |
Rugnux report: low warning thresholds, worded as prompts to check; ice apart from powder
Build Packages / Create release (push) Successful in 15s
Build Packages / build:rugnux:aarch64 (cross) (push) Successful in 7m56s
Build Packages / build:rugnux-tgz (x86_64) (push) Successful in 8m39s
Build Packages / build:viewer-tgz:cpu (push) Successful in 10m23s
Build Packages / build:viewer-tgz:cuda (push) Successful in 12m48s
Build Packages / build:rpm (rocky8_nocuda) (push) Successful in 15m22s
Build Packages / build:rpm (rocky9_nocuda) (push) Successful in 16m11s
Build Packages / build:windows:nocuda (push) Successful in 18m24s
Build Packages / build:windows:cuda (push) Successful in 20m42s
Build Packages / HDF5 consumer tests (DIALS, XDS) (push) Successful in 24m38s
Build Packages / build:rpm (ubuntu2204_nocuda) (push) Successful in 19m11s
Build Packages / build:rpm (ubuntu2404_nocuda) (push) Successful in 19m24s
Build Packages / Generate python client (push) Successful in 45s
Build Packages / build:rugnux:windows (push) Successful in 11m0s
Build Packages / Build documentation (push) Successful in 1m22s
Build Packages / build:rpm (rocky8_sls9) (push) Successful in 20m36s
Build Packages / build:rpm (rocky9_sls9) (push) Successful in 19m52s
Build Packages / build:rpm (rocky8) (push) Successful in 18m15s
Build Packages / build:rpm (rocky9) (push) Successful in 18m10s
Build Packages / build:rpm (ubuntu2204) (push) Successful in 14m2s
Build Packages / build:rpm (ubuntu2404) (push) Successful in 12m29s
Build Packages / Unit tests (push) Successful in 1h14m50s
Owner decision: a warning is a prompt to check and must catch the real cases (9min) at the cost of some spurious ones. The physically motivated corrections stay (<|L|> outside its physical range is not twinning; a single sweep's indexing choice; NO_LATTICE on rotation; the no-crystal report); thresholds raised only to cut noise come back down: - SUPERCELL_POSSIBLE warns wherever the class measures and rocks (as before rc173's audit fix), worded as "check the cell", naming weak ordered intensity of a correct cell and spots of further lattice domains as the other readings. 9min (rock 4.2%) warns again. - LATTICE_TRANSLATION warns on every admitted vector (>=75% of the origin); below 90% the wording names a very strong pseudo-translation as the other reading. - PSEUDO_TRANSLATION warns on every detection; below a 20% peak it is worded as weak, check. - SWEEP_GAPS warns where the degraded ranges cover at least 1% of the sweep (the 4 sets of 77 below that had 1-2 frames, 0.4-0.6% of the sweep). - Powder rings are split between hexagonal-ice positions and the rest (MeasurePowderRings, report-only fields); ICE_RINGS and POWDER_RINGS warn separately from 5% of the spots, and ICE_RINGS also where the merge's ice gate found ice. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D1G8gJVAy6gp1K5Dz3NE5C |
||
|
|
8a8c992cca |
Rugnux report: warn only where the evidence supports the claim
Report-layer fixes from the warnings audit of the rc173 full battery. Processing is unchanged (merged MTZ/HKL bit-identical on the sets checked). - SUPERCELL_POSSIBLE stays a key and a summary line; a warning only where the rocking part reaches 20% (sub-cells that refine normally rocked at 2.1-16.2%, the accepted doubled cells at 4.2% and 29.1%). The summary says where further lattice domains may put spots on the half-integer nodes. - LATTICE_TRANSLATION only where the Patterson at the vector reaches 90% of the origin (UNDECLARED_LATTICE_TRANSLATION_PCT, new); the two admitted vectors on the battery read 79% and 85% on crystals refining in the deposited cell, and are now reported as a very strong pseudo-translation. PSEUDO_TRANSLATION warns from a 20% peak (xtriage convention; detected peaks were 8.1% on one set, 24.8-63.2% on the rest). - <|L|> outside 0.375-0.55 (on the adopted or the pre-search merge) is TWINNING_VERDICT= NOT_READABLE with no warning, instead of a twin or SYMMETRY_SUSPECT reading. - NO_LATTICE no longer fires on a rotation run that indexed the sweep with no frame indexed on its own; INDEXING_RATE is --developer on rotation. - A rotation run that finds no lattice writes a report (VERDICT= FAILED, NO_LATTICE) before exiting 1, instead of an input-parameter error and no report (NoLatticeFound). - Powder and Ice summary lines, ICE_* keys, and a POWDER_RINGS flag from a 0.5 spot fraction. - SWEEP_GAPS warns only where the degraded ranges cover 10% of the sweep (77 -> 48 sets). - A single rotation sweep no longer carries an INDEXING_AMBIGUITY warning (one orientation matrix, consistent hand); INDEXING_AMBIGUITY_OPERATORS and an Indexing choice line instead. - A DOMAIN more than 10 deg away is a second crystal; the MULTIPLE_LATTICES sum is documented. - Mosaicity line and docs name XDS's suggested REFLECTING_RANGE_E.S.D. as the comparable number (0.90x median over 34 in-house sets; per-image SIGMAR runs ~1.35x higher). - HARMONIC_CONTAMINATION, SCALING_NOT_CONVERGED, POWDER_RINGS in the documented vocabulary. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D1G8gJVAy6gp1K5Dz3NE5C |
||
|
|
a1816e905e |
ShadowFinder: add beam-stop holder arms that let part of the beam through
After the existing mask is complete, a second step takes the pixels it left out that are
significantly dimmer than their ring, joins them through a 6 px bridge and across module gaps of
any width, and adds a piece whole when it holds >= 2000 dim pixels of which >= 200 are deep. The
existing mask is never touched, so a sweep with no such piece keeps its mask bit for bit.
Quick subset tests (battery --only, no model check) against the rc173
|
||
|
|
56b82b2948 |
Rugnux: radial background correction on smooth powder/ice rings by default
The local radial background at ring radii (--background-radial) already
existed and is gated per image on the smooth-ice channel of the ice score,
but it was off unless asked for. Systematically negative merged
intensities at ring radii (I/sigma < -4 on 0.4-1.6% of reflections of the
affected open sets) come from the flat annulus mean over-subtracting a
sharp ring. rugnux now runs with =auto unless the flag says otherwise; the
library default (and so the broker) stays off.
Measured on the open arm against rc173 (commit 727bd0d6d as reference):
auto: 8agq (smooth ice, fires) CC_model .9327->.9476, R shell-scaled
.1987->.1795, I/sig<-4 1.55%->1.15%; 8rud R shell-scaled
.2507->.2456, ISa 10.0->13.3; 5reo, 7kcn, 9fhc bit-identical
(gate does not fire); wall time unchanged.
forced on (not adopted): same 8agq gain and 8rud .2414, 9fhc/8qq7
small gains, but 7kcn (no ice) CC_model .9491->.9411, ISa
11.0->7.5 - which is why the gate stays.
ISa falls on 8agq (15.6->13.3) while agreement with the model rises: the
merge-statistics vs external-model trade the settings comment describes.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D1G8gJVAy6gp1K5Dz3NE5C
|
||
|
|
5a9aca682b |
Rugnux: spherical-harmonic crystal-frame absorption as a candidate surface
A new correction surface, fitted after the time x detector surface and before the goniometer-frame 8x8 grid: log A is a sum of real spherical harmonics (l = 1..6, 48 terms) of the diffracted-beam direction de-rotated into the crystal frame. The incident-beam path depends on phi alone and is in the per-frame scale already. It runs through ApplyCellSurface unchanged in everything but the update: the cells are 32 x 64 equal-solid-angle direction bins, and each round the per-cell sums (ref2, cross, the same damping) become one ridge-regularised Gauss-Newton step on the coefficients (prior width 0.1/l per degree-l coefficient) instead of independent per-cell steps. The half-set Fisher-z gate adopts or refuses it exactly as it does the grids; where it is refused, the grid after it sees what it saw before. Why: the folded 8x8 grid (hemispheres share a cell) is the weak basis for long-wavelength absorption. Offline, held out by unique reflection, this basis lowered held-out scatter 4-8% on 6 of 11 long-wavelength sets where no cell grid did, raised model-phased anomalous peaks 0.02-0.2 sigma, and was neutral on hard-X-ray controls. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D1G8gJVAy6gp1K5Dz3NE5C |
||
|
|
23f446acbb |
Rugnux: French-Wilson amplitudes as ctruncate gives them
Compared with ctruncate (CCP4 9, version 1.17.29) on rugnux's own merged intensities of the open battery arm, three differences: - ctruncate gives no amplitude to an intensity below -3.7 sigma (exactly that bound on every set checked; up to 2498 reflections on one set). Rugnux turned them into small, confident amplitudes (F/Fc ~0.3 on the sets whose background is over-subtracted on powder/ice rings). They now get F = NaN (missing in MTZ, '?' in mmCIF); IMEAN is kept. They are also left out of the shell mean that sets the Wilson prior. - The switch to sqrt(I) at I/sigma = 4 left 4-6 sigma amplitudes 2-3% above ctruncate's on every set (1.019-1.028). The posterior now applies up to 20 sigma (emulated: 0.995-1.000). - A shell whose mean intensity is not positive gave a prior at the 1e-10 clamp and amplitudes of ~0 (one set's outer shell); it now takes the nearest lower-resolution shell's mean. The remaining gap (weak amplitudes 2-5% below ctruncate's in the outer shells) is ctruncate's anisotropy-corrected prior; not attempted. An offline R-free ablation put the whole ctruncate conversion at -0.0006 median (15/18 sets better) and dropping its rejected negatives at -0.0009 mean (-0.009 on the worst set). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D1G8gJVAy6gp1K5Dz3NE5C |
||
|
|
a0518abe62 |
Rugnux: warn about further lattices only where they are domains of the crystal
Build Packages / Create release (push) Successful in 16s
Build Packages / build:rugnux:aarch64 (cross) (push) Successful in 8m32s
Build Packages / build:rugnux-tgz (x86_64) (push) Successful in 9m5s
Build Packages / build:viewer-tgz:cpu (push) Successful in 10m43s
Build Packages / build:viewer-tgz:cuda (push) Successful in 12m37s
Build Packages / build:rpm (rocky8_nocuda) (push) Successful in 15m37s
Build Packages / build:rpm (rocky9_nocuda) (push) Successful in 16m35s
Build Packages / build:windows:nocuda (push) Successful in 17m57s
Build Packages / build:windows:cuda (push) Successful in 20m33s
Build Packages / HDF5 consumer tests (DIALS, XDS) (push) Successful in 24m2s
Build Packages / build:rpm (ubuntu2204_nocuda) (push) Successful in 19m18s
Build Packages / build:rugnux:windows (push) Successful in 11m7s
Build Packages / build:rpm (ubuntu2404_nocuda) (push) Successful in 20m27s
Build Packages / Generate python client (push) Successful in 52s
Build Packages / build:rpm (rocky8_sls9) (push) Successful in 20m5s
Build Packages / Build documentation (push) Successful in 1m52s
Build Packages / build:rpm (rocky9_sls9) (push) Successful in 20m2s
Build Packages / build:rpm (rocky8) (push) Successful in 17m32s
Build Packages / build:rpm (rocky9) (push) Successful in 18m29s
Build Packages / build:rpm (ubuntu2204) (push) Successful in 14m28s
Build Packages / build:rpm (ubuntu2404) (push) Successful in 11m54s
Build Packages / Unit tests (push) Successful in 1h15m53s
MULTIPLE_LATTICES and EXTRA_LATTICE_INTENSITY_PCT now count DOMAIN, TWIN_DOMAIN and SEGMENTED lattices only. A FOREIGN lattice (an unrelated cell) is still listed but no longer warned about: it is as often a wrong main lattice or tNCS as a second crystal (one of the four such sets in the battery census is a tNCS crystal). On the census this names 25 of 200 rotation sets instead of 29. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D1G8gJVAy6gp1K5Dz3NE5C |
||
|
|
d481da0474 |
Docs: further lattices and mosaicity in the report; battery records both
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D1G8gJVAy6gp1K5Dz3NE5C |
||
|
|
ae444437f4 |
rugnux: accept a PDB structure-factor mmCIF as the -z reference
-z (now also --reference; --reference-mtz still works) takes an SF-mmCIF (e.g. a deposited -sf.cif, gzipped or not) as well as an MTZ. The format is recognised by content: a file starting with "MTZ " is an MTZ, anything else is parsed as CIF. The first merged reflection block with the requested column (or, by default, one the auto choice accepts) is converted to a gemmi::Mtz in memory with GEMMI's CifToMtz and then read by the unchanged MTZ loader, so the in-memory reference is exactly what the MTZ path yields. Unmerged (_diffrn_refln) and anomalous-only blocks are passed over; the log names the block used. The R-free set comes from _refln.status (f -> FreeR_flag 0, o -> 1: the CCP4 convention the loader already reads) and is preferred to _refln.pdbx_r_free_flag, whose convention varies by program; a status column with no 'f' is ignored and pdbx_r_free_flag is used instead. Checked on two open-arm sets in the deposited setting (one with F_meas_au only, one with intensity_meas): reference loaded with the deposited cell and group, the inherited free set agrees with the deposited status 'f' on every common reflection, and the merge correlates at CC 0.99 with the deposition. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D1G8gJVAy6gp1K5Dz3NE5C |
||
|
|
ba2773083b |
Docs: the written setting, the reference frame and its free-R gate
RUGNUX_ADVANCED (new section "The setting the files are written in", -z and --model paragraphs), RUGNUX_REPORT (SETTING_* keys, REFERENCE_MISMATCH, model change-of-basis keys), CPU_DATA_ANALYSIS_DECISIONS / _INTEGRATION, CHANGELOG entries under rc.173. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D1G8gJVAy6gp1K5Dz3NE5C |
||
|
|
f3c3ecdeb6 |
v1.0.0-rc.173
Build Packages / Unit tests (push) Successful in 1h11m14s
Build Packages / build:windows:nocuda (push) Successful in 17m41s
Build Packages / build:windows:cuda (push) Successful in 20m18s
Build Packages / build:viewer-tgz:cpu (push) Successful in 9m32s
Build Packages / build:viewer-tgz:cuda (push) Successful in 11m47s
Build Packages / build:rugnux-tgz (x86_64) (push) Successful in 9m41s
Build Packages / build:rugnux:windows (push) Successful in 11m12s
Build Packages / build:rugnux:aarch64 (cross) (push) Successful in 7m28s
Build Packages / build:rpm (rocky8_nocuda) (push) Successful in 16m42s
Build Packages / build:rpm (rocky9_nocuda) (push) Successful in 16m33s
Build Packages / build:rpm (ubuntu2204_nocuda) (push) Successful in 16m0s
Build Packages / build:rpm (rocky8_sls9) (push) Successful in 19m1s
Build Packages / build:rpm (rocky9_sls9) (push) Successful in 19m10s
Build Packages / build:rpm (rocky8) (push) Successful in 18m39s
Build Packages / build:rpm (rocky9) (push) Successful in 16m56s
Build Packages / build:rpm (ubuntu2204) (push) Successful in 16m42s
Build Packages / build:rpm (ubuntu2404) (push) Successful in 13m0s
Build Packages / HDF5 consumer tests (DIALS, XDS) (push) Successful in 26m4s
Build Packages / Generate python client (push) Successful in 42s
Build Packages / Build documentation (push) Successful in 1m39s
Build Packages / Create release (push) Successful in 15s
Build Packages / build:rpm (ubuntu2404_nocuda) (push) Successful in 10m40s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D1G8gJVAy6gp1K5Dz3NE5C |
||
|
|
d397717ff7 |
Viewer: dock the magnifier, fixed zoom levels, Shift-driven with a frame
Build Packages / Unit tests (push) Successful in 1h11m40s
Build Packages / build:windows:nocuda (push) Successful in 17m39s
Build Packages / build:windows:cuda (push) Successful in 20m10s
Build Packages / build:viewer-tgz:cpu (push) Successful in 10m2s
Build Packages / build:viewer-tgz:cuda (push) Successful in 11m28s
Build Packages / build:rugnux-tgz (x86_64) (push) Successful in 9m4s
Build Packages / build:rugnux:windows (push) Successful in 11m20s
Build Packages / build:rugnux:aarch64 (cross) (push) Successful in 7m46s
Build Packages / build:rpm (ubuntu2204_nocuda) (push) Successful in 16m15s
Build Packages / build:rpm (ubuntu2404_nocuda) (push) Successful in 16m21s
Build Packages / build:rpm (rocky8_sls9) (push) Successful in 18m1s
Build Packages / build:rpm (rocky9_sls9) (push) Successful in 19m19s
Build Packages / build:rpm (rocky8) (push) Successful in 18m17s
Build Packages / build:rpm (rocky9) (push) Successful in 18m48s
Build Packages / build:rpm (ubuntu2204) (push) Successful in 15m59s
Build Packages / build:rpm (ubuntu2404) (push) Successful in 16m19s
Build Packages / HDF5 consumer tests (DIALS, XDS) (push) Successful in 25m2s
Build Packages / Generate python client (push) Successful in 1m3s
Build Packages / Build documentation (push) Successful in 1m28s
Build Packages / Create release (push) Successful in 18s
Build Packages / build:rpm (rocky8_nocuda) (push) Successful in 10m50s
Build Packages / build:rpm (rocky9_nocuda) (push) Successful in 11m15s
The magnifier moves from a helper window into its own dock below the inspector. It has three fixed zoom levels (x64 and x32 with the pixel values written on the pixels, x10 without) instead of wheel zoom, and follows the cursor only while Shift is held over the diffraction image. Meanwhile the diffraction view draws a frame around the area it covers, just outside that area so it stays visible at low zoom without hiding the pixels; releasing Shift (seen by the application-wide key filter, so wherever the focus is), moving without it or leaving the image hides it. A "Pop out" button moves the magnifier into a separate window and back. Qt's own dock floating stays disabled: a floated dock is placed off-screen on WSLg. Whether it was popped out, and the window geometry, persist across sessions. The inspector's image statistics become a collapsible section so a small screen can give the space to the magnifier. kLayoutVersion is bumped for the new dock. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> |
||
|
|
4fd8167a5c |
Merge branch 'hq-pool4' into rc173: geometry walk fix and supercell report
Build Packages / Create release (push) Successful in 16s
Build Packages / build:rugnux:aarch64 (cross) (push) Successful in 8m20s
Build Packages / build:rugnux-tgz (x86_64) (push) Successful in 9m0s
Build Packages / build:viewer-tgz:cpu (push) Successful in 10m48s
Build Packages / build:viewer-tgz:cuda (push) Successful in 12m0s
Build Packages / build:rpm (rocky9_nocuda) (push) Successful in 16m11s
Build Packages / build:rpm (rocky8_nocuda) (push) Successful in 16m14s
Build Packages / build:windows:nocuda (push) Successful in 17m48s
Build Packages / build:windows:cuda (push) Successful in 20m10s
Build Packages / HDF5 consumer tests (DIALS, XDS) (push) Successful in 24m14s
Build Packages / build:rpm (ubuntu2404_nocuda) (push) Successful in 18m29s
Build Packages / build:rpm (ubuntu2204_nocuda) (push) Successful in 19m32s
Build Packages / build:rugnux:windows (push) Successful in 10m51s
Build Packages / Generate python client (push) Successful in 52s
Build Packages / build:rpm (rocky8_sls9) (push) Successful in 18m54s
Build Packages / Build documentation (push) Successful in 52s
Build Packages / build:rpm (rocky9_sls9) (push) Successful in 19m36s
Build Packages / build:rpm (rocky8) (push) Successful in 17m49s
Build Packages / build:rpm (rocky9) (push) Successful in 19m0s
Build Packages / build:rpm (ubuntu2204) (push) Successful in 13m58s
Build Packages / build:rpm (ubuntu2404) (push) Successful in 11m52s
Build Packages / Unit tests (push) Successful in 1h13m19s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D1G8gJVAy6gp1K5Dz3NE5C |
||
|
|
3de894989c |
Report summary: a Supercell line beside pseudo-symmetry and twinning
The SUPERCELL_POSSIBLE advice now also sits in the summary at the top of the report, with the doubled cell ready for -C; the rule is shared with the warning. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D1G8gJVAy6gp1K5Dz3NE5C |
||
|
|
7ae44d07d1 |
Merge branch 'hq-supercell' into hq-pool4
# Conflicts: # docs/CHANGELOG.md |
||
|
|
dd18d8c21d |
Warn SUPERCELL_POSSIBLE where the half-integer class looks like Bragg reflections
Advisory only: the class is measured (<I/sigma> >= 0.5) and its rocking part is at least 2% of the lattice's, three standard errors clear. The warning asks the user to process both settings - the run's cell and the reported doubled cell with -C - and compare them in refinement. Of 105 battery rotation sets it names 8: both crystals whose accepted cell is the doubled one, one pseudo-translation whose doubled description is an accepted alternative, and five correct sub-cells with weak ordered half-integer intensity. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D1G8gJVAy6gp1K5Dz3NE5C |
||
|
|
ba6cb5e1a1 |
Merge branch 'hq-geowalk' into hq-pool4
# Conflicts: # docs/CHANGELOG.md |
||
|
|
6c9205a670 |
Report the strongest index-2 superstructure class and the cell it doubles to
The report-only supercell probe now reaches the results report: SUPERCELL_CLASS (parity of the primitive indices), its occupancy and Bragg-like (rocking) part against the lattice's own reflections, its <I/sigma>, and SUPERCELL_DOUBLED_CELL, the Niggli-reduced cell to give with -C. No decision is taken on it: correct cells whose half-integer class is diffuse, and cells whose depositor kept the sub-cell, cannot be told from a real doubling by the data alone. On a crystal with a real doubled axis the reported cell matched the deposited one, and processing on it with -C brought R_free against the deposited model from 0.60 to 0.29. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D1G8gJVAy6gp1K5Dz3NE5C |
||
|
|
8153646716 |
rugnux: geometry walk keeps a round the validation spots prefer, and probes small moves
The between-pass geometry walk kept a round only when the realised held-out residual fell by more than its noise, and started only on a fit move of a trust-region step or more. The residual is dominated by low-resolution reflections, where a distance and the compensating cell scale move every spot alike, and its centroids are taken inside a disc centred on the prediction, so it barely sees a distance error that costs the high-resolution shells. On 8pqd the canonical pass ran at 96.456 mm; the fit asked for 95.878 mm (0.6 %, less than a step, so no walk). Forced, that round read the residual only 0.74 sigma lower but put 70.4 % of the validation spots on the lattice against 58.1 %. Now a round is kept when either the residual falls beyond its noise (HeldOutResidualFell) or the validation evidence prefers it (ValidationEvidencePrefers, z = 3.29). A move of less than a step is first tried as two index-only probes on the validation frames (fit's geometry vs the one in hand) and pays for a re-integrated round only where the fit's geometry scores higher; walks started by a large move run as before. 8pqd: 96.456 -> 95.878 mm, d_min 1.374 -> 1.306 A, R_free .218 -> .206, REFMAC R_free .209 -> .202, Wilson B 34.4 -> 30.7 (pool had 1.325 A / .209 / .203). 6vww 7n0i 7ris 8egn 8xtf 9qw8 9w3y 6qaj 6cdl 9i0a myob_x06da_split lyso_x06da_half_image unchanged (probes say the geometry in hand stands); probe cost 1-10 s per run. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D1G8gJVAy6gp1K5Dz3NE5C |
||
|
|
1dd32e2f22 |
CHANGELOG: rc173 entries for the pooled high-resolution changes; bandwidth is now used
Build Packages / Create release (push) Successful in 27s
Build Packages / build:viewer-tgz:cpu (push) Successful in 11m25s
Build Packages / build:rugnux-tgz (x86_64) (push) Successful in 10m43s
Build Packages / build:viewer-tgz:cuda (push) Successful in 12m30s
Build Packages / build:windows:nocuda (push) Successful in 17m10s
Build Packages / build:rugnux:aarch64 (cross) (push) Successful in 5m56s
Build Packages / build:windows:cuda (push) Successful in 19m42s
Build Packages / HDF5 consumer tests (DIALS, XDS) (push) Successful in 22m24s
Build Packages / build:rpm (rocky8_nocuda) (push) Successful in 13m18s
Build Packages / build:rugnux:windows (push) Successful in 10m45s
Build Packages / build:rpm (ubuntu2404_nocuda) (push) Successful in 14m50s
Build Packages / build:rpm (ubuntu2204_nocuda) (push) Successful in 15m0s
Build Packages / build:rpm (rocky9_nocuda) (push) Successful in 17m6s
Build Packages / build:rpm (rocky8_sls9) (push) Successful in 15m14s
Build Packages / Generate python client (push) Successful in 1m4s
Build Packages / Build documentation (push) Successful in 1m7s
Build Packages / build:rpm (rocky9_sls9) (push) Successful in 15m19s
Build Packages / build:rpm (rocky8) (push) Successful in 14m52s
Build Packages / build:rpm (ubuntu2204) (push) Successful in 15m31s
Build Packages / build:rpm (ubuntu2404) (push) Successful in 14m15s
Build Packages / build:rpm (rocky9) (push) Successful in 15m59s
Build Packages / Unit tests (push) Successful in 1h19m3s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D1G8gJVAy6gp1K5Dz3NE5C |
||
|
|
7283c40279 |
Merge branch 'hq-pool3' into rc173: high-resolution quality pool and regression cures
Build Packages / Create release (push) Successful in 16s
Build Packages / build:rugnux:aarch64 (cross) (push) Successful in 7m37s
Build Packages / build:rugnux-tgz (x86_64) (push) Successful in 9m20s
Build Packages / build:viewer-tgz:cpu (push) Successful in 10m15s
Build Packages / build:viewer-tgz:cuda (push) Successful in 11m55s
Build Packages / build:rpm (rocky8_nocuda) (push) Successful in 16m7s
Build Packages / build:rpm (rocky9_nocuda) (push) Successful in 16m55s
Build Packages / build:windows:nocuda (push) Successful in 17m56s
Build Packages / build:windows:cuda (push) Successful in 20m31s
Build Packages / build:rpm (ubuntu2204_nocuda) (push) Successful in 15m40s
Build Packages / HDF5 consumer tests (DIALS, XDS) (push) Successful in 26m47s
Build Packages / build:rugnux:windows (push) Successful in 10m56s
Build Packages / build:rpm (ubuntu2404_nocuda) (push) Successful in 19m32s
Build Packages / build:rpm (rocky8_sls9) (push) Successful in 18m46s
Build Packages / Generate python client (push) Successful in 21s
Build Packages / Build documentation (push) Successful in 1m51s
Build Packages / build:rpm (rocky9_sls9) (push) Successful in 19m24s
Build Packages / build:rpm (rocky8) (push) Successful in 17m26s
Build Packages / build:rpm (rocky9) (push) Successful in 17m49s
Build Packages / build:rpm (ubuntu2204) (push) Successful in 21m27s
Build Packages / build:rpm (ubuntu2404) (push) Successful in 19m52s
Build Packages / Unit tests (push) Successful in 1h37m59s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D1G8gJVAy6gp1K5Dz3NE5C |
||
|
|
9e510816e0 |
Merge hq-cure-merge into hq-pool3; R_MEAS stays the ordinary statistic, the weighted one is R_MEAS_WEIGHTED
R_MEAS is what users set beside XDS/AIMLESS, so its meaning does not change; the merge-weighted value from hq-cure-merge is reported beside it (R_MEAS_WEIGHTED, REFRES_R_MEAS_WEIGHTED). The per-hand table keeps the ordinary statistic. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D1G8gJVAy6gp1K5Dz3NE5C |
||
|
|
9cb08b0346 |
Docs: harmonic beam-centre disagreement decided both ways; geometry commit bar is the residual's noise
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D1G8gJVAy6gp1K5Dz3NE5C |
||
|
|
5c5eb00904 |
Merge statistics: R_meas weighted as the merge weights each observation
The delta-CC1/2 disposition keeps a weak stretch in the merge (downgraded) wherever removing it would not raise CC1/2, and the merge then carries each of its observations at the small 1/sigma^2 its scaled-up counting error gives it. R_meas counted those observations at full weight, so the frames that add next to nothing to the intensities set the number. hq-pool battery: 8xtf kept 115 weak frames (scale 0.1-0.2 of the run's) with the same CC1/2, <I/sigma> and CC_model per shell as rc173 with 84 frames rejected, and R_meas was 1.3-1.5x higher in every shell; 9w3y (33 deg rejected -> 0, every model metric better) and lyso_x10sa_strong read the same way. The disposition itself is not segmentation-dependent: conviction is on the batch grid, not the ledger ranges, and those sets' dispositions changed because the corrected data changed. R_meas now weights each observation by its merge weight v = 1/sigma^2 under the error model (corrected_sigma on the host, ModelSigma on the GPU, with the error model of the last MergeAccum), normalised per reflection to Kish's effective count, so equal sigmas give the ordinary formula (WeightedRmeasTerms). Where the proportional term dominates - strong reflections - frames are weighted alike, as in the merge: 8xtf's lowest shell reads 15.0%, the rc173 run with 84 frames rejected 15.2%. The per-hand table is weighted the same way. R_MEAS_UNWEIGHTED / REFRES_R_MEAS_UNWEIGHTED keep the XDS/AIMLESS convention and are what to set beside XDS; the battery scorer records them. MULTIPLICITY stays a count. Effect (weighted / unweighted): lyso_x06da_ref 0.0454 / 0.0479, 8xtf 0.225 / 0.907, insu_I_x06da_ref REFRES 0.072 / 0.232. GPU and CPU paths agree to the last printed digit on lyso_x06da_ref. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D1G8gJVAy6gp1K5Dz3NE5C |
||
|
|
94ed6aec04 |
Scaling: a frame below the credible floor does not hold the loop's step open
ComputeSmoothGWindow leaves a frame below MIN_CREDIBLE_SCALE_RATIO of the median out of every window, and DropCollapsedScales drops it after the loop, but RunScalingLoop still counted its step. Such a frame has lost its vote in its own references and keeps moving, so the loop was stopped as "unsettled". On 8xtf (hq-pool battery) the first-pass partials loop stopped after 16 rounds at rms dlogG 1.8e-01 (base 9.5e-04); with the frame left out of the step it settles in 23 rounds (8.0e-04), and every other loop of that run that had stopped unsettled (pass 2 at 1.6e-03) now settles too. Every loop of that sweep that stopped unsettled was one that went on to drop a frame. The final 8xtf merge is bit-identical; the false SCALING_NOT_CONVERGED warning goes. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D1G8gJVAy6gp1K5Dz3NE5C |
||
|
|
6009842324 | Merge branch 'hq-bwuse' into hq-pool | ||
|
|
1a307d9c36 |
rugnux: use the pre-scan's measured bandwidth when the file states none
The pre-scan's spot-shape estimate (spot_width::EstimateBandwidth) becomes the run's bandwidth where it
is significant (z > 3) and neither the file nor --bandwidth states one; an explicit value, including
--bandwidth 0, still wins. Everything that already reads GetBandwidthFWHM() - prediction, partiality,
the profile's radial width, the stencil growth, scaling - takes it from there. Below z 3 the bandwidth
stays unset, so monochromatic runs are bit-identical (12 mono sets checked on p.hkl md5).
The width tiers stop as soon as r80 settles, often at 15 frames and a few hundred spots, which is
too few for the slope. The pre-scan now keeps measuring spot shapes for the bandwidth alone until the
pool holds 1000 spots or the sample ends. Those extra frames feed neither r80 nor the powder
measurement, so r1..r3, powder and the spot-resolution quantiles are unchanged. Over the 68-set
battery plus the known mono controls (47 sets re-probed) no monochromatic set crosses z 3 (highest
lyso_x06da_5keV 2.0, insu 5-6 keV 1.7); the one new positive is 9z44 (ALS 8.2.1, multilayer
beamline, 0.38% at z 3.1 from 382 spots instead of z 1.0 from 94).
Two hidden b > 0 mode switches go, so the bandwidth acts continuously:
- the background clip default dropped from 4 to 3 sigma when a bandwidth was set. With the measured
bandwidth, clip 3 vs 4 on the MicroMAX pink sets: REFRES R_meas 0.0507/0.0507 (lyso),
0.0842/0.0844 (thau), REFRES ISa 28.83/28.77, 14.12/14.12 - no bandwidth-specific effect.
- the "--integration-stencil has no effect without --bandwidth" message, which is decided before the
pre-scan and would now be wrong.
The one set where clip 3 helps (9z44, 7 A: R_meas 0.252 -> 0.201) gains the same at zero bandwidth, so
that is a property of the clip, not of the beam.
Effect of the measured bandwidth (stencil 0, clip 4), against hq-integ
|
||
|
|
032bf9fe2b |
Rugnux: walk the goniometer rotation scale to its fixed point, decided on the whole sweep
The pass-1 post-refinement fits the rotation scale k only on the frames the stored angles still track, and a rate error is exactly what stops them tracking the rest: on a sweep whose stage turned ~3 % slow the fit read 0.979 over 94 deg, failed its leave-a-fifth-out test and was thrown away, leaving half the frames unscaled. The pass no longer decides. Between the passes, at the pass-2 detector geometry, the lattice is indexed (index-only probe) under the stored angles and under the fitted k and scored on the validation frames of the whole sweep: share of the spots on the lattice beyond the wrong-spindle null. k is adopted only where it scores higher by more than the binomial noise of the two (ValidationEvidencePrefers - the test the beam-centre arms already used, now one function); the run then integrates and post-refines at k (post-refine-only probe), fits again on top of it and repeats until the next k no longer scores better (WalkRotationScale). The stored angles are the first hypothesis. Measured: 1.000 25.1 %, 0.97874 58.9 %, 0.97041 90.0 %, 0.97006 90.7 % (not significant) -> 0.97041 adopted. Probes restore the experiment, the pass-2 geometry, pass-1 mosaicity and the beam-centre-search flag; a probe opens no beam-centre search. Forced pass-1 results get their axis scaled; the header revert drops the scale. GONIOMETER_ROTATION_SCALE reports the adopted k (SUSPECT = adopted). The leave-a-fifth-out figure stays in the log only. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D1G8gJVAy6gp1K5Dz3NE5C |
||
|
|
9b6736dbda |
Changelog: hot-pixel mask, Wilson outlier test, bandwidth report, surface gate, polarization docs
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D1G8gJVAy6gp1K5Dz3NE5C |
||
|
|
a2c2810551 |
Merge: a clipped observation is no witness in the Wilson test
The pair rule drops the improbable (higher) member of a discordant pair. If the lower member lost its core to saturation or the mask, its profile estimate of what remained may be low, and a genuinely strong reflection would be replaced by the clipped value - the failure Aimless guards against. Integration now marks a reflection whose signal disk was not fully readable (Reflection::clipped, from the engines' existing full-disk test); the flag is carried through the partials to the fulls (OR over an event's partials, CPU and GPU combine alike), and the Wilson test never counts a clipped observation as a probable witness against a larger one. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D1G8gJVAy6gp1K5Dz3NE5C |
||
|
|
b1327033ae |
rugnux: --polarization is a polarization degree; the default is an undulator value
The help text claimed 0.99 is right for every synchrotron in the corpus. Bending-magnet, superbend and wiggler sources are plausibly 0.8-0.95, no file format read states the value reliably, and it cannot be fitted from a single dataset (it correlates with spindle-symmetric absorption). Say what the number is (degree p; XDS FRACTION_OF_POLARIZATION = (1+p)/2) and that a known beamline value can be passed. Documentation only; the default stays 0.99. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D1G8gJVAy6gp1K5Dz3NE5C |
||
|
|
257686c6fd |
Merge: Wilson outlier test
The median outlier test needs three observations, so a reflection measured once or twice (one good observation and one artefact, the usual case after Friedel merging) was never tested, and where there were more, a precise-looking artefact (a hot pixel, thousands of counts) could outweigh mates from weak frames and become the weighted median itself. Every observation of the written merge is now also judged against Wilson statistics beyond 4 A: E^2 = I / (epsilon <I/epsilon>_shell), centric and acentric laws, a bound set by alpha = 0.01 expected false rejections per dataset (ln(2N/alpha); twice that for centrics), the lower confidence limit I - z*sigma (own sigma, z from the same budget) required to exceed it, shells whose <I> is not established at that significance not judged, and the bound widened by the dataset's measured tail scale (peaks over threshold on the well-measured shells; 1 for a Wilson crystal, larger under tNCS/anisotropy). An improbable singleton is rejected; one with company only when most of its reflection's other observations are probable and it disagrees with them. The reflection is the group, or the Friedel pair under -A. Search merges are not tested (epsilon is 1 in P1, and the screw rows are the reflections a wrong epsilon would call improbable). The flags are handed to the device merge as pre-rejections, so CPU and GPU agree. Report: OBSERVATIONS_REJECTED_WILSON= (part of OBSERVATIONS_REJECTED=), and the developer report lists each rejected observation (hkl, d, E^2, image, x, y). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D1G8gJVAy6gp1K5Dz3NE5C |
||
|
|
cab91e2663 | Merge branch 'hq-prescan' into hq-integ | ||
|
|
23e1976e55 |
Surfaces: compare held-out half-set CC on Fisher's z; fit modulation, time, goniometer frame in that order
The correction-surface gate averaged the per-shell change of the held-out half-set CC over 20
equal-occupancy shells and adopted a surface on its sign. On the shells where a multiplicative error
shows, CC1/2 sits at 0.99-0.9996 and a large reduction of the error moves it in the fourth decimal;
the shells beyond the data's reach (up to 12 of 20 at CC ~ 0) each add +-0.01, so the sign was set
by noise (measured spread of the mean +-0.001-0.003 against effects of -0.0003..-0.0008). It refused
the 24x24 detector surface on four EIGER2 16M sweeps. The change is now averaged on atanh(CC) - the
candidate from the hq-bisect investigation.
The order of the three overlapping surfaces also decides what is adopted. With the gate fixed,
goniometer-frame first took a 5 keV insulin sweep from ISa 31.8 to 20.1 (the time surface then
refused; R_meas 7.8 -> 8.9%, CC to the model 0.8307 -> 0.8282) and cost a 0.1 deg-sliced thaumatin
sweep R_meas 18.2 -> 19.6%; time x detector first refused the detector surface on the 16 keV
thaumatin sweep (ISa 33 instead of 40). Modulation, time, goniometer frame avoids both.
Bare runs, --report-resolution at XDS's range, against rc173 (
|
||
|
|
aea13044b5 |
Record the corrections a DECTRIS detector applied; read multichannel NXmx
The broker rebuilds the outgoing StartMessage from DiffractionExperiment, and FillMessage hard-coded countrate_correction_enabled and flatfield_enabled to false. JFJochReceiverLite parsed the true values from the detector's stream2 start message and dropped them, so every DECTRIS file written through the broker said neither correction was applied - DECTRIS enables both by default. pixel_mask_applied had the same defect: it reported the local apply_mask setting (an FPGA feature), not what the detector did to the pixels, which ReceiverLite forwards byte for byte. These now come from the stream: DetectorSetup carries them, ReceiverLite copies them in Configure, FillMessage reads them. Two more fields the DECTRIS stream sends and NXmx defines are passed through to the master file: countrate_correction_lookup_table (uint32, possibly bslz4/bszstd compressed in the stream) and virtual_pixel_interpolation_applied. The flatfield is deliberately not written - it makes the master file too large. PSI EIGER is unchanged: jfjoch never enables rate correction and the detector server starts with it off. The reader also opens the DECTRIS "hdf5 nexus v2024.2 nxmx" layout, where /entry/data/data is 4D [image, channel, y, x] and the pixel mask is kept per channel. Only the first channel is read; this is compatibility, not full multichannel support. A _process.h5 made from such a file links its pictures to that channel. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013nW6FNRP1bBJJ8pfHiByAT |
||
|
|
19a850cd20 |
rugnux: measure the X-ray bandwidth from the pre-scan's spot shapes (reported only)
Per isolated strong spot of the spot-width sample, second moments along and across its radius, with the exact per-spot Jacobians (pixels per radian of 2theta and of the angle across the scattering plane, from the geometry) and the sensor parallax fixed from physics (conversion depth exponential with length L cos(psi), truncated at the thickness, smeared z tan(psi) along the ray's in-plane direction). y = (m_rad - 1/12 - par_u) - (jr/jt)^2 (m_tan - 1/12 - par_v) is linear in (2 jr tan theta)^2 with slope sigma^2; fitted over eight equal-count 20%-trimmed bins, error from 200 seeded bootstrap re-draws inflated by the reduced chi^2, significant at z > 3. The pre-scan logs the FWHM, its standard error, z and chi2 next to the bandwidth the run uses; nothing consumes it, so output is unchanged. The truncated-exponential depth variance moves into SensorAbsorption.h (ConversionDepthVariance_um2), shared with the integrator's parallax_var_px2 (same arithmetic). Catch2: a synthetic spot population painted with 0.45% FWHM bandwidth and 450 um Si parallax recovers 0.449% (z 82); the same spots without bandwidth give 0.06% at z 0.7. On the battery sets (67d49f base, estimate as logged): MicroMAX pink lyso 0.41% z 7.3, thau 0.42% z 6.9, CHESS 7B2 9q41 0.36% z 14.6, ALS 8.2.1 8u0i 0.27% z 5.6; mono controls lyso_micromax_mono, lyso_x06da_ref, 5mln and near misses 9z44, 7orr, lyso_x06da_5keV all below z 3. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D1G8gJVAy6gp1K5Dz3NE5C |
||
|
|
beb97b62d3 |
rugnux: mask defective pixels measured on the pre-scan's own frames
Unmasked persistent hot pixels are integrated into whichever reflection's box they fall in; under
rotation one pixel collects a different reflection on every frame that reaches it, and the merge
carries intensities hundreds to thousands of times their shell mean on one or two observations.
HotPixelFinder (rugnux/HotPixels.{h,cpp}) reads the pre-scan sample a second time, once the
beam-stop projection has measured where the background puts the beam, and on each frame calls a
pixel lit when it exceeds its 2 px iso-2theta ring level (max of the ring and 1/16-sector medians)
by 3.3 sigma (sqrt(level) or the ring's MAD) + 2. A pixel lit on at least max(k1, kB) frames is
persistent: k1 = 1 + ceil((osc + 5 deg)/|zeta| / frame spacing) is more than one reflection can
light, kB the binomial bound (0.01 family-wise over the detector) from the ring's own lit rate.
A persistent pixel is masked, as the new PixelMask bit 10, only if it stands alone (component of
persistent pixels <= 2), reads on average >= 10x its ring and its mean excess is above the Poisson
bound; pixels holding the error value on most frames are masked with them. Counting sensors (thickness > 0)
and rotation data only; a CCD is left alone. One log line reports the counts.
Drawing the rings about the file's centre, as a first version did, masked pixels along the
background fall-off on a sweep whose file centre is 171 px from the background's and cost it 14%
ISa; about the measured centre that sweep is within 1%. Masking the detector's outermost row and
column unconditionally was tried and dropped: the persistence test already catches the hot pixels
there, and the whole lines bought nothing measurable.
Numbers below are from the looser first criterion (no isolation / 10x gate), against rc173-final
on the same base: merged reflections > 30x their shell mean gone on the
sets with proven hot pixels (7brr 21 -> 0, 9ih9 15 -> 0, 8xte 10 -> 0, 6z8o worst 1706x -> 40x);
6z8o CC1/2 0.50 -> 0.995, ISa 8.6 -> 12.8, CC to model 0.82 -> 0.90; 8xte ISa 8.0 -> 10.8; 6u7g
ISa 9.8 -> 12.0; controls (lyso_x06da_ref, marCCD) unchanged.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D1G8gJVAy6gp1K5Dz3NE5C
|
||
|
|
38bb511d23 |
Make a first-pass detector tilt no mounting can have prove itself on the spots
The first-pass rotation fit refines the spindle-perpendicular detector tilt freely, and on a sweep whose seed spots reach only a few degrees of 2theta the keystone that would determine it is a pixel or two. The fit then commits whatever the centroids' own systematics prefer - measured 2.5 deg on one sweep seeded to 11.7 A - and that tilt mispredicts the detector corners by 20-60 px against a 6 px integration disc, collapsing the run from 2.8 A to 6.35 A and biasing the metric-symmetry arbiter to a = b on the way. On synthetic data the same runaway is reproducible: a 1.5 deg detector error on 6 A reflections walks the free fit to 3.9 deg, on 8 A reflections to 37. Three data-driven discriminators were tried first and refuted on the corpus: a blanket restraint (0.13-0.16 A and up to 28% of ISa lost on the crystals whose tilt is largest and real, and in-house runs pinned at a header tilt known to be wrong), the distance's held-out excitation criterion (the rocking angles move by a tenth of their noise whether the tilt is real or not), and a keystone comparison of the fitted and header tilts with the beam free in both arms (236-set battery: ~30 sets moved, one collapsed from P1 to C2, one lost a screw axis; differences of 0.007-0.6 sigma held the header on right and wrong cases alike). For a tilt of a few tenths of a degree the keystone is a fraction of a pixel and nothing in the spots says whether it is real. What separated the cases was the tilt's size: every set the keystone arm moved carries 0.08-0.46 deg, and a survey of 211 corpus sets leaves the file's tilt by more than 0.56 deg on exactly one - a 2theta arm swung out 12.8 deg that its file records as square, which the free fit recovers and the held arm refuses by 90 sigma. So the hardware prior decides whether to ask, and the spots decide. Below 1 deg of walk from the tilt the pass started at the fit is trusted as before, by construction. Beyond it the winning candidate is refined again from its start with the tilt held there - the beam centre taking the shift the tilt is equivalent to, so the header tilt is never paired with a beam fitted beside a refused tilt - and the two are judged as the rounds of one chain already are, on the spots each indexes inside the wide gate: the walked tilt stands only when it leads by more than the count's own noise. A real tilt of degrees has a keystone of tens of pixels over the seed spots and wins outright; an artefact has none and loses on a tie. Held rather than bounded, because a box the fit lands on is the same wrong answer at a smaller size. Decided at the fit, so every pass and arm of a run handles itself and nothing is carried between passes; the unconstrained alternative is re-solved beside a refused tilt too. The chain that drives a candidate to its fixed point becomes a lambda so it can be run on the held candidate. The run logs the walk, what it would have moved the far corner by, the shift the beam took instead and both spot counts; where it was refused the report's REFINED_DETECTOR_TILT is the starting tilt and REFUSED_DETECTOR_TILT what the fit had walked to. Tests: a half-degree tilt is found, kept and not reported as a walk; a walk past the prior is made on synthetic data, and the result's verdict, counts and geometry agree with each other. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013nW6FNRP1bBJJ8pfHiByAT |
||
|
|
d37db5b58e |
docs: 6z9g in EXTERNAL_TEST_DATA, and what makes it the only index-4 set
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013nW6FNRP1bBJJ8pfHiByAT |
||
|
|
e8d09033d1 |
docs: EXTERNAL_TEST_DATA takes the detector from the files, without an entry-vs-file list
The image file is authoritative for the detector and the PDB entries' detector fields are known to be unreliable, so the page no longer keeps a per-entry conflict table (eighteen rows, among them 5MLN and 9H0Q) or the paragraphs arguing individual cases. The intro bullet now says in one clause that the file wins where the entry disagrees; the paragraph on how marCCD and SMV rows fill the column stays. The table's values are unchanged - 5MLN (miniCBF "PILATUS3 2M, S/N 24-0118") and 9H0Q (NXmx description "Dectris EIGER1 Si 9M", E-18-0102) were re-read from the headers and already matched. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013nW6FNRP1bBJJ8pfHiByAT |
||
|
|
c3c6118cc1 |
docs: EXTERNAL_TEST_DATA no longer records the download round
Drops the Round column and its explanation. Statements that depended on a round or on table position now describe the whole table: the detector comparison covers all 163 comparable rows in one conflict table (18 conflicts, sorted by PDB id) with one paragraph on the marCCD/SMV headers; the per-round "in numbers" sections become one whole-table section (repository, facility, crystal system, long axes), dropping the per-round size and file-format tallies; the archive section no longer counts archives per round. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013nW6FNRP1bBJJ8pfHiByAT |
||
|
|
a1944fd7ae |
docs: credit the Keele University and UQ eSpace data repositories
Two of the new open-arm datasets come from them. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013nW6FNRP1bBJJ8pfHiByAT |
||
|
|
232e03afa8 |
docs: eighteen third-round open-arm sets in EXTERNAL_TEST_DATA; one table sorted by PDB id
Adds 5ky6 5mln 5t39 6cdl 6f3p 6g1f 6jgh 6nen 6qaj 6s1u 6w75 6zqr 6zqy 6zr0 7ou1 7raa 9fcf 9h0q in the existing row form: deposited values from RCSB, the detector from the image files, DOIs resolved (6NEN's is a Crossref DOI whose landing page refuses scripted access). New notes: the five screw-free negative controls, the 5KY6 RAR set, the damaged 6ZR0 zip, the hand-downloaded 6NEN archive, two detector conflicts (5MLN, 9H0Q), third-round counts. The table rows, which were grouped by download round, are now sorted by PDB id; the round moves into a Round column, and the prose that referred to "the first 95 rows" or "the last 51 rows" refers to the round instead. Counts updated to 171 datasets / 164 PDB entries (all 18 new entries have released structure factors). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013nW6FNRP1bBJJ8pfHiByAT |
||
|
|
6dfe065365 |
v1.0.0-rc.172 (#82)
Build Packages / Create release (push) Successful in 16s
Build Packages / build:rugnux:aarch64 (cross) (push) Successful in 8m27s
Build Packages / build:rugnux-tgz (x86_64) (push) Successful in 9m15s
Build Packages / build:viewer-tgz:cpu (push) Successful in 10m11s
Build Packages / build:viewer-tgz:cuda (push) Successful in 12m6s
Build Packages / build:rpm (rocky8_nocuda) (push) Successful in 15m44s
Build Packages / build:rpm (rocky9_nocuda) (push) Successful in 16m1s
Build Packages / build:windows:nocuda (push) Successful in 17m29s
Build Packages / build:windows:cuda (push) Successful in 19m58s
Build Packages / HDF5 consumer tests (DIALS, XDS) (push) Successful in 24m7s
Build Packages / build:rpm (ubuntu2404_nocuda) (push) Successful in 19m8s
Build Packages / build:rugnux:windows (push) Successful in 10m58s
Build Packages / build:rpm (ubuntu2204_nocuda) (push) Successful in 20m46s
Build Packages / Generate python client (push) Successful in 53s
Build Packages / build:rpm (rocky8_sls9) (push) Successful in 20m13s
Build Packages / Build documentation (push) Successful in 1m36s
Build Packages / build:rpm (rocky9_sls9) (push) Successful in 19m57s
Build Packages / build:rpm (rocky8) (push) Successful in 18m7s
Build Packages / build:rpm (rocky9) (push) Successful in 18m54s
Build Packages / build:rpm (ubuntu2204) (push) Successful in 19m32s
Build Packages / build:rpm (ubuntu2404) (push) Successful in 17m30s
Build Packages / Unit tests (push) Successful in 1h39m2s
* Fixed `jfjoch_broker` cancelling every data collection with a CUDA "out of memory" error after long operation: GPU memory no longer leaks with each collection. * Rugnux scales a rotation sweep until the per-frame scales settle instead of for a fixed three rounds, and says so when they did not - merged intensities, and the space group, resolution cut and frame rejection read off them, change accordingly; `--scaling-iterations` is now the cap on that loop (default 100). * Rugnux places every frame of a marCCD, SMV or miniCBF series at the spindle angle its own header states, so a series with missing frames, or with angles written modulo 360, is no longer read at the wrong geometry or refused. * Every rotation run writes two diagnostic files beside its reflections: `<prefix>_detector.jpg`, the detector projection with the pixel mask and the detected beam-stop shadow drawn on it, and `<prefix>_plot.txt`, one row per image. Reviewed-on: #82 Co-authored-by: Filip Leonarski <filip.leonarski@psi.ch> |
||
|
|
30b6800289 |
v1.0.0-rc.171 (#81)
Build Packages / build:windows:nocuda (push) Successful in 17m20s
Build Packages / build:windows:cuda (push) Successful in 19m52s
Build Packages / build:viewer-tgz:cpu (push) Successful in 9m38s
Build Packages / build:viewer-tgz:cuda (push) Successful in 11m18s
Build Packages / build:rugnux-tgz (x86_64) (push) Successful in 9m34s
Build Packages / build:rugnux:aarch64 (cross) (push) Successful in 5m42s
Build Packages / HDF5 consumer tests (DIALS, XDS) (push) Successful in 20m33s
Build Packages / Create release (push) Successful in 33s
Build Packages / build:rugnux:windows (push) Successful in 12m0s
Build Packages / build:rpm (rocky8_nocuda) (push) Successful in 15m42s
Build Packages / build:rpm (ubuntu2204_nocuda) (push) Successful in 14m59s
Build Packages / build:rpm (rocky9_nocuda) (push) Successful in 16m8s
Build Packages / build:rpm (ubuntu2404_nocuda) (push) Successful in 14m35s
Build Packages / build:rpm (rocky8_sls9) (push) Successful in 16m55s
Build Packages / build:rpm (rocky9_sls9) (push) Successful in 16m58s
Build Packages / Generate python client (push) Successful in 16s
Build Packages / build:rpm (rocky8) (push) Successful in 15m21s
Build Packages / Build documentation (push) Successful in 54s
Build Packages / build:rpm (rocky9) (push) Successful in 16m23s
Build Packages / build:rpm (ubuntu2204) (push) Successful in 12m2s
Build Packages / build:rpm (ubuntu2404) (push) Successful in 10m6s
Build Packages / Unit tests (push) Successful in 1h10m26s
* Rugnux: basic support for CCD images (marCCD, SMV) and for gzipped miniCBF. * `jfjoch_viewer`: opens the CCD formats, and fixes to the dataset plots. * Documentation updates. Reviewed-on: #81 Co-authored-by: Filip Leonarski <filip.leonarski@psi.ch> |
||
|
|
cb5a2f032a |
v1.0.0-rc.170 (#80)
Build Packages / Create release (push) Successful in 23s
Build Packages / build:rugnux-tgz (x86_64) (push) Successful in 10m6s
Build Packages / build:rugnux:aarch64 (cross) (push) Successful in 9m6s
Build Packages / build:viewer-tgz:cpu (push) Successful in 11m15s
Build Packages / build:viewer-tgz:cuda (push) Successful in 12m21s
Build Packages / build:windows:nocuda (push) Successful in 17m9s
Build Packages / build:windows:cuda (push) Successful in 19m49s
Build Packages / HDF5 consumer tests (DIALS, XDS) (push) Successful in 25m42s
Build Packages / build:rpm (ubuntu2204_nocuda) (push) Successful in 16m0s
Build Packages / build:rpm (ubuntu2404_nocuda) (push) Successful in 14m54s
Build Packages / build:rpm (rocky8_nocuda) (push) Successful in 17m7s
Build Packages / build:rugnux:windows (push) Successful in 10m47s
Build Packages / build:rpm (rocky9_nocuda) (push) Successful in 17m4s
Build Packages / build:rpm (rocky8_sls9) (push) Successful in 17m8s
Build Packages / Generate python client (push) Successful in 45s
Build Packages / Build documentation (push) Successful in 1m45s
Build Packages / build:rpm (rocky9_sls9) (push) Successful in 19m23s
Build Packages / build:rpm (ubuntu2204) (push) Successful in 19m20s
Build Packages / build:rpm (ubuntu2404) (push) Successful in 18m43s
Build Packages / build:rpm (rocky8) (push) Successful in 19m31s
Build Packages / build:rpm (rocky9) (push) Successful in 20m16s
Build Packages / Unit tests (push) Successful in 1h41m19s
* Fixed a `jfjoch_broker` crash during indexing: sorting no longer misbehaves on non-finite values, and GPU FFT indexer kernel launches are now error-checked. * rugnux needs about a third less peak memory to scale, merge and post-refine rotation data, with identical results. * `rugnux --model`: the placed coordinate file carries the space group its own coordinates obey, and says so when that is not the group the reflection files beside it carry. * `jfjoch_viewer`: fixes in the dataset plots, inspector and layout; spot markers lose their black outline by default (a checkbox under "Image features" restores it) and the highest-pixel markers are white boxes around the pixel. Reviewed-on: #80 Co-authored-by: Filip Leonarski <filip.leonarski@psi.ch> |