Create a time-of-flight lookup table for ODIN#

[1]:
import scipp as sc
from ess.reduce import time_of_flight
from ess.reduce.nexus.types import AnyRun
from ess.odin.beamline import choppers

Setting up the workflow#

[2]:
source_position = sc.vector([0, 0, 0], unit='m')
disk_choppers = choppers(source_position)

wf = time_of_flight.TofLookupTableWorkflow()
wf[time_of_flight.DiskChoppers[AnyRun]] = disk_choppers
wf[time_of_flight.SourcePosition] = source_position
wf[time_of_flight.NumberOfSimulatedNeutrons] = 200_000  # Increase this number for more reliable results
wf[time_of_flight.SimulationSeed] = 1234
wf[time_of_flight.PulseStride] = 2
wf[time_of_flight.LtotalRange] = sc.scalar(55.0, unit="m"), sc.scalar(65.0, unit="m")
wf[time_of_flight.DistanceResolution] = sc.scalar(0.1, unit="m")
wf[time_of_flight.TimeResolution] = sc.scalar(250.0, unit='us')
wf[time_of_flight.LookupTableRelativeErrorThreshold] = 0.02

Compute the table#

[3]:
table = wf.compute(time_of_flight.TimeOfFlightLookupTable)
table
Downloading file 'ess/ess.h5' from 'https://github.com/scipp/tof-sources/raw/refs/heads/main/1/ess/ess.h5' to '/home/runner/.cache/tof'.
[3]:
TofLookupTable(array=<scipp.DataArray>
Dimensions: Sizes[distance:105, event_time_offset:573, ]
Coordinates:
* distance                  float64              [m]  (distance)  [54.8, 54.9, ..., 65.1, 65.2]
* event_time_offset         float64            [µs]  (event_time_offset)  [0, 249.75, ..., 142607, 142857]
Data:
                            float64            [µs]  (distance, event_time_offset)  [-nan, -nan, ..., 140620, 141146]  [-nan, -nan, ..., 36957.4, 76124.2]

, pulse_period=<scipp.Variable> ()    float64            [µs]  71428.6, pulse_stride=2, distance_resolution=<scipp.Variable> ()    float64              [m]  0.1, time_resolution=<scipp.Variable> ()    float64            [µs]  249.75, choppers=DataGroup(sizes={'cutout': None}, keys=[
    WFMC_1: DataGroup(8, {'cutout': 6}),
    WFMC_2: DataGroup(8, {'cutout': 6}),
    FOC_1: DataGroup(8, {'cutout': 6}),
    BP_1: DataGroup(8, {'cutout': 1}),
    FOC_2: DataGroup(8, {'cutout': 6}),
    BP_2: DataGroup(8, {'cutout': 1}),
    T0_alpha: DataGroup(8, {'cutout': 1}),
    T0_beta: DataGroup(8, {'cutout': 1}),
    FOC_3: DataGroup(8, {'cutout': 6}),
    FOC_4: DataGroup(8, {'cutout': 6}),
    FOC_5: DataGroup(8, {'cutout': 6}),
]))
[4]:
table.plot()
[4]:
../_images/odin_odin-make-tof-lookup-table_6_0.svg

Save to file#

[5]:
# Save chopper metadata
table.choppers = sc.DataGroup(disk_choppers)
# Write to file
table.save_hdf5('ODIN-tof-lookup-table.h5')
Writing type '<class 'scippneutron.chopper.disk_chopper.DiskChopper'>' to HDF5 not implemented, skipping.
Writing type '<class 'scippneutron.chopper.disk_chopper.DiskChopper'>' to HDF5 not implemented, skipping.
Writing type '<class 'scippneutron.chopper.disk_chopper.DiskChopper'>' to HDF5 not implemented, skipping.
Writing type '<class 'scippneutron.chopper.disk_chopper.DiskChopper'>' to HDF5 not implemented, skipping.
Writing type '<class 'scippneutron.chopper.disk_chopper.DiskChopper'>' to HDF5 not implemented, skipping.
Writing type '<class 'scippneutron.chopper.disk_chopper.DiskChopper'>' to HDF5 not implemented, skipping.
Writing type '<class 'scippneutron.chopper.disk_chopper.DiskChopper'>' to HDF5 not implemented, skipping.
Writing type '<class 'scippneutron.chopper.disk_chopper.DiskChopper'>' to HDF5 not implemented, skipping.
Writing type '<class 'scippneutron.chopper.disk_chopper.DiskChopper'>' to HDF5 not implemented, skipping.
Writing type '<class 'scippneutron.chopper.disk_chopper.DiskChopper'>' to HDF5 not implemented, skipping.
Writing type '<class 'scippneutron.chopper.disk_chopper.DiskChopper'>' to HDF5 not implemented, skipping.