def test_linlogspace_linear_log_linear(): q_linloglin = tools.linlogspace(dim='qz', edges=[0.008, 0.03, 0.08, 0.12], unit='1/angstrom', scale=['linear', 'log', 'linear'], num=[16, 20, 10]) exp_lin = sc.linspace(dim='qz', start=0.008, stop=0.03, num=16, unit='1/angstrom') exp_log = sc.geomspace(dim='qz', start=0.03, stop=0.08, num=21, unit='1/angstrom') exp_lin2 = sc.linspace(dim='qz', start=0.08, stop=0.12, num=11, unit='1/angstrom') expected = sc.concat([exp_lin, exp_log['qz', 1:], exp_lin2['qz', 1:]], 'qz') assert sc.allclose(q_linloglin, expected)
def params(): dim = 'frame' return { 'frequency': sc.scalar(56.0, unit="Hz"), 'phase': sc.scalar(0.5, unit='rad'), 'position': sc.vector(value=[0., 0., 5.], unit='m'), 'cutout_angles_center': sc.linspace(dim=dim, start=0.25, stop=2.0 * np.pi, num=6, unit='rad'), 'cutout_angles_width': sc.linspace(dim=dim, start=0.1, stop=0.6, num=6, unit='rad'), 'kind': sc.scalar('wfm') }
def test_mantid_convert_tof_to_direct_energy_transfer(): efixed = 1000 * sc.Unit('meV') in_ws = make_workspace('tof', emode='Direct', efixed=efixed) out_mantid = mantid_convert_units(in_ws, 'energy_transfer', emode='Direct', efixed=efixed) in_da = scn.mantid.from_mantid(in_ws) out_scipp = scn.convert(data=in_da, origin='tof', target='energy_transfer', scatter=True) # The conversion consists of multiplications and additions, thus the relative error # changes with the inputs. In this case, small tof yields a large error due to # the 1/tof**2 factor in the conversion. # rtol is chosen to account for linearly changing tof in the input data. assert sc.allclose( out_scipp.coords['energy_transfer'], out_mantid.coords['energy_transfer'], rtol=sc.linspace( 'energy_transfer', 1e-6, 1e-10, out_scipp.coords['energy_transfer'].sizes['energy_transfer'])) assert sc.identical(out_scipp.coords['spectrum'], out_mantid.coords['spectrum'])
def test_basic_stitching(): frames = sc.Dataset() shift = -5.0 frames['time_min'] = sc.array(dims=['frame'], values=[0.0], unit=sc.units.us) frames['time_max'] = sc.array(dims=['frame'], values=[10.0], unit=sc.units.us) frames['time_correction'] = sc.array(dims=['frame'], values=[shift], unit=sc.units.us) frames["wfm_chopper_mid_point"] = sc.vector(value=[0., 0., 2.0], unit='m') data = sc.DataArray(data=sc.ones(dims=['t'], shape=[100], unit=sc.units.counts), coords={ 't': sc.linspace(dim='t', start=0.0, stop=10.0, num=101, unit=sc.units.us), 'source_position': sc.vector(value=[0., 0., 0.], unit='m') }) nbins = 10 stitched = wfm.stitch(data=data, dim='t', frames=frames, bins=nbins) # Note dimension change to TOF as well as shift assert sc.identical( sc.values(stitched), sc.DataArray( data=sc.ones(dims=['tof'], shape=[nbins], unit=sc.units.counts) * nbins, coords={ 'tof': sc.linspace(dim='tof', start=0.0 - shift, stop=10.0 - shift, num=nbins + 1, unit=sc.units.us), 'source_position': sc.vector(value=[0., 0., 2.], unit='m') }))
def test_linlogspace_linear(): q_lin = tools.linlogspace(dim='qz', edges=[0.008, 0.08], scale='linear', num=50, unit='1/angstrom') expected = sc.linspace(dim='qz', start=0.008, stop=0.08, num=50, unit='1/angstrom') assert sc.allclose(q_lin, expected)
def _bin_event_data_for_ploting(data, frame, bins_per_frame): """ Bin event data using `bins_per_frame` to make a meaningful plot. """ return sc.bin(data, edges=[ sc.linspace(dim='tof', start=frame["time_min"].value, stop=frame["time_max"].value, num=bins_per_frame, unit=frame['time_min'].unit) ]).bins.sum()
def test_cutout_angles_from_begin_end(params): dim = 'frame' del params['cutout_angles_center'] del params['cutout_angles_width'] params["cutout_angles_begin"] = sc.linspace(dim=dim, start=0.0, stop=1.5 * np.pi, num=6, unit='rad') params["cutout_angles_end"] = sc.linspace(dim=dim, start=0.1, stop=2.0 * np.pi, num=6, unit='rad') chopper = ch.make_chopper(**params) assert sc.allclose( ch.cutout_angles_width(chopper), params["cutout_angles_end"] - params["cutout_angles_begin"]) assert sc.allclose( ch.cutout_angles_center(chopper), 0.5 * (params["cutout_angles_begin"] + params["cutout_angles_end"]))
def _stitch_dense_data( item: sc.DataArray, frames: sc.Dataset, dim: str, new_dim: str, bins: Union[int, sc.Variable]) -> Union[sc.DataArray, dict]: # Make empty data container if isinstance(bins, int): new_coord = sc.linspace( dim=new_dim, start=(frames["time_min"]["frame", 0] - frames["time_correction"]["frame", 0]).value, stop=(frames["time_max"]["frame", -1] - frames["time_correction"]["frame", -1]).value, num=bins + 1, unit=frames["time_min"].unit, ) else: new_coord = bins dims = [] shape = [] for dim_ in item.dims: if dim_ != dim: dims.append(dim_) shape.append(item.sizes[dim_]) else: dims.append(new_dim) shape.append(new_coord.sizes[new_dim] - 1) out = sc.DataArray(data=sc.zeros(dims=dims, shape=shape, with_variances=item.variances is not None, unit=item.unit), coords={new_dim: new_coord}) for group in ["coords", "attrs"]: for key in getattr(item, group): if key != dim: getattr(out, group)[key] = getattr(item, group)[key].copy() for i in range(frames.sizes["frame"]): section = item[dim, frames["time_min"].data[ "frame", i]:frames["time_max"].data["frame", i]].rename_dims({dim: new_dim}) section.coords[new_dim] = section.coords[dim] - frames[ "time_correction"].data["frame", i] if new_dim != dim: del section.coords[dim] out += sc.rebin(section, new_dim, out.coords[new_dim]) return out
def _do_stitching_on_beamline(wavelengths, dim, event_mode=False): # Make beamline parameters for 6 frames coords = wfm.make_fake_beamline(nframes=6) # They are all created half-way through the pulse. # Compute their arrival time at the detector. alpha = sc.to_unit(constants.m_n / constants.h, 's/m/angstrom') dz = sc.norm(coords['position'] - coords['source_position']) arrival_times = sc.to_unit(alpha * dz * wavelengths, 'us') + coords['source_pulse_t_0'] + ( 0.5 * coords['source_pulse_length']) coords[dim] = arrival_times # Make a data array that contains the beamline and the time coordinate tmin = sc.min(arrival_times) tmax = sc.max(arrival_times) dt = 0.1 * (tmax - tmin) if event_mode: num = 2 else: num = 2001 time_binning = sc.linspace(dim=dim, start=(tmin - dt).value, stop=(tmax + dt).value, num=num, unit=dt.unit) events = sc.DataArray(data=sc.ones(dims=['event'], shape=arrival_times.shape, unit=sc.units.counts, with_variances=True), coords=coords) if event_mode: da = sc.bin(events, edges=[time_binning]) else: da = sc.histogram(events, bins=time_binning) # Find location of frames frames = wfm.get_frames(da) stitched = wfm.stitch(frames=frames, data=da, dim=dim, bins=2001) wav = scn.convert(stitched, origin='tof', target='wavelength', scatter=False) if event_mode: out = wav else: out = sc.rebin(wav, dim='wavelength', bins=sc.linspace(dim='wavelength', start=1.0, stop=10.0, num=1001, unit='angstrom')) choppers = {key: da.meta[key].value for key in ch.find_chopper_keys(da)} # Distance between WFM choppers dz_wfm = sc.norm(choppers["chopper_wfm_2"]["position"].data - choppers["chopper_wfm_1"]["position"].data) # Delta_lambda / lambda dlambda_over_lambda = dz_wfm / sc.norm( coords['position'] - frames['wfm_chopper_mid_point'].data) return out, dlambda_over_lambda