User Tools

Site Tools


analysis:course:week7

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
analysis:course:week7 [2013/10/27 17:45]
mvdm [Cross-correlation for continuous signals]
analysis:course:week7 [2018/07/07 10:19] (current)
Line 1: Line 1:
-===== Time-frequency analysis II: second-order relationships,​ phase-amplitude relationships ​=====+===== Time-frequency analysis II: cross-frequency coupling ​=====
  
 Goals: Goals:
  
-  * 1 +  * Use the spectrogram as a basis to reveal correlations in power across frequencies 
-  * 2+  * Understand how to compute and interpret autocorrelation and crosscorrelation functions 
 +  * Apply the Hilbert transform to obtain signal phase over time for a given frequency 
 +  * Relate phase of one frequency to power at another by using ''​histc()''​
  
 Deliverables:​ Deliverables:​
  
-  * 1+  * A function averageXbyYbin() that computes the average of signal B based on bins defined over signal A
  
-Resources:+Assignment:
  
-  * +  * Test for coupling between delta phase and low-gamma amplitude in a ventral striatal LFP
-  * 2+
  
 +Resources:
 +
 +  * (background reading, a short review on cross-frequency coupling) Jensen and Colgin, TICS 2007
 +  * (optional, a nice application of the tools covered here) Tort et al. PNAS 2008
 ==== Introduction ==== ==== Introduction ====
  
Line 21: Line 26:
 ==== Reminder: correlation ==== ==== Reminder: correlation ====
  
-A simple yet powerful tool for characterizing dependencies between variables -- such as power in one frequency ​band and another ​-- is Pearson'​s product-moment correlation coefficient (or "​correlation coefficient"​ in short), which for a finite sample can be computed as follows:+A simple yet powerful tool for characterizing dependencies between variables -- such as power in two different ​frequency ​bands -- is Pearson'​s product-moment correlation coefficient ("​correlation coefficient"​ in short). For a finite sample, the correlation coefficient //r// can be computed as follows:
  
 {{ http://​upload.wikimedia.org/​math/​e/​d/​f/​edff63534d48d2756b11b969391bf60e.png?​400 |}} {{ http://​upload.wikimedia.org/​math/​e/​d/​f/​edff63534d48d2756b11b969391bf60e.png?​400 |}}
  
-where x and y are the signals to be correlated, with means of x-bar and y-bar respectively. In other words, ​it is the covariance between X and Y divided by the product of their standard deviations. It is 0 for independent (uncorrelated) signals, -1 for perfectly anticorrelated signals, and 1 for perfectly correlated signals.+where x and y are the signals to be correlated, with means of x-bar and y-bar respectively. In other words, ​//r// is the covariance between X and Ydivided by the product of their standard deviations. It is 0 for independent (uncorrelated) signals, -1 for perfectly anticorrelated signals, and 1 for perfectly correlated signals.
  
 Note that the correlation coefficient only captures //linear// relationships between variables, as can be seen from these scatterplots:​ Note that the correlation coefficient only captures //linear// relationships between variables, as can be seen from these scatterplots:​
  
 {{ http://​upload.wikimedia.org/​wikipedia/​commons/​thumb/​d/​d4/​Correlation_examples2.svg/​400px-Correlation_examples2.svg.png?​400 |}} {{ http://​upload.wikimedia.org/​wikipedia/​commons/​thumb/​d/​d4/​Correlation_examples2.svg/​400px-Correlation_examples2.svg.png?​400 |}}
 +
 +(source: wikipedia)
  
 The MATLAB function ''​corrcoef()''​ computes the sample correlation coefficient,​ and in addition provides the probability of obtaining the reported //r// value under the null hypothesis that the signals are independent ("​p-value"​):​ The MATLAB function ''​corrcoef()''​ computes the sample correlation coefficient,​ and in addition provides the probability of obtaining the reported //r// value under the null hypothesis that the signals are independent ("​p-value"​):​
Line 67: Line 74:
  
 As we would expect, nearby frequencies tend to be correlated. The blob around 80-100Hz indicates that these frequencies tend to co-occur. In contrast, there is a dark patch centered around (60,95) indicating that power in those frequencies is slightly anti-correlated. Note also the positive correlation around (20,60) suggesting that beta and low-gamma power co-occur. This pattern in the cross-frequency correlation matrix is characteristic for ventral striatal LFPs (van der Meer and Redish, 2009). As we would expect, nearby frequencies tend to be correlated. The blob around 80-100Hz indicates that these frequencies tend to co-occur. In contrast, there is a dark patch centered around (60,95) indicating that power in those frequencies is slightly anti-correlated. Note also the positive correlation around (20,60) suggesting that beta and low-gamma power co-occur. This pattern in the cross-frequency correlation matrix is characteristic for ventral striatal LFPs (van der Meer and Redish, 2009).
-=== Autocorrelation for continuous signals === 
  
-The above analysis focused on the //​co-occurrence//​ of power across different frequenciesit asks, "when power at some frequency is high, what does that tell me about the power at other frequencies //at that same time//"? ​+☛ As a second-order method, how this plot looks is sensitive to the parameters of the (first-order) spectrogram. What in this plot changes if you vary the width of the window used to compute the spectrogram?​ 
 + 
 +==== Autocorrelation for continuous signals ==== 
 + 
 +The above analysis focused on the //​co-occurrence//​ of power across different frequenciesit asks, "when power at some frequency is high, what does that imply about the power at other frequencies //at that same time//"? ​
  
 However, often we are also interested in relationships that are not limited to co-occurrence -- for instance, it is possible that power at a certain frequency predicts that **some time later** a power increase in some other band will occur. To characterize such relationships,​ which involve a time lag, we first need the concept of //​autocorrelation//​. However, often we are also interested in relationships that are not limited to co-occurrence -- for instance, it is possible that power at a certain frequency predicts that **some time later** a power increase in some other band will occur. To characterize such relationships,​ which involve a time lag, we first need the concept of //​autocorrelation//​.
  
-== Autocorrelation ​on synthetic signals ==+=== Autocorrelation ​of some synthetic signals ​===
  
 The correlation of a signal with itself is 1 by definition. However, what about the correlation of a signal with the same signal, //one sample later//? For white noise, where each sample is generated independently,​ this should be zero: The correlation of a signal with itself is 1 by definition. However, what about the correlation of a signal with the same signal, //one sample later//? For white noise, where each sample is generated independently,​ this should be zero:
Line 79: Line 89:
 <code matlab> <code matlab>
 wnoise = randn(1000,​1);​ wnoise = randn(1000,​1);​
-[r,p] = corrcoef(wnoise(1:​end-1),​wnoise(2:​end))+[r,p] = corrcoef(wnoise(1:​end-1),​wnoise(2:​end)) ​% same signal, offset by one sample
 </​code>​ </​code>​
  
 Note that when passing two arguments to ''​corrcoef()''​ the output is a 2x2 matrix, where the diagonals are 1 and the off-diagonal elements are of interest. Note that when passing two arguments to ''​corrcoef()''​ the output is a 2x2 matrix, where the diagonals are 1 and the off-diagonal elements are of interest.
  
-We can generalize this example to computing correlations not just for a lag of one sample, as above, but for //any// lag:+We can generalize this example to computing correlations not just for a lag of //one// sample, as above, but for //any// lag. To do this, MATLAB provides the ''​xcorr()''​ function:
  
 <code matlab> <code matlab>
-[acf,lags] = xcorr(wnoise,​100,'​coeff'​);​+[acf,lags] = xcorr(wnoise,​100,'​coeff'​); ​% compute correlation coefficients for lags up to 100
 plot(lags,​acf,'​LineWidth',​2);​ grid on; plot(lags,​acf,'​LineWidth',​2);​ grid on;
 set(gca,'​FontSize',​18);​ xlabel('​time lag (samples)'​);​ ylabel('​correlation ({\itr})'​);​ set(gca,'​FontSize',​18);​ xlabel('​time lag (samples)'​);​ ylabel('​correlation ({\itr})'​);​
Line 96: Line 106:
 {{ :​analysis:​course:​week7_fig2.png?​600 |}} {{ :​analysis:​course:​week7_fig2.png?​600 |}}
  
-As expected, the autocorrelation of white noise is essentially zero for any lag (except 0).+As expected, the autocorrelation of white noise is essentially zero for any lag (except 0). Note the use of [[http://​web.ift.uib.no/​Teori/​KURS/​WRK/​TeX/​symALL.html | LaTeX markup]] to italicize the //r// in the ylabel.
  
 What if we try a signal that is not just white noise, but has a clear periodicity?​ What if we try a signal that is not just white noise, but has a clear periodicity?​
Line 105: Line 115:
  
 wnoise = randn(size(tvec));​ wnoise = randn(size(tvec));​
-sgnl = sin(2*pi*10*tvec) + wnoise; % correlated signal+sgnl = sin(2*pi*10*tvec) + wnoise; % 10 Hz sine wave plus Gaussian white noise
  
 subplot(211);​ subplot(211);​
Line 123: Line 133:
 {{ :​analysis:​course:​week7_fig3.png?​600 |}} {{ :​analysis:​course:​week7_fig3.png?​600 |}}
  
-The autocorrelation ​now has peaks at 0.1s, corresponding to the 10Hz component in the original signal. An intuitive interpretation of this plot is: given a pak in the signal at time t = 0, what on average are the expected values at other times? ​We can see that if there is a peak at 0, then we expect peaks at 0.1, 0.2, etc. and troughs at 0.5, 0.15... .+The autocorrelation ​(acorr) ​has peaks at 0.1s, corresponding to the 10Hz component in the original signal. An intuitive interpretation of this plot is: given a peak in the signal at time t = 0, what on average are the expected values at other times? ​For this signal, we can see that if there is a peak at 0, then we expect peaks at 0.1, 0.2, etc. and troughs at 0.5, 0.15... .
  
-☛ What would you expect the autocorrelation to look like if the above code were modified to use a //​rectified//​ sine wave (''​abs(sin(..))''​)?​ Verify your prediction. When you do, note that the periodicity becomes difficult to see by eye in the raw signal, yet the acorr pulls it out.+☛ What would you expect the autocorrelation to look like if the above code were modified to use a //​rectified//​ sine wave (''​abs(sin(..))''​)?​ Verify your prediction. ​
  
-== Application to real data ==+You should notice that the autocorrelation now has twice the number of peaks compared to the original sine wave. In addition, this periodicity is perhaps not obvious in the original signal, but it is quite clear in the acorr. Autocorrelation functions average out noise that may be obscuring an underlying periodic signal; similarly, autocorrelations of [[http://​www.nature.com/​nature/​journal/​v436/​n7052/​full/​nature03721.html | grid cell rate maps]] often look much more impressive than the original (noisy) rate map! 
 + 
 +A final difference is that there is now a //baseline offset// in the acorr. This occurs because after rectification,​ the original signal no longer has mean zero, and unlike ''​corrcoef()'',​ ''​xcorr()''​ does not actually subtract the mean from the signal(s). 
 + 
 +☛ Subtract the mean from the rectified signal and plot the acorr again. Verify that the value at lag 1 matches the output of ''​corrcoef()''​ for lag 1. 
 + 
 +=== Application to real data ===
  
 Is there any periodicity in ventral striatal gamma power? That is, given high power at t = 0, what values do we expect at other times? If gamma power varies randomly, then we expect the acorr to look like that for white noise. If, on the other hand, high gamma power at time 0 tells us something about what powers to expect at other times, we will see something different. Is there any periodicity in ventral striatal gamma power? That is, given high power at t = 0, what values do we expect at other times? If gamma power varies randomly, then we expect the acorr to look like that for white noise. If, on the other hand, high gamma power at time 0 tells us something about what powers to expect at other times, we will see something different.
Line 134: Line 150:
  
 <code matlab> <code matlab>
-% spectrogram with better time resolution (should use ft; note is slow)+% spectrogram with better time resolution (slow!)
 Fs = 500; Fs = 500;
 d = decimate(Data(cscR),​4);​ d = decimate(Data(cscR),​4);​
Line 150: Line 166:
 pwr2 = mean(P(F_idx2,:​));​ pwr2 = mean(P(F_idx2,:​));​
  
-[ac,lags] = xcorr(pwr2,pwr2,​50,'​coeff'​);​+[ac,lags] = xcorr(pwr2-mean(pwr2),​50,'​coeff'​); ​% remember to subtract the mean!
 lags = lags.*mean(diff(T));​ lags = lags.*mean(diff(T));​
 figure; figure;
Line 162: Line 178:
 {{ :​analysis:​course:​week7_fig4.png?​600 |}} {{ :​analysis:​course:​week7_fig4.png?​600 |}}
  
-Some differences with our reference ​acorss (from white noise, and the 10Hz sine wave) are apparent. First, the central peak around t = 0 now has a certain nonzero width: if we have a high low-gamma power at time t = 0, power tends to stay elevated for a certain amount of time. Judging from the inflection point at around 0.2s, it appears that if low gamma power is high, it takes about 0.2s to return to a kind of baseline.+Some differences with our reference ​acorrs ​from the previous section (white noise, and the 10Hz sine wave) are apparent. First, the central peak around t = 0 now has a certain nonzero width: if we have a peak in low-gamma power at time t = 0, power tends to stay elevated for a certain amount of time. Judging from the inflection point at around 0.2s, it appears that if low gamma power is high, it takes about 0.2s to return to a kind of baseline.
  
 ☛ What do you expect would happen to the width of this central peak if you were to change the width of the time window used to compute the spectrogram,​ say to twice the original width? ☛ What do you expect would happen to the width of this central peak if you were to change the width of the time window used to compute the spectrogram,​ say to twice the original width?
  
-Second, a small dip in the baseline is apparent around 0.6s. This suggests that if we have high low-gamma power at t = 0, we are less likely than average to see high gamma power 0.6s later. +Second, a small dip in the baseline is apparent around 0.6s. This suggests that if we have high low-gamma power at t = 0, we are less likely than average to see high gamma power 0.6s later. ​This is an example of a "​second-order"​ effect: we build on our "​first-order"​ analysis (the spectrogram) to reveal further structure in how gamma power is organized over time.  
-  +==== Cross-correlation for continuous signals ​====
-=== Cross-correlation for continuous signals ===+
  
-The //​autocorrelation//​ computes the correlation of a signal with itself over some different time lags. The //​cross-correlation//​ does the same but between two //​different//​ signals. It asks: given a peak in signal 1 at time zero, what do we know about signal 2?+The //​autocorrelation//​ computes the correlation of a signal ​//with itself// over some different time lags. The //​cross-correlation//​ does the same but between two //​different//​ signals. It asks: given a peak in signal 1 at time zero, what do we know about signal 2?
  
 Let's apply this idea to ventral striatal gamma power by asking how high-gamma power varies given a peak in low-gamma power at t = 0: Let's apply this idea to ventral striatal gamma power by asking how high-gamma power varies given a peak in low-gamma power at t = 0:
Line 181: Line 196:
 pwr2 = mean(P(F_idx2,:​));​ pwr2 = mean(P(F_idx2,:​));​
  
-[ac,lags] = xcorr(pwr,​pwr2,​50,'​coeff'​);​+[ac,lags] = xcorr(pwr-mean(pwr),pwr2-mean(pwr2),​50,'​coeff'​); ​% note, two different input signals now
 lags = lags.*mean(diff(T));​ lags = lags.*mean(diff(T));​
 figure; figure;
Line 193: Line 208:
 {{ :​analysis:​course:​week7_fig5.png?​600 |}} {{ :​analysis:​course:​week7_fig5.png?​600 |}}
  
-A clear peak in the xcorr is visible: high-gamma power tends to be maximal about 0.25s //before// a peak in low-gamma power. ​Note that the xcorr is asymmetric: a low-gamma peak does not predict elevated ​high-gamma power to follow as strongly as in the other direction. In other words, if there is strong high-gamma, then low-gamma is likely to follow, but the reverse is the case to a lesser extent (if at all). This result is consistent with the pattern we saw in the spectrogram in the previous module.+Note that the xcorr is asymmetric: ​given a low-gamma peak at t = 0, high-gamma power tends to be higher before, rather than after this time. In other words, if there is strong high-gamma, then low-gamma is likely to follow, but the reverse is the case to a lesser extent (if at all). You can verify this by reversing the order of the inputs into ''​xcorr()'',​ which will yield a mirror image flipped around time zero. This result is consistent with the pattern we saw in the spectrogram in the previous module, where high-gamma tends to be closely followed by low-gamma, but not the other way around. 
 +==== Extracting signal phases ==== 
 + 
 +In the previous section, we explored the relationships between different power bands of a signal. Such relationships are a form of //​cross-frequency coupling//: what happens in one frequency band depends on what happens in another. Such cross-frequency relationships are not limited to //power//, but can also extend to //phase//, as the following figure (from [[http://​www.ncbi.nlm.nih.gov/​pubmed/​17548233 | Jensen and Colgin, 2007]]) illustrates:​ 
 + 
 +{{ :​analysis:​course:​jensen_colgin_fig1.png?​750 |}} 
 + 
 +The power-to-power coupling (a) we have explored using the correlation matrix of the spectrogram. To reveal cross-frequency coupling involving phase, we need a way to extract the phase of a signal. One way to accomplish this is to use the Hilbert transform:​ 
 + 
 +<code matlab>​ 
 +Fs = 500; dt = 1./Fs; 
 +tvec = 0:​dt:​1-dt;​ 
 + 
 +wnoise = randn(size(tvec));​ 
 +sgnl = sin(2*pi*4*tvec) + 0.1*wnoise;​ 
 + 
 +h = hilbert(sgnl);​ 
 +phi = angle(h); 
 +</​code>​ 
 + 
 +The Hilbert transform of a periodic signal returns a complex quantity that, similar to the Fourier transform, contains both amplitude and phase information. Here, we access the phase component by ''​angle(h)''​ (the amplitude would be obtained by ''​abs(h)''​),​ and plot it with some ''​plotyy()'',​ a nice function that gives two signals their own y-axis: 
 + 
 +<code matlab>​ 
 +[ax_h,​h1,​h2] = plotyy(tvec,​sgnl,​tvec,​phi);​ 
 +set(ax_h(2),'​YColor',​[1 0 0],'​YLim',​[-pi pi],'​YTick',​-pi:​pi/​2:​pi,'​YTickLabel',​{'​-p','​-p/​2','​0','​p/​2','​p'​},​ ... 
 +   '​fontname','​symbol','​XTick',​[]);​ 
 +set(h2,'​Color',​[1 0 0]); 
 +set(get(ax_h(2),'​Ylabel'​),'​String','​phase (radians)'​)  
 +box off; 
 +</​code>​  
 + 
 +The result: 
 + 
 +{{ :​analysis:​course:​week7_fig6.png?​600 |}} 
 + 
 +Obviously, phase is only defined for a signal with sufficiently narrow frequency content. Thus, for real data, the application of the Hilbert transform to extract signal phase should be preceded by a bandpass filter. 
 + 
 +A further caveat when extracting phase is that if the signal gets small relative to the noise, phases still get returned, but they can get unreliable without warning. 
 + 
 +☛ Contaminate the above signal with increasing amounts of noise to verify this. 
 + 
 +==== Relating signal phases to amplitude ==== 
 + 
 +=== Synthetic data === 
 + 
 +How can we detect relationships between phase and amplitude? It will be helpful to first generate a test signal that displays phase-amplitude coupling: 
 + 
 +<code matlab>​ 
 +Fs = 500; dt = 1./Fs; 
 +tvec = 0:​dt:​1-dt;​ 
 + 
 +f1 = 8; 
 +s1 = sin(2*pi*f1*tvec)+0.05*randn(size(tvec));​ 
 +s1_phi = angle(hilbert(s1));​ % phase of slow signal 
 +dphi = exp(-abs(s1_phi)/​1.5);​ % envelope with peaks at phase 0, based on slow phase 
 + 
 +f2 = 80; 
 +s2 = 0.3.*sin(2*pi*f2*tvec).*dphi;​ % fast oscillation multiplied by envelope 
 + 
 +s = s1+s2; 
 +plot(tvec,​s);​ xlim([0 0.5]); 
 +</​code>​ 
 + 
 +This gives 
 + 
 +{{ :​analysis:​course:​week7_fig7.png?​600 |}} 
 + 
 +Notice how the fast (80Hz) oscillation is strongest at the peaks of the slow (8Hz) signal. Given such a signal, we may wonder if we can extract this relationship by computing the correlation coefficient between phase (of the slow signal) and power (of the fast signal). However, as ''​corrcoef(s1_phi,​dphi)''​ will demonstrate,​ the correlation is in fact zero. This is because the relationship between phase and power is //​non-linear//:​ starting from the most negative phase, power first increases with phase until the phase is zero, and then decreases again in a symmetric fashion. A linear measure such as Pearson'​s correlation coefficient cannot detect this, as illustrated in the figure in the first section. 
 + 
 +A general-purpose workaround is to divide signal phase into bins, and compute the average power for each bin. We can then ask if power varies as a function of bin, which if true would indicate cross-frequency phase-amplitude coupling. 
 + 
 +To do this, we can define a function ''​averageXbyYbin()''​ as follows: 
 + 
 +<code matlab>​ 
 +function x_avg = averageXbyYbin(x,​y,​y_edges) 
 + 
 +[~,idx] = histc(y,​y_edges);​ % idx returns which bin each point in y goes into 
 + 
 +x_avg = zeros(size(y_edges));​ 
 +for iBin = length(y_edges):​-1:​1 % for each bin... 
 +    
 +   if sum(idx == iBin) ~= 0 % at least one sample in this bin 
 +      x_avg(iBin) = nanmean(x(idx == iBin)); % compute average of those x's that go in it 
 +   end 
 +     
 +end 
 +</​code>​ 
 + 
 +One quirk of MATLAB'​s phenomenally useful ''​histc()''​ function is that it creates N bins out of N edges, when perhaps N-1 bins would be more intuitive. This is because the Nth output bin is for those data points that fall exactly on the Nth edge. Thus, to plot our output correctly, we have to do something like 
 + 
 +<code matlab>​ 
 +phi_edges = -pi:​pi/​8:​pi;​ 
 +pow_bin = averageXbyYbin(dphi,​s1_phi,​phi_edges);​ 
 + 
 +pow_bin(end-1) = pow_bin(end-1)+pow_bin(end);​ % add counts on last edge to preceding bin 
 +pow_bin = pow_bin(1:​end-1);​ % trim 
 + 
 +phi_centers = phi_edges(1:​end-1)+pi/​16;​ % convert edges to centers 
 +plot(phi_centers,​pow_bin);​ 
 +</​code>​ 
 + 
 +The output shows that we have recovered the original phase-amplitude relationship. The ''​averageXbyYbin()''​ function can be modified to also return standard deviations, or even the full distributions,​ for each bin to permit statistical significance testing.  
 + 
 +=== Real data === 
 + 
 +The cross-frequency power correlation matrix above suggests that low-gamma power (~45-65Hz) co-occurs with delta power (3-4Hz). This raises the possibility that low-gamma power is modulated by the phase of the delta rhythm. 
 + 
 +☛ Plot the average low-gamma power as a function of delta phase for the ventral striatal LFP used previously in this module. As with the cross-frequency correlation plot above, restrict your analysis to the risk session only. You can use a skeleton like the following:​ 
 + 
 +<code matlab>​ 
 +%% load and restrict the data 
 + 
 +%% define frequency ranges of interest 
 + 
 +%% design filters for frequency ranges 
 + 
 +%% filter the data (remember to use filtfilt!) 
 + 
 +%% extract delta phase and low gamma power 
 + 
 +%% use averageXbyYbin to plot relationship (ideally with standard deviations) 
 +</​code>​ 
 + 
 +In fact, the above is unlikely to work "out of the box" because for much of the session, there is very little delta power. Thus, the phases that will be extracted will be essentially random, as we noted above. The code you used to detect sharp wave-ripple complexes in Module 5 can be adapted to exclude epochs without much delta power.
analysis/course/week7.1382910300.txt.gz · Last modified: 2018/07/07 10:19 (external edit)