2.3.1. prismatique.discretization.Params

class Params(z_supersampling=16, sample_supercell_reduced_xy_dims_in_pixels=(64, 64), interpolation_factors=(1, 1), num_slices=25, skip_validation_and_conversion=False)[source]

Bases: PreSerializableAndUpdatable

The simulation parameters related to the discretization of real-space and Fourier/\(k\)-space.

In prismatic, a sample is constructed by defining an orthorhombic unit cell of atoms, which may be optionally tiled a finite number of times in the \(x\)-, \(y\)-, and \(z\)-directions to form a supercell, upon which periodic boundary conditions are imposed on the supercell in the \(x\)- and \(y\)-directions. In the case of crystal samples that do not possess primitive cells with orthorhombic symmetry, one can typically find a larger unit cell within the crystal with the required orthorhombic symmetry.

Both the PRISM and the standard multislice algorithms make certain assumptions regarding the total potential within the sample. First, the total potential is treated classically. Second, the isolated atom approximation is assumed, wherein the total potential within \(V\left(\mathbf{r}\right)\) the sample is modelled by:

(2.3.1.1)\[V\left(\mathbf{r}\right)=\sum_{j=1}^{N}V_{j}^{\left(\text{atom}\right)} \left(\left|\mathbf{r}-\mathbf{r}_{j}\right|\right),\]

where

(2.3.1.2)\[\mathbf{r}=x\hat{\mathbf{x}}+y\hat{\mathbf{y}}+z\hat{\mathbf{z}},\]
(2.3.1.3)\[\mathbf{r}_{j}=x_{j}\hat{\mathbf{x}}+y_{j}\hat{\mathbf{y}} +z_{j}\hat{\mathbf{z}},\]

\(N\) is the number of atoms within the sample, \(V_{j}^{\left(\text{atom}\right)} \left(\left|\mathbf{r}-\mathbf{r}_{j}\right|\right)\) is the effective isolated potential of the \(j^{\text{th}}\) atom at the position \(\mathbf{r}_{j}\) [we will refer to \(j\) as the atom label]. In the isolated atom approximation bond effects are neglected. Corrections due to the bond effects should be small in most cases since electron scattering is mainly from the nucleus with the core and valence electrons screening the nucleus [Kirkland1]. The errors due to the isolated atom approximation are most prominent for low angle scattering, which may cause problems with phase contrast bright field images, whereas high angle annular dark field STEM images should be more accurate [Kirkland1]. In any case, due to the simplicity and cheap computational costs, prismatic adopts the isolated atom approximation described above. The effective isolated potentials are parameterized based on single-atom scattering factors determined through Hartree-Fock calculations [Kirkland1], [DaCosta1]. Third, the beam electrons are assumed to interact with an effective potential \(\tilde{V}\left(\mathbf{r}\right)\) within the sample, which is obtained by coarse-graining \(V\left(\mathbf{r}\right)\) along the \(z\)-axis:

(2.3.1.4)\[\tilde{V}\left(\mathbf{r}\right)=\sum_{n=0}^{N_{\text{slices}}-1} \delta\left(z-z_{n}\right) \tilde{V}_{n}\left(x,y\right),\]

where \(N_{\text{slices}}\) is a positive integer;

(2.3.1.5)\[z_{n}=n\delta z,\]

with

(2.3.1.6)\[\delta z = \frac{\Delta Z}{N_{\text{slices}}},\]

\(\Delta Z\) is the \(z\)-dimension of the sample’s supercell in units of length; and

(2.3.1.7)\[\begin{split}\tilde{V}_{n}\left(x,y\right) & =\int_{z_{n}}^{z_{n+1}}dz\, V\left(\mathbf{r}\right)\\ & =\sum_{j=1}^{N}\int_{z_{n}}^{z_{n+1}}dz\, V_{j}^{\left(\text{atom}\right)} \left(\left|\mathbf{r}-\mathbf{r}_{j}\right|\right).\end{split}\]

In other words, the sample is partitioned into \(N_{\text{slices}}\) slices of thickness \(\delta z\) along the \(z\)-axis and \(V\left(\mathbf{r}\right)\) is coarse-grained over these slices to obtain \(\tilde{V}\left(\mathbf{r}\right)\). Note that \(z=z_0\) and \(z=z_{N_{\text{slices}}}\) are the \(z\)-coordinates of the entrance and exit surfaces of the sample’s supercell respectively. We will refer to \(\tilde{V}_{n}\left(x,y\right)\) as the \(n^{\text{th}}\) potential slice.

At this point, the user can choose one of two approaches to complete the calculation of the effective potential \(\tilde{V}_{n}\left(x,y\right)\). In the simpler approach, we approximate Eq. (2.3.1.7) by

(2.3.1.8)\[\tilde{V}_{n}\left(x,y\right)=\sum_{j\in A_{n}} \tilde{V}_{j}^{\left(\text{atom}\right)}\left(x-x_{j},y-y_{j}\right),\]

where the \(\tilde{V}_{j}^{\left(\text{atom}\right)} \left(x-x_{j},y-y_{j}\right)\) are the 2D projected isolated atomic potentials:

(2.3.1.9)\[\tilde{V}_{j}^{\left(\text{atom}\right)}\left(x-x_{j},y-y_{j}\right) =\int_{-\infty}^{\infty}dz\,V_{j}^{\left(\text{atom}\right)} \left(\left|\mathbf{r}-\mathbf{r}_{j}\right|\right),\]

and \(A_{n}\) is the set of atom labels corresponding to the atoms with \(z\)-coordinates \(z_{j}\in\left[z_{n},z_{n+1}\right)\). The integrals in Eq. (2.3.1.9) can be evaluated analytically, thus avoiding costly numerical integrations. This simpler approach should only yield accurate results when the slice thickness \(\delta z\) is large compared to the effective extent of each isolated atomic potential in the sample and that the \(z_{j}\sim\delta z\left(1+2l\right)/2\), where \(0\le l<N_{\text{slices}}\). In the second approach, the limits of integration in Eq. (2.3.1.7) are not extended to infinity, and the integrals are evaluated numerically. This approach is more accurate but is more computationally expensive.

Both real-space and momentum/Fourier/angular-space need to be discretized in order to handle wavefunctions, as well as the potential slices numerically. Each potential slice is discretized with pixel sizes in the \(x\)- and \(y\)-directions given by:

(2.3.1.10)\[\Delta x=\frac{\Delta X}{N_{x}},\quad\Delta y=\frac{\Delta Y}{N_{y}},\]

where \(\Delta x\) and \(\Delta y\) are the potential slice pixel sizes along the \(x\)- and \(y\)-directions respectively, \(\Delta X\) and \(\Delta Y\) are the \(x\)- and \(y\)-dimensions of the sample’s supercell in units of length respectively, and \(N_x\) and \(N_y\) are the \(x\)- and \(y\)-dimensions of the sample’s supercell in units of potential slice pixels respectively. We will refer to \(\left(N_{x},N_{y}\right)\) as the “pixelated potential slice \(xy\)-dimensions”. For practical reasons, it is convenient to refer to the quantity:

(2.3.1.11)\[\left(\tilde{N}_{x},\tilde{N}_{y}\right)=\left(\frac{N_{x}}{4f_{x}}, \frac{N_{y}}{4f_{y}}\right),\]

as the “sample supercell’s reduced \(xy\)-dimensions in units of pixels”, where \(f_{x}\) and \(f_{y}\) are positive integers called the \(x\) and \(y\) interpolation factors, which are discussed further in the documentation for the subpackage prismatique.stem and the class prismatique.tilt.Params. Note that in STEM simulations that use the multislice algorithm, \(f_{x}=f_{y}=1\). In order for \(\left(\tilde{N}_{x},\tilde{N}_{y}\right)\) to be a pair of integers, we constrain \(N_{x}\) and \(N_{y}\) to be divisible by \(4f_{x}\) and \(4f_{y}\) respectively. In prismatique, the user specifies indirectly \(\Delta x\) and \(\Delta y\) by specifying directly \(\left(\tilde{N}_{x},\tilde{N}_{y}\right)\).

Parameters:
z_supersamplingint, optional

See the above discussion for context. If z_supersampling is set to 0, then the first of the two approaches discussed above is used to calculate \(\tilde{V}_{n}\left(x,y\right)\), i.e. Eq. (2.3.1.8) is used. Otherwise, if z_supersampling is set to a positive integer, then Eq. (2.3.1.7) is used to calculate \(\tilde{V}_{n}\left(x,y\right)\), and z_supersampling specifies the number of evenly spaced quadrature points to use in numerically evaluating the integral. Note that z_supersampling must be a non-negative integer.

sample_supercell_reduced_xy_dims_in_pixelsarray_like (int, shape=(2,)), optional

sample_supercell_reduced_xy_dims_in_pixels[0] and sample_supercell_reduced_xy_dims_in_pixels[1] specify \(\tilde{N}_x\) and \(\tilde{N}_y\) respectively, where \(\left(\tilde{N}_{x},\tilde{N}_{y}\right)\) are the sample supercell’s reduced \(xy\)-dimensions in units of pixels.

interpolation_factorsarray_like (int, shape=(2,)), optional

interpolation_factors[0] and interpolation_factors[1] are the interpolation factors \(f_x\) and \(f_y\) respectively, which are discussed above. Note that interpolation_factors must be set to (1, 1) if using the multislice algorithm for STEM simulations.

num_slicesint, optional

The number of slices \(N_{\text{slices}}\) used to partition the sample.

skip_validation_and_conversionbool, optional

Let validation_and_conversion_funcs and core_attrs denote the attributes validation_and_conversion_funcs and core_attrs respectively, both of which being dict objects.

Let params_to_be_mapped_to_core_attrs denote the dict representation of the constructor parameters excluding the parameter skip_validation_and_conversion, where each dict key key is a different constructor parameter name, excluding the name "skip_validation_and_conversion", and params_to_be_mapped_to_core_attrs[key] would yield the value of the constructor parameter with the name given by key.

If skip_validation_and_conversion is set to False, then for each key key in params_to_be_mapped_to_core_attrs, core_attrs[key] is set to validation_and_conversion_funcs[key] (params_to_be_mapped_to_core_attrs).

Otherwise, if skip_validation_and_conversion is set to True, then core_attrs is set to params_to_be_mapped_to_core_attrs.copy(). This option is desired primarily when the user wants to avoid potentially expensive deep copies and/or conversions of the dict values of params_to_be_mapped_to_core_attrs, as it is guaranteed that no copies or conversions are made in this case.

Attributes:
core_attrs

dict: The “core attributes”.

de_pre_serialization_funcs

dict: The de-pre-serialization functions.

pre_serialization_funcs

dict: The pre-serialization functions.

validation_and_conversion_funcs

dict: The validation and conversion functions.

Methods

de_pre_serialize([serializable_rep, ...])

Construct an instance from a serializable representation.

dump([filename, overwrite])

Serialize instance and save the result in a JSON file.

dumps()

Serialize instance.

get_core_attrs([deep_copy])

Return the core attributes.

get_de_pre_serialization_funcs()

Return the de-pre-serialization functions.

get_pre_serialization_funcs()

Return the pre-serialization functions.

get_validation_and_conversion_funcs()

Return the validation and conversion functions.

load([filename, skip_validation_and_conversion])

Construct an instance from a serialized representation that is stored in a JSON file.

loads([serialized_rep, ...])

Construct an instance from a serialized representation.

pre_serialize()

Pre-serialize instance.

update([new_core_attr_subset_candidate, ...])

Update a subset of the core attributes.

Methods

de_pre_serialize

Construct an instance from a serializable representation.

dump

Serialize instance and save the result in a JSON file.

dumps

Serialize instance.

get_core_attrs

Return the core attributes.

get_de_pre_serialization_funcs

Return the de-pre-serialization functions.

get_pre_serialization_funcs

Return the pre-serialization functions.

get_validation_and_conversion_funcs

Return the validation and conversion functions.

load

Construct an instance from a serialized representation that is stored in a JSON file.

loads

Construct an instance from a serialized representation.

pre_serialize

Pre-serialize instance.

update

Update a subset of the core attributes.

Attributes

core_attrs

dict: The "core attributes".

de_pre_serialization_funcs

dict: The de-pre-serialization functions.

pre_serialization_funcs

dict: The pre-serialization functions.

validation_and_conversion_funcs

dict: The validation and conversion functions.

property core_attrs

dict: The “core attributes”.

The keys of core_attrs are the same as the attribute validation_and_conversion_funcs, which is also a dict object.

Note that core_attrs should be considered read-only.

property de_pre_serialization_funcs

dict: The de-pre-serialization functions.

de_pre_serialization_funcs has the same keys as the attribute validation_and_conversion_funcs, which is also a dict object.

Let validation_and_conversion_funcs and pre_serialization_funcs denote the attributes validation_and_conversion_funcs pre_serialization_funcs respectively, the last of which being a dict object as well.

Let core_attrs_candidate_1 be any dict object that has the same keys as validation_and_conversion_funcs, where for each dict key key in core_attrs_candidate_1, validation_and_conversion_funcs[key](core_attrs_candidate_1) does not raise an exception.

Let serializable_rep be a dict object that has the same keys as core_attrs_candidate_1, where for each dict key key in core_attrs_candidate_1, serializable_rep[key] is set to pre_serialization_funcs[key](core_attrs_candidate_1[key]).

The items of de_pre_serialization_funcs are expected to be set to callable objects that would lead to de_pre_serialization_funcs[key](serializable_rep[key]) not raising an exception for each dict key key in serializable_rep.

Let core_attrs_candidate_2 be a dict object that has the same keys as serializable_rep, where for each dict key key in validation_and_conversion_funcs, core_attrs_candidate_2[key] is set to de_pre_serialization_funcs[key](serializable_rep[key]).

The items of de_pre_serialization_funcs are also expected to be set to callable objects that would lead to validation_and_conversion_funcs[key](core_attrs_candidate_2) not raising an exception for each dict key key in core_attrs_candidate_2.

Note that de_pre_serialization_funcs should be considered read-only.

classmethod de_pre_serialize(serializable_rep={}, skip_validation_and_conversion=False)

Construct an instance from a serializable representation.

Parameters:
serializable_repdict, optional

A dict object that has the same keys as the attribute validation_and_conversion_funcs, which is also a dict object.

Let validation_and_conversion_funcs and de_pre_serialization_funcs denote the attributes validation_and_conversion_funcs de_pre_serialization_funcs respectively, the last of which being a dict object as well.

The items of serializable_rep are expected to be objects that would lead to de_pre_serialization_funcs[key](serializable_rep[key]) not raising an exception for each dict key key in serializable_rep.

Let core_attrs_candidate be a dict object that has the same keys as serializable_rep, where for each dict key key in serializable_rep, core_attrs_candidate[key] is set to de_pre_serialization_funcs[key](serializable_rep[key])``.

The items of serializable_rep are also expected to be set to objects that would lead to validation_and_conversion_funcs[key](core_attrs_candidate) not raising an exception for each dict key key in serializable_rep.

skip_validation_and_conversionbool, optional

Let core_attrs denote the attribute core_attrs, which is a dict object.

If skip_validation_and_conversion is set to False, then for each key key in serializable_rep, core_attrs[key] is set to validation_and_conversion_funcs[key] (core_attrs_candidate), with validation_and_conversion_funcs and core_attrs_candidate_1 being introduced in the above description of serializable_rep.

Otherwise, if skip_validation_and_conversion is set to True, then core_attrs is set to core_attrs_candidate.copy(). This option is desired primarily when the user wants to avoid potentially expensive deep copies and/or conversions of the dict values of core_attrs_candidate, as it is guaranteed that no copies or conversions are made in this case.

Returns:
instance_of_current_clsCurrent class

An instance constructed from the serializable representation serializable_rep.

dump(filename='serialized_rep_of_fancytype.json', overwrite=False)

Serialize instance and save the result in a JSON file.

Parameters:
filenamestr, optional

The relative or absolute path to the JSON file in which to store the serialized representation of an instance.

overwritebool, optional

If overwrite is set to False and a file exists at the path filename, then the serialized instance is not written to that file and an exception is raised. Otherwise, the serialized instance will be written to that file barring no other issues occur.

Returns:
dumps()

Serialize instance.

Returns:
serialized_repdict

A serialized representation of an instance.

get_core_attrs(deep_copy=True)

Return the core attributes.

Parameters:
deep_copybool, optional

Let core_attrs denote the attribute core_attrs, which is a dict object.

If deep_copy is set to True, then a deep copy of core_attrs is returned. Otherwise, a shallow copy of core_attrs is returned.

Returns:
core_attrsdict

The attribute core_attrs.

classmethod get_de_pre_serialization_funcs()[source]

Return the de-pre-serialization functions.

Returns:
de_pre_serialization_funcsdict

The attribute de_pre_serialization_funcs.

classmethod get_pre_serialization_funcs()[source]

Return the pre-serialization functions.

Returns:
pre_serialization_funcsdict

The attribute pre_serialization_funcs.

classmethod get_validation_and_conversion_funcs()[source]

Return the validation and conversion functions.

Returns:
validation_and_conversion_funcsdict

The attribute validation_and_conversion_funcs.

classmethod load(filename='serialized_rep_of_fancytype.json', skip_validation_and_conversion=False)

Construct an instance from a serialized representation that is stored in a JSON file.

Users can save serialized representations to JSON files using the method fancytypes.PreSerializable.dump().

Parameters:
filenamestr, optional

The relative or absolute path to the JSON file that is storing the serialized representation of an instance.

filename is expected to be such that json.load(open(filename, "r")) does not raise an exception.

Let serializable_rep=json.load(open(filename, "r")).

Let validation_and_conversion_funcs and de_pre_serialization_funcs denote the attributes validation_and_conversion_funcs de_pre_serialization_funcs respectively, both of which being dict objects as well.

filename is also expected to be such that de_pre_serialization_funcs[key](serializable_rep[key]) does not raise an exception for each dict key key in de_pre_serialization_funcs.

Let core_attrs_candidate be a dict object that has the same keys as de_pre_serialization_funcs, where for each dict key key in serializable_rep, core_attrs_candidate[key] is set to de_pre_serialization_funcs[key](serializable_rep[key])``.

filename is also expected to be such that validation_and_conversion_funcs[key](core_attrs_candidate) does not raise an exception for each dict key key in serializable_rep.

skip_validation_and_conversionbool, optional

Let core_attrs denote the attribute core_attrs, which is a dict object.

Let core_attrs_candidate be as defined in the above description of filename.

If skip_validation_and_conversion is set to False, then for each key key in core_attrs_candidate, core_attrs[key] is set to validation_and_conversion_funcs[key] (core_attrs_candidate), , with validation_and_conversion_funcs and core_attrs_candidate being introduced in the above description of filename.

Otherwise, if skip_validation_and_conversion is set to True, then core_attrs is set to core_attrs_candidate.copy(). This option is desired primarily when the user wants to avoid potentially expensive deep copies and/or conversions of the dict values of core_attrs_candidate, as it is guaranteed that no copies or conversions are made in this case.

Returns:
instance_of_current_clsCurrent class

An instance constructed from the serialized representation stored in the JSON file.

classmethod loads(serialized_rep='{}', skip_validation_and_conversion=False)

Construct an instance from a serialized representation.

Users can generate serialized representations using the method dumps().

Parameters:
serialized_repstr | bytes | bytearray, optional

The serialized representation.

serialized_rep is expected to be such that json.loads(serialized_rep) does not raise an exception.

Let serializable_rep=json.loads(serialized_rep).

Let validation_and_conversion_funcs and de_pre_serialization_funcs denote the attributes validation_and_conversion_funcs de_pre_serialization_funcs respectively, both of which being dict objects as well.

serialized_rep is also expected to be such that de_pre_serialization_funcs[key](serializable_rep[key]) does not raise an exception for each dict key key in de_pre_serialization_funcs.

Let core_attrs_candidate be a dict object that has the same keys as serializable_rep, where for each dict key key in de_pre_serialization_funcs, core_attrs_candidate[key] is set to de_pre_serialization_funcs[key](serializable_rep[key])``.

serialized_rep is also expected to be such that validation_and_conversion_funcs[key](core_attrs_candidate) does not raise an exception for each dict key key in serializable_rep.

skip_validation_and_conversionbool, optional

Let core_attrs denote the attribute core_attrs, which is a dict object.

If skip_validation_and_conversion is set to False, then for each key key in core_attrs_candidate, core_attrs[key] is set to validation_and_conversion_funcs[key] (core_attrs_candidate), with validation_and_conversion_funcs and core_attrs_candidate_1 being introduced in the above description of serialized_rep.

Otherwise, if skip_validation_and_conversion is set to True, then core_attrs is set to core_attrs_candidate.copy(). This option is desired primarily when the user wants to avoid potentially expensive deep copies and/or conversions of the dict values of core_attrs_candidate, as it is guaranteed that no copies or conversions are made in this case.

Returns:
instance_of_current_clsCurrent class

An instance constructed from the serialized representation.

property pre_serialization_funcs

dict: The pre-serialization functions.

pre_serialization_funcs has the same keys as the attribute validation_and_conversion_funcs, which is also a dict object.

Let validation_and_conversion_funcs and core_attrs denote the attributes validation_and_conversion_funcs and core_attrs respectively, the last of which being a dict object as well.

For each dict key key in core_attrs, pre_serialization_funcs[key](core_attrs[key]) is expected to yield a serializable object, i.e. it should yield an object that can be passed into the function json.dumps without raising an exception.

Note that pre_serialization_funcs should be considered read-only.

pre_serialize()

Pre-serialize instance.

Returns:
serializable_repdict

A serializable representation of an instance.

update(new_core_attr_subset_candidate={}, skip_validation_and_conversion=False)

Update a subset of the core attributes.

Parameters:
new_core_attr_subset_candidatedict, optional

A dict object.

skip_validation_and_conversionbool, optional

Let validation_and_conversion_funcs and core_attrs denote the attributes validation_and_conversion_funcs and core_attrs respectively, both of which being dict objects.

If skip_validation_and_conversion is set to False, then for each key key in core_attrs that is also in new_core_attr_subset_candidate, core_attrs[key] is set to validation_and_conversion_funcs[key] (new_core_attr_subset_candidate).

Otherwise, if skip_validation_and_conversion is set to True, then for each key key in core_attrs that is also in new_core_attr_subset_candidate, core_attrs[key] is set to new_core_attr_subset_candidate[key]. This option is desired primarily when the user wants to avoid potentially expensive deep copies and/or conversions of the dict values of new_core_attr_subset_candidate, as it is guaranteed that no copies or conversions are made in this case.

property validation_and_conversion_funcs

dict: The validation and conversion functions.

The keys of validation_and_conversion_funcs are the names of the constructor parameters, excluding skip_validation_and_conversion if it exists as a construction parameter.

Let core_attrs denote the attribute core_attrs, which is also a dict object.

For each dict key key in core_attrs, validation_and_conversion_funcs[key](core_attrs) is expected to not raise an exception.

Note that validation_and_conversion_funcs should be considered read-only.