From 20332e2013bdcb5781df804c73dc9c2bfac49068 Mon Sep 17 00:00:00 2001 From: Jan Benda Date: Mon, 18 Jan 2021 13:13:35 +0100 Subject: [PATCH] [pointprocesses] improved chapter --- pointprocesses/code/counthist.m | 25 +- pointprocesses/code/isihist.m | 2 +- pointprocesses/code/isis.m | 2 - pointprocesses/code/isiserialcorr.m | 16 +- pointprocesses/code/plotisiserialcorr.m | 16 ++ pointprocesses/code/rasterplot.m | 30 +- pointprocesses/lecture/fanoexamples.py | 40 ++- pointprocesses/lecture/pointprocesses.tex | 330 +++++++++++++--------- pointprocesses/lecture/rasterexamples.py | 2 +- scientificcomputing-script.tex | 3 +- 10 files changed, 272 insertions(+), 194 deletions(-) create mode 100644 pointprocesses/code/plotisiserialcorr.m diff --git a/pointprocesses/code/counthist.m b/pointprocesses/code/counthist.m index 67b4cae..2f5b746 100644 --- a/pointprocesses/code/counthist.m +++ b/pointprocesses/code/counthist.m @@ -1,16 +1,11 @@ -function [counts, bins] = counthist(spikes, w) -% Compute and plot histogram of spike counts. +function counthist(spikes, w) +% Plot histogram of spike counts. % -% [counts, bins] = counthist(spikes, w) +% counthist(spikes, w) % % Arguments: % spikes: a cell array of vectors of spike times in seconds -% w: observation window duration in seconds for computing the counts -% -% Returns: -% counts: the histogram of counts normalized to probabilities -% bins: the bin centers for the histogram - +% w: duration of window in seconds for computing the counts % collect spike counts: tmax = spikes{1}(end); n = []; @@ -21,12 +16,12 @@ function [counts, bins] = counthist(spikes, w) % for tk = 0:w:tmax-w % nn = sum((times >= tk) & (times < tk+w)); % %nn = length(find((times >= tk) & (times < tk+w))); -% n = [n nn]; +% n = [n, nn]; % end % alternative 2: use the hist() function to do that! tbins = 0.5*w:w:tmax-0.5*w; nn = hist(times, tbins); - n = [n nn]; + n = [n, nn]; end % histogram of spike counts: @@ -36,9 +31,7 @@ function [counts, bins] = counthist(spikes, w) counts = counts / sum(counts); % plot: - if nargout == 0 - bar(bins, counts); - xlabel('counts k'); - ylabel('P(k)'); - end + bar(bins, counts); + xlabel('counts k'); + ylabel('P(k)'); end diff --git a/pointprocesses/code/isihist.m b/pointprocesses/code/isihist.m index 00b02c3..a24989c 100644 --- a/pointprocesses/code/isihist.m +++ b/pointprocesses/code/isihist.m @@ -8,7 +8,7 @@ function [pdf, centers] = isihist(isis, binwidth) % binwidth: optional width in seconds to be used for the isi bins % % Returns: -% pdf: vector with probability density of interspike intervals in Hz +% pdf: vector with pdf of interspike intervals in Hertz % centers: vector with centers of interspikeintervalls in seconds if nargin < 2 diff --git a/pointprocesses/code/isis.m b/pointprocesses/code/isis.m index 65a346b..509dcc5 100644 --- a/pointprocesses/code/isis.m +++ b/pointprocesses/code/isis.m @@ -5,11 +5,9 @@ function isivec = isis(spikes) % % Arguments: % spikes: a cell array of vectors of spike times in seconds -% isivec: a column vector with all the interspike intervalls % % Returns: % isivec: a column vector with all the interspike intervalls - isivec = []; for k = 1:length(spikes) difftimes = diff(spikes{k}); diff --git a/pointprocesses/code/isiserialcorr.m b/pointprocesses/code/isiserialcorr.m index 21bb474..1b813fc 100644 --- a/pointprocesses/code/isiserialcorr.m +++ b/pointprocesses/code/isiserialcorr.m @@ -1,15 +1,15 @@ -function isicorr = isiserialcorr(isivec, maxlag) +function [isicorr, lags] = isiserialcorr(isivec, maxlag) % serial correlation of interspike intervals % % isicorr = isiserialcorr(isivec, maxlag) % % Arguments: % isivec: vector of interspike intervals in seconds -% maxlag: the maximum lag in seconds +% maxlag: the maximum lag % % Returns: % isicorr: vector with the serial correlations for lag 0 to maxlag - +% lags: vector with the lags corresponding to isicorr lags = 0:maxlag; isicorr = zeros(size(lags)); for k = 1:length(lags) @@ -21,14 +21,4 @@ function isicorr = isiserialcorr(isivec, maxlag) isicorr(k) = corr(isivec(1:end-lag), isivec(lag+1:end)); end end - - if nargout == 0 - % plot: - plot(lags, isicorr, '-b'); - hold on; - scatter(lags, isicorr, 50.0, 'b', 'filled'); - hold off; - xlabel('Lag k') - ylabel('\rho_k') - end end diff --git a/pointprocesses/code/plotisiserialcorr.m b/pointprocesses/code/plotisiserialcorr.m new file mode 100644 index 0000000..3f21418 --- /dev/null +++ b/pointprocesses/code/plotisiserialcorr.m @@ -0,0 +1,16 @@ +function isicorr = plotisiserialcorr(isivec, maxlag) +% plot serial correlation of interspike intervals +% +% plotisiserialcorr(isivec, maxlag) +% +% Arguments: +% isivec: vector of interspike intervals in seconds +% maxlag: the maximum lag + [isicorr, lags] = isiserialcorr(isivec, maxlag); + plot(lags, isicorr, '-b'); + hold on; + scatter(lags, isicorr, 20.0, 'b', 'filled'); + hold off; + xlabel('Lag k') + ylabel('\rho_k') +end diff --git a/pointprocesses/code/rasterplot.m b/pointprocesses/code/rasterplot.m index 7b28820..ccbfe60 100644 --- a/pointprocesses/code/rasterplot.m +++ b/pointprocesses/code/rasterplot.m @@ -2,21 +2,35 @@ function rasterplot(spikes, tmax) % Display a spike raster of the spike times given in spikes. % % rasterplot(spikes, tmax) +% +% Arguments: % spikes: a cell array of vectors of spike times in seconds -% tmax: plot spike raster upto tmax seconds - +% tmax: plot spike raster up to tmax seconds + in_msecs = tmax < 1.5 + spiketimes = []; + trials = []; ntrials = length(spikes); for k = 1:ntrials times = spikes{k}; times = times(times0$, then the length of an interval is independent of all the previous @@ -282,15 +325,21 @@ thus spike trains may approximate renewal processes. However, other variables like the intracellular calcium concentration or the states of slowly switching ion channels may carry information -from one interspike interval to the next and thus introducing -correlations. Such non-renewal dynamics can then be described by the -non-zero serial correlations (\figref{returnmapfig}). +from one interspike interval to the next and thus introduce +correlations between intervals. Such non-renewal dynamics is then +characterized by the non-zero serial correlations +(\figref{returnmapfig}). \begin{exercise}{isiserialcorr.m}{} - Implement a function \varcode{isiserialcorr()} that takes a vector of - interspike intervals as input argument and calculates the serial - correlation. The function should further plot the serial - correlation. + Implement a function \varcode{isiserialcorr()} that takes a vector + of interspike intervals as input argument and calculates the serial + correlations up to some maximum lag. +\end{exercise} + +\begin{exercise}{plotisiserialcorr.m}{} + Implement a function \varcode{plotisiserialcorr()} that takes a + vector of interspike intervals as input argument and generates a + plot of the serial correlations. \end{exercise} @@ -326,10 +375,11 @@ split into many segments $i$, each of duration $W$, and the number of events $n_i$ in each of the segments can be counted. The integer event counts can be quantified in the usual ways: \begin{itemize} -\item Histogram of the counts $n_i$. For homogeneous Poisson spike - trains with rate $\lambda$ the resulting probability distributions - follow a Poisson distribution (\figref{countstatsfig}), where the - probability of counting $k$ events within a time window $W$ is given by +\item Histogram of the counts $n_i$ appropriately normalized to + probability distributions. For homogeneous Poisson spike trains with + rate $\lambda$ the resulting probability distributions follow a + Poisson distribution (\figref{countstatsfig}), where the probability + of counting $k$ events within a time window $W$ is given by \begin{equation} \label{poissondist} P(k) = \frac{(\lambda W)^k e^{\lambda W}}{k!} @@ -338,7 +388,7 @@ counts can be quantified in the usual ways: \item Variance of counts: $\sigma_n^2 = \langle (n - \langle n \rangle)^2 \rangle$. \end{itemize} -Because spike counts are unitless and positive numbers, the +Because spike counts are unitless and positive numbers the \begin{itemize} \item \entermde{Fano Faktor}{Fano factor} (variance of counts divided by average count) @@ -351,7 +401,6 @@ Because spike counts are unitless and positive numbers, the homogeneous Poisson processes the Fano factor equals one, independently of the time window $W$. \end{itemize} -is an additional measure quantifying event counts. Note that all of these statistics depend in general on the chosen window length $W$. The average spike count, for example, grows @@ -372,33 +421,33 @@ information encoded in the mean spike count is transmitted. \begin{figure}[t] \includegraphics{fanoexamples} - \titlecaption{\label{fanofig} - Count variance and Fano factor.}{Variance of event counts as a - function of mean counts obtained by varying the duration of the - count window (left). Dividing the count variance by the respective - mean results in the Fano factor that can be plotted as a function - of the count window (right). For Poisson spike trains the variance - always equals the mean counts and consequently the Fano factor - equals one irrespective of the count window (top). A spike train - with positive correlations between interspike intervals (caused by - an Ornstein-Uhlenbeck process) has a minimum in the Fano factor, - that is an analysis window for which the relative count variance - is minimal somewhere close to the correlation time scale of the - interspike intervals (bottom).} + \titlecaption{\label{fanofig} Fano factor.}{Counting events in time + windows of given duration and then dividing the variance of the + counts by their mean results in the Fano factor. Here, the Fano + factor is plotted as a function of the duration of the window used + to count events. For Poisson spike trains the variance always + equals the mean counts and consequently the Fano factor equals one + irrespective of the count window (left). A spike train with + positive correlations between interspike intervals (caused by an + Ornstein-Uhlenbeck process) has a minimum in the Fano factor, that + is an analysis window for which the relative count variance is + minimal somewhere close to the correlation time scale of the + interspike intervals (right).} \end{figure} \begin{exercise}{counthist.m}{} Implement a function \varcode{counthist()} that calculates and plots the distribution of spike counts observed in a certain time - window. The function should take two input arguments: (i) a - cell-array of vectors containing the spike times in seconds observed - in a number of trials, and (ii) the duration of the time window that - is used to evaluate the counts. + window. The function should take two input arguments: a cell-array + of vectors containing the spike times in seconds observed in a + number of trials, and the duration of the time window that is used + to evaluate the counts. \end{exercise} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{Time-dependent firing rate} +\label{nonstationarysec} So far we have discussed stationary spike trains. The statistical properties of these did not change within the observation time (stationary point @@ -566,6 +615,7 @@ relevate time-scale. \end{exercise} \section{Spike-triggered Average} +\label{stasec} The graphical representation of the neuronal activity alone is not sufficient tot investigate the relation between the neuronal response diff --git a/pointprocesses/lecture/rasterexamples.py b/pointprocesses/lecture/rasterexamples.py index 07b8628..7a9f4f0 100644 --- a/pointprocesses/lecture/rasterexamples.py +++ b/pointprocesses/lecture/rasterexamples.py @@ -85,7 +85,7 @@ def plot_inhomogeneous_spikes(ax): if __name__ == "__main__": - fig, (ax1, ax2) = plt.subplots(1, 2, figsize=cm_size(figure_width, 0.5*figure_width)) + fig, (ax1, ax2) = plt.subplots(1, 2) fig.subplots_adjust(**adjust_fs(fig, left=4.0, right=1.0, top=1.2)) plot_homogeneous_spikes(ax1) plot_inhomogeneous_spikes(ax2) diff --git a/scientificcomputing-script.tex b/scientificcomputing-script.tex index 13ca240..016a6a4 100644 --- a/scientificcomputing-script.tex +++ b/scientificcomputing-script.tex @@ -116,9 +116,10 @@ \includechapter{pointprocesses} % add a chapter on simulating point-processes/spike trains -% (Poisson spike trains, integrate-and-fire models) +% (Poisson spike trains, LMP models, integrate-and-fire models, full HH like models) % add chapter on information theory, mutual information, stimulus reconstruction, coherence +% move STA here! % add a chapter on Bayesian inference (the Neuroscience of it and a % bit of application for statistical problems).