Skip to content

Commit b9ad956

Browse files
author
Maxwell Bertolero
committed
added nodal roles
participation coef and within module degree, with weighted graph functionality.
1 parent 1ff6c81 commit b9ad956

File tree

1 file changed

+130
-0
lines changed

1 file changed

+130
-0
lines changed

brainx/nodal_roles.py

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
#Author: Maxwell Bertolero
2+
3+
import numpy as np
4+
from random import choice
5+
import networkx as nx
6+
7+
def within_module_degree(graph, partition, weighted = False):
8+
'''
9+
Computes the within-module degree for each node (Guimera et al. 2005)
10+
11+
------
12+
Inputs
13+
------
14+
graph = Networkx Graph, unweighted, undirected.
15+
partition = dictionary from modularity partition of graph using Louvain method
16+
17+
------
18+
Output
19+
------
20+
Dictionary of the within-module degree of each node.
21+
22+
'''
23+
new_part = {}
24+
for m,n in zip(partition.values(),partition.keys()):
25+
try:
26+
new_part[m].append(n)
27+
except KeyError:
28+
new_part[m] = [n]
29+
partition = new_part
30+
wd_dict = {}
31+
32+
#loop through each module, look at nodes in modules
33+
for m in partition.keys():
34+
mod_list = partition[m]
35+
mod_wd_dict = {}
36+
#get within module degree of each node
37+
for source in mod_list:
38+
count = 0
39+
for target in mod_list:
40+
if (source,target) in graph.edges() or (target,source) in graph.edges():
41+
if weighted == True:
42+
count += graph.get_edge_data(source,target)['weight']
43+
count += graph.get_edge_data(target,source)['weight'] # i assume this will only get one weighted edge.
44+
else:
45+
count += 1
46+
mod_wd_dict[source] = count
47+
# z-score
48+
all_mod_wd = mod_wd_dict.values()
49+
avg_mod_wd = float(sum(all_mod_wd) / len(all_mod_wd))
50+
std = np.std(all_mod_wd)
51+
#add to dictionary
52+
for source in mod_list:
53+
wd_dict[source] = (mod_wd_dict[source] - avg_mod_wd) / std
54+
return wd_dict
55+
56+
57+
def participation_coefficient(graph, partition):
58+
'''
59+
Computes the participation coefficient for each node (Guimera et al. 2005).
60+
61+
------
62+
Inputs
63+
------
64+
graph = Networkx graph
65+
partition = modularity partition of graph
66+
67+
------
68+
Output
69+
------
70+
Dictionary of the participation coefficient for each node.
71+
72+
'''
73+
#this is because the dictionary output of Louvain is "backwards"
74+
new_part = {}
75+
for m,n in zip(partition.values(),partition.keys()):
76+
try:
77+
new_part[m].append(n)
78+
except KeyError:
79+
new_part[m] = [n]
80+
partition = new_part
81+
pc_dict = {}
82+
all_nodes = set(graph.nodes())
83+
# loop through modules
84+
if weighted == False:
85+
for m in partition.keys():
86+
#set of nodes in modules
87+
mod_list = set(partition[m])
88+
#set of nodes outside that module
89+
between_mod_list = list(set.difference(all_nodes, mod_list))
90+
for source in mod_list:
91+
#degree of node
92+
degree = float(nx.degree(G=graph, nbunch=source))
93+
count = 0
94+
# between module degree
95+
for target in between_mod_list:
96+
if (source,target) in graph.edges() or(source,target) in graph.edges():
97+
count += 1
98+
bm_degree = float(count)
99+
if bm_degree == 0.0:
100+
pc = 0.0
101+
else:
102+
pc = 1 - ((float(bm_degree) / float(degree))**2)
103+
pc_dict[source] = pc
104+
return pc_dict
105+
#this is because the dictionary output of Louvain is "backwards"
106+
if weighted == True:
107+
for m in partition.keys():
108+
#set of nodes in modules
109+
mod_list = set(partition[m])
110+
#set of nodes outside that module
111+
between_mod_list = list(set.difference(all_nodes, mod_list))
112+
for source in mod_list:
113+
#degree of node
114+
degree = 0
115+
edges = G.edges([source],data=True)
116+
for edge in edges:
117+
degree += graph.get_edge_data(edge[0],edge[1])['weight']
118+
count = 0
119+
# between module degree
120+
for target in between_mod_list:
121+
if (source,target) in graph.edges() or(source,target) in graph.edges():
122+
count += graph.get_edge_data(source,target)['weight']
123+
count += graph.get_edge_data(target,source)['weight'] # i assume this will only get one weighted edge.
124+
bm_degree = float(count)
125+
if bm_degree == 0.0:
126+
pc = 0.0
127+
else:
128+
pc = 1 - ((float(bm_degree) / float(degree))**2)
129+
pc_dict[source] = pc
130+
return pc_dict

0 commit comments

Comments
 (0)