API Reference

DirectorField

class nemaktis.lc_material.DirectorField(**kwargs)

The DirectorField class stores the director field and mesh informations. It is initialized given either the lengths and dimensions of the associated 3D mesh or a path to a vti file containing the director field and mesh details. In the first version of this constructor: .. code-block:: python

nfield = DirectorField(

mesh_lengths=(Lx,Ly,Lz), mesh_dimensions=(Nx,Ny,Nz))

the actual values of the director field needs to be provided later using the “init_from_funcs” method or via the setter method “vals” (numpy array of shape (Nz,Ny,Nx,3)). The mesh lengths needs to be specified in micrometer. In the second version of this constructor: .. code-block:: python

nfield = DirectorField(vti_file=”path to vti file”)

the values of the director field and the details of the mesh are automatically assigned from the vti file.

set_mask(*, mask_type, mask_formula=None, mask_ndarray=None)

Set a mask for the LC domain. This method allows to specifify complex shape for the LC domain inside the regular cartesian mesh specified at construction. Positive mask value are associated with the LC domain, while negative values are associated with the embedding fluid. Three possible ways of initializing the mask are possible. If you simply want to specify a spherical domain for a droplet centered on the mesh and of diameter equal to the mesh length along z, call: .. code-block:: python

nfield.set_mask(mask_type=”droplet”)

You can also use a string formula depending on the space variables x, y and z and which must evaluates to a value >=0 if the associated point is inside the LC domain, else to a value <=0: .. code-block:: python

nfield.set_mask(mask_type=”formula”, mask_formula=”your formula”)

Finally, you can directly gives a numpy array of shape (Nz,Ny,Nx), where each value in this array must be >=0 if the associated mesh point is inside the LC domain, else <=0:

nfield.set_mask(mask_type="raw", mask_ndarray=your_mask_array)
delete_mask()

Delete the current LC mask.

property mask_type

“droplet”, “formula” or “raw”.

Type

Returns the mask type

property mask_formula

Returns the LC mask formula if it was set, else returns None.

property mask_vals

Returns the LC mask boolean array.

extend(scale_x, scale_y)

Extend the computational mesh in the xy plane by padding new points near the x and y boundaries. These new points are initialized with the edge value of the director field on the x and y boundaries. :param scale_x: The mesh length in the x-direction will be scaled by this factor. :type scale_x: float :param scale_y: The mesh length in the y-direction will be scaled by this factor. :type scale_y: float

rotate_90deg(axis)

Rotate the director field by 90 degrees around the specified axis.

Parameters

axis (str) – Axis around which to perform the rotation. Need to be under the form ‘[s]A’ where the optional parameter ‘s’=’+’ or ‘-‘ decribes the sign of rotation and ‘A’=’x’, ‘y’ or ‘z’ defines the rotation axis.

rotate_180deg(axis)

Rotate the director field by 180 degrees around the specified axis.

Parameters

axis (str) – Axis around which to perform the rotation. Need to be under the form ‘A’ where ‘A’=’x’, ‘y’ or ‘z’ defines the rotation axis.

rotate(axis, angle, fill_value=None)

Rotate the director field by an arbitrary angle around the specified axis.

Parameters
  • axis (str) – Axis around which to perform the rotation. Need to be under the form ‘A’ where ‘A’=’x’, ‘y’ or ‘z’ defines the rotation axis.

  • angle (float) – Angle of rotation in degrees.

rescale_mesh(scaling_factor)

Scale the mesh using the given scaling factor.

Parameters

scaling_factor (factor) – The mesh lengths and spacings will be multiplied by this factor.

property vals

Numpy array for the director values, of shape (Nz,Ny,Nx,3).

init_from_funcs(nx_func, ny_func, nz_func)

Initialize the director field from three functions for each of its component. The functions must depends on the space variables x, y and z. We recall that the mesh is centered on the origin. If the given function are numpy-vectorizable, this function should be pretty fast. If not, a warning will be printed and the given function will be vectorized with the numpy method vectorize (in which case you should expect a much slower execution time).

normalize()

Normalize the director field values to 1.

save_to_vti(filename)

Save the director field into a vti file. The “.vti” extension is automatically appended, no need to include it in the filename parameter (but in case you do only one extension will be added)

get_pos(ix, iy, iz)

Returns the spatial position associated with the mesh indices (ix,iy,iz) It is assumed that the mesh is centered on the origin (0,0,0).

get_mesh_dimensions()

Returns the dimensions (Nx,Ny,Nz) of the simulation mesh

get_mesh_lengths()

Returns the lengths (Lx,Ly,Lz) of the simulation mesh

get_mesh_spacings()

Returns the spacings (dx,dy,dz) of the simulation mesh

get_n_vertices()

Returns the number of vertices in the simulation mesh

LCMaterial

class nemaktis.lc_material.LCMaterial(*, director_field, ne, no, nhost=1, nin=1)

A class containing the director field data, simulation mesh, and physics constants.

Parameters
  • director_field (DirectorField object) –

  • ne (float or math string depending on the wavelength variable "lambda" (µm)) – The extraordinary refractive index associated with the LC material.

  • no (float or math string depending on the wavelength variable "lambda" (µm)) – The ordinary refractive index associated with the LC material.

  • nhost (optional, float or math string depending on the wavelength variable "lambda" (µm)) – The refractive index associated with an eventual host fluid in which the LC domain is embedded (see DirectorField.set_mask).

  • nin (optional, float or math string depending on the wavelength variable "lambda" (µm)) – The refractive index associated with the input medium below the LC layer. A default value of 1 is assumed.

add_isotropic_layer(*, nlayer, thickness)

Add an isotropic layer above the sample. Light is assumed to propagate in the z-direction, and will cross first the LC material, and then the isotropic layers specified with this function.

Parameters
  • nlayer (float) – Refractive index of the new isotropic layer

  • thickness (float) – Thickness (µm) of the new isotropic layer

LightPropagator

class nemaktis.light_propagator.LightPropagator(*, material, wavelengths, max_NA_objective, max_NA_condenser=0, N_radial_wavevectors=1)

The LightPropagator class allows to propagate optical fields through a LC sample as in a real microscope: a set of plane waves with different wavevectors and wavelengths are sent on the LC sample, and the associated transmitted optical fields (which can now longer be represented as plane waves due to diffraction) are calculated using one of the backend.

The actual set of wavelengths for the plane waves (choosen at construction) approximate the relevant part of the spectrum of the illumination light, whereas the set of wavevectors (also calculated at construction) are determined from the numerical aperture of the input condenser. The more open the condenser aperture is, the smoother the micrograph will look, since an open condenser aperture is associated with a wide range of angle for the wavectors of the incident plane waves. Conversely, an almost closed condenser aperture is associated with a single plane wave incident normally on the sample.

Note that with the FieldViewer class, the transmitted optical fields calculated with this class can be projected on a visualisation screen through an objective of given numerical aperture. The numerical apertures of both the objective and condenser aperture can be set interactively in the FieldViewer class, whereas in this class we only specify the maximum value allowed for both quantities.

The simulation and choice of backend is done by calling the method propagate_field.

For each wavelength and wavevector of the incident plane wave, two simulations are done: one with a light source polarised along x, and one with a light source polarised along y. This allows us to fully caracterize the transmission of the LC sample and reconstruct any kind of optical micrograph.

Parameters
  • material (LCMaterial object) –

  • wavelengths (array-like object) – An array containing all the wavelengths of the spectrum for the light source.

  • max_NA_objective (float) – Sets the maximal numerical aperture for the microscope objective (you can dynamically adjust this quantity later on with a FieldViewer).

  • max_NA_condenser (float) – Sets the maximal numerical aperture for the microscope condenser (you can dynamically adjust this quantity later on with a FieldViewer).

  • N_radial_wavevectors (int) – Sets the number of wavevectors in the radial direction for the illumination plane waves. The total number of plane waves for each wavelength is 1+3*Nr*(Nr-1), where Nr correspond to the value of this parameter.

property material

Returns the current LC material

propagate_fields(*, method, bulk_filename=None)

Propagate optical fields through the LC sample using the specified backend.

Parameters
  • method ("bpm" | "dtmm") –

    If equal to “bpm”, the beam propagation backend will be used. Should be used if accuracy is privileged over speed.

    If equal to “dtmm”, the diffractive transfer matrix backend will be used (in its simplest version). Should be used if speed is privileged over accuracy.

  • bulk_filename (None or string) – If none, the backend will not export the bulk value of the optical fields in the LC layer. Else, the bulk fields values will be exported to a vti file whose basename is set by this parameter.

OpticalFields

class nemaktis.light_propagator.OpticalFields(**kwargs)

The OpticalFields object stores the mesh information of the transverse mesh (plane mesh orthogonal to the z-direction, default altitude of 0) and the optical fields values on this mesh. Since this python package is mainly used to reconstruct micrographs, we only store internally the complex horizontal electric field for two simulation: one with a light source polarised along x, and the other with a light source polarised along y. In case multiple wavelengths/wavectors were used in the simulation, we store these quantities separately for each wavelength/wavevector.

This class is initialised either manually or with a path to a vti file containing previously calculated optical fields and mesh details.

In the first version of this constructor:

optical_fields = OpticalFields(
    wavelengths=[l0,l1,...,lN], max_NA_objective=NA_o,
    max_NA_condenser=NA_c, N_radial_wavevectors=Nr,
    mesh_lengths=(Lx,Ly), mesh_dimensions=(Nx,Ny))

the actual values of the transverse fields needs to be provided later using the raw setter method fields_vals (shape (N_wavelengths,N_wavevectors,4,Ny,Nx), with N_wavevectors=3*Nr*(Nr-1)+1).

In the second version of this constructor:

optical_fields = OpticalFields(vti_file="path to vti file")

the values of the wavelengths and transverse fields are automatically assigned from the vti file.

copy()

Returns a hard copy of this OpticalFields object

property focused_vals

Numpy array for the optical fields values after focalisation by the microscope objective, of shape (N_wavelengths,N_wavevectors,4,Ny,Nx).

property vals

Numpy array for the optical fields values, of shape (N_wavelengths,N_wavevectors,4,Ny,Nx).

If you want to initialize by hand the optical fields, the four components in the third dimension correspond to:

  • complex Ex field for an input polarisation//x

  • complex Ey field for an input polarisation//x

  • complex Ex field for an input polarisation//y

  • complex Ey field for an input polarisation//y

focus_fields(z_focus=None)

Propagate the optical fields through the objective lens to the screen conjugate to the focusing plane (whose altitude inside the sample is set with the parameter z_focus).

save_to_vti(filename)

Save the optical fields into a vti file.

The “.vti” extension is automatically appended, no need to include it in the filename parameter (but in case you do only one extension will be added)

get_pos(ix, iy)

Returns the position associated with the mesh indices (ix,iy)

It is assumed that the mesh is centered on the origin (0,0).

get_wavelengths()

Returns the wavelength array

get_wavevectors()

Returns the wavevectors array

get_qr_index(NA_condenser)

For internal use.

Allows to build sub-range of wavevector index for a given numerical aperture of the condenser, which must be smaller than the internal maximal numerical aperture set at construction.

get_delta_qr()

For internal use.

Allows to build integration rule with respect to the wavectors.

get_mesh_dimensions()

Returns the dimensions (Nx,Ny) of the transverse mesh

get_mesh_lengths()

Returns the lengths (Lx,Ly) of the transverse mesh

get_mesh_spacings()

Returns the spacings (dx,dy,dz) of the transverse mesh

get_n_vertices()

Returns the number of vertices in the transverse mesh

FieldViewer

class nemaktis.field_viewer.FieldViewer(optical_fields, cmf=None)

A class allowing to recombine optical fields to generate optical micrographs like in a real microscope.

Parameters
polariser = True

Is there a polariser in the optical setup?

analyser = True

Is there an analyser in the optical setup?

compensator = 'No'

If “No”, remove the compensator from the optical setup. Other values set the type of compensator:

  • “Quarter-wave”: An achromatic quarter-wave compensator

  • “Half-wave”: An achromatic half-wave compensator

  • “Tint-sensitive”: a full-wave compensator at 540 nm.

polariser_angle = 0

Angle (in degree) between the privileged axis of the polariser and the x-axis

analyser_angle = 90

Angle (in degree) between the privileged axis of the analyser and the x-axis

compensator_angle = 0

Angle (in degree) between the fast axis of the compensator and the x-axis

intensity = 1

Intensity factor of the micrograph

NA_condenser = 0

Numerical aperture of the microscope’s condenser

n_tiles_x = 1

Number of repetitions of the micrograph in the x-direction

n_tiles_y = 1

Number of repetitions of the micrograph in the y-direction

grayscale = False

Should we calculate a grayscale micrograph (True) or a color micrograph (False)

NA_objective = 1

Numerical aperture of the microscope’s objective

plot()

Run a graphical user interface allowing to dynamically adjust the attributes of this class and visualize the associated micrographs in real-time.

property z_focus

Current vertical position of the focal plane

get_image()

Returns the current micrograph as a numpy array of shape (Ny,Nx,3|1), (last dim is 3 if in color mode, 1 if in grayscale mode).

update_image()

Recompute the micrograph from the optical fields data