For Loops and Trial Averaged Frequency Spectra
Authors
In this notebook, you will learn how to apply frequency analysis methods to real LFP and spike data.
Setup
Import Libraries
import xarray as xr
from pathlib import Path
import numpy as np
import matplotlib.pyplot as plt
from scipy import signal
from nitime.algorithms import multi_taper_psdDownload Dataset
import owncloud
owncloud.Client.from_public_link('https://uni-bonn.sciebo.de/s/M56DCkpyCJ9FRoi', folder_password="ibots"
).get_file('/', 'dataset_session_754312389.nc')TrueSection 1: Calculating Trial Averaged Frequency Spectra
To reduce the prominence of noise in our results, we often calculate the average across multiple trials. When your data from each trial or channel is of the same length, you can simply apply the functions to compute the power spectra directly to the data and you will get spectra calculated for each trial and channel (or cells, in the case of spike data) organized the same way as your original data.
| Code | Description |
|---|---|
freqs, power_density = signal.welch(data, fs = sampling_frequency) |
Calculate the power spectral density using Welch’s method |
plt.pcolormesh(x, y, C, cmap = 'plasma', shading = 'gouraud') |
Make a 2D colormap of values in a 2D array (C) against x and y values. The optional parameters cmap and shading defines the colormap and the interpolation applied to the plot, respectively. |
np.mean(data, axis = (dim_num1, dim_num2)) or data.mean(axis = dim_num1, dim_num2) |
Calculate the average of the data across both the dim_num1 and the dim_num2 dimensions of the array. |
plt.plot(x, y) |
Plot y values against x values. |
plt.semilogx(x, y) |
Plot y values against x values with a logarithmic x-axis and linear y-axis. |
plt.semilogy(x, y) |
Plot y values against x values with a logarithmic y-axis and a linear x-axis. |
plt.loglog(x, y) |
Plot y values against x values with logarithmic x- and y-axis. |
plt.xlim([some_lower_xlim, some_upper_xlim]) |
Limit the x-axis in a plot to be between the numbers some_lower_xlim and some_upper_xlim. |
np.arange(start, stop, step) |
Makes an array with all the integers between two values, with a given spacing |
Load dataset
Run cells below to load dataset and extract relevant data
Exercises
loadpath = 'dataset_session_754312389.nc'
dataset_path = Path(loadpath)
dataset = xr.load_dataset(dataset_path)
dataset<xarray.Dataset> Size: 225MB
Dimensions: (channel_depth: 23, trial_nr: 75, time_lfp: 1875,
time_csd: 1875, time_whole_rec_lfp: 373124,
time_whole_rec_ecp: 373124, unit_id_LGN: 27,
time_spikes: 1500, unit_id_V1: 91, unit_id_LM: 13,
stimulus_start_times: 75, stimulus_stop_times: 75,
channel_id: 23)
Coordinates: (12/13)
* channel_depth (channel_depth) int64 184B 0 -40 -80 ... -840 -880
* trial_nr (trial_nr) int32 300B 0 1 2 3 4 5 ... 70 71 72 73 74
* time_lfp (time_lfp) float64 15kB -1e+03 -999.2 ... 499.2
* time_csd (time_csd) float64 15kB -1e+03 -999.2 ... 499.2
* time_whole_rec_lfp (time_whole_rec_lfp) float64 3MB 1.286e+06 ... 1....
* time_whole_rec_ecp (time_whole_rec_ecp) float64 3MB 1.286e+06 ... 1....
... ...
* time_spikes (time_spikes) float64 12kB -999.5 -998.5 ... 499.5
* unit_id_V1 (unit_id_V1) int32 364B 951795075 ... 951798053
* unit_id_LM (unit_id_LM) int32 52B 951791074 ... 951792163
* stimulus_start_times (stimulus_start_times) float64 600B 1.29e+06 ... ...
* stimulus_stop_times (stimulus_stop_times) float64 600B 1.29e+06 ... 1...
* channel_id (channel_id) int32 92B 850144538 ... 850144362
Data variables:
lfp_V1 (channel_depth, trial_nr, time_lfp) float64 26MB ...
csd_V1 (channel_depth, trial_nr, time_csd) float64 26MB ...
lfp_whole_recording_V1 (channel_depth, time_whole_rec_lfp) float64 69MB ...
ecp_whole_recording_V1 (channel_depth, time_whole_rec_ecp) float64 69MB ...
spike_counts_LGN (unit_id_LGN, trial_nr, time_spikes) int16 6MB 0 ...
spike_counts_V1 (unit_id_V1, trial_nr, time_spikes) int16 20MB 0 ...
spike_counts_LM (unit_id_LM, trial_nr, time_spikes) int16 3MB 0 ....
pupil_width (trial_nr) float64 600B 39.12 40.53 ... 46.57 44.31
run_speed (trial_nr) float64 600B 1.155 1.597 ... 1.251 1.711
Attributes:
time_unit: millisecond
lfp_unit: Volt
channel_depth_unit: micrometer
note_channel_depth: Measured in distance from electrode closest t...
sampling_frequency_lfp: 1250
sampling_frequency_spikes: 1000
sampling_frequency_unit: Hz
stimulus_onset: 1000
stimulus_offset: 1250- channel_depth: 23
- trial_nr: 75
- time_lfp: 1875
- time_csd: 1875
- time_whole_rec_lfp: 373124
- time_whole_rec_ecp: 373124
- unit_id_LGN: 27
- time_spikes: 1500
- unit_id_V1: 91
- unit_id_LM: 13
- stimulus_start_times: 75
- stimulus_stop_times: 75
- channel_id: 23
- channel_depth(channel_depth)int640 -40 -80 -120 ... -800 -840 -880
array([ 0, -40, -80, -120, -160, -200, -240, -280, -320, -360, -400, -440, -480, -520, -560, -600, -640, -680, -720, -760, -800, -840, -880]) - trial_nr(trial_nr)int320 1 2 3 4 5 6 ... 69 70 71 72 73 74
array([ 0, 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], dtype=int32) - time_lfp(time_lfp)float64-1e+03 -999.2 ... 498.4 499.2
array([-1000. , -999.2, -998.4, ..., 497.6, 498.4, 499.2])
- time_csd(time_csd)float64-1e+03 -999.2 ... 498.4 499.2
array([-1000. , -999.2, -998.4, ..., 497.6, 498.4, 499.2])
- time_whole_rec_lfp(time_whole_rec_lfp)float641.286e+06 1.286e+06 ... 1.584e+06
array([1285609.738645, 1285610.538645, 1285611.338645, ..., 1584106.565384, 1584107.365384, 1584108.165384]) - time_whole_rec_ecp(time_whole_rec_ecp)float641.286e+06 1.286e+06 ... 1.584e+06
array([1285609.738645, 1285610.538645, 1285611.338645, ..., 1584106.565384, 1584107.365384, 1584108.165384]) - unit_id_LGN(unit_id_LGN)int32951782498 951782516 ... 951798528
array([951782498, 951782516, 951782530, 951782631, 951782683, 951782699, 951782744, 951782795, 951782832, 951782895, 951787033, 951792341, 951792375, 951792398, 951792418, 951792441, 951792504, 951792544, 951797077, 951798318, 951798391, 951798404, 951798553, 951798681, 951801317, 951798434, 951798528], dtype=int32) - time_spikes(time_spikes)float64-999.5 -998.5 ... 498.5 499.5
array([-999.5, -998.5, -997.5, ..., 497.5, 498.5, 499.5])
- unit_id_V1(unit_id_V1)int32951795075 951795086 ... 951798053
array([951795075, 951795086, 951795098, 951795140, 951795163, 951795222, 951795238, 951795256, 951795269, 951795290, 951795309, 951795317, 951795403, 951797419, 951795458, 951795474, 951795487, 951795495, 951795554, 951795680, 951795563, 951795611, 951795663, 951795688, 951795706, 951795713, 951795721, 951797465, 951795729, 951795737, 951795747, 951795873, 951795753, 951795782, 951795792, 951795760, 951795768, 951795775, 951795807, 951795824, 951795832, 951795839, 951795858, 951795880, 951795886, 951795896, 951795918, 951797520, 951797539, 951797553, 951795936, 951795943, 951795967, 951795976, 951797567, 951797489, 951796016, 951796073, 951796125, 951796165, 951796176, 951796229, 951797633, 951796333, 951797647, 951797664, 951796352, 951796494, 951797718, 951796542, 951796556, 951797730, 951796585, 951797742, 951796629, 951796639, 951796660, 951796696, 951796791, 951797776, 951796866, 951796906, 951796928, 951796949, 951797595, 951797613, 951797709, 951797764, 951797811, 951797995, 951798053], dtype=int32) - unit_id_LM(unit_id_LM)int32951791074 951791093 ... 951792163
array([951791074, 951791093, 951791202, 951791214, 951791273, 951791305, 951791297, 951791401, 951791422, 951791467, 951791442, 951791453, 951792163], dtype=int32) - stimulus_start_times(stimulus_start_times)float641.29e+06 1.294e+06 ... 1.584e+06
array([1289613.25125, 1293616.60125, 1299621.62125, 1301623.29125, 1303624.97125, 1307628.33125, 1309629.95125, 1319638.32125, 1329646.71125, 1333650.07125, 1337653.40125, 1341656.74125, 1351665.05125, 1357670.12125, 1361673.43125, 1371681.84125, 1373683.47125, 1375685.17125, 1383691.83125, 1387695.15125, 1397703.53125, 1401706.88125, 1403708.58125, 1407711.93125, 1411715.25125, 1413716.94125, 1415718.63125, 1417720.26125, 1419721.95125, 1421723.62125, 1423725.25125, 1427728.62125, 1429730.28125, 1431731.94125, 1433733.62125, 1435735.32125, 1441740.33125, 1447745.31125, 1451748.67125, 1459755.38125, 1461757.06125, 1467762.05125, 1473767.09125, 1481773.75125, 1485777.10125, 1489780.46125, 1491782.12125, 1493783.81125, 1497787.16125, 1501790.48125, 1503792.14125, 1505793.80125, 1511798.87125, 1515802.17125, 1517803.89125, 1519805.55125, 1521807.23125, 1529813.91125, 1531815.57125, 1533817.23125, 1537820.57125, 1541823.93125, 1543825.60125, 1545827.30125, 1547828.93125, 1551832.29125, 1553833.96125, 1563842.35125, 1565843.99125, 1569847.35125, 1571849.02125, 1573850.69125, 1575852.34125, 1577854.07125, 1583859.05125]) - stimulus_stop_times(stimulus_stop_times)float641.29e+06 1.294e+06 ... 1.584e+06
array([1289863.450591, 1293866.800591, 1299871.820591, 1301873.490591, 1303875.173091, 1307878.525591, 1309880.158091, 1319888.525591, 1329896.908091, 1333900.265591, 1337903.598091, 1341906.940591, 1351915.258091, 1357920.320591, 1361923.638091, 1371932.033091, 1373933.675591, 1375935.370591, 1383942.035591, 1387945.363091, 1397953.738091, 1401957.083091, 1403958.778091, 1407962.128091, 1411965.450591, 1413967.138091, 1415968.823091, 1417970.465591, 1419972.150591, 1421973.823091, 1423975.460591, 1427978.823091, 1429980.490591, 1431982.153091, 1433983.830591, 1435985.523091, 1441990.535591, 1447995.523091, 1451998.875591, 1460005.585591, 1462007.260591, 1468012.260591, 1474017.293091, 1482023.960591, 1486027.308091, 1490030.665591, 1492032.325591, 1494034.013091, 1498037.360591, 1502040.685591, 1504042.350591, 1506044.010591, 1512049.070591, 1516052.383091, 1518054.088091, 1520055.753091, 1522057.428091, 1530064.110591, 1532065.775591, 1534067.438091, 1538070.778091, 1542074.135591, 1544075.808091, 1546077.498091, 1548079.138091, 1552082.495591, 1554084.165591, 1564092.550591, 1566094.193091, 1570097.553091, 1572099.225591, 1574100.895591, 1576102.553091, 1578104.268091, 1584109.255591]) - channel_id(channel_id)int32850144538 850144530 ... 850144362
array([850144538, 850144530, 850144522, 850144514, 850144506, 850144498, 850144490, 850144482, 850144474, 850144466, 850144458, 850144450, 850144442, 850144434, 850144426, 850144418, 850144410, 850144402, 850144394, 850144386, 850144378, 850144370, 850144362], dtype=int32)
- lfp_V1(channel_depth, trial_nr, time_lfp)float64-8.516e-06 -1.156e-05 ... 6.131e-06
array([[[-8.51569421e-06, -1.15631923e-05, -3.76924291e-07, ..., -2.17654367e-06, 1.68119712e-07, -6.94200500e-06], [ 2.81771330e-08, 6.29403676e-06, 9.98029865e-06, ..., 1.01304291e-05, 5.93295341e-06, 1.72969475e-05], [-1.27271427e-06, -3.68783112e-06, -4.46340366e-06, ..., 3.65666426e-06, 2.96670978e-06, 1.24568597e-06], ..., [ 4.70565253e-06, 1.94317598e-06, 1.20455675e-06, ..., 4.07503496e-06, 7.65054254e-06, 3.91673831e-06], [ 8.38144661e-07, 2.28123812e-06, 3.70896321e-06, ..., 1.34013793e-05, 1.15462596e-05, 8.42411093e-06], [ 7.32479652e-06, 1.07711181e-06, 7.00885884e-06, ..., 1.92065863e-05, 1.92065863e-05, 1.92065863e-05]], [[ 3.91952787e-06, 1.70056905e-06, 5.97275690e-06, ..., 4.06974274e-06, 4.04094749e-06, -4.68055730e-06], [-4.10311367e-06, 5.00856269e-06, 6.20500275e-06, ..., 8.75868311e-06, 5.69604080e-06, 8.57744575e-06], [ 1.09646506e-06, 1.62070262e-06, 1.10953040e-07, ..., 1.01990671e-05, -8.36754580e-06, -1.43387447e-05], ... [-6.46738552e-06, -1.19701456e-05, -2.41882630e-05, ..., -2.31175915e-05, -2.37374262e-05, -7.53926446e-06], [ 2.91850049e-05, 2.81713398e-05, 5.17618757e-05, ..., 4.44764295e-05, 4.08778688e-05, 3.83233192e-05], [-1.80642354e-05, -1.06068608e-05, -3.71177368e-06, ..., 1.48063260e-05, 1.48063260e-05, 1.48063260e-05]], [[ 4.42062699e-05, 5.99208645e-05, 7.60618853e-05, ..., 9.85508013e-05, 8.87923195e-05, 8.02998878e-05], [-6.30930699e-06, 2.14882295e-05, 5.40961203e-06, ..., -6.18517313e-05, -8.49961217e-05, -7.07025406e-05], [ 1.32347041e-04, 9.66830285e-05, 9.77152893e-05, ..., -3.68393584e-05, -2.08663734e-05, -1.27901811e-05], ..., [ 7.59530363e-07, -9.00525049e-06, -1.95382678e-05, ..., -2.78150664e-05, -1.46349189e-05, 3.65395950e-06], [ 3.22381374e-05, 3.90163375e-05, 6.39709157e-05, ..., 5.17422904e-05, 4.94353600e-05, 3.90770304e-05], [-2.50190016e-05, -1.82145705e-05, -1.97245214e-05, ..., 6.13148062e-06, 6.13148062e-06, 6.13148062e-06]]]) - csd_V1(channel_depth, trial_nr, time_csd)float64-0.04729 -0.04843 ... 0.004271
array([[[-0.04729251, -0.04843248, -0.03745331, ..., -0.0506883 , -0.05553956, -0.06003479], [-0.01093619, 0.01574628, 0.00914164, ..., 0.00598613, 0.01101591, 0.03123014], [-0.03696462, -0.04099173, -0.03852095, ..., 0.00098069, -0.0050393 , -0.01264635], ..., [-0.01247878, 0.00877942, 0.02265446, ..., 0.00331111, 0.03482657, 0.01182155], [-0.00745365, -0.01184343, -0.0143719 , ..., -0.00701411, -0.00677321, 0.00801698], [-0.00185681, 0.00029347, 0.01247577, ..., 0.04692436, 0.04692436, 0.04692436]], [[-0.05243487, -0.04187987, -0.01951768, ..., 0.00767212, 0.02122529, -0.00091668], [-0.03800667, -0.0267893 , 0.00151346, ..., -0.06356118, -0.05255179, -0.02253284], [-0.13918267, -0.15069373, -0.14869443, ..., -0.08287076, -0.10533221, -0.11878146], ... [-0.0317182 , -0.0291328 , -0.04440809, ..., 0.0128667 , -0.00803555, 0.00140582], [-0.00313798, -0.02211998, 0.00973861, ..., 0.01834821, 0.02898202, 0.03053275], [ 0.01935376, 0.02458448, 0.02770717, ..., 0.0335107 , 0.0335107 , 0.0335107 ]], [[ 0.05527245, 0.06647928, 0.08365367, ..., 0.03946655, -0.00638597, 0.01617121], [ 0.00484864, 0.04955322, 0.00056809, ..., -0.02495747, -0.04720462, -0.05647099], [ 0.14248465, 0.09267001, 0.12532577, ..., -0.02102215, 0.01070787, -0.00105385], ..., [ 0.02074605, 0.01291679, -0.00810403, ..., -0.00440359, 0.01890968, 0.03686672], [-0.03145411, -0.01193072, 0.05258549, ..., 0.06270049, 0.05033156, 0.03718263], [-0.01626375, -0.00653823, -0.01209703, ..., 0.00427089, 0.00427089, 0.00427089]]]) - lfp_whole_recording_V1(channel_depth, time_whole_rec_lfp)float641.131e-05 2.316e-05 ... 6.131e-06
array([[ 1.13123117e-05, 2.31601759e-05, 2.56464473e-05, ..., 2.90957718e-05, 2.80686400e-05, 1.92065863e-05], [ 1.25864221e-05, 2.61936713e-05, 2.05721887e-05, ..., 2.51329249e-05, 1.10562717e-05, 1.14064589e-05], [ 1.06294434e-05, 1.20898434e-05, 1.05466595e-05, ..., 4.39547441e-06, 2.49921901e-06, -3.03491628e-06], ..., [-1.51105564e-05, -2.86651554e-05, -2.43583384e-05, ..., 1.55104740e-05, 1.08842192e-05, 7.88508374e-06], [-2.60411104e-05, -3.63399664e-05, -2.41173628e-05, ..., 4.57287775e-05, 2.16324211e-05, 1.48063260e-05], [-1.92918607e-05, -3.23216874e-05, -2.71540780e-05, ..., 5.95832945e-05, 2.76861759e-05, 6.13148062e-06]]) - ecp_whole_recording_V1(channel_depth, time_whole_rec_ecp)float641.131e-05 2.316e-05 ... 6.131e-06
array([[ 1.13123117e-05, 2.31601759e-05, 2.56464473e-05, ..., 2.90957718e-05, 2.80686400e-05, 1.92065863e-05], [ 1.25864221e-05, 2.61936713e-05, 2.05721887e-05, ..., 2.51329249e-05, 1.10562717e-05, 1.14064589e-05], [ 1.06294434e-05, 1.20898434e-05, 1.05466595e-05, ..., 4.39547441e-06, 2.49921901e-06, -3.03491628e-06], ..., [-1.51105564e-05, -2.86651554e-05, -2.43583384e-05, ..., 1.55104740e-05, 1.08842192e-05, 7.88508374e-06], [-2.60411104e-05, -3.63399664e-05, -2.41173628e-05, ..., 4.57287775e-05, 2.16324211e-05, 1.48063260e-05], [-1.92918607e-05, -3.23216874e-05, -2.71540780e-05, ..., 5.95832945e-05, 2.76861759e-05, 6.13148062e-06]]) - spike_counts_LGN(unit_id_LGN, trial_nr, time_spikes)int160 0 0 0 0 0 0 0 ... 1 0 0 0 0 0 0 0
array([[[0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], ..., [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0]], [[0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], ..., [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0]], [[0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], ..., ... ..., [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0]], [[0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], ..., [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0]], [[0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], ..., [0, 0, 0, ..., 0, 0, 0], [0, 1, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0]]], dtype=int16) - spike_counts_V1(unit_id_V1, trial_nr, time_spikes)int160 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0
array([[[0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], ..., [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0]], [[0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], ..., [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0]], [[0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], [0, 0, 1, ..., 0, 0, 0], ..., ... ..., [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0]], [[0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], ..., [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0]], [[0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], ..., [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0]]], dtype=int16) - spike_counts_LM(unit_id_LM, trial_nr, time_spikes)int160 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0
array([[[0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], ..., [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0]], [[0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], ..., [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0]], [[0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], ..., ... ..., [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0]], [[0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 1], ..., [0, 0, 0, ..., 0, 1, 0], [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0]], [[0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], ..., [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0]]], dtype=int16) - pupil_width(trial_nr)float6439.12 40.53 53.87 ... 46.57 44.31
array([39.11652012, 40.53014519, 53.86896327, 50.82396045, 52.16879212, 57.96043078, 54.92497335, 55.54967205, 43.90274746, 44.79854897, 38.38702834, 40.71644189, 37.98256784, 35.66463223, 33.77803219, 37.33170246, 34.40298455, 33.56487003, 34.8366242 , 34.23566353, 37.82023369, 36.64031488, 34.90016986, 34.01127022, 34.01676223, 33.07691675, 36.24898149, 34.31897366, 32.37205121, 32.29131936, 31.22026173, 32.11667831, 35.9407955 , 33.83439488, 40.32179372, 40.2773362 , 36.8416765 , 38.28154173, 32.92621992, 34.10611125, 32.64213782, 35.34716687, 38.83240189, 41.4527341 , 40.80453453, 34.4518716 , 33.54378434, 34.76110284, 39.39896604, 38.12986388, 35.01399576, 36.1764032 , 36.91026669, 38.09285533, 37.47092614, 35.08431869, 34.10750204, 33.98908271, 33.49633874, 31.95082717, 36.40762283, 33.54301125, 30.16956358, 34.97767163, 35.73862834, 37.5021579 , 46.90415398, 64.55582159, 65.24024526, 62.84832274, 63.79648979, 64.1050437 , 54.12537803, 46.57182176, 44.30600894]) - run_speed(trial_nr)float641.155 1.597 6.057 ... 1.251 1.711
array([ 1.15461545, 1.59668837, 6.056658 , 5.15987544, 8.52760497, 11.22847943, 4.57915849, 3.55552612, 1.21703267, 1.14123532, 1.22313026, 1.45219009, 1.27881682, 1.28545771, 1.30252225, 1.45938978, 1.23683681, 1.35499306, 1.24373061, 1.72814998, 1.10057218, 1.12037113, 1.0171456 , 1.12698213, 1.23746278, 1.0051122 , 1.22995347, 1.18035543, 1.33973747, 1.31655126, 1.42316228, 1.16454631, 1.1175898 , 1.33965127, 1.44008401, 1.27856107, 1.08369774, 1.2852668 , 1.22042713, 0.93635542, 1.10224883, 1.3656531 , 1.14346642, 1.34443297, 1.27934364, 1.22477016, 0.89182778, 1.08752668, 1.29883034, 1.38104512, 0.96683534, 1.19810534, 0.99052094, 0.9343001 , 1.71404147, 1.51968473, 1.23845685, 0.84848258, 1.59605601, 1.25635954, 1.22987165, 1.64782276, 1.75731669, 1.67665638, 1.42473997, 1.02886151, 5.65275275, 8.34342969, 9.03230058, 10.64468513, 8.17371765, 1.18762197, 1.36400808, 1.25093511, 1.71061779])
- channel_depthPandasIndex
PandasIndex(Index([ 0, -40, -80, -120, -160, -200, -240, -280, -320, -360, -400, -440, -480, -520, -560, -600, -640, -680, -720, -760, -800, -840, -880], dtype='int64', name='channel_depth')) - trial_nrPandasIndex
PandasIndex(Index([ 0, 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], dtype='int32', name='trial_nr')) - time_lfpPandasIndex
PandasIndex(Index([ -1000.0, -999.1999999999999, -998.4, -997.5999999999999, -996.8, -995.9999999999999, -995.1999999999998, -994.3999999999999, -993.5999999999998, -992.7999999999998, ... 492.00000000004263, 492.80000000004276, 493.6000000000429, 494.4000000000428, 495.20000000004273, 496.00000000004286, 496.800000000043, 497.6000000000429, 498.40000000004284, 499.20000000004296], dtype='float64', name='time_lfp', length=1875)) - time_csdPandasIndex
PandasIndex(Index([ -1000.0, -999.1999999999999, -998.4, -997.5999999999999, -996.8, -995.9999999999999, -995.1999999999998, -994.3999999999999, -993.5999999999998, -992.7999999999998, ... 492.00000000004263, 492.80000000004276, 493.6000000000429, 494.4000000000428, 495.20000000004273, 496.00000000004286, 496.800000000043, 497.6000000000429, 498.40000000004284, 499.20000000004296], dtype='float64', name='time_csd', length=1875)) - time_whole_rec_lfpPandasIndex
PandasIndex(Index([1285609.7386445338, 1285610.5386446053, 1285611.338644677, 1285612.1386447486, 1285612.9386448204, 1285613.7386448921, 1285614.5386449639, 1285615.3386450356, 1285616.1386451072, 1285616.938645179, ... 1584100.9653832503, 1584101.7653833218, 1584102.5653833936, 1584103.365383465, 1584104.1653835368, 1584104.9653836086, 1584105.7653836801, 1584106.5653837519, 1584107.3653838234, 1584108.1653838952], dtype='float64', name='time_whole_rec_lfp', length=373124)) - time_whole_rec_ecpPandasIndex
PandasIndex(Index([1285609.7386445338, 1285610.5386446053, 1285611.338644677, 1285612.1386447486, 1285612.9386448204, 1285613.7386448921, 1285614.5386449639, 1285615.3386450356, 1285616.1386451072, 1285616.938645179, ... 1584100.9653832503, 1584101.7653833218, 1584102.5653833936, 1584103.365383465, 1584104.1653835368, 1584104.9653836086, 1584105.7653836801, 1584106.5653837519, 1584107.3653838234, 1584108.1653838952], dtype='float64', name='time_whole_rec_ecp', length=373124)) - unit_id_LGNPandasIndex
PandasIndex(Index([951782498, 951782516, 951782530, 951782631, 951782683, 951782699, 951782744, 951782795, 951782832, 951782895, 951787033, 951792341, 951792375, 951792398, 951792418, 951792441, 951792504, 951792544, 951797077, 951798318, 951798391, 951798404, 951798553, 951798681, 951801317, 951798434, 951798528], dtype='int32', name='unit_id_LGN')) - time_spikesPandasIndex
PandasIndex(Index([ -999.5, -998.5, -997.5, -996.4999999999999, -995.5, -994.4999999999999, -993.5, -992.4999999999999, -991.5, -990.4999999999999, ... 490.50000000000006, 491.50000000000006, 492.50000000000006, 493.50000000000006, 494.50000000000006, 495.50000000000006, 496.50000000000006, 497.50000000000006, 498.50000000000006, 499.50000000000006], dtype='float64', name='time_spikes', length=1500)) - unit_id_V1PandasIndex
PandasIndex(Index([951795075, 951795086, 951795098, 951795140, 951795163, 951795222, 951795238, 951795256, 951795269, 951795290, 951795309, 951795317, 951795403, 951797419, 951795458, 951795474, 951795487, 951795495, 951795554, 951795680, 951795563, 951795611, 951795663, 951795688, 951795706, 951795713, 951795721, 951797465, 951795729, 951795737, 951795747, 951795873, 951795753, 951795782, 951795792, 951795760, 951795768, 951795775, 951795807, 951795824, 951795832, 951795839, 951795858, 951795880, 951795886, 951795896, 951795918, 951797520, 951797539, 951797553, 951795936, 951795943, 951795967, 951795976, 951797567, 951797489, 951796016, 951796073, 951796125, 951796165, 951796176, 951796229, 951797633, 951796333, 951797647, 951797664, 951796352, 951796494, 951797718, 951796542, 951796556, 951797730, 951796585, 951797742, 951796629, 951796639, 951796660, 951796696, 951796791, 951797776, 951796866, 951796906, 951796928, 951796949, 951797595, 951797613, 951797709, 951797764, 951797811, 951797995, 951798053], dtype='int32', name='unit_id_V1')) - unit_id_LMPandasIndex
PandasIndex(Index([951791074, 951791093, 951791202, 951791214, 951791273, 951791305, 951791297, 951791401, 951791422, 951791467, 951791442, 951791453, 951792163], dtype='int32', name='unit_id_LM')) - stimulus_start_timesPandasIndex
PandasIndex(Index([1289613.2512503476, 1293616.6012503474, 1299621.6212503475, 1301623.2912503474, 1303624.9712503476, 1307628.3312503474, 1309629.9512503473, 1319638.3212503474, 1329646.7112503473, 1333650.0712503474, 1337653.4012503475, 1341656.7412503476, 1351665.0512503474, 1357670.1212503475, 1361673.4312503475, 1371681.8412503474, 1373683.4712503473, 1375685.1712503475, 1383691.8312503477, 1387695.1512503477, 1397703.5312503476, 1401706.8812503475, 1403708.5812503477, 1407711.9312503475, 1411715.2512503476, 1413716.9412503475, 1415718.6312503477, 1417720.2612503476, 1419721.9512503475, 1421723.6212503477, 1423725.2512503476, 1427728.6212503475, 1429730.2812503476, 1431731.9412503475, 1433733.6212503477, 1435735.3212503477, 1441740.3312503477, 1447745.3112503476, 1451748.6712503475, 1459755.3812503477, 1461757.0612503476, 1467762.0512503476, 1473767.0912503477, 1481773.7512503476, 1485777.1012503477, 1489780.4612503476, 1491782.1212503477, 1493783.8112503474, 1497787.1612503477, 1501790.4812503476, 1503792.1412503477, 1505793.8012503476, 1511798.8712503477, 1515802.1712503475, 1517803.8912503475, 1519805.5512503476, 1521807.2312503476, 1529813.9112503477, 1531815.5712503477, 1533817.2312503476, 1537820.5712503474, 1541823.9312503478, 1543825.6012503474, 1545827.3012503476, 1547828.9312503475, 1551832.2912503476, 1553833.9612503476, 1563842.3512503474, 1565843.9912503478, 1569847.3512503477, 1571849.0212503476, 1573850.6912503475, 1575852.3412503474, 1577854.0712503474, 1583859.0512503476], dtype='float64', name='stimulus_start_times')) - stimulus_stop_timesPandasIndex
PandasIndex(Index([1289863.4505906447, 1293866.8005906448, 1299871.8205906446, 1301873.490590645, 1303875.1730906446, 1307878.5255906447, 1309880.1580906447, 1319888.5255906447, 1329896.9080906447, 1333900.2655906447, 1337903.5980906447, 1341906.9405906445, 1351915.2580906446, 1357920.3205906448, 1361923.6380906447, 1371932.0330906445, 1373933.6755906448, 1375935.370590645, 1383942.0355906447, 1387945.3630906448, 1397953.738090645, 1401957.0830906448, 1403958.7780906446, 1407962.128090645, 1411965.450590645, 1413967.1380906447, 1415968.823090645, 1417970.4655906449, 1419972.1505906447, 1421973.8230906448, 1423975.4605906447, 1427978.823090645, 1429980.4905906448, 1431982.1530906449, 1433983.8305906449, 1435985.5230906447, 1441990.5355906447, 1447995.5230906447, 1451998.8755906448, 1460005.5855906447, 1462007.2605906448, 1468012.2605906453, 1474017.2930906452, 1482023.960590645, 1486027.3080906447, 1490030.6655906448, 1492032.3255906447, 1494034.0130906447, 1498037.3605906449, 1502040.6855906448, 1504042.350590645, 1506044.0105906448, 1512049.0705906448, 1516052.3830906448, 1518054.088090645, 1520055.753090645, 1522057.4280906445, 1530064.1105906446, 1532065.7755906447, 1534067.4380906445, 1538070.7780906446, 1542074.1355906448, 1544075.8080906447, 1546077.4980906448, 1548079.1380906447, 1552082.495590645, 1554084.165590645, 1564092.5505906448, 1566094.193090645, 1570097.5530906448, 1572099.2255906449, 1574100.8955906448, 1576102.5530906448, 1578104.2680906446, 1584109.255590645], dtype='float64', name='stimulus_stop_times')) - channel_idPandasIndex
PandasIndex(Index([850144538, 850144530, 850144522, 850144514, 850144506, 850144498, 850144490, 850144482, 850144474, 850144466, 850144458, 850144450, 850144442, 850144434, 850144426, 850144418, 850144410, 850144402, 850144394, 850144386, 850144378, 850144370, 850144362], dtype='int32', name='channel_id'))
- time_unit :
- millisecond
- lfp_unit :
- Volt
- channel_depth_unit :
- micrometer
- note_channel_depth :
- Measured in distance from electrode closest to scalp
- sampling_frequency_lfp :
- 1250
- sampling_frequency_spikes :
- 1000
- sampling_frequency_unit :
- Hz
- stimulus_onset :
- 1000
- stimulus_offset :
- 1250
Run the cell below to extract LFP and spike data from dataset.
# extract data
lfp_V1 = dataset['lfp_V1']
channels_depth = dataset['channel_depth']
sampling_frequency_lfp = dataset.sampling_frequency_lfp # Hz
time_lfp = lfp_V1.time_lfp.values # ms
spike_counts_LGN = dataset['spike_counts_LGN']
spike_counts_V1 = dataset['spike_counts_V1']
spike_counts_LM = dataset['spike_counts_LM']
sampling_frequency_spikes = dataset.sampling_frequency_spikes # Hz
time_spikes = dataset['time_spikes'] # ms
lfp_V1<xarray.DataArray 'lfp_V1' (channel_depth: 23, trial_nr: 75, time_lfp: 1875)> Size: 26MB
array([[[-8.51569421e-06, -1.15631923e-05, -3.76924291e-07, ...,
-2.17654367e-06, 1.68119712e-07, -6.94200500e-06],
[ 2.81771330e-08, 6.29403676e-06, 9.98029865e-06, ...,
1.01304291e-05, 5.93295341e-06, 1.72969475e-05],
[-1.27271427e-06, -3.68783112e-06, -4.46340366e-06, ...,
3.65666426e-06, 2.96670978e-06, 1.24568597e-06],
...,
[ 4.70565253e-06, 1.94317598e-06, 1.20455675e-06, ...,
4.07503496e-06, 7.65054254e-06, 3.91673831e-06],
[ 8.38144661e-07, 2.28123812e-06, 3.70896321e-06, ...,
1.34013793e-05, 1.15462596e-05, 8.42411093e-06],
[ 7.32479652e-06, 1.07711181e-06, 7.00885884e-06, ...,
1.92065863e-05, 1.92065863e-05, 1.92065863e-05]],
[[ 3.91952787e-06, 1.70056905e-06, 5.97275690e-06, ...,
4.06974274e-06, 4.04094749e-06, -4.68055730e-06],
[-4.10311367e-06, 5.00856269e-06, 6.20500275e-06, ...,
8.75868311e-06, 5.69604080e-06, 8.57744575e-06],
[ 1.09646506e-06, 1.62070262e-06, 1.10953040e-07, ...,
1.01990671e-05, -8.36754580e-06, -1.43387447e-05],
...
[-6.46738552e-06, -1.19701456e-05, -2.41882630e-05, ...,
-2.31175915e-05, -2.37374262e-05, -7.53926446e-06],
[ 2.91850049e-05, 2.81713398e-05, 5.17618757e-05, ...,
4.44764295e-05, 4.08778688e-05, 3.83233192e-05],
[-1.80642354e-05, -1.06068608e-05, -3.71177368e-06, ...,
1.48063260e-05, 1.48063260e-05, 1.48063260e-05]],
[[ 4.42062699e-05, 5.99208645e-05, 7.60618853e-05, ...,
9.85508013e-05, 8.87923195e-05, 8.02998878e-05],
[-6.30930699e-06, 2.14882295e-05, 5.40961203e-06, ...,
-6.18517313e-05, -8.49961217e-05, -7.07025406e-05],
[ 1.32347041e-04, 9.66830285e-05, 9.77152893e-05, ...,
-3.68393584e-05, -2.08663734e-05, -1.27901811e-05],
...,
[ 7.59530363e-07, -9.00525049e-06, -1.95382678e-05, ...,
-2.78150664e-05, -1.46349189e-05, 3.65395950e-06],
[ 3.22381374e-05, 3.90163375e-05, 6.39709157e-05, ...,
5.17422904e-05, 4.94353600e-05, 3.90770304e-05],
[-2.50190016e-05, -1.82145705e-05, -1.97245214e-05, ...,
6.13148062e-06, 6.13148062e-06, 6.13148062e-06]]])
Coordinates:
* channel_depth (channel_depth) int64 184B 0 -40 -80 -120 ... -800 -840 -880
* trial_nr (trial_nr) int32 300B 0 1 2 3 4 5 6 ... 68 69 70 71 72 73 74
* time_lfp (time_lfp) float64 15kB -1e+03 -999.2 -998.4 ... 498.4 499.2- channel_depth: 23
- trial_nr: 75
- time_lfp: 1875
- -8.516e-06 -1.156e-05 -3.769e-07 ... 6.131e-06 6.131e-06 6.131e-06
array([[[-8.51569421e-06, -1.15631923e-05, -3.76924291e-07, ..., -2.17654367e-06, 1.68119712e-07, -6.94200500e-06], [ 2.81771330e-08, 6.29403676e-06, 9.98029865e-06, ..., 1.01304291e-05, 5.93295341e-06, 1.72969475e-05], [-1.27271427e-06, -3.68783112e-06, -4.46340366e-06, ..., 3.65666426e-06, 2.96670978e-06, 1.24568597e-06], ..., [ 4.70565253e-06, 1.94317598e-06, 1.20455675e-06, ..., 4.07503496e-06, 7.65054254e-06, 3.91673831e-06], [ 8.38144661e-07, 2.28123812e-06, 3.70896321e-06, ..., 1.34013793e-05, 1.15462596e-05, 8.42411093e-06], [ 7.32479652e-06, 1.07711181e-06, 7.00885884e-06, ..., 1.92065863e-05, 1.92065863e-05, 1.92065863e-05]], [[ 3.91952787e-06, 1.70056905e-06, 5.97275690e-06, ..., 4.06974274e-06, 4.04094749e-06, -4.68055730e-06], [-4.10311367e-06, 5.00856269e-06, 6.20500275e-06, ..., 8.75868311e-06, 5.69604080e-06, 8.57744575e-06], [ 1.09646506e-06, 1.62070262e-06, 1.10953040e-07, ..., 1.01990671e-05, -8.36754580e-06, -1.43387447e-05], ... [-6.46738552e-06, -1.19701456e-05, -2.41882630e-05, ..., -2.31175915e-05, -2.37374262e-05, -7.53926446e-06], [ 2.91850049e-05, 2.81713398e-05, 5.17618757e-05, ..., 4.44764295e-05, 4.08778688e-05, 3.83233192e-05], [-1.80642354e-05, -1.06068608e-05, -3.71177368e-06, ..., 1.48063260e-05, 1.48063260e-05, 1.48063260e-05]], [[ 4.42062699e-05, 5.99208645e-05, 7.60618853e-05, ..., 9.85508013e-05, 8.87923195e-05, 8.02998878e-05], [-6.30930699e-06, 2.14882295e-05, 5.40961203e-06, ..., -6.18517313e-05, -8.49961217e-05, -7.07025406e-05], [ 1.32347041e-04, 9.66830285e-05, 9.77152893e-05, ..., -3.68393584e-05, -2.08663734e-05, -1.27901811e-05], ..., [ 7.59530363e-07, -9.00525049e-06, -1.95382678e-05, ..., -2.78150664e-05, -1.46349189e-05, 3.65395950e-06], [ 3.22381374e-05, 3.90163375e-05, 6.39709157e-05, ..., 5.17422904e-05, 4.94353600e-05, 3.90770304e-05], [-2.50190016e-05, -1.82145705e-05, -1.97245214e-05, ..., 6.13148062e-06, 6.13148062e-06, 6.13148062e-06]]]) - channel_depth(channel_depth)int640 -40 -80 -120 ... -800 -840 -880
array([ 0, -40, -80, -120, -160, -200, -240, -280, -320, -360, -400, -440, -480, -520, -560, -600, -640, -680, -720, -760, -800, -840, -880]) - trial_nr(trial_nr)int320 1 2 3 4 5 6 ... 69 70 71 72 73 74
array([ 0, 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], dtype=int32) - time_lfp(time_lfp)float64-1e+03 -999.2 ... 498.4 499.2
array([-1000. , -999.2, -998.4, ..., 497.6, 498.4, 499.2])
- channel_depthPandasIndex
PandasIndex(Index([ 0, -40, -80, -120, -160, -200, -240, -280, -320, -360, -400, -440, -480, -520, -560, -600, -640, -680, -720, -760, -800, -840, -880], dtype='int64', name='channel_depth')) - trial_nrPandasIndex
PandasIndex(Index([ 0, 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], dtype='int32', name='trial_nr')) - time_lfpPandasIndex
PandasIndex(Index([ -1000.0, -999.1999999999999, -998.4, -997.5999999999999, -996.8, -995.9999999999999, -995.1999999999998, -994.3999999999999, -993.5999999999998, -992.7999999999998, ... 492.00000000004263, 492.80000000004276, 493.6000000000429, 494.4000000000428, 495.20000000004273, 496.00000000004286, 496.800000000043, 497.6000000000429, 498.40000000004284, 499.20000000004296], dtype='float64', name='time_lfp', length=1875))
Example: Calculate the power spectrum for all trials and all cells containing spike data from LM with Welch’s method. Make a 2D colormap of the trial averaged power spectrum with the freqs on the x-axis and cell numbers in LM (cell_nrs_LM) on the y-axis.
freqs, psd_spikes_LM_trials = signal.welch(spike_counts_LM.values, sampling_frequency_spikes)
cell_nrs_LM = np.arange(spike_counts_LM.shape[0])
plt.pcolormesh(freqs, cell_nrs_LM, psd_spikes_LM_trials.mean(axis=1), cmap = 'plasma', shading='gouraud')
plt.xlabel('Frequency (Hz)')
plt.ylabel('Cell nr.')
plt.xlim([0,100]);Exercise: Calculate the power spectrum for all trials and all cells containing spike data from V1 with Welch’s method. Make a 2D colormap of the trial averaged power spectrum with the freqs on the x-axis and cell numbers in V1 (cell_nrs_V1) on the y-axis.
Hint: To focus on a subset of frequencies, for example the frequencies below 100 Hz, you can limit the x-axis to focus on them using plt.xlim([lower_limit, upper_limit]) (insert numbers for lower_limit and upper_limit).
Solution
freqs, psd_spikes_V1_trials = signal.welch(spike_counts_V1.values, sampling_frequency_spikes)
cell_nrs_V1 = np.arange(spike_counts_V1.shape[0])
plt.pcolormesh(freqs, cell_nrs_V1, psd_spikes_V1_trials.mean(axis=1), cmap = 'plasma', shading='gouraud')
plt.xlabel('Frequency (Hz)')
plt.ylabel('Cell nr.')
plt.xlim([0,100]);Exercise: Calculate the power spectrum for all trials and all cells containing spike data from LGN with Welch’s method. make a 2D colormap of the trial averaged power spectrum with the freqs on the x-axis and cell numbers on the y-axis.
Do you notice anything different with this plot compared to the equivalent plots for V1 and LM spikes? Is there a frequency where the power is notably higher for some cells?
Solution
freqs, psd_spikes_LGN_trials = signal.welch(spike_counts_LGN.values, sampling_frequency_spikes)
cell_nrs_LGN = np.arange(spike_counts_LGN.shape[0])
plt.pcolormesh(freqs, cell_nrs_LGN, psd_spikes_LGN_trials.mean(axis=1), cmap = 'plasma', shading='gouraud')
plt.xlabel('Frequency (Hz)')
plt.ylabel('Cell nr.')
plt.xlim([0,100]);Exercise: Calculate the power spectrum for all trials and channels containing LFP data from V1 with Welch’s method. Compute the trial averaged power spectrum and make a 2D colormap with freqs on the x-axis and channels_depth on the y-axis.
NB: Make sure to use the sampling frequency for the LFP (sampling_frequency_lfp) in the function for Welch’s method.
Solution
freqs, psd_lfp_V1 = signal.welch(lfp_V1.values, sampling_frequency_lfp)
plt.pcolormesh(freqs, channels_depth, psd_lfp_V1.mean(axis=1), cmap = 'plasma', shading='gouraud')
plt.xlabel('Frequency (Hz)')
plt.ylabel(r'Depth ($\mu$m)')
plt.xlim([0,100]);Exercise: From the LFP spectrum computed in the exercise above, calculate the average power spectrum for V1 LFP across both channels and trials. Make a 1D plot of that average against frequencies.
Solution
psd_lfp_trial_avg = np.mean(psd_lfp_V1, axis=(0,1))
plt.plot(freqs, psd_lfp_trial_avg);Exercise: It’s often useful (and common practice) to plot frequency spectra on logarithmic axes rather than on linear axes. Create the same plot as above, but with a logarithmic x-axis (and a linear y-axis).
Solution
plt.semilogx(freqs, psd_lfp_trial_avg)
plt.xlabel('Frequency (Hz)')
plt.ylabel('Power spectral density');Exercise: Create the same plot as above, but with a logarithmic y-axis (and a linear x-axis).
At approximately which frequencies are there bumps in the spectrum?
Solution
plt.loglog(freqs, psd_lfp_trial_avg)
plt.xlabel('Frequency (Hz)')
plt.ylabel('Power spectral density');Exercise: Create the same plot as above, but with both axes logarithmic.
Solution
plt.loglog(freqs, psd_lfp_trial_avg)
plt.xlabel('Frequency (Hz)')
plt.ylabel('Power spectral density');Demo
The spectra of single spikes (delta pulse) is a flat line.
fake_spikes = np.zeros(1000)
fake_spikes[100] = 1
plt.plot(fake_spikes)freqs, psd = signal.welch(fake_spikes, 1000)
plt.plot(freqs, psd)
plt.title('Power spectrum of single spike (delta pulse)')
plt.xlabel('Frequency (Hz)')The power spectrum for a poisson process is also a flat, albeit noisier, line.
poisson_process = np.random.poisson(size=(100,1000))
freqs, psd = signal.welch(poisson_process, 1000)
plt.plot(freqs, psd.mean(axis=0))
plt.title('Power spectrum of poisson process')
plt.xlabel('Frequency (Hz)')The power spectra of a delta impulse and a poisson process are useful to have in mind when we assess the power spectrum of spike trains. If the power spectrum of a spike train is a flat and noisy line, it indicates that the neuron fires as a poisson process.
Example: Calculate the power spectrum for V1 spikes and average across both cells and trials. Make a 1D plot of the average power spectral density against frequencies.
freqs, psd_spikes_V1_trials = signal.welch(spike_counts_V1.values, sampling_frequency_spikes)
plt.plot(freqs, psd_spikes_V1_trials.mean(axis=(0,1)))
plt.xlabel('Frequency (Hz)')
plt.ylabel('Power spectral density');Exercise: Calculate the power spectrum for LGN spikes and average across both cells and trials. Make a 1D plot of the power spectral density against frequencies.
Is there a correspondence between any of the frequencies where you find peaks in the power spectrum for LGN spikes and where you find peaks in the spectrum for V1 LFP?
Solution
freqs, psd_spikes_LGN_trials = signal.welch(spike_counts_LGN.values, sampling_frequency_spikes)
plt.plot(freqs, psd_spikes_LGN_trials.mean(axis=(0,1)))
plt.xlabel('Frequency (Hz)')
plt.ylabel('Power spectral density')
plt.xlim(0,100);Section 2: Iteration with For Loops
There are different kinds of loops in programming languages that are used for different purposes. When you know when to start and stop an iteration, for loops are the most appropriate. For example, when you want to start at the first trial and stop at the last trial, or start at the 5th trial and stop at the 10th trial, you can specify that with a for loop. Going through the 5th to the 10th trial would have the following structure in Python code:
for itrial in range(4, 10):
# do some analysis of the data in the trial with index "itrial"| Code | Description |
|---|---|
for letter in ["a", "b", "c"]: print(letter) |
Print every letter in the list ["a", "b", "c"] |
for i in range(5): print(i) |
Print every number i between 0 and 5 (not including 5) |
for i in range(2, 7): print(i) |
Print every number i between 2 and 7 (not including 7) |
for i in range(1, 10, 2): print(i) |
Print eververy second number i between 1 and 10 (not including 10) |
for x_i in x: print(x_i) |
Print every element x_i in the collection x |
for x_i in x: for y_i in y: print(x_i, y_i) |
Print every element x_i and y_i in the collections x and y |
new_list = [] or new_list = list() |
Initialize an empty list named new_list |
new_list.append(element) |
Append an element to the list new_list |
Exercise: Write a for loop that prints the numbers 0 to 9.
Solution
for num in range(9):
print(num)0
1
2
3
4
5
6
7
8Exercise: Write a for loop that prints the numbers 5 to 10.
Solution
for i in range(5,10):
print(i)5
6
7
8
9Exercise: Write a for loop that counts from 0 to 100 in steps of 10.
Solution
for j in range(0,100,10):
print(j)0
10
20
30
40
50
60
70
80
90Exercise: Use a loop to print all fruits and colors, for example banana is yellow".
Solution
fruits = ["banana", "orange", "cherry"]
colors= ["yellow", "orange", "green"];
for fruit in fruits:
for color in colors:
print(fruit+' is '+color)banana is yellow
banana is orange
banana is green
orange is yellow
orange is orange
orange is green
cherry is yellow
cherry is orange
cherry is greenExample: Write a loop that calculates the square of each element in numbers and stores the result in a new list called squared_numbers. Display the squared_numbers list at the end to check that it is correct.
numbers = [4, 6, 12, 50]
squared_numbers = []
for i in range(len(numbers)):
num_squared = numbers[i]**2
squared_numbers.append(num_squared)
squared_numbers[16, 36, 144, 2500]Exercise: Write a loop that multiplies each element in the list numbers by 4 and store the results in a new list called multiplied_numbers. Display multiplied_numbers to check that it is correct.
Solution
numbers = [4, 6, 12, 50]
multiplied_numbers = []
for num in numbers:
mult_number = 4*num
multiplied_numbers.append(mult_number)
multiplied_numbers[16, 24, 48, 200]Exercise: Write a loop that print out "Run experiment for animal n" for each animal id in the list below.
Solution
animal_ids = ["m23", "m59", "m145"]
for animal_id in animal_ids:
print('Run experiment for animal '+animal_id)Run experiment for animal m23
Run experiment for animal m59
Run experiment for animal m145Exercise: Use a for loop within another for loop to print "This is block b" for each block in blocks and "This is trial t" for each t in trials.
Solution
blocks = [1, 2, 3]
trials = [1, 2, 3, 4, 5, 6, 7, 8 , 9 ,10]
for block in blocks:
print(f'This is block {block}')
for trial in trials:
print(f'This is trial {trial}')This is block 1
This is trial 1
This is trial 2
This is trial 3
This is trial 4
This is trial 5
This is trial 6
This is trial 7
This is trial 8
This is trial 9
This is trial 10
This is block 2
This is trial 1
This is trial 2
This is trial 3
This is trial 4
This is trial 5
This is trial 6
This is trial 7
This is trial 8
This is trial 9
This is trial 10
This is block 3
This is trial 1
This is trial 2
This is trial 3
This is trial 4
This is trial 5
This is trial 6
This is trial 7
This is trial 8
This is trial 9
This is trial 10Section 3: Analysis Inside For Loops
Sometimes, your data (for example from different trials) isn’t all of the same length, so you can’t apply the functions to do your analysis directly to the data with all trials together. Or you might want to skip trials that don’t meet certain conditions from your analysis. In those cases, you will often need to use for loops and carry out your analysis inside each loop. Here, you’ll get some practice doing your frequency analysis inside a loop and storing the results.
| Code | Description |
|---|---|
freqs, psd = signal.welch(sig, fs = sampling_frequency) |
Calculate the power spectral density for a signal sig using Welch’s method |
plt.plot(x, y) |
Plot y values against x values. |
np.shape(data) or data.shape |
Gives you the dimensions of the data. The output for data containing 20 channels on the first dimension, 50 trials, and 1000 time points would be (20,50,1000). data.shape[2] would give you the number of the second dimension (1000 in this example). |
np.mean(data, axis = (dim_num)) or data.mean(axis = dim_num) |
Calculate the average of the data across the dim_num dimension of the array. |
lfp_trace = lfp_V1[ichan, itrial] |
Get the lfp trace from the channel ichan in trial itrial. |
new_list = [] or new_list = list() |
Initialize an empty list named new_list |
new_list.append(element) |
Append an element to the list new_list |
Exercises
Example: Loop through the first five trials and use Welch’s method to calculate the power spectrum for the LFP trace from the channel at index 8 in each trial. Store the results in a list. Calculate the trial averaged frequency spectrum and plot it against the frequencies (freqs).
Note: the frequencies for which the spectrum is calculated will be identical for all trials and do not need to be stored in a list. The frequencies returned in the last iteration can be used.
psd_lfp_V1 = []
# select which channel to get the lfp trace from
ichan = 8
# loop through the first 5 trials
for itrial in range(0,5,1):
lfp_trace = lfp_V1[ichan, itrial]
# calculate the power spectrum for this lfp trace
freqs, psd_lfp_trial = signal.welch(lfp_trace, fs = sampling_frequency_lfp)
# store the psd calculated for lfp trace in this trial
psd_lfp_V1.append(psd_lfp_trial)
psd_lfp_trial_avg = np.mean(psd_lfp_V1, axis = 0)
plt.loglog(freqs, psd_lfp_trial_avg)
plt.xlabel('Frequency (Hz)')
plt.ylabel('Power spectral density');Exercise: Loop through trials 5 to 10 and calculate the frequency spectrum for the LFP trace from channel at index 20 in each trial. Store the results in a list. Calculate the trial averaged frequency spectrum and plot it against the frequencies (freqs).
Solution
psd_lfp_V1 = []
ichan = 20
for itrial in range(5,10,1):
lfp_trace = lfp_V1[ichan, itrial]
freqs, psd_lfp_trial = signal.welch(lfp_trace, fs = sampling_frequency_lfp)
psd_lfp_V1.append(psd_lfp_trial)
psd_lfp_trial_avg = np.mean(psd_lfp_V1, axis = 0)
plt.loglog(freqs, psd_lfp_trial_avg)
plt.xlabel('Frequency (Hz)')
plt.ylabel('Power spectral density')Exercise: Loop through all (75) trials, calculate the frequency spectrum for the LFP trace from channel at index 8 in each trial, and store the results in a list. Calculate the trial averaged frequency spectrum and plot it against the frequencies (freqs).
Hint: Instead of writing 75 in the range of the loop, you can use the np.shape(data)[some_number] or data.shape[some_number] to get the number of trials in the array containing lfp traces from all trials and channels. Trials are on dimension 1.
Solution
psd_lfp_V1 = []
ichan = 8
for itrial in range(lfp_V1.shape[1]):
lfp_trace = lfp_V1[ichan, itrial]
freqs, psd_trial = signal.welch(lfp_trace, fs = sampling_frequency_lfp)
psd_lfp_V1.append(psd_trial)
psd_lfp_trial_avg = np.mean(psd_lfp_V1, axis = 0)
plt.loglog(freqs, psd_lfp_trial_avg)
plt.xlabel('Frequency (Hz)')
plt.ylabel('Power spectral density')Example: Loop through all trials and calculate the frequency spectrum for the LGN spikes of the cell at index 5. Store the results in a list and calculate and plot the trial averaged frequency spectrum of the spikes of this cell.
icell = 5
psd_spikes_LGN_all_trials = []
for itrial in range(spike_counts_LGN.shape[1]):
spikes = spike_counts_LGN[icell, itrial]
freqs, psd = signal.welch(spikes, sampling_frequency_spikes)
psd_spikes_LGN_all_trials.append(psd)
psd_spikes_LGN_trial_avg = np.mean(psd_spikes_LGN_all_trials, axis = 0)
plt.plot(freqs, psd_spikes_LGN_trial_avg)
plt.xlabel('Frequency (Hz)')
plt.ylabel('Power spectral density');Exercise: Loop through all trials and calculate the frequency spectrum for the V1 spikes of the cell at index 5. Store the results in a list and calculate and plot the trial averaged frequency spectrum of the spikes of this cell.
Solution
icell = 5
psd_spikes_V1_all_trials = []
for itrial in range(spike_counts_V1.shape[1]):
spikes = spike_counts_V1[icell, itrial]
freqs, psd = signal.welch(spikes, sampling_frequency_spikes)
psd_spikes_V1_all_trials.append(psd)
psd_V1_trial_avg = np.mean(psd_spikes_V1_all_trials, axis = 0)
plt.plot(freqs, psd_V1_trial_avg)
plt.xlabel('Frequency (Hz)')
plt.ylabel('Power spectral density')Exercise: Loop through all cells and calculate the frequency spectrum for the LGN spikes of each cell in the first trial (itrial = 0) and store the results in a list. Calculate and plot the population averaged frequency spectrum of the spikes from all cells in this single trial.
Solution
itrial = 0
psd_spikes_all_units = []
for icell in range(spike_counts_LGN.shape[0]):
spikes = spike_counts_LGN[icell, itrial]
freqs, psd = signal.welch(spikes, sampling_frequency_spikes)
psd_spikes_all_units.append(psd)
psd_population_avg = np.mean(psd_spikes_all_units, axis = 0)
plt.plot(freqs, psd_population_avg)
plt.xlabel('Frequency (Hz)')
plt.ylabel('Power spectral density')Section 4: Nested For Loops for Multidimensional Data
If you need to go through both different channels and trials or both different cells and trials for an analysis, you will need to use a loop within a loop, or a nested for loop.
| Code | Description |
|---|---|
for x_i in x: for y_i in y: print(x_i, y_i) |
Print every element x_i and y_i in the collections x and y |
new_list = [] or new_list = list() |
Initialize an empty list named new_list |
new_list.append(element) |
Append an element to the list new_list |
np.mean(data, axis = (dim_num)) or data.mean(axis = dim_num) |
Calculate the average of the data across the dim_num dimension of the array. |
plt.pcolormesh(x, y, C, cmap = 'plasma', shading = 'gouraud') |
Make a 2D colormap of values in a 2D array (C) against x and y values. The optional parameters cmap and shading defines the colormap and the interpolation applied to the plot, respectively. |
Exercises
Example: Loop through both the cells and the trials and calculate the power spectrum for the LGN spike count of each cell in each trial. Store the resulting power spectra for each cell and trial in lists. Calculate the trial average and make a 2D colormap plot of the results with frequencies on the x-axis and cells on the y-axis.
psd_spikes_LGN = []
for icell in range(spike_counts_LGN.shape[0]):
psd_spikes_LGN_all_trials = []
for itrial in range(spike_counts_LGN.shape[1]):
spikes = spike_counts_LGN[icell, itrial]
freqs, psd = signal.welch(spikes, sampling_frequency_spikes)
psd_spikes_LGN_all_trials.append(psd)
psd_spikes_LGN.append(psd_spikes_LGN_all_trials)
psd_spikes_LGN_trial_avg = np.mean(psd_spikes_LGN, axis = 1)
cell_nrs_LGN = np.arange(spike_counts_LGN.shape[0])
plt.pcolormesh(freqs, cell_nrs_LGN, psd_spikes_LGN_trial_avg, cmap='plasma', shading='gouraud')
plt.xlim([0,100])
plt.xlabel('Frequency (Hz)')
plt.ylabel('Cell nr.')
plt.title('Trial averaged power spectrum LGN spikes');Exercise: Loop through both the cells and the trials and calculate the power spectrum for the LM spike count (spike_counts_LM) of each cell in each trial. Store the resulting power spectra for each cell and trial in lists. Calculate the trial average and make a 2D colormap plot of the results with frequencies on the x-axis and cells on the y-axis.
Solution
psd_spikes_LM = []
for icell in range(spike_counts_LM.shape[0]):
psd_spikes_LM_all_trials = []
for itrial in range(spike_counts_LM.shape[1]):
spikes = spike_counts_LM[icell, itrial]
freqs, psd = signal.welch(spikes, sampling_frequency_spikes)
psd_spikes_LM_all_trials.append(psd)
psd_spikes_LM.append(psd_spikes_LM_all_trials)
psd_spikes_LM_trial_avg = np.mean(psd_spikes_LM, axis = 1)
cell_nrs_LM = np.arange(spike_counts_LM.shape[0])
plt.pcolormesh(freqs, cell_nrs_LM, psd_spikes_LM_trial_avg, cmap='plasma', shading='gouraud')
plt.xlim([0,100])
plt.xlabel('Frequency (Hz)')
plt.ylabel('Cell nr.')
plt.title('Trial averaged power spectrum')Exercise: Loop through both the cells and the trials and calculate the power spectrum for the V1 spike count (spike_counts_V1) of each cell in each trial. Store the resulting power spectra for each cell and trial in lists. Calculate the trial average and make a 2D colormap plot of the results with frequencies on the x-axis and cells on the y-axis.
Solution
psd_spikes_LGN = []
for icell in range(spike_counts_LGN.shape[0]):
psd_spikes_LGN_all_trials = []
for itrial in range(spike_counts_LGN.shape[1]):
spikes = spike_counts_LGN[icell, itrial]
freqs, psd = signal.welch(spikes, sampling_frequency_spikes)
psd_spikes_LGN_all_trials.append(psd)
psd_spikes_LGN.append(psd_spikes_LGN_all_trials)
psd_spikes_LGN_trial_avg = np.mean(psd_spikes_LGN, axis = 1)
cell_nrs_LGN = np.arange(spike_counts_LGN.shape[0])
plt.pcolormesh(freqs, cell_nrs_LGN, psd_spikes_LGN_trial_avg, cmap='plasma', shading='gouraud')
plt.xlim([0,100])
plt.xlabel('Frequency (Hz)')
plt.ylabel('Cell nr.')
plt.title('Trial averaged power spectrum')Exercise: Loop through both the channels and the trials and calculate the frequency spectrum for all LFP traces. Store the resulting power spectra. Calculate the trial average, and make a 2D colormap plot of the results with frequencies on the x-axis and cells on the y-axis.
NB: Make sure to use the sampling frequency for the LFP (sampling_frequency_lfp) in the function for Welch’s method.
Solution
psd_lfp_V1_chans = []
for ichan in range(lfp_V1.shape[0]):
psd_single_chan_all_trials = []
for itrial in range(lfp_V1.shape[1]):
lfp_trace = lfp_V1[ichan, itrial]
freqs, psd = signal.welch(lfp_trace, fs = sampling_frequency_lfp)
psd_single_chan_all_trials.append(psd)
psd_lfp_V1_chans.append(psd_single_chan_all_trials)
psd_lfp_trial_avg_chans = np.mean(psd_lfp_V1_chans, axis = 1)
plt.pcolormesh(freqs, channels_depth, psd_lfp_trial_avg_chans, cmap='plasma', shading='gouraud')
plt.xlim([0,100])
plt.xlabel('Frequency (Hz)')
plt.ylabel(r'Depth ($\mu$m)')