From 4f58b0e331a2a2a3377ee346dcb31fb4ea8312c9 Mon Sep 17 00:00:00 2001 From: Eric Prestat Date: Sun, 10 Apr 2022 12:32:18 +0100 Subject: [PATCH] Remove unnecessary code and check if the parameters are of the correct type and length --- hyperspy/_signals/eds_tem.py | 15 ++++-- hyperspy/misc/eds/utils.py | 73 ++++++++++---------------- hyperspy/tests/signals/test_eds_tem.py | 30 +++++------ 3 files changed, 53 insertions(+), 65 deletions(-) diff --git a/hyperspy/_signals/eds_tem.py b/hyperspy/_signals/eds_tem.py index 9563532c27..a3e53f62ef 100755 --- a/hyperspy/_signals/eds_tem.py +++ b/hyperspy/_signals/eds_tem.py @@ -25,7 +25,7 @@ from scipy import constants import pint -from hyperspy.signal import BaseSetMetadataItems +from hyperspy.signal import BaseSetMetadataItems, BaseSignal from hyperspy import utils from hyperspy._signals.eds import (EDSSpectrum, LazyEDSSpectrum) from hyperspy.defaults_parser import preferences @@ -399,13 +399,22 @@ def quantification(self, -------- vacuum_mask """ + if (not isinstance(intensities, (list, tuple)) or + not isinstance(intensities[0], BaseSignal)): + raise ValueError( + "The parameter `intensities` must be a list of signals." + ) + elif len(intensities) <= 1: + raise ValueError("Several X-ray line intensities are required.") + if isinstance(navigation_mask, float): if self.axes_manager.navigation_dimension > 0: navigation_mask = self.vacuum_mask(navigation_mask, closing) else: navigation_mask = None - xray_lines = [intensity.metadata.Sample.xray_lines[0] for intensity in intensities] + xray_lines = [intensity.metadata.Sample.xray_lines[0] + for intensity in intensities] it = 0 if absorption_correction: if show_progressbar is None: # pragma: no cover @@ -559,7 +568,7 @@ def quantification(self, utils.plot.plot_signals(composition, **kwargs) if absorption_correction: - _logger.info(f'Convergence reach after {it} interations.') + _logger.info(f'Convergence reached after {it} interations.') if method == 'zeta': mass_thickness.metadata.General.title = 'Mass thickness' diff --git a/hyperspy/misc/eds/utils.py b/hyperspy/misc/eds/utils.py index 2c9458b624..02e28824ea 100644 --- a/hyperspy/misc/eds/utils.py +++ b/hyperspy/misc/eds/utils.py @@ -422,55 +422,36 @@ def quantification_cliff_lorimer(intensities, # Value used as an threshold to prevent using zeros as denominator min_intensity = 0.1 dim = intensities.shape - if len(dim) > 1: - dim2 = reduce(lambda x, y: x * y, dim[1:]) - intens = intensities.reshape(dim[0], dim2) - intens = intens.astype('float') - - if absorption_correction is None: - # default to ones - absorption_correction = np.ones_like(intens, dtype=float) - else: - absorption_correction = absorption_correction.reshape(dim[0], dim2) - - for i in range(dim2): - index = np.where(intens[:, i] > min_intensity)[0] - if len(index) > 1: - ref_index, ref_index2 = index[:2] - intens[:, i] = _quantification_cliff_lorimer( - intens[:, i], kfactors, absorption_correction[:, i], - ref_index, ref_index2) - else: - intens[:, i] = np.zeros_like(intens[:, i]) - if len(index) == 1: - intens[index[0], i] = 1. - - intens = intens.reshape(dim) - if mask is not None: - from hyperspy.signals import BaseSignal - if isinstance(mask, BaseSignal): - mask = mask.data - for i in range(dim[0]): - intens[i][(mask==True)] = 0 - return intens + dim2 = reduce(lambda x, y: x * y, dim[1:]) + intens = intensities.reshape(dim[0], dim2).astype(float) + + if absorption_correction is None: + # default to ones + absorption_correction = np.ones_like(intens, dtype=float) else: - index = np.where(intensities > min_intensity)[0] - if absorption_correction is None: - # default to ones - absorption_correction = np.ones_like(intensities, dtype=float) + absorption_correction = absorption_correction.reshape(dim[0], dim2) + + for i in range(dim2): + index = np.where(intens[:, i] > min_intensity)[0] if len(index) > 1: ref_index, ref_index2 = index[:2] - intens = _quantification_cliff_lorimer( - intensities, - kfactors, - absorption_correction, - ref_index, - ref_index2) + intens[:, i] = _quantification_cliff_lorimer( + intens[:, i], kfactors, absorption_correction[:, i], + ref_index, ref_index2) else: - intens = np.zeros_like(intensities) + intens[:, i] = np.zeros_like(intens[:, i]) if len(index) == 1: - intens[index[0]] = 1. - return intens + intens[index[0], i] = 1. + + intens = intens.reshape(dim) + if mask is not None: + from hyperspy.signals import BaseSignal + if isinstance(mask, BaseSignal): + mask = mask.data + for i in range(dim[0]): + intens[i][(mask==True)] = 0 + + return intens quantification_cliff_lorimer.__doc__ %= (_ABSORPTION_CORRECTION_DOCSTRING) @@ -635,11 +616,11 @@ def quantification_cross_section(intensities, if absorption_correction is None: # default to ones - absorption_correction = np.ones_like(intensities, dtype='float') + absorption_correction = np.ones_like(intensities, dtype=float) shp = len(intensities.shape) - 1 slices = (slice(None),) + (None,) * shp - x_sections = np.array(cross_sections, dtype='float')[slices] + x_sections = np.array(cross_sections, dtype=float)[slices] number_of_atoms = intensities / (x_sections * dose * 1e-10) * absorption_correction total_atoms = np.cumsum(number_of_atoms, axis=0)[-1] composition = number_of_atoms / total_atoms diff --git a/hyperspy/tests/signals/test_eds_tem.py b/hyperspy/tests/signals/test_eds_tem.py index f2f337077a..792c3ef024 100644 --- a/hyperspy/tests/signals/test_eds_tem.py +++ b/hyperspy/tests/signals/test_eds_tem.py @@ -202,6 +202,19 @@ def test_metadata(self): TEM_md.probe_area, 1.2) np.testing.assert_approx_equal(TEM_md.Detector.EDS.real_time, 3.1) + def test_quant_one_intensity_error(self): + s = self.signal + method = 'CL' + kfactors = [1, 2.0009344042484134] + intensities = s.get_lines_intensity()[:1] + assert len(intensities) == 1 + with pytest.raises(ValueError): + _ = s.quantification(intensities, method, kfactors) + + intensities = s.get_lines_intensity()[0] + with pytest.raises(ValueError): + _ = s.quantification(intensities, method, kfactors) + def test_quant_lorimer(self): s = self.signal method = 'CL' @@ -281,22 +294,7 @@ def test_quant_lorimer_ac(self): atol=1e-3) np.testing.assert_allclose(res3[0][0].data, np.ones((2, 2)) * 31.816908, atol=1e-3) - np.testing.assert_allclose(res[0].data, res4[0][0].data, atol=1e-5) - - def test_quant_lorimer_ac_single_spectrum(self): - s = self.signal.inav[0] - method = 'CL' - kfactors = [1, 2.0009344042484134] - composition_units = 'weight' - intensities = s.get_lines_intensity() - res = s.quantification(intensities, method, kfactors, - composition_units) - np.testing.assert_allclose(res[0].data, 22.70779, atol=1e-3) - res2 = s.quantification(intensities, method, kfactors, - composition_units, - absorption_correction=True, - thickness=1.) - np.testing.assert_allclose(res2[0].data, 22.743013, atol=1e-3) + np.testing.assert_allclose(res[0].data, res4[0][0].data, atol=1e-5) def test_quant_zeta(self): s = self.signal