Source code for optiland.nonsequential.results.far_field_pattern

"""Far-field angular pattern result for Non-Sequential Raytracing.

Kramer Harrison, 2026
"""

from __future__ import annotations

from typing import TYPE_CHECKING

import numpy as np

if TYPE_CHECKING:
    from pathlib import Path


[docs] class FarFieldPattern: """Angular flux distribution in the far field. Attributes: intensity: Intensity [W/sr], shape (n_theta, n_phi). theta: Polar angle bin centres [deg], shape (n_theta,). phi: Azimuthal angle bin centres [deg], shape (n_phi,). total_flux: Total flux recorded [W]. num_rays_hit: Number of rays recorded. """ def __init__( self, intensity: np.ndarray, theta: np.ndarray, phi: np.ndarray, total_flux: float, num_rays_hit: int, ) -> None: """Initialize FarFieldPattern. Args: intensity: Intensity [W/sr], shape (n_theta, n_phi). theta: Polar angle centres [deg]. phi: Azimuthal angle centres [deg]. total_flux: Total detected flux [W]. num_rays_hit: Number of rays that contributed. """ self.intensity = intensity self.theta = theta self.phi = phi self.total_flux = float(total_flux) self.num_rays_hit = int(num_rays_hit)
[docs] def plot(self, ax=None, projection: str = "polar", **kwargs): """Plot the far-field pattern. Args: ax: Optional Matplotlib Axes. If None, a new figure is created. projection: Plot projection type ('polar' or 'cartesian'). **kwargs: Additional arguments passed to the plot function. Returns: The Matplotlib Figure object. """ import matplotlib.pyplot as plt # noqa: PLC0415 if ax is None: fig, ax = plt.subplots() else: fig = ax.get_figure() # Sum over phi for 1D polar plot intensity_1d = self.intensity.sum(axis=1) ax.plot(self.theta, intensity_1d, **kwargs) ax.set_xlabel("theta [deg]") ax.set_ylabel("Intensity [W/sr] (integrated over phi)") ax.set_title(f"Far-Field Pattern -- {self.num_rays_hit} rays") return fig
[docs] def save(self, path: str | Path) -> None: """Save far-field pattern to a .npz file. Args: path: Output file path. """ np.savez( path, intensity=self.intensity, theta=self.theta, phi=self.phi, total_flux=self.total_flux, num_rays_hit=self.num_rays_hit, )