11# -*- coding: utf-8 -*-
2- """graph_utils.py: Graph related utilties. It does not require networkx library.
3- It writes files to be used with graphviz.
4-
5- Last modified: Sat Jan 18, 2014 05:01PM
2+ """graph_utils.py:
63
4+ Some network analysis utilities.
75"""
86
7+ from __future__ import print_function , division
8+
99__author__ = "Dilawar Singh"
10- __copyright__ = "Copyright 2013, NCBS Bangalore"
11- __credits__ = ["NCBS Bangalore" , "Bhalla Lab" ]
12- __license__ = "GPL"
13- __version__ = "1.0.0"
10+ __copyright__ = "Copyright 2018-19, NCBS Bangalore"
1411__maintainer__ = "Dilawar Singh"
151216- __status__ = "Development"
1713
1814import sys
15+ import hashlib
1916from . import _moose
20- import inspect
21- from . import print_utils as debug
17+ from . import print_utils as pu
2218import re
2319
2420pathPat = re .compile (r'.+?\[\d+\]$' )
2521
26- def getMoosePaths (pat , isRoot = True ):
27- ''' Return a list of paths for a given pattern. '''
28- if type (pat ) != str :
29- pat = pat .path
30- assert type (pat ) == str
31- moose_paths = [x .path for x in _moose .wildcardFind (pat )]
32- return moose_paths
33-
3422def writeGraphviz (filename = None , pat = '/##[TYPE=Compartment]' ):
35- '''This is a generic function. It takes the the pattern, search for paths
36- and write a graphviz file.
23+ '''Write Electrical network to a dot graph.
24+
25+ Params:
26+
27+ :filename: Default None. Write graphviz file to this path. If None, write to
28+ stdout.
29+ :pat: Compartment path. By default, search for all moose.Compartment.
3730 '''
3831
3932 def fix (path ):
@@ -44,14 +37,9 @@ def fix(path):
4437 path = path + '[0]'
4538 return path
4639
47-
48- pathList = getMoosePaths (pat )
4940 compList = _moose .wildcardFind (pat )
5041 if not compList :
51- debug .dump ("WARN"
52- , "No compartment found"
53- , frame = inspect .currentframe ()
54- )
42+ pu .warn ("No compartment found" )
5543
5644 dot = []
5745 dot .append ("digraph G {" )
@@ -83,3 +71,57 @@ def fix(path):
8371 graphviz .write (dot )
8472 return True
8573
74+ def writeCRN (compt , path = None ):
75+ """Write chemical reaction network to a graphviz file.
76+
77+ :param compt: Given compartment.
78+ :param filepath: Save to this filepath. If None, write to stdout.
79+ """
80+ dot = _crn (compt )
81+ if path is None :
82+ print (dot , file = sys .stdout )
83+ return
84+ with open (path , 'w' ) as f :
85+ f .write (dot )
86+
87+ def _fixLabel (name ):
88+ name = name .replace ('*' , 'star' )
89+ name = name .replace ('.' , '_' )
90+ return "\" {}\" " .format (name )
91+
92+ def _addNode (n , nodes , dot ):
93+ node = hashlib .sha224 (n .path .encode ()).hexdigest ()
94+ nodeType = 'pool'
95+ if isinstance (n , _moose .Reac ) or isinstance (n , _moose .ZombieReac ):
96+ node = 'r' + node
97+ nodeType = 'reac'
98+ else :
99+ node = 'p' + node
100+ if node in nodes :
101+ return node
102+
103+ nLabel = n .name
104+ if nodeType == 'reac' :
105+ nLabel = "kf=%g kb=%g" % (n .Kf , n .Kb )
106+ dot .append ('\t %s [label="%s", kf=%g, kb=%g, shape=rect]' % (
107+ node , nLabel , n .Kf , n .Kb ))
108+ else :
109+ dot .append ('\t %s [label="%s", concInit=%g]' % (
110+ node , nLabel , n .concInit ))
111+ return node
112+
113+ def _crn (compt ):
114+ nodes = {}
115+ reacs = _moose .wildcardFind (compt .path + '/##[TYPE=Reac]' )
116+ reacs += _moose .wildcardFind (compt .path + '/##[TYPE=ZombieReac]' )
117+ dot = ['digraph %s {\n \t overlap=false' % compt .name ]
118+ for r in reacs :
119+ rNode = _addNode (r , nodes , dot )
120+ for s in r .neighbors ['sub' ]:
121+ sNode = _addNode (s , nodes , dot )
122+ dot .append ('\t %s -> %s' % (sNode , rNode ))
123+ for p in r .neighbors ['prd' ]:
124+ pNode = _addNode (p , nodes , dot )
125+ dot .append ('\t %s -> %s' % (rNode , pNode ))
126+ dot .append ('}' )
127+ return '\n ' .join (dot )
0 commit comments