Skip to content

Commit ae4e50a

Browse files
committed
feat: pulse shaping
1 parent 323d88a commit ae4e50a

File tree

1 file changed

+81
-16
lines changed

1 file changed

+81
-16
lines changed

src/ess/beer/io.py

Lines changed: 81 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import h5py
66
import scipp as sc
7+
import scipp.constants
78

89
from .types import (
910
DetectorData,
@@ -44,20 +45,25 @@ def _unique_child_group_h5(
4445

4546

4647
def _load_beer_mcstas(f, bank=1):
47-
for key in f['/entry1/instrument/components']:
48-
if 'sampleMantid' in key:
49-
sample_position_path = f'/entry1/instrument/components/{key}/Position'
50-
break
51-
else:
52-
raise ValueError('Sample position entry not found in file.')
53-
data, events, params, sample_pos, chopper_pos = _load_h5(
54-
f,
55-
f'NXentry/NXdetector/bank{bank:02}_events_dat_list_p_x_y_n_id_t',
56-
f'NXentry/NXdetector/bank{bank:02}_events_dat_list_p_x_y_n_id_t/events',
57-
'NXentry/simulation/Param',
58-
sample_position_path,
59-
'/entry1/instrument/components/0017_cMCA/Position',
48+
positions = {
49+
key: f'/entry1/instrument/components/{key}/Position'
50+
for key in f['/entry1/instrument/components']
51+
}
52+
data, events, params, sample_pos, psc1_pos, psc2_pos, psc3_pos, mca_pos, mcc_pos = (
53+
_load_h5(
54+
f,
55+
f'NXentry/NXdetector/bank{bank:02}_events_dat_list_p_x_y_n_id_t',
56+
f'NXentry/NXdetector/bank{bank:02}_events_dat_list_p_x_y_n_id_t/events',
57+
'NXentry/simulation/Param',
58+
positions['sampleMantid'],
59+
positions['PSC1'],
60+
positions['PSC2'],
61+
positions['PSC3'],
62+
positions['MCA'],
63+
positions['MCC'],
64+
)
6065
)
66+
6167
events = events[()]
6268
da = sc.DataArray(
6369
sc.array(dims=['events'], values=events[:, 0], variances=events[:, 0] ** 2),
@@ -75,21 +81,70 @@ def _load_beer_mcstas(f, bank=1):
7581
v = v[0]
7682
if isinstance(v, bytes):
7783
v = v.decode()
78-
if k in ('mode', 'sample_filename'):
84+
if k in ('mode', 'sample_filename', 'lambda'):
7985
da.coords[k] = sc.scalar(v)
8086

87+
if da.coords['lambda'].value == '0':
88+
if da.coords['mode'].value in [
89+
'0',
90+
'3',
91+
'4',
92+
'5',
93+
'6',
94+
'7',
95+
'8',
96+
'9',
97+
'10',
98+
'15',
99+
'16',
100+
]:
101+
da.coords['lambda'] = sc.scalar(2.1, unit='angstrom')
102+
elif da.coords['mode'].value in ['1', '2']:
103+
da.coords['lambda'] = sc.scalar(3.1, unit='angstrom')
104+
elif da.coords['mode'].value == '11':
105+
da.coords['lambda'] = sc.scalar(3.0, unit='angstrom')
106+
elif da.coords['mode'].value == '12':
107+
da.coords['lambda'] = sc.scalar(3.5, unit='angstrom')
108+
elif da.coords['mode'].value == '13':
109+
da.coords['lambda'] = sc.scalar(6.0, unit='angstrom')
110+
elif da.coords['mode'].value == '14':
111+
da.coords['lambda'] = sc.scalar(4.0, unit='angstrom')
112+
else:
113+
da.coords['lambda'] = sc.scalar(
114+
float(da.coords['lambda'].value), unit='angstrom'
115+
)
116+
81117
da.coords['sample_position'] = sc.vector(sample_pos[:], unit='m')
82118
da.coords['detector_position'] = sc.vector(
83119
list(map(float, da.coords.pop('position').value.split(' '))), unit='m'
84120
)
85-
da.coords['chopper_position'] = sc.vector(chopper_pos[:], unit='m')
121+
122+
if da.coords['mode'].value in ['0', '1', '2', '11', '16']:
123+
da.coords['chopper_position'] = sc.vector([0.0, 0.0, 0.0], unit='m')
124+
elif da.coords['mode'].value in ['3', '4', '12', '13', '15']:
125+
da.coords['chopper_position'] = sc.vector(
126+
0.5 * (psc1_pos[:] + psc3_pos[:]), unit='m'
127+
)
128+
elif da.coords['mode'].value in ['5', '6']:
129+
da.coords['chopper_position'] = sc.vector(
130+
0.5 * (psc1_pos[:] + psc2_pos[:]), unit='m'
131+
)
132+
elif da.coords['mode'].value in ['7', '8', '9', '10']:
133+
da.coords['chopper_position'] = sc.vector(0.5 * mca_pos[:], unit='m')
134+
elif da.coords['mode'].value == '14':
135+
da.coords['chopper_position'] = sc.vector(mcc_pos[:], unit='m')
136+
else:
137+
raise ValueError(f'Unkonwn chopper mode {da.coords["mode"].value}.')
138+
86139
da.coords['x'].unit = 'm'
87140
da.coords['y'].unit = 'm'
88141
da.coords['t'].unit = 's'
89142

90143
z = sc.norm(da.coords['detector_position'] - da.coords['sample_position'])
144+
# z = da.coords['position'].fields.z - da.coords['sample_position'].fields.z
91145
L1 = sc.norm(da.coords['sample_position'] - da.coords['chopper_position'])
92146
L2 = sc.sqrt(da.coords['x'] ** 2 + da.coords['y'] ** 2 + z**2)
147+
93148
# Source is assumed to be at the origin
94149
da.coords['L0'] = L1 + L2 + sc.norm(da.coords['chopper_position'])
95150
da.coords['Ltotal'] = L1 + L2
@@ -102,7 +157,17 @@ def _load_beer_mcstas(f, bank=1):
102157
da.coords.pop('y')
103158
da.coords.pop('n')
104159

105-
da.coords['event_time_offset'] = da.coords.pop('t')
160+
# expression of temporal offset delta_t checked for pulse shaping mode: 4,5,6
161+
delta_t = (
162+
sc.constants.m_n
163+
/ sc.constants.h
164+
* da.coords['lambda']
165+
* sc.norm(da.coords['chopper_position']).to(unit='angstrom')
166+
).to(unit='s')
167+
168+
t = da.coords.pop('t')
169+
da.coords['event_time_offset'] = t % sc.scalar(1 / 14, unit=t.unit)
170+
da.coords["approximate_tof"] = da.coords['event_time_offset'] - delta_t
106171
return da
107172

108173

0 commit comments

Comments
 (0)