Skip to content

Commit

Permalink
Merge pull request #64 from scipp/to-event-data
Browse files Browse the repository at this point in the history
Add method to generate data that resembles nxevent_data
  • Loading branch information
nvaytet authored Nov 26, 2024
2 parents 412241d + 64ee4c8 commit cb489e1
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 0 deletions.
27 changes: 27 additions & 0 deletions src/tof/result.py
Original file line number Diff line number Diff line change
Expand Up @@ -379,3 +379,30 @@ def __repr__(self) -> str:

def __str__(self) -> str:
return self.__repr__()

def to_nxevent_data(self, key: str) -> sc.DataArray:
"""
Convert a component reading to event data that resembles event data found in a
NeXus file.
Parameters
----------
key:
Name of the component.
"""
start = sc.datetime("2024-01-01T12:00:00.000000")
period = sc.reciprocal(self.source.frequency)
raw_data = self[key].data.flatten(to='event')
# Select only the neutrons that make it to the detector
event_data = raw_data[~raw_data.masks['blocked_by_others']].copy()
dt = period.to(unit=event_data.coords['toa'].unit)
event_time_zero = (dt * (event_data.coords['toa'] // dt)).to(dtype=int) + start
event_data.coords['event_time_zero'] = event_time_zero
event_data.coords['event_time_offset'] = event_data.coords.pop(
'toa'
) % period.to(unit=dt.unit)
return (
event_data.drop_coords(['tof', 'speed', 'time', 'wavelength'])
.group('event_time_zero')
.rename_dims(event_time_zero='pulse')
)
41 changes: 41 additions & 0 deletions tests/model_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -387,3 +387,44 @@ def test_component_distance():
assert sc.identical(res['monitor'].data.coords['distance'], monitor.distance)
assert sc.identical(res['detector'].data.coords['distance'], detector.distance)
assert sc.identical(res['chopper'].data.coords['distance'], chopper.distance)


def test_to_nxevent_data():
source = tof.Source(facility='ess', neutrons=100_000)
choppers = [
tof.Chopper(
frequency=14.0 * Hz,
open=sc.array(
dims=['cutout'],
values=[0.0],
unit='deg',
),
close=sc.array(
dims=['cutout'],
values=[10.0],
unit='deg',
),
phase=90.0 * deg,
distance=8.0 * meter,
name="chopper",
)
]
detectors = [
tof.Detector(distance=26.0 * meter, name='monitor'),
tof.Detector(distance=32.0 * meter, name='detector'),
]
model = tof.Model(source=source, choppers=choppers, detectors=detectors)
res = model.run()

# There should be 1 pulse for monitor data, and 2 pulses for detector data as it
# wraps around the pulse period.
for key, npulses in zip(('monitor', 'detector'), (1, 2)):
nxevent_data = res.to_nxevent_data(key)
assert sc.identical(res['monitor'].data.sum().data, nxevent_data.sum().data)
assert nxevent_data.sizes['pulse'] == npulses
assert nxevent_data.bins.concat().value.coords[
'event_time_offset'
].min() >= sc.scalar(0.0, unit='us')
assert nxevent_data.bins.concat().value.coords[
'event_time_offset'
].max() <= sc.reciprocal(source.frequency).to(unit='us')

0 comments on commit cb489e1

Please sign in to comment.