snompy.sample.Sample#

class snompy.sample.Sample(eps_stack=None, beta_stack=None, t_stack=None, eps_env=None, nu_vac=None)#

A class representing a layered sample with a semi-infinite substrate and superstrate.

Parameters:
eps_stackarray_like

Dielectric function of each layer in the stack (with the first element corresponding to the semi-infinite superstrate, and the last to the semi-infinite substrate). eps_stack should have first dimension size two greater than t_stack, and all eps_stack[i, …] should be broadcastable with all t_stack[i, …]. Either eps_stack or beta_stack must be None.

beta_stackarray_like

Quasistatic reflection coefficients of each interface in the stack (with the first element corresponding to the top interface). beta_stack should have first dimension size one greater than t_stack, and all beta_stack[i, …] should be broadcastable with all t_stack[i, …]. Either eps_stack or beta_stack must be None.

t_stackarray_like

Thicknesses of each finite-thickness layer sandwiched between the interfaces in the stack. A zero-size array can be used for the case of a bulk sample with a single interface.

eps_envarray_like

Dielectric function of the environment (equivalent to eps_stack[0]). This is used to calculate eps_stack from beta_stack if needed.

nu_vacfloat

Vacuuum wavenumber of incident light in inverse meters. Used to calculate far-field reflection coefficients via the transfer matrix method. Should be broadcastable with all eps_stack[i, …].

Attributes:
eps_stack

Dielectric function of each layer in the stack (with the first element corresponding to the semi-infinite superstrate, and the last to the semi-infinite substrate).

beta_stack

Quasistatic reflection coefficients of each interface in the stack (with the first element corresponding to the top interface).

t_stack

Thicknesses of each finite-thickness layer sandwiched between the interfaces in the stack.

multilayer

True if sample has one or more finite-thickness layer sandwiched between the interfaces in the stack, False for bulk samples.

eps_envarray_like

Dielectric function of the enviroment (equivalent to eps_stack[0]).

Methods

image_depth_and_charge(z_Q[, n_lag])

Calculate the depth and relative charge of an image charge induced below the top surface of the sample.

refl_coef([q, theta_in, nu_vac, polarization])

Return the momentum-dependent Fresnel reflection coefficient for the sample, using the transfer matrix method.

refl_coef_qs([q])

Return the momentum-dependent quasistatic reflection coefficient for the sample.

refl_coef_qs_above_surf(z_Q[, n_lag])

Return the effective quasistatic reflection coefficient for a charge over the sample surface, evaluated at the position of the charge itself.

surf_pot_and_field(z_Q[, n_lag])

Return the electric potential and field at the sample surface, induced by a charge above the top interface.

trans_coef([q, theta_in, nu_vac, polarization])

Return the momentum-dependent Fresnel transmission coefficient for the sample, using the transfer matrix method.

trans_coef_qs([q])

Return the momentum-dependent quasistatic transmission coefficient for the sample.

transfer_matrix([q, theta_in, nu_vac, ...])

Return the transfer matrix for the sample for incident light with a given wavenumber, in-plane momentum and polarization.

transfer_matrix_qs([q])

Return the transfer matrix for the sample in the quasistatic limit.

__init__(eps_stack=None, beta_stack=None, t_stack=None, eps_env=None, nu_vac=None)#
image_depth_and_charge(z_Q, n_lag=None)#

Calculate the depth and relative charge of an image charge induced below the top surface of the sample.

This function works by evaluating the electric potential and field induced at the sample surface using Sample.surf_pot_and_field().

Parameters:
z_Qfloat

Height of the charge above the sample.

n_lagint

The order of the Laguerre polynomial used by surf_pot_and_field().

Returns:
d_imagecomplex

The effective depth of the image charge induced below the surface.

beta_imagecomplex

The relative charge of the image charge induced below the surface.

See also

surf_pot_and_field

Surface electric potential and field.

Notes

This function calculates the depth of an image charge induced by a charge \(q\) at height \(z_Q\) above a sample surface using the equation

\[d_{image} = \left| \frac{\phi \rvert_{z=0}}{E_z \rvert_{z=0}} \right| - z_Q,\]

and the effective charge of the image, relative to \(q\), using the equation

\[\beta_{image} = \frac{ \left( \phi \rvert_{z=0} \right)^2 } {E_z \rvert_{z=0}},\]

where \(\phi\) is the electric potential, and \(E_z\) is the vertical component of the electric field. These are based on equations (9) and (10) from reference [1]. The depth \(d_{image}\) is forced to be a real number by taking the absolute value of the \(\phi\)-\(E_z\) ratio, as described in reference [2].

References

[1]

B. Hauer, A. P. Engelhardt, and T. Taubner, “Quasi-analytical model for scattering infrared near-field microscopy on layered systems,” Opt. Express, vol. 20, no. 12, p. 13173, Jun. 2012, doi: 10.1364/OE.20.013173.

[2]

C. Lupo et al., “Quantitative infrared near-field imaging of suspended topological insulator nanostructures,” pp. 1-23, Dec. 2021, [Online]. Available: http://arxiv.org/abs/2112.10104

refl_coef(q=None, theta_in=None, nu_vac=None, polarization='p')#

Return the momentum-dependent Fresnel reflection coefficient for the sample, using the transfer matrix method.

Parameters:
qfloat, default 0.0

In-plane electromagnetic wave momentum. Must be broadcastable with all eps_stack[i, …] and t_stack[i, …]. Either q or theta_in must be None.

theta_infloat

Angle of the incident light to the surface normal in radians. Must be broadcastable with all eps_stack[i, …] and t_stack[i, …]. Used to calculate q. Either q or theta_in must be None.

nu_vacfloat

Vacuuum wavenumber of incident light in inverse meters. Used to calculate far-field reflection coefficients via the transfer matrix method. Should be broadcastable with all eps_stack[i, …].

polarization: {“p”, “s”}

The polarization of the incident light. “p” for parallel to the plane of incidence, and “s” for perpendicular (from the German word senkrecht).

Returns:
rcomplex

Fresnel reflection coefficient of the sample.

refl_coef_qs(q=0.0)#

Return the momentum-dependent quasistatic reflection coefficient for the sample.

Parameters:
qfloat, default 0.0

In-plane electromagnetic wave momentum. Must be broadcastable with all eps_stack[i, …] and t_stack[i, …]. Either q or theta_in must be None.

Returns:
betacomplex

Quasistatic reflection coefficient of the sample.

refl_coef_qs_above_surf(z_Q, n_lag=None)#

Return the effective quasistatic reflection coefficient for a charge over the sample surface, evaluated at the position of the charge itself.

This function works by performing integrals over all values of in-plane electromagnetic wave momentum q, using Gauss-Laguerre quadrature.

Parameters:
z_Qfloat

Height of the charge above the sample.

n_lagint

The order of the Laguerre polynomial used to evaluate the integrals over all q.

Returns:
beta_effcomplex

The effective quasistatic reflection coefficient at position z_Q.

See also

numpy.polynomial.laguerre.laggauss

Laguerre polynomial weights and roots for integration.

Notes

This function evaluates

\[\overline{\beta} =\frac {\int_0^\infty \beta(q) q e^{-2 z_Q q} dq} {\int_0^\infty q e^{-2 z_Q q} dq}\]

where \(\overline{\beta}\) is the effective quasistatic reflection coefficient for a charge at height \(z_Q\) (evaluated at the position of the charge itself), \(q\) is the electromagnetic wave momentum, and \(\beta(q)\) is the momentum-dependent effective reflection coefficient for the surface [1].

To do this, the denominator is first solved explicitly as \(1 / (4 z_Q^2)\). Then the substitution \(x = 2 z_Q q\), is made to give

\[\overline{\beta} = \int_0^\infty \beta\left(\frac{x}{2 z_Q}\right) x e^{-x} dx.\]

It then uses the Gauss-Laguerre approximation [2]

\[\int_0^{\infty} e^{-x} f(x) dx \approx \sum_{j=1}^J w_j f(x_j),\]

where \(x_j\) is the \(j^{th}\) root of the Laguerre polynomial

\[L_J(x) = \sum_{j=0}^{J} {J \choose j} \frac{(-1)^j}{j!} x^j,\]

and \(w_j\) is a weight given by

\[w_j = \frac{x_j}{\left((J + 1) L_{J + 1}(x_j) \right)^2}.\]

The integral can therefore be approximated by the sum

\[\overline{\beta} \approx \sum_{j=1}^J w_j \beta\left(\frac{x_j}{2 z_Q}\right) x_j.\]

The choice of \(J\), defined in this function as n_lag, will affect the accuracy of the approximation, with higher \(J\) values leading to more accurate evaluation of the integrals.

In this function the Laguerre weights and roots are found using numpy.polynomial.laguerre.laggauss() and the momentum-dependent reflection coefficient is found using snompy.sample.Sample.refl_coef_qs().

References

[1]

L. Mester, A. A. Govyadinov, S. Chen, M. Goikoetxea, and R. Hillenbrand, “Subsurface chemical nanoidentification by nano-FTIR spectroscopy,” Nat. Commun., vol. 11, no. 1, p. 3359, Dec. 2020, doi: 10.1038/s41467-020-17034-6.

[2]

S. Ehrich, “On stratified extensions of Gauss-Laguerre and Gauss-Hermite quadrature formulas,” J. Comput. Appl. Math., vol. 140, no. 1-2, pp. 291-299, Mar. 2002, doi: 10.1016/S0377-0427(01)00407-1.

surf_pot_and_field(z_Q, n_lag=None)#

Return the electric potential and field at the sample surface, induced by a charge above the top interface.

This function works by performing integrals over all values of in-plane electromagnetic wave momentum q, using Gauss-Laguerre quadrature.

Parameters:
z_Qfloat

Height of the charge above the sample.

n_lagint

The order of the Laguerre polynomial used to evaluate the integrals over all q.

Returns:
phicomplex

The electric potential induced at the sample surface by the charge.

Ecomplex

The component of the surface electric field perpendicular to the surface.

See also

numpy.polynomial.laguerre.laggauss

Laguerre polynomial weights and roots for integration.

Notes

This function evaluates the integrals

\[\begin{split}\begin{align*} \phi \rvert_{z=0} &= \int_0^\infty \beta(q) e^{-2 z_Q q} dq, \ \text{and}\\ E_z \rvert_{z=0} &= \int_0^\infty \beta(q) q e^{-2 z_Q q} dq, \end{align*}\end{split}\]

where \(\phi\) is the electric potential, \(E_z\) is the vertical component of the electric field, \(q\) is the electromagnetic wave momentum, \(\beta(q)\) is the momentum-dependent effective reflection coefficient for the surface, and \(z_Q\) is the height of the inducing charge above the surface [1].

To do this, it first makes the substitution \(x = 2 z_Q q\), such that the integrals become

\[\begin{split}\begin{align*} \phi \rvert_{z=0} & = \frac{1}{2 z_Q} \int_0^\infty \beta\left(\frac{x}{2 z_Q}\right) e^{-x} dx, \ \text{and}\\ E_z \rvert_{z=0} & = \frac{1}{4 z_Q^2} \int_0^\infty \beta\left(\frac{x}{2 z_Q}\right) x e^{-x} dx. \end{align*}\end{split}\]

It then uses the Gauss-Laguerre approximation [2]

\[\int_0^{\infty} e^{-x} f(x) dx \approx \sum_{j=1}^J w_j f(x_j),\]

where \(x_j\) is the \(j^{th}\) root of the Laguerre polynomial

\[L_J(x) = \sum_{j=0}^{J} {J \choose j} \frac{(-1)^j}{j!} x^j,\]

and \(w_j\) is a weight given by

\[w_j = \frac{x_j}{\left((J + 1) L_{J + 1}(x_j) \right)^2}.\]

The integrals can therefore be approximated by the sums

\[\begin{split}\begin{align*} \phi \rvert_{z=0} & \approx \frac{1}{2 z_Q} \sum_{j=1}^J w_j \beta\left(\frac{x_j}{2 z_Q}\right), \ \text{and}\\ E_z \rvert_{z=0} & \approx \frac{1}{4 z_Q^2} \sum_{j=1}^J w_j \beta\left(\frac{x_j}{2 z_Q}\right) x_j. \end{align*}\end{split}\]

The choice of \(J\), defined in this function as n_lag, will affect the accuracy of the approximation, with higher \(J\) values leading to more accurate evaluation of the integrals.

In this function the Laguerre weights and roots are found using numpy.polynomial.laguerre.laggauss() and the momentum-dependent reflection coefficient is found using snompy.sample.Sample.refl_coef_qs().

References

[1]

L. Mester, A. A. Govyadinov, S. Chen, M. Goikoetxea, and R. Hillenbrand, “Subsurface chemical nanoidentification by nano-FTIR spectroscopy,” Nat. Commun., vol. 11, no. 1, p. 3359, Dec. 2020, doi: 10.1038/s41467-020-17034-6.

[2]

S. Ehrich, “On stratified extensions of Gauss-Laguerre and Gauss-Hermite quadrature formulas,” J. Comput. Appl. Math., vol. 140, no. 1-2, pp. 291-299, Mar. 2002, doi: 10.1016/S0377-0427(01)00407-1.

trans_coef(q=None, theta_in=None, nu_vac=None, polarization='p')#

Return the momentum-dependent Fresnel transmission coefficient for the sample, using the transfer matrix method.

Parameters:
qfloat, default 0.0

In-plane electromagnetic wave momentum. Must be broadcastable with all eps_stack[i, …] and t_stack[i, …]. Either q or theta_in must be None.

theta_infloat

Angle of the incident light to the surface normal in radians. Must be broadcastable with all eps_stack[i, …] and t_stack[i, …]. Used to calculate q. Either q or theta_in must be None.

nu_vacfloat

Vacuuum wavenumber of incident light in inverse meters. Used to calculate far-field reflection coefficients via the transfer matrix method. Should be broadcastable with all eps_stack[i, …].

polarization: {“p”, “s”}

The polarization of the incident light. “p” for parallel to the plane of incidence, and “s” for perpendicular (from the German word senkrecht).

Returns:
tcomplex

Fresnel transmission coefficient of the sample.

trans_coef_qs(q=0.0)#

Return the momentum-dependent quasistatic transmission coefficient for the sample.

Parameters:
qfloat, default 0.0

In-plane electromagnetic wave momentum. Must be broadcastable with all eps_stack[i, …] and t_stack[i, …]. Either q or theta_in must be None.

Returns:
t_qscomplex

Quasistatic transmission coefficient of the sample.

transfer_matrix(q=None, theta_in=None, nu_vac=None, polarization='p')#

Return the transfer matrix for the sample for incident light with a given wavenumber, in-plane momentum and polarization.

Parameters:
qfloat, default 0.0

In-plane electromagnetic wave momentum. Must be broadcastable with all eps_stack[i, …] and t_stack[i, …]. Either q or theta_in must be None.

theta_infloat

Angle of the incident light to the surface normal in radians. Must be broadcastable with all eps_stack[i, …] and t_stack[i, …]. Used to calculate q. Either q or theta_in must be None.

nu_vacfloat

Vacuuum wavenumber of incident light in inverse meters. Used to calculate far-field reflection coefficients via the transfer matrix method. Should be broadcastable with all eps_stack[i, …].

polarization: {“p”, “s”}

The polarization of the incident light. “p” for parallel to the plane of incidence, and “s” for perpendicular (from the German word senkrecht).

Returns:
Mcomplex

The transfer matrix of the sample.

Notes

This implementation of the transfer matrix method is based on the description given in reference [1].

References

[1]

T. Zhan, X. Shi, Y. Dai, X. Liu, and J. Zi, “Transfer matrix method for optics in graphene layers,” J. Phys. Condens. Matter, vol. 25, no. 21, p. 215301, May 2013, doi: 10.1088/0953-8984/25/21/215301.

transfer_matrix_qs(q=0.0)#

Return the transfer matrix for the sample in the quasistatic limit.

Parameters:
qfloat, default 0.0

In-plane electromagnetic wave momentum. Must be broadcastable with all eps_stack[i, …] and t_stack[i, …]. Either q or theta_in must be None.

Returns:
M_qscomplex

The quasistatic transfer matrix of the sample.

Notes

This implementation of the transfer matrix method is based on the description given in reference [1].

References

[1]

T. Zhan, X. Shi, Y. Dai, X. Liu, and J. Zi, “Transfer matrix method for optics in graphene layers,” J. Phys. Condens. Matter, vol. 25, no. 21, p. 215301, May 2013, doi: 10.1088/0953-8984/25/21/215301.