Skip to content

Commit

Permalink
Add bessel beam
Browse files Browse the repository at this point in the history
  • Loading branch information
MatthewFilipovich committed Dec 9, 2024
1 parent 3780592 commit 0865c1d
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 1 deletion.
2 changes: 1 addition & 1 deletion tests/test_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ def test_visualize(self):
field = Field(data, wavelength=1, spacing=1)

# Test visualization of the field data
fig = field.visualize(intensity=True, show=False, return_fig=True)
fig = field.visualize(show=False, return_fig=True)
self.assertIsInstance(fig, plt.Figure)


Expand Down
23 changes: 23 additions & 0 deletions tests/test_profiles.py
Original file line number Diff line number Diff line change
Expand Up @@ -354,5 +354,28 @@ def test_incoherent(self):
self.assertTrue(torch.all(incoherent_data == 0)) # off-diagonal elements should be zero


class TestBesselProfile(unittest.TestCase):
def setUp(self):
self.shape = (100, 100)
self.cone_angle = torch.pi / 4
self.wavelength = 0.5
self.spacing = (0.1, 0.1)
self.offset = (0.0, 0.0)

self.profile = bessel(
shape=self.shape,
cone_angle=self.cone_angle,
wavelength=self.wavelength,
spacing=self.spacing,
offset=self.offset,
)

def test_bessel_shape(self):
self.assertEqual(self.profile.shape, self.shape)

def test_bessel_values(self):
self.assertTrue(torch.all(self.profile.abs() <= 1))


if __name__ == "__main__":
unittest.main()
1 change: 1 addition & 0 deletions torchoptics/profiles/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""This module contains functions to generate different types of profiles."""

from .bessel import bessel
from .gratings import blazed_grating, sinusoidal_amplitude_grating, sinusoidal_phase_grating
from .hermite_gaussian import gaussian, hermite_gaussian
from .laguerre_gaussian import laguerre_gaussian
Expand Down
61 changes: 61 additions & 0 deletions torchoptics/profiles/bessel.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
"""This module defines a function to generate the bessel beam profile."""

import math
from typing import Optional

import torch
from torch import Tensor

from ..config import get_default_wavelength
from ..planar_geometry import PlanarGeometry
from ..type_defs import Scalar, Vector2

__all__ = ["bessel"]


def bessel(
shape: Vector2,
cone_angle: float,
wavelength: Optional[Scalar] = None,
spacing: Optional[Vector2] = None,
offset: Optional[Vector2] = None,
) -> Tensor:
r"""
Generates a zeroth-order Bessel beam.
The zeroth-order Bessel beam is defined by the following equation:
.. math::
\psi(r) = J_0(k \, r \sin(\theta)),
where:
- :math:`J_0` is the zeroth-order Bessel function of the first kind,
- :math:`\theta` is the cone angle of the Bessel beam, and
- :math:`k` is the wave number, :math:`k = 2\pi / \lambda`.
Args:
shape (Vector2): Number of grid points along the planar dimensions.
cone_angle (float): The cone angle in radians.
wavelength (Scalar, optional): The wavelength of the beam. Default: if `None`, uses a global default
(see :meth:`torchoptics.set_default_wavelength()`).
spacing (Optional[Vector2]): Distance between grid points along planar dimensions. Default: if
`None`, uses a global default (see :meth:`torchoptics.set_default_spacing()`).
offset (Optional[Vector2]): Center coordinates of the beam. Default: `(0, 0)`.
Returns:
Tensor: The generated zeroth-order Bessel beam profile.
"""
wavelength = wavelength if wavelength is not None else get_default_wavelength()

# Calculate the wave number k and its radial component
k = 2 * torch.pi / wavelength # type: ignore
k_r = k * math.sin(cone_angle)

# Generate the planar grid
x, y = PlanarGeometry(shape, spacing=spacing, offset=offset).meshgrid()
r = torch.sqrt(x**2 + y**2)

# Calculate the zeroth-order Bessel beam
return torch.special.bessel_j0(k_r * r) # pylint: disable=not-callable

0 comments on commit 0865c1d

Please sign in to comment.