Files
Jungfraujoch/common/GridScanResult.h
T
leonarski_fandClaude Opus 5 c08e37443a grid scan: PLACEHOLDER GridScanCrystal/GridScanResult, to be replaced at integration
Revert this commit and nothing else when the real types land.

The two structs and the two OpenAPI schemas here are stand-ins. The real
GridScanCrystal/GridScanResult belong to the grid-scan analysis, in
image_analysis/grid_scan_analysis/GridScanResult.h, alongside the ranking, clustering and
crystal selection that produce them. They are duplicated here only so that the serialisation
in the previous commit - the /result/scan payload, the CBOR END block, the HDF5 master - could
land without waiting for that work.

The field list was checked against the real header and agrees with it: all twelve
GridScanCrystal fields match by name, type and meaning, res_A included (NaN where nothing was
measured), and GridScanResult carries the two beam sizes beside the crystal list.

To integrate: delete common/GridScanResult.h and its line in common/CMakeLists.txt, point the
two includes - common/ScanResult.h and common/JFJochMessages.h - at the real header, and
replace the grid_scan_crystal / grid_scan_result schemas in broker/jfjoch_api.yaml. Nothing
else refers to these two structs.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EFEJG6WBQv8th4UJFNe53N
2026-09-08 07:28:01 +02:00

54 lines
3.0 KiB
C++

// SPDX-FileCopyrightText: 2026 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
// SPDX-License-Identifier: GPL-3.0-only
#pragma once
// PLACEHOLDER - TO BE REPLACED AT INTEGRATION. The real GridScanCrystal/GridScanResult live in
// image_analysis/grid_scan_analysis/GridScanResult.h, alongside the analysis that owns the ranking,
// clustering and crystal selection producing them. This file carries only the shape the rest of the
// system needs, so that the /result/scan payload, the CBOR END block and the HDF5 master could land
// without waiting for it; the field list has been checked against the real header and agrees with it.
//
// To integrate: delete this file and its line in common/CMakeLists.txt, and point the two includes -
// common/ScanResult.h and common/JFJochMessages.h - at the real header. Nothing else refers to these
// two structs. The grid_scan_crystal / grid_scan_result schemas in broker/jfjoch_api.yaml are the
// same placeholder and go the same way.
#include <cmath>
#include <cstdint>
#include <vector>
// One crystal picked out of a grid scan. Positions are in the grid's own frame: nx/ny are fractional
// grid coordinates and x_um/y_um the same point as a signed offset along the two grid axes, so a
// consumer can address the crystal either by grid step or by stage motion without redoing the
// arithmetic.
struct GridScanCrystal {
float nx = 0.0f; // centre, fractional grid coordinate along the fast grid axis
float ny = 0.0f; // centre, fractional grid coordinate along the slow grid axis
float x_um = 0.0f; // centre, signed offset along the fast grid axis
float y_um = 0.0f; // centre, signed offset along the slow grid axis
int64_t image_number = -1; // the grid point at the centre, as an image ordinal
float major_um = 0.0f; // extent along the crystal's own major principal axis
float minor_um = 0.0f; // extent along its minor principal axis
// Direction of the major axis from the +x grid axis, counter-clockwise. An AXIS, not a direction:
// it lives in [0, 180) and wraps, so 179 deg and 0 deg are adjacent. Averaging two such angles
// arithmetically across the wrap turns two nearly parallel needles into a right angle - combine
// them on the doubled angle (mean of 2*theta, halved) or not at all.
float angle_deg = 0.0f;
float score = 0.0f;
float ice_score = 0.0f;
float res_A = NAN; // NaN where no resolution was measured in the blob
int64_t n_images = 0; // grid points that fell in this crystal
};
// The crystals a raster found, sorted by score descending. Today the analysis returns zero or one, but
// N is the design intent: nothing may assume at most one entry.
struct GridScanResult {
std::vector<GridScanCrystal> crystals;
// The beam the extents above were measured with, along the grid axes. Those extents still contain
// it, so this says what a consumer has to take back out.
float beam_size_x_um = 0.0f;
float beam_size_y_um = 0.0f;
};