From dc96da4b3b5a23bed6650050e07756c5ed60868c Mon Sep 17 00:00:00 2001 From: Eric Prestat Date: Sun, 16 Jun 2024 09:50:40 +0100 Subject: [PATCH] Fix User guide: left over from the split --- doc/conf.py | 1 + doc/user_guide/eds.rst | 100 ++++++++--------- doc/user_guide/eels.rst | 11 +- doc/user_guide/images/EDS_preferences_gui.png | Bin 11166 -> 15537 bytes doc/user_guide/metadata_structure.rst | 4 + exspy/_misc/eels/effective_angle.py | 3 +- .../eels/electron_inelastic_mean_free_path.py | 33 ++++-- exspy/_misc/eels/tools.py | 10 +- exspy/_misc/material.py | 101 +++++++++++------- 9 files changed, 157 insertions(+), 106 deletions(-) diff --git a/doc/conf.py b/doc/conf.py index be78d02e9..26879e545 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -44,6 +44,7 @@ "sphinx_copybutton", "sphinx.ext.autodoc", "sphinx.ext.autosummary", + "sphinx.ext.doctest", "sphinx.ext.githubpages", "sphinx.ext.intersphinx", "sphinx.ext.napoleon", diff --git a/doc/user_guide/eds.rst b/doc/user_guide/eds.rst index eee7ce488..d10688e65 100644 --- a/doc/user_guide/eds.rst +++ b/doc/user_guide/eds.rst @@ -38,7 +38,8 @@ Loading data All data are loaded with the :py:func:`hyperspy.api.load` function, as described in detail in the :external+hyperspy:ref:`loading files` of the HyperSpy documentation. HyperSpy is able to import different formats, among them -``msa`` and ``rpl`` (the raw format of Oxford Instruments and Bruker). +:external+rsciio:ref:`msa ` and :external+rsciio:ref:`rpl ` +(the raw format of Oxford Instruments and Bruker). Here are three examples of files exported by Oxford Instruments software (INCA). For a single spectrum: @@ -59,7 +60,7 @@ dimensional signal with the energy axis in first position): >>> si -Finally, for a stack of spectrum images, using "*" as a wildcard character: +Finally, for a stack of spectrum images, using ``"*"`` as a wildcard character: .. code-block:: python @@ -138,7 +139,7 @@ or through the GUI: .. figure:: images/EDS_microscope_parameters_gui.png :align: center - :width: 350 + :width: 300 EDS microscope parameters preferences window @@ -159,7 +160,7 @@ or through the GUI: .. figure:: images/EDS_preferences_gui.png :align: center - :width: 400 + :width: 300 EDS preferences window @@ -231,19 +232,15 @@ The description of the sample is also stored in the ├── thickness = 100 └── xray_lines = ['Fe_Ka', 'Pt_La'] - -The following methods are either called "set" or "add". - -* "set" methods overwrite previously defined values -* "add" methods add to the previously defined values - Elements ^^^^^^^^ -The elements present in the sample can be defined using the -:py:meth:`~.signals.EDSSpectrum.set_elements` and -:py:meth:`~.signals.EDSSpectrum.add_elements` methods. Only element -abbreviations are accepted: +The elements present in the sample can be defined using two methods: + +- :py:meth:`~.signals.EDSSpectrum.set_elements` to overwrite previously defined elements +- :py:meth:`~.signals.EDSSpectrum.add_elements` to add to the previously defined elements + +Only element abbreviations are accepted: .. code-block:: python @@ -256,11 +253,13 @@ abbreviations are accepted: X-ray lines ^^^^^^^^^^^ -Similarly, the X-ray lines can be defined using the -:py:meth:`~.signals.EDSSpectrum.set_lines` and -:py:meth:`~.signals.EDSSpectrum.add_lines` methods. The corresponding -elements will be added automatically. -Several lines per element can be defined at once. +Similarly, the X-ray lines can be defined using: + +- :py:meth:`~.signals.EDSSpectrum.set_lines` to overwrite previously defined values +- :py:meth:`~.signals.EDSSpectrum.add_lines` to add to the previously defined elements + +The corresponding elements will be added automatically. Several lines per +element can be defined at once. .. code-block:: python @@ -278,7 +277,7 @@ overvoltage of 2 (< beam energy / 2)): .. code-block:: python - >>> s = hs.datasets.example_signals.EDS_SEM_Spectrum() + >>> s = exspy.data.EDS_SEM_TM002() >>> s.set_elements(['Al', 'Cu', 'Mn']) >>> s.set_microscope_parameters(beam_energy=30) >>> s.add_lines() @@ -300,7 +299,7 @@ energy: .. code-block:: python - >>> s = hs.datasets.example_signals.EDS_SEM_Spectrum() + >>> s = exspy.data.EDS_SEM_TM002() >>> s.set_elements(['Mn']) >>> s.set_microscope_parameters(beam_energy=5) >>> s.add_lines(['Mn_Ka']) @@ -310,18 +309,18 @@ energy: Elemental database ^^^^^^^^^^^^^^^^^^ -HyperSpy includes an elemental database, which contains the energy of the +`eXSpy` includes an elemental database, which contains the energy of the X-ray lines. .. code-block:: python - >>> hs.material.elements.Fe.General_properties + >>> exspy.material.elements.Fe.General_properties ├── Z = 26 ├── atomic_weight = 55.845 └── name = iron - >>> hs.material.elements.Fe.Physical_properties + >>> exspy.material.elements.Fe.Physical_properties └── density (g/cm^3) = 7.874 - >>> hs.material.elements.Fe.Atomic_properties.Xray_lines + >>> exspy.material.elements.Fe.Atomic_properties.Xray_lines ├── Ka │ ├── energy (keV) = 6.404 │ └── weight = 1.0 @@ -345,14 +344,14 @@ Finding elements from energy ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ To find the nearest X-ray line for a given energy, use the utility function -:py:func:`~.misc.eds.utils.get_xray_lines_near_energy` to search the elemental +:py:func:`~.utils.eds.get_xray_lines_near_energy` to search the elemental database: .. code-block:: python - >>> s = hs.datasets.example_signals.EDS_SEM_Spectrum() + >>> s = exspy.data.EDS_SEM_TM002() >>> P = s.find_peaks1D_ohaver(maxpeakn=1)[0] - >>> hs.eds.get_xray_lines_near_energy(P['position'], only_lines=['a', 'b']) + >>> exspy.utils.eds.get_xray_lines_near_energy(P['position'], only_lines=['a', 'b']) ['C_Ka', 'Ca_La', 'B_Ka'] The lines are returned in order of distance from the specified energy, and can @@ -369,7 +368,7 @@ You can visualize an EDS spectrum using the .. code-block:: python - >>> s = hs.datasets.example_signals.EDS_SEM_Spectrum() + >>> s = exspy.data.EDS_SEM_TM002() >>> s.plot() .. figure:: images/EDS_plot_spectrum.png @@ -389,13 +388,13 @@ Plotting X-ray lines X-ray lines can be added as plot labels with :py:meth:`~.signals.EDSSpectrum.plot`. The lines are either retrieved -from ``metadata.Sample.Xray_lines``, or selected with the same method as -:py:meth:`~.signals.EDSSpectrum.add_lines` using the elements in -``metadata.Sample.elements``. +from :ref:`metadata.Sample.Xray_lines `, or selected +with the same method as :py:meth:`~.signals.EDSSpectrum.add_lines` using +the elements defined in :ref:`metadata.Sample.elements `. .. code-block:: python - >>> s = hs.datasets.example_signals.EDS_SEM_Spectrum() + >>> s = exspy.data.EDS_SEM_TM002() >>> s.add_elements(['C','Mn','Cu','Al','Zr']) >>> s.plot(True) @@ -409,7 +408,7 @@ You can also select a subset of lines to label: .. code-block:: python - >>> s = hs.datasets.example_signals.EDS_SEM_Spectrum() + >>> s = exspy.data.EDS_SEM_TM002() >>> s.add_elements(['C','Mn','Cu','Al','Zr']) >>> s.plot(True, only_lines=['Ka','b']) @@ -451,9 +450,9 @@ Mn Ka to the peak energy (``energy_resolution_MnKa`` in the metadata): :align: center :width: 500 - Iron map as computed and displayed by ``get_lines_intensity`` + Iron map as computed and displayed by :py:meth:`~.signals.EDSSpectrum.get_lines_intensity` -The X-ray lines defined in ``metadata.Sample.Xray_lines`` are used by default. +The X-ray lines defined in :ref:`metadata.Sample.Xray_lines ` are used by default. The EDS maps can be plotted using :py:func:`hyperspy.api.plot.plot_images`, see :external+hyperspy:ref:`plotting several images` for more information in setting plotting parameters. @@ -598,8 +597,8 @@ ranges containing no X-ray lines: >>> m.fit_background() The width of the X-ray lines is defined from the energy resolution (FWHM at -Mn Ka) provided by ``energy_resolution_MnKa`` in ``metadata``. This parameter -can be calibrated by fitting with +Mn Ka) provided by :ref:`metadata.Acquisition_instrument.Detector.EDS.energy_resolution_MnKa `. +This parameter can be calibrated by fitting with :py:meth:`~.models.EDSModel.calibrate_energy_axis`: .. code-block:: python @@ -692,8 +691,8 @@ 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`. +:py:func:`~.utils.eds.edx_cross_section_to_zeta` or +:py:func:`~.utils.eds.zeta_to_edx_cross_section`. Using the Cliff-Lorimer method as an example, quantification can be carried out as follows: @@ -722,14 +721,14 @@ transformed into weight percent either with the option Fe (Fe_Ka): Composition = 4.96 weight percent Pt (Pt_La): Composition = 95.04 weight percent -or using :py:func:`~.misc.material.atomic_to_weight`: +or using :py:func:`~.material.atomic_to_weight`: .. code-block:: python >>> # With atomic_percent from before - >>> weight_percent = hs.material.atomic_to_weight(atomic_percent) + >>> weight_percent = exspy.material.atomic_to_weight(atomic_percent) -The reverse method is :py:func:`~.misc.material.weight_to_atomic`. +The reverse method is :py:func:`~.material.weight_to_atomic`. The zeta-factor method needs both the ``beam_current`` (in nA) and the acquisition or dwell time (referred to as ``real_time`` in seconds) in order @@ -834,17 +833,18 @@ Mass absorption coefficient database ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ A mass absorption coefficient database :ref:`[Chantler2005] ` -is available: +is available can be accessed using :py:meth:`exspy.material.mass_absorption_coefficient` +and :py:meth:`exspy.material.mass_absorption_mixture`: .. code-block:: python - >>> hs.material.mass_absorption_coefficient( + >>> exspy.material.mass_absorption_coefficient( ... element='Al', energies=['C_Ka','Al_Ka']) array([ 26330.38933818, 372.02616732]) .. code-block:: python - >>> hs.material.mass_absorption_mixture( + >>> exspy.material.mass_absorption_mixture( ... elements=['Al','Zn'], weight_percent=[50,50], energies='Al_Ka') 2587.4161643905127 @@ -852,20 +852,20 @@ Electron and X-ray range ^^^^^^^^^^^^^^^^^^^^^^^^ 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` +:py:meth:`exspy.utils.eds.electron_range` and :py:meth:`exspy.utils.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.) + >>> exspy.utils.eds.xray_range('Cu_Ka', 30.) 1.9361716759499248 To calculate the X-ray range of Cu Ka in pure Carbon at 30kV in micron: .. code-block:: python - >>> hs.eds.xray_range('Cu_Ka', 30., hs.material.elements.C. + >>> exspy.utils.eds.xray_range('Cu_Ka', 30., exspy.material.elements.C. ... Physical_properties.density_gcm3) 7.6418811280855454 @@ -873,5 +873,5 @@ To calculate the electron range in pure Copper at 30 kV in micron .. code-block:: python - >>> hs.eds.electron_range('Cu', 30.) + >>> exspy.utils.eds.electron_range('Cu', 30.) 2.8766744984001607 diff --git a/doc/user_guide/eels.rst b/doc/user_guide/eels.rst index fd1066e71..0d34b4810 100644 --- a/doc/user_guide/eels.rst +++ b/doc/user_guide/eels.rst @@ -15,7 +15,7 @@ The functions described in this chapter are only available for the .. code-block:: python - >>> s.set_signal_type("EELS") + >>> s.set_signal_type("EELS") # doctest: +SKIP Note these chapter discusses features that are available only for :py:class:`~.signals.EELSSpectrum` class. However, this class inherits @@ -47,10 +47,9 @@ they are arranged in the order closest to 849 eV. .. code-block:: python - >>> from hyperspy.misc.eels.tools import get_edges_near_energy - >>> get_edges_near_energy(532) + >>> exspy.utils.eels.get_edges_near_energy(532) ['O_K', 'Pd_M3', 'Sb_M5', 'Sb_M4'] - >>> get_edges_near_energy(849, width=6) + >>> exspy.utils.eels.get_edges_near_energy(849, width=6) ['La_M4', 'Fe_L1'] The static method :py:meth:`~.signals.EELSSpectrum.print_edges_near_energy` @@ -59,7 +58,7 @@ more information about the edges. .. code-block:: python - >>> s = hs.datasets.artificial_data.get_core_loss_eels_signal() + >>> s = exspy.data.EELS_MnFe() >>> s.print_edges_near_energy(401, width=20) +-------+-------------------+-----------+-----------------------------+ | edge | onset energy (eV) | relevance | description | @@ -85,7 +84,7 @@ to aid identification of edges. .. code-block:: python - >>> s = hs.datasets.artificial_data.get_core_loss_eels_signal() + >>> s = exspy.data.EELS_MnFe() >>> s.edges_at_energy() .. figure:: images/EELS_edges_at_energy.png diff --git a/doc/user_guide/images/EDS_preferences_gui.png b/doc/user_guide/images/EDS_preferences_gui.png index 11392d7ea5761bdb95443df4c5cf84368bb42db4..3985a0c83f0177835530c1f58ceeca17544b3185 100644 GIT binary patch literal 15537 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 ht$nlr0Q58N`g<@XxJx literal 11166 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 diff --git a/doc/user_guide/metadata_structure.rst b/doc/user_guide/metadata_structure.rst index cdbaa1a7d..985d8052b 100644 --- a/doc/user_guide/metadata_structure.rst +++ b/doc/user_guide/metadata_structure.rst @@ -101,6 +101,8 @@ General See :external+hyperspy:ref:`HyperSpy-Metadata-General `. +.. _sample-metadata: + Sample ====== @@ -315,6 +317,8 @@ spectrometer The spectrometer model, e.g. Gatan Enfinium ER (Model 977). +.. _eds-detector-metadata: + EDS ^^^ diff --git a/exspy/_misc/eels/effective_angle.py b/exspy/_misc/eels/effective_angle.py index dabbf1944..e3cc40504 100644 --- a/exspy/_misc/eels/effective_angle.py +++ b/exspy/_misc/eels/effective_angle.py @@ -36,7 +36,8 @@ def effective_angle(E0, E, alpha, beta): Returns ------- - float : effective collection angle in mrad + effective_angle : float + The effective collection angle in mrad. Notes ----- diff --git a/exspy/_misc/eels/electron_inelastic_mean_free_path.py b/exspy/_misc/eels/electron_inelastic_mean_free_path.py index 4c865d415..f45e14acf 100644 --- a/exspy/_misc/eels/electron_inelastic_mean_free_path.py +++ b/exspy/_misc/eels/electron_inelastic_mean_free_path.py @@ -39,6 +39,15 @@ def iMFP_Iakoubovskii(density, electron_energy): beam_energy : float Electron beam energy in keV + Returns + ------- + inelastic_mean_free_path : float + The inelastic mean free path in nanometers. + + See Also + -------- + exspy.utils.eels.iMFP_TPP2M, exspy.utils.eels.angular_correction + Notes ----- For details see Equation 9 in reference [*]_. @@ -47,11 +56,6 @@ def iMFP_Iakoubovskii(density, electron_energy): ‘Thickness Measurements with Electron Energy Loss Spectroscopy’. Microscopy Research and Technique 71, no. 8 (2008): 626–31. https://onlinelibrary.wiley.com/doi/10.1002/jemt.20597 - - Returns - ------- - float - Inelastic mean free path in nanometers """ theta_C = 20 # mrad inv_lambda = ( @@ -64,7 +68,7 @@ def iMFP_Iakoubovskii(density, electron_energy): def iMFP_TPP2M(electron_energy, density, M, N_v, E_g): - """Electron inelastic mean free path using TPP-2M + """Electron inelastic mean free path using TPP-2M. Parameters ---------- @@ -81,8 +85,12 @@ def iMFP_TPP2M(electron_energy, density, M, N_v, E_g): Returns ------- - float - Inelastic mean free path in nanometers + inelastic_mean_free_path : float + The inelastic mean free path in nanometers. + + See Also + -------- + exspy.utils.eels.iMFP_Iakoubovskii, exspy.utils.eels.iMFP_angular_correction Notes ----- @@ -122,6 +130,15 @@ def iMFP_angular_correction(density, beam_energy, alpha, beta): alpha, beta : float Convergence and collection angles in mrad. + Returns + ------- + correction : float + The correction factor on the mean free path due to the collection angle. + + See Also + -------- + exspy.utils.eels.iMFP_Iakoubovskii, exspy.utils.eels.iMFP_TPP2M + Notes ----- For details see Equation 9 in reference [*]_. diff --git a/exspy/_misc/eels/tools.py b/exspy/_misc/eels/tools.py index 7349fdfa4..61c3e7e10 100644 --- a/exspy/_misc/eels/tools.py +++ b/exspy/_misc/eels/tools.py @@ -376,6 +376,10 @@ def get_edges_near_energy(energy, width=10, only_major=False, order="closest"): edges : list All edges that are within the given energy window, sorted by energy difference to the given energy. + + See Also + -------- + exspy.utils.eels.get_info_from_edges """ if width < 0: @@ -428,8 +432,12 @@ def get_info_from_edges(edges): Returns ------- info : list - a list of dictionaries with information corresponding to the provided + A list of dictionaries with information corresponding to the provided edges. + + See Also + -------- + exspy.utils.eels.get_edges_near_energy """ edges = np.atleast_1d(edges) diff --git a/exspy/_misc/material.py b/exspy/_misc/material.py index 8fc5fd733..08f6c034d 100644 --- a/exspy/_misc/material.py +++ b/exspy/_misc/material.py @@ -32,9 +32,9 @@ def _weight_to_atomic(weight_percent, elements): Parameters ---------- - weight_percent: array of float + weight_percent : array of float The weight fractions (composition) of the sample. - elements: list of str + elements : list of str A list of element abbreviations, e.g. ['Al','Zn'] Returns @@ -42,8 +42,11 @@ def _weight_to_atomic(weight_percent, elements): atomic_percent : array of float Composition in atomic percent. + Examples + -------- Calculate the atomic percent of modern bronze given its weight percent: - >>> hs.material.weight_to_atomic((88, 12), ("Cu", "Sn")) + + >>> exspy.material.weight_to_atomic((88, 12), ("Cu", "Sn")) array([ 93.19698614, 6.80301386]) """ @@ -71,24 +74,29 @@ def weight_to_atomic(weight_percent, elements="auto"): Parameters ---------- - weight_percent: list of float or list of signals + weight_percent : list of float or list of signals The weight fractions (composition) of the sample. - elements: list of str + elements : list of str A list of element abbreviations, e.g. ['Al','Zn']. If elements is 'auto', take the elements in en each signal metadata of th weight_percent list. Returns ------- - atomic_percent : as weight_percent + atomic_percent : numpy.ndarray of float Composition in atomic percent. Examples -------- Calculate the atomic percent of modern bronze given its weight percent: - >>> hs.material.weight_to_atomic((88, 12), ("Cu", "Sn")) + + >>> exspy.material.weight_to_atomic((88, 12), ("Cu", "Sn")) array([ 93.19698614, 6.80301386]) + See also + -------- + exspy.material.atomic_to_weight + """ from hyperspy.signals import BaseSignal @@ -111,20 +119,21 @@ def _atomic_to_weight(atomic_percent, elements): Parameters ---------- - atomic_percent: array + atomic_percent : array The atomic fractions (composition) of the sample. - elements: list of str + elements : list of str A list of element abbreviations, e.g. ['Al','Zn'] Returns ------- - weight_percent : array of float - composition in weight percent. + weight_percent : numpy.ndarray of float + Composition in weight percent. Examples -------- Calculate the weight percent of modern bronze given its atomic percent: - >>> hs.material.atomic_to_weight([93.2, 6.8], ("Cu", "Sn")) + + >>> exspy.material.atomic_to_weight([93.2, 6.8], ("Cu", "Sn")) array([ 88.00501989, 11.99498011]) """ @@ -152,24 +161,29 @@ def atomic_to_weight(atomic_percent, elements="auto"): Parameters ---------- - atomic_percent: list of float or list of signals + atomic_percent : list of float or list of signals The atomic fractions (composition) of the sample. - elements: list of str + elements : list of str A list of element abbreviations, e.g. ['Al','Zn']. If elements is 'auto', take the elements in en each signal metadata of the atomic_percent list. Returns ------- - weight_percent : as atomic_percent - composition in weight percent. + weight_percent : numpy.ndarray of float + Composition in weight percent. Examples -------- Calculate the weight percent of modern bronze given its atomic percent: - >>> hs.material.atomic_to_weight([93.2, 6.8], ("Cu", "Sn")) + + >>> exspy.material.atomic_to_weight([93.2, 6.8], ("Cu", "Sn")) array([ 88.00501989, 11.99498011]) + See also + -------- + exspy.material.weight_to_atomic + """ from hyperspy.signals import BaseSignal @@ -194,23 +208,26 @@ def _density_of_mixture(weight_percent, elements, mean="harmonic"): Parameters ---------- - weight_percent: array + weight_percent : array A list of weight percent for the different elements. If the total is not equal to 100, each weight percent is divided by the sum of the list (normalization). - elements: list of str + elements : list of str A list of element symbols, e.g. ['Al', 'Zn'] - mean: 'harmonic' or 'weighted' - The type of mean use to estimate the density + mean : ``'harmonic'`` or ``'weighted'`` + The type of mean use to estimate the density. + Default is ``'harmonic'``. Returns ------- - density: The density in g/cm3. + density : numpy.ndarray of float + The density in g/cm3. Examples -------- Calculate the density of modern bronze given its weight percent: - >>> hs.material.density_of_mixture([88, 12],['Cu', 'Sn']) + + >>> exspy.material.density_of_mixture([88, 12],['Cu', 'Sn']) 8.6903187973131466 """ @@ -255,25 +272,28 @@ def density_of_mixture(weight_percent, elements="auto", mean="harmonic"): Parameters ---------- - weight_percent: list of float or list of signals + weight_percent : list of float or list of signals A list of weight percent for the different elements. If the total is not equal to 100, each weight percent is divided by the sum of the list (normalization). - elements: list of str + elements : list of str A list of element symbols, e.g. ['Al', 'Zn']. If elements is 'auto', take the elements in en each signal metadata of the weight_percent list. - mean: 'harmonic' or 'weighted' - The type of mean use to estimate the density + mean : ``'harmonic'`` or ``'weighted'`` + The type of mean use to estimate the density. + Default is ``'harmonic'``. Returns ------- - density: The density in g/cm3. + density : numpy.ndarray of float or hyperspy.api.signals.BaseSignal + The density in g/cm3. Examples -------- Calculate the density of modern bronze given its weight percent: - >>> hs.material.density_of_mixture([88, 12],['Cu', 'Sn']) + + >>> exspy.material.density_of_mixture([88, 12],['Cu', 'Sn']) 8.6903187973131466 """ @@ -306,17 +326,18 @@ def mass_absorption_coefficient(element, energies): Return ------ - mass absorption coefficient(s) in cm^2/g + mass_absorption_coefficients : numpy.ndarray of float + Mass absorption coefficient(s) in cm^2/g Examples -------- - >>> hs.material.mass_absorption_coefficient( + >>> exspy.material.mass_absorption_coefficient( >>> element='Al', energies=['C_Ka','Al_Ka']) array([ 26330.38933818, 372.02616732]) See also -------- - :py:func:`~hs.material.mass_absorption_mixture` + exspy.material.mass_absorption_mixture Note ---- @@ -366,18 +387,18 @@ def _mass_absorption_mixture(weight_percent, elements, energies): Examples -------- - >>> hs.material.mass_absorption_mixture( + >>> exspy.material.mass_absorption_mixture( >>> elements=['Al','Zn'], weight_percent=[50,50], energies='Al_Ka') 2587.4161643905127 Return ------ - float or array of float - mass absorption coefficient(s) in cm^2/g + mass_absorption_coefficient : numpy.ndarray of float + The mass absorption coefficient(s) in cm^2/g See also -------- - :py:func:`~hs.material.mass_absorption` + exspy.material.mass_absorption Note ---- @@ -427,18 +448,18 @@ def mass_absorption_mixture(weight_percent, elements="auto", energies="auto"): Examples -------- - >>> hs.material.mass_absorption_mixture( + >>> exspy.material.mass_absorption_mixture( >>> elements=['Al','Zn'], weight_percent=[50,50], energies='Al_Ka') 2587.41616439 Return ------ - float or array of float - mass absorption coefficient(s) in cm^2/g + mass_absorption_coefficient : numpy.ndarray of float or hyperspy.api.signals.BaseSignal + The Mass absorption coefficient(s) of the mixture in cm^2/g See also -------- - :py:func:`~hs.material.mass_absorption_coefficient` + exspy.material.mass_absorption_coefficient Note ----