GetConformerRMSMatrix#

nvmolkit.conformerRmsd.GetConformerRMSMatrix(
mol: Mol,
prealigned: bool = False,
stream: Stream | None = None,
) AsyncGpuResult#

Compute the pairwise RMSD matrix between all conformers of a molecule on GPU.

GPU-accelerated equivalent of AllChem.GetConformerRMSMatrix(mol, prealigned=prealigned). For N conformers with M atoms, computes N*(N-1)/2 pairwise RMSD values using one GPU thread-block per pair. When prealigned is False (default), each pair is optimally superimposed via the Kabsch algorithm before computing RMSD.

Differences from RDKit:

  • Zero-atom molecules always raise ValueError regardless of conformer count. RDKit returns [nan] for exactly 2 zero-atom conformers and raises ZeroDivisionError for 3 or more.

  • Results are returned as an AsyncGpuResult (device tensor) rather than a Python list, to keep the conformer-selection pipeline on the GPU.

The result can be passed directly to nvmolkit.clustering.butina() for GPU-accelerated Butina clustering.

Parameters:
  • mol – RDKit molecule with two or more conformers. Strip hydrogens first (Chem.RemoveHs) if you want heavy-atom RMSD, as this function operates on all atoms present in the molecule.

  • prealigned – If True, skip Kabsch alignment and compute RMSD on raw coordinates. If False (default), optimally align each pair.

  • stream – CUDA stream to use. If None, uses the current stream.

Returns:

AsyncGpuResult wrapping a 1-D tensor of shape (N*(N-1)/2,) containing RMSD values in lower-triangle condensed order. The RMSD for conformer pair (i, j) with i > j is at index i*(i-1)//2 + j.

Raises:
  • ValueError – If mol is None or has conformers but no atoms.

  • TypeError – If stream is not a torch.cuda.Stream or None.

Example

>>> from rdkit import Chem
>>> from rdkit.Chem import AllChem, rdDistGeom
>>> from nvmolkit.conformerRmsd import GetConformerRMSMatrix
>>> from nvmolkit.clustering import butina
>>>
>>> mol = Chem.AddHs(Chem.MolFromSmiles('CCCCCC'))
>>> rdDistGeom.EmbedMultipleConfs(mol, numConfs=50)
>>> no_h = Chem.RemoveHs(mol)
>>>
>>> # GPU equivalent of: AllChem.GetConformerRMSMatrix(no_h)
>>> rmsd_matrix = GetConformerRMSMatrix(no_h)
>>>
>>> # Reshape to square for GPU Butina clustering
>>> import torch
>>> n = no_h.GetNumConformers()
>>> square = torch.zeros(n, n, device='cuda', dtype=torch.float64)
>>> idx = torch.tril_indices(n, n, offset=-1)
>>> square[idx[0], idx[1]] = rmsd_matrix.torch()
>>> square = square + square.T
>>> clusters = butina(square, cutoff=0.5)