|
8 | 8 | from typing import TYPE_CHECKING, Dict, Iterable, List, Optional, Tuple, Union |
9 | 9 |
|
10 | 10 | from ase import Atoms |
| 11 | +from scipy.spatial.transform import Rotation |
11 | 12 | from openbabel import openbabel as ob |
12 | 13 | from openbabel import pybel |
13 | 14 | from rdkit import Chem |
@@ -2446,3 +2447,25 @@ def sorted_distances_of_atom(xyz_dict: dict, atom_index: int) -> List[Tuple[int, |
2446 | 2447 |
|
2447 | 2448 | distances = [(i, d_matrix[atom_index, i]) for i in range(d_matrix.shape[0]) if i != atom_index] |
2448 | 2449 | return sorted(distances, key=lambda x: x[1]) |
| 2450 | + |
| 2451 | + |
| 2452 | +def kabsch(xyz1: dict, xyz2: dict) -> float: |
| 2453 | + """ |
| 2454 | + Return the kabsch similarity score between two sets of Cartesian coordinates in Ångstrom. |
| 2455 | + The algorithm requires the atoms to be ordered the same in both sets of coordinates. |
| 2456 | + This will not be directly useful for comparing two conformers of the same species, |
| 2457 | + but could be used to compare two different species with the same atom types and counts. (e.g., isomers, reactants and products, etc.). |
| 2458 | +
|
| 2459 | + Args: |
| 2460 | + xyz1 (dict): The first set of Cartesian coordinates. |
| 2461 | + xyz2 (dict): The second set of Cartesian coordinates. |
| 2462 | +
|
| 2463 | + Returns: |
| 2464 | + float: The Kabsch similarity score in Ångstrom. |
| 2465 | + """ |
| 2466 | + if xyz1["symbols"] != xyz2["symbols"]: |
| 2467 | + raise ValueError("The two xyz coordinates must have the same atom symbols to compute Kabsch score.") |
| 2468 | + xyz1, xyz2 = translate_to_center_of_mass(xyz1), translate_to_center_of_mass(xyz2) |
| 2469 | + coords1, coords2 = np.array(xyz1['coords']), np.array(xyz2['coords']) |
| 2470 | + _, score = Rotation.align_vectors(coords1, coords2) |
| 2471 | + return score |
0 commit comments