Files
leonarski_fandClaude Opus 5 61a7c91b90 Ice: detect it on two channels, and only handle it when it is there
The per-image ice score was read off the PLAIN azimuthal profile. That profile is a
per-ring mean, so a few strong Bragg reflections landing in a ring's q bin lift it
exactly as ice would. Measured over 37 rotation crystals, that did not merely add
noise - it INVERTED the metric: the two highest-scoring crystals had no ice at all
(4.23 and 4.06), while a clean control read 1.57. A decoy null - the identical
statistic evaluated at q positions where hexagonal ice cannot be - reaches 1.51 at its
99th percentile and 2.70 at its maximum, so that metric cannot support any absolute
threshold whatsoever.

The adaptive spot finder already computes the right input for its own threshold: a
sigma-clipped per-resolution-ring background, in the same bins. A powder ring is
azimuthally smooth and survives the clip; Bragg peaks do not. On the clipped profile
the clean population tightens to 1.00-1.22 and the crystals with confirmed ice sit at
2.08-2.37, against a decoy null that never exceeds 1.29.

That channel is blind to one thing: ice in large crystallites diffracts as DISCRETE
spots and leaves the radial profile flat. So a second channel counts found spots on the
rings against the same q width of ice-free flanks beside them. The two barely overlap -
the smooth-ice crystals read 2.1-2.4 / ~1.0 and the textured ones ~1.1 / 3.8-17.6,
while a clean crystal reads 1.04 on both.

Both are then used as a GATE (--ice-min-score 1.5, --ice-min-spot-ratio 2.0, both
calibrated on the battery, 0 disables): the eleven fixed hexagonal bands cover 16-26 %
of the unique reflections at typical resolutions whether or not the crystal has ice, so
flagging, the exclusion from the scale fit and the merge-time CC1/2 ring mask are now
all skipped when neither channel sees any. The gate is applied in the full pipeline and
in --scale, which reads the stored per-image values back out of the _process.h5.

Also fixes the merge-time mask's control: the shoulder now excludes reflections that
are themselves on an ice ring. The rings are not evenly spaced - 1.947/1.916/1.882 A
sit 0.05-0.06 apart in q - so for those three the [w,3w) shoulder landed squarely on
the neighbours and the test compared ice against ice. Measured, that is the only thing
this changes: it removes firings on those three rings and leaves every other firing's
CC pair identical to three decimals.

And the online ice half-width, which was 0.02 in the API against 0.03 offline, so the
same data got a narrower band online than the measured ~0.06 ring FWHM justifies.

Battery (37 rotation crystals, against the previous behaviour): space groups 34/37 in
both and NO crystal's space group changes; 6 crystals gain unique reflections, 1 loses.
Best of them gains 7082 unique reflections with R_meas 16.0 -> 14.3, CC1/2 95.9 -> 97.3
and ISa 13.7 -> 19.0; another goes R_meas 54.9 -> 42.9, CC1/2 84.0 -> 90.4, ISa
3.9 -> 5.5; a third reaches CC1/2 99.4 from 95.7 at an unchanged reflection count. The
one crystal that loses reflections improves on both R_meas and CC1/2.

Not done here: the ScanResult/API/plot-type/frontend/viewer layers for the new
spot_count_ice_control (they need the OpenAPI regeneration). Message, CBOR, HDF5
write/read and the receiver plots are.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-06 16:17:23 +02:00
..
2026-07-11 07:19:11 +02:00
2026-06-23 20:29:49 +02:00
2024-10-05 13:14:49 +02:00
2025-11-28 12:47:35 +01:00
2026-06-23 20:29:49 +02:00
2026-07-28 21:58:00 +02:00
2026-07-28 21:58:00 +02:00
2026-06-16 14:13:29 +02:00
2024-10-05 13:14:49 +02:00
2024-10-05 13:14:49 +02:00
2024-10-05 13:14:49 +02:00

Jungfraujoch Frontend

Building

To build web interface:

cd frontend_ui
npm install
npm run openapi
npm run build

Available Scripts

In the project directory, you can run:

npm start

Runs the app in the development mode.

The page will reload if you make edits.
You will also see any lint errors in the console.

npm test

Launches the test runner in the interactive watch mode.
See the section about running tests for more information.

npm run build

Builds the app for production to the dist folder.
It correctly bundles React in production mode and optimizes the build for the best performance.

The build is minified and the filenames include the hashes.
Your app is ready to be deployed!

npm run openapi

npm audit findings

npm audit currently reports 17 advisories (3 high, 13 moderate, 1 low). All of them live in build-time tooling and never reach the production bundle shipped to the browser. Summary of the chains:

Source dep Vulnerable transitives When it runs
@redocly/cli @opentelemetry/*, dompurify (via redoc), ws (via simple-websocket), js-yaml, protobufjs, @babel/core npm run redocly / redocly4broker — static OpenAPI HTML generation
vite esbuild@0.27.x Dev server and dep pre-bundling. Production build uses Rollup.
vite-plugin-svgr @babel/core, js-yaml (via cosmiconfig) Vite build plugin
openapi-typescript-codegen js-yaml npm run openapi — TS client generation

Notes on the high-severity items:

  • esbuild GHSA-gv7w-rqvm-qjhr is a Deno-specific RCE via NPM_CONFIG_REGISTRY; GHSA-g7r4-m6w7-qqqr is an arbitrary-file-read in the dev server on Windows. Neither applies to a Linux build of the production bundle.
  • ws GHSA-96hv-2xvq-fx4p only matters when simple-websocket opens a socket, which happens during docs generation, not at runtime.

npm audit fix cannot resolve any of these without downgrading @redocly/cli (no real fix) or jumping vite to a major that switches the bundler to Rolldown.