[Bio] / Detour / GraphBuilder.py Repository: Repository Listing Bio

# Annotation of /Detour/GraphBuilder.py

Revision 1.1.1.1 - (view) (download) (as text)

 1 : sheradon 1.1 2 : import string 3 : from pydot import * 4 : # Compbio tools we'll need: 5 : try: 6 : from KahOM.RecoElem import * 7 : from FaST.BssFactory import * 8 : except: 9 : #print 'Could not import KahOM modules.' 10 : pass 11 : 12 : class unique: 13 : uniqueN = 100 14 : def get(self): 15 : self.uniqueN = self.uniqueN + 1 16 : return self.uniqueN 17 : uN = unique() 18 : recycling = {} 19 : 20 : # ----------------- 21 : def makeDot(re): 22 : # ----------------- 23 : """Generates a pydot Dot graph structure from a recoElem. 24 : @type re: RecoElem 25 : @rtype: Dot 26 : """ 27 : global recycling 28 : recycling = {} 29 : degree = {} 30 : s = Dot(graph_name = 'graph%d' % uN.get(), type = 'digraph', rankdir = 'LR', \ 31 : label = re.Name, overlap = 'scale', fontsize = '12', nslimit = '2.0', mclimit = '2.0') 32 : 33 : rxns = [] 34 : try: 35 : re.gatherReactions(rxns) # make list of reactions 36 : except: 37 : print 'makeDot failed: Could not gatherReactions from recoElem.' 38 : return None 39 : rxns = uniqueReactions(rxns) # remove duplicates 40 : 41 : # Make nodes & edges for each reaction here... 42 : for rxn in rxns: 43 : 44 : if rxn.Direction == '1' or rxn.Direction == 'forward': direction = 'forward' 45 : elif rxn.Direction == 'both': direction = 'both' 46 : 47 : # Inputs 48 : into = Node('invis%d' % uN.get(), style = 'invis', fixedsize = 'true', height = '0', width = '0') 49 : s.add_node(into) 50 : for input in rxn.Inputs: 51 : nn = getNodeByLabel(input.Name) 52 : # If not created yet or it's a "non-connected" (common things e.g. ATP), make a new node 53 : if nn == None or not input.isConnected: 54 : label = string.replace(input.Name, ' ', r'\n') # break into multiple lines 55 : nn = Node("node%d" % uN.get(), label = label, shape = 'box') 56 : if input.isConnected: recycling[input.Name] = nn # reuse node 57 : else: nn.shape = 'plaintext' # or mark it as a 'multi' 58 : s.add_node(nn) 59 : degree[nn.get_name()] = 1 60 : # Otherwise we keep the existing and increment its degree count 61 : else: degree[nn.get_name()] += 1 62 : ne = Edge(nn.get_name(), into.get_name(), dir=direction) 63 : s.add_edge(ne) 64 : if input.isConnected: ne.weight = '2' 65 : else: ne.weight = '1' 66 : 67 : # Outputs 68 : outof = Node('invis%d' % uN.get(), style = 'invis', fixedsize = 'true', height = '0', width = '0') 69 : s.add_node(outof) 70 : for output in rxn.Outputs: 71 : nn = getNodeByLabel(output.Name) 72 : # same drill as above... this is when we create a new node: 73 : if nn == None or not output.isConnected: 74 : label = string.replace(output.Name, ' ', r'\n') # break into multiple lines 75 : nn = Node('node%d' % uN.get(), label = label, shape = 'box') 76 : if output.isConnected: recycling[output.Name] = nn # reuse node 77 : else: nn.shape = 'plaintext' # or mark it as a 'multi' 78 : s.add_node(nn) 79 : degree[nn.get_name()] = 1 80 : # Otherwise keep existing node, increment degree 81 : else: degree[nn.get_name()] += 1 82 : ne = Edge(outof.get_name(), nn.get_name(), dir=direction) 83 : s.add_edge(ne) 84 : if output.isConnected: ne.weight = '2' 85 : else: ne.weight = '1' 86 : 87 : # edge connecting inputs to outputs 88 : s.add_edge(Edge(into.get_name(), outof.get_name(), tooltip = rxn.asString(), label = '?', dir = direction)) 89 : 90 : # OK, go through each node and adjust its size based on its degree. 91 : # That is, ones with tons of in/out activity will be bigger. 92 : for n in s.get_node_list(): 93 : if n.style == 'invis': continue 94 : try: 95 : # n.fontsize = 12 + 4*degree[n.get_name()] 96 : n.height = str(0.20 + 0.10 * degree[n.get_name()]) 97 : n.width = str(0.7 * string.atof(n.height) * max(map(len, string.split(n.label, r'\n')))) 98 : except KeyError: pass 99 : return s 100 : 101 : 102 : # -------------------------- 103 : def getNodeByLabel(label, recycling=recycling): 104 : # -------------------------- 105 : """Get a Node with this label, if it's been created. Note that the pydot.Graph built-in 106 : get_node(str) won't work because it takes a name (eg. node132), not label. 107 : @type label: string 108 : @rtype: Node 109 : """ 110 : try: return recycling[label] 111 : except: return None 112 : 113 : # -------------------------- 114 : def uniqueReactions(rxns): 115 : # -------------------------- 116 : """Get rid of duplicates. Don't think it's very efficient because of 117 : the asString generation and rebuilding the list, but it's quick to write. 118 : @type: [Reaction] 119 : @rtype: [Reaction] 120 : """ 121 : umap = {} 122 : urxns = [] 123 : for r in rxns: 124 : umap[r.asString()] = r 125 : for key in umap.keys(): 126 : urxns.append(umap[key]) 127 : return urxns 128 : 129 :

 MCS Webmaster ViewVC Help Powered by ViewVC 1.0.3