pypolar.fresnel

Useful routines for planar-interface Fresnel calculations.

The functions in this module assume two semi-infinite media with a planar interface. Light is incident from a medium with real refractive index n_i (default 1), onto a medium with complex refractive index m. Absorbing media follow the pypolar convention m = n - 1j * n * kappa.

Angles are measured from the surface normal. Set deg=True when passing angles in degrees.

Incidence-angle helpers:

* brewster(index_of_refraction, n_i=1, deg=False)
* critical(index_of_refraction, n_i=1, deg=False)

Field-amplitude Fresnel coefficients:

* r_par_amplitude(index_of_refraction, angle, n_i=1, deg=False)
* r_per_amplitude(index_of_refraction, angle, n_i=1, deg=False)
* t_par_amplitude(index_of_refraction, angle, n_i=1, deg=False)
* t_per_amplitude(index_of_refraction, angle, n_i=1, deg=False)

Power (irradiance) Fresnel coefficients:

* R_par(index_of_refraction, angle, n_i=1, deg=False)
* R_per(index_of_refraction, angle, n_i=1, deg=False)
* T_par(index_of_refraction, angle, n_i=1, deg=False)
* T_per(index_of_refraction, angle, n_i=1, deg=False)
* R_unpolarized(index_of_refraction, angle, n_i=1, deg=False)
* T_unpolarized(index_of_refraction, angle, n_i=1, deg=False)

Ellipsometry helpers:

* ellipsometry_rho(index_of_refraction, angle, n_i=1, deg=False)
* ellipsometry_index(rho, angle, n_i=1, deg=False)
pypolar.fresnel.R_par(m, theta_i, n_i=1, deg=False)[source]

Reflected fraction of parallel-polarized optical power by an interface.

The reflected fraction of incident power (or flux) assuming that the electric field of the incident light is polarized parallel (p) to the plane of incidence (transverse magnetic or TM electric field).

The index of refraction for medium of the incoming field defaults to 1, but can be set any real value. The medium of the outgoing field is characterized by an index of refraction that may be complex.

Parameters:
  • m – complex index of refraction of medium [-]

  • theta_i – incidence angle from normal [radians/degrees]

  • n_i – real refractive index of incident medium [-]

  • deg – theta_i is in degrees [True/False]

Returns:

reflected fraction of parallel-polarized irradiance [-]

pypolar.fresnel.R_per(m, theta_i, n_i=1, deg=False)[source]

Return the fraction of perpendicular-polarized optical power reflectedby an interface.

The fraction of the incident power (or flux) reflected at the interface between two semi-infinite media. The incident light is assumed to be polarized perpendicular (s, or senkrecht) to the plane of incidence (transverse electric or TE field).

The index of refraction for medium of the incoming field defaults to 1, but can be set any real value. The medium of the outgoing field is characterized by an index of refraction that may be complex.

Parameters:
  • m – complex index of refraction of medium [-]

  • theta_i – incidence angle from normal [radians/degrees]

  • n_i – real refractive index of incident medium [-]

  • deg – theta_i is in degrees [True/False]

Returns:

reflected fraction of perpendicular-polarized irradiance [-]

pypolar.fresnel.R_unpolarized(m, theta_i, n_i=1, deg=False)[source]

Fraction of unpolarized light that is reflected.

Calculate reflection fraction of incident power (or flux) assuming that the incident light is unpolarized

Parameters:
  • m – complex index of refraction of medium [-]

  • theta_i – incidence angle from normal [radians/degrees]

  • n_i – real refractive index of incident medium [-]

  • deg – theta_i is in degrees [True/False]

Returns:

fraction of unpolarized irradiance reflected [-]

pypolar.fresnel.T_par(m, theta_i, n_i=1, deg=False)[source]

Return the transmitted fraction of parallel-polarized optical power through an interface.

The transmitted fraction of incident power (or flux) assuming that the electric field of the incident light is polarized parallel (p) to the plane of incidence (transverse magnetic or TM electric field).

The index of refraction for medium of the incoming field defaults to 1, but can be set any real value. The medium of the outgoing field is characterized by an index of refraction that may be complex.

Parameters:
  • m – complex index of refraction of medium [-]

  • theta_i – incidence angle from normal [radians/degrees]

  • n_i – real refractive index of incident medium [-]

  • deg – theta_i is in degrees [True/False]

Returns:

transmitted fraction of parallel-polarized irradiance [-]

pypolar.fresnel.T_per(m, theta_i, n_i=1, deg=False)[source]

Return the transmitted fraction of perpendicular-polarized optical power through an interface.

The transmitted fraction of the incident power (or flux) through the interface between two semi-infinite media. The incident light is assumed to be polarized perpendicular (s, or senkrecht) to the plane of incidence (transverse electric or TE field).

The index of refraction for medium of the incoming field defaults to 1, but can be set any real value. The medium of the outgoing field is characterized by an index of refraction that may be complex.

Parameters:
  • m – complex index of refraction of medium [-]

  • theta_i – incidence angle from normal [radians/degrees]

  • n_i – real refractive index of incident medium [-]

  • deg – theta_i is in degrees [True/False]

Returns:

transmitted fraction of perpendicular-polarized irradiance [-]

pypolar.fresnel.T_unpolarized(m, theta_i, n_i=1, deg=False)[source]

Fraction of unpolarized light that is transmitted.

Calculate transmitted fraction of incident power (or flux) assuming that the incident light is unpolarized

Parameters:
  • m – complex index of refraction of medium [-]

  • theta_i – incidence angle from normal [radians/degrees]

  • n_i – real refractive index of incident medium [-]

  • deg – theta_i is in degrees [True/False]

Returns:

fraction of unpolarized irradiance transmitted [-]

pypolar.fresnel.brewster(m, n_i=1, deg=False)[source]

Brewster’s angle for an interface.

Parameters:
  • m – complex index of refraction of medium [-]

  • n_i – real refractive index of incident medium [-]

  • deg – theta_i is in degrees [True/False]

Returns:

Brewster’s angle from normal to surface [radians/degrees]

pypolar.fresnel.critical(m, n_i=1, deg=False)[source]

Critical angle for total internal reflection at interface.

Parameters:
  • m – complex index of refraction of medium [-]

  • n_i – real refractive index of incident medium [-]

  • deg – theta_i is in degrees [True/False]

Returns:

critical angle from normal to surface [radians/degrees]

pypolar.fresnel.ellipsometry_index(rho, theta_i, n_i=1, deg=False)[source]

Calculate the index of refraction for an isotropic sample.

Parameters:
  • rho – r_par_amplitude/r_per_amplitude [-]

  • theta_i – incidence angle from normal [radians/degrees]

  • n_i – real refractive index of incident medium [-]

  • deg – theta_i is in degrees [True/False]

Returns:

complex index of refraction [-]

pypolar.fresnel.ellipsometry_rho(m, theta_i, n_i=1, deg=False)[source]

Calculate the ellipsometer parameter rho.

Parameters:
  • m – complex index of refraction of medium [-]

  • theta_i – incidence angle from normal [radians/degrees]

  • n_i – real refractive index of incident medium [-]

  • deg – theta_i is in degrees [True/False]

Returns:

ellipsometer parameter rho [-]

pypolar.fresnel.r_par_amplitude(m, theta_i, n_i=1, deg=False)[source]

Reflected fraction of parallel-polarized field at an interface.

This is the fraction of the incident electric field reflected at the interface between two semi-infinite media. The incident field is assumed to be polarized parallel (p) to the plane of incidence (transverse magnetic or TM field).

The index of refraction for medium of the incoming field defaults to 1, but can be set any real value. The medium of the outgoing field is characterized by an index of refraction that may be complex.

Parameters:
  • m – complex index of refraction of medium [-]

  • theta_i – incidence angle from normal [radians/degrees]

  • n_i – real refractive index of incident medium [-]

  • deg – theta_i is in degrees [True/False]

Returns:

reflected fraction of parallel field [-]

pypolar.fresnel.r_per_amplitude(m, theta_i, n_i=1, deg=False)[source]

Reflected fraction of perpendicular-polarized field at an interface.

This is the fraction of the incident electric field reflected at the interface between two semi-infinite media. The incident field is assumed to be polarized perpendicular (s, or senkrecht) to the plane of incidence (transverse electric or TE field).

The index of refraction for medium of the incoming field defaults to 1, but can be set any real value. The medium of the outgoing field is characterized by an index of refraction that may be complex.

Parameters:
  • m – complex index of refraction of medium [-]

  • theta_i – incidence angle from normal [radians/degrees]

  • n_i – real refractive index of incident medium [-]

  • deg – theta_i is in degrees [True/False]

Returns:

reflected fraction of perpendicular field [-]

pypolar.fresnel.t_par_amplitude(m, theta_i, n_i=1, deg=False)[source]

Find the transmitted fraction of parallel-polarized field through an interface.

This is the fraction of the incident electric field transmitted through the interface between two semi-infinite media. The incident field is assumed to be polarized parallel (p) to the plane of incidence (transverse magnetic or TM field).

The index of refraction for medium of the incoming field defaults to 1, but can be set any real value. The medium of the outgoing field is characterized by an index of refraction that may be complex.

Parameters:
  • m – complex index of refraction of medium [-]

  • theta_i – incidence angle from normal [radians/degrees]

  • n_i – real refractive index of incident medium [-]

  • deg – theta_i is in degrees [True/False]

Returns:

transmitted fraction of parallel field [-]

pypolar.fresnel.t_per_amplitude(m, theta_i, n_i=1, deg=False)[source]

Return the transmitted fraction of perpendicular-polarized field through an interface.

This is the fraction of the incident electric field transmitted through the interface between two semi-infinite media. The incident field is assumed to be polarized perpendicular (s, or senkrecht) to the plane of incidence (transverse electric or TE field).

The index of refraction for medium of the incoming field defaults to 1, but can be set any real value. The medium of the outgoing field is characterized by an index of refraction that may be complex.

Parameters:
  • m – complex index of refraction of medium [-]

  • theta_i – incidence angle from normal [radians/degrees]

  • n_i – real refractive index of incident medium [-]

  • deg – theta_i is in degrees [True/False]

Returns:

transmitted fraction of perpendicular field [-]

pypolar.sym_fresnel

Useful routines for symbolic Fresnel calculations at planar interfaces.

The functions in this module return symbolic SymPy expressions for Fresnel field and power coefficients at a planar interface. Light is incident from a medium with real refractive index n_i (default 1), onto a medium with complex refractive index m.

Angles are measured from the surface normal. Set deg=True when passing angles in degrees.

Incidence-angle helpers:

* brewster(index_of_refraction, n_i=1, deg=False)
* critical(index_of_refraction, n_i=1, deg=False)

Field-amplitude Fresnel coefficients:

* r_par_amplitude(index_of_refraction, angle, n_i=1, deg=False)
* r_per_amplitude(index_of_refraction, angle, n_i=1, deg=False)
* t_par_amplitude(index_of_refraction, angle, n_i=1, deg=False)
* t_per_amplitude(index_of_refraction, angle, n_i=1, deg=False)

Power (irradiance) Fresnel coefficients:

* R_par(index_of_refraction, angle, n_i=1, deg=False)
* R_per(index_of_refraction, angle, n_i=1, deg=False)
* T_par(index_of_refraction, angle, n_i=1, deg=False)
* T_per(index_of_refraction, angle, n_i=1, deg=False)
* R_unpolarized(index_of_refraction, angle, n_i=1, deg=False)
* T_unpolarized(index_of_refraction, angle, n_i=1, deg=False)

Ellipsometry helpers:

* ellipsometry_rho(index_of_refraction, angle, n_i=1, deg=False)
* ellipsometry_index(rho, angle, n_i=1, deg=False)
pypolar.sym_fresnel.R_par(m, theta_i, n_i=1, deg=False)[source]

Fraction of parallel-polarized light that is reflected (R_p).

Calculate reflected fraction of incident power (or flux) assuming that the E-field of the incident light is parallel to the plane of incidence

Parameters:
  • m – complex index of refraction of medium [-]

  • theta_i – incidence angle from normal [radians/degrees]

  • n_i – real refractive index of incident medium [-]

  • deg – theta_i is in degrees [True/False]

Returns:

reflected power [-]

pypolar.sym_fresnel.R_per(m, theta_i, n_i=1, deg=False)[source]

Fraction of perpendicular-polarized light that is reflected (R_s).

Calculate reflected fraction of incident power (or flux) assuming that the E-field of the incident light is perpendicular to the plane of incidence

Parameters:
  • m – complex index of refraction of medium [-]

  • theta_i – incidence angle from normal [radians/degrees]

  • n_i – real refractive index of incident medium [-]

  • deg – theta_i is in degrees [True/False]

Returns:

reflected irradiance [-]

pypolar.sym_fresnel.R_unpolarized(m, theta_i, n_i=1, deg=False)[source]

Fraction of unpolarized light that is reflected.

Calculate reflection fraction of incident power (or flux) assuming that the incident light is unpolarized

Parameters:
  • m – complex index of refraction of medium [-]

  • theta_i – incidence angle from normal [radians/degrees]

  • n_i – real refractive index of incident medium [-]

  • deg – theta_i is in degrees [True/False]

Returns:

reflected irradiance [-]

pypolar.sym_fresnel.T_par(m, theta_i, n_i=1, deg=False)[source]

Fraction of parallel-polarized light that is transmitted (T_p).

Calculate transmitted fraction of incident power (or flux) assuming that the E-field of the incident light is parallel to the plane of incidence

Parameters:
  • m – complex index of refraction of medium [-]

  • theta_i – incidence angle from normal [radians/degrees]

  • n_i – real refractive index of incident medium [-]

  • deg – theta_i is in degrees [True/False]

Returns:

transmitted irradiance [-]

pypolar.sym_fresnel.T_per(m, theta_i, n_i=1, deg=False)[source]

Fraction of perpendicular-polarized light that is transmitted (T_s).

Calculate transmitted fraction of incident power (or flux) assuming that the E-field of the incident light is perpendicular to the plane of incidence

Parameters:
  • m – complex index of refraction of medium [-]

  • theta_i – incidence angle from normal [radians/degrees]

  • n_i – real refractive index of incident medium [-]

  • deg – theta_i is in degrees [True/False]

Returns:

transmitted field amplitude [-]

pypolar.sym_fresnel.T_unpolarized(m, theta_i, n_i=1, deg=False)[source]

Fraction of unpolarized light that is transmitted.

Calculate transmitted fraction of incident power (or flux) assuming that the incident light is unpolarized

Parameters:
  • m – complex index of refraction of medium [-]

  • theta_i – incidence angle from normal [radians/degrees]

  • n_i – real refractive index of incident medium [-]

  • deg – theta_i is in degrees [True/False]

Returns:

reflected irradiance [-]

pypolar.sym_fresnel.brewster(m, n_i=1, deg=False)[source]

Brewster’s angle for an interface.

Parameters:
  • m – complex index of refraction of medium [-]

  • n_i – real refractive index of incident medium [-]

  • deg – theta_i is in degrees [True/False]

Returns:

Brewster’s angle from normal to surface [radians/degrees]

pypolar.sym_fresnel.critical(m, n_i=1, deg=False)[source]

Critical angle for total internal reflection at interface.

Parameters:
  • m – complex index of refraction of medium [-]

  • n_i – real refractive index of incident medium [-]

  • deg – theta_i is in degrees [True/False]

Returns:

critical angle from normal to surface [radians/degrees]

pypolar.sym_fresnel.ellipsometry_index(rho, theta_i, n_i=1, deg=False)[source]

Calculate the index of refraction for an isotropic sample.

Parameters:
  • rho – r_par_amplitude/r_per_amplitude [-]

  • theta_i – incidence angle from normal [radians/degrees]

  • n_i – real refractive index of incident medium [-]

  • deg – theta_i is in degrees [True/False]

Returns:

complex index of refraction [-]

pypolar.sym_fresnel.ellipsometry_rho(m, theta_i, n_i=1, deg=False)[source]

Calculate the ellipsometer parameter rho.

Parameters:
  • m – complex index of refraction of medium [-]

  • theta_i – incidence angle from normal [radians/degrees]

  • n_i – real refractive index of incident medium [-]

  • deg – theta_i is in degrees [True/False]

Returns:

ellipsometer parameter rho [-]

pypolar.sym_fresnel.r_par_amplitude(m, theta_i, n_i=1, deg=False)[source]

Calculate the reflected amplitude for parallel polarized light.

Parameters:
  • m – complex index of refraction of medium [-]

  • theta_i – angle from normal to surface [radians/degrees]

  • n_i – real refractive index of incident medium [-]

  • deg – theta_i is in degrees [True/False]

Returns:

reflected fraction of parallel field [-]

pypolar.sym_fresnel.r_per_amplitude(m, theta_i, n_i=1, deg=False)[source]

Calculate the reflected amplitude for perpendicular polarized light.

Parameters:
  • m – complex index of refraction of medium [-]

  • theta_i – incidence angle from normal [radians/degrees]

  • n_i – real refractive index of incident medium [-]

  • deg – theta_i is in degrees [True/False]

Returns:

reflected fraction of perpendicular field [-]

pypolar.sym_fresnel.t_par_amplitude(m, theta_i, n_i=1, deg=False)[source]

Calculate the transmitted amplitude for parallel polarized light.

Parameters:
  • m – complex index of refraction of medium [-]

  • theta_i – incidence angle from normal [radians/degrees]

  • n_i – real refractive index of incident medium [-]

  • deg – theta_i is in degrees [True/False]

Returns:

transmitted fraction of parallel field [-]

pypolar.sym_fresnel.t_per_amplitude(m, theta_i, n_i=1, deg=False)[source]

Calculate the transmitted amplitude for perpendicular polarized light.

Parameters:
  • m – complex index of refraction of medium [-]

  • theta_i – incidence angle from normal [radians/degrees]

  • n_i – real refractive index of incident medium [-]

  • deg – theta_i is in degrees [True/False]

Returns:

transmitted fraction of perpendicular field [-]

pypolar.jones

Useful routines for managing polarization with the Jones calculus.

The routines are broken into four broad categories: creating Jones vectors, creating Jones Matrices, interpreting Jones Vectors, and converting to the Mueller / Stokes matrix calculus.

Creating Jones vectors for specific polarization states:

* field_linear(angle)
* field_left_circular()
* field_right_circular()
* field_horizontal()
* field_vertical()
* field_ellipsometry(tanpsi, Delta)
* field_elliptical(azimuth, elliptic_angle)
* field_components(Ex, Ey) [raw-component constructor]

Creating Jones Matrices for polarizing elements:

* op_linear_polarizer(angle)
* op_retarder(fast_axis_angle, retardance)
* op_attenuator(transmittance)
* op_mirror()
* op_rotation(angle)
* op_quarter_wave_plate(fast_axis_angle)
* op_half_wave_plate(fast_axis_angle)
* op_fresnel_reflection(index_of_refraction, angle)
* op_fresnel_transmission(index_of_refraction, angle)

Interpreting the polarization state:

* use_alternate_convention(boolean)
* interpret(jones_vector)
* intensity(jones_vector)
* phase(jones_vector)
* ellipse_orientation(jones_vector) [alias]
* ellipse_azimuth(jones_vector)
* ellipse_axes(jones_vector)
* ellipticity(jones_vector)
* ellipticity_angle(jones_vector)
* amplitude_ratio(jones_vector)
* amplitude_ratio_angle(jones_vector)
* normalize(jones_vector, preserve_global_phase=True)
* polarization_variable(jones_vector)

Converting to Mueller formalism:

* jones_op_to_mueller_op(jones_matrix)
* jones_to_stokes(jones_vector)
pypolar.jones.amplitude_ratio(J)[source]

Return the ratio of electric fields.

This is the amplitude of the vibrations along x measured relative to the amplitude along y.

pypolar.jones.amplitude_ratio_angle(J)[source]

Return the ratio of electric fields.

The tangent of this angle is the ratio of electric fields in the y and x directions.

pypolar.jones.ellipse_axes(J)[source]

Return the semi - major and semi - minor radii of the ellipse.

Twice these values will be the semi - major or semi - minor diameters.

pypolar.jones.ellipse_azimuth(J)[source]

Return the angle between the major semi - axis and the x - axis.

The polarization ellipse is rotated by this angle (called the azimuth) relative to the laboratory frame.

pypolar.jones.ellipse_orientation(J)[source]

Return the orientation angle of the polarization ellipse.

This is a naming-parity alias for ellipse_azimuth().

pypolar.jones.ellipticity(J)[source]

Return the ellipticity of the polarization ellipse.

This is the ratio of semi - minor to semi - major radii. The ellipticity is a measure of the fatness of the ellipse. The ellipticity can be defined to always be positive. However negative values can be used to indicate left - handed polarization. Thus the ellipticity will range from -1 to 0 to 1 as light moves from LCP to Linear Polarization to RCP.

pypolar.jones.ellipticity_angle(J)[source]

Return the ellipticity angle of the polarization ellipse.

The tangent of this angle is the ratio of semi - minor:semi - major radii. It is between -pi / 4 ≤ angle ≤ pi / 4. Positive values are for right–handed ellipticity. Negative values for left - handed ellipticity.

pypolar.jones.field_components(Ex, Ey)[source]

Build a Jones vector directly from x/y complex field components.

Parameters:
  • Ex – Complex electric-field component along x.

  • Ey – Complex electric-field component along y.

Returns:

Jones vector [Ex, Ey], conjugated when the alternate sign convention is active.

pypolar.jones.field_ellipsometry(tanpsi, Delta)[source]

Jones vector for using ellipometer parameters.

This creates a Jones vector for the specific set of ellipsometry parameters tanpsi and Delta. See Fujiwara table 3.1 for example

Parameters:
  • tanpsi – abs(E_x / E_y) [-]

  • Delta – angle(E_x) - angle(E_y) [radians]

Returns:

Jones vector with specified characteristics

pypolar.jones.field_elliptical(azimuth, elliptic_angle, phi_x=0, E_0=1)[source]

Jones vector for elliptically polarized light.

Uses Azzam’s equation 1.75

Parameters:
  • azimuth – tilt angle of ellipse from x - axis [radians]

  • elliptic_angle – arctan(minor - axis / major - axis) [radians]

  • phi_x – phase for E field in x - direction [radians]

  • E_0 – amplitude of field

Returns:

Jones vector with specified characteristics

pypolar.jones.field_horizontal()[source]

Jones Vector for horizontal polarized light.

pypolar.jones.field_left_circular()[source]

Jones Vector for left circular polarized light.

pypolar.jones.field_linear(theta)[source]

Jones vector for linear polarized light at angle theta from horizontal plane.

pypolar.jones.field_right_circular()[source]

Jones Vector for right circular polarized light.

pypolar.jones.field_vertical()[source]

Jones Vector for vertical polarized light.

pypolar.jones.intensity(J)[source]

Return the intensity.

pypolar.jones.interpret(J)[source]

Interpret a Jones vector.

Parameters:

J – Jones vector with two complex entries.

Examples

interpret([1, -1j]) -> “Right circular polarization”

interpret([0.5, 0.5]) -> “Linear polarization at 45.000000 degrees CCW from x-axis”

interpret(np.array([exp(-1j * pi), exp(-1j * pi / 3)])) -> “Left elliptical polarization, rotated with respect to the axes”

Returns:

Human-readable interpretation string. Malformed or unphysical inputs are reported with diagnostic strings.

pypolar.jones.jones_op_to_mueller_op(JJ)[source]

Convert a complex 2x2 Jones matrix to a real 4x4 Mueller matrix.

Hauge, Muller, and Smith, “Conventions and Formulas for Using the Mueller- Stokes Calculus in Ellipsometry,” Surface Science, 96, 81 - 107 (1980)

Parameters:

JJ – Jones matrix

Returns:

equivalent 4x4 Mueller matrix

pypolar.jones.jones_to_stokes(J)[source]

Convert Jones vector to Stokes vector.

Parameters:

J – Jones vector

Returns:

Stokes vector

pypolar.jones.normalize(J, preserve_global_phase=True)[source]

Normalize a Jones vector by dividing by its Euclidean norm.

Parameters:
  • J – Jones vector.

  • preserve_global_phase – If True (default), preserve the global phase. If False, remove global phase by making the first non-zero component real and non-negative.

Returns:

Normalized Jones vector. A zero vector is returned unchanged.

pypolar.jones.op_attenuator(t)[source]

Jones matrix operator for an isotropic optical attenuator.

The transmittance t=I / I_0 is the fraction of light getting through the attenuator or absorber.

Parameters:

t – fraction of intensity getting through attenuator [—]

pypolar.jones.op_fresnel_reflection(m, theta, n_i=1)[source]

Jones matrix operator for Fresnel reflection at angle theta.

Parameters:
  • m – complex index of refraction [-]

  • theta – angle from normal to surface [radians]

  • n_i – real refractive index of incident medium [-]

Returns:

2x2 matrix of the Fresnel reflection operator [-]

pypolar.jones.op_fresnel_transmission(m, theta, n_i=1)[source]

Jones matrix operator for Fresnel transmission at angle theta.

This operator acts on field amplitudes in the p/s basis and returns the transmitted field amplitudes. It does not include irradiance normalization factors.

Parameters:
  • m – complex index of refraction [-]

  • theta – angle from normal to surface [radians]

  • n_i – real refractive index of incident medium [-]

Returns:

2x2 Fresnel transmission operator [-]

pypolar.jones.op_half_wave_plate(theta)[source]

Jones matrix operator for a rotated half - wave plate.

The half wave plate has been rotated around a normal to the surface of the plate.

Parameters:

theta – angle from fast - axis to horizontal plane [radians]

Returns:

2x2 matrix of the half - wave plate operator [-]

pypolar.jones.op_linear_polarizer(theta)[source]

Jones matrix operator for a rotated linear polarizer.

The polarizer has been rotated around a normal to its surface.

Parameters:

theta – rotation angle measured from the horizontal plane [radians]

pypolar.jones.op_mirror()[source]

Jones matrix operator for a perfect mirror.

pypolar.jones.op_quarter_wave_plate(theta)[source]

Jones matrix operator for an rotated quarter - wave plate.

The QWP had been rotated around a normal to its surface.

Parameters:

theta – angle from fast - axis to horizontal plane [radians]

Returns:

2x2 matrix of the quarter - wave plate operator [-]

pypolar.jones.op_retarder(theta, delta)[source]

Jones matrix operator for an rotated optical retarder.

The retarder has been rotated around a normal to its surface.

Parameters:
  • theta – rotation angle between fast - axis and the horizontal plane [radians]

  • delta – phase delay introduced between fast and slow - axes [radians]

pypolar.jones.op_rotation(theta)[source]

Jones matrix operator to rotate light around the optical axis.

Parameters:

theta – angle of rotation around optical axis [radians]

Returns:

2x2 matrix of the rotation operator [-]

pypolar.jones.phase(J)[source]

Return the phase.

pypolar.jones.polarization_variable(J)[source]

Return the complex polarization variable, chi.

This reduces the Jones vector to a single complex number and is useful when the amplitude and absolute - phase are of secondary interest. These are eliminated and chi is representative of the polarization state in the complex plane.

pypolar.jones.use_alternate_convention(state)[source]

Change sign convention used for Jones calculus.

Read the documentation about the different conventions possible.

The default convention is to assume the wave function is represented by exp(j*(omega * t - k * z)) and that the perspective when viewing a sectional pattern is to look back along the optical axis towards the source. This is the most commonly used convention, but there are noteable exceptions (Wikipedia, Fowler, and Hecht (sometimes).

Call this function once at the beginning and everything should be just fine.

pypolar.sym_jones

Useful routines for symbolic manipulation of Jones vectors and matrices.

Creating Jones vectors for specific polarization states:

* field_linear(angle)
* field_left_circular()
* field_right_circular()
* field_horizontal()
* field_vertical()
* field_ellipsometry(tanpsi, Delta)
* field_elliptical(azimuth, elliptic_angle)
* field_components(A, B) [raw-component constructor]

Creating Jones Matrices for polarizing elements:

* op_linear_polarizer(angle)
* op_retarder(fast_axis_angle, retardance)
* op_attenuator(transmittance)
* op_mirror()
* op_rotation(angle)
* op_quarter_wave_plate(fast_axis_angle)
* op_half_wave_plate(fast_axis_angle)
* op_fresnel_reflection(index_of_refraction, angle)
* op_fresnel_transmission(index_of_refraction, angle)

Interpreting the polarization state:

* use_alternate_convention(boolean)
* interpret(jones_vector)
* intensity(jones_vector)
* phase(jones_vector)
* ellipse_orientation(jones_vector)
* ellipse_azimuth(jones_vector) [alias]
* ellipse_axes(jones_vector)
* ellipticity_angle(jones_vector)
* ellipticity(jones_vector)
* amplitude_ratio(jones_vector)
* amplitude_ratio_angle(jones_vector)
* polarization_variable(jones_vector)

Converting to Mueller formalism:

* jones_op_to_mueller_op(jones_matrix)
* jones_to_stokes(jones_vector)
pypolar.sym_jones.amplitude_ratio(J)[source]

Return the ratio of electric field amplitudes.

This is the amplitude in the y-direction measured relative to x.

pypolar.sym_jones.amplitude_ratio_angle(J)[source]

Return the angle whose tangent equals the amplitude ratio Ey/Ex.

pypolar.sym_jones.ellipse_axes(J)[source]

Return the semi-major and semi-minor axes of the polarization ellipse.

pypolar.sym_jones.ellipse_azimuth(J)[source]

Backward-compatible alias for ellipse_orientation().

pypolar.sym_jones.ellipse_orientation(J)[source]

Return the angle between the major semi-axis and the x-axis.

This angle is sometimes called the azimuth or psi.

pypolar.sym_jones.ellipticity(J)[source]

Backward-compatible ellipticity ratio (minor/major), signed by handedness.

pypolar.sym_jones.ellipticity_angle(J)[source]

Return the ellipticity angle of the polarization ellipse.

pypolar.sym_jones.field_components(A, B)[source]

Build a Jones vector directly from x/y complex field components.

This preserves the previous symbolic field_elliptical(A, B) behavior.

pypolar.sym_jones.field_ellipsometry(tanpsi, Delta)[source]

Jones vector for using ellipsometer parameters.

Parameters:
  • tanpsi – abs(E_x / E_y) [-]

  • Delta – angle(E_x) - angle(E_y) [radians]

pypolar.sym_jones.field_elliptical(azimuth, elliptic_angle, phi_x=0, E_0=1)[source]

Jones vector for elliptically polarized light.

Uses the same parameterization as the numeric Jones implementation.

Parameters:
  • azimuth – Tilt angle of ellipse from x-axis [radians]

  • elliptic_angle – arctan(minor-axis / major-axis) [radians]

  • phi_x – Phase for E field in x-direction [radians]

  • E_0 – Total field amplitude

pypolar.sym_jones.field_horizontal()[source]

Jones Vector for horizontal polarized light.

pypolar.sym_jones.field_left_circular()[source]

Jones Vector for left circular polarized light.

pypolar.sym_jones.field_linear(theta)[source]

Jones vector for linear polarized light at angle theta from horizontal plane.

pypolar.sym_jones.field_right_circular()[source]

Jones Vector for right circular polarized light.

pypolar.sym_jones.field_vertical()[source]

Jones Vector for vertical polarized light.

pypolar.sym_jones.intensity(J)[source]

Return the intensity.

pypolar.sym_jones.interpret(J)[source]

Interpret a Jones vector.

Parameters:

J – Jones vector with two entries

pypolar.sym_jones.jones_op_to_mueller_op(J)[source]

Convert a symbolic 2x2 Jones matrix to a symbolic 4x4 Mueller matrix.

Parameters:

J – Jones matrix in the x/y basis

pypolar.sym_jones.jones_to_stokes(J)[source]

Convert a symbolic Jones vector to a symbolic Stokes vector.

Parameters:

J – Jones vector in the x/y basis

pypolar.sym_jones.op_attenuator(t)[source]

Jones matrix operator for an optical attenuator.

Parameters:

t – fraction of intensity passing through attenuator [—]

pypolar.sym_jones.op_fresnel_reflection(m, theta, n_i=1)[source]

Jones matrix operator for Fresnel reflection at angle.

Parameters:
  • m – complex index of refraction [-]

  • theta – angle from normal to surface [radians]

  • n_i – real refractive index of incident medium [-]

Returns:

2x2 matrix of the Fresnel reflection operator [-]

pypolar.sym_jones.op_fresnel_transmission(m, theta, n_i=1)[source]

Jones matrix operator for Fresnel transmission at angle theta.

This operator acts on field amplitudes in the p/s basis and returns the transmitted field amplitudes. It does not include irradiance normalization factors.

Parameters:
  • m – complex index of refraction [-]

  • theta – angle from normal to surface [radians]

  • n_i – real refractive index of incident medium [-]

Returns:

2x2 Fresnel transmission operator [-]

pypolar.sym_jones.op_half_wave_plate(theta)[source]

Jones matrix operator for a rotated half-wave plate.

The HWP is rotated about a normal to its surface.

Parameters:

theta – angle from fast-axis to horizontal plane [radians]

Returns:

2x2 matrix of the half-wave plate operator [-]

pypolar.sym_jones.op_linear_polarizer(theta)[source]

Jones matrix operator for a rotated linear polarizer.

The polarizer is rotated around a normal to its surface.

Parameters:

theta – rotation angle measured from the horizontal plane [radians]

pypolar.sym_jones.op_mirror()[source]

Jones matrix operator for a perfect mirror.

pypolar.sym_jones.op_quarter_wave_plate(theta)[source]

Jones matrix operator for a rotated quarter-wave plate.

The QWP is rotated about a normal to its surface.

Parameters:

theta – angle from fast-axis to horizontal plane [radians]

Returns:

2x2 matrix of the quarter-wave plate operator [-]

pypolar.sym_jones.op_retarder(theta, delta)[source]

Jones matrix operator for a rotated optical retarder.

The retarder is rotated around a normal to its surface.

Parameters:
  • theta – rotation angle between fast-axis and the horizontal plane [radians]

  • delta – phase delay introduced between fast and slow-axes [radians]

pypolar.sym_jones.op_rotation(theta)[source]

Jones matrix operator to rotate light around the optical axis.

Parameters:

theta – angle of rotation about optical axis [radians]

Returns:

2x2 matrix of the rotation operator [-]

pypolar.sym_jones.phase(J)[source]

Return the phase.

pypolar.sym_jones.polarization_variable(J)[source]

Return the complex polarization variable chi = E_y / E_x.

pypolar.sym_jones.use_alternate_convention(state)[source]

Set the sign convention used by symbolic Jones field constructors.

pypolar.mueller

Useful basic routines for managing polarization with the Stokes / Mueller calculus.

The routines are broken up into four groups: (1) creating Stokes vectors, (2) creating Mueller matrix operators, (3) interpretation, and (4) conversion.

Functions to create Stokes vectors:

* stokes_components(I, Q, U, V)
* stokes_linear(angle)
* stokes_left_circular()
* stokes_right_circular()
* stokes_horizontal()
* stokes_vertical()
* stokes_unpolarized()
* stokes_elliptical(DOP, azimuth, ellipticity)
* stokes_ellipsometry(tanpsi, Delta)

Functions to create Mueller matrix operators:

* op_linear_polarizer(angle)
* op_retarder(fast_axis_angle, phase_delay)
* op_attenuator(transmittance)
* op_mirror()
* op_rotation(angle)
* op_quarter_wave_plate(fast_axis_angle)
* op_half_wave_plate(fast_axis_angle)
* op_fresnel_reflection(index_of_refraction, incidence_angle)
* op_fresnel_transmission(index_of_refraction, incidence_angle)

Functions to interpret Stokes vectors:

* intensity(stokes_vector)
* degree_of_polarization(stokes_vector)
* ellipse_orientation(stokes_vector)
* ellipticity_angle(stokes_vector)
* ellipse_axes(stokes_vector)
* interpret(stokes_vector)

Functions to convert:

* stokes_to_jones(stokes_vector)
* mueller_to_jones(mueller_matrix)
pypolar.mueller.degree_of_polarization(S)[source]

Return the degree of polarization.

pypolar.mueller.ellipse_axes(S)[source]

Return the semi-major and semi-minor axes of the polarization ellipse.

pypolar.mueller.ellipse_orientation(S)[source]

Return the angle between the major semi-axis and the x-axis.

The polarization ellipse is rotated by an angle from the laboratory frame. This is that angle: often represented by psi.

pypolar.mueller.ellipticity_angle(S)[source]

Return the ellipticity of the polarization ellipse.

This parameter is often represented by Chi.

pypolar.mueller.intensity(S)[source]

Return the intensity.

pypolar.mueller.interpret(S)[source]

Interpret a Stokes vector.

If a 4x4 array is passed, run basic Mueller-matrix admissibility checks.

Parameters:

S – Stokes vector with shape (4,) or Mueller matrix with shape (4, 4).

Examples

interpret([1, 0, 0, 0]) -> “Unpolarized light”

Returns:

Human-readable interpretation string.

pypolar.mueller.mueller_to_jones(M)[source]

Convert a Mueller matrix to a Jones matrix.

Theocaris, Matrix Theory of Photoelasticity, eqns 4.70-4.76, 1979

Parameters:

M – 4x4 Mueller matrix.

Returns:

Corresponding 2x2 Jones matrix.

pypolar.mueller.op_attenuator(t)[source]

Mueller matrix operator for an optical attenuator.

Parameters:

t – fraction of light getting through attenuator [—]

pypolar.mueller.op_fresnel_reflection(m, theta, n_i=1)[source]

Mueller matrix operator for Fresnel reflection at angle theta.

Convert from the Jones operator to ensure that phase changes are handled correctly and that results remain consistent with the field-amplitude Fresnel model.

Parameters:
  • m – complex index of refraction [-]

  • theta – angle from normal to surface [radians]

  • n_i – real refractive index of incident medium [-]

Returns:

4x4 Fresnel reflection Mueller matrix [-]

pypolar.mueller.op_fresnel_transmission(m, theta, n_i=1)[source]

Mueller matrix operator for Fresnel transmission at angle theta.

Convert from the Jones operator so the Mueller operator remains consistent with field-amplitude Fresnel transmission (including phase effects).

Parameters:
  • m – complex index of refraction [-]

  • theta – angle from normal to surface [radians]

  • n_i – real refractive index of incident medium [-]

Returns:

4x4 Fresnel transmission operator [-]

pypolar.mueller.op_half_wave_plate(theta)[source]

Mueller matrix for a rotated half-wave plate.

Parameters:

theta – rotation angle between fast-axis and the horizontal plane [radians]

Returns:

a Mueller matrix operator for the rotated half-wave plate.

pypolar.mueller.op_linear_polarizer(theta)[source]

Mueller matrix operator for a rotated linear polarizer.

The polarizer is rotated around a normal to its surface.

Parameters:

theta – rotation angle measured from the horizontal plane [radians]

pypolar.mueller.op_mirror()[source]

Mueller matrix operator for a perfect mirror.

pypolar.mueller.op_quarter_wave_plate(theta)[source]

Mueller matrix operator for an quarter-wave plate.

Parameters:

theta – rotation angle between fast-axis and the horizontal plane [radians]

Returns:

a Mueller matrix operator for the rotated quarter-wave plate.

pypolar.mueller.op_retarder(theta, delta)[source]

Mueller matrix operator for an rotated optical retarder.

The retarder is rotated around a normal to its surface.

Parameters:
  • theta – rotation angle between fast-axis and the horizontal plane [radians]

  • delta – phase delay introduced between fast and slow-axes [radians]

pypolar.mueller.op_rotation(theta)[source]

Mueller matrix operator to rotate light around the optical axis.

Parameters:

theta – rotation angle [radians]

pypolar.mueller.stokes_components(I, Q, U, V)[source]

Stokes vector from explicit components.

Parameters:
  • I – Total intensity component.

  • Q – Horizontal/vertical linear polarization component.

  • U – ±45 degree linear polarization component.

  • V – Circular polarization component.

Returns:

Stokes vector with shape (4,) for scalar inputs, or stacked array with shape (…, 4) for broadcast-compatible array inputs.

pypolar.mueller.stokes_ellipsometry(tanpsi, Delta)[source]

Stokes vector using ellipsometer parameters.

This creates a Stokes vector for the specific set of ellipsometry parameters tanpsi and Delta. See Fujiwara table 3.1 for example.

Parameters:
  • tanpsi – abs(E_x / E_y) [-]

  • Delta – angle(E_x) - angle(E_y) [radians]

Returns:

normalized Stokes vector with specified properties

pypolar.mueller.stokes_elliptical(DOP, azimuth, ellipticity)[source]

Stokes vector for partially polarized elliptically polarized light.

Parameters:
  • DOP – degree of polarization [-]

  • azimuth – tilt of ellipse relative to horizontal [radians]

  • ellipticity – ratio of minor to major axes [-]

Returns:

normalized Stokes vector with specified properties

pypolar.mueller.stokes_horizontal()[source]

Stokes vector for horizontal polarized light.

pypolar.mueller.stokes_left_circular()[source]

Stokes vector for left circular polarized light.

pypolar.mueller.stokes_linear(theta)[source]

Stokes vector for light polarized at angle theta from the horizontal plane.

pypolar.mueller.stokes_right_circular()[source]

Stokes vector for right circular polarized light.

pypolar.mueller.stokes_to_jones(S)[source]

Convert a (list of) Stokes vector(s) to a (list of) Jones vector(s).

The sign convention for the Jones vector can be set by calling pypolar.jones.use_alternate_convention(True). The default is to assume that the field is represented by exp(j * omega * t-k * z).

Parameters:

S – Single Stokes vector with shape (4,) or array with shape (n, 4).

Returns:

Jones vector with shape (2,), array of Jones vectors with shape (n, 2), or None for invalid array shape.

pypolar.mueller.stokes_unpolarized()[source]

Stokes vector for vertical polarized light.

pypolar.mueller.stokes_vertical()[source]

Stokes vector for vertical polarized light.

pypolar.sym_mueller

Symbolic manipulation of polarization using the Stokes/Mueller calculus.

The routines are broken up into four groups: (1) creating Stokes vectors, (2) creating Mueller matrix operators, (3) interpretation, and (4) conversion.

Functions to create Stokes vectors:

* stokes_components(I, Q, U, V)
* stokes_linear(angle)
* stokes_left_circular()
* stokes_right_circular()
* stokes_horizontal()
* stokes_vertical()
* stokes_unpolarized()
* stokes_elliptical(DOP, azimuth, ellipticity)
* stokes_ellipsometry(tanpsi, Delta)

Functions to create Mueller matrix operators:

* op_linear_polarizer(angle)
* op_retarder(fast_axis_angle, phase_delay)
* op_attenuator(transmittance)
* op_mirror()
* op_rotation(angle)
* op_quarter_wave_plate(fast_axis_angle)
* op_half_wave_plate(fast_axis_angle)
* op_fresnel_reflection(index_of_refraction, incidence_angle)
* op_fresnel_transmission(index_of_refraction, incidence_angle)

Functions to interpret Stokes vectors:

* intensity(stokes_vector)
* degree_of_polarization(stokes_vector)
* ellipse_orientation(stokes_vector)
* ellipticity_angle(stokes_vector)
* ellipse_axes(stokes_vector)
* interpret(stokes_vector)

Functions to convert:

* stokes_to_jones(stokes_vector)
* mueller_to_jones(mueller_matrix)
pypolar.sym_mueller.degree_of_polarization(S)[source]

Return the degree of polarization.

pypolar.sym_mueller.ellipse_axes(S)[source]

Return the semi-major and semi-minor axes.

These are the axes of the polarization ellipse.

pypolar.sym_mueller.ellipse_orientation(S)[source]

Return orientation of the polarization ellipse.

The orientation is the angle between the major semi-axis and the x-axis of the polarization ellipse (often represented by psi).

pypolar.sym_mueller.ellipticity_angle(S)[source]

Return ellipticity of the polarization ellipse.

The ellipticity of the polarization ellipse (often represented by chi)

pypolar.sym_mueller.intensity(S)[source]

Return the intensity.

pypolar.sym_mueller.interpret(S)[source]

Interpret a symbolic Stokes vector.

If a 4x4 matrix is passed, report symbolic Mueller-matrix admissibility checks.

Parameters:

S – Stokes vector with shape (4, 1) or (1, 4), or Mueller matrix with shape (4, 4).

Returns:

Human-readable interpretation string.

pypolar.sym_mueller.mueller_to_jones(M)[source]

Convert a Mueller matrix to a Jones matrix.

Theocaris, Matrix Theory of Photoelasticity, eqns 4.70-4.76, 1979

Parameters:

M – a 4x4 Mueller matrix

Returns:

the corresponding 2x2 Jones matrix

pypolar.sym_mueller.op_attenuator(t)[source]

Mueller matrix operator for an optical attenuator.

Parameters:

t – fraction of light getting through attenuator [—]

pypolar.sym_mueller.op_fresnel_reflection(m, theta, n_i=1)[source]

Mueller matrix operator for Fresnel reflection.

Build the Mueller operator from complex field-amplitude reflection coefficients. This preserves phase-delay effects while ensuring real Mueller matrix entries.

Parameters:
  • m – complex index of refraction [-]

  • theta – angle from normal to surface [radians]

  • n_i – real refractive index of incident medium [-]

Returns:

4x4 Fresnel reflection operator [-]

pypolar.sym_mueller.op_fresnel_transmission(m, theta, n_i=1)[source]

Mueller matrix operator for Fresnel transmission.

Build the Mueller operator from the complex field-amplitude transmission coefficients. This preserves phase-delay effects while ensuring the Mueller matrix entries are real-valued.

Parameters:
  • m – complex index of refraction [-]

  • theta – angle from normal to surface [radians]

  • n_i – real refractive index of incident medium [-]

Returns:

4x4 Fresnel transmission operator [-]

pypolar.sym_mueller.op_half_wave_plate(theta)[source]

Mueller matrix operator for rotated half-wave plate.

The HWP is rotated about a normal to its surface.

Parameters:

theta – rotation angle between fast-axis and the horizontal plane [radians]

pypolar.sym_mueller.op_linear_polarizer(theta)[source]

Mueller matrix operator for a rotated linear polarizer.

The polarizer is rotated about a normal to its surface.

Parameters:

theta – rotation angle measured from the horizontal plane [radians]

pypolar.sym_mueller.op_mirror()[source]

Mueller matrix operator for a perfect mirror.

pypolar.sym_mueller.op_quarter_wave_plate(theta)[source]

Mueller matrix operator for a rotated quarter-wave plate.

The QWP is rotated about a normal to its surface.

Parameters:

theta – rotation angle between fast-axis and the horizontal plane [radians]

pypolar.sym_mueller.op_retarder(theta, delta)[source]

Mueller matrix operator for a rotated optical retarder.

The retarder is rotated about a normal to its surface.

Parameters:
  • theta – rotation angle between fast-axis and the horizontal plane [radians]

  • delta – phase delay introduced between fast and slow-axes [radians]

pypolar.sym_mueller.op_rotation(theta)[source]

Mueller matrix operator to rotate light about the optical axis.

Parameters:

theta – rotation angle [radians]

pypolar.sym_mueller.stokes_components(I, Q, U, V)[source]

Stokes vector from explicit components.

Parameters:
  • I – Total intensity component.

  • Q – Horizontal/vertical linear polarization component.

  • U – +/-45 degree linear polarization component.

  • V – Circular polarization component.

Returns:

Symbolic Stokes column vector.

pypolar.sym_mueller.stokes_ellipsometry(tanpsi, Delta)[source]

Stokes vector from ellipsometer parameters.

Parameters:
  • tanpsi – abs(E_x / E_y) [-]

  • Delta – angle(E_x) - angle(E_y) [radians]

pypolar.sym_mueller.stokes_elliptical(DOP, azimuth, ellipticity)[source]

Stokes vector from polarization ellipse parameters.

Parameters:
  • DOP – degree of polarization [-]

  • azimuth – orientation of ellipse major-axis [radians]

  • ellipticity – arctan(minor/major) [radians]

pypolar.sym_mueller.stokes_horizontal()[source]

Stokes vector for horizontal polarized light.

pypolar.sym_mueller.stokes_left_circular()[source]

Stokes vector for left circular polarized light.

pypolar.sym_mueller.stokes_linear(theta)[source]

Stokes vector for linear polarized light at angle.

Parameters:
  • m – complex index of refraction [-]

  • theta – angle from horizontal plane [radians]

pypolar.sym_mueller.stokes_right_circular()[source]

Stokes vector for right circular polarized light.

pypolar.sym_mueller.stokes_to_jones(S)[source]

Convert a Stokes vector to a Jones vector.

This conversion loses some of the information in the Stokes vector because the unpolarized fraction is lost. Furthermore, since the Jones vector can differ by an arbitrary phase, the phase is chosen to make the horizontal component real.

Parameters:

S – a Stokes vector

Returns:

a corresponding Jones vector

pypolar.sym_mueller.stokes_unpolarized()[source]

Stokes vector for unpolarized light.

pypolar.sym_mueller.stokes_vertical()[source]

Stokes vector for vertical polarized light.

pypolar.visualization

A set of basic routines for visualizing polarization.

Functions for drawing the polarization ellipse (sectional pattern):

* draw_jones_ellipse(J, simple=False, **kwargs)
* draw_stokes_ellipse(S, **kwargs)

Functions for drawing 2D and 3D representations:

* draw_jones_field(J, offset=0, **kwargs)
* draw_stokes_field(S, offset=0, **kwargs)

Functions for drawing animated 2D and 3D representations:

* draw_jones_animated(J, nframes=64, **kwargs)
* draw_stokes_animated(S, **kwargs)
Functions for drawing Poincaré representations::
  • draw_empty_sphere(ax=None, **kwargs)

  • draw_jones_poincare(J, ax=None, label=None, normalize=”s0”, text_kwargs=None, **kwargs)

  • draw_stokes_poincare(S, ax=None, label=None, normalize=”s0”, text_kwargs=None, **kwargs)

  • join_jones_poincare(J1, J2, ax=None, normalize=”s0”, **kwargs)

  • join_stokes_poincare(S1, S2, ax=None, normalize=”s0”, **kwargs)

Poincaré coordinates use reduced Stokes values (S1/S0, S2/S0, S3/S0), so partially polarized states lie inside the unit sphere.

Jones-vector plots follow the package-wide sign convention set by pypolar.jones.use_alternate_convention(…).

Set normalize=”unit” to project states onto the unit sphere using (S1,S2,S3) / sqrt(S1^2+S2^2+S3^2).

Example: Poincaré sphere plot of a Jones vector:

J = pypolar.jones.field_linear(np.pi / 6)
pypolar.visualization.draw_jones_poincare(J)

Example: Poincaré sphere plot of two Stokes vectors:

S1 = pypolar.mueller.stokes_left_circular()
S2 = pypolar.mueller.stokes_linear(np.radians(15))

fig = plt.figure(figsize=(8, 8))
ax = fig.add_subplot(111, projection='3d')
pypolar.visualization.draw_empty_sphere(ax)
pypolar.visualization.draw_stokes_poincare(S1, ax, label='  S1')
pypolar.visualization.draw_stokes_poincare(S2, ax, label='  S2')
pypolar.visualization.join_stokes_poincare(S1, S2, ax, lw=2, ls=':', color='orange')
pypolar.visualization.draw_empty_sphere(ax=None, **kwargs)[source]

Plot an empty Poincaré sphere.

Parameters:
  • ax – pyplot axis

  • **kwargs – style arguments passed to guide line artists.

Returns:

tuple(fig, ax, artists) with surface, line, and text handles.

pypolar.visualization.draw_jones_animated(J, nframes=64, **kwargs)[source]

Animate 3D and 2D representations of the polarization field.

Parameters:
  • J – Jones vector

  • nframes – number of frames to create

  • **kwargs – style arguments passed to line artists in each frame.

Returns:

matplotlib.animation.FuncAnimation – animation handle. The associated figure and axes are available via ani._fig and ani._args[1:].

Example

Display an animation in Jupyter notebooks:

import matplotlib.pyplot as plt
import pypolar.jones as jones
import pypolar.visualization as vis

plt.rcParams["animation.html"] = "jshtml"
J = jones.field_linear(0)
ani = vis.draw_jones_animated(J, nframes=32)
ani

In scripts, save the animation to a file:

ani = vis.draw_jones_animated(J, nframes=32)
ani.save("jones_field.mp4")
pypolar.visualization.draw_jones_ellipse(J, simple=False, **kwargs)[source]

Draw a 2D sectional pattern for a Jones vector.

Parameters:
  • J – Jones vector

  • simple – if True then just draw a simple ellipse plot

  • **kwargs – style arguments passed to line artists.

Returns:

tuple(fig, ax_or_axes, artists) where ax_or_axes is one axis for simple=True and (ax1, ax2) for simple=False.

pypolar.visualization.draw_jones_field(J, offset=0, **kwargs)[source]

Draw 3D and 2D representations of a Jones vector.

Parameters:
  • J – Jones vector

  • offset – phase offset in radians for the plotted snapshot. offset=0 uses the default phase origin; changing it rotates the highlighted instantaneous field point around the ellipse.

  • **kwargs – style arguments passed to line artists.

Returns:

tuple(fig, (ax3d, ax2d), artists) where artists includes line and text handles for each axis.

Example

Plot a static field representation:

import matplotlib.pyplot as plt
import pypolar.jones as jones
import pypolar.visualization as vis

J = jones.field_left_circular()
vis.draw_jones_field(J)
plt.show()
pypolar.visualization.draw_jones_poincare(J, ax=None, label=None, normalize='s0', text_kwargs=None, **kwargs)[source]

Plot one Jones state on or inside the Poincaré sphere.

Parameters:
  • J – Jones vector with shape (2,)

  • ax – optional matplotlib 3D axis

  • label – optional text label

  • normalize – either “s0” or “unit”

  • text_kwargs – optional style args for label text

  • **kwargs – style arguments passed to draw_stokes_poincare

Returns:

tuple(fig, ax, artists) as returned by draw_stokes_poincare().

pypolar.visualization.draw_stokes_animated(S, **kwargs)[source]

Draw animated 3D and 2D field representations from a Stokes vector.

Parameters:
  • S – Stokes vector

  • **kwargs – style arguments passed to draw_jones_animated.

Returns:

matplotlib.animation.FuncAnimation – animation handle as returned by draw_jones_animated().

Example

Display an animation in Jupyter notebooks:

import matplotlib.pyplot as plt
import pypolar.mueller as mueller
import pypolar.visualization as vis

plt.rcParams["animation.html"] = "jshtml"
S = mueller.stokes_right_circular()
ani = vis.draw_stokes_animated(S, nframes=32)
ani
pypolar.visualization.draw_stokes_ellipse(S, **kwargs)[source]

Draw polarization ellipse panels from a Stokes vector.

Parameters:
  • S – Stokes vector

  • **kwargs – style arguments passed to draw_jones_ellipse.

Returns:

tuple(fig, ax_or_axes, artists) as returned by draw_jones_ellipse().

pypolar.visualization.draw_stokes_field(S, offset=0, **kwargs)[source]

Draw 3D and 2D field representations of a Stokes vector.

Parameters:
  • S – Stokes vector

  • offset – phase offset in radians for the plotted snapshot after converting S to a Jones vector. Meaning matches draw_jones_field().

  • **kwargs – style arguments passed to draw_jones_field.

Returns:

tuple(fig, (ax3d, ax2d), artists) as returned by draw_jones_field().

Example

Plot a static field representation from a Stokes vector:

import matplotlib.pyplot as plt
import pypolar.mueller as mueller
import pypolar.visualization as vis

S = mueller.stokes_linear(0)
vis.draw_stokes_field(S)
plt.show()

For animated output in notebooks, use draw_stokes_animated().

pypolar.visualization.draw_stokes_poincare(S, ax=None, label=None, normalize='s0', text_kwargs=None, **kwargs)[source]

Plot one Stokes state on or inside the Poincaré sphere.

Coordinates are controlled by normalize: * normalize=”s0” uses reduced Stokes values (S1/S0, S2/S0, S3/S0). * normalize=”unit” uses pure-state projection

(S1,S2,S3) / sqrt(S1^2+S2^2+S3^2).

Any keyword arguments for point styling should use standard Matplotlib names (for example linewidth, lw, color, linestyle, markersize). Label styling should use text_kwargs; legacy text keys like ha, va, and fontsize in **kwargs are still accepted when label is provided.

Parameters:
  • S – Stokes vector with shape (4,)

  • ax – optional matplotlib 3D axis

  • label – optional text label

  • normalize – either “s0” or “unit”

  • text_kwargs – optional style args for label text

  • **kwargs – style arguments passed directly to matplotlib.axes.Axes.plot

Returns:

tuple(fig, ax, artists) with point and optional label handles.

pypolar.visualization.join_jones_poincare(J1, J2, ax=None, normalize='s0', **kwargs)[source]

Plot a connection between two Jones vectors on or inside the Poincaré sphere.

Parameters:
  • J1 – first Jones vector with shape (2,)

  • J2 – second Jones vector with shape (2,)

  • ax – optional matplotlib 3D axis

  • normalize – either “s0” or “unit”

  • **kwargs – style arguments passed to join_stokes_poincare

Returns:

tuple(fig, ax, line) as returned by join_stokes_poincare().

pypolar.visualization.join_stokes_poincare(S1, S2, ax=None, normalize='s0', **kwargs)[source]

Plot a connection between two Stokes vectors on or inside the Poincaré sphere.

The direction follows a great-circle path for non-zero-radius endpoints and uses linear interpolation when an endpoint is at the origin.

Parameters:
  • S1 – first Stokes vector with shape (4,)

  • S2 – second Stokes vector with shape (4,)

  • ax – optional matplotlib 3D axis

  • normalize – either “s0” or “unit”

  • **kwargs – style arguments passed to matplotlib.axes.Axes.plot

Returns:

tuple(fig, ax, line) where line is the connecting arc/segment.

pypolar.poincare

Poincaré sphere visualization routines.

Functions for drawing Poincaré representations::
  • draw_empty_sphere(ax=None, **kwargs)

  • draw_jones_poincare(J, ax=None, label=None, normalize=”s0”, text_kwargs=None, **kwargs)

  • draw_stokes_poincare(S, ax=None, label=None, normalize=”s0”, text_kwargs=None, **kwargs)

  • join_jones_poincare(J1, J2, ax=None, normalize=”s0”, **kwargs)

  • join_stokes_poincare(S1, S2, ax=None, normalize=”s0”, **kwargs)

Poincaré coordinates use reduced Stokes values (S1/S0, S2/S0, S3/S0), so partially polarized states lie inside the unit sphere.

Set normalize=”unit” to project states onto the unit sphere using (S1,S2,S3) / sqrt(S1^2+S2^2+S3^2).

pypolar.poincare.draw_empty_sphere(ax=None, **kwargs)[source]

Plot an empty Poincaré sphere.

Parameters:
  • ax – pyplot axis

  • **kwargs – style arguments passed to guide line artists.

Returns:

tuple(fig, ax, artists) with surface, line, and text handles.

pypolar.poincare.draw_jones_poincare(J, ax=None, label=None, normalize='s0', text_kwargs=None, **kwargs)[source]

Plot one Jones state on or inside the Poincaré sphere.

Parameters:
  • J – Jones vector with shape (2,)

  • ax – optional matplotlib 3D axis

  • label – optional text label

  • normalize – either “s0” or “unit”

  • text_kwargs – optional style args for label text

  • **kwargs – style arguments passed to draw_stokes_poincare

Returns:

tuple(fig, ax, artists) as returned by draw_stokes_poincare().

pypolar.poincare.draw_stokes_poincare(S, ax=None, label=None, normalize='s0', text_kwargs=None, **kwargs)[source]

Plot one Stokes state on or inside the Poincaré sphere.

Coordinates are controlled by normalize: * normalize=”s0” uses reduced Stokes values (S1/S0, S2/S0, S3/S0). * normalize=”unit” uses pure-state projection

(S1,S2,S3) / sqrt(S1^2+S2^2+S3^2).

Any keyword arguments for point styling should use standard Matplotlib names (for example linewidth, lw, color, linestyle, markersize). Label styling should use text_kwargs; legacy text keys like ha, va, and fontsize in **kwargs are still accepted when label is provided.

Parameters:
  • S – Stokes vector with shape (4,)

  • ax – optional matplotlib 3D axis

  • label – optional text label

  • normalize – either “s0” or “unit”

  • text_kwargs – optional style args for label text

  • **kwargs – style arguments passed directly to matplotlib.axes.Axes.plot

Returns:

tuple(fig, ax, artists) with point and optional label handles.

pypolar.poincare.join_jones_poincare(J1, J2, ax=None, normalize='s0', **kwargs)[source]

Plot a connection between two Jones vectors on or inside the Poincaré sphere.

Parameters:
  • J1 – first Jones vector with shape (2,)

  • J2 – second Jones vector with shape (2,)

  • ax – optional matplotlib 3D axis

  • normalize – either “s0” or “unit”

  • **kwargs – style arguments passed to join_stokes_poincare

Returns:

tuple(fig, ax, line) as returned by join_stokes_poincare().

pypolar.poincare.join_stokes_poincare(S1, S2, ax=None, normalize='s0', **kwargs)[source]

Plot a connection between two Stokes vectors on or inside the Poincaré sphere.

The direction follows a great-circle path for non-zero-radius endpoints and uses linear interpolation when an endpoint is at the origin.

Parameters:
  • S1 – first Stokes vector with shape (4,)

  • S2 – second Stokes vector with shape (4,)

  • ax – optional matplotlib 3D axis

  • normalize – either “s0” or “unit”

  • **kwargs – style arguments passed to matplotlib.axes.Axes.plot

Returns:

tuple(fig, ax, line) where line is the connecting arc/segment.

pypolar.ellipsometry

Useful routines for isotropic ellipsometry calculations.

This module provides helpers to move between Fresnel reflection quantities and common ellipsometry parameters, plus utilities for null ellipsometers and rotating-analyzer simulations.

Angles are measured from the surface normal for incidence-angle inputs. Set deg=True when passing angles in degrees.

Core conversion helpers:

* rho_from_m(index_of_refraction, incidence_angle, deg=False)
* rho_from_tanpsi_Delta(tanpsi, Delta, deg=False)
* tanpsi_Delta_from_rho(rho, deg=False)
* m_from_rho(rho, incidence_angle, deg=False)
* m_from_tanpsi_and_Delta(tanpsi, Delta, incidence_angle, deg=False)

Null-ellipsometer helpers:

* rho_from_zone_2_null_angles(P, A, deg=False)
* rho_from_zone_4_null_angles(P, A, deg=False)
* null_angles(index_of_refraction, incidence_angle, deg=False)
* null_angles_report(index_of_refraction, incidence_angle, deg=False)

Rotating-analyzer signal synthesis:

* rotating_analyzer_signal(phi, IDC, IS, IC, noise=0, deg=False)
* RAE_from_rho(phi, rho, P, average=1, noise=0, deg=False)
* rotating_analyzer_signal_from_rho(phi, rho, P, QWP=False, average=1, noise=0, deg=False)
* rotating_analyzer_signal_from_m(phi, index_of_refraction, incidence_angle, P, average=1, noise=0, deg=False)

Rotating-analyzer inversion helpers:

* find_fourier(phi, signal, deg=False)
* rho_from_rotating_analyzer_data(phi, signal, P, QWP=False, deg=False)
* rho_from_PSA(phi, signal, P, deg=False)
* m_from_rotating_analyzer_data(phi, signal, incidence_angle, P, QWP=False, deg=False)
pypolar.ellipsometry.RAE_from_rho(phi, rho, P, average=1, noise=0, deg=False)[source]

Create normalized rotating ellipsometer signal for sample.

See eqn 4.19 and eqn 4.23 in Fujiwara 2007

Generate the expected reading at each analyzer angle in an ellipsometer with a sample characterized by a material with an ellipsometer parameter rho = tan(psi)exp(j * Delta)

This is a classic source::polarizer::QWP::sample::analyzer::detector arrangement. The QWP is oriented at +45° if present.

Note that the default returned array is normalized between 0 and 1. therefore the noise should be scaled accordingly.

Parameters:
  • phi – array of analyzer angles from 0 to 2pi [radians / degrees]

  • rho – ellipsometer parameter for surface [complex]

  • P – angle of polarizer [radians / degrees]

  • average – average value of signal over 2pi [AU]

  • noise – std dev of normal noise distribution [AU]

  • deg – phi and P are in degrees [True / False]

Returns:

Array of ellipsometer readings for each angle phi [-]

pypolar.ellipsometry.find_fourier(phi, signal, deg=False)[source]

Calculate first few Fourier series coefficients.

Fit the signal to the function

I_ave * ( 1 + alpha * cos(2 * phi) + beta * sin(2 * phi) )

Parameters:
  • phi – array of analyzer angles [radians / degrees]

  • signal – array of ellipsometer intensities [AU]

  • deg – phi is in degrees [True / False]

Returns:

I_ave, alpha, beta

pypolar.ellipsometry.m_from_rho(rho, theta_i, deg=False)[source]

Calculate the index of refraction for an isotropic sample.

rho = r_par_amplitude / r_per_amplitude or

rho = tan(psi)*exp(j * Delta)

Formula from McCrackin “Measurement of the thickness and refractive index of very thin films and the optical properties of surfaces by ellipsometry”, Journal of Research of the National Bureau of Standards, (1963).

Parameters:
  • rho – complex reflectance ratio [-]

  • theta_i – incidence angle from normal [radians / degrees]

  • deg – theta_i is in degrees [True / False]

Returns:

complex index of refraction [-]

pypolar.ellipsometry.m_from_rotating_analyzer_data(phi, signal, theta_i, P, QWP=False, deg=False)[source]

Recover m from rotating analyzer data.

Parameters:
  • phi – array of analyzer angles [radians / degrees]

  • signal – array of ellipsometer intensities [AU]

  • theta_i – incidence angle from normal [radians / degrees]

  • P – incident polarization azimuthal angle [radians / degrees]

  • QWP – True if QWP is present

  • deg – phi, theta_i, and P are in degrees [True / False]

Returns:

complex index of refraction [-]

pypolar.ellipsometry.m_from_tanpsi_and_Delta(tanpsi, Delta, theta_i, deg=False)[source]

Return the index of refraction for observed Delta, tanpsi, and theta_i.

Parameters:
  • tanpsi – abs() of ratio of field amplitudes [-]

  • Delta – phase change caused by reflection [-]

  • theta_i – incidence angle from normal [radians / degrees]

  • deg – theta_i and Delta are in degrees [True / False]

Returns:

complex index of refraction [-]

pypolar.ellipsometry.null_angles(m, theta_i, deg=False)[source]

Generate expected ellipsometer angles for all zones.

The various null angles fall into four sets called zones, two with the fast - axis of the quarter wave plate set 45° (2 & 4) and two with the fast - axis of the quarter wave plate set to -45° (1 & 3). In each zone there are four combinations of polarizer and analyzer angles that have a null reading (because rotation of a linear polarizer by 180° should give the same result.

Table 1 from McCrackin “Measurement of the thickness and refractive index of very thin films and the optical properties of surfaces by ellipsometry”, Journal of Research of the National Bureau of Standards, (1963).

All angles returned fall between 0 and 2pi.

Parameters:
  • m – complex index of refraction [-]

  • theta_i – incidence angle from normal [radians / degrees]

  • deg – theta_i in degrees, return null angles in degrees? [True / False]

Returns:

dictionary with null angles [(P1, A1), (P2, A2), (P3, A3), (P4, A4)] for each zone

pypolar.ellipsometry.null_angles_report(m, theta_i, deg=False)[source]

Create a report showing null angles for sample.

Parameters:
  • m – complex index of refraction [-]

  • theta_i – incidence angle from normal [radians / degrees]

  • deg – theta_i is in degrees [True / False]

Returns:

string containing a report listing null angles for each zone.

pypolar.ellipsometry.rho_from_PSA(phi, signal, P, deg=False)[source]

Recover rho from polarizer / sample / rotating analyzer system.

Based on equation 4.24 in Fujiwara 2005. Note that the PSA arrangement allows 0<=psi<=90° and 0<=Delta<=180°.

In this system the measurement error increases when Delta is near zero or 180°. Since this corresponds to linearly polarized light and would be exactly what would be measured for dielectric samples.

Parameters:
  • phi – array of analyzer angles [radians / degrees]

  • signal – array of ellipsometer intensities [AU]

  • P – incident polarization azimuthal angle [radians / degrees]

  • deg – phi and P are in degrees [True / False]

Returns:

rho = tan(psi)*exp(1j * Delta) [-]

pypolar.ellipsometry.rho_from_m(m, theta_i, deg=False)[source]

Calculate the complex ratio of reflection amplitudes.

This assumes that the material is flat and isotropic (e.g., no surface film). It also assumes that the parallel (or perpendicular) field remains entirely parallel (or perpendicular) and is fully characterized by Fresnel reflection.

Parameters:
  • m – complex index of refraction [-]

  • theta_i – incidence angle from normal [radians / degrees]

  • deg – theta_i is in degrees [True / False]

Returns:

complex ellipsometer parameter rho [-]

pypolar.ellipsometry.rho_from_rotating_analyzer_data(phi, signal, P, QWP=False, deg=False)[source]

Recover rho from rotating analyzer data.

Based on equation 3.297 from Azzam (should be fixed to work with any P value)

Parameters:
  • phi – array of analyzer angles [radians / degrees]

  • signal – array of ellipsometer intensities [AU]

  • P – incident polarization azimuthal angle [radians / degrees]

  • QWP – True if QWP is present

  • deg – phi and P are in degrees [True / False]

Returns:

rho = tan(psi)*exp(1j * Delta) [-] fit: array of fitted data

pypolar.ellipsometry.rho_from_tanpsi_Delta(tanpsi, Delta, deg=False)[source]

Calculate the index of refraction for an isotropic sample.

Formula from McCrackin “Measurement of the thickness and refractive index of very thin films and the optical properties of surfaces by ellipsometry”, Journal of Research of the National Bureau of Standards, (1963).

Parameters:
  • tanpsi – tan(psi) or abs(rpar / rperp) [-]

  • Delta – phase change caused by reflection [radians / degrees]

  • deg – Delta is in degrees [True / False]

Returns:

complex ellipsometer parameter rho [-]

pypolar.ellipsometry.rho_from_zone_2_null_angles(P, A, deg=False)[source]

Recover rho from Null ellipsometer measurements in zone 2.

Parameters:
  • P – polarizer angle for null reading [radians / degrees]

  • A – analyzer angle for null reading [radians / degrees]

  • deg – P and A are in degrees [True / False]

Returns:

complex ellipsometer parameter rho [-]

pypolar.ellipsometry.rho_from_zone_4_null_angles(P, A, deg=False)[source]

Recover rho from Null ellipsometer measurements in zone 4.

Parameters:
  • P – polarizer angle for null reading in zone 4 [radians / degrees]

  • A – analyzer angle for null reading in zone 4 [radians / degrees]

  • deg – P and A are in degrees [True / False]

Returns:

complex ellipsometer parameter rho [-]

pypolar.ellipsometry.rotating_analyzer_signal(phi, IDC, IS, IC, noise=0, deg=False)[source]

Create theoretical rotating ellipsometer signal.

In theory the rotating analyzer ellipsometer generates a sinusoidal signal with an offset. This function does that and allows the optional addition of normally distributed noise.

Parameters:
  • phi – array of analyzer angles [radians / degrees]

  • IDC – DC amplitude of signal [-]

  • IS – sin(2 * phi) amplitude coefficient [-]

  • IC – cos(2 * phi) amplitude coefficient [-]

  • noise – std dev of normal noise distribution [-]

  • deg – phi is in degrees [True / False]

Returns:

Array of ellipsometer readings for each angle phi [-]

pypolar.ellipsometry.rotating_analyzer_signal_from_m(phi, m, theta_i, P, average=1, noise=0, deg=False)[source]

Create rotating ellipsometer signal for sample with known index.

Parameters:
  • phi – array of analyzer angles from 0 to 2pi [radians / degrees]

  • m – complex index of refraction of sample [-]

  • theta_i – angle of incidence (from normal) [radians / degrees]

  • P – angle of incident polarized light [radians / degrees]

  • average – average value of signal over 2pi [AU]

  • noise – std dev of normal noise distribution [-]

  • deg – phi, theta_i and P ar in degrees [True / False]

Returns:

Array of ellipsometer readings for each angle phi [-]

pypolar.ellipsometry.rotating_analyzer_signal_from_rho(phi, rho, P, QWP=False, average=1, noise=0, deg=False)[source]

Create normalized rotating ellipsometer signal for sample.

Generate the expected reading at each analyzer angle in an ellipsometer with a sample characterized by a material with an ellipsometer parameter rho = tan(psi)exp(j * Delta)

This is a classic source::polarizer::QWP::sample::analyzer::detector arrangement. The QWP is oriented at +45° if present.

Note that the default returned array is normalized between 0 and 1. therefore the noise should be scaled accordingly.

Parameters:
  • phi – array of analyzer angles from 0 to 2pi [radians / degrees]

  • rho – ellipsometer parameter for surface [complex]

  • P – angle of polarizer [radians / degrees]

  • QWP – True if QWP is present

  • average – average value of signal over 2pi [AU]

  • noise – std dev of normal noise distribution [AU]

  • deg – phi and P are in degrees [True / False]

Returns:

Array of ellipsometer readings for each angle phi [-]

pypolar.ellipsometry.tanpsi_Delta_from_rho(rho, deg=False)[source]

Extract ellipsometer parameters from rho.

rho = r_par_amplitude / r_per_amplitude or

rho = tan(psi)*exp(j * Delta)

Formula from Fujiwara 2007 eqn 4.6 and correspond to the case when the complex refractive index is negative (m = n - k * 1j)

Parameters:
  • rho – complex reflectance ratio [-]

  • deg – return Delta in degrees? [True / False]

Returns:

tanpsi – tan(psi) or abs(r_p / r_s) [-] Delta: phase change caused by reflection [radians / degrees]

pypolar.gaerter