44
55import h5py
66import scipp as sc
7+ import scipp .constants
78
89from .types import (
910 DetectorData ,
@@ -44,20 +45,25 @@ def _unique_child_group_h5(
4445
4546
4647def _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