// SPDX-FileCopyrightText: 2026 Filip Leonarski, Paul Scherrer Institute // SPDX-License-Identifier: GPL-3.0-only #pragma once // Pass A of BraggIntegrationEngineCPU, as the data it hands on: what the walk over one reflection's box // counts, and the clip sums of its background ring. Integers only, so the counts do not depend on the // order the pixels are visited in: the Metal engine walks the boxes on the GPU and gets the CPU's // counts exactly. Compiled by the host and by the Metal compiler, so the two agree on the layout - // which is also why there are no default member initialisers (Metal does not take a struct with them // as a buffer type); zero one with {}. #ifndef __METAL_VERSION__ #include #endif struct BraggBoxSums { int64_t I_sum, I_sum_x, I_sum_y; // readable signal-disk pixels, and their first moments int64_t x_sum, y_sum; // the positions behind I_sum, to take the background out of the centroid int64_t bkg_sum; // ring pixels kept for the background int64_t n_inner, n_inner_valid; // signal-disk pixels kept, and how many of them were readable int32_t n_disk, n_own; // signal-disk pixels, and how many of them are this reflection's int32_t n_bkg; // ring pixels behind bkg_sum int32_t n_ring, n_clean; // readable ring pixels, and those no predicted neighbour covers int32_t overloaded; // a signal-disk pixel was saturated, or unreadable on this frame only int32_t n_saturated; // signal-disk pixels at the saturation limit int32_t unused; }; // The ring pixels at or below a reflection's clip threshold (BraggIntegrationEngineCPU::ClipThreshold). struct BraggClipSums { int64_t sum; int32_t n; int32_t unused; }; // What the Metal kernels are told about the frame, beside the stencil (BraggStencilParams). struct BraggPassAFrame { int32_t width, height; float r1_sq, r2_sq, r3_sq; float claim, inv_claim; // how far a reflection claims pixels in the owner map int32_t use_owner; // an overlap treatment is on, so the owner map is built and read int32_t exclude; // ... and a pixel a neighbour owns leaves the signal disk int32_t n_rad; // radial background bins; 0 when the curve is not accumulated int32_t n_curve; // bins of the handed-over curve the clip follows (RadialClipOffset); 0: none uint32_t static_mask_words; // length of the run's packed pixel mask uint32_t n; // reflections }; // Compiled on both sides, so a layout the host and the Metal compiler disagree on fails to compile. static_assert(sizeof(BraggBoxSums) == 96, "BraggBoxSums layout shared with the Metal kernels"); static_assert(sizeof(BraggClipSums) == 16, "BraggClipSums layout shared with the Metal kernels"); static_assert(sizeof(BraggPassAFrame) == 52, "BraggPassAFrame layout shared with the Metal kernels");