DREAM#
[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
source = tof.Source(facility="ess", neutrons=1_000_000, pulses=2)
High-flux mode#
Chopper parameters#
[2]:
choppers = {
"psc1": {
"frequency": {"value": 210.0, "unit": "Hz"},
"open": {
"value": [-1.23, 70.49, 84.765, 113.565, 170.29, 271.635, 286.035, 301.17],
"unit": "deg",
},
"close": {
"value": [1.23, 73.51, 88.035, 116.835, 175.31, 275.565, 289.965, 303.63],
"unit": "deg",
},
"distance": {"value": 6.145, "unit": "m"},
"phase": {"value": -155.0, "unit": "deg"},
"type": "chopper",
"direction": "anticlockwise",
"name": "psc1",
},
"psc2": {
"frequency": {"value": 196.0, "unit": "Hz"},
"open": {
"value": [-1.23, 27.0, 55.8, 142.385, 156.765, 214.115, 257.23, 315.49],
"unit": "deg",
},
"close": {
"value": [1.23, 30.6, 59.4, 145.615, 160.035, 217.885, 261.17, 318.11],
"unit": "deg",
},
"distance": {"value": 6.155, "unit": "m"},
"phase": {"value": 100.5, "unit": "deg"},
"type": "chopper",
"direction": "clockwise",
"name": "psc2",
},
"oc": {
"frequency": {"value": 14.0, "unit": "Hz"},
"open": {"value": [-13.8], "unit": "deg"},
"close": {"value": [13.8], "unit": "deg"},
"distance": {"value": 6.174, "unit": "m"},
"phase": {"value": 27.0, "unit": "deg"},
"type": "chopper",
"direction": "anticlockwise",
"name": "oc",
},
"bcc": {
"frequency": {"value": 112.0, "unit": "Hz"},
"open": {"value": [-36.875, 143.125], "unit": "deg"},
"close": {"value": [36.875, 216.875], "unit": "deg"},
"distance": {"value": 9.78, "unit": "m"},
"phase": {"value": 20.0, "unit": "deg"},
"type": "chopper",
"direction": "anticlockwise",
"name": "bcc",
},
"t0": {
"frequency": {"value": 28.0, "unit": "Hz"},
"open": {"value": [-157.45], "unit": "deg"},
"close": {"value": [157.45], "unit": "deg"},
"distance": {"value": 13.05, "unit": "m"},
"phase": {"value": 90.0, "unit": "deg"},
"type": "chopper",
"direction": "anticlockwise",
"name": "t0",
},
}
[3]:
dream_choppers = {}
for key, ch in choppers.items():
dream_choppers[key] = tof.Chopper.from_json(name=key, params=ch).to_diskchopper()
for key, ch in dream_choppers.items():
print(key)
display(ch)
psc1
- axle_positionscippVariable()vector3m[0. 0. 6.145]
- frequencyscippVariable()float64Hz210.0
- beam_positionscippVariable()float64deg0.0
- phasescippVariable()float64deg-155.0
- slit_beginscippVariable(cutout: 8)float64deg-1.23, 70.49, ..., 286.035, 301.170
- slit_endscippVariable(cutout: 8)float64deg1.23, 73.51, ..., 289.965, 303.630
- slit_heightNoneType()None
- radiusNoneType()None
psc2
- axle_positionscippVariable()vector3m[0. 0. 6.155]
- frequencyscippVariable()float64Hz-196.0
- beam_positionscippVariable()float64deg0.0
- phasescippVariable()float64deg-100.5
- slit_beginscippVariable(cutout: 8)float64deg-1.23, 27.0, ..., 257.230, 315.490
- slit_endscippVariable(cutout: 8)float64deg1.23, 30.6, ..., 261.170, 318.110
- slit_heightNoneType()None
- radiusNoneType()None
oc
- axle_positionscippVariable()vector3m[0. 0. 6.174]
- frequencyscippVariable()float64Hz14.0
- beam_positionscippVariable()float64deg0.0
- phasescippVariable()float64deg27.0
- slit_beginscippVariable(cutout: 1)float64deg-13.8
- slit_endscippVariable(cutout: 1)float64deg13.8
- slit_heightNoneType()None
- radiusNoneType()None
bcc
- axle_positionscippVariable()vector3m[0. 0. 9.78]
- frequencyscippVariable()float64Hz112.0
- beam_positionscippVariable()float64deg0.0
- phasescippVariable()float64deg20.0
- slit_beginscippVariable(cutout: 2)float64deg-36.875, 143.125
- slit_endscippVariable(cutout: 2)float64deg36.875, 216.875
- slit_heightNoneType()None
- radiusNoneType()None
t0
- axle_positionscippVariable()vector3m[ 0. 0. 13.05]
- frequencyscippVariable()float64Hz28.0
- beam_positionscippVariable()float64deg0.0
- phasescippVariable()float64deg90.0
- slit_beginscippVariable(cutout: 1)float64deg-157.450
- slit_endscippVariable(cutout: 1)float64deg157.450
- 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(77.0, unit="m"), name="detector")
params = [
tof.Chopper.from_diskchopper(ch, name=key) for key, ch in dream_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]] = dream_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='Å'>)
High-resolution mode#
Chopper parameters#
[8]:
choppers = {
"psc1": {
"frequency": {"value": 210.0, "unit": "Hz"},
"open": {
"value": [-1.23, 70.49, 84.765, 113.565, 170.29, 271.635, 286.035, 301.17],
"unit": "deg",
},
"close": {
"value": [1.23, 73.51, 88.035, 116.835, 175.31, 275.565, 289.965, 303.63],
"unit": "deg",
},
"distance": {"value": 6.145, "unit": "m"},
"phase": {"value": -155.0, "unit": "deg"},
"type": "chopper",
"direction": "anticlockwise",
"name": "psc1",
},
"psc2": {
"frequency": {"value": 196.0, "unit": "Hz"},
"open": {
"value": [-1.23, 27.0, 55.8, 142.385, 156.765, 214.115, 257.23, 315.49],
"unit": "deg",
},
"close": {
"value": [1.23, 30.6, 59.4, 145.615, 160.035, 217.885, 261.17, 318.11],
"unit": "deg",
},
"distance": {"value": 6.155, "unit": "m"},
"phase": {"value": 100.5, "unit": "deg"},
"type": "chopper",
"direction": "clockwise",
"name": "psc2",
},
"oc": {
"frequency": {"value": 14.0, "unit": "Hz"},
"open": {"value": [-13.8], "unit": "deg"},
"close": {"value": [13.8], "unit": "deg"},
"distance": {"value": 6.174, "unit": "m"},
"phase": {"value": 27.0, "unit": "deg"},
"type": "chopper",
"direction": "anticlockwise",
"name": "oc",
},
"bcc": {
"frequency": {"value": 112.0, "unit": "Hz"},
"open": {"value": [-36.875, 143.125], "unit": "deg"},
"close": {"value": [36.875, 216.875], "unit": "deg"},
"distance": {"value": 9.78, "unit": "m"},
"phase": {"value": 20.0, "unit": "deg"},
"type": "chopper",
"direction": "anticlockwise",
"name": "bcc",
},
"t0": {
"frequency": {"value": 28.0, "unit": "Hz"},
"open": {"value": [-157.45], "unit": "deg"},
"close": {"value": [157.45], "unit": "deg"},
"distance": {"value": 13.05, "unit": "m"},
"phase": {"value": 90.0, "unit": "deg"},
"type": "chopper",
"direction": "anticlockwise",
"name": "t0",
},
}
[9]:
dream_choppers = {}
for key, ch in choppers.items():
dream_choppers[key] = tof.Chopper.from_json(name=key, params=ch).to_diskchopper()
for key, ch in dream_choppers.items():
print(key)
display(ch)
psc1
- axle_positionscippVariable()vector3m[0. 0. 6.145]
- frequencyscippVariable()float64Hz210.0
- beam_positionscippVariable()float64deg0.0
- phasescippVariable()float64deg-155.0
- slit_beginscippVariable(cutout: 8)float64deg-1.23, 70.49, ..., 286.035, 301.170
- slit_endscippVariable(cutout: 8)float64deg1.23, 73.51, ..., 289.965, 303.630
- slit_heightNoneType()None
- radiusNoneType()None
psc2
- axle_positionscippVariable()vector3m[0. 0. 6.155]
- frequencyscippVariable()float64Hz-196.0
- beam_positionscippVariable()float64deg0.0
- phasescippVariable()float64deg-100.5
- slit_beginscippVariable(cutout: 8)float64deg-1.23, 27.0, ..., 257.230, 315.490
- slit_endscippVariable(cutout: 8)float64deg1.23, 30.6, ..., 261.170, 318.110
- slit_heightNoneType()None
- radiusNoneType()None
oc
- axle_positionscippVariable()vector3m[0. 0. 6.174]
- frequencyscippVariable()float64Hz14.0
- beam_positionscippVariable()float64deg0.0
- phasescippVariable()float64deg27.0
- slit_beginscippVariable(cutout: 1)float64deg-13.8
- slit_endscippVariable(cutout: 1)float64deg13.8
- slit_heightNoneType()None
- radiusNoneType()None
bcc
- axle_positionscippVariable()vector3m[0. 0. 9.78]
- frequencyscippVariable()float64Hz112.0
- beam_positionscippVariable()float64deg0.0
- phasescippVariable()float64deg20.0
- slit_beginscippVariable(cutout: 2)float64deg-36.875, 143.125
- slit_endscippVariable(cutout: 2)float64deg36.875, 216.875
- slit_heightNoneType()None
- radiusNoneType()None
t0
- axle_positionscippVariable()vector3m[ 0. 0. 13.05]
- frequencyscippVariable()float64Hz28.0
- beam_positionscippVariable()float64deg0.0
- phasescippVariable()float64deg90.0
- slit_beginscippVariable(cutout: 1)float64deg-157.450
- slit_endscippVariable(cutout: 1)float64deg157.450
- slit_heightNoneType()None
- radiusNoneType()None
Tof model#
[10]:
params = [
tof.Chopper.from_diskchopper(ch, name=key) for key, ch in dream_choppers.items()
] + [detector]
model = tof.Model(source=source, components=params)
res = model.run()
res.plot()
[10]:
Plot(ax=<Axes: xlabel='Time [μs]', ylabel='Distance [m]'>, fig=<Figure size 1200x480 with 2 Axes>)
[11]:
res["detector"].plot()
[11]:
Wavelength lookup table#
[12]:
wf = GenericUnwrapWorkflow(
run_types=[SampleRun], monitor_types=[], wavelength_from="analytical"
)
wf[DiskChoppers[SampleRun]] = dream_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')
[12]:
[13]:
frames = wf.compute(ChopperFrameSequence[SampleRun])
at_sample = frames.propagate_to(detector.distance)
at_sample.draw()
[13]:
(<Figure size 640x480 with 1 Axes>,
<Axes: title={'center': 'Frame propagation through chopper cascade'}, xlabel='ms', ylabel='Å'>)