ESTIA#
[1]:
import scipp as sc
import tof
import scippnexus as snx
from ess.reduce.unwrap import GenericUnwrapWorkflow
from ess.reduce.nexus.types import *
from ess.reduce.unwrap.types import *
from ess.reduce.unwrap.lut import LtotalRange, ChopperFrameSequence
Chopper parameters#
[2]:
min_wavelength = sc.scalar(3.75, unit="angstrom")
chopper_position = sc.scalar(10.895, unit="m")
max_velocity = (sc.constants.h / sc.constants.m_n / min_wavelength).to(unit="m/s")
delay = chopper_position / max_velocity
pulse_stride = 1
frequency = -sc.scalar(14.0, unit="Hz") / pulse_stride
estia_choppers = {
"fc": DiskChopper(
frequency=frequency,
beam_position=sc.scalar(0.0, unit="deg"),
phase=delay * frequency * sc.scalar(360, unit="deg"),
axle_position=sc.vector(
value=[0, 0.0, chopper_position.value], unit=chopper_position.unit
),
slit_begin=sc.array(
dims=["cutout"],
values=[0.0],
unit="deg",
),
slit_end=sc.array(
dims=["cutout"],
values=[98.0],
unit="deg",
),
),
}
[3]:
estia_choppers["fc"]
[3]:
- axle_positionscippVariable()vector3m[ 0. 0. 10.895]
- frequencyscippVariable()float64Hz-14.0
- beam_positionscippVariable()float64deg0.0
- phasescippVariable()float64deg-52.05099341448456
- slit_beginscippVariable(cutout: 1)float64deg0.0
- slit_endscippVariable(cutout: 1)float64deg98.0
- slit_heightNoneType()None
- radiusNoneType()None
Tof model#
[4]:
source = tof.Source(facility="ess", neutrons=1_000_000, pulses=2)
source_position = sc.vector([0, 0, 0], unit="m")
detector = tof.Detector(distance=sc.scalar(45.0, unit="m"), name="detector")
params = [
tof.Chopper.from_diskchopper(ch, name=key) for key, ch in estia_choppers.items()
] + [detector]
model = tof.Model(source=source, components=params)
res = model.run()
res.plot()
[4]:
Plot(ax=<Axes: xlabel='Time [μs]', ylabel='Distance [m]'>, fig=<Figure size 1200x480 with 2 Axes>)
[5]:
res["detector"].plot()
[5]:
Wavelength lookup table#
[6]:
wf = GenericUnwrapWorkflow(
run_types=[SampleRun], monitor_types=[], wavelength_from="analytical"
)
wf[DiskChoppers[SampleRun]] = estia_choppers
wf[LtotalRange[SampleRun, snx.NXdetector]] = sc.scalar(5, unit="m"), detector.distance
wf[Position[snx.NXsource, SampleRun]] = source_position
table = wf.compute(LookupTable[SampleRun, snx.NXdetector])
table.plot() + table.array["distance", -1].plot(errorbars="band")
[6]:
[7]:
frames = wf.compute(ChopperFrameSequence[SampleRun])
at_sample = frames.propagate_to(detector.distance)
at_sample.draw()
[7]:
(<Figure size 640x480 with 1 Axes>,
<Axes: title={'center': 'Frame propagation through chopper cascade'}, xlabel='ms', ylabel='Å'>)