GetConformerRMSMatrix#
- nvmolkit.conformerRmsd.GetConformerRMSMatrix( ) 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. Whenprealignedis False (default), each pair is optimally superimposed via the Kabsch algorithm before computing RMSD.Differences from RDKit:
Zero-atom molecules always raise
ValueErrorregardless of conformer count. RDKit returns[nan]for exactly 2 zero-atom conformers and raisesZeroDivisionErrorfor 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 indexi*(i-1)//2 + j.- Raises:
ValueError – If
molis None or has conformers but no atoms.TypeError – If
streamis not atorch.cuda.Streamor 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)