Source code for ess.bifrost.io.mcstas

# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) 2025 Scipp contributors (https://github.com/scipp)

"""McStas input for BIFROST."""

import scipp as sc
import scippnexus as snx

from ess.spectroscopy.types import (
    BeamlineWithSpectrometerCoords,
    DetectorData,
    NeXusData,
    PulsePeriod,
    RunType,
)

from ..types import McStasDetectorData


[docs] def assemble_detector_data( detector: BeamlineWithSpectrometerCoords[RunType], event_data: NeXusData[snx.NXdetector, RunType], ) -> McStasDetectorData[RunType]: """Custom assemble function that returns McStasDetectorData.""" from ess.reduce.nexus.workflow import assemble_detector_data as reduce_assemble return McStasDetectorData[RunType](reduce_assemble(detector, event_data))
[docs] def convert_simulated_time_to_event_time_offset( mcstas_data: McStasDetectorData[RunType], pulse_period: PulsePeriod, ) -> DetectorData[RunType]: """Helper to make McStas simulated event data look more like real data McStas has the ability to track the time-of-flight from source to detector for every probabilistic neutron ray. This is very helpful, but unfortunately real instrument at ESS are not able to record the same information due to how the timing and data collection systems work. Real neutron events will record their event_time_zero most-recent-pulse reference time, and their event_time_offset detection time relative to that reference time. These two values added together give a real wall time; and information about the primary spectrometer is necessary to find any time-of-flight This function takes event data with per-event coordinate event_time_offset (actually McStas time-of-arrival) and converts the coordinate to be the time-of-arrival modulo the source repetition period. Notes ----- If the input data has realistic event_time_offset values, this function should be a noop. Returns ------- : A copy of the data with realistic per-event coordinate event_time_offset. """ def wrap_event_time_offset(event_time_offset: sc.Variable) -> sc.Variable: return event_time_offset % pulse_period.to(unit=event_time_offset.unit) res = mcstas_data.transform_coords( frame_time=wrap_event_time_offset, rename_dims=False, keep_intermediate=False, keep_inputs=False, ) return DetectorData[RunType]( res.transform_coords(event_time_offset='frame_time', keep_inputs=False) )
providers = ( assemble_detector_data, convert_simulated_time_to_event_time_offset, )