Photodiode Angular Weights#

This example demonstrates how to build a custom angular mask on top of the single-detector Fibonacci mesh using angular_weights.

Single photodiode with custom angular weights, Full detector mesh, Masked detector mesh, Effect of the angular mask
import numpy as np
import matplotlib.pyplot as plt

from PyMieSim import (
    ureg,
    PolarizationState,
    Gaussian,
    Sphere,
    Photodiode,
    Simulation,
)


source = Gaussian(
    wavelength=1064 * ureg.nanometer,
    polarization=PolarizationState(angle=0 * ureg.degree),
    optical_power=1 * ureg.watt,
    numerical_aperture=0.25,
)

scatterer = Sphere(
    diameter=1200 * ureg.nanometer,
    material=1.46,
    medium=1.0,
)

detector = Photodiode(
    numerical_aperture=0.18,
    phi_offset=30 * ureg.degree,
    gamma_offset=10 * ureg.degree,
    sampling=500,
)

setup = Simulation(
    scatterer=scatterer,
    source=source,
    detector=detector,
)

baseline_coupling = setup.get("coupling")

# Rebuild the current mesh explicitly so the example can derive weights from it.
detector.initialize_mesh(scatterer)

x_coordinates = np.asarray(detector.mesh.cartesian.x.magnitude)
y_coordinates = np.asarray(detector.mesh.cartesian.y.magnitude)
z_coordinates = np.asarray(detector.mesh.cartesian.z.magnitude)

# Keep only one side of the collectio n cone to form a simple half-aperture mask.
active_points = x_coordinates >= 0.50
angular_weights = np.zeros(detector.sampling, dtype=np.complex128)
angular_weights[active_points] = 1.0

detector.angular_weights = angular_weights

weighted_active_points = np.abs(detector.angular_weights) > 0.0

masked_coupling = setup.get("coupling")

figure = plt.figure(figsize=(15, 5))

full_mesh_axis = figure.add_subplot(1, 3, 1, projection="3d")
full_mesh_axis.scatter(
    x_coordinates,
    y_coordinates,
    z_coordinates,
    s=18,
    c="#1f77b4",
    label="full detector",
)
full_mesh_axis.set(
    title="Full detector mesh",
    xlabel="x",
    ylabel="y",
    zlabel="z",
)
full_mesh_axis.legend(loc="upper left")

masked_mesh_axis = figure.add_subplot(1, 3, 2, projection="3d")
masked_mesh_axis.scatter(
    x_coordinates[weighted_active_points],
    y_coordinates[weighted_active_points],
    z_coordinates[weighted_active_points],
    s=18,
    c="#1f77b4",
    label="active",
)
masked_mesh_axis.scatter(
    x_coordinates[~weighted_active_points],
    y_coordinates[~weighted_active_points],
    z_coordinates[~weighted_active_points],
    s=18,
    c="#d9d9d9",
    label="masked",
)
masked_mesh_axis.set(
    title="Masked detector mesh",
    xlabel="x",
    ylabel="y",
    zlabel="z",
)
masked_mesh_axis.legend(loc="upper left")

for axis in (full_mesh_axis, masked_mesh_axis):
    axis.set_xlim(-1.0, 1.0)
    axis.set_ylim(-1.0, 1.0)
    axis.set_zlim(-1.0, 1.0)
    axis.view_init(elev=22, azim=38)

coupling_axis = figure.add_subplot(1, 3, 3)
coupling_values = [
    baseline_coupling.to("microwatt").magnitude,
    masked_coupling.to("microwatt").magnitude,
]
coupling_axis.bar(
    ["full detector", "masked detector"],
    coupling_values,
    color=["#4c72b0", "#dd8452"],
)
coupling_axis.set(
    ylabel="Coupling [$\\mu$W]",
    title="Effect of the angular mask",
)

figure.suptitle("Single photodiode with custom angular weights")
figure.tight_layout()

if plt.get_backend().lower() != "agg":
    plt.show()

Total running time of the script: (0 minutes 0.485 seconds)

Gallery generated by Sphinx-Gallery