[Bio] / Detour / GraphBuilder.py Repository:
ViewVC logotype

Annotation of /Detour/GraphBuilder.py

Parent Directory Parent Directory | Revision Log Revision Log


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