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

This notebook shows how to create a time-of-flight lookup table for frame unwrapping at BIFROST.

[1]:
from ess.reduce import nexus
import sciline
import scipp as sc
from scippneutron.conversion.graph import beamline as beamline_graph
import scippnexus as snx
from ess.reduce.nexus.types import RawChoppers, DiskChoppers
from ess.reduce.time_of_flight.lut import (
    LtotalRange,
    NumberOfSimulatedNeutrons,
    SourcePosition,
    TofLookupTableWorkflow,
)
from scippneutron.chopper import DiskChopper

from ess.bifrost import BifrostSimulationWorkflow
from ess.bifrost.data import simulated_elastic_incoherent_with_phonon
from ess.spectroscopy.types import *

Load and process beamline parameters#

First, load all required beamline parameters from an input NeXus file. We only need to know the geometry up to the sample which is the same for all banks, so choosing a single detector is enough.

[2]:
input_filename = simulated_elastic_incoherent_with_phonon()
with snx.File(input_filename) as f:
    detector_names = list(f['entry/instrument'][snx.NXdetector])
[3]:
bifrost_workflow = BifrostSimulationWorkflow(detector_names)
bifrost_workflow[Filename[SampleRun]] = input_filename

M = nexus.types.CalibratedMonitor[SampleRun, FrameMonitor3]
C = RawChoppers[SampleRun]
choppers, monitor = bifrost_workflow.compute((C, M)).values()
beamline = sciline.compute_mapped(bifrost_workflow, BeamlineWithSpectrometerCoords[SampleRun])[0]

Compute the required distance range to include the monitor and all detectors. Strictly speaking, we only need the range from the chosen monitor up to the Bragg peak monitor as we unwrap the regular detector data at the sample position. But this implementation is simpler and should work fine.

[4]:
l_monitor = sc.norm(monitor.coords['source_position'] - monitor.coords['position'])
l_min = l_monitor
l_max = beamline.transform_coords('Ltotal', graph=beamline_graph.beamline(scatter=True)).coords['Ltotal'].max()

The choppers in the simulated file need to be processed before they can be used for computing a lookup table. The following works for the specific simulation but is not usable in general.

[5]:
def extract_chopper_plateau(chopper):
    processed = chopper.copy()
    # These are constant in the simulated data.
    processed['rotation_speed'] = processed['rotation_speed'].data.mean()
    processed['phase'] = processed['phase'].data.mean()
    # Guessing here as this is not stored in the file.
    processed['beam_position'] = sc.scalar(0.0, unit='deg')
    return DiskChopper.from_nexus(processed)


disk_choppers = choppers.apply(extract_chopper_plateau)

Compute the lookup table#

Construct a lookup table workflow:

[6]:
workflow = TofLookupTableWorkflow()
workflow[DiskChoppers] = disk_choppers
workflow[LtotalRange] = (l_min, l_max)
workflow[SourcePosition] = beamline.coords['source_position']

# Increase this number for more reliable results:
workflow[NumberOfSimulatedNeutrons] = 600_000
[7]:
workflow.visualize(TimeOfFlightLookupTable, graph_attr={"rankdir": "LR"})
[7]:
../../_images/user-guide_bifrost_bifrost-make-tof-lookup-table_12_0.svg

Compute a lookup table:

[8]:
table = workflow.compute(TimeOfFlightLookupTable)
table
[8]:
Show/Hide data repr Show/Hide attributes
scipp.DataArray (107.98 KB)
    • distance: 23
    • event_time_offset: 287
    • distance
      (distance)
      float64
      m
      161.200, 161.300, ..., 163.300, 163.400
      Values:
      array([161.19961458, 161.29961458, 161.39961458, 161.49961458, 161.59961458, 161.69961458, 161.79961458, 161.89961458, 161.99961458, 162.09961458, 162.19961458, 162.29961458, 162.39961458, 162.49961458, 162.59961458, 162.69961458, 162.79961458, 162.89961458, 162.99961458, 163.09961458, 163.19961458, 163.29961458, 163.39961458])
    • distance_resolution
      ()
      float64
      m
      0.09999999999999432
      Values:
      array(0.1)
    • error_threshold
      ()
      float64
      𝟙
      0.1
      Values:
      array(0.1)
    • event_time_offset
      (event_time_offset)
      float64
      µs
      0.0, 249.750, ..., 7.118e+04, 7.143e+04
      Values:
      array([ 0. , 249.75024975, 499.5004995 , 749.25074925, 999.000999 , 1248.75124875, 1498.5014985 , 1748.25174825, 1998.001998 , 2247.75224775, 2497.5024975 , 2747.25274725, 2997.002997 , 3246.75324675, 3496.5034965 , 3746.25374625, 3996.003996 , 4245.75424575, 4495.5044955 , 4745.25474525, 4995.004995 , 5244.75524476, 5494.50549451, 5744.25574426, 5994.00599401, 6243.75624376, 6493.50649351, 6743.25674326, 6993.00699301, 7242.75724276, 7492.50749251, 7742.25774226, 7992.00799201, 8241.75824176, 8491.50849151, 8741.25874126, 8991.00899101, 9240.75924076, 9490.50949051, 9740.25974026, 9990.00999001, 10239.76023976, 10489.51048951, 10739.26073926, 10989.01098901, 11238.76123876, 11488.51148851, 11738.26173826, 11988.01198801, 12237.76223776, 12487.51248751, 12737.26273726, 12987.01298701, 13236.76323676, 13486.51348651, 13736.26373626, 13986.01398601, 14235.76423576, 14485.51448551, 14735.26473526, 14985.01498501, 15234.76523477, 15484.51548452, 15734.26573427, 15984.01598402, 16233.76623377, 16483.51648352, 16733.26673327, 16983.01698302, 17232.76723277, 17482.51748252, 17732.26773227, 17982.01798202, 18231.76823177, 18481.51848152, 18731.26873127, 18981.01898102, 19230.76923077, 19480.51948052, 19730.26973027, 19980.01998002, 20229.77022977, 20479.52047952, 20729.27072927, 20979.02097902, 21228.77122877, 21478.52147852, 21728.27172827, 21978.02197802, 22227.77222777, 22477.52247752, 22727.27272727, 22977.02297702, 23226.77322677, 23476.52347652, 23726.27372627, 23976.02397602, 24225.77422577, 24475.52447552, 24725.27472527, 24975.02497502, 25224.77522478, 25474.52547453, 25724.27572428, 25974.02597403, 26223.77622378, 26473.52647353, 26723.27672328, 26973.02697303, 27222.77722278, 27472.52747253, 27722.27772228, 27972.02797203, 28221.77822178, 28471.52847153, 28721.27872128, 28971.02897103, 29220.77922078, 29470.52947053, 29720.27972028, 29970.02997003, 30219.78021978, 30469.53046953, 30719.28071928, 30969.03096903, 31218.78121878, 31468.53146853, 31718.28171828, 31968.03196803, 32217.78221778, 32467.53246753, 32717.28271728, 32967.03296703, 33216.78321678, 33466.53346653, 33716.28371628, 33966.03396603, 34215.78421578, 34465.53446553, 34715.28471528, 34965.03496503, 35214.78521479, 35464.53546454, 35714.28571429, 35964.03596404, 36213.78621379, 36463.53646354, 36713.28671329, 36963.03696304, 37212.78721279, 37462.53746254, 37712.28771229, 37962.03796204, 38211.78821179, 38461.53846154, 38711.28871129, 38961.03896104, 39210.78921079, 39460.53946054, 39710.28971029, 39960.03996004, 40209.79020979, 40459.54045954, 40709.29070929, 40959.04095904, 41208.79120879, 41458.54145854, 41708.29170829, 41958.04195804, 42207.79220779, 42457.54245754, 42707.29270729, 42957.04295704, 43206.79320679, 43456.54345654, 43706.29370629, 43956.04395604, 44205.79420579, 44455.54445554, 44705.29470529, 44955.04495504, 45204.7952048 , 45454.54545455, 45704.2957043 , 45954.04595405, 46203.7962038 , 46453.54645355, 46703.2967033 , 46953.04695305, 47202.7972028 , 47452.54745255, 47702.2977023 , 47952.04795205, 48201.7982018 , 48451.54845155, 48701.2987013 , 48951.04895105, 49200.7992008 , 49450.54945055, 49700.2997003 , 49950.04995005, 50199.8001998 , 50449.55044955, 50699.3006993 , 50949.05094905, 51198.8011988 , 51448.55144855, 51698.3016983 , 51948.05194805, 52197.8021978 , 52447.55244755, 52697.3026973 , 52947.05294705, 53196.8031968 , 53446.55344655, 53696.3036963 , 53946.05394605, 54195.8041958 , 54445.55444555, 54695.3046953 , 54945.05494505, 55194.80519481, 55444.55544456, 55694.30569431, 55944.05594406, 56193.80619381, 56443.55644356, 56693.30669331, 56943.05694306, 57192.80719281, 57442.55744256, 57692.30769231, 57942.05794206, 58191.80819181, 58441.55844156, 58691.30869131, 58941.05894106, 59190.80919081, 59440.55944056, 59690.30969031, 59940.05994006, 60189.81018981, 60439.56043956, 60689.31068931, 60939.06093906, 61188.81118881, 61438.56143856, 61688.31168831, 61938.06193806, 62187.81218781, 62437.56243756, 62687.31268731, 62937.06293706, 63186.81318681, 63436.56343656, 63686.31368631, 63936.06393606, 64185.81418581, 64435.56443556, 64685.31468531, 64935.06493506, 65184.81518482, 65434.56543457, 65684.31568432, 65934.06593407, 66183.81618382, 66433.56643357, 66683.31668332, 66933.06693307, 67182.81718282, 67432.56743257, 67682.31768232, 67932.06793207, 68181.81818182, 68431.56843157, 68681.31868132, 68931.06893107, 69180.81918082, 69430.56943057, 69680.31968032, 69930.06993007, 70179.82017982, 70429.57042957, 70679.32067932, 70929.07092907, 71178.82117882, 71428.57142857])
    • pulse_period
      ()
      float64
      µs
      71428.57142857142
      Values:
      array(71428.57142857)
    • pulse_stride
      ()
      int64
      1
      Values:
      array(1)
    • time_resolution
      ()
      float64
      µs
      249.7502497502497
      Values:
      array(249.75024975)
    • (distance, event_time_offset)
      float64
      µs
      2.133e+05, 2.136e+05, ..., 2.130e+05, 2.132e+05
      σ = 107.934, 95.979, ..., 102.876, 91.752
      Values:
      array([[213341.6864886 , 213636.64025433, 213849.59353037, ..., 212828.40335417, 213049.88286867, 213341.6864886 ], [213325.71687959, 213648.54907211, 213860.55919535, ..., 212775.52065651, 213069.66758465, 213325.71687959], [213296.61515133, 213601.65351687, 213894.96704068, ..., 212782.48336924, 213074.23918631, 213296.61515133], ..., [213198.87197696, 213555.78455175, 213744.88618416, ..., 212690.8410454 , 212935.51748802, 213198.87197696], [213273.44312467, 213506.7430191 , 213763.56418778, ..., 212709.27473465, 212969.32061073, 213273.44312467], [213177.82308826, 213449.33390375, 213804.65301013, ..., 212672.6966706 , 212951.49220145, 213177.82308826]], shape=(23, 287))

      Variances (σ²):
      array([[11649.7373125 , 9211.87909639, 14070.33966637, ..., 12108.57094422, 11477.31467435, 11649.7373125 ], [ 9346.66671161, 16715.87548133, 12522.68920955, ..., 17856.14319789, 5858.8177213 , 9346.66671161], [ 9813.90961975, 11519.01054855, 9457.87137764, ..., 2930.59474672, 13377.87242274, 9813.90961975], ..., [12670.86036693, 10225.15996723, 8614.88065459, ..., 10557.55277072, 12306.46826711, 12670.86036693], [10090.41511923, 17989.8804586 , 11109.69537392, ..., 14927.02470821, 10756.46437128, 10090.41511923], [ 8418.50695141, 10473.64276991, 11978.01051458, ..., 11533.12144481, 10583.44504234, 8418.50695141]], shape=(23, 287))
[9]:
table.plot()
[9]:
../../_images/user-guide_bifrost_bifrost-make-tof-lookup-table_15_0.svg

Save to file#

[10]:
table.save_hdf5('BIFROST-simulation-tof-lookup-table.h5')