Source code for ess.estia.load

# Copyright (c) 2025 Scipp contributors (https://github.com/scipp)
import h5py
import scipp as sc

from ..reflectometry.types import (
    Filename,
    RawDetectorData,
    RunType,
)
from .mcstas import parse_events_ascii, parse_events_h5


[docs] def load_mcstas_events( filename: Filename[RunType], ) -> RawDetectorData[RunType]: """ Load event data from a McStas run and reshape it to look like what we would expect if we loaded data from a real experiment file. """ if h5py.is_hdf5(filename): with h5py.File(filename) as f: da = parse_events_h5(f) else: with open(filename) as f: da = parse_events_ascii(f) da.coords['sample_rotation'] = sc.scalar( float(da.coords['omegaa'].value), unit='deg' ) da.coords['detector_rotation'] = 2 * da.coords['sample_rotation'] + sc.scalar( 1.65, unit='deg' ) xbins = sc.linspace('x', -0.25, 0.25, 14 * 32 + 1) ybins = sc.linspace('y', -0.25, 0.25, 65) da = da.bin(x=xbins, y=ybins).rename_dims({'y': 'stripe'}) da.coords['stripe'] = sc.arange('stripe', 0, 64) da.coords['z_index'] = sc.arange('x', 14 * 32 - 1, -1, -1) # Information is not available in the mcstas output files, therefore it's hardcoded da.coords['sample_position'] = sc.vector([0.264298, -0.427595, 35.0512], unit='m') da.coords['source_position'] = sc.vector([0, 0, 0.0], unit='m') da.coords['detector_position'] = sc.vector( tuple(map(float, da.coords['position'].value.split(' '))), unit='m' ) rotation_by_detector_rotation = sc.spatial.rotation( value=[ sc.scalar(0.0), sc.sin(da.coords['detector_rotation'].to(unit='rad')), sc.scalar(0.0), sc.cos(da.coords['detector_rotation'].to(unit='rad')), ] ) position = sc.spatial.as_vectors( x=sc.midpoints(da.coords['x']) * sc.scalar(1.0, unit='m'), y=sc.midpoints(da.coords['y']) * sc.scalar(1.0, unit='m'), z=sc.scalar(0.0, unit='m'), ) da.coords['position'] = ( da.coords['detector_position'] + rotation_by_detector_rotation * position ) da.bins.coords['event_time_zero'] = ( sc.scalar(0, unit='s') * da.bins.coords['t'] ).to(unit='ns') da.bins.coords['event_time_offset'] = ( sc.scalar(1, unit='s') * da.bins.coords['t'] ).to(unit='ns') % sc.scalar(1 / 14, unit='s').to(unit='ns') da.bins.coords['wavelength'] = sc.scalar(1, unit='angstrom') * da.bins.coords['L'] da.coords["sample_size"] = sc.scalar(1.0, unit='m') * float( da.coords['sample_length'].value ) da.coords["beam_size"] = sc.scalar(2.0, unit='mm') da = da.fold('x', sizes={'blade': 14, 'wire': 32}) da.bins.coords.pop('L') da.bins.coords.pop('t') return RawDetectorData[RunType](da)
providers = ()