Re: [Rdkit-discuss] Problems with Conformer ID assignment
Open-Source Cheminformatics and Machine Learning
Brought to you by:
glandrum
From: markus <m.k...@tu...> - 2008-08-21 13:48:26
|
Greg Landrum wrote: > Hi Markus, > > On Thu, Aug 21, 2008 at 1:34 PM, markus <m.k...@tu...> wrote: > >> Hi, >> somehow I do not get the way RDKit organizes the IDs of conformers: >> > > Yes, the way conformers is handled is confusing at first. > > First I'll show you how to do what I think you were trying to do, then > I'll try and explain what the problem was: > > >> >>> from Chem import AllChem as Chem >> >>> import copy >> >>> mol=Chem.MolFromSmiles('c1ccccc1N') >> >>> Chem.EmbedMultipleConfs(mol,10) >> <rdBase._vecti object at 0x8301e2c> >> >>> mol2=copy.deepcopy(mol) >> >>> for i in range(mol.GetNumConformers()): >> ... print mol.GetConformer(i) >> ... >> > > The best way to loop over a molecule's conformers is using its > GetConformers() method: > > [14]>>> m = Chem.MolFromSmiles('c1ccccc1N') > [15]>>> AllChem.EmbedMultipleConfs(m,10) > Out[15] <rdBase._vecti object at 0x218182c> > [16]>>> [conf.GetId() for conf in m.GetConformers()] > Out[16] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] > > The molecule's GetConformer(x) method doesn't actually return the > conformer with index X, it returns the conformer with ID x. This is > what causes the problem here: > > >> >>> mol.AddConformer(mol2.GetConformer(4)) >> 4 >> >>> print 'NumConfs: %d\n' %(mol.GetNumConformers()) >> NumConfs: 11 >> >> >>> for i in range(mol.GetNumConformers()): >> ... print mol.GetConformer(i) >> ... >> <Chem.rdchem.Conformer object at 0x831448c> >> <Chem.rdchem.Conformer object at 0x831448c> >> <Chem.rdchem.Conformer object at 0x831448c> >> <Chem.rdchem.Conformer object at 0x831448c> >> <Chem.rdchem.Conformer object at 0x831448c> >> <Chem.rdchem.Conformer object at 0x831448c> >> <Chem.rdchem.Conformer object at 0x831448c> >> <Chem.rdchem.Conformer object at 0x831448c> >> <Chem.rdchem.Conformer object at 0x831448c> >> <Chem.rdchem.Conformer object at 0x831448c> >> Traceback (most recent call last): >> File "<stdin>", line 2, in <module> >> ValueError: Bad Conformer Id >> >>> >> > > Continuing my example from above will help show what went wrong : > [17]>>> m2 = copy.deepcopy(m) > [18]>>> m.AddConformer(m2.GetConformer(4)) > Out[18] 4 > [21]>>> [conf.GetId() for conf in m.GetConformers()] > Out[21] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 4] > > You can see that there are two conformers with id 4, but none with id > 10, which is what you were trying to retrieve above. Note that the > second conformer with id 4 cannot be retrieved using m.GetConformer : > that always returns the first conformer with the corresponding Id. > > >> Why can't I iterate over the conformers the second time? >> Do I have to assign a ConfID explicitly, when adding a Conformer? >> > > No, you don't. But if you're adding a conformer to a molecule that > already has a set of conformers, you might want to use the optional > assignId argument to Mol.AddConformer to tell the molecule to > automatically assign a new Id: > > [22]>>> m.AddConformer(m2.GetConformer(5),assignId=True) > Out[22] 10 > [23]>>> [conf.GetId() for conf in m.GetConformers()] > Out[23] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 4, 10] > > To summarize and expand a bit: > A molecule's conformers don't have to have sequential ids and the ids > can be arbitrary positive values. So if a molecule has 10 conformers, > you can't be sure that mol.GetConformer(3) will work. If you want to > loop over a molecule's conformers use the GetConformers() method. > > I hope this helps, > -greg > O.K, Conformer IDs and Indices are not the same, that's what I got wrong. Just to get certain on a detail: Calling GetConformers() returns the List of Conformers in a defined order, doesn't it? So I could repeatedly index by calling GetConformers()[X] to get the same Conformer (at Position Number X in the List) as an alternative to calling by previously assigned IDs. Cheers Markus |