Utillity functions and classes

This module contains utility functions and classes.

ase.utils.opencew(filename, world=None)[source]

Create and open filename exclusively for writing.

If master cpu gets exclusive write access to filename, a file descriptor is returned (a dummy file descriptor is returned on the slaves). If the master cpu does not get write access, None is returned on all processors.

ase.utils.gcd()

greatest common divisor of x and y

ase.utils.seterr(**kwargs)[source]

Set how floating-point errors are handled.

See np.seterr() for more details.

ase.utils.plural(n, word)[source]

Use plural for n!=1.

>>> plural(0, 'egg'), plural(1, 'egg'), plural(2, 'egg')
('0 eggs', '1 egg', '2 eggs')
ase.utils.formula_hill(numbers, empirical=False)[source]

Convert list of atomic numbers to a chemical formula as a string.

Elements are alphabetically ordered with C and H first.

If argument \(empirical\), element counts will be divided by greatest common divisor to yield an empirical formula

ase.utils.formula_metal(numbers, empirical=False)[source]

Convert list of atomic numbers to a chemical formula as a string.

Elements are alphabetically ordered with metals first.

If argument \(empirical\), element counts will be divided by greatest common divisor to yield an empirical formula

ase.utils.convert_string_to_fd(name, world=None)[source]

Create a file-descriptor for text output.

Will open a file for writing with given name. Use None for no output and ‘-‘ for sys.stdout.

ase.utils.workdir(path, mkdir=False)[source]

Temporarily change, and optionally create, working directory.

class ase.utils.timing.Timer(print_levels=1000)[source]

Timer object.

Use like this:

timer = Timer()
timer.start('description')
# do something
timer.stop()

or:

with timer('description'):
    # do something

To get a summary call:

timer.write()
class ase.utils.timing.timer(name)[source]

Decorator for timing a method call.

Example:

from ase.utils.timing import timer, Timer

class A:
    def __init__(self):
        self.timer = Timer()

    @timer('Add two numbers')
    def add(self, x, y):
        return x + y

Symmetry equivalence checker

This module compares two atomic structures to see if they are symmetrically equivalent. It is based on the recipe used in XtalComp

class ase.utils.structure_comparator.SymmetryEquivalenceCheck(angle_tol=1.0, ltol=0.05, stol=0.05, vol_tol=0.1, scale_volume=False, to_primitive=False)[source]

Compare two structures to determine if they are symmetry equivalent.

Based on the recipe from Comput. Phys. Commun. 183, 690-697 (2012).

Parameters:

angle_tol: float

angle tolerance for the lattice vectors in degrees

ltol: float

relative tolerance for the length of the lattice vectors (per atom)

stol: float

position tolerance for the site comparison in units of (V/N)^(1/3) (average length between atoms)

vol_tol: float

volume tolerance in angstrom cubed to compare the volumes of the two structures

scale_volume: bool

if True the volumes of the two structures are scaled to be equal

to_primitive: bool

if True the structures are reduced to their primitive cells note that this feature requires spglib to installed

Examples:

>>> from ase.build import bulk
>>> from ase.utils.structure_comparator import SymmetryEquivalenceCheck
>>> comp = SymmetryEquivalenceCheck()

Compare a cell with a rotated version

>>> a = bulk('Al', orthorhombic=True)
>>> b = a.copy()
>>> b.rotate(60, 'x', rotate_cell=True)
>>> comp.compare(a, b)
True

Transform to the primitive cell and then compare

>>> pa = bulk('Al')
>>> comp.compare(a, pa)
False
>>> comp = SymmetryEquivalenceCheck(to_primitive=True)
>>> comp.compare(a, pa)
True

Compare one structure with a list of other structures

>>> import numpy as np
>>> from ase import Atoms
>>> s1 = Atoms('H3', positions=[[0.5, 0.5, 0],
...                             [0.5, 1.5, 0],
...                             [1.5, 1.5, 0]],
...            cell=[2, 2, 2], pbc=True)
>>> comp = SymmetryEquivalenceCheck(stol=0.068)
>>> s2_list = []
>>> for d in np.linspace(0.1, 1.0, 5):
...     s2 = s1.copy()
...     s2.positions[0] += [d, 0, 0]
...     s2_list.append(s2)
>>> comp.compare(s1, s2_list[:-1])
False
>>> comp.compare(s1, s2_list)
True
compare(s1, s2)[source]

Compare the two structures.

Return True if the two structures are equivalent, False otherwise.

Parameters:

s1: Atoms object.

Transformation matrices are calculated based on this structure.

s2: Atoms or list

s1 can be compared to one structure or many structures supplied in a list. If s2 is a list it returns True if any structure in s2 matches s1, False otherwise.