This page was generated from a Jupyter notebook. Check the source code or download the notebook..

Polarization prism with total internal reflection#

This example shows how to perform and subsequently plot a polarization analysis in a prisim with total internal reflection. This notebook depends on the example file Prism using total internal reflection.zmx, which is also supplied.

Included functionalities#

  • Sequential mode:

    • Usage of zospy.analyses.polarization.PolarizationTransmission to perform a polarization transmission analysis.

    • Usage of zospy.analyses.polarization.PolarizationPupilMap to calculate the polarization pupil map.

Warranty and liability#

The examples are provided ‘as is’. There is no warranty and rights cannot be derived from them, as is also stated in the general license of this repository.

Import dependencies#

[1]:
from warnings import warn

import matplotlib.pyplot as plt
import numpy as np

import zospy as zp

Input values#

[2]:
# Input Jones Vector
jx = 1
jy = 1
x_phase = 0
y_phase = 0

Connect to OpticStudio in standalone mode#

[3]:
zos = zp.ZOS()
oss = zos.connect(mode="standalone")

Load the optical system#

Load the example file ‘Prism using total internal reflection’.

[4]:
# OpticStudio requires absolute paths, but ZOSPy can handle relative paths
oss.load("Prism using total internal reflection.zmx")

Render the model#

To render the model, we use the zospy.analyses.systemviewers.Viewer3D function. For this system, zospy.analyses.systemviewers.CrossSection cannot be used because the system is not rotationally symmetric.

[5]:
draw3d = zp.analyses.systemviewers.Viewer3D(
    surface_line_thickness="Thick",
    rays_line_thickness="Thick",
    number_of_rays=7,
    hide_x_bars=True,
).run(oss)

if zos.version < (24, 1, 0):
    warn("Exporting the 3D viewer data is not available for this version of OpticStudio.")
else:
    plt.imshow(draw3d.data)
    plt.axis("off")
../../_images/examples_Polarization_Prism_polarization_prism_example_10_0.png

Transmission analysis#

Run the Transmission analysis from zospy.analyses.polarization.transmission.

[6]:
result_transmission = zp.analyses.polarization.PolarizationTransmission(
    jx=jx, jy=jy, x_phase=x_phase, y_phase=y_phase, sampling="64x64"
).run(oss)


print("Field position     Transmission")

for transmission in result_transmission.data.field_transmissions:
    print(
        f"{transmission.field_pos.value} {transmission.field_pos.unit:<14} {transmission.total_transmission * 100:.2f}%"
    )
Field position     Transmission
0.0 deg            64.18%

Get a polarization map using zospy.analyses.polarization.PolarizationPupilMap

[7]:
result_pupil_map = zp.analyses.polarization.PolarizationPupilMap(
    jx=jx, jy=jy, x_phase=x_phase, y_phase=y_phase, sampling="17x17"
).run(oss)
df = result_pupil_map.data.pupil_map

print(df)
        Px     Py        Ex        Ey  Intensity  Phase (Deg)  Orientation
0   -1.000  0.000  0.478226  0.673308   0.682044   137.096154   122.267525
1   -0.875 -0.375  0.505769  0.668042   0.702082   134.067624   123.969140
2   -0.875 -0.250  0.501666  0.666814   0.696309  -225.063934   123.893391
3   -0.875 -0.125  0.496899  0.665856   0.690273  -223.867939   123.809086
4   -0.875  0.000  0.491385  0.665160   0.683897  -222.250933   123.722118
..     ...    ...       ...       ...        ...          ...          ...
192  0.875  0.000  0.672867  0.476981   0.680261  -222.668754   147.755937
193  0.875  0.125  0.678455  0.475828   0.686713  -220.284484   147.700755
194  0.875  0.250  0.684247  0.474248   0.693105  -217.117400   147.589012
195  0.875  0.375  0.690386  0.472140   0.699549   147.216066   147.420181
196  1.000  0.000  0.683282  0.457999   0.676638   136.423377   149.777610

[197 rows x 7 columns]

Plot the pupil map

[8]:
xy_length = len(np.unique(df["Px"]))

for i in range(len(df)):
    # E-field coordinates
    phi = np.linspace(0, 2 * np.pi) - np.pi / 3
    Ex = np.real(df["Ex"][i] * np.exp(1j * phi)) / xy_length + df["Px"].iloc[i]
    Ey = (
        np.real(df["Ey"].iloc[i] * np.exp(1j * phi + 1j * df["Phase (Deg)"].iloc[i] * np.pi / 180)) / xy_length
        + df["Py"].iloc[i]
    )

    # Plot E-field trajectories
    line = plt.plot(Ex, Ey, "k")

    # Add arrows
    line[0].axes.annotate(
        "",
        xytext=(Ex[0], Ey[0]),
        xy=(Ex[1], Ey[1]),
        arrowprops={"arrowstyle": "->", "color": "k"},
    )
plt.xlabel("Px")
plt.ylabel("Py")
plt.axis("equal")

plt.title("Prism using total internal reflection")
[8]:
Text(0.5, 1.0, 'Prism using total internal reflection')
../../_images/examples_Polarization_Prism_polarization_prism_example_16_1.png