Every dense map that needs geometry now evaluates each image pixel at its place on the detector plane (DetectorModules), so it is right for a stacked panel layout and picks up refined module placements: - AzimuthalIntegrationMapping: bins, resolution, solid-angle/polarisation corrections built per pixel through the table; a pixel on no panel is left as a masked one. The geometry cache key now includes the panel table, so a mapping built after the stills module placement is rebuilt rather than served from the cache. ResolutionMaskBits follows (it is a lookup). - ROIMap / ExportROIMap: azimuthal ROIs on the plane (box and circle ROIs stay in image pixels). - ROIIntegration CPU+GPU: the weighted sums are taken per ROI and panel in image pixels and placed on the plane at the end (exact; the affine commutes with a weighted mean). - HotPixelFinder: ring/sector keys and the zeta of the persistence rule on the plane. - Background beam-centre walk CPU+GPU: pixels binned at their plane position; host and device share BackgroundPlanePoint so they stay bit-identical. New common/PanelRows.h: ForEachPixelInRows, ForEachPixel cut to a band of rows in index order, for the row-parallel builders. An empty table takes the old arithmetic in the old order: rotation sets and every single-panel input are unchanged. [PanelLayout] AzintMapping and ResolutionMask enabled (+ azimuthal ROI map and ROI centroid on the plane); new BeamCenterFromBackground_BinsOnThePlane and ROIIntegrationGPU_MatchesCPU_Panels. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015CeEGgpKdfkCTJb3YNMJcu
42 lines
2.1 KiB
C++
42 lines
2.1 KiB
C++
// SPDX-FileCopyrightText: 2026 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
|
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
|
|
#pragma once
|
|
|
|
// Included only under JFJOCH_USE_CUDA. Free of CUDA headers, so the host fit can hold one.
|
|
|
|
#include <cstdint>
|
|
#include <memory>
|
|
#include <vector>
|
|
|
|
#include "BackgroundBand.h"
|
|
|
|
// The two passes over the pixels of the background beam-centre fit (FindBeamCenterFromBackground),
|
|
// on the device: binning every usable pixel into its cell about a trial centre, and summing the
|
|
// binned pixels again under a clip. They are all of the fit's cost; the fit itself stays on the host.
|
|
//
|
|
// Each cell is summed in the order the host sums it - pixel order within each of the host's row
|
|
// blocks, the blocks then added in block order - so a pixel that lands in the same cell on both
|
|
// sides adds the same rounding on both. Whatever differs comes from BackgroundBandCell (see there).
|
|
class BeamCenterBackgroundGPU {
|
|
struct Impl;
|
|
std::unique_ptr<Impl> impl;
|
|
public:
|
|
// block_row: the first row of each of the host's row blocks, and one past the last row at the end.
|
|
// panels: where the image's panels are on the plane; empty when the image is the plane.
|
|
BeamCenterBackgroundGPU(int width, int height, const std::vector<int> &block_row,
|
|
const std::vector<BackgroundPanel> &panels, const char *usable, const float *mean);
|
|
~BeamCenterBackgroundGPU();
|
|
|
|
// Bin the band about (beam_x, beam_y) and sum each cell: the values, their squares, the two
|
|
// derivatives, and the count.
|
|
void Bin(const BackgroundBand &band, float beam_x, float beam_y,
|
|
std::vector<double> &sum, std::vector<double> &sum_sq,
|
|
std::vector<double> &sum_jx, std::vector<double> &sum_jy, std::vector<int32_t> &count);
|
|
|
|
// Sum the pixels the last Bin put in each cell again, leaving out those above the cell's
|
|
// clip_limit and every pixel of a cell whose limit is negative.
|
|
void Clip(const std::vector<float> &clip_limit,
|
|
std::vector<double> &sum, std::vector<double> &sum_sq, std::vector<int32_t> &count);
|
|
};
|