pyMOE package

Submodules

pyMOE.aperture module

aperture.py

Definition of Class Aperture

class pyMOE.aperture.Aperture(x, y)

Bases: object

Class Aperture:

Creates an Aperture object that is an homogenous array of values corresponding to the transfer function matrix across the aperture

Args:
x:

Vector for the x axis

y:

Vector for the y axis

Methods:
aperture:

returns the aperture

shape:

returns the shape of the aperture

discretize(levels)

Discretizes the aperture to the number of levels

height2phase(wavelength, n1, n0=1)

Converts the height to phase

Args:
wavelength:

Wavelength of the light

n1:

Refractive index of the medium where the light is propagating

n0:

Refractive index of the medium background

modulos(mod, normalize_to_max=True, mod_tolerance=1e-64, align_max=True)

Discretizes the aperture to the number of levels

phase2height(wavelength, n1, n0=1)

Converts the phase to height

Args:
wavelength:

Wavelength of the light

n1:

Refractive index of the medium where the light is propagating

n0:

Refractive index of the medium background

phase_unwrap()

Unwraps the phase of the aperture

pixelize(pixelize_x, pixelize_y, verbose=True)

Pixelizes the aperture to the given pixelize_x in real space coordinates by averaging the data within the pixel, keeping same shape

property shape
class pyMOE.aperture.ApertureField(x, y)

Bases: object

Class Aperture:

Creates an Aperture object that is an homogenous array of complex values corresponding to the transfer function matrix across the aperture

Args:
x:

Vector for the x axis

y:

Vector for the y axis

Methods:
aperture:

returns the complex aperture array

amplitude:

sets or returns the amplitude of the aperture array

phase:

sets or returns the phase of the aperture array

unwrap:

retursn the unwrapped phase

shape:

returns the shape of the aperture

property amplitude
property phase
property shape
property unwrap

pyMOE.dither module

dither.py Module for dithering of masks/images

pyMOE.dither.dither_img(input_img, output_filename, plotting=False)

Returns a make dithered image from input_img, save to output_img.

Args:
inputcv2:

input image as a 2D grid (use cv2 img)

output_filename:

filename of image to be written

plotting:

binary value, if True shows the plot, defaults to False

pyMOE.dither.floyd_steinberg(input_img, plot=False)

Applies Floyd-Steinberg dithering algorithm to input image.

Args:
input_img:

input image as a 2D grid (use cv2 img)

plot:

binary value, if True shows the plot, defaults to False

pyMOE.ensemble module

ensemble.py

Definition of Class Ensemble

class pyMOE.ensemble.Ensemble(aperture_array_amp, aperture_array_phase, screen_array, wavelength_array, input_light_field, topographies_array=None, propagation_methods=None)

Bases: object

Class Ensemble:

Creates a object with an optical ensemble of apertures, fields and screens

Args:
aperture_array:

array of apertures (Aperture objects)

screen_array:

array of screens (Screen objects)

propagation_methods_array:

propagators from propagate (optimize) module to use (function names)

wavelength_array:

array of wavelengths (scalar)

input_light_field:

input light (1 Field object)

topografies_array:

(optional) if given consider it as the topografies from where the phases can be obtained

Methods:
fields:

returns the fields at the apertures

screens:

returns the fields stored

overall_screen:

returns the field stored in an overall screen

property apertures_amplitudes
property apertures_phases
property apertures_xar
property fields
property screens

pyMOE.export module

export.py Module containing several functions to export masks to gds.

pyMOE.export.grayim2gds(infile, outfile, pixelx, pixely, cellname, level, layer=0, datatype=0, verbose=False)

(void) Transforms one image (converted to grayscale) into a gds, using cv2

Args:
infile:

input IMAGE file (on extension that cv2 can read ), e.g. “image.png”

outfile:

output GDS file, e.g. “image.gds”

pixelx:

pixel size in x, in um

pixely:

pixel size in y, in um

cellname:

string with cellname, e.g. “TOP”

level:

int from 0 to 255, pixels gray value to be passed to GDS

layer:

(optional) gray level, defaults to 0

datatype:

(optional) gds datatype, defaults to 0

verbose:

(optional) defaults to False, if True prints

infilxe = “image.png” outfilxe = “image.gds” pixelx = 1 #um pixely = 1 #um grayim2gds(infilxe, outfilxe, pixelx, pixely,”TOP”, 0)

pyMOE.export.grayim2gds_writer(infile, outfile, pixelx, pixely, cellname, level, layer=0, datatype=0, verbose=False)

(void) Transforms one image (converted to grayscale) into a gds, using cv2 by default adds the image to (layer, datatype) = (0,0)

Args:
infile:

input IMAGE file (on extension that cv2 can read ), e.g. “image.png”

outfile:

output GDS file, e.g. “image.gds”

pixelx:

pixel size in x, in um

pixely:

pixel size in y, in um

cellname:

string with cellname, e.g. “TOP”

level:

int from 0 to 255 (0 = black, 255=white) , pixels gray value to be passed to GDS

layer:

(optional) gray level, defaults to 0

datatype:

(optional) gds datatype, defaults to 0

verbose:

(optional) defaults to False, if True prints

infilxe = “image.png” outfilxe = “image.gds” cellname = “TOP” #name of the gds cell graycolor = 0 #black pixels pixelx = 1 #um pixely = 1 #um

grayim2gds_writer(infilxe, outfilxe, pixelx, pixely,cellname, graycolor, verbose=True)

pyMOE.export.grayim2gds_writer_frac(infile, outfile, pixelx, pixely, cellname, level, nm=None, layer=0, datatype=0, verbose=False)

(void) Transforms one image (converted to grayscale) into a gds, using cv2

By default adds the image to (layer, datatype) = (0,0)

Args:
infile:

input IMAGE file (on extension that cv2 can read ), e.g. “image.png”

outfile:

output GDS file, e.g. “image.gds”

pixelx:

pixel size in x, in um

pixely:

pixel size in y, in um

cellname:

string with cellname, e.g. “TOP”

level:

int from 0 to 255 (0 = black, 255=white) , pixels gray value to be passed to GDS

nm:

(optional) If nm is given fractionates the image, nr of pixels for each fractioned part (should be multiple of pixel sizes), defaults to None

layer:

(optional) gray level, defaults to 0

datatype:

(optional) gds datatype, defaults to 0

verbose:

(optional) defaults to False, if True prints

infilxe = “image.png” outfilxe = “image.gds” pixelx = 1 #um pixely = 1 #um cellname = “TOP” #name of the gds cell graycolor = 0 #black pixels frac = 250 #size of frac pixels in the image

grayim2gds_writer_frac(infilxe, outfilxe, pixelx, pixely, cellname, graycolor, frac, verbose=True)

pyMOE.export.grayim2gds_writer_klops(infile, output_filename, pixelx, pixely, cellname, level, layer=0, datatype=0, verbose=False)

(void) Transforms one image (converted to grayscale) into a gds, using cv2 for reading the image by default adds the image to (layer, datatype) = (0,0)

Args:
infile:

input IMAGE file (on extension that cv2 can read ), e.g. “image.png”

output_filename:

intermediate GDS file

pixelx:

pixel size in x, in um

pixely:

pixel size in y, in um

cellname:

string with cellname, e.g. “TOP”

level:

int from 0 to 255 (0 = black, 255=white) , pixels gray value to be passed to GDS

layer:

(optional) gray level, defaults to 0

datatype:

(optional) gds datatype, defaults to 0

verbose:

(optional) defaults to False, if True prints

pyMOE.field module

field.py

Definition of Class Field and related functions

class pyMOE.field.Field(x, y)

Bases: object

Class Field:

Creates an E Field object is an of values corresponding to an input or modulated electric field

Args:
x:

Vector for the x axis

y:

Vector for the y axis

Methods:
field:

returns the field

shape:

returns the shape of the field

property amplitude
property intensity
property phase
property shape
class pyMOE.field.Screen(x, y, z)

Bases: object

Class Screen:
Creates a Screen object that is 1D or 2D and has internal xyz coordinates

to facilitate the propagation of a field onto a target screen

Args:
x:

Vector for the x axis

y:

Vector for the y axis

z:

Vector for the z axis

Methods:
screen:

returns the field on the screen

shape:

returns the shape of the field

property amplitude
property intensity
property nindex
property phase
property shape
slice_X(y, z)
slice_XY(z)
slice_XZ(y)
slice_Y(x, z)
slice_YZ(x)
slice_Z(x, y)
pyMOE.field.create_empty_field(xmin, xmax, N_x, ymin, ymax, N_y)

Creates an empty field max of the mesh dimensions provided

Args:
xmin, xmax:

range for x

N_x:

number of x points

ymin, ymax:

range for y

N_y:

number of y points

Returns:
field:

empty Field

pyMOE.field.create_empty_field_from_aperture(aperture)

Creates an empty field with the same spatial dimensions of the given aperture but does not modulate the field.

Args:
aperture:

aperture

Returns:
field:

empty Field of same spatial dimensions

pyMOE.field.create_empty_field_from_field(field)

Creates an empty field with the same spatial dimensions of the given field

Args:
field:

field

Returns:
field:

empty Field of same spatial dimensions

pyMOE.field.create_screen_XY(xmin, xmax, N_x, ymin, ymax, N_y, z)

Creates an empty screen of the mesh dimensions provided

Args:
xmin, xmax:

range for x

N_x:

number of x points

ymin, ymax:

range for y

N_y:

number of y points

z:

z position of the screen plane

Returns:
screen:

empty Screen

pyMOE.field.create_screen_YZ(ymin, ymax, N_y, zmin, zmax, N_z, x=0)

Creates an empty screen of the mesh dimensions provided

Args:
ymin, ymax:

range for y

N_y:

number of y points

zmin, zmax:

range for z

N_z:

number of z points

x:

x position of the screen plane

Returns:
screen:

empty Screen

pyMOE.field.create_screen_ZZ(zmin, zmax, N_z, x=0, y=0, log=False)

Creates an empty screen of the mesh dimensions provided

Args:
zmin, zmax:

range for z

N_z:

number of z points

x:

x position of the screen line

y:

y position of the screen line

Returns:
screen:

empty Screen

pyMOE.field.generate_gaussian_beam(field, w0, z, wavelength, center=(0, 0), E0=1)

Generates a Gaussian beam (with wimaginary part) https://spie.org/publications/spie-publication-resources/optipedia-free-optics-information/fg12_p18-19_gaussian_beams#_=_

Args:
field:

Input field object to add the flat field

w0:

Beam waist at z=0

z:

Z-coordinate, with origin in minimum waist

wavelength:

Wavelength in meters

center:

center in (x,y) plane, default (0,0)

E0:

Amplitude of the electric field

Returns:
field:

returns the field.

pyMOE.field.generate_gaussian_field(field, E0, w0, center=(0, 0))

Generates a Gaussian beam amplitude (no imaginary part) **to be deprecated in favor of generate_gaussian_beam

E = E0*exp(-r^2/w0^2) E0 - amplitude on axis r - radius w0 - radius where amplitude is 1/e of it’s on axis value

Args:
field:

Input field object to add the flat field

E:

Amplitude of the electric field

Returns:
field:

returns the field.

pyMOE.field.generate_uniform_field(field, E0=1)

Generates a unifor, wavefront field with amplitude E

Args:
field:

Input field object to add the flat field

E0:

Amplitude of the electric field

Returns:
field:

returns the field.

pyMOE.field.modulate_field(field, amplitude_mask=None, phase_mask=None, autograd=False)

Modulates the input field with the given amplitude or phase mask. If amplitude_mask is not given, it assumes an amplitude of 1 for the amplitude modulatiom. If phase is not given, it assumes a phase of 0 for the phase modulation The field dimensions and the provided masks must be the same otherwise it raises an error.

Args:
field:

Input field to be modulated

amplitude_mask:

Mask of amplitude aperture

phase_mask:

Mask of phase aperture

Returns:
field:

returns the modulated field.

pyMOE.field.oblique(field, wavelength, thetax, thetay)

Transform the normal incident field into an oblique incidence by angles (thetax, thetay) defined against aperture normal

Args:
thetax:

Angle between surface normal and x axis (radians)

thetay:

Angle between surface normal and y axis (radians)

Returns:
field:

returns the oblique field

pyMOE.gds_klops module

gds_klops.py Module containing several functions for operations with/within mask files (e.g. gds)

These functions might require pya, gdspy, gdstk or gdshelpers libraries. Functions using gdspy and/or pya are exemplified within the notebooks.

####DISCLAIMER: these functions were written with klayout-0.26.11 version ####There might be some inconsistencies for later versions of pya library ####Nevertheless, tests were made for klayout-0.28.17 and no apparent conflict was found.

pyMOE.gds_klops.cell_wpol(cs, cellname)

Transforms contourf into GDS2 using gdshelpers ‘cs’ = contours FROM matplotlif contourf function ‘cellname’ = string cellname, e.g. ‘TOP’ Returns: cell with polygon, multipolygon array

pyMOE.gds_klops.cell_wpol_gdspy(cs, cellname, prec=1e-06, mpoints=1000000000.0)

Cell made with cut polygons from the z profile

Args:
cs:

contours FROM matplotlif contourf function

cellname:

string cellname, e.g. ‘TOP’

Returns:

[0] gdspy library [1] cell with polygons

##By default the levels start at 0 and go to the number of levels in the contourplot

pyMOE.gds_klops.cell_wpol_gdspy_fast(cs, cellname, prec=1e-06, mpoints=1000000000.0)

Cell made with cut polygons from the z profile

Args:
cs:

contours FROM matplotlif contourf function

cellname:

string cellname, e.g. ‘TOP’

Returns:

[0] gdspy library [1] cell with polygons

##By default the levels start at 0 and go to the number of levels in the contourplot #CAREFUL, this is better for estimation ONLY as we need enough resolution in the contourplot for this approach to work properly

pyMOE.gds_klops.cell_wpol_gdstk(cs, cellname)

Transforms contourf into GDS2 using gdstk

Args:
cs:

contours FROM matplotlif contourf function

cellname:

string cellname, e.g. ‘TOP’

Returns:

[0] gdstk library [1] cell with polygons

pyMOE.gds_klops.change_layers(fstgds_filename, fst_cellname, layerspol, new_layers, output_filename)

(void) Transforms layers from the source layer into the destination #by default considers datatypes are int(0), set datatypes to 0 function can be used before

Args:
fstgds_filename:

string filename of gds to read

fst_cellname:

string name of cell in the gds

layerspol:

array of the layers of the gds file

new_layers:

array of destination layers - MUST HAVE THE SAME CORRESPONDENCE

output_filename:

string filename of output gds

pyMOE.gds_klops.change_layers_gdspy(fstgds_filename, new_cellname, layerspol, new_layers, output_filename)

Transforms layers from the source layer (layerpol) into the destination (new_layers) By default considers datatypes are int(0), set datatypes to 0 function can be used before Assumes that we have the polygons in the top level of the input gds

Args:
fstgds_filename:

string filename of gds to read

new_cellname:

string name of cell in the gds

layerspol:

array of the layers of the gds file, if it is not the same, leaves the absent layers untouched

new_layers:

array of destination layers - MUST HAVE THE SAME CORRESPONDENCE

output_filename:

string filename of output gds

pyMOE.gds_klops.correct_gds(inputfilename_gds, outputfilename_dxf)

(void) corrects gds to be able to read/write gds files

pyMOE.gds_klops.diffs_layers_arrays(readfile, cellname, layerspol1, datatypes1, layerspol2, datatypes2, outfile)

(void) Sequentially makes the difference from one layer to the other, from layerspol1 to layerspol2

Args:
readfile:

string filename of input gds

cellname:

string name of cell

layerspol1:

numpy array with all layer that will be substracted

datatypes1:

numpy array with all datatypes that will be subtracted

layerspol2:

numpy array with all layer where we will subtract

datatypes2:

numpy array with all datatypes where we will substract

outfile:

string filename of output gds

pyMOE.gds_klops.gds_to_dxf(inputfilename_gds, outputfilename_dxf)

(void) writes to file (it is named to be dxf… other extensions also work)

pyMOE.gds_klops.import_gds(fstgds_filename, fst_cellname, fst_layer_nr, fst_datatype_nr, sndgds_filename, snd_cellname, snd_layer_nr, snd_datatype_nr, output_filename, clear_gds=True)

(void) Imports shapes from fst gds file INTO snd gds file

Args:
Ngds_filename:

string filename of N(=fst,snd) gds

N_cellname:

string name of cell in N(=fst,snd) gds

N_layer_nr:

int layer number in N(=fst,snd) gds

N_datatype_nr:

int datatype number in N(=fst,snd) gds

output_filename:

string filename of output gds

clear_gds:

clear gds, before inserting shapes, defaults to True

pyMOE.gds_klops.inspect_gds2layers_gdstk(filename)

Get all layer polygons from gds filename =’filename’

Returns:

[0] gstk lib object with all information of cell, layers and shapes [1] pol_dict, dictionary of gdstk Polygons {(layer_nr, datatype_nr): [Polygon1, Polygon2,…]} [2] nmpy array with (layer_nr, datatype_nr) [3] list with (layer_nr, datatype_nr)

pyMOE.gds_klops.instance_array(cell_name, input_filename, transx, transy, nr_inst_X, nr_inst_Y, pitx, pity, output_filename)

(void) Makes array of existing object(s) in the gds

Args:
cell_name:

string name of cell

input_filename:

string name of the input gds

transx:

translation vector in x in um

transy:

translation vector in y in um

nr_inst_X:

int number of repeated objects in x

nr_inst_Y:

int number of repeated objects in y

pitx:

int pitch in x in um

pity:

int pitch in y in um

output_filename:

string filename of output gds

pyMOE.gds_klops.merge_layer(readfile, cellname, layer_nr, datatype_nr, outputfile)

(void) Merges all shapes within gds (only tested gds with single layer)

Args:
readfile:

string filename of input gds

cellname:

string name of cell

layer_nr:

int layer number

datatype_nr:

int datatype number

outputfile:

string filename of output gds

pyMOE.gds_klops.rescale_layout(readfile, cellname, factor, outfile, divfactor=1, newcellname=None, verbose=True)

(void) Rescales the layout

Args:
readfile:

string filename of input gds

cellname:

string name of cell in the readfile

factor:

int with scaling factor multiply

outfile:

string filename of output gds

divfactor:

int with scaling factor division, defaults to 1

newcellname:

string name of the cell in the outfile, defaults to cellname

pyMOE.gds_klops.reset_datatypes(fstgds_filename, fst_cellname, fst_layer_nr, fst_datatype_nr, snd_layer_nr, snd_datatype_nr, output_filename)

(void) resets datatypes

Args:
Ngds_filename:

string filename of N(=fst,snd) gds

N_cellname:

string name of cell in N(=fst,snd) gds

N_layer_nr:

int layer number in N(=fst,snd) gds

N_datatype_nr:

int datatype number in N(=fst,snd) gds

output_filename:

string filename of output gds

pyMOE.gds_klops.rotate_layout(readfile, cellname, angle, outputfile, transx=0, transy=0)

rotate layout by angle, inspired in https://www.klayout.de/forum/discussion/2143/import-a-gds-then-make-into-a-cell-to-rotate

translation with vector (transx, transy), default = (0,0)

pyMOE.gdsconverter module

gdsconverter.py GDS converter module

class pyMOE.gdsconverter.GDSMask(mask, units=1e-06, precision=1e-09, verbose=True)

Bases: object

Class GDSMask:

Creates a class to integrate the GDS library and layout corresponding to a mask aperture. Receives an aperture and provides methods to calculate the corresponding GDS layout

Args:
mask:

aperture object

Methods:
levels:

number of unique discretized levels in mask

layers:

list of layers in layout

cells:

list of cells in layout

total_polygons:

total number of polygons in layout in all layers

total_vertices:

total number of vertices in all polygons in all layers

create_layout():

Creates layout (raster or vector or edges etc todo)

merge(layer):

merges polygons in layer

plot():

plots mask

viewer():

Opens LayoutViewer of gdspy

save_gds(filename):

saves layout to gds file

property aperture
create_layout(mode='raster', cellname='TOP', merge=False, break_vertices=250, **kwargs)

Creates GDS layout of the discretized aperture

Args:
mode:

default Raster. (can also accept contour)

cellname:

name of the topcell to include all the merged polygons

merge:

default False. If True, will merge the individual pixel polygons

break_vertices:

threshold value to speed up the merging of polygons

Returns:

# :gdslib: l ibrary with topcell will update the class internal gdslib

property levels
property total_polygons
property total_vertices
view_layout()

Runs gdspy.LayoutViewer

write_gds(filename, mode='raster', cells=None, timestamp=None, binary_cells=None)

Writes layout to gds file using gdspy library

DEPRECATED

write_layout(filename)

Writes layout togds file using klayout pya library

class pyMOE.gdsconverter.GrayscaleCalibration(mask_height_scale=1e-06, verbose=True)

Bases: object

Class GrayscaleCalibration:

Creates a class to integrate the GDS library and layout corresponding to a mask aperture. Receives an aperture and provides methods to calculate the corresponding GDS layout

Args:
mask:

aperture object

add_corners(field_width=10000, field_height=10000, corner_length=500, corner_width=100, layer='layer127')

Adds corners around the mask

add_label(label, position=(-4000, -4000), rotate=True, mag=100, layer='layer127')

Adds text label to the mask file

adjust_grayvalues(height_offset=None)

Adjusts the grayvalues of the mask to the calibration values

calibrate_layer_names(force_naming=False, datatype=0)

Changes the layer names to the calibrated grayvalues

get_levels_from_height_range(mask_height_range, endpoint=True)

Extracts the levels from the given height range and number of layers on the mask

get_levels_from_layer_names()

Extracts the levels from the layer names in the mask Assumes that the layer name is “LevelDDD_xxx” where xxx is the height in um

load_calibration(filename)

Loads the calibration file from a csv file with two columns, the first column with the grayscale value and the second column with the height value

Args:
filename:

string with the path to the calibration file

load_gdsfile(gdsfile)

Loads the mask file

Args:
gdsfile:

string with the path to the gds file

plot_calibration()
save_calibrated_gdsfile(filename, force_save=False)
pyMOE.gdsconverter.cell_wpol_gdspy(cs, cellname, prec=1e-06, mpoints=1000000000.0)

###Initially coming from gds_klops ###TODO: migrate functions from the gds_klops (implemented with various libraries) to gdsp y

Cell made with cut polygons from the z profile

Args:
cs:

contours FROM matplotlif contourf function

cellname:

string cellname, e.g. ‘TOP’

Returns:
[0]:

gdspy library,

[1]:

cell with polygons

##By default the levels start at 0 and go to the number of levels in the contourplot

pyMOE.gdsconverter.count_vertices(pols)

Counts vertices of polygons

Args:
pols:

polygon or polygon set

Returns:

number of vertices

pyMOE.gdsconverter.create_corners_cell(layout, field_width, field_height, corner_length, corner_width, layer='layer127')
pyMOE.gdsconverter.create_label_cell(layout, text, position=(0, 0), rotate=True, mag=1000, layer='layer127')
pyMOE.gdsconverter.create_poly_dicing_corner(length, width)
pyMOE.gdsconverter.find_closest_indices(x, y)
pyMOE.gdsconverter.levels2grayvalue(levels, calibration_height, calibration_grayvalue)
pyMOE.gdsconverter.load_grayscale_contrast(filename)
pyMOE.gdsconverter.merge_polygons(polygons, layer=0, assume_non_overlap=True, break_vertices=250, verbose=True)

Merge polygons function receives a list of polygons or polygon set and will iteratively merge consecutive polygons, assuming to be in the same layer. If we assume that polygons are sequentially located in the matrix, then it is expected that consecutive polygons can be merged, while polygons far apart are probably not in the same cluster.

The boolean operation compares the new polygon with the existing operand, and it becomes slower with more polyons/vertices already included in the merged set. To optimize this, we consider a break_vertices threshold where the merged set of polygons is broken into a separate list to continue the merging. This will result in a merged set that could be smaller, but is much faster to execute, scaling with N instead of N^2.

Args:
polygons:

must be a list of polygons, polygonset, rectangles etc that the boolean operation accepts

layer:

default 0 and ignored. The merged list of merged polygons will have the same layer as the input polygons (assumed the same for all)

assume_non_overlap:

default True, if True the function will break the merged list of polygons when reaching break_vertices

break_vertices:

approximate number of vertices to consider in the boolean operation before breaking the list.

verbose:

default True. Prints the progress bar.

Returns:

list of merged polygons or polygonsets.

pyMOE.generate module

generate.py

Module containing several functions to construct arbitrary aperture masks

pyMOE.generate.aperture_add(aperture1, aperture2)

Adds two apertures

pyMOE.generate.aperture_multiply(aperture1, aperture2)

Multiply two apertures

pyMOE.generate.aperture_operation(aperture1, aperture2, operand)

Executes the operation on the apertures 1 and 2. Both apertures must have the same spatial distribution and shape.

Args:
aperture1:

First Aperture

aperture2:

Second Aperture

operand:

numpy operand function to consider

Returns:
aperture:

Aperture with result of operation

pyMOE.generate.aperture_rotate(aperture_in, angle, pivot=None, background=0)

Rotates image around the pivot point, using the scipy ndimage (default applies spline interpolation + rotation of 2D array) https://docs.scipy.org/doc/scipy/reference/generated/scipy.ndimage.rotate.html

Args:
aperture_in:

input aperture object

angle:

rotation angle in degrees

pivot:

coordinates of pivot point (center of rotation) in the img 2D array, defaults to center of aperture

background:

background value where rotation is done, by default 0

Returns:

Rotated 2D array, with padding

pyMOE.generate.aperture_subtract(aperture1, aperture2)

Subtracts two apertures

pyMOE.generate.arbitrary_aperture_function(aperture, function, center=(0, 0), **function_args)

Updates aperture and returns phase mask calculated based on function

Args:
aperture:

mask of type Aperture

function:

function to calculate the phase on

**function_args:

additional arguments to pass onto the function

Returns:
aperture:

aperture with fresnel phase

pyMOE.generate.boundary_from_function()
pyMOE.generate.circular_aperture(aperture, radius, center=(0, 0))

Updates aperture and returns 2D circular aperture mask

Args:
aperture:

mask of type Aperture

radius:

radius of the circle aperture

center:

default (x0=0, y0=0) center of circle

Returns:
aperture:

aperture with circular amplitude

pyMOE.generate.clip_aperture(aperture_in, new_dx0_1, new_dx0_2, new_dy0_1, new_dy0_2)

Clips the aperture between [new_dx0_1, new_dx0_2] and [new_dy0_1, new_dy0_2] limits

Args:
aperture_in:

input aperture object

new_dx0_1, new_dx0_2:

limits in x

new_dy0_1, new_dy0_2:

limits in y

Returns:

Clipped aperture with limits [new_dx0_1, new_dx0_2] and [new_dy0_1, new_dy0_2]

pyMOE.generate.clip_aperture_within(aperture_in, new_dx0_1, new_dx0_2, new_dy0_1, new_dy0_2)

Clips the aperture by a rectangular aperture

Args:
aperture_in:

input aperture object

new_dx0_1, new_dx0_2:

limits in x

new_dy0_1, new_dy0_2:

limits in y

Returns:

Clipped aperture_in

pyMOE.generate.create_aperture_from_array(array, pixel_size, center=False)

Creates an aperture from the given array, where each pixel is of pixel_size

Args:
array:

2D numpy array of a mask

pixel_size:

absolute value for each pixel, as a tuple (x,y)

center:

if True, will center the image at the origin

Returns:
aperture:

aperture with the mask inserted

pyMOE.generate.create_empty_aperture(xmin, xmax, N_x, ymin, ymax, N_y)

Creates an empty aperture max of the mesh dimensions provided

Args:
xmin, xmax:

range for x

N_x:

number of x points

ymin, ymax:

range for y

N_y:

number of y points

Returns:
mask:

empty Aperture

pyMOE.generate.create_empty_aperture_from_aperture(aperture)

Creates an empty aperture with the same spatial dimensions of the given aperture

Args:
aperture:

aperture

Returns:
aperture:

empty Aperture of same spatial dimensions

pyMOE.generate.fresnel_phase(aperture, focal_length, wavelength, radius=None, center=(0, 0))

Updates aperture and returns Fresnel phase mask

Args:
aperture:

mask of type Aperture

focal_length:

design focal length

wavelength:

design wavelength

radius:

if defined, truncates the fresnel phase to inside this radius

Returns:
aperture:

aperture with fresnel phase

pyMOE.generate.fresnel_zone_plate_aperture(aperture, focal_length, wavelength, radius=None, center=(0, 0))

Updates aperture and returns Fresnel zone plate aperture

Args:
aperture:

mask of type Aperture

focal_length:

design focal length

wavelength:

design wavelength

radius:

if defined, truncates the fresnel phase to inside this radius

Returns:
aperture:

aperture with fresnel zone plate

pyMOE.generate.makegrid(N_pixels, xsize, ysize)

Creates a square meshgrid of N_pixels by N_pixels in with arrays till xsize and ysize

Args:
N_pixels:

nr of pixels , by default the results 2D array is N_pixels by N_pixels

xsize:

size in x

ysize:

size in y

Returns:

Meshgrid (XX, YY)

pyMOE.generate.rectangular_aperture(aperture, width, height, corner=None, center=None)

Updates aperture and returns 2D rectangular aperture mask

Args:
aperture:

aperture of type Aperture

width, height:

width and height of the rectangle

corner:

if given, sets the lower left corner of the rectangle

center:

if given, sets the center of the rectangle

Returns:
aperture:

aperture with rectangular amplitude

pyMOE.generate.resize_linear(image_matrix, new_height: int, new_width: int)

Perform a pure-numpy linear-resampled resize of an image. https://stackoverflow.com/questions/48121916/numpy-resize-rescale-image

Args:
image_matrix:

input 2D array (image)

new_height:

integer, height of the image

new_width:

integer, width of the image

Returns:
output_image:

resized 2D array (image)

pyMOE.generate.truncate_aperture_radius(aperture, radius, center=(0, 0), truncate_value=0)

Truncates the aperture to inside the circle of radius at center

Args:
aperture:

mask to be truncated

radius:

radius to select the region

center:

center points tuple of the circle

truncate_value:

value to truncate the mask, by default 0

Returns:

aperture

pyMOE.holograms module

holograms.py Library module for hologram generation and visualiation

class pyMOE.holograms.Field(a, b)

Bases: object

Class to define complex fields with methods for amplitude and phase

property amplitude
property intensity
property phase
pyMOE.holograms.algorithm_Gerchberg_Saxton(target_intensity, iterations=3, levels=None, input_phase=None, source_beam=None, verbose=True)

Creates hologram phase mask to generate target intensity using Gerchberg Saxton Algorithm.

U0 - input field U1 - calculated far-field

Args:
target_intensity:

2D array of intensity values

levels:

Scalar or array: levels to consider in the phase mask as physical constraint. If None, it does not discretize.

input_phase:

If given, uses this input_phase as starting phase instead of random.

Returns:
phase_mask:

2D phase mask

error_list:

list of errors measured in each iteration

pyMOE.holograms.calculate_phase_farfield(phase, source_beam=None)

Calculates a proportional far field of a given phase aperture and source_beam

TODO Fraunhofer propagation

Args:
phase:

phase mask

source_beam:

if not given, assumes constant intensity=1

Returns
far_field:

far field amplitude

pyMOE.holograms.correct_mask_shift(mask)

pyMOE.importing module

importing.py Module containing functions to import gds files, inspect them in matplotlib and save gds files as image files

pyMOE.importing.gds2img(infile, outfile, norm, rescaled=0, verbose=False)

(void) plots the gds for inspection in python matplotlib and saves the figure to image file Note: if plotting different gds file together, please make sure they are aligned (e.g. centered at origin)

Args:
infile:

string gds filename (e.g. ‘yolo.gds’)

outfile:

string img filename (e.g. ‘yolo.tiff’)

norm:

maximum level of gray (e.g. 128)

rescaled:

if !=0 will rescale the layout

verb:

if True, shows verbose, defaults to False

pyMOE.importing.gds2imgtiff(infile, outfile, norm, rescaled=0, verbose=False, pixels_per_unit=1)

Converts GDS to 16-bit TIFF image preserving full gray-level resolution.

pyMOE.importing.inspect_gds2(filename, colors, rescale=0, **kwargs)

Plots the gds for inspection in python matplotlib, only with the borders of the features Note: if plotting different gds file together, please make sure they are aligned (e.g. centered at origin)

Args:
filename:

string gds filename (e.g. ‘yolo.gds’)

color:

string color name for plotting

rescale:

int rescaling factor for all points in mask, by default is 0

pyMOE.importing.inspect_gds2layers(filename, norm, rescale=0, verbose=False, **kwargs)

Returns cell, polygon dictionary, (xmin,xmax) and (ymin,ymax) for representation of the gds layers into a grayscale image

Args:
filename:

string gds filename (e.g. ‘yolo.gds’)

norm:

maximum level of gray (e.g. 128)

verbose:

if True show some information while doing the operations. defaults false

for **kwargs, add ‘axes = subplot’, where subplot has been previously defined as subplot = fig.add_subplot(111) with ‘import matplotlib.pyplot as plt’ and ‘fig = plt.figure()’

pyMOE.importing.inspect_gds2layersplt(filename, norm, rescale=0, verbose=False, **kwargs)

Returns cell, polygon dictionary, (xmin,xmax) and (ymin,ymax) for representation of ALL gds layers into a grayscale image

Args:
filename:

string gds filename (e.g. ‘yolo.gds’)

norm:

maximum level of gray (e.g. 128)

verbose:

if True show some information while doing the operations. defaults false

for **kwargs, add ‘axes = subplot’, where subplot has been previously defined as subplot = fig.add_subplot(111) with ‘import matplotlib.pyplot as plt’ and ‘fig = plt.figure()’

pyMOE.importing.makesubplot(x, y, *argv, **kwargs)

Makes a subplot object for plotting

pyMOE.metas module

metas.py Module containing functions to create metasurfaces from phase masks

pyMOE.metas.metasurface_from_phase(xsiz, ysiz, pixelx, pixely, p, aperture_vals, topcellname, outfilen, gdspyelements='pillar', verbose=False, rotation=None, scaling=None, grid='square', mindim=0.05, smallerdim=0, largest_phase=None)

Transform a 2D array (aperture_vals) representing the phase into a 2D metasurface and saves it to gds

Args:
xsiz:

x size of aperture in x in um

ysiz:

y size of aperture size in y in um

pixelx:

pixel size in x in um

pixely:

pixel size in y in um

p:

periodicity in um

aperture_vals:

2D array with the phase

topcellname:

string with name of top cell, e.g. ‘TOP’

oufilen:

string filename of output gds

gdspyelements:

gdspy element to be used as individual meta-element (also accepts array of such elements for iteration, with same dimension as unique values in aperture_vals). If == ‘pillar’ (default) -> gdspy circle with 1 um diameter

verbose:

if True, prints during execution

rotation:

array with the rotation angles of unique meta-elements (1:1 correspondence with unique aperture_vals values!), Rotation angle is anti-clockwise in radians. If None (default), sets the rotation angle = 0 for all elements.

scaling:

array with the scaling factor of unique meta-element (1:1 correspondence with unique aperture_vals values!), Scaling factor is with respect to the dimension of the individual meta-element. If None (default), sets scaling factor to 1.0 for all elements.

grid:

Type of grid, options are ‘square’ or ‘hex’. Default is ‘square’. Please make sure the aperture_vals have been evaluated in an hexagonal grid, to make sure the values match.

mindim:

clipping scaling factor (cannot scale below a certain value, to avoid very small elements)

smallerdim:

lowest scaling factor

largest_phase:

largest phase in the phase mask. If None, takes the maximum of aperture_vals

Returns:

None

pyMOE.metas.metasurface_from_phase_instances(xsiz, ysiz, pixelx, pixely, p, aperture_vals, topcellname, outfilen, gdspyelements='pillar', infile=None, verbose=False, rotation=None, scaling=None, grid='square', mindim=0.05, smallerdim=0, tempfile='temp.gds', largest_phase=None)

Transform a 2D array (aperture_vals) representing the phase into a 2D metasurface using instances (from pya) package and saves it to gds

Args:
xsiz:

x size of aperture in x in um

ysiz:

y size of aperture size in y in um

pixelx:

pixel size in x in um

pixely:

pixel size in y in um

p:

periodicity in um

aperture_vals:

2D array with the phase

topcellname:

string with name of top cell, e.g. ‘TOP’

oufilen:

string filename of output gds

gdspyelements:

gdspy element to be used as individual meta-element (also accepts array of such elements for iteration, with same dimension as unique values in aperture_vals). If == ‘pillar’ (default) -> gdspy circle with 1 um diameter. If ‘infile’ is provided, ignores this design.

infile:

string with filename to be used as meta-element

verbose:

if True, prints during execution

rotation:

array with the rotation angles of unique meta-elements (1:1 correspondence with unique aperture_vals values!), Rotation angle is anti-clockwise in radians. If None (default), sets the rotation angle = 0 for all elements.

scaling:

array with the scaling factor of unique meta-element (1:1 correspondence with unique aperture_vals values!), Scaling factor is with respect to the dimension of the individual meta-element. If None (default), sets scaling factor to 1.0 for all elements.

grid:

Type of grid, options are ‘square’ or ‘hex’. Default is ‘square’. Please make sure the aperture_vals have been evaluated in an hexagonal grid, to make sure the values match.

mindim:

clipping scaling factor (cannot scale below a certain value, to avoid very small elements)

smallerdim:

lowest scaling factor

tempfile:

string with name of a temporary file that will be used to have the individual elements and make the instances

largest_phase:

largest phase in the phase mask. If None, takes the maximum of aperture_vals

Returns:

None

pyMOE.metrics module

metas.py Module containing functions to create metasurfaces from phase masks

pyMOE.metas.metasurface_from_phase(xsiz, ysiz, pixelx, pixely, p, aperture_vals, topcellname, outfilen, gdspyelements='pillar', verbose=False, rotation=None, scaling=None, grid='square', mindim=0.05, smallerdim=0, largest_phase=None)

Transform a 2D array (aperture_vals) representing the phase into a 2D metasurface and saves it to gds

Args:
xsiz:

x size of aperture in x in um

ysiz:

y size of aperture size in y in um

pixelx:

pixel size in x in um

pixely:

pixel size in y in um

p:

periodicity in um

aperture_vals:

2D array with the phase

topcellname:

string with name of top cell, e.g. ‘TOP’

oufilen:

string filename of output gds

gdspyelements:

gdspy element to be used as individual meta-element (also accepts array of such elements for iteration, with same dimension as unique values in aperture_vals). If == ‘pillar’ (default) -> gdspy circle with 1 um diameter

verbose:

if True, prints during execution

rotation:

array with the rotation angles of unique meta-elements (1:1 correspondence with unique aperture_vals values!), Rotation angle is anti-clockwise in radians. If None (default), sets the rotation angle = 0 for all elements.

scaling:

array with the scaling factor of unique meta-element (1:1 correspondence with unique aperture_vals values!), Scaling factor is with respect to the dimension of the individual meta-element. If None (default), sets scaling factor to 1.0 for all elements.

grid:

Type of grid, options are ‘square’ or ‘hex’. Default is ‘square’. Please make sure the aperture_vals have been evaluated in an hexagonal grid, to make sure the values match.

mindim:

clipping scaling factor (cannot scale below a certain value, to avoid very small elements)

smallerdim:

lowest scaling factor

largest_phase:

largest phase in the phase mask. If None, takes the maximum of aperture_vals

Returns:

None

pyMOE.metas.metasurface_from_phase_instances(xsiz, ysiz, pixelx, pixely, p, aperture_vals, topcellname, outfilen, gdspyelements='pillar', infile=None, verbose=False, rotation=None, scaling=None, grid='square', mindim=0.05, smallerdim=0, tempfile='temp.gds', largest_phase=None)

Transform a 2D array (aperture_vals) representing the phase into a 2D metasurface using instances (from pya) package and saves it to gds

Args:
xsiz:

x size of aperture in x in um

ysiz:

y size of aperture size in y in um

pixelx:

pixel size in x in um

pixely:

pixel size in y in um

p:

periodicity in um

aperture_vals:

2D array with the phase

topcellname:

string with name of top cell, e.g. ‘TOP’

oufilen:

string filename of output gds

gdspyelements:

gdspy element to be used as individual meta-element (also accepts array of such elements for iteration, with same dimension as unique values in aperture_vals). If == ‘pillar’ (default) -> gdspy circle with 1 um diameter. If ‘infile’ is provided, ignores this design.

infile:

string with filename to be used as meta-element

verbose:

if True, prints during execution

rotation:

array with the rotation angles of unique meta-elements (1:1 correspondence with unique aperture_vals values!), Rotation angle is anti-clockwise in radians. If None (default), sets the rotation angle = 0 for all elements.

scaling:

array with the scaling factor of unique meta-element (1:1 correspondence with unique aperture_vals values!), Scaling factor is with respect to the dimension of the individual meta-element. If None (default), sets scaling factor to 1.0 for all elements.

grid:

Type of grid, options are ‘square’ or ‘hex’. Default is ‘square’. Please make sure the aperture_vals have been evaluated in an hexagonal grid, to make sure the values match.

mindim:

clipping scaling factor (cannot scale below a certain value, to avoid very small elements)

smallerdim:

lowest scaling factor

tempfile:

string with name of a temporary file that will be used to have the individual elements and make the instances

largest_phase:

largest phase in the phase mask. If None, takes the maximum of aperture_vals

Returns:

None

pyMOE.optimizer module

metas.py Module containing functions to create metasurfaces from phase masks

pyMOE.metas.metasurface_from_phase(xsiz, ysiz, pixelx, pixely, p, aperture_vals, topcellname, outfilen, gdspyelements='pillar', verbose=False, rotation=None, scaling=None, grid='square', mindim=0.05, smallerdim=0, largest_phase=None)

Transform a 2D array (aperture_vals) representing the phase into a 2D metasurface and saves it to gds

Args:
xsiz:

x size of aperture in x in um

ysiz:

y size of aperture size in y in um

pixelx:

pixel size in x in um

pixely:

pixel size in y in um

p:

periodicity in um

aperture_vals:

2D array with the phase

topcellname:

string with name of top cell, e.g. ‘TOP’

oufilen:

string filename of output gds

gdspyelements:

gdspy element to be used as individual meta-element (also accepts array of such elements for iteration, with same dimension as unique values in aperture_vals). If == ‘pillar’ (default) -> gdspy circle with 1 um diameter

verbose:

if True, prints during execution

rotation:

array with the rotation angles of unique meta-elements (1:1 correspondence with unique aperture_vals values!), Rotation angle is anti-clockwise in radians. If None (default), sets the rotation angle = 0 for all elements.

scaling:

array with the scaling factor of unique meta-element (1:1 correspondence with unique aperture_vals values!), Scaling factor is with respect to the dimension of the individual meta-element. If None (default), sets scaling factor to 1.0 for all elements.

grid:

Type of grid, options are ‘square’ or ‘hex’. Default is ‘square’. Please make sure the aperture_vals have been evaluated in an hexagonal grid, to make sure the values match.

mindim:

clipping scaling factor (cannot scale below a certain value, to avoid very small elements)

smallerdim:

lowest scaling factor

largest_phase:

largest phase in the phase mask. If None, takes the maximum of aperture_vals

Returns:

None

pyMOE.metas.metasurface_from_phase_instances(xsiz, ysiz, pixelx, pixely, p, aperture_vals, topcellname, outfilen, gdspyelements='pillar', infile=None, verbose=False, rotation=None, scaling=None, grid='square', mindim=0.05, smallerdim=0, tempfile='temp.gds', largest_phase=None)

Transform a 2D array (aperture_vals) representing the phase into a 2D metasurface using instances (from pya) package and saves it to gds

Args:
xsiz:

x size of aperture in x in um

ysiz:

y size of aperture size in y in um

pixelx:

pixel size in x in um

pixely:

pixel size in y in um

p:

periodicity in um

aperture_vals:

2D array with the phase

topcellname:

string with name of top cell, e.g. ‘TOP’

oufilen:

string filename of output gds

gdspyelements:

gdspy element to be used as individual meta-element (also accepts array of such elements for iteration, with same dimension as unique values in aperture_vals). If == ‘pillar’ (default) -> gdspy circle with 1 um diameter. If ‘infile’ is provided, ignores this design.

infile:

string with filename to be used as meta-element

verbose:

if True, prints during execution

rotation:

array with the rotation angles of unique meta-elements (1:1 correspondence with unique aperture_vals values!), Rotation angle is anti-clockwise in radians. If None (default), sets the rotation angle = 0 for all elements.

scaling:

array with the scaling factor of unique meta-element (1:1 correspondence with unique aperture_vals values!), Scaling factor is with respect to the dimension of the individual meta-element. If None (default), sets scaling factor to 1.0 for all elements.

grid:

Type of grid, options are ‘square’ or ‘hex’. Default is ‘square’. Please make sure the aperture_vals have been evaluated in an hexagonal grid, to make sure the values match.

mindim:

clipping scaling factor (cannot scale below a certain value, to avoid very small elements)

smallerdim:

lowest scaling factor

tempfile:

string with name of a temporary file that will be used to have the individual elements and make the instances

largest_phase:

largest phase in the phase mask. If None, takes the maximum of aperture_vals

Returns:

None

pyMOE.plotting module

plotting.py Module for plotting apertures ans save them as image files

pyMOE.plotting.plot_aperture(aperture, scale=None, colorbar=True, only_plot=False, filename=None, **kwargs)

Plots the given aperture

Args:
aperture:

Aperture object of the mask

colorbar:

True/False flag to plot colorbars

only_plot:

if True, only shows image without labels and axes

filename:

if provided, saves figure to filename

###available output file extensions are same as opencv https://docs.opencv.org/3.4/d4/da8/group__imgcodecs.html

pyMOE.plotting.plot_field(field, which='both', scale=None, colorbar=True, only_plot=False, filename=None, **kwargs)

Plots the given field

Args:
field:

Field object of the mask

which:

default “both”, “amplitude” or “phase”

colorbar:

True/False flag to plot colorbars

only_plot:

if True, only shows image without labels and axes

filename:

if provided, saves figure to filename

###available output file extensions are same as opencv https://docs.opencv.org/3.4/d4/da8/group__imgcodecs.html

pyMOE.plotting.plot_field_legacy(aperture, which='both', scale=None, colorbar=True, only_plot=False, filename=None, **kwargs)

Plots the given aperture

Args:
aperture:

Aperture object of the mask

which:

default “both”, “amplitude” or “phase”

colorbar:

True/False flag to plot colorbars

only_plot:

if True, only shows image without labels and axes

filename:

if provided, saves figure to filename

###available output file extensions are same as opencv https://docs.opencv.org/3.4/d4/da8/group__imgcodecs.html

pyMOE.plotting.plot_screen_XY(screen, z=0, which='both', scale=None, colorbar=True, only_plot=False, filename=None, **kwargs)

Plots the given screen

Args:
screen:

Screen object of the mask

z:

z position to plot the XY slice (default 0)

which:

default “both”, “amplitude” or “phase”

colorbar:

True/False flag to plot colorbars

only_plot:

if True, only shows image without labels and axes

filename:

if provided, saves figure to filename

###available output file extensions are same as opencv https://docs.opencv.org/3.4/d4/da8/group__imgcodecs.html

pyMOE.plotting.plot_screen_XZ(screen, y=0, which='both', scale=None, colorbar=True, only_plot=False, filename=None, **kwargs)

Plots the given screen XZ slice at given y position (finds nearest y index)

Args:
screen:

Screen object of the mask

y:

y position to plot the XZ slice

which:

default “both”, “amplitude” or “phase”

colorbar:

True/False flag to plot colorbars

only_plot:

if True, only shows image without labels and axes

filename:

if provided, saves figure to filename

###available output file extensions are same as opencv https://docs.opencv.org/3.4/d4/da8/group__imgcodecs.html

pyMOE.plotting.plot_screen_YZ(screen, x=0, which='both', scale=None, colorbar=True, only_plot=False, filename=None, **kwargs)

Plots the given screen YZ slice at given x position (finds nearest x index)

Args:
screen:

Screen object of the mask

x:

x position to plot the YZ slice

which:

default “both”, “amplitude” or “phase”

colorbar:

True/False flag to plot colorbars

only_plot:

if True, only shows image without labels and axes

filename:

if provided, saves figure to filename

###available output file extensions are same as opencv https://docs.opencv.org/3.4/d4/da8/group__imgcodecs.html

pyMOE.plotting.plot_screen_ZZ(screen, x=0, y=0, which='both', scale=None, only_plot=False, filename=None, **kwargs)

Plots the given screen

Args:
screen:

Screen object of the mask

x:

x position to plot the ZZ slice

y:

y position to plot the ZZ slice

which:

default “both”, “amplitude” or “phase”

colorbar:

True/False flag to plot colorbars

only_plot:

if True, only shows image without labels and axes

filename:

if provided, saves figure to filename

###available output file extensions are same as opencv https://docs.opencv.org/3.4/d4/da8/group__imgcodecs.html

pyMOE.plotting.save_mask_plot(maskcir, xsize, ysize, filename)

pyMOE.propagate module

propagate.py

This module had origin in the “propopt” repository module with same name -> For more information, examples of use and validation tests,

please see link for repository : https://github.com/cunhaJ/propopt

Here, “propopt” code has been modified and extended for use with apertures and masks of “pyMOE”

pyMOE.propagate.ASM(field, screen, wavelength, pad, n=1.0, mode=None, bl=False, shift=None, kykx=(0.0, 0.0))

Implements the Angular Spectrum Method (ASM), with czt and bandlimit options.

Args:
field:

Input Field

screen:

Observation Screen

wavelength:

Wavelength

pad:

Padding around area of interest (assumed constant =0 all around), in nr. of pixels

n:

refractive index of the propagation medium (default=1 for vacuum/air)

mode:

ASM mode, options: None (default) = convetional ASM; “czt” = Chirp Z-Transform; “BLAS” = Band-Limited ASM

bl:

Boolean, default False, if True enforces band limit filters akin Matushima & Shimobaba

shift:

tuple (shift_y, shift_x) with shift at the output screen plane, default None = calculates the shift from screen limits. If mode=”czt” shift is not used.

kykx:

tuple (ky,kx) angular input direction, default = (0.,0.)

Returns:
screen:

Returns the screen populated with the result

pyMOE.propagate.ASM_kernel(field, z, wavelength, input_extent, input_df, n=1.0, bandlimit=False, shift_yx=(0.0, 0.0), kykx=(0.0, 0.0))

Compute the ASM propagation kernel H(kx, ky)

Args:
field:

Input Field

z:

Distance to Screen plane

wavelength:

Wavelength

input_extent:

Spatial extent of the input field (might be already padded)

n:

Refractive index of the propagation medium (default=1 for vacuum/air)

bandlimit:

Boolean, default False, if True enforces band limit filters akin Matushima & Shimobaba

shift_yx:

tuple (shift_y, shift_x) with shift at the output screen plane, default (0.,0.)

kykx:

tuple (ky,kx) angular input direction, default = (0.,0.)

Returns:
H field kernel:

Returns the kernel

pyMOE.propagate.ASM_propagate(field, screen, z, wavelength, pad_width, n=1.0, mode=None, bl=True, shift=None, kykx=(0.0, 0.0))

Angular Spectrum Method (ASM) propagation computation.

Args:
field:

Input Field

screen:

Observation Screen

z:

Distance to Screen plane

wavelength:

Wavelength

pad_width:

Padding around area of interest (assumed constant =0 all around), in nr. of pixels

n:

refractive index of the propagation medium (default=1 for vacuum/air)

mode:

ASM mode, options: None (default) = convetional ASM; “czt” = Chirp Z-Transform; “BLAS” = Band-Limited ASM

bl:

Boolean, default False, if True enforces band limit filters akin Matushima & Shimobaba

shift:

tuple (shift_y, shift_x) with shift at the output screen plane, default None = calculates the shift from screen limits. If mode=”czt” shift is not used.

kykx:

tuple (ky,kx) angular input direction, default = (0.,0.), required for “off-axis” for non-czt

Returns:
field:

Returns the calculated field

pyMOE.propagate.Bluestein(field, screen, wavelength, n=None)

Implements the Bluestein propagation

Args:

field:

input Field

screen:

Observation Screen

wavelength:

wavelength to consider

n:

refractive index of the propagation medium (default=1 for vacuum/air)

Returns:
screen:

Returns the screen populated with the result

pyMOE.propagate.Fraunhofer_criterion(wavelength, radius)

Calculation of “Fraunhofer distance” , Goodman 4-27

Args:
wavelength:

wavelength of the illumination m

radius:

(max) radius of the aperture in m

Returns:

Fraunhofer distance

pyMOE.propagate.Fresnel_criterion(wavelength, radius)

Calculation of “Fresnel distance” , Goodman

Args:
wavelength:

wavelength of the illumination m

radius:

(max) radius of the aperture in m

Returns:

Fresnel distance

pyMOE.propagate.Fresnel_num(width, wavelength, zdist)

Calculation of Fresnel number, Goodman pag 85

Args:
width:

size of the aperture in m

wavelength:

wavelength of the aperture in m

zdist:

distance to the screen in m

Returns:

Fresnel number

pyMOE.propagate.RS_intXY(zs, mask, npixmask, pixsizemask, npixscreen, dxscreen, dyscreen, wavelength, verbose=False)

Calculates the RS int of the first kind returns Escreen (complex electric field at obs screen), Iscreen (intensity at obs screen), iplot (the actual intensity)

Args:
zs:

distance to screen [m]

mask:

Electric field at the mask, complex valued 2D function

npixmask:

number of pixels on the side of the mask

pixsizemask:

size of pixel of the mask [m]

npixscreen:

number of pixels on the side of the screen (observation)

dxscreen:

max_x of the screen [m], the screen range is [-dxscreen, dxscreen]

dyscreen:

max_y of the screen [m], the screen range is [-dyscreen, dyscreen]

wavelength:

wavelength of the light [m]

verbose:

defaults to False, if True prints

pyMOE.propagate.RS_intXY_kernel(dmask, nps, npm, xs, ys, zs, xm, ym, zm, k, E0m, verbose)
pyMOE.propagate.RS_intYZ(zmin, zmax, nzs, yfixed, mask, npixmask, pixsizemask, npixscreen, dxscreen, dyscreen, wavelength, nind, verbose=False)

Calculates the RS_int in the of the first kind, taking information about mask, distance to screen, and screen information returns Escreen (complex electric field at obs screen), Iscreen (intensity at obs screen), iplot (the actual intensity)

Args:

[zmin, zmax]:

distance range limits in z [m]

nzs:

number of points along the optical axis

yfixed:

y fixed coordinates

mask:

Electric field at the mask, complex valued 2D function

npixmask:

number of pixels on the side of the mask

pixsizemask:

size of pixel of the mask [m]

npixscreen:

number of pixels on the side of the screen (observation)

dxscreen:

max_x of the screen [m], the screen range is [-dxscreen, dxscreen]

dyscreen:

max_y of the screen [m], the screen range is [-dyscreen, dyscreen]

nind:

scaling refractive index

wavelength:

wavelength of the light [m]

verbose:

defaults to False, if True prints

pyMOE.propagate.RS_intYZ_kernel(dmask, npm, nzs, npixscreen, xfixed, ys, zarray, xm, ym, zm, k, E0m, verbose)
pyMOE.propagate.RS_intZZ(zmin, zmax, nzs, xfixed, yfixed, mask, npixmask, pixsizemask, npixscreen, dxscreen, dyscreen, wavelength, nind, verbose=False)

Calculates the RS_int in the of the first kind, taking information about mask, distance to screen, and screen information returns Escreen (complex electric field at obs screen), Iscreen (intensity at obs screen), iplot (the actual intensity)

Args:
[zmin, zmax]:

distance range limits in z [m]

nzs:

number of points along the optical axis

xfixed, yfixed:

x and y fixed coordinates

mask:

Electric field at the mask, complex valued 2D function

npixmask:

number of pixels on the side of the mask

pixsizemask:

size of pixel of the mask [m]

npixscreen:

number of pixels on the side of the screen (observation)

dxscreen:

max_x of the screen [m], the screen range is [-dxscreen, dxscreen]

dyscreen:

max_y of the screen [m], the screen range is [-dyscreen, dyscreen]

nind:

scaling refractive index

wavelength:

wavelength of the light [m]

verbose:

defaults to False, if True prints

pyMOE.propagate.RS_intZZ_kernel(dmask, npm, nzs, xs, ys, zs, xm, ym, zm, k, E0m, verbose)
pyMOE.propagate.RS_integral(field, screen, wavelength, n=None, parallel_computing=True, simp2d=False, sampler=None, method=None)

Calculates the Raleyigh Sommerfeld integral in the of the first kind (Mahajan 2011 part II eq 1-20), receiving an input field and an observation screen plane on which to calculate the integral.

Args:

field:

input Field

screen:

Observation Screen

wavelength:

wavelength to consider

n:

refractive index of the propagation medium (default=1 for vacuum/air)

parallel_computing:

Flag to trigger the concurrent computation of the kernels using Python Dask library

simp2d:

Defaults False, if True uses the simpson2d function

Returns:
screen:

Returns the screen populated with the result

pyMOE.propagate.SASM(field, screen, wavelength, pad_factor=2, crop=False)

Implements the Scalable Angular Spectrum Method propagation (Heintzmann et al. )

Args:
field:

input Field

screen:

Observation Screen

wavelength:

wavelength to consider

pad_factor:

zero padding factor all around (integrer multiple of the side pixel size)

crop:

boolean, if True, crops the size to the non zero pixels

Returns:
screen:

Returns the screen populated with the result

pyMOE.propagate.bluestein_czt(x, f1, f2, fs, mout)

Bluestein from Hu et al. 2020 x = field.field * F

TO COMPLETE

pyMOE.propagate.circ_zz24(aperture_rad, zdist, wavelength)

This function is the axial intensity for a circular aperture following 1992 JOSA 9(2) paper “Diffraction by a circular aperture: a generalization of Fresnel diffraction theory” , exp (24)

Args:
aperture_rad:

Radius of the circular aperture in m

zdist:

Distance of propagation

wavelength:

Wavelength of incoming illumination in m

Returns:

Propagated intensity to zdist

pyMOE.propagate.crop_to_physical_size(arr, dx_out, desired_size_meters)

Center crop an array based on physical size and pixel spacing.

pyMOE.propagate.fraunhofer(z, mask, npixmask, pixsizemask, npixscreen, dxscreen, dyscreen, wavelength)

Calculate Fraunhofer approximation, following Goodman exp 4-25

Args:
z:

distance to the observation plane in m

mask:

2D map (x-y plane) npixel vs npixel mask

npixmask:

number of pixels of the mask

pixsizemask:

size of the pixel at the mask in m

npixscreen:

size of the pixel at the screen

dxscreen:

x-size of the screen in m

dyscreen:

y-size of the screen in m

wavelength:

wavelength in m

Returns:

2D map (x-y plane) with abs of Electric field

pyMOE.propagate.fraunhofer_kernel(k, xm, ym, mask, z, wavelength)
pyMOE.propagate.fresnel(z, mask, npixmask, pixsizemask, npixscreen, dxscreen, dyscreen, wavelength)

Calculate Fresnel approximation, following Goodman exp 4-17

Args:
z:

distance to the observation plane in m

mask:

2D map (x-y plane) npixel vs npixel mask

npixmask:

number of pixels of the mask

pixsizemask:

size of the pixel at the mask in m

npixscreen:

size of the pixel at the screen

dxscreen:

x-size of the screen in m

dyscreen:

y-size of the screen in m

wavelength:

wavelength in m

Returns:

2D map (x-y plane) with abs of Electric field at distance z

pyMOE.propagate.fresnel_kernel(k, xm, ym, z, mask)
pyMOE.propagate.propagate_through_ensemble(ensemble, wavelength, xar_plus_z=None, propagation_methods_array=None)

Propagates though Ensemble object (various MOE surfaces)

Args:
ensemble:

Ensemble object

wavelength:

Propagation wavelength

xar_plus_z:

Array with optimization variables (and optionally z position as variable)

propagation_methods_array:

Propagation method

Returns:
overall_field_at_screen:

Returns a screen concatenating both

pyMOE.propagate.resize_field_to_shape(field, output_shape)

Resize a 2D complex array to the desired output shape by resizing real and imaginary parts separately.

pyMOE.propagate.scalable_angular_spectrum_method(field, screen, z, wavelength, pad_factor=2, skip_final_phase=True, crop=False)

kernel based on Heintzmann et al. 2023

pyMOE.propagate.scalar_bluestein(field, screen, d, wavelength)

Scalar diffraction computation using Bluestein’s method.

Args:
field:

input Field

screen:

Observation Screen

d:

Observation distance z of the the Screen position

wavelength:

Wavelength

Returns:
screen:

Returns the screen populated with the result

pyMOE.propagate.zero_pad(arr, pad_factor=2)

pyMOE.sag_functions module

sag_functions.py Module containing several sag or phase functions for various optical elements

pyMOE.sag_functions.Alvarez_phase(XX, YY, f1, f2, tuning_distance, wavelength)

returns the phase of an Alvarez lens profile

Args:
XX:

x array from meshgrid

YY:

y array from meshgrid

f1:

shorter focal distance f1<f2

f2:

longer focal distance f1<f2

tuning_distance:

tuning displacement range for the Alvarez lens

wavelength:

wavelength of design

Note:

pyMOE.sag_functions.alternate_transitions(x, transitions, start_value=1)
pyMOE.sag_functions.alternate_transitions_symmetric(x, transitions, start_value=1)
pyMOE.sag_functions.axicon(x, y, angle)
pyMOE.sag_functions.dammann_2d(XX, YY, transitions_x=None, period_x=1, transitions_y=None, period_y=1, start_value_x=1, start_value_y=1)
pyMOE.sag_functions.dammann_grating_element(x, transitions, start_value=1)
pyMOE.sag_functions.dammann_grating_periodic(x, transitions, period=1, start_value=1)
pyMOE.sag_functions.fresnel_lens_phase(XX, YY, focal_length, wavelength, phase_offset=3.141592653589793)

returns the COMPLEX PHASE of a fresnel lens with input meshgrid (x,y) with center at (x0,y0)

Args:
XX:

x array from meshgrid

YY:

y array from meshgrid

focal_length:

focal distance

wavelength:

wavelength of design

Note: for angle (in rad), call numpy.angle(…)

pyMOE.sag_functions.height2phase(height, wavelength, n1, n0=1)

Converts the height to phase Args:

wavelength:

Wavelength of the light

n1:

Refractive index of the medium where the light is propagating

n0:

Refractive index of the medium background

pyMOE.sag_functions.monkey_saddle(x, y, a, b)

returns a COMPLEX PHASE monkey saddle function

Args:
x:

x array from meshgrid

y:

y array from meshgrid

a:

arbitrary parameter

b:

arbitrary parameter

pyMOE.sag_functions.phase2height(phase, wavelength, n1, n0=1)

Converts the phase to height Args:

wavelength:

Wavelength of the light

n1:

Refractive index of the medium where the light is propagating

n0:

Refractive index of the medium background

pyMOE.sag_functions.polychromatic_fresnel_phase_axisymmetric(XX, YY, focal_length, wavelengths, phase_offset=3.141592653589793, L_repetitions=10, ramp_up_down=True)
pyMOE.sag_functions.saddle(x, y, a, b)

returns a COMPLEX PHASE saddle function

Args:
x:

x array from meshgrid

y:

y array from meshgrid

a:

arbitrary parameter

b:

arbitrary parameter

pyMOE.sag_functions.spiral(x, y, L)

returns a spiral COMPLEX PHASE with input meshgrid (x,y) with center at (x0,y0)

Args:
x:

x array from meshgrid

y:

y array from meshgrid

L:

topological charge

Returns

spiral phase

pyMOE.sag_functions.theta_to_wavelength(theta, wavelengths, L_repetitions=1, ramp_up_down=True)

Converts a theta map to the respetive wavelengths for axisimmetric fresnel phase

pyMOE.utils module

utils.py Module containing utility functions

class pyMOE.utils.Timer(name=None, enabled=True)

Bases: object

Timer helper class to calculated elapsed time of chunk of code, from https://stackoverflow.com/a/5849861/7996766

pyMOE.utils.create_levels(start, end, levels)

Creates linear levels list with N

pyMOE.utils.digitize_array_to_bins(array, levels)

Digitizes the given array to within the number of levels provided

Args:
array:

input array of values

levels:

integer number of levels to consider or array of levels

Returns:
bins:

bins corresponding to the levels

digitized:

digitized array

To do:

Consider the midpoint selection in the future

pyMOE.utils.discretize_array(array, levels)
pyMOE.utils.find_closest_indices(x, y)
pyMOE.utils.mean_squared_error(new, original)

Calculates mean squared error between the new array and the original

pyMOE.utils.progress_bar(progress, bar_length=20, bar_character='#')

Progress bar. Writes a progress bar in place in the output

Args:
progress:

value between 0 and 1

bar_length:

number of characters to consider in the bar

pyMOE.utils.qmc_2d(f, ax, bx, ay, by, sobol_samples)

Calculates 2D integral via Quasi Monte Carlo method using Sobol sequences https://en.wikipedia.org/wiki/Quasi-Monte_Carlo_method We are approximating the integral of f to the average of the function evaluated in a set of points

Arguments:
f_ravel:

2D array to integrate

[ax, bx]:

limits of integration in x, [lower, upper]

[ay, by]:

limits of integration in y, [lower, upper]

sobol_samples:

subset of a Sobol sequence of same dimension as f

Returns:
res:

integral estimation

pyMOE.utils.simpson2d(f, ax, bx, ay, by)

Implements Simpson method for calculating a double integral in 2D array f

Arguments:
f:

2D array to calculate integral

[ax, bx]:

limits of integration in x, [lower, upper]

[ay, by]:

limits of integration in y, [lower, upper]

Module contents