Files
Jungfraujoch/reader/JFJochMultiReader.h
T
leonarski_fandClaude Opus 5.5 6557ba87f4 rugnux: several stills inputs in one run; inputs are files, never a directory
Every input is a file named on the command line, read in the order given (a shell glob gives them
sorted by name); a directory is refused with the glob form to use instead.

- Several Jungfraujoch/NXmx masters of stills are read as one run (JFJochMultiReader): their images
  one after another, the pixel masks combined, the per-image efficiency placed at each input's
  images. They must share the detector, wavelength (0.1%), distance (0.1 mm) and beam centre (1 px),
  since stills geometry refinement refines one geometry for all frames; rotation sweeps are refused.
  The log gives the indexing rate of each input beside the run's (ProcessResult::image_indexed).
- SACLA HDF5 / CXI (JFJochCrystFELReader::ReadFiles, ReadCXI, Open) and XTC
  (JFJochXTCReader::ReadFiles) take the list of files instead of scanning a directory;
  CanReadCXI and xtc::CanRead accept only a file; ListFiles and xtc::CollectStreams are gone.
- Several inputs must be one format, --mode mx, and stored files (no broker, no --simulate-live);
  one frame of a CBF/marCCD/SMV sweep still names the whole sweep.

Validated: two Jungfraujoch lysozyme stills runs together (49,920 frames, known cell) 57.1% indexed (59.3% /
54.9% per run), 1.22 A, CC1/2 0.986, R_split 8.8%, REFMAC R/R-free 0.253/0.269 against 0.257/0.273
for the earlier hand-built combined master. Rotation: 5reo and lyso_x10sa_90deg_1 unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015CeEGgpKdfkCTJb3YNMJcu
2026-10-20 23:30:17 +02:00

47 lines
2.0 KiB
C++

// SPDX-FileCopyrightText: 2026 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
// SPDX-License-Identifier: GPL-3.0-only
#ifndef JFJOCHMULTIREADER_H
#define JFJOCHMULTIREADER_H
#include <memory>
#include <string>
#include <vector>
#include "JFJochReader.h"
// Several stills collections read as one: the images of input 0, then those of input 1, and so on, so
// image i of the whole is image i - FirstImage(k) of the input k it falls in. The inputs must be the
// same detector at the same geometry - one wavelength, distance and beam centre for the whole run, as
// stills geometry refinement refines one for all frames - and the constructor refuses them otherwise.
// The dataset is the first input's, with the pixel masks of all inputs combined and the per-image
// efficiency of each input placed at its images.
class JFJochMultiReader : public JFJochReader {
std::vector<std::unique_ptr<JFJochReader>> inputs;
std::vector<int64_t> first_image; // image 0 of input k is image first_image[k] of the whole
uint64_t number_of_images = 0;
// The input image_number falls in, and its number there.
std::pair<size_t, int64_t> Locate(int64_t image_number) const;
bool LoadImage_i(std::shared_ptr<JFJochReaderDataset> &dataset,
DataMessage &message,
std::vector<uint8_t> &buffer,
int64_t image_number,
bool update_dataset) override;
public:
explicit JFJochMultiReader(std::vector<std::unique_ptr<JFJochReader>> inputs);
[[nodiscard]] uint64_t GetNumberOfImages() const override;
void Close() override;
bool ReadRawImage(int64_t image_number, JFJochReaderRawImage &image) override;
std::vector<SpotToSave> ReadSpots(int64_t image) const override;
[[nodiscard]] size_t GetNumberOfInputs() const;
[[nodiscard]] int64_t FirstImage(size_t input) const;
[[nodiscard]] uint64_t ImagesInInput(size_t input) const;
};
#endif //JFJOCHMULTIREADER_H