-
Notifications
You must be signed in to change notification settings - Fork 206
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added support for complex data #1058
Changes from 49 commits
e0d73ff
fc892fc
70839c2
94f9bac
d5e84be
fbc5997
657f48d
fea7d37
3728afa
ae60991
2becaf6
5086820
1d19b4d
e90cbb7
cf78763
b6c28c7
499925b
39957d7
d911cbe
7d81608
1e3ca5d
a54f4f3
5c00684
6e6f55f
d27479c
f8b4971
d82d7fe
5cf77ac
36f7176
d6c24b8
55ca8a3
e0e82df
d7b465f
3951cfa
2e22145
c7d0b12
bc190ae
59ee0b3
b9cac04
8d37c2c
3313e6f
867c5b9
7be3646
3f5ce02
e6a9d42
719ad06
8bf2d3c
3f62e73
8dbe4c3
07438d2
2fd4bda
018261c
f7276e7
5d4b721
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,23 @@ Dielectric function tools | |
|
||
.. versionadded:: 0.7 | ||
|
||
The :py:class:`~.signals.dielectric_function.DielectricFunction` class inherits from | ||
:py:class:`~.signals.complex_signal.ComplexSignal` and can thus access complex properties. | ||
To convert a :py:class:`~.signals.complex_signal.ComplexSignal` to a | ||
:py:class:`~.signals.dielectric_function.DielectricFunction`, make sure that the signal dimension | ||
and signyl type are properly set: | ||
|
||
.. code-block:: python | ||
|
||
>>> self.metadata.Signal.record_by = 'spectrum' | ||
>>> s.set_signal_type('DielectricFunction') | ||
|
||
Note that a :py:class:`~._signals.dielectric_function.DielectricFunction` does not inherit from | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe a simpler "Note that DielectricFunction is complex and therefore it is a subclass of ComplexSignal" would contain the same information in a more compact form? |
||
:py:class:`~._signals.signal1d.Signal1D`, because most functionality can not operate on complex | ||
data. | ||
|
||
|
||
|
||
Number of effective electrons | ||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
Electron Holography | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe this new section of the documentation should probably be added in #1079 instead and this one document the new methods in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It doesn't seem to be gone. |
||
******************* | ||
|
||
HyperSpy provides the user with a class which can be used to process electron holography data and | ||
electron wave data in general: | ||
|
||
* :py:class:`~._signals.electron_wave_image.ElectronWaveImage` | ||
|
||
The usage of the class is explained in the following sections. | ||
|
||
|
||
|
||
The ElectronWaveImage class | ||
=========================== | ||
|
||
The :py:class:`~._signals.electron_wave_image.ElectronWaveImage` class can hold information about | ||
the complex electron wave. It inherits from :py:class:`~._signals.complex_signal.ComplexSignal` | ||
and as such relevant properties like the `amplitude`, `phase` and the `real` and `imag` part of | ||
the complex data can be directly accessed and return appropriate | ||
:py:class:`~._signals.signal2d.Signal2D` signals. | ||
|
||
To transform a complex signal into a :py:class:`~._signals.electron_wave_image.ElectronWaveImage` | ||
use: | ||
|
||
.. code-block:: python | ||
|
||
>>> s.metadata.Signal.record_by = 'image' | ||
>>> s.set_signal_type('electron wave') | ||
|
||
Note that a :py:class:`~._signals.electron_wave_image.ElectronWaveImage` does not inherit from | ||
:py:class:`~._signals.signal2d.Signal2D`, because most functionality can not operate on complex | ||
data. | ||
|
||
|
||
Add a linear phase ramp | ||
----------------------- | ||
|
||
A linear phase ramp can be added to the signal via the :py:func:`~._signals.signal2d.Signal2D.add_phase_ramp` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this a typo There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I know that there is no |
||
method. The parameters `ramp_x` and `ramp_y` dictate the slope of the ramp in `x`- and `y` direction, | ||
while the offset is determined by the `offset` parameter. The fulcrum of the linear ramp is at the origin | ||
and the slopes are given in units of the axis with the according scale taken into account. | ||
Both are available via the :py:class:`~.axes.AxesManager` of the signal. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,6 +23,7 @@ HyperSpy User Guide (DRAFT) | |
eels.rst | ||
eds.rst | ||
dielectric_function.rst | ||
electron_holography.rst | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. electron_holography is still here too. |
||
io.rst | ||
events.rst | ||
metadata_structure.rst | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,11 +27,13 @@ spectroscopy data analysis. | |
|
||
Currently the following signal subclasses are available: | ||
|
||
* :py:class:`~._signals.complex_signal.ComplexSignal` | ||
* :py:class:`~._signals.signal1d.Signal1D` | ||
* :py:class:`~._signals.signal2d.Signal2D` | ||
* :py:class:`~._signals.eels.EELSSpectrum` | ||
* :py:class:`~._signals.eds_tem.EDSTEMSpectrum` | ||
* :py:class:`~._signals.eds_sem.EDSSEMSpectrum` | ||
* :py:class:`~._signals.electron_wave_image.ElectronWaveImage` | ||
* :py:class:`~._signals.spectrum_simulation.SpectrumSimulation` | ||
* :py:class:`~._signals.image_simulation.ImageSimulation` | ||
|
||
|
@@ -62,12 +64,12 @@ information (including calibration) can be accessed (and modified) in the | |
Transforming between signal subclasses | ||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
|
||
The different subclasses are characterized by three | ||
The different subclasses are characterized by four | ||
:py:attr:`~.signal.BaseSignal.metadata` attributes (see the table below): | ||
|
||
`record_by` | ||
Can be "spectrum", "image" or "", the latter meaning undefined and describes | ||
the way the data is arranged in memory. It is possible to transform any | ||
the way the data is arranged in memory. It is possible to transform any non-complex | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point. Why not providing a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is "non-complex" in "It is possible to transform any non-complex" necessary? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this was left over from before we had distinct classes for |
||
:py:class:`~.signal.BaseSignal` subclass to a :py:class:`~._signals.signal1d.Signal1D` | ||
or :py:class:`~._signals.signal2d.Signal2D` subclass using the following | ||
:py:class:`~.signal.BaseSignal` methods: :py:meth:`~.signal.BaseSignal.as_signal2D` | ||
|
@@ -95,27 +97,36 @@ The different subclasses are characterized by three | |
:py:meth:`~.signal.BaseSignal.set_signal_origin` changes the signal_origin in place, | ||
which may result in a :py:class:`~.signal.BaseSignal` subclass transformation. | ||
|
||
`dtype` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe we shouldn't document this in this way here. The |
||
Describes the underlying data type of the signal data and is determined automatically. | ||
Can be "real" or "complex". It is important to note that `data` passed to the constructor of a | ||
:py:class:`~._signals.complex_signal.ComplexSignal`, which is not already complex, will be | ||
converted to the numpy standard of `np.complex`/`np.complex128`. `data` which is already | ||
complex will be passed as is. | ||
|
||
.. table:: BaseSignal subclass :py:attr:`~.signal.BaseSignal.metadata` attributes. | ||
|
||
+---------------------------------------------------------------+-----------+-------------+---------------+ | ||
| BaseSignal subclass | record_by | signal_type | signal_origin | | ||
+===============================================================+===========+=============+===============+ | ||
| :py:class:`~.signal.BaseSignal` | - | - | - | | ||
+---------------------------------------------------------------+-----------+-------------+---------------+ | ||
| :py:class:`~._signals.signal1d.Signal1D` | spectrum | - | - | | ||
+---------------------------------------------------------------+-----------+-------------+---------------+ | ||
| :py:class:`~._signals.spectrum_simulation.SpectrumSimulation` | spectrum | - | simulation | | ||
+---------------------------------------------------------------+-----------+-------------+---------------+ | ||
| :py:class:`~._signals.eels.EELSSpectrum` | spectrum | EELS | - | | ||
+---------------------------------------------------------------+-----------+-------------+---------------+ | ||
| :py:class:`~._signals.eds_sem.EDSSEMSpectrum` | spectrum | EDS_SEM | - | | ||
+---------------------------------------------------------------+-----------+-------------+---------------+ | ||
| :py:class:`~._signals.eds_tem.EDSTEMSpectrum` | spectrum | EDS_TEM | - | | ||
+---------------------------------------------------------------+-----------+-------------+---------------+ | ||
| :py:class:`~._signals.signal2d.Signal2D` | image | - | - | | ||
+---------------------------------------------------------------+-----------+-------------+---------------+ | ||
| :py:class:`~._signals.image_simulation.ImageSimulation` | image | - | simulation | | ||
+---------------------------------------------------------------+-----------+-------------+---------------+ | ||
+---------------------------------------------------------------+-----------+---------------+---------------+---------+ | ||
| BaseSignal subclass | record_by | signal_type | signal_origin | dtype | | ||
+===============================================================+===========+===============+===============+=========+ | ||
| :py:class:`~.signal.BaseSignal` | - | - | - | real | | ||
+---------------------------------------------------------------+-----------+---------------+---------------+---------+ | ||
| :py:class:`~._signals.complex_signal.ComplexSignal` | - | - | - | complex | | ||
+---------------------------------------------------------------+-----------+---------------+---------------+---------+ | ||
| :py:class:`~._signals.signal1d.Signal1D` | spectrum | - | - | real | | ||
+---------------------------------------------------------------+-----------+---------------+---------------+---------+ | ||
| :py:class:`~._signals.spectrum_simulation.SpectrumSimulation` | spectrum | - | simulation | real | | ||
+---------------------------------------------------------------+-----------+---------------+---------------+---------+ | ||
| :py:class:`~._signals.eels.EELSSpectrum` | spectrum | EELS | - | real | | ||
+---------------------------------------------------------------+-----------+---------------+---------------+---------+ | ||
| :py:class:`~._signals.eds_sem.EDSSEMSpectrum` | spectrum | EDS_SEM | - | real | | ||
+---------------------------------------------------------------+-----------+---------------+---------------+---------+ | ||
| :py:class:`~._signals.signal2d.Signal2D` | image | - | - | real | | ||
+---------------------------------------------------------------+-----------+---------------+---------------+---------+ | ||
| :py:class:`~._signals.electron_wave_image.ElectronWaveImage` | image | electron_wave | - | complex | | ||
+---------------------------------------------------------------+-----------+---------------+---------------+---------+ | ||
| :py:class:`~._signals.image_simulation.ImageSimulation` | image | - | simulation | real | | ||
+---------------------------------------------------------------+-----------+---------------+---------------+---------+ | ||
|
||
|
||
The following example shows how to transform between different subclasses. | ||
|
@@ -198,6 +209,8 @@ following table: | |
+===============================================================+========+ | ||
| :py:class:`~.signal.BaseSignal` | False | | ||
+---------------------------------------------------------------+--------+ | ||
| :py:class:`~._signals.complex_signal.ComplexSignal` | False | | ||
+---------------------------------------------------------------+--------+ | ||
| :py:class:`~._signals.signal1d.Signal1D` | False | | ||
+---------------------------------------------------------------+--------+ | ||
| :py:class:`~._signals.spectrum_simulation.SpectrumSimulation` | False | | ||
|
@@ -210,6 +223,8 @@ following table: | |
+---------------------------------------------------------------+--------+ | ||
| :py:class:`~._signals.signal2d.Signal2D` | False | | ||
+---------------------------------------------------------------+--------+ | ||
| :py:class:`~._signals.electron_wave_image.ElectronWaveImage` | False | | ||
+---------------------------------------------------------------+--------+ | ||
| :py:class:`~._signals.image_simulation.ImageSimulation` | False | | ||
+---------------------------------------------------------------+--------+ | ||
|
||
|
@@ -993,3 +1008,43 @@ for example: | |
├── record_by = spectrum | ||
├── signal_origin = simulation | ||
└── signal_type = | ||
|
||
|
||
|
||
Handling complex data | ||
^^^^^^^^^^^^^^^^^^^^^ | ||
|
||
The HyperSpy :py:class:`~.hyperspy.signals.ComplexSignal` signal class allows the user to access | ||
complex properties like the `real` and `imag` parts of the data or the `amplitude` (also known | ||
as the modulus) and `phase` (also known as angle or argument). | ||
directly. Getting and setting those properties can be done as follows: | ||
|
||
..code-block:: python | ||
|
||
>>> real = s.real # real is a new HyperSpy signal accessing the same data | ||
>>> s.real = new_real # new_real can be an array or signal | ||
>>> imag = s.imag # imag is a new HyperSpy signal accessing the same data | ||
>>> s.imag = new_imag # new_imag can be an array or signal | ||
|
||
|
||
Calculate the angle / phase / argument | ||
-------------------------------------- | ||
|
||
The :py:func:`~hyperspy.signals.ComplexSignal.angle` function can be used to calculate the | ||
angle, which is equivalent to using the `phase` property if no argument is used. If the data is | ||
real, the angle will be 0 for positive values and 2$\pi$ for negative values. If the `deg` | ||
parameter is set to `True`, the result will be given in degrees, otherwise in rad (default). | ||
The underlying function is the :py:func:`~numpy.angle` function. | ||
:py:func:`~hyperspy.signals.ComplexSignal.angle` will return an appropriate HyperSpy signal. | ||
|
||
|
||
Phase unwrapping | ||
---------------- | ||
|
||
With the :py:func:`~hyperspy.signals.ComplexSignal.unwrapped_phase` method the complex phase | ||
of a signal can be unwrapped and returned as a new signal. The underlying method is | ||
:py:func:`~skimage.restoration.unwrap`, which uses the algorithm described in: | ||
Miguel Arevallilo Herraez, David R. Burton, Michael J. Lalor, and Munther A. Gdeisat, | ||
“Fast two-dimensional phase-unwrapping algorithm based on sorting by reliability following | ||
a noncontinuous path”, Journal Applied Optics, Vol. 41, No. 35, pp. 7437, 2002. | ||
(doi: 10.1364/AO.41.007437). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo signyl