Skip to content

Directivity Module

The directivity module provides tools to work with directivity.

The following conventions are used within this module:

  • The inclination angle \(\theta\) has a range \([0, \pi]\).
  • The azimuth angle \(\phi\) has a range \([0 , 2 \pi]\).
FUNCTION DESCRIPTION
cardioid

Generate a cardioid pattern.

figure_eight

Generate a figure-of-eight pattern.

spherical_harmonic

Calculate spherical harmonic of order m and degree n.

spherical_to_cartesian

Convert spherical coordinates to cartesian coordinates.

cartesian_to_spherical

Convert cartesian coordinates to spherical coordinates.

CLASS DESCRIPTION
Directivity

Abstract class for directivity.

Omni

Class for omni-directional directivity.

Cardioid

Class for cardioid directivity.

FigureEight

Class for figure-of-eight directivity.

SphericalHarmonic

Class for spherical harmonic directivity.

Custom

Class for custom directivity.

Classes

Directivity

Directivity(rotation=None)

Abstract directivity class.

This class defines several methods to be implemented by subclasses.

PARAMETER DESCRIPTION
rotation

Rotation of the directivity pattern.

DEFAULT: None

Source code in acoustic_toolbox/directivity.py
def __init__(self, rotation=None):
    """Rotation of the directivity pattern.

    Args:
      rotation: Rotation of the directivity pattern.
    """
    self.rotation = (
        rotation if rotation else np.array([1.0, 0.0, 0.0])
    )  # X, Y, Z rotation

Functions

using_spherical
using_spherical(
    theta, phi, r=None, include_rotation: bool = True
)

Return the directivity for given spherical coordinates.

PARAMETER DESCRIPTION
theta

angle \(\theta\)

phi

angle \(\phi\)

r

norm (optional)

DEFAULT: None

include_rotation

Apply the rotation to the directivity.

TYPE: bool DEFAULT: True

RETURNS DESCRIPTION

Directivity.

Todo

Correct for rotation!!!!

Source code in acoustic_toolbox/directivity.py
def using_spherical(self, theta, phi, r=None, include_rotation: bool = True):
    r"""Return the directivity for given spherical coordinates.

    Args:
      theta: angle $\theta$
      phi: angle $\phi$
      r: norm (optional)
      include_rotation: Apply the rotation to the directivity.

    Returns:
      Directivity.

    Todo:
      Correct for rotation!!!!
    """
    # TODO: Correct for rotation!!!! use 'r' if needed in rotation logic
    return self._directivity(theta, phi)
using_cartesian
using_cartesian(x, y, z, include_rotation: bool = True)

Return the directivity for given cartesian coordinates.

PARAMETER DESCRIPTION
x

x

y

y

z

z

include_rotation

Apply the rotation to the directivity.

TYPE: bool DEFAULT: True

RETURNS DESCRIPTION

Directivity.

Todo

Correct for rotation!!!!

Source code in acoustic_toolbox/directivity.py
def using_cartesian(self, x, y, z, include_rotation: bool = True):
    """Return the directivity for given cartesian coordinates.

    Args:
      x: x
      y: y
      z: z
      include_rotation: Apply the rotation to the directivity.

    Returns:
      Directivity.

    Todo:
      Correct for rotation!!!!
    """
    r, theta, phi = cartesian_to_spherical(x, y, z)
    return self.using_spherical(theta, phi, r, include_rotation)
plot
plot(
    filename: str | None = None,
    include_rotation: bool = True,
) -> Figure

Directivity plot. Plot to filename when given.

PARAMETER DESCRIPTION
filename

Filename

TYPE: str | None DEFAULT: None

include_rotation

Apply the rotation to the directivity. By default the rotation is applied in this figure.

TYPE: bool DEFAULT: True

RETURNS DESCRIPTION
Figure

Figure.

Todo

filename

Source code in acoustic_toolbox/directivity.py
def plot(
    self, filename: str | None = None, include_rotation: bool = True
) -> Figure:
    """Directivity plot. Plot to ``filename`` when given.

    Args:
      filename: Filename
      include_rotation: Apply the rotation to the directivity.
        By default the rotation is applied in this figure.

    Returns:
      Figure.

    Todo:
      filename
    """
    raise NotImplementedError(
        "`Directivity.plot` needs to be re-implemented, due to underlying issues from python-acoustics."
    )
    # I'm not sure how the example notebook ever ran before...
    # The method needs to be re-implemented to match the `plot` function.
    del filename
    return plot(self, include_rotation)

Omni

Omni(rotation=None)

Bases: Directivity

Class to work with omni-directional directivity.

Source code in acoustic_toolbox/directivity.py
def __init__(self, rotation=None):
    """Rotation of the directivity pattern.

    Args:
      rotation: Rotation of the directivity pattern.
    """
    self.rotation = (
        rotation if rotation else np.array([1.0, 0.0, 0.0])
    )  # X, Y, Z rotation

Cardioid

Cardioid(rotation=None)

Bases: Directivity

Cardioid directivity.

Source code in acoustic_toolbox/directivity.py
def __init__(self, rotation=None):
    """Rotation of the directivity pattern.

    Args:
      rotation: Rotation of the directivity pattern.
    """
    self.rotation = (
        rotation if rotation else np.array([1.0, 0.0, 0.0])
    )  # X, Y, Z rotation

FigureEight

FigureEight(rotation=None)

Bases: Directivity

Directivity of a figure of eight.

Source code in acoustic_toolbox/directivity.py
def __init__(self, rotation=None):
    """Rotation of the directivity pattern.

    Args:
      rotation: Rotation of the directivity pattern.
    """
    self.rotation = (
        rotation if rotation else np.array([1.0, 0.0, 0.0])
    )  # X, Y, Z rotation

SphericalHarmonic

SphericalHarmonic(rotation=None, m: int = 0, n: int = 0)

Bases: Directivity

Directivity of a spherical harmonic of degree n and order m.

Source code in acoustic_toolbox/directivity.py
def __init__(self, rotation=None, m: int = 0, n: int = 0):
    """Constructor."""
    super().__init__(rotation=rotation)
    self.m = m
    """Order `m`."""
    self.n = n
    """Degree `n`."""

Attributes

m instance-attribute
m = m

Order m.

n instance-attribute
n = n

Degree n.

Functions

Custom

Custom(theta=None, phi=None, r=None)

Bases: Directivity

A class to work with directivity.

Source code in acoustic_toolbox/directivity.py
def __init__(self, theta=None, phi=None, r=None):
    """Constructor."""
    self.theta = theta
    """Latitude. 1-D array."""

    self.phi = phi
    """Longitude. 1-D array."""
    self.r = r
    """Magnitude or radius. 2-D array."""

Attributes

theta instance-attribute
theta = theta

Latitude. 1-D array.

phi instance-attribute
phi = phi

Longitude. 1-D array.

r instance-attribute
r = r

Magnitude or radius. 2-D array.

Functions

Functions

cardioid

cardioid(theta, a=1.0, k=1.0)

A cardioid pattern.

PARAMETER DESCRIPTION
a

a

DEFAULT: 1.0

k

k

DEFAULT: 1.0

theta

angle \(\theta\)

RETURNS DESCRIPTION

Cardioid pattern.

Source code in acoustic_toolbox/directivity.py
def cardioid(theta, a=1.0, k=1.0):
    r"""A cardioid pattern.

    Args:
      a: a
      k: k
      theta: angle $\theta$

    Returns:
      Cardioid pattern.
    """
    return np.abs(a + a * np.cos(k * theta))

figure_eight

figure_eight(theta, phi=0.0)

A figure-of-eight pattern.

PARAMETER DESCRIPTION
theta

angle \(\theta\)

phi

angle \(\phi\)

DEFAULT: 0.0

RETURNS DESCRIPTION

Figure-of-eight pattern.

Source code in acoustic_toolbox/directivity.py
def figure_eight(theta, phi=0.0):
    r"""A figure-of-eight pattern.

    Args:
      theta: angle $\theta$
      phi: angle $\phi$

    Returns:
      Figure-of-eight pattern.
    """
    del phi
    # return spherical_harmonic(theta, phi, m=0, n=1)
    return np.abs(np.cos(theta))

spherical_harmonic

spherical_harmonic(theta, phi, m: int = 0, n: int = 0)

Spherical harmonic of order m and degree n.

Note

The degree n is often denoted l.

See Also

scipy.special.sph_harm_y

Source code in acoustic_toolbox/directivity.py
def spherical_harmonic(theta, phi, m: int = 0, n: int = 0):
    """Spherical harmonic of order `m` and degree `n`.

    Note:
      The degree `n` is often denoted `l`.

    See Also:
      [`scipy.special.sph_harm_y`][scipy.special.sph_harm_y]
    """
    return sph_harm_y(n, m, theta, phi).real

spherical_to_cartesian

spherical_to_cartesian(r, theta, phi)

Convert spherical coordinates to cartesian coordinates.

PARAMETER DESCRIPTION
r

norm

theta

angle \(\theta\)

phi

angle \(\phi\)

RETURNS DESCRIPTION
x

\(x = r \sin{\theta}\cos{\phi}\)

y

\(y = r \sin{\theta}\sin{\phi}\)

z

\(z = r \cos{\theta}\)

Source code in acoustic_toolbox/directivity.py
def spherical_to_cartesian(r, theta, phi):
    r"""Convert spherical coordinates to cartesian coordinates.

    Args:
      r: norm
      theta: angle $\theta$
      phi: angle $\phi$

    Returns:
       x: $x = r \sin{\theta}\cos{\phi}$
       y: $y = r \sin{\theta}\sin{\phi}$
       z: $z = r \cos{\theta}$
    """
    r = np.asanyarray(r)
    theta = np.asanyarray(theta)
    phi = np.asanyarray(phi)
    return (
        r * np.sin(theta) * np.cos(phi),
        r * np.sin(theta) * np.sin(phi),
        r * np.cos(theta),
    )

cartesian_to_spherical

cartesian_to_spherical(x, y, z)

Convert cartesian coordinates to spherical coordinates.

PARAMETER DESCRIPTION
x

x

y

y

z

z

RETURNS DESCRIPTION
r

\(r = \sqrt{\left( x^2 + y^2 + z^2 \right)}\)

theta

\(\theta = \arccos{\frac{z}{r}}\)

phi

\(\phi = \arccos{\frac{y}{x}}\)

Source code in acoustic_toolbox/directivity.py
def cartesian_to_spherical(x, y, z):
    r"""Convert cartesian coordinates to spherical coordinates.

    Args:
      x: x
      y: y
      z: z

    Returns:
      r: $r = \sqrt{\left( x^2 + y^2 + z^2 \right)}$
      theta: $\theta = \arccos{\frac{z}{r}}$
      phi: $\phi = \arccos{\frac{y}{x}}$
    """
    x = np.asanyarray(x)
    y = np.asanyarray(y)
    z = np.asanyarray(z)
    r = np.linalg.norm(np.vstack((x, y, z)), axis=0)
    return r, np.arccos(z / r), np.arctan(y / x)

plot

plot(d: Directivity, sphere: bool = False) -> Figure

Plot directivity d.

PARAMETER DESCRIPTION
d

Directivity

TYPE: Directivity

sphere

Plot on a sphere.

TYPE: bool DEFAULT: False

RETURNS DESCRIPTION
Figure

Figure

Source code in acoustic_toolbox/directivity.py
def plot(d: Directivity, sphere: bool = False) -> Figure:
    """Plot directivity `d`.

    Args:
      d: Directivity
      sphere: Plot on a sphere.

    Returns:
      Figure
    """
    theta, phi = np.meshgrid(
        np.linspace(0.0, np.pi, 50), np.linspace(0.0, +2.0 * np.pi, 50)
    )

    # Directivity strength. Real-valued. Can be positive and negative.
    dr = d.using_spherical(theta, phi)

    if sphere:
        x, y, z = spherical_to_cartesian(1.0, theta, phi)

    else:
        x, y, z = spherical_to_cartesian(np.abs(dr), theta, phi)
    # R, theta, phi = cartesian_to_spherical(x, y, z)

    fig = plt.figure()
    ax = fig.add_subplot(111, projection="3d")
    # p = ax.plot_surface(x, y, z, cmap=plt.cm.jet, rstride=1, cstride=1, linewidth=0)

    norm = Normalize()
    norm.autoscale(dr)
    colors = cm.jet(norm(dr))
    m = cm.ScalarMappable(cmap=cm.jet, norm=norm)
    m.set_array(dr)
    ax.plot_surface(x, y, z, facecolors=colors, rstride=1, cstride=1, linewidth=0)
    plt.colorbar(m, ax=ax)

    ax.set_xlabel("$x$")
    ax.set_ylabel("$y$")
    ax.set_zlabel("$z$")
    return fig

:::