In this part we analyze data from a stimulation experiment.
Current was measured intracellularly from a layer V pyramidal neuron. To measure the repeated postsynaptic response to synaptic transmission, a presynaptic neuron was repeatedly stimulated by means of phototlytic release of the excitatory neurotransmitter glutamate using short pulses of UV light [2,3] (cf. Lecture).
For generating the pulses, a shutter (similar to that in a photo camera) was used to start and interrupt a continuous UV laser beam. The movement of the mechanical shutter was recorded along with the physiological data. This allows to determine the exact times at which the shutter was opened as the onset of the presynaptic stimulation. These shutter opening times will serve us as the trigger for cutting out pieces from the postsynaptic current trace.
The goal is to determine
One goal of todays exercises is to explore visualization techniques and to produce „camera-ready‟ figures that combine different graphs in one figure. Make sure that all axes have proper labels (dimension and units).
Useful command with matplotlib:
fig.add_axes() and fig.add_suplot()
Start a new python script for tasks 1 – 4. When you later run this script it should reproduce Figure 1. Estimated time: 3h.
load data set B. The file contains matlab struct “data”. Use data file with „no_struct‟ extension with python. Important struct fields are:
I : current traceZ : shutter command voltageI_TimeResolutionS : temporal resolution of current recording in secondsZ_TimeResolutionS : temporal resolution of shutter command voltage
Detect the stimulation onset index/times from the variable “Z”, the shutter is closed when the shutter control voltage is +5 V, and open when it assumes -2V. Note that shutter command voltage was sampled with different time resolution than the current trace. There are 42 shutter openings corresponding to 3 different presynaptic stimulation sites (3 different presynaptic neurons that were targeted) and 14 repetitions for each target site. The stimulation sequence was as follows: target 1, target 2, target 3, target 1, ... and so on. You thus need to group the 14 appropriate indices for each of the sites: first collect all time indices of opening, then “reshape” your array (42 x 1) such that you receive a matrix of 3 x 14 entries.
Average EPSC: For each of the three presynaptic sites extract the responses to the stimulation during 100ms following the stimulation (cutouts). Note: You need to appropriately convert the stimulus onset times in order to trigger the cutouts in the current trace because of the different temporal resolutions of shutter data and current data! Open a new Figure 1. Produce 3 graphs (panels) in Figure 1, one for each presynaptic stimulation target that shows the average EPSC across the 14 repeated stimulations.
Amplitude variability: In order to quantify the amplitude variability measure the peak amplitude for each single repetition and calculate mean and standard deviation of peak amplitudes across repetitions, as well as the coefficient of variation CV (std / mean). Add the numbers as text to your graphs. Do your results fit to the results displayed in Figure 5C in [1]?
Temporal precision: You want to know the temporal precision with which the PSCs occurred in repeated trials. An easy way to do this is to detect the PSC onset, again by using a threshold, and then measure the standard deviation of onset times (jitter) in milliseconds. The smaller the jitter, the more precise is the response. Report the jitter for all three synaptic contacts and add the number to the graphs. Do your results fit to those reported in [1]? What contributes to the observed temporal jitter (cf. Fig. 3E in [2])?
B – data from laser uncaging experiments as published in Boucsein et al. (2005). This data set contains voltage clamp recordings from one layer 5 pyramidal cell in the acute neocortical slice from rat somatosensory cortex. Presynaptic neurons at three different target sites were stimulated by means of focused photolysis of caged glutamate. These neurons produced action potentials, which resulted in excitatory postsynaptic currents (EPSCs) in the postsynaptic cell.
I thank Michael Pereira for adopting the Matlab command hints for python programming.
[1] Boucsein C, Nawrot M, Rotter S, Aertsen A, Heck D (2005) Controlling Synaptic input Patterns In vitro by Dynamic Photo Stimulation. J Neurophysiol 94: 2948-2958
[2] Nawrot MP, Schnepel P, Aertsen A and Boucsein C (2009) Precisely timed signal transmission in neocortical networks with reliable intermediate-range projections. Frontiers in Neural Circuits 3:1 http://frontiersin.org/neuralcircuits/paper/10.3389/neuro.04/001.2009/pdf/
[3] Boucsein C, Nawrot MP, Schnepel P, Aertsen A (2011) Beyond the cortical column: abundance and physiology of horizontal connections imply a strong role for inputs from the surround. Frontiers in Neuroscience 5:32. doi: 10.3389/fnins.2011.00032
In [1]:
import scipy.io
# please edit the data path if necessary
# squeeze_me=True removes unnessecary dimensions
data = scipy.io.loadmat('data/synaptic_response_variability_nostruct.mat',
squeeze_me=True)
In [2]:
dtI = data['I_TimeResolutionS']
dtZ = data['Z_TimeResolutionS']
I = data['I'] # current trace
Z = data['Z'].round() # shutter command voltage
print I.shape, Z.shape, dtI, dtZ
In [3]:
tI = arange(len(I))*dtI
tZ = arange(len(Z))*dtZ
#windowZ = slice(-1)
windowZ = slice(18/dtZ,24/dtZ)
#windowI = slice(-1)
windowI = slice(18/dtI,24/dtI)
Detect the stimulation onset index/times from the variable “Z”, the shutter is closed when the shutter control voltage is +5 V, and open when it assumes -2V. Note that shutter command voltage was sampled with different time resolution than the current trace. There are 42 shutter openings corresponding to 3 different presynaptic stimulation sites (3 different presynaptic neurons that were targeted) and 14 repetitions for each target site. The stimulation sequence was as follows: target 1, target 2, target 3, target 1, ... and so on. You thus need to group the 14 appropriate indices for each of the sites: first collect all time indices of opening, then “reshape” your array (42 x 1) such that you receive a matrix of 3 x 14 entries.
In [4]:
shutter_open = (Z < 0).astype(int)
shutter_onset = diff(shutter_open).clip(0,1)
shutter_onset_idx = find(shutter_onset)
#scale the shutter onset indices to match the I sampling frequency
onset_I = shutter_onset_idx*(dtZ/dtI)
N_shutter = shutter_onset.sum()
print N_shutter, 'is the number of events (answer to everything)'
In [5]:
plot(tI[windowI], I[windowI])
vlines(onset_I*dtI, 140,150)
xlim(windowI.start*dtI,windowI.stop*dtI)
xlabel('time [ms]')
Out[5]:
2. Average EPSC: For each of the three presynaptic sites extract the responses to the stimulation during 100ms following the stimulation (cutouts). Note: You need to appropriately convert the stimulus onset times in order to trigger the cutouts in the current trace because of the different temporal resolutions of shutter data and current data! Show the average EPSC across the 14 repeated stimulations.
In [6]:
cutout_window = 75*1e-3 #in seconds
ncutout = int(cutout_window/dtI) #number of bins to cut out
# Select indices within the cot-out windows
select_idxI = tile(arange(0,ncutout),(N_shutter,1)).T
# shift each cut-out window by the shutter offset time
select_idxI += onset_I.astype(int) # astype(int) ensures that the indices are integers
select_idxI = select_idxI.reshape(select_idxI.shape[0],-1,3)
3. Amplitude variability: In order to quantify the amplitude variability measure the peak amplitude for each single repetition and calculate mean and standard deviation of peak amplitudes across repetitions, as well as the coefficient of variation CV (std/mean). Add the numbers as text to your graph s. Do your results fit to the results displayed in Figure 5C in [1]?
In [7]:
EPSC_mean = I[select_idxI].mean(1)
EPSC_peaks = I[select_idxI].max(0)
peak_times = EPSC_mean.argmax(0)
time = arange(0,ncutout)*dtI*1e3 #in ms
plot(time, EPSC_mean)
errorbar(peak_times*dtI*1e3,EPSC_mean.max(0),yerr=EPSC_peaks.std(0), fmt=None)
title('Average EPSC')
xlabel('time [ms]')
legend(['site 1','site 2','site 3'])
Out[7]:
In [8]:
print 'the peak CVs for sites 1,2,3 are:', EPSC_peaks.std(0)/EPSC_peaks.mean(0)
Temporal precision: You want to know the temporal precision with which the PSCs occurred in repeated trials. An easy way to do this is to detect the PSC onset, again by using a threshold, and then measure the standard deviation of onset times (jitter) in milliseconds.
The smaller the jitter , the more precise is the response. Report the jitter for all three synaptic contacts and add the number to the graphs. Do your results fit to those reported in [1]? What contributes to the observed temporal jitter (cf. Fig. 3E in [2])?
In [9]:
thres = 35
onset_offsets = diff((I[select_idxI] > thres).astype(int),0).clip(0,1).argmax(0)
time = arange(0,ncutout)*dtI*1e3 #in
plot(time, EPSC_mean)
errorbar(onset_offsets.mean(0)*dtI*1e3,[thres]*3,xerr=onset_offsets.std(0)*dtI*1e3, fmt=None)
title('Average EPSC')
xlabel('time [ms]')
legend(['site 1','site 2','site 3'])
print 'the onset jittes in ms for sites 1,2,3 is:', onset_offsets.std(0)
In [10]:
#Now mask the outlier
onset_offsets = ma.array(onset_offsets)
onset_offsets[9,2] = ma.masked
plot(time, EPSC_mean)
errorbar(onset_offsets.mean(0)*dtI*1e3,[thres]*3,xerr=onset_offsets.std(0)*dtI*1e3, fmt=None)
title('Average EPSC')
xlabel('time [ms]')
legend(['site 1','site 2','site 3'])
print 'the onset jittes in ms for sites 1,2,3 is:', onset_offsets.std(0)