Skip to content

Commit

Permalink
Merge pull request #30 from ericpre/fix_docstring
Browse files Browse the repository at this point in the history
Fix docstring
  • Loading branch information
ericpre committed Apr 3, 2024
2 parents 3305ba4 + 790e801 commit a8bb882
Show file tree
Hide file tree
Showing 10 changed files with 135 additions and 106 deletions.
12 changes: 9 additions & 3 deletions doc/api/signals.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
:mod:`holospy.signals.hologram_image`
-------------------------------------
:mod:`holospy.signals`
----------------------

.. automodule:: holospy.signals.hologram_image
.. currentmodule:: holospy.signals

.. autosummary::
HologramImage
LazyHologramImage

.. automodule:: holospy.signals
:members:
2 changes: 1 addition & 1 deletion doc/api/tools.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
:mod:`holospy.tools`
--------------------------
--------------------

.. automodule:: holospy.tools
:members:
17 changes: 9 additions & 8 deletions doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
# sys.path.insert(0, os.path.abspath('.'))

import hyperspy.api as hs
import numpydoc
from packaging.version import Version


# Set logging level to `ERROR` to avoid exspy warning in documentation
Expand All @@ -38,7 +36,7 @@
extensions = [
# numpydoc is necessary to parse the docstring using sphinx
# otherwise the nitpicky option will raise many warnings
# "numpydoc",
"numpydoc",
"sphinx_design",
"sphinx_favicon",
"sphinx.ext.autodoc",
Expand Down Expand Up @@ -106,17 +104,20 @@
]

# Check links to API when building documentation
nitpicky = False
# Remove when fixed in hyperspy
nitpick_ignore_regex = [(r"py:.*", r"hyperspy.api.*")]
nitpicky = True

# -- Options for numpydoc extension -----------------------------------

numpydoc_show_class_members = False
numpydoc_xref_param_type = True
numpydoc_xref_ignore = {"type", "optional", "default", "of"}

if Version(numpydoc.__version__) >= Version("1.6.0rc0"):
numpydoc_validation_checks = {"all", "ES01", "EX01", "GL02", "GL03", "SA01", "SS06"}
autoclass_content = "both"

autodoc_default_options = {
"show-inheritance": True,
}
toc_object_entries_show_parents = "hide"

# -- Options for towncrier_draft extension -----------------------------------

Expand Down
30 changes: 15 additions & 15 deletions doc/user_guide/electron_holography.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ Electron Holography
HoloSpy provides the user with a signal class which can be used to process
(off-axis) electron holography data:

* :py:class:`~.signals.hologram_image.HologramImage`
* :py:class:`~.signals.HologramImage`

It inherits from :external+hyperspy:py:class:`hyperspy._signals.signal2d.Signal2D` class and thus can
It inherits from :external+hyperspy:py:class:`hyperspy.api.signals.Signal2D` class and thus can
use all of its functionality. The usage of the class is explained in the
following sections.

To transform a :external+hyperspy:py:class:`hyperspy._signals.signal2d.Signal2D` (or subclass) into a
:py:class:`~.signals.hologram_image.HologramImage` use:
To transform a :external+hyperspy:py:class:`hyperspy.api.signals.Signal2D` (or subclass) into a
:py:class:`~.signals.HologramImage` use:

.. code-block:: python
Expand All @@ -30,10 +30,10 @@ and :ref:`[Joy1993] <Joy1993>`.
Fourier based reconstruction of off-axis holograms (includes
finding a side band in FFT, isolating and filtering it, recenter and
calculate inverse Fourier transform) can be performed using the
:py:meth:`~.signals.hologram_image.HologramImage.reconstruct_phase` method
which returns a :external+hyperspy:py:class:`hyperspy._signals.complex_signal2d.ComplexSignal2D` class,
:py:meth:`~.signals.HologramImage.reconstruct_phase` method
which returns a :external+hyperspy:py:class:`hyperspy.api.signals.ComplexSignal2D` class,
containing the reconstructed electron wave.
The :py:meth:`~.signals.hologram_image.HologramImage.reconstruct_phase` method
The :py:meth:`~.signals.HologramImage.reconstruct_phase` method
takes sideband position and size as parameters:

.. code-block:: python
Expand All @@ -51,10 +51,10 @@ The parameters can be found automatically by calling following methods:
... sb='lower')
>>> sb_size = im.estimate_sideband_size(sb_position)
:py:meth:`~.signals.hologram_image.HologramImage.estimate_sideband_position`
:py:meth:`~.signals.HologramImage.estimate_sideband_position`
method searches for maximum of intensity in upper or lower part of FFT pattern
(parameter ``sb``) excluding the middle area defined by ``ap_cb_radius``.
:py:meth:`~._signals.hologram_image.HologramImage.estimate_sideband_size` method
:py:meth:`~.signals.HologramImage.estimate_sideband_size` method
calculates the radius of the sideband filter as half of the distance to the
central band which is commonly used for strong phase objects. Alternatively,
the sideband filter radius can be recalculate as 1/3 of the distance
Expand Down Expand Up @@ -105,7 +105,7 @@ than pixels (by default) by setting ``sb_unit`` value either to ``mrad`` or
... sb_position=sb_position, sb_size=30,
... sb_smoothness=0.05*30,sb_unit='mrad')
Also the :py:meth:`~.signals.hologram_image.HologramImage.reconstruct_phase`
Also the :py:meth:`~.signals.HologramImage.reconstruct_phase`
method can output wave images with desired size (shape). By default the shape
of the original hologram is preserved. Though this leads to oversampling of the
output wave images, since the information is limited by the size of the
Expand All @@ -121,11 +121,11 @@ diameter of the sideband as follows:
... output_shape=(out_size, out_size))
Note that the
:py:meth:`~.signals.hologram_image.HologramImage.reconstruct_phase`
:py:meth:`~.signals.HologramImage.reconstruct_phase`
method can be called without parameters, which will cause their automatic
assignment by
:py:meth:`~.signals.hologram_image.HologramImage.estimate_sideband_position`
and :py:meth:`~.signals.hologram_image.HologramImage.estimate_sideband_size`
:py:meth:`~.signals.HologramImage.estimate_sideband_position`
and :py:meth:`~.signals.HologramImage.estimate_sideband_size`
methods. This, however, is not recommended for not experienced users.

.. _holography.stats-label:
Expand All @@ -151,7 +151,7 @@ calculated and displayed as follows:
Getting hologram statistics
---------------------------
There are many reasons to have an access to some parameters of holograms which describe the quality of the data.
:meth:`~.signals.hologram_image.HologramImage.statistics` can be used to calculate carrier frequency,
:meth:`~.signals.HologramImage.statistics` can be used to calculate carrier frequency,
fringe spacing and estimate fringe contrast. The method outputs dictionary with the values listed above calculated also
in different units. In particular fringe spacing is calculated in pixels (fringe sampling) as well as in
calibrated units. Carrier frequency is calculated in inverse pixels or calibrated units as well as radians.
Expand Down Expand Up @@ -186,4 +186,4 @@ By default ``apodization`` parameter is set to ``hanning`` which applies Hanning
especially with extreme sampling of fringes and strong contrast variation due to Fresnel effects
the calculated fringe contrast provides only an estimate and the values may differ strongly depending on apodization.

For further information see documentation of :meth:`~.signals.hologram_image.HologramImage.statistics`.
For further information see documentation of :meth:`~.signals.HologramImage.statistics`.
62 changes: 34 additions & 28 deletions holospy/reconstruct.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,18 @@


def estimate_sideband_position(
holo_data, holo_sampling, central_band_mask_radius=None, sb="lower", high_cf=True
data, sampling, central_band_mask_radius=None, sb="lower", high_cf=True
):
"""
Finds the position of the sideband and returns its position.
Parameters
----------
holo_data: ndarray
data : numpy.ndarray
The data of the hologram.
holo_sampling: tuple
sampling : tuple
The sampling rate in both image directions.
central_band_mask_radius: float, optional
central_band_mask_radius : float, optional
The aperture radius used to mask out the centerband.
sb : str, optional
Chooses which sideband is taken. 'lower', 'upper', 'left', or 'right'.
Expand All @@ -46,10 +46,11 @@ def estimate_sideband_position(
Returns
-------
Tuple of the sideband position (y, x), referred to the unshifted FFT.
tuple
The sideband position (y, x), referred to the unshifted FFT.
"""
sb_position = (0, 0)
f_freq = freq_array(holo_data.shape, holo_sampling)
f_freq = freq_array(data.shape, sampling)
# If aperture radius of centerband is not given, it will be set to 5 % of
# the Nyquist frequ.:
if central_band_mask_radius is None:
Expand All @@ -59,7 +60,7 @@ def estimate_sideband_position(
if not high_cf: # Cut out higher frequencies, if necessary:
ap_cb *= aperture_function(f_freq, np.max(f_freq) / (2 * np.sqrt(2)), 1e-6)
# Imitates 0:
fft_holo = fft2(holo_data) / np.prod(holo_data.shape)
fft_holo = fft2(data) / np.prod(data.shape)
fft_filtered = fft_holo * ap_cb
# Sideband position in pixels referred to unshifted FFT
cb_position = (
Expand All @@ -84,13 +85,13 @@ def estimate_sideband_position(
return sb_position


def estimate_sideband_size(sb_position, holo_shape, sb_size_ratio=0.5):
def estimate_sideband_size(sb_position, shape, sb_size_ratio=0.5):
"""
Estimates the size of sideband filter
Parameters
----------
holo_shape : array_like
shape : array_like
Holographic data array
sb_position : tuple
The sideband position (y, x), referred to the non-shifted FFT.
Expand All @@ -99,7 +100,7 @@ def estimate_sideband_size(sb_position, holo_shape, sb_size_ratio=0.5):
Returns
-------
sb_size : float
float
Size of sideband filter
"""
Expand All @@ -108,9 +109,9 @@ def estimate_sideband_size(sb_position, holo_shape, sb_size_ratio=0.5):
np.array(
(
np.asarray(sb_position) - np.asarray([0, 0]),
np.asarray(sb_position) - np.asarray([0, holo_shape[1]]),
np.asarray(sb_position) - np.asarray([holo_shape[0], 0]),
np.asarray(sb_position) - np.asarray(holo_shape),
np.asarray(sb_position) - np.asarray([0, shape[1]]),
np.asarray(sb_position) - np.asarray([shape[0], 0]),
np.asarray(sb_position) - np.asarray(shape),
)
)
* sb_size_ratio
Expand All @@ -119,8 +120,8 @@ def estimate_sideband_size(sb_position, holo_shape, sb_size_ratio=0.5):


def reconstruct(
holo_data,
holo_sampling,
data,
sampling,
sb_size,
sb_position,
sb_smoothness,
Expand All @@ -131,34 +132,34 @@ def reconstruct(
Parameters
----------
holo_data : array_like
data : array_like
Holographic data array
holo_sampling : tuple
sampling : tuple
Sampling rate of the hologram in y and x direction.
sb_size : float
Size of the sideband filter in pixel.
sb_position : tuple
Sideband position in pixel.
sb_smoothness: float
sb_smoothness : float
Smoothness of the aperture in pixel.
output_shape: tuple, optional
output_shape : tuple, optional
New output shape.
plotting : bool
Plots the masked sideband used for reconstruction.
Returns
-------
wav : nparray
Reconstructed electron wave
numpy.ndarray
Reconstructed electron wave
"""

holo_size = holo_data.shape
f_sampling = np.divide(1, [a * b for a, b in zip(holo_size, holo_sampling)])
holo_size = data.shape
f_sampling = np.divide(1, [a * b for a, b in zip(holo_size, sampling)])

fft_exp = fft2(holo_data) / np.prod(holo_size)
fft_exp = fft2(data) / np.prod(holo_size)

f_freq = freq_array(holo_data.shape, holo_sampling)
f_freq = freq_array(data.shape, sampling)

sb_size *= np.mean(f_sampling)
sb_smoothness *= np.mean(f_sampling)
Expand Down Expand Up @@ -190,7 +191,7 @@ def reconstruct(

fft_aperture = fftshift(fftshift(fft_aperture)[y_min:y_max, x_min:x_max])

wav = ifft2(fft_aperture) * np.prod(holo_data.shape)
wav = ifft2(fft_aperture) * np.prod(data.shape)

return wav

Expand All @@ -207,6 +208,10 @@ def aperture_function(r, apradius, rsmooth):
Radius (center) of the smooth aperture. Decay starts at apradius - rsmooth.
rsmooth : float
Smoothness in halfwidth. rsmooth = 1 will cause a decay from 1 to 0 over 2 pixel.
Returns
-------
numpy.ndarray
"""

return 0.5 * (1.0 - np.tanh((abs(r) - apradius) / (0.5 * rsmooth)))
Expand All @@ -220,12 +225,13 @@ def freq_array(shape, sampling):
----------
shape : tuple
The shape of the array.
sampling: tuple
sampling : tuple
The sampling rates of the array.
Returns
-------
Array of the frequencies.
numpy.ndarray
Frequencies
"""
f_freq_1d_y = np.fft.fftfreq(shape[0], sampling[0])
f_freq_1d_x = np.fft.fftfreq(shape[1], sampling[1])
Expand Down
10 changes: 9 additions & 1 deletion holospy/signals/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,15 @@
# You should have received a copy of the GNU General Public License
# along with holospy. If not, see <http://www.gnu.org/licenses/>.

"""Signals to be operated on. The basic unit of data"""
"""
Modules containing the HoloSpy signals and their lazy counterparts.
HologramImage
For holography data
LazyHologramImage
For holography data processed lazily
"""

from .hologram_image import HologramImage, LazyHologramImage

Expand Down
Loading

0 comments on commit a8bb882

Please sign in to comment.