Skip to content

Commit

Permalink
Merge pull request #352 from MikhailRyazanov/tmp
Browse files Browse the repository at this point in the history
Additional sample image and updated README diagram
  • Loading branch information
MikhailRyazanov committed Apr 20, 2022
2 parents c3e60c0 + 14e03d6 commit 476e3c9
Show file tree
Hide file tree
Showing 22 changed files with 320 additions and 244 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ Changelog
Unreleased
----------

* Offline HTML and PDF documentation is now available at Read the Docs and can
be built locally (PR #343, #348, #349).
* Correct behavior of relative basis_dir in basex under Python 2 (PR #336).
* Analytical Abel transform of axially symmetric piecewise polynomials in
spherical coordinates (PR #339).
* Improvements in tools.analytical.SampleImage class: more consistent and
intuitive interface, accurate Abel transform for existing images, additional
sample images with exact Abel transform (PR #339).
sample images with exact Abel transform (PR #339, #352).

v0.8.5 (2022-01-21)
-------------------
Expand Down
9 changes: 5 additions & 4 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Introduction
.. begin-github-only2
.. image:: https://raw.githubusercontent.com/PyAbel/PyAbel/master/doc/overview.svg
:align: center

.. end-github-only2
Expand Down Expand Up @@ -96,12 +97,12 @@ and *then* proceed with the usual module uninstallation process (for example, ``
Example of use
--------------

Using PyAbel can be simple. The following Python code imports the PyAbel package, generates a sample image, performs a forward transform using the Hansen–Law method, and then a reverse transform using the Three Point method:
Using PyAbel can be simple. The following Python code imports the PyAbel package, generates a sample image, performs a forward transform using the Hansen–Law method, and then an inverse transform using the Three Point method:

.. code-block:: python
import abel
original = abel.tools.analytical.SampleImage().func
original = abel.tools.analytical.SampleImage(name='Gerber').func
forward_abel = abel.Transform(original, direction='forward',
method='hansenlaw').transform
inverse_abel = abel.Transform(forward_abel, direction='inverse',
Expand All @@ -118,8 +119,8 @@ The results can then be plotted using Matplotlib:
fig, axs = plt.subplots(1, 2, figsize=(6, 3))
axs[0].imshow(forward_abel, cmap='ocean_r')
axs[1].imshow(inverse_abel, cmap='ocean_r')
axs[0].imshow(forward_abel, clim=(0, None), cmap='ocean_r')
axs[1].imshow(inverse_abel, clim=(0, None), cmap='ocean_r')
axs[0].set_title('Forward Abel transform')
axs[1].set_title('Inverse Abel transform')
Expand Down
19 changes: 19 additions & 0 deletions abel/tests/test_tools_analytical.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,24 @@ def test_sample_Gaussian():
assert_allclose(test.abel, np.sqrt(np.pi) * sigma * ref)


def test_sample_Gerber():
"""
Test SampleImage 'Gerber'.
"""
# test transform with forward Daun with cubic splines (the most accurate)
test = SampleImage(n=513, name='Gerber') # original resolution, rmax = 256
proj = Transform(test.func, method='daun', direction='forward',
symmetry_axis=(0, 1),
transform_options={'degree': 3,
'verbose': False}).transform
assert_allclose(proj, test.abel, atol=6e-3 * np.max(proj))

# test sigma-independence of total intensity
test1 = SampleImage(name='Gerber', sigma=1)
test2 = SampleImage(name='Gerber', sigma=2)
assert_allclose(test1.abel.sum(), test2.abel.sum(), rtol=1e-3)


def test_sample_O2():
"""
Test SampleImage 'O2'.
Expand Down Expand Up @@ -111,5 +129,6 @@ def test_sample_Ominus():
if __name__ == "__main__":
test_sample_Dribinski()
test_sample_Gaussian()
test_sample_Gerber()
test_sample_O2()
test_sample_Ominus()
32 changes: 30 additions & 2 deletions abel/tools/analytical.py
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,13 @@ class SampleImage(BaseAnalytical):
Its Abel transform is also a Gaussian with the same width:
:math:`\sqrt{\pi}\, \textbf{sigma} \exp(-r^2 / \textbf{sigma}^2)`.
``'Gerber'``
Artificial test image used in the lin-BASEX article
`Rev. Sci. Instrum. 84, 033101 (2013)
<https://dx.doi.org/10.1063/1.4793404>`__, Table I.
8 Gaussian peaks with various intensities and anisotropies up to
4th order (β\ :sub:`4`).
``'O2'``
Synthetic image mimicking a velocity-map image of O\ :sup:`+` from
multiphoton photodissociation/ionization
Expand All @@ -437,7 +444,8 @@ class SampleImage(BaseAnalytical):
1/*e* halfwidth of peaks in pixels, default values are:
2⋅\ *r*\ :sub:`max`/180 for ``'Dribinski'``,
2⋅\ *r*\ :sub:`max`/500 for ``'Ominus'``,
*r*\ :sub:`max`/3 for ``'Gaussian'``.
*r*\ :sub:`max`/3 for ``'Gaussian'``,
:math:`\sqrt{2}` (std. dev. = 1) for ``'Gerber'``.
For ``'O2'``: HWHM of narrow peaks in pixels, default is 1.5 for any
*r*\ :sub:`max`.
Expand Down Expand Up @@ -478,8 +486,28 @@ def __init__(self, n=361, name='Dribinski', sigma=None, temperature=200):
self.name = 'Gaussian'
self._scale = 0
width = self.r_max / 3 if sigma is None else sigma
# parameters: A r0 width angular
# parameters: A r0 width angular
self._peaks = [(1, 0, width, [1])]
elif name == 'gerber':
self.name = 'Gerber'
self._scale = self.r_max / 256
width = np.sqrt(2) if sigma is None else sigma

def sphere(r, beta0, beta2, beta4):
N = 160000 / (4 * np.pi * np.sqrt(np.pi) * width)
return (N / r**2, r, width,
beta0 * np.array([1, 0, 0, 0, 0]) +
beta2 * np.array([-1/2, 0, 3/2, 0, 0]) +
beta4 * np.array([3/8, 0, -30/8, 0, 35/8]))
# parameters: r0 beta0 beta2 beta4
self._peaks = [sphere(38, 1.2, -0.4, 0),
sphere(70, 1.5, -1, 0.5),
sphere(90, 1.5, 1, 0.4),
sphere(134, 2, 1, 0.4),
sphere(138, 1.8, 0.5, 0),
sphere(143, 1, 0.5, 0.25),
sphere(196, 2, 1, -0.5),
sphere(230, 2, 1, -0.5)]
elif name == 'o2':
self.name = 'O2'
self._scale = self.r_max / 330
Expand Down
12 changes: 7 additions & 5 deletions abel/tools/vmi.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ def radial_integration(IM, origin=None, radial_ranges=None):
r""" Intensity variation in the angular coordinate.
This function is the :math:`\theta`-coordinate complement to
:func:`abel.tools.vmi.angular_integration`.
:func:`abel.tools.vmi.average_radial_intensity_3D`.
Evaluates intensity vs angle for defined radial ranges.
Determines the anisotropy parameter for each radial range.
Expand All @@ -266,14 +266,16 @@ def radial_integration(IM, origin=None, radial_ranges=None):
image origin in the (row, column) format. If ``None``, the geometric
center of the image (``rows // 2, cols // 2``) is used.
radial_ranges : list of tuple ranges or int step
tuple
radial_ranges : list of tuple or int
list of tuple
integration ranges
``[(r0, r1), (r2, r3), ...]``
evaluates the intensity vs angle
``[(r0, r1), (r2, r3), ...]``.
Evaluates the intensity vs angle
for the radial ranges ``r0_r1``, ``r2_r3``, etc.
int
radial step.
Evaluates the intensity vs angle for
the whole radial range ``(0, step), (step, 2*step), ..``
Returns
Expand Down
Binary file modified doc/overview.pdf
Binary file not shown.

0 comments on commit 476e3c9

Please sign in to comment.