Source code for ess.reduce.time_of_flight.simulation

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

import scipp as sc
from scippneutron.chopper import DiskChopper

from .types import SimulationResults


[docs] def simulate_beamline( choppers: Mapping[str, DiskChopper], neutrons: int = 1_000_000, pulses: int = 1, seed: int | None = None, facility: str = 'ess', ) -> SimulationResults: """ Simulate a pulse of neutrons propagating through a chopper cascade using the ``tof`` package (https://tof.readthedocs.io). Parameters ---------- choppers: A dict of DiskChopper objects representing the choppers in the beamline. See https://scipp.github.io/scippneutron/user-guide/chopper/processing-nexus-choppers.html#Build-DiskChopper for more information. neutrons: Number of neutrons to simulate. pulses: Number of pulses to simulate. seed: Seed for the random number generator used in the simulation. facility: Facility where the experiment is performed. """ import tof tof_choppers = [ tof.Chopper( frequency=abs(ch.frequency), direction=tof.AntiClockwise if (ch.frequency.value > 0.0) else tof.Clockwise, open=ch.slit_begin, close=ch.slit_end, phase=abs(ch.phase), distance=ch.axle_position.fields.z, name=name, ) for name, ch in choppers.items() ] source = tof.Source(facility=facility, neutrons=neutrons, pulses=pulses, seed=seed) if not tof_choppers: events = source.data.squeeze().flatten(to='event') return SimulationResults( time_of_arrival=events.coords["time"], speed=events.coords["speed"], wavelength=events.coords["wavelength"], weight=events.data, distance=0.0 * sc.units.m, ) model = tof.Model(source=source, choppers=tof_choppers) results = model.run() # Find name of the furthest chopper in tof_choppers furthest_chopper = max(tof_choppers, key=lambda c: c.distance) events = results[furthest_chopper.name].data.squeeze().flatten(to='event') events = events[ ~(events.masks["blocked_by_others"] | events.masks["blocked_by_me"]) ] return SimulationResults( time_of_arrival=events.coords["toa"], speed=events.coords["speed"], wavelength=events.coords["wavelength"], weight=events.data, distance=furthest_chopper.distance, )