def test_axis2invcm(): axis = DataAxis(size=20, offset=200, scale=10) if not "axis" in getfullargspec(DataAxis)[0]: raises(ImportError, axis2invcm, axis) try: from hyperspy.axes import UniformDataAxis except ImportError: skip("HyperSpy version doesn't support non-uniform axis") axis = UniformDataAxis(size=21, offset=200, scale=10) axis2 = DataAxis(axis=arange(0.2, 0.410, 0.01), units="µm") axis3 = DataAxis(axis=arange(1, 2, 0.1), units=r"cm$^{-1}$") invcmaxis, factor = axis2invcm(axis) invcmaxis2, factor2 = axis2invcm(axis2) raises(AttributeError, axis2invcm, axis3) assert factor == 1e7 assert factor2 == 1e4 assert invcmaxis.name == "Wavenumber" assert invcmaxis.units == r"cm$^{-1}$" assert not invcmaxis.navigate assert invcmaxis2.units == r"cm$^{-1}$" assert invcmaxis2.size == 21 assert_allclose(invcmaxis.axis[0], invcmaxis2.axis[0]) assert_allclose(invcmaxis.axis[-1], invcmaxis2.axis[-1]) assert_allclose(invcmaxis.axis[0], 25000)
def test_axis2eV(): axis = DataAxis(size=20, offset=200, scale=10) if not "axis" in getfullargspec(DataAxis)[0]: raises(ImportError, axis2eV, axis) try: from hyperspy.axes import UniformDataAxis except ImportError: skip("HyperSpy version doesn't support non-uniform axis") axis = UniformDataAxis(size=20, offset=200, scale=10) axis2 = DataAxis(axis=arange(0.2, 0.400, 0.01), units="µm") axis3 = DataAxis(axis=arange(1, 2, 0.1), units="eV") evaxis, factor = axis2eV(axis) evaxis2, factor2 = axis2eV(axis2) raises(AttributeError, axis2eV, axis3) assert factor == 1e6 assert factor2 == 1e3 assert evaxis.name == "Energy" assert evaxis.units == "eV" assert not evaxis.navigate assert evaxis2.units == "eV" assert evaxis2.size == 20 assert_allclose(evaxis.axis[0], evaxis2.axis[0]) assert_allclose(evaxis.axis[-1], evaxis2.axis[-1]) assert_allclose(evaxis.axis[0], 3.1781816)
def test_crop_reverses_indexing(self): # reverse indexing axis = DataAxis(axis=self._axis) axis.crop(-14, -2) assert axis.size == 12 np.testing.assert_almost_equal(axis.axis[0], 4) np.testing.assert_almost_equal(axis.axis[-1], 169) # mixed reverses indexing axis = DataAxis(axis=self._axis) axis.crop(2, -2) assert axis.size == 12 np.testing.assert_almost_equal(axis.axis[0], 4) np.testing.assert_almost_equal(axis.axis[-1], 169)
def test_data2eV(): try: from hyperspy.axes import UniformDataAxis except ImportError: skip("HyperSpy version doesn't support non-uniform axis") data = 100 * ones(20) ax0 = DataAxis(axis=arange(200, 400, 10), units="nm") evaxis, factor = axis2eV(ax0) evdata = data2eV(data, factor, ax0, evaxis.axis) assert_allclose(evdata[0], 12.271168) ax0 = DataAxis(axis=arange(0.2, 0.4, 0.01), units="µm") evaxis, factor = axis2eV(ax0) evdata = data2eV(data, factor, ax0, evaxis.axis) assert_allclose(evdata[0], 12.271168e-3)
def test_scale_as_quantity_setter_string_no_previous_units(self): axis = DataAxis(size=2048, scale=12E-12, offset=5.0) axis.scale_as_quantity = '2.5 nm' assert axis.scale == 2.5 # the units haven't been set previously, so the offset is not converted nt.assert_almost_equal(axis.offset, 5.0) assert axis.units == 'nm'
def test_axes2eV(): axis = DataAxis(axis=arange(200, 400, 10)) axis2 = DataAxis(axis=arange(0.2, 0.400, 0.01), units='µm') axis3 = DataAxis(axis=arange(1, 2, 0.1), units='eV') evaxis, factor = axis2eV(axis) evaxis2, factor2 = axis2eV(axis2) raises(AttributeError, axis2eV, axis3) assert factor == 1e6 assert factor2 == 1e3 assert evaxis.name == 'Energy' assert evaxis.units == 'eV' assert not evaxis.navigate assert evaxis2.units == 'eV' assert evaxis2.size == 20 assert_allclose(evaxis.axis[0], evaxis2.axis[0]) assert_allclose(evaxis.axis[-1], evaxis2.axis[-1]) assert_allclose(evaxis.axis[0], 3.1781816)
def test_to_invcm_relative(jacobian): axis = DataAxis(size=20, offset=200, scale=10) data = ones(20) S1 = LumiSpectrum(data, axes=(axis.get_axis_dictionary(), )) if not "axis" in getfullargspec(DataAxis)[0]: raises(ImportError, S1.to_invcm_relative, 244) try: from hyperspy.axes import UniformDataAxis except ImportError: skip("HyperSpy version doesn't support non-uniform axis") axis = UniformDataAxis(size=20, offset=200, scale=10) data = ones(20) S1 = LumiSpectrum(data, axes=(axis.get_axis_dictionary(), )) S2 = S1.to_invcm_relative(laser=244, inplace=False, jacobian=jacobian) S1.axes_manager[0].units = "µm" S1.axes_manager[0].axis = axis.axis / 1000 S1.data *= 1000 S1.to_invcm_relative(laser=0.244, jacobian=jacobian) assert S1.axes_manager[0].units == r"cm$^{-1}$" assert S2.axes_manager[0].name == "Wavenumber" assert S2.axes_manager[0].size == 20 assert S1.axes_manager[0].axis[0] == S2.axes_manager[0].axis[0] assert_allclose(S1.data, S2.data, 5e-4) nav = UniformDataAxis(size=4) # navigation dimension 1 L1 = LumiSpectrum( ones((4, 20)), axes=[nav.get_axis_dictionary(), axis.get_axis_dictionary()]) L2 = L1.to_invcm_relative(laser=244, inplace=False, jacobian=jacobian) L1.to_invcm_relative(laser=244, jacobian=jacobian) assert L1.axes_manager.signal_axes[0].units == r"cm$^{-1}$" assert L2.axes_manager.signal_axes[0].name == "Wavenumber" assert L2.axes_manager.signal_axes[0].size == 20 assert (L1.axes_manager.signal_axes[0].axis[0] == L2.axes_manager.signal_axes[0].axis[0]) assert_allclose(L1.data, L2.data, 5e-4) # navigation dimension 2 M1 = LumiSpectrum( ones((4, 4, 20)), axes=[ nav.get_axis_dictionary(), nav.get_axis_dictionary(), axis.get_axis_dictionary(), ], ) M2 = M1.to_invcm_relative(laser=244, inplace=False, jacobian=jacobian) M1.to_invcm_relative(laser=244, jacobian=jacobian) assert M1.axes_manager.signal_axes[0].units == r"cm$^{-1}$" assert M2.axes_manager.signal_axes[0].name == "Wavenumber" assert M2.axes_manager.signal_axes[0].size == 20 assert (M1.axes_manager.signal_axes[0].axis[0] == M2.axes_manager.signal_axes[0].axis[0]) assert_allclose(M1.data, M2.data, 5e-4)
def test_crop(self, use_indices): axis = DataAxis(axis=self._axis) start, end = 4., 196. if use_indices: start = axis.value2index(start) end = axis.value2index(end) axis.crop(start, end) assert axis.size == 12 np.testing.assert_almost_equal(axis.axis[0], 4) np.testing.assert_almost_equal(axis.axis[-1], 169)
def test_check_axes_calibration(): axisDA1 = DataAxis(axis=arange(10)**2) axisDA2 = DataAxis(axis=arange(10)) axisDA3 = DataAxis(axis=arange(10), units='s') axisDA4 = DataAxis(axis=arange(10), units='seconds') expression = "x ** power" axisFDA1 = FunctionalDataAxis(size=10, expression=expression, power=2) axisFDA2 = FunctionalDataAxis(size=12, expression=expression, power=2) axisUDA1 = UniformDataAxis(size=10, scale=1, offset=10) axisUDA2 = UniformDataAxis(size=10, scale=1, offset=0) assert check_axes_calibration(axisDA1, axisDA1) assert not check_axes_calibration(axisDA1, axisDA2) assert check_axes_calibration(axisDA3, axisDA4) assert check_axes_calibration(axisFDA1, axisFDA1) assert not check_axes_calibration(axisFDA1, axisFDA2) assert check_axes_calibration(axisUDA1, axisUDA1) assert not check_axes_calibration(axisUDA1, axisUDA2) assert not check_axes_calibration(axisDA1, axisUDA1) assert not check_axes_calibration(axisFDA1, axisUDA1) assert check_axes_calibration(axisDA1, axisFDA1) assert check_axes_calibration(axisDA2, axisUDA2)
def __call__(self, signal, axes=None, order=0): """Slice the signal according to the ROI, and return it. Arguments --------- signal : Signal The signal to slice with the ROI. axes : specification of axes to use, default = None The axes argument specifies which axes the ROI will be applied on. The items in the collection can be either of the following: * a tuple of: - DataAxis. These will not be checked with signal.axes_manager. - anything that will index signal.axes_manager * For any other value, it will check whether the navigation space can fit the right number of axis, and use that if it fits. If not, it will try the signal space. """ if axes is None and signal in self.signal_map: axes = self.signal_map[signal][1] else: axes = self._parse_axes(axes, signal.axes_manager) linewidth = self.linewidth / np.min([ax.scale for ax in axes]) profile = Line2DROI.profile_line(signal.data, (self.x1, self.y1), (self.x2, self.y2), axes=axes, linewidth=linewidth, order=order) length = np.linalg.norm(np.diff(np.array( ((self.x1, self.y1), (self.x2, self.y2))), axis=0), axis=1)[0] axm = signal.axes_manager.deepcopy() idx = [] for ax in axes: idx.append(ax.index_in_axes_manager) for i in reversed(sorted(idx)): # Remove in reversed order axm.remove(i) axis = DataAxis(len(profile), scale=length / len(profile), units=axes[0].units, navigate=axes[0].navigate) axis.axes_manager = axm i0 = min(axes[0].index_in_array, axes[1].index_in_array) axm._axes.insert(i0, axis) from hyperspy.signals import Signal roi = Signal(profile, axes=axm._get_axes_dicts(), metadata=signal.metadata.deepcopy().as_dictionary(), original_metadata=signal.original_metadata.deepcopy(). as_dictionary()) return roi
def test_error_DataAxis(self): with pytest.raises(ValueError): _ = DataAxis(axis=np.arange(16)**2, _type='UniformDataAxis') with pytest.raises(AttributeError): self.axis.index_in_axes_manager() with pytest.raises(IndexError): self.axis._get_positive_index(-17) with pytest.raises(ValueError): self.axis._get_array_slices(slice_=slice(1,2,1.5)) with pytest.raises(IndexError): self.axis._get_array_slices(slice_=slice(225,-1.1,1)) with pytest.raises(IndexError): self.axis._get_array_slices(slice_=slice(225.1,0,1))
def test_nonuniformaxis(tmp_path, file, lazy): fname = tmp_path / file data = np.arange(10) axis = DataAxis(axis=1 / np.arange(1, data.size + 1), navigate=False) s = Signal1D(data, axes=(axis.get_axis_dictionary(), )) if lazy: s = s.as_lazy() s.save(fname, overwrite=True) s2 = load(fname) np.testing.assert_array_almost_equal(s.axes_manager[0].axis, s2.axes_manager[0].axis) assert (s2.axes_manager[0].is_uniform == False) assert (s2.axes_manager[0].navigate == False) assert (s2.axes_manager[0].size == data.size)
def test_to_eV(): axis = DataAxis(axis=arange(200, 400, 10)) data = ones(20) S1 = LumiSpectrum(data, axes=(axis.get_axis_dictionary(), )) S1.to_eV() axis.units = 'µm' axis.axis = axis.axis / 1000 data *= 1000 S2 = CLSEMSpectrum(data, axes=(axis.get_axis_dictionary(), )) S3 = S2.to_eV(inplace=False) assert S1.axes_manager[0].units == 'eV' assert S3.axes_manager[0].name == 'Energy' assert S3.axes_manager[0].size == 20 assert S1.axes_manager[0].axis[0] == S3.axes_manager[0].axis[0] assert_allclose(S1.data, S3.data, 5e-4)
def axis2eV(ax0): """Converts given signal axis to eV using wavelength dependent permittivity of air. Assumes WL in units of nm unless the axis units are specifically set to µm. """ if ax0.units == 'eV': raise AttributeError('Signal unit is already eV.') # transform axis, invert direction if ax0.units == 'µm': evaxis = nm2eV(1000 * ax0.axis)[::-1] factor = 1e3 # correction factor for intensity else: evaxis = nm2eV(ax0.axis)[::-1] factor = 1e6 axis = DataAxis(axis=evaxis, name='Energy', units='eV', navigate=False) return axis, factor
def axis2eV(ax0): """Converts given signal axis to energy scale (eV) using wavelength dependent permittivity of air. Assumes wavelength in units of nm unless the axis units are specifically set to µm. """ # Check if non_uniform_axis is available in hyperspy version if not 'axis' in getfullargspec(DataAxis)[0]: raise ImportError('Conversion to energy axis works only ' 'if the non_uniform_axis branch of HyperSpy is used.') if ax0.units == 'eV': raise AttributeError('Signal unit is already eV.') # transform axis, invert direction if ax0.units == 'µm': evaxis=nm2eV(1000*ax0.axis)[::-1] factor = 1e3 # correction factor for intensity else: evaxis=nm2eV(ax0.axis)[::-1] factor = 1e6 axis = DataAxis(axis = evaxis, name = 'Energy', units = 'eV', navigate=False) return axis, factor
def test_joinspectra_nonuniform(average, scale, kind): try: from hyperspy.axes import UniformDataAxis except ImportError: skip("HyperSpy version doesn't support non-uniform axis") s1 = LumiSpectrum(arange(32)) s2 = LumiSpectrum(arange(32) + 25) s2.axes_manager.signal_axes[0].offset = 25 s1.axes_manager.signal_axes[0].convert_to_non_uniform_axis() s = join_spectra([s1, s2], r=2, average=average, scale=scale, kind=kind) assert s.axes_manager.signal_axes[0].is_uniform == False assert s.axes_manager.signal_axes[0].size == 57 assert s.axes_manager.signal_axes[0].axis[-1] == 56 assert s.data.size == 57 assert s.data[-1] == 56 s1 = LumiSpectrum(arange(12)) s2 = LumiSpectrum(arange(12) + 3.8, axes=[DataAxis(axis=arange(12) + 3.8)]) s = join_spectra([s1, s2], r=2, average=average, scale=scale, kind=kind) assert s.axes_manager[0].axis.size == 16 assert s.data.size == 16 assert s.data[-1] == 14.8
def axis2invcm(ax0): r"""Converts given signal axis to wavenumber scale (cm$^{-1}$). Assumes wavelength in units of nm unless the axis units are specifically set to µm. """ # Check if non_uniform_axis is available in hyperspy version if not 'axis' in getfullargspec(DataAxis)[0]: raise ImportError('Conversion to energy axis works only ' 'if the non_uniform_axis branch of HyperSpy is used.') if ax0.units == r'cm$^{-1}$': raise AttributeError(r'Signal unit is already cm$^{-1}$.') # transform axis, invert direction if ax0.units == 'µm': invcmaxis=nm2invcm(1000*ax0.axis)[::-1] factor = 1e4 # correction factor for intensity else: invcmaxis=nm2invcm(ax0.axis)[::-1] factor = 1e7 axis = DataAxis(axis = invcmaxis, name = 'Wavenumber', units = r'cm$^{-1}$', navigate=False) return axis,factor
def __call__(self, signal, out=None, axes=None, order=0): """Slice the signal according to the ROI, and return it. Arguments --------- signal : Signal The signal to slice with the ROI. out : Signal, default = None If the 'out' argument is supplied, the sliced output will be put into this instead of returning a Signal. See Signal.__getitem__() for more details on 'out'. axes : specification of axes to use, default = None The axes argument specifies which axes the ROI will be applied on. The items in the collection can be either of the following: * a tuple of: - DataAxis. These will not be checked with signal.axes_manager. - anything that will index signal.axes_manager * For any other value, it will check whether the navigation space can fit the right number of axis, and use that if it fits. If not, it will try the signal space. order : The spline interpolation order to use when extracting the line profile. 0 means nearest-neighbor interpolation, and is both the default and the fastest. """ if axes is None and signal in self.signal_map: axes = self.signal_map[signal][1] else: axes = self._parse_axes(axes, signal.axes_manager) profile = Line2DROI.profile_line(signal.data, (self.x1, self.y1), (self.x2, self.y2), axes=axes, linewidth=self.linewidth, order=order) length = np.linalg.norm(np.diff(np.array( ((self.x1, self.y1), (self.x2, self.y2))), axis=0), axis=1)[0] if out is None: axm = signal.axes_manager.deepcopy() i0 = min(axes[0].index_in_array, axes[1].index_in_array) axm.remove([ax.index_in_array + 3j for ax in axes]) axis = DataAxis(profile.shape[i0], scale=length / profile.shape[i0], units=axes[0].units, navigate=axes[0].navigate) axis.axes_manager = axm axm._axes.insert(i0, axis) from hyperspy.signals import BaseSignal roi = BaseSignal( profile, axes=axm._get_axes_dicts(), metadata=signal.metadata.deepcopy().as_dictionary(), original_metadata=signal.original_metadata.deepcopy( ).as_dictionary()) return roi else: out.data = profile i0 = min(axes[0].index_in_array, axes[1].index_in_array) ax = out.axes_manager._axes[i0] size = len(profile) scale = length / len(profile) axchange = size != ax.size or scale != ax.scale if axchange: ax.size = len(profile) ax.scale = length / len(profile) out.events.data_changed.trigger(out)
def test_update_from(self): ax2 = DataAxis(size=2, units="nm", scale=0.5) self.axis.update_from(ax2, attributes=("units", "scale")) assert ((ax2.units, ax2.scale) == (self.axis.units, self.axis.scale))
def setup_method(self, method): self.axis = DataAxis(size=10, scale=0.1, offset=10, units='nm')
def setUp(self): self.axis = DataAxis(size=10, scale=0.1, offset=10)
def test_unsorted_axis(self): with pytest.raises(ValueError): DataAxis(axis=np.array([10, 40, 1, 30, 20]))
def test_update_from(self): ax2 = DataAxis(units="plumage", name="parrot", axis=np.arange(16)) self.axis.update_from(ax2, attributes=("units", "name")) assert ((ax2.units, ax2.name) == (self.axis.units, self.axis.name))
def setup_method(self, method): self.axis = DataAxis(size=2048, scale=12E-12, units='m', offset=5E-9)
def setup_method(self, method): self._axis = np.arange(16)**2 self.axis = DataAxis(axis=self._axis)
def setup_method(self, method): self.axis = DataAxis(size=10, scale=-0.1, offset=10)
def setup_method(self, method): axis = DataAxis(axis=1 / (np.arange(10) + 1), navigate=False) self.s = Signal1D(np.arange(10), axes=(axis.get_axis_dictionary(), ))