API Reference

The API reference is generated automatically from the package source.

Core simulation routines for cw-EPR spectra of radical pairs.

    1. Sc. Theresia Quintes, M. Sc. Florian Quintes, 2019-2026

@author: Thresia Quintes, Florian Quintes

radpair.core.do_simulation(spinsystem, experiment, simopt)

Simulate a cw-EPR spectrum for a spin-correlated radical pair.

Solves the spin Hamiltonian analytically using a pseudo-secular approximation for the hyperfine couplings. Supports up to five anisotropic nuclei groups, each assignable to the donor or acceptor radical. Zero-field splitting (D, E) and exchange interaction (J) are included.

Parameters:
  • spinsystem (Spinsystem) – Spin-system object describing the radical pair. See the Spinsystem protocol for required attributes.

  • experiment (Experiment) – Experiment object with the magnetic-field axis and microwave frequency. See the Experiment protocol.

  • simopt (SimulationOptions) – Simulation options (grid density, interpolation, CPU cores). See the SimulationOptions protocol.

Returns:

Real-valued intensity array of the simulated spectrum, matching the shape of experiment.B_z.

Return type:

ndarray

radpair.core.do_simulation_multicore(spinsystem, experiment, simopt)

Simulate a cw-EPR spectrum using multiple CPU cores.

Wraps do_simulation() with the multicore() decorator, which splits the magnetic-field axis across simopt.cpu_cores processes via multiprocessing.Pool. Recommended for single simulations where wall-clock time matters.

Parameters:
  • spinsystem (Spinsystem) – Spin-system object (see Spinsystem).

  • experiment (Experiment) – Experiment object (see Experiment).

  • simopt (SimulationOptions) – Simulation options (see SimulationOptions). simopt.cpu_cores controls the number of worker processes (0 = auto-detect).

Returns:

Real-valued intensity array of the simulated spectrum, matching the shape of experiment.B_z.

Return type:

ndarray

Helper classes for the radpair package.

Provides Matrix (tensor rotation) and Core (nuclei group) used by radpair.core.do_simulation().

    1. Sc. Theresia Quintes, M. Sc. Florian Quintes, 2019-2026

@author: Thresia Quintes, Florian Quintes

class radpair.classes.Core(number, spin)

Represent a group of chemically equivalent nuclei.

Parameters:
  • number (int)

  • spin (float)

number

Number of coupling nuclei.

Type:

int

spin

Magnetic spin of one nucleus.

Type:

float

total_spin

Total magnetic spin of all nuclei (number * spin).

Type:

float

pascal

Intensity distribution from a (normalized) Pascal triangle.

Type:

np.ndarray

mI_len

Length of the mI_vector.

Type:

int

mI_vector

Array of all magnetic spin projection values.

Type:

np.ndarray

hyperfine_matrix

Matrix of hyperfine couplings for every m_I value.

Type:

np.ndarray

get_magnetic_spin_vector()

Compute and store the magnetic spin projection vector.

Populates self.mI_vector with evenly spaced values from -total_spin to +total_spin.

Return type:

None

set_hyperfine_matrix(hyperfine_arr)

Set up the hyperfine matrix from coupling constants.

Computes the outer product of the magnetic spin vector with the hyperfine coupling array and stores the result in self.hyperfine_matrix.

Parameters:

hyperfine_arr (ndarray) – Array of hyperfine coupling constants for each orientation.

Return type:

None

class radpair.classes.Matrix(mat)

Represent an n×n matrix and provide rotation operations.

Parameters:

mat (ndarray)

matrix

Tensor in its initial (eigenbasis) state.

Type:

np.ndarray

matrix_rot

Rotated matrices (None until matrot() is called).

Type:

np.ndarray or None

get_hyperfine_projection()

Compute the effective hyperfine coupling for each orientation.

Only applicable to hyperfine tensors. The effective coupling is the Euclidean norm of the third column of the rotated matrix:

\[A_{\mathrm{eff}} = \sqrt{A_{xz}^2 + A_{yz}^2 + A_{zz}^2}\]
Returns:

Effective hyperfine couplings, shape (N,), where N is the number of orientations. The i-th element corresponds to the i-th orientation.

Return type:

ndarray

matrot(phi, theta, psi=0.0)

Rotate the matrix using Euler transformation (y-convention).

The result is stored in self.matrix_rot without modifying self.matrix.

Parameters:
  • phi (ndarray) – Phi angles in radians for the transformation.

  • theta (ndarray) – Theta angles in radians for the transformation.

  • psi (ndarray) – Psi angles in radians for the transformation (default 0.0).

Return type:

None

Math helper functions for the radpair package.

Provides unit conversion, tensor rotation, Pascal-triangle generation, Fibonacci-sphere grid points, and spherical-coordinate conversion.

    1. Sc. Theresia Quintes, M. Sc. Florian Quintes, 2019-2026

@author: Thresia Quintes, Florian Quintes

radpair.functions.MHz_2_T(nu, g_tensor)

Convert a frequency in MHz to the corresponding magnetic field in Tesla.

The conversion uses the isotropic g-value and the Bohr magneton:

\[B = \frac{\nu_{\mathrm{MHz}} \times 10^{6}} {g_{\mathrm{iso}} \cdot \mu_{B} \times 10^{-3}}\]
Parameters:
  • nu (float | ndarray) – Frequency (or array of frequencies) in MHz.

  • g_tensor (ndarray) – g-tensor diagonal elements, shape (3,). All values must be positive.

Returns:

Magnetic field in Tesla (scalar if nu is scalar, array otherwise).

Return type:

float | ndarray

Raises:

ValueError – If any element of g_tensor is not positive.

radpair.functions.cartesian2spherical(xyz)

Convert Cartesian coordinates to spherical coordinates.

Parameters:

xyz (ndarray) – Cartesian coordinates (x, y, z) for n points, shape (n, 3).

Returns:

Spherical coordinates (r, theta, phi) for each point, shape (3, n). Here theta is the polar angle (from the z-axis) and phi is the azimuthal angle (from the x-axis).

Return type:

ndarray

radpair.functions.get_D_diag(D, E)

Return the diagonal elements of the ZFS D-tensor.

The diagonal tensor is constructed from the zero-field splitting parameters D and E as:

\[\begin{split}\mathrm{diag}(D) = \begin{pmatrix} D - E & 0 & 0 \\ 0 & D + E & 0 \\ 0 & 0 & -2D \end{pmatrix}\end{split}\]
Parameters:
  • D (float) – ZFS parameter D.

  • E (float) – ZFS parameter E.

Returns:

Array of shape (3,) containing the diagonal elements.

Return type:

ndarray

radpair.functions.get_fibonacci_sphere(points)

Generate a Fibonacci sphere in spherical coordinates.

Parameters:

points (int) – Number of grid points on the sphere.

Return type:

tuple[ndarray, ndarray]

Returns:

  • theta (np.ndarray) – Polar angles (from the z-axis) of the grid points.

  • phi (np.ndarray) – Azimuthal angles (from the x-axis) of the grid points.

radpair.functions.get_generalized_Pascal(number, spin)

Compute a generalized Pascal triangle for number nuclei of spin spin.

Returns the relative intensities of the hyperfine lines for a group of number chemically equivalent nuclei with magnetic spin spin.

(c) Stephan Rein Modified by: Florian Quintes

Parameters:
  • number (int) – Number of chemically equivalent nuclei (>= 0).

  • spin (float) – Magnetic spin quantum number (>= 0, multiple of 0.5).

Returns:

Array of relative intensities. For number == 0 returns [1].

Return type:

ndarray

Raises:
  • ValueError – If number or spin is negative, or spin is not a multiple of 0.5.

  • TypeError – If number is not an integer.

radpair.functions.get_multiplicity(spin)

Return the multiplicity of a particle with spin S.

\[M = 2S + 1\]
Parameters:

spin (float) – Magnetic spin quantum number (must be non-negative and a multiple of 0.5).

Returns:

Multiplicity (number of Zeeman levels).

Return type:

int

Raises:

ValueError – If spin is negative or not a multiple of 0.5.

radpair.functions.get_normalized_Pascal(number, spin)

Compute a normalized generalized Pascal triangle (sum = 1).

Wraps get_generalized_Pascal() and rescales the result so that all intensities sum to 1.

Parameters:
  • number (int) – Number of chemically equivalent nuclei (>= 0).

  • spin (float) – Magnetic spin quantum number (>= 0, multiple of 0.5).

Returns:

Normalized array of relative intensities summing to 1.

Return type:

ndarray

radpair.functions.rescale_array(arr, norm=1.0)

Rescale a 1-D array so that its elements sum to norm.

Parameters:
  • arr (ndarray) – 1-D array to be rescaled.

  • norm (float) – Target sum of all array values (default is 1.0).

Returns:

Rescaled array.

Return type:

ndarray

Raises:

ZeroDivisionError – If the array sums to zero.

radpair.functions.sphere_fibonacci_grid_points(ng)

Calculate Fibonacci-spiral grid points on a unit sphere.

Parameters:

ng (int) – Number of grid points to generate.

Returns:

Cartesian coordinates of the grid points, shape (ng, 3).

Return type:

ndarray

Notes

This code is distributed under the GNU LGPL license. Original source: https://people.sc.fsu.edu/~jburkardt/py_src/sphere_fibonacci_grid/sphere_fibonacci_grid.py

Modified 15 May 2015 by John Burkardt.

Reference

Richard Swinbank, James Purser, “Fibonacci grids: A novel approach to global modelling”, Quarterly Journal of the Royal Meteorological Society, Volume 132, Number 619, July 2006 Part B, pages 1769-1793.

radpair.functions.tensor_rotation(tensor, phi, theta, psi=None)

Rotate a tensor (or batch of tensors) via Euler transformation.

The Euler matrix O of the SO(3) group is set up in y-convention (already in multiplied form) and the orthogonal similarity transformation is carried out:

\[T' = O^{\mathsf{T}} \cdot T \cdot O\]

where \(O^{-1} = O^{\mathsf{T}}\) (orthogonality).

Parameters:
  • tensor (ndarray) – Tensor to be rotated. A single 2-D array of shape (3, 3) or a batch of 2-D arrays of shape (N, 3, 3).

  • phi (ndarray) – Phi (Euler) angles in radians, shape (N,).

  • theta (ndarray) – Theta (Euler) angles in radians, shape (N,).

  • psi (ndarray | None) – Psi (Euler) angles in radians, shape (N,). If None, zeros are used (default).

Returns:

Rotated tensor(s). Shape matches the input tensor except that the leading dimension becomes N (the number of angles).

Return type:

ndarray

Raises:

ValueError – If tensor does not have 2 or 3 dimensions.

radpair.functions.vector_product_combinations(a, b)

Compute the outer product of two 1-D arrays.

Given two vectors, returns a matrix containing all pairwise products.

Parameters:
  • a (ndarray) – First 1-D array (used as column vector).

  • b (ndarray) – Second 1-D array (used as row vector).

Returns:

Matrix of shape (len(a), len(b)) containing the products of all permutations of values from a with values from b.

Return type:

ndarray

Examples

>>> import numpy as np
>>> vector_product_combinations(np.array([1, 2, 3]), np.array([4, 5, 6]))
array([[ 4,  5,  6],
       [ 8, 10, 12],
       [12, 15, 18]])

Provide decorators and multicore helpers for simulation routines.

© M. Sc. Florian Quintes, 2026

@contact: florian.quintes@pc.uni-freiburg.de

@author: Florian Quintes

radpair._wrappers.function_benchmark(func, niter=100)

Run func niter times and print best, worst, and average runtime.

Parameters:
  • func (Callable[..., Any]) – Function which will be benchmarked.

  • niter (int) – Number of function calls (default is 100).

Returns:

Wrapper that runs the benchmark and prints timing statistics. The wrapper does not return the original result.

Return type:

Callable[..., None]

radpair._wrappers.multicore(simulation)

Parallelise a simulation routine using multiprocessing.Pool.

The decorated function must accept (spinsystem, experiment, simopt) and is executed on simopt.cpu_cores processes, each handling a slice of the magnetic-field axis.

Parameters:

simulation (Callable[..., ndarray]) – Simulation function with the signature (spinsystem, experiment, simopt) -> np.ndarray.

Returns:

Wrapper with the same signature that distributes the work across CPU cores and returns the concatenated spectrum.

Return type:

Callable[..., ndarray]

radpair._wrappers.timer(func)

Measure the wall-clock runtime of a single function call.

Parameters:

func (Callable[[ParamSpec(P)], TypeVar(R)]) – Function whose runtime will be measured.

Returns:

Wrapper that prints the runtime and returns the original result.

Return type:

Callable[[ParamSpec(P)], TypeVar(R)]

Protocol definitions describing the dynamic-attribute interfaces used by radpair.core.do_simulation().

Users typically pass plain objects (e.g. types.SimpleNamespace or simple classes) whose attributes are accessed dynamically via vars() and getattr. These protocols document the required attributes so that static type checkers and IDEs can provide autocomplete and validation.

© M. Sc. Florian Quintes, 2026

@author: Florian Quintes

class radpair._types.Experiment(*args, **kwargs)

Protocol for the experiment object passed to do_simulation.

B_z

Magnetic field axis for the output spectrum in milliTesla.

Type:

np.ndarray

freq_mw

Microwave frequency in Hz.

Type:

float

magnetic_field

Magnetic field sweep axis in milliTesla (used by the multicore wrapper to split work across processes).

Type:

np.ndarray

class radpair._types.SimulationOptions(*args, **kwargs)

Protocol for the simulation-options object passed to do_simulation.

grid_points

Number of orientation-grid knots for the spherical integration.

Type:

int

refinement

Interpolation factor. 1 disables interpolation; values > 1 enable interpolation onto a finer grid.

Type:

int

cpu_cores

Number of worker processes for multicore execution. 0 means auto-detect via multiprocessing.cpu_count().

Type:

int

class radpair._types.Spinsystem(*args, **kwargs)

Protocol for the spin-system object passed to do_simulation.

Describes a singlet-born spin-correlated radical pair with up to five anisotropic nuclei groups. Each group is assigned to either the donor or the acceptor radical via donor_list / acceptor_list.

g1, g2

Diagonal g-tensor elements of radical 1 (donor) and radical 2 (acceptor), shape (3,). All values must be positive.

Type:

np.ndarray

A1, A2, A3, A4, A5

Diagonal hyperfine coupling tensors for nuclei groups 1–5 in MHz, each of shape (3,). Inactive groups should be zero arrays.

Type:

np.ndarray

D

Zero-field splitting parameter D in MHz.

Type:

float

E

Zero-field splitting parameter E in MHz.

Type:

float

J_ex

Exchange interaction J in MHz.

Type:

float

width_gauss

Gaussian linewidth in milliTesla (despite the attribute name).

Type:

float

g1_frame, g2_frame, D_frame

Euler angles [alpha, beta, gamma] (radians) for the g-tensors and ZFS tensor relative to the lab frame, each of shape (3,).

Type:

np.ndarray

A1_frame, A2_frame, A3_frame, A4_frame, A5_frame

Euler angles for hyperfine tensors 1–5, each of shape (3,).

Type:

np.ndarray

n1, n2, n3, n4, n5

Number of chemically equivalent nuclei in each group (>= 0).

Type:

int

I1, I2, I3, I4, I5

Nuclear spin of each group (multiple of 0.5, >= 0).

Type:

float

donor_list

Core indices (1–5) assigned to the donor radical.

Type:

list[int]

acceptor_list

Core indices (1–5) assigned to the acceptor radical.

Type:

list[int]