Source code for ewoksscxrd.tasks.tifffiles

import os
import logging
from silx.io import open as silx_open
from ewokscore import Task
from PIL import Image, TiffImagePlugin
from concurrent.futures import ThreadPoolExecutor, as_completed

try:
    import hdf5plugin  # noqa: F401
except ImportError:
    pass

logger = logging.getLogger(__name__)


[docs] def save_tiff_worker(frame, file_path, tiff_info_dict): """Worker to save a single TIFF frame.""" im = Image.fromarray(frame) tif_info = TiffImagePlugin.ImageFileDirectory_v2() for key, value in tiff_info_dict.items(): tif_info[key] = value im.save(file_path, format="TIFF", tiffinfo=tif_info) return file_path
[docs] class TiffFiles( Task, input_names=[ "images", "output", ], optional_input_names=["detector_name"], output_names=["output_path", "images_list"], ): """ Reads an HDF5 file with frames, extracts each individual frame, and saves them as TIFF images in a folder called 'xdi'. The TIFF images will have a key called imageDescription, default is `eiger`, if the detector name is supplied, it will be set accordingly The HDF5 file is assumed to contain a 2D or 3D dataset (n_frames, height, width) at the dataset path "/entry_0000/measurement/data". The output folder `xdi` is created in PROCESSED_DATA/sample/sample_dataset/scan0001. """
[docs] def run(self): args = self.inputs # Getting the dataset name from the input "output" parts = args.output.split(os.sep) pd_idx = parts.index("PROCESSED_DATA") base_name = parts[pd_idx + 2] processed_data_dir = os.path.join(os.path.dirname(args.output), "xdi") os.makedirs(processed_data_dir, exist_ok=True) with silx_open(args.images[0]) as h5file: ds = h5file["/entry_0000/measurement/data"] n_frames = ds.shape[0] tiff_info_dict = { 270: ( f"detector={args.detector_name}" if args.detector_name else "detector=eiger" ) } # Use ThreadPoolExecutor for parallel TIFF writing saved_files = [] with ThreadPoolExecutor() as executor: futures = [] for i in range(n_frames): frame = ds[i] tiff_file_name = f"{base_name}_{i:04d}.tif" file_path = os.path.join(processed_data_dir, tiff_file_name) futures.append( executor.submit( save_tiff_worker, frame, file_path, tiff_info_dict ) ) for fut in as_completed(futures): saved_files.append(fut.result()) # Sort the files in order (as_completed is unordered) saved_files.sort() self.outputs.output_path = processed_data_dir self.outputs.images_list = saved_files