コード例 #1
0
def findRings(graph):
    """
    a very simple ring detection algorightm to identify 5, and 6 member aromatic rings

            A    <- head
           / \   
          B   C  <- tier 1
          |   |
          D   E  <- tier 2
           \ /
            F    <- tier 3, ring closure (6 member-ring)

    
            A    <- head 
           / \              
          B   C  <- tier 1
          |   |
          D---E  <- tier 2, ring closure (5-member ring)


            A   <- head 
            |             
            B   <- tier 1
           / \
          C---D <- tier 2  # SPURIOUS, RECOGNIZED BUT NOT COUNTED

              
    """
    # TODO add a planarity check?
    rings5 = []
    rings6 = []
    if DEBUG: print "- starting ring detection..."
    for head in graph.keys():
        tier1 = graph[head]
        tier2 = []
        tier3 = []
        # populate tier2 
        for node1 in tier1:
            for tmp in graph[node1]:
                if not tmp == head and not tmp in tier2 and (not tmp in tier1) :
                    tier2.append(tmp)
        # populate tier3
        for node2 in tier2:
            for tmp in graph[node2]:
                if (not tmp == head) and (not tmp in tier2) and (not tmp in tier1) and (not tmp in tier3):
                    tier3.append(tmp)
        # 6 member rings
        for x in tier3:
            candidate  = []
            for c in tier2:
                if x in graph[c]:
                    if not c in candidate:
                        candidate.append(c)
            if len(candidate) >1:
                r6 = [ head ] 
                r6.append(x)
                r6 += candidate
                for c in candidate:
                    r6 += hf.intersect( graph[head], graph[c])
                r6.sort()
                if not r6 in rings6:
                    rings6.append( r6 )
                    if DEBUG: print "    6member!", r6
                break
        # 5 member rings
        for c1 in tier2:
            for c2 in tier2:
                if not c1 == c2:
                    if (c2 in graph[c1]) and (c1 in graph[c2]):
                        is_3_ring = False
                        for k in graph[c1]:
                            if k in graph[c2]: 
                                is_3_ring =True
                                if DEBUG: print "       [ ...catched a cycle_3... ]"
                                break
                        if not is_3_ring :
                            r5 = [ head ] 
                            r5.append(c1)
                            r5.append(c2)
                            r5 += hf.intersect( graph[head], graph[c1])
                            r5 += hf.intersect( graph[head], graph[c2])
                            r5.sort()
                            if not r5 in rings5:
                                if DEBUG: print "    5member ring!",r5
                                rings5.append(r5)
                        break
    return rings5, rings6