tcutility package#

Subpackages#

Submodules#

tcutility.cache module#

timed_cache(delay)[source]#

Decorator that creates a timed cache for the function or method. This cache will expire after a chosen amount of time.

Parameters:

delay (float) – the expiry time for the function cache.

cache(func)[source]#

Function decorator that stores results from previous calls to the function or method.

cache_file(file)[source]#

Function decorator that stores results of a function to a file. Because results are written to a file the values persist between Python sessions. This is useful, for example, for online API calls.

Parameters:

file – the filepath to store function call results to. Files will be stored in the platform dependent temporary file directory.

See also

platformdirs.user_cache_dir for information on the temporary directory.

tcutility.cite module#

cite(doi, style='wiley', mode='html')[source]#

Format an article in a certain style.

Parameters:
  • doi (str) – the article DOI to generate a citation for.

  • style (str) – the style formatting to use. Can be ['wiley', 'acs', 'rsc'].

  • mode – the formatting mode. Can be ['html', 'latex', 'plain'].

Return type:

str

tcutility.connect module#

class OSName(*values)[source]#

Bases: Enum

An enumeration of the different operating systems.

WINDOWS = 1#
LINUX = 2#
MACOS = 3#
class Connection(server=None, username=None, key_filename=None)[source]#

Bases: object

Main class used for creating and using SSH sessions to remote servers. It gives you the option to execute any shell code, but also provides useful default commands (for example, cd and ls). The Connection class also allows you to download and upload files between your local machine and the remote.

Parameters:
  • server (str) – the adress of the server you want to connect to. You can prepend the server adress with your username separated from the adress with a @ character. For example: Connection('username@server.address.nl') is the same as Connection('server.address.nl', 'username').

  • username (str) – the username used to log in to the remote server.

  • key_filename (str) – if you cannot log in using only the ssh command you can try to give the filename of the private key that matches a public key on the server.

Usage:

This class is a context manager and the with-syntax should be used to open and automatically close connections. For example, to open a connection to the Snellius supercomputer we use the following code:

from tcutility.connect import Connection

with Connection('username@server.address.nl') as server:
    print(server.pwd())  # this will print the home-directory of the logged-in user
    server.cd('example/path/to/some/data')
    print(server.pwd())  # ~/example/path/to/some/data

Warning

Currently we only support logging in using SSH keys. Make sure that you can log in to the remote with SSH keys. There might be server specific instructions on how to enable this authentication method.

open()[source]#
close()[source]#
full_path(path)[source]#
Return type:

str

execute(command)[source]#

Run a command on the server and return the output.

Parameters:

command (str) – the command to run on the server.

Return type:

str

Returns:

Data written in stdout after the command was run.

Raises:

RuntimeError` with error message if there was something printed to the stderr

Note

The __call__ method redirects to this method. This means you can directly call the Connection object with your command.

ls(path='')[source]#

Run the ls program and return useful information about the paths.

Parameters:

path – the path to run ls on.

Return type:

Result

Returns:

Result object containing information from the output of the ls program.

The keys are the path names and the values contain the information.

  • owner (str) - the username of the owner of the path.

  • date (datetime.datetime) - datetime object holding the date the file was created.

  • is_dir (bool) - whether the path is a directory.

  • is_hidden (bool) - whether the path is hidden.

  • permissions (str) - the permissions given to the path.

cd(path='~')[source]#

Run the cd command.

Parameters:

path – the path to change directories to. This is relative to the current directory.

Note

Due to limitations with some servers (e.g. Snellius) we do not actually run the cd command, but update the internal Connection.currdir attribute. Before running any command we prepend with cd {self.currdir}; .... In this way we run commands from the correct directory.

pwd()[source]#

Run the pwd command.

Note

Due to limitations with some servers (e.g. Snellius) we do not actually run the pwd command, instead we return the internal Connection.currdir attribute. See the Connection.cd() method for more details.

Return type:

str

mkdir(dirname)[source]#

Run the mkdir command.

Parameters:

dirname – the name of the directory to make. This is relative to the current directory.

rm(file_path)[source]#
rmtree(dirname)[source]#
download(server_path, local_path)[source]#

Download a file from the server and store it on your local machine.

Parameters:
  • server_path (str) – the path on the server to the file to download. The path is relative to the current directory.

  • local_path (str) – the path on the local machine where the file is stored.

upload(local_path, server_path=None)[source]#

Upload a file from your local machine to the server. If the server_path is not given, store it in the current directory.

Parameters:
  • local_path (str) – the path on the local machine where the file to be uploaded is stored.

  • server_path (str) – the path to upload the file to. If not given or set to None we upload the file to the current directory with the same filename.

path_exists(path)[source]#
open_file(file_path)[source]#
chmod(rights, file_path)[source]#
class ServerFile(file_path, server)[source]#

Bases: object

class Server(username=None)[source]#

Bases: Connection

Helper subclass of :class:Connection that is used to quickly connect to a specific server. The constructor takes only the username as the server url is already set. You can also specify default settings for sbatch calls, for example the partition or time-limits.

server = None#
sbatch_defaults = {}#
preamble_defaults = {}#
postamble_defaults = {}#
program_modules = {}#
class Local[source]#

Bases: Server

server = None#
sbatch_defaults = {}#
preamble_defaults = {}#
postamble_defaults = {}#
program_modules = {}#
home = '~'#
execute(command)[source]#

Execute a command on the local machine and return the output.

Parameters:

command (str) – the command to run.

Return type:

str

Note

We use subprocess.check_output with the shell=True argument enabled.

mkdir(dirname)[source]#

Run the mkdir command.

Parameters:

dirname – the name of the directory to make. This is relative to the current directory.

rm(file_path)[source]#
rmtree(dirname)[source]#
download(server_path, local_path)[source]#

Download a file from the server and store it on your local machine.

Parameters:
  • server_path (str) – the path on the server to the file to download. The path is relative to the current directory.

  • local_path (str) – the path on the local machine where the file is stored.

upload(local_path, server_path=None)[source]#

Upload a file from your local machine to the server. If the server_path is not given, store it in the current directory.

Parameters:
  • local_path (str) – the path on the local machine where the file to be uploaded is stored.

  • server_path (str) – the path to upload the file to. If not given or set to None we upload the file to the current directory with the same filename.

path_exists(path)[source]#
Return type:

bool

open_file(file_path)[source]#
chmod(rights, path)[source]#
pwd()[source]#

Run the pwd command.

Note

Due to limitations with some servers (e.g. Snellius) we do not actually run the pwd command, instead we return the internal Connection.currdir attribute. See the Connection.cd() method for more details.

ls(dirname)[source]#

Run the ls program and return useful information about the paths.

Parameters:

path – the path to run ls on.

Returns:

Result object containing information from the output of the ls program.

The keys are the path names and the values contain the information.

  • owner (str) - the username of the owner of the path.

  • date (datetime.datetime) - datetime object holding the date the file was created.

  • is_dir (bool) - whether the path is a directory.

  • is_hidden (bool) - whether the path is hidden.

  • permissions (str) - the permissions given to the path.

class Ada(username=None)[source]#

Bases: Server

Default set-up for a connection to the Ada cluster. By default we use the tc partition.

server = 'ada.labs.vu.nl'#
sbatch_defaults = {'N': 1, 'mem': 250000, 'ntasks_per_node': 16, 'p': 'tc'}#
preamble_defaults = {'AMS': ['export SCM_TMPDIR="/scratch/$SLURM_JOBID"', 'srun mkdir -p $SCM_TMPDIR', 'chmod 700 $SCM_TMPDIR']}#
program_modules = {'AMS': {'2021': 'module load shared ams/2021.102', '2022': 'module load shared ams/2022.103', '2023': 'module load shared ams/2023.101', '2024': 'module load shared ams/2024.102', 'latest': 'module load shared ams/2024.102'}}#
postamble_defaults = {'AMS': ['srun rm -rf $SCM_TMPDIR']}#
class Snellius(username=None)[source]#

Bases: Server

Default set-up for a connection to the Snellius cluster. By default we use the rome partition and a time-limit set to 120:00:00.

server = 'snellius.surf.nl'#
sbatch_defaults = {'N': 1, 'ntasks_per_node': 16, 'p': 'rome', 't': '120:00:00'}#
program_modules = {'AMS': {'2023': 'module load 2023 AMS/2023.104-intelmpi', '2024': 'module load 2024 AMS/2024.104-intelmpi-aocl', 'latest': 'module load 2024 AMS/2024.104-intelmpi-aocl'}}#
get_current_server()[source]#

Return the Server-subclass of the server location of the current shell. If the server location could not be detected returns Local.

Return type:

Server

tcutility.constants module#

tcutility.environment module#

requires_optional_package(package_name, os_name=None)[source]#

Ensures a given package is available before running a function, otherwise raises an ImportError. This can be used to check for optional dependencies which are required for specific functionality.

Parameters:
  • package_name (str) – name of the required package

  • os_name (Optional[str]) – name of the os that this package must be specified on, if omitted defaults to all os

tcutility.errors module#

Module containing errors to distinguish between tcutility-specific errors and general python errors from other packages / scripts.

exception TCError[source]#

Bases: Exception

Base class for all errors in the tcutility package.

exception TCJobError(job_class, message)[source]#

Bases: TCError

An error that occurs when a job fails to run properly.

exception TCMoleculeError[source]#

Bases: TCError

An error that occurs when a molecule is not in a valid state.

exception TCCompDetailsError(section, message)[source]#

Bases: TCError

An error that occurs when the computation details are not in a valid state. It expects a section such as a “Functional” or “Basis set” and a message.

exception MissingOptionalPackageError(package_name)[source]#

Bases: TCError

Missing optional package related error.

This is a template taken from the PLAMS package (SCM-NV/PLAMS).

extras_install = {'attrs': 'vdd', 'docx': 'report', 'h5py': 'analysis', 'htmldocx': 'report', 'matplotlib': 'plot', 'networkx': 'analysis', 'opencv-python': 'report', 'openpyxl': 'vdd', 'pandas': 'vdd', 'pyfmo': 'adf', 'requests': 'cite', 'scipy': 'analysis'}#

tcutility.formula module#

parse_molecule(molecule)[source]#

Analyse a molecule and return the molstring describing its parts. Each part will then be separated by a + sign in the new string.

Parameters:

molecule (Molecule) – plams.Molecule object to be parsed.

Return type:

str

Returns:

A string that contains each part of the molecule separated by a + sign, for use in molecule() function for further formatting.

molecule(molecule, mode='unicode')[source]#

Parse and return a string containing a molecular formula that will show up properly in LaTeX, HTML or unicode.

Parameters:
  • molecule (Union[str, Molecule]) – plams.Molecule object or a string that contains the molecular formula to be parsed. It can be either single molecule or a reaction. Molecules should be separated by + or ->.

  • mode (str) – the formatter to convert the string to. Should be unicode, html, latex, pyplot.

Return type:

str

Returns:

A string that is formatted to be rendered nicely in either HTML or LaTeX. In the returned strings any numbers will be subscripted and +, -, * and will be superscripted. For latex and pyplot modes we apply \mathrm to letters.

Examples

>>> molecule('C9H18NO*')
'C₉H₁₈NO•'
>>> molecule('C2H2 + CH3* -> C2H2CH3', mode='html')
'C<sub>2</sub>H<sub>2</sub> + CH<sub>3</sub><sup>•</sup> -> C<sub>2</sub>H<sub>2</sub>CH3'

See also

The parse_molecule() function is used to convert plams.Molecule objects to a molecular formula.

tcutility.geometry module#

class Transform[source]#

Bases: object

Transformation matrix that handles rotation, translation and scaling of sets of 3D coordinates.

Build and return a transformation matrix. This 4x4 matrix encodes rotations, translations and scaling.

\(\textbf{M} = \begin{bmatrix} \textbf{R}\text{diag}(S) & \textbf{T} \\ \textbf{0}_3 & 1 \end{bmatrix}\)

where \(\textbf{R} \in \mathbb{R}^{3 \times 3}\), \(\textbf{T} \in \mathbb{R}^{3 \times 1}\) and \(\textbf{0}_3 = [0, 0, 0] \in \mathbb{R}^{1 \times 3}\).

When applied to a coordinates \([\textbf{x}, \textbf{y}, \textbf{z}, \textbf{1}]^T \in \mathbb{R}^{n \times 4}\) it will apply these transformations simultaneously.

apply(v)[source]#

Applies the transformation matrix to vector(s) \(v \in \mathbb{R}^{N \times 3}\).

Application is a three-step process:

  1. Append row vector of ones to the bottom of \(v\)

  2. Apply the transformation matrix: \(\textbf{M}v\)

  3. Remove the bottom row vector of ones and return the result

Return type:

ndarray

Returns:

A new array \(v' = \textbf{M}v\) that has been transformed using this transformation matrix.

Note

The Transform.__call__() method redirects to this method. Calling transform.apply(coords) is the same as transform(coords).

combine_transforms(other)[source]#

Combine two different transform objects. This involves creating a new Transform object and multiplying the two transform matrices and assigning it to the new object.

Parameters:

other (Transform) – the transformation matrix object to combine this one with.

Return type:

Transform

Returns:

A new transformation matrix that is a product of the original (left side) and other (right side) matrices.

Note

The Transform.__matmul__() method redirects to this method. Calling new = this.combine_transforms(other) is the same as new = this @ other.

translate(T=None, x=None, y=None, z=None)[source]#

Add a translation component to the transformation matrix. Arguments can be given as a container of x, y, z values. They can also be given separately. You can also specify x, y and z components separately

Example usage:
Transform.translate([2, 3, 0])
Transform.translate(x=2, y=3)
rotate(R=None, x=None, y=None, z=None)[source]#

Add a rotational component to transformation matrix. Arguments can be given as a rotation matrix R in R^3x3 or by specifying the angle to rotate along the x, y or z axes

Example usage:
Transform.rotate(get_rotmat(x=1, y=-1))
Transform.rotate(x=1, y=-1)
scale(S=None, x=None, y=None, z=None)[source]#

Add a scaling component to the transformation matrix. Arguments can be given as a container of x, y, z values. You can also specify x, y and z components separately

Example usage:
Transform.scale([0, 0, 3])
Transform.scale(z=3)
reflect(normal=None)[source]#

Add a reflection across a plane given by a normal vector to the transformation matrix. The reflection is given as

\(R = \mathbb{I} - 2\frac{nn^T}{n^Tn} \in \mathbb{R}^{3 \times 3}\)

where \(n\) is the normal vector of the plane to reflect along.

Parameters:

normal (ndarray) – the normal vector of the plane to reflect across. If not given or None, it will be set to one unit along the x-axis, i.e. a reflection along the yz-plane.

References

https://en.wikipedia.org/wiki/Reflection_(mathematics)

get_rotmat()[source]#
get_translation()[source]#
to_vtkTransform()[source]#
class KabschTransform(X, Y)[source]#

Bases: Transform

Use Kabsch-Umeyama algorithm to calculate the optimal transformation matrix \(T_{Kabsch}\) that minimizes the RMSD between two sets of coordinates \(X \in \mathbb{R}^{N \times 3}\) and \(Y \in \mathbb{R}^{N \times 3}\), such that

\(\text{arg}\min_{T_{Kabsch}} \text{RMSD}(T_{Kabsch}(X), Y)\)

It is numerically stable and works when the covariance matrix is singular. Both sets of points must be the same size for this algorithm to work. The coordinates are first centered onto their centroids before determining the optimal rotation matrix.

Parameters:
  • X (ndarray) – array containing the first set of coordinates. The Kabsch transformation matrix will be made such that applying it to X will yield Y.

  • Y (ndarray) – array containing the second set of coordinates. These coordinates is the target to transform to.

Warning

In principle, the Kabsch-Umeyama algorithm does not care about the dimensions of the coordinates, however we will always assume 3D coordinates as that is our most common use-case. Further, the Transform class also assumes 3D coordinates. If you would like to make use of 2D or 1D Transforms we suggest you simply set the correct axes to zero.

See also

Transform

The main transformation class.

Example

from tcutility import geometry
import numpy as np

# create two arrays that are the same
X, Y = np.arange(5 * 3).reshape(5, 3), np.arange(5 * 3).reshape(5, 3)

# create a transformation matrix to change X
Tx = geometry.Transform()
Tx.rotate(x=1, y=1, z=1)
Tx.translate(x=1, y=1, z=1)

X = Tx(X)

# get the Kabsch transformation matrix
Tkabsch = geometry.KabschTransform(X, Y)

# check if applying the transformation matrix to X yields Y
assert np.isclose(Tkabsch(X), Y).all()

References

class MolTransform(mol)[source]#

Bases: Transform

A subclass of Transform that is designed to generate transformation for a molecule. It adds, among others, methods for aligning atoms to specific vectors, planes, or setting the centroid of the molecule. The nice thing is that the class applies the transformations based only on the atom indices given by the user.

Parameters:

mol (Molecule) – the molecule that is used for the alignment.

Note

Indexing starts at 1 instead of 0.

center(*indices)[source]#

Center the molecule on given indices or by its centroid.

Parameters:

indices – the indices that are used to center the molecule. If not given the centering will be done based on all atoms.

align_to_vector(index1, index2, vector=None)[source]#

Align the molecule such that a bond lays on a given vector.

Parameters:
  • index1 (int) – index of the first atom.

  • index2 (int) – index of the second atom.

  • vector (Sequence[float]) – the vector to align the atoms to. If not given or None it defaults to (1, 0, 0).

align_to_plane(index1, index2, index3, vector=None)[source]#

Align a molecule such that the normal of the plane defined by three atoms is aligned to a given vector.

Parameters:
  • index1 (int) – index of the first atom.

  • index2 (int) – index of the second atom.

  • index3 (int) – index of the third atom.

  • vector (Sequence[float]) – the vector to align the atoms to. If not given or None it defaults to (0, 1, 0).

get_rotmat(x=None, y=None, z=None)[source]#

Create a rotation matrix based on the Tait-Bryant sytem. In this system, x, y, and z are angles of rotation around the corresponding axes. This function uses the right-handed convention

Parameters:
  • x (float) – Rotation around the x-axis in radians.

  • y (float) – Rotation around the y-axis in radians.

  • z (float) – Rotation around the z-axis in radians.

Return type:

ndarray

Returns:

the rotation matrix \(\textbf{R} \in \mathbb{R}^{3 \times 3}\) with the specified axis rotations.

See also

apply_rotmat()

For applying the rotation matrix to coordinates.

rotate()

For rotating coordinates directly, given Tait-Bryant angles.

Transform.rotate()

The Transform class allows you to also rotate.

rotmat_to_angles(R)[source]#
Return type:

Tuple[float]

apply_rotmat(coords, R)[source]#

Apply a rotation matrix to a set of coordinates.

Parameters:
  • coords (ndarray) – the coordinates :math`in mathbb{R}^{n times 3}` to rotate.

  • R (ndarray) – the rotation matrix to apply.

Returns:

math`in mathbb{R}^{n times 3}` rotated using the given rotation matrix.

Return type:

New coordinates

See also

get_rotmat()

For creating a rotation matrix.

rotate()

For rotating coordinates directly, given Tait-Bryant angles.

rotate(coords, x=None, y=None, z=None)[source]#

Build and apply a rotation matrix to a set of coordinates.

Parameters:
  • coords (ndarray) – the coordinates :math`in mathbb{R}^{n times 3}` to rotate.

  • x (float) – Rotation around the x-axis in radians.

  • y (float) – Rotation around the y-axis in radians.

  • z (float) – Rotation around the z-axis in radians.

Return type:

ndarray

See also

get_rotmat()

For creating a rotation matrix.

vector_align_rotmat(a, b)[source]#

Calculate a rotation matrix that aligns vector a onto vector b.

Parameters:
  • a (ndarray) – vector that is to be aligned.

  • b (ndarray) – vector that is the target of the alignment.

Return type:

ndarray

Returns:

Rotation matrix R, such that geometry.apply_rotmat(a, R) == b.

tcutility.log module#

class Emojis[source]#

Bases: object

Class containing some useful emojis and other characters. Supports dot-notation and indexation to get a character.

E.g. Emojis.wait == Emojis['wait']

wait = '🕒'#
good = '✅'#
cancel = '🛑'#
sleep = '💤'#
fail = '❌'#
send = '📤'#
receive = '📥'#
empty = '⠀⠀'#
finish = '🏁'#
warning = '⚠️'#
question = '❔'#
info = 'ℹ️'#
rarrow = '─>'#
larrow = '<─'#
lrarrow = '<─>'#
rlarrow = '<─>'#
angstrom = 'Å'#
class NoPrint(stdout=None, stderr=None)[source]#

Bases: object

Context-manager that suppresses printing. It works by redirecting prints to a temporary output file. This file is deleted after exiting the context-manager.

time_stamp()[source]#

Return the current timestamp in a “[YYYY/MM/DD HH:MM:SS] “” format.

log(message='', level=20, end='\\n')[source]#

Print a nicely formatteed message. This function adds the current timestamp and supports multi-line printing (split on the \n escape character). For verbosity levels we use the following convention:

NOTSET   = 0
DEBUG    = 10
INFO     = 20
WARN     = 30
ERROR    = 40
CRITICAL = 50
Parameters:
  • message (Any) – the message to send. Before printing we will use the message.__str__ method to get the string representation. If the message is a dict we use the json module to format the message nicely.

  • level (int) – the level to print the message at. We compare the level against the module-wide log_level variable (by default log_level = 20). If the level is below log_level we do not print it.

  • end (str) – the end of the string. This is usually the new-line character \n.

flow(message='', tags=['straight'], level=20)[source]#

Function to create flowchart-like output. It will print a message prepended by flow elements (arrows and lines). The flow elements are determined based on the given tags.

Return type:

None

table(rows, header=None, sep='   ', hline=[], level=20)[source]#

Print a table given rows and a header. Values in rows will be cast to strings first.

Parameters:
  • rows (List[List[Any]]) – list of nrows sequences containing ncols data inside the table.

  • header (Optional[List[str]]) – list of ncols strings that represent the column names of the table. They will be printed at the top of the table.

  • sep (str) – str representing the separation between columns.

  • hline (List[int]) – list of integers specifying rows after which lines will be drawn. Supports negative indices, e.g. -1 will draw a line at the end of the table.

Returns:

the table in string format, where lines are separated by “n”

Return type:

str

rectangle_list(values, spaces_before=0, level=20)[source]#

This function prints a list of strings in a rectangle to the output. This is similar to what the ls program does in unix.

loadbar(sequence, comment='', Nsegments=50, Nsteps=10, level=20)[source]#

Return values from an iterable sequence and also print a progress bar for the iteration over this sequence.

Parameters:
  • sequence (Union[Iterable[TypeVar(T)], Sequence[TypeVar(T)]]) – any iterable sequence. Should define the __len__ method.

  • comment (str) – a string to be printed at the end of the loading bar to give information about the loading bar.

  • Nsegments (int) – length of the loading bar in characters.

  • Nsteps (int) – number of times to print the loading bar during iteration. If the output is a tty-type stream Nsteps will be set to the length of sequence.

Return type:

Generator[TypeVar(T), None, None]

boxed(message, title=None, message_align='left', title_align='left', round_corners=True, double_edge=False, level=20)[source]#

Print a message surrounded by a box with optional title.

Parameters:
  • message (str) – the message to place in the box. Multiline messages are separated by “n”.

  • title (Optional[str]) – the title placed in the top edge of the box.

  • message_align (str) – alignment of the text inside the box. One of [“left”, “center”, “right”].

  • title_align (str) – alignment of the title. One of [“left”, “center”, “right”].

  • round_corners (bool) – whether the corners of the box should be rounded or not. Rounded corners are only available for single-edge boxes.

  • double_edge (bool) – whether the edges of the box should be double.

Return type:

None

Returns:

The printed message in strings format.

debug(message, level=10, caller_level=2)[source]#

Print a debug message.

info(message, level=20, caller_level=2)[source]#

Print an informative message.

warn(message, level=30, caller_level=2)[source]#

Print a warning message.

error(message, level=40, caller_level=2)[source]#

Print an error message.

critical(message, level=50, caller_level=2)[source]#

Print a critical message.

caller_name(level=1)[source]#

Return the full name of the caller of a function.

Parameters:

level (int) – the number of levels to skip when getting the caller name. Level 1 is always this function. When used by a different function it should be set to 2. E.g. when using the log.warn function level is set to 2.

Return type:

str

Returns:

The full name of the caller function.

tcutility.molecule module#

load(path)[source]#

Load a molecule from a given xyz file path. The xyz file is structured as follows:

[int]
Comment line
[str] [float] [float] [float] atom_tag1 atom_tag2 atom_key1=...
[str] [float] [float] [float] atom_tag1 atom_tag2 atom_key1=...
[str] [float] [float] [float]

mol_tag1
mol_tag2
mol_key1=...
mol_key2 = ...

The xyz file is parsed and returned as a plams.Molecule object. Flags and tags are given as mol.flags and mol.flags.tags respectively. Similarly for the atoms, the flags and tags are given as mol.atoms[i].flags and mol.atoms[i].flags.tags

Return type:

Molecule

save(mol, path, comment='')[source]#

Save a molecule in a custom xyz file format. Molecule and atom flags can be provided as the “flags” parameter of the object (mol.flags and atom.flags).

from_string(s)[source]#

Load a molecule from a string. Currently only supports simple XYZ-files, e.g. not extended XYZ-files with flags.

Parameters:

s (str) – string containing the molecule to parse. This function only reads the element, x, y and z coordinates on each line. Other lines will not be read.

Return type:

Molecule

Returns:

A new molecule object with the elements and coordinates from the input.

Example

s = """
    O      -0.77012509       2.82058313      -0.00000000
    H      -0.77488739       2.61994920      -0.93878823
    H      -0.75583818       2.00242615       0.50201099
    """
mol = from_string(s)
guess_fragments(mol)[source]#

Guess fragments based on data from the xyz file. Two methods are currently supported, see the tabs below. We also support reading of charges and spin-polarizations for the fragments. They should be given as charge_{fragment_name} and spinpol_{fragment_name} respectively.

8

N       0.00000000       0.00000000      -0.81474153
B      -0.00000000      -0.00000000       0.83567034
H       0.47608351      -0.82460084      -1.14410295
H       0.47608351       0.82460084      -1.14410295
H      -0.95216703       0.00000000      -1.14410295
H      -0.58149793       1.00718395       1.13712667
H      -0.58149793      -1.00718395       1.13712667
H       1.16299585      -0.00000000       1.13712667

frag_Donor = 1, 3-5
frag_Acceptor = 2, 6-8
charge_Donor = -1
spinpol_Acceptor = 2

In this case, fragment atom indices must be provided below the coordinates. The fragment name must be prefixed with frag_. Indices can be given as integers or as ranges using -.

Parameters:

mol (Molecule) – the molecule that is to be split into fragments. It should have defined either method shown above. If it does not define these methods this function returns None.

Return type:

Dict[str, Molecule]

Returns:

A dictionary containing fragment names as keys and plams.Molecule objects as values. Atoms that were not included by either method will be placed in the molecule object with key None.

number_of_electrons(mol, charge=0)[source]#

The number of electrons in a molecule.

Parameters:
  • mol (Molecule) – the molecule to count the number of electrons from.

  • charge (int) – the charge of the molecule.

Return type:

int

Returns:

The sum of the atomic numbers in the molecule minus the charge of the molecule.

write_mol_to_xyz_file(out_file, mols, include_n_atoms=False)[source]#

Writes a list of molecules to a file in xyz format.

Return type:

None

write_mol_to_amv_file(out_file, mols, energies, mol_names=None)[source]#

Writes a list of molecules to a file in amv format.

Return type:

None

tcutility.pathfunc module#

split_all(path)[source]#

Split a path into all of its parts.

Parameters:

path (str) – the path to be split, it will be separated using os.path.split().

Return type:

List[str]

Returns:

A list of parts of the original path.

Example

>>> split_all('a/b/c/d')
['a', 'b', 'c', 'd']
get_subdirectories(root, include_intermediates=False, max_depth=None, _current_depth=0)[source]#

Get all sub-directories of a root directory.

Parameters:
  • root (str) – the root directory.

  • include_intermediates (bool) – whether to include intermediate sub-directories instead of only the lowest levels.

  • max_depth (Optional[int]) – the maximum depth depth to look for subdirectories, e.g. setting it to 1 will return only the contents of the root path.

Return type:

List[str]

Returns:

A list of sub-directories with root included in the paths.

Example

Given a file-structure as follows:

root
|- subdir_a
|  |- subsubdir_b
|  |- subsubdir_c
|- subdir_b
|- subdir_c

Then we get the following outputs.

>>> get_subdirectories('root', include_intermediates=True)
['root',
 'root/subdir_a',
 'root/subdir_a/subsubdir_b',
 'root/subdir_a/subsubdir_c',
 'root/subdir_b',
 'root/subdir_c']
path_depth(path)[source]#

Calculate the depth of a given path.

Return type:

int

match(root, pattern, sort_by=None)[source]#

Find and return information about subdirectories of a root that match a given pattern.

Parameters:
  • root (str) – the root of the subdirectories to look in.

  • pattern (str) – a string specifying the pattern the subdirectories should correspond to. It should look similar to a format string, without the f in front of the string. Inside curly braces you can put a variable name, which you can later extract from the Anything inside curly braces will be matched to word characters ([a-zA-Z0-9_-]) including dashes and underscores.

  • sort_by (Optional[str]) – the key to sort the results by. If not given, the results will be returned in the order they were found.

Return type:

Dict[str, dict]

Returns:

A Result object containing the matched directories as keys and information (also Result object) about those matches as the values. Each information dictionary contains the variables given in the pattern. E.g. using a pattern such as {a}/{b}/{c} will populate the info.a, info.b and info.c keys of the info Result object.

Example

Given a file-structure as follows:

root
|- NH3-BH3
|   |- BLYP_QZ4P
|   |  |- extra_dir
|   |  |- blablabla
|   |
|   |- BLYP_TZ2P
|   |  |- another_dir
|   |
|   |- M06-2X_TZ2P
|
|- SN2
|   |- BLYP_TZ2P
|   |- M06-2X_TZ2P
|   |  |- M06-2X_TZ2P

We can run the following scripts to match the subdirectories.

from tcutility import log
# get the matches, we want to extract the system name (NH3-BH3 or SN2)
# and the functional and basis-set
# we don't want the subdirectories
matches = match('root', '{system}/{functional}_{basis_set}')

# print the matches as a table
rows = []
for d, info in matches.items():
    rows.append([d, info.system, info.functional, info.basis_set])

log.table(rows, ['Directory', 'System', 'Functional', 'Basis-Set'])

which prints

[2024/01/17 14:39:08] Directory                  System    Functional   Basis-Set
[2024/01/17 14:39:08] ───────────────────────────────────────────────────────────
[2024/01/17 14:39:08] root/SN2/M06-2X_TZ2P       SN2       M06-2X       TZ2P
[2024/01/17 14:39:08] root/NH3-BH3/BLYP_TZ2P     NH3-BH3   BLYP         TZ2P
[2024/01/17 14:39:08] root/NH3-BH3/M06-2X_TZ2P   NH3-BH3   M06-2X       TZ2P
[2024/01/17 14:39:08] root/SN2/BLYP_TZ2P         SN2       BLYP         TZ2P
[2024/01/17 14:39:08] root/NH3-BH3/BLYP_QZ4P     NH3-BH3   BLYP         QZ4P

tcutility.slurm module#

tcutility.spell_check module#

naive_recursive(a, b)[source]#

The naïve recursive algorithm to obtain the Levenshtein distance between two strings. We do not recommend using this algorithm as it is quite slow and faster alternatives exist.

Parameters:
  • a (str) – strings to compare.

  • b (str) – strings to compare.

Return type:

float

Returns:

The Levenshtein distance between the strings a and b.

See also

wagner_fischer()

A more efficient algorithm to obtain the Levenshtein distance (up to 25x faster).

wagner_fischer(a, b, substitution_cost=1, case_missmatch_cost=1, insertion_cost=1)[source]#

Return the Levenshtein distance using the Wagner-Fischer algorithm. You can also change the penalty for various errors for this algorithm. By default, all types of errors incur a penalty of 1.

Parameters:
  • a (str) – strings to compare.

  • b (str) – strings to compare.

  • substitution_cost (float) – the penalty for the erroneous substitution of a character.

  • case_missmatch_cost (float) – the penalty for miss-matching the case of a character.

  • insertion_cost (float) – the cost for the erroneous insertion or deletion of a character.

Return type:

float

Returns:

The Levenshtein distance between the strings a and b.

Example

>>> wagner_fischer('kitten', 'sitting')
3

See also

naive_recursive()

An alternative (and slower) algorithm to obtain the Levenshtein distance.

get_closest(a, others, compare_func=<function wagner_fischer>, ignore_case=False, ignore_chars='', maximum_distance=-1, **kwargs)[source]#

Return strings that are similar to an input string using the Levenshtein distance.

Parameters:
  • a (str) – the string to compare the rest to.

  • others (List[str]) – a collection of strings to compare to a. The returned strings will be taken from this collection.

  • compare_func – the function to use to compare the strings. Defaults to the efficient wagner_fischer() algorithm.

  • ignore_case (bool) – whether the case of the strings is taken into account. If enabled, all strings are turned to lower-case before comparison.

  • ignore_chars (str) – a strings specifying characters that should be ignored.

  • maximum_distance (int) – the maximum Levenshtein distance to allow. If it is lower than the lowest distance for the collection of strings, we return the strings with the lowest distance. If set to None we return the lowest distance strings.

Return type:

List[str]

Returns:

A collection of strings that have a Levenshtein distance to a below maximum_distance or have the lowest distance to a if all strings have a distance greater than maximum_distance. If the lowest distance is 0, return an empty list instead.

Example

>>> closest = get_closest('kitten', ['mitten', 'bitten', 'sitting'])
>>> print(closest)
['mitten', 'bitten']
make_suggestion(a, others, **kwargs)[source]#

Print a warning that gives suggestions for strings that are close to a given string.

Example

>>> make_suggestion('kitten', ['mitten', 'bitten', 'sitting'])
[2024/01/30 15:26:35] [WARNING](main): Could not find "kitten". Did you mean mitten or bitten?

See also

get_closest() for a description of the function arguments.

check(a, others, caller_level=2, **kwargs)[source]#

tcutility.timer module#

class timer(name='', level=20)[source]#

Bases: object

The main timer class. It acts both as a context-manager and decorator.

print_timings()[source]#

tcutility.typing_utilities module#

ensure_list(x)#
squeeze_list(x)#
ensure_2d(x, transposed=False)[source]#

Module contents#

class ADFFragmentJob(*args, **kwargs)[source]#

Bases: ADFJob

add_fragment(mol, name=None, charge=0, spin_polarization=0)[source]#

Add a fragment to this job. Optionally give the name, charge and spin-polarization of the fragment as well.

Parameters:
  • mol (Molecule) – the molecule corresponding to the fragment.

  • name (Optional[str]) – the name of the fragment. By default it will be set to fragment{N+1} if N is the number of fragments already present.

  • charge (int) – the charge of the fragment to be added.

  • spin_polarization (int) – the spin-polarization of the fragment to be added.

frag_occupations(frag=None, subspecies=None, alpha=None, beta=None)[source]#

Set the occupations of the fragments.

Parameters:
  • frag – the fragment to set the occupations for.

  • subspecies – the symmetry subspecies to set the occupations for. If set to None we assume we have A subspecies.

  • alpha – the number of alpha electrons. If set to None we will guess the number of electrons based on the spin-polarization set.

  • beta – the number of beta electrons. If set to None we will guess the number of electrons based on the spin-polarization set.

guess_fragments()[source]#

Guess what the fragments are based on data stored in the molecule provided for this job. This will automatically set the correct fragment molecules, names, charges and spin-polarizations.

See also

tcutility.molecule.guess_fragments() for an explanation of the xyz-file format required to guess the fragments.
ADFFragmentJob.add_fragment() to manually add a fragment.

Note

This function will be automatically called if there were no fragments given to this calculation.

remove_virtuals(frag=None, subspecies=None, nremove=None)[source]#

Remove virtual orbitals from the fragments.

Parameters:
  • frag – the fragment to remove virtuals from. If set to None we remove all virtual orbitals of all fragments.

  • subspecies – the symmetry subspecies to remove virtuals from. If set to None we assume we have A subspecies.

  • nremove – the number of virtuals to remove. If set to None we will guess the number of virtuals based on the basis-set chosen.

run()[source]#

Run the ADFFragmentJob. This involves setting up the calculations for each fragment as well as the parent job. It will also submit a calculation with the SCF iterations set to 0 in order to facilitate investigation of the field effects using PyOrb.

class ADFJob(*args, **kwargs)[source]#

Bases: AMSJob

SCF(iterations=300, thresh=1e-08)[source]#

Set the SCF settings for this calculations.

Parameters:
  • iterations (int) – number of iterations to perform for this calculation. Defaults to 300.

  • thresh (float) – the convergence criteria for the SCF procedure. Defaults to 1e-8.

Note

When setting the number of iterations to 0 or 1 the AlwaysClaimSuccess key will also be set to Yes. This is to prevent the job from being flagged as a failure when reading it using tcutility.results.

SCF_convergence(thresh=1e-08)[source]#

Set the SCF convergence criteria for the job.

Parameters:

thresh (float) – the convergence criteria for the SCF procedure. Defaults to 1e-8.

Deprecated since version 0.9.2: Please use ADFJob.SCF() instead of this method.

basis_set(typ='TZ2P', core='None')[source]#

Set the basis-set type and frozen core approximation for this calculation.

Parameters:
  • typ (str) – the type of basis-set to use. Default is TZ2P.

  • core (str) – the size of the frozen core approximation. Default is None.

Raises:

ValueError – if the basis-set name or core is incorrect.

Note

If the selected functional is the r2SCAN-3c functional, then the basis-set will be set to mTZ2P.

See also

tcutility.data.basis_sets for an overview of the available basis-sets in ADF.

excitations(excitation_number=10, excitation_type='', method='Davidson', use_TDA=False, energy_gap=None)[source]#

Calculate the electronic excitations using TD-DFT.

Parameters:
  • excitation_number (int) – the number of excitations to include. Defaults to 10.

  • excitation_type (str) – the type of excitations to include. Defaults to an empty string, indicating the default value for ADF.

  • method (str) – the excitation methodology to use. Defaults to Davidson. If set to the None, the excitations are disabled.

  • use_TDA (bool) – whether to enable the Tamm-Dancoff approximation. Defaults to False.

  • energy_gap (Optional[List[float]]) – list with two variables from which to limit excitations calculated i.e. (0, 0.3) in Hartrees. Defaults to None.

functional(funtional_name, dispersion='')[source]#

Set the functional to be used by the calculation. This also sets the dispersion if it is specified in the functional name.

Parameters:
  • funtional_name (str) – the name of the functional. The value can be the same as the ones used in the ADF GUI.

  • dispersion (str) – dispersion setting to use with the functional. This is used when you want to use a functional from LibXC.

Raises:

ValueError – if the functional name is not recognized.

Note

Setting the functional to r2SCAN-3c will automatically set the basis-set to mTZ2P.

See also

tcutility.data.functionals for an overview of the available functionals in ADF.

irrep_occupations(irrep, orbital_numbers)[source]#

Set the orbital occupations per irrep.

Parameters:
  • irrep (str) – the irrep to set occupations for.

  • orbital_numbers (str) – the orbital occupation numbers as you would write in an input file.s

multiplicity(val)[source]#

Set the multiplicity of the system. If the value is not one the calculation will also be unrestricted. We use the following values:

  1. singlet

  2. doublet

  3. triplet

The multiplicity is equal to 2*S+1 for spin-polarization S.

occupations(strategy)[source]#

Set the orbital filling strategy for ADF.

Parameters:

strategy (str) – the name of the filling strategy. This can contain multiple of the options allowed.

quality(val='Good')[source]#

Set the numerical quality of the calculation.

Parameters:

val (str) – the numerical quality value to set to. This is the same as the ones used in the ADF GUI. Defaults to Good.

Raises:

ValueError – if the quality value is incorrect.

relativity(level='Scalar')[source]#

Set the treatment of relativistic effects for this calculation.

Parameters:

level (str) – the level to set. Can be the same as the values in the ADF GUI and documentation. By default it is set to Scalar.

Raises:

ValueError – if the relativistic correction level is not correct.

solvent(name=None, eps=None, rad=None, use_klamt=False, radii=None)[source]#

Model solvation using COSMO for this calculation.

Parameters:
  • name (Optional[str]) – the name of the solvent you want to use. Please see the ADF manual for a list of available solvents.

  • eps (Optional[float]) – the dielectric constant of your solvent. You can use this in place of the solvent name if you need more control over COSMO.

  • rad (Optional[float]) – the radius of the solvent molecules. You can use this in place of the solvent name if you need more control over COSMO.

  • use_klamt (bool) – whether to use the klamt atomic radii. This is usually used when you have charged species (?).

  • radii (Optional[Dict[str, float]]) – the atomic radii to use for the COSMO calculation. A dictionary such as {Cl: 1.04} will be converted to Cl = 0.01 in the input script. This gets (partially) overwritten if use_klamt is enables.

Raises:

ValueError – if the solvent name is given, but incorrect.

See also

tcutility.data.cosmo for an overview of the available solvent names and formulas.

spin_polarization(val)[source]#

Set the spin-polarization of the system. If the value is not zero the calculation will also be unrestricted.

symmetry(group)[source]#

Specify the symmetry group to be used by ADF.

Parameters:

group (str) – the symmetry group to be used.

unrestricted(val)[source]#

Whether the calculation should be unrestricted.

class AMSJob(*args, **kwargs)[source]#

Bases: Job

This is the AMS base job which will serve as the parent class for ADFJob, DFTBJob and the future BANDJob. It holds all methods related to changing the settings at the AMS level. It also handles preparing the jobs, e.g. writing runfiles and inputs.

IRC(direction='both', hess_file=None, step_size=0.2, min_path_length=0.1, max_points=300)[source]#

Set the task of the job to intrinsic reaction coordinate (IRC).

Parameters:
  • direction (str) – the direction to take the first step into. By default it will be set to both.

  • hess_file (Optional[str]) – the path to a .rkf file to read the Hessian from. This is the adf.rkf file for ADF calculations. If set to None the Hessian will be calculated prior to starting the IRC calculation.

  • step_size (float) – the size of the step taken between each constrained optimization. By default it will be set to 0.2 \(a_0\sqrt{Da}\).

  • min_path_length (float) – the length of the IRC path before switching to minimization. By default it will be set to 0.1 \(\AA\).

  • max_points (int) – the maximum number of IRC points in a direction. Be default it is set to 300.

PESScan(index=0, distances=None, angles=None, dihedrals=None, sumdists=None, difdists=None, npoints=10)[source]#

Set the task of the job to potential energy surface scan (PESScan).

Parameters:
  • distances (Optional[Sequence[Sequence[Union[int, float]]]]) – sequence of tuples or lists containing [atom_index1, atom_index2, start, end]. Atom indices start at 1. Distances are given in \(\AA\).

  • angles (Optional[Sequence[Sequence[Union[int, float]]]]) – sequence of tuples or lists containing [atom_index1, atom_index2, atom_index3, start, end]. Atom indices start at 1. Angles are given in degrees

  • dihedrals (Optional[Sequence[Sequence[Union[int, float]]]]) – sequence of tuples or lists containing [atom_index1, atom_index2, atom_index3, atom_index4, start, end]. Atom indices start at 1. Angles are given in degrees

  • sumdists (Optional[Sequence[Sequence[Union[int, float]]]]) – sequence of tuples or lists containing [atom_index1, atom_index2, atom_index3, atom_index4, start, end]. Atom indices start at 1. Sum of distances is given in \(\AA\).

  • difdists (Optional[Sequence[Sequence[Union[int, float]]]]) – sequence of tuples or lists containing [atom_index1, atom_index2, atom_index3, atom_index4, start, end]. Atom indices start at 1. Difference of distances is given in \(\AA\).

  • npoints (int) – the number of PES points to optimize.

Note

Currently we only support generating settings for 1-dimensional PESScans. We will add support for N-dimensional PESScans later.

charge(val)[source]#

Set the charge of the system.

constraint(line)[source]#
electric_field(direction, magnitude=None)[source]#

Set an electric field for this system.

Parameters:
  • direction (List[float]) – the vector with the direction and strength of the electric field.

  • magnitude (Optional[float]) – if given, the direction will be normalized and magnitude will be used as the field strength.

geometry_convergence(gradients=1e-05, energy=1e-05, step=0.01, stress=0.0005)[source]#

Set the convergence criteria for the geometry optimization.

Parameters:
  • gradients (float) – the convergence criteria for the gradients during geometry optimizations. Defaults to 1e-5.

  • energy (float) – the convergence criteria for the energy during geometry optimizations. Defaults to 1e-5.

  • step (float) – the convergence criteria for the step-size during geometry optimizations. Defaults to 1e-2.

  • stress (float) – the convergence criteria for the stress-energy per atom during geometry optimizations. Defaults to 5e-4

optimization()[source]#

Set the task of the job to geometry optimization. By default also calculates the normal modes after convergence.

property output_mol_path#

The default file path for output molecules when running ADF calculations. It will not be created for singlepoint calculations.

single_point()[source]#

Set the task of the job to single point.

transition_state(distances=None, angles=None, dihedrals=None, ModeToFollow=1)[source]#

Set the task of the job to transition state search. Optionally you can give some TS coordinates to accelerate convergence. By default also calculates the normal modes after convergence.

Parameters:
  • distances (Optional[Sequence[Sequence[Union[int, float]]]]) – sequence of tuples or lists containing [atom_index1, atom_index2, factor]. Atom indices start at 1.

  • angles (Optional[Sequence[Sequence[Union[int, float]]]]) – sequence of tuples or lists containing [atom_index1, atom_index2, atom_index3, factor]. Atom indices start at 1.

  • dihedrals (Optional[Sequence[Sequence[Union[int, float]]]]) – sequence of tuples or lists containing [atom_index1, atom_index2, atom_index3, atom_index4, factor]. Atom indices start at 1.

  • ModeToFollow (int) – the vibrational mode to follow during optimization.

use_version(version='latest')[source]#

Set the version of AMS to use for the calculation. Which versions are available depends on the location you are currently in. We currently support the following versions:

  • On Snellius: 2023 and 2024.

  • On Bazis: 2021, 2022, 2023 and 2024.

vibrations(enable=True, NegativeFrequenciesTolerance=0.0)[source]#

Set the calculation of vibrational modes.

Parameters:
  • enable (bool) – whether to calculate the vibrational modes.

  • NegativeFrequenciesTolerance (float) – the tolerance for negative modes. Modes with frequencies above this value will not be counted as imaginary. Use this option when you experience a lot of numerical noise.

class CRESTJob(*args, **kwargs)[source]#

Bases: Job

property best_conformer_path#
charge(val)[source]#

Set the charge of the system.

property conformer_directory#
property crest_path: str#
get_conformer_xyz(number=None)[source]#

Return paths to conformer xyz files for this job.

Parameters:

number (Optional[int]) – the number of files to return, defaults to 10. If the directory already exists, for example if the job was already run, we will return up to number files.

get_rotamer_xyz(number=None)[source]#

Return paths to rotamer xyz files for this job.

Parameters:

number (Optional[int]) – the number of files to return, defaults to 10. If the directory already exists, for example if the job was already run, we will return up to number files.

md_length(val)[source]#

Set the length of the molecular dynamics steps. The default length will be multiplied by this value, e.g. the default value is 1.

md_temperature(val)[source]#

Set the temperature of the molecular dynamics steps. Defaults to 400K.

multiplicity(val)[source]#

Set the multiplicity of the system. If the value is not one the calculation will also be unrestricted. We use the following values:

  1. singlet

  2. doublet

  3. triplet

The multiplicity is equal to 2*S+1 for spin-polarization of S.

property rotamer_directory#
solvent(name=None, model='alpb')[source]#

Model solvation using the ALPB or GBSA model. For available solvents see the XTB documentation.

Parameters:
  • name (Optional[str]) – the name of the solvent you want to use. If None turns off solvation.

  • model (str) – the name of the model to use. Must be alpb or gbsa. Defaults to alpb.

spin_polarization(val)[source]#

Set the spin-polarization of the system.

class QCGJob(*args, **kwargs)[source]#

Bases: CRESTJob

alpb(solvent)[source]#
property best_ensemble_path#
property ensemble_directory#
ensemble_mode(mode)[source]#
get_ensemble_xyz(number=None)[source]#

Return paths to conformer xyz files for this job.

Parameters:

number (Optional[int]) – the number of files to return, defaults to 10. If the directory already exists, for example if the job was already run, we will return up to number files.

nofix(enable=True)[source]#
nsolv(nsolv)[source]#
solvent(name=None, model='alpb', nsolv=None, mol=None)[source]#

Model solvation using the ALPB or GBSA model. For available solvents see the XTB documentation.

Parameters:
  • name (Optional[str]) – the name of the solvent you want to use. If None turns off solvation.

  • model (str) – the name of the model to use. Must be alpb or gbsa. Defaults to alpb.

class DFTBJob(*args, **kwargs)[source]#

Bases: AMSJob

Setup and run a density functional with tight-binding (DFTB) calculation as implemented in the Amsterdam modelling suite (AMS). This class supports all methods of the parent AMSJob.

kspace(quality='Good')[source]#

Set the k-space integration quality for this job.

Parameters:

quality (str) – the type of basis-set to use. Default is Good.

model(name='GFN1-xTB', dispersion=None, parameter_dir=None)[source]#

Set the model Hamiltonian for the job to use.

Parameters:

name (str) – name of the model Hamiltonian. This is the same name as the one in the DFTB gui. Default is GFN1-xTB.

solvent(name=None, grid_size=974)[source]#

Model solvation using the GBSA model.

Parameters:
  • name (str) – the name of the solvent you want to use. Must be None, Acetone, Acetonitrile, CHCl3, CS2, DMSO, Ether, H2O, Methanol, THF or Toluene.

  • grid_size – the size of the grid used to construct the solvent accessible surface. Must be 230, 974, 2030 or 5810.

class NMRJob(*args, **kwargs)[source]#

Bases: Job

A job that handles calculation of Nuclear Magnetic Resonance (NMR) chemical shifts. The job will first run an tcutility.job.adf.ADFJob calculation at the SAOP/TZ2P level of theory to prepare for the NMR program of AMS. The NMR shifts will be calculated for all atoms and any additional coordinate (NICS). New NICS points can be given using the NMRJob.add_nics_point() method.

add_nics_point(coordinate)[source]#

Add a NICS point to be calculated.

Parameters:

coordinate (Tuple[float, float, float]) – the (x, y, z) coordinates of a NICS point to calculate the chemical shift for. Has to be given as cartesian coordinates and using unit angstrom.

class ORCAJob(use_tmpdir=False, *args, **kwargs)[source]#

Bases: Job

QRO(enable=True)[source]#
basis_set(value)[source]#
charge(val)[source]#
get_input()[source]#
get_memory_usage()[source]#
ghost_atoms(indices)[source]#
main(val)[source]#

Add main options for this ORCA calculation, they will be added to the input prepended with exclamation marks.

Parameters:

val (Union[str, List[str]]) – the main options to add. This can be a string or a list of strings with the main options.

method(method)[source]#
molecule(mol, natoms=None)[source]#

Add a molecule to this calculation in various formats.

Parameters:
  • mol (Union[str, Molecule, Atom, List[Atom]]) – the molecule to read, can be a path (str). If the path exists already we read it. If it does not exist yet, it will be read in later. mol can also be a plams.Molecule object or a single or a list of plams.Atom objects.

  • natoms (Optional[int]) – If the molecule is supplied as a path you should also give the number of atoms.

multiplicity(val)[source]#
optimization()[source]#
property output_mol_path#

The default file path for output molecules when running ADF calculations. It will not be created for singlepoint calculations.

reference(ref)[source]#
remove_main(val)[source]#
single_point()[source]#
spin_polarization(val)[source]#
transition_state()[source]#
vibrations(enable=True, numerical=False)[source]#
class XTBJob(*args, **kwargs)[source]#

Bases: Job

PESScan(distances=[], angles=[], dihedrals=[], npoints=20, quality='Normal', mode='concerted')[source]#

Set the task of the job to potential energy surface scan (PESScan).

Parameters:
  • distances (list) – sequence of tuples or lists containing [atom_index1, atom_index2, start, end]. Atom indices start at 1. Distances are given in \(\AA\).

  • angles (list) – sequence of tuples or lists containing [atom_index1, atom_index2, atom_index3, start, end]. Atom indices start at 1. Angles are given in degrees

  • dihedrals (list) – sequence of tuples or lists containing [atom_index1, atom_index2, atom_index3, atom_index4, start, end]. Atom indices start at 1. Angles are given in degrees

  • npoints (int) – the number of PES points to optimize.

Note

Currently we only support generating settings for 1-dimensional PESScans. We will add support for N-dimensional PESScans later.

charge(val)[source]#

Set the charge of the system.

model(method)[source]#

Set the method used by XTB. This includes GFN0-xTB, GFN1-xTB, GFN2-xTB and GFNFF.

Parameters:

method (Union[str, int]) – the method to use. Can be specified by its full name, e.g. ‘GFN2-xTB’, is the same as ‘GFN2’ or simply 2.

multiplicity(val)[source]#

Set the multiplicity of the system. If the value is not one the calculation will also be unrestricted. We use the following values:

  1. singlet

  2. doublet

  3. triplet

The multiplicity is equal to 2*S+1 for spin-polarization of S.

optimization(quality='Normal', calculate_hess=True)[source]#

Do a geometry optimization and calculate the normal modes of the input structure.

Parameters:
property output_mol_path#

This method should return the name of the output molecule if it makes sense to give it back. E.g. for ADF it will be output.xyz in the workdir for optimization jobs.

solvent(name=None, model='alpb')[source]#

Model solvation using the ALPB or GBSA model.

Parameters:
  • name (str) – the name of the solvent you want to use. Must be None, Acetone, Acetonitrile, CHCl3, CS2, DMSO, Ether, H2O, Methanol, THF or Toluene.

  • grid_size – the size of the grid used to construct the solvent accessible surface. Must be 230, 974, 2030 or 5810.

spin_polarization(val)[source]#

Set the spin-polarization of the system.

vibrations(enable=True)[source]#
from_string(s)[source]#

Load a molecule from a string. Currently only supports simple XYZ-files, e.g. not extended XYZ-files with flags.

Parameters:

s (str) – string containing the molecule to parse. This function only reads the element, x, y and z coordinates on each line. Other lines will not be read.

Return type:

Molecule

Returns:

A new molecule object with the elements and coordinates from the input.

Example

s = """
    O      -0.77012509       2.82058313      -0.00000000
    H      -0.77488739       2.61994920      -0.93878823
    H      -0.75583818       2.00242615       0.50201099
    """
mol = from_string(s)
guess_fragments(mol)[source]#

Guess fragments based on data from the xyz file. Two methods are currently supported, see the tabs below. We also support reading of charges and spin-polarizations for the fragments. They should be given as charge_{fragment_name} and spinpol_{fragment_name} respectively.

8

N       0.00000000       0.00000000      -0.81474153
B      -0.00000000      -0.00000000       0.83567034
H       0.47608351      -0.82460084      -1.14410295
H       0.47608351       0.82460084      -1.14410295
H      -0.95216703       0.00000000      -1.14410295
H      -0.58149793       1.00718395       1.13712667
H      -0.58149793      -1.00718395       1.13712667
H       1.16299585      -0.00000000       1.13712667

frag_Donor = 1, 3-5
frag_Acceptor = 2, 6-8
charge_Donor = -1
spinpol_Acceptor = 2

In this case, fragment atom indices must be provided below the coordinates. The fragment name must be prefixed with frag_. Indices can be given as integers or as ranges using -.

Parameters:

mol (Molecule) – the molecule that is to be split into fragments. It should have defined either method shown above. If it does not define these methods this function returns None.

Return type:

Dict[str, Molecule]

Returns:

A dictionary containing fragment names as keys and plams.Molecule objects as values. Atoms that were not included by either method will be placed in the molecule object with key None.

load(path)[source]#

Load a molecule from a given xyz file path. The xyz file is structured as follows:

[int]
Comment line
[str] [float] [float] [float] atom_tag1 atom_tag2 atom_key1=...
[str] [float] [float] [float] atom_tag1 atom_tag2 atom_key1=...
[str] [float] [float] [float]

mol_tag1
mol_tag2
mol_key1=...
mol_key2 = ...

The xyz file is parsed and returned as a plams.Molecule object. Flags and tags are given as mol.flags and mol.flags.tags respectively. Similarly for the atoms, the flags and tags are given as mol.atoms[i].flags and mol.atoms[i].flags.tags

Return type:

Molecule

number_of_electrons(mol, charge=0)[source]#

The number of electrons in a molecule.

Parameters:
  • mol (Molecule) – the molecule to count the number of electrons from.

  • charge (int) – the charge of the molecule.

Return type:

int

Returns:

The sum of the atomic numbers in the molecule minus the charge of the molecule.

save(mol, path, comment='')[source]#

Save a molecule in a custom xyz file format. Molecule and atom flags can be provided as the “flags” parameter of the object (mol.flags and atom.flags).

write_mol_to_amv_file(out_file, mols, energies, mol_names=None)[source]#

Writes a list of molecules to a file in amv format.

Return type:

None

write_mol_to_xyz_file(out_file, mols, include_n_atoms=False)[source]#

Writes a list of molecules to a file in xyz format.

Return type:

None

get_info(calc_dir)[source]#
quick_status(calc_dir)[source]#

Quickly check the status of a calculation.

Parameters:

calc_dir (Union[str, Path]) – the directory of the calculation to check.

Return type:

Result

Returns:

Dictionary containing information about the calculation status:

  • fatal (bool)True if calculation cannot be read correctly, False otherwise

  • reasons (list[str]) – list of reasons to explain the status, they can be errors, warnings, etc.

  • name (str) – calculation status written as a string, one of (“SUCCESS”, “RUNNING”, “UNKNOWN”, “SUCCESS(W)”, “FAILED”).

    If the job is being managed by slurm it can also take values of (“COMPLETING”, “CONFIGURING”, “PENDING”).

  • code (str) – calculation status written as one or two characters, one of (“S”, “R”, “U”, “W” “F”)

    If the job is being managed by slurm it can also take values of (“CG”, “CF”, “PD”).

read(calc_dir)[source]#

Master function for reading data from calculations. It reads general information as well as engine-specific information.

Parameters:

calc_dir (Union[str, Path]) – path pointing to the working directory for the desired calculation

Return type:

Result

Returns:

dictionary containing information about the calculation

class Result(*args, **kwargs)[source]#

Bases: dict

Class used for storing results from AMS calculations. The class is functionally a dictionary, but allows dot notation to access variables in the dictionary. The class works case-insensitively, but will retain the case of the key when it was first set.

as_plams_settings()[source]#

Returns this Result object as a plams.Settings object.

copy() a shallow copy of D[source]#
get_multi_key(key, default=None)[source]#

Method that returns the value of a “multikey”. The multikey is multiple keys joined by dots. E.g. res.properties.energy.bond can be gotten by calling res.get_multi_key(“properties.energy.bond”)

Return type:

TypeVar(T)

get_parent_tree()[source]#

Method to get the path from this object to the parent object. The result is presented in a formatted string

getsizeof()[source]#

Return the size of this object in bytes.

items()[source]#

We override the items method from dict in order to skip certain keys. We want to hide keys starting and ending with dunders, as they should not be exposed to the user.

keys() a set-like object providing a view on D's keys[source]#
multi_keys()[source]#

Return multi_keys for this Result object. These are unnested keys that can be used if you want a flattened Result object.

prune()[source]#

Remove empty paths of this object.

class timer(name='', level=20)[source]#

Bases: object

The main timer class. It acts both as a context-manager and decorator.

class Connection(server=None, username=None, key_filename=None)[source]#

Bases: object

Main class used for creating and using SSH sessions to remote servers. It gives you the option to execute any shell code, but also provides useful default commands (for example, cd and ls). The Connection class also allows you to download and upload files between your local machine and the remote.

Parameters:
  • server (str) – the adress of the server you want to connect to. You can prepend the server adress with your username separated from the adress with a @ character. For example: Connection('username@server.address.nl') is the same as Connection('server.address.nl', 'username').

  • username (str) – the username used to log in to the remote server.

  • key_filename (str) – if you cannot log in using only the ssh command you can try to give the filename of the private key that matches a public key on the server.

Usage:

This class is a context manager and the with-syntax should be used to open and automatically close connections. For example, to open a connection to the Snellius supercomputer we use the following code:

from tcutility.connect import Connection

with Connection('username@server.address.nl') as server:
    print(server.pwd())  # this will print the home-directory of the logged-in user
    server.cd('example/path/to/some/data')
    print(server.pwd())  # ~/example/path/to/some/data

Warning

Currently we only support logging in using SSH keys. Make sure that you can log in to the remote with SSH keys. There might be server specific instructions on how to enable this authentication method.

cd(path='~')[source]#

Run the cd command.

Parameters:

path – the path to change directories to. This is relative to the current directory.

Note

Due to limitations with some servers (e.g. Snellius) we do not actually run the cd command, but update the internal Connection.currdir attribute. Before running any command we prepend with cd {self.currdir}; .... In this way we run commands from the correct directory.

chmod(rights, file_path)[source]#
close()[source]#
download(server_path, local_path)[source]#

Download a file from the server and store it on your local machine.

Parameters:
  • server_path (str) – the path on the server to the file to download. The path is relative to the current directory.

  • local_path (str) – the path on the local machine where the file is stored.

execute(command)[source]#

Run a command on the server and return the output.

Parameters:

command (str) – the command to run on the server.

Return type:

str

Returns:

Data written in stdout after the command was run.

Raises:

RuntimeError` with error message if there was something printed to the stderr

Note

The __call__ method redirects to this method. This means you can directly call the Connection object with your command.

full_path(path)[source]#
Return type:

str

ls(path='')[source]#

Run the ls program and return useful information about the paths.

Parameters:

path – the path to run ls on.

Return type:

Result

Returns:

Result object containing information from the output of the ls program.

The keys are the path names and the values contain the information.

  • owner (str) - the username of the owner of the path.

  • date (datetime.datetime) - datetime object holding the date the file was created.

  • is_dir (bool) - whether the path is a directory.

  • is_hidden (bool) - whether the path is hidden.

  • permissions (str) - the permissions given to the path.

mkdir(dirname)[source]#

Run the mkdir command.

Parameters:

dirname – the name of the directory to make. This is relative to the current directory.

open()[source]#
open_file(file_path)[source]#
path_exists(path)[source]#
pwd()[source]#

Run the pwd command.

Note

Due to limitations with some servers (e.g. Snellius) we do not actually run the pwd command, instead we return the internal Connection.currdir attribute. See the Connection.cd() method for more details.

Return type:

str

rm(file_path)[source]#
rmtree(dirname)[source]#
upload(local_path, server_path=None)[source]#

Upload a file from your local machine to the server. If the server_path is not given, store it in the current directory.

Parameters:
  • local_path (str) – the path on the local machine where the file to be uploaded is stored.

  • server_path (str) – the path to upload the file to. If not given or set to None we upload the file to the current directory with the same filename.

class Local[source]#

Bases: Server

chmod(rights, path)[source]#
download(server_path, local_path)[source]#

Download a file from the server and store it on your local machine.

Parameters:
  • server_path (str) – the path on the server to the file to download. The path is relative to the current directory.

  • local_path (str) – the path on the local machine where the file is stored.

execute(command)[source]#

Execute a command on the local machine and return the output.

Parameters:

command (str) – the command to run.

Return type:

str

Note

We use subprocess.check_output with the shell=True argument enabled.

home = '~'#
ls(dirname)[source]#

Run the ls program and return useful information about the paths.

Parameters:

path – the path to run ls on.

Returns:

Result object containing information from the output of the ls program.

The keys are the path names and the values contain the information.

  • owner (str) - the username of the owner of the path.

  • date (datetime.datetime) - datetime object holding the date the file was created.

  • is_dir (bool) - whether the path is a directory.

  • is_hidden (bool) - whether the path is hidden.

  • permissions (str) - the permissions given to the path.

mkdir(dirname)[source]#

Run the mkdir command.

Parameters:

dirname – the name of the directory to make. This is relative to the current directory.

open_file(file_path)[source]#
path_exists(path)[source]#
Return type:

bool

postamble_defaults = {}#
preamble_defaults = {}#
program_modules = {}#
pwd()[source]#

Run the pwd command.

Note

Due to limitations with some servers (e.g. Snellius) we do not actually run the pwd command, instead we return the internal Connection.currdir attribute. See the Connection.cd() method for more details.

rm(file_path)[source]#
rmtree(dirname)[source]#
sbatch_defaults = {}#
server = None#
upload(local_path, server_path=None)[source]#

Upload a file from your local machine to the server. If the server_path is not given, store it in the current directory.

Parameters:
  • local_path (str) – the path on the local machine where the file to be uploaded is stored.

  • server_path (str) – the path to upload the file to. If not given or set to None we upload the file to the current directory with the same filename.

class Server(username=None)[source]#

Bases: Connection

Helper subclass of :class:Connection that is used to quickly connect to a specific server. The constructor takes only the username as the server url is already set. You can also specify default settings for sbatch calls, for example the partition or time-limits.

postamble_defaults = {}#
preamble_defaults = {}#
program_modules = {}#
sbatch_defaults = {}#
server = None#
class ServerFile(file_path, server)[source]#

Bases: object

cache(func)[source]#

Function decorator that stores results from previous calls to the function or method.

cache_file(file)[source]#

Function decorator that stores results of a function to a file. Because results are written to a file the values persist between Python sessions. This is useful, for example, for online API calls.

Parameters:

file – the filepath to store function call results to. Files will be stored in the platform dependent temporary file directory.

See also

platformdirs.user_cache_dir for information on the temporary directory.

cite(doi, style='wiley', mode='html')[source]#

Format an article in a certain style.

Parameters:
  • doi (str) – the article DOI to generate a citation for.

  • style (str) – the style formatting to use. Can be ['wiley', 'acs', 'rsc'].

  • mode – the formatting mode. Can be ['html', 'latex', 'plain'].

Return type:

str

requires_optional_package(package_name, os_name=None)[source]#

Ensures a given package is available before running a function, otherwise raises an ImportError. This can be used to check for optional dependencies which are required for specific functionality.

Parameters:
  • package_name (str) – name of the required package

  • os_name (Optional[str]) – name of the os that this package must be specified on, if omitted defaults to all os

class Transform[source]#

Bases: object

Transformation matrix that handles rotation, translation and scaling of sets of 3D coordinates.

Build and return a transformation matrix. This 4x4 matrix encodes rotations, translations and scaling.

\(\textbf{M} = \begin{bmatrix} \textbf{R}\text{diag}(S) & \textbf{T} \\ \textbf{0}_3 & 1 \end{bmatrix}\)

where \(\textbf{R} \in \mathbb{R}^{3 \times 3}\), \(\textbf{T} \in \mathbb{R}^{3 \times 1}\) and \(\textbf{0}_3 = [0, 0, 0] \in \mathbb{R}^{1 \times 3}\).

When applied to a coordinates \([\textbf{x}, \textbf{y}, \textbf{z}, \textbf{1}]^T \in \mathbb{R}^{n \times 4}\) it will apply these transformations simultaneously.

apply(v)[source]#

Applies the transformation matrix to vector(s) \(v \in \mathbb{R}^{N \times 3}\).

Application is a three-step process:

  1. Append row vector of ones to the bottom of \(v\)

  2. Apply the transformation matrix: \(\textbf{M}v\)

  3. Remove the bottom row vector of ones and return the result

Return type:

ndarray

Returns:

A new array \(v' = \textbf{M}v\) that has been transformed using this transformation matrix.

Note

The Transform.__call__() method redirects to this method. Calling transform.apply(coords) is the same as transform(coords).

combine_transforms(other)[source]#

Combine two different transform objects. This involves creating a new Transform object and multiplying the two transform matrices and assigning it to the new object.

Parameters:

other (Transform) – the transformation matrix object to combine this one with.

Return type:

Transform

Returns:

A new transformation matrix that is a product of the original (left side) and other (right side) matrices.

Note

The Transform.__matmul__() method redirects to this method. Calling new = this.combine_transforms(other) is the same as new = this @ other.

get_rotmat()[source]#
get_translation()[source]#
reflect(normal=None)[source]#

Add a reflection across a plane given by a normal vector to the transformation matrix. The reflection is given as

\(R = \mathbb{I} - 2\frac{nn^T}{n^Tn} \in \mathbb{R}^{3 \times 3}\)

where \(n\) is the normal vector of the plane to reflect along.

Parameters:

normal (ndarray) – the normal vector of the plane to reflect across. If not given or None, it will be set to one unit along the x-axis, i.e. a reflection along the yz-plane.

References

https://en.wikipedia.org/wiki/Reflection_(mathematics)

rotate(R=None, x=None, y=None, z=None)[source]#

Add a rotational component to transformation matrix. Arguments can be given as a rotation matrix R in R^3x3 or by specifying the angle to rotate along the x, y or z axes

Example usage:
Transform.rotate(get_rotmat(x=1, y=-1))
Transform.rotate(x=1, y=-1)
scale(S=None, x=None, y=None, z=None)[source]#

Add a scaling component to the transformation matrix. Arguments can be given as a container of x, y, z values. You can also specify x, y and z components separately

Example usage:
Transform.scale([0, 0, 3])
Transform.scale(z=3)
to_vtkTransform()[source]#
translate(T=None, x=None, y=None, z=None)[source]#

Add a translation component to the transformation matrix. Arguments can be given as a container of x, y, z values. They can also be given separately. You can also specify x, y and z components separately

Example usage:
Transform.translate([2, 3, 0])
Transform.translate(x=2, y=3)
class KabschTransform(X, Y)[source]#

Bases: Transform

Use Kabsch-Umeyama algorithm to calculate the optimal transformation matrix \(T_{Kabsch}\) that minimizes the RMSD between two sets of coordinates \(X \in \mathbb{R}^{N \times 3}\) and \(Y \in \mathbb{R}^{N \times 3}\), such that

\(\text{arg}\min_{T_{Kabsch}} \text{RMSD}(T_{Kabsch}(X), Y)\)

It is numerically stable and works when the covariance matrix is singular. Both sets of points must be the same size for this algorithm to work. The coordinates are first centered onto their centroids before determining the optimal rotation matrix.

Parameters:
  • X (ndarray) – array containing the first set of coordinates. The Kabsch transformation matrix will be made such that applying it to X will yield Y.

  • Y (ndarray) – array containing the second set of coordinates. These coordinates is the target to transform to.

Warning

In principle, the Kabsch-Umeyama algorithm does not care about the dimensions of the coordinates, however we will always assume 3D coordinates as that is our most common use-case. Further, the Transform class also assumes 3D coordinates. If you would like to make use of 2D or 1D Transforms we suggest you simply set the correct axes to zero.

See also

Transform

The main transformation class.

Example

from tcutility import geometry
import numpy as np

# create two arrays that are the same
X, Y = np.arange(5 * 3).reshape(5, 3), np.arange(5 * 3).reshape(5, 3)

# create a transformation matrix to change X
Tx = geometry.Transform()
Tx.rotate(x=1, y=1, z=1)
Tx.translate(x=1, y=1, z=1)

X = Tx(X)

# get the Kabsch transformation matrix
Tkabsch = geometry.KabschTransform(X, Y)

# check if applying the transformation matrix to X yields Y
assert np.isclose(Tkabsch(X), Y).all()

References

class MolTransform(mol)[source]#

Bases: Transform

A subclass of Transform that is designed to generate transformation for a molecule. It adds, among others, methods for aligning atoms to specific vectors, planes, or setting the centroid of the molecule. The nice thing is that the class applies the transformations based only on the atom indices given by the user.

Parameters:

mol (Molecule) – the molecule that is used for the alignment.

Note

Indexing starts at 1 instead of 0.

align_to_plane(index1, index2, index3, vector=None)[source]#

Align a molecule such that the normal of the plane defined by three atoms is aligned to a given vector.

Parameters:
  • index1 (int) – index of the first atom.

  • index2 (int) – index of the second atom.

  • index3 (int) – index of the third atom.

  • vector (Sequence[float]) – the vector to align the atoms to. If not given or None it defaults to (0, 1, 0).

align_to_vector(index1, index2, vector=None)[source]#

Align the molecule such that a bond lays on a given vector.

Parameters:
  • index1 (int) – index of the first atom.

  • index2 (int) – index of the second atom.

  • vector (Sequence[float]) – the vector to align the atoms to. If not given or None it defaults to (1, 0, 0).

center(*indices)[source]#

Center the molecule on given indices or by its centroid.

Parameters:

indices – the indices that are used to center the molecule. If not given the centering will be done based on all atoms.

get_rotmat(x=None, y=None, z=None)[source]#

Create a rotation matrix based on the Tait-Bryant sytem. In this system, x, y, and z are angles of rotation around the corresponding axes. This function uses the right-handed convention

Parameters:
  • x (float) – Rotation around the x-axis in radians.

  • y (float) – Rotation around the y-axis in radians.

  • z (float) – Rotation around the z-axis in radians.

Return type:

ndarray

Returns:

the rotation matrix \(\textbf{R} \in \mathbb{R}^{3 \times 3}\) with the specified axis rotations.

See also

apply_rotmat()

For applying the rotation matrix to coordinates.

rotate()

For rotating coordinates directly, given Tait-Bryant angles.

Transform.rotate()

The Transform class allows you to also rotate.

rotmat_to_angles(R)[source]#
Return type:

Tuple[float]

apply_rotmat(coords, R)[source]#

Apply a rotation matrix to a set of coordinates.

Parameters:
  • coords (ndarray) – the coordinates :math`in mathbb{R}^{n times 3}` to rotate.

  • R (ndarray) – the rotation matrix to apply.

Returns:

math`in mathbb{R}^{n times 3}` rotated using the given rotation matrix.

Return type:

New coordinates

See also

get_rotmat()

For creating a rotation matrix.

rotate()

For rotating coordinates directly, given Tait-Bryant angles.

rotate(coords, x=None, y=None, z=None)[source]#

Build and apply a rotation matrix to a set of coordinates.

Parameters:
  • coords (ndarray) – the coordinates :math`in mathbb{R}^{n times 3}` to rotate.

  • x (float) – Rotation around the x-axis in radians.

  • y (float) – Rotation around the y-axis in radians.

  • z (float) – Rotation around the z-axis in radians.

Return type:

ndarray

See also

get_rotmat()

For creating a rotation matrix.

vector_align_rotmat(a, b)[source]#

Calculate a rotation matrix that aligns vector a onto vector b.

Parameters:
  • a (ndarray) – vector that is to be aligned.

  • b (ndarray) – vector that is the target of the alignment.

Return type:

ndarray

Returns:

Rotation matrix R, such that geometry.apply_rotmat(a, R) == b.

class PyFragResult(path, step_prefix='Step.')[source]#

Bases: object

coord()[source]#
property fragments#
get_geometry(*args, **kwargs)[source]#
get_molecules(calc='complex')[source]#
Return type:

List[Molecule]

get_property(key, calc='complex')[source]#
interaction_energy()[source]#
orbital_energy_gap(orb1, orb2, calc='complex')[source]#
orbs(calc='complex')[source]#
overlap(orb1, orb2, calc='complex', absolute=True)[source]#
set_coord(coord)[source]#
set_mask(mask)[source]#
set_property(name, vals)[source]#
sfo_coefficient(sfo, mo, calc='complex')[source]#
sort_by(val, calc='complex')[source]#
strain_energy(fragment='')[source]#
total_energy()[source]#
property ts_idx#
get_pyfrag_results(path)[source]#
concatenate_irc_trajectories(result_objects, reverse=False)[source]#

Concatenates trajectories from irc calculations, often being forward and backward, through the RMSD values.

Parameters:
  • job_dirs – A list of directories containing the ams.rkf files.

  • user_log_level – The log level set by the user.

  • reverse (bool) – A boolean indicating whether to reverse the trajectory. Default is False.

Return type:

Tuple[List[Molecule], List[float]]

Returns:

A tuple containing a list of Molecule objects and a list of energies.

Raises:

Exception – If an exception is raised in the try block, it is caught and printed.

class VDDCharge(atom_index, atom_symbol, charge, frag_index)[source]#

Bases: object

change_unit(ratio)[source]#
atom_index: int#
atom_symbol: str#
charge: float#
frag_index: int#
avg_relative_bond_length_delta(base, pos, neg, atom1, atom2)[source]#

Function to calculate relative atom distance change in vibrational mode

Parameters:
  • base (Molecule) – plams.Molecule object containing the coordinates before applying vibration

  • pos (Molecule) – plams.Molecule object with the vibrational mode added

  • neg (Molecule) – plams.Molecule object with the vibrational mode subtracted

  • atom1 (int) – label for the first atom

  • atom2 (int) – label for the second atom

Return type:

float

Returns:

Average relative difference from the baseline distance between selected atoms in this vibrational mode (as percentage).

determine_ts_reactioncoordinate(data, mode_index=0, bond_tolerance=1.28, min_delta_dist=0.0)[source]#

Function to retrieve reaction coordinate from a given transitionstate, using the first imaginary frequency.

Parameters:
  • data (Result) – TCutility.Result object containing calculation data

  • mode_index (int) – vibrational mode index to analyze

  • bond_tolerance (float) – parameter for plams.Molecule.guess_bonds() function

  • min_delta_dist (float) – minimum relative bond length change before qualifying as active atom. If 0, all bond changes are counted

Return type:

ndarray

Returns:

Array containing all the obtained reaction coordinates. Reaction coordinate format is [active_atom1, active_atom2, sign], using Distance reactioncoordinate Symmetry elements are ignored, by convention the atom labels are increasing (atom1 < atom2)

validate_transitionstate(calc_dir, rcatoms=None, analyze_modes=1, **kwargs)[source]#
Function to determine whether a transition state calculation yielded the expected transition state. Checks the reaction coordinates provided by the user (or in the .rkf file User Input section) and compares

this against the reaction coordinates found in the imaginary modes of the transitionstate. If the transitionstate has multiple imaginary frequencies, it is possible to check multiple modes for the expected reaction coordinate.

Parameters:
  • calc_dir (str) – path pointing to the desired calculation.

  • rcatoms (list) – list or array containing expected reaction coordinates, to check against the transition state. If not defined, it is obtained from the ams.rkf user input. Only uses ‘Distance’ reaction coordinate. Format should be [atomlabel1, atomlabel2, (optional) sign]

  • analyze_modes (int) – Number of imaginary modes to analyze, default only the first mode. Modes are ordered lowest frequency first. If 0 or negative value is provided, analyze all modes with imaginary frequency.

  • **kwargs – keyword arguments for use in determine_ts_reactioncoordinate().

Return type:

bool

Returns:

Boolean value, True if the found transition state reaction coordinates contain the expected reaction coordinates, False otherwise. If multiple modes are analyzed, returns True if at least one mode contains the expected reaction coordinates.

functional_name_from_path_safe_name(path_safe_name)[source]#

Return information about a given functional given its path-safe name. This can be useful when you want to know the functional from a path name.

Return type:

Result

Returns:

A Result object containing information about the functional if it exists. Else it will return None.

See also

get_available_functionals() for an overview of the information returned.

get_functional(functional_name)[source]#

Return information about a given functional.

Parameters:

functional_name (str) – the name of the functional. It should exist in the get_available_functionals() keys.

Return type:

Result

Returns:

A Result object containing information about the functional if it exists. Else it will return None.

See also

get_available_functionals() for an overview of the information returned.

get_available_functionals()[source]#

Function that returns a dictionary of all available XC-functionals.

Returns:

A Result object containing information about all available XC-functionals.

The functional names are stored as the keys and the functional information is stored as the values. The values contain the following information:

  • name (str) - the name of the functional.

  • path_safe_name (str) - the name of the functional made suitable for file paths.

    This name is the same as the normal name, but without parentheses. Asterisks are replaced with lower-case s.

  • name_no_disp (str) - the name of functional without the dispersion correction.

  • category (str) - the category the functional belongs to.

  • dispersion (str) - the dispersion correction part of the functional name.

  • dispersion_name (str) - the name of the dispersion correction as it would be written in ADF.

  • includes_disp (bool) - whether the functional already includes a dispersion correction.

  • use_libxc (bool) - whether the functional is from the LibXC library.

  • available_in_adf (bool) - whether the functional is available in ADF.

  • available_in_band (bool) - whether the functional is available in BAND.

  • available_in_orca (bool) - whether the functional is available in ORCA.

  • adf_settings (:class:`Result <tcutility.results.result.Result>`) - the settings that are used to select the functional in the ADF input.

  • name_latex (str) - the name of the functional formatted to be used with LaTeX renderers.

  • name_html (str) - the name of the functional formatted to be used with HTML renderers.

  • dois (List[str]) - a list of relevant dois for this functional.

timed_cache(delay)[source]#

Decorator that creates a timed cache for the function or method. This cache will expire after a chosen amount of time.

Parameters:

delay (float) – the expiry time for the function cache.