Visualization Module
Visualization Module
Provides plotting functions for ray tracing and detector analysis. Functions are organized into single-axis functions (for composability) and composite figure builders.
Modules
common : Shared utilities and styling raytracing_plots : Ray path and surface visualization detector_plots : Detector and beam analysis visualization
Examples
Single-axis functions for custom layouts:
>>> import matplotlib.pyplot as plt
>>> from surface_roughness.visualization import (
... plot_ray_paths_projection,
... plot_ray_endpoints_scatter,
... plot_detection_counts,
... )
>>> fig, axes = plt.subplots(1, 2)
>>> plot_ray_paths_projection(axes[0], ray_history, projection="xz")
>>> plot_ray_endpoints_scatter(axes[1], rays, projection="xy")
Composite figures for quick visualization:
>>> from surface_roughness.visualization import (
... create_ray_overview_figure,
... create_detector_scan_figure,
... )
>>> fig = create_ray_overview_figure(rays, surface)
>>> fig = create_detector_scan_figure(angles, counts, intensities, total)
- lsurf.visualization.get_color_mapping(values, cmap_name='viridis', vmin=None, vmax=None)[source]
Create color mapping for values.
- Parameters:
- Returns:
colors (ndarray) – RGBA colors for each value.
norm (Normalize) – Normalization object.
sm (ScalarMappable) – ScalarMappable for colorbar.
- Return type:
- lsurf.visualization.get_projection_config(projection)[source]
Get axis indices and labels for xy/xz/yz projections.
- lsurf.visualization.wavelength_to_color(wavelength_m)[source]
Convert wavelength (in meters) to approximate visible color.
- Parameters:
wavelength_m (float or ndarray) – Wavelength in meters.
- Returns:
color – RGB color tuple(s) in [0, 1] range.
- Return type:
tuple or ndarray
Notes
Uses simplified visible spectrum approximation. Wavelengths outside visible range return gray.
- lsurf.visualization.setup_axis_grid(ax, xlabel='', ylabel='', title='', grid=True)[source]
Apply standard axis formatting.
- lsurf.visualization.add_colorbar(ax, mappable, label='', orientation='vertical')[source]
Add colorbar to axes.
- lsurf.visualization.create_figure(nrows=1, ncols=1, figsize=None, constrained_layout=True, **kwargs)[source]
Create figure with standard settings.
- Parameters:
- Returns:
fig (Figure) – Matplotlib figure.
axes (Axes or ndarray) – Axes object(s).
- Return type:
- lsurf.visualization.save_figure(fig, path, dpi=150, bbox_inches='tight', **kwargs)[source]
Save figure with standard settings.
- lsurf.visualization.plot_ray_paths_projection(ax, ray_history, projection='xz', max_rays=100, color_by='wavelength', alpha=0.6, linewidth=0.5, show_colorbar=True)[source]
Plot ray paths as a 2D projection on given axis.
- Parameters:
ax (Axes) – Matplotlib axes to draw on.
ray_history (List[RayBatch]) – List of ray batches at different time steps.
projection (str) – Projection plane: ‘xy’, ‘xz’, or ‘yz’.
max_rays (int) – Maximum rays to plot for performance.
color_by (str) – Color rays by: ‘wavelength’, ‘intensity’, ‘generation’, ‘index’.
alpha (float) – Line transparency.
linewidth (float) – Line width.
show_colorbar (bool) – Whether to add colorbar.
- Returns:
sm – ScalarMappable for external colorbar, or None.
- Return type:
ScalarMappable or None
- lsurf.visualization.plot_ray_endpoints_scatter(ax, rays, projection='xy', color_by='intensity', alpha=0.5, size=5, show_colorbar=True)[source]
Plot ray endpoint positions as scatter plot.
- Parameters:
- Returns:
sm – For external colorbar.
- Return type:
ScalarMappable or None
- lsurf.visualization.plot_ray_endpoints_histogram(ax, rays, projection='xy', bins=50, cmap='hot')[source]
Plot 2D histogram of ray endpoint density.
- lsurf.visualization.plot_surface_profile(ax, surface, x_range=(-200, 200), y=0.0, n_points=1000, color='blue', linewidth=2.0, label='Surface')[source]
Plot surface height profile along x-axis.
- Parameters:
- lsurf.visualization.plot_bounce_points(ax, bounce_positions, bounce_number=1, color=None, size=20, alpha=0.7, projection='xz', label=None)[source]
Plot ray bounce points on surface.
- Parameters:
ax (Axes) – Matplotlib axes.
bounce_positions (ndarray) – (N, 3) array of bounce positions.
bounce_number (int) – Bounce index (for color selection).
color (str, optional) – Override color.
size (float) – Marker size.
alpha (float) – Transparency.
projection (str) – Coordinate projection (‘xz’, ‘xy’, ‘yz’).
label (str, optional) – Legend label.
- lsurf.visualization.plot_incoming_rays(ax, rays, surface, projection='xz', color='gold', alpha=0.3, linewidth=0.5, max_rays=100)[source]
Plot incoming ray segments from origin to surface intersection.
- Parameters:
ax (Axes) – Matplotlib axes.
rays (RayBatch) – Ray batch before intersection.
surface (Surface) – Surface for intersection calculation.
projection (str) – Coordinate projection.
color (str) – Ray color.
alpha (float) – Transparency.
linewidth (float) – Line width.
max_rays (int) – Maximum rays to plot.
- lsurf.visualization.plot_reflected_rays(ax, rays, length=100.0, projection='xz', color='cyan', alpha=0.3, linewidth=0.5, max_rays=100)[source]
Plot reflected ray segments from current position.
- lsurf.visualization.plot_multi_bounce_paths(ax, ray_paths, projection='xz', reflected_color='cyan', refracted_color='orange', alpha=0.3, linewidth=0.5, max_paths=100)[source]
Plot multi-bounce ray paths from trace_rays_multi_bounce output.
- Parameters:
ax (Axes) – Matplotlib axes.
ray_paths (dict) – Dictionary with ‘reflected_paths’ and/or ‘refracted_paths’ lists.
projection (str) – Coordinate projection.
reflected_color (str) – Color for reflected paths.
refracted_color (str) – Color for refracted paths.
alpha (float) – Transparency.
linewidth (float) – Line width.
max_paths (int) – Maximum paths to plot.
- lsurf.visualization.create_ray_overview_figure(rays, surface, reflected_rays=None, bounce_points=None, figsize=(16, 10), x_range=(-500, 500), title='Ray Tracing Overview', save_path=None)[source]
Create comprehensive ray tracing overview figure.
- Parameters:
rays (RayBatch) – Initial rays.
surface (Surface) – Wave surface.
reflected_rays (RayBatch, optional) – Reflected rays.
bounce_points (List[ndarray], optional) – List of bounce position arrays per bounce.
figsize (tuple) – Figure size.
x_range (tuple) – X-axis range.
title (str) – Figure title.
save_path (str, optional) – Path to save figure.
- Returns:
Matplotlib figure.
- Return type:
Figure
- lsurf.visualization.plot_production_ray_overview(original_rays, surface, config, output_path, timestamp, max_bounces=2)[source]
Create production simulation ray overview with surface bounce points.
Shows incoming rays, bounce points on wave surface (colored by bounce number), and reflected rays toward recording sphere.
- Parameters:
original_rays (RayBatch) – Original rays before tracing.
surface (Surface) – The wave surface (e.g., CurvedWaveSurface).
config (dict) – Simulation configuration with keys: - grazing_angle: Beam grazing angle in degrees - beam_radius: Beam radius in meters - earth_radius: Earth radius in meters - recording_altitude: Recording sphere altitude in meters - source_distance: Source distance in meters
output_path (str) – Directory to save figure.
timestamp (str) – Timestamp for filename.
max_bounces (int) – Maximum number of bounces to visualize (default: 2).
- Returns:
Matplotlib figure.
- Return type:
Figure
- lsurf.visualization.plot_wave_surface_detail(reflected_rays, surface, x_range=(-200, 200), figsize=(12, 6), save_path=None)[source]
Plot wave surface detail with ray intersection points.
- Parameters:
- Returns:
Matplotlib figure.
- Return type:
Figure
- lsurf.visualization.plot_ray_paths_with_surface(rays, reflected_rays, surface, detector_distance=1000.0, source_distance=1000.0, refracted_rays=None, ray_paths=None, figsize=(16, 10), save_path=None)[source]
Plot full ray paths (incoming, reflected, and refracted) with wave surface.
- Parameters:
rays (RayBatch) – Initial ray batch (before interaction).
reflected_rays (RayBatch) – Reflected ray batch (after interaction).
surface (Surface) – The surface object.
detector_distance (float) – Detector distance in meters.
source_distance (float) – Source distance in meters (unused, for API compatibility).
refracted_rays (RayBatch, optional) – Refracted ray batch (after interaction).
ray_paths (dict, optional) – Dictionary with ray path data from trace_rays_multi_bounce containing: - ‘reflected_paths’: list of Nx3 arrays, one per ray - ‘refracted_paths’: list of Nx3 arrays for refracted rays - ‘reflected_final_dirs’: final direction for each reflected path - ‘refracted_final_dirs’: final direction for each refracted path
figsize (tuple) – Figure size.
save_path (str, optional) – Path to save figure.
- Returns:
Matplotlib figure.
- Return type:
Figure
- lsurf.visualization.plot_fresnel_reflection(incident_rays, reflected_rays, refracted_rays, surface_normal, surface_angle_deg, n1, n2, wavelength, fresnel_func=None, figsize=(16, 10), save_path=None)[source]
Create comprehensive Fresnel reflection visualization.
Shows ray paths, intensity distributions, Fresnel curves, and energy summary.
- Parameters:
incident_rays (RayBatch) – Original incident rays.
reflected_rays (RayBatch) – Reflected rays from surface interaction.
refracted_rays (RayBatch, optional) – Refracted (transmitted) rays.
surface_normal (tuple) – Surface normal vector (nx, ny, nz).
surface_angle_deg (float) – Surface tilt angle in degrees.
n1 (float) – Refractive index of incident medium.
n2 (float) – Refractive index of transmission medium.
wavelength (float) – Optical wavelength in meters.
fresnel_func (callable, optional) – Function to compute Fresnel coefficients: fresnel_func(n1, n2, cos_theta, pol). If not provided, uses surface_roughness.utilities.fresnel.fresnel_coefficients.
figsize (tuple) – Figure size.
save_path (str, optional) – Path to save figure.
- Returns:
Matplotlib figure with 6 subplots.
- Return type:
Figure
- lsurf.visualization.plot_brewster_validation(angles_theory_deg, R_s_theory, R_p_theory, angles_sim_deg, R_s_sim, R_p_sim, n1, n2, brewster_angle_deg, brewster_sim_deg, wavelength, num_rays_per_angle=1000, figsize=(16, 10), save_path=None)[source]
Create Brewster angle validation visualization.
Compares theoretical Fresnel curves with ray-traced simulation results.
- Parameters:
angles_theory_deg (ndarray) – Theory angle array in degrees.
R_s_theory (ndarray) – Theoretical s-polarization reflectance.
R_p_theory (ndarray) – Theoretical p-polarization reflectance.
angles_sim_deg (ndarray) – Simulation angle array in degrees.
R_s_sim (ndarray) – Simulated s-polarization reflectance.
R_p_sim (ndarray) – Simulated p-polarization reflectance.
n1 (float) – Refractive index of incident medium.
n2 (float) – Refractive index of transmission medium.
brewster_angle_deg (float) – Theoretical Brewster angle in degrees.
brewster_sim_deg (float) – Simulated Brewster angle (minimum R_p) in degrees.
wavelength (float) – Optical wavelength in meters.
num_rays_per_angle (int) – Number of rays used per angle in simulation.
figsize (tuple) – Figure size.
save_path (str, optional) – Path to save figure.
- Returns:
Matplotlib figure with validation plots.
- Return type:
Figure
- lsurf.visualization.plot_polarization_vector_components(recorded_rays, bins=50, figsize=(18, 6), save_path=None, vmin=None, vmax=None, cmap='RdBu_r', projection='angular')[source]
Plot 3D polarization vector components at the detection surface.
Creates three subfigures showing the average X (horizontal), Y (vertical), and Z (depth) components of the polarization vector binned by position.
- Parameters:
recorded_rays (RecordedRays) – Recorded rays at the detection sphere, must have polarization_vectors.
bins (int) – Number of bins in each dimension for the 2D histogram.
figsize (tuple) – Figure size (width, height).
save_path (str, optional) – Path to save figure.
vmin (float, optional) – Minimum value for colormap. Default is symmetric around 0.
vmax (float, optional) – Maximum value for colormap. Default is symmetric around 0.
cmap (str) – Colormap name. Default ‘RdBu_r’ is diverging (good for signed values).
projection (str) – Type of projection for binning: - ‘angular’: Use elevation and azimuth angles - ‘spatial’: Use X and Y positions on detection surface
- Returns:
Matplotlib figure with three subplots.
- Return type:
Figure
Notes
The polarization vector represents the electric field direction at each ray. For unpolarized light scattered from a wavy surface: - X component: Horizontal polarization - Y component: Vertical polarization - Z component: Along depth/propagation direction
Each bin shows the intensity-weighted average polarization component.
- lsurf.visualization.plot_polarization_ellipse(recorded_rays, bins=30, figsize=(12, 10), save_path=None, projection='angular', arrow_scale=1.0)[source]
Plot polarization state as arrows/ellipses on the detection surface.
Shows the average polarization direction in each bin as an arrow.
- Parameters:
recorded_rays (RecordedRays) – Recorded rays at the detection sphere, must have polarization_vectors.
bins (int) – Number of bins in each dimension.
figsize (tuple) – Figure size.
save_path (str, optional) – Path to save figure.
projection (str) – Type of projection: ‘angular’ or ‘spatial’.
arrow_scale (float) – Scale factor for arrow lengths.
- Returns:
Matplotlib figure with polarization arrows.
- Return type:
Figure
- lsurf.visualization.plot_polarization_vs_elevation(recorded_rays, bins=50, figsize=(14, 5), save_path=None)[source]
Plot polarization degree as a function of ray elevation angle.
Averages over all azimuth angles to show how polarization varies with the ray angle from horizontal.
- Parameters:
recorded_rays (RecordedRays) – Recorded rays at the detection sphere, must have polarization_vectors.
bins (int) – Number of elevation angle bins.
figsize (tuple) – Figure size (width, height).
save_path (str, optional) – Path to save figure.
- Returns:
Matplotlib figure with polarization vs elevation plots.
- Return type:
Figure
Notes
- The polarization degree is computed as:
DoP = (E_x² - E_y²) / (E_x² + E_y²)
Where E_x is the horizontal component and E_y is the vertical component of the polarization vector. DoP = +1 means fully horizontal polarization, DoP = -1 means fully vertical polarization, DoP = 0 means unpolarized or 45° linear polarization.
- lsurf.visualization.plot_fresnel_reflectance_curves(n1=1.0, n2=1.33, angles_deg=None, brewster_angle_deg=None, figsize=(8, 6), save_path=None)[source]
Plot Fresnel reflection coefficients R_s, R_p, and R_unpolarized vs elevation.
Creates a single-subplot figure showing how the reflection coefficients for s-polarization, p-polarization, and unpolarized light vary with elevation angle (angle above horizontal). This convention matches the measured reflectance plots for easy comparison.
- Parameters:
n1 (float, optional) – Refractive index of incident medium (default: 1.0 for air)
n2 (float, optional) – Refractive index of transmitting medium (default: 1.33 for water)
angles_deg (ndarray, optional) – Elevation angles in degrees to compute (default: 0 to 90 in 0.5° steps)
brewster_angle_deg (float, optional) – Brewster angle (as incidence angle) to mark on plot. If None, computed from n1, n2.
figsize (tuple, optional) – Figure size in inches
save_path (str, optional) – Path to save figure
- Returns:
Matplotlib figure
- Return type:
Figure
Notes
The x-axis shows elevation angle (angle above horizontal), which relates to incidence angle as: elevation = 90° - incidence_angle.
Low elevation (grazing) → high incidence angle → high reflectance
High elevation (steep) → low incidence angle → low reflectance
Fresnel equations for reflection: - R_s = |r_s|² where r_s = (n1*cos_i - n2*cos_t) / (n1*cos_i + n2*cos_t) - R_p = |r_p|² where r_p = (n2*cos_i - n1*cos_t) / (n2*cos_i + n1*cos_t) - R_unpolarized = (R_s + R_p) / 2
Brewster angle: θ_B = arctan(n2/n1), where R_p = 0
- lsurf.visualization.plot_measured_polarization_reflectance(recorded_rays, bins=50, figsize=(10, 6), save_path=None)[source]
Plot measured reflected intensity decomposed into s and p polarization.
Analyzes recorded rays to show how the reflected intensity is distributed between s-polarization (horizontal) and p-polarization (vertical) as a function of ray elevation angle. This treats the surface as an unknown reflector and measures its polarization behavior.
- Parameters:
recorded_rays (RecordedRays) – Recorded rays with polarization vectors
bins (int, optional) – Number of elevation angle bins (default: 50)
figsize (tuple, optional) – Figure size in inches
save_path (str, optional) – Path to save figure
- Returns:
Matplotlib figure
- Return type:
Figure
Notes
For each ray, the polarization vector is decomposed into: - s-component: horizontal (perpendicular to vertical plane containing ray) - p-component: vertical (in the vertical plane containing ray)
The intensity is then weighted by |E_s|² and |E_p|² to get the intensity in each polarization state.
- lsurf.visualization.get_ray_coordinates(recorded_rays, projection='angular')[source]
Convert recorded rays to coordinates for binning/plotting.
- Parameters:
recorded_rays (RecordedRays) – Recorded rays at the detection sphere.
projection (str) – Type of projection for binning: - ‘angular’: Use elevation and azimuth angles - ‘spatial’: Use X and Y positions on detection surface
- Returns:
x_coord (ndarray) – X coordinates for plotting/binning.
y_coord (ndarray) – Y coordinates for plotting/binning.
xlabel (str) – Label for x-axis.
ylabel (str) – Label for y-axis.
- Return type:
- lsurf.visualization.plot_ray_paths_2d(ray_history, max_rays=100, color_by='wavelength', alpha=0.4, linewidth=0.8, figsize=(15, 5), save_path=None)[source]
Create figure with three 2D projections of ray paths.
This is a convenience function for quick visualization. For custom layouts, use plot_ray_paths_projection() on individual axes.
- Parameters:
ray_history (List[RayBatch]) – List of ray batches at different propagation steps.
max_rays (int) – Maximum rays to plot (sampled uniformly if exceeded).
color_by (str) – Color rays by: ‘wavelength’, ‘intensity’, ‘generation’, ‘index’.
alpha (float) – Line transparency.
linewidth (float) – Line width.
figsize (tuple) – Figure size.
save_path (str, optional) – Path to save figure.
- Returns:
Matplotlib figure with three subplots (XY, XZ, YZ).
- Return type:
Figure
- lsurf.visualization.plot_ray_endpoints(rays, plane='xy', color_by='wavelength', bins=50, figsize=(12, 5), save_path=None)[source]
Create figure with scatter and histogram of ray endpoints.
This is a convenience function for quick visualization. For custom layouts, use plot_ray_endpoints_scatter() and plot_ray_endpoints_histogram().
- Parameters:
- Returns:
Matplotlib figure with scatter and histogram.
- Return type:
Figure
- lsurf.visualization.plot_beam_slice(ax, rays, axis='z', slice_value=0.0, slice_width=0.1, color_by='intensity', point_size=20, alpha=0.6, show_colorbar=True)[source]
Plot beam profile at a specific slice along propagation axis.
- Parameters:
ax (Axes) – Matplotlib axes.
rays (RayBatch) – Ray batch.
axis (str) – Propagation axis: ‘x’, ‘y’, or ‘z’.
slice_value (float) – Position along axis to slice.
slice_width (float) – Width of slice.
color_by (str) – Color by: ‘intensity’, ‘wavelength’.
point_size (float) – Scatter point size.
alpha (float) – Transparency.
show_colorbar (bool) – Whether to add colorbar.
- Returns:
ScalarMappable for external colorbar.
- Return type:
scatter or None
- lsurf.visualization.plot_wavelength_histogram(ax, rays, bins=50, alpha=0.7, color='steelblue', edgecolor='black', label=None, weight_by_intensity=False)[source]
Plot histogram of ray wavelengths.
- Parameters:
- lsurf.visualization.plot_wavelength_intensity_histogram(ax, rays, bins=50, alpha=0.7, color='orange', edgecolor='black', label=None)[source]
Plot intensity-weighted histogram of ray wavelengths.
Deprecated: Use plot_wavelength_histogram(weight_by_intensity=True) instead.
- lsurf.visualization.plot_detection_counts(ax, detector_angles_deg, detection_counts, color='blue', marker='o', linewidth=2, markersize=8, label=None)[source]
Plot detection counts vs detector angle.
- Parameters:
ax (Axes) – Matplotlib axes.
detector_angles_deg (ndarray) – Detector angles in degrees.
detection_counts (ndarray) – Number of rays detected.
color (str) – Line color.
marker (str) – Marker style.
linewidth (float) – Line width.
markersize (float) – Marker size.
label (str, optional) – Legend label.
- lsurf.visualization.plot_detection_efficiency(ax, detector_angles_deg, detected_intensities, total_source_intensity, color='magenta', marker='o', linewidth=2, markersize=8, label=None)[source]
Plot detection efficiency vs detector angle.
- Parameters:
ax (Axes) – Matplotlib axes.
detector_angles_deg (ndarray) – Detector angles in degrees.
detected_intensities (ndarray) – Total intensity detected.
total_source_intensity (float) – Total source intensity.
color (str) – Line color.
marker (str) – Marker style.
linewidth (float) – Line width.
markersize (float) – Marker size.
label (str, optional) – Legend label.
- lsurf.visualization.plot_mean_arrival_time(ax, detector_angles_deg, mean_times, std_times=None, detection_counts=None, color='cyan', marker='o', linewidth=2, markersize=8, label=None)[source]
Plot mean arrival time vs detector angle.
- Parameters:
ax (Axes) – Matplotlib axes.
detector_angles_deg (ndarray) – Detector angles in degrees.
mean_times (ndarray) – Mean arrival times in seconds.
std_times (ndarray, optional) – Standard deviation of arrival times.
detection_counts (ndarray, optional) – For masking invalid data.
color (str) – Line color.
marker (str) – Marker style.
linewidth (float) – Line width.
markersize (float) – Marker size.
label (str, optional) – Legend label.
- lsurf.visualization.plot_timing_distribution(ax, all_time_distributions, detector_angles_deg, log_scale=True, show_legend=True, max_curves=10)[source]
Plot arrival time distributions for multiple detector positions.
- Parameters:
ax (Axes) – Matplotlib axes.
all_time_distributions (list) – List of (times, intensities, angles) tuples for each detector.
detector_angles_deg (ndarray) – Detector angles in degrees.
log_scale (bool) – Whether to use log scales.
show_legend (bool) – Whether to show legend.
max_curves (int) – Maximum number of curves to plot.
- lsurf.visualization.plot_arrival_angle_distribution(ax, detector_angles_deg, mean_angles, std_angles=None, detection_counts=None, color='magenta', marker='o', linewidth=2, markersize=8)[source]
Plot mean arrival angle vs detector position.
- Parameters:
ax (Axes) – Matplotlib axes.
detector_angles_deg (ndarray) – Detector position angles.
mean_angles (ndarray) – Mean arrival angles to normal.
std_angles (ndarray, optional) – Standard deviation.
detection_counts (ndarray, optional) – For masking invalid data.
color (str) – Line color.
marker (str) – Marker style.
linewidth (float) – Line width.
markersize (float) – Marker size.
- lsurf.visualization.plot_angular_histogram(ax, all_time_distributions, detection_counts, bins=50, color='purple', alpha=0.7)[source]
Plot histogram of all arrival angles.
- lsurf.visualization.create_wavelength_figure(rays, bins=50, figsize=(10, 5), title='Wavelength Distribution', save_path=None)[source]
Create figure with wavelength histograms.
- lsurf.visualization.create_beam_profile_figure(rays, axis='z', num_slices=5, figsize=(15, 4), title=None, save_path=None)[source]
Create figure showing beam profile at multiple slices.
- lsurf.visualization.create_detector_scan_figure(detector_angles_deg, detection_counts, detected_intensities, total_source_intensity, mean_arrival_times=None, std_arrival_times=None, mean_angles_to_normal=None, std_angles_to_normal=None, all_time_distributions=None, figsize=(16, 12), title='Detector Scan Results', save_path=None)[source]
Create comprehensive detector scan figure.
- Parameters:
detector_angles_deg (ndarray) – Detector angles in degrees.
detection_counts (ndarray) – Number of rays detected.
detected_intensities (ndarray) – Total intensity detected.
total_source_intensity (float) – Source intensity.
mean_arrival_times (ndarray, optional) – Mean arrival times.
std_arrival_times (ndarray, optional) – Std of arrival times.
mean_angles_to_normal (ndarray, optional) – Mean arrival angles.
std_angles_to_normal (ndarray, optional) – Std of arrival angles.
all_time_distributions (list, optional) – Timing data.
figsize (tuple) – Figure size.
title (str) – Figure title.
save_path (str, optional) – Save path.
- Returns:
Matplotlib figure.
- Return type:
Figure
- lsurf.visualization.plot_detector_scan_results(detector_angles_deg, detection_counts, detected_intensities, reflected_rays, surface, total_source_intensity, mean_arrival_times=None, std_arrival_times=None, mean_angles_to_normal=None, std_angles_to_normal=None, all_time_distributions=None, detector_distance=1000.0, detector_radius=5.0, water_normal=None, figsize=(24, 14), save_path=None)[source]
Create comprehensive detector scan visualization with multiple subplots.
This is the full production visualization with all panels including the wave surface and ray visualizations.
- Parameters:
detector_angles_deg (ndarray) – Detector angles in degrees (0-90).
detection_counts (ndarray) – Number of rays detected at each position.
detected_intensities (ndarray) – Total intensity detected at each position.
reflected_rays (RayBatch) – Batch of reflected rays.
surface (Surface) – The surface object (must have _surface_z method).
total_source_intensity (float) – Total intensity of source rays.
mean_arrival_times (ndarray, optional) – Mean arrival time at each detector position.
std_arrival_times (ndarray, optional) – Standard deviation of arrival times.
mean_angles_to_normal (ndarray, optional) – Mean angle to normal at each detector.
std_angles_to_normal (ndarray, optional) – Standard deviation of angles.
all_time_distributions (list, optional) – List of (times, intensities, angles) tuples for each detector.
detector_distance (float) – Distance to detector in meters.
detector_radius (float) – Detector radius in meters.
water_normal (ndarray) – Normal vector for water surface.
figsize (tuple) – Figure size (width, height).
save_path (str, optional) – Path to save figure.
- Returns:
Matplotlib figure with comprehensive visualization.
- Return type:
Figure
- lsurf.visualization.plot_statistics_evolution(stats_history, figsize=(15, 10), save_path=None)[source]
Create figure showing evolution of ray statistics over propagation.
This is a convenience function for visualizing how beam properties change during propagation.
- Parameters:
stats_history (List[RayStatistics]) – List of RayStatistics objects at different propagation steps.
figsize (tuple) – Figure size.
save_path (str, optional) – Path to save figure.
- Returns:
Matplotlib figure with statistics evolution.
- Return type:
Figure
- lsurf.visualization.plot_beam_profile(rays, axis='z', num_slices=5, figsize=(15, 4), save_path=None)[source]
Create figure showing beam profile at multiple slices.
This is an alias for create_beam_profile_figure for backward compatibility.
- lsurf.visualization.plot_wavelength_distribution(rays, bins=50, figsize=(10, 6), save_path=None)[source]
Create figure showing wavelength distribution of rays.
This is a convenience function for quick visualization. For custom layouts, use plot_wavelength_histogram() on a single axis.
- lsurf.visualization.create_ocean_simulation_figures(original_rays, surface, recorded_rays, reflected_rays, refracted_rays, config, output_dir, timestamp)[source]
Create complete visualization suite for ocean wave simulation.
Generates 8 figures: 1. Ray paths overview (full scale and surface detail) 2. Recorded rays statistics (6-panel figure) 3. Intensity vs angle (log scale, fraction) 4. Intensity vs angle (linear scale, fraction) 5. Intensity density (log scale, ns⁻¹) 6. Intensity density (linear scale, ns⁻¹) 7. 3D visualization 8. Energy conservation check
- Parameters:
original_rays (RayBatch) – Initial input rays before interaction
surface (CurvedWaveSurface) – The ocean surface model
recorded_rays (RecordedRays) – Rays detected at the recording sphere
reflected_rays (RayBatch) – Reflected rays from surface
refracted_rays (RayBatch) – Refracted rays into water
config (dict) – Simulation configuration parameters
output_dir (str) – Directory for output files
timestamp (str) – Timestamp string for filenames
- lsurf.visualization.plot_geometry_schematic(source_position, beam_direction, grazing_angle_deg, detector_altitude, intersection_points, reflected_directions, n_rays_to_show=20, save_path=None)[source]
Plot a schematic overview of the simulation geometry.
Shows side view (x-z plane) with source, rays, ocean surface, and detector sphere.
- Parameters:
source_position (tuple) – Source (x, y, z) position in meters
beam_direction (tuple or ndarray) – Beam direction unit vector
grazing_angle_deg (float) – Grazing angle in degrees
detector_altitude (float) – Detector sphere radius in meters
intersection_points (ndarray, shape (N, 3)) – XYZ coordinates of surface intersections
reflected_directions (ndarray, shape (N, 3)) – Direction vectors of reflected rays
n_rays_to_show (int) – Number of rays to display
save_path (str, optional) – Path to save figure
- Returns:
fig – The created figure
- Return type:
- lsurf.visualization.plot_ocean_intersections_top_view(intersection_points, wave_surface=None, n_bins=100, save_path=None)[source]
Plot top-down heatmap of where rays hit the ocean surface.
- Parameters:
intersection_points (ndarray, shape (N, 3)) – XYZ coordinates of surface intersections
wave_surface (CurvedWaveSurface, optional) – The ocean surface for context (not currently used)
n_bins (int) – Number of bins for the 2D histogram
save_path (str, optional) – Path to save figure
- Returns:
fig – The created figure
- Return type:
- lsurf.visualization.plot_3d_intersection_scatter(intersection_points, save_path=None)[source]
3D scatter plot of ocean surface intersection points with equal axes.
- Parameters:
intersection_points (ndarray, shape (N, 3)) – XYZ coordinates of surface intersections
save_path (str, optional) – Path to save figure
- Returns:
fig – The created figure
- Return type:
- lsurf.visualization.plot_pareto_front(pareto_result, time_threshold_ns=10.0, source_power=1.0, save_path=None)[source]
Plot the Pareto front of energy density vs time spread.
- Parameters:
- Returns:
fig – The created figure, or None if no data
- Return type:
matplotlib.figure.Figure or None
- lsurf.visualization.plot_energy_density_map(peak_result, recorded_rays, source_power=1.0, detector_center=None, save_path=None)[source]
Plot energy density map on detector sphere with peak location marked.
- Parameters:
peak_result (dict) – Result from find_peak_energy_density()
recorded_rays (RecordedRays) – Recorded rays for overlay
source_power (float) – Input source power for normalization (W)
detector_center (array-like, optional) – Center of detector sphere (not used currently)
save_path (str, optional) – Path to save figure
- Returns:
fig – The created figure
- Return type:
- lsurf.visualization.plot_mollweide_detector_projection(recorded_rays, save_path=None)[source]
Mollweide projection showing where rays intersect the detector sphere.
- Parameters:
recorded_rays (RecordedRays) – Recorded rays on detection sphere
save_path (str, optional) – Path to save figure
- Returns:
fig – The created figure
- Return type:
- lsurf.visualization.plot_time_spread_comparison(pareto_result, source_position, beam_direction, divergence_angle_rad, detector_altitude, surface=None, n_top=10, source_power=1.0, time_threshold_ns=10.0, save_path=None)[source]
Compare ray-traced time spread with single-bounce geometric estimate.
The geometric estimate assumes a single reflection (source → surface → detector). Ray-traced values may exceed this if rays take multi-bounce paths due to atmospheric refraction causing rays to return to the surface multiple times.
- Parameters:
pareto_result (dict) – Result from compute_pareto_front()
source_position (tuple) – Source (x, y, z) position in meters
beam_direction (tuple) – Beam direction unit vector
divergence_angle_rad (float) – Beam half-angle divergence in radians
detector_altitude (float) – Detector sphere radius in meters
surface (Surface, optional) – Surface object for geometric estimate. If None, uses flat surface at z=0.
n_top (int) – Number of top intensity bins to analyze
source_power (float) – Input source power for normalization (W)
time_threshold_ns (float) – Time threshold for highlighting (ns)
save_path (str, optional) – Path to save figure
- Returns:
fig – The created figure
- Return type:
- lsurf.visualization.plot_arrival_time_distributions(recorded_rays, pareto_result, n_top=10, bins=50, time_threshold_ns=10.0, save_path=None)[source]
Plot arrival time histograms for the top N intensity bins.
Shows the actual distribution of arrival times (not just percentiles) for each of the highest energy density detector bins.
- Parameters:
recorded_rays (RecordedRays) – Recorded rays on detection sphere
pareto_result (dict) – Result from compute_pareto_front()
n_top (int) – Number of top intensity bins to plot
bins (int) – Number of histogram bins
time_threshold_ns (float) – Time threshold to mark on plots (ns)
save_path (str, optional) – Path to save figure
- Returns:
fig – The created figure, or None if no data
- Return type:
matplotlib.figure.Figure or None
- lsurf.visualization.plot_time_spread_geometry_side(ax, result, source_position, detector_position, scale=1000.0)[source]
Plot side view (X-Z plane) of time spread geometry.
- Parameters:
ax (Axes) – Matplotlib axes to plot on.
result (TimeSpreadResult) – Time spread estimation result.
source_position (tuple) – (x, y, z) source position in meters.
detector_position (tuple) – (x, y, z) detector position in meters.
scale (float) – Scale factor for display (default 1000 for km).
- lsurf.visualization.plot_beam_footprint_top(ax, result, source_position, detector_position, grazing_angle_deg=None)[source]
Plot top view (X-Y plane) of beam footprint.
- Parameters:
ax (Axes) – Matplotlib axes to plot on.
result (TimeSpreadResult) – Time spread estimation result.
source_position (tuple) – (x, y, z) source position in meters.
detector_position (tuple) – (x, y, z) detector position in meters.
grazing_angle_deg (float, optional) – Grazing angle for display in info box.
- lsurf.visualization.plot_arrival_time_histogram(ax, result, threshold_ns=10.0)[source]
Plot histogram of arrival times for edge rays.
- Parameters:
ax (Axes) – Matplotlib axes to plot on.
result (TimeSpreadResult) – Time spread estimation result.
threshold_ns (float) – Time threshold to mark on plot.
- lsurf.visualization.plot_footprint_arrival_times(ax, result)[source]
Plot footprint colored by arrival time.
- Parameters:
ax (Axes) – Matplotlib axes to plot on.
result (TimeSpreadResult) – Time spread estimation result.
- lsurf.visualization.plot_time_spread_vs_divergence(ax, divergences_deg, time_spreads_ns, threshold_ns=10.0, source_altitude=None, grazing_angle_deg=None, detector_altitude=None)[source]
Plot time spread as function of beam divergence.
- Parameters:
ax (Axes) – Matplotlib axes to plot on.
divergences_deg (ndarray) – Array of divergence angles in degrees.
time_spreads_ns (ndarray) – Corresponding time spreads in nanoseconds.
threshold_ns (float) – Time threshold to mark on plot.
source_altitude (float, optional) – Parameters for title display.
grazing_angle_deg (float, optional) – Parameters for title display.
detector_altitude (float, optional) – Parameters for title display.
- lsurf.visualization.create_time_spread_schematic(result, source_position, detector_position, grazing_angle_deg=None, save_path=None)[source]
Create composite figure showing time spread geometry.
- Parameters:
result (TimeSpreadResult) – Time spread estimation result.
source_position (tuple) – (x, y, z) source position in meters.
detector_position (tuple) – (x, y, z) detector position in meters.
grazing_angle_deg (float, optional) – Grazing angle for display.
save_path (str, optional) – Path to save figure.
- Returns:
fig – Matplotlib figure.
- Return type:
Figure
- lsurf.visualization.create_arrival_time_figure(result, threshold_ns=10.0, save_path=None)[source]
Create composite figure showing arrival time distribution.
- Parameters:
result (TimeSpreadResult) – Time spread estimation result.
threshold_ns (float) – Time threshold to mark on plot.
save_path (str, optional) – Path to save figure.
- Returns:
fig – Matplotlib figure.
- Return type:
Figure
- lsurf.visualization.plot_ray_trajectories(ax, trajectories, source_altitude=0.0, show_straight_lines=True, show_earth_surface=True, duct_center=0.0, duct_width=0.0, xlim=None, ylim=None, cmap='turbo', linewidth=1.5, impact_parameter_keys=False, use_colorbar=False)[source]
Plot ray trajectories on a single axis.
- Parameters:
ax (matplotlib.axes.Axes) – Axes to plot on.
trajectories (dict) – Dictionary mapping initial angle (degrees) or impact parameter (meters) to trajectory array. Each trajectory is shape (N, 2) with [x, z] in meters.
source_altitude (float) – Source altitude in meters (for straight line reference).
show_straight_lines (bool) – If True, show dashed straight-line references.
show_earth_surface (bool) – If True, show Earth’s curved surface.
xlim (tuple, optional) – X-axis limits in km.
ylim (tuple, optional) – Y-axis limits in km.
cmap (str) – Colormap for ray colors.
linewidth (float) – Line width for trajectories.
impact_parameter_keys (bool) – If True, dictionary keys are impact parameters in meters (not angles).
use_colorbar (bool) – If True, use colorbar instead of legend (better for many rays).
- Returns:
sm – ScalarMappable for colorbar if use_colorbar=True, else None.
- Return type:
ScalarMappable or None
Examples
>>> fig, ax = plt.subplots() >>> plot_ray_trajectories(ax, trajectories, source_altitude=0) >>> plt.show()
- lsurf.visualization.plot_refractive_index_profile(ax, atmosphere, max_altitude_km=100.0, n_points=500, color='b', linewidth=2.0, annotate_sea_level=True, wavelength=5.32e-07)[source]
Plot refractive index vs altitude profile.
- Parameters:
ax (matplotlib.axes.Axes) – Axes to plot on.
atmosphere (MaterialField) – Atmosphere material with n_at_altitude method.
max_altitude_km (float) – Maximum altitude in km.
n_points (int) – Number of points for profile.
color (str) – Line color.
linewidth (float) – Line width.
annotate_sea_level (bool) – If True, annotate the sea level value.
wavelength (float) – Wavelength in meters for spectral atmospheres (default: 532nm).
Examples
>>> fig, ax = plt.subplots() >>> plot_refractive_index_profile(ax, atmosphere) >>> plt.show()
- lsurf.visualization.plot_trajectory_offset(ax, trajectories, source_altitude=0.0, cmap='turbo', linewidth=1.5, xlim=None)[source]
Plot angular deviation from initial ray direction vs horizontal distance.
Shows how much the ray direction has changed from its initial launch angle as it propagates through the atmosphere. Atmospheric refraction typically bends rays downward (toward higher n), resulting in negative angular offsets.
- Parameters:
ax (matplotlib.axes.Axes) – Axes to plot on.
trajectories (dict) – Dictionary mapping initial angle (degrees) to trajectory array. Each trajectory is shape (N, 2) with columns [x, z] in meters.
source_altitude (float) – Source altitude in meters (unused, kept for API compatibility).
cmap (str) – Colormap for ray colors.
linewidth (float) – Line width for curves.
xlim (tuple, optional) – X-axis limits in km.
Examples
>>> fig, ax = plt.subplots() >>> plot_trajectory_offset(ax, trajectories, source_altitude=0) >>> plt.show()
- lsurf.visualization.plot_horizontal_ray_deviation(ax, trajectories, cmap='turbo', linewidth=1.5, xlim=None, use_colorbar=False)[source]
Plot angular deviation from initial direction for rays with varying impact parameters.
For rays that start at different altitudes (impact parameters), this shows how each ray bends relative to its initial direction as it propagates through the atmosphere. Atmospheric refraction typically bends rays downward.
- Parameters:
ax (matplotlib.axes.Axes) – Axes to plot on.
trajectories (dict) – Dictionary mapping impact parameter (meters) to trajectory array. Each trajectory is shape (N, 2) with columns [x, z] in meters.
cmap (str) – Colormap for ray colors.
linewidth (float) – Line width for curves.
xlim (tuple, optional) – X-axis limits in km.
use_colorbar (bool) – If True, skip legend (colorbar added externally).
Examples
>>> fig, ax = plt.subplots() >>> plot_horizontal_ray_deviation(ax, trajectories) >>> plt.show()
- lsurf.visualization.create_atmospheric_refraction_figure(trajectories, atmosphere, title='Atmospheric Refraction', source_altitude=0.0, xlim=None, ylim=None, show_earth_surface=True, show_straight_lines=True, duct_center=0.0, duct_width=0.0, figsize=(14, 5))[source]
Create a two-panel figure with ray trajectories and refractive index profile.
- Parameters:
trajectories (dict) – Dictionary mapping initial angle (degrees) to trajectory array. Each trajectory is shape (N, 2) with columns [x, z] in meters.
atmosphere (MaterialField) – Atmosphere material with n_at_altitude method.
title (str) – Title for the trajectory plot.
source_altitude (float) – Source altitude in meters.
xlim (tuple, optional) – X-axis limits in km for trajectory plot.
ylim (tuple, optional) – Y-axis limits in km for trajectory plot.
show_earth_surface (bool) – If True, show Earth’s curved surface in trajectory plot.
show_straight_lines (bool) – If True, show dashed straight-line references.
figsize (tuple) – Figure size (width, height) in inches.
- Returns:
fig – The created figure.
- Return type:
Examples
>>> fig = create_atmospheric_refraction_figure( ... trajectories, atmosphere, ... title="Exponential Atmosphere", ... xlim=(0, 1000), ylim=(0, 100), ... ) >>> plt.savefig("refraction.png")
- lsurf.visualization.create_atmospheric_refraction_figure_with_offset(trajectories, atmosphere, title='Atmospheric Refraction', source_altitude=0.0, xlim=None, ylim=None, show_earth_surface=True, show_straight_lines=True, duct_center=0.0, duct_width=0.0, figsize=(16, 10), horizontal_rays=False)[source]
Create a four-panel figure with trajectories, offset, and refractive index.
Panels: - Top-left: Ray trajectories (refracted vs straight-line) - Top-right: Refractive index profile vs altitude - Bottom: Altitude offset between refracted and straight paths
- Parameters:
trajectories (dict) – Dictionary mapping initial angle (degrees) to trajectory array. Each trajectory is shape (N, 2) with columns [x, z] in meters.
atmosphere (MaterialField) – Atmosphere material with n_at_altitude method.
title (str) – Title for the figure.
source_altitude (float) – Source altitude in meters.
xlim (tuple, optional) – X-axis limits in km for trajectory plot.
ylim (tuple, optional) – Y-axis limits in km for trajectory plot.
show_earth_surface (bool) – If True, show Earth’s curved surface in trajectory plot.
show_straight_lines (bool) – If True, show dashed straight-line references.
figsize (tuple) – Figure size (width, height) in inches.
horizontal_rays (bool) – If True, use plot for horizontal rays with varying impact parameters. If False (default), use plot for rays with varying initial angles.
- Returns:
fig – The created figure.
- Return type:
Examples
>>> fig = create_atmospheric_refraction_figure_with_offset( ... trajectories, atmosphere, ... title="Exponential Atmosphere", ... xlim=(0, 1000), ylim=(0, 100), ... ) >>> plt.savefig("refraction_with_offset.png")
- lsurf.visualization.plot_trajectory_comparison(results, figsize=None, suptitle='Atmospheric Model Comparison')[source]
Create a comparison figure with multiple trajectory plots.
- Parameters:
results (list of dict) – List of result dictionaries, each containing: - ‘trajectories’: dict mapping angle to trajectory array - ‘title’: plot title - ‘xlim’: x-axis limits in km - ‘ylim’: y-axis limits in km
figsize (tuple, optional) – Figure size. Auto-determined if None.
suptitle (str) – Super title for the figure.
- Returns:
fig – The created figure.
- Return type:
Examples
>>> results = [ ... {'trajectories': traj1, 'title': 'Model A', 'xlim': (0, 100), 'ylim': (0, 50)}, ... {'trajectories': traj2, 'title': 'Model B', 'xlim': (0, 100), 'ylim': (0, 50)}, ... ] >>> fig = plot_trajectory_comparison(results)
- lsurf.visualization.save_atmospheric_figure(fig, filename, output_dir=None, dpi=150)[source]
Save an atmospheric refraction figure.
- Parameters:
fig (matplotlib.figure.Figure) – Figure to save.
filename (str or Path) – Output filename.
output_dir (Path, optional) – Output directory. Created if doesn’t exist.
dpi (int) – Resolution in dots per inch.
- Returns:
output_path – Full path to saved file.
- Return type:
Path
- lsurf.visualization.plot_homogeneous_absorption(alpha, distance, simulated_intensity, simulated_optical_depth, initial_intensity=1.0, save_path=None, show=True)[source]
Plot Beer-Lambert decay for homogeneous absorbing medium.
- Parameters:
alpha (float) – Absorption coefficient in m^-1
distance (float) – Total propagation distance in m
simulated_intensity (float) – Simulated final intensity
simulated_optical_depth (float) – Simulated accumulated optical depth
initial_intensity (float) – Initial intensity (default 1.0)
save_path (str or Path, optional) – Path to save figure
show (bool) – Whether to display the figure
- Returns:
The matplotlib figure
- Return type:
plt.Figure
- lsurf.visualization.plot_exponential_atmosphere_absorption(alpha_sea_level, scale_height, final_altitude, simulated_intensity, simulated_optical_depth, max_altitude=100000.0, save_path=None, show=True)[source]
Plot absorption profiles for exponential atmosphere.
- Parameters:
alpha_sea_level (float) – Absorption coefficient at sea level in m^-1
scale_height (float) – Atmospheric scale height in m
final_altitude (float) – Final ray altitude in m
simulated_intensity (float) – Simulated final intensity
simulated_optical_depth (float) – Simulated accumulated optical depth
max_altitude (float) – Maximum altitude for plots in m
save_path (str or Path, optional) – Path to save figure
show (bool) – Whether to display the figure
- Returns:
The matplotlib figure
- Return type:
plt.Figure
- lsurf.visualization.plot_spectral_atmosphere_absorption(get_extinction, get_optical_depth, earth_radius, ray_wavelengths, ray_positions, ray_optical_depths, wavelength_range=(3e-07, 1.5e-06), altitude_range=(0, 50000), test_altitudes=None, test_wavelengths=None, save_path=None, show=True)[source]
Plot spectral absorption characteristics.
- Parameters:
get_extinction (callable) – Function(altitude, wavelength) -> extinction coefficient
get_optical_depth (callable) – Function(z1, z2, wavelength) -> optical depth
earth_radius (float) – Earth radius in m
ray_wavelengths (ndarray) – Array of ray wavelengths in m
ray_positions (ndarray) – Array of ray positions (N, 3)
ray_optical_depths (ndarray) – Array of simulated optical depths
wavelength_range (tuple) – (min, max) wavelength in m for plots
altitude_range (tuple) – (min, max) altitude in m for plots
test_altitudes (list, optional) – Altitudes for extinction vs wavelength plot
test_wavelengths (list, optional) – Wavelengths for optical depth vs altitude plot
save_path (str or Path, optional) – Path to save figure
show (bool) – Whether to display the figure
- Returns:
The matplotlib figure
- Return type:
plt.Figure
- lsurf.visualization.plot_geometry_analysis(rings, output_path=None, figsize=(16, 14), dpi=150)[source]
Create 4-panel geometry analysis figure.
Panels: (a) Full geometry schematic (Earth + detector sphere + sample rings) (b) Zoomed view showing no-shadowing geometry with sight lines (c) Distance vs elevation curve (d) Angular width and distance vs ring index
- Parameters:
rings (ConstantSizeDetectorRings) – Detector ring configuration
output_path (str or Path, optional) – If provided, save figure to this path
figsize (tuple) – Figure size in inches
dpi (int) – Resolution for saved figure
- Returns:
Matplotlib figure object
- Return type:
Figure
- lsurf.visualization.plot_ring_side_view(rings, output_path=None, figsize=(16, 8), dpi=150)[source]
Create side view cross-section of detector rings.
Shows all rings with constant physical size and normals pointing toward origin.
- Parameters:
rings (ConstantSizeDetectorRings) – Detector ring configuration
output_path (str or Path, optional) – If provided, save figure to this path
figsize (tuple) – Figure size in inches
dpi (int) – Resolution for saved figure
- Returns:
Matplotlib figure object
- Return type:
Figure
- lsurf.visualization.plot_ring_overview(rings, ring_intensities, detected_positions=None, output_path=None, figsize=(10, 10), dpi=150)[source]
Create top-down ring overview with intensity coloring.
- Parameters:
rings (ConstantSizeDetectorRings) – Detector ring configuration
ring_intensities (ndarray) – Total intensity per ring (shape: n_rings)
detected_positions (ndarray, optional) – Ray detection positions (N, 3) for scatter overlay
output_path (str or Path, optional) – If provided, save figure to this path
figsize (tuple) – Figure size in inches
dpi (int) – Resolution for saved figure
- Returns:
Matplotlib figure object
- Return type:
Figure
- lsurf.visualization.plot_ring_azimuth_heatmap(rings, intensity_map, ray_count_map, az_min=-10.0, az_max=10.0, output_path=None, figsize=(14, 6), dpi=150)[source]
Create ring-azimuth heatmaps for intensity and ray count.
- Parameters:
rings (ConstantSizeDetectorRings) – Detector ring configuration
intensity_map (ndarray) – Intensity per (ring, azimuth_bin), shape (n_rings, n_az_bins)
ray_count_map (ndarray) – Ray count per (ring, azimuth_bin), shape (n_rings, n_az_bins)
az_min (float) – Azimuth range in degrees
az_max (float) – Azimuth range in degrees
output_path (str or Path, optional) – If provided, save figure to this path
figsize (tuple) – Figure size in inches
dpi (int) – Resolution for saved figure
- Returns:
Matplotlib figure object
- Return type:
Figure
- lsurf.visualization.plot_timing_heatmap(rings, first_arrival_map, time_spread_map, global_first_ns, az_min=-10.0, az_max=10.0, output_path=None, figsize=(14, 6), dpi=150)[source]
Create timing heatmaps (first arrival and time spread).
- Parameters:
rings (ConstantSizeDetectorRings) – Detector ring configuration
first_arrival_map (ndarray) – First arrival time per bin in ns, shape (n_rings, n_az_bins)
time_spread_map (ndarray) – Time spread (10-90%) per bin in ns, shape (n_rings, n_az_bins)
global_first_ns (float) – Global first arrival time in ns (for relative timing)
az_min (float) – Azimuth range in degrees
az_max (float) – Azimuth range in degrees
output_path (str or Path, optional) – If provided, save figure to this path
figsize (tuple) – Figure size in inches
dpi (int) – Resolution for saved figure
- Returns:
Matplotlib figure object
- Return type:
Figure
- lsurf.visualization.plot_per_ring_timing_distributions(rings, ring_data, az_limit=10.0, output_path=None, figsize_per_col=4.0, figsize_per_row=3.5, dpi=150)[source]
Create per-ring timing distribution histograms.
- Parameters:
rings (ConstantSizeDetectorRings) – Detector ring configuration
ring_data (list of dict) – List of dicts with keys: - ring_idx: int - az_center: float (azimuth center in degrees) - times_rel_ns: ndarray (times relative to bin first arrival, ns) - intensities: ndarray (ray intensities) - dist_km: float
az_limit (float) – Azimuth limit for title
output_path (str or Path, optional) – If provided, save figure to this path
figsize_per_col (float) – Figure size multipliers
figsize_per_row (float) – Figure size multipliers
dpi (int) – Resolution for saved figure
- Returns:
Matplotlib figure object, or None if no data
- Return type:
Figure or None
- lsurf.visualization.plot_spread_analysis(rings, ring_stats, output_path=None, figsize=(14, 5), dpi=150)[source]
Create per-ring spread analysis (azimuthal and timing).
- Parameters:
rings (ConstantSizeDetectorRings) – Detector ring configuration
ring_stats (list of dict) – List of dicts with keys: - ring_idx: int - n_rays: int - az_std: float (azimuth std in degrees) - time_spread_ns: float - dist_km: float
output_path (str or Path, optional) – If provided, save figure to this path
figsize (tuple) – Figure size in inches
dpi (int) – Resolution for saved figure
- Returns:
Matplotlib figure object, or None if no data
- Return type:
Figure or None
- lsurf.visualization.plot_polar_irradiance(rings, irradiance_map, n_azimuth_bins, output_path=None, figsize=(10, 10), dpi=150)[source]
Create polar heatmap of irradiance.
- Parameters:
rings (ConstantSizeDetectorRings) – Detector ring configuration
irradiance_map (ndarray) – Irradiance per (ring, azimuth_bin), shape (n_rings, n_azimuth_bins)
n_azimuth_bins (int) – Number of azimuth bins
output_path (str or Path, optional) – If provided, save figure to this path
figsize (tuple) – Figure size in inches
dpi (int) – Resolution for saved figure
- Returns:
Matplotlib figure object
- Return type:
Figure
- lsurf.visualization.plot_ring_time_spread_comparison(rings, ring_stats, source_position, beam_direction, divergence_angle_rad, surface=None, output_path=None, figsize=(14, 5), dpi=150)
Compare ray-traced time spread with geometric estimate.
The geometric estimate computes the path difference for rays at the edge of the divergence cone reflecting through the beam footprint on the surface.
- Parameters:
rings (ConstantSizeDetectorRings) – Detector ring configuration
ring_stats (list of dict) – Per-ring statistics with time_spread_ns and dist_km
source_position (tuple) – Source (x, y, z) position in meters
beam_direction (tuple) – Beam direction unit vector
divergence_angle_rad (float) – Beam half-angle divergence in radians
surface (Surface, optional) – Ocean surface for geometric estimate. If None, uses flat surface at z=0.
output_path (str or Path, optional) – If provided, save figure to this path
figsize (tuple) – Figure size in inches
dpi (int) – Resolution for saved figure
- Returns:
Matplotlib figure object, or None if no data
- Return type:
Figure or None
- lsurf.visualization.plot_constant_size_timing_analysis(rings, bin_stats, output_path=None, figsize=(16, 10), dpi=150)[source]
Plot timing analysis for constant physical size bins.
Creates a 2x2 figure: - (a) Time spread vs distance (each point is one bin) - (b) First arrival vs distance - (c) Time spread heatmap (ring vs azimuth, scaled to show structure) - (d) Number of azimuth bins per ring (shows scaling with distance)
- Parameters:
- Returns:
Matplotlib figure object, or None if no data
- Return type:
Figure or None
- lsurf.visualization.plot_constant_size_timing_distributions(rings, bin_stats, ray_positions, ray_times, ray_intensities, n_top=12, output_path=None, figsize_per_col=4.0, figsize_per_row=3.5, dpi=150)[source]
Plot timing distributions for top bins by ray count.
- Parameters:
rings (ConstantSizeDetectorRings) – Detector ring configuration
bin_stats (list of dict) – Results from compute_constant_size_bin_stats
ray_positions (ndarray) – Raw ray data for histogram computation
ray_times (ndarray) – Raw ray data for histogram computation
ray_intensities (ndarray) – Raw ray data for histogram computation
n_top (int) – Number of top bins to plot
output_path (str or Path, optional) – If provided, save figure to this path
figsize_per_col (float) – Figure size multipliers
figsize_per_row (float) – Figure size multipliers
dpi (int) – Resolution for saved figure
- Returns:
Matplotlib figure object, or None if no data
- Return type:
Figure or None
- lsurf.visualization.compute_ring_azimuth_maps(ray_positions, ray_times, ray_intensities, rings, az_min=-10.0, az_max=10.0, n_az_bins=40)[source]
Compute 2D maps of intensity, ray count, and timing by ring and azimuth.
- Parameters:
ray_positions (ndarray) – Ray detection positions (N, 3)
ray_times (ndarray) – Ray detection times (N,)
ray_intensities (ndarray) – Ray intensities (N,)
rings (ConstantSizeDetectorRings) – Detector ring configuration
az_min (float) – Azimuth range in degrees
az_max (float) – Azimuth range in degrees
n_az_bins (int) – Number of azimuth bins
- Returns:
Dictionary with keys: - intensity_map: (n_rings, n_az_bins) total intensity - ray_count_map: (n_rings, n_az_bins) ray count - first_arrival_map: (n_rings, n_az_bins) first arrival time in ns - time_spread_map: (n_rings, n_az_bins) time spread (10-90%) in ns - ray_ring_indices: (N,) ring index per ray - ray_azimuth_deg: (N,) azimuth per ray in degrees
- Return type:
- lsurf.visualization.compute_ring_spread_stats(ray_positions, ray_times, ray_intensities, rings, az_limit=10.0, n_az_bins=40)[source]
Compute per-ring spread statistics (azimuthal and timing).
- Parameters:
ray_positions (ndarray) – Ray detection positions (N, 3)
ray_times (ndarray) – Ray detection times (N,)
ray_intensities (ndarray) – Ray intensities (N,)
rings (ConstantSizeDetectorRings) – Detector ring configuration
az_limit (float) – Azimuth limit in degrees (filter to +/- this range)
n_az_bins (int) – Number of azimuth bins within the range
- Returns:
Per-ring statistics with keys: ring_idx, n_rays, az_std, time_spread_ns, dist_km, total_intensity
- Return type:
- lsurf.visualization.compute_constant_size_bin_stats(ray_positions, ray_times, ray_intensities, rings, az_bin_size_m=10000.0, az_range_deg=10.0, min_rays_per_bin=3)[source]
Compute timing statistics for constant physical size bins.
Each bin has approximately the same physical size: - Radial: detector_radial_size (from rings configuration) - Azimuthal: az_bin_size_m (varies in angular size with distance)
- Parameters:
ray_positions (ndarray) – Ray detection positions (N, 3)
ray_times (ndarray) – Ray detection times (N,)
ray_intensities (ndarray) – Ray intensities (N,)
rings (ConstantSizeDetectorRings) – Detector ring configuration
az_bin_size_m (float) – Physical azimuthal bin size in meters (default: 10 km)
az_range_deg (float) – Azimuth range in degrees (±this value)
min_rays_per_bin (int) – Minimum rays required to compute statistics
- Returns:
Per-bin statistics with keys: - ring_idx, az_bin_idx, n_az_bins - az_center_deg, elev_center_deg - distance_km - n_rays, total_intensity - first_arrival_ns (relative to global first) - time_spread_ns (10-90 percentile) - bin_area_m2
- Return type:
Submodules
Ray Tracing Visualization - Individual Axis Functions |
|
Detector Visualization - Individual Axis Functions |
|
Visualization Common Utilities |