soprano.calculate.nmr.utils#

Helper functions for NMR calculations and plotting

Functions

calculate_distances(pairs, atoms)

Calculate the distances between pairs of atoms.

extract_indices(atoms, xelement, yelement)

filter_pairs_by_distance(pairs, ...)

Filters pairs of indices based on a cutoff distance.

gaussian(X, x0, Y, y0, x_broadening, ...)

Calculate the Gaussian broadening function.

generate_contour_map(peaks[, grid_size, ...])

Generate a contour map based on the provided peaks and broadening parameters.

generate_peaks(data, pairs, labels, ...)

Generate peaks for the NMR data.

get_atom_labels(atoms[, logger])

Get the labels for the atoms in the Atoms object.

get_energy(positions, positions_original, C, k)

Compute the total energy of the system

get_force_matrix(positions, positions_original)

This is a vectorised version of the above function, which is much faster

get_pair_dipolar_couplings(atoms, pairs[, ...])

Get the dipolar couplings for a list of pairs of atoms.

get_pair_j_couplings(atoms, pairs[, ...])

Get the J couplings for a list of pairs of atoms.

get_total_forces(positions, positions_original)

lorentzian(X, x0, Y, y0, x_broadening, ...)

Calculate the Lorentzian broadening function.

merge_peaks(peaks[, xtol, ytol, corr_tol, ...])

Merge peaks that are identical.

optimise_annotations(positions[, max_iters, ...])

prepare_species_labels(isotope, element)

process_pairs(idx_x, idx_y, pairs)

Process pairs of indices and update element indices.

sort_peaks(peaks[, priority, reverse])

Sort the peaks in the order of increasing x and y values TODO: This doesn't work in some cases.

styled_plot(*style_sheets)

Return a decorator that will apply matplotlib style sheets to a plot. style_sheets is a base set of styles, which will be ignored if no_base_style is set in the decorated function arguments. The style will further be overwritten by any styles in the style optional argument of the decorated function. :param style_sheets: Any matplotlib supported definition of a style sheet. Can be a list of style of style sheets. :type style_sheets: list, str, or dict.

validate_elements(atoms, xelement, yelement)

Classes

Peak2D(x, y, xlabel, ylabel[, ...])

Class to hold peak data.

class soprano.calculate.nmr.utils.Peak2D(x, y, xlabel, ylabel, correlation_strength=1, color='C0', idx_x=None, idx_y=None)[source]#

Bases: object

Class to hold peak data. This is used to store the peak data for a correlation peak in a 2D NMR spectrum.

The data stored includes: - the peak position in x and y - the correlation strength - the x and y labels for the peak - the color of the peak - the index of the x and y labels in the list of all labels

Parameters:
  • x (float)

  • y (float)

  • xlabel (str)

  • ylabel (str)

  • correlation_strength (float)

  • color (str)

  • idx_x (int | None)

  • idx_y (int | None)

equivalent_to(other, xtol=0.005, ytol=0.005, corr_tol=0.1, ignore_correlation_strength=False)[source]#

Check if two peaks are equivalent. We compare the x and y coordinates and the correlation strength.

Parameters:
  • other (Peak2D) – The other peak to compare to

  • xtol (float, optional) – The tolerance for the x coordinate. Defaults to 0.005.

  • ytol (float, optional) – The tolerance for the y coordinate. Defaults to 0.005.

  • corr_tol (float, optional) – The tolerance for the correlation strength. Defaults to 0.1.

Returns:

True if the peaks are equivalent, False otherwise

Return type:

bool

soprano.calculate.nmr.utils.calculate_distances(pairs, atoms)[source]#

Calculate the distances between pairs of atoms.

Parameters:
  • pairs (List[Tuple[int, int]]) – List of tuples representing pairs of atom indices.

  • atoms (Atoms) – Atoms object that provides the get_distance method.

Returns:

Array of distances corresponding to the pairs.

Return type:

np.ndarray

soprano.calculate.nmr.utils.filter_pairs_by_distance(pairs, pairs_el_idx, pair_distances, rcut)[source]#

Filters pairs of indices based on a cutoff distance.

Parameters:
  • pairs (List[Tuple[int, int]]) – List of tuples representing pairs of indices.

  • pairs_el_idx (List[Tuple[int, int]]) – List of tuples representing pairs of element indices.

  • pair_distances (np.ndarray) – Array of distances corresponding to the pairs.

  • rcut (float) – Cutoff distance for filtering pairs.

Returns:

  • Filtered list of pairs.

  • Filtered list of element index pairs.

  • Filtered array of pair distances.

  • Unique sorted array of x indices.

  • Unique sorted array of y indices.

Return type:

Tuple[List[Tuple[int, int]], List[Tuple[int, int]], np.ndarray, np.ndarray, np.ndarray]

Raises:

ValueError – If no pairs are found after filtering by distance.

soprano.calculate.nmr.utils.gaussian(X, x0, Y, y0, x_broadening, y_broadening)[source]#

Calculate the Gaussian broadening function.

\[f(x, y) = \exp\left(-\frac{(x - x_0)^2}{2 w_x^2} - \frac{(y - y_0)^2}{2 w_y^2}\right)\]

where \(w_x\) and \(w_y\) are the broadening factors in the x and y directions, respectively. These correspond to the standard deviation of the Gaussian function.

Parameters:
  • X (np.ndarray) – Array of x values.

  • x0 (float) – x-coordinate of the peak.

  • Y (np.ndarray) – Array of y values.

  • y0 (float) – y-coordinate of the peak.

  • x_broadening (float) – Broadening factor in the x direction.

  • y_broadening (float) – Broadening factor in the y direction.

Returns:

Array of intensity values.

Return type:

np.ndarray

soprano.calculate.nmr.utils.generate_contour_map(peaks, grid_size=100, broadening='gaussian', x_broadening=1.0, y_broadening=1.0, xlims=None, ylims=None)[source]#

Generate a contour map based on the provided peaks and broadening parameters.

Parameters:
  • peaks (List[Peak2D]) – List of Peak2D objects containing x, y coordinates and correlation strength.

  • grid_size (int, optional) – Size of the grid for the contour map. Default is 100.

  • broadening (str, optional) – Type of broadening function to use (‘lorentzian’ or ‘gaussian’). Default is ‘lorentzian’.

  • x_broadening (float, optional) – Broadening factor in the x direction. Default is 1.0.

  • y_broadening (float, optional) – Broadening factor in the y direction. Default is 1.0.

  • xlims (Optional[Tuple[float, float]], optional) – Limits for the x-axis. Default is None.

  • ylims (Optional[Tuple[float, float]], optional) – Limits for the y-axis. Default is None.

Returns:

Meshgrid arrays X, Y and the intensity grid Z.

Return type:

Tuple[np.ndarray, np.ndarray, np.ndarray]

soprano.calculate.nmr.utils.generate_peaks(data, pairs, labels, markersizes, yaxis_order, xelement, yelement)[source]#

Generate peaks for the NMR data.

Parameters:
  • data (List[float]) – The NMR data.

  • pairs (Iterable[Tuple[int, int]]) – Pairs of indices for the peaks.

  • labels (List[str]) – Labels for the peaks.

  • markersizes (Union[List[float], float]) – Marker sizes for the peaks.

  • yaxis_order (str) – Order of the y-axis.

  • xelement (str) – Element symbol for the x-axis.

  • yelement (str) – Element symbol for the y-axis.

Returns:

List of generated peaks.

Return type:

List[Peak2D]

soprano.calculate.nmr.utils.get_atom_labels(atoms, logger=None)[source]#

Get the labels for the atoms in the Atoms object. If the labels are not present, they will be generated using the MagresViewLabels class.

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

  • logger (Optional[logging.Logger], optional) – Logger object. Default is None.

Returns:

Array of labels.

Return type:

np.ndarray

soprano.calculate.nmr.utils.get_energy(positions, positions_original, C, k)[source]#

Compute the total energy of the system

soprano.calculate.nmr.utils.get_force_matrix(positions, positions_original, C=0.01, k=1e-05)[source]#

This is a vectorised version of the above function, which is much faster

Parameters:
  • positions (np.array) – The y coordinates of the annotations

  • positions_original (np.array) – The original y coordinates of the annotations

  • C (float, optional) – The repulsive force constant between annotations, by default 0.01

  • k (float, optional) – The spring force constant for the spring holding the annotation to it’s original position, by default 0.00001

soprano.calculate.nmr.utils.get_pair_dipolar_couplings(atoms, pairs, isotopes=None, unit='kHz')[source]#

Get the dipolar couplings for a list of pairs of atoms. For pairs where i == j, the dipolar coupling is set to zero.

Parameters:
  • atoms (ASE Atoms object) – The atoms object that contains the atoms.

  • pairs (list of tuples) – List of pairs of atom indices.

  • isotopes (dict, optional)

  • unit (str)

Returns:

dipolar_couplings – List of dipolar couplings for the pairs.

Return type:

list of float

soprano.calculate.nmr.utils.get_pair_j_couplings(atoms, pairs, isotopes=None, unit='Hz', tag='isc')[source]#

Get the J couplings for a list of pairs of atoms. For pairs where i == j, the J coupling is set to zero.

Parameters:
  • atoms (ASE Atoms object) – The atoms object that contains the atoms.

  • pairs (list of tuples) – List of pairs of atom indices.

  • isotopes (dict, optional) – Dictionary of isotopes for the atoms.

  • unit (str, optional) – Unit of the J coupling. Default is ‘Hz’.

  • tag (str, optional) – Name of the J coupling component to return. Default is ‘isc’. Magres files usually contain isc, isc_spin, isc_fc, isc_orbital_p and isc_orbital_d.

Returns:

j_couplings – List of J couplings for the pairs.

Return type:

list of float

soprano.calculate.nmr.utils.get_total_forces(positions, positions_original, C=0.01, k=1e-05)[source]#
Parameters:
  • positions (np.array) – The y coordinates of the annotations

  • positions_original (np.array) – The original y coordinates of the annotations

  • C (float, optional) – The repulsive force constant between annotations, by default 0.01

  • k (float, optional) – The spring force constant for the spring holding the annotation to it’s original position, by default 0.00001

soprano.calculate.nmr.utils.lorentzian(X, x0, Y, y0, x_broadening, y_broadening)[source]#

Calculate the Lorentzian broadening function.

\[f(x, y) = \frac{1}{((x - x_0) / w_x)^2 + ((y - y_0) / w_y)^2 + 1}\]

where \(w_x\) and \(w_y\) are the broadening factors in the x and y directions, respectively. These correspond to the half-width at half-maximum (HWHM) of the Lorentzian function.

Parameters:
  • X (np.ndarray) – Array of x values.

  • x0 (float) – x-coordinate of the peak.

  • Y (np.ndarray) – Array of y values.

  • y0 (float) – y-coordinate of the peak.

  • x_broadening (float) – Broadening factor in the x direction.

  • y_broadening (float) – Broadening factor in the y direction.

Returns:

Array of intensity values.

Return type:

np.ndarray

soprano.calculate.nmr.utils.merge_peaks(peaks, xtol=1e-05, ytol=1e-05, corr_tol=1e-05, ignore_correlation_strength=False)[source]#

Merge peaks that are identical.

Parameters:
  • peaks (Iterable[Peak2D]) – List of peaks to merge.

  • xtol (float) – Tolerance for x-axis comparison.

  • ytol (float) – Tolerance for y-axis comparison.

  • corr_tol (float) – Tolerance for correlation strength comparison.

  • ignore_correlation_strength (bool) – Whether to ignore correlation strength in comparison.

Returns:

List of unique merged peaks.

Return type:

List[Peak2D]

soprano.calculate.nmr.utils.optimise_annotations(positions, max_iters=10000, C=0.01, k=1e-05, ftol=0.001)[source]#
Parameters:
  • positions (list or np.array) – The x or y coordinates of the annotations to be optimised

  • max_iters (int, optional) – The maximum number of iterations to run for, by default 10000

  • C (float, optional) – The repulsive force constant between annotations, by default 0.01

  • k (float, optional) – The spring force constant for the spring holding the annotation to it’s original position, by default 0.00001

  • ftol (float, optional) – The tolerance for the forces, by default 1e-3. If all the net forces are below this value, the optimisation will stop even if the maximum number of iterations has not been reached.

soprano.calculate.nmr.utils.process_pairs(idx_x, idx_y, pairs)[source]#

Process pairs of indices and update element indices.

Parameters:
  • idx_x (np.ndarray) – Array of x element indices.

  • idx_y (np.ndarray) – Array of y element indices.

  • pairs (Optional[List[Tuple[int, int]]]) – List of tuples representing pairs of indices, or None.

Returns:

  • List of pairs of indices.

  • List of pairs of element indices.

  • Updated array of x element indices.

  • Updated array of y element indices.

Return type:

Tuple[List[Tuple[int, int]], List[Tuple[int, int]], np.ndarray, np.ndarray]

soprano.calculate.nmr.utils.sort_peaks(peaks, priority='x', reverse=False)[source]#

Sort the peaks in the order of increasing x and y values TODO: This doesn’t work in some cases. Investigate why.

Parameters:
  • peaks (List[Peak2D])

  • priority (str)

  • reverse (bool)

Return type:

List[Peak2D]

soprano.calculate.nmr.utils.styled_plot(*style_sheets)[source]#

Return a decorator that will apply matplotlib style sheets to a plot. style_sheets is a base set of styles, which will be ignored if no_base_style is set in the decorated function arguments. The style will further be overwritten by any styles in the style optional argument of the decorated function. :param style_sheets: Any matplotlib

supported definition of a style sheet. Can be a list of style of style sheets.