def test_mean_filter(self): bulk_value = 1 test_value = 4 data = np.array([bulk_value] * 9 * 9 * 4, dtype=np.float64).reshape(9, 9, 4) data = sc.Variable(dims=['y', 'x', 'z'], values=data) data['z', 1]['x', 4]['y', 4].value = test_value # centre at z == 1 data['z', 2]['x', 4]['y', 0].value = test_value # edge at z == 3 data['z', 3]['x', 0]['y', 0].value = test_value # corner at z == 2 centre_mean = (bulk_value * 8 + test_value * 1) / 9 corner_mean = (bulk_value * 3 + test_value * 1) / 4 edge_mean = (bulk_value * 5 + test_value * 1) / 6 mean = operations.mean_from_adj_pixels(data) assert sc.identical(mean['z', 0], data['z', 0]) # mean of 1 everywhere same as original assert sc.identical( mean['z', 1]['y', 3:6]['x', 3:6], sc.Variable(dims=['y', 'x'], values=np.array([centre_mean] * 9).reshape(3, 3))) assert sc.identical( mean['z', 2]['y', 0:1]['x', 3:6], sc.Variable(dims=['y', 'x'], values=np.array([edge_mean] * 3).reshape(1, 3))) assert sc.identical( mean['z', 2]['y', 1:2]['x', 3:6], sc.Variable(dims=['y', 'x'], values=np.array([centre_mean] * 3).reshape(1, 3))) assert mean['z', 3]['y', 0]['x', 0].value == corner_mean
def test_convert_input_unchanged(): inputs = make_test_data(coords=('tof', 'Ltotal'), dataset=True) original = inputs.copy(deep=True) result = scn.convert(inputs, origin='tof', target='wavelength', scatter=True) assert not sc.identical(result, original) assert sc.identical(inputs, original)
def test_convert_binned_convert_slice(target): tof = make_test_data(coords=('tof', 'Ltotal', 'two_theta'))['tof', 0].copy() tof.data = make_tof_binned_events() original = tof.copy() full = scn.convert(tof, origin='tof', target=target, scatter=True) sliced = scn.convert(tof['spectrum', 1:2], origin='tof', target=target, scatter=True) assert sc.identical(sliced, full['spectrum', 1:2]) assert sc.identical(tof, original)
def test_neutron_beamline(): d = make_dataset_with_beamline() assert sc.identical(scn.source_position(d), sc.vector(value=np.array([0, 0, -10]), unit=sc.units.m)) assert sc.identical(scn.sample_position(d), sc.vector(value=np.array([0, 0, 0]), unit=sc.units.m)) assert sc.identical(scn.L1(d), 10.0 * sc.units.m) assert sc.identical( scn.L2(d), sc.Variable(dims=['position'], values=np.ones(4), unit=sc.units.m)) two_theta = scn.two_theta(d) assert sc.identical(scn.L1(d) + scn.L2(d), scn.Ltotal(d, scatter=True)) assert two_theta.unit == sc.units.rad assert two_theta.dims == ['position']
def test_load_component_info_to_2d_geometry(geom_file): geometry = mantid.load_component_info_to_2d(geom_file, sizes={ 'x': 10, 'y': 10 }) assert geometry["position"].sizes == {'x': 10, 'y': 10} assert sc.identical( geometry["x"], sc.DataArray(data=sc.array( dims=["x"], values=np.arange(0.0, 0.1, 0.01), unit=sc.units.m))) assert sc.identical( geometry["y"], sc.DataArray(data=sc.array( dims=["y"], values=np.arange(0.0, 0.1, 0.01), unit=sc.units.m)))
def test_sample_ub(self): import mantid.simpleapi as mantid ws = mantid.CreateWorkspace(DataY=np.ones(1), DataX=np.arange(2)) args = {'a': 1, 'b': 1, 'c': 1, 'alpha': 90, 'beta': 90, 'gamma': 90} mantid.SetUB(ws, **args) d = scn.mantid.from_mantid(ws) assert sc.identical( d.attrs['sample_ub'], sc.spatial.linear_transform( value=ws.sample().getOrientedLattice().getUB(), unit=sc.units.angstrom**-1)) assert sc.identical( d.attrs['sample_u'], sc.spatial.linear_transform( value=ws.sample().getOrientedLattice().getU()))
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_convert_beam_length_and_angle(target, make_ref): original = make_test_data(coords=('incident_beam', 'scattered_beam')) converted = scn.convert(original, origin='position', target=target, scatter=True) assert sc.identical(converted.meta[target], make_ref())
def test_extract_energy_initial(): from mantid.simpleapi import mtd mtd.clear() ds = scn.load(scn.data.get_path("CNCS_51936_event.nxs"), mantid_args={"SpectrumMax": 1}) assert sc.identical(ds.coords["incident_energy"], sc.scalar(value=3.0, unit=sc.Unit("meV")))
def test_convert_beam_length_no_scatter(): original = make_test_data(coords=('position', 'source_position')) converted = scn.convert(original, origin='position', target='Ltotal', scatter=False) expected = sc.norm(make_position() - make_source_position()) assert sc.identical(converted.coords['Ltotal'], expected)
def test_z_offset(): x = 0.0 * sc.units.m y = 0.0 * sc.units.m initial_z = 2.0 * sc.units.m expected_z = 0.0 * sc.units.m expected_result = sc.geometry.position(x, y, expected_z) actual_result = resolution.z_offset(sc.geometry.position(x, y, initial_z), -2 * sc.units.m) assert sc.identical(actual_result, expected_result)
def test_convert_tof_to_wavelength_no_scatter(): # scatter=True and scatter=False only differ in how Ltotal is computed. tof = make_test_data(coords=('tof', 'Ltotal'), dataset=True) no_scatter = scn.convert(tof, origin='tof', target='wavelength', scatter=False) scatter = scn.convert(tof, origin='tof', target='wavelength', scatter=True) assert sc.identical(no_scatter, scatter)
def test_detector_resolution(): expected_result = (np.arctan(1.0) * 180.0 / np.pi / (2 * np.sqrt(2 * np.log(2)))) * sc.units.deg detector_spatial_resolution = 1 * sc.units.m z_pixel_position = 2 * sc.units.m z_sample_position = 1 * sc.units.m actual_result = resolution.detector_resolution(detector_spatial_resolution, z_pixel_position, z_sample_position) assert sc.identical(actual_result, expected_result)
def test_convert_dataset_vs_dataarray(origin, target): inputs = make_dataset_in(origin) expected = scn.convert(inputs, origin=origin, target=target, scatter=True) result = sc.Dataset( data={ name: scn.convert( data.copy(), origin=origin, target=target, scatter=True) for name, data in inputs.items() }) for name, data in result.items(): assert sc.identical(data, expected[name])
def test_nxobject_monitor(nexus_group: Tuple[Callable, LoadFromNexus]): resource, loader = nexus_group with resource(builder_with_events_monitor_and_log())() as f: monitor = nexus.NXroot(f, loader)['monitor'] assert monitor.nx_class == nexus.NX_class.NXmonitor assert sc.identical( monitor[...], sc.DataArray(sc.array(dims=['time_of_flight'], values=[1.0]), coords={ 'time_of_flight': sc.array(dims=['time_of_flight'], values=[1.0]) }))
def test_EventWorkspace_with_pulse_times(): import mantid.simpleapi as sapi small_event_ws = sapi.CreateSampleWorkspace(WorkspaceType='Event', NumBanks=1, NumEvents=10) d = scn.mantid.convert_EventWorkspace_to_data_array(small_event_ws, load_pulse_times=True) assert d.data.values[0].coords['pulse_time'].dtype == sc.DType.datetime64 assert sc.identical( d.data.values[0].coords['pulse_time']['event', 0], sc.scalar(value=small_event_ws.getSpectrum(0).getPulseTimes() [0].to_datetime64()))
def test_loads_data_with_coords(nexus_group: Tuple[Callable, LoadFromNexus]): resource, loader = nexus_group builder = NexusBuilder() da = sc.DataArray( sc.array(dims=['xx', 'yy'], unit='K', values=[[1.1, 2.2], [3.3, 4.4]])) da.coords['xx'] = sc.array(dims=['xx'], unit='m', values=[0.1, 0.2]) builder.add_detector( Detector(detector_numbers=np.array([1, 2, 3, 4]), data=da)) with resource(builder)() as f: detector = nexus.NXroot(f, loader)['entry/detector_0'] loaded = detector[...] assert sc.identical(loaded, da.rename_dims({'yy': 'dim_1'}))
def test_time_series_log_extraction(): import mantid.simpleapi as sapi ws = sapi.CreateWorkspace(DataX=[0, 1], DataY=[1]) times = [ np.datetime64(t) for t in ['2021-01-01T00:00:00', '2021-01-01T00:30:00', '2021-01-01T00:50:00'] ] for i, t in enumerate(times): sapi.AddTimeSeriesLog(ws, Name='time_log', Time=str(t), Value=float(i)) da = scn.from_mantid(ws) assert da.attrs['time_log'].value.coords[ 'time'].dtype == sc.DType.datetime64 # check times assert sc.identical( sc.Variable(dims=['time'], values=np.array(times).astype('datetime64[ns]')), da.attrs['time_log'].value.coords['time']) # check values assert sc.identical(sc.Variable(dims=['time'], values=np.arange(3.)), da.attrs['time_log'].value.data) sapi.DeleteWorkspace(ws)
def test_median_filter(self): bulk_value = 1.0 test_value = 4.0 data = np.array([bulk_value] * 9 * 9 * 4, dtype=np.float64).reshape(9, 9, 4) data = sc.Variable(dims=['y', 'x', 'z'], values=data) data['z', 1]['x', 4]['y', 4].value = test_value # centre at z == 1 data['z', 2]['x', 3]['y', 0].value = test_value # edge at z == 3 data['z', 2]['x', 4]['y', 0].value = test_value # edge at z == 3 data['z', 2]['x', 5]['y', 0].value = test_value # edge at z == 3 data['z', 3]['x', 0]['y', 0].value = test_value # corner at z == 2 data['z', 3]['x', 0]['y', 1].value = test_value # corner at z == 2 centre_median = bulk_value corner_median = np.median( [bulk_value, bulk_value, test_value, test_value]) edge_median = np.median([ bulk_value, bulk_value, bulk_value, test_value, test_value, test_value ]) median = operations.median_from_adj_pixels(data) assert sc.identical(median['z', 0], data['z', 0]) # median of 1 everywhere same as original assert sc.identical( median['z', 1]['y', 3:6]['x', 3:6], sc.Variable(dims=['y', 'x'], values=np.array([centre_median] * 9).reshape(3, 3))) assert sc.identical( median['z', 2]['y', 0:1]['x', 3:6], sc.Variable(dims=['y', 'x'], values=np.array([bulk_value, edge_median, bulk_value]).reshape(1, 3))) assert median['z', 3]['y', 0]['x', 0].value == corner_median
def test_convert_slice(target): tof = make_test_data(coords=('tof', 'position', 'sample_position', 'source_position'), dataset=True) expected = scn.convert(tof['counts'], origin='tof', target=target, scatter=True)['spectrum', 0].copy() assert sc.identical( scn.convert(tof['counts']['spectrum', 0].copy(), origin='tof', target=target, scatter=True), expected) # Converting slice of item is same as item of converted slice assert sc.identical( scn.convert(tof['counts']['spectrum', 0].copy(), origin='tof', target=target, scatter=True).data, scn.convert(tof['spectrum', 0].copy(), origin='tof', target=target, scatter=True)['counts'].data)
def test_convert_coords_vs_attributes(): with_coords = make_test_data(coords=('tof', 'Ltotal'), dataset=True) with_attrs = with_coords.copy() with_attrs['counts'].attrs['Ltotal'] = with_attrs.coords.pop('Ltotal') from_coords = scn.convert(with_coords, origin='tof', target='wavelength', scatter=True) from_attrs = scn.convert(with_attrs, origin='tof', target='wavelength', scatter=True) assert sc.identical(from_coords, from_attrs)
def test_convert_tof_to_energy_transfer_indirect_unphysical(): tof = make_test_data(coords=('tof', 'L1', 'L2'), dataset=True) ef = 25.0 * sc.units.meV tof.coords['final_energy'] = ef t0 = sc.to_unit(tof.coords['L2'] * sc.sqrt(m_n / ef), sc.units.s) coord, is_unphysical = make_unphysical_tof(t0, tof) tof.coords['tof'] = coord result = scn.convert(tof, origin='tof', target='energy_transfer', scatter=True) assert sc.identical(sc.isnan(result.coords['energy_transfer']), is_unphysical)
def test_nxobject_log(nexus_group: Tuple[Callable, LoadFromNexus]): resource, loader = nexus_group with resource(builder_with_events_monitor_and_log())() as f: log = nexus.NXroot(f, loader)['entry']['log'] assert log.nx_class == nexus.NX_class.NXlog assert sc.identical( log[...], sc.DataArray( sc.array(dims=['time'], values=[1.1, 2.2, 3.3]), coords={ 'time': sc.epoch(unit='ns') + sc.array( dims=['time'], unit='s', values=[4.4, 5.5, 6.6]).to( unit='ns', dtype='int64') }))
def test_mantid_convert_tof_to_dspacing(): in_ws = make_workspace('tof') out_mantid = mantid_convert_units(in_ws, 'dspacing') in_da = scn.mantid.from_mantid(in_ws) out_scipp = scn.convert(data=in_da, origin='tof', target='dspacing', scatter=True) assert sc.allclose(out_scipp.coords['dspacing'], out_mantid.coords['dspacing'], rtol=1e-8 * sc.units.one) assert sc.identical(out_scipp.coords['spectrum'], out_mantid.coords['spectrum'])
def test_WorkspaceGroup_parsed_correctly(self): from mantid.simpleapi import (mtd, CreateSampleWorkspace, GroupWorkspaces) CreateSampleWorkspace(OutputWorkspace="ws1") CreateSampleWorkspace(OutputWorkspace="ws2") CreateSampleWorkspace(OutputWorkspace="ws3") GroupWorkspaces(InputWorkspaces="ws1,ws2,ws3", OutputWorkspace="NewGroup") converted_group = scn.from_mantid(mtd["NewGroup"]) converted_single = scn.from_mantid(mtd["ws1"]) assert len(converted_group) == 3 assert sc.identical(converted_group['ws1'], converted_single) mtd.clear()
def convert_Workspace2D_to_data_array(ws, load_run_logs=True, advanced_geometry=False, **ignored): dim, unit = validate_and_get_unit(ws.getAxis(0).getUnit()) spec_dim, spec_coord = init_spec_axis(ws) coords_labs_data = _convert_MatrixWorkspace_info( ws, advanced_geometry=advanced_geometry, load_run_logs=load_run_logs) _, data_unit = validate_and_get_unit(ws.YUnit(), allow_empty=True) if ws.id() == 'MaskWorkspace': coords_labs_data["data"] = sc.Variable(dims=[spec_dim], unit=data_unit, values=ws.extractY().flatten(), dtype=sc.DType.bool) else: stddev2 = ws.extractE() np.multiply(stddev2, stddev2, out=stddev2) # much faster than np.power coords_labs_data["data"] = sc.Variable(dims=[spec_dim, dim], unit=data_unit, values=ws.extractY(), variances=stddev2) array = sc.DataArray(**coords_labs_data) if ws.hasAnyMaskedBins(): bin_mask = sc.zeros(dims=array.dims, shape=array.shape, dtype=sc.DType.bool) for i in range(ws.getNumberHistograms()): # maskedBinsIndices throws instead of returning empty list if ws.hasMaskedBins(i): set_bin_masks(bin_mask, dim, i, ws.maskedBinsIndices(i)) common_mask = sc.all(bin_mask, spec_dim) if sc.identical(common_mask, sc.any(bin_mask, spec_dim)): array.masks["bin"] = common_mask else: array.masks["bin"] = bin_mask # Avoid creating dimensions that are not required since this mostly an # artifact of inflexible data structures and gets in the way when working # with scipp. if len(spec_coord.values) == 1: if 'position' in array.coords: array.coords['position'] = array.coords['position'][spec_dim, 0] array = array[spec_dim, 0].copy() return array
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_convert_beams(target): def check_positions(data): assert 'sample_position' not in data.coords assert ('source_position' in data.coords) == (target == 'scattered_beam') assert ('position' in data.coords) == (target == 'incident_beam') # A single sample position. original = make_test_data(coords=('position', 'sample_position', 'source_position')) converted = scn.convert(original, origin='position', target=target, scatter=True) check_positions(converted) assert sc.identical( converted.coords[target], make_incident_beam() if target == 'incident_beam' else make_scattered_beam()) # Two sample positions. original = make_test_data(coords=('position', 'source_position')) original.coords['sample_position'] = sc.vectors(dims=['spectrum'], values=[[1.0, 0.0, 0.2], [2.1, -0.3, 1.4]], unit='m') converted = scn.convert(original, origin='position', target=target, scatter=True) check_positions(converted) if target == 'incident_beam': assert sc.allclose(converted.coords['incident_beam'], sc.vectors(dims=['spectrum'], values=[[1.0, 0.0, 10.2], [2.1, -0.3, 11.4]], unit='m'), rtol=1e-14 * sc.units.one) if target == 'scattered_beam': assert sc.allclose(converted.coords['scattered_beam'], sc.vectors(dims=['spectrum'], values=[[0.0, 0.0, -0.2], [-2.0, 0.3, -0.4]], unit='m'), rtol=1e-14 * sc.units.one)
def test_advanced_geometry_with_absent_shape(self): import mantid.simpleapi as mantid # single bank 3 by 3 ws = mantid.CreateSampleWorkspace(NumBanks=1, BankPixelWidth=3, StoreInADS=False) # Save and reload trick to purge sample shape info file_name = "example_geometry.nxs" geom_path = os.path.join(tempfile.gettempdir(), file_name) mantid.SaveNexusGeometry(ws, geom_path) # Does not save shape info assert os.path.isfile(geom_path) # sanity check out = mantid.LoadEmptyInstrument( Filename=geom_path, StoreInADS=False) # reload without sample info os.remove(geom_path) assert not out.componentInfo().hasValidShape(0) # sanity check da = scn.mantid.from_mantid(out, advanced_geometry=True) # Shapes have zero size assert sc.identical(sc.sum(da.meta['shape']), sc.vector(value=[0, 0, 0], unit=sc.units.m))
def test_mantid_convert_tof_to_energy(): in_ws = make_workspace('tof') out_mantid = mantid_convert_units(in_ws, 'energy') in_da = scn.mantid.from_mantid(in_ws) out_scipp = scn.convert(data=in_da, origin='tof', target='energy', scatter=True) # Mantid reverses the order of the energy dim. mantid_energy = sc.empty_like(out_mantid.coords['energy']) assert mantid_energy.dims[1] == 'energy' mantid_energy.values = out_mantid.coords['energy'].values[..., ::-1] assert sc.allclose(out_scipp.coords['energy'], mantid_energy, rtol=1e-7 * sc.units.one) assert sc.identical(out_scipp.coords['spectrum'], out_mantid.coords['spectrum'])