-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path2022-08-29__Visualizing_subnets.jl
182 lines (136 loc) · 4.35 KB
/
2022-08-29__Visualizing_subnets.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# -*- coding: utf-8 -*-
# ---
# jupyter:
# jupytext:
# formats: ipynb,jl:light
# text_representation:
# extension: .jl
# format_name: light
# format_version: '1.5'
# jupytext_version: 1.13.7
# kernelspec:
# display_name: Julia 1.7.0
# language: julia
# name: julia-1.7
# ---
# # 2022-08-29 • Visualizing subnets
# ## Imports
# +
#
# -
using Revise
using MyToolbox
using VoltoMapSim
# ## Params
# Based on Roxin; same as previous nb's.
d = 6
p = get_params(
duration = 10minutes,
p_conn = 0.04,
g_EE = 1 / d,
g_EI = 18 / d,
g_IE = 36 / d,
g_II = 31 / d,
ext_current = Normal(-0.5 * pA/√seconds, 5 * pA/√seconds),
E_inh = -80 * mV,
record_v = [1, 801],
);
# ## Run sim
s = cached(sim, [p.sim]);
s = augment_simdata(s, p);
# ## Connection stats
# conn matrix is [from, to].
#
# So one row is all outputs of one neuron.
#
# Summing over cols i.e. dim two gives num outputs.
num_out = count(s.is_connected, dims=2)
num_in = vec(count(s.is_connected, dims=1));
using PyPlot
using VoltoMapSim.Plot
ydistplot("Num out" => num_out, "Num in" => num_in);
# Sure yes, 40 = 1000 * 0.04.
# Median is a bit lower than that as we post-hoc deleted the self connections.
# ## Export & draw graphs
# Let's export to Graphviz dot, to explore viz options with Gephi.
lines = ["digraph {"]
for id in s.neuron_IDs
outputs = join(s.output_neurons[id], ", ")
type = s.neuron_type[id]
push!(lines, " $(id) [type = $(type)]")
push!(lines, " $(id) -> {$(outputs)}")
end
push!(lines, "}")
dot = join(lines, "\n")
lines[[1:5; end-2:end]]
open(joinpath(homedir(), ".phdcache", "graph.dot"), "w") do io
println(io, dot)
end
# Nice! Graphviz, fun.
# ![](images/gephi.png)
# All 1000 neurons are drawn (inhibitory in red). The highlighted neurons are the inputs and outputs of one neuron.
# Now I want only a subset of the net.
# Say: 1, 801, and their inputs and outputs.
lines = ["digraph {"]
for m in [1, 801]
t = s.neuron_type[m]
push!(lines, " $m [type = $t]")
for n in s.input_neurons[m]
t = s.neuron_type[n]
push!(lines, " $n [type = $t]")
push!(lines, " $n -> $m")
end
for n in s.output_neurons[m]
t = s.neuron_type[n]
push!(lines, " $n [type = $t]")
push!(lines, " $m -> $n")
end
end
push!(lines, "}")
open(joinpath(homedir(), ".phdcache", "graph.dot"), "w") do io
println(io, join(lines, "\n"))
end
# Seems like gephi can't handle `{…} -> ` format alas. So all inputs on sep line.
# ![](images/gephi-1-801.png)
# (Yifan Hu layout with default settings)
# So these two random neurons have 7 disynaptic connections between them:
# 2 from the exc (`1`, left) to the inh (`801`, right); and 5 from the inh to the exc. All 7 pass through an excitatory neuron.
# Same but using graphviz as layouter:
# ![](images/graphviz-1-801.svg)
# (Open in new tab to see full size).
# ## Inputs only
# Above has inputs and outputs. What if we export: inputs to both neurons, and inputs to these inputs.
# I should have a function that does this the graphviz.dot file generation..
# What's its inputs. Let's say (m => n) pairs.
function gen_dot_file(edges, s; dir=joinpath(homedir(), ".phdcache"), filename="graph.dot")
nodes = Set()
lines = ["digraph {"] # DIrected graph
for (m, n) in edges
push!(nodes, m, n)
push!(lines, " $m -> $n")
end
for n in sort!(collect(nodes))
t = s.neuron_type[n]
c = (t == :exc) ? "#3fb17d" : "#ee7993"
push!(lines, " $n [type = $t, color = \"$c\"]")
end
push!(lines, "}")
open(joinpath(dir, filename), "w") do io
println(io, join(lines, "\n"))
end
end;
edges = []
n = 1
for m in s.input_neurons[n]
push!(edges, m => n)
for l in s.input_neurons[m]
push!(edges, l => m)
end
end
gen_dot_file(edges, s)
# This of just the inputs to the inputs of one neuron contains already 770 neurons, i.e. almost all 1000 of them.
# Visualizing it is not very helpful, except for showing that the direct inputs are strongly interconnected (Yifan Hu layout, default gephi params):
# ![](images/gephi-in-to-in.png)
# With direct inputs to neuron `1` highlighted:
# ![](images/gephi-in-to-in-high.png)
# Most of the neurons in the tangle in the middle are neurons that connect to multiple (2 to 5) direct inputs of `1`.