Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
6fe2e9a
Updated drawing of network (network_status_graph.py; vertically cente…
igorpodolak Mar 20, 2020
d5df424
"selection of output in record.py"
igorpodolak Mar 22, 2020
2ddc41c
Merge branch 'master' of https://github.com/ziemowit-s/neuronpp into …
igorpodolak Mar 22, 2020
e5fe31f
"centered display of graph in network_status_graph.py; selection of o…
igorpodolak Mar 23, 2020
4fb520f
Display of true/predicted classes in record.py; true_labels added as …
igorpodolak Mar 24, 2020
7758ed8
"class labels passed to record:plot() --> plot_animate()"
igorpodolak Mar 25, 2020
06fc25d
Merge remote-tracking branch 'origin/master' into models_igr
igorpodolak Mar 26, 2020
3ed9930
Plotting of outputs: record.py: true_labels added; names changed
igorpodolak Mar 26, 2020
c8fb1e2
record.py: namedtuple as parameter method
igorpodolak Mar 27, 2020
597409e
record.py: simulation parameters to _plot_animate passed with a named…
igorpodolak Mar 27, 2020
cf742d9
minor errors (due to tragic namedtuple
igorpodolak Mar 27, 2020
ef7ae7f
Merge remote-tracking branch 'origin/models_igr'
ziemowit-s Mar 27, 2020
79f38d8
fixed Record to work with markers, not work yet
ziemowit-s Mar 27, 2020
34a7336
Corrected errors in record.py; changed its parameters a bit
igorpodolak Mar 27, 2020
387e21a
Merge remote-tracking branch 'origin/models_igr' into models_igr
igorpodolak Mar 27, 2020
f2d346e
minor errors in record.py, plot_animate()
igorpodolak Mar 27, 2020
8411e81
minor errors in inheritance in record.py
igorpodolak Mar 27, 2020
2ca9dec
Merge remote-tracking branch 'origin/master' into models_igr
ziemowit-s Apr 2, 2020
be385e8
changes to Record
ziemowit-s Apr 2, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions neuronpp/utils/network_status_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ def __init__(self, cells, weight_name='w', plot_fixed_weight_edges=True):

self.correct_position = (0.1, 0.1)

self.population_sizes = dict()
self.population_names = self._get_population_names()
self.edges = self._get_edges(weight_name)

Expand Down Expand Up @@ -69,6 +70,10 @@ def update_spikes(self, sim_time):

def _get_edges(self, weight_name):
result = []
# compute the number of cells in each layer
for c in self.cells:
pop_name = c.name.split('[')[0]
self.population_sizes[pop_name] = self.population_sizes.get(pop_name, 0) + 1
for c in self.cells:
soma = c.filter_secs('soma')
if c._spike_detector is None:
Expand All @@ -81,11 +86,13 @@ def _get_edges(self, weight_name):
except ValueError:
x_pos = self.population_names.index(pop_name)

y_pos = int(split_name[-1][:-1])
# shift down the layer by half its size to vertically center graph
y_pos = int(split_name[-1][:-1]) - self.population_sizes[pop_name] // 2

if 'inh' in c.name:
self.colors.append('red')
y_pos -= 5
# todo center vertically by half width of the hid layer
y_pos -= 6
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was original idea how to present plot but now I think it was bad idea to manually shift it like this. But it maybe as it is

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Problem w linii 95 z rzeczywistym przesunięciem polega na znalezieniu nazwy warstwy poprzedzającej. Jeśli jest nią 'hid_1' to wtedy może być przez

Suggested change
y_pos -= 6
y_pos -= self.population_sizes['hid_1'] // 2 + self.population_sizes[pop_name]

elif 'hid' in c.name:
self.colors.append('blue')
else:
Expand All @@ -110,7 +117,8 @@ def _find_target(self, c, x_pos, y_pos, weight_name):
except ValueError:
x_trg = self.population_names.index(pop_name)

y_trg = int(split_target[-1][:-1])
# center veritically
y_trg = int(split_target[-1][:-1]) - self.population_sizes[pop_name] // 2

weight = None
if self.plot_constant_connections and hasattr(nc.target.hoc, weight_name):
Expand All @@ -125,7 +133,8 @@ def _find_weights(c, weight_name):
for nc in c.ncs:
if "SpikeDetector" in nc.name:
continue
elif isinstance(nc.source, Seg) and isinstance(nc.target, PointProcess) and hasattr(nc.target.hoc, weight_name):
elif isinstance(nc.source, Seg) and isinstance(nc.target, PointProcess) and hasattr(nc.target.hoc,
weight_name):
weight = getattr(nc.target.hoc, weight_name)
targets.append(weight)
return targets
Expand Down
52 changes: 40 additions & 12 deletions neuronpp/utils/record.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
from nrn import Segment, Section
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this concept of recording with labels should be moved to separated class which inherits from Record, eg. RecordWithLabels. In this case - dt and true_labels params from the _plot_animate() metod can be moved into consructor.

from collections import defaultdict

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from neuron import h
import matplotlib.pyplot as plt

from neuronpp.core.hocwrappers.seg import Seg


Expand Down Expand Up @@ -39,7 +37,8 @@ def __init__(self, elements, variables='v'):
try:
s = getattr(elem.hoc, "_ref_%s" % var)
except AttributeError:
raise AttributeError("there is no attribute of %s. Maybe you forgot to append loc param for sections?" % var)
raise AttributeError(
"there is no attribute of %s. Maybe you forgot to append loc param for sections?" % var)

rec = h.Vector().record(s)
self.recs[var].append((name, rec))
Expand Down Expand Up @@ -84,16 +83,19 @@ def _plot_static(self, position=None):
for i, (name, rec) in enumerate(section_recs):
rec_np = rec.as_numpy()
if np.max(np.isnan(rec_np)):
raise ValueError("Vector recorded for variable: '%s' and segment: '%s' contains nan values." % (var_name, name))
raise ValueError(
"Vector recorded for variable: '%s' and segment: '%s' contains nan values." % (var_name, name))

if position is not "merge":
ax = self._get_subplot(fig=fig, var_name=var_name, position=position, row_len=len(section_recs), index=i + 1)
ax = self._get_subplot(fig=fig, var_name=var_name, position=position, row_len=len(section_recs),
index=i + 1)
ax.set_title("Variable: %s" % var_name)
ax.plot(self.t, rec, label=name)
ax.set(xlabel='t (ms)', ylabel=var_name)
ax.legend()

def _plot_animate(self, steps=10000, y_lim=None, position=None):
def _plot_animate(self, steps=10000, y_lim=None, position=None, true_class=None, pred_class=None, stepsize=None,
dt=None):
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you add new params to the method with docstring - please add docstring as well for them

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

"""
Call each time you want to redraw plot.

Expand Down Expand Up @@ -125,13 +127,14 @@ def _plot_animate(self, steps=10000, y_lim=None, position=None):
if position == 'merge':
ax = fig.add_subplot(1, 1, 1)
else:
ax = self._get_subplot(fig=fig, var_name=var_name, position=position, row_len=len(section_recs), index=i + 1)
ax = self._get_subplot(fig=fig, var_name=var_name, position=position, row_len=len(section_recs),
index=i + 1)

if y_lim:
ax.set_ylim(y_lim[0], y_lim[1])
line, = ax.plot([], lw=1)
ax.set_title("Variable: %s" % var_name)
ax.set_ylabel(var_name)
# ax.set_title("Variable: %s" % var_name)
ax.set_ylabel("{}_{}".format(var_name, i))
ax.set_xlabel("t (ms)")
ax.legend()

Expand All @@ -143,17 +146,42 @@ def _plot_animate(self, steps=10000, y_lim=None, position=None):

ax.set_xlim(t.min(), t.max())
if y_lim is None:
ax.set_ylim(r.min()-(np.abs(r.min()*0.05)), r.max()+(np.abs(r.max()*0.05)))
ax.set_ylim(r.min() - (np.abs(r.min() * 0.05)), r.max() + (np.abs(r.max() * 0.05)))

# update data
line.set_data(t, r)

# info draw triangles for true and predicted classes
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be parametrize from top -> plot() function, to set or no this drawing (as optional)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I shall an an option

true_x, true_y, pred_x, pred_y = self._class_tcks(label=i, true_class=true_class, pred_class=pred_class,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i is not a label. It is an enumerator of sections to records with the same variable name (eg. v)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this is an error here, or rather it is used in assumption that labels are 0, 1, 2, ... They need not to be. I shall pass a table of class_names as parameter, consistent with enumeration, and then see line in line 177 we shall have
if true_class[k] == class_names[label], and similarly in 179: if pred_class == true_classes[label]

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i represents number of segment saved to be recorded. If you want to record from 5 neurons - 2 input, 3 output in the same Record object - you can. So in this case i won't represent any true values, but rather enumerator.

I think you should add parameter to the Record object to show predicted/true values, but it must be done explicitely as optional param: in the constructor or in the plotting method. Because otherwise it is extremelly error prone.

t=t, r=r, stepsize=stepsize, dt=dt)
ax.scatter(true_x, true_y, c="orange", marker="^", alpha=0.95)
ax.scatter(pred_x, pred_y, c="magenta", marker="v", alpha=0.95)

# info join plots by removing labels and ticks from subplots that are not on the edge
for key in self.axs:
for ax in self.axs[key]:
ax[0].label_outer()
fig.subplots_adjust(left=0.09, bottom=0.075, right=0.99, top=0.98, wspace=None, hspace=0.00)
fig.canvas.draw()
fig.canvas.flush_events()

if create_fig:
plt.show(block=False)

def _class_tcks(self, label, true_class, pred_class, t, r, stepsize, dt):
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

write full name of the function

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, how about

Suggested change
def _class_tcks(self, label, true_class, pred_class, t, r, stepsize, dt):
def _draw_true_predicted_class_marks(self, label, true_class, pred_class, t, r, stepsize, dt):

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it works for me

n = len(true_class)
x = t[::int(2 * stepsize / dt)][-n:]
true_x = []
pred_x = []
for k in range(n):
# get the true classes for the current label
if true_class[k] == label:
true_x.append(x[k])
if pred_class[k] == label:
pred_x.append(x[k])
true_y = [min(r) + 2] * len(true_x)
pred_y = [max(r) - 2] * len(pred_x)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to find better true_y (position of lower triangle) and red_y (position of upper one). All goes well as long as the motor neurone are activated.

return true_x, true_y, pred_x, pred_y

def to_csv(self, filename):
cols = ['time']
data = [self.t.as_numpy().tolist()]
Expand Down