Files
Jungfraujoch/reader/HDF5ImageLocator.h
T
leonarski_f 84228bf8be
Build Packages / Create release (push) Successful in 24s
Build Packages / build:viewer:macos-arm64:nocuda (push) Successful in 3m29s
Build Packages / build:rugnux:macos-arm64:nocuda (push) Successful in 2m43s
Build Packages / build:rugnux:linux-aarch64:cuda (push) Successful in 8m27s
Build Packages / build:rugnux:linux-x86_64:cuda (push) Successful in 9m53s
Build Packages / build:viewer:linux-x86_64:nocuda (push) Successful in 9m58s
Build Packages / build:viewer:linux-x86_64:cuda (push) Successful in 11m22s
Build Packages / build:jfjoch:rocky8:nocuda (push) Successful in 13m39s
Build Packages / build:viewer:windows-x86_64:nocuda (push) Successful in 18m37s
Build Packages / build:jfjoch:rocky9:nocuda (push) Successful in 16m32s
Build Packages / build:viewer:windows-x86_64:cuda (push) Successful in 24m11s
Build Packages / HDF5 consumer tests (DIALS, XDS) (push) Successful in 25m30s
Build Packages / build:jfjoch:ubuntu2404:nocuda (push) Successful in 19m3s
Build Packages / build:jfjoch:ubuntu2204:nocuda (push) Successful in 20m23s
Build Packages / build:jfjoch:rocky8:cuda-sls9 (push) Successful in 19m41s
Build Packages / Generate python client (push) Successful in 50s
Build Packages / Build documentation (push) Successful in 1m16s
Build Packages / build:jfjoch:rocky9:cuda-sls9 (push) Successful in 21m0s
Build Packages / build:jfjoch:rocky8:cuda (push) Successful in 18m38s
Build Packages / build:rugnux:windows-x86_64:cuda (push) Successful in 14m33s
Build Packages / build:jfjoch:rocky9:cuda (push) Successful in 17m55s
Build Packages / build:jfjoch:ubuntu2204:cuda (push) Successful in 20m50s
Build Packages / build:jfjoch:ubuntu2404:cuda (push) Successful in 18m38s
Build Packages / Unit tests (push) Successful in 1h46m14s
v1.0.0-rc.173 (#83)
* jfjoch_broker: Optional per-dataset authentication - statistics, images and plots can require a bearer token, which jfjoch_viewer supports.
* jfjoch_viewer: Dark mode and a theme-matched colour scheme, a magnifier panel, and simpler contrast and background controls.
* Rugnux: Multiple performance improvements on GPU and CPU (CPU-only processing up to 40% faster, faster image decoding on ARM), with unchanged results.
* Rugnux: `--model` rigid-body refinement runs on the GPU, and the model-validation check is faster and more reliable.
* Rugnux: Improved scaling and merging - error model, outlier rejection, absorption correction and French-Wilson amplitudes now agree more closely with XDS and ctruncate.
* Rugnux: Improved integration - radial background on powder and ice rings, crowded rotation data keep their reflections, and CPU-only builds integrate large unit cells as GPU builds do.
* Rugnux: More robust detector geometry - measured beam centre, X-ray bandwidth and goniometer rate, and geometry refinement accepted only on significant evidence.
* Rugnux: Merged files are written in the standard setting, or in the setting of a reference MTZ, structure-factor mmCIF or model, with its free-R flags.
* Rugnux: Richer report - ice and powder rings, further lattices, superstructure candidates and mosaicity, with warnings worded as prompts to check.
* Rugnux: Clear error messages when a data set needs more GPU or host memory than is available.

Reviewed-on: #83
Co-authored-by: Filip Leonarski <filip.leonarski@psi.ch>
2026-09-29 15:57:32 +02:00

83 lines
4.1 KiB
C++

// SPDX-FileCopyrightText: 2026 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
// SPDX-License-Identifier: GPL-3.0-only
#pragma once
#include <map>
#include <memory>
#include <optional>
#include <string>
#include <vector>
#include "../writer/HDF5Objects.h" // HDF5ReadOnlyFile, HDF5VirtualDatasetMapping, HDF5DataSetLayout
#include "../common/JFJochMessages.h" // FileWriterFormat, HDF5DataSourceMessage
// Turns a global image number into the HDF5 file + local index that physically holds its pixels,
// for all three on-disk layouts (legacy linked data files, VDS, contiguous/integrated). This is
// the part of the reader whose "links to files stay" constant: it knows where the raw images
// live, independent of which master file the per-image metadata is read from.
//
// Open data-file handles are cached, so scanning many images (e.g. reprocessing) does not reopen
// the same file on every read. HDF5 is not thread-safe, so every call must be made with the
// global hdf5_mutex held by the caller; the locator does no locking of its own.
class HDF5ImageLocator {
public:
struct Location {
std::shared_ptr<HDF5ReadOnlyFile> file;
uint32_t local_index = 0;
// Path the file was opened from. Needed to open it a second time as a plain file, for the
// positional reads HDF5ImageSource does outside the mutex.
std::string path;
// Where the images sit INSIDE that file. /entry/data/data everywhere DECTRIS writes, but a
// VDS names its source dataset and is free to name another one, so take it at its word.
std::string dataset = "/entry/data/data";
// Channel to read when the dataset is 4D, [image, channel, y, x], as the DECTRIS "hdf5 nexus
// v2024.2 nxmx" format writes it (one channel per threshold). Only the first channel of the
// master is read.
hsize_t channel = 0;
};
// One data file of a legacy multi-file dataset, with the dataset the master's link names
// inside it - the same "take the link at its word" the VDS branch already does.
struct LegacyFile {
std::string path;
std::string dataset;
};
// Layout description, filled by the reader once the master file has been parsed. All paths
// are absolute: legacy data files and VDS mapping filenames are resolved relative to the
// master before being handed over, so the locator never deals with relative paths.
struct Layout {
FileWriterFormat format = FileWriterFormat::NoFile;
HDF5DataSetLayout data_layout = HDF5DataSetLayout::CONTIGUOUS;
std::shared_ptr<HDF5ReadOnlyFile> master_file;
std::string master_filename;
std::vector<LegacyFile> legacy_files;
size_t images_per_file = 1;
std::vector<HDF5VirtualDatasetMapping> vds_mappings;
};
void Configure(Layout layout);
void Clear();
// Resolve a global image number to {file, local index}. Throws if the image is not covered
// by the layout. Does not bounds-check against the total image count - the caller does that.
Location Resolve(int64_t global_image) const;
// Source mapping for re-writing a derived file (e.g. _process.h5) so it links back to the
// original pixel sources rather than to a master. total_images is supplied by the caller.
// stride is the step between consecutive images of the derived file in the SOURCE: image i of the
// output comes from source image first_image + i * stride. It has to match the stride the caller
// processed with, or the pictures and the per-image analysis in the derived file describe
// different frames.
std::vector<HDF5DataSourceMessage> GetSourceMapping(uint64_t first_image,
std::optional<uint64_t> image_count,
uint64_t total_images,
uint64_t stride = 1) const;
private:
Layout layout_;
mutable std::map<std::string, std::shared_ptr<HDF5ReadOnlyFile> > file_cache_;
std::shared_ptr<HDF5ReadOnlyFile> OpenCached(const std::string &path) const;
};