Source code for ess.bifrost.cutting

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

"""Cutting BIFROST data."""

from collections.abc import Callable

import scipp as sc

from ess.spectroscopy.types import (
    DataGroupedByRotation,
    DetectorData,
    InstrumentAngle,
    RunType,
    SampleAngle,
)


[docs] def group_by_rotation( data: DetectorData[RunType], sample_angle: SampleAngle[RunType], instrument_angle: InstrumentAngle[RunType], ) -> DataGroupedByRotation[RunType]: """Group data by rotation angles. Parameters ---------- data: Detector events with time coordinates. sample_angle: Sample rotation angle "a3". May be time-dependent (1d array with dim "time") or scalar. instrument_angle: Instrument rotation angle "a4". May be time-dependent (1d array with dim "time") or scalar. Returns ------- : ``data`` grouped by rotation angles "a3" and "a4". """ graph = { 'a3': _make_angle_from_time_calculator(sample_angle), 'a4': _make_angle_from_time_calculator(instrument_angle), } grouped = data.transform_coords(('a3', 'a4'), graph=graph).group('a3', 'a4') return DataGroupedByRotation[RunType](grouped)
def _make_angle_from_time_calculator(angle: sc.DataArray) -> Callable[..., sc.Variable]: if angle.ndim == 0: return lambda: angle.data else: lut = sc.lookup(angle, 'time') return lambda event_time_zero: lut[event_time_zero] providers = (group_by_rotation,)