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