NetAnalyzer 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- NetAnalyzer/__init__.py +11 -0
- NetAnalyzer/adv_mat_calc.py +106 -0
- NetAnalyzer/cli_manager.py +331 -0
- NetAnalyzer/graph2sim.py +106 -0
- NetAnalyzer/integration.py +165 -0
- NetAnalyzer/main_modules.py +610 -0
- NetAnalyzer/net_parser.py +78 -0
- NetAnalyzer/net_plotter.py +200 -0
- NetAnalyzer/netanalyzer.py +1257 -0
- NetAnalyzer/performancer.py +83 -0
- NetAnalyzer/ranker.py +353 -0
- NetAnalyzer/seed_parser.py +27 -0
- NetAnalyzer/templates/net_explorer.txt +83 -0
- NetAnalyzer/templates/network.txt +1 -0
- NetAnalyzer-1.0.0.dist-info/LICENSE.txt +21 -0
- NetAnalyzer-1.0.0.dist-info/METADATA +86 -0
- NetAnalyzer-1.0.0.dist-info/RECORD +20 -0
- NetAnalyzer-1.0.0.dist-info/WHEEL +5 -0
- NetAnalyzer-1.0.0.dist-info/entry_points.txt +8 -0
- NetAnalyzer-1.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import re
|
|
3
|
+
import sys
|
|
4
|
+
import graphviz
|
|
5
|
+
import json
|
|
6
|
+
import base64
|
|
7
|
+
import igraph as ig
|
|
8
|
+
from igraph.layout import Layout
|
|
9
|
+
import matplotlib as mpl
|
|
10
|
+
import random
|
|
11
|
+
import numpy as np
|
|
12
|
+
import pickle
|
|
13
|
+
from py_report_html import Py_report_html
|
|
14
|
+
class Net_plotter:
|
|
15
|
+
|
|
16
|
+
TEMPLATES = os.path.join(os.path.dirname(__file__), 'templates')
|
|
17
|
+
|
|
18
|
+
def __init__(self, net_data, options={}):
|
|
19
|
+
|
|
20
|
+
self.group_nodes = net_data['group_nodes']
|
|
21
|
+
self.reference_nodes = net_data['reference_nodes']
|
|
22
|
+
self.graph = net_data['graph']
|
|
23
|
+
self.layers = net_data['layers']
|
|
24
|
+
|
|
25
|
+
if options['method'] == 'graphviz':
|
|
26
|
+
self.plot_dot(options)
|
|
27
|
+
if options['method'] == 'igraph':
|
|
28
|
+
self.plot_igraph(options)
|
|
29
|
+
elif options['method'] == 'cyt_app':
|
|
30
|
+
self.plot_cyt_app(options)
|
|
31
|
+
else:
|
|
32
|
+
container = {'net_data' : {'group_nodes' : self.group_nodes, 'reference_nodes' : self.reference_nodes, 'graph' : self.graph, 'layers' : self.layers}}
|
|
33
|
+
template = open(os.path.join(Net_plotter.TEMPLATES, 'network.txt')).read()
|
|
34
|
+
report = Py_report_html(container, os.path.basename(options['output_file']), True, True)
|
|
35
|
+
report.build(template, build_options=options)
|
|
36
|
+
report.write(options['output_file'] + '.html')
|
|
37
|
+
|
|
38
|
+
def get_node_layer(self, node_id):
|
|
39
|
+
return self.graph.nodes(data=True)[node_id]['layer']
|
|
40
|
+
|
|
41
|
+
## GRAPHVIZ
|
|
42
|
+
##############################################################
|
|
43
|
+
def plot_dot(self, user_options = {}): # input keys: layout
|
|
44
|
+
# Watch out: Node ids must be with no ":".
|
|
45
|
+
options = {'layout': "sfdp"}
|
|
46
|
+
options.update(user_options)
|
|
47
|
+
graphviz_colors = ['lightsteelblue1', 'lightyellow1', 'lightgray', 'orchid2']
|
|
48
|
+
palette = {}
|
|
49
|
+
for layer in self.layers: palette[layer] = graphviz_colors.pop(0)
|
|
50
|
+
graph = graphviz.Graph('graph')
|
|
51
|
+
graph.attr(overlap = 'false', outputorder='edgesfirst')
|
|
52
|
+
for e in self.graph.edges:
|
|
53
|
+
l0 = self.get_node_layer(e[0])
|
|
54
|
+
graph.node(f'"{e[0]}"', '', style = 'filled', fillcolor = palette[l0])
|
|
55
|
+
l1 = self.get_node_layer(e[1])
|
|
56
|
+
graph.node(f'"{e[1]}"', '', style = 'filled', fillcolor = palette[l1])
|
|
57
|
+
graph.edge(f'"{e[0]}"', f'"{e[1]}"')
|
|
58
|
+
|
|
59
|
+
for nodeID in self.reference_nodes: graph.node(f'"{nodeID}"', '', style = 'filled', fillcolor = 'firebrick1')
|
|
60
|
+
graphviz_border_colors = ['blue', 'darkorange', 'red', 'olivedrab4']
|
|
61
|
+
for groupID, gNodes in self.group_nodes.items():
|
|
62
|
+
border_color = graphviz_border_colors.pop(0)
|
|
63
|
+
for nodeID in gNodes: graph.node(f'"{nodeID}"', '', color = border_color, penwidth = '10')
|
|
64
|
+
graph.render(outfile= options['output_file'] + '.png', format='png', engine = options['layout'])
|
|
65
|
+
|
|
66
|
+
## IGRAPH
|
|
67
|
+
##########################################################################
|
|
68
|
+
def plot_igraph(self, user_options = {}):
|
|
69
|
+
random.seed(1234)
|
|
70
|
+
ig_net = ig.Graph.from_networkx(self.graph)
|
|
71
|
+
net_edge_weight = ig_net.es['weight']
|
|
72
|
+
newMax= np.percentile(net_edge_weight, 90)
|
|
73
|
+
#net_edge_weight = [ f"rgba(0.5,0.5,0.5,{round(w/newMax, 3)})" for w in net_edge_weight ]
|
|
74
|
+
norm_net_edge_weight = [ ]
|
|
75
|
+
for w in net_edge_weight:
|
|
76
|
+
normalized = round(w/newMax, 3)
|
|
77
|
+
if normalized > 1: normalized = 1
|
|
78
|
+
norm_net_edge_weight.append(f"rgba(0.7,0.7,0.7,{normalized})")
|
|
79
|
+
cmap=mpl.colormaps['Pastel1']
|
|
80
|
+
node_ids = ig_net.vs['_nx_name']
|
|
81
|
+
node_base_color = list(cmap(0))
|
|
82
|
+
node_base_color[3] = 0.25
|
|
83
|
+
node_base_color = tuple(node_base_color)
|
|
84
|
+
node_colors = [node_base_color] * len(node_ids)
|
|
85
|
+
# Node color
|
|
86
|
+
count = 1
|
|
87
|
+
for groupID, gNodes in self.group_nodes.items():
|
|
88
|
+
color = cmap(count)
|
|
89
|
+
for n in gNodes:
|
|
90
|
+
idx = node_ids.index(n)
|
|
91
|
+
node_colors[idx] = color
|
|
92
|
+
count += 1
|
|
93
|
+
|
|
94
|
+
# Node order: tag each node with a int that says in which order mut be plotted. 0 is the first node to be plotted and N node the last (so the first in the image)
|
|
95
|
+
node_order=[0] * len(node_ids)
|
|
96
|
+
node_count = len(node_ids) -1
|
|
97
|
+
node_dict = {}
|
|
98
|
+
for groupID, gNodes in self.group_nodes.items():
|
|
99
|
+
for n in gNodes:
|
|
100
|
+
node_dict[n] = node_count
|
|
101
|
+
node_count -= 1
|
|
102
|
+
for i,n_id in enumerate(node_ids):
|
|
103
|
+
order = node_dict.get(n_id)
|
|
104
|
+
if order == None:
|
|
105
|
+
order = node_count
|
|
106
|
+
node_count -= 1
|
|
107
|
+
node_order[i] = order
|
|
108
|
+
opts = {
|
|
109
|
+
'bbox' : (2400, 2400),
|
|
110
|
+
'vertex_size' : 7,
|
|
111
|
+
'layout' : "drl",
|
|
112
|
+
'edge_color' : norm_net_edge_weight,
|
|
113
|
+
'vertex_color': node_colors,
|
|
114
|
+
'vertex_order': node_order
|
|
115
|
+
}
|
|
116
|
+
opts.update(user_options)
|
|
117
|
+
layout = self.get_igraph_layout(node_ids, ig_net, opts.pop('layout'), opts)
|
|
118
|
+
ig.plot(ig_net, layout=layout, target=user_options['output_file'] + '.png', **opts)
|
|
119
|
+
|
|
120
|
+
def get_igraph_layout(self, node_ids, igraph_obj, layout_name, opts):
|
|
121
|
+
layout = None
|
|
122
|
+
load_path = opts.get('load')
|
|
123
|
+
if load_path != None:
|
|
124
|
+
sorted_coords = []
|
|
125
|
+
with open(load_path, 'rb') as file:
|
|
126
|
+
tagged_coordinates = pickle.load(file)
|
|
127
|
+
for nodeID in node_ids: # Reorder file loaded layout with the current node ordering in the igraph object
|
|
128
|
+
coords = tagged_coordinates.get(nodeID)
|
|
129
|
+
if coords != None: sorted_coords.append(coords)
|
|
130
|
+
layout = Layout(sorted_coords) # Create layout objet from reordered loaded node coords
|
|
131
|
+
else:
|
|
132
|
+
layout_custom_opts = {}
|
|
133
|
+
custom_opts_string = opts.get('custom_opts')
|
|
134
|
+
if layout_custom_opts != None: layout_custom_opts = eval(re.sub(';', ',', custom_opts_string))
|
|
135
|
+
layout = igraph_obj.layout(layout_name, **layout_custom_opts)
|
|
136
|
+
save_path = opts.get('save')
|
|
137
|
+
if save_path != None:
|
|
138
|
+
tagged_coordinates = {}
|
|
139
|
+
for i, n in enumerate(node_ids):
|
|
140
|
+
tagged_coordinates[n] = layout[i]
|
|
141
|
+
with open(save_path, 'wb') as file: pickle.dump(tagged_coordinates, file)
|
|
142
|
+
return layout
|
|
143
|
+
|
|
144
|
+
## CYTOSCAPE APP
|
|
145
|
+
###########################################################################
|
|
146
|
+
def plot_cyt_app(self, user_options = {}):
|
|
147
|
+
options = {}
|
|
148
|
+
options.update(user_options)
|
|
149
|
+
|
|
150
|
+
group_nodes = {}
|
|
151
|
+
for groupID, gNodes in self.group_nodes.items():
|
|
152
|
+
for gNode in gNodes:
|
|
153
|
+
group_nodes[gNode] = groupID
|
|
154
|
+
|
|
155
|
+
node_cyt_ids = {}
|
|
156
|
+
nodes = []
|
|
157
|
+
count = 0
|
|
158
|
+
for node in self.graph.nodes:
|
|
159
|
+
self.cyt_app_add_node(nodes, count, node, group_nodes)
|
|
160
|
+
node_cyt_ids[node] = str(count)
|
|
161
|
+
count += 1
|
|
162
|
+
edges = self.cyt_app_add_edges(node_cyt_ids, count)
|
|
163
|
+
cys_net = {
|
|
164
|
+
'elements' : {
|
|
165
|
+
'nodes' : nodes,
|
|
166
|
+
'edges' : edges
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
with open(options['output_file'] + '.cyjs', 'w') as f: f.write(json.dumps(cys_net, indent=4))
|
|
170
|
+
|
|
171
|
+
def cyt_app_add_node(self, nodes, count, node, group_nodes):
|
|
172
|
+
cyt_node = {
|
|
173
|
+
'data' : {
|
|
174
|
+
'id' : str(count),
|
|
175
|
+
'name' : node
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
cyt_node['data']['type'] = self.get_node_layer(node)
|
|
179
|
+
if len(self.reference_nodes) > 0:
|
|
180
|
+
cyt_node['data']['ref'] = 'y' if node in self.reference_nodes else 'n'
|
|
181
|
+
if len(group_nodes) > 0:
|
|
182
|
+
query = group_nodes[node]
|
|
183
|
+
if query != None: cyt_node['data']['group'] = query
|
|
184
|
+
nodes.append(cyt_node)
|
|
185
|
+
|
|
186
|
+
def cyt_app_add_edges(self, node_ids, count):
|
|
187
|
+
edges = []
|
|
188
|
+
for e in self.graph.edges:
|
|
189
|
+
edges.append({
|
|
190
|
+
'data' : {
|
|
191
|
+
'id' : str(count),
|
|
192
|
+
'source' : node_ids[e[0]],
|
|
193
|
+
'target' : node_ids[e[1]],
|
|
194
|
+
"interaction" : "-",
|
|
195
|
+
"weight" : 1.0
|
|
196
|
+
}
|
|
197
|
+
})
|
|
198
|
+
count +=1
|
|
199
|
+
return edges
|
|
200
|
+
###########################################################################
|