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
andz
and which must evaluates to a value >=0 if the associated point is inside the LC domain, else to a value <=0: .. code-block:: pythonnfield.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 thex
andy
boundaries. These new points are initialized with the edge value of the director field on thex
andy
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
andz
. 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 methodvectorize
(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 alongy
. 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
optical_fields (
OpticalFields
object) – Can be created either by a LightPropagator or directly by importing a vti file exported in a previous simulation.cmf (numpy ndarray) – A color matching array created with the dtmm package, see https://dtmm.readthedocs.io/en/latest/reference.html#module-dtmm.color
-
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