#pragma once #include #include #include #include "aare/FileInterface.hpp" #include "aare/FilePtr.hpp" #include "aare/NDArray.hpp" #include "aare/defs.hpp" namespace aare { struct JungfrauDataHeader { uint64_t framenum; uint64_t bunchid; }; class JungfrauDataFile : public FileInterface { size_t m_rows{}; //!< number of rows in the image, from find_frame_size(); size_t m_cols{}; //!< number of columns in the image, from find_frame_size(); size_t m_bytes_per_frame{}; //!< number of bytes per frame excluding header size_t m_total_frames{}; //!< total number of frames in the series of files size_t m_offset{}; //!< file index of the first file, allow starting at non //!< zero file size_t m_current_file_index{}; //!< The index of the open file size_t m_current_frame_index{}; //!< The index of the current frame (with //!< reference to all files) std::vector m_last_frame_in_file{}; //!< Used for seeking to the correct file std::filesystem::path m_path; //!< path to the files std::string m_base_name; //!< base name used for formatting file names FilePtr m_fp; //!< RAII wrapper for a FILE* using pixel_type = uint16_t; static constexpr size_t header_size = sizeof(JungfrauDataHeader); static constexpr size_t n_digits_in_file_index = 6; //!< to format file names public: JungfrauDataFile(const std::filesystem::path &fname); std::string base_name() const; //!< get the base name of the file (without path and extension) size_t bytes_per_frame() override; size_t pixels_per_frame() override; size_t bytes_per_pixel() const; size_t bitdepth() const override; void seek(size_t frame_index) override; //!< seek to the given frame index (note not byte offset) size_t tell() override; //!< get the frame index of the file pointer size_t total_frames() const override; size_t rows() const override; size_t cols() const override; std::array shape() const; size_t n_files() const; //!< get the number of files in the series. // Extra functions needed for FileInterface Frame read_frame() override; Frame read_frame(size_t frame_number) override; std::vector read_n(size_t n_frames = 0) override; void read_into(std::byte *image_buf) override; void read_into(std::byte *image_buf, size_t n_frames) override; size_t frame_number(size_t frame_index) override; DetectorType detector_type() const override; /** * @brief Read a single frame from the file into the given buffer. * @param image_buf buffer to read the frame into. (Note the caller is * responsible for allocating the buffer) * @param header pointer to a JungfrauDataHeader or nullptr to skip header) */ void read_into(std::byte *image_buf, JungfrauDataHeader *header = nullptr); /** * @brief Read a multiple frames from the file into the given buffer. * @param image_buf buffer to read the frame into. (Note the caller is * responsible for allocating the buffer) * @param n_frames number of frames to read * @param header pointer to a JungfrauDataHeader or nullptr to skip header) */ void read_into(std::byte *image_buf, size_t n_frames, JungfrauDataHeader *header = nullptr); /** * @brief Read a single frame from the file into the given NDArray * @param image NDArray to read the frame into. */ void read_into(NDArray *image, JungfrauDataHeader *header = nullptr); JungfrauDataHeader read_header(); std::filesystem::path current_file() const { return fpath(m_current_file_index + m_offset); } private: /** * @brief Find the size of the frame in the file. (256x256, 256x1024, * 512x1024) * @param fname path to the file * @throws std::runtime_error if the file is empty or the size cannot be * determined */ void find_frame_size(const std::filesystem::path &fname); void parse_fname(const std::filesystem::path &fname); void scan_files(); void open_file(size_t file_index); std::filesystem::path fpath(size_t frame_index) const; }; } // namespace aare