From 80b1e2c7baaf04309e0c3211b7c3fde9c1cac673 Mon Sep 17 00:00:00 2001 From: k8macarthur Date: Wed, 17 Mar 2021 08:28:58 +0100 Subject: [PATCH 1/7] Update user guide to reflect that k-factors assume weight percent. --- doc/user_guide/eds.rst | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/doc/user_guide/eds.rst b/doc/user_guide/eds.rst index 7e8b522d83..512bc3820b 100644 --- a/doc/user_guide/eds.rst +++ b/doc/user_guide/eds.rst @@ -684,10 +684,11 @@ must be determined experimentally using standards. Zeta-factors should be provided in units of kg/m^2. The method is described further in :ref:`[Watanabe1996] ` -and :ref:`[Watanabe2006] `. Cross sections should be -provided in units of barns (b). Further details on the cross section method can -be found in :ref:`[MacArthur2016] `. Conversion between -zeta-factors and cross sections is possible using +and :ref:`[Watanabe2006] `. K-factors are unitless but are based +on the assumption of weight percent. Cross sections should be provided in units +of barns (b). Further details on the cross section method can be found in +:ref:`[MacArthur2016] `. Conversion between zeta-factors and +cross sections is possible using :py:func:`~.misc.eds.utils.edx_cross_section_to_zeta` or :py:func:`~.misc.eds.utils.zeta_to_edx_cross_section`. @@ -811,13 +812,13 @@ composition maps for each element. >>> factors=factors, absorption_correction=True >>> thickness = 100.) -At this stage absorption correction is only applicable for parallel-sided, -thin-film samples. Absorption correction is calculated on a pixel by pixel +At this stage absorption correction is only applicable for parallel-sided, +thin-film samples. Absorption correction is calculated on a pixel by pixel basis after having determined a sample mass-thickness map. It therefore may be a source of error in particularly inhomogeneous specimens. - + Absorption correction can also only be applied to spectra from a single EDS -detector. For systems that consist of multiple detectors, such as the Thermo +detector. For systems that consist of multiple detectors, such as the Thermo Fisher Super-X, it is therefore necessary to load the spectra from each detector separately. @@ -847,13 +848,13 @@ is available: Electron and X-ray range ^^^^^^^^^^^^^^^^^^^^^^^^ -The electron and X-ray range in a bulk material can be estimated with +The electron and X-ray range in a bulk material can be estimated with :py:meth:`hs.eds.electron_range` and :py:meth:`hs.eds.xray_range` To calculate the X-ray range of Cu Ka in pure Copper at 30 kV in micron: .. code-block:: python - + >>> hs.eds.xray_range('Cu_Ka', 30.) 1.9361716759499248 @@ -871,4 +872,3 @@ To calculate the electron range in pure Copper at 30 kV in micron >>> hs.eds.electron_range('Cu', 30.) 2.8766744984001607 - From 7172fd8333751b9337585689227bf22bf82a37c9 Mon Sep 17 00:00:00 2001 From: k8macarthur Date: Wed, 17 Mar 2021 09:28:39 +0100 Subject: [PATCH 2/7] Fix error in the ACF part of the k-factor quantification. --- hyperspy/misc/eds/utils.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/hyperspy/misc/eds/utils.py b/hyperspy/misc/eds/utils.py index 0f8bdb09d0..d3c7360789 100644 --- a/hyperspy/misc/eds/utils.py +++ b/hyperspy/misc/eds/utils.py @@ -440,7 +440,7 @@ def quantification_cliff_lorimer(intensities, else: index = np.where(intensities > min_intensity)[0] if absorption_correction is not None: - absorption_correction = absorption_correction + absorption_correction = absorption_correction.reshape(dim[0], dim2) else: # default to ones absorption_correction = np.ones_like(intens, dtype='float') @@ -498,8 +498,9 @@ def _quantification_cliff_lorimer(intensities, other_index = list(range(len(kfactors))) other_index.pop(ref_index) for i in other_index: - ab[i] = intensities[ref_index] * kfactors[ref_index] \ - / (intensities[i] * absorption_correction[i]) / kfactors[i] + ab[i] = (intensities[ref_index] * absorption_correction[ref_index]) \ + / (intensities[i] * absorption_correction[i]) \ + *( kfactors[ref_index] / kfactors[i]) # Ca = ab /(1 + ab + ab/ac + ab/ad + ...) ab = ab for i in other_index: From da1567111f197b4917abe00bf14fb66f41dcd06a Mon Sep 17 00:00:00 2001 From: k8macarthur Date: Wed, 17 Mar 2021 09:33:58 +0100 Subject: [PATCH 3/7] Add test to check reversing of element order does not change quantification. --- hyperspy/tests/signal/test_eds_tem.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/hyperspy/tests/signal/test_eds_tem.py b/hyperspy/tests/signal/test_eds_tem.py index 9d451554ef..4777991831 100644 --- a/hyperspy/tests/signal/test_eds_tem.py +++ b/hyperspy/tests/signal/test_eds_tem.py @@ -250,6 +250,13 @@ def test_quant_lorimer_ac(self): composition_units, absorption_correction=True, thickness=0.0001) + list.reverse(intensities) + list.reverse(kfactors) + res5 = s.quantification(intensities, method, kfactors, + composition_units, + absorption_correction=True, + thickness=300.) + np.testing.assert_allclose(res5[0][0].data, res3[0][1].data, atol=1e-5) np.testing.assert_allclose(res2[0][0].data, np.ones((2, 2)) * 22.70779, atol=1e-3) np.testing.assert_allclose(res3[0][0].data, np.ones((2, 2)) * 22.587251, From 2012bafc39f50b817b316689eabe729bd515e1d2 Mon Sep 17 00:00:00 2001 From: k8macarthur Date: Wed, 17 Mar 2021 09:36:46 +0100 Subject: [PATCH 4/7] Scale back docs fix to keep them in separate pull requests. --- doc/user_guide/eds.rst | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/doc/user_guide/eds.rst b/doc/user_guide/eds.rst index 512bc3820b..93b8bf756b 100644 --- a/doc/user_guide/eds.rst +++ b/doc/user_guide/eds.rst @@ -684,11 +684,10 @@ must be determined experimentally using standards. Zeta-factors should be provided in units of kg/m^2. The method is described further in :ref:`[Watanabe1996] ` -and :ref:`[Watanabe2006] `. K-factors are unitless but are based -on the assumption of weight percent. Cross sections should be provided in units -of barns (b). Further details on the cross section method can be found in -:ref:`[MacArthur2016] `. Conversion between zeta-factors and -cross sections is possible using +and :ref:`[Watanabe2006] `. Cross sections should be +provided in units of barns (b). Further details on the cross section method can +be found in :ref:`[MacArthur2016] `. Conversion between +zeta-factors and cross sections is possible using :py:func:`~.misc.eds.utils.edx_cross_section_to_zeta` or :py:func:`~.misc.eds.utils.zeta_to_edx_cross_section`. From b6ce7de9dfcddf4830904fb0a6b27ba58796fb0b Mon Sep 17 00:00:00 2001 From: k8macarthur Date: Wed, 17 Mar 2021 10:09:49 +0100 Subject: [PATCH 5/7] Update cliff lorimer ac test after changing acf calculation. --- hyperspy/tests/signal/test_eds_tem.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hyperspy/tests/signal/test_eds_tem.py b/hyperspy/tests/signal/test_eds_tem.py index 4777991831..5370df0495 100644 --- a/hyperspy/tests/signal/test_eds_tem.py +++ b/hyperspy/tests/signal/test_eds_tem.py @@ -257,7 +257,7 @@ def test_quant_lorimer_ac(self): absorption_correction=True, thickness=300.) np.testing.assert_allclose(res5[0][0].data, res3[0][1].data, atol=1e-5) - np.testing.assert_allclose(res2[0][0].data, np.ones((2, 2)) * 22.70779, + np.testing.assert_allclose(res2[0][0].data, np.ones((2, 2)) * 22.743013, atol=1e-3) np.testing.assert_allclose(res3[0][0].data, np.ones((2, 2)) * 22.587251, atol=1e-3) From 10118497146edc04656c8f3fbee901888ee1aca3 Mon Sep 17 00:00:00 2001 From: k8macarthur Date: Wed, 17 Mar 2021 10:29:30 +0100 Subject: [PATCH 6/7] Update res3 in quant_cliff_lorimer_ac --- hyperspy/tests/signal/test_eds_tem.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hyperspy/tests/signal/test_eds_tem.py b/hyperspy/tests/signal/test_eds_tem.py index 5370df0495..09e190ac6a 100644 --- a/hyperspy/tests/signal/test_eds_tem.py +++ b/hyperspy/tests/signal/test_eds_tem.py @@ -259,7 +259,7 @@ def test_quant_lorimer_ac(self): np.testing.assert_allclose(res5[0][0].data, res3[0][1].data, atol=1e-5) np.testing.assert_allclose(res2[0][0].data, np.ones((2, 2)) * 22.743013, atol=1e-3) - np.testing.assert_allclose(res3[0][0].data, np.ones((2, 2)) * 22.587251, + 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) From 0d0ee4c38efe0ee041179546ba8758e01fdd6417 Mon Sep 17 00:00:00 2001 From: k8macarthur Date: Wed, 17 Mar 2021 14:34:52 +0100 Subject: [PATCH 7/7] Change absorption correction definition back without dimension rearrangement. --- hyperspy/misc/eds/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hyperspy/misc/eds/utils.py b/hyperspy/misc/eds/utils.py index d3c7360789..69626baeb3 100644 --- a/hyperspy/misc/eds/utils.py +++ b/hyperspy/misc/eds/utils.py @@ -440,7 +440,7 @@ def quantification_cliff_lorimer(intensities, else: index = np.where(intensities > min_intensity)[0] if absorption_correction is not None: - absorption_correction = absorption_correction.reshape(dim[0], dim2) + absorption_correction = absorption_correction else: # default to ones absorption_correction = np.ones_like(intens, dtype='float')