Classes
Array
- class py4DSTEM.Array(data: ndarray, name: str | None = 'array', units: str | None = '', dims: list | None = None, dim_names: list | None = None, dim_units: list | None = None, slicelabels=None)
A class which stores any N-dimensional array-like data, plus basic metadata: a name and units, as well as calibrations for each axis of the array, and names and units for those axis calibrations.
In the simplest usage, only a data array is passed:
>>> ar = Array(np.ones((20,20,256,256)))
will create an array instance whose data is the numpy array passed, and with automatically populated dimension calibrations in units of pixels.
Additional arguments may be passed to populate the object metadata:
>>> ar = Array( >>> np.ones((20,20,256,256)), >>> name = 'test_array', >>> units = 'intensity', >>> dims = [ >>> [0,5], >>> [0,5], >>> [0,0.01], >>> [0,0.01] >>> ], >>> dim_units = [ >>> 'nm', >>> 'nm', >>> 'A^-1', >>> 'A^-1' >>> ], >>> dim_names = [ >>> 'rx', >>> 'ry', >>> 'qx', >>> 'qy' >>> ], >>> )
will create an array with a name and units for its data, where its first two dimensions are in units of nanometers, have pixel sizes of 5nm, and are described by the handles ‘rx’ and ‘ry’, and where its last two dimensions are in units of inverse Angstroms, have pixels sizes of 0.01A^-1, and are described by the handles ‘qx’ and ‘qy’.
Arrays in which the length of each pixel is non-constant are also supported. For instance,
>>> x = np.logspace(0,1,100) >>> y = np.sin(x) >>> ar = Array( >>> y, >>> dims = [ >>> x >>> ] >>> )
generates an array representing the values of the sine function sampled 100 times along a logarithmic interval from 1 to 10. In this example, this data could then be plotted with, e.g.
>>> plt.scatter(ar.dims[0], ar.data)
If the slicelabels keyword is passed, the first N-1 dimensions of the array are treated normally, while the final dimension is used to represent distinct arrays which share a common shape and set of dim vectors. Thus
>>> ar = Array( >>> np.ones((50,50,4)), >>> name = 'test_array_stack', >>> units = 'intensity', >>> dims = [ >>> [0,2], >>> [0,2] >>> ], >>> dim_units = [ >>> 'nm', >>> 'nm' >>> ], >>> dim_names = [ >>> 'rx', >>> 'ry' >>> ], >>> slicelabels = [ >>> 'a', >>> 'b', >>> 'c', >>> 'd' >>> ] >>> )
will generate a single Array instance containing 4 arrays which each have a shape (50,50) and a common set of dim vectors [‘rx’,’ry’], and which can be indexed into with the names assigned in slicelabels using
>>> ar.get_slice('a')
which will return a 2D (non-stack-like) Array instance with shape (50,50) and the dims assigned above. The Array attribute .rank is equal to the number of dimensions for a non-stack-like Array, and is equal to N-1 for stack-like arrays.
- __init__(data: ndarray, name: str | None = 'array', units: str | None = '', dims: list | None = None, dim_names: list | None = None, dim_units: list | None = None, slicelabels=None)
- Accepts:
data (np.ndarray): the data name (str): the name of the Array units (str): units for the pixel values dims (variable): calibration vectors for each of the axes of the data
array. Valid values for each element of the list are None, a number, a 2-element list/array, or an M-element list/array where M is the data array. If None is passed, the dim will be populated with integer values starting at 0 and its units will be set to pixels. If a number is passed, the dim is populated with a vector beginning at zero and increasing linearly by this step size. If a 2-element list/array is passed, the dim is populated with a linear vector with these two numbers as the first two elements. If a list/array of length M is passed, this is used as the dim vector, (and must therefore match this dimension’s length). If dims recieves a list of fewer than N arguments for an N-dimensional data array, the extra dimensions are populated as if None were passed, using integer pixel values. If the dims parameter is not passed, all dim vectors are populated this way.
- dim_units (list): the units for the calibration dim vectors. If
nothing is passed, dims vectors which have been populated automatically with integers corresponding to pixel numbers will be assigned units of ‘pixels’, and any other dim vectors will be assigned units of ‘unknown’. If a list with length < the array dimensions, the passed values are assumed to apply to the first N dimensions, and the remaining values are populated with ‘pixels’ or ‘unknown’ as above.
- dim_names (list): labels for each axis of the data array. Values
which are not passed, following the same logic as described above, will be autopopulated with the name “dim#” where # is the axis number.
- slicelabels (None or True or list): if not None, must be True or a
list of strings, indicating a “stack-like” array. In this case, the first N-1 dimensions of the array are treated normally, in the sense of populating dims, dim_names, and dim_units, while the final dimension is treated distinctly: it indexes into distinct arrays which share a set of dimension attributes, and can be sliced into using the string labels from the slicelabels list, with the syntax array[‘label’] or array.get_slice(‘label’). If slicelabels is True or is a list with length less than the final dimension length, unassigned dimensions are autopopulated with labels array{i}. The flag array.is_stack is set to True and the array.rank attribute is set to N-1.
- Returns:
A new Array instance
- get_dim(n)
Return the n’th dim vector
- dim(n)
Return the n’th dim vector
- set_dim(n: int, dim: list | ndarray, units: str | None = None, name: str | None = None)
Sets the n’th dim vector, using dim as described in the Array documentation. If units and/or name are passed, sets these values for the n’th dim vector.
- Accepts:
n (int): specifies which dim vector dim (list or array): length must be either 2, or equal to the
length of the n’th axis of the data array
units (Optional, str): name: (Optional, str):
- get_dim_units(n)
Return the n’th dim vector units
- set_dim_units(n: int, units: str)
Sets the n’th dim vector units to units.
- Accepts:
n (int): specifies which dim vector units (str): new units
- get_dim_name(n)
Get the n’th dim vector name
- set_dim_name(n: int, name: str)
Sets the n’th dim vector name to name.
- Accepts:
n (int): specifies which dim vector name (str): new name
- to_h5(group)
Takes an h5py Group instance and creates a subgroup containing this Array, tags indicating its EMD type and Python class, and the array’s data and metadata.
- Accepts:
group (h5py Group)
- Returns:
(h5py Group) the new array’s Group
- add_to_tree(node)
Add an unrooted node as a child of the current, rooted node. To move an already rooted node/branch, use .graft(). To create a rooted node, use Root().
- cut_from_tree(root_metadata=True)
Removes a branch from an object tree at this node.
A new root node is created under this object with this object’s name. Metadata from the current root is transferred/not transferred to the new root according to the value of root_metadata.
- Accepts:
- root_metadata (True, False, or ‘copy’): if True adds the old root’s
metadata to the new root; if False adds no metadata to the new root; if ‘copy’ adds copies of all metadata from the old root to the new root.
- Returns:
(Node) the new root node
- force_add_to_tree(node)
Add node node as a child of the current node, whether or not node is rooted. If it’s unrooted, performs a simple add. If it is rooted, performs a graft, excluding the root metadata from node.
- classmethod from_h5(group)
Takes an h5py Group which is open in read mode. Confirms that a a Node of this name exists in this group, and loads and returns it with it’s metadata.
- Accepts:
group (h5py Group)
- Returns:
(Node)
- get_from_tree(name)
Finds and returns an object from an EMD tree using the string key name, with ‘/’ delimiters between ‘parent/child’ nodes. Search from the root node by adding a leading ‘/’; otherwise, searches from the current node.
- graft(node, merge_metadata=True)
Moves the branch beginning node onto this tree at this node.
For the reverse (i.e. grafting from this tree onto another tree) either use that tree’s .graft method, or use this tree’s ._graft.
- Accepts:
node (Node): merge_metadata (True, False, or ‘copy’): if True adds the old root’s
metadata to the new root; if False adds no metadata to the new root; if ‘copy’ adds copies of all metadata from the old root to the new root.
- Returns:
(Node) this tree’s root node
- static newnode(method)
Decorator which may be added to node methods which product and return a new node. If such a method is decorated with
>>> @newnode
then the new node is added to the parent node’s tree, and a Metadata instance is added to the new node’s metadata which stores information about how the node was created, namely: method’s name, the parent’s class and name, and all the arguments passed to method.
- show_tree(root=False)
Display the object tree. If root is False, displays the branch of the tree downstream from this node. If root is True, displays the full tree from the root node.
- tree(arg=None, **kwargs)
Usages -
>>> .tree() # show tree from current node >>> .tree(show=True) # show from root >>> .tree(show=False) # show from current node >>> .tree(add=node) # add a child node >>> .tree(get='path') # return a '/' delimited child node >>> .tree(get='/path') # as above, starting at root >>> .tree(cut=True) # remove/return a branch, keep root metadata >>> .tree(cut=False) # remove/return a branch, discard root md >>> .tree(cut='copy') # remove/return a branch, copy root metadata >>> .tree(graft=node) # remove/graft a branch, keeping root metadata >>> .tree(graft=(node,True)) # as above >>> .tree(graft=(node,False)) # as above, discard root metadata >>> .tree(graft=(node,'copy')) # as above, copy root metadata
The show, add, and get methods can be accessed directly with
>>> .tree(arg)
for an arg of the appropriate type (bool, Node, and string).
BraggVectors
- class py4DSTEM.BraggVectors(Rshape, Qshape, name='braggvectors', verbose=False, calibration=None)
Stores localized bragg scattering positions and intensities for a 4D-STEM datacube.
Raw (detector coordinate) vectors are accessible as
>>> braggvectors.raw[ scan_x, scan_y ]
and calibrated vectors as
>>> braggvectors.cal[ scan_x, scan_y ]
To set which calibrations are being applied, call
>>> braggvectors.setcal( >>> center = bool, >>> ellipse = bool, >>> pixel = bool, >>> rotate = bool >>> )
If .setcal is not called, calibrations will be automatically selected based based on the contents of the instance’s calibrations property. The calibrations performed in the last call to braggvectors.cal are exposed as
>>> braggvectors.calstate
After grabbing some vectors
>>> vects = braggvectors.raw[ scan_x,scan_y ]
the values themselves are accessible as
>>> vects.qx,vects.qy,vects.I >>> vects['qx'],vects['qy'],vects['intensity']
Alternatively, you can access the centered vectors in pixel units with
>>> vects.get_vectors( >>> scan_x, >>> scan_y, >>> center = bool, >>> ellipse = bool, >>> pixel = bool, >>> rotate = bool >>> )
which will return the vectors at scan position (scan_x,scan_y) with the requested calibrations applied.
- __init__(Rshape, Qshape, name='braggvectors', verbose=False, calibration=None)
- set_raw_vectors(x)
Given some PointListArray x of the correct shape, sets this to the raw vectors
- property raw
Calling
>>> raw[ scan_x, scan_y ]
returns those bragg vectors.
- property cal
Calling
>>> cal[ scan_x, scan_y ]
retrieves data. Use .setcal to set the calibrations to be applied, or .calstate to see which calibrations are currently set. Calibrations are initially all set to False. Call .setcal() (with no arguments) to automatically detect which calibrations are present and apply those.
- setcal(center=None, ellipse=None, pixel=None, rotate=None)
Calling
>>> braggvectors.setcal( >>> center = bool, >>> ellipse = bool, >>> pixel = bool, >>> rotate = bool, >>> )
sets the calibrations that will be applied to vectors subsequently retrieved with
>>> braggvectors.cal[ scan_x, scan_y ]
Any arguments left as None will be automatically set based on the calibration measurements available.
- calibrate()
Autoupdate the calstate when relevant calibrations are set
- get_vectors(scan_x, scan_y, center, ellipse, pixel, rotate)
Returns the bragg vectors at the specified scan position with the specified calibration state.
- Parameters:
scan_x (int) –
scan_y (int) –
center (bool) –
ellipse (bool) –
pixel (bool) –
rotate (bool) –
- Returns:
vectors
- Return type:
BVects
- to_h5(group)
Constructs the group, adds the bragg vector pointlists, and adds metadata describing the shape
- add_to_tree(node)
Add an unrooted node as a child of the current, rooted node. To move an already rooted node/branch, use .graft(). To create a rooted node, use Root().
- attach(node)
Attach node to the current object’s tree, attaching calibration and detaching calibrations as needed.
- cut_from_tree(root_metadata=True)
Removes a branch from an object tree at this node.
A new root node is created under this object with this object’s name. Metadata from the current root is transferred/not transferred to the new root according to the value of root_metadata.
- Accepts:
- root_metadata (True, False, or ‘copy’): if True adds the old root’s
metadata to the new root; if False adds no metadata to the new root; if ‘copy’ adds copies of all metadata from the old root to the new root.
- Returns:
(Node) the new root node
- fit_origin(mask=None, fitfunction='plane', robust=False, robust_steps=3, robust_thresh=2, mask_check_data=True, plot=True, plot_range=None, cmap='RdBu_r', returncalc=True, **kwargs)
Fit origin of bragg vectors.
- Parameters:
mask (2b boolean array, optional) – ignore points where mask=True
fitfunction (str, optional) – must be ‘plane’ or ‘parabola’ or ‘bezier_two’
robust (bool, optional) – If set to True, fit will be repeated with outliers removed.
robust_steps (int, optional) – Optional parameter. Number of robust iterations performed after initial fit.
robust_thresh (int, optional) – Threshold for including points, in units of root-mean-square (standard deviations) error of the predicted values after fitting.
mask_check_data (bool) – Get mask from origin measurements equal to zero. (TODO - replace)
plot (bool, optional) – plot results
plot_range (float) – min and max color range for plot (pixels)
cmap (colormap) – plotting colormap
- Returns:
Return value depends on returnfitp. If
returnfitp==False
(default), returns a 4-tuple containing:qx0_fit: (ndarray) the fit origin x-position
qy0_fit: (ndarray) the fit origin y-position
qx0_residuals: (ndarray) the x-position fit residuals
qy0_residuals: (ndarray) the y-position fit residuals
- Return type:
(variable)
- fit_p_ellipse(bvm, center, fitradii, mask=None, returncalc=False, **kwargs)
- Parameters:
bvm (BraggVectorMap) – a 2D array used for ellipse fitting
center (2-tuple of floats) – the center (x0,y0) of the annular fitting region
fitradii (2-tuple of floats) – inner and outer radii (ri,ro) of the fit region
mask (ar-shaped ndarray of bools) – ignore data wherever mask==True
- Returns:
p_ellipse if returncal is True
- force_add_to_tree(node)
Add node node as a child of the current node, whether or not node is rooted. If it’s unrooted, performs a simple add. If it is rooted, performs a graft, excluding the root metadata from node.
- classmethod from_h5(group)
Takes an h5py Group which is open in read mode. Confirms that a a Node of this name exists in this group, and loads and returns it with it’s metadata.
- Accepts:
group (h5py Group)
- Returns:
(Node)
- get_bragg_vector_map(mode='cal', sampling=1, weights=None, weights_thresh=0.005)
Returns a 2D histogram of Bragg vector intensities in diffraction space, aka a Bragg vector map.
- Parameters:
mode (str) – Must be ‘cal’ or ‘raw’. Use the calibrated or raw vector positions.
sampling (number) – The sampling rate of the histogram, in units of the camera’s sampling. sampling = 2 upsamples and sampling = 0.5 downsamples, each by a factor of 2.
weights (None or array) – If None, use all real space scan positions. Otherwise must be a real space shaped array representing a weighting factor applied to vector intensities from each scan position. If weights is boolean uses beam positions where weights is True. If weights is number-like, scales by the values, and skips positions where wieghts<weights_thresh.
weights_thresh (number) – If weights is an array of numbers, pixels where weights>weight_thresh are skipped.
- Returns:
An Array with .data representing the data, and .dim[0] and .dim[1] representing the sampling grid.
- Return type:
BraggVectorHistogram
- get_bvm(mode='cal', sampling=1, weights=None, weights_thresh=0.005)
Returns a 2D histogram of Bragg vector intensities in diffraction space, aka a Bragg vector map.
- Parameters:
mode (str) – Must be ‘cal’ or ‘raw’. Use the calibrated or raw vector positions.
sampling (number) – The sampling rate of the histogram, in units of the camera’s sampling. sampling = 2 upsamples and sampling = 0.5 downsamples, each by a factor of 2.
weights (None or array) – If None, use all real space scan positions. Otherwise must be a real space shaped array representing a weighting factor applied to vector intensities from each scan position. If weights is boolean uses beam positions where weights is True. If weights is number-like, scales by the values, and skips positions where wieghts<weights_thresh.
weights_thresh (number) – If weights is an array of numbers, pixels where weights>weight_thresh are skipped.
- Returns:
An Array with .data representing the data, and .dim[0] and .dim[1] representing the sampling grid.
- Return type:
BraggVectorHistogram
- get_from_tree(name)
Finds and returns an object from an EMD tree using the string key name, with ‘/’ delimiters between ‘parent/child’ nodes. Search from the root node by adding a leading ‘/’; otherwise, searches from the current node.
- get_masked_peaks(mask, update_inplace=False, returncalc=True)
Alias for mask_in_Q.
- get_virtual_image(mode=None, geometry=None, name='bragg_virtual_image', returncalc=True, center=True, ellipse=True, pixel=True, rotate=True)
Calculates a virtual image based on the values of the Braggvectors integrated over some detector function determined by mode and geometry.
- Parameters:
mode (str) –
- defines the type of detector used. Options:
’circular’, ‘circle’: uses round detector, like bright field
’annular’, ‘annulus’: uses annular detector, like dark field
geometry (variable) –
- expected value depends on the value of mode, as follows:
’circle’, ‘circular’: nested 2-tuple, ((qx,qy),radius)
’annular’ or ‘annulus’: nested 2-tuple, ((qx,qy),(radius_i,radius_o))
Values can be in pixels or calibrated units. Note that (qx,qy) can be skipped, which assumes peaks centered at (0,0).
center (bool) – Apply calibration - center coordinate.
ellipse (bool) – Apply calibration - elliptical correction.
pixel (bool) – Apply calibration - pixel size.
rotate (bool) – Apply calibration - QR rotation.
- Returns:
virtual_im
- Return type:
- graft(node, merge_metadata=True)
Moves the branch beginning node onto this tree at this node.
For the reverse (i.e. grafting from this tree onto another tree) either use that tree’s .graft method, or use this tree’s ._graft.
- Accepts:
node (Node): merge_metadata (True, False, or ‘copy’): if True adds the old root’s
metadata to the new root; if False adds no metadata to the new root; if ‘copy’ adds copies of all metadata from the old root to the new root.
- Returns:
(Node) this tree’s root node
- histogram(mode='cal', sampling=1, weights=None, weights_thresh=0.005)
Returns a 2D histogram of Bragg vector intensities in diffraction space, aka a Bragg vector map.
- Parameters:
mode (str) – Must be ‘cal’ or ‘raw’. Use the calibrated or raw vector positions.
sampling (number) – The sampling rate of the histogram, in units of the camera’s sampling. sampling = 2 upsamples and sampling = 0.5 downsamples, each by a factor of 2.
weights (None or array) – If None, use all real space scan positions. Otherwise must be a real space shaped array representing a weighting factor applied to vector intensities from each scan position. If weights is boolean uses beam positions where weights is True. If weights is number-like, scales by the values, and skips positions where wieghts<weights_thresh.
weights_thresh (number) – If weights is an array of numbers, pixels where weights>weight_thresh are skipped.
- Returns:
An Array with .data representing the data, and .dim[0] and .dim[1] representing the sampling grid.
- Return type:
BraggVectorHistogram
- mask_in_Q(mask, update_inplace=False, returncalc=True)
Remove peaks which fall inside the diffraction shaped boolean array mask, in raw (uncalibrated) peak positions.
- Parameters:
mask (2d boolean array) – The mask. Must be diffraction space shaped
update_inplace (bool) – If False (default) copies this BraggVectors instance and removes peaks from the copied instance. If True, removes peaks from this instance.
returncalc (bool) – Toggles returning the answer
- Returns:
bvects
- Return type:
- mask_in_R(mask, update_inplace=False, returncalc=True)
Remove peaks which fall inside the real space shaped boolean array mask.
- Parameters:
mask (2d boolean array) – The mask. Must be real space shaped
update_inplace (bool) – If False (default) copies this BraggVectors instance and removes peaks from the copied instance. If True, removes peaks from this instance.
returncalc (bool) – Toggles returning the answer
- Returns:
bvects
- Return type:
- measure_origin(center_guess=None, score_method=None, findcenter='max')
Finds the diffraction shifts of the center beam using the raw Bragg vector measurements.
If a center guess is not specified, first, a guess at the unscattered beam position is determined, either by taking the CoM of the Bragg vector map, or by taking its maximal pixel. Once a unscattered beam position is determined, the Bragg peak closest to this position is identified. The shifts in these peaks positions from their average are returned as the diffraction shifts.
- Parameters:
center_guess (2-tuple) – initial guess for the center
score_method (str) –
- Method used to find center peak
’intensity’: finds the most intense Bragg peak near the center
’distance’: finds the closest Bragg peak to the center
’intensity weighted distance’: determines center through a combination of weighting distance and intensity
(str) (findcenter) – position options: ‘CoM’, or ‘max.’ Only used if center_guess is None. CoM finds the center of mass of bragg ector map, ‘max’ uses its brightest pixel.
Returns –
(3-tuple): A 3-tuple comprised of:
qx0 ((R_Nx,R_Ny)-shaped array): the origin x-coord
qy0 ((R_Nx,R_Ny)-shaped array): the origin y-coord
braggvectormap ((R_Nx,R_Ny)-shaped array): the Bragg vector map of only the Bragg peaks identified with the unscattered beam. Useful for diagnostic purposes.
- measure_origin_beamstop(center_guess, radii, max_dist=None, max_iter=1, **kwargs)
Find the origin from a set of braggpeaks assuming there is a beamstop, by identifying pairs of conjugate peaks inside an annular region and finding their centers of mass.
- Parameters:
center_guess (2-tuple) – qx0,qy0
radii (2-tuple) – the inner and outer radii of the specified annular region
max_dist (number) – the maximum allowed distance between the reflection of two peaks to consider them conjugate pairs
max_iter (integer) – for values >1, repeats the algorithm after updating center_guess
- Returns:
the origins
- Return type:
(2d masked array)
- static newnode(method)
Decorator which may be added to node methods which product and return a new node. If such a method is decorated with
>>> @newnode
then the new node is added to the parent node’s tree, and a Metadata instance is added to the new node’s metadata which stores information about how the node was created, namely: method’s name, the parent’s class and name, and all the arguments passed to method.
- plot(index: tuple[int, int] | list[int], cal: str = 'cal', returnfig: bool = False, **kwargs)
Plot Bragg vector, from a specified index. Calls py4DSTEM.process.diffraction.plot_diffraction_pattern(braggvectors.<cal/raw>[index], **kwargs). Optionally can return the figure.
- Parameters:
index (tuple[int,int] | list[int]) – scan position for which Bragg vectors to plot
cal (str, optional) – Choice to plot calibrated or raw Bragg vectors must be ‘raw’ or ‘cal’, by default ‘cal’
returnfig (bool, optional) – Boolean to return figure or not, by default False
- Returns:
matplotlib figure, axes returned if returnfig is True
- Return type:
tuple (figure, axes)
- show_tree(root=False)
Display the object tree. If root is False, displays the branch of the tree downstream from this node. If root is True, displays the full tree from the root node.
- to_strainmap(name: str | None = None)
Generate a StrainMap object from the BraggVectors equivalent to py4DSTEM.StrainMap(braggvectors=braggvectors)
- Parameters:
name (str, optional) – The name of the strainmap. Defaults to None which reverts to default name ‘strainmap’.
- Returns:
A py4DSTEM StrainMap object generated from the BraggVectors
- Return type:
py4DSTEM.StrainMap
- tree(arg=None, **kwargs)
Usages -
>>> .tree() # show tree from current node >>> .tree(show=True) # show from root >>> .tree(show=False) # show from current node >>> .tree(add=node) # add a child node >>> .tree(get='path') # return a '/' delimited child node >>> .tree(get='/path') # as above, starting at root >>> .tree(cut=True) # remove/return a branch, keep root metadata >>> .tree(cut=False) # remove/return a branch, discard root md >>> .tree(cut='copy') # remove/return a branch, copy root metadata >>> .tree(graft=node) # remove/graft a branch, keeping root metadata >>> .tree(graft=(node,True)) # as above >>> .tree(graft=(node,False)) # as above, discard root metadata >>> .tree(graft=(node,'copy')) # as above, copy root metadata
The show, add, and get methods can be accessed directly with
>>> .tree(arg)
for an arg of the appropriate type (bool, Node, and string).
Calibration
- class py4DSTEM.Calibration(name: str | None = 'calibration', root: Root | None = None)
Stores calibration measurements.
Usage
For some calibration instance c
>>> c['x'] = y
will set the value of some calibration item called ‘x’ to y, and
>>> _y = c['x']
will return the value currently stored as ‘x’ and assign it to _y. Additionally, for calibration items in the list l given below, the syntax
>>> c.set_p(p) >>> p = c.get_p()
is equivalent to
>>> c.p = p >>> p = c.p
is equivalent to
>>> c['p'] = p >>> p = c['p']
where in the first line of each couplet the parameter p is set and in the second it’s retrieved, for parameters p in the list
- l = [
Q_pixel_size, * R_pixel_size, * Q_pixel_units, * R_pixel_units, * qx0, qy0, qx0_mean, qy0_mean, qx0shift, qy0shift, origin, * origin_meas, origin_meas_mask, origin_shift, a, * b, * theta, * p_ellipse, * ellipse, * QR_rotation_degrees, * QR_flip, * QR_rotflip, * probe_semiangle, probe_param, probe_center, probe_convergence_semiangle_pixels, probe_convergence_semiangle_mrad,
]
There are two advantages to using the getter/setter syntax for parameters in l (e.g. either c.set_p or c.p) instead of the normal dictionary-like getter/setter syntax (i.e. c[‘p’]). These are (1) enabling retrieving parameters by beam scan position, and (2) enabling propagation of any calibration changes to downstream data objects which are affected by the altered calibrations. See below.
Get a parameter by beam scan position
Some parameters support retrieval by beam scan position. In these cases, calling
>>> c.get_p(rx,ry)
will return the value of parameter p at beam position (rx,ry). This works only for the above syntax. Using either of
>>> c.p >>> c['p']
will return an R-space shaped array.
Trigger downstream calibrations
Some objects store their own internal calibration state, which depends on the calibrations stored here. For example, a DataCube stores dimension vectors which calibrate its 4 dimensions, and which depend on the pixel sizes and the origin position.
Modifying certain parameters therefore can trigger other objects which depend on these parameters to re-calibrate themselves by calling their .calibrate() method, if the object has one. Methods marked with a * in the list l above have this property. Only objects registered with the Calibration instance will have their .calibrate method triggered by changing these parameters. An object data can be registered by calling
>>> c.register_target( data )
and deregistered with
>>> c.deregister_target( data )
If an object without a .calibrate method is registerd when a * method is called, nothing happens.
The .calibrate methods are triggered by setting some parameter p using either
>>> c.set_p( val )
or
>>> c.p = val
syntax. Setting the parameter with
>>> c['p'] = val
will not trigger re-calibrations.
Calibration + Data
Data in py4DSTEM is stored in filetree like representations, and Calibration instances are the top-level objects in these trees, in that they live here:
- Root
|–metadata | |– *—> calibration <—* | |–some_object(e.g.datacube) | |–another_object(e.g.max_dp) | |–etc. |–etc. :
Every py4DSTEM Data object has a tree with a calibration, and calling
>>> data.calibration
will return the that Calibration instance. See also the docstring for the Data class.
Attaching an object to a different Calibration
To modify the calibration associated with some object data, use
>>> c.attach( data )
where c is the new calibration instance. This (1) moves data into the top level of c’s data tree, which means the new calibration will now be accessible normally at
>>> data.calibration
and (2) if and only if data was registered with its old calibration, de-registers it there and registers it with the new calibration. If data was not registered with the old calibration and it should be registered with the new one, c.register_target( data ) should be called.
To attach data to a different location in the calibration instance’s tree, use node.attach( data ). See the Data.attach docstring.
- __init__(name: str | None = 'calibration', root: Root | None = None)
- Parameters:
name (optional, str) –
- attach(data)
Attach data to this calibration instance, placing it in the top level of the Calibration instance’s tree. If data was in a different data tree, remove it. If data was registered with a different calibration instance, de-register it there and register it here. If data was not previously registerd and it should be, after attaching it run self.register_target(data).
- register_target(new_target)
Register an object to recieve calls to it calibrate method when certain calibrations get updated
- unregister_target(target)
Unlink an object from recieving calls to calibrate when certain calibration values are changed
- set_origin_meas(x)
- Parameters:
x (2-tuple or 3 uple of 2D R-shaped arrays) – qx0,qy0,[mask]
- set_probe_param(x)
- Parameters:
x (3-tuple) – (probe size, x0, y0)
- to_h5(group)
Saves the metadata dictionary _params to group, then adds the calibration’s target’s list
- classmethod from_h5(group)
Takes a valid group for an HDF5 file object which is open in read mode. Determines if it’s a valid Metadata representation, and if so loads and returns it as a Calibration instance. Otherwise, raises an exception.
- Accepts:
group (HDF5 group)
- Returns:
A Calibration instance
Custom
- class py4DSTEM.Custom(name='custom')
- __init__(name='custom')
- to_h5(group)
Constructs an h5 group, adds metadata, and adds all attributes which point to EMD nodes.
- Accepts:
group (h5py Group)
- Returns:
(h5py Group) the new node’s Group
- add_to_tree(node)
Add an unrooted node as a child of the current, rooted node. To move an already rooted node/branch, use .graft(). To create a rooted node, use Root().
- cut_from_tree(root_metadata=True)
Removes a branch from an object tree at this node.
A new root node is created under this object with this object’s name. Metadata from the current root is transferred/not transferred to the new root according to the value of root_metadata.
- Accepts:
- root_metadata (True, False, or ‘copy’): if True adds the old root’s
metadata to the new root; if False adds no metadata to the new root; if ‘copy’ adds copies of all metadata from the old root to the new root.
- Returns:
(Node) the new root node
- force_add_to_tree(node)
Add node node as a child of the current node, whether or not node is rooted. If it’s unrooted, performs a simple add. If it is rooted, performs a graft, excluding the root metadata from node.
- classmethod from_h5(group)
Takes an h5py Group which is open in read mode. Confirms that a a Node of this name exists in this group, and loads and returns it with it’s metadata.
- Accepts:
group (h5py Group)
- Returns:
(Node)
- get_from_tree(name)
Finds and returns an object from an EMD tree using the string key name, with ‘/’ delimiters between ‘parent/child’ nodes. Search from the root node by adding a leading ‘/’; otherwise, searches from the current node.
- graft(node, merge_metadata=True)
Moves the branch beginning node onto this tree at this node.
For the reverse (i.e. grafting from this tree onto another tree) either use that tree’s .graft method, or use this tree’s ._graft.
- Accepts:
node (Node): merge_metadata (True, False, or ‘copy’): if True adds the old root’s
metadata to the new root; if False adds no metadata to the new root; if ‘copy’ adds copies of all metadata from the old root to the new root.
- Returns:
(Node) this tree’s root node
- static newnode(method)
Decorator which may be added to node methods which product and return a new node. If such a method is decorated with
>>> @newnode
then the new node is added to the parent node’s tree, and a Metadata instance is added to the new node’s metadata which stores information about how the node was created, namely: method’s name, the parent’s class and name, and all the arguments passed to method.
- show_tree(root=False)
Display the object tree. If root is False, displays the branch of the tree downstream from this node. If root is True, displays the full tree from the root node.
- tree(arg=None, **kwargs)
Usages -
>>> .tree() # show tree from current node >>> .tree(show=True) # show from root >>> .tree(show=False) # show from current node >>> .tree(add=node) # add a child node >>> .tree(get='path') # return a '/' delimited child node >>> .tree(get='/path') # as above, starting at root >>> .tree(cut=True) # remove/return a branch, keep root metadata >>> .tree(cut=False) # remove/return a branch, discard root md >>> .tree(cut='copy') # remove/return a branch, copy root metadata >>> .tree(graft=node) # remove/graft a branch, keeping root metadata >>> .tree(graft=(node,True)) # as above >>> .tree(graft=(node,False)) # as above, discard root metadata >>> .tree(graft=(node,'copy')) # as above, copy root metadata
The show, add, and get methods can be accessed directly with
>>> .tree(arg)
for an arg of the appropriate type (bool, Node, and string).
Data
- class py4DSTEM.Data(calibration=None)
The purpose of the Data class is to ensure calibrations are linked to data containing class instances, while allowing multiple objects to share a single Calibration. The calibrations of a Data instance data is accessible as
>>> data.calibration
In py4DSTEM, Data containing objects are stored internally in filetree like representations, defined by the EMD1.0 and emdfile specifications, e.g.
- Root
|–metadata | |–calibration | |–some_object(e.g.datacube) | |–another_object(e.g.max_dp) | |–etc. | |–one_more_object(e.g.crystal) | |–etc. :
Calibrations are metadata which always live in the root of such a tree. Running data.calibration returns the calibrations from the tree root, and therefore the same calibration instance is referred to be all objects in the same tree. The root itself is accessible from any Data instance as
>>> data.root
To examine the tree of a Data instance, in a Python interpreter do
>>> data.tree(True)
to display the whole data tree, and
>>> data.tree()
to display the tree of from the current node on, i.e. the branch downstream of data.
Calling
>>> data.calibration
will raise a warning and return None if no root calibrations are found.
Some objects should be modified when the calibrations change - these objects must have .calibrate() method, which is called any time relevant calibration parameters change if the object has been registered with the calibrations.
To transfer data from it’s current tree to another existing tree, use
>>> data.attach(some_other_data)
which will move the data to the new tree. If the data was registered with it’s old calibrations, this will also de-register it there and register it with the new calibrations such that .calibrate() is called when it should be.
See also the Calibration docstring.
- __init__(calibration=None)
- attach(node)
Attach node to the current object’s tree, attaching calibration and detaching calibrations as needed.
DataCube
- class py4DSTEM.DataCube(data: ndarray, name: str | None = 'datacube', slicelabels: bool | list | None = None, calibration: Calibration | None = None)
Storage and processing methods for 4D-STEM datasets.
- __init__(data: ndarray, name: str | None = 'datacube', slicelabels: bool | list | None = None, calibration: Calibration | None = None)
- Accepts:
data (np.ndarray): the data name (str): the name of the datacube calibration (None or Calibration or ‘pass’): default (None)
creates and attaches a new Calibration instance to root metadata, or, passing a Calibration instance uses this instead.
- slicelabels (None or list): names for slices if this is a
stack of datacubes
- Returns:
A new DataCube instance.
- calibrate()
Calibrate the coordinate axes of the datacube. Using the calibrations at self.calibration, sets the 4 dim vectors (Qx,Qy,Rx,Ry) according to the pixel size, units and origin positions, then updates the meshgrids representing Q and R space.
- copy()
Copys datacube
- add(data, name='')
Adds a block of data to the DataCube’s tree. If data is an instance of an EMD/py4DSTEM class, add it to the tree. If it’s a numpy array, turn it into an Array instance, then save to the tree.
- set_scan_shape(Rshape)
Reshape the data given the real space scan shape.
- Accepts:
Rshape (2-tuple)
- swap_RQ()
Swaps the first and last two dimensions of the 4D datacube.
- swap_Rxy()
Swaps the real space x and y coordinates.
- swap_Qxy()
Swaps the diffraction space x and y coordinates.
- crop_Q(ROI)
Crops the data in diffraction space about the region specified by ROI.
- Accepts:
ROI (4-tuple): Specifies (Qx_min,Qx_max,Qy_min,Qy_max)
- crop_R(ROI)
Crops the data in real space about the region specified by ROI.
- Accepts:
ROI (4-tuple): Specifies (Rx_min,Rx_max,Ry_min,Ry_max)
- bin_Q(N, dtype=None)
Bins the data in diffraction space by bin factor N
- Parameters:
N (int) – The binning factor
dtype (a datatype (optional)) – Specify the datatype for the output. If not passed, the datatype is left unchanged
- Returns:
datacube
- Return type:
- pad_Q(N=None, output_size=None)
Pads the data in diffraction space by pad factor N, or to match output_size.
- Accepts:
N (float, or Sequence[float]): the padding factor output_size ((int,int)): the padded output size
- resample_Q(N=None, output_size=None, method='bilinear', conserve_array_sums=False)
Resamples the data in diffraction space by resampling factor N, or to match output_size, using either ‘fourier’ or ‘bilinear’ interpolation.
- Accepts:
N (float, or Sequence[float]): the resampling factor output_size ((int,int)): the resampled output size method (str): ‘fourier’ or ‘bilinear’ (default)
- bin_Q_mmap(N, dtype=<class 'numpy.float32'>)
Bins the data in diffraction space by bin factor N for memory mapped data
- Accepts:
N (int): the binning factor dtype: the data type
- bin_R(N)
Bins the data in real space by bin factor N
- Accepts:
N (int): the binning factor
- thin_R(N)
Reduces the data in real space by skipping every N patterns in the x and y directions.
- Accepts:
N (int): the thinning factor
- filter_hot_pixels(thresh, ind_compare=1, return_mask=False)
This function performs pixel filtering to remove hot / bright pixels. We first compute a moving local ordering filter, applied to the mean diffraction image. This ordering filter will return a single value from the local sorted intensity values, given by ind_compare. ind_compare=0 would be the highest intensity, =1 would be the second hightest, etc. Next, a mask is generated for all pixels which are least a value thresh higher than the local ordering filter output. Finally, we loop through all diffraction images, and any pixels defined by mask are replaced by their 3x3 local median.
- Parameters:
datacube (DataCube) –
thresh (float) – threshold for replacing hot pixels, if pixel value minus local ordering filter exceeds it.
ind_compare (int) – which median filter value to compare against. 0 = brightest pixel, 1 = next brightest, etc.
return_mask (bool) – if True, returns the filter mask
- Returns:
datacube (DataCube) mask (optional, boolean Array) the bad pixel mask
- median_filter_masked_pixels(mask, kernel_width: int = 3)
This function fixes a datacube where the same pixels are consistently bad. It requires a mask that identifies all the bad pixels in the dataset. Then for each diffraction pattern, a median kernel is applied around each bad pixel with the specified width.
- get_vacuum_probe(ROI=None, align=True, mask=None, threshold=0.0, expansion=12, opening=3, verbose=False, returncalc=True)
Computes a vacuum probe.
Which diffraction patterns are included in the calculation is specified by the ROI parameter. Diffraction patterns are aligned before averaging if align is True (default). A global mask is applied to each diffraction pattern before aligning/averaging if mask is specified. After averaging, a final masking step is applied according to the parameters threshold, expansion, and opening.
- Parameters:
ROI (optional, boolean array or len 4 list/tuple) – If unspecified, uses the whole datacube. If a boolean array is passed must be real-space shaped, and True pixels are used. If a 4-tuple is passed, uses the region inside the limits (rx_min,rx_max,ry_min,ry_max)
align (optional, bool) – if True, aligns the probes before averaging
mask (optional, array) – mask applied to each diffraction pattern before alignment and averaging
threshold (float) – in the final masking step, values less than max(probe)*threshold are considered outside the probe
expansion (int) – number of pixels by which the final mask is expanded after thresholding
opening (int) – size of binary opening applied to the final mask to eliminate stray bright pixels
verbose (bool) – toggles verbose output
returncalc (bool) – if True, returns the answer
- Returns:
probe – the vacuum probe
- Return type:
Probe, optional
- get_probe_size(dp=None, thresh_lower=0.01, thresh_upper=0.99, N=100, plot=False, returncal=True, write_to_cal=True, **kwargs)
Gets the center and radius of the probe in the diffraction plane.
The algorithm is as follows: First, create a series of N binary masks, by thresholding the diffraction pattern DP with a linspace of N thresholds from thresh_lower to thresh_upper, measured relative to the maximum intensity in DP. Using the area of each binary mask, calculate the radius r of a circular probe. Because the central disk is typically very intense relative to the rest of the DP, r should change very little over a wide range of intermediate values of the threshold. The range in which r is trustworthy is found by taking the derivative of r(thresh) and finding identifying where it is small. The radius is taken to be the mean of these r values. Using the threshold corresponding to this r, a mask is created and the CoM of the DP times this mask it taken. This is taken to be the origin x0,y0.
- Parameters:
dp (str or array) – specifies the diffraction pattern in which to find the central disk. A position averaged, or shift-corrected and averaged, DP works best. If mode is None, the diffraction pattern stored in the tree from ‘get_dp_mean’ is used. If mode is a string it specifies the name of another virtual diffraction pattern in the tree. If mode is an array, the array is used to calculate probe size.
thresh_lower (float, 0 to 1) – the lower limit of threshold values
thresh_upper (float, 0 to 1) – the upper limit of threshold values
N (int) – the number of thresholds / masks to use
plot (bool) – if True plots results
plot_params (dict) – dictionary to modify defaults in plot
return_calc (bool) – if True returns 3-tuple described below
write_to_cal (bool) – if True, looks for a Calibration instance and writes the measured probe radius there
- Returns:
A 3-tuple containing:
r: (float) the central disk radius, in pixels
x0: (float) the x position of the central disk center
y0: (float) the y position of the central disk center
- Return type:
(3-tuple)
- find_Bragg_disks(template, data=None, radial_bksb=False, filter_function=None, corrPower=1, sigma=None, sigma_dp=0, sigma_cc=2, subpixel='multicorr', upsample_factor=16, minAbsoluteIntensity=0, minRelativeIntensity=0.005, relativeToPeak=0, minPeakSpacing=60, edgeBoundary=20, maxNumPeaks=70, CUDA=False, CUDA_batched=True, distributed=None, ML=False, ml_model_path=None, ml_num_attempts=1, ml_batch_size=8, name='braggvectors', returncalc=True)
Finds the Bragg disks in the diffraction patterns represented by data by cross/phase correlatin with template.
Behavior depends on data. If it is None (default), runs on the whole DataCube, and stores the output in its tree. Otherwise, nothing is stored in tree, but some value is returned. Valid entries are:
- a 2-tuple of numbers (rx,ry): run on this diffraction image,
and return a QPoints instance
- a 2-tuple of arrays (rx,ry): run on these diffraction images,
and return a list of QPoints instances
- an Rspace shapped 2D boolean array: run on the diffraction images
specified by the True counts and return a list of QPoints instances
For disk detection on a full DataCube, the calculation can be performed on the CPU, GPU or a cluster. By default the CPU is used. If CUDA is set to True, tries to use the GPU. If CUDA_batched is also set to True, batches the FFT/IFFT computations on the GPU. For distribution to a cluster, distributed must be set to a dictionary, with contents describing how distributed processing should be performed - see below for details.
For each diffraction pattern, the algorithm works in 4 steps:
any pre-processing is performed to the diffraction image. This is accomplished by passing a callable function to the argument filter_function, a bool to the argument radial_bksb, or a value >0 to sigma_dp. If none of these are passed, this step is skipped.
the diffraction image is cross correlated with the template. Phase/hybrid correlations can be used instead by setting the corrPower argument. Cross correlation can be skipped entirely, and the subsequent steps performed directly on the diffraction image instead of the cross correlation, by passing None to template.
the maxima of the cross correlation are located and their positions and intensities stored. The cross correlation may be passed through a gaussian filter first by passing the sigma_cc argument. The method for maximum detection can be set with the subpixel parameter. Options, from something like fastest/least precise to slowest/most precise are ‘pixel’, ‘poly’, and ‘multicorr’.
filtering is applied to remove untrusted or undesired positive counts, based on their intensity (minRelativeIntensity,`relativeToPeak`, minAbsoluteIntensity) their proximity to one another or the image edge (minPeakSpacing, edgeBoundary), and the total number of peaks per pattern (maxNumPeaks).
- Parameters:
template (2D array) – the vacuum probe template, in real space. For Probe instances, this is probe.kernel. If None, does not perform a cross correlation.
data (variable) – see above
radial_bksb (bool) – if True, computes a radial background given by the median of the (circular) polar transform of each each diffraction pattern, and subtracts this background from the pattern before applying any filter function and computing the cross correlation. The origin position must be set in the datacube’s calibrations. Currently only supported for full datacubes on the CPU.
filter_function (callable) – filtering function to apply to each diffraction pattern before peak finding. Must be a function of only one argument (the diffraction pattern) and return the filtered diffraction pattern. The shape of the returned DP must match the shape of the probe kernel (but does not need to match the shape of the input diffraction pattern, e.g. the filter can be used to bin the diffraction pattern). If using distributed disk detection, the function must be able to be pickled with by dill.
corrPower (float between 0 and 1, inclusive) – the cross correlation power. A value of 1 corresponds to a cross correlation, 0 corresponds to a phase correlation, and intermediate values correspond to hybrid correlations.
sigma (float) – alias for sigma_cc
sigma_dp (float) – if >0, a gaussian smoothing filter with this standard deviation is applied to the diffraction pattern before maxima are detected
sigma_cc (float) – if >0, a gaussian smoothing filter with this standard deviation is applied to the cross correlation before maxima are detected
subpixel (str) –
Whether to use subpixel fitting, and which algorithm to use. Must be in (‘none’,’poly’,’multicorr’).
’none’: performs no subpixel fitting
’poly’: polynomial interpolation of correlogram peaks (default)
’multicorr’: uses the multicorr algorithm with DFT upsampling
upsample_factor (int) – upsampling factor for subpixel fitting (only used when subpixel=’multicorr’)
minAbsoluteIntensity (float) – the minimum acceptable correlation peak intensity, on an absolute scale
minRelativeIntensity (float) – the minimum acceptable correlation peak intensity, relative to the intensity of the brightest peak
relativeToPeak (int) – specifies the peak against which the minimum relative intensity is measured – 0=brightest maximum. 1=next brightest, etc.
minPeakSpacing (float) – the minimum acceptable spacing between detected peaks
(int) (edgeBoundary) – the diffraction image edge, in pixels.
maxNumPeaks (int) – the maximum number of peaks to return
CUDA (bool) – If True, import cupy and use an NVIDIA GPU to perform disk detection
CUDA_batched (bool) – If True, and CUDA is selected, the FFT and IFFT steps of disk detection are performed in batches to better utilize GPU resources.
distributed (dict) –
contains information for parallel processing using an IPyParallel or Dask distributed cluster. Valid keys are:
ipyparallel (dict):
- client_file (str): path to client json for connecting to your
existing IPyParallel cluster
- dask (dict): client (object): a dask client that connects to
your existing Dask cluster
- data_file (str): the absolute path to your original data
file containing the datacube
- cluster_path (str): defaults to the working directory during
processing
if distributed is None, which is the default, processing will be in serial
name (str) – name for the output BraggVectors
returncalc (bool) – if True, returns the answer
- Returns:
See above.
- Return type:
variable
- get_beamstop_mask(threshold=0.25, distance_edge=2.0, include_edges=True, sigma=0, use_max_dp=False, scale_radial=None, name='mask_beamstop', returncalc=True)
This function uses the mean diffraction pattern plus a threshold to create a beamstop mask.
- Parameters:
threshold (float) – Value from 0 to 1 defining initial threshold for beamstop mask, taken from the sorted intensity values - 0 is the dimmest pixel, while 1 uses the brighted pixels.
distance_edge (float) – How many pixels to expand the mask.
include_edges (bool) – If set to True, edge pixels will be included in the mask.
sigma (float) – Gaussain blur std to apply to image before thresholding.
use_max_dp (bool) – Use the max DP instead of the mean DP.
scale_radial (float) – Scale from center of image by this factor (can help with edge)
name (string) – Name of the output array.
returncalc (bool) – Set to true to return the result.
- Returns:
if returncalc is True, returns the beamstop mask
- Return type:
(Optional)
- get_radial_bkgrnd(rx, ry, sigma=2)
Computes and returns a background image for the diffraction pattern at (rx,ry), populated by radial rings of constant intensity about the origin, with the value of each ring given by the median value of the diffraction pattern at that radial distance.
- Parameters:
rx (int) – The x-coord of the beam position
ry (int) – The y-coord of the beam position
sigma (number) – If >0, applying a gaussian smoothing in the radial direction before returning
- Returns:
background – The radial background
- Return type:
ndarray
- get_radial_bksb_dp(rx, ry, sigma=2)
Computes and returns the diffraction pattern at beam position (rx,ry) with a radial background subtracted. See the docstring for datacube.get_radial_background for more info.
- Parameters:
rx (int) – The x-coord of the beam position
ry (int) – The y-coord of the beam position
sigma (number) – If >0, applying a gaussian smoothing in the radial direction before returning
- Returns:
data – The radial background subtracted diffraction image
- Return type:
ndarray
- get_local_ave_dp(rx, ry, radial_bksb=False, sigma=2, braggmask=False, braggvectors=None, braggmask_radius=None)
Computes and returns the diffraction pattern at beam position (rx,ry) after weighted local averaging with its nearest-neighbor patterns, using a 3x3 gaussian kernel for the weightings.
- Parameters:
rx (int) – The x-coord of the beam position
ry (int) – The y-coord of the beam position
radial_bksb (bool) – It True, apply a radial background subtraction to each pattern before averaging
sigma (number) – If radial_bksb is True, use this sigma for radial smoothing of the background
braggmask (bool) – If True, masks bragg scattering at each scan position before averaging. braggvectors and braggmask_radius must be specified.
braggvectors (BraggVectors) – The Bragg vectors to use for masking
braggmask_radius (number) – The radius about each Bragg point to mask
- Returns:
data – The radial background subtracted diffraction image
- Return type:
ndarray
- get_braggmask(braggvectors, rx, ry, radius)
Returns a boolean mask which is False in a radius of radius around each bragg scattering vector at scan position (rx,ry).
- Parameters:
braggvectors (BraggVectors) – The bragg vectors
rx (int) – The x-coord of the beam position
ry (int) – The y-coord of the beam position
radius (number) – mask pixels about each bragg vector to this radial distance
- Returns:
mask
- Return type:
boolean ndarray
- add_to_tree(node)
Add an unrooted node as a child of the current, rooted node. To move an already rooted node/branch, use .graft(). To create a rooted node, use Root().
- attach(node)
Attach node to the current object’s tree, attaching calibration and detaching calibrations as needed.
- cut_from_tree(root_metadata=True)
Removes a branch from an object tree at this node.
A new root node is created under this object with this object’s name. Metadata from the current root is transferred/not transferred to the new root according to the value of root_metadata.
- Accepts:
- root_metadata (True, False, or ‘copy’): if True adds the old root’s
metadata to the new root; if False adds no metadata to the new root; if ‘copy’ adds copies of all metadata from the old root to the new root.
- Returns:
(Node) the new root node
- dim(n)
Return the n’th dim vector
- force_add_to_tree(node)
Add node node as a child of the current node, whether or not node is rooted. If it’s unrooted, performs a simple add. If it is rooted, performs a graft, excluding the root metadata from node.
- classmethod from_h5(group)
Takes an h5py Group which is open in read mode. Confirms that a a Node of this name exists in this group, and loads and returns it with it’s metadata.
- Accepts:
group (h5py Group)
- Returns:
(Node)
- static get_calibrated_detector_geometry(calibration, mode, geometry, centered, calibrated)
Determine the detector geometry in pixels, given some mode and geometry in calibrated units, where the calibration state is specified by { centered, calibrated}
- Parameters:
calibration (Calibration) – Used to retrieve the center positions. If None, confirms that centered and calibrated are False then passes, otherwise raises an exception
mode (str) – see the DataCube.get_virtual_image docstring
geometry (variable) – see the DataCube.get_virtual_image docstring
centered (bool) – see the DataCube.get_virtual_image docstring
calibrated (bool) – see the DataCube.get_virtual_image docstring
- Returns:
geo – the geometry in detector pixels
- Return type:
tuple
- get_dim(n)
Return the n’th dim vector
- get_dim_name(n)
Get the n’th dim vector name
- get_dim_units(n)
Return the n’th dim vector units
- get_dp_max(returncalc=True)
Calculates the max diffraction pattern.
Calls DataCube.get_virtual_diffraction - see that method’s docstring for more custimizable virtual diffraction.
- Parameters:
returncalc (bool) – toggles returning the answer
- Returns:
max_dp
- Return type:
- get_dp_mean(returncalc=True)
Calculates the mean diffraction pattern.
Calls DataCube.get_virtual_diffraction - see that method’s docstring for more custimizable virtual diffraction.
- Parameters:
returncalc (bool) – toggles returning the answer
- Returns:
mean_dp
- Return type:
- get_dp_median(returncalc=True)
Calculates the max diffraction pattern.
Calls DataCube.get_virtual_diffraction - see that method’s docstring for more custimizable virtual diffraction.
- Parameters:
returncalc (bool) – toggles returning the answer
- Returns:
max_dp
- Return type:
- get_from_tree(name)
Finds and returns an object from an EMD tree using the string key name, with ‘/’ delimiters between ‘parent/child’ nodes. Search from the root node by adding a leading ‘/’; otherwise, searches from the current node.
- get_virtual_diffraction(method, mask=None, shift_center=False, subpixel=False, verbose=True, name='virtual_diffraction', returncalc=True)
Function to calculate virtual diffraction images.
- Parameters:
method (str) – defines method used for averaging/combining diffraction patterns. Options are (‘mean’, ‘median’, ‘max’)
mask (None or 2D array) – if None (default), all pixels are used. Otherwise, must be a boolean or floating point or complex array with the same shape as real space. For bool arrays, only True pixels are used in the computation. Otherwise a weighted average is performed.
shift_center (bool) – toggles shifting the diffraction patterns to account for beam shift. Currently only supported for ‘max’ and ‘mean’ modes. Default is False.
subpixel (bool) – if shift_center is True, toggles subpixel shifts via Fourier interpolation. Ignored if shift_center is False.
verbose (bool) – toggles progress bar
name (string) – name for the output DiffractionImage instance
returncalc (bool) – toggles returning the output
- Returns:
diff_im
- Return type:
DiffractionImage
- get_virtual_image(mode, geometry, centered=False, calibrated=False, shift_center=False, subpixel=False, verbose=True, dask=False, return_mask=False, name='virtual_image', returncalc=True, test_config=False)
Calculate a virtual image.
The detector is determined by the combination of the mode and geometry arguments, supporting point, circular, rectangular, annular, and custom mask detectors. The values passed to geometry may be given with respect to an origin at the corner of the detector array or with respect to the calibrated center position, and in units of pixels or real calibrated units, depending on the values of the centered and calibrated arguments, respectively. The mask may be shifted pattern-by-pattern to account for diffraction scan shifts using the shift_center argument.
The computed virtual image is stored in the datacube’s tree, and is also returned by default.
- Parameters:
mode (str) –
defines geometry mode for calculating virtual image, and the expected input for the geometry argument. options:
’point’: uses a single pixel detector
’circle’, ‘circular’: uses a round detector, like bright field
’annular’, ‘annulus’: uses an annular detector, like dark field
’rectangle’, ‘square’, ‘rectangular’: uses rectangular detector
’mask’: any diffraction-space shaped 2D array, representing a flexible detector
geometry (variable) –
the expected value of this argument is determined by mode as follows:
’point’: 2-tuple, (qx,qy), ints
’circle’, ‘circular’: nested 2-tuple, ((qx,qy),radius),
’annular’, ‘annulus’: nested 2-tuple, ((qx,qy),(radius_i,radius_o)),
’rectangle’, ‘square’, ‘rectangular’: 4-tuple, (xmin,xmax,ymin,ymax)
- mask: any boolean or floating point 2D array with the same
size as datacube.Qshape
centered (bool) – if False, the origin is in the upper left corner. If True, the origin is set to the mean origin in the datacube calibrations, so that a bright-field image could be specified with, e.g., geometry=((0,0),R). The origin can set with datacube.calibration.set_origin(). For mode=”mask”, has no effect. Default is False.
calibrated (bool) – if True, geometry is specified in units of ‘A^-1’ instead of pixels. The datacube’s calibrations must have its “Q_pixel_units” parameter set to “A^-1”. For mode=”mask”, has no effect. Default is False.
shift_center (bool) – if True, the mask is shifted at each real space position to account for any shifting of the origin of the diffraction images. The datacube’s calibration[‘origin’] parameter must be set. The shift applied to each pattern is the difference between the local origin position and the mean origin position over all patterns, rounded to the nearest integer for speed. Default is False. If shift_center is True, centered is automatically set to True.
subpixel (bool) – if True, applies subpixel shifts to virtual image
verbose (bool) – toggles a progress bar
dask (bool) – if True, use dask to distribute the calculation
return_mask (bool) – if False (default) returns a virtual image as usual. Otherwise does not compute or return a virtual image, instead finding and returning the mask that will be used in subsequent calls to this function using these same parameters. In this case, must be either True or a 2-tuple of integers corresponding to (rx,ry). If True is passed, returns the mask used if shift_center is set to False. If a 2-tuple is passed, returns the mask used at scan position (rx,ry) if shift_center is set to True. Nothing is added to the datacube’s tree.
name (str) – the output object’s name
returncalc (bool) – if True, returns the output
test_config (bool) – if True, prints the Boolean values of (centered,`calibrated`,`shift_center`). Does not compute the virtual image.
- Returns:
virt_im
- Return type:
VirtualImage (optional, if returncalc is True)
- graft(node, merge_metadata=True)
Moves the branch beginning node onto this tree at this node.
For the reverse (i.e. grafting from this tree onto another tree) either use that tree’s .graft method, or use this tree’s ._graft.
- Accepts:
node (Node): merge_metadata (True, False, or ‘copy’): if True adds the old root’s
metadata to the new root; if False adds no metadata to the new root; if ‘copy’ adds copies of all metadata from the old root to the new root.
- Returns:
(Node) this tree’s root node
- make_bragg_mask(Qshape, g1, g2, radius, origin, max_q, return_sum=True, include_origin=True, rotation_deg=0, **kwargs)
Creates and returns a mask consisting of circular disks about the points of a 2D lattice.
- Parameters:
Qshape (2 tuple) – the shape of diffraction space
g1 (len 2 array or tuple) – the lattice vectors
g2 (len 2 array or tuple) – the lattice vectors
radius (number) – the disk radius
origin (len 2 array or tuple) – the origin
max_q (nuumber) – the maxima distance to tile to
return_sum (bool) – if False, return a 3D array, where each slice contains a single disk; if False, return a single 2D masks of all disks
include_origin (bool) – if False, removes origin disk
rotation_deg (float) – rotate g1 and g2 vectors
- Returns:
(2 or 3D array) the mask
- static make_detector(shape, mode, geometry)
Generate a 2D mask representing a detector function.
- Parameters:
shape (2-tuple) – defines shape of mask. Should be the shape of diffraction space.
mode (str) – defines geometry mode for calculating virtual image. See the docstring for DataCube.get_virtual_image
geometry (variable) – defines geometry for calculating virtual image. See the docstring for DataCube.get_virtual_image
- Returns:
detector_mask
- Return type:
2d array
- static newnode(method)
Decorator which may be added to node methods which product and return a new node. If such a method is decorated with
>>> @newnode
then the new node is added to the parent node’s tree, and a Metadata instance is added to the new node’s metadata which stores information about how the node was created, namely: method’s name, the parent’s class and name, and all the arguments passed to method.
- position_detector(mode, geometry, data=None, centered=None, calibrated=None, shift_center=False, subpixel=True, scan_position=None, invert=False, color='r', alpha=0.7, **kwargs)
Position a virtual detector by displaying a mask over a diffraction space image. Calling .get_virtual_image() using the same mode and geometry parameters will compute a virtual image using this detector.
- Parameters:
mode (str) – see the DataCube.get_virtual_image docstring
geometry (variable) – see the DataCube.get_virtual_image docstring
data (None or 2d-array or 2-tuple of ints) – The diffraction image to overlay the mask on. If None (default), looks for a max or mean or median diffraction image in this order and if found, uses it, otherwise, uses the diffraction pattern at scan position (0,0). If a 2d array is passed, must be diffraction space shaped array. If a 2-tuple is passed, uses the diffraction pattern at scan position (rx,ry).
centered (bool) – see the DataCube.get_virtual_image docstring
calibrated (bool) – see the DataCube.get_virtual_image docstring
shift_center (None or bool or 2-tuple of ints) – If None (default) and data is either None or an array, the mask is not shifted. If None and data is a 2-tuple, shifts the mask according to the origin at the scan position (rx,ry) specified in data. If False, does not shift the mask. If True and data is a 2-tuple, shifts the mask accordingly, and if True and data is any other value, raises an error. If shift_center is a 2-tuple, shifts the mask according to the origin value at this 2-tuple regardless of the value of data (enabling e.g. overlaying the mask for a specific scan position on a max or mean diffraction image.)
subpixel (bool) – if True, applies subpixel shifts to virtual image
invert (bool) – if True, invert the masked pixel (i.e. pixels outside the detector are overlaid with a mask)
color (any matplotlib color specification) – the mask color
alpha (number) – the mask transparency
kwargs (dict) – Any additional arguments are passed on to the show() function
- set_dim(n: int, dim: list | ndarray, units: str | None = None, name: str | None = None)
Sets the n’th dim vector, using dim as described in the Array documentation. If units and/or name are passed, sets these values for the n’th dim vector.
- Accepts:
n (int): specifies which dim vector dim (list or array): length must be either 2, or equal to the
length of the n’th axis of the data array
units (Optional, str): name: (Optional, str):
- set_dim_name(n: int, name: str)
Sets the n’th dim vector name to name.
- Accepts:
n (int): specifies which dim vector name (str): new name
- set_dim_units(n: int, units: str)
Sets the n’th dim vector units to units.
- Accepts:
n (int): specifies which dim vector units (str): new units
- show_tree(root=False)
Display the object tree. If root is False, displays the branch of the tree downstream from this node. If root is True, displays the full tree from the root node.
- to_h5(group)
Takes an h5py Group instance and creates a subgroup containing this Array, tags indicating its EMD type and Python class, and the array’s data and metadata.
- Accepts:
group (h5py Group)
- Returns:
(h5py Group) the new array’s Group
- tree(arg=None, **kwargs)
Usages -
>>> .tree() # show tree from current node >>> .tree(show=True) # show from root >>> .tree(show=False) # show from current node >>> .tree(add=node) # add a child node >>> .tree(get='path') # return a '/' delimited child node >>> .tree(get='/path') # as above, starting at root >>> .tree(cut=True) # remove/return a branch, keep root metadata >>> .tree(cut=False) # remove/return a branch, discard root md >>> .tree(cut='copy') # remove/return a branch, copy root metadata >>> .tree(graft=node) # remove/graft a branch, keeping root metadata >>> .tree(graft=(node,True)) # as above >>> .tree(graft=(node,False)) # as above, discard root metadata >>> .tree(graft=(node,'copy')) # as above, copy root metadata
The show, add, and get methods can be accessed directly with
>>> .tree(arg)
for an arg of the appropriate type (bool, Node, and string).
DiffractionSlice
- class py4DSTEM.DiffractionSlice(data: ndarray, name: str | None = 'diffractionslice', units: str | None = 'intensity', slicelabels: bool | list | None = None, calibration=None)
Stores a diffraction-space shaped 2D data array.
- __init__(data: ndarray, name: str | None = 'diffractionslice', units: str | None = 'intensity', slicelabels: bool | list | None = None, calibration=None)
- Accepts:
data (np.ndarray): the data name (str): the name of the diffslice units (str): units of the pixel values slicelabels(None or list): names for slices if this is a 3D stack
- Returns:
(DiffractionSlice instance)
- add_to_tree(node)
Add an unrooted node as a child of the current, rooted node. To move an already rooted node/branch, use .graft(). To create a rooted node, use Root().
- attach(node)
Attach node to the current object’s tree, attaching calibration and detaching calibrations as needed.
- cut_from_tree(root_metadata=True)
Removes a branch from an object tree at this node.
A new root node is created under this object with this object’s name. Metadata from the current root is transferred/not transferred to the new root according to the value of root_metadata.
- Accepts:
- root_metadata (True, False, or ‘copy’): if True adds the old root’s
metadata to the new root; if False adds no metadata to the new root; if ‘copy’ adds copies of all metadata from the old root to the new root.
- Returns:
(Node) the new root node
- dim(n)
Return the n’th dim vector
- force_add_to_tree(node)
Add node node as a child of the current node, whether or not node is rooted. If it’s unrooted, performs a simple add. If it is rooted, performs a graft, excluding the root metadata from node.
- classmethod from_h5(group)
Takes an h5py Group which is open in read mode. Confirms that a a Node of this name exists in this group, and loads and returns it with it’s metadata.
- Accepts:
group (h5py Group)
- Returns:
(Node)
- get_dim(n)
Return the n’th dim vector
- get_dim_name(n)
Get the n’th dim vector name
- get_dim_units(n)
Return the n’th dim vector units
- get_from_tree(name)
Finds and returns an object from an EMD tree using the string key name, with ‘/’ delimiters between ‘parent/child’ nodes. Search from the root node by adding a leading ‘/’; otherwise, searches from the current node.
- graft(node, merge_metadata=True)
Moves the branch beginning node onto this tree at this node.
For the reverse (i.e. grafting from this tree onto another tree) either use that tree’s .graft method, or use this tree’s ._graft.
- Accepts:
node (Node): merge_metadata (True, False, or ‘copy’): if True adds the old root’s
metadata to the new root; if False adds no metadata to the new root; if ‘copy’ adds copies of all metadata from the old root to the new root.
- Returns:
(Node) this tree’s root node
- static newnode(method)
Decorator which may be added to node methods which product and return a new node. If such a method is decorated with
>>> @newnode
then the new node is added to the parent node’s tree, and a Metadata instance is added to the new node’s metadata which stores information about how the node was created, namely: method’s name, the parent’s class and name, and all the arguments passed to method.
- set_dim(n: int, dim: list | ndarray, units: str | None = None, name: str | None = None)
Sets the n’th dim vector, using dim as described in the Array documentation. If units and/or name are passed, sets these values for the n’th dim vector.
- Accepts:
n (int): specifies which dim vector dim (list or array): length must be either 2, or equal to the
length of the n’th axis of the data array
units (Optional, str): name: (Optional, str):
- set_dim_name(n: int, name: str)
Sets the n’th dim vector name to name.
- Accepts:
n (int): specifies which dim vector name (str): new name
- set_dim_units(n: int, units: str)
Sets the n’th dim vector units to units.
- Accepts:
n (int): specifies which dim vector units (str): new units
- show_tree(root=False)
Display the object tree. If root is False, displays the branch of the tree downstream from this node. If root is True, displays the full tree from the root node.
- to_h5(group)
Takes an h5py Group instance and creates a subgroup containing this Array, tags indicating its EMD type and Python class, and the array’s data and metadata.
- Accepts:
group (h5py Group)
- Returns:
(h5py Group) the new array’s Group
- tree(arg=None, **kwargs)
Usages -
>>> .tree() # show tree from current node >>> .tree(show=True) # show from root >>> .tree(show=False) # show from current node >>> .tree(add=node) # add a child node >>> .tree(get='path') # return a '/' delimited child node >>> .tree(get='/path') # as above, starting at root >>> .tree(cut=True) # remove/return a branch, keep root metadata >>> .tree(cut=False) # remove/return a branch, discard root md >>> .tree(cut='copy') # remove/return a branch, copy root metadata >>> .tree(graft=node) # remove/graft a branch, keeping root metadata >>> .tree(graft=(node,True)) # as above >>> .tree(graft=(node,False)) # as above, discard root metadata >>> .tree(graft=(node,'copy')) # as above, copy root metadata
The show, add, and get methods can be accessed directly with
>>> .tree(arg)
for an arg of the appropriate type (bool, Node, and string).
Metadata
- class py4DSTEM.Metadata(name: str | None = 'metadata', data: dict | None = None)
Stores metadata in the form of a flat (non-nested) dictionary. Keys are arbitrary strings. Values may be strings, numbers, arrays, or lists of the above types.
Usage:
>>> meta = Metadata() >>> meta['param'] = value >>> val = meta['param']
If the parameter has not been set, the getter methods return None.
- __init__(name: str | None = 'metadata', data: dict | None = None)
- Parameters:
name (Optional, string) –
- copy(name=None)
- to_h5(group)
Accepts an h5py Group which is open in write or append mode. Writes a new group with this object’s name and saves its metadata in it.
- Accepts:
group (h5py Group)
- classmethod from_h5(group)
Accepts an h5py Group which is open in read mode, confirms that it represents an EMD MetadataDict group, then loads and returns it as a Metadata instance.
- Accepts:
group (HDF5 group)
- Returns:
(Metadata)
Node
- class py4DSTEM.Node(name: str | None = 'node')
Nodes contain attributes and methods paralleling the EMD 1.0 file specification in Python runtime objects.
EMD 1.0 is a singly-rooted file format. That is to say: An EMD data object can and must exist in one and only one EMD tree. An EMD file can contain any number of EMD trees, each containing data and metadata which is, within the limits of the EMD group specifications, of some arbitrary complexity. An EMD 1.0 file thus represents, stores, and enables access to some arbitrary data in long term storage on a file system in the form of an HDF5 file. The Node class provides machinery for building trees of data and metadata which mirror the EMD tree format but which exist in a live Python instance, rather than on the file system. This facilitates ease of transfer between Python and the file system.
Nodes are intended to be used a base class on which other, more complex classes can be biult. Nodes themselves contain the machinery for managing a tree heirarchy of other Nodes and Metadata instances, and for reading and writing those trees. They do not contain any particular data. Classes storing data and analysis methods which inherit from Node will inherit its tree management and EMD i/o functionality.
Below, the 4 elements of the node class are each described in turn: roots, trees, metadata, and i/o.
ROOTS
EMD data objects can and must exist in one and only one EMD tree, each of which must have a single, named root node. To parallel this in our runtime objects, each Node has a root property, which can be found by calling self.root.
By default new nodes have their root set to None. If a node with .root == None is saved to file, it is placed inside a new root with the same name as the object itself, and this is then saved to the file as a new (minimal) EMD tree.
A new root node can be instantiated by calling
>>> rootnode = Root(name=some_name).
Objects added to an existing rooted tree (including a new root node) automatically have their root assigned to the root of that tree. Adding objects to trees is discussed below.
TREES
The tree associated with a node can be manipulated with the .tree method. If we have some rooted node node1 and some unrooted node node2, the unrooted node can be added to the existing tree as a child of the rooted node with
>>> node1.tree(node2)
If we have a rooted node node1 and another rooted node node2, we can’t simply add node2 with the code above, as this would create a conflict between the two roots. In this case, we can move node2 from its current tree to the new tree using
>>> node1.tree(graft=node2)
The .tree method has various additional functionalities, including printing the tree, retrieving objects from the tree, and cutting branches from the tree. These are summarized below:
>>> .tree() # show tree from current node >>> .tree(show=True) # show from root >>> .tree(show=False) # show from current node >>> .tree(add=node) # add a child node >>> .tree(get='path') # return a '/' delimited child node >>> .tree(get='/path') # as above, starting at root >>> .tree(cut=True) # remove/return a branch, keep root metadata >>> .tree(cut=False) # remove/return a branch, discard root md >>> .tree(cut='copy') # remove/return a branch, copy root metadata >>> .tree(graft=node) # remove/graft a branch, keep root metadata >>> .tree(graft=(node,True)) # as above >>> .tree(graft=(node,False)) # as above, discard root metadata >>> .tree(graft=(node,'copy')) # as above, copy root metadata
The show, add, and get methods can be accessed directly with
>>> .tree(arg)
for an arg of the appropriate type (bool, Node, and string), i.e. in most cases, the keyword can be dropped. So
>>> .tree() >>> .tree(node) >>> .tree(True) >>> .tree('some/node')
will, respectively, print the tree from the current node to screen, add the node node to the tree, pring the tree from the root node to screen, and return the node at the emdpath ‘some/node’.
If a node needs to be added to a tree and it may or may not already have its own root, calling
>>> .tree(add=node, force=True)
or
>>> .tree(node, force=True)
will add the node to the tree, using a simple add if node has no root, and grafting it if it does have a root.
METADATA
Nodes can contain any number of Metadata instances, each of which wraps a Python dictionary of some arbitrary complexity (to within the limits of the Metadata group EMD specification, which limits permissible values somewhat).
The code:
>>> md1 = Metadata(name='md1') >>> md2 = Metadata(name='md2') >>> <<< some code populating md1 + md2 >>> >>> node.metadata = md1 >>> node.metadata = md2
will create two Metadata objects, populate them with data, then add them to the node. Note that Node.metadata is not a Python attribute, it is specially defined property, such that the last line of code does not overwrite the line before it - rather, assigning to the .metadata property adds the new metadata object to a running dictionary of arbitrarily many metadata objects. Both of these two metadata instances can therefore still be retrieved, using:
>>> x = node.metadata['md1'] >>> y = node.metadata['md2']
Note, however, that if the second metadata instance has an identical name to the first instance, then in will overwrite the old instance.
I/O
# TODO
- __init__(name: str | None = 'node')
- show_tree(root=False)
Display the object tree. If root is False, displays the branch of the tree downstream from this node. If root is True, displays the full tree from the root node.
- add_to_tree(node)
Add an unrooted node as a child of the current, rooted node. To move an already rooted node/branch, use .graft(). To create a rooted node, use Root().
- force_add_to_tree(node)
Add node node as a child of the current node, whether or not node is rooted. If it’s unrooted, performs a simple add. If it is rooted, performs a graft, excluding the root metadata from node.
- get_from_tree(name)
Finds and returns an object from an EMD tree using the string key name, with ‘/’ delimiters between ‘parent/child’ nodes. Search from the root node by adding a leading ‘/’; otherwise, searches from the current node.
- graft(node, merge_metadata=True)
Moves the branch beginning node onto this tree at this node.
For the reverse (i.e. grafting from this tree onto another tree) either use that tree’s .graft method, or use this tree’s ._graft.
- Accepts:
node (Node): merge_metadata (True, False, or ‘copy’): if True adds the old root’s
metadata to the new root; if False adds no metadata to the new root; if ‘copy’ adds copies of all metadata from the old root to the new root.
- Returns:
(Node) this tree’s root node
- cut_from_tree(root_metadata=True)
Removes a branch from an object tree at this node.
A new root node is created under this object with this object’s name. Metadata from the current root is transferred/not transferred to the new root according to the value of root_metadata.
- Accepts:
- root_metadata (True, False, or ‘copy’): if True adds the old root’s
metadata to the new root; if False adds no metadata to the new root; if ‘copy’ adds copies of all metadata from the old root to the new root.
- Returns:
(Node) the new root node
- tree(arg=None, **kwargs)
Usages -
>>> .tree() # show tree from current node >>> .tree(show=True) # show from root >>> .tree(show=False) # show from current node >>> .tree(add=node) # add a child node >>> .tree(get='path') # return a '/' delimited child node >>> .tree(get='/path') # as above, starting at root >>> .tree(cut=True) # remove/return a branch, keep root metadata >>> .tree(cut=False) # remove/return a branch, discard root md >>> .tree(cut='copy') # remove/return a branch, copy root metadata >>> .tree(graft=node) # remove/graft a branch, keeping root metadata >>> .tree(graft=(node,True)) # as above >>> .tree(graft=(node,False)) # as above, discard root metadata >>> .tree(graft=(node,'copy')) # as above, copy root metadata
The show, add, and get methods can be accessed directly with
>>> .tree(arg)
for an arg of the appropriate type (bool, Node, and string).
- static newnode(method)
Decorator which may be added to node methods which product and return a new node. If such a method is decorated with
>>> @newnode
then the new node is added to the parent node’s tree, and a Metadata instance is added to the new node’s metadata which stores information about how the node was created, namely: method’s name, the parent’s class and name, and all the arguments passed to method.
- classmethod from_h5(group)
Takes an h5py Group which is open in read mode. Confirms that a a Node of this name exists in this group, and loads and returns it with it’s metadata.
- Accepts:
group (h5py Group)
- Returns:
(Node)
- to_h5(group)
Takes an h5py Group instance and creates a subgroup containing this node, tags indicating the groups EMD type and Python class, and any metadata in this node.
- Accepts:
group (h5py Group)
- Returns:
(h5py Group) the new node’s Group
PointList
- class py4DSTEM.PointList(data: ndarray, name: str | None = 'pointlist')
A wrapper around structured numpy arrays, with read/write functionality in/out of EMD formatted HDF5 files.
- __init__(data: ndarray, name: str | None = 'pointlist')
Instantiate a PointList.
- Parameters:
data (structured numpy ndarray) – the data; the dtype of this array will specify the fields of the PointList.
name (str) – name for the PointList
- Returns:
a PointList instance
- add(data)
Appends a numpy structured array. Its dtypes must agree with the existing data.
- remove(mask)
Removes points wherever mask==True
- sort(field, order='ascending')
Sorts the point list according to field, which must be a field in self.dtype. order should be ‘descending’ or ‘ascending’.
- copy(name=None)
Returns a copy of the PointList. If name=None, sets to {name}_copy
- add_fields(new_fields, name='')
Creates a copy of the PointList, but with additional fields given by new_fields.
- Parameters:
new_fields – a list of 2-tuples, (‘name’, dtype)
name – a name for the new pointlist
- add_data_by_field(data, fields=None)
Add a list of data arrays to the PointList, in the fields given by fields. If fields is not specified, assumes the data arrays are in the same order as self.fields
- Parameters:
data (list) – arrays of data to add to each field
- add_to_tree(node)
Add an unrooted node as a child of the current, rooted node. To move an already rooted node/branch, use .graft(). To create a rooted node, use Root().
- cut_from_tree(root_metadata=True)
Removes a branch from an object tree at this node.
A new root node is created under this object with this object’s name. Metadata from the current root is transferred/not transferred to the new root according to the value of root_metadata.
- Accepts:
- root_metadata (True, False, or ‘copy’): if True adds the old root’s
metadata to the new root; if False adds no metadata to the new root; if ‘copy’ adds copies of all metadata from the old root to the new root.
- Returns:
(Node) the new root node
- force_add_to_tree(node)
Add node node as a child of the current node, whether or not node is rooted. If it’s unrooted, performs a simple add. If it is rooted, performs a graft, excluding the root metadata from node.
- classmethod from_h5(group)
Takes an h5py Group which is open in read mode. Confirms that a a Node of this name exists in this group, and loads and returns it with it’s metadata.
- Accepts:
group (h5py Group)
- Returns:
(Node)
- get_from_tree(name)
Finds and returns an object from an EMD tree using the string key name, with ‘/’ delimiters between ‘parent/child’ nodes. Search from the root node by adding a leading ‘/’; otherwise, searches from the current node.
- graft(node, merge_metadata=True)
Moves the branch beginning node onto this tree at this node.
For the reverse (i.e. grafting from this tree onto another tree) either use that tree’s .graft method, or use this tree’s ._graft.
- Accepts:
node (Node): merge_metadata (True, False, or ‘copy’): if True adds the old root’s
metadata to the new root; if False adds no metadata to the new root; if ‘copy’ adds copies of all metadata from the old root to the new root.
- Returns:
(Node) this tree’s root node
- static newnode(method)
Decorator which may be added to node methods which product and return a new node. If such a method is decorated with
>>> @newnode
then the new node is added to the parent node’s tree, and a Metadata instance is added to the new node’s metadata which stores information about how the node was created, namely: method’s name, the parent’s class and name, and all the arguments passed to method.
- show_tree(root=False)
Display the object tree. If root is False, displays the branch of the tree downstream from this node. If root is True, displays the full tree from the root node.
- tree(arg=None, **kwargs)
Usages -
>>> .tree() # show tree from current node >>> .tree(show=True) # show from root >>> .tree(show=False) # show from current node >>> .tree(add=node) # add a child node >>> .tree(get='path') # return a '/' delimited child node >>> .tree(get='/path') # as above, starting at root >>> .tree(cut=True) # remove/return a branch, keep root metadata >>> .tree(cut=False) # remove/return a branch, discard root md >>> .tree(cut='copy') # remove/return a branch, copy root metadata >>> .tree(graft=node) # remove/graft a branch, keeping root metadata >>> .tree(graft=(node,True)) # as above >>> .tree(graft=(node,False)) # as above, discard root metadata >>> .tree(graft=(node,'copy')) # as above, copy root metadata
The show, add, and get methods can be accessed directly with
>>> .tree(arg)
for an arg of the appropriate type (bool, Node, and string).
- to_h5(group)
Takes an h5py Group instance and creates a subgroup containing this PointList, tags indicating its EMD type and Python class, and the pointlist’s data and metadata.
- Accepts:
group (h5py Group)
- Returns:
(h5py Group) the new pointlist’s group
PointListArray
- class py4DSTEM.PointListArray(dtype, shape, name: str | None = 'pointlistarray')
An 2D array of PointLists which share common coordinates.
- __init__(dtype, shape, name: str | None = 'pointlistarray')
Creates an empty PointListArray.
- Parameters:
dtype – the dtype of the numpy structured arrays which will comprise the data of each PointList
shape (2-tuple of ints) – the shape of the array of PointLists
name (str) – a name for the PointListArray
- Returns:
a PointListArray instance
- get_pointlist(i, j, name=None)
Returns the pointlist at i,j
- copy(name='')
Returns a copy of itself.
- add_fields(new_fields, name='')
Creates a copy of the PointListArray, but with additional fields given by new_fields.
- Parameters:
new_fields – a list of 2-tuples, (‘name’, dtype)
name – a name for the new pointlist
- to_h5(group)
Takes an h5py Group instance and creates a subgroup containing this PointListArray, tags indicating its EMD type and Python class, and the pointlistarray’s data and metadata.
- Accepts:
group (h5py Group)
- Returns:
(h5py Group) the new pointlistarray’s group
- add_to_tree(node)
Add an unrooted node as a child of the current, rooted node. To move an already rooted node/branch, use .graft(). To create a rooted node, use Root().
- cut_from_tree(root_metadata=True)
Removes a branch from an object tree at this node.
A new root node is created under this object with this object’s name. Metadata from the current root is transferred/not transferred to the new root according to the value of root_metadata.
- Accepts:
- root_metadata (True, False, or ‘copy’): if True adds the old root’s
metadata to the new root; if False adds no metadata to the new root; if ‘copy’ adds copies of all metadata from the old root to the new root.
- Returns:
(Node) the new root node
- force_add_to_tree(node)
Add node node as a child of the current node, whether or not node is rooted. If it’s unrooted, performs a simple add. If it is rooted, performs a graft, excluding the root metadata from node.
- classmethod from_h5(group)
Takes an h5py Group which is open in read mode. Confirms that a a Node of this name exists in this group, and loads and returns it with it’s metadata.
- Accepts:
group (h5py Group)
- Returns:
(Node)
- get_from_tree(name)
Finds and returns an object from an EMD tree using the string key name, with ‘/’ delimiters between ‘parent/child’ nodes. Search from the root node by adding a leading ‘/’; otherwise, searches from the current node.
- graft(node, merge_metadata=True)
Moves the branch beginning node onto this tree at this node.
For the reverse (i.e. grafting from this tree onto another tree) either use that tree’s .graft method, or use this tree’s ._graft.
- Accepts:
node (Node): merge_metadata (True, False, or ‘copy’): if True adds the old root’s
metadata to the new root; if False adds no metadata to the new root; if ‘copy’ adds copies of all metadata from the old root to the new root.
- Returns:
(Node) this tree’s root node
- static newnode(method)
Decorator which may be added to node methods which product and return a new node. If such a method is decorated with
>>> @newnode
then the new node is added to the parent node’s tree, and a Metadata instance is added to the new node’s metadata which stores information about how the node was created, namely: method’s name, the parent’s class and name, and all the arguments passed to method.
- show_tree(root=False)
Display the object tree. If root is False, displays the branch of the tree downstream from this node. If root is True, displays the full tree from the root node.
- tree(arg=None, **kwargs)
Usages -
>>> .tree() # show tree from current node >>> .tree(show=True) # show from root >>> .tree(show=False) # show from current node >>> .tree(add=node) # add a child node >>> .tree(get='path') # return a '/' delimited child node >>> .tree(get='/path') # as above, starting at root >>> .tree(cut=True) # remove/return a branch, keep root metadata >>> .tree(cut=False) # remove/return a branch, discard root md >>> .tree(cut='copy') # remove/return a branch, copy root metadata >>> .tree(graft=node) # remove/graft a branch, keeping root metadata >>> .tree(graft=(node,True)) # as above >>> .tree(graft=(node,False)) # as above, discard root metadata >>> .tree(graft=(node,'copy')) # as above, copy root metadata
The show, add, and get methods can be accessed directly with
>>> .tree(arg)
for an arg of the appropriate type (bool, Node, and string).
Probe
- class py4DSTEM.Probe(data: ndarray, name: str | None = 'probe')
Stores a vacuum probe.
Both a vacuum probe and a kernel for cross-correlative template matching derived from that probe are stored and can be accessed at
>>> p.probe >>> p.kernel
respectively, for some Probe instance p. If a kernel has not been computed the latter expression returns None.
- __init__(data: ndarray, name: str | None = 'probe')
- Accepts:
- data (2D or 3D np.ndarray): the vacuum probe, or
the vacuum probe + kernel
name (str): a name
- Returns:
(Probe)
- classmethod from_vacuum_data(data, mask=None, threshold=0.2, expansion=12, opening=3)
Generates and returns a vacuum probe Probe instance from either a 2D vacuum image or a 3D stack of vacuum diffraction patterns.
The probe is multiplied by mask, if it’s passed. An additional masking step zeros values outside of a mask determined by threshold, expansion, and opening, generated by first computing the binary image probe < max(probe)*threshold, then applying a binary expansion and then opening to this image. No alignment is performed - i.e. it is assumed that the beam was stationary during acquisition of the stack. To align the images, use the DataCube .get_vacuum_probe method.
- Parameters:
data (2D or 3D array) – the vacuum diffraction data. For 3D stacks, use shape (N,Q_Nx,Q_Ny)
mask (boolean array, optional) – mask applied to the probe
threshold (float) – threshold determining mask which zeros values outside of probe
expansion (int) – number of pixels by which the zeroing mask is expanded to capture the full probe
opening (int) – size of binary opening used to eliminate stray bright pixels
- Returns:
probe – the vacuum probe
- Return type:
- classmethod generate_synthetic_probe(radius, width, Qshape)
Makes a synthetic probe, with the functional form of a disk blurred by a sigmoid (a logistic function).
- Parameters:
radius (float) – the probe radius
width (float) – the blurring of the probe edge. width represents the full width of the blur, with x=-w/2 to x=+w/2 about the edge spanning values of ~0.12 to 0.88
Qshape (2 tuple) – the diffraction plane dimensions
- Returns:
probe – the probe
- Return type:
- measure_disk(thresh_lower=0.01, thresh_upper=0.99, N=100, returncalc=True, data=None)
Finds the center and radius of an average probe image.
A naive algorithm. Creates a series of N binary masks by thresholding the probe image a linspace of N thresholds from thresh_lower to thresh_upper, relative to the image max/min. For each mask, we find the square root of the number of True valued pixels divided by pi to estimate a radius. Because the central disk is intense relative to the remainder of the image, the computed radii are expected to vary very little over a wider range threshold values. A range of r values considered trustworthy is estimated by taking the derivative r(thresh)/dthresh identifying where it is small, and the mean of this range is returned as the radius. A center is estimated using a binary thresholded image in combination with the center of mass operator.
- Parameters:
thresh_lower (float, 0 to 1) – the lower limit of threshold values
thresh_upper (float, 0 to 1)) – the upper limit of threshold values
N (int) – the number of thresholds / masks to use
returncalc (True) – toggles returning the answer
data (2d array, optional) – if passed, uses this 2D array in place of the probe image when performing the computation. This also supresses storing the results in the Probe’s calibration metadata
- Returns:
r, x0, y0 – the radius and origin
- Return type:
(3-tuple)
- get_kernel(mode='flat', origin=None, data=None, returncalc=True, **kwargs)
Creates a cross-correlation kernel from the vacuum probe.
Specific behavior and valid keyword arguments depend on the mode specified. In each case, the center of the probe is shifted to the origin and the kernel normalized such that it sums to 1. This is the only processing performed if mode is ‘flat’. Otherwise, a centrosymmetric region of negative intensity is added around the probe intended to promote edge-filtering-like behavior during cross correlation, with the functional form of the subtracted region defined by mode and the relevant **kwargs. For normalization, flat probes integrate to 1, and the remaining probes integrate to 1 before subtraction and 0 after. Required keyword arguments are:
‘flat’: No required arguments. This mode is recommended for bullseye or other structured probes
‘gaussian’: Required arg sigma (number), the width (standard deviation) of a centered gaussian to be subtracted.
‘sigmoid’: Required arg radii (2-tuple), the inner and outer radii (ri,ro) of an annular region with a sine-squared sigmoidal radial profile to be subtracted.
‘sigmoid_log’: Required arg radii (2-tuple), the inner and outer radii (ri,ro) of an annular region with a logistic sigmoidal radial profile to be subtracted.
- Parameters:
mode (str) – must be in ‘flat’,’gaussian’,’sigmoid’,’sigmoid_log’
origin (2-tuple, optional) – specify the origin. If not passed, looks for a value for the probe origin in metadata. If not found there, calls .measure_disk.
data (2d array, optional) – if specified, uses this array instead of the probe image to compute the kernel
**kwargs – see descriptions above
- Returns:
kernel
- Return type:
2D array
- static get_probe_kernel_flat(probe, origin=None, bilinear=False)
Creates a cross-correlation kernel from the vacuum probe by normalizing and shifting the center.
- Parameters:
probe (2d array) – the vacuum probe
origin (2-tuple (optional)) – the origin of diffraction space. If not specified, finds the origin using get_probe_radius.
bilinear (bool (optional)) – By default probe is shifted via a Fourier transform. Setting this to True overrides it and uses bilinear shifting. Not recommended!
- Returns:
kernel – the cross-correlation kernel corresponding to the probe, in real space
- Return type:
ndarray
- static get_probe_kernel_edge_gaussian(probe, sigma, origin=None, bilinear=True)
Creates a cross-correlation kernel from the probe, subtracting a gaussian from the normalized probe such that the kernel integrates to zero, then shifting the center of the probe to the array corners.
- Parameters:
probe (ndarray) – the diffraction pattern corresponding to the probe over vacuum
sigma (float) – the width of the gaussian to subtract, relative to the standard deviation of the probe
origin (2-tuple (optional)) – the origin of diffraction space. If not specified, finds the origin using get_probe_radius.
bilinear (bool) – By default probe is shifted via a Fourier transform. Setting this to True overrides it and uses bilinear shifting. Not recommended!
- Returns:
kernel – the cross-correlation kernel
- Return type:
ndarray
- static get_probe_kernel_edge_sigmoid(probe, radii, origin=None, type='sine_squared', bilinear=True)
Creates a convolution kernel from an average probe, subtracting an annular trench about the probe such that the kernel integrates to zero, then shifting the center of the probe to the array corners.
- Parameters:
probe (ndarray) – the diffraction pattern corresponding to the probe over vacuum
radii (2-tuple) – the sigmoid inner and outer radii
origin (2-tuple (optional)) – the origin of diffraction space. If not specified, finds the origin using get_probe_radius.
type (string) – must be ‘logistic’ or ‘sine_squared’
bilinear (bool) – By default probe is shifted via a Fourier transform. Setting this to True overrides it and uses bilinear shifting. Not recommended!
- Returns:
kernel – the cross-correlation kernel
- Return type:
2d array
- add_to_tree(node)
Add an unrooted node as a child of the current, rooted node. To move an already rooted node/branch, use .graft(). To create a rooted node, use Root().
- attach(node)
Attach node to the current object’s tree, attaching calibration and detaching calibrations as needed.
- cut_from_tree(root_metadata=True)
Removes a branch from an object tree at this node.
A new root node is created under this object with this object’s name. Metadata from the current root is transferred/not transferred to the new root according to the value of root_metadata.
- Accepts:
- root_metadata (True, False, or ‘copy’): if True adds the old root’s
metadata to the new root; if False adds no metadata to the new root; if ‘copy’ adds copies of all metadata from the old root to the new root.
- Returns:
(Node) the new root node
- dim(n)
Return the n’th dim vector
- force_add_to_tree(node)
Add node node as a child of the current node, whether or not node is rooted. If it’s unrooted, performs a simple add. If it is rooted, performs a graft, excluding the root metadata from node.
- classmethod from_h5(group)
Takes an h5py Group which is open in read mode. Confirms that a a Node of this name exists in this group, and loads and returns it with it’s metadata.
- Accepts:
group (h5py Group)
- Returns:
(Node)
- get_dim(n)
Return the n’th dim vector
- get_dim_name(n)
Get the n’th dim vector name
- get_dim_units(n)
Return the n’th dim vector units
- get_from_tree(name)
Finds and returns an object from an EMD tree using the string key name, with ‘/’ delimiters between ‘parent/child’ nodes. Search from the root node by adding a leading ‘/’; otherwise, searches from the current node.
- graft(node, merge_metadata=True)
Moves the branch beginning node onto this tree at this node.
For the reverse (i.e. grafting from this tree onto another tree) either use that tree’s .graft method, or use this tree’s ._graft.
- Accepts:
node (Node): merge_metadata (True, False, or ‘copy’): if True adds the old root’s
metadata to the new root; if False adds no metadata to the new root; if ‘copy’ adds copies of all metadata from the old root to the new root.
- Returns:
(Node) this tree’s root node
- static newnode(method)
Decorator which may be added to node methods which product and return a new node. If such a method is decorated with
>>> @newnode
then the new node is added to the parent node’s tree, and a Metadata instance is added to the new node’s metadata which stores information about how the node was created, namely: method’s name, the parent’s class and name, and all the arguments passed to method.
- set_dim(n: int, dim: list | ndarray, units: str | None = None, name: str | None = None)
Sets the n’th dim vector, using dim as described in the Array documentation. If units and/or name are passed, sets these values for the n’th dim vector.
- Accepts:
n (int): specifies which dim vector dim (list or array): length must be either 2, or equal to the
length of the n’th axis of the data array
units (Optional, str): name: (Optional, str):
- set_dim_name(n: int, name: str)
Sets the n’th dim vector name to name.
- Accepts:
n (int): specifies which dim vector name (str): new name
- set_dim_units(n: int, units: str)
Sets the n’th dim vector units to units.
- Accepts:
n (int): specifies which dim vector units (str): new units
- show_tree(root=False)
Display the object tree. If root is False, displays the branch of the tree downstream from this node. If root is True, displays the full tree from the root node.
- to_h5(group)
Takes an h5py Group instance and creates a subgroup containing this Array, tags indicating its EMD type and Python class, and the array’s data and metadata.
- Accepts:
group (h5py Group)
- Returns:
(h5py Group) the new array’s Group
- tree(arg=None, **kwargs)
Usages -
>>> .tree() # show tree from current node >>> .tree(show=True) # show from root >>> .tree(show=False) # show from current node >>> .tree(add=node) # add a child node >>> .tree(get='path') # return a '/' delimited child node >>> .tree(get='/path') # as above, starting at root >>> .tree(cut=True) # remove/return a branch, keep root metadata >>> .tree(cut=False) # remove/return a branch, discard root md >>> .tree(cut='copy') # remove/return a branch, copy root metadata >>> .tree(graft=node) # remove/graft a branch, keeping root metadata >>> .tree(graft=(node,True)) # as above >>> .tree(graft=(node,False)) # as above, discard root metadata >>> .tree(graft=(node,'copy')) # as above, copy root metadata
The show, add, and get methods can be accessed directly with
>>> .tree(arg)
for an arg of the appropriate type (bool, Node, and string).
QPoints
- class py4DSTEM.QPoints(data: ndarray, name: str | None = 'qpoints')
Stores a set of diffraction space points, with fields ‘qx’, ‘qy’ and ‘intensity’
- __init__(data: ndarray, name: str | None = 'qpoints')
- Accepts:
- data (structured numpy ndarray): should have three fields, which
will be renamed ‘qx’,’qy’,’intensity’
name (str): the name of the QPoints instance
- Returns:
A new QPoints instance
- add(data)
Appends a numpy structured array. Its dtypes must agree with the existing data.
- add_data_by_field(data, fields=None)
Add a list of data arrays to the PointList, in the fields given by fields. If fields is not specified, assumes the data arrays are in the same order as self.fields
- Parameters:
data (list) – arrays of data to add to each field
- add_fields(new_fields, name='')
Creates a copy of the PointList, but with additional fields given by new_fields.
- Parameters:
new_fields – a list of 2-tuples, (‘name’, dtype)
name – a name for the new pointlist
- add_to_tree(node)
Add an unrooted node as a child of the current, rooted node. To move an already rooted node/branch, use .graft(). To create a rooted node, use Root().
- attach(node)
Attach node to the current object’s tree, attaching calibration and detaching calibrations as needed.
- copy(name=None)
Returns a copy of the PointList. If name=None, sets to {name}_copy
- cut_from_tree(root_metadata=True)
Removes a branch from an object tree at this node.
A new root node is created under this object with this object’s name. Metadata from the current root is transferred/not transferred to the new root according to the value of root_metadata.
- Accepts:
- root_metadata (True, False, or ‘copy’): if True adds the old root’s
metadata to the new root; if False adds no metadata to the new root; if ‘copy’ adds copies of all metadata from the old root to the new root.
- Returns:
(Node) the new root node
- force_add_to_tree(node)
Add node node as a child of the current node, whether or not node is rooted. If it’s unrooted, performs a simple add. If it is rooted, performs a graft, excluding the root metadata from node.
- classmethod from_h5(group)
Takes an h5py Group which is open in read mode. Confirms that a a Node of this name exists in this group, and loads and returns it with it’s metadata.
- Accepts:
group (h5py Group)
- Returns:
(Node)
- get_from_tree(name)
Finds and returns an object from an EMD tree using the string key name, with ‘/’ delimiters between ‘parent/child’ nodes. Search from the root node by adding a leading ‘/’; otherwise, searches from the current node.
- graft(node, merge_metadata=True)
Moves the branch beginning node onto this tree at this node.
For the reverse (i.e. grafting from this tree onto another tree) either use that tree’s .graft method, or use this tree’s ._graft.
- Accepts:
node (Node): merge_metadata (True, False, or ‘copy’): if True adds the old root’s
metadata to the new root; if False adds no metadata to the new root; if ‘copy’ adds copies of all metadata from the old root to the new root.
- Returns:
(Node) this tree’s root node
- static newnode(method)
Decorator which may be added to node methods which product and return a new node. If such a method is decorated with
>>> @newnode
then the new node is added to the parent node’s tree, and a Metadata instance is added to the new node’s metadata which stores information about how the node was created, namely: method’s name, the parent’s class and name, and all the arguments passed to method.
- remove(mask)
Removes points wherever mask==True
- show_tree(root=False)
Display the object tree. If root is False, displays the branch of the tree downstream from this node. If root is True, displays the full tree from the root node.
- sort(field, order='ascending')
Sorts the point list according to field, which must be a field in self.dtype. order should be ‘descending’ or ‘ascending’.
- to_h5(group)
Takes an h5py Group instance and creates a subgroup containing this PointList, tags indicating its EMD type and Python class, and the pointlist’s data and metadata.
- Accepts:
group (h5py Group)
- Returns:
(h5py Group) the new pointlist’s group
- tree(arg=None, **kwargs)
Usages -
>>> .tree() # show tree from current node >>> .tree(show=True) # show from root >>> .tree(show=False) # show from current node >>> .tree(add=node) # add a child node >>> .tree(get='path') # return a '/' delimited child node >>> .tree(get='/path') # as above, starting at root >>> .tree(cut=True) # remove/return a branch, keep root metadata >>> .tree(cut=False) # remove/return a branch, discard root md >>> .tree(cut='copy') # remove/return a branch, copy root metadata >>> .tree(graft=node) # remove/graft a branch, keeping root metadata >>> .tree(graft=(node,True)) # as above >>> .tree(graft=(node,False)) # as above, discard root metadata >>> .tree(graft=(node,'copy')) # as above, copy root metadata
The show, add, and get methods can be accessed directly with
>>> .tree(arg)
for an arg of the appropriate type (bool, Node, and string).
RealSlice
- class py4DSTEM.RealSlice(data: ndarray, name: str | None = 'realslice', units: str | None = 'intensity', slicelabels: bool | list | None = None, calibration=None)
Stores a real-space shaped 2D data array.
- __init__(data: ndarray, name: str | None = 'realslice', units: str | None = 'intensity', slicelabels: bool | list | None = None, calibration=None)
- Accepts:
data (np.ndarray): the data name (str): the name of the realslice slicelabels(None or list): names for slices if this is a stack of
realslices
- Returns:
A new RealSlice instance
- add_to_tree(node)
Add an unrooted node as a child of the current, rooted node. To move an already rooted node/branch, use .graft(). To create a rooted node, use Root().
- attach(node)
Attach node to the current object’s tree, attaching calibration and detaching calibrations as needed.
- cut_from_tree(root_metadata=True)
Removes a branch from an object tree at this node.
A new root node is created under this object with this object’s name. Metadata from the current root is transferred/not transferred to the new root according to the value of root_metadata.
- Accepts:
- root_metadata (True, False, or ‘copy’): if True adds the old root’s
metadata to the new root; if False adds no metadata to the new root; if ‘copy’ adds copies of all metadata from the old root to the new root.
- Returns:
(Node) the new root node
- dim(n)
Return the n’th dim vector
- force_add_to_tree(node)
Add node node as a child of the current node, whether or not node is rooted. If it’s unrooted, performs a simple add. If it is rooted, performs a graft, excluding the root metadata from node.
- classmethod from_h5(group)
Takes an h5py Group which is open in read mode. Confirms that a a Node of this name exists in this group, and loads and returns it with it’s metadata.
- Accepts:
group (h5py Group)
- Returns:
(Node)
- get_dim(n)
Return the n’th dim vector
- get_dim_name(n)
Get the n’th dim vector name
- get_dim_units(n)
Return the n’th dim vector units
- get_from_tree(name)
Finds and returns an object from an EMD tree using the string key name, with ‘/’ delimiters between ‘parent/child’ nodes. Search from the root node by adding a leading ‘/’; otherwise, searches from the current node.
- graft(node, merge_metadata=True)
Moves the branch beginning node onto this tree at this node.
For the reverse (i.e. grafting from this tree onto another tree) either use that tree’s .graft method, or use this tree’s ._graft.
- Accepts:
node (Node): merge_metadata (True, False, or ‘copy’): if True adds the old root’s
metadata to the new root; if False adds no metadata to the new root; if ‘copy’ adds copies of all metadata from the old root to the new root.
- Returns:
(Node) this tree’s root node
- static newnode(method)
Decorator which may be added to node methods which product and return a new node. If such a method is decorated with
>>> @newnode
then the new node is added to the parent node’s tree, and a Metadata instance is added to the new node’s metadata which stores information about how the node was created, namely: method’s name, the parent’s class and name, and all the arguments passed to method.
- set_dim(n: int, dim: list | ndarray, units: str | None = None, name: str | None = None)
Sets the n’th dim vector, using dim as described in the Array documentation. If units and/or name are passed, sets these values for the n’th dim vector.
- Accepts:
n (int): specifies which dim vector dim (list or array): length must be either 2, or equal to the
length of the n’th axis of the data array
units (Optional, str): name: (Optional, str):
- set_dim_name(n: int, name: str)
Sets the n’th dim vector name to name.
- Accepts:
n (int): specifies which dim vector name (str): new name
- set_dim_units(n: int, units: str)
Sets the n’th dim vector units to units.
- Accepts:
n (int): specifies which dim vector units (str): new units
- show_tree(root=False)
Display the object tree. If root is False, displays the branch of the tree downstream from this node. If root is True, displays the full tree from the root node.
- to_h5(group)
Takes an h5py Group instance and creates a subgroup containing this Array, tags indicating its EMD type and Python class, and the array’s data and metadata.
- Accepts:
group (h5py Group)
- Returns:
(h5py Group) the new array’s Group
- tree(arg=None, **kwargs)
Usages -
>>> .tree() # show tree from current node >>> .tree(show=True) # show from root >>> .tree(show=False) # show from current node >>> .tree(add=node) # add a child node >>> .tree(get='path') # return a '/' delimited child node >>> .tree(get='/path') # as above, starting at root >>> .tree(cut=True) # remove/return a branch, keep root metadata >>> .tree(cut=False) # remove/return a branch, discard root md >>> .tree(cut='copy') # remove/return a branch, copy root metadata >>> .tree(graft=node) # remove/graft a branch, keeping root metadata >>> .tree(graft=(node,True)) # as above >>> .tree(graft=(node,False)) # as above, discard root metadata >>> .tree(graft=(node,'copy')) # as above, copy root metadata
The show, add, and get methods can be accessed directly with
>>> .tree(arg)
for an arg of the appropriate type (bool, Node, and string).
VirtualDiffraction
- class py4DSTEM.VirtualDiffraction(data: ndarray, name: str | None = 'virtualdiffraction')
Stores a diffraction-space shaped 2D image with metadata indicating how this image was generated from a self.
- __init__(data: ndarray, name: str | None = 'virtualdiffraction')
- Parameters:
data (np.ndarray) – the 2D data
name (str) – the name
- Returns:
A new VirtualDiffraction instance
- add_to_tree(node)
Add an unrooted node as a child of the current, rooted node. To move an already rooted node/branch, use .graft(). To create a rooted node, use Root().
- attach(node)
Attach node to the current object’s tree, attaching calibration and detaching calibrations as needed.
- cut_from_tree(root_metadata=True)
Removes a branch from an object tree at this node.
A new root node is created under this object with this object’s name. Metadata from the current root is transferred/not transferred to the new root according to the value of root_metadata.
- Accepts:
- root_metadata (True, False, or ‘copy’): if True adds the old root’s
metadata to the new root; if False adds no metadata to the new root; if ‘copy’ adds copies of all metadata from the old root to the new root.
- Returns:
(Node) the new root node
- dim(n)
Return the n’th dim vector
- force_add_to_tree(node)
Add node node as a child of the current node, whether or not node is rooted. If it’s unrooted, performs a simple add. If it is rooted, performs a graft, excluding the root metadata from node.
- classmethod from_h5(group)
Takes an h5py Group which is open in read mode. Confirms that a a Node of this name exists in this group, and loads and returns it with it’s metadata.
- Accepts:
group (h5py Group)
- Returns:
(Node)
- get_dim(n)
Return the n’th dim vector
- get_dim_name(n)
Get the n’th dim vector name
- get_dim_units(n)
Return the n’th dim vector units
- get_from_tree(name)
Finds and returns an object from an EMD tree using the string key name, with ‘/’ delimiters between ‘parent/child’ nodes. Search from the root node by adding a leading ‘/’; otherwise, searches from the current node.
- graft(node, merge_metadata=True)
Moves the branch beginning node onto this tree at this node.
For the reverse (i.e. grafting from this tree onto another tree) either use that tree’s .graft method, or use this tree’s ._graft.
- Accepts:
node (Node): merge_metadata (True, False, or ‘copy’): if True adds the old root’s
metadata to the new root; if False adds no metadata to the new root; if ‘copy’ adds copies of all metadata from the old root to the new root.
- Returns:
(Node) this tree’s root node
- static newnode(method)
Decorator which may be added to node methods which product and return a new node. If such a method is decorated with
>>> @newnode
then the new node is added to the parent node’s tree, and a Metadata instance is added to the new node’s metadata which stores information about how the node was created, namely: method’s name, the parent’s class and name, and all the arguments passed to method.
- set_dim(n: int, dim: list | ndarray, units: str | None = None, name: str | None = None)
Sets the n’th dim vector, using dim as described in the Array documentation. If units and/or name are passed, sets these values for the n’th dim vector.
- Accepts:
n (int): specifies which dim vector dim (list or array): length must be either 2, or equal to the
length of the n’th axis of the data array
units (Optional, str): name: (Optional, str):
- set_dim_name(n: int, name: str)
Sets the n’th dim vector name to name.
- Accepts:
n (int): specifies which dim vector name (str): new name
- set_dim_units(n: int, units: str)
Sets the n’th dim vector units to units.
- Accepts:
n (int): specifies which dim vector units (str): new units
- show_tree(root=False)
Display the object tree. If root is False, displays the branch of the tree downstream from this node. If root is True, displays the full tree from the root node.
- to_h5(group)
Takes an h5py Group instance and creates a subgroup containing this Array, tags indicating its EMD type and Python class, and the array’s data and metadata.
- Accepts:
group (h5py Group)
- Returns:
(h5py Group) the new array’s Group
- tree(arg=None, **kwargs)
Usages -
>>> .tree() # show tree from current node >>> .tree(show=True) # show from root >>> .tree(show=False) # show from current node >>> .tree(add=node) # add a child node >>> .tree(get='path') # return a '/' delimited child node >>> .tree(get='/path') # as above, starting at root >>> .tree(cut=True) # remove/return a branch, keep root metadata >>> .tree(cut=False) # remove/return a branch, discard root md >>> .tree(cut='copy') # remove/return a branch, copy root metadata >>> .tree(graft=node) # remove/graft a branch, keeping root metadata >>> .tree(graft=(node,True)) # as above >>> .tree(graft=(node,False)) # as above, discard root metadata >>> .tree(graft=(node,'copy')) # as above, copy root metadata
The show, add, and get methods can be accessed directly with
>>> .tree(arg)
for an arg of the appropriate type (bool, Node, and string).
VirtualImage
- class py4DSTEM.VirtualImage(data: ndarray, name: str | None = 'virtualimage')
A container for storing virtual image data and metadata, including the real-space shaped 2D image and metadata indicating how this image was generated from a datacube.
- __init__(data: ndarray, name: str | None = 'virtualimage')
- Parameters:
data (np.ndarray) – the 2D data
name (str) – the name
- add_to_tree(node)
Add an unrooted node as a child of the current, rooted node. To move an already rooted node/branch, use .graft(). To create a rooted node, use Root().
- attach(node)
Attach node to the current object’s tree, attaching calibration and detaching calibrations as needed.
- cut_from_tree(root_metadata=True)
Removes a branch from an object tree at this node.
A new root node is created under this object with this object’s name. Metadata from the current root is transferred/not transferred to the new root according to the value of root_metadata.
- Accepts:
- root_metadata (True, False, or ‘copy’): if True adds the old root’s
metadata to the new root; if False adds no metadata to the new root; if ‘copy’ adds copies of all metadata from the old root to the new root.
- Returns:
(Node) the new root node
- dim(n)
Return the n’th dim vector
- force_add_to_tree(node)
Add node node as a child of the current node, whether or not node is rooted. If it’s unrooted, performs a simple add. If it is rooted, performs a graft, excluding the root metadata from node.
- classmethod from_h5(group)
Takes an h5py Group which is open in read mode. Confirms that a a Node of this name exists in this group, and loads and returns it with it’s metadata.
- Accepts:
group (h5py Group)
- Returns:
(Node)
- get_dim(n)
Return the n’th dim vector
- get_dim_name(n)
Get the n’th dim vector name
- get_dim_units(n)
Return the n’th dim vector units
- get_from_tree(name)
Finds and returns an object from an EMD tree using the string key name, with ‘/’ delimiters between ‘parent/child’ nodes. Search from the root node by adding a leading ‘/’; otherwise, searches from the current node.
- graft(node, merge_metadata=True)
Moves the branch beginning node onto this tree at this node.
For the reverse (i.e. grafting from this tree onto another tree) either use that tree’s .graft method, or use this tree’s ._graft.
- Accepts:
node (Node): merge_metadata (True, False, or ‘copy’): if True adds the old root’s
metadata to the new root; if False adds no metadata to the new root; if ‘copy’ adds copies of all metadata from the old root to the new root.
- Returns:
(Node) this tree’s root node
- static newnode(method)
Decorator which may be added to node methods which product and return a new node. If such a method is decorated with
>>> @newnode
then the new node is added to the parent node’s tree, and a Metadata instance is added to the new node’s metadata which stores information about how the node was created, namely: method’s name, the parent’s class and name, and all the arguments passed to method.
- set_dim(n: int, dim: list | ndarray, units: str | None = None, name: str | None = None)
Sets the n’th dim vector, using dim as described in the Array documentation. If units and/or name are passed, sets these values for the n’th dim vector.
- Accepts:
n (int): specifies which dim vector dim (list or array): length must be either 2, or equal to the
length of the n’th axis of the data array
units (Optional, str): name: (Optional, str):
- set_dim_name(n: int, name: str)
Sets the n’th dim vector name to name.
- Accepts:
n (int): specifies which dim vector name (str): new name
- set_dim_units(n: int, units: str)
Sets the n’th dim vector units to units.
- Accepts:
n (int): specifies which dim vector units (str): new units
- show_tree(root=False)
Display the object tree. If root is False, displays the branch of the tree downstream from this node. If root is True, displays the full tree from the root node.
- to_h5(group)
Takes an h5py Group instance and creates a subgroup containing this Array, tags indicating its EMD type and Python class, and the array’s data and metadata.
- Accepts:
group (h5py Group)
- Returns:
(h5py Group) the new array’s Group
- tree(arg=None, **kwargs)
Usages -
>>> .tree() # show tree from current node >>> .tree(show=True) # show from root >>> .tree(show=False) # show from current node >>> .tree(add=node) # add a child node >>> .tree(get='path') # return a '/' delimited child node >>> .tree(get='/path') # as above, starting at root >>> .tree(cut=True) # remove/return a branch, keep root metadata >>> .tree(cut=False) # remove/return a branch, discard root md >>> .tree(cut='copy') # remove/return a branch, copy root metadata >>> .tree(graft=node) # remove/graft a branch, keeping root metadata >>> .tree(graft=(node,True)) # as above >>> .tree(graft=(node,False)) # as above, discard root metadata >>> .tree(graft=(node,'copy')) # as above, copy root metadata
The show, add, and get methods can be accessed directly with
>>> .tree(arg)
for an arg of the appropriate type (bool, Node, and string).