Basics of signals#
Signal initialization#
Many of the values in the AxesManager
can be
set when making the BaseSignal
object.
>>> dict0 = {'size': 10, 'name':'Axis0', 'units':'A', 'scale':0.2, 'offset':1}
>>> dict1 = {'size': 20, 'name':'Axis1', 'units':'B', 'scale':0.1, 'offset':2}
>>> s = hs.signals.BaseSignal(np.random.random((10,20)), axes=[dict0, dict1])
>>> s.axes_manager
<Axes manager, axes: (|20, 10)>
Name | size | index | offset | scale | units
================ | ====== | ====== | ======= | ======= | ======
---------------- | ------ | ------ | ------- | ------- | ------
Axis1 | 20 | 0 | 2 | 0.1 | B
Axis0 | 10 | 0 | 1 | 0.2 | A
This also applies to the metadata
.
>>> metadata_dict = {'General':{'name':'A BaseSignal'}}
>>> metadata_dict['General']['title'] = 'A BaseSignal title'
>>> s = hs.signals.BaseSignal(np.arange(10), metadata=metadata_dict)
>>> s.metadata
├── General
│ ├── name = A BaseSignal
│ └── title = A BaseSignal title
└── Signal
└── signal_type =
Instead of using a list of axes dictionaries [dict0, dict1]
during signal
initialization, you can also pass a list of axes objects: [axis0, axis1]
.
Signal subclasses#
The signals
module, which contains all available signal subclasses,
is imported in the user namespace when loading HyperSpy. In the following
example we create a Signal2D instance from a 2D numpy array:
>>> im = hs.signals.Signal2D(np.random.random((64,64)))
>>> im
<Signal2D, title: , dimensions: (|64, 64)>
The table below summarises all the
BaseSignal
subclasses currently distributed
with HyperSpy. From HyperSpy 2.0, all domain specific signal
subclasses, characterized by the signal_type
metadata attribute, are
provided by dedicated extension packages.
The generic subclasses provided by HyperSpy are characterized by the the data
dtype
and the signal dimension. In particular, there are specialised signal
subclasses to handle complex data. See the table and diagram below. Where
appropriate, functionalities are restricted to certain
BaseSignal
subclasses.
BaseSignal subclass |
signal_dimension |
signal_type |
dtype |
---|---|---|---|
real |
|||
1 |
real |
||
2 |
real |
||
complex |
|||
1 |
complex |
||
2 |
complex |
Changed in version 1.0: The subclasses Simulation
, SpectrumSimulation
and ImageSimulation
were removed.
Added in version 1.5: External packages can register extra BaseSignal
subclasses.
Changed in version 2.0: The subclasses EELS
, EDS_SEM
, EDS_TEM
and
DielectricFunction
have been moved to the extension package
exspy
and the subclass hologram
has been
moved to the extension package holospy
.
HyperSpy extensions#
Domain specific functionalities for specific types of data are provided through
a number of dedicated python packages that qualify as HyperSpy extensions. These
packages provide subclasses of the generic signal classes listed above, depending
on the dimensionality and type of the data. Some examples are included in the
diagram above.
If an extension package is installed on your system, the provided signal
subclasses are registered with HyperSpy and these classes are directly
available when loading the hyperspy.api
into the namespace. A list of packages
that extend HyperSpy
is curated in a dedicated repository.
The metadata attribute signal_type
describes the nature of the signal. It can
be any string, normally the acronym associated with a particular signal. To print
all BaseSignal
subclasses available in your system call
the function print_known_signal_types()
as in the following
example (assuming the extensions eXSpy and
holoSpy are installed):
>>> hs.print_known_signal_types()
+--------------------+---------------------+--------------------+----------+
| signal_type | aliases | class name | package |
+--------------------+---------------------+--------------------+----------+
| DielectricFunction | dielectric function | DielectricFunction | exspy |
| EDS_SEM | | EDSSEMSpectrum | exspy |
| EDS_TEM | | EDSTEMSpectrum | exspy |
| EELS | TEM EELS | EELSSpectrum | exspy |
| hologram | | HologramImage | holospy |
+--------------------+---------------------+--------------------+----------+
When loading data, the signal_type
will be
set automatically by the file reader, as defined in rosettasciio
. If the
extension providing the corresponding signal subclass is installed,
load()
will return the subclass from the hyperspy extension,
otherwise a warning will be raised to explain that
no registered signal class can be assigned to the given signal_type
.
Since the load()
can return domain specific signal objects (e.g.
EDSSEMSpectrum
from eXSpy
) provided by extensions, the corresponding
functionalities (so-called method of object in object-oriented programming,
e.g. EDSSEMSpectrum.get_lines_intensity()
) implemented in signal classes of
the extension can be accessed directly. To use additional functionalities
implemented in extensions, but not as method of the signal class, the extensions
need to be imported explicitly (e.g. import exspy
). Check the user guides
of the respective HyperSpy extensions for details on the
provided methods and functions.
For details on how to write and register extensions see Writing packages that extend HyperSpy.
Transforming between signal subclasses#
The BaseSignal
method
set_signal_type()
changes the signal_type
in place, which may result in a BaseSignal
subclass
transformation.
The following example shows how to change the signal dimensionality and how
to transform between different subclasses (converting to EELS
requires the
extension eXSpy to be installed):
>>> s = hs.signals.Signal1D(np.random.random((10,20,100))) >>> s <Signal1D, title: , dimensions: (20, 10|100)> >>> s.metadata ├── General │ └── title = └── Signal └── signal_type = >>> im = s.to_signal2D() >>> im <Signal2D, title: , dimensions: (100|20, 10)> >>> im.metadata ├── General │ └── title = └── Signal └── signal_type = >>> s.set_signal_type("EELS") >>> s <EELSSpectrum, title: , dimensions: (20, 10|100)> >>> s.metadata ├── General │ └── title = └── Signal └── signal_type = EELS >>> s.change_dtype("complex") >>> s <ComplexSignal1D, title: , dimensions: (20, 10|100)>