4
$\begingroup$

I'm trying to find the Euclidean distance between two atoms in the molecule with SMILES representation O=CC1OC12CC1OC12 using the rdkit package. Looking online, I have converged to the following code.

import numpy as np
from rdkit import Chem

mol = Chem.MolFromSmiles('O=CC1OC12CC1OC12')

conf = mol.GetConformer()
at1Coords = np.array(conf.GetAtomPosition(bond_i.GetBeginAtomIdx()))
at2Coords = np.array(conf.GetAtomPosition(bond_i.GetEndAtomIdx()))
print(np.linalg.norm(at2Coords - at1Coords))

But I get the error

conf = mol.GetConformer()  
ValueError: Bad Conformer Id

I was wondering how to fix the issue. Thanks!

$\endgroup$
0

2 Answers 2

2
$\begingroup$

The issue was that I had to embed the molecule to have a 3D conformation. So I added following line:

AllChem.EmbedMolecule(mol)

Feel free to answer with better suggestions and alternatives.

$\endgroup$
1
$\begingroup$

This is a bit late but there is an easy way. You have no conformer and to get the Euclidean distance, you need to embed the molecule ( as mentioned ) and optimize it in 3D. Unless, you load from a mol file with coordinates.

Below is an implementation for a smiles string.

from rdkit import Chem
from rdkit.Chem import AllChem
import numpy as np

def generateMolFromSmiles( smiles ):
    m = Chem.MolFromSmiles( smiles )
    m = Chem.AddHs( m )
    AllChem.EmbedMolecule( m, randomSeed=0xf00d )
    AllChem.MMFFOptimizeMolecule( m )
    return m

def getDistOfMol( smiles ):
    m = generateMolFromSmiles( smiles )
    distMat = Chem.Get3DDistanceMatrix(m)
    return distMat

smiles = "O=CC1OC12CC1OC12"
distMat  = getDistOfMol( smiles )
print( distMat ) # full matrix of numOfAtoms x numOfAtoms
print( distMat[0,2] ) # distance between atom 0 and atom 2

Output:

[[0.         1.22448701 2.34475022 3.53889923 3.25859597 4.5416131
  4.77052328 5.13509918 3.71333938 2.03965411 2.78446249 4.68794261
  5.37807671 5.09749518 3.36268049]
 ............
 [3.36268049 3.19077316 3.11178336 3.25145896 2.22885191 3.06533768
  2.21724756 2.17967672 1.08128432 3.7068481  4.00560363 3.67573384
  3.91252705 2.52605715 0.        ]]

Note the matrix is numOfAtoms x numOfAtoms. You only need one row to know the distances between all atoms. The first row is the distance between atom 0 and atoms 0-n. The second row is the distance between atom 1 and atoms 0-n. etc...

Note there is no direction here. I've done an implementation that gets direction but it's a bit more complicated. I just parsed the molfile but GetAtomPosition() will return the x,y,z coordinates. Then numpy transformations can be done to get any geometric value. The rdGeometry module provides many options as well.

The distance between atom 0 and atom 2

2.344750223949128
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.