// SPDX-FileCopyrightText: 2026 Filip Leonarski, Paul Scherrer Institute // SPDX-License-Identifier: GPL-3.0-only #pragma once #include #include #include #include // A CrystFEL detector geometry file (.geom), as far as it places pixels and says what they are worth: // 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. Both the current syntax and // the older one - global keys that only take effect for the panels that follow them, bad regions // stated in whole-frame coordinates - are read. // // Every length is in pixels except clen and coffset, which are in metres. A value CrystFEL takes from // the image file instead (clen = /path, photon_energy = /path) is kept as that path, for the reader // to resolve. namespace crystfel { 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::string clen; // metres, or an HDF5 path double coffset = 0; // metres std::optional adu_per_eV; std::optional adu_per_photon; std::optional max_adu; 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; }; struct Geometry { std::vector panels; std::vector bad; std::string data = "/data/data"; std::string photon_energy; // eV, or an HDF5 path std::string mask; // HDF5 path, or empty std::string mask_file; // file holding it, or empty for the image file itself uint32_t mask_good = 0, mask_bad = 0; }; Geometry Read(const std::string &filename); } // namespace crystfel