sim_helper module

Helper functions for simulating LTEM images.

An assortment of helper functions broadly categorized into four sections

  • Simulating images from phase shifts
  • Processing micromagnetic outputs
  • Helper functions for displaying vector fields
  • Generating variations of magnetic vortex/skyrmion states

Known Bugs:

  • Simulating images with sharp edges in the electrostatic phase shift and thickness maps gives images with incorrect Fresnel fringes. This can be resolved by applying a light filter to the electrostatic phase shift and thickness map before simulating images.

Author: Arthur McCray, ANL, Summer 2019.

sim_helper.Bloch(dim, chirality='cw', pad=True, ir=0, show=False)[source]

Create a Bloch vortex magnetization structure.

Unlike Lillihook, this function does not produce a rigorously calculated magnetization structure. It is just a vortex that looks like some experimental observations.

Parameters:
  • dim (int) – Dimension of lattice.
  • chirality (str) –
    • ‘cw’: clockwise rotation
    • ’ccw’: counter-clockwise rotation.
  • pad (bool) – Whether or not to leave some space between the edge of the magnetization and the edge of the image.
  • ir (float) – Inner radius of the vortex in pixels.
  • show (bool) – If True, will show the x, y, z components in plot form.
Returns:

(mag_x, mag_y, mag_z)

  • mag_x (ndarray) – 2D Numpy array of shape (dim, dim). x-component of magnetization vector.
  • mag_y (ndarray) – 2D Numpy array of shape (dim, dim). y-component of magnetization vector.
  • mag_z (ndarray) – 2D Numpy array of shape (dim, dim). z-component of magnetization vector.

Return type:

tuple

sim_helper.Lillihook(dim, rad=None, Q=1, gamma=1.5708, P=1, show=False)[source]

Define a skyrmion magnetization.

This function makes a skyrmion magnetization as calculated and defined in [1]. It returns three 2D arrays of size (dim, dim) containing the x, y, and z magnetization components at each pixel.

Parameters:
  • dim (int) – Dimension of lattice.
  • rad (float) – Radius parameter (see [1]). Default dim//16.
  • Q (int) – Topological charge. - 1: skyrmion - 2: biskyrmion - -1: antiskyrmion
  • gamma (float) – Helicity. - 0 or Pi: Neel - Pi/2 or 3Pi/2: Bloch
  • P (int) – Polarity (z direction in center), +/- 1.
  • show (bool) – (optional) If True, will plot the x, y, z components.
Returns:

(mag_x, mag_y, mag_z)

  • mag_x (ndarray) – 2D Numpy array (dim, dim). x-component of magnetization vector.
  • mag_y (ndarray) – 2D Numpy array (dim, dim). y-component of magnetization vector.
  • mag_z (ndarray) – 2D Numpy array (dim, dim). z-component of magnetization vector.

Return type:

tuple

References

  1. Lilliehöök, D., Lejnell, K., Karlhede, A. & Sondhi, S. Quantum Hall Skyrmions with higher topological charge. Phys. Rev. B 56, 6805–6809 (1997).
sim_helper.Neel(dim, chirality='io', pad=True, ir=0, show=False)[source]

Create a Neel magnetization structure.

Unlike Lillihook, this function does not produce a rigorously calculated magnetization structure.

Parameters:
  • dim (int) – Dimension of lattice.
  • chirality (str) –
    • ‘cw’: clockwise rotation
    • ’ccw’: counter-clockwise rotation.
  • pad (bool) – Whether or not to leave some space between the edge of the magnetization and the edge of the image.
  • ir (float) – Inner radius of the vortex in pixels.
  • show (bool) – If True, will show the x, y, z components in plot form.
Returns:

(mag_x, mag_y, mag_z)

  • mag_x (ndarray) – 2D Numpy array of shape (dim, dim). x-component of magnetization vector.
  • mag_y (ndarray) – 2D Numpy array of shape (dim, dim). y-component of magnetization vector.
  • mag_z (ndarray) – 2D Numpy array of shape (dim, dim). z-component of magnetization vector.

Return type:

tuple

sim_helper.load_ovf(file=None, sim='norm', B0=10000.0, v=1)[source]

Load a .ovf or .omf file of magnetization values.

This function takes magnetization output files from OOMMF or Mumax, pulls some data from the header and returns 3D arrays for each magnetization component as well as the pixel resolutions.

Parameters:
  • file (string) – Path to file
  • sim (string) –

    Define how the magnetization is scaled as it’s read from the file. OOMMF writes .omf files with vectors in units of A/m, while Mumax writes .omf files with vectors normalized. This allows the reading to scale the vectors appropriately to gauss or simply make sure everything is normalized (as is needed for the phase calculation).

    • ”OOMMF”: Vectors scaled by mu0 and output in Tesla
    • ”mumax”: Vectors scaled by B0 and given those units (gauss or T)
    • ”norm”: (default) Normalize all vectors (does not change (0,0,0) vectors)
    • ”raw”: Don’t do anything with the values.
  • B0 (float) – Saturation induction (gauss). Only relevant if sim==”mumax”
  • v (int) –

    Verbosity.

    • 0 : No output
    • 1 : Default output
    • 2 : Extended output, print full header.
Returns:

(mag_x, mag_y, mag_z, del_px)

  • mag_x (2D array) – x-component of magnetization (units depend on sim).
  • mag_y (2D array) – y-component of magnetization (units depend on sim).
  • mag_z (2D array) – z-component of magnetization (units depend on sim).
  • del_px (float) – Scale of datafile in y/x direction (nm/pixel)
  • zscale (float) – Scale of datafile in z-direction (nm/pixel)

Return type:

tuple

sim_helper.make_thickness_map(mag_x=None, mag_y=None, mag_z=None, file=None, D3=True)[source]

Define a 2D thickness map where magnetization is 0.

Island structures or empty regions are often defined in micromagnetic simulations as regions with (0,0,0) magnetization. This function creates an array where those values are 0, and 1 otherwise. It then sums along the z direction to make a 2D map.

It can take inputs either as magnetization components or a filename which it will read with the load_ovf() function.

Parameters:
  • mag_x (3D array) – Numpy array of x component of the magnetization.
  • mag_y (3D array) – Numpy array of y component of the magnetization.
  • mag_z (3D array) – Numpy array of z component of the magnetization.
  • file (str) – Path to .ovf or .omf file.
  • D3 (bool) – Whether or not to return the 3D map.
Returns:

2D array of thickness values scaled to total thickness. i.e. 0 corresponds to 0 thickness and 1 to zscale*zdim.

Return type:

ndarray

sim_helper.reconstruct_ovf(file=None, savename=None, save=1, v=1, flip=True, thk_map=None, pscope=None, defval=0, theta_x=0, theta_y=0, B0=10000.0, sample_V0=10, sample_xip0=50, mem_thk=50, mem_xip0=1000, add_random=0, sym=False, qc=None, method='mans')[source]

Load a micromagnetic output file and reconstruct simulated LTEM images.

This is an “all-in-one” function that takes a magnetization datafile, material parameters, and imaging conditions to simulate LTEM images and reconstruct them.

The image simulation step uses the Mansuripur algorithm [1] for calculating the phase shift if theta_x and theta_y == 0, as it is computationally very efficient. For nonzero tilts it employs the linear superposition method for determining phase shift, which allows for 3d magnetization inputs and robust tilting the sample. A substrate can be accounted for as well, though it is assumed to be uniform and non-magnetic, i.e. applying a uniform phase shift.

Imaging parameters are defined by the defocus value, tilt angles, and microscope object which contains accelerating voltage, aberrations, etc.

Parameters:
  • file (str) – Path to file.
  • savename (str) – Name prepended to saved files. If None -> filename
  • save (int) –

    Integer value that sets which files are saved.

    • 0 – Saves nothing, still returns results.
    • 1 – (default) Saves simulated images, simulated phase shift, and reconstructed magnetizations, both the color image and x/y components.
    • 2 – Saves simulated images, simulated phase shift, and all reconstruction TIE images.
  • v (int) –

    Integer value which sets verbosity

    • 0: All output suppressed.
    • 1: Default prints and final reconstructed image displayed.
    • 2: Extended output. Prints full datafile header, displays simulated tfs.
  • flip (bool) – Whether to use a single through focal series (tfs) (False) or two (True), one for sample in normal orientation and one with it flipped in the microscope. Samples that are not uniformly thin require flip=True.
  • thk_map (2D/3D array) –

    Numpy array of same (y,x) shape as magnetization arrays. Binary shape function of the sample, 1 where the sample is and 0 where there is no sample. If a 2D array is given it will be tiled along the z-direction to make it the same size as the magnetization arrays.

    The make_thickness_map() function can be useful for island structures or as a guide of how to define a thickness map.

    Default None -> Uniform thickness, equivalent to array of 1’s.

  • pscope (Microscope object) – Contains all microscope parameters such as accelerating voltage, aberrations, etc., along with the methods to propagate the electron wave function.
  • def_val (float) – The defocus values at which to calculate the images.
  • theta_x (float) – Rotation around x-axis (degrees). Default 0. Rotates around x axis then y axis if both are nonzero.
  • theta_y (float) – Rotation around y-axis (degrees). Default 0.
  • B0 (float) – Saturation induction (gauss).
  • sample_V0 (float) – Mean inner potential of sample (V).
  • sample_xip0 (float) – Extinction distance (nm).
  • mem_thk (float) – Support membrane thickness (nm). Default 50.
  • mem_xip0 (float) – Support membrane extinction distance (nm). Default 1000.
  • add_random – (float): Whether or not to add amorphous background to the simulation. True or 1 will add a default background, any other value will be multiplied to scale the additional phase term.
  • sym (bool) – (optional) Fourier edge effects are marginally improved by symmetrizing the images before reconstructing, but the process is more computationally intensive as images are 4x as large. (default) False.
  • qc (float) – (optional) The Tikhonov frequency to use as a filter, (default) None. If you use a Tikhonov filter the resulting magnetization is no longer quantitative
  • method (str) –

    (optional) Method of phase calculation to use if theta_x == 0 and theta_y == 0. If either are nonzero then the linear superposition method will be used.

    • ”Mans” : Use Mansuripur algorithm (default)
    • ”Linsup” : Use linear superposition method
Returns:

A dictionary of image arrays

key value
’byt’ y-component of integrated magnetic induction
’bxt’ x-component of integrated magnetic induction
’bbt’ Magnitude of integrated magnetic induction
’phase_m_sim’ Simulated magnetic phase shift
’phase_e_sim’ Simulated electrostatic phase shift
’phase_m’ Magnetic phase shift (radians)
’phase_e’ Electrostatic phase shift (if using flip stack) (radians),
’dIdZ_m’ Intensity derivative for calculating phase_m
’dIdZ_e’ Intensity derivative for calculating phase_e (if using flip stack)
’color_b’ RGB image of magnetization
’inf_im’ In-focus image

Return type:

dict

sim_helper.rot_thickness_map(thk_map_3D=None, theta_x=0, theta_y=0, zscale=None)[source]

Tilt a thickness map around the x and y axis.

While the phase calculation takes care of tilting the sample in the algorithm, image simualtions require a thickness map to calculate the wave function amplitude, and this must be rotated according to theta_x and theta_y.

This function returns a rotated thickness map of the same shape inputted as well as the thickness scaling factor.

This function only works for high tilt angles when zscale = del_px.

Parameters:
  • thk_map_3D (3D array) – Numpy array of shape (z,y,x) shape to be rotated.
  • theta_x (float) – Rotation around x-axis (degrees). Rotates around x axis then y axis if both are nonzero.
  • theta_y (float) – Rotation around y-axis (degrees).
  • zscale (float) – Scaling (nm/pixel) in z direction.
Returns:

(thk_map_tilt, isl_thickness_tilt)

  • thk_map_tilt (ndarray) – 2D Numpy array, tilted thickness map normalized to values [0,1]
  • isl_thickness_tilt (float) – scale factor (nm) for thk_map_tilt. Multiplying thk_map_tilt * isl_thickness_tilt gives the thickness map in nanometers.

Return type:

tuple

sim_helper.show_3D(mag_x, mag_y, mag_z, a=15, ay=None, az=15, l=None, show_all=True)[source]

Display a 3D vector field with arrows.

Arrow color is determined by direction, with in-plane mapping to a HSV color-wheel and out of plane to white (+z) and black (-z).

Plot can be manipulated by clicking and dragging with the mouse. a, ay, and az control the number of arrows that will be plotted along each axis, i.e. there will be a*ay*az total arrows. In the default case a controls both ax and ay.

Parameters:
  • mag_x (3D array) – (z,y,x). x-component of magnetization.
  • mag_y (3D array) – (z,y,x). y-component of magnetization.
  • mag_z (3D array) – (z,y,x). z-component of magnetization.
  • a (int) – Number of arrows to plot along the x-axis, if ay=None then this sets the y-axis too.
  • ay (int) – (optional) Number of arrows to plot along y-axis. Defaults to a.
  • az (int) – Number of arrows to plot along z-axis. if az > depth of array, az is set to 1.
  • l (float) – Scale of arrows. Larger -> longer arrows.
  • show_all (bool) –
    • True: (default) All arrows are displayed with a grey background.
    • False: Alpha value of arrows is controlled by in-plane component. As arrows point out-of-plane they become transparent, leaving only in-plane components visible. The background is black.
Returns:

None. Displays a matplotlib axes3D object.

Return type:

None

sim_helper.show_sims(phi, im_un, im_in, im_ov, title=None)[source]

Plot phase, underfocus, infocus, and overfocus images in one plot.

Uses same scale of intensity values for all simulated images but not phase.

Parameters:
  • phi (2D array) – Image of phase shift of object.
  • im_un (2D array) – Underfocus image.
  • im_in (2D array) – Infocus image.
  • im_ov (2D array) – Overfocus image.
Returns:

Displays matplotlib plot.

Return type:

None

sim_helper.sim_images(mphi=None, ephi=None, pscope=None, isl_shape=None, del_px=1, def_val=0, add_random=False, save_path=None, save_name=None, isl_thk=20, isl_xip0=50, mem_thk=50, mem_xip0=1000, v=1, Filter=True)[source]

Simulate LTEM images for a given electron phase shift through a sample.

This function returns LTEM images simulated for in-focus and at +/- def_val for comparison to experimental data and reconstruction.

It was primarily written for simulating images of magnetic island structures, and as such the sample is defined in two parts: a uniform support membrane across the region and islands of magnetic material defined by an array isl_shape. The magnetization is defined with 2D arrays corresponding to the x- and y-components of the magnetization vector.

There are many required parameters here that must be set to account for the support membrane. The default values apply to 20nm permalloy islands on a 50nm SiN membrane window.

There is a known bug where sharp edges in the ephi creates problems with the image simulations. As a workaround, this function applies a light gaussian filter (sigma = 1 pixel) to the ephi and isl_shape arrays. This can be controlled with the filter argument.

Parameters:
  • mphi (2D array) – Numpy array of size (M, N), magnetic phase shift
  • ephi (2D array) – Numpy array of size (M, N), Electrostatic phase shift
  • pscope (Microscope object) – Contains all microscope parameters as well as methods for propagating electron wave functions.
  • isl_shape (2D/3D array) – Array of size (z,y,x) or (y,x). If 2D the thickness will be taken as the isl_shape values multiplied by isl_thickness. If 3D, the isl_shape array will be summed along the z-axis becoming and multiplied by isl_thickness. (Default) None -> uniform flat material with thickness = isl_thk.
  • del_px (Float) – Scale factor (nm/pixel). Default = 1.
  • def_val (Float) – The defocus values at which to calculate the images.
  • add_random (Float) – Whether or not to add amorphous background to the simulation. True or 1 will add a default background, any other value will be multiplied to scale the additional phase term.
  • save_path – String. Will save a stack [underfocus, infocus, overfocus] as well as (mphi+ephi) as tiffs along with a params.text file. (Default) None -> Does not save.
  • save_name (str) – Name prepended to saved files.
  • v (int) – Verbosity. Set v=0 to suppress print statements.
  • isl_thk (float) – Island thickness (nm). Default 20 (nm).
  • isl_xip0 (float) – Island extinction distance (nm). Default 50 (nm).
  • mem_thk (float) – Support membrane thickness (nm). Default 50 (nm).
  • mem_xip0 (float) – Support membrane extinction distance (nm). Default 1000 (nm).
  • Filter (Bool) – Apply a light gaussian filter to ephi and isl_shape.
Returns:

(Tphi, im_un, im_in, im_ov)

  • Tphi (2D array) – Numpy array of size (M,N). Total electron phase shift (ephi+mphi).
  • im_un (2D array) – Numpy array of size (M,N). Simulated image at delta z = -def_val.
  • im_in (2D array) – Numpy array of size (M,N). Simulated image at zero defocus.
  • im_ov (2D array) – Numpy array of size (M,N). Simulated image at delta z = +def_val.

Return type:

tuple

sim_helper.std_mansPhi(mag_x=None, mag_y=None, mag_z=None, zscale=1, del_px=1, isl_shape=None, pscope=None, b0=10000.0, isl_thk=20, isl_V0=20, mem_thk=50, mem_V0=10, add_random=None)[source]

Calculates the electron phase shift through a given 2D magnetization.

This function was originally created for simulating LTEM images of magnetic island structures, and it is kept as an example of how to set up and use the mansPhi function. It defines the sample in two parts: a uniform membrane across the region and an island structure defined by isl_shape. The magnetization is defined with 2D arrays corresponding to the x- and y- components of the magnetization vector.

The magnetic phase shift is calculated using the Mansuripur algorithm (see comp_phase.py), and the electrostatic phase shift is computed directly from the materials parameters and geometry given.

Parameters:
  • mag_x (2D/3D Array) – X-component of the magnetization at each pixel.
  • mag_y (2D/3D Array) – Y-component of the magnetization at each pixel.
  • mag_z (2D/3D Array) – Z-component of the magnetization at each pixel.
  • isl_shape (2D/3D array) – Array of size (z,y,x) or (y,x). If 2D the thickness will be taken as the isl_shape values multiplied by isl_thickness. If 3D, the isl_shape array will be summed along the z-axis becoming and multiplied by isl_thickness. (Default) None -> uniform flat material with thickness = isl_thk.
  • zscale (float) – Scale factor (nm/pixel) along beam direction.
  • del_px (float) – Scale factor (nm/pixel) along x/y directions.
  • pscope (Microscope object) – Accelerating voltage is the only relevant parameter here.
  • b0 (float) – Saturation induction (gauss). Default 1e4.
  • isl_thk (float) – Island thickness (nm). Default 20.
  • isl_V0 (float) – Island mean inner potential (V). Default 20.
  • mem_thk (float) – Support membrane thickness (nm). Default 50.
  • mem_V0 (float) – Support membrane mean inner potential (V). Default 10.
  • add_random (float) – Account for the random phase shift of the amorphous membrane. Phase shift will scale with mem_V0 and mem_thk, but the initial factor has to be set by hand. True -> 1/32, which is a starting place that works well for some images.
Returns:

(ephi, mphi)

  • ephi (2D array) – Numpy array of size (M,N). Electrostatic phase shift.
  • mphi (2D array) – Numpy array of size (M,N). Magnetic phase shift.

Return type:

tuple