Code needed to report average membrane potential of neural group

I am working with a network of excitatory pyramidal (PYR) and inhibitory (PVN) neurons. The model is working fine. But I wish to additionally measure the average membrane potential of the PYR group as a surrogate for estimating field potential fluctuations. I added one line of code:

PYRvoltage_average = np.mean(PYR_v, axis=0)

But despite reading up on this for awhile, I continue to get error messages. I appreciate any help solving this problem

Minimal code to reproduce problem

PYR_v = StateMonitor(PYR,'v',record = True)
PYRvoltage_average = np.mean(PYR_v, axis=0)

Full traceback of error

TypeError                                 Traceback (most recent call last)
Cell In[247], line 53
     50 PYRspike_data.to_csv('PYRspikedata.csv', index=False)
     51 #PYRvoltage_data=PYR_v.v
     52 #np.save('PYRvoltage_data.npy',PYRvoltage_data)
---> 53 PYRvoltage_average = np.mean(PYR_v, axis=0)

File ~\AppData\Local\Programs\Python\Python310\lib\site-packages\numpy\core\fromnumeric.py:3504, in mean(a, axis, dtype, out, keepdims, where)
   3501     else:
   3502         return mean(axis=axis, dtype=dtype, out=out, **kwargs)
-> 3504 return _methods._mean(a, axis=axis, dtype=dtype,
   3505                       out=out, **kwargs)

File ~\AppData\Local\Programs\Python\Python310\lib\site-packages\numpy\core\_methods.py:118, in _mean(a, axis, dtype, out, keepdims, where)
    115         dtype = mu.dtype('f4')
    116         is_float16_result = True
--> 118 ret = umr_sum(arr, axis, dtype, out, keepdims, where=where)
    119 if isinstance(ret, mu.ndarray):
    120     with _no_nep50_warning():

TypeError: unsupported operand type(s) for +: 'StateMonitorView' and 'StateMonitorView'

Another surrogate to field potential would be to report the average PYR IPSCs, EPSCs, or both combined. But this presents the same coding problem as for reporting average Vm.

Hello, Marcel. I only just saw that you had addressed the coding of average values within a neuron group in an April 2022 post. I will attempt to implement this. Thank you!

Hi @MitchG_HunterCollege The post you are referencing was about only recording the average value – if the average value is all you need, this would indeed be a good option, since it would not waste memory. But calculating the average after recording all values is possible as well, of course. In your code, you are getting an error since you are trying to take the mean of the whole monitor (PYR_v), instead of the recorded membrane potential (PYR_V.v).

PS: I edited your post for better formatting, so that it is easier to read. You can format code our output by enclosing it in triple backticks like this:

```
print("Python code")
```

Alternatively, you can use the “Preformatted Text” button in the editor (or press Cmd+e).

Hello, Marcel
I apologize for continual questions which reflect my ignorance with brian/python coding. I am trying to (1) calculate, (2) plot out, and (3) save as an excel-compatible data array the average membrane potential of neurons in a PYR group during a simulation run. Your prior advice enabled me to create the mean voltage over time (I believe this was correctly created, since there wasn’t an error message). However, I am unable to figure out how to plot the time vs average voltage.

Here is my relevant code:

defaultclock.dt = 0.01*ms
PYR = NeuronGroup(2000, model=eqs_pyr, reset=reset, threshold='v >= vpeak', method = 'euler')
PYR_v = StateMonitor(PYR,'v',record = True)
PYRvoltage_average = np.mean(PYR_v.v, axis=0)
duration = 3 * second

plt.figure(0)
plt.plot(PYR_v.t/ms,PYRvoltage_average.v/mV)
plt.xlabel("Time (ms)")
plt.ylabel("PYR Average Membrane Potential (mV)")
plt.title('PYR network Average Vm')
plt.show()

I get this error message for the plot module:

AttributeError                            Traceback (most recent call last)
Cell In[64], line 243
    242 plt.figure(30)
--> 243 plt.plot(PYR_v.t/ms,PYRvoltage_average.v/mV)
    244 plt.xlabel("Time (ms)")
    245 plt.ylabel("PYR Average Membrane Potential (mV)")
AttributeError: 'Quantity' object has no attribute 'v'

If I change to:

plt.plot(PYR_v.t/ms,PYRvoltage_average/mV)

I get different error:

ValueError                                Traceback (most recent call last)
Cell In[77], line 243
    241 #plot average membrane potential of PYR1 to PYR20
    242 plt.figure(30)
--> 243 plt.plot(PYR_v.t/ms,PYRvoltage_average/mV)
    244 plt.xlabel("Time (ms)")
    245 plt.ylabel("PYR Average Membrane Potential (mV)")
ValueError: x and y must have same first dimension, but have shapes (300000,) and (0,)

Hi @MitchG_HunterCollege ,
After you take the average with np.mean, you have a Quantity (equivalent of a numpy array, but with unit information attached). This object does not have an attribute v (as the error message states) you can plot it directly.

Regarding the second error: this looks as if you took the average before running the simulation, which means that PYRvoltage_average is empty. You need to first run the simulation to have PYR_v record the v values, and then you can take the average of these values. Here’s a simplified variant of your code that shows this in action:

from brian2 import *

defaultclock.dt = 0.01*ms
tau = 10*ms
eqs_pyr = "dv/dt = 1*mV*xi*tau**-0.5 : volt"  # Random walk instead of real neuron model
PYR = NeuronGroup(20, model=eqs_pyr, method = 'euler')
PYR_v = StateMonitor(PYR,'v',record = True)

duration = 3 * second
run(duration)

PYRvoltage_average = np.mean(PYR_v.v, axis=0)
print(type(PYRvoltage_average))
plt.figure(0)
for idx in range(5):  # Add five example traces
    plt.plot(PYR_v.t/ms,PYR_v.v[idx]/mV, lw=0.5, color='gray')
plt.plot(PYR_v.t/ms,PYRvoltage_average/mV, lw=2)
plt.xlabel("Time (ms)")
plt.ylabel("PYR Average Membrane Potential (mV)")
plt.title('PYR network Average Vm')
plt.show()

Hi, Marcel. Now this works! I also successfully created an average IPSC across the PYR network, which is the best correlate to field potential. Thanks again very much! Mitch

1 Like

Hi again, Marcel. I would still like additionally to save the averaged voltage and ipsc among the PYR cells in network.
PYRvoltage_average = np.mean(PYR_v.v, axis=0)
print(type(PYRvoltage_average))
PYRipsc_average = np.mean(PYR_Isyn_i_pyr.Isyn_i_pyr, axis=0)
print(type(PYRipsc_average))

Can these be outputted to csv or other excel-compatible file format?
Thanks!

Hi @MitchG_HunterCollege . Brian’s Quantity objects are standard numpy arrays with additional unit information, so you can also use standard numpy tools to save them to a file. For example, to create a csv file you could use the numpy.savetxt function:

np.savetxt('averages.csv',
           np.column_stack((PYRvoltage_average, PYRipsc_average)),
           delimiter=',', header='PYRvoltage,PYRipsc')

Note that the values will be in the base unit (in this case, I assume volt and amp). If you wanted to save them in, say, mV and nA, you’d divide them by those units first, i.e. use:

np.savetxt('averages.csv',
           np.column_stack((PYRvoltage_average/mV, PYRipsc_average/nA)),
           delimiter=',', header='PYRvoltage,PYRipsc')