Files
Jungfraujoch/docs/FPGA_DATA_ANALYSIS.md
T
leonarski_f 30b6800289
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
v1.0.0-rc.171 (#81)
* 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>
2026-09-17 14:42:52 +02:00

5.7 KiB

FPGA data analysis

Jungfraujoch FPGA design has incorporated X-ray diffraction image analysis capabilities.

Pixel mask

Pixels can be masked. For each module a 32-bit map of pixels is loaded to FPGA, with non-zero value meaning masked pixels. According to this map, pixels will be assigned a special value (minimum number for signed types and maximum number for non-signed types) and will be excluded from subsequent analysis.

ADU histogram

Before conversion to photons/energy, an ADU histogram can be calculated for a module. This allows to preserve some signature of unconverted values. This is done on a module-basis and works with bins with 32 ADU width.

For EIGER this can be used as just a histogram procedure.

JUNGFRAU conversion

For JUNGFRAU, module images are converted from ADUs to an energy value and divided by a given number to give units of keV. Result of the operation is rounded to integers.

Pixel thresholding

Pixel range can be specified. Pixels below a minimum threshold will be assigned zero. Pixels above a maximum threshold will be assigned saturated pixel value (the largest number for a given bit-width and sign type). This is specifically designed to operate on unsummed frames, so frame-specific parameters (overload/noise) can be handled.

Frame summation

Frames can be summed together (on a per-module basis) in Jungfraujoch, with a limit of 256 frames added together.

Azimuthal integration

To implement azimuthal integration, FPGA is able to sum pixels based on a provided integration map and per-pixel corrections. This way Jungfraujoch implements azimuthal integration with solid angle and polarization corrections. Corrections were implemented according to formulas developed by Jensen et al. (J. Synchrotron Rad., 29, 1420-1428, 2022).

Given FPGA limitations, split-pixels cannot be implemented and number of bins is limited to 2048 per detector module. This way 2D azimuthal integration, as needed for example by SAS-TT, cannot be currently implemented with the FPGA card and needs to be done on a CPU. One needs to be careful with per-pixel corrections - their acceptable range is constrained by 16-bit fixed point integer implementation and is tuned for standard SAXS/WAXS range.

As with ROIs, azimuthal integration is also available on CPU through the shared analysis library, so it applies to both the FPGA-accelerated (JUNGFRAU/PSI) and the DECTRIS-driven (EIGER) workflows.

Spot finding

Jungfraujoch FPGA implements a built-in spot finder. Spot finder allows to apply the following criteria for finding strong pixels:

  1. Resolution criterion - pixels only within a provided resolution range can be considered as strong pixels (calculating resolution map needs to happen on CPU before data collection run).
  2. Bad pixels - pixels marked as bad, as well as chip edges and module edges are excluded from spot finding,
  3. Overloads - pixels marked as overloads on JUNGFRAU are always included in the strong pixel output, but are excluded for signal-to-noise ratio calculation,
  4. Pixel value - pixels above certain threshold value can be marked as strong,
  5. Signal-to-noise (SNR) ratio - pixels with SNR above a threshold can be marked as strong,
  6. Connected pixels - strong pixels can be discarded if they are "alone", so their 8 directly neighboring pixels are not counted as strong pixels.

All the above criteria except the bad-pixel criterion are optional (can be turned off); only pixels that fulfill all enabled criteria are selected as strong pixels.

SNR ratio calculation

Signal-to-noise ratio is calculated for a rectangular area. In horizontal direction the area is fixed - line of 1024 pixels is divided into 32 areas each of 32 pixels. This is dictated by the data flow within the FPGA. In vertical direction the area is flexible - it is 15 lines above and below of the given pixel. Given the very large box size, approximations are made, for example that N ≈ N-1 in calculating standard deviation.

Region-of-interest (ROI) integration

There are 16 ROIs, and the ROI map holds a 16-bit mask per pixel, so a pixel can belong to any subset of them (including none). For each ROI, sum, sum of squares, max count, and number of valid pixels will be calculated. Jungfraujoch also calculates X and Y values weighted by pixel values, though this feature is not properly tested at the moment and not integrated in downstream analysis.

ROIs are not specific to the FPGA path. The same ROI definitions — box, circle, and azimuthal (Q-range with an optional φ-sector) — are also evaluated on CPU by the shared image_analysis/roi/ engine, so ROI statistics are produced both for the FPGA-accelerated JUNGFRAU/PSI workflow and for detectors driven through DECTRIS SIMPLON (e.g. EIGER), which have no FPGA acquisition path.

Pixel statistics

The following statistics are collected for each module:

  • Number of masked pixels
  • Number of saturated pixels (excl. masked)
  • Number of error pixels (excl. masked)
  • Sum of valid pixels in the module
  • Minimum value of valid pixels in the module
  • Maximum value of valid pixels in the module

Valid pixels are not masked, not saturated, not error pixels.

Square root compression

Jungfraujoch FPGA includes lossy compression preserving counting statistic properties of X-ray image, while reducing bit width of an image. Scheme was described in Wakonig et al., J. Appl. Cryst., 53, 574-586, 2020. Pixel value X is replaced with round(sqrt(N*N*X)), i.e. round(N*sqrt(X)), where N is integer constant in range 1 to 16. N is what the host writes to the sqrtmult register; the FPGA squares it before multiplying the pixel value.