Skip to content

Commit

Permalink
Changed graph to accomodate networkx
Browse files Browse the repository at this point in the history
Given object, each node is structured n:{obj=object}, where n=id(object)
  • Loading branch information
johnsekar committed May 24, 2017
1 parent 7eb5995 commit 454b131
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 27 deletions.
17 changes: 11 additions & 6 deletions tests/test_wc_rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,15 +189,20 @@ class z(bio.Site):pass
x1.add_bond_to(z1)
y1.init_binding_state()
c1.add([A1,B1])

g = c1.graph
nodes = sorted(list(x.label for x in g.nodes()))
edges = sorted(list(tuple(x.label for x in edge) for edge in g.edges() ) )

def get_node_label(graph,node): return graph.node[node]['obj'].label

nodes1 = sorted([get_node_label(g,x) for x in g.nodes()])
nodes2 = ['A', 'B', 'BindingState', 'BindingState', 'BindingState', 'Complex', 'PhosphorylationState', 'x', 'y', 'z']
edges2 = [('A', 'x'), ('A', 'y'), ('B', 'z'), ('Complex', 'A'), ('Complex', 'B'), ('x', 'BindingState'), ('y', 'BindingState'), ('z', 'BindingState'), ('z', 'PhosphorylationState')]
self.assertEqual(nodes,nodes2)
self.assertEqual(edges,edges2)

edges1 = sorted([tuple([get_node_label(g,x) for x in edge]) for edge in g.edges()])
edges2 = [('A', 'x'), ('A', 'y'), ('B', 'z'), ('BindingState', 'x'), ('BindingState', 'z'), ('Complex', 'A'), ('Complex', 'B'), ('x', 'BindingState'), ('y', 'BindingState'), ('z', 'BindingState'), ('z', 'PhosphorylationState')]

self.assertEqual(nodes1,nodes2)
self.assertEqual(edges2,edges2)


def test_current(self):pass

Expand Down
13 changes: 6 additions & 7 deletions wc_rules/bioschema.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import wc_rules.utils as utils
import wc_rules.ratelaw as rl
import wc_rules.graph_utils as g
import networkx as nx

###### Structures ######
class BaseClass(core.Model):
Expand Down Expand Up @@ -39,15 +40,12 @@ def label(self):
return self.__class__.__name__

##### Graph Methods #####
def node_match(self,other):
return g.node_compare(self,other)
def get_graph(self,recurse=True,memo=None):
return g.get_graph(self,recurse=recurse,memo=memo)

def get_edges(self):
return g.get_edges(self)

@property
def graph(self):
return g.get_graph(self)
return self.get_graph(recurse=True)

class Complex(BaseClass):
class GraphMeta(BaseClass.GraphMeta):
Expand Down Expand Up @@ -240,6 +238,7 @@ def set_target(self,value):
self.target = value
return self


class BondOperation(Operation):
sites = core.OneToManyAttribute(Site,related_name='bond_op')
@property
Expand Down Expand Up @@ -302,7 +301,7 @@ class Dephosphorylate(SetFalse): pass

def main():
pass

if __name__ == '__main__':
main()

47 changes: 33 additions & 14 deletions wc_rules/graph_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,37 @@ def node_compare(current,other):
if current_attr != other_attr: return False
return True

def get_edges(node):
edges = []
for attrname in node.__class__.GraphMeta.outward_edges:
if getattr(node,attrname) is not None:
attr_obj = getattr(node,attrname)
if isinstance(attr_obj,core.RelatedManager):
for x in attr_obj:
edges.append(tuple([node,x]))
edges.extend(x.get_edges())
else:
edges.append(tuple([node,attr_obj]))
return edges
def get_graph(current_obj,recurse=True,memo=None):
def update_graph(graph,obj1):
if id(obj1) not in graph:
graph.add_node(id(obj1),obj=obj1)
else:
graph.node[id(obj1)]['obj'] = obj1

def get_graph(node):
return nx.DiGraph(node.get_edges())
# Initializing if a memo is not provided
if memo is None:
memo = nx.DiGraph()
# Adding node if not already in memo, else updating it
update_graph(memo,current_obj)

# getting list of next nodes to check
next_nodes = []
for attrname in current_obj.__class__.GraphMeta.outward_edges:
if getattr(current_obj,attrname) is not None:
attr = getattr(current_obj,attrname)
if isinstance(attr,list):
next_nodes.extend(attr)
else:
next_nodes.append(attr)
# for each node in next_nodes,
# if an edge already exists, ignore
# if adding a new edge, recurse onto that node using current memo
for x in next_nodes:
update_graph(memo,x)
e = tuple([id(current_obj),id(x)])
if e not in memo.edges():
memo.add_edge(*e)
if recurse is True:
memo2 = x.get_graph(recurse=True,memo=memo)
memo = memo2
return memo

0 comments on commit 454b131

Please sign in to comment.