diff --git a/pointprocesses/lecture/isihexamples.py b/pointprocesses/lecture/isihexamples.py index b1c7daa..674bbd7 100644 --- a/pointprocesses/lecture/isihexamples.py +++ b/pointprocesses/lecture/isihexamples.py @@ -55,11 +55,11 @@ def plotisih( ax, isis, binwidth=None ) : binwidth = 5e-4 h, b = np.histogram(isis, np.arange(0.0, np.max(isis)+binwidth, binwidth), density=True) ax.text(0.9, 0.85, 'rate={:.0f}Hz'.format(1.0/np.mean(isis)), ha='right', transform=ax.transAxes) - ax.text(0.9, 0.75, 'mean={:.0f}ms'.format(1000.0*np.mean(isis)), ha='right', transform=ax.transAxes) - ax.text(0.9, 0.65, 'CV={:.2f}'.format(np.std(isis)/np.mean(isis)), ha='right', transform=ax.transAxes) + ax.text(0.9, 0.7, 'mean={:.0f}ms'.format(1000.0*np.mean(isis)), ha='right', transform=ax.transAxes) + ax.text(0.9, 0.55, 'CV={:.2f}'.format(np.std(isis)/np.mean(isis)), ha='right', transform=ax.transAxes) ax.set_xlabel('ISI', 'ms') ax.set_ylabel('p(ISI)', '1/s') - ax.bar( 1000.0*b[:-1], h, bar_fac*1000.0*np.diff(b), facecolor=colors['blue']) + ax.bar( 1000.0*b[:-1], h, bar_fac*1000.0*np.diff(b), **fsA) # parameter: rate = 20.0 @@ -85,16 +85,18 @@ x[x<0.0] = 0.0 inhspikes = pifspikes(x, trials, dt, D=0.3) fig, (ax1, ax2) = plt.subplots(1, 2) -fig.subplots_adjust(**adjust_fs(fig, top=1.5)) -ax1.set_title('stationary') -ax1.set_xlim(0.0, 200.0) -ax1.set_ylim(0.0, 40.0) -plotisih(ax1, isis(homspikes)) +fig.subplots_adjust(**adjust_fs(fig, top=0.5, right=1.5)) +ax1.set_xlim(0.0, 150.0) +ax1.set_ylim(0.0, 31.0) +ax1.set_xticks(np.arange(0.0, 151.0, 50.0)) +ax1.set_yticks(np.arange(0.0, 31.0, 10.0)) +plotisih(ax1, isis(homspikes), 0.005) -ax2.set_title('non-stationary') -ax2.set_xlim(0.0, 200.0) -ax2.set_ylim(0.0, 40.0) -plotisih(ax2, isis(inhspikes)) +ax2.set_xlim(0.0, 150.0) +ax2.set_ylim(0.0, 31.0) +ax2.set_xticks(np.arange(0.0, 151.0, 50.0)) +ax2.set_yticks(np.arange(0.0, 31.0, 10.0)) +plotisih(ax2, isis(inhspikes), 0.005) plt.savefig('isihexamples.pdf') plt.close() diff --git a/pointprocesses/lecture/pointprocesses.tex b/pointprocesses/lecture/pointprocesses.tex index 5849a9a..81bbb9a 100644 --- a/pointprocesses/lecture/pointprocesses.tex +++ b/pointprocesses/lecture/pointprocesses.tex @@ -1,36 +1,41 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\chapter{Spiketrain analysis} +\chapter{Spike-train analysis} \label{pointprocesseschapter} -\exercisechapter{Spiketrain analysis} +\exercisechapter{Spike-train analysis} \entermde[action potential]{Aktionspotential}{Action potentials} -(\enterm[spike|seealso{action potential}]{spikes}) are the carriers of -information in the nervous system. Thereby it is the time at which the -spikes are generated that is of importance for information -transmission. The waveform of the action potential is largely -stereotyped and therefore does not carry information. - -The result of the pre-processing of electrophysiological recordings are -series of spike times, which are termed \enterm{spiketrains}. If -measurements are repeated we get several \enterm{trials} of -spiketrains (\figref{rasterexamplesfig}). - -Spiketrains are times of events, the action potentials. Analyzing -spike trains leads into the realm of the so called \entermde[point - process]{Punktprozess}{point processes}. - -\begin{figure}[ht] +(\enterm[spike|seealso{action potential}]{spikes}) carry information +within neural systems. More precisely, the times at which action +potentials are generated contain the information. The waveform of the +action potential is largely stereotyped and therefore conveys no +information. Analyzing the statistics of spike times and their +relation to sensory stimuli or motor actions is central to +neuroscientific research. With multi-electrode arrays it is nowadays +possible to record from hundreds or even thousands of neurons +simultaneously. The open challenge is how to analyze such data sets in +order to understand how neural systems work. Let's start with the +basics in this chapter. + +The result of the pre-processing of electrophysiological recordings +are series of spike times, which are termed \enterm[spike train]{spike + trains}. If measurements are repeated we get several \enterm{trials} +of spike trains (\figref{rasterexamplesfig}). Spike trains are lists +of times of events, the action potentials. Analyzing spike trains +leads into the realm of the statistics of so called \entermde[point +process]{Punktprozess}{point processes}. + +\begin{figure}[bt] \includegraphics[width=1\textwidth]{rasterexamples} - \titlecaption{\label{rasterexamplesfig}Raster-plot.}{Raster-plots of - ten trials of data illustrating the times of the action - potentials. Each vertical dash illustrates the time at which an - action potential was observed. Each line displays the events of - one trial. Shown is a stationary point process (homogeneous point + \titlecaption{\label{rasterexamplesfig}Raster plot.}{Raster plots of + ten trials of data illustrating the times of action + potentials. Each vertical stroke illustrates the time at which an + action potential was observed. Each row displays the events of one + trial. Shown is a stationary point process (homogeneous point process with a rate $\lambda=20$\;Hz, left) and an non-stationary - point process (perfect integrate-and-fire neuron driven by - Ohrnstein-Uhlenbeck noise with a time-constant $\tau=100$\,ms, - right).} + point process with a rate that varies in time (noisy perfect + integrate-and-fire neuron driven by Ohrnstein-Uhlenbeck noise with + a time-constant $\tau=100$\,ms, right).} \end{figure} @@ -43,7 +48,7 @@ spike trains leads into the realm of the so called \entermde[point crosses some threshold. For example:\vspace{-1ex} \begin{itemize} \item Action potentials/heart beat: created by the dynamics of the - neuron/sinoatrial node + neuron/sinoatrial node. \item Earthquake: defined by the dynamics of the pressure between tectonical plates. \item Communication calls in crickets/frogs/birds: shaped by @@ -59,21 +64,21 @@ spike trains leads into the realm of the so called \entermde[point $T_i=t_{i+1}-t_i$ and the number of events $n_i$. } \end{figure} +\noindent A temporal \entermde{Punktprozess}{point process} is a stochastic -process that generates a sequence of events at times $\{t_i\}$, $t_i -\in \reZ$. In the neurosciences, the statistics of point processes is -of importance since the timing of neuronal events (action potentials, -post-synaptic potentials, events in EEG or local-field recordings, -etc.) is crucial for information transmission and can be treated as -such a process. +process that generates a sequence of events at times $\{t_i\}$. In +the neurosciences, the statistics of point processes is of importance +since the timing of neuronal events (action potentials, post-synaptic +potentials, events in EEG or local-field recordings, etc.) is crucial +for information transmission and can be treated as such a process. The events of a point process can be illustrated by means of a raster plot in which each vertical line indicates the time of an event. The event from two different point processes are shown in -\figref{rasterexamplesfig}. Point processes can be described using -the intervals between successive events $T_i=t_{i+1}-t_i$ and the -number of observed events within a certain time window $n_i$ -(\figref{pointprocessscetchfig}). +\figref{rasterexamplesfig}. In addition to the event times, point +processes can be described using the intervals $T_i=t_{i+1}-t_i$ +between successive events or the number of observed events within a +certain time window $n_i$ (\figref{pointprocessscetchfig}). \begin{exercise}{rasterplot.m}{} Implement a function \varcode{rasterplot()} that displays the times of @@ -94,7 +99,7 @@ real-valued variables: \begin{figure}[t] \includegraphics[width=0.96\textwidth]{isihexamples}\vspace{-2ex} - \titlecaption{\label{isihexamplesfig}Interspike interval + \titlecaption{\label{isihexamplesfig}Interspike-interval histograms}{of the spike trains shown in \figref{rasterexamplesfig}.} \end{figure} @@ -144,7 +149,7 @@ the interval $T_i$. The parameter $k$ is called the \enterm{lag} (\determ{Verz\"ogerung}) $k$. Stationary and non-stationary return maps are distinctly different \figref{returnmapfig}. -\begin{figure}[t] +\begin{figure}[tp] \includegraphics[width=1\textwidth]{returnmapexamples} \includegraphics[width=1\textwidth]{serialcorrexamples} \titlecaption{\label{returnmapfig}Interspike interval @@ -314,7 +319,7 @@ The homogeneous Poisson process has the following properties: \includegraphics[width=0.48\textwidth]{poissoncounthistdist100hz10ms}\hfill \includegraphics[width=0.48\textwidth]{poissoncounthistdist100hz100ms} \titlecaption{\label{hompoissoncountfig}Distribution of counts of a - Poisson spiketrain.}{The count statistics was generated for two + Poisson spike train.}{The count statistics was generated for two different windows of width $W=10$\,ms (left) and width $W=100$\,ms (right). The red line illustrates the corresponding Poisson distribution \eqnref{poissoncounts}.} @@ -324,7 +329,7 @@ The homogeneous Poisson process has the following properties: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{Time-dependent firing rate} -So far we have discussed stationary spiketrains. The statistical properties +So far we have discussed stationary spike trains. The statistical properties of these did not change within the observation time (stationary point processes). Most commonly, however, this is not the case. A sensory neuron, for example, might respond to a stimulus by modulating its @@ -351,7 +356,7 @@ justifications, their pros- and cons. \begin{figure}[tp] \includegraphics[width=\columnwidth]{isimethod} - \titlecaption{Instantaneous firing rate.}{The recorded spiketrain + \titlecaption{Instantaneous firing rate.}{The recorded spike train (top). Arrows illustrate the interspike intervals and numbers give the intervals in milliseconds. The inverse of the interspike intervals is the \emph{instantaneous firing rate} @@ -412,7 +417,7 @@ methods make an assumption about the relevant observation time-scale \begin{figure}[tp] \includegraphics[width=\columnwidth]{binmethod} \titlecaption{Estimating the PSTH using the binning method.}{The - same spiketrain as shown in \figref{instratefig} (top). Vertical + same spike train as shown in \figref{instratefig} (top). Vertical gray lines indicate the borders between adjacent bins in which the number of action potentials is counted (red numbers). The firing rate is then the histogram normalized to the binwidth @@ -448,8 +453,8 @@ time-scale. \begin{figure}[tp] \includegraphics[width=\columnwidth]{convmethod} \titlecaption{Estimating the firing rate using the convolution - method.}{The same spiketrain as in \figref{instratefig} (top). The - convolution of the spiketrain with a kernel replaces each spike + method.}{The same spike train as in \figref{instratefig} (top). The + convolution of the spike train with a kernel replaces each spike event with the kernel (red). A Gaussian kernel is used here, but other kernels are also possible. If the kernel is properly normalized the firing rate results directly form the superposition diff --git a/pointprocesses/lecture/rasterexamples.py b/pointprocesses/lecture/rasterexamples.py index 042bda2..f616c18 100644 --- a/pointprocesses/lecture/rasterexamples.py +++ b/pointprocesses/lecture/rasterexamples.py @@ -1,5 +1,6 @@ import numpy as np import matplotlib.pyplot as plt +from plotstyle import * def hompoisson(rate, trials, duration) : spikes = [] @@ -8,8 +9,8 @@ def hompoisson(rate, trials, duration) : t = 0.0 while t < duration : t += np.random.exponential(1/rate) - times.append( t ) - spikes.append( times ) + times.append(t) + spikes.append(times) return spikes def inhompoisson(rate, trials, dt) : @@ -18,7 +19,7 @@ def inhompoisson(rate, trials, dt) : for k in range(trials) : x = np.random.rand(len(rate)) times = dt*np.nonzero(x
= vthresh :
v = vreset
times.append(k*dt)
- spikes.append( times )
+ spikes.append(times)
return spikes
# parameter:
@@ -64,23 +65,22 @@ x[x<0.0] = 0.0
# pif spike trains:
inhspikes = pifspikes(x, trials, dt, D=0.3)
-fig = plt.figure( figsize=(9,4) )
-ax = fig.add_subplot(1, 2, 1)
-ax.set_title('stationary')
-ax.set_xlim(0.0, duration)
-ax.set_ylim(-0.5, trials-0.5)
-ax.set_xlabel('Time [s]')
-ax.set_ylabel('Trials')
-ax.eventplot(homspikes, colors=[[0, 0, 0]], linelength=0.8)
+fig, (ax1, ax2) = plt.subplots(1, 2, figsize=cm_size(figure_width, 0.5*figure_width))
+fig.subplots_adjust(**adjust_fs(fig, left=4.0, right=1.0, top=1.2))
-ax = fig.add_subplot(1, 2, 2)
-ax.set_title('non-stationary')
-ax.set_xlim(0.0, duration)
-ax.set_ylim(-0.5, trials-0.5)
-ax.set_xlabel('Time [s]')
-ax.set_ylabel('Trials')
-ax.eventplot(inhspikes, colors=[[0, 0, 0]], linelength=0.8)
+ax1.set_title('stationary')
+ax1.set_xlim(0.0, duration)
+ax1.set_ylim(-0.5, trials-0.5)
+ax1.set_xlabel('Time [s]')
+ax1.set_ylabel('Trial')
+ax1.eventplot(homspikes, colors=[lsA['color']], linelength=0.8, lw=1)
+
+ax2.set_title('non-stationary')
+ax2.set_xlim(0.0, duration)
+ax2.set_ylim(-0.5, trials-0.5)
+ax2.set_xlabel('Time [s]')
+ax2.set_ylabel('Trial')
+ax2.eventplot(inhspikes, colors=[lsA['color']], linelength=0.8, lw=1)
-plt.tight_layout()
plt.savefig('rasterexamples.pdf')
plt.close()
diff --git a/pointprocesses/lecture/returnmapexamples.py b/pointprocesses/lecture/returnmapexamples.py
index db9326d..99bf88d 100644
--- a/pointprocesses/lecture/returnmapexamples.py
+++ b/pointprocesses/lecture/returnmapexamples.py
@@ -40,19 +40,21 @@ def pifspikes(input, trials, dt, D=0.1) :
spikes.append( times )
return spikes
+
def isis( spikes ) :
isi = []
for k in range(len(spikes)) :
isi.extend(np.diff(spikes[k]))
return np.array( isi )
-def plotreturnmap(ax, isis, lag=1, max=None) :
+
+def plotreturnmap(ax, isis, lag=1, max=1.0) :
ax.set_xlabel(r'ISI$_i$', 'ms')
ax.set_ylabel(r'ISI$_{i+1}$', 'ms')
- if max != None :
- ax.set_xlim(0.0, 1000.0*max)
- ax.set_ylim(0.0, 1000.0*max)
- ax.scatter(1000.0*isis[:-lag], 1000.0*isis[lag:], c=colors['blue'])
+ ax.set_xlim(0.0, 1000.0*max)
+ ax.set_ylim(0.0, 1000.0*max)
+ isiss = isis[isis