Skip to content

Commit

Permalink
Update DDF.py
Browse files Browse the repository at this point in the history
updated the comments to better suit style used elsewhere in repository

Some slight variable renaming for consistency
  • Loading branch information
maclariz authored Jul 8, 2024
1 parent bff3634 commit 8b176e8
Showing 1 changed file with 80 additions and 51 deletions.
131 changes: 80 additions & 51 deletions py4DSTEM/process/digitaldarkfield/DDF.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,28 +23,43 @@ def aperture_array_generator(
n2lims=(-5, 5),
returns="both",
):
# shape is a tuple describing the shape of the diffraction patterns
# center is a tuple of the centre position (vertical, horizontal)
# pad is
# mode tells what kind of calculation is desired. Which parameters are required depends on this choice:
#'single': just one aperture at a specified position:
# g1 and g2, lattice vectors (non-colinear)
# s1 and s2, multiples of these used to find the required lattice position
# i.e. aperture placed at s1*g1 + s2*g2
# r1, r2 unused
#'2-beam': just a line of apertures along spots for a 2-beam condition:
# g1: lattice vector
# n1lims: tuple of integers giving the largest multiples of this lattice vector to be used,
# negative and positive
# r1 and r2, inner and outerradii in pixels over which aperture points will be found (optional)
#'array': an array defined by g1 and g2 centred on s1*g1+s2*g2
# r1 and r2, inner and outerradii in pixels over which aperture points will be found (optional)
# n1lims and n2lims: tuple of integers giving the largest multiples of each lattice vector to be used
# r1 set to a small but non-zero value (a few pixels) can be used to exclude the primary beam
# returns sets whether the function returns:
#'both' = a centered array and an array in raw pixel numbers (uncentered)
#'centered' = just the version centered on [0,0]
# in all cases, the return is a list of (Qx,Qy) tuples
"""
shape is a tuple describing the shape of the diffraction patterns
center is a tuple of the centre position (vertical, horizontal)
pad is any edge boundary desired (i.e. no aperture positions within pad pixels of edge)
mode tells what kind of calculation is desired. Which parameters are required and exactly what they mean
depends on this choice:
'single': just one aperture at a specified position:
g1 and g2, lattice vectors (non-colinear)
s1 and s2, multiples of these used to find the required lattice position
i.e. aperture placed at s1*g1 + s2*g2
r1, r2 unused
'2-beam': just a line of apertures along spots for a 2-beam condition:
g1: lattice vector
g2: unused
n1lims: tuple of integers giving the largest multiples of this lattice vector to be used,
negative and positive
r1 and r2, inner and outerradii in pixels over which aperture points will be found (optional)
this is a good way to exclude the central spot by setting r > disc radius
'array': an array defined by g1 and g2 centred on s1*g1+s2*g2
r1 and r2, inner and outerradii in pixels as for '2-beam'
n1lims and n2lims: tuple of integers giving the largest multiples of each lattice vector to be used,
as for 2-beam
returns sets whether the function returns:
'both' = a centered array and an array in raw pixel numbers (uncentered)
'centered' = just the version centered on [0,0]
in all cases, the return is a list of (Qx,Qy) tuples
"""

V, H = shape[0], shape[1]

Expand Down Expand Up @@ -104,13 +119,24 @@ def aperture_array_generator(
else:
print("incorrect mode selection")


def pointlist_to_array(bplist, idim, jdim):
# This function turns the py4dstem pointslist object to a simple array that is more
# convenient for rapid array processing in numpy
"""
This function turns the py4dstem pointslist object to a simple numpy array that is more
convenient for rapid array processing in numpy
idim and jdim are the dimensions in the Rx and Ry directions
returns an array called pointsarray
This will be an 2D numpy array of n points x 5 columns:
qx
qy
I
Rx
Ry
"""
for i, j in tqdmnd(idim, jdim):
if i == j == 0:
ps = np.array(
pointsarray = np.array(
[
bplist.cal[i, j].qx,
bplist.cal[i, j].qy,
Expand All @@ -129,43 +155,46 @@ def pointlist_to_array(bplist, idim, jdim):
bplist.cal[i, j].qx.shape[0] * [j],
]
).T
ps = np.vstack((ps, nps))
return ps # as a numpy array
# ps will be an 2D numpy array of n points x 5 columns:
# qx
# qy
# I
# Rx
# Ry


pointsarray = np.vstack((pointsarray, nps))
return pointsarray

def pointlist_differences(apertureposition, pointsarray):
# calculates differences between a specific aperture position
# and a whole list of detected points for a dataset
# returns the Euclidean distances as a 1D array
"""
calculates differences between a specific aperture position
and a whole list of detected points for a dataset (as an array)
returns the Euclidean distances as a 1D numpy array
"""
subtractor = np.array(
[[apertureposition[0], apertureposition[1]] * pointsarray.shape[0]]
).reshape((pointsarray.shape[0], 2))
diff = ((pointsarray[:, :2] - subtractor) ** 2).sum(axis=1) ** 0.5
return diff # as a numpy array


def DDFimage(dataset, points, aperturearray, tol=1):
# dataset is a 4DSTEM dataset as a numpy array, only used to get the size of image
# points is an array of points as calculated by pointlist_to_array above
# centerarray is a list of tuples of aperture centers,
# as defined by aperture_array_generator above
# tol is the tolerance for a displacement between points and centers (in pixels)
# this does rely on the pointslist_differences function
return diff


def DDFimage(dataset, pointsarray, aperturearray, tol=1):
"""
dataset is a 4DSTEM dataset as a numpy array, only used to get the size of image
pointsarray is an array of points as calculated by pointlist_to_array
aperturearray is a list of tuples of aperture centers generated by aperture_array_generator
tol is the tolerance for a displacement between points and centers (in pixels)
this does rely on the pointslist_differences function
returns a the DDF image as a 2D numpy array
"""
image = np.zeros_like(dataset[:, :, 0, 0])
for aperture_index in tqdmnd(len(aperturearray)):
apertureposition = aperturearray[aperture_index]
intensities = np.vstack(
(points[:, 2:].T, pointlist_differences(apertureposition, points))
(pointsarray[:, 2:].T, pointlist_differences(apertureposition, pointsarray))
).T
intensities2 = np.delete(intensities, np.where(intensities[:, 3] > tol), axis=0)
for row in range(intensities2[:, 0].shape[0]):
image[
intensities2[row, 1].astype(int), intensities2[row, 2].astype(int)
] += intensities2[row, 0]
return image # as a 2D numpy array
return image

0 comments on commit 8b176e8

Please sign in to comment.