Dear James,

On Thu, Jun 10, 2010 at 2:35 PM, James Davidson <j.david...@vernalis.com> wrote:
>
> I have been trying figure-out how to return the count of aromatic rings for
> molecules (in Python), and am going to have to admit defeat!  I saw in an
> earlier message
> (http://www.mail-archive.com/rdkit-discuss@lists.sourceforge.net/msg00153.html)
> a similar query, but I'm afraid it didn't help me very much.  I also read
> the section on Aromaticity in the rdkit book, and realised that maybe this
> isn't a trivial exercise!

Correct. Counting the number of non-fused rings that are aromatic,
like the post you reference does, is pretty easy; including the fused
rings that are aromatic is more challenging.

> I would like the count to count aromatic ring-systems such that bicyclic (eg
> indole or naphthalene) would only count as 1.  For reference, this appears
> to be the behaviour of the OpenEye OEDetermineAromaticRingSystems function -
> where the molecule derived from the smiles
> "C(O)(=O)c1cccc2c1[nH]c(C3CCCc4c3cccc4)c2" (which contains an indole and a
> tetrahydronaphthalene) gives a count of 2.
>
> Any help would be greatly appreciated.

I've attached a script that's not quite what you want, but it gets you
almost there: it finds all aromatic ring systems, including fused
ones. Anthracene, for example, gives 6 rings. The modifications to
this to get what you're looking for aren't a straightforward
post-processing step, but shouldn't be too bad. If there's not enough
here, let me know and I will take a look at adding the extra code.

This code isn't perfectly polished and could certainly be faster, but
it does seem mostly functional.

-greg
#
# Copyright (C) 2010 Greg Landrum
#
from rdkit import Chem

def IsRingAromatic(ring,aromaticBonds):
    for bidx in ring:
        if not aromaticBonds[bidx]:
            return False
    return True

def HasRingAromatic(ring,aromaticBonds):
    for bidx in ring:
        if aromaticBonds[bidx]:
            return True
    return False

def GetFusedRings(rings):
    res=rings[:]
    
    pool=[]
    for i in range(len(rings)):
        for j in range(i+1,len(rings)):
            ovl=rings[i]&rings[j]
            if ovl:
                fused=rings[i]|rings[j]
                fused.difference_update(ovl)
                pool.append(fused)
    while pool:
        res.extend(pool)
        nextRound=[]
        for ringi in rings:
            li=len(ringi)
            for poolj in pool:
                ovl = ringi&poolj
                if ovl:
                    lj = len(poolj)
                    fused = ringi|poolj
                    fused.difference_update(ovl)
                    lf = len(fused)
                    if lf>li and lf>lj and fused not in nextRound and fused not in res:
                        nextRound.append(fused)
        pool = nextRound
    return res

def FindAromaticRings(mol):
    # flag whether or not bonds are aromatic:
    aromaticBonds = [0]*mol.GetNumBonds()
    for bond in mol.GetBonds():
        if bond.GetIsAromatic():
            aromaticBonds[bond.GetIdx()]=1

    # get the list of all rings:
    ri = mol.GetRingInfo()
    # collect the ones that have at least one aromatic bond:
    rings=[set(x) for x in ri.BondRings() if HasRingAromatic(x,aromaticBonds)]

    # generate all fused ring systems from that set
    fusedRings=GetFusedRings(rings)

    aromaticRings = [x for x in fusedRings if IsRingAromatic(x,aromaticBonds)]
    return aromaticRings

if __name__=='__main__':
    m = Chem.MolFromSmiles('C1=CC2=CC=CC=CC2=C1')
    print FindAromaticRings(m)
    
    m = Chem.MolFromSmiles('C1=CC2=C(C=C1)C=C1C=C3C=C4C=C5C(C=CC=C5C5=CC=CC6=C5C=CC=C6)=CC4=CC3=CC1=C2')
    print FindAromaticRings(m)
------------------------------------------------------------------------------
ThinkGeek and WIRED's GeekDad team up for the Ultimate 
GeekDad Father's Day Giveaway. ONE MASSIVE PRIZE to the 
lucky parental unit.  See the prize list and enter to win: 
http://p.sf.net/sfu/thinkgeek-promo
_______________________________________________
Rdkit-discuss mailing list
Rdkit-discuss@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/rdkit-discuss

Reply via email to