annotate tools/myTools/bin/sfa/vis/utils.py @ 1:7e5c71b2e71f draft default tip

Uploaded
author laurenmarazzi
date Wed, 22 Dec 2021 16:00:34 +0000
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
1
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
2 import numpy as np
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
3 import networkx as nx
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
4
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
5
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
6 __all__ = [
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
7 'compute_graphics',
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
8 ]
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
9
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
10
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
11 def _rgb_to_hex(tup):
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
12 """Convert RGBA to #AARRGGBB
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
13 """
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
14 tup = tuple(tup)
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
15 if len(tup) == 3:
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
16 return '#%02x%02x%02x' % tup
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
17 elif len(tup) == 4:
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
18 return '#%02x%02x%02x%02x' % (tup[3], tup[0], tup[1], tup[2])
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
19 else:
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
20 raise ValueError("Array or tuple for RGB or RGBA should be given.")
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
21
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
22
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
23 def compute_graphics(
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
24 F,
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
25 act,
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
26 A,
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
27 n2i,
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
28 lw_min=1.0,
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
29 lw_max=10.0,
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
30 pct_link=90,
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
31 pct_act=50,
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
32 dg=None):
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
33 """Compute graphics of signal flow.
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
34
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
35 This method performs a calculation for generating colors
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
36 of nodes and links for visualizing purpose.
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
37
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
38 Parameters
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
39 ----------
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
40 F : numpy.ndarray
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
41 A matrix of signal flows.
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
42 It is usually calculated as W2*x1 - W1*x1,
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
43 where W is weight matrix and
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
44 x is a vector of activities at steady-state.
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
45
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
46 act : numpy.ndarray
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
47 Change in the activities. It is usually calculated
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
48 as x2 - x1, where x is
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
49 the a vector of activities at steady-state.
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
50
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
51 A : numpy.ndarray
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
52 Adjacency matrix of the network.
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
53
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
54 n2i : dict
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
55 Name to index dictionary.
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
56
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
57 lw_min : float, optional
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
58 Minimum link width, which is also used for unchanged flow.
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
59
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
60 lw_max : float, optional
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
61 Maximum link width.
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
62
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
63 pct_link : int, optional
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
64 Percentile of link width, which is used to set
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
65 the maximum value for setting link widths.
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
66 Default value is 90.
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
67
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
68 pct_act : int, optional
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
69 Percentile of activity, which is used to set
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
70 the maximum value for coloring nodes.
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
71 Default value is 50.
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
72
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
73 dg : NetworkX.DiGraph, optional
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
74 Existing NetworkX object to contain graphics information
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
75 for visualizing nodes and links.
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
76
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
77 Returns
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
78 -------
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
79 dg : NetworkX.DiGraph
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
80 NetworkX object containing graphics information
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
81 for visualizing nodes and links.
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
82
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
83 """
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
84
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
85 if not dg:
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
86 dg = nx.DiGraph()
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
87 dg.add_nodes_from(n2i)
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
88
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
89 _compute_graphics_nodes(dg, n2i, act, pct_act)
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
90 _compute_graphics_links(dg, n2i, A, F, pct_link, lw_min, lw_max)
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
91
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
92 return dg
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
93
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
94
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
95 def _compute_graphics_nodes(dg, n2i, act, pct_act):
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
96 color_white = np.array([255, 255, 255])
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
97 color_up = np.array([255, 0, 0])
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
98 color_dn = np.array([0, 0, 255])
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
99
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
100 abs_act = np.abs(act)
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
101 thr = np.percentile(abs_act, pct_act)
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
102 thr = 1 if thr == 0 else thr
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
103
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
104 arr_t = np.zeros_like(act)
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
105 for i, elem in enumerate(act):
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
106 t = np.clip(np.abs(elem) / thr, a_min=0, a_max=1)
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
107 arr_t[i] = t
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
108
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
109 for iden, idx in n2i.items():
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
110 fold = act[idx]
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
111
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
112 if fold > 0:
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
113 color = color_white + arr_t[idx] * (color_up - color_white)
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
114 elif fold <= 0:
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
115 color = color_white + arr_t[idx] * (color_dn - color_white)
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
116
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
117 color = _rgb_to_hex(np.int32(color))
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
118
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
119 data = dg.nodes[iden]
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
120 data['FILL_COLOR'] = color
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
121 data['BORDER_WIDTH'] = 2
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
122 data['BORDER_COLOR'] = _rgb_to_hex((40, 40, 40))
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
123 # end of for
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
124
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
125
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
126 def _compute_graphics_links(dg, n2i, A, F, pct_link, lw_min, lw_max):
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
127 i2n = {val: key for key, val in n2i.items()}
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
128
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
129 log_flows = np.log10(np.abs(F[F.nonzero()]))
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
130 flow_max = log_flows.max()
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
131 flow_min = log_flows.min()
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
132 flow_thr = np.percentile(log_flows, pct_link)
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
133
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
134 ir, ic = A.nonzero() # F.nonzero()
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
135 for i, j in zip(ir, ic):
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
136 tgt = i2n[i]
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
137 src = i2n[j]
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
138 f = F[i, j]
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
139
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
140 #link = net.nxdg[src][tgt]['VIS']
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
141 dg.add_edge(src, tgt)
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
142 data = dg.edges[src, tgt]
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
143
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
144
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
145 #header_old = link.header
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
146 #args_header = header_old.width, header_old.height, header_old.offset
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
147 if f > 0:
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
148 sign_link = +1 # PosHeader(*args_header)
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
149 color_link = _rgb_to_hex((255, 10, 10, 70))
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
150 elif f < 0:
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
151 sign_link = -1 # NegHeader(*args_header)
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
152 color_link = _rgb_to_hex((10, 10, 255, 70))
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
153 else: # When flow is zero, show the sign of the original link.
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
154 if A[i, j] > 0:
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
155 sign_link = +1 # PosHeader(*args_header)
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
156 elif A[i, j] < 0:
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
157 sign_link = -1 # NegHeader(*args_header)
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
158 else:
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
159 raise RuntimeError("Abnormal state has been reached in "
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
160 "_compute_graphics_links.")
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
161
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
162 color_link = _rgb_to_hex((100, 100, 100, 100))
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
163
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
164
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
165 # If header exists, it should be removed,
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
166 # because the sign of signal flow can be different
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
167 # from the original sign of header.
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
168 if 'HEADER' in data:
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
169 data.pop('HEADER')
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
170
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
171 data['SIGN'] = sign_link
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
172 data['FILL_COLOR'] = color_link
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
173
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
174 if f == 0:
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
175 data['WIDTH'] = lw_min
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
176 elif (flow_max - flow_min) == 0:
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
177 data['WIDTH'] = 0.5 * (lw_max + lw_min)
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
178 else:
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
179 log_f = np.log10(np.abs(f))
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
180 log_f = np.clip(log_f, a_min=flow_min, a_max=flow_thr)
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
181 lw = (log_f - flow_min) / (flow_max - flow_min) * (
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
182 lw_max - lw_min) + lw_min
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
183 data['WIDTH'] = lw
7e5c71b2e71f Uploaded
laurenmarazzi
parents:
diff changeset
184