Analyze multi-compartment neuron results¶
Note
This guide is a continuation of the Simulation guide.
After a simulation, BSB will write its outcomes in .nio
files. These files leverage the HDF5
(Hierarchical Data Format version 5) format, which is widely employed in scientific computing,
engineering, and data analysis. HDF5 files store data in groups (or blocks), in a dictionary
fashion, which allows for efficient management and organization of large datasets.
The content is read/written using the Neo Python package, a library designed for handling electrophysiology data.
In our case, we have only one block
of data since we only ran one simulation. We also have a
unique segment
since all our data is recorded with the same time frame (see
Neo docs for more details).
Let’s extract the simulation block data produced by your last simulation. First, load the content from
your simulation-results/NAME_OF_YOUR_NEO_FILE.nio
file, use the following code:
from neo import io
# Read simulation data
my_file_name = "simulation-results/NAME_OF_YOUR_NEO_FILE.nio"
sim = io.NixIO(my_file_name, mode="ro")
block = sim.read_all_blocks()[0]
segment = block.segments[0]
my_signals = segment.analogsignals
If you followed the previous simulation example, the analogsignals attribute in the block should contain a list of all measured signals: the membrane potential recorded by the vrecorder device and the synapse current obtained from the synapses_rec device.
Each AnalogSignal
object contains information about the device name,
the sampling rate, and an array of the simulated measurement values.
Additional information is available through the annotations attribute.
import matplotlib.pylab as plt # you might have to pip install matplotlib
has_plotted_neuron = False # We will only plot one neuron recording here
has_plotted_synapse = False # We will only plot one synapse recording here
for signal in my_signals:
name_device = signal.name # Retrieve the name of the device
cell_id = signal.annotations["cell_id"] # Retrieve the cell ID
# If the signal comes from a synapse recorder,
# and if we did not plot a synapse recording yet
if name_device == "synapses_rec" and not has_plotted_synapse:
synapse_type = signal.annotations["synapse_type"]
out_filename = (
f"simulation-results/{name_device}_{str(cell_id)}_{synapse_type}.png"
)
has_plotted_synapse = True
# If the signal comes from a voltage recorder,
# and if we did not plot a neuron recording yet
elif name_device == "vrecorder" and not has_plotted_neuron:
out_filename = f"simulation-results/{name_device}_{str(cell_id)}.png"
has_plotted_neuron = True
# If we plotted both types of recording, we exit the loop
elif has_plotted_neuron and has_plotted_synapse:
break
# We still have some plotting to do
else:
continue
sim_time = signal.times # Time points of simulation recording
# Plot and save figure to file in images folder
plt.figure()
plt.xlabel(f"Time ({signal.times.units.dimensionality.string})")
plt.ylabel(f"{signal.units.dimensionality.string}")
plt.plot(sim_time, signal.magnitude)
plt.savefig(out_filename, dpi=200)
This code generates 2 plots: one for a postsynaptic synapse and one for the membrane
potential. The resulting figures are saved in the simulation-results
folder.
Here are some example of the figures that are produced:

Example of the membrane potential recorded.¶

Example of the AMPA synapse current recoded.¶
Next steps: