// SPDX-FileCopyrightText: 2026 Filip Leonarski, Paul Scherrer Institute // SPDX-License-Identifier: GPL-3.0-only #pragma once #include #include #include "JFJochReader.h" #include "XTC.h" // Reads serial-crystallography stills straight from LCLS-I XTC files: one camera image per event, // from a single-panel detector such as the Rayonix CCDs at MFX and XPP. A multi-panel detector // (CSPAD, ePix, JUNGFRAU at LCLS) is stored as raw per-module data with its own calibration, and is // not read here. // // XTC records the events and not the experiment: there is no distance, beam centre or wavelength // in it that this reader can use. Those come from a DIALS experiment list (.expt) beside the XTC // files, or in their parent directory - the geometry a deposition ships for cctbx.xfel, and what // cctbx.xfel itself reads them with. Without one the run is refused rather than guessed. // // The images are stills: no goniometer. Each is decoded on demand. The pixels are passed on as // stored - the CCD's constant offset of a few counts is left in, as it is in an SMV image, and the // pre-scan finds the defective pixels. class JFJochXTCReader : public JFJochReader { std::vector frames_; std::shared_ptr dataset_; bool LoadImage_i(std::shared_ptr &dataset, DataMessage &message, std::vector &buffer, int64_t image_number, bool update_dataset) override; template CompressedImage DecodeInto(int64_t image_number, Buffer &buffer, std::vector &scratch) const; void ReadGeometry(const std::string &expt); public: ~JFJochXTCReader() override = default; static bool CanRead(const std::string &path); // path is one XTC stream, or a directory whose streams are all read. void ReadFiles(const std::string &path); [[nodiscard]] uint64_t GetNumberOfImages() const override; void Close() override; bool ReadRawImage(int64_t image_number, JFJochReaderRawImage &image) override; [[nodiscard]] std::vector ReadSpots(int64_t image) const override; };