Analysis API reference

This page is the reference documentation for the asap3.analysis package. It is generated directly from the docstrings in the source code.

The narrative documentation, with examples and advice on when to use which method, is on the Local crystalline order and Radial Distribution Functions pages.

All the objects below can be imported from the asap3.analysis package regardless of which submodule they are defined in:

from asap3.analysis import CNA, FullCNA, PTM, RadialDistributionFunction

The dotted names below show the defining submodule, since that is where the source code lives.

Coordination numbers

asap3.analysis.localstructure.CoordinationNumbers(atoms, rCut=None, minimum_image=None)[source]

Coordination numbers of the atoms.

Parameters:
  • atoms (ase.Atoms) – The atoms to be analyzed.

  • rCut (float, optional) – The cutoff. If not given, a value between the first and second coordination shell is guessed from the atomic numbers.

  • minimum_image (bool, optional) – Whether to use the minimum image convention. If not given, it is decided from the cutoff and the size of the computational box.

Returns:

numpy.ndarray – The coordination number of each atom.

Common Neighbor Analysis

asap3.analysis.localstructure.CNA(atoms, rCut=None)[source]

Restricted Common Neighbor Analysis on an Atoms object.

Parameters:
  • atoms (ase.Atoms) – The atoms to be analyzed.

  • rCut (float, optional) – The cutoff, which must lie between the first and second neighbor shell. If not given, a value is guessed from the atomic numbers.

Returns:

numpy.ndarray – An array of integers (int8) reflecting the local crystal structure. FCC is class 0, HCP is class 1 and everything else is class 2.

See also

RestrictedCNA

Observer version of this analysis.

class asap3.analysis.localstructure.RestrictedCNA(atoms, rCut=None, analyze_first=True)[source]

Restricted Common Neighbor Analysis on an Atoms object.

Sets the tags of the atoms according to their local crystal structure. FCC is class 0, HCP is class 1 and everything else is class 2.

This class is intended for use as an observer, so its analyze method is called automatically by e.g. the dynamics. It can itself act as a subject, so a Plotter or a Trajectory can be called just after the calculations.

Parameters:
  • atoms (ase.Atoms) – The atoms to be analyzed.

  • rCut (float, optional) – The cutoff, which must lie between the first and second neighbor shell. If not given, a value is guessed from the atomic numbers.

  • analyze_first (bool, optional) – Whether an analysis should be made as soon as this object is created. Leave as True if you plan to attach a Trajectory as an observer to this object, and the Trajectory will save the initial state.

Note

Implementation details: The object will reuse (and possibly update) the neighbor list of any associated calculator, if the neighbor list is usable, or create its own if not.

analyze()[source]

Runs the CNA analysis.

update()

Runs the CNA analysis.

class asap3.analysis.localstructure.FullCNA(atoms=None, rCut=None)[source]

Full Common Neighbor Analysis on an Atoms object.

This CNA calculator can be used as a stand-alone analyzer or as an observer. To calculate the CNA of some atoms once, create the object and call the appropriate get_cna method.

The same object can be used to calculate the CNA multiple times when an atoms object is altered (although little if anything is saved by reusing the object). Each time a get_cna_xxx method is called, the CNA is recalculated. If you use a different atoms object or want to change the cutoff, call the update method.

To use as an observer, derive a subclass and give it a method which gets the relevant CNA data and stores it (or whatever the observer should do with the data).

Parameters:
  • atoms (ase.Atoms, optional) – The atoms to be analyzed. If not given here, it must be given to the update method before any analysis.

  • rCut (float, optional) – The cutoff. If not given, a value is guessed from the atomic numbers.

Note

Implementation details: The object will reuse (and possibly update) the neighbor list of any associated calculator, if the neighbor list is usable, or create its own if not.

get_normal_and_total_cna()[source]

Return the per-atom and the total CNA.

Unlike calling the two methods separately, the actual CNA calculation is only done once.

Returns:

  • normal (list of dict) – The same as get_normal_cna would return.

  • total (dict) – The same as get_total_cna would return.

Note

This function is not supported in parallel simulations.

get_normal_cna()[source]

Get the CNA as a dictionary per atom.

Returns:

list of dict – One dictionary per atom. The keys are the CNA tuples, and the values are the number of times they occur.

get_total_cna()[source]

Get the total CNA for the system.

Returns:

dict – The CNA tuples as keys, and the total number of bonds with that CNA index as values.

get_total_perz_cna()[source]

Get the total CNA for the system per element.

Returns:

dict – The keys are the pairs of elements encountered in the system, always given with the smallest atomic number first. The values are dictionaries summarizing the CNA (as for get_total_cna) for bonds between these elements.

Note

This function is not supported in parallel simulations.

update(atoms=None, rCut=None)[source]

Change the atoms or the cutoff.

Parameters:
  • atoms (ase.Atoms, optional) – The new atoms to be analyzed.

  • rCut (float, optional) – The new cutoff.

Raises:

ValueError – If no atoms have been specified, neither here nor when the object was created.

Polyhedral Template Matching

asap3.analysis.ptm.PTM(atoms, cutoff=10.0, rmsd_max=None, **kwargs)[source]

Run Polyhedral Template Matching on an Atoms object.

Parameters:
  • atoms (ase.Atoms) – The atoms object.

  • cutoff (float, optional) – A cutoff used for the neighbor list. It must be large enough that all nearest neighbors are returned (second-nearest for BCC). Using too large a value may impact performance, but not results. The default is 10.0.

  • rmsd_max (float, optional) – If set, matches with an RMSD above this threshold are reclassified as unknown structure (type 0). This is done as post-processing, and is completely equivalent to data['structure'][data['rmsd'] > rmsd_max] = 0.

  • target_structures (tuple of str, optional) – The structures to be investigated. Defaults to ('sc', 'fcc', 'hcp', 'ico', 'bcc'). It MUST be a tuple, not a list or other sequence.

  • calculate_strains (bool, optional) – Set to True to calculate strains. The default is False.

  • quick (bool, optional) – Set to True to skip topological ordering of neighbors. It gives a factor of two in speed, but more misclassified atoms at high temperatures. The default is False.

  • return_nblist (bool, optional) – Return the neighbor list object used internally. This may be used for preprocessing. Do not enable unless you need it, as this object can use a lot of memory. The default is False.

  • return_mappings (bool or tuple of str, optional) – Return the mapping of neighbors to the template used internally. Set to True to get mappings for all structures, or to a tuple of structures to get them for some (see target_structures).

Returns:

dict – A dictionary of NumPy arrays, each of the same length as the number of atoms. In the descriptions below, i is the first index of the array and identifies the atom.

'structure'

The local crystal structure around atom i, if any. 0 = none; 1 = SC; 2 = FCC; 3 = HCP; 4 = Icosahedral; 5 = BCC.

'alloytype'

The alloy structure identified. 0 = unidentified; 1 = pure element; 2 = L1_0; 3 = L1_2 majority atom; 4 = L1_2 minority atom. 0 is returned if structure != 2 or if no known alloy structure is recognized.

'rmsd'

The RMSD error in the fitting to the template, or inf if no structure was identified.

'scale'

The average distance to the nearest neighbors for structures 1-4; or the average distance to nearest and next-nearest neighbors for structure 5 (BCC); or inf if no structure was identified.

'orientation'

The orientation of the crystal lattice, expressed as a unit quaternion. If no structure was found, the illegal value (0, 0, 0, 0) is returned.

'strain'

The strain tensor as a symmetric 3x3 matrix. Only present if calculate_strains=True. The trace of the matrix is 1.0, since a hydrostatic component of the strain cannot be determined without a-priori knowledge of the reference lattice parameter. If such knowledge is available, the hydrostatic component of the strain can be calculated from scale[i].

'info'

A tuple of two integers: the number of atoms analyzed by PTM, and the number of atoms skipped due to insufficient neighbors.

'nblist'

A neighbor list object. Only present if return_nblist=True.

class asap3.analysis.ptm.PTMobserver(atoms, cutoff=10.0, rmsd_max=None, target_structures=None, calculate_strains=False, quick=False, quantity='structure', analyze_first=True)[source]

Polyhedral Template Matching observer object.

By default, sets the tags of the atoms according to their local crystal structure. 0 = none; 1 = FCC; 2 = HCP; 3 = BCC; 4 = Icosahedral; 5 = SC.

This class is intended for use as an observer, so its analyze method is called automatically by e.g. the dynamics. It can itself act as a subject, so a Plotter or a Trajectory can be called just after the calculations. The get_data method returns the full dictionary of PTM data from the last calculation.

Parameters:
  • atoms (ase.Atoms) – The atoms object.

  • cutoff (float, optional) – A cutoff used for the neighbor list. It must be large enough that all nearest neighbors are returned (second-nearest for BCC). Using too large a value may impact performance, but not results. The default is 10.0.

  • rmsd_max (float, optional) – If set, matches with an RMSD above this threshold are reclassified as unknown structure (type 0). This is done as post-processing, and is completely equivalent to data['structure'][data['rmsd'] > rmsd_max] = 0.

  • target_structures (tuple of str, optional) – The structures to be investigated. Defaults to ('sc', 'fcc', 'hcp', 'ico', 'bcc'). It MUST be a tuple, not a list or other sequence.

  • calculate_strains (bool, optional) – Set to True to calculate strains. The default is False.

  • quick (bool, optional) – Set to True to skip topological ordering of neighbors. It gives a factor of two in speed, but more misclassified atoms at high temperatures. The default is False.

  • quantity (str or None, optional) – The quantity used to set the tags, either 'structure' (the default) or 'alloytype'. If None, the tags are not set.

  • analyze_first (bool, optional) – Whether an analysis should be made as soon as this object is created. Leave as True if you plan to attach a Trajectory as an observer to this object, and the Trajectory will save the initial state.

See also

PTM

The function performing the analysis.

analyze()[source]

Runs the PTM analysis.

update()

Runs the PTM analysis.

class asap3.analysis.ptm.PTMdislocations(atoms, cutoff=10.0, rmsd_max=None, target_structures=None, calculate_strains=False, quick=False, quantity='structure', analyze_first=True)[source]

Polyhedral Template Matching observer detecting dislocations.

Sets the tags of the atoms according to their local crystal structure, after postprocessing of the HCP atoms for dislocation detection. The dislocation detection assumes that the majority of the system is in the FCC structure.

Tags are set to 0 = none; 1 = FCC; 2 = HCP; 3 = BCC; 4 = Icosahedral; 5 = SC; 6 = Twin boundary; 7 = Stacking fault; 8 = Partial dislocation line.

Otherwise, this object is like PTMobserver; refer to it for further documentation and parameters, with the exception that the quantity parameter is ignored.

analyze()[source]

Runs the PTM analysis.

update()

Runs the PTM analysis.

Radial distribution functions

class asap3.analysis.rdf.RadialDistributionFunction(atoms, rMax, nBins, groups=None, average=1, autoclear=False, verbose=False)[source]

Create a RadialDistributionFunction observer.

Parameters:
  • atoms (ase.Atoms) – The atoms being analyzed.

  • rMax (float) – The maximum distance in the RDF.

  • nBins (int) – The number of bins in the histograms, i.e. how many points are calculated on the curve. Increasing this has only a small effect on memory consumption and calculation time (unless it is increased to absurd values).

  • groups (numpy.ndarray, optional) – An array of non-negative integers, one for each atom. Defines which groups the atoms belong to. The RDF is calculated for each group.

  • average (int, optional) – How many times the RDF should be calculated and averaged before any observer of this object is notified and/or the RDF is saved to a file. The default is 1.

  • autoclear (bool, optional) – Whether the RDF should be cleared after it has been processed by observers and/or written to a file. The default, False, is to continue to accumulate data. The actually clearing is delayed until the next time update() is called

  • verbose (bool, optional) – Print progress information to stderr. The default is False.

attach(function, interval=1, *args, **kwargs)

Attach a callback function.

Parameters:
  • function (callable) – The function to call. If it is not callable, its write method is used instead.

  • interval (int, optional) – Call function every interval steps. The default is 1.

  • *args – Extra positional arguments passed to function.

  • **kwargs – Extra keyword arguments passed to function.

clear()[source]

Clear the accumulated RDFs. Called automatically.

get_rdf(groups=None, elements=None, normalize='volume')[source]

Get an RDF.

If get_rdf is called on a newly created RadialDistributionFunction object that was created without specifying the average parameters, it is assumed that the user is not using the object as an observer, but wants an immediate calculation of the RDF. In that case, calling get_rdf triggers the calculation of the RDFs. In all other cases previously stored RDFs are returned.

Parameters:
  • groups (int or list of int, optional) – Only get the RDF for atoms in these groups. The default is all groups.

  • elements (int or tuple of int, optional) – Get the partial RDF for one element, given as an atomic number, or for two elements, given as a tuple of two atomic numbers (a, b). The returned RDF then tells how many neighbors an atom has, or how many b neighbors an a atom has, respectively.

  • normalize (str, optional) – How the RDF is normalized. The default is 'volume'.

Returns:

numpy.ndarray – The radial distribution function.

classmethod load(filename)[source]

Create a new RDF object from a file.

output_file(prefix)[source]

Give the file prefix for saving RDFs, and turn on saving.

Turn on the autosaving feature, and specify the prefix of the file name. The prefix should be a string, and should not contain the “%” character unless you know what you are doing.

save(filename=None)[source]

Trigger a save into a file.

Normally called automatically, but calling it manually is allowed.

update(atoms=None)[source]

Calculate the RDF of the atoms.

Make an RDF calculation now.

If average == 1, any observers of this object are notified. If average > 1, the calculated RDFs are accumulated, and once a sufficient number of RDFs have been accumulated the observers are notified and the averaged RDFs are ready.

Parameters:

atoms (ase.Atoms, optional) – Replace the atoms being observed before calculating.

Finding and cutting out clusters

Identifying connected clusters of atoms, saving them to files, and tracking the position of a cluster through a trajectory.

asap3.analysis.findcluster.findclusters(atoms, tag, cutoff, arrayname='cluster', tags=None, returnclusters=False)[source]

Find clusters of atoms with a given tag.

Find connected clusters of atoms with a given tag. Each cluster is assigned a cluster number starting with 0, the cluster numbers are assigned to an array named 'cluster' on the atoms. The name of the array can be changed.

Parameters:
  • atoms (ase.Atoms) – The atoms to be analyzed.

  • tag (int or None) – The tag identifying interesting atoms. atoms.get_tags() is used to read the tags from the atoms, and only atoms matching tag are considered in the clustering. Set tag=None to consider all atoms (for a dense sample this gives a single cluster spanning the entire system).

  • cutoff (float) – The cutoff distance used to identify if two atoms are neighbors.

  • arrayname (str, optional) – The name of the array on the atoms where the cluster ID is stored. Changed to 'dislocation' by the dislocation module. The default is 'cluster'.

  • tags (numpy.ndarray, optional) – An array to be used as tags instead of atoms.get_tags(). Ignored if tag=None.

  • returnclusters (bool, optional) – If True, also return a dictionary mapping cluster sizes to lists of clusters. The default is False.

Returns:

  • cluster_sizes (list of int) – The size of each cluster.

  • clustermap (dict) – Maps a cluster size to the list of clusters of that size; each such cluster is itself a list of atom indices. Only returned if returnclusters is True.

asap3.analysis.cutcluster.cut_clusters_by_size(atoms, tag, cutoff, size, folder, environment=0, environ_exclude=[1])[source]

Find clusters of specific size, save to files.

Find connected clusters (using asap3.analysis.findcluster.findclusters()), pick the ones with a given size, and save them to a folder as Trajectory files.

Parameters:
  • atoms (ase.Atoms) – The atoms to be analyzed.

  • tag (int or None) – The tag identifying interesting atoms. atoms.get_tags() is used to read the tags from the atoms, and only atoms matching tag are considered in the clustering. Set tag=None to consider all atoms (for a dense sample this gives a single cluster spanning the entire system).

  • cutoff (float) – The cutoff distance used to identify if two atoms are neighbors.

  • size (int or sequence of int) – The cluster size (or sizes) picked out.

  • folder (str) – The folder where the output is saved.

  • environment (float, optional) – If nonzero, any atom within that range of the cluster is also included, unless its tag is in environ_exclude. The default is 0.

  • environ_exclude (sequence of int, optional) – Atoms with these tags are not included in the environment. The default is [1].

class asap3.analysis.clusterposition.ClusterCenter(cutoff=3.0)[source]
calculate_center(atoms, startatom=None)[source]

Calculate the center of mass position of a cluster of atoms.

Parameters:
  • atoms (ase.Atoms) – The atoms containing the cluster.

  • startatom (int, optional) – An atom belonging to the cluster. If not specified, one of the highest coordinated atoms is used.

Returns:

numpy.ndarray – The center of mass of the cluster, as a vector of three floats.

add_atom_to_cluster(n, pos)[source]

Add an atom and all its neighbors to the cluster.

calculate_from_trajectory(traj, startatom=None, selector=None)[source]

Calculate the center of mass for a cluster in a trajectory file.

Parameters:
  • traj (ase.io.Trajectory or str) – The trajectory object, or the name of a trajectory file.

  • startatom (int, optional) – An atom guaranteed to be in the cluster. If not specified, the atom with the highest coordination number is used (if there is only one cluster this should work).

  • selector (callable, optional) – A function defining which atoms should be considered. It is called with one argument, the atoms object, and should return either an array of booleans, one per atom, indicating whether they should be included, or an array of integers interpreted as the indices of the atoms to be included. This can e.g. be used to select a cluster sitting on a substrate.

Returns:

numpy.ndarray – The center-of-mass positions, one for each frame in the trajectory.

Running averages

class asap3.analysis.averagepositions.RunningAverage(atoms, interval, numavg)[source]

Calculate running average positions of atoms.

Attach this observer to the atoms to make average positions available e.g. for CNA analysis. The observer is called often (maybe every 5 time steps). After it has been called interval times (or a multiple hereof) the average positions are calculated, and the attached analysis functions are called.

During analysis, positions of the atoms are set to the average positions. After analysis, observers can be called e.g. to store the results. Observers may be called before or after the positions are restored to their instantaneous values.

Parameters:
  • atoms (ase.Atoms) – The atoms being observed. Temporary data is stored on the atoms.

  • interval (int) – How often analysis is done.

  • numavg (int) – How many frames are used for the averaging. If numavg == interval, all calls are used to collect data, and the average is over all times since the last analysis. If numavg < interval, only the last numavg calls before the analysis are used to collect data. numavg > interval is not supported.

Raises:

NotImplementedError – If numavg is greater than interval.

Warning

As the atoms are changed before and after analysis, migration may be triggered in parallel simulations.

Notes

The important methods are

update()

Update the running average, and do analysis if needed. This is the method that should be attached to the dynamics.

__call__()

Same as update().

attach_analysis(callable, *args, **kwargs)

Attach an analysis function. Arguments are passed on.

attach_observer(callable, interval=1, *args, **kwargs)

Call an external observer, for example to store the result of the analysis. The observer is called every interval’th time the analysis is performed; it is rare to set interval different from 1. The observer is called after the positions have been restored to their instantaneous values.

attach_observer_avgpos(callable, interval=1, *args, **kwargs)

As attach_observer, except that the observer is called while the positions still have their average value.

attach_analysis(func, *args, **kwargs)[source]

Attach an analysis method

attach_observer(func, interval=1, *args, **kwargs)[source]

Attach an observer called after analysis

attach_observer_avgpos(func, interval=1, *args, **kwargs)[source]

Attach an observer called after analysis but while positions remain averaged.

reset()[source]

Reset internal variables after an analysis

set_extra_data(name, source=None, once=False)[source]

Forward to observers that extra data should be stored.

This method makes sure that if a BundleTrajectory is attached to an NPT dynamics through a RunningAverage object, then information about the dynamics is still saved in the BundleTrajectory.

It works by forwarding the call to set_extra_data to any observers having a set_extra_data method, whether they are attached before or after calling this method.