MEG visual tutorial: Group analysis (BIDS)

Authors: Francois Tadel, Elizabeth Bock.

The aim of this tutorial is to reproduce in the Brainstorm environment the analysis described in the SPM tutorial "Multimodal, Multisubject data fusion". It is part of a collective effort to document and standardize MEG/EEG group analysis, see Frontier's research topic: From raw MEG/EEG to publication: how to perform MEG/EEG group analysis with free academic software.

The data processed here consists in simultaneous MEG/EEG recordings of 16 subjects performing a simple visual task on a large number of famous, unfamiliar and scrambled faces. This tutorial follows another page that explains how to process one single subject in details.

License

This dataset was obtained from the OpenNeuro project (https://openneuro.org/), accession #ds117. It is made available under the Creative Commons Attribution 4.0 International Public License. Please cite the following reference if you use these data:
Wakeman DG, Henson RN, A multi-subject, multi-modal human neuroimaging dataset, Scientific Data (2015)
Any questions, please contact: rik.henson@mrc-cbu.cam.ac.uk

For citing the analysis, the processing pipeline is published in this article:
Tadel F, Bock E, Niso G, Mosher JC, Cousineau M, Pantazis D, Leahy RM, Baillet S, MEG/EEG Group Analysis With Brainstorm, Frontiers in Neuroscience, Feb 2019

Download and installation

First, make sure you have enough space on your hard drive, at least 40Gb:

You can follow this tutorial after processing the recordings for the 16 good subjects (6 runs per subject) as illustrated in the single subject tutorial. Otherwise, we provide a Brainstorm protocol that includes all the imported data, downsampled at 275Hz:

The database you need in order to follow this tutorial should contain the following:

Overview of the analysis

Coregistration of the acquisition runs

For each subject, all the runs have been registered to a common head position with MaxFilter. To verify this, select all the channel files within one subject, right-click > Display sensors > MEG (all). The surfaces representing the MEG helmet are perfectly overlapping for all the runs. When the runs are not aligned, it looks like this.

This means we can safely average or compare the MEG sensor values across runs within one subject. However, it is not reliable to average MEG recordings across subjects, because of the anatomical differences between subjects.

This doesn't mean we can estimate the sources only once per subject. We have computed different SSP projectors and selected different bad channels for each acquisition run. To be able to use this information efficiently we should estimate the sources for each run separately, then average the sources across runs.

The forward model is the same for all the runs within one subject, therefore it can be computed for the first run and copied to all the other runs.

Objectives

The objectives for this tutorial are to reproduce the analysis presented in the following documents:

Summary of the results we will compute in this tutorial:

Expected effects:

The methodology that we will follow for computing the averages and the other statistics is described in the tutorial "Workflows".

This tutorial page illustrates how to run the analysis using the interface. In practice, with a larger number of subjects, going through all these steps manually with the Brainstorm GUI is not practical, time consuming and prone to manipulation errors. We encourage our users to script their group analyses instead of performing all these steps manually. Typically, one would select a few subjects, prototype the group analysis pipeline with the interactive interface, generate the corresponding Matlab script, and finally run it on all the subjects of the database in reproducible way. Assembling a processing script is discussed in the online tutorial Scripting and illustrated with the scripts tutorial_frontiers2018*.m.

Subject averages: Famous, Unfamiliar, Scrambled

We will start by computing the subject-level averages for all the data types we have: sensor-level recordings, source maps and time-frequency results. We will use a weighted average to group the results we have for each run (weighted by the number of good trials). We want to compute the averages for each experimental condition separately (famous, unfamiliar, scrambled).

Since the files are already selected in the interface, we will also compute a grand average across subject. In this context, we will consider that each subject has the same weight in the grand average (option "weighted" not selected). Note that it is not accurate to average MEG recordings across subjects, but we can do it just to get a general idea of the group effects (more information).

MEG/EEG

Sources

Time-frequency

Subject averages: Faces

One of the contrast we want to study is faces (Famous and Unfamiliar) vs non-faces (Scrambled). We need to re-average the Famous and Unfamiliar averages together.

MEG/EEG

Sources

Time-frequency

Subject averages: Within-subject differences

To detect correctly the differences between two conditions at the source level, we need to estimate the differences of the conditions for each subject, and then normalize the difference (see tutorial Workflows).

Sources: Faces - Scrambled

Sources: Famous - Unfamiliar

Subject averages: Filter and normalize

Before comparing the averages across subjects we are going to low-pass filter the signals below 32Hz (to smooth possible latency differences between subjects) and normalize the source and time-frequency values with respect with a baseline (see tutorial Workflows).

MEG/EEG

Sources

Time-frequency

Subject averages: Screen captures

Now we have all the measures ready to be compared across subjects: MEG/EEG, sources, time-frequency. Let's take a few screen captures to make sure the primary visual response look good for all the subjects. The screen captures below represent from left to right:

sub-01
sub002.gif

sub-02
sub003.gif

sub-03
sub004.gif

sub-04
sub006.gif

sub-05
sub007.gif

sub-06
sub008.gif

sub-07
sub009.gif

sub-08
sub010.gif

sub-09
sub011.gif

sub-10
sub012.gif

sub-11
sub013.gif

sub-12
sub014.gif

sub-13
sub015.gif

sub-14
sub017.gif

sub-15
sub018.gif

sub-16
sub019.gif

Group analysis: MEG/EEG

Grand averages

We have already computed the group averages for all the conditions. We will not look much further at these results as we are more interested in the contrasts between conditions. Below are screen captures for all group averages (top=MEG MAG, bottom=EEG). Topography at [50,100,150,200,250,300]ms.

Faces: Famous / Unfamiliar

gavg_data_famous.gif gavg_data_unfamiliar.gif

Scrambled
gavg_data_scrambled.gif

Faces - Scrambled: Differences of averages

We could compute the contrasts directly from the grand averages, but we will do it from the subject averages because it will be the same file selection for the statistics.

Faces - Scrambled: Significance testing

We have computed the amplitude of the difference between the two conditions, and we will try now to estimate a p-value indicating the significance of each of these values. In all the screen captures below: top=MEG MAG, bottom=EEG.

Famous - Unfamiliar: Differences of averages

Famous - Unfamiliar: Significance testing

Group analysis: Sources

Project sources on template

The sources were estimated on the individual anatomy of each subject, the resulting cortical source maps cannot be averaged directly. We need first to re-interpolate all the individual results on a common template (the ICBM152 brain, available in the "default anatomy" folder of the protocol). We also need to extract the absolute values for these source maps: the sign of the minimum norm maps are relative to the orientation of the current with respect to the surface normal, which can vary between subjects.

Spatial smoothing

The source maps estimated with constrained orientations can show very focal activity: two adjacent vertices may have very different normals, and therefore very different current values. When averaging multiple subjects, the peaks of activity may not align very well across subjects. Smoothing spatially the source maps may help obtaining better group results.

MEG: mean(|Faces-Scrambled|)

MEG: Chi2-test |Faces-Scrambled|=0

MEG: Chi2-test log(|Faces-Scrambled|)=0

MEG: mean(|Faces|)-mean(|Scrambled|)

MEG: Student t-test |Faces|=|Scrambled|

EEG: Faces-Scrambled

Scripting

The following script from the Brainstorm distribution reproduces the analysis presented in this tutorial page: brainstorm3/toolbox/script/tutorial_visual_group.m

Execution reports: Subject averages, MEG/EEG group results, Source group results

1 function tutorial_visual_group(ProtocolName, reports_dir) 2 % TUTORIAL_VISUAL_GROUP: Runs the Brainstorm/SPM group analysis pipeline (group analysis, BIDS VERSION) 3 % 4 % ONLINE TUTORIALS: 5 % - https://neuroimage.usc.edu/brainstorm/Tutorials/VisualSingle 6 % - https://neuroimage.usc.edu/brainstorm/Tutorials/VisualGroup 7 % 8 % INPUTS: 9 % - ProtocolName : Name of the protocol in which the recordings for the 19 subjects have been imported (TutorialVisual or TutorialGroup) 10 % This folder must include: the run-level averages (recordings and time-frequency) and the source kernels for each run 11 % - reports_dir : If defined, exports all the reports as HTML to this folder 12 13 % @============================================================================= 14 % This function is part of the Brainstorm software: 15 % https://neuroimage.usc.edu/brainstorm 16 % 17 % Copyright (c) University of Southern California & McGill University 18 % This software is distributed under the terms of the GNU General Public License 19 % as published by the Free Software Foundation. Further details on the GPLv3 20 % license can be found at http://www.gnu.org/copyleft/gpl.html. 21 % 22 % FOR RESEARCH PURPOSES ONLY. THE SOFTWARE IS PROVIDED "AS IS," AND THE 23 % UNIVERSITY OF SOUTHERN CALIFORNIA AND ITS COLLABORATORS DO NOT MAKE ANY 24 % WARRANTY, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF 25 % MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, NOR DO THEY ASSUME ANY 26 % LIABILITY OR RESPONSIBILITY FOR THE USE OF THIS SOFTWARE. 27 % 28 % For more information type "brainstorm license" at command prompt. 29 % =============================================================================@ 30 % 31 % Author: Francois Tadel, Elizabeth Bock, 2016-2018 32 33 % ===== CHECK PROTOCOL ===== 34 % Start Brainstorm without the GUI 35 if ~brainstorm('status') 36 brainstorm nogui 37 end 38 % Output folder for reports 39 if (nargin < 2) || isempty(reports_dir) || ~isdir(reports_dir) 40 reports_dir = []; 41 end 42 % You have to specify the folder in which the tutorial dataset is unzipped 43 if (nargin < 1) || isempty(ProtocolName) 44 ProtocolName = 'TutorialGroup'; 45 end 46 % Select current protocol 47 iProtocol = bst_get('Protocol', ProtocolName); 48 if isempty(iProtocol) 49 error(['Unknown protocol: ' ProtocolName]); 50 end 51 if (iProtocol ~= bst_get('iProtocol')) 52 gui_brainstorm('SetCurrentProtocol', iProtocol); 53 end 54 % Process: Select results files in: sub-01/sub-01_ses-meg_task-facerecognition_run-01_proc-sss_meg_notch 55 sFiles = bst_process('CallProcess', 'process_select_files_results', [], [], ... 56 'subjectname', 'sub-01', ... 57 'condition', 'sub-01_ses-meg_task-facerecognition_run-01_proc-sss_meg_notch'); 58 if isempty(sFiles) 59 error(['No source files available in folder: sub-01/sub-01_ses-meg_task-facerecognition_run-01_proc-sss_meg_notch.' 10 ... 60 'You should run tutorial_visual_single first, or download the ' 10 ... 61 'protocol TutorialGroup.zip from the Brainstorm website.']); 62 end 63 % Process: Select file comments with tag: Unconstr 64 sFiles = bst_process('CallProcess', 'process_select_tag', sFiles, [], 'tag', 'Unconstr'); 65 if ~isempty(sFiles) 66 isUnconstrained = 1; 67 else 68 isUnconstrained = 0; 69 end 70 % Start a new report 71 bst_report('Start'); 72 73 74 % ===== DELETE ALL THE EXISTING FILES ===== 75 GroupSubjectName = bst_get('NormalizedSubjectName'); 76 DirIntra = bst_get('DirAnalysisIntra'); 77 % Delete group analysis 78 [sSubject, iSubject] = bst_get('Subject', GroupSubjectName); 79 if ~isempty(sSubject) 80 db_delete_subjects(iSubject); 81 end 82 % Get all the files in the intra subjects 83 sAvgSrc = bst_process('CallProcess', 'process_select_files_data', [], [], ... 84 'subjectname', 'All', ... 85 'condition', DirIntra, ... 86 'includeintra', 1); 87 % If there are existing files: delete the contents of the folders 88 if ~isempty(sAvgSrc) 89 % Get the base folder of the protocol 90 ProtocolInfo = bst_get('ProtocolInfo', iProtocol); 91 % Get all the folders 92 AllIntraDir = unique(cellfun(@bst_fileparts, {sAvgSrc.FileName}, 'UniformOutput', 0)); 93 % Loop over the intra folders 94 for iSubj = 1:length(AllIntraDir) 95 % Get all the files 96 subjIntraDir = dir(fullfile(ProtocolInfo.STUDIES, AllIntraDir{iSubj}, '*.mat')); 97 subjIntraFiles = setdiff({subjIntraDir.name}, 'brainstormstudy.mat'); 98 % Delete all the files 99 for iFile = 1:length(subjIntraFiles) 100 delete(fullfile(ProtocolInfo.STUDIES, AllIntraDir{iSubj}, subjIntraFiles{iFile})); 101 end 102 end 103 % Reload protocol 104 db_reload_database(iProtocol); 105 end 106 107 108 %% ===== SUBJECT AVERAGES: FAMOUS, UNFAMILIAR, SCRAMBLED ============================== 109 % ==================================================================================== 110 111 % ===== SUBJECT AVERAGE: MEG+EEG ===== 112 % Process: Select data files in: */*/Avg 113 sAvgRun = bst_process('CallProcess', 'process_select_files_data', [], [], ... 114 'subjectname', 'All', ... 115 'tag', 'Avg'); 116 % Process: Weighted Average: By trial group (subject average) 117 sAvgSubj = bst_process('CallProcess', 'process_average', sAvgRun, [], ... 118 'avgtype', 6, ... % By trial group (subject average) 119 'avg_func', 1, ... % Arithmetic average: mean(x) 120 'weighted', 1, ... 121 'keepevents', 1); 122 % Process: Average: By trial group (grand average) 123 sAvgGroup = bst_process('CallProcess', 'process_average', sAvgSubj, [], ... 124 'avgtype', 7, ... % By trial group (grand average) 125 'avg_func', 1, ... % Arithmetic average: mean(x) 126 'weighted', 0, ... 127 'keepevents', 0); 128 129 % ===== SUBJECT AVERAGES: SOURCES (EEG) ===== 130 % Process: Select source files in: */*/EEG 131 sAvgRunSrcEeg = bst_process('CallProcess', 'process_select_files_results', [], [], 'tag', 'EEG'); 132 % Process: Weighted Average: By trial group (subject average) - EEG 133 sAvgSubjSrcEeg = bst_process('CallProcess', 'process_average', sAvgRunSrcEeg, [], ... 134 'avgtype', 6, ... % By trial group (subject average) 135 'avg_func', 1, ... % Arithmetic average: mean(x) 136 'weighted', 1, ... 137 'scalenormalized', 0); 138 % Process: Add tag: EEG 139 sAvgSubjSrcEeg = bst_process('CallProcess', 'process_add_tag', sAvgSubjSrcEeg, [], ... 140 'tag', 'EEG', ... 141 'output', 1); % Add to comment 142 143 % ===== SUBJECT AVERAGES: SOURCES (MEG) ===== 144 % Process: Select source files in: */*/MEG 145 sAvgRunSrcMeg = bst_process('CallProcess', 'process_select_files_results', [], [], 'tag', 'MEG'); 146 % Process: Weighted Average: By trial group (subject average) - MEG 147 sAvgSubjSrcMeg = bst_process('CallProcess', 'process_average', sAvgRunSrcMeg, [], ... 148 'avgtype', 6, ... % By trial group (subject average) 149 'avg_func', 1, ... % Arithmetic average: mean(x) 150 'weighted', 1, ... 151 'scalenormalized', 1); 152 % Process: Add tag: MEG 153 sAvgSubjSrcMeg = bst_process('CallProcess', 'process_add_tag', sAvgSubjSrcMeg, [], ... 154 'tag', 'MEG', ... 155 'output', 1); % Add to comment 156 157 % ===== SUBJECT AVERAGES: TIMEFREQ ===== 158 % Process: Select time-frequency files in: */* 159 sAvgRunTf = bst_process('CallProcess', 'process_select_files_timefreq', [], []); 160 % Process: Weighted Average: By trial group (subject average) 161 sAvgSubjTf = bst_process('CallProcess', 'process_average', sAvgRunTf, [], ... 162 'avgtype', 6, ... % By trial group (subject average) 163 'avg_func', 1, ... % Arithmetic average: mean(x) 164 'weighted', 1, ... 165 'scalenormalized', 1); 166 167 168 169 %% ===== SUBJECT AVERAGES: FACES ====================================================== 170 % ==================================================================================== 171 172 % ===== FACES AVERAGE: MEG+EEG ====== 173 % Process: Select data files in: */* 174 sAllData = bst_process('CallProcess', 'process_select_files_data', [], [], ... 175 'subjectname', 'All', ... 176 'includeintra', 1); 177 % Process: Select file comments with tag: "WAvg: Avg: Famous (6 files)" 178 sAvgSubjFamous = bst_process('CallProcess', 'process_select_tag', sAllData, [], 'tag', 'WAvg: Avg: Famous (6 files)'); 179 % Process: Select file comments with tag: "WAvg: Avg: Unfamiliar (6 files)" 180 sAvgSubjUnfamiliar = bst_process('CallProcess', 'process_select_tag', sAllData, [], 'tag', 'WAvg: Avg: Unfamiliar (6 files)'); 181 % Process: Weighted Average A&B 182 sAvgSubjFaces = bst_process('CallProcess', 'process_average_ab', sAvgSubjFamous, sAvgSubjUnfamiliar, ... 183 'weighted', 1); 184 % Process: Add tag: Faces 185 sAvgSubjFaces = bst_process('CallProcess', 'process_add_tag', sAvgSubjFaces, [], ... 186 'tag', 'Faces', ... 187 'output', 2); % Add to file name 188 % Process: Set comment 189 sAvgSubjFaces = bst_process('CallProcess', 'process_set_comment', sAvgSubjFaces, [], ... 190 'tag', 'WAvg: Avg: Faces', ... 191 'isindex', 0); 192 % Process: Average: By trial group (grand average) 193 sAvgGroupFaces = bst_process('CallProcess', 'process_average', sAvgSubjFaces, [], ... 194 'avgtype', 7, ... % By trial group (grand average) 195 'avg_func', 1, ... % Arithmetic average: mean(x) 196 'weighted', 0, ... 197 'keepevents', 0); 198 199 % ===== FACES AVERAGE: SOURCES (EEG) ====== 200 % Process: Select source files in: */*/EEG 201 sSrcEeg = bst_process('CallProcess', 'process_select_files_results', [], [], ... 202 'subjectname', 'All', ... 203 'tag', 'EEG', ... 204 'includeintra', 1); 205 % Process: Select file comments with tag: "WAvg: Avg: Famous" 206 sAvgSubjFamousSrcEeg = bst_process('CallProcess', 'process_select_tag', sSrcEeg, [], 'tag', 'WAvg: Avg: Famous'); 207 % Process: Select file comments with tag: "WAvg: Avg: Unfamiliar" 208 sAvgSubjUnfamiliarSrcEeg = bst_process('CallProcess', 'process_select_tag', sSrcEeg, [], 'tag', 'WAvg: Avg: Unfamiliar'); 209 % Process: Weighted Average A&B 210 sAvgSubjFacesSrcEeg = bst_process('CallProcess', 'process_average_ab', sAvgSubjFamousSrcEeg, sAvgSubjUnfamiliarSrcEeg, ... 211 'weighted', 1, ... 212 'scalenormalized', 1); 213 % Process: Add tag: Faces 214 sAvgSubjFacesSrcEeg = bst_process('CallProcess', 'process_add_tag', sAvgSubjFacesSrcEeg, [], ... 215 'tag', 'Faces', ... 216 'output', 2); % Add to file name 217 % Process: Set comment 218 sAvgSubjFacesSrcEeg = bst_process('CallProcess', 'process_set_comment', sAvgSubjFacesSrcEeg, [], ... 219 'tag', 'WAvg: Avg: Faces | EEG', ... 220 'isindex', 0); 221 222 % ===== FACES AVERAGE: SOURCES (MEG) ====== 223 % Process: Select source files in: */* 224 sSrcMeg = bst_process('CallProcess', 'process_select_files_results', [], [], ... 225 'subjectname', 'All', ... 226 'tag', 'MEG', ... 227 'includeintra', 1); 228 % Process: Select file comments with tag: Famous 229 sAvgSubjFamousSrcMeg = bst_process('CallProcess', 'process_select_tag', sSrcMeg, [], 'tag', 'Famous'); 230 % Process: Select file comments with tag: Unfamiliar 231 sAvgSubjUnfamiliarSrcMeg = bst_process('CallProcess', 'process_select_tag', sSrcMeg, [], 'tag', 'Unfamiliar'); 232 % Process: Weighted Average A&B 233 sAvgSubjFacesSrcMeg = bst_process('CallProcess', 'process_average_ab', sAvgSubjFamousSrcMeg, sAvgSubjUnfamiliarSrcMeg, ... 234 'weighted', 1, ... 235 'scalenormalized', 1); 236 % Process: Add tag: Faces 237 sAvgSubjFacesSrcMeg = bst_process('CallProcess', 'process_add_tag', sAvgSubjFacesSrcMeg, [], ... 238 'tag', 'Faces', ... 239 'output', 2); % Add to file name 240 % Process: Set comment 241 sAvgSubjFacesSrcMeg = bst_process('CallProcess', 'process_set_comment', sAvgSubjFacesSrcMeg, [], ... 242 'tag', 'WAvg: Avg: Faces | MEG', ... 243 'isindex', 0); 244 245 % ===== FACES AVERAGE: TIMEFREQ ====== 246 % Process: Select time-frequency files in: */* 247 sAllTf = bst_process('CallProcess', 'process_select_files_timefreq', [], [], ... 248 'subjectname', 'All', ... 249 'includeintra', 1); 250 % Process: Select file comments with tag: "WAvg: Avg: Famous" 251 sAvgSubjFamousTf = bst_process('CallProcess', 'process_select_tag', sAllTf, [], 'tag', 'WAvg: Avg: Famous'); 252 % Process: Select file comments with tag: "WAvg: Avg: Unfamiliar" 253 sAvgSubjUnfamiliarTf = bst_process('CallProcess', 'process_select_tag', sAllTf, [], 'tag', 'WAvg: Avg: Unfamiliar'); 254 % Process: Weighted Average A&B 255 sAvgSubjFacesTf = bst_process('CallProcess', 'process_average_ab', sAvgSubjFamousTf, sAvgSubjUnfamiliarTf, ... 256 'weighted', 1); 257 % Process: Add tag: Faces 258 sAvgSubjFacesTf = bst_process('CallProcess', 'process_add_tag', sAvgSubjFacesTf, [], ... 259 'tag', 'Faces', ... 260 'output', 2); % Add to file name 261 % Process: Set comment 262 sAvgSubjFacesTf = bst_process('CallProcess', 'process_set_comment', sAvgSubjFacesTf, [], ... 263 'tag', 'WAvg: Avg: Faces', ... 264 'isindex', 0); 265 266 267 268 %% ===== SUBJECT AVERAGES: WITHIN-SUBJECT DIFFERENCES ================================= 269 % ==================================================================================== 270 271 % ===== FACES - SCRAMBLED: SOURCES EEG ===== 272 % Process: Select source files in: */*/EEG 273 sSrcEeg = bst_process('CallProcess', 'process_select_files_results', [], [], ... 274 'subjectname', 'All', ... 275 'tag', 'EEG', ... 276 'includeintra', 1); 277 % Process: Select file comments with tag: "WAvg: Avg: Faces" 278 sAvgSubjFacesSrcEeg = bst_process('CallProcess', 'process_select_tag', sSrcEeg, [], 'tag', 'WAvg: Avg: Faces'); 279 % Process: Select file comments with tag: "WAvg: Avg: Scrambled" 280 sAvgSubjScrambledSrcEeg = bst_process('CallProcess', 'process_select_tag', sSrcEeg, [], 'tag', 'WAvg: Avg: Scrambled'); 281 % Process: Difference: A-B 282 sDiffFacesSubjSrcEeg = bst_process('CallProcess', 'process_diff_ab', sAvgSubjFacesSrcEeg, sAvgSubjScrambledSrcEeg, ... 283 'source_abs', 0); 284 % Process: Set comment 285 sDiffFacesSubjSrcEeg = bst_process('CallProcess', 'process_set_comment', sDiffFacesSubjSrcEeg, [], ... 286 'tag', 'Faces - Scrambled | EEG', ... 287 'isindex', 0); 288 289 % ===== FACES - SCRAMBLED: SOURCES MEG ===== 290 % Process: Select source files in: */*/MEG 291 sSrcMeg = bst_process('CallProcess', 'process_select_files_results', [], [], ... 292 'subjectname', 'All', ... 293 'tag', 'MEG', ... 294 'includeintra', 1); 295 % Process: Select file comments with tag: "WAvg: Avg: Faces" 296 sAvgSubjFacesSrcMeg = bst_process('CallProcess', 'process_select_tag', sSrcMeg, [], 'tag', 'WAvg: Avg: Faces'); 297 % Process: Select file comments with tag: "WAvg: Avg: Scrambled" 298 sAvgSubjScrambledSrcMeg = bst_process('CallProcess', 'process_select_tag', sSrcMeg, [], 'tag', 'WAvg: Avg: Scrambled'); 299 % Process: Difference: A-B 300 sDiffFacesSubjSrcMeg = bst_process('CallProcess', 'process_diff_ab', sAvgSubjFacesSrcMeg, sAvgSubjScrambledSrcMeg, ... 301 'source_abs', 0); 302 % Process: Set comment 303 sDiffFacesSubjSrcMeg = bst_process('CallProcess', 'process_set_comment', sDiffFacesSubjSrcMeg, [], ... 304 'tag', 'Faces - Scrambled | MEG', ... 305 'isindex', 0); 306 307 % ===== FAMOUS - UNFAMILIAR: SOURCE EEG ===== 308 % Process: Select file comments with tag: "WAvg: Avg: Famous" 309 sAvgSubjFamousSrcEeg = bst_process('CallProcess', 'process_select_tag', sSrcEeg, [], 'tag', 'WAvg: Avg: Famous'); 310 % Process: Select file comments with tag: "WAvg: Avg: Unfamiliar" 311 sAvgSubjUnfamiliarSrcEeg = bst_process('CallProcess', 'process_select_tag', sSrcEeg, [], 'tag', 'WAvg: Avg: Unfamiliar'); 312 % Process: Difference: A-B 313 sDiffFamousSubjSrcEeg = bst_process('CallProcess', 'process_diff_ab', sAvgSubjFamousSrcEeg, sAvgSubjUnfamiliarSrcEeg, ... 314 'source_abs', 0); 315 % Process: Set comment 316 sDiffFamousSubjSrcEeg = bst_process('CallProcess', 'process_set_comment', sDiffFamousSubjSrcEeg, [], ... 317 'tag', 'Famous - Unfamiliar | EEG', ... 318 'isindex', 0); 319 320 % ===== FAMOUS - UNFAMILIAR: SOURCE MEG ===== 321 % Process: Select file comments with tag: "WAvg: Avg: Famous" 322 sAvgSubjFamousSrcMeg = bst_process('CallProcess', 'process_select_tag', sSrcMeg, [], 'tag', 'WAvg: Avg: Famous'); 323 % Process: Select file comments with tag: "WAvg: Avg: Unfamiliar" 324 sAvgSubjUnfamiliarSrcMeg = bst_process('CallProcess', 'process_select_tag', sSrcMeg, [], 'tag', 'WAvg: Avg: Unfamiliar'); 325 % Process: Difference: A-B 326 sDiffFamousSubjSrcMeg = bst_process('CallProcess', 'process_diff_ab', sAvgSubjFamousSrcMeg, sAvgSubjUnfamiliarSrcMeg, ... 327 'source_abs', 0); 328 % Process: Set comment 329 sDiffFamousSubjSrcMeg = bst_process('CallProcess', 'process_set_comment', sDiffFamousSubjSrcMeg, [], ... 330 'tag', 'Famous - Unfamiliar | MEG', ... 331 'isindex', 0); 332 333 334 335 %% ===== SUBJECT AVERAGES: FILTER AND NORMALIZE ======================================= 336 % ==================================================================================== 337 338 % ===== FILTER: MEG+EEG ===== 339 % Process: Select data files in: */Intra 340 sAvgData = bst_process('CallProcess', 'process_select_files_data', [], [], ... 341 'subjectname', 'All', ... 342 'condition', DirIntra, ... 343 'includeintra', 1); 344 % Process: Low-pass:32Hz 345 sAvgData = bst_process('CallProcess', 'process_bandpass', sAvgData, [], ... 346 'sensortypes', 'MEG, EEG', ... 347 'highpass', 0, ... 348 'lowpass', 32, ... 349 'attenuation', 'strict', ... % 60dB 350 'mirror', 0, ... 351 'overwrite', 1); 352 % Process: Extract time: [-202ms,900ms] 353 sAvgData = bst_process('CallProcess', 'process_extract_time', sAvgData, [], ... 354 'timewindow', [-0.2018, 0.9], ... 355 'overwrite', 1); 356 357 % ===== FILTER AND NORMALIZE: SOURCES ===== 358 % Process: Select source files in: */Intra 359 sAvgSrc = bst_process('CallProcess', 'process_select_files_results', [], [], ... 360 'subjectname', 'All', ... 361 'condition', DirIntra, ... 362 'includeintra', 1); 363 % Process: Low-pass:32Hz 364 sAvgSrc = bst_process('CallProcess', 'process_bandpass', sAvgSrc, [], ... 365 'highpass', 0, ... 366 'lowpass', 32, ... 367 'attenuation', 'strict', ... % 60dB 368 'mirror', 0, ... 369 'overwrite', 1); 370 % Process: Extract time: [-202ms,900ms] 371 sAvgSrc = bst_process('CallProcess', 'process_extract_time', sAvgSrc, [], ... 372 'timewindow', [-0.2018, 0.9], ... 373 'overwrite', 1); 374 % Process: Z-score transformation: [-202ms,-5ms] 375 sAvgSrc = bst_process('CallProcess', 'process_baseline_norm', sAvgSrc, [], ... 376 'baseline', [-0.2018, -0.005], ... 377 'source_abs', 0, ... 378 'method', 'zscore', ... % Z-score transformation: x_std = (x - μ) / σ 379 'overwrite', 1); 380 381 % ===== NORMALIZE: TIMEFREQ ===== 382 % Process: Select time-frequency files in: */Intra 383 sAvgTf = bst_process('CallProcess', 'process_select_files_timefreq', [], [], ... 384 'subjectname', 'All', ... 385 'condition', DirIntra, ... 386 'includeintra', 1); 387 % Process: Event-related perturbation (ERS/ERD): [-200ms,-4ms] 388 sAvgTf = bst_process('CallProcess', 'process_baseline_norm', sAvgTf, [], ... 389 'baseline', [-0.2, -0.004], ... 390 'method', 'ersd', ... % Event-related perturbation (ERS/ERD): x_std = (x - μ) / μ * 100 391 'overwrite', 1); 392 393 % Save report 394 ReportFile = bst_report('Save', []); 395 if ~isempty(reports_dir) && ~isempty(ReportFile) 396 bst_report('Export', ReportFile, bst_fullfile(reports_dir, ['report_' ProtocolName '_1prepare.html'])); 397 end 398 399 400 401 %% ===== SUBJECT AVERAGES: SCREEN CAPTURES ============================================ 402 % ==================================================================================== 403 % Start a new report 404 bst_report('Start'); 405 % Set colormap: local color scale 406 bst_colormaps('SetMaxMode', 'stat2', 'local'); 407 408 % ===== FACES: RECORDINGS ====== 409 % Process: Select data files in: */*/WAvg: Avg: Faces | 410 sAvgFaces = bst_process('CallProcess', 'process_select_files_data', [], [], ... 411 'subjectname', 'All', ... 412 'tag', 'WAvg: Avg: Faces |', ... 413 'includeintra', 1); 414 % Process: Snapshot: Recordings time series 415 bst_process('CallProcess', 'process_snapshot', sAvgFaces, [], ... 416 'target', 1, ... % Sensor/MRI registration 417 'modality', 1); % MEG 418 % Process: Snapshot: Recordings time series 419 bst_process('CallProcess', 'process_snapshot', sAvgFaces, [], ... 420 'target', 5, ... % Recordings time series 421 'modality', 4, ... % EEG 422 'time', 0.1055); 423 424 % ===== FACES: SOURCES MEG ====== 425 % Process: Select source files in: */*/WAvg: Avg: Faces | MEG 426 sAvgFacesSrcMeg = bst_process('CallProcess', 'process_select_files_results', [], [], ... 427 'subjectname', 'All', ... 428 'condition', DirIntra, ... 429 'tag', 'WAvg: Avg: Faces | MEG', ... 430 'includeintra', 1); 431 % Process: Snapshot: Sources (one time) 432 bst_process('CallProcess', 'process_snapshot', sAvgFacesSrcMeg, [], ... 433 'target', 8, ... % Sources (one time) 434 'orient', 6, ... % back 435 'time', 0.1055, ... 436 'threshold', 10); 437 438 % ===== FACES: TIME-FREQ EEG ====== 439 % Process: Select time-frequency files in: */*/WAvg: Avg: Faces 440 sAvgFacesTf = bst_process('CallProcess', 'process_select_files_timefreq', [], [], ... 441 'subjectname', 'All', ... 442 'tag', 'WAvg: Avg: Faces', ... 443 'includeintra', 1); 444 % Process: Snapshot: Time-frequency maps 445 bst_process('CallProcess', 'process_snapshot', sAvgFacesTf, [], ... 446 'target', 14, ... % Time-frequency maps 447 'time', 0.1055, ... 448 'rowname', 'EEG070'); 449 450 % Save report 451 ReportFile = bst_report('Save', []); 452 if ~isempty(reports_dir) && ~isempty(ReportFile) 453 bst_report('Export', ReportFile, bst_fullfile(reports_dir, ['report_' ProtocolName '_2snapshots.html'])); 454 end 455 456 457 458 %% ===== GROUP ANALYSIS: FACES-SCRAMBLED: MEG/EEG ===================================== 459 % ==================================================================================== 460 % Start a new report 461 bst_report('Start'); 462 % Set colormap: global color scale 463 bst_colormaps('SetMaxMode', 'meg', 'global'); 464 bst_colormaps('SetMaxMode', 'eeg', 'global'); 465 % Set display properties for statistics: p<0.05, FDR-corrected 466 StatThreshOptions = bst_get('StatThreshOptions'); 467 StatThreshOptions.pThreshold = 0.05; 468 StatThreshOptions.Correction = 'fdr'; 469 StatThreshOptions.Control = [1 2 3]; 470 bst_set('StatThreshOptions', StatThreshOptions); 471 472 % ===== GRAND AVERAGES ===== 473 % Process: Select data files in: Group_analysis/Intra 474 sAvgData = bst_process('CallProcess', 'process_select_files_data', [], [], ... 475 'subjectname', GroupSubjectName, ... 476 'condition', DirIntra, ... 477 'includeintra', 1); 478 % Take screen captures 479 DataScreenCapture(sAvgData(1), 1, 1, ''); 480 DataScreenCapture(sAvgData(2), 1, 1, ''); 481 DataScreenCapture(sAvgData(3), 1, 1, ''); 482 DataScreenCapture(sAvgData(4), 1, 1, ''); 483 % Define function for screen captures 484 function DataScreenCapture(sFiles, isMEG, isEEG, Comment) 485 if isMEG 486 % Process: Snapshot: Recordings time series 487 bst_process('CallProcess', 'process_snapshot', sFiles, [], ... 488 'target', 5, ... % Recordings time series 489 'modality', 3, ... % MEG (Magnetometers) 490 'time', 0.1055, ... 491 'Comment', ['MEG MAG: ' Comment]); 492 % Process: Snapshot: Recordings topography (contact sheet) 493 bst_process('CallProcess', 'process_snapshot', sFiles, [], ... 494 'target', 7, ... % Recordings topography (contact sheet) 495 'modality', 3, ... % MEG (Magnetometers) 496 'contact_time', [0.050, 0.300], ... 497 'contact_nimage', 6, ... 498 'Comment', ['MEG MAG: ' Comment]); 499 end 500 if isEEG 501 % Process: Snapshot: Recordings time series 502 bst_process('CallProcess', 'process_snapshot', sFiles, [], ... 503 'target', 5, ... % Recordings time series 504 'modality', 4, ... % EEG 505 'time', 0.1055, ... 506 'Comment', ['EEG: ' Comment]); 507 % Process: Snapshot: Recordings topography (contact sheet) 508 bst_process('CallProcess', 'process_snapshot', sFiles, [], ... 509 'target', 7, ... % Recordings topography (contact sheet) 510 'modality', 4, ... % EEG 511 'contact_time', [0.050, 0.300], ... 512 'contact_nimage', 6, ... 513 'Comment', ['EEG: ' Comment]); 514 end 515 end 516 517 % ===== FACES-SCRAMBLED: MEAN DIFF ===== 518 % Process: Select data files in: */DirIntra/"Avg: Faces | " 519 sSubjAvgFacesData = bst_process('CallProcess', 'process_select_files_data', [], [], ... 520 'subjectname', 'All', ... 521 'condition', DirIntra, ... 522 'tag', 'Avg: Faces | ', ... 523 'includeintra', 1); 524 % Process: Select data files in: */DirIntra/"WAvg: Avg: Scrambled (6 files)" 525 sSubjAvgScrambledData = bst_process('CallProcess', 'process_select_files_data', [], [], ... 526 'subjectname', 'All', ... 527 'condition', DirIntra, ... 528 'tag', 'WAvg: Avg: Scrambled (6 files)', ... 529 'includeintra', 1); 530 % Process: Difference of means [mean] 531 sDiffFacesData = bst_process('CallProcess', 'process_diff_mean', sSubjAvgFacesData, sSubjAvgScrambledData, ... 532 'avg_func', 1, ... % Arithmetic average mean(A) - mean(B) 533 'weighted', 0); 534 % Process: Set comment 535 sDiffFacesData = bst_process('CallProcess', 'process_set_comment', sDiffFacesData, [], ... 536 'tag', 'Faces - Scrambled', ... 537 'isindex', 0); 538 % Take screen captures 539 DataScreenCapture(sDiffFacesData, 1, 1, sDiffFacesData.Comment); 540 541 % ===== FACES-SCRAMBLED: PARAMETRIC T-TEST ===== 542 % Process: Select data files in: */DirIntra/"Avg: Faces | " 543 sSubjAvgFacesData = bst_process('CallProcess', 'process_select_files_data', [], [], ... 544 'subjectname', 'All', ... 545 'condition', DirIntra, ... 546 'tag', 'Avg: Faces | ', ... 547 'includeintra', 1); 548 % Process: Select data files in: */DirIntra/"WAvg: Avg: Scrambled (6 files)" 549 sSubjAvgScrambledData = bst_process('CallProcess', 'process_select_files_data', [], [], ... 550 'subjectname', 'All', ... 551 'condition', DirIntra, ... 552 'tag', 'WAvg: Avg: Scrambled (6 files)', ... 553 'includeintra', 1); 554 % Process: t-test paired [ALL] H0:(A=B), H1:(A<>B) 555 sStatParamFacesData = bst_process('CallProcess', 'process_test_parametric2p', sSubjAvgFacesData, sSubjAvgScrambledData, ... 556 'timewindow', [], ... 557 'sensortypes', '', ... 558 'isabs', 0, ... 559 'avgtime', 0, ... 560 'avgrow', 0, ... 561 'Comment', '', ... 562 'test_type', 'ttest_paired', ... % Paired Student's t-test (A-B)~N(m,v)t = mean(A-B) / std(A-B) * sqrt(n) df=n-1 563 'tail', 'two'); % Two-tailed 564 % Process: Set comment 565 sStatParamFacesData = bst_process('CallProcess', 'process_set_comment', sStatParamFacesData, [], ... 566 'tag', 'Faces - Scrambled: Parametric t-test', ... 567 'isindex', 0); 568 % Take screen captures 569 DataScreenCapture(sStatParamFacesData, 1, 1, sStatParamFacesData.Comment); 570 571 % ===== FACES-SCRAMBLED: NON-PARAMETRIC T-TEST ===== 572 % Process: Perm t-test paired [All] H0:(A=B), H1:(A<>B) 573 sStatPermFacesData = bst_process('CallProcess', 'process_test_permutation2p', sSubjAvgFacesData, sSubjAvgScrambledData, ... 574 'timewindow', [], ... 575 'sensortypes', '', ... 576 'isabs', 0, ... 577 'avgtime', 0, ... 578 'avgrow', 0, ... 579 'iszerobad', 0, ... 580 'Comment', '', ... 581 'test_type', 'ttest_paired', ... % Paired Student's t-test T = mean(A-B) / std(A-B) * sqrt(n) 582 'randomizations', 1000, ... 583 'tail', 'two'); % Two-tailed 584 % Process: Set comment 585 sStatPermFacesData = bst_process('CallProcess', 'process_set_comment', sStatPermFacesData, [], ... 586 'tag', 'Faces - Scrambled: Permutation t-test', ... 587 'isindex', 0); 588 % Take screen captures 589 DataScreenCapture(sStatPermFacesData, 1, 1, sStatPermFacesData.Comment); 590 591 % ===== FACES-SCRAMBLED: CLUSTER T-TEST ===== 592 % Process: FT t-test paired cluster [all EEG] H0:(A=B), H1:(A<>B) 593 sStatClustFacesData = bst_process('CallProcess', 'process_ft_timelockstatistics', sSubjAvgFacesData, sSubjAvgScrambledData, ... 594 'sensortypes', 'EEG', ... 595 'timewindow', [], ... 596 'isabs', 0, ... 597 'avgtime', 0, ... 598 'avgchan', 0, ... 599 'randomizations', 1000, ... 600 'statistictype', 2, ... % Paired t-test 601 'tail', 'two', ... % Two-tailed 602 'correctiontype', 2, ... % cluster 603 'minnbchan', 0, ... 604 'clusteralpha', 0.05); 605 % If FieldTrip is available and results were returned 606 if ~isempty(sStatClustFacesData) 607 % Process: Set comment 608 sStatClustFacesData = bst_process('CallProcess', 'process_set_comment', sStatClustFacesData, [], ... 609 'tag', 'Faces - Scrambled: Cluster t-test EEG', ... 610 'isindex', 0); 611 % Take screen captures 612 DataScreenCapture(sStatClustFacesData, 0, 1, sStatClustFacesData.Comment); 613 end 614 615 616 %% ===== GROUP ANALYSIS: FACES-SCRAMBLED: MEG/EEG ===================================== 617 % ==================================================================================== 618 % ===== FAMOUS-UNFAMILIAR: MEAN DIFF ===== 619 % Process: Select data files in: */DirIntra/"Avg: Famous | " 620 sSubjAvgFamousData = bst_process('CallProcess', 'process_select_files_data', [], [], ... 621 'subjectname', 'All', ... 622 'condition', DirIntra, ... 623 'tag', 'Avg: Famous (6 files)', ... 624 'includeintra', 1); 625 % Process: Select data files in: */DirIntra/"WAvg: Avg: Unfamiliar (6 files)" 626 sSubjAvgUnfamiliarData = bst_process('CallProcess', 'process_select_files_data', [], [], ... 627 'subjectname', 'All', ... 628 'condition', DirIntra, ... 629 'tag', 'WAvg: Avg: Unfamiliar (6 files)', ... 630 'includeintra', 1); 631 % Process: Difference of means [mean] 632 sDiffFamousData = bst_process('CallProcess', 'process_diff_mean', sSubjAvgFamousData, sSubjAvgUnfamiliarData, ... 633 'avg_func', 1, ... % Arithmetic average mean(A) - mean(B) 634 'weighted', 0); 635 % Process: Set comment 636 sDiffFamousData = bst_process('CallProcess', 'process_set_comment', sDiffFamousData, [], ... 637 'tag', 'Famous - Unfamiliar', ... 638 'isindex', 0); 639 % Take screen captures 640 DataScreenCapture(sDiffFamousData, 1, 1, sDiffFamousData.Comment); 641 642 % ===== FAMOUS-UNFAMILIAR: PARAMETRIC T-TEST ===== 643 % Process: t-test paired [All] H0:(A=B), H1:(A<>B) 644 sStatParamFamousData = bst_process('CallProcess', 'process_test_parametric2p', sSubjAvgFamousData, sSubjAvgUnfamiliarData, ... 645 'timewindow', [], ... 646 'sensortypes', '', ... 647 'isabs', 0, ... 648 'avgtime', 0, ... 649 'avgrow', 0, ... 650 'Comment', '', ... 651 'test_type', 'ttest_paired', ... % Paired Student's t-test (A-B)~N(m,v)t = mean(A-B) / std(A-B) * sqrt(n) df=n-1 652 'tail', 'two'); % Two-tailed 653 % Process: Set comment 654 sStatParamFamousData = bst_process('CallProcess', 'process_set_comment', sStatParamFamousData, [], ... 655 'tag', 'Famous - Unfamiliar: Parametric t-test', ... 656 'isindex', 0); 657 % Take screen captures 658 DataScreenCapture(sStatParamFamousData, 1, 1, sStatParamFamousData.Comment); 659 660 % ===== FAMOUS-UNFAMILIAR: CLUSTER T-TEST ===== 661 % Process: FT t-test paired cluster [all EEG] H0:(A=B), H1:(A<>B) 662 sStatClustFamousData = bst_process('CallProcess', 'process_ft_timelockstatistics', sSubjAvgFamousData, sSubjAvgUnfamiliarData, ... 663 'sensortypes', 'EEG', ... 664 'timewindow', [], ... 665 'isabs', 0, ... 666 'avgtime', 0, ... 667 'avgchan', 0, ... 668 'randomizations', 1000, ... 669 'statistictype', 2, ... % Paired t-test 670 'tail', 'two', ... % Two-tailed 671 'correctiontype', 2, ... % cluster 672 'minnbchan', 0, ... 673 'clusteralpha', 0.05); 674 % If FieldTrip is available and results were returned 675 if ~isempty(sStatClustFacesData) 676 % Process: Set comment 677 sStatClustFamousData = bst_process('CallProcess', 'process_set_comment', sStatClustFamousData, [], ... 678 'tag', 'Famous - Unfamiliar: Cluster t-test EEG', ... 679 'isindex', 0); 680 % Take screen captures 681 DataScreenCapture(sStatClustFamousData, 0, 1, sStatClustFamousData.Comment); 682 end 683 684 % Save report 685 ReportFile = bst_report('Save', []); 686 if ~isempty(reports_dir) && ~isempty(ReportFile) 687 bst_report('Export', ReportFile, bst_fullfile(reports_dir, ['report_' ProtocolName '_3meeg.html'])); 688 end 689 690 691 692 %% ===== FACES-SCRAMBLED: SOURCES (MEG) =============================================== 693 % ==================================================================================== 694 % Start a new report 695 bst_report('Start'); 696 697 % ===== PROJECT SOURCES ===== 698 % Process: Select source files in: */Intra 699 sAvgSrc = bst_process('CallProcess', 'process_select_files_results', [], [], ... 700 'subjectname', 'All', ... 701 'condition', DirIntra, ... 702 'includeintra', 1); 703 % Process: Absolute values / Norm for unconstrained 704 if isUnconstrained 705 % Process: Unconstrained to flat map 706 sAvgSrc = bst_process('CallProcess', 'process_source_flat', sAvgSrc, [], ... 707 'method', 1); % Norm: sqrt(x^2+y^2+z^2) 708 else 709 sAvgSrc = bst_process('CallProcess', 'process_absolute', sAvgSrc, [], ... 710 'overwrite', 1); 711 end 712 % Process: Project on default anatomy 713 sProjSrc = bst_process('CallProcess', 'process_project_sources', sAvgSrc, [], ... 714 'headmodeltype', 'surface'); % Cortex surface 715 % Process: Spatial smoothing (3.00,abs) 716 sProjSrc = bst_process('CallProcess', 'process_ssmooth_surfstat', sProjSrc, [], ... 717 'fwhm', 3, ... 718 'overwrite', 1, ... 719 'source_abs', 1); 720 721 % ===== MOVE FILES ===== 722 % File tags / destination folder 723 ListTags = {'Avg: Faces | EEG', 'Faces_EEG'; ... 724 'Avg: Faces | MEG', 'Faces_MEG'; ... 725 'Avg: Famous (6 files) | EEG', 'Famous_EEG'; ... 726 'Avg: Famous (6 files) | MEG', 'Famous_MEG'; ... 727 'Avg: Unfamiliar (6 files) | EEG', 'Unfamiliar_EEG'; ... 728 'Avg: Unfamiliar (6 files) | MEG', 'Unfamiliar_MEG'; ... 729 'Avg: Scrambled (6 files) | EEG', 'Scrambled_EEG'; ... 730 'Avg: Scrambled (6 files) | MEG', 'Scrambled_MEG'; ... 731 'Faces - Scrambled | EEG', 'Faces-Scrambled_EEG'; ... 732 'Faces - Scrambled | MEG', 'Faces-Scrambled_MEG'; ... 733 'Famous - Unfamiliar | EEG', 'Famous-Unfamiliar_EEG'; ... 734 'Famous - Unfamiliar | MEG', 'Famous-Unfamiliar_MEG'}; 735 % Move group by group 736 for i = 1:size(ListTags,1) 737 % Find names of files to move 738 iTag = find(~cellfun(@(c)isempty(strfind(c, ListTags{i,1})), {sProjSrc.Comment})); 739 if isempty(iTag) 740 continue; 741 end 742 % Process: Move files 743 bst_process('CallProcess', 'process_movefile', {sProjSrc(iTag).FileName}, [], ... 744 'subjectname', GroupSubjectName, ... 745 'folder', ListTags{i,2}); 746 end 747 748 749 % ===== LOOP ON MODALITY ===== 750 AllModalities = {'MEG','EEG'}; 751 for iMod = 1:length(AllModalities) 752 % Selected modality for this loop 753 Mod = AllModalities{iMod}; 754 755 % ===== |FACES-SCRAMBLED|: MEAN DIFF ====== 756 % Process: Select source files in: Group_analysis/Faces-Scrambled_MOD 757 sDiffFaces = bst_process('CallProcess', 'process_select_files_results', [], [], ... 758 'subjectname', GroupSubjectName, ... 759 'condition', ['Faces-Scrambled_', Mod]); 760 % Process: Weighted Average: By folder (grand average) 761 sAbsDiffFaces = bst_process('CallProcess', 'process_average', sDiffFaces, [], ... 762 'avgtype', 4, ... % By folder (grand average) 763 'avg_func', 1, ... % Arithmetic average: mean(x) 764 'weighted', 0, ... 765 'scalenormalized', 0); 766 % Process: Set comment 767 sAbsDiffFaces = bst_process('CallProcess', 'process_set_comment', sAbsDiffFaces, [], ... 768 'tag', ['mean(|Faces-Scrambled|) | ' Mod], ... 769 'isindex', 0); 770 % Process: Move files 771 sAbsDiffFaces = bst_process('CallProcess', 'process_movefile', sAbsDiffFaces, [], ... 772 'subjectname', GroupSubjectName, ... 773 'folder', DirIntra); 774 % Colormap: Custom max: [-10,+10] Z 775 bst_colormaps('SetMaxCustom', 'stat2', [], -10, 10); 776 % Process: Snapshot: Sources (contact sheet) 777 bst_process('CallProcess', 'process_snapshot', sAbsDiffFaces, [], ... 778 'target', 9, ... % Sources (contact sheet) 779 'orient', 4, ... % bottom 780 'contact_time', [0.05, 0.4], ... 781 'contact_nimage', 16, ... 782 'threshold', 30, ... 783 'Comment', [Mod ': mean(|Faces-Scrambled|)']); 784 % Process: Snapshot: Sources (contact sheet) 785 bst_process('CallProcess', 'process_snapshot', sAbsDiffFaces, [], ... 786 'target', 9, ... % Sources (contact sheet) 787 'orient', 2, ... % right 788 'contact_time', [0.05, 0.4], ... 789 'contact_nimage', 16, ... 790 'threshold', 30, ... 791 'Comment', [Mod ': mean(|Faces-Scrambled|)']); 792 793 % ===== |FACES-SCRAMBLED|: PARAMETRIC CHI2-TEST ====== 794 % Process: Select source files in: Group_analysis/Faces-Scrambled_MOD 795 sDiffFaces = bst_process('CallProcess', 'process_select_files_results', [], [], ... 796 'subjectname', GroupSubjectName, ... 797 'condition', ['Faces-Scrambled_' Mod]); 798 % Process: Chi2-test [all] H0:(|Zi| = 0) 799 sChiParamFaces = bst_process('CallProcess', 'process_test_parametric1', sDiffFaces, [], ... 800 'timewindow', [], ... 801 'scoutsel', {}, ... 802 'scoutfunc', 1, ... % Mean 803 'isnorm', 0, ... 804 'avgtime', 0, ... 805 'Comment', '', ... 806 'test_type', 'chi2_onesample', ... % One-sample Chi2 test Zi~N(0,1), i=1..nQ = sum(|Zi|^2) Q~Chi2(n) 807 'tail', 'two'); % Two-tailed 808 % Process: Set comment 809 sChiParamFaces = bst_process('CallProcess', 'process_set_comment', sChiParamFaces, [], ... 810 'tag', ['|Faces-Scrambled|=0: Parametric Chi2 test | ' Mod], ... 811 'isindex', 0); 812 % Process: Move files 813 sChiParamFaces = bst_process('CallProcess', 'process_movefile', sChiParamFaces, [], ... 814 'subjectname', GroupSubjectName, ... 815 'folder', DirIntra); 816 % Set colormap: global color scale 817 bst_colormaps('SetMaxMode', 'stat2', 'global'); 818 % Process: Snapshot: Sources (contact sheet) 819 bst_process('CallProcess', 'process_snapshot', sChiParamFaces, [], ... 820 'target', 9, ... % Sources (contact sheet) 821 'orient', 4, ... % bottom 822 'contact_time', [0.05, 0.4], ... 823 'contact_nimage', 16, ... 824 'Comment', [Mod ': |Faces-Scrambled|=0: Parametric Chi2-test']); 825 % Process: Snapshot: Sources (contact sheet) 826 bst_process('CallProcess', 'process_snapshot', sChiParamFaces, [], ... 827 'target', 9, ... % Sources (contact sheet) 828 'orient', 2, ... % right 829 'contact_time', [0.05, 0.4], ... 830 'contact_nimage', 16, ... 831 'Comment', [Mod ': |Faces-Scrambled|=0: Parametric Chi2-test']); 832 833 % ===== LOG(|FACES-SCRAMBLED|): PARAMETRIC CHI2-TEST ====== 834 % Process: Select source files in: Group_analysis/Faces-Scrambled_MOD 835 sDiffFaces = bst_process('CallProcess', 'process_select_files_results', [], [], ... 836 'subjectname', GroupSubjectName, ... 837 'condition', ['Faces-Scrambled_' Mod]); 838 % Process: Duplicate folders: Add tag "_log" 839 sDiffFacesLog = bst_process('CallProcess', 'process_duplicate', sDiffFaces, [], ... 840 'target', 2, ... % Duplicate folders 841 'tag', '_log'); 842 % Process: Run Matlab command 843 sDiffFacesLog = bst_process('CallProcess', 'process_matlab_eval', sDiffFacesLog, [], ... 844 'matlab', 'Data = log(Data);', ... 845 'overwrite', 1); 846 % Process: Chi2-test [all] H0:(|Zi| = 0) 847 sChiParamFacesLog = bst_process('CallProcess', 'process_test_parametric1', sDiffFacesLog, [], ... 848 'timewindow', [], ... 849 'scoutsel', {}, ... 850 'scoutfunc', 1, ... % Mean 851 'isnorm', 0, ... 852 'avgtime', 0, ... 853 'Comment', '', ... 854 'test_type', 'chi2_onesample', ... % One-sample Chi2 test Zi~N(0,1), i=1..nQ = sum(|Zi|^2) Q~Chi2(n) 855 'tail', 'two'); % Two-tailed 856 % Process: Set comment 857 sChiParamFacesLog = bst_process('CallProcess', 'process_set_comment', sChiParamFacesLog, [], ... 858 'tag', ['log(|Faces-Scrambled|)=0: Parametric Chi2 test | ' Mod], ... 859 'isindex', 0); 860 % Process: Move files 861 sChiParamFacesLog = bst_process('CallProcess', 'process_movefile', sChiParamFacesLog, [], ... 862 'subjectname', GroupSubjectName, ... 863 'folder', DirIntra); 864 % Set colormap: global color scale 865 bst_colormaps('SetMaxMode', 'stat2', 'global'); 866 % Process: Snapshot: Sources (contact sheet) 867 bst_process('CallProcess', 'process_snapshot', sChiParamFacesLog, [], ... 868 'target', 9, ... % Sources (contact sheet) 869 'orient', 4, ... % bottom 870 'contact_time', [0.05, 0.4], ... 871 'contact_nimage', 16, ... 872 'Comment', [Mod ': log(|Faces-Scrambled|)=0: Parametric Chi2-test']); 873 % Process: Snapshot: Sources (contact sheet) 874 bst_process('CallProcess', 'process_snapshot', sChiParamFacesLog, [], ... 875 'target', 9, ... % Sources (contact sheet) 876 'orient', 2, ... % right 877 'contact_time', [0.05, 0.4], ... 878 'contact_nimage', 16, ... 879 'Comment', [Mod ': log(|Faces-Scrambled|)=0: Parametric Chi2-test']); 880 881 882 % ===== |FACES|-|SCRAMBLED|: MEAN DIFF ====== 883 % Process: Select source files in: Group_analysis/Faces_MOD 884 sAvgFaces = bst_process('CallProcess', 'process_select_files_results', [], [], ... 885 'subjectname', GroupSubjectName, ... 886 'condition', ['Faces_' Mod]); 887 % Process: Select source files in: Group_analysis/Scrambled_MOD 888 sAvgScrambled = bst_process('CallProcess', 'process_select_files_results', [], [], ... 889 'subjectname', GroupSubjectName, ... 890 'condition', ['Scrambled_' Mod]); 891 % Process: Difference of means [abs(mean)] 892 sDiffAbsFaces = bst_process('CallProcess', 'process_diff_mean', sAvgFaces, sAvgScrambled, ... 893 'avg_func', 2, ... % Absolute value of average abs(mean(A)) - abs(mean(B)) 894 'weighted', 0); 895 % Process: Set comment 896 sDiffAbsFaces = bst_process('CallProcess', 'process_set_comment', sDiffAbsFaces, [], ... 897 'tag', ['mean(|Faces|)-mean(|Scrambled|) | ' Mod], ... 898 'isindex', 0); 899 % Colormap: Custom max: [-10,+10] Z 900 bst_colormaps('SetMaxCustom', 'stat2', [], -10, 10); 901 % Process: Snapshot: Sources (contact sheet) 902 bst_process('CallProcess', 'process_snapshot', sDiffAbsFaces, [], ... 903 'target', 9, ... % Sources (contact sheet) 904 'orient', 4, ... % bottom 905 'contact_time', [0.05, 0.4], ... 906 'contact_nimage', 16, ... 907 'threshold', 30, ... 908 'Comment', [Mod ': mean(|Faces|)-mean(|Scrambled|)']); 909 % Process: Snapshot: Sources (contact sheet) 910 bst_process('CallProcess', 'process_snapshot', sDiffAbsFaces, [], ... 911 'target', 9, ... % Sources (contact sheet) 912 'orient', 2, ... % right 913 'contact_time', [0.05, 0.4], ... 914 'contact_nimage', 16, ... 915 'threshold', 30, ... 916 'Comment', [Mod ': mean(|Faces|)-mean(|Scrambled|)']); 917 918 % ===== |FACES|-|SCRAMBLED|: PARAMETRIC T-TEST ====== 919 % Process: Select source files in: Group_analysis/Faces_MOD 920 sAvgFaces = bst_process('CallProcess', 'process_select_files_results', [], [], ... 921 'subjectname', GroupSubjectName, ... 922 'condition', ['Faces_' Mod]); 923 % Process: Select source files in: Group_analysis/Scrambled_MOD 924 sAvgScrambled = bst_process('CallProcess', 'process_select_files_results', [], [], ... 925 'subjectname', GroupSubjectName, ... 926 'condition', ['Scrambled_' Mod]); 927 % Process: t-test paired [-202ms,900ms] H0:(A=B), H1:(A<>B) 928 sTtestParamFaces = bst_process('CallProcess', 'process_test_parametric2p', sAvgFaces, sAvgScrambled, ... 929 'timewindow', [], ... 930 'scoutsel', {}, ... 931 'scoutfunc', 1, ... % Mean 932 'isnorm', 0, ... 933 'avgtime', 0, ... 934 'Comment', '', ... 935 'test_type', 'ttest_paired', ... % Paired Student's t-test (A-B)~N(m,v)t = mean(A-B) / std(A-B) * sqrt(n) df=n-1 936 'tail', 'two'); % Two-tailed 937 % Process: Set comment 938 sTtestParamFaces = bst_process('CallProcess', 'process_set_comment', sTtestParamFaces, [], ... 939 'tag', ['|Faces|=|Scrambled|: Parametric t-test | ' Mod], ... 940 'isindex', 0); 941 % Set colormap: global color scale 942 bst_colormaps('SetMaxMode', 'stat2', 'global'); 943 % Process: Snapshot: Sources (contact sheet) 944 bst_process('CallProcess', 'process_snapshot', sTtestParamFaces, [], ... 945 'target', 9, ... % Sources (contact sheet) 946 'orient', 4, ... % bottom 947 'contact_time', [0.05, 0.4], ... 948 'contact_nimage', 16, ... 949 'Comment', [Mod ': |Faces|-|Scrambled|: Parametric t-test']); 950 % Process: Snapshot: Sources (contact sheet) 951 bst_process('CallProcess', 'process_snapshot', sTtestParamFaces, [], ... 952 'target', 9, ... % Sources (contact sheet) 953 'orient', 2, ... % right 954 'contact_time', [0.05, 0.4], ... 955 'contact_nimage', 16, ... 956 'Comment', [Mod ': |Faces|-|Scrambled|: Parametric t-test']); 957 end 958 959 960 961 % Save report 962 ReportFile = bst_report('Save', []); 963 if ~isempty(reports_dir) && ~isempty(ReportFile) 964 bst_report('Export', ReportFile, bst_fullfile(reports_dir, ['report_' ProtocolName '_4sources.html'])); 965 end 966 967 968 969 970 end 971





Feedback: Comments, bug reports, suggestions, questions
Email address (if you expect an answer):


Tutorials/VisualGroup (last edited 2019-10-29 10:37:33 by FrancoisTadel)