// SPDX-FileCopyrightText: 2026 Filip Leonarski, Paul Scherrer Institute // SPDX-License-Identifier: GPL-3.0-only #pragma once #include #include #include #include // Where the panels of a stills detector lie and what their pixels are worth, as the XFEL readers // gather it from a file's own metadata (or, while it is still read, a CrystFEL geometry file): the // panels with their pixel ranges in the stored frame, fast/slow-scan directions and corners, the camera // length, the pixel size, the gain and the regions to leave out. The conventions are CrystFEL's - a // corner is the very corner of the panel's first pixel, x and y in pixels in the detector plane. // // Lengths are in pixels, except the camera length, which is held in metres. A value taken from the // image files (a camera length or photon energy stated per shot) is kept as its path, with the factor // that turns the stored number into the unit held here. namespace xfel { // A number stated in the layout, or a path to it in the image file, times scale. struct Value { std::string path; // empty: value holds the number double value = 0; double scale = 1; // what one stored unit at path is worth }; struct Panel { std::string name; int64_t min_fs = 0, max_fs = 0, min_ss = 0, max_ss = 0; // inclusive, in the stored frame double fs_x = 1, fs_y = 0, ss_x = 0, ss_y = 1; double corner_x = 0, corner_y = 0; double res = 0; // pixels per metre std::optional clen; // metres double coffset = 0; // metres std::optional adu_per_eV; std::optional adu_per_photon; std::optional max_adu; int64_t mask_edge_pixels = 0; bool no_index = false; }; // A region to leave out: either a pixel range on one panel (or, in the old syntax, on the whole // frame), or a box in the laboratory plane, in pixels. struct BadRegion { std::string panel; // empty: fs/ss are whole-frame coordinates bool in_lab = false; double min_x = 0, max_x = 0, min_y = 0, max_y = 0; int64_t min_fs = 0, max_fs = 0, min_ss = 0, max_ss = 0; }; // A mask array: a pixel is bad where it has any of bad's bits set, or lacks any of good's - or, with // nonzero_good, where the array is zero. struct Mask { std::string data; // HDF5 path std::string file; // file holding it, or empty for the image file itself uint32_t good = 0, bad = 0; bool nonzero_good = false; [[nodiscard]] bool Bad(uint32_t v) const { return (bad != 0 && (v & bad) != 0) || (good != 0 && (v & good) != good) || (nonzero_good && v == 0); } }; struct Layout { std::vector panels; std::vector bad; std::vector masks; std::string data = "/data/data"; std::optional photon_energy; // eV std::optional wavelength; // Angstrom; used where no photon_energy is stated // A stored value below, above or at these marks a pixel unusable in that frame. std::optional flag_lessthan, flag_morethan, flag_equal; }; } // namespace xfel