Not yet compiled or tested: work stopped after the feasibility study. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
51 lines
2.5 KiB
C++
51 lines
2.5 KiB
C++
// SPDX-FileCopyrightText: 2026 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
|
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
|
|
#pragma once
|
|
|
|
#include <cstdint>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
// The LCLS-I XTC container, as far as reading camera frames out of it needs: what the LCLS data
|
|
// system (pdsdata) wrote at LCLS until 2023, and what serial-crystallography depositions from that
|
|
// era (Rayonix at MFX and XPP) are archived as.
|
|
//
|
|
// A file is a sequence of datagrams. Each is a 40-byte header - the event's clock time and timestamp
|
|
// (16 bytes, whose top bits name the transition: Configure, BeginRun, ..., L1Accept for an event),
|
|
// an environment word, and the outermost Xtc header - followed by the Xtc's payload. An Xtc header is
|
|
// five 32-bit words: damage, the source (two words), the type and version, and the extent, which
|
|
// counts the header itself. A container (type Id_Xtc) holds further Xtcs one after another; anything
|
|
// else is a leaf holding one data object. A camera image is a leaf of type Id_Frame (Camera::FrameV1):
|
|
// width, height, bit depth and offset, 32 bits each, then the pixels row by row. Everything is
|
|
// little-endian and uncompressed.
|
|
//
|
|
// A run is written as several streams (-s00, -s01, ...) by different recorders, each holding a
|
|
// share of the events. Their order across streams is the event time, which this reader does not
|
|
// reconstruct: stills are independent, so the streams are read one after another.
|
|
namespace xtc {
|
|
|
|
// One camera image: where its pixels start in which file.
|
|
struct Frame {
|
|
std::string file;
|
|
uint64_t offset = 0; // of the first pixel
|
|
uint32_t width = 0;
|
|
uint32_t height = 0;
|
|
};
|
|
|
|
// True if the path is an XTC file (or a directory holding one) - by its first datagram, not its name.
|
|
bool CanRead(const std::string &path);
|
|
|
|
// The event streams of the path: the file itself, or every XTC file in a directory, by name. The
|
|
// "smalldata" copies (.smd.xtc) carry the events without their images and are left out.
|
|
std::vector<std::string> CollectStreams(const std::string &path);
|
|
|
|
// Every L1Accept of the file that holds a 16-bit camera image, in file order. Where an event holds
|
|
// images from more than one camera, the largest is taken - the diffraction detector.
|
|
std::vector<Frame> IndexFrames(const std::string &file);
|
|
|
|
// Reads one image as 32-bit pixels into out (width*height values), through scratch.
|
|
void ReadFrame(const Frame &frame, int32_t *out, std::vector<uint8_t> &scratch);
|
|
|
|
} // namespace xtc
|