Back to the main page.

Bug 2523 - implement ft_crossfrequencyanalysis function, pipeline and documentation

Reported 2014-04-03 15:46:00 +0200
Modified 2017-07-06 12:33:34 +0200
Product: FieldTrip
Component: core
Version: unspecified
Hardware: PC
Operating System: Windows
Importance: P5 normal
Assigned to: R Seymour
Depends on:
See also:

Haiteng Jiang - 2014-04-03 15:46:19 +0200

The goal is to implement FT_CFC function , which performs cross frequency analyses between the phase data (low frequency )obtained from the power data (high frequency). The rough idea is as following: cfg=[]; cfg.freq1 =2:20; % frequency of phase cfg.freq2 =20:10:120; % frequency of amplitude cfg.toi =[0 1]; % time of interest cfg.crsschan =eye(length(data.label)); % specifies what to use for phase and what for amplitude. It should support phase of one electrode and amplitude of another electrode cfg.method='ModulationIndex'; % different CFC method CFC=ft_CFC(cfg,data); related function: integration with ft_connectivityanalysis. Some function is overlapping To be discussed pipeline: ft_preprocess----->ft_freqanalysis (low frequency phase/ high frequency amplitude)-------> ft_appenddatacfc?--------->ft_cfc

Jörn M. Horschig - 2014-04-03 15:54:32 +0200

I can see why many people would want this, but as far as I remember the reason why it is not implemented is because: a) there is no gold-standard what method to use, and also no objective way to determine one b)

Jörn M. Horschig - 2014-04-03 15:55:17 +0200

(In reply to Jörn M. Horschig from comment #1) yea, and I wanted to delete that comment, because I saw that apparently JM and Robert changed their minds on this ;) so ignore comment 1!

Johanna - 2014-04-04 13:54:10 +0200

To back up Jorn: see bug 532. Maybe for clarity it should be called ft_phaseamplitude rather than CFC? Unless the idea is to generalise it to other types of CFC later.

Robert Oostenveld - 2014-04-04 14:52:29 +0200

(In reply to Johanna from comment #3) I think it could do various cross-frequency measures, also power-power, phase-phase etc. The overall structure of dealing with freq twice would be shared and probably the computational details are similar enough to accommodate all of them.

Haiteng Jiang - 2014-04-05 21:22:48 +0200

Yes , we can implement different methods (e.g. phase locking value , mean vector length ,cross spectrum coherence , modulation index...). At this moment, I have two major concerns . First , some method is quite computational expensive (e.g Modulation index). Another problem is that no one reported frequency *frequency comodulogram CFC so far on MEG data to my knowledge. The existed papers only showed specific frequency pair coupling. Therefore , we need to find a dataset . Nevertheless , I am going to try to my MEG data first.

Eelke Spaak - 2014-04-23 11:37:21 +0200

Hmm this seems a duplicate of bug 532? (Hesitant to mark it as duplicate for now, given some of the comments above.)

Haiteng Jiang - 2014-04-25 08:17:56 +0200

Hi Eelke, Thanks for pointing it out. I didn't know that we had plans to implement this long time ago! Of course , it is a lot of work. Ignorant and fearless newbie is taking the challenge. I think it does make sense to implement some widely-used CFC measures and then it is up to the users choose . We can go step by step. The main issue is the time and computation load if you think (multiple channels /trials; loop for high frequency and low frequency/ cross-channels) or even later statistic. Actually I and Ole are speeding the code right now. After I submit my paper to Journal of Neuroscience Methods special issue (the deadline is the end of May), I am going to incorporate with Fieldtrip. You are most welcome to have a joint effort . Later , we can also consider implementing the cross-frequency directionality stuff in Fieldtip.

Haiteng Jiang - 2014-05-04 09:45:43 +0200

Created attachment 622 implement ft_crossfrequencyanalysis function

Haiteng Jiang - 2014-05-04 09:52:25 +0200

Hi all, I just had my first ft_crossfrequencyanalysis implementation . Please see the previous attachment. At this moment , it supports within-channel CFC (three methods: phase locking value , mean vector length , modulation index). After we discuss the pipeline , I am going to extend. Comments are welcome.It works in the following way: % Pre-processed data %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% f1 =4:1:20; % interest low frequency range of CFC f2 =30:10:150; % interest high frequency range of CFC %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % extract low frequency signal %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% cfg = []; cfg.output = 'fourier'; = 'all'; cfg.method = 'mtmconvol'; cfg.taper = 'hanning'; cfg.foi = f1; cfg.t_ftimwin = ones(length(cfg.foi),1).*0.5; cfg.toi = 0.5:1/data.fsample:3.5; LFsig = ft_freqanalysis(cfg, data); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % extract high frequency envelope signal %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% cfg = []; cfg.output = 'fourier'; = 'all'; cfg.method = 'mtmconvol'; cfg.taper = 'hanning'; cfg.foi = f2; cfg.t_ftimwin = 5./cfg.foi; cfg.toi = 0.5:1/data.fsample:3.5; HFsig = ft_freqanalysis(cfg, data); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % ft_crossfreqanalysis %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% tic; cfg =[]; cfg.method ='plv'; % or mvl/mi cfg.keeptrials = 'no'; CFC = ft_crossfreqanalysis(cfg,LFsig,HFsig); Best, Haiteng

Robert Oostenveld - 2014-07-04 12:46:04 +0200

Since both Diego and I would like to start contributing to this function, I'll take the existing code and add it to fieldtrip. Subsequently I will start working on it, making it more FT-like and ensure compatibility with other functions and data structures.

Robert Oostenveld - 2014-07-04 12:52:29 +0200

mac011> svn commit Adding ft_crossfrequencyanalysis.m Sending ft_freqstatistics.m Sending private/msphere.m Sending private/refine.m Transmitting file data .... Committed revision 9694. bummer! I accidentally also committed changes to three other functions. The change to msphere is minor. The change to refine pertains to a planned functionality enhancement, it now has "fix me" in the relevant piece of code. It should not hurt anyone. ft_freqstatistics is messed up, so I will revert it to the previous version (more or less). The part of the code that I'll remove is based on this mac011> svn commit Sending ft_freqstatistics.m Transmitting file data . Committed revision 9696.

Robert Oostenveld - 2014-07-04 13:21:12 +0200

(In reply to Robert Oostenveld from comment #11) I made the function code and documentation consistent with fieldtrip standards, using code from ft_examplefunction. mac011> svn commit ft_crossfrequencyanalysis.m Sending ft_crossfrequencyanalysis.m Transmitting file data . Committed revision 9697.

Robert Oostenveld - 2014-07-04 13:32:14 +0200

mac011> svn commit Sending ft_crossfrequencyanalysis.m Adding test/test_ft_crossfrequencyanalysis.m Transmitting file data .. Committed revision 9698. The test script is basically the one from the 7z file, after formatting it in FT fashion. The test script runs and the output looks ok to me.

Robert Oostenveld - 2014-07-04 13:48:27 +0200

mac011> svn commit Sending ft_crossfrequencyanalysis.m Sending test/test_ft_crossfrequencyanalysis.m Transmitting file data .. Committed revision 9699.

Haiteng Jiang - 2014-07-07 12:25:46 +0200

(In reply to Robert Oostenveld from comment #14) Hi Robert, Thanks for the initializing. It works pretty good . I am very happy that you and Dieog join the development. To make this function more powerful , we might need some sub functions to make it more extensive like 'ft_connectivityanalysis (ft_connectivity_dtf,ft_connectivity_pdf,etc)'. Thus, we can have ft_crossfrequency_mvl,ft_crossfrequency_mi,ft_crossfrequency_plv) subfunctions as well. Of course , we can support time-dynamic CFC in these subfunctions. Let us implement this first and then test the influence on the way how we estimate the phase/power as we discussed in the FT meeting.

Robert Oostenveld - 2014-07-07 12:33:31 +0200

(In reply to Haiteng Jiang from comment #15) right now the low level functions are relatively small and therefore I do not yet see the need for having them outside the main ft_crossfrequencyanalysis function. We have done this for ft_conenctivityanalysis, but maintaining the two sets of function is also work. Let's put this on the agenda for Wednesday.

Jan-Mathijs Schoffelen - 2016-02-19 11:53:12 +0100

is this ever going to happen?

Diego Lozano Soldevilla - 2016-02-19 16:25:52 +0100

(In reply to Jan-Mathijs Schoffelen from comment #17) If no one wants to do it (as it seems), I've planned to do it at some piont. If there's no rush I'll contribute with CFC measures like bicoherence, cross-frequency coherence, weighted-phase locking factor... I can use the simulations of my thesis to write down a wiki example script or minitutorial about how the distinct CFC provide spurious correlations.

Haiteng Jiang - 2016-02-21 11:57:52 +0100

(In reply to Diego Lozano Soldevilla from comment #18 Hi Deigo, I am fine if you take over. I don't have time for this in the next a few months anyway (leaving Holland this month, one month holiday in China, moving to US....). Nevertheless, the core code ft_crossfreqanalysis I wrote before is over there. We can add more CFC measures and write down a detailed tutorial. Digeo, you have my own CFC implementation (independent of FT ) as well, so it shouldn't be too difficult to merge. As you pointed out, it is also important to keep in mind how artifactual CFC generates. We should make readers be aware of this. Overall, I think a joint effort with you will be best. Let me know how do you think.

Diego Lozano Soldevilla - 2016-02-22 16:30:24 +0100

(In reply to Haiteng Jiang from comment #19) Thanks for your reply Haiteng. Not clear to me if you want to take over or not. Given you've your own CFC implementation (outside of FT) and it's easy to merge, I propose you to merge it. In the end, I create my own CFC functions to deal with MEG data and I've to start from scratch anyway to follow FT flow (new CFC measures, channel pairs support, etc). If you don't have the time, I'll take over ;)

Haiteng Jiang - 2016-02-28 09:27:42 +0100

(In reply to Diego Lozano Soldevilla from comment #20) Hi Diego, let us distribute the tasks and be clear for the individual responsibility. I will implement the CFC measure in my NeuroImage paper ( coherence, phase locking, mean vector length, modulation index) and you take care of other measures (e.g., bicoherence, weighted-phase locking factor...). The main tasks are actually integrating with FT structure and plotting. I am planning to work on this after I settle down in US (around June I think). Nevertheless, let us keep communicating and updating each other . All the best, Haiteng

Jan-Mathijs Schoffelen - 2016-11-29 09:29:16 +0100

Any news here?

R Seymour - 2017-07-05 11:40:11 +0200

Hi all, Have written some MATLAB PAC code which could be adapted for use in ft_crossfrequencyanalysis. There could involve various things for example: - Code for 4 approaches (Tort, Ozkurt, Canolty, Cohen) + more as necessary - Extending this code for trial-based data - Application of surrogate data (shuffled, shifted, amplitude swapped) - Production of phase-amplitude comodulograms - Simulated PAC for validation of results - Code for calculating preferred phase Does this sound OK? I don't want to tread on anyone's toes but seems like work on this has stagnated. Cheers, Robert (PhD student - Aston Brain Centre & Macquarie University)

Diego Lozano Soldevilla - 2017-07-05 11:50:07 +0200

(In reply to R Seymour from comment #23) Go ahead! Fine with me

Robert Oostenveld - 2017-07-06 12:33:34 +0200

Hi Robert, Work on this has indeed stalled, your contribution on this would be very welcome! I suggest that you go through and that you make a branch in which you develop this functionality. That allows for easy reviewing and commenting on the code, without messing up the stable release version along the way. You can then send a pull request, which we can review and merge. Furthermore, it would be very valuable to see the (user) interface of the function at work in a test script (in fieldtrip/test), which is part of that branch. Most important in that test script is to demonstrate how it would work. Showing the correctness of the methods would also be nice, but is a second concern. My experience is that the details of the user interface sometimes need discussion in order to align the new functionality with FieldTrip in general. The script could start with simulating data with a few channels and random data.