Welcome to LumiSpy’s documentation!

Build_status Tests Codecov_status CodeQL_status Python_version PyPI_version Anaconda_version License DOI Documentation_status

LumiSpy is a Python package extending the functionality for multi-dimensional data analysis provided by the HyperSpy library. It is aimed at helping with the analysis of luminescence spectroscopy data (cathodoluminescence, photoluminescence, electroluminescence, Raman, SNOM).

Check out the Installation section for further information, including how to start using this project.

Complementing this documentation, the LumiSpy Demos repository contains curated Jupyter notebooks to provide tutorials and exemplary workflows.

Note

This project is under active development. Everyone is welcome to contribute. Please read our (see Contributing) guidelines and get started!

Contents

Installation

To install LumiSpy, you have the following options (independent of the operating system you use):

  1. LumiSpy is included in the HyperSpy Bundle, a standalone program that includes a python distribution and all relevant libraries (recommended if you do not use python for anything else).

  2. Installation using conda (recommended if you are also working with other python packages).

  3. Installation using pip.

  4. Installing the development version from GitHub, refer to the appropriate section in the HyperSpy user guide (replacing hyperspy by lumispy).

Installation using conda

Follow these 3 steps to install LumiSpy using conda.

1. Creating a conda environment

LumiSpy requires Python 3 and conda – we suggest using the Python 3 version of Miniconda.

We recommend creating a new environment for the LumiSpy package (or installing it in the HyperSpy environment, if you have one already). To create a new environment:

  1. Load the anaconda prompt.

  2. Run the following command:

(base) conda create -n lumispy -y
2. Installing the package in the new environment

Now activate the LumiSpy environment and install the package from conda-forge:

(base) conda activate lumispy
(lumispy) conda install -c conda-forge lumispy -y

Required dependencies will be installed automatically.

Installation is completed! To start using it, check the next section.

Note

If you run into trouble, check the more detailed documentation in the HyperSpy user guide.

3. Getting Started

To get started using LumiSpy, especially if you are unfamiliar with Python, we recommend using Jupyter notebooks. Having installed LumiSpy as above, a Jupyter notebook can be installed and opened using the following commands entered into an anaconda prompt (from scratch):

(base) conda activate lumispy
(lumispy) conda install -c conda-forge jupyterlab -y
(lumispy) jupyter lab

Tutorials and exemplary workflows have been curated as a series of Jupyter notebooks that you can work through and modify to perform many common analyses.

Installation using pip

Alternatively, you can also find LumiSpy in the Python Package Index (PyPI) and install it using (requires pip):

pip install lumispy

Required dependencies will be installed automatically.

Updating the package

Using conda:

conda update lumispy -c conda-forge

Using pip:

pip install lumispy --upgrade

Note

If you want to be notified about new releases, please Watch (Releases only) the Lumispy repository on GitHub (requires a GitHub account).

Introduction

What is LumiSpy

LumiSpy is an open-source python library aimed at helping with the analysis of luminescence spectroscopy data – the development started mainly with photoluminescence (PL), cathodoluminescence (CL), electroluminescence (EL) and Raman spectroscopy in mind. Besides the standard continuous-excitation spectral data, the idea is to provide tools also for the analysis of time-resolved (transient) measurements. However, it may prove useful also for other optical measurements, such as absorption or transmission spectroscopy, scanning optical near field miscroscopy (SNOM), as well as fourier-transform infrared spectroscopy (FTIR).

LumiSpy is an extension to the python package `HyperSpy <https://hyperspy.org>`_ that facilitates hyperspectral data analysis, i.e. maps or linescans where a spectrum is collected at each pixel. Or more general, multidimensional datasets that can be described as multidimensional arrays of a given signal. Notable features that HyperSpy provides are:

  • base signal classes for the handling of (multidimensional) spectral data,

  • the necessary tools for loading various data file formats with a focus on electron microscopy

  • analytical tools that exploit the multidimensionality of datasets,

  • a user-friendly and powerful framework for model fitting that provides many standard functions and can be easily extended to custom ones,

  • machine learning algorithms that can be useful e.g. for denoising data,

  • efficient handling of big datasets,,

  • functions for data visualization both to evaluate datasets during the analysis and provide interactive operation for certain functions, as well as for plotting of data.

  • extracting subsets of data from multidimensional datasets via regions of interest and a powerful numpy-style indexing mechanism,

  • handling of non-uniform data axes (introduced in the v1.7 release).

LumiSpy provides in particular:

  • additional Signal types specifically for luminescence spectra and transients,

  • transformation to Non-uniform signal axes for use of other units, such as electron Volt and wavenumbers (Raman shift),

  • various utility functions useful in luminescence spectroscopy data analysis, such as joining multiple spectra along the signal axis, normalizing data, etc.

LumiSpy should facilitate an easy and reproducible analysis of single spectra or spectral images

Signal types

As an extension to HyperSpy, LumiSpy provides several signal types extending the base classes available in HyperSpy. When the LumiSpy library is installed, these additional signal types are directly available to HyperSpy. To print all available specialised hyperspy.signal.BaseSignal subclasses installed in your system call the hyperspy.utils.print_known_signal_types() function:

>>> hs.print_known_signal_types()

The different subclasses are characterized by the signal_type metadata attribute. Some additional properties are summarized in the table below. Depending on the use case, certain functions will only be available for some signal types (or inheriting) signal types.

LumiSpy subclasses and their basic attributes.

BaseSignal subclass

signal_dimension

signal_type

dtype

aliases

LumiSpectrum

1

Luminescence

real

LuminescenceSpectrum

CLSpectrum

1

CL

real

CLSpectrum, cathodoluminescence

CLSEMSpectrum

1

CL_SEM

real

CLSEM, cathodoluminescence SEM

CLSTEMSpectrum

1

CL_STEM

real

CLSTEM, cathodoluminescence STEM

ELSpectrum

1

EL

real

ELSpectrum, electroluminescence

PLSpectrum

1

PL

real

PLSpectrum, photoluminescence

LumiTransient

1

Transient

real

TRLumi, TR luminescence, time-resolved luminescence

LumiTransient

2

TransientSpec

real

TRLumiSpec, TR luminescence spectrum, time-resolved luminescence spectrum

The hierarchy of the LumiSpy signal types and their inheritance from HyperSpy is summarized in the following diagram:

│ └── LumiSpectrum
│ │ ├── CLSpectrum
│ │ │ ├── CLSEMSpectrum
│ │ │ └── CLSTEMSpectrum
│ │ ├── ELSpectrum
│ │ └── PLSpectrum
│ └── LumiTransient
└── hyperspy.signal.Signal2D

Where are we heading?

LumiSpy is under active development, and as a user-driven project, we welcome contributions (see Contributing) to the code and documentation from any other users.

Currrently, we have implemented the base functionality that extends HyperSpy’s capabilities to additional signal classes. In the near future, the following functions should be developed:

  • handling of transient (time-resolved) data,

  • reading of common PL data formats,

  • more dedicated analysis functionalities,

Non-uniform signal axes

LumiSpy facilitates the use of non-uniform axes, where the points of the axis vector are not uniformly spaced. This situation occurs in particular when converting a wavelength scale to energy (eV) or wavenumbers (e.g. for Raman shifts).

The conversion of the signal axis can be performed using the functions to_eV(), to_invcm() and to_raman_shift() (alias for to_invcm_relative()). If the unit of the signal axis is set, the functions can handle wavelengths in either nm or µm.

Accepted parameters are inplace=True/False (default is True), which determines whether the current signal object is modified or a new one is created, and jacobian=True/False (default is True, see Jacobian transformation).

The energy axis

The transformation from wavelength \lambda to energy E is defined as E = h c/ \lambda. Taking into account the refractive index of air and doing a conversion from nm to eV, we get:

E[eV] = \frac{10^9}{e}\frac{h c}{n_{air} \lambda[nm]},

where h is the Planck constant, c is the speed of light, e is the elementary charge and n_{air} is the refractive index of air, see also [Pfueller].

>>> s2 = s.to_eV(inplace=False)
>>> s.to_eV()

Note

The refractive index of air n_{air} is wavelength dependent. This dependence is taken into account by LumiSpy based on the analytical formula given by [Peck] valid from 185-1700 nm (outside of this range, the values of the refractive index at the edges of the range are used and a warning is raised).

The wavenumber axis/Raman shifts

The transformation from wavelength \lambda to wavenumber \tilde{\nu} (spatial frequency of the wave) is defined as \tilde{\nu} = 1/ \lambda. The wavenumber is usually given in units of \mathrm{cm}^{-1}.

When converting a signal to Raman shift, i.e. the shift in wavenumbers from the exciting laser wavelength, the laser wavelength has to be passed to the function using the parameter laser using the same units as for the original axis (e.g. 325 for nm or 0.325 for µm) unless it is contained in the LumiSpy metadata structure under Acquisition_instrument.Laser.wavelength.

TODO: Automatically read laser wavelength from metadata if given there.

>>> s2 = s.to_invcm(inplace=False)
>>> s.to_invcm()
>>> s2 = s.to_raman_shift(inplace=False, laser=325)
>>> s.to_raman_shift(laser=325)

Jacobian transformation

When transforming the signal axis, the signal intensity is automatically rescaled (Jacobian transformation), unless the jacobian=False option is given. Only converting the signal axis, and leaving the signal intensity unchanged, implies that the integral of the signal over the same interval would lead to different results depending on the quantity on the axis (see e.g. [Mooney] and [Wang]).

For the energy axis as example, if we require I(E)dE = I(\lambda)d\lambda, then E=hc/\lambda implies

I(E) = I(\lambda)\frac{d\lambda}{dE} = I(\lambda)\frac{d}{dE}
\frac{h c}{E} = - I(\lambda) \frac{h c}{E^2}

The minus sign just reflects the different directions of integration in the wavelength and energy domains. The same argument holds for the conversion from wavelength to wavenumber (just without the additional prefactors in the equation). The renormalization in LumiSpy is defined such that the intensity is converted from counts/nm (or counts/µm) to counts/meV. The following figure illustrates the effect of the Jacobian transformation:

Illustration of the Jacobian transformation from wavelength (nm) to energy (eV).
Transformation of the variance

Scaling the signal intensities implies that also the stored variance of the signal needs to be scaled accordingly. According to Var(aX) = a^2Var(X), the variance has to be multiplied with the square of the Jacobian. This squared renormalization is automatically performed by LumiSpy if jacobian=True. In particular, homoscedastic (constant) noise will consequently become heteroscedastic (changing as a function of the signal axis vector). Therefore, if the metadata.Signal.Noise_properties.variance attribute is a constant, it is converted into a hyperspy.signal.BaseSignal object before the transformation.

See Signal variance (noise) for more general information on data variance in the context of model fitting and the HyperSpy documentation on setting the noise properties.

Note

If the Jacobian transformation is performed, the values of metadata.Signal.Noise_properties.Variance_linear_model are reset to their default values (gain_factor=1, gain_offset=0 and correlation_factor=1). Should these values deviate from the defaults, make sure to run hyperspy.signal.BaseSignal.estimate_poissonian_noise_variance() prior to the transformation.

References

Pfueller

C. Pfüller, Dissertation, HU Berlin, p. 28 (2011). doi:10.18452/16360

Peck

E.R. Peck and K. Reeder, J. Opt. Soc. Am. 62, 958 (1972). doi:10.1364/JOSA.62.000958

Mooney

J. Mooney and P. Kambhampati, The Journal of Physical Chemistry Letters 4, 3316 (2013). doi:10.1021/jz401508t

Wang

Y. Wang and P. D. Townsend, J. Luminesc. 142, 202 (2013). doi:10.1016/j.jlumin.2013.03.052

Fitting luminescence data

LumiSpy is compatible with HyperSpy model fitting. It can fit using both uniform and and non-uniform axes (e.g. energy scale). A general introduction can be found in the HyperSpy user guide.

TODO: Note on advantages of fitting signals in the eV axis (not restricted to Gaussians). See e.g. [Wang]__

TODO: Show how to extract the modeled signal with all/one component.

See also the LumiSpy demo notebooks for examples of data fitting.

Signal variance (noise)

TODO: Documentation on variance handling in the context of fitting, in particular using hyperspy.signal.BaseSignal.estimate_poissonian_noise_variance()

References

Utility functions

This section summarizes various useful functions implemented in LumiSpy.

Join spectra

In case several spectra (or spectral images) where subsequently recorded for different, but overlapping spectral windows, LumiSpy provides a utility join_spectra() to merge these into a single spectrum. The main argument is a list of two or more spectral objects. Spectra are joined at the centre of the overlapping range along the signal axis. To avoid steps in the intensity, several parameters (see docstring: join_spectra()) allow to tune the scaling of the later signals with respect to the previous ones. By default, the scaling parameter is determined as average ratio between the two signals in the range of +/- 50 pixels around the centre of the overlapping region.

>>> import lumispy as lum
>>> s = lum.join_spectra((s1,s2))

Scaling and normalizing signal data

For comparative plotting or a detailed analysis, the intensity of spectra may need to be either scaled by the respective integration times or normalized. The luminescence signal classes provide these functionalities in the methods scale_by_exposure() and normalize().

Both functions can operate directly on the signal (inplace=True), but as default a new signal is returned.

The scaling function can use the integration_time (unit: seconds) provided in the LumiSpy metadata structure (metadata.Acqusition_instrument.Detector.integration_time). Otherwise, the appropriate parameter has to be passed to the function.

>>> scaled = s.scale_by_exposure(integration_time=0.5, inplace=True)

Normalization is performed for the pixel with maximum intensity, Alternatively, the parameter pos in calibrated units of the signal axis can be given to normalize the intensity at this position. Normalization may be convenient for plotting, but should usually not be performed on signals used as input for further analysis (therefore the default is inplace=False).

>>> s.normalize(pos=450)

Replacing negative data values

Log-scale plotting fails in the presence of negative values in the dataset (e.g. introduced after background removal). In this case, the utility function remove_negative() replaces all negative values in the data array by a basevalue (default basevalue=1). The default operational mode is inplace=False (a new signal object is returned).

>>> s.remove_negative(0.1)

Utilities for spectral maps

The function crop_edges() removes the specified number of pixels from all four edges of a spectral map. It is a convenience wrapper for the inav method in HyperSpy.

>>> s.crop_edges(crop_px=2)

[TODO: add possibility to crop different amounts of pixels on different sides]

Unit conversion

For convenience, LumiSpy provides functions that convert between different units commonly used for the signal axis. Namely,

For the energy axis, the conversion uses the wavelength-dependent refractive index of air.

Solving the grating equation

The function solve_grating_equation() follows the conventions described in the tutorial from Horiba Scientific.

LumiSpy metadata structure

LumiSpy extends the HyperSpy metadata structure with conventions for metadata specific to its signal types. Refer to the HyperSpy metadata documentation for general metadata fields.

The metadata of any signal objects is stored in the metadata attribute, which has a tree structure. By convention, the node labels are capitalized and the ones for leaves are not capitalized. When a leaf contains a quantity that is not dimensionless, the units can be given in an extra leaf with the same label followed by the _units suffix.

Besides directly accesing the metadata tree structure, e.g. s.metadata.Signal.signal_type, the HyperSpy methods hyperspy.misc.utils.DictionaryTreeBrowser.set_item(), hyperspy.misc.utils.DictionaryTreeBrowser.has_item() and hyperspy.misc.utils.DictionaryTreeBrowser.get_item() can be used to add to, search for and read from items in the metadata tree, respectively.

The luminescence specific metadata structure is represented in the following tree diagram. The default units are given in parentheses. Details about the leaves can be found in the following sections of this chapter. Note that not all types of leaves will apply to every type of measurement. For example, while parallel acquisition with a CCD is characterized by the central_wavelength, a serial acquisition with a PMT will require a start_wavelength and a step_size.

metadata
├── General
│   └── # see HyperSpy
├── Sample
│   └── # see HyperSpy
├── Signal
│   ├── signal_type
│   ├── quantity
│   └── # otherwise see HyperSpy
└── Acquisition_instrument
    ├── Laser / SEM / TEM
    │   ├── laser_type
    │   ├── model
    │   ├── wavelength (nm)
    │   ├── power (mW)
    │   ├── objective_magnification
    │   ├── Filter
    │   │   ├── filter_type
    │   │   ├── position
    │   │   ├── optical_density
    │   │   ├── cut_on_wavelength (nm)
    │   │   └── cut_off_wavelength (nm)
    │   └── # for SEM/TEM see HyperSpy
    ├── Spectrometer
    │   ├── model
    │   ├── acquisition_mode
    │   ├── entrance_slit_width (mm)
    │   ├── exit_slit_width (mm)
    │   ├── central_wavelength (nm)
    │   ├── start_wavelength (nm)
    │   ├── step_size (nm)
    │   ├── Grating
    │   │   ├── groove_density (grooves/mm)
    │   │   ├── blazing_angle (º)
    │   │   └── blazing_wavelength (nm)
    │   └── Filter
    │       ├── filter_type
    │       ├── position
    │       ├── optical_density
    │       ├── cut_on_wavelength (nm)
    │       └── cut_off_wavelength (nm)
    ├── Detector
    │   ├── detector_type
    │   ├── model
    │   ├── frames
    │   ├── integration_time (s)
    │   ├── saturation_fraction
    │   ├── binning
    │   ├── processing
    │   ├── sensor_roi
    │   └── pixel_size (µm)
    └── Spectral_image
        ├── mode
        ├── drift_correction_periodicity
        └── drift_correction_units (s)

General

See HyperSpy-Metadata-General.

Sample

See HyperSpy-Metadata-Sample.

Signal

signal_type

type: string

String that describes the type of signal. The LumiSpy specific signal classes are summarized under Signal types.

quantity

type: string

The name of the quantity of the “intensity axis” with the units in round brackets if required, for example ‘Intensity (counts/s)’.

See HyperSpy-Metadata-Signal for additional fields.

Acquisition Instrument

Laser / SEM / TEM

For SEM or TEM see HyperSpy-Metadata-SEM or HyperSpy-Metadata-TEM.

Laser
laser_type

type: string

The type of laser used, e.g. ‘HeCd’.

model

type: string

Model of the laser (branding by manufacturer).

wavelength

type: float

Emission wavelength of the exciting laser in nm.

power

type: float

Measured power of the excitation laser in mW.

magnification

type: int

Magnification of the microscope objective used to focus the beam to the sample.

Filter

Information about additional filters entered into the lightpath before the sample. In case multiple filters are used, they should be numbered Filter_1, etc.

filter_type

type: string

Type of filter (e.g. ‘optical density’, ‘short pass’, ‘long pass’, ‘bandpass’, ‘color’).

position

type: string

Position in the beam (e.g. ‘excitation’ vs. ‘detection’ in case of optical excitation).

optical_density

type: float

Optical density in case of an intensity filter.

cut_on_wavelength

type: float

Cut on wavelength in nm in case of a long-pass or bandpass filter.

cut_off_wavelength

type: float

Cut off wavelength in nm in case of a short-pass or bandpass filter.

Spectrometer

Contains information about the spectrometer, configuration and grating used for the measurement. In case multiple spectrometers are connected in series, they should be numbered Spectrometer_1, etc.

model

type: string

Model of the spectrometer (branding by manufacturer).

acquisition_mode

type: string

Acquisition mode (e.g. ‘Parallel dispersive’, versus ‘Serial dispersive’).

entrance_slit_width

type: float

Width of the entrance slit in mm.

exit_slit_width

type: float

Width of the exit slit (serial acquisition) in mm.

central_wavelength

type: float

Central wavelength during acquisition (parallel acquisition).

start_wavelength

type: float

Start wavelength in nm (serial acquisition).

step_size

type: float

Step size in nm (serial acquisition).

Grating

Information of the dispersion grating employed in the measurement.

groove_density

type: int

Density of lines on the grating in grooves/mm.

blazing_angle

type: int

Angle in degree (º) that the grating is blazed at.

blazing_wavelength

type: int

Wavelength that the grating blaze is optimized for in nm.

Filter

Information about additional filters entered into the lightpath after the sample. In case multiple filters are used, they should be numbered Filter_1, etc. See Filter above for details on items that may potentially be included.

Detector

Contains information about the detector used to acquire the signal. Contained leaves will differ depending on the type of detector.

detector_type

type: string

The type of detector used to acquire the signal (CCD, PMT, StreakCamera, TCSPD).

model

type: string

The model of the used detector.

frames

type: int

Number of frames that are summed to yield the total integration time.

integration_time (s)

type: float

Time over which the signal is integrated. In case multiple frames are summed, it is the total exposure time. In case of serial acquisition, it is the dwell time per data point.

saturation_fraction

type: float

Fraction of the signal intensity compared with the saturation threshold of the CCD.

binning

type: tuple of int

A tuple that describes the binning of a parallel detector such a CCD on readout in x and y directions.

processing

type: string

Information about automatic processing performed on the data, e.g. ‘dark subtracted’.

sensor_roi

type: tuple of int

Tuple of length 2 or 4 that specifies range of pixels on a detector that are read out: (offset x, offset y, size x, size y) for a 2D array detector and (offset, size) for a 1D line detector.

pixel_size

type: float or tuple of float

Size of a pixel in µm. Tuple of length 2 (width, height), when the pixel is not square.

Spectral_image

Contains information about mapping parameters, such as step size, drift correction, etc.

mode

type: string

Mode of the spectrum image acquisition such as ‘Map’ or ‘Linescan’.

drift_correction_periodicity

type: int/float

Periodicity of the drift correction in specified units (standard s).

drift_correction_units

type: string

Units of the drift correction such as ‘s’, ‘px’, ‘rows’.

lumispy

lumispy package

Subpackages
lumispy.signals package
Submodules
lumispy.signals.cl_spectrum module
Signal class for cathodoluminescence spectral data
class lumispy.signals.cl_spectrum.CLSEMSpectrum(*args, **kwargs)

Bases: CLSpectrum

1D scanning electron microscopy cathodoluminescence signal class.

correct_grating_shift(cal_factor_x_axis, corr_factor_grating, sem_magnification, **kwargs)

Applies shift caused by the grating offset wrt the scanning centre. Authorship: Gunnar Kusch (gk419@cam.ac.uk)

Parameters
  • cal_factor_x_axis – The navigation correction factor.

  • corr_factor_grating – The grating correction factor.

  • sem_magnification – The SEM (real) magnification value. For the Attolight original metadata, take the SEM.Real_Magnification value

  • kwargs – The parameters passed to hyperspy.align1D() function like: interpolation_method (‘linear’, ‘nearest’, ‘zero’, ‘slinear’, ‘quadratic, ‘cubic’) parallel: Bool crop, expand, fill_value …

class lumispy.signals.cl_spectrum.CLSTEMSpectrum(*args, **kwargs)

Bases: CLSpectrum

1D scanning transmission electron microscopy cathodoluminescence signal class.

class lumispy.signals.cl_spectrum.CLSpectrum(*args, **kwargs)

Bases: LumiSpectrum

General 1D cathodoluminescence signal class.

_make_signal_mask(luminescence_roi)

Creates a mask from the peak position and peak widths of the luminescence spectrum.

Parameters

luminescence_roi (array) – In the form of an array of pairwise elements [[peak1_x, peak1_width], [peak2_x, peak2_width],…].

Returns

A signal_mask.

Return type

array

remove_spikes(threshold='auto', show_diagnosis_histogram=False, inplace=False, luminescence_roi=None, signal_mask=None, add_noise=False, navigation_mask=None, interactive=False, **kwargs)

HyperSpy-based spike removal tool adapted to LumiSpy to run non-interactively and without noise addition by default. Graphical interface to remove spikes from EELS spectra or luminescence data. If non-interactive, it removes all spikes and returns a ~hyperspy.signals._signal_tools.SpikesRemoval object.

Parameters
  • signal_mask (bool array) – Restricts the operation to the signal locations not marked as True (masked).

  • navigation_mask (bool array) – Restricts the operation to the navigation locations not marked as True (masked).

  • threshold ('auto' or int) – if int set the threshold value use for the detecting the spikes. If auto, determine the threshold value as being the first zero value in the histogram obtained from the spikes_diagnosis() method.

  • interactive (bool) – If True, remove the spikes using the graphical user interface. If False, remove all the spikes automatically, which can introduce artefacts if used with signal containing peak-like features. However, this can be mitigated by using the signal_mask argument to mask the signal of interest.

  • display (bool) – If True, display the user interface widgets. If False, return the widgets container in a dictionary, usually for customisation or testing.

  • toolkit (str, iterable of strings or None) – If None (default), all available widgets are displayed or returned. If string, only the widgets of the selected toolkit are displayed if available. If an interable of toolkit strings, the widgets of all listed toolkits are displayed or returned.

  • **kwargs (dict) –

    Keyword arguments pass to

    SpikesRemoval()

See also

spikes_diagnosis()

Parameters
  • show_diagnosis_histogram (bool) – Plot or not the derivative histogram to show the magnitude of the spikes present.

  • inplace (bool) – If False, a new signal object is created and returned. If True, the original signal object is modified.

  • luminescence_roi (array) – The peak position and peak widths of the peaks in the luminescence spectrum. In the form of an array of pairwise elements [[peak1_x, peak1_width], [peak2_x, peak2_width],…] in the units of the signal axis. It creates a signal_mask protecting the peak regions. To be used instead of signal_mask.

Returns

Depends on inplace, returns or overwrites the CLSpectrum after spike removal.

Return type

None or CLSpectrum

class lumispy.signals.cl_spectrum.LazyCLSEMSpectrum(*args, **kwargs)

Bases: LazySignal, CLSEMSpectrum

Lazy 1D scanning electron microscopy cathodoluminescence signal class.

class lumispy.signals.cl_spectrum.LazyCLSTEMSpectrum(*args, **kwargs)

Bases: LazySignal, CLSTEMSpectrum

Lazy 1D scanning transmission electron microscopy cathodoluminescence signal class.

class lumispy.signals.cl_spectrum.LazyCLSpectrum(*args, **kwargs)

Bases: LazySignal, CLSpectrum

General lazy 1D cathodoluminescence signal class.

lumispy.signals.common_luminescence module
Signal class for luminescence data (BaseSignal class)
class lumispy.signals.common_luminescence.CommonLumi

Bases: object

General luminescence signal class (dimensionless)

crop_edges(crop_px)

Crop the amount of pixels from the four edges of the scanning region, from out the edges inwards.

Parameters

crop_px (int) – Amount of pixels to be cropped on each side individually.

Returns

signal_cropped – A smaller cropped CL signal object. If inplace is True, the original object is modified and no LumiSpectrum is returned.

Return type

CommonLuminescence

normalize(pos=nan, element_wise=False, inplace=False)

Normalizes data to value at pos along signal axis, defaults to maximum value.

Can be helpful for e.g. plotting, but does not make sense to use on signals that will be used as input for further calculations!

Parameters
  • pos (float, int) – If ‘nan’ (default), spectra are normalized to the maximum. If float, position along signal axis in calibrated units at which to normalize the spectra. If int, index along signal axis at which to normalize the spectra.

  • element_wise (boolean) – If False (default), a spectrum image is normalized by a common factor. If True, each spectrum is normalized individually.

  • inplace (boolean) – If False (default), a new signal object is created and returned. If True, the operation is performed on the existing signal object.

Notes

Sets metadata.Signal.normalized to True. If metadata.Signal.quantity contains the word ‘Intensity’, replaces this field with ‘Normalized intensity’.

remove_negative(basevalue=1, inplace=False)

Sets all negative values to ‘basevalue’, e.g. for logarithmic scale plots.

Parameters
  • basevalue (float) – Value by which negative values are replaced (default = 1).

  • inplace (boolean) – If False (default), a new signal object is created and returned. Otherwise, the operation is performed on the existing signal object.

Notes

Sets metadata.Signal.negative_removed to True.

scale_by_exposure(integration_time=None, inplace=False, **kwargs)

Scale data in spectrum by integration time / exposure, (e.g. convert counts to counts/s).

Parameters
  • integration_time (float) – Integration time (exposure) in s. If not given, the function tries to use the ‘metadata.Acqusition_instrument.Detector.integration_time’ field or alternatively find any ‘integration_time’, ‘exposure’ or ‘dwell_time’ fields in the original_metadata.

  • inplace (boolean) – If False (default), a new signal object is created and returned. If True, the operation is performed on the existing signal object.

Notes

Sets metadata.Signal.scaled to True. If intensity units is ‘counts’, replaces them by ‘counts/s’.

Deprecated since version 0.2: The exposure argument was renamed integration_time, and it will be removed in LumiSpy 1.0.

lumispy.signals.common_transient module
Signal class for transient data (BaseSignal class)
class lumispy.signals.common_transient.CommonTransient

Bases: object

General transient signal class (dimensionless)

lumispy.signals.el_spectrum module
Signal class for electroluminescence spectral data
class lumispy.signals.el_spectrum.ELSpectrum(*args, **kwargs)

Bases: LumiSpectrum

General 1D electroluminescence signal class

class lumispy.signals.el_spectrum.LazyELSpectrum(*args, **kwargs)

Bases: LazySignal, ELSpectrum

General lazy 1D electroluminescence signal class

lumispy.signals.luminescence_spectrum module

Signal class for Luminescence spectral data (1D).

class lumispy.signals.luminescence_spectrum.LazyLumiSpectrum(*args, **kwargs)

Bases: LazySignal, LumiSpectrum

General lazy 1D luminescence signal class.

class lumispy.signals.luminescence_spectrum.LumiSpectrum(*args, **kwargs)

Bases: Signal1D, CommonLumi

General 1D luminescence signal class.

_convert_data(newaxis, factor, inplace, jacobian, data2, var2)

Utility function to perform the data and variance conversion for signal unit transformations.

_reset_variance_linear_model()

Resets the variance linear model parameters to their default values, as they are not applicable any longer after a Jacobian transformation.

centroid(slice=None, npeaks=1)

Finds the centroid (center of mass) of a peak in the spectrum from the wavelength (or pixel number) and the intensity at each pixel value. It basically represents a “weighted average” of the peak. NOTE: This function only works for a single peak. If you have multiple peaks, slice the signal beforehand or use the slice parameter. TODO: Implement this function for multiple peaks (npeaks = 2) by finding the top 2 peaks from mean spectrum and then returning a signal with 2 com.

Parameters

slice (tuple (2)) – An tuple representing the indices of the wavelength (start index, end index) where the peak is located. If the tuple contains int, it slices on index. Ig the tuple contains float, it slices on signal units (defualt hyperspy s.inav[:] functionality).

Returns

signal – A signal containing the center of mass for each navigation pixel.

Return type

Signal1D

px_to_nm_grating_solver(gamma_deg, deviation_angle_deg, focal_length_mm, ccd_width_mm, grating_central_wavelength_nm, grating_density_gr_mm, inplace=False)

Converts signal axis of 1D signal (in pixels) to wavelength, solving the grating equation. See lumispy.axes.solve_grating_equation for more details.

Parameters
  • gamma_deg (float) – Inclination angle between the focal plane and the centre of the grating (found experimentally from calibration). In degree.

  • deviation_angle_deg (float) – Also known as included angle. It is defined as the difference between angle of diffraction (\beta) and angle of incidence (\alpha). Given by manufacturer specsheet. In degree.

  • focal_length_mm (float) – Given by manufacturer specsheet. In mm.

  • ccd_width_mm (float) – The width of the CDD. Given by manufacturer specsheet. In mm.

  • grating_central_wavelength_nm (float) – Wavelength at the centre of the grating, where exit slit is placed. In nm.

  • grating_density_gr_mm (int) – Grating density in gratings per mm.

  • inplace (bool) – If False, it returns a new object with the transformation. If True, the original object is transformed, returning no object.

Returns

signal – A signal with calibrated wavelength units.

Return type

LumiSpectrum

Examples

>>> s = LumiSpectrum(np.ones(20),))
>>> s.px_to_nm_grating_solver(*params, inplace=True)
>>> s.axes_manager.signal_axes[0].units == 'nm'
remove_background_from_file(background=None, inplace=False, **kwargs)

Subtract the background to the signal in all navigation axes. If no background file is passed as argument, the remove_background() from HyperSpy is called with the GUI.

Parameters
  • background (array shape (2, n) or Signal1D) – An array containing the background x-axis and the intensity values [[xs],[ys]] or a Signal1D object. If the x-axis values do not match the signal_axes, then interpolation is done before subtraction. If only the intensity values are provided, [ys], the functions assumes no interpolation needed.

  • inplace (boolean) – If False, it returns a new object with the transformation. If True, the original object is transformed, returning no object.

Returns

signal – A background subtracted signal.

Return type

LumiSpectrum

Notes

This function does not work with non-uniform axes.

savetxt(filename, fmt='%.5f', delimiter='\t', axes=True, transpose=False, **kwargs)

Writes luminescence spectrum object to simple text file.

Writes single spectra to a two-column data file with signal axis as X and data as Y. Writes linescan data to file with signal axis as first row and navigation axis as first column (flipped if transpose=True).

Parameters
  • filename (string) –

  • fmt (str or sequence of strs, optional) – A single or sequence of format strings. Default is ‘%.5f’.

  • delimiter (str, optional) – String or character separating columns. Default is ‘,’

  • axes (bool, optional) – If True (default), include axes in saved file. If False, save the data array only.

  • transpose (bool, optional) – If True, transpose data array and exchange axes. Default is false. Ignored for single spectra.

  • **kwargs – Takes any additional arguments of numpy.loadtxt, e.g. newline header, footer, comments, or encoding.

See also

numpy.savetxt

Examples

>>> import lumispy as lum
>>> import numpy as np
...
>>> # Spectrum:
>>> S = lum.signals.LumiSpectrum(np.arange(5))
>>> S.savetxt('spectrum.txt')
0.00000     0.00000
1.00000     1.00000
2.00000     2.00000
3.00000     3.00000
4.00000     4.00000
...
>>> # Linescan:
>>> L = lum.signals.LumiSpectrum(np.arange(25).reshape((5,5)))
>>> L.savetxt('linescan.txt')
0.00000     0.00000 1.00000 2.00000 3.00000 4.00000
0.00000     0.00000 5.00000 10.00000        15.00000        20.00000
1.00000     1.00000 6.00000 11.00000        16.00000        21.00000
2.00000     2.00000 7.00000 12.00000        17.00000        22.00000
3.00000     3.00000 8.00000 13.00000        18.00000        23.00000
4.00000     4.00000 9.00000 14.00000        19.00000        24.00000
to_array(axes=True, transpose=False)
Returns luminescence spectrum object as numpy array (optionally

including the axes).

Returns single spectra as two-column array. Returns linescan data as array with signal axis as first row and navigation axis as first column (flipped if transpose=True).

Parameters
  • axes (bool, optional) – If True (default), include axes in array. If False, return the data array only.

  • transpose (bool, optional) – If True, transpose data array and exchange axes. Default is false. Ignored for single spectra.

  • **kwargs – Takes any additional arguments of numpy.loadtxt, e.g. newline header, footer, comments, or encoding.

Notes

The output of this function can be used to convert a signal object to a pandas dataframe, e.g. using df = pd.Dataframe(S.to_array()).

Examples

>>> import lumispy as lum
>>> import numpy as np
...
>>> # Spectrum:
>>> S = lum.signals.LumiSpectrum(np.arange(5))
>>> S.to_array()
array([[0., 0.],
      [1., 1.],
      [2., 2.],
      [3., 3.],
      [4., 4.]])
...
>>> # Linescan:
>>> L = lum.signals.LumiSpectrum(np.arange(25).reshape((5,5)))
>>> L.to_array()
array([[ 0.,  0.,  1.,  2.,  3.,  4.],
      [ 0.,  0.,  1.,  2.,  3.,  4.],
      [ 1.,  5.,  6.,  7.,  8.,  9.],
      [ 2., 10., 11., 12., 13., 14.],
      [ 3., 15., 16., 17., 18., 19.],
      [ 4., 20., 21., 22., 23., 24.]])
to_eV(inplace=True, jacobian=True)

Converts signal axis of 1D signal to non-linear energy axis (eV) using wavelength dependent refractive index of air. Assumes wavelength in units of nm unless the axis units are specifically set to µm.

The intensity is converted from counts/nm (counts/µm) to counts/meV by doing a Jacobian transformation, see e.g. Mooney and Kambhampati, J. Phys. Chem. Lett. 4, 3316 (2013), doi:10.1021/jz401508t, which ensures that integrated signals are correct also in the energy domain. If the variance of the signal is known, i.e. metadata.Signal.Noise_properties.variance is a signal representing the variance, a squared renormalization of the variance is performed. Note that if the variance is a number (not a signal instance), it is converted to a signal if the Jacobian transformation is performed

Parameters
  • inplace (boolean) – If False, a new signal object is created and returned. Otherwise (default) the operation is performed on the existing signal object.

  • jacobian (boolean) – The default is to do the Jacobian transformation (recommended at least for luminescence signals), but the transformation can be suppressed by setting this option to False.

Examples

>>> import numpy as np
>>> from lumispy import LumiSpectrum
>>> S1 = LumiSpectrum(np.ones(20), DataAxis(axis = np.arange(200,400,10)), ))
>>> S1.to_eV()
to_invcm(inplace=True, jacobian=True)

Converts signal axis of 1D signal to non-linear wavenumber axis (cm^-1). Assumes wavelength in units of nm unless the axis units are specifically set to µm.

The intensity is converted from counts/nm (counts/µm) to counts/cm^-1 by doing a Jacobian transformation, see e.g. Mooney and Kambhampati, J. Phys. Chem. Lett. 4, 3316 (2013), doi:10.1021/jz401508t, which ensures that integrated signals are correct also in the wavenumber domain. If the variance of the signal is known, i.e. metadata.Signal.Noise_properties.variance is a signal representing the variance, a squared renormalization of the variance is performed. Note that if the variance is a number (not a signal instance), it is converted to a signal if the Jacobian transformation is performed

Parameters
  • inplace (boolean) – If False, a new signal object is created and returned. Otherwise (default) the operation is performed on the existing signal object.

  • jacobian (boolean) – The default is to do the Jacobian transformation (recommended at least for luminescence signals), but the transformation can be suppressed by setting this option to False.

Examples

>>> import numpy as np
>>> from lumispy import LumiSpectrum
>>> S1 = LumiSpectrum(np.ones(20), DataAxis(axis = np.arange(200,400,10)), ))
>>> S1.to_invcm()
to_invcm_relative(laser=None, inplace=True, jacobian=False)

Converts signal axis of 1D signal to non-linear wavenumber axis (cm^-1) relative to the exciting laser wavelength (Raman/Stokes shift). Assumes wavelength in units of nm unless the axis units are specifically set to µm.

The intensity is converted from counts/nm (counts/µm) to counts/cm^-1 by doing a Jacobian transformation, see e.g. Mooney and Kambhampati, J. Phys. Chem. Lett. 4, 3316 (2013), doi:10.1021/jz401508t, which ensures that integrated signals are correct also in the wavenumber domain. If the variance of the signal is known, i.e. metadata.Signal.Noise_properties.variance is a signal representing the variance, a squared renormalization of the variance is performed. Note that if the variance is a number (not a signal instance), it is converted to a signal if the Jacobian transformation is performed

Parameters
  • inplace (boolean) – If False, a new signal object is created and returned. Otherwise (default) the operation is performed on the existing signal object.

  • laser (float or None) – Laser wavelength in the same units as the signal axis. If None (default), checks if it is stored in metadata.Acquisition_instrument.Laser.wavelength.

  • jacobian (boolean) – The default is not to do the Jacobian transformation for Raman shifts, but the transformation can be activated by setting this option to True.

Examples

>>> import numpy as np
>>> from lumispy import LumiSpectrum
>>> S1 = LumiSpectrum(np.ones(20), DataAxis(axis = np.arange(200,400,10)), ))
>>> S1.to_invcm(laser=325)
to_raman_shift(laser=None, inplace=True, jacobian=False)

Converts signal axis of 1D signal to non-linear wavenumber axis (cm^-1) relative to the exciting laser wavelength (Raman/Stokes shift). Assumes wavelength in units of nm unless the axis units are specifically set to µm.

The intensity is converted from counts/nm (counts/µm) to counts/cm^-1 by doing a Jacobian transformation, see e.g. Mooney and Kambhampati, J. Phys. Chem. Lett. 4, 3316 (2013), doi:10.1021/jz401508t, which ensures that integrated signals are correct also in the wavenumber domain. If the variance of the signal is known, i.e. metadata.Signal.Noise_properties.variance is a signal representing the variance, a squared renormalization of the variance is performed. Note that if the variance is a number (not a signal instance), it is converted to a signal if the Jacobian transformation is performed

Parameters
  • inplace (boolean) – If False, a new signal object is created and returned. Otherwise (default) the operation is performed on the existing signal object.

  • laser (float or None) – Laser wavelength in the same units as the signal axis. If None (default), checks if it is stored in metadata.Acquisition_instrument.Laser.wavelength.

  • jacobian (boolean) – The default is not to do the Jacobian transformation for Raman shifts, but the transformation can be activated by setting this option to True.

Examples

>>> import numpy as np
>>> from lumispy import LumiSpectrum
>>> S1 = LumiSpectrum(np.ones(20), DataAxis(axis = np.arange(200,400,10)), ))
>>> S1.to_invcm(laser=325)
lumispy.signals.luminescence_transient module
Signal class for luminescence transient data (1D)
class lumispy.signals.luminescence_transient.LazyLumiTransient(*args, **kwargs)

Bases: LazySignal, LumiTransient

General lazy 1D luminescence signal class (transient/time resolved)

class lumispy.signals.luminescence_transient.LumiTransient(*args, **kwargs)

Bases: Signal1D, CommonTransient

General 1D luminescence signal class (transient/time resolved)

lumispy.signals.luminescence_transientspec module
Signal class for luminescence transient data (2D)
class lumispy.signals.luminescence_transientspec.LazyLumiTransientSpectrum(*args, **kwargs)

Bases: LazySignal, LumiTransientSpectrum

General lazy 2D luminescence signal class (transient/time resolved)

class lumispy.signals.luminescence_transientspec.LumiTransientSpectrum(*args, **kwargs)

Bases: Signal2D, CommonLumi, CommonTransient

General 2D luminescence signal class (transient/time resolved)

lumispy.signals.pl_spectrum module
Signal class for Photoluminescence spectral data
class lumispy.signals.pl_spectrum.LazyPLSpectrum(*args, **kwargs)

Bases: LazySignal, PLSpectrum

General lazy 1D photoluminescence signal class

class lumispy.signals.pl_spectrum.PLSpectrum(*args, **kwargs)

Bases: LumiSpectrum

General 1D photoluminescence signal class

Module contents
lumispy.utils package
Submodules
lumispy.utils.axes module
lumispy.utils.axes._n_air(x)

Refractive index of air as a function of WL in nm. This analytical function is correct for the range 185-1700 nm. According to E.R. Peck and K. Reeder. Dispersion of air, J. Opt. Soc. Am. 62, 958-962 (1972).

lumispy.utils.axes.axis2eV(ax0)

Converts given signal axis to energy scale (eV) using wavelength dependent refractive index of air. Assumes wavelength in units of nm unless the axis units are specifically set to µm.

lumispy.utils.axes.axis2invcm(ax0)

Converts given signal axis to wavenumber scale (cm$^{-1}$). Assumes wavelength in units of nm unless the axis units are specifically set to µm.

lumispy.utils.axes.data2eV(data, factor, evaxis, ax0)

The intensity is converted from counts/nm (counts/µm) to counts/meV by doing a Jacobian transformation, see e.g. Mooney and Kambhampati, J. Phys. Chem. Lett. 4, 3316 (2013). Ensures that integrated signals are still correct.

lumispy.utils.axes.data2invcm(data, factor, invcmaxis, ax0=None)

The intensity is converted from counts/nm (counts/µm) to counts/cm$^{-1}$ by doing a Jacobian transformation, see e.g. Mooney and Kambhampati, J. Phys. Chem. Lett. 4, 3316 (2013). Ensures that integrated signals are still correct.

lumispy.utils.axes.eV2nm(x)

Converts energy (eV) to wavelength (nm) using wavelength-dependent refractive index of air.

lumispy.utils.axes.invcm2nm(x)

Converts wavenumber (cm$^{-1}$) to wavelength (nm).

lumispy.utils.axes.join_spectra(S, r=50, scale=True, average=False, kind='slinear')

Takes list of Signal1D objects and returns a single object with all spectra joined. Joins spectra at the center of the overlapping range. Scales spectra by a factor determined as average over the range center -/+ r pixels. Works both for uniform and non-uniform axes (FunctionalDataAxis is converted into a non-uniform DataAxis).

Parameters
  • S (list of Signal1D objects (with overlapping signal axes)) –

  • r (int, optional) – Number of pixels left/right of center (default 50) defining the range over which to determine the scaling factor, has to be less than half of the overlapping pixels. Change the size of r or use average=True if the function induces a step in the intensity.

  • scale (boolean, optional) – If True (default), the later spectra in the list are scaled by a factor determined over center -/+ r pixels. If False, spectra are joined without scaling, which will likely induce a step unless average=True.

  • average (boolean, optional) – If True, the contribution of the two signals is continuously graded within the range defined by r instead of joining at the center of the range (default).

  • kind (str, optional) – Interpolation method (default ‘slinear’) to use when joining signals with a uniform signal axes. See scipy.interpolate.interp1d for options.

Returns

  • A new Signal1D object containing the joined spectra (properties are copied

  • from first spectrum).

Examples

>>> s1 = hs.signals.Signal1D(np.ones(32))
>>> s2 = hs.signals.Signal1D(np.ones(32)*2)
>>> s2.axes_manager.signal_axes[0].offset = 25
>>> lum.join_spectra([s1,s2],r=2)
<Signal1D, title: , dimensions: (|57)>
lumispy.utils.axes.nm2eV(x)

Converts wavelength (nm) to energy (eV) using wavelength-dependent refractive index of air.

lumispy.utils.axes.nm2invcm(x)

Converts wavelength (nm) to wavenumber (cm$^{-1}$).

lumispy.utils.axes.solve_grating_equation(axis, gamma_deg, deviation_angle_deg, focal_length_mm, ccd_width_mm, grating_central_wavelength_nm, grating_density_gr_mm)

Solves the grating equation. See horiba.com/uk/scientific/products/optics-tutorial/wavelength-pixel-position for equations.

Parameters
  • axis (hyperspy.axis) – Axis in pixel units (no units) to convert to wavelength.

  • gamma_deg (float) – Inclination angle between the focal plane and the centre of the grating (found experimentally from calibration). In degree.

  • deviation_angle_deg (float) – Also known as included angle. It is defined as the difference between angle of diffraction (\beta) and angle of incidence (\alpha). Given by manufacturer specsheet. In degree.

  • focal_length_mm (float) – Given by manufacturer specsheet. In mm.

  • ccd_width_mm (float) – The width of the CDD. Given by manufacturer specsheet. In mm.

  • grating_central_wavelength_nm (float) – Wavelength at the centre of the grating, where exit slit is placed. In nm.

  • grating_density_gr_mm (int) – Grating density in gratings per mm.

Returns

axis – HyperSpy axis object.

Return type

hyperspy.axis

lumispy.utils.axes.var2eV(variance, factor, evaxis, ax0)

The variance is converted doing a squared Jacobian renormalization to match with the transformation of the data.

lumispy.utils.axes.var2invcm(variance, factor, invcmaxis, ax0=None)

The variance is converted doing a squared Jacobian renormalization to match with the transformation of the data.

lumispy.utils.io module
lumispy.utils.io.savetxt(S, filename, fmt='%.5f', delimiter='\t', axes=True, transpose=False, **kwargs)

Writes signal object to simple text file.

Writes single spectra to a two-column data file with signal axis as X and data as Y. Writes linescan data to file with signal axis as first row and navigation axis as first column (flipped if transpose=True). Writes image to file with the navigation axes as first column and first row. Writes 2D data (e.g. map of a fit parameter value) to file with the signal axes as first column and first row.

Parameters
  • filename (string) –

  • fmt (str or sequence of strs, optional) – A single or sequence of format strings. Default is ‘%.5f’.

  • delimiter (str, optional) – String or character separating columns. Default is ‘,’

  • axes (bool, optional) – If True (default), include axes in saved file. If False, save the data array only.

  • transpose (bool, optional) – If True, transpose data array and exchange axes. Default is false. Ignored for single spectra.

  • **kwargs – Takes any additional arguments of numpy.loadtxt, e.g. newline header, footer, comments, or encoding.

See also

numpy.savetxt

Examples

>>> import lumispy as lum
>>> import numpy as np
...
>>> # Spectrum:
>>> S = lum.signals.LumiSpectrum(np.arange(5))
>>> lum.savetxt(S, 'spectrum.txt')
0.00000     0.00000
1.00000     1.00000
2.00000     2.00000
3.00000     3.00000
4.00000     4.00000
...
>>> # Linescan:
>>> L = lum.signals.LumiSpectrum(np.arange(25).reshape((5,5)))
>>> lum.savetxt(L, 'linescan.txt')
0.00000     0.00000 1.00000 2.00000 3.00000 4.00000
0.00000     0.00000 5.00000 10.00000        15.00000        20.00000
1.00000     1.00000 6.00000 11.00000        16.00000        21.00000
2.00000     2.00000 7.00000 12.00000        17.00000        22.00000
3.00000     3.00000 8.00000 13.00000        18.00000        23.00000
4.00000     4.00000 9.00000 14.00000        19.00000        24.00000
lumispy.utils.io.to_array(S, axes=True, transpose=False)

Returns signal object as numpy array (optionally including the axes).

Returns single spectra as two-column array. Returns linescan data as array with signal axis as first row and navigation axis as first column (flipped if transpose=True). Returns image as array with the navigation axes as first column and first row. Returns 2D data (e.g. map of a fit parameter value) as array with the signal axes as first column and first row.

Parameters
  • axes (bool, optional) – If True (default), include axes in array. If False, return the data array only.

  • transpose (bool, optional) – If True, transpose data array and exchange axes. Default is false. Ignored for single spectra.

  • **kwargs – Takes any additional arguments of numpy.loadtxt, e.g. newline header, footer, comments, or encoding.

Notes

The output of this function can be used to convert a signal object to a pandas dataframe, e.g. using df = pd.Dataframe(lum.to_array(S)).

Examples

>>> import lumispy as lum
>>> import numpy as np
...
>>> # Spectrum:
>>> S = lum.signals.LumiSpectrum(np.arange(5))
>>> lum.to_array(S)
array([[0., 0.],
      [1., 1.],
      [2., 2.],
      [3., 3.],
      [4., 4.]])
...
>>> # Linescan:
>>> L = lum.signals.LumiSpectrum(np.arange(25).reshape((5,5)))
>>> lum.to_array(L)
array([[ 0.,  0.,  1.,  2.,  3.,  4.],
      [ 0.,  0.,  1.,  2.,  3.,  4.],
      [ 1.,  5.,  6.,  7.,  8.,  9.],
      [ 2., 10., 11., 12., 13., 14.],
      [ 3., 15., 16., 17., 18., 19.],
      [ 4., 20., 21., 22., 23., 24.]])
lumispy.utils.signals module
lumispy.utils.signals.com(spectrum_intensities, wavelengths)

Finds the centroid (center of mass) of a peak in the spectrum from the wavelength (or pixel number) and the intensity at each pixel value. :param spectrum_intensities: An array with the intensities of the spectrum. :type spectrum_intensities: array :param wavelengths: An array with the wavelength for each intensity value. :type wavelengths: array

Returns

center_of_mass – The centroid of the spectrum.

Return type

float

Examples

# Assume we have a spectrum with wavelengths and intensities >>> wavelengths = [200, 300, 400, 500, 600, 700] >>> intensities = [1, 2, 3, 2, 1, 0]

>>> center_of_mass = com(wavelengths, intensities)
>>> print(center_of_mass)  # Outputs: 450.0
Module contents
Module contents

Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

UNRELEASED

Changed

2022-11-02 - version 0.2.1

Added
  • Improved documentation

  • Use lgtm.com to check code integrity

Changed
  • Fix conversion to Raman shift (relative wavenumber) and make jacobian=False default; fix inplace=False for axis conversions

  • Fix to_eV and to_invcm, as slicing with .isig[] was failing on converted signals

  • s.remove_negative now defaults to inplace=False (previously True)

Maintenance
  • Use softprops/action-gh-release action instead of deprecated create-release, pin action to a commit SHA

2022-04-29 - version 0.2

Added
  • Set up read the docs documentation

  • Added metadata convention

  • Add proper handling of variance on Jacobian transformation during axis conversion (eV, invcm)

Changed
  • Account for the general availability of non-uniform axes with the HyperSpy v1.7 release

  • Make LumiTransient 1D and add 2D LumiTransientSpectrum class

  • Add python 3.10 build, remove python 3.6

  • Fix error in background dimensions that allows compatibility for updated map in HyperSpy (failing integration tests)

  • Fix for links in PyPi

  • Deprecate exposure argument of s.scale_by_exposure in favor of integration_time in line with metadata convention

  • Add deprecation warning to remove_background_from_file

2021-11-23 - version 0.1.3

Changed
  • Mentions of the now deleted non_uniform_axes branch in HyperSpy updated to RELEASE_next_minor

  • Change ‘master’ to ‘main’ branch

  • Updated/corrected badges and other things in README.md and other documentation files

2021-08-22 - version 0.1.2

Added
  • This project now keeps a Changelog

  • Added signal-hierarchy for time-resolved luminescence

  • Added GitHub action for release

  • Created logo

Changed
  • Consistent black-formatting

  • fixed join_spectra

  • fixed tests

2021-03-26 - version 0.1

Added
  • The first release, basic functionality implemented

Citing LumiSpy

LumiSpy is maintained by an active community of developers.

If LumiSpy has been significant to a project that leads to an academic publication, please acknowledge that fact by citing it. The DOI in the badge below is the Concept DOI – it can be used to cite the project without referring to a specific version. If you are citing LumiSpy because you have used it to process data, please use the DOI of the specific version that you have employed. You can find it by clicking on the DOI badge below:

https://zenodo.org/badge/DOI/10.5281/zenodo.4640445.svg

Contributing

LumiSpy is meant to be a community maintained project. We welcome contributions in the form of bug reports, documentation, code, feature requests, and more. In the following we refer to some resources to help you make useful contributions.

Issues

The issue tracker can be used to report bugs or propose new features. When reporting a bug, the following is useful:

  • give a minimal example demonstrating the bug,

  • copy and paste the error traceback.

Pull Requests

If you want to contribute to the LumiSpy source code, you can send us a pull request. Small bug fixes are corrections to the user guide are typically a good starting point. But don’t hesitate also for significant code contributions - if needed, we’ll help you to get the code ready to common standards.

Please refer to the HyperSpy developer guide in order to get started and for detailed contributing guidelines.

The kikuchypy contributors guide, another HyperSpy extension, also is a valuable resource that can get you started and provides useful guidelines.

Reviewing

As quality assurance, to improve the code, and to ensure a generalized functionality, pull requests need to be thoroughly reviewed by at least one other member of the development team before being merged.

Documentation

The LumiSpy documentation consists of three elements:

Improving documentation is always welcome and a good way of starting out to learn the GitHub functionality. You can contribute through pull requests to the respective repositories.

Code style

LumiSpy follows Style Guide for Python Code with The Black Code style.

For docstrings, we follow the numpydoc standard.

Package imports should be structured into three blocks with blank lines between them:

  • standard libraries (like os and typing),

  • third party packages (like numpy and hyperspy),

  • and finally lumispy imports.

Writing tests

All functionality in LumiSpy is tested via the pytest framework. The tests reside in the test directory. Tests are short methods that call functions in LumiSpy and compare resulting output values with known answers. Please refer to the HyperSpy development guide for further information on tests.

Releasing a new version

LumiSpy versioning follows semantic versioning and the version number is therefore a three-part number: MAJOR.MINOR.PATCH. Each number will change depending on the type of changes according to the following:

  • MAJOR increases when making incompatible API changes,

  • MINOR increases when adding functionality in a backwards compatible manner, and

  • PATCH increases when making backwards compatible bug fixes.

The process to release a new version that is pushed to PyPI and Conda-Forge is documented in the Releasing guide.

License

LumiSpy is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License (GPL) as published by the Free Software Foundation, either version 3 of the license, or (at your option) any later version.

LumiSpy is distributed in the hope that it will be useful, but without any warranty; without even the implied warranty of merchantability or fitness for a particular purpose. See the GNU General Public License for more details.