Tutorial 28: Scripting

[TUTORIAL UNDER DEVELOPMENT: NOT READY FOR PUBLIC USE]

Authors: Francois Tadel, Elizabeth Bock, Sylvain Baillet

The previous tutorials explained how to use Brainstorm in an interactive way to process one subject with two acquisition runs. In the context of a typical neuroimaging study, you may have tens or hundreds of subjects to process in the same way, it is unrealistic to do everything manually. Some parts of the analysis can be processed in batches with no direct supervision, others require more attention. This tutorial introduces tools and tricks that will help you assemble an efficient analysis pipeline.

Requirements: You need a license for the Matlab environment in order to use these tools and execute custom scripts. If you are running the compiled version of Brainstorm with the MCR library, the only custom code you can run is through the menu File > Matlab console and the process "Run Matlab command".

Starting a new script

The easiest way to get started with a new Brainstorm script is to use the script generator, already introduced in the tutorial Select files and run processes. Select some files in the Process1 or Process2 tabs, select a list of processes, and use the menu Generate .m script. The example below should work on the the protocol "TutorialIntroduction" created during the introduction tutorials.

Line by line: Header

% Script generated by Brainstorm (19-Jul-2016)

All the lines starting with a "%" are comments, they are never executed.

% Input files
sFiles = [];
SubjectNames = {...
    'Subject01'};

These lines define the script inputs:

% Start a new report
bst_report('Start', sFiles);

Start a new report of activity: Clears all the previous logs and gets ready to record new messages. The report will collect all the messages that are generated during the execution of the script by the various processes. You can explicitely add screen captures and additional messages to the current report with the function bst_report. This report will remain open until the function bst_report('Start') is called again. To display the current report, use the menu File > Report viewer.

The syntax function_name('SubFunction', arguments) is used a lot in Brainstorm, to call a subfunction available inside a .m file. This line above calls the function Report() in the file brainstorm3/toolbox/process/bst_report.m. This is made possible with the use of the short script "macro_methodcall" you will see at the top of many files. Many of the Brainstorm .m files are actually libraries of functions, rather than simple "scripts" or "functions".

Line by line: Body

% Process: Select data files in: Subject01/*/Avg: deviant
sFiles = bst_process('CallProcess', 'process_select_files_data', sFiles, [], ...
    'subjectname',   SubjectNames{1}, ...
    'condition',     '', ...
    'tag',           'Avg: deviant', ...
    'includebad',    0, ...
    'includeintra',  0, ...
    'includecommon', 0);

% Process: Low-pass:30Hz
sFiles = bst_process('CallProcess', 'process_bandpass', sFiles, [], ...
    'highpass',    0, ...
    'lowpass',     30, ...
    'mirror',      1, ...
    'sensortypes', 'MEG', ...
    'overwrite',   0);

% Process: Snapshot: Recordings time series
sFiles = bst_process('CallProcess', 'process_snapshot', sFiles, [], ...
    'target',         5, ...  % Recordings time series
    'modality',       1, ...  % MEG (All)
    'orient',         4, ...  % bottom
    'time',           0.11, ...
    'contact_time',   [0, 0.1], ...
    'contact_nimage', 12, ...
    'threshold',      20, ...
    'Comment',        'Run');

You will find one block per process you selected in the pipeline editor. They all have the same syntax:
output_files = bst_process('CallProcess', process_name, input_files_A, input_files_B, options_list);

% Save and display report
ReportFile = bst_report('Save', sFiles);

Closes the current report and saves it in the user Brainstorm report folder ($HOME/.brainstorm/reports). These reports are in .mat format and contain all the information necessary to re-run the execution exactly in the same way, but they not easy to read.

The parameter "sFiles" is optional, it indicates what are the files that are considered as the final results of the script. You can remove it without breaking your script: ReportFile = bst_report('Save');

bst_report('Open', ReportFile);

Opens the report viewer to display what happened during the execution. This is equivalent to using the menu File > Report viewer. You can comment this line (ie. add a "%" at the beginning of the line) if you don't want to show the report at the end of the execution.

% bst_report('Export', ReportFile, ExportDir);

This function exports the report in readable format, as an HTML that includes all the screen captures embedded in it. It is disabled by default. If you want to use this feature: remove the "%" at the beginning of the line, and define the variable ExportDir.

ExportDir must be a string that defines where to save the HTML report. It can be wither the absolute path to a HTML file (eg. 'C:\Users\myuser\Documents\report_example.html') or just a folder (eg. 'C:\Users\myuser\Documents'). If you enter only a path to a folder, a default file name including the protocol name and a date tag is generated (report_ProtocolName_YYMMDD_HHMMSS.html).

Simplify the calls

This script you generated is like any Matlab script: you can edit it, rename the variables, add tests and loops, etc. The first important thing to understand is how to edit the options or change the inputs/outputs of a process. The script generator uses only one variable for all the file lists (sFiles) and the output process is always the input of the following process. This is usually too restrictive to write a full analysis script: we commonly need to have multiple lists of files or to run two different operations on the same file.

Let's consider the first process call, which selects the averages for the Deviant condition in both runs.

sFiles = bst_process('CallProcess', 'process_select_files_data', sFiles, [], ...
    'subjectname',   SubjectNames{1}, ...
    'condition',     '', ...
    'tag',           'Avg: deviant', ...
    'includebad',    0, ...
    'includeintra',  0, ...
    'includecommon', 0);

There is no need to set the parameter sFiles, because there is no input, you can replace it with an empty matrix []. You can therefore remove the line "sFiles = [];". We can also rename the output variable "sAvgData", to be a bit more specific.

sAvgData = bst_process('CallProcess', 'process_select_files_data', [], [], ...

You can omit all the options that are not defined, not used, or kept to their default values:

sAvgData = bst_process('CallProcess', 'process_select_files_data', [], [], ...
    'subjectname',   SubjectNames{1}, ...
    'tag',           'Avg: deviant');

Edit the call to the low-pass filter: Change the input to sAvgData and the output to sAvgDataLow, this way we will be able to keep track of the two files if we need to use them independently later in the script.

sAvgDataLow = bst_process('CallProcess', 'process_bandpass', sAvgData, [], ...
    'highpass',    0, ...
    'lowpass',     30, ...
    'sensortypes', 'MEG');

Edit the call to the snapshot process: Change the input to sAvgDataLow, and remove the output parameter (we are not expecting output from it).

bst_process('CallProcess', 'process_snapshot', sAvgDataLow, [], ...
    'target',   5, ...  % Recordings time series
    'modality', 1);     % MEG (All)

Replace the last lines with the following, to export the report instead of opening in the report viewer (edit the file path to point at your own user folder instead).

ReportFile = bst_report('Save');
bst_report('Export', ReportFile, 'C:\Users\franc\Documents\report_test.html');

Interaction with Matlab

Select the code for the first process in the Matlab editor, right-click > Evaluate selection (or press F9).

edit1.gif

If you haven't executed your script yet, you will get the following error in the Matlab command window:

Undefined variable "SubjectNames" or class "SubjectNames".

The variable SubjectNames is not defined yet: Execute the first two lines "SubjectNames = {'Subject01'}", then try again. You should now have a new variable in your Matlab workspace, which points at the two average files. Type "sAvgData(1)" in your command window to display the first element:

>> sAvgData(1)
ans =
          iStudy: 6
           iItem: 1
        FileName: 'Subject01/S01_AEF_20131218_01_600Hz_notch/data_deviant_average_160513_1329.mat'
        FileType: 'data'
         Comment: 'Avg: deviant (39 files)'
       Condition: 'S01_AEF_20131218_01_600Hz_notch'
     SubjectFile: 'Subject01/brainstormsubject.mat'
     SubjectName: 'Subject01'
        DataFile: ''
     ChannelFile: 'Subject01/S01_AEF_20131218_01_600Hz_notch/channel_ctf_acc1.mat'
    ChannelTypes: {'ADC A'  'ADC V'  'DAC'  'ECG'  'EOG'  'FitErr'  'HLU'  'MEG'  'MEG REF' ...}

The field "sAvgData(1).FileName" contains the relative path to the to the Deviant average in the first run. This structure sAvgData contains also a lot of information that can be helpful in your script:

Naming conventions

To help you navigate in the Brainstorm code, here are some naming conventions:

Running the script

The simplified script looks like this:

% Input files
SubjectNames = {'Subject01'};
% Start a new report
bst_report('Start');

% Process: Select data files in: Subject01/*/Avg: deviant
sAvgData = bst_process('CallProcess', 'process_select_files_data', [], [], ...
    'subjectname',   SubjectNames{1}, ...
    'tag',           'Avg: deviant');
% Process: Low-pass:30Hz
sAvgDataLow = bst_process('CallProcess', 'process_bandpass', sAvgData, [], ...
    'highpass',    0, ...
    'lowpass',     30, ...
    'sensortypes', 'MEG');
% Process: Snapshot: Recordings time series
bst_process('CallProcess', 'process_snapshot', sAvgDataLow, [], ...
    'target',   5, ...  % Recordings time series
    'modality', 1);     % MEG (All)

% Save and display report
ReportFile = bst_report('Save');
bst_report('Export', ReportFile, 'C:\Users\franc\Documents\report_test.html');

You have three ways to execute it:

At the end of the execution, nothing happens, because we indicated we wanted to just export the report instead of opening it. To check out the report of execution: use the menu File > Report viewer from the Brainstorm window, or open the report_test.html that was saved somewhere on your computer.

On this page, you can get review everything that happened in the script: when it was executed, how long it took, what are the processes that were executed, some produced messages (two files were selected with the first process), and at the end you have the screen captures taken by process_snapshot.

Running the script again

If you execute the script again, it will not behave as expected anymore. The selection process we used assumes that there is only one file per folder with a comment that includes "Avg: deviant". This is not the case anymore after the execution, because the low-pass filtered files also contain the same tags. The execution of the first process of the script now returns 4 files.

>> sAvgData = bst_process('CallProcess', 'process_select_files_data', [], [], ...
    'subjectname',   SubjectNames{1}, ...
    'tag',           'Avg: deviant')

sAvgData =
1x4 struct array with fields:
    iStudy
    iItem
    ...

If you want to exclude the low-pass filtered files from this selection, you can add another process that will refine the selection. We will use the script generator again to

Starting Brainstorm

Selecting files

- Inputs / outputs

- Select processes

- Adding tags to help with the file selection later

Database requests

bst_get / bst_set

sStudy = bst_get('Study', sAvgData(1).iStudy)

sStudy.Data(sAvgData(1).iItem)

File manipulation

Loop over subject and runs

Creating loops is not supported yet by the script generator, but relatively easy to do from a script without having to know too much about Matlab programming.

1) Fill the cell array SubjectNames with all your subjects names, with the same dimensions as the list of input raw files (sFiles)

How to process many subjects

This section proposes a standard workflow for processing a full group study with Brainstorm. It contains the same steps of analysis as the introduction tutorials, but separating what can be done automatically from what should be done manually. This workflow can be adapted to most ERP studies (stimulus-based).

Final script

The following script from the Brainstorm distribution reproduces the introduction tutorials ("Get started"): brainstorm3/toolbox/script/tutorial_introduction.m

1 function tutorial_introduction(tutorial_dir, reports_dir) 2 % TUTORIAL_INTRODUCTION: Script that runs all the Brainstorm introduction tutorials. 3 % 4 % INPUTS: 5 % - tutorial_dir : Directory where the sample_introduction.zip file has been unzipped 6 % - reports_dir : Directory where to save the execution report (instead of displaying it) 7 8 % @============================================================================= 9 % This function is part of the Brainstorm software: 10 % https://neuroimage.usc.edu/brainstorm 11 % 12 % Copyright (c)2000-2020 University of Southern California & McGill University 13 % This software is distributed under the terms of the GNU General Public License 14 % as published by the Free Software Foundation. Further details on the GPLv3 15 % license can be found at http://www.gnu.org/copyleft/gpl.html. 16 % 17 % FOR RESEARCH PURPOSES ONLY. THE SOFTWARE IS PROVIDED "AS IS," AND THE 18 % UNIVERSITY OF SOUTHERN CALIFORNIA AND ITS COLLABORATORS DO NOT MAKE ANY 19 % WARRANTY, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF 20 % MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, NOR DO THEY ASSUME ANY 21 % LIABILITY OR RESPONSIBILITY FOR THE USE OF THIS SOFTWARE. 22 % 23 % For more information type "brainstorm license" at command prompt. 24 % =============================================================================@ 25 % 26 % Author: Francois Tadel, 2016-2017 27 28 29 % ===== FILES TO IMPORT ===== 30 % Output folder for reports 31 if (nargin < 2) || isempty(reports_dir) || ~isdir(reports_dir) 32 reports_dir = []; 33 end 34 % You have to specify the folder in which the tutorial dataset is unzipped 35 if (nargin == 0) || isempty(tutorial_dir) || ~file_exist(tutorial_dir) 36 error('The first argument must be the full path to the dataset folder.'); 37 end 38 % Subject name 39 SubjectName = 'Subject01'; 40 % Build the path of the files to import 41 AnatDir = fullfile(tutorial_dir, 'sample_introduction', 'anatomy'); 42 Run1File = fullfile(tutorial_dir, 'sample_introduction', 'data', 'S01_AEF_20131218_01_600Hz.ds'); 43 Run2File = fullfile(tutorial_dir, 'sample_introduction', 'data', 'S01_AEF_20131218_02_600Hz.ds'); 44 NoiseFile = fullfile(tutorial_dir, 'sample_introduction', 'data', 'S01_Noise_20131218_02_600Hz.ds'); 45 % Check if the folder contains the required files 46 if ~file_exist(Run1File) 47 error(['The folder ' tutorial_dir ' does not contain the folder from the file sample_introduction.zip.']); 48 end 49 % Re-inialize random number generator 50 if (bst_get('MatlabVersion') >= 712) 51 rng('default'); 52 end 53 54 55 %% ===== TUTORIAL #1: CREATE PROTOCOL ================================================ 56 % =================================================================================== 57 disp([10 'DEMO> Tutorial #1: Create protocol' 10]); 58 % The protocol name has to be a valid folder name (no spaces, no weird characters...) 59 ProtocolName = 'TutorialIntroduction'; 60 % Start brainstorm without the GUI 61 if ~brainstorm('status') 62 brainstorm nogui 63 end 64 % Delete existing protocol 65 gui_brainstorm('DeleteProtocol', ProtocolName); 66 % Create new protocol 67 gui_brainstorm('CreateProtocol', ProtocolName, 0, 0); 68 % Start a new report 69 bst_report('Start'); 70 % Reset colormaps 71 bst_colormaps('RestoreDefaults', 'meg'); 72 73 74 %% ===== TUTORIAL #2: IMPORT ANATOMY ================================================= 75 % =================================================================================== 76 disp([10 'DEMO> Tutorial #2: Import anatomy' 10]); 77 % Process: Import FreeSurfer folder 78 bst_process('CallProcess', 'process_import_anatomy', [], [], ... 79 'subjectname', SubjectName, ... 80 'mrifile', {AnatDir, 'FreeSurfer'}, ... 81 'nvertices', 15000, ... 82 'nas', [127, 213, 139], ... 83 'lpa', [ 52, 113, 96], ... 84 'rpa', [202, 113, 91]); 85 % This automatically calls the SPM registration procedure because the AC/PC/IH points are not defined 86 87 88 89 %% ===== TUTORIAL #3: EXPLORE ANATOMY ================================================ 90 % =================================================================================== 91 disp([10 'DEMO> Tutorial #3: Explore anatomy' 10]); 92 % Get subject definition 93 sSubject = bst_get('Subject', SubjectName); 94 % Get MRI file and surface files 95 MriFile = sSubject.Anatomy(sSubject.iAnatomy).FileName; 96 CortexFile = sSubject.Surface(sSubject.iCortex).FileName; 97 HeadFile = sSubject.Surface(sSubject.iScalp).FileName; 98 % Display MRI 99 hFigMri1 = view_mri(MriFile); 100 hFigMri3 = view_mri_3d(MriFile, [], [], 'NewFigure'); 101 hFigMri2 = view_mri_slices(MriFile, 'x', 20); 102 pause(0.5); 103 % Close figures 104 close([hFigMri1 hFigMri2 hFigMri3]); 105 % Display scalp and cortex 106 hFigSurf = view_surface(HeadFile); 107 hFigSurf = view_surface(CortexFile, [], [], hFigSurf); 108 hFigMriSurf = view_mri(MriFile, CortexFile); 109 % Figure configuration 110 iTess = 2; 111 panel_surface('SetShowSulci', hFigSurf, iTess, 1); 112 panel_surface('SetSurfaceColor', hFigSurf, iTess, [1 0 0]); 113 panel_surface('SetSurfaceSmooth', hFigSurf, iTess, 0.5, 0); 114 panel_surface('SetSurfaceTransparency', hFigSurf, iTess, 0.8); 115 figure_3d('SetStandardView', hFigSurf, 'left'); 116 pause(0.5); 117 % Close figures 118 close([hFigSurf hFigMriSurf]); 119 120 121 122 %% ===== TUTORIAL #4: CHANNEL FILE =================================================== 123 % =================================================================================== 124 disp([10 'DEMO> Tutorial #4: Channel file' 10]); 125 % Process: Create link to raw files 126 sFilesRun1 = bst_process('CallProcess', 'process_import_data_raw', [], [], ... 127 'subjectname', SubjectName, ... 128 'datafile', {Run1File, 'CTF'}, ... 129 'channelalign', 1); 130 sFilesRun2 = bst_process('CallProcess', 'process_import_data_raw', [], [], ... 131 'subjectname', SubjectName, ... 132 'datafile', {Run2File, 'CTF'}, ... 133 'channelalign', 1); 134 sFilesNoise = bst_process('CallProcess', 'process_import_data_raw', [], [], ... 135 'subjectname', SubjectName, ... 136 'datafile', {NoiseFile, 'CTF'}, ... 137 'channelalign', 0); 138 sFilesRaw = [sFilesRun1, sFilesRun2, sFilesNoise]; 139 % Process: Snapshot: Sensors/MRI registration 140 bst_process('CallProcess', 'process_snapshot', [sFilesRun1, sFilesRun2], [], ... 141 'target', 1, ... % Sensors/MRI registration 142 'modality', 1, ... % MEG (All) 143 'orient', 1, ... % left 144 'Comment', 'MEG/MRI Registration'); 145 146 % View sensors 147 hFig = view_surface(HeadFile); 148 hFig = view_channels(sFilesRun1.ChannelFile, 'MEG', 1, 1, hFig); 149 % Hide sensors 150 pause(0.5); 151 hFig = view_channels(sFilesRun1.ChannelFile, 'MEG', 0, 0, hFig); 152 % View coils 153 hFig = view_channels(sFilesRun1.ChannelFile, 'CTF', 1, 1, hFig); 154 % View helmet 155 pause(0.5); 156 hFig = view_helmet(sFilesRun1.ChannelFile, hFig); 157 pause(0.5); 158 close(hFig); 159 % Edit good/bad channel for current file 160 gui_edit_channel(sFilesRun1.ChannelFile); 161 pause(0.5); 162 % Unload everything 163 bst_memory('UnloadAll', 'Forced'); 164 165 166 167 %% ===== TUTORIAL #5: REVIEW RAW ===================================================== 168 % =================================================================================== 169 disp([10 'DEMO> Tutorial #5: Review raw' 10]); 170 % Process: Convert to continuous (CTF): Continuous 171 bst_process('CallProcess', 'process_ctf_convert', sFilesRaw, [], ... 172 'rectype', 2); % Continuous 173 174 % View recordings 175 hFigMeg = view_timeseries(sFilesRun1.FileName, 'MEG'); 176 hFigEeg = view_timeseries(sFilesRun1.FileName, 'Misc'); 177 hFigSel = view_timeseries(sFilesRun1.FileName, 'MEG', {'MLT11','MLT12','MLT13'}); 178 % Figure configuration 179 pause(0.5); 180 panel_record('SetTimeLength', 3); 181 panel_record('SetStartTime', 100); 182 panel_record('SetDisplayMode', hFigMeg, 'column'); 183 panel_montage('SetCurrentMontage', hFigMeg, 'CTF LT'); 184 % Set filters: panel_filter('SetFilters', LowPassEnabled, LowPassValue, HighPassEnabled, HighPassValue, SinRemovalEnabled, SinRemovalValue, MirrorEnabled, FullSourcesEnabled) 185 panel_filter('SetFilters', 1, 100, 1, 1, 0, [], 0, 0); 186 pause(0.5); 187 panel_record('SetDisplayMode', hFigMeg, 'butterfly'); 188 panel_montage('SetCurrentMontage', hFigMeg, ''); 189 % Close figures 190 close([hFigMeg hFigEeg hFigSel]); 191 192 193 194 %% ===== TUTORIAL #8: STIM DELAYS ==================================================== 195 % =================================================================================== 196 disp([10 'DEMO> Tutorial #8: Stim delays' 10]); 197 % Process: Detect: standard_fix 198 bst_process('CallProcess', 'process_evt_detect_analog', [sFilesRun1, sFilesRun2], [], ... 199 'eventname', 'standard_fix', ... 200 'channelname', 'UADC001', ... 201 'timewindow', [], ... 202 'threshold', 1.2, ... 203 'blanking', 0.2, ... 204 'highpass', 0, ... 205 'lowpass', 0, ... 206 'refevent', 'standard', ... 207 'isfalling', 0, ... 208 'ispullup', 0, ... 209 'isclassify', 0); 210 % Process: Detect: deviant_fix 211 bst_process('CallProcess', 'process_evt_detect_analog', [sFilesRun1, sFilesRun2], [], ... 212 'eventname', 'deviant_fix', ... 213 'channelname', 'UADC001', ... 214 'timewindow', [], ... 215 'threshold', 1.2, ... 216 'blanking', 0.2, ... 217 'highpass', 0, ... 218 'lowpass', 0, ... 219 'refevent', 'deviant', ... 220 'isfalling', 0, ... 221 'ispullup', 0, ... 222 'isclassify', 0); 223 % Process: Read from channel 224 bst_process('CallProcess', 'process_evt_read', [sFilesRun1, sFilesRun2], [], ... 225 'stimchan', 'UDIO001', ... 226 'trackmode', 1, ... % Value: detect the changes of channel value 227 'zero', 0); 228 229 % Process: Delete events 230 bst_process('CallProcess', 'process_evt_delete', [sFilesRun1, sFilesRun2], [], ... 231 'eventname', 'standard, deviant, button'); 232 % Process: Rename event (standard_fix>standard) 233 bst_process('CallProcess', 'process_evt_rename', [sFilesRun1, sFilesRun2], [], ... 234 'src', 'standard_fix', ... 235 'dest', 'standard'); 236 % Process: Rename event (deviant_fix>deviant) 237 bst_process('CallProcess', 'process_evt_rename', [sFilesRun1, sFilesRun2], [], ... 238 'src', 'deviant_fix', ... 239 'dest', 'deviant'); 240 % Process: Rename event (64>button) 241 bst_process('CallProcess', 'process_evt_rename', [sFilesRun1, sFilesRun2], [], ... 242 'src', '64', ... 243 'dest', 'button'); 244 245 246 247 %% ===== TUTORIAL #10: FREQUENCY FILTERS ============================================= 248 % =================================================================================== 249 disp([10 'DEMO> Tutorial #10: Frequency filters' 10]); 250 % Process: Sinusoid removal: 60Hz 120Hz 180Hz 300Hz 251 sFilesNotch = bst_process('CallProcess', 'process_notch', sFilesRaw, [], ... 252 'freqlist', [60, 120, 180], ... 253 'sensortypes', 'MEG', ... 254 'read_all', 0); 255 % Process: Power spectrum density (Welch) 256 sFilesPsd = bst_process('CallProcess', 'process_psd', [sFilesRaw, sFilesNotch], [], ... 257 'timewindow', [], ... 258 'win_length', 4, ... 259 'win_overlap', 50, ... 260 'clusters', {}, ... 261 'sensortypes', 'MEG', ... 262 'edit', struct(... 263 'Comment', 'Power', ... 264 'TimeBands', [], ... 265 'Freqs', [], ... 266 'ClusterFuncTime', 'none', ... 267 'Measure', 'power', ... 268 'Output', 'all', ... 269 'SaveKernel', 0)); 270 % Process: Snapshot: Frequency spectrum 271 bst_process('CallProcess', 'process_snapshot', sFilesPsd, [], ... 272 'target', 10, ... % Frequency spectrum 273 'modality', 1, ... % MEG (All) 274 'Comment', 'Power spectrum density'); 275 % Process: Delete folders 276 bst_process('CallProcess', 'process_delete', sFilesRaw, [], ... 277 'target', 2); % Delete folders 278 % Separate the three outputs 279 sFilesRun1 = {sFilesNotch(1).FileName}; 280 sFilesRun2 = {sFilesNotch(2).FileName}; 281 sFilesNoise = {sFilesNotch(3).FileName}; 282 283 284 285 %% ===== TUTORIAL #11: BAD CHANNELS ================================================== 286 % =================================================================================== 287 % % Process: Set bad channels 288 % sFiles = bst_process('CallProcess', 'process_channel_setbad', sFilesRun2, [], ... 289 % 'sensortypes', 'MRT51, MLO52, MLO42, MLO43'); 290 291 292 293 %% ===== TUTORIAL #12: ARTIFACTS DETECTION =========================================== 294 % =================================================================================== 295 disp([10 'DEMO> Tutorial #12: Artifacts detection' 10]); 296 % Process: Detect heartbeats 297 bst_process('CallProcess', 'process_evt_detect_ecg', [sFilesRun1, sFilesRun2], [], ... 298 'channelname', 'ECG', ... 299 'timewindow', [], ... 300 'eventname', 'cardiac'); 301 % Process: Detect eye blinks 302 bst_process('CallProcess', 'process_evt_detect_eog', [sFilesRun1, sFilesRun2], [], ... 303 'channelname', 'VEOG', ... 304 'timewindow', [], ... 305 'eventname', 'blink'); 306 % Process: Remove simultaneous 307 bst_process('CallProcess', 'process_evt_remove_simult', [sFilesRun1, sFilesRun2], [], ... 308 'remove', 'cardiac', ... 309 'target', 'blink', ... 310 'dt', 0.25, ... 311 'rename', 0); 312 313 314 315 %% ===== TUTORIAL #13: SSP =========================================================== 316 % =================================================================================== 317 disp([10 'DEMO> Tutorial #13: SSP' 10]); 318 % Process: SSP ECG: cardiac 319 bst_process('CallProcess', 'process_ssp_ecg', [sFilesRun1, sFilesRun2], [], ... 320 'eventname', 'cardiac', ... 321 'sensortypes', 'MEG', ... 322 'usessp', 0, ... 323 'select', 1); 324 % Process: SSP EOG: blink 325 bst_process('CallProcess', 'process_ssp_eog', sFilesRun1, [], ... 326 'eventname', 'blink', ... 327 'sensortypes', 'MEG', ... 328 'usessp', 0, ... 329 'select', [1 2]); 330 bst_process('CallProcess', 'process_ssp_eog', sFilesRun2, [], ... 331 'eventname', 'blink', ... 332 'sensortypes', 'MEG', ... 333 'usessp', 0, ... 334 'select', 1); 335 336 337 %% ===== TUTORIAL #14: BAD SEGMENTS ================================================== 338 % =================================================================================== 339 disp([10 'DEMO> Tutorial #14: Bad segments' 10]); 340 % Process: Detect other artifacts 341 bst_process('CallProcess', 'process_evt_detect_badsegment', [sFilesRun1, sFilesRun2], [], ... 342 'timewindow', [], ... 343 'sensortypes', 'MEG', ... 344 'threshold', 3, ... % 3 345 'isLowFreq', 1, ... 346 'isHighFreq', 1); 347 348 % Process: Rename event (1-7Hz > saccade) (Run02 only) 349 bst_process('CallProcess', 'process_evt_rename', sFilesRun2, [], ... 350 'src', '1-7Hz', ... 351 'dest', 'saccade'); 352 353 % Manual selection of saccades (cannot be done from the pipeline editor: manual edition of the structures) 354 sMatRun2 = in_bst_data(sFilesRun2{1}, 'F'); 355 iEvtSaccade = find(strcmpi({sMatRun2.F.events.label}, 'saccade')); 356 sMatRun2.F.events(iEvtSaccade).times = [30, 81.5, 104, 142.5, 167, 187.5, 246.5, 319; 31, 83, 105, 144, 168, 188.5, 248, 320]; 357 sMatRun2.F.events(iEvtSaccade).epochs = ones(1, size(sMatRun2.F.events(iEvtSaccade).times, 2)); 358 sMatRun2.F.events(iEvtSaccade).channels = cell(1, size(sMatRun2.F.events(iEvtSaccade).times, 2)); 359 sMatRun2.F.events(iEvtSaccade).notes = cell(1, size(sMatRun2.F.events(iEvtSaccade).times, 2)); 360 bst_save(file_fullpath(sFilesRun2{1}), sMatRun2, 'v6', 1); 361 362 % Process: SSP: saccade (Run02 only) 363 bst_process('CallProcess', 'process_ssp', sFilesRun2, [], ... 364 'timewindow', [], ... 365 'eventname', 'saccade', ... 366 'eventtime', [-0.2, 0.2], ... 367 'bandpass', [1.5, 7], ... 368 'sensortypes', 'MEG', ... 369 'usessp', 1, ... 370 'saveerp', 0, ... 371 'method', 1, ... 372 'select', 1); 373 % Process: Detect other artifacts (Run02 only) 374 bst_process('CallProcess', 'process_evt_detect_badsegment', sFilesRun2, [], ... 375 'timewindow', [], ... 376 'sensortypes', 'MEG', ... 377 'threshold', 3, ... % 3 378 'isLowFreq', 1, ... 379 'isHighFreq', 1); 380 381 % Process: Rename event (1-7Hz > bad_1-7Hz) 382 bst_process('CallProcess', 'process_evt_rename', [sFilesRun1, sFilesRun2], [], ... 383 'src', '1-7Hz', ... 384 'dest', 'bad_1-7Hz'); 385 % Process: Rename event (40-240Hz > bad_40-240Hz) 386 bst_process('CallProcess', 'process_evt_rename', [sFilesRun1, sFilesRun2], [], ... 387 'src', '40-240Hz', ... 388 'dest', 'bad_40-240Hz'); 389 % Process: Snapshot: SSP projectors 390 bst_process('CallProcess', 'process_snapshot', [sFilesRun1, sFilesRun2], [], ... 391 'target', 2, ... % SSP projectors 392 'Comment', 'SSP projectors'); 393 394 395 396 %% ===== TUTORIAL #15: IMPORT EVENTS ================================================= 397 % =================================================================================== 398 disp([10 'DEMO> Tutorial #15: Import events' 10]); 399 % Process: Import MEG/EEG: Events (Run01) 400 sFilesEpochs1 = bst_process('CallProcess', 'process_import_data_event', sFilesRun1, [], ... 401 'subjectname', SubjectName, ... 402 'condition', '', ... 403 'eventname', 'standard, deviant', ... 404 'timewindow', [], ... 405 'epochtime', [-0.100, 0.500], ... 406 'createcond', 0, ... 407 'ignoreshort', 1, ... 408 'usectfcomp', 1, ... 409 'usessp', 1, ... 410 'freq', [], ... 411 'baseline', [-0.1, -0.0017]); 412 % Process: Import MEG/EEG: Events (Run02) 413 sFilesEpochs2 = bst_process('CallProcess', 'process_import_data_event', sFilesRun2, [], ... 414 'subjectname', SubjectName, ... 415 'condition', '', ... 416 'eventname', 'standard, deviant', ... 417 'timewindow', [], ... 418 'epochtime', [-0.100, 0.500], ... 419 'createcond', 0, ... 420 'ignoreshort', 1, ... 421 'usectfcomp', 1, ... 422 'usessp', 1, ... 423 'freq', [], ... 424 'baseline', [-0.1, -0.0017]); 425 % Display raster plot 426 hFigRaster = view_erpimage({sFilesEpochs1.FileName}, 'erpimage', 'MEG'); 427 panel_display(); 428 bst_report('Snapshot', hFigRaster, sFilesEpochs1(1).FileName, 'ERP image'); 429 close(hFigRaster); 430 431 432 %% ===== TUTORIAL #16: AVERAGE ======================================================= 433 % =================================================================================== 434 disp([10 'DEMO> Tutorial #16: Average' 10]); 435 % Process: Average: By trial group (folder average) 436 sFilesAvg = bst_process('CallProcess', 'process_average', [sFilesEpochs1, sFilesEpochs2], [], ... 437 'avgtype', 5, ... % By trial groups (folder average) 438 'avg_func', 1, ... % Arithmetic average: mean(x) 439 'weighted', 0, ... 440 'keepevents', 1); 441 % Process: Delete events 'cardiac' 442 bst_process('CallProcess', 'process_evt_delete', sFilesAvg, [], ... 443 'eventname', 'cardiac'); 444 % Process: Snapshot: Recordings time series 445 bst_process('CallProcess', 'process_snapshot', sFilesAvg, [], ... 446 'target', 5, ... % Recordings time series 447 'modality', 1, ... % MEG (All) 448 'Comment', 'Evoked response'); 449 % Set colormap: global color scale 450 bst_colormaps('SetMaxMode', 'meg', 'global'); 451 % Process: Snapshot: Recordings topography (contact sheet) 452 bst_process('CallProcess', 'process_snapshot', sFilesAvg, [], ... 453 'target', 7, ... % Recordings topography (contact sheet) 454 'modality', 1, ... % MEG 455 'contact_time', [0, 0.350], ... 456 'contact_nimage', 15, ... 457 'Comment', 'Evoked response'); 458 459 % Process: Average+Stderr: By trial group (subject average) 460 sFilesAvgAll = bst_process('CallProcess', 'process_average', [sFilesEpochs1, sFilesEpochs2], [], ... 461 'avgtype', 6, ... % By trial group (subject average) 462 'avg_func', 7, ... % Arithmetic average + Standard error 463 'weighted', 0, ... 464 'keepevents', 1); 465 % Process: Delete events 'cardiac' 466 bst_process('CallProcess', 'process_evt_delete', sFilesAvgAll, [], ... 467 'eventname', 'cardiac'); 468 % Process: Delete events 'saccade' 469 bst_process('CallProcess', 'process_evt_delete', sFilesAvgAll, [], ... 470 'eventname', 'saccade'); 471 % Process: Snapshot: Recordings time series 472 bst_process('CallProcess', 'process_snapshot', sFilesAvgAll, [], ... 473 'target', 5, ... % Recordings time series 474 'modality', 1, ... % MEG (All) 475 'Comment', 'Evoked response'); 476 477 478 %% ===== TUTORIAL #17: EXPLORATION =================================================== 479 % =================================================================================== 480 disp([10 'DEMO> Tutorial #17: Bad segments' 10]); 481 % View averages 482 hFigMeg1 = view_timeseries(sFilesAvg(1).FileName, 'MEG'); 483 hFigMeg2 = view_timeseries(sFilesAvg(2).FileName, 'MEG'); 484 hFigEeg1 = view_timeseries(sFilesAvg(1).FileName, 'Misc'); 485 hFigEeg2 = view_timeseries(sFilesAvg(2).FileName, 'Misc'); 486 hFigTopo1 = view_topography(sFilesAvg(1).FileName, 'MEG', '2DSensorCap'); 487 hFigTopo2 = view_topography(sFilesAvg(2).FileName, 'MEG', '2DSensorCap'); 488 hFigTp2 = view_topography(sFilesAvg(3).FileName, 'MEG', '3DSensorCap'); 489 hFigTp3 = view_topography(sFilesAvg(3).FileName, 'MEG', '2DDisc'); 490 hFigTp4 = view_topography(sFilesAvg(3).FileName, 'MEG', '2DLayout'); 491 % Set time: 90ms 492 panel_time('SetCurrentTime', 0.090); 493 % Set filters: 40Hz low-pass, no high-pass 494 panel_filter('SetFilters', 1, 40, 0, [], 0, [], 0, 0); 495 % View selected sensors 496 SelectedChannels = {'MLC31', 'MLC32'}; 497 bst_figures('SetSelectedRows', SelectedChannels); 498 view_timeseries(sFilesAvg(4).FileName, [], SelectedChannels); 499 % Select time window 500 figure_timeseries('SetTimeSelectionManual', hFigMeg1, [0.070, 0.130]); 501 % Show sensors on 2DSensorCap topography 502 isMarkers = 1; 503 isLabels = 0; 504 figure_3d('ViewSensors', hFigTopo1, isMarkers, isLabels); 505 % Display time contact sheet for a figure 506 pause(0.5); 507 hContactFig = view_contactsheet( hFigTopo2, 'time', 'fig', [], 12, [0 0.120] ); 508 pause(0.5); 509 close(hContactFig); 510 511 512 513 %% ===== TUTORIAL #18: COLORMAPS ===================================================== 514 % =================================================================================== 515 disp([10 'DEMO> Tutorial #18: Colormaps' 10]); 516 % Set 'Meg' colormap to 'jet' 517 bst_colormaps('SetColormapName', 'meg', 'jet'); 518 pause(0.5); 519 % Set 'Meg' colormap to 'rwb' 520 bst_colormaps('SetColormapName', 'meg', 'cmap_rbw'); 521 % Set colormap to display absolute values 522 bst_colormaps('SetColormapAbsolute', 'meg', 1); 523 % Normalize colormap for each time frame 524 bst_colormaps('SetMaxMode', 'meg', 'local'); 525 % Hide colorbar 526 bst_colormaps('SetDisplayColorbar', 'meg', 0); 527 pause(0.5); 528 % Restore colormap to default values 529 bst_colormaps('RestoreDefaults', 'meg'); 530 % Edit good/bad channel for current file 531 gui_edit_channelflag(sFilesAvg(1).FileName); 532 % Close figures 533 pause(0.5); 534 bst_memory('UnloadAll', 'Forced'); 535 536 537 538 %% ===== TUTORIAL #20: HEAD MODEL ==================================================== 539 % =================================================================================== 540 disp([10 'DEMO> Tutorial #20: Head model' 10]); 541 % Process: Compute head model 542 bst_process('CallProcess', 'process_headmodel', sFilesAvg, [], ... 543 'comment', '', ... 544 'sourcespace', 1, ... 545 'meg', 3); % Overlapping spheres 546 % Get study structure 547 sStudy = bst_get('Study', sFilesAvg(1).iStudy); 548 % Show spheres 549 hFig = view_spheres(sStudy.HeadModel(sStudy.iHeadModel).FileName, sStudy.Channel.FileName, sSubject); 550 pause(0.5); 551 close(hFig); 552 553 554 555 %% ===== TUTORIAL #21: NOISE COVARIANCE ============================================== 556 % =================================================================================== 557 disp([10 'DEMO> Tutorial #21: Noise covariance' 10]); 558 % Process: Compute covariance (noise or data) 559 bst_process('CallProcess', 'process_noisecov', sFilesNoise, [], ... 560 'baseline', [], ... 561 'sensortypes', 'MEG, EEG, SEEG, ECOG', ... 562 'target', 1, ... % Noise covariance (covariance over baseline time window) 563 'dcoffset', 1, ... % Block by block, to avoid effects of slow shifts in data 564 'identity', 0, ... 565 'copycond', 1, ... 566 'copysubj', 0, ... 567 'replacefile', 1); % Replace 568 % Process: Snapshot: Noise covariance 569 bst_process('CallProcess', 'process_snapshot', sFilesNoise, [], ... 570 'target', 3, ... % Noise covariance 571 'Comment', 'Noise covariance'); 572 573 % Process: Compute covariance (noise or data) [Run01] 574 bst_process('CallProcess', 'process_noisecov', sFilesEpochs1, [], ... 575 'baseline', [-0.1, -0.0017], ... 576 'datatimewindow', [0, 0.5], ... 577 'sensortypes', 'MEG, EEG, SEEG, ECOG', ... 578 'target', 2, ... % Data covariance (covariance over data time window) 579 'dcoffset', 1, ... % Block by block, to avoid effects of slow shifts in data 580 'identity', 0, ... 581 'copycond', 0, ... 582 'copysubj', 0, ... 583 'replacefile', 1); % Replace 584 % Process: Compute covariance (noise or data) [Run02] 585 bst_process('CallProcess', 'process_noisecov', sFilesEpochs2, [], ... 586 'baseline', [-0.1, -0.0017], ... 587 'datatimewindow', [0, 0.5], ... 588 'sensortypes', 'MEG, EEG, SEEG, ECOG', ... 589 'target', 2, ... % Data covariance (covariance over data time window) 590 'dcoffset', 1, ... % Block by block, to avoid effects of slow shifts in data 591 'identity', 0, ... 592 'copycond', 0, ... 593 'copysubj', 0, ... 594 'replacefile', 1); % Replace 595 % Process: Snapshot: Data covariance 596 bst_process('CallProcess', 'process_snapshot', [sFilesEpochs1(1), sFilesEpochs2(1)], [], ... 597 'target', 12, ... % Data covariance 598 'Comment', 'Data covariance'); 599 600 601 602 %% ===== TUTORIAL #22: SOURCE ESTIMATION ============================================= 603 % =================================================================================== 604 disp([10 'DEMO> Tutorial #22: Source estimation' 10]); 605 % === GET DEVIANT AVERAGE RUN01 === 606 % Process: Select recordings in: Subject01/S01_AEF_20131218_01_600Hz_notch 607 sFiles01 = bst_process('CallProcess', 'process_select_files_data', [], [], ... 608 'subjectname', SubjectName, ... 609 'condition', 'S01_AEF_20131218_01_600Hz_notch', ... 610 'includebad', 0); 611 % Process: Select file comments with tag: deviant 612 sFilesAvgDeviant01 = bst_process('CallProcess', 'process_select_tag', sFiles01, [], ... 613 'tag', 'Avg: deviant', ... 614 'search', 2, ... % Search the file comments 615 'select', 1); % Select only the files with the tag 616 617 % === CONSTRAINED EXAMPLE === 618 % Minimum norm options 619 InverseOptions = struct(... 620 'Comment', 'MN: MEG', ... 621 'InverseMethod', 'minnorm', ... 622 'InverseMeasure', 'amplitude', ... 623 'SourceOrient', {{'fixed'}}, ... 624 'Loose', 0.2, ... 625 'UseDepth', 1, ... 626 'WeightExp', 0.5, ... 627 'WeightLimit', 10, ... 628 'NoiseMethod', 'reg', ... 629 'NoiseReg', 0.1, ... 630 'SnrMethod', 'fixed', ... 631 'SnrRms', 0.001, ... 632 'SnrFixed', 3, ... 633 'ComputeKernel', 1, ... 634 'DataTypes', {{'MEG'}}); 635 % Process: Compute sources [2018] 636 sFilesSrcDeviant01 = bst_process('CallProcess', 'process_inverse_2018', sFilesAvgDeviant01, [], ... 637 'output', 2, ... % Kernel only: one per file 638 'inverse', InverseOptions); 639 640 % === DISPLAY SOURCES MANUALLY === 641 % View time series 642 hFigSrc1 = view_timeseries(sFilesAvgDeviant01(1).FileName, 'MEG'); 643 % View on the cortex surface 644 hFigSrc2 = script_view_sources(sFilesSrcDeviant01.FileName, 'cortex'); 645 % Set current time to 90ms 646 panel_time('SetCurrentTime', 0.090); 647 % Set orientation 648 figure_3d('SetStandardView', hFigSrc2, 'left'); 649 % Set surface threshold 650 iSurf = 1; 651 thresh = .30; 652 panel_surface('SetDataThreshold', hFigSrc2, iSurf, thresh); 653 % Set surface smoothing 654 panel_surface('SetSurfaceSmooth', hFigSrc2, iSurf, .6, 0); 655 % Show sulci 656 panel_surface('SetShowSulci', hFigSrc2, iSurf, 1); 657 658 % View sources on MRI (3D orthogonal slices) 659 hFigSrc3 = script_view_sources(sFilesSrcDeviant01.FileName, 'mri3d'); 660 panel_surface('SetDataThreshold', hFigSrc3, iSurf, thresh); 661 % Set the position of the cuts in the 3D figure 662 cutsPosVox = [74 93 159]; 663 panel_surface('PlotMri', hFigSrc3, cutsPosVox); 664 665 % View sources with MRI Viewer 666 hFigSrc4 = script_view_sources(sFilesSrcDeviant01.FileName, 'mriviewer'); 667 panel_surface('SetDataThreshold', hFigSrc4, iSurf, thresh); 668 % Set the position of the cuts in the MRI Viewer (values in millimeters) 669 figure_mri('SetLocation', 'voxel', hFigSrc4, [], cutsPosVox); 670 % Close figures 671 close([hFigSrc1 hFigSrc2 hFigSrc3 hFigSrc4]); 672 673 % === UNCONSTRAINED EXAMPLE === 674 % Unconstrained minnorm 675 InverseOptions.Comment = 'MN: MEG'; 676 InverseOptions.InverseMeasure = 'amplitude'; 677 InverseOptions.SourceOrient = {'free'}; 678 % Process: Compute sources [2018] 679 sFilesSrcUnconst = bst_process('CallProcess', 'process_inverse_2018', sFilesAvgDeviant01, [], ... 680 'output', 2, ... % Kernel only: one per file 681 'inverse', InverseOptions); 682 683 684 % === NORMALIZED SOURCES === 685 % dSPM 686 InverseOptions.Comment = 'dSPM: MEG'; 687 InverseOptions.InverseMeasure = 'dspm2018'; 688 InverseOptions.SourceOrient = {'fixed'}; 689 sFilesSrcDspm = bst_process('CallProcess', 'process_inverse_2018', sFilesAvgDeviant01, [], ... 690 'output', 2, ... % Kernel only: one per file 691 'inverse', InverseOptions); 692 % sLORETA (old function) 693 sFilesSrcSloreta = bst_process('CallProcess', 'process_inverse', sFilesAvgDeviant01, [], ... 694 'comment', '', ... 695 'method', 3, ... % sLORETA 696 'wmne', struct(... 697 'SourceOrient', {{'fixed'}}, ... 698 'loose', 0.2, ... 699 'SNR', 3, ... 700 'pca', 1, ... 701 'diagnoise', 0, ... 702 'regnoise', 1, ... 703 'magreg', 0.1, ... 704 'gradreg', 0.1, ... 705 'depth', 1, ... 706 'weightexp', 0.5, ... 707 'weightlimit', 10), ... 708 'sensortypes', 'MEG, MEG MAG, MEG GRAD, EEG', ... 709 'output', 2); % Kernel only: one per file 710 % Process: Z-score normalization: [-100ms,-2ms] 711 sFilesSrcZscore = bst_process('CallProcess', 'process_baseline_norm', sFilesSrcDeviant01, [], ... 712 'baseline', [-0.100, -0.002], ... 713 'source_abs', 0, ... 714 'method', 'zscore'); % Z-score transformation: x_std = (x - μ) / σ 715 716 % Process: Snapshot: Sources (one time) 717 bst_process('CallProcess', 'process_snapshot', sFilesSrcDeviant01, [], ... 718 'target', 8, ... % Sources (one time) 719 'orient', 1, ... % left 720 'time', 0.09, ... 721 'threshold', 30, ... 722 'Comment', 'Current density map (Constrained)'); 723 bst_process('CallProcess', 'process_snapshot', sFilesSrcDspm, [], ... 724 'target', 8, ... % Sources (one time) 725 'orient', 1, ... % left 726 'time', 0.09, ... 727 'threshold', 60, ... 728 'Comment', 'dSPM'); 729 bst_process('CallProcess', 'process_snapshot', sFilesSrcSloreta, [], ... 730 'target', 8, ... % Sources (one time) 731 'orient', 1, ... % left 732 'time', 0.09, ... 733 'threshold', 60, ... 734 'Comment', 'sLORETA'); 735 bst_process('CallProcess', 'process_snapshot', sFilesSrcZscore, [], ... 736 'target', 8, ... % Sources (one time) 737 'orient', 1, ... % left 738 'time', 0.09, ... 739 'threshold', 60, ... 740 'Comment', 'Z-score'); 741 bst_process('CallProcess', 'process_snapshot', sFilesSrcUnconst, [], ... 742 'target', 8, ... % Sources (one time) 743 'orient', 1, ... % left 744 'time', 0.0917, ... 745 'threshold', 0, ... 746 'Comment', 'Current density map (Unconstrained)'); 747 748 % === DELETE EXPERIMENTS === 749 % Process: Delete constrained example 750 bst_process('CallProcess', 'process_delete', [sFilesSrcDeviant01, sFilesSrcDspm, sFilesSrcSloreta, sFilesSrcZscore, sFilesSrcUnconst], [], ... 751 'target', 1); % Delete selected files 752 753 754 % === SHARED KERNEL === 755 % Constrained minnorm 756 InverseOptions.Comment = 'MN: MEG'; 757 InverseOptions.InverseMeasure = 'amplitude'; 758 InverseOptions.SourceOrient = {'fixed'}; 759 % Process: Compute sources [2018] 760 sFilesAvgSrc = bst_process('CallProcess', 'process_inverse_2018', sFilesAvg, [], ... 761 'output', 1, ... % Kernel only: shared 762 'inverse', InverseOptions); 763 764 765 % === AVERAGE SOURCES ACROSS RUNS === 766 % Process: Average: By trial group (subject average) 767 sFilesIntraSrc = bst_process('CallProcess', 'process_average', sFilesAvgSrc, [], ... 768 'avgtype', 6, ... % By trial group (subject average) 769 'avg_func', 1, ... % Arithmetic average: mean(x) 770 'weighted', 1, ... 771 'scalenormalized', 0); 772 % Process: Low-pass:40Hz 773 sFilesIntraSrcLow = bst_process('CallProcess', 'process_bandpass', sFilesIntraSrc, [], ... 774 'highpass', 0, ... 775 'lowpass', 40, ... 776 'attenuation', 'strict', ... % 60dB 777 'mirror', 0, ... 778 'overwrite', 0); 779 % Process: Z-score normalization: [-100ms,-2ms] 780 sFilesIntraZscore = bst_process('CallProcess', 'process_baseline_norm', sFilesIntraSrcLow, [], ... 781 'baseline', [-0.100, -0.0017], ... 782 'source_abs', 0, ... 783 'method', 'zscore'); % Z-score transformation: x_std = (x - μ) / σ 784 785 % Process: Delete intermediate results 786 bst_process('CallProcess', 'process_delete', sFilesIntraSrcLow, [], ... 787 'target', 1); % Delete selected files 788 % Screen captures 789 bst_process('CallProcess', 'process_snapshot', sFilesIntraZscore, [], ... 790 'target', 8, ... % Sources (one time) 791 'orient', 1, ... % left 792 'time', 0.09, ... 793 'threshold', 40, ... 794 'Comment', 'Average across runs (left)'); 795 bst_process('CallProcess', 'process_snapshot', sFilesIntraZscore, [], ... 796 'target', 8, ... % Sources (one time) 797 'orient', 2, ... % right 798 'time', 0.09, ... 799 'threshold', 40, ... 800 'Comment', 'Average across runs (right)'); 801 bst_process('CallProcess', 'process_snapshot', sFilesIntraZscore(1), [], ... 802 'target', 9, ... % Sources (contact sheet) 803 'orient', 1, ... % left 804 'contact_time', [0, 0.35], ... 805 'contact_nimage', 15, ... 806 'threshold', 20, ... 807 'Comment', 'Average across runs'); 808 809 810 %% ===== TUTORIAL #23: SCOUTS ======================================================== 811 % =================================================================================== 812 disp([10 'DEMO> Tutorial #23: Scouts' 10]); 813 % Load surface file 814 sCortex = in_tess_bst(CortexFile); 815 % Add new scouts in first atlas 816 sCortex.iAtlas = find(strcmpi({sCortex.Atlas.Name}, 'Destrieux')); 817 % Save file 818 bst_save(file_fullpath(CortexFile), sCortex, 'v7'); 819 % Unload everything 820 bst_memory('UnloadAll', 'Forced'); 821 % Find scouts indices to display: {'A1L', 'A1R', 'IFGL', 'M1L'} 822 [tmp,iScouts,tmp] = intersect({sCortex.Atlas(sCortex.iAtlas).Scouts.Label}, {'G_temp_sup-G_T_transv L', 'G_temp_sup-G_T_transv R', 'G_front_inf-Opercular L', 'G_precentral L'}); 823 824 % View cortex 825 hFigSurf1 = view_surface(CortexFile, [], [], 'NewFigure'); 826 hFigSurf2 = view_surface(CortexFile, [], [], 'NewFigure'); 827 figure_3d('SetStandardView', hFigSurf1, 'left'); 828 figure_3d('SetStandardView', hFigSurf2, 'right'); 829 panel_surface('SetSurfaceSmooth', hFigSurf1, 1, .6, 0); 830 panel_surface('SetSurfaceSmooth', hFigSurf2, 1, .6, 0); 831 panel_surface('SetShowSulci', hFigSurf1, 1, 1); 832 panel_surface('SetShowSulci', hFigSurf2, 1, 1); 833 % Configure scouts display 834 panel_scout('SetScoutsOptions', 0, 1, 1, 'all', 0.7, 1, 1, 0); 835 % View scouts 836 hFigScouts = view_scouts({sFilesIntraZscore.FileName}, iScouts); 837 hLegend = findobj(hFigScouts, 'Type', 'legend'); 838 if ~isempty(hLegend) && ishandle(hLegend(1)) 839 set(hLegend(1), 'Units', 'pixels'); 840 pos = get(hLegend(1), 'Position'); 841 set(hLegend(1), 'Position', [1, 1, pos(3), pos(4)]); 842 end 843 % Save figures 844 bst_report('Snapshot', hFigScouts, sFilesIntraZscore(1).FileName, 'Scouts', [100 100 670 250]); 845 % Close all 846 pause(1); 847 bst_memory('UnloadAll', 'Forced'); 848 849 850 851 %% ===== TUTORIAL #24: TIME-FREQUENCY ================================================ 852 % =================================================================================== 853 disp([10 'DEMO> Tutorial #24: Time-frequency' 10]); 854 % Process: Simulate generic signals 855 sSim = bst_process('CallProcess', 'process_simulate_matrix', [], [], ... 856 'subjectname', 'Test', ... 857 'condition', 'Simulation', ... 858 'samples', 6000, ... 859 'srate', 1000, ... 860 'matlab', ['f1 = 2; f2 = 20; f3 = 50;' 10 'i =2000:6000;' 10 'Data(1,i) = sin(f1*2*pi*t(i)) + 0.4 * cos(f2*2*pi*t(i));' 10 'Data = Data + 0.2 * sin(f3*2*pi*t) + 0.4 * rand(1,6000);']); 861 862 % Time-frequency options 863 TfOptions = struct(... 864 'Comment', 'Power,1-60Hz', ... 865 'TimeBands', [], ... 866 'Freqs', [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60], ... 867 'MorletFc', 1, ... 868 'MorletFwhmTc', 3, ... 869 'ClusterFuncTime', 'none', ... 870 'Measure', 'power', ... 871 'Output', 'average', ... 872 'SaveKernel', 0); 873 % Process: Time-frequency (Morlet wavelets) 874 sSimTf1 = bst_process('CallProcess', 'process_timefreq', sSim, [], ... 875 'edit', TfOptions, ... 876 'normalize', 'multiply'); % 1/f compensation: Multiply output values by frequency 877 878 % === NORMALIZATION === 879 % Process: Time-frequency (Morlet wavelets) 880 sSimTf2 = bst_process('CallProcess', 'process_timefreq', sSim, [], ... 881 'edit', TfOptions, ... 882 'normalize', 'none'); % None: Save non-standardized time-frequency maps 883 % Process: Spectral flattening 884 sSimTf2Multi = bst_process('CallProcess', 'process_tf_norm', sSimTf2, [], ... 885 'normalize', 'multiply', ... % 1/f compensation (multiple by frequency) 886 'overwrite', 0); 887 % Process: Event-related perturbation (ERS/ERD): [750ms,1250ms] 888 sSimTf2Ersd = bst_process('CallProcess', 'process_baseline_norm', sSimTf2, [], ... 889 'baseline', [0.75, 1.25], ... 890 'method', 'ersd', ... % Event-related perturbation (ERS/ERD): x_std = (x - μ) / μ * 100 891 'overwrite', 0); 892 893 % Process: Snapshot: Time-frequency maps 894 bst_process('CallProcess', 'process_snapshot', sSimTf2, [], ... 895 'target', 14, ... % Time-frequency maps 896 'Comment', 'Not normalized'); 897 % Process: Snapshot: Time-frequency maps 898 bst_process('CallProcess', 'process_snapshot', sSimTf2Multi, [], ... 899 'target', 14, ... % Time-frequency maps 900 'Comment', 'Spectral flattening: 1/f compensation'); 901 % Process: Snapshot: Time-frequency maps 902 bst_process('CallProcess', 'process_snapshot', sSimTf2Ersd, [], ... 903 'target', 14, ... % Time-frequency maps 904 'Comment', 'ERS/ERD'); 905 % Spectrum/Time series 906 hFigTf1 = view_spectrum(sSimTf2.FileName, 'Spectrum'); 907 hFigTf2 = view_spectrum(sSimTf2.FileName, 'TimeSeries'); 908 panel_time('SetCurrentTime', 0.5); 909 panel_freq('SetCurrentFreq', 2, 0); 910 bst_report('Snapshot', [hFigTf1 hFigTf2], sSimTf2.FileName, 'Not normalized: 2s/20Hz', [200, 200, 400, 250]); 911 panel_time('SetCurrentTime', 2.02); 912 panel_freq('SetCurrentFreq', 20, 0); 913 bst_report('Snapshot', [hFigTf1 hFigTf2], sSimTf2.FileName, 'Not normalized: 2s/20Hz', [200, 200, 400, 250]); 914 bst_memory('UnloadAll', 'Forced'); 915 916 917 % === HILBERT TRANSFORM === 918 % Process: Hilbert transform 919 sSimHilbert = bst_process('CallProcess', 'process_hilbert', sSim, [], ... 920 'edit', struct(... 921 'Comment', 'Power', ... 922 'TimeBands', [], ... 923 'Freqs', {{'delta', '2, 4', 'mean'; 'theta', '5, 7', 'mean'; 'alpha', '8, 12', 'mean'; 'beta', '15, 29', 'mean'; 'gamma1', '30, 59', 'mean'; 'gamma2', '60, 90', 'mean'}}, ... 924 'ClusterFuncTime', 'none', ... 925 'Measure', 'power', ... 926 'Output', 'all', ... 927 'SaveKernel', 0), ... 928 'normalize', 'none', ... % None: Save non-standardized time-frequency maps 929 'mirror', 0); 930 % Process: Spectral flattening 931 sSimHilbertMulti = bst_process('CallProcess', 'process_tf_norm', sSimHilbert, [], ... 932 'normalize', 'multiply', ... % 1/f compensation (multiple by frequency) 933 'overwrite', 0); 934 % Process: Event-related perturbation (ERS/ERD): [750ms,1250ms] 935 sSimHilbertErsd = bst_process('CallProcess', 'process_baseline_norm', sSimHilbert, [], ... 936 'baseline', [0.75, 1.25], ... 937 'method', 'ersd', ... % Event-related perturbation (ERS/ERD): x_std = (x - μ) / μ * 100 938 'overwrite', 0); 939 940 % Process: Snapshot: Time-frequency maps 941 bst_process('CallProcess', 'process_snapshot', sSimHilbert, [], ... 942 'target', 14, ... % Time-frequency maps 943 'Comment', 'Not normalized'); 944 % Process: Snapshot: Time-frequency maps 945 bst_process('CallProcess', 'process_snapshot', sSimHilbertMulti, [], ... 946 'target', 14, ... % Time-frequency maps 947 'Comment', 'Spectral flattening: 1/f compensation'); 948 % Process: Snapshot: Time-frequency maps 949 bst_process('CallProcess', 'process_snapshot', sSimHilbertErsd, [], ... 950 'target', 14, ... % Time-frequency maps 951 'Comment', 'ERS/ERD'); 952 953 % === SINGLE TRIALS === 954 TfOptions.Comment = 'Avg,Power,1-150Hz'; 955 TfOptions.Freqs = [1, 2, 3.1, 4.2, 5.4, 6.7, 8, 9.5, 11, 12.6, 14.3, 16.1, 18.1, 20.1, 22.3, 24.6, 27, 29.6, 32.4, 35.3, 38.4, 41.6, 45.1, 48.8, 52.7, 56.9, 61.3, 66, 70.9, 76.2, 81.8, 87.7, 94, 100.6, 107.7, 115.2, 123.1, 131.6, 140.5, 150]; 956 % Process: Time-frequency (Morlet wavelets) 957 sEpochsAvgTf = bst_process('CallProcess', 'process_timefreq', sFilesEpochs1, [], ... 958 'sensortypes', 'MEG, EEG', ... 959 'edit', TfOptions, ... 960 'normalize', 'none'); % None: Save non-standardized time-frequency maps 961 % Process: Event-related perturbation (ERS/ERD): [-75ms,0ms] 962 sEpochsAvgTfErsd = bst_process('CallProcess', 'process_baseline_norm', sEpochsAvgTf, [], ... 963 'baseline', [-0.075, 0], ... 964 'method', 'ersd', ... % Event-related perturbation (ERS/ERD): x_std = (x - μ) / μ * 100 965 'overwrite', 0); 966 967 % === DISPLAY === 968 % View time-frequency file 969 hFigTf1 = view_timefreq(sEpochsAvgTfErsd.FileName, 'SingleSensor'); 970 % Configure display 971 sOptions = panel_display('GetDisplayOptions'); 972 sOptions.HideEdgeEffects = 1; 973 sOptions.HighResolution = 1; 974 panel_display('SetDisplayOptions', sOptions); 975 % Other display modes 976 hFigTf2 = view_timefreq(sEpochsAvgTfErsd.FileName, 'AllSensors'); 977 hFigTf3 = view_timefreq(sEpochsAvgTfErsd.FileName, '2DLayout'); 978 hFigTf4 = view_timefreq(sEpochsAvgTfErsd.FileName, '2DLayoutOpt'); 979 bst_colormaps('SetColormapName', 'stat2', 'jet'); 980 bst_colormaps('SetColormapAbsolute', 'stat2', 1); 981 bst_report('Snapshot', hFigTf1, sEpochsAvgTfErsd.FileName, 'Time-frequency', [200, 200, 400, 250]); 982 bst_report('Snapshot', [hFigTf2 hFigTf3 hFigTf4], sEpochsAvgTfErsd.FileName, 'Time-frequency', [200, 200, 750, 400]); 983 close([hFigTf1 hFigTf2 hFigTf3 hFigTf4]); 984 % Image [channel x time] 985 hFigTf5 = view_erpimage(sEpochsAvgTfErsd.FileName, 'trialimage'); 986 % Topographies 987 hFigTf6 = view_topography(sEpochsAvgTfErsd.FileName, 'MEG', '3DSensorCap'); 988 hFigTf7 = view_topography(sEpochsAvgTfErsd.FileName, 'MEG', '2DDisc'); 989 hFigTf8 = view_topography(sEpochsAvgTfErsd.FileName, 'MEG', '2DSensorCap'); 990 hFigTf9 = view_topography(sEpochsAvgTfErsd.FileName, 'MEG', '2DLayout'); 991 panel_time('SetCurrentTime', 0.175); 992 panel_freq('SetCurrentFreq', 8, 0); 993 bst_report('Snapshot', [hFigTf5 hFigTf6 hFigTf7 hFigTf8 hFigTf9], sEpochsAvgTfErsd.FileName, 'Time-frequency: 8Hz', [200, 200, 400, 250]); 994 close([hFigTf5 hFigTf6 hFigTf7 hFigTf8 hFigTf9]); 995 996 997 % === AVERAGE FOR SCOUTS === 998 % Select all sources for the single deviant epochs 999 sFilesEpochDeviantSrc = bst_process('CallProcess', 'process_select_files_results', [], [], ... 1000 'subjectname', SubjectName, ... 1001 'condition', '', ... 1002 'includebad', 0); 1003 sFilesEpochDeviantSrc = bst_process('CallProcess', 'process_select_tag', sFilesEpochDeviantSrc, [], ... 1004 'tag', 'deviant', ... 1005 'search', 1, ... % Search the file names 1006 'select', 1); % Select only the files with the tag 1007 sFilesEpochDeviantSrc = bst_process('CallProcess', 'process_select_tag', sFilesEpochDeviantSrc, [], ... 1008 'tag', 'average', ... 1009 'search', 1, ... % Search the file names 1010 'select', 2); % Exclude the files with the tag 1011 1012 % Process: Time-frequency (Morlet wavelets) 1013 sFilesTfScout = bst_process('CallProcess', 'process_timefreq', sFilesEpochDeviantSrc, [], ... 1014 'clusters', {'Destrieux', {'G_temp_sup-G_T_transv L', 'G_temp_sup-G_T_transv R', 'G_front_inf-Opercular L', 'G_precentral L'}}, ... 1015 'scoutfunc', 1, ... % Mean 1016 'edit', struct(... 1017 'Comment', 'Deviant: Scouts,Avg,Power,1-150Hz', ... 1018 'TimeBands', [], ... 1019 'Freqs', [1, 2, 3.1, 4.2, 5.4, 6.7, 8, 9.5, 11, 12.6, 14.3, 16.1, 18.1, 20.1, 22.3, 24.6, 27, 29.6, 32.4, 35.3, 38.4, 41.6, 45.1, 48.8, 52.7, 56.9, 61.3, 66, 70.9, 76.2, 81.8, 87.7, 94, 100.6, 107.7, 115.2, 123.1, 131.6, 140.5, 150], ... 1020 'MorletFc', 1, ... 1021 'MorletFwhmTc', 3, ... 1022 'ClusterFuncTime', 'after', ... 1023 'Measure', 'power', ... 1024 'Output', 'average', ... 1025 'SaveKernel', 0), ... 1026 'normalize', 'none'); % None: Save non-standardized time-frequency maps) 1027 % Process: Event-related perturbation (ERS/ERD): [-75ms,0ms] 1028 sFilesTfScoutErsd = bst_process('CallProcess', 'process_baseline_norm', sFilesTfScout, [], ... 1029 'baseline', [-0.075, 0], ... 1030 'method', 'ersd', ... % Event-related perturbation (ERS/ERD): x_std = (x - μ) / μ * 100 1031 'overwrite', 0); 1032 % Process: Snapshot: Time-frequency maps 1033 bst_process('CallProcess', 'process_snapshot', sFilesTfScoutErsd, [], ... 1034 'target', 14, ... % Time-frequency maps 1035 'Comment', 'ERS/ERD'); 1036 1037 1038 % === FULL CORTEX / HILBERT === 1039 % Process: Hilbert transform 1040 sFilesHilbertCortex = bst_process('CallProcess', 'process_hilbert', sFilesEpochDeviantSrc, [], ... 1041 'clusters', {}, ... 1042 'scoutfunc', 1, ... % Mean 1043 'edit', struct(... 1044 'Comment', 'Deviant: Avg,Magnitude', ... 1045 'TimeBands', [], ... 1046 'Freqs', {{'delta', '2, 4', 'mean'; 'theta', '5, 7', 'mean'; 'alpha', '8, 12', 'mean'; 'beta', '15, 29', 'mean'; 'gamma1', '30, 59', 'mean'; 'gamma2', '60, 90', 'mean'}}, ... 1047 'ClusterFuncTime', 'none', ... 1048 'Measure', 'power', ... 1049 'Output', 'average', ... 1050 'RemoveEvoked', 0, ... 1051 'SaveKernel', 0), ... 1052 'normalize', 'none', ... % None: Save non-standardized time-frequency maps 1053 'mirror', 0); 1054 % Process: Event-related perturbation (ERS/ERD): [-75ms,0ms] 1055 sFilesHilbertCortexErsd = bst_process('CallProcess', 'process_baseline_norm', sFilesHilbertCortex, [], ... 1056 'baseline', [-0.075, 0], ... 1057 'method', 'ersd', ... % Event-related perturbation (ERS/ERD): x_std = (x - μ) / μ * 100 1058 'overwrite', 0); 1059 1060 % View results 1061 hFigTf1 = view_surface_data([], sFilesHilbertCortexErsd.FileName); 1062 hFigTf2 = view_timefreq(sFilesHilbertCortexErsd.FileName, 'SingleSensor', 362); 1063 figure_3d('SetStandardView', hFigTf1, 'left'); 1064 panel_surface('SetDataThreshold', hFigTf1, 1, 0.5); 1065 panel_time('SetCurrentTime', 0.175); 1066 panel_freq('SetCurrentFreq', 3); 1067 bst_colormaps('RestoreDefaults', 'stat2'); 1068 bst_report('Snapshot', [hFigTf1 hFigTf2], sFilesHilbertCortexErsd.FileName, 'Hilbert transform: Alpha band', [200, 200, 400, 250]); 1069 bst_memory('UnloadAll', 'Forced'); 1070 1071 1072 %% ===== TUTORIAL #25: DIFFRERENCE =================================================== 1073 % =================================================================================== 1074 disp([10 'DEMO> Tutorial #25: Difference' 10]); 1075 1076 % ===== SELECT TRIALS (DATA) ===== 1077 % Process: Select recordings in: Subject01/* 1078 sFilesAll = bst_process('CallProcess', 'process_select_files_data', [], [], ... 1079 'subjectname', SubjectName, ... 1080 'condition', '', ... 1081 'includebad', 0); 1082 % Process: Select file names with tag: deviant_trial 1083 sEpochDeviant = bst_process('CallProcess', 'process_select_tag', sFilesAll, [], ... 1084 'tag', 'deviant_trial', ... 1085 'search', 1, ... % Search the file names 1086 'select', 1); % Select only the files with the tag 1087 % Process: Select file names with tag: standard_trial 1088 sEpochStandard = bst_process('CallProcess', 'process_select_tag', sFilesAll, [], ... 1089 'tag', 'standard_trial', ... 1090 'search', 1, ... % Search the file names 1091 'select', 1); % Select only the files with the tag 1092 1093 % ===== SELECT TRIALS (SOURCE) ===== 1094 % Process: Select recordings in: Subject01/* 1095 sFilesAllSrc = bst_process('CallProcess', 'process_select_files_results', [], [], ... 1096 'subjectname', SubjectName, ... 1097 'condition', '', ... 1098 'includebad', 0); 1099 % Process: Select file names with tag: deviant_trial 1100 sEpochDeviantSrc = bst_process('CallProcess', 'process_select_tag', sFilesAllSrc, [], ... 1101 'tag', 'deviant_trial', ... 1102 'search', 1, ... % Search the file names 1103 'select', 1); % Select only the files with the tag 1104 % Process: Select file names with tag: standard_trial 1105 sEpochStandardSrc = bst_process('CallProcess', 'process_select_tag', sFilesAllSrc, [], ... 1106 'tag', 'standard_trial', ... 1107 'search', 1, ... % Search the file names 1108 'select', 1); % Select only the files with the tag 1109 1110 % ===== ABSOLUTE DIFFERENCE ====== 1111 % Process: Difference: A-B, abs 1112 sDiffSrc = bst_process('CallProcess', 'process_diff_ab', sFilesIntraSrc(1).FileName, sFilesIntraSrc(2).FileName, ... 1113 'source_abs', 1); 1114 % Process: Set comment: deviant|abs - standard|abs 1115 sDiffSrc = bst_process('CallProcess', 'process_set_comment', sDiffSrc, [], ... 1116 'tag', 'deviant|abs - standard|abs', ... 1117 'isindex', 1); 1118 % Process: Low-pass:40Hz 1119 sDiffSrcZscore = bst_process('CallProcess', 'process_bandpass', sDiffSrc, [], ... 1120 'highpass', 0, ... 1121 'lowpass', 40, ... 1122 'attenuation', 'strict', ... % 60dB 1123 'mirror', 0, ... 1124 'overwrite', 1); 1125 % Process: Z-score transformation: [-100ms,-2ms] 1126 sDiffSrcZscore = bst_process('CallProcess', 'process_baseline_norm', sDiffSrcZscore, [], ... 1127 'baseline', [-0.1, -0.002], ... 1128 'source_abs', 0, ... 1129 'method', 'zscore', ... % Z-score transformation: x_std = (x - μ) / σ 1130 'overwrite', 0); 1131 % Process: Snapshot: Sources (contact sheet) 1132 bst_process('CallProcess', 'process_snapshot', sDiffSrcZscore, [], ... 1133 'target', 9, ... % Sources (contact sheet) 1134 'modality', 1, ... % MEG (All) 1135 'orient', 1, ... % left 1136 'contact_time', [0, 0.35], ... 1137 'contact_nimage', 15, ... 1138 'threshold', 30, ... 1139 'Comment', 'Difference deviant - standard (absolute)'); 1140 1141 % ===== RELATIVE DIFFERENCE ===== 1142 % Process: Difference: A-B 1143 sDiffSrcRel = bst_process('CallProcess', 'process_diff_ab', sFilesIntraSrc(1).FileName, sFilesIntraSrc(2).FileName, ... 1144 'source_abs', 0); 1145 % Process: Set comment: deviant - standard 1146 sDiffSrcRel = bst_process('CallProcess', 'process_set_comment', sDiffSrcRel, [], ... 1147 'tag', 'deviant - standard', ... 1148 'isindex', 1); 1149 % Process: Low-pass:40Hz 1150 sDiffSrcRelZscore = bst_process('CallProcess', 'process_bandpass', sDiffSrcRel, [], ... 1151 'highpass', 0, ... 1152 'lowpass', 40, ... 1153 'attenuation', 'strict', ... % 60dB 1154 'mirror', 0, ... 1155 'overwrite', 1); 1156 % Process: Z-score transformation: [-100ms,-2ms] 1157 sDiffSrcRelZscore = bst_process('CallProcess', 'process_baseline_norm', sDiffSrcRelZscore, [], ... 1158 'baseline', [-0.1, -0.002], ... 1159 'source_abs', 0, ... 1160 'method', 'zscore', ... % Z-score transformation: x_std = (x - μ) / σ 1161 'overwrite', 0); 1162 % Configure colormap: hot/absolute 1163 bst_colormaps('SetColormapName', 'stat2', 'hot'); 1164 bst_colormaps('SetColormapAbsolute', 'stat2', 1); 1165 % Process: Snapshot: Sources (contact sheet) 1166 bst_process('CallProcess', 'process_snapshot', sDiffSrcRelZscore, [], ... 1167 'target', 9, ... % Sources (contact sheet) 1168 'modality', 1, ... % MEG (All) 1169 'orient', 1, ... % left 1170 'contact_time', [0, 0.35], ... 1171 'contact_nimage', 15, ... 1172 'threshold', 30, ... 1173 'Comment', 'Difference deviant - standard (relative)'); 1174 % Restore colormap: rwb/relative 1175 bst_colormaps('SetColormapName', 'stat2', 'cmap_rbw'); 1176 bst_colormaps('SetColormapAbsolute', 'stat2', 0); 1177 1178 % ===== DIFFERENCE OF MEANS ===== 1179 % Process: Select uniform number of files [uniform] 1180 [sEpochDeviantUni, sEpochStandardUni] = bst_process('CallProcess', 'process_select_uniform2', sEpochDeviant, sEpochStandard, ... 1181 'nfiles', 0, ... 1182 'method', 4); % Uniformly distributed 1183 % Process: Difference of means [mean] 1184 sDiffMean = bst_process('CallProcess', 'process_diff_mean', sEpochDeviantUni, sEpochStandardUni, ... 1185 'avg_func', 1, ... % Arithmetic average mean(A) - mean(B) 1186 'weighted', 0); 1187 % Process: Snapshot: Recordings time series 1188 bst_process('CallProcess', 'process_snapshot', sDiffMean, [], ... 1189 'target', 5, ... % Recordings time series 1190 'modality', 1, ... % MEG (All) 1191 'Comment', 'Difference of means'); 1192 1193 1194 1195 %% ===== TUTORIAL #26: STATISTICS ==================================================== 1196 % =================================================================================== 1197 disp([10 'DEMO> Tutorial #26: Statistics' 10]); 1198 % ===== HISTOGRAMS ===== 1199 % Process: Extract values: [160ms] MLP57 1200 sHistoDeviant = bst_process('CallProcess', 'process_extract_values', sEpochDeviant, [], ... 1201 'timewindow', [0.16, 0.16], ... 1202 'sensortypes', 'MLP57', ... 1203 'isabs', 0, ... 1204 'avgtime', 0, ... 1205 'avgrow', 0, ... 1206 'dim', 2, ... % Concatenate time (dimension 2) 1207 'Comment', ''); 1208 % Process: Extract values: [160ms] MLP57 1209 sHistoStandard = bst_process('CallProcess', 'process_extract_values', sEpochStandard, [], ... 1210 'timewindow', [0.16, 0.16], ... 1211 'sensortypes', 'MLP57', ... 1212 'isabs', 0, ... 1213 'avgtime', 0, ... 1214 'avgrow', 0, ... 1215 'dim', 2, ... % Concatenate time (dimension 2) 1216 'Comment', ''); 1217 % Display histograms 1218 hFigHisto = view_histogram({sHistoDeviant.FileName, sHistoStandard.FileName}); 1219 bst_report('Snapshot', hFigHisto, sHistoDeviant.FileName, 'Histograms for MLP57/160ms'); 1220 close(hFigHisto); 1221 1222 % ===== EXEMPLE #1: PARAMETRIC/DATA ===== 1223 % Process: t-test [equal] [-100ms,500ms] H0:(A-B = 0) 1224 sTestParamData = bst_process('CallProcess', 'process_test_parametric2', sEpochDeviant, sEpochStandard, ... 1225 'timewindow', [-0.1, 0.5], ... 1226 'sensortypes', '', ... 1227 'isabs', 0, ... 1228 'avgtime', 0, ... 1229 'avgrow', 0, ... 1230 'Comment', '', ... 1231 'test_type', 'ttest_equal', ... % Student's t-test (equal variance) t = (mean(A)-mean(B)) / (Sx * sqrt(1/nA + 1/nB))Sx = sqrt(((nA-1)*var(A) + (nB-1)*var(B)) / (nA+nB-2)) df = nA + nB - 2 1232 'tail', 'two'); % Two-tailed 1233 % Set display properties 1234 StatThreshOptions = bst_get('StatThreshOptions'); 1235 StatThreshOptions.pThreshold = 0.05; 1236 StatThreshOptions.Correction = 'fdr'; 1237 StatThreshOptions.Control = [1 2 3]; 1238 bst_set('StatThreshOptions', StatThreshOptions); 1239 % Process: Snapshot: Recordings time series 1240 bst_process('CallProcess', 'process_snapshot', sTestParamData, [], ... 1241 'target', 5, ... % Recordings time series 1242 'modality', 1, ... % MEG (All) 1243 'time', 0.16, ... 1244 'Comment', 'Parametric t-test (p<0.05, FDR)'); 1245 % Process: Snapshot: Recordings topography (one time) 1246 bst_process('CallProcess', 'process_snapshot', sTestParamData, [], ... 1247 'target', 6, ... % Recordings topography (one time) 1248 'modality', 1, ... % MEG (All) 1249 'time', 0.16, ... 1250 'Comment', 'Parametric t-test (p<0.05, FDR)'); 1251 1252 % ===== EXEMPLE #2: NON-PARAMETRIC/DATA ===== 1253 % Process: Perm t-test equal [-100ms,500ms MEG] H0:(A=B), H1:(A<>B) 1254 sTestPermData = bst_process('CallProcess', 'process_test_permutation2', sEpochDeviant, sEpochStandard, ... 1255 'timewindow', [-0.1, 0.5], ... 1256 'sensortypes', 'MEG', ... 1257 'isabs', 0, ... 1258 'avgtime', 0, ... 1259 'avgrow', 0, ... 1260 'iszerobad', 1, ... 1261 'Comment', '', ... 1262 'test_type', 'ttest_equal', ... % Student's t-test (equal variance) t = (mean(A)-mean(B)) / (Sx * sqrt(1/nA + 1/nB))Sx = sqrt(((nA-1)*var(A) + (nB-1)*var(B)) / (nA+nB-2)) 1263 'randomizations', 1000, ... 1264 'tail', 'two'); % Two-tailed 1265 % Process: Snapshot: Recordings time series 1266 bst_process('CallProcess', 'process_snapshot', sTestPermData, [], ... 1267 'target', 5, ... % Recordings time series 1268 'modality', 1, ... % MEG (All) 1269 'time', 0.16, ... 1270 'Comment', 'Non-parametric t-test (p<0.05, FDR)'); 1271 % Process: Snapshot: Recordings topography (one time) 1272 bst_process('CallProcess', 'process_snapshot', sTestPermData, [], ... 1273 'target', 6, ... % Recordings topography (one time) 1274 'modality', 1, ... % MEG (All) 1275 'time', 0.16, ... 1276 'Comment', 'Non-parametric t-test (p<0.05, FDR)'); 1277 1278 % ===== EXEMPLE #3: CLUSTER/DATA ===== 1279 % Process: FT t-test unequal cluster [-100ms,500ms MEG] H0:(A=B), H1:(A<>B) 1280 sTestClustData = bst_process('CallProcess', 'process_ft_timelockstatistics', sEpochDeviant, sEpochStandard, ... 1281 'sensortypes', 'MEG', ... 1282 'timewindow', [-0.1, 0.5], ... 1283 'isabs', 0, ... 1284 'avgtime', 0, ... 1285 'avgchan', 0, ... 1286 'randomizations', 1000, ... 1287 'statistictype', 1, ... % Independent t-test 1288 'tail', 'two', ... % Two-tailed 1289 'correctiontype', 2, ... % cluster 1290 'minnbchan', 0, ... 1291 'clusteralpha', 0.05); 1292 % Process: Snapshot: Recordings time series 1293 bst_process('CallProcess', 'process_snapshot', sTestClustData, [], ... 1294 'target', 5, ... % Recordings time series 1295 'time', 0.16, ... 1296 'modality', 1, ... % MEG (All) 1297 'Comment', 'Cluster-based permutation test'); 1298 % Process: Snapshot: Recordings topography (one time) 1299 bst_process('CallProcess', 'process_snapshot', sTestClustData, [], ... 1300 'target', 6, ... % Recordings topography (one time) 1301 'modality', 1, ... % MEG (All) 1302 'time', 0.16, ... 1303 'Comment', 'Cluster-based permutation test'); 1304 1305 % ===== EXAMPLE #4: PARAMETRIC/SOURCES ===== 1306 % Process: t-test [equal] [-100ms,500ms] H0:(A-B = 0) 1307 sTestParamSrc = bst_process('CallProcess', 'process_test_parametric2', sEpochDeviantSrc, sEpochStandardSrc, ... 1308 'timewindow', [-0.1, 0.5], ... 1309 'scoutsel', {}, ... 1310 'scoutfunc', 1, ... % Mean 1311 'isnorm', 0, ... 1312 'avgtime', 0, ... 1313 'Comment', '', ... 1314 'test_type', 'ttest_equal', ... % Student's t-test (equal variance) t = (mean(A)-mean(B)) / (Sx * sqrt(1/nA + 1/nB))Sx = sqrt(((nA-1)*var(A) + (nB-1)*var(B)) / (nA+nB-2)) df = nA + nB - 2 1315 'tail', 'two'); % Two-tailed 1316 % Process: Difference of means [abs(mean)] 1317 sDiffMeanSrc = bst_process('CallProcess', 'process_diff_mean', sEpochDeviantSrc, sEpochStandardSrc, ... 1318 'avg_func', 2, ... % Absolute value of average abs(mean(A)) - abs(mean(B)) 1319 'weighted', 0); 1320 % Process: Apply statistic threshold: p<0.05 (FDR:1,2,3) 1321 sDiffMeanSrcThresh = bst_process('CallProcess', 'process_extract_pthresh2', sTestParamSrc, sDiffMeanSrc, ... 1322 'pthresh', 0.05, ... 1323 'correction', 3, ... % False discovery rate (FDR) 1324 'control1', 1, ... 1325 'control2', 1, ... 1326 'control3', 1); 1327 % Process: Snapshot: Sources (one time) 1328 bst_process('CallProcess', 'process_snapshot', sTestParamSrc, [], ... 1329 'target', 8, ... % Sources (one time) 1330 'orient', 1, ... % left 1331 'time', 0.148, ... 1332 'threshold', 40, ... 1333 'Comment', 'Parametric t-test (p<0.05, FDR)'); 1334 % Process: Snapshot: Sources (one time) 1335 bst_process('CallProcess', 'process_snapshot', sDiffMeanSrc, [], ... 1336 'target', 8, ... % Sources (one time) 1337 'orient', 1, ... % left 1338 'time', 0.148, ... 1339 'threshold', 40, ... 1340 'Comment', 'abs(average(deviant)) - abs(average(standard))'); 1341 % Process: Snapshot: Sources (one time) 1342 bst_process('CallProcess', 'process_snapshot', sDiffMeanSrcThresh, [], ... 1343 'target', 8, ... % Sources (one time) 1344 'orient', 1, ... % left 1345 'time', 0.148, ... 1346 'threshold', 0, ... 1347 'Comment', 'Different of mean thresholded with t-test results'); 1348 1349 % ===== EXAMPLE #5: PARAMETRIC/SCOUTS ===== 1350 % Process: t-test equal [-100ms,500ms] H0:(A=B), H1:(A<>B) 1351 sTestParamScout = bst_process('CallProcess', 'process_test_parametric2', sEpochDeviantSrc, sEpochStandardSrc, ... 1352 'timewindow', [-0.1, 0.5], ... 1353 'scoutsel', {'Destrieux', {'G_front_inf-Opercular L', 'G_precentral L', 'G_temp_sup-G_T_transv L'}}, ... 1354 'scoutfunc', 1, ... % Mean 1355 'isnorm', 0, ... 1356 'avgtime', 0, ... 1357 'Comment', '', ... 1358 'test_type', 'ttest_equal', ... % Student's t-test (equal variance) t = (mean(A)-mean(B)) / (Sx * sqrt(1/nA + 1/nB))Sx = sqrt(((nA-1)*var(A) + (nB-1)*var(B)) / (nA+nB-2)) df = nA + nB - 2 1359 'tail', 'two'); % Two-tailed 1360 % Process: Apply statistic threshold: p<0.05 (FDR:1,2,3) 1361 sTestParamScoutThresh = bst_process('CallProcess', 'process_extract_pthresh', sTestParamScout, [], ... 1362 'pthresh', 0.05, ... 1363 'correction', 3, ... % False discovery rate (FDR) 1364 'control1', 1, ... 1365 'control2', 1, ... 1366 'control3', 1); 1367 % Process: Compute head model 1368 bst_process('CallProcess', 'process_headmodel', sTestParamScoutThresh, [], ... 1369 'sourcespace', 1, ... % Cortex surface 1370 'meg', 3); % Overlapping spheres 1371 % Process: Simulate recordings from scouts 1372 sSimulData = bst_process('CallProcess', 'process_simulate_recordings', sTestParamScoutThresh, [], ... 1373 'scouts', {'Destrieux', {'G_front_inf-Opercular L', 'G_precentral L', 'G_temp_sup-G_T_transv L'}}, ... 1374 'savesources', 1); 1375 1376 % Get corresponding source file 1377 [sStudy,iStudy,iRes] = bst_get('ResultsForDataFile', sSimulData.FileName); 1378 sSimulSrc = sStudy.Result(iRes).FileName; 1379 % Reset visualization filters 1380 panel_filter('SetFilters', 0, [], 0, [], 0, [], 0, 0); 1381 % Process: Snapshot: Recordings time series 1382 bst_process('CallProcess', 'process_snapshot', sTestParamScout, [], ... 1383 'target', 5, ... % Recordings time series 1384 'time', 0.148, ... 1385 'Comment', 'Parametric t-test (p<0.05, FDR)'); 1386 % Process: Snapshot: Sources (one time) 1387 bst_process('CallProcess', 'process_snapshot', sSimulSrc, [], ... 1388 'target', 8, ... % Sources (one time) 1389 'orient', 1, ... % left 1390 'time', 0.148, ... 1391 'threshold', 0, ... 1392 'Comment', 'Simulated sources'); 1393 % Process: Snapshot: Recordings time series 1394 bst_process('CallProcess', 'process_snapshot', sSimulData, [], ... 1395 'target', 5, ... % Recordings time series 1396 'modality', 1, ... % MEG (All) 1397 'time', 0.148, ... 1398 'Comment', 'Simulated MEG recordings'); 1399 1400 1401 % ===== EXAMPLE #6: NON-PARAMETRIC/TIMEFREQ ===== 1402 TfOptions.Output = 'all'; 1403 % Process: Time-frequency (Morlet wavelets) / DEVIANT 1404 sEpochDeviantTf = bst_process('CallProcess', 'process_timefreq', sEpochDeviant, [], ... 1405 'sensortypes', 'MLP57', ... 1406 'edit', TfOptions, ... 1407 'normalize', 'none'); % None: Save non-standardized time-frequency maps 1408 % Process: Time-frequency (Morlet wavelets) / STANDARD 1409 sEpochStandardTf = bst_process('CallProcess', 'process_timefreq', sEpochStandard, [], ... 1410 'sensortypes', 'MLP57', ... 1411 'edit', TfOptions, ... 1412 'normalize', 'none'); % None: Save non-standardized time-frequency maps 1413 % Process: Perm t-test equal [-100ms,500ms 1-150Hz] H0:(A=B), H1:(A<>B) 1414 sTestTf = bst_process('CallProcess', 'process_test_permutation2', sEpochDeviantTf, sEpochStandardTf, ... 1415 'timewindow', [-0.1, 0.5], ... 1416 'freqrange', [1, 150], ... 1417 'rows', '', ... 1418 'isabs', 0, ... 1419 'avgtime', 0, ... 1420 'avgrow', 0, ... 1421 'avgfreq', 0, ... 1422 'matchrows', 0, ... 1423 'iszerobad', 1, ... 1424 'Comment', '', ... 1425 'test_type', 'ttest_equal', ... % Student's t-test (equal variance) t = (mean(A)-mean(B)) / (Sx * sqrt(1/nA + 1/nB))Sx = sqrt(((nA-1)*var(A) + (nB-1)*var(B)) / (nA+nB-2)) 1426 'randomizations', 1000, ... 1427 'tail', 'two'); % Two-tailed 1428 % Set stat threshold 1429 StatThreshOptions.pThreshold = 0.05; 1430 StatThreshOptions.Correction = 'none'; 1431 bst_set('StatThreshOptions', StatThreshOptions); 1432 % Process: Snapshot: Time-frequency maps 1433 bst_process('CallProcess', 'process_snapshot', sTestTf, [], ... 1434 'target', 14, ... % Time-frequency maps 1435 'Comment', 'Non-parametric t-test (p<0.05, Uncorrected)'); 1436 % Process: Delete intermediate results 1437 bst_process('CallProcess', 'process_delete', [sEpochDeviantTf, sEpochStandardTf], [], ... 1438 'target', 1); % Delete selected files 1439 1440 1441 1442 %% ===== SAVE REPORT ===== 1443 % Save and display report 1444 ReportFile = bst_report('Save', []); 1445 if ~isempty(reports_dir) && ~isempty(ReportFile) 1446 bst_report('Export', ReportFile, reports_dir); 1447 else 1448 bst_report('Open', ReportFile); 1449 end 1450 1451 disp([10 'DEMO> Done.' 10]);


For an example of a script illustrating how to create loops, look at the tutorial MEG visual: single subject. brainstorm3/toolbox/script/tutorial_visual_single.m

1 function tutorial_visual_single(bids_dir, reports_dir) 2 % TUTORIAL_VISUAL_SINGLE: Runs the Brainstorm/SPM group analysis pipeline (single subject, BIDS version). 3 % 4 % ONLINE TUTORIALS: https://neuroimage.usc.edu/brainstorm/Tutorials/VisualSingle 5 % 6 % INPUTS: 7 % - bids_dir: Path to folder ds000117 (https://openneuro.org/datasets/ds000117) 8 % |- derivatives/freesurfer/sub-XX : Segmentation folders generated with FreeSurfer 9 % |- derivatives/meg_derivatives/sub-XX/ses-meg/meg/*.fif : MEG+EEG recordings (processed with MaxFilter's SSS) 10 % |- derivatives/meg_derivatives/sub-emptyroom/ses-meg/meg/*.fif : Empty room measurements 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)2000-2020 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 34 %% ===== SCRIPT VARIABLES ===== 35 % Full list of subjects to process 36 SubjectNames = {'sub-01', 'sub-02', 'sub-03', 'sub-04', 'sub-05', 'sub-06', 'sub-07', 'sub-08', ... 37 'sub-09', 'sub-10', 'sub-11', 'sub-12', 'sub-13', 'sub-14', 'sub-15', 'sub-16'}; 38 % Empty-room dates for each subject (so that we can match automatically recordings with empty-room) 39 EmptyRoomSubj = 'sub-emptyroom'; 40 AcquisitionDates = {'09-Apr-2009', '06-May-2009', '11-May-2009', '18-May-2009', '15-May-2009', '15-May-2009', '15-May-2009', '15-May-2009', ... 41 '15-May-2009', '15-May-2009', '01-Jun-2009', '01-Jun-2009', '01-Jun-2009', '26-Nov-2009', '08-Dec-2009', '08-Dec-2009'}; 42 % Bad channels {iSubj} = {Run01, Run02, Run03, Run04, Run05, Run06} 43 BadChannels{1} = {'EEG016', 'EEG070', 'EEG050',{'EEG008','EEG050'}, [], []}; 44 BadChannels{2} = {{'EEG027', 'EEG030', 'EEG038'}, 'EEG010', 'EEG010', 'EEG010', 'EEG010', 'EEG010'}; 45 BadChannels{3} = {{'EEG008','EEG017'}, {'EEG008','EEG017'}, {'EEG008','EEG017'}, {'EEG008','EEG017'}, {'EEG008','EEG017','EEG001'}, {'EEG008','EEG017','EEG020'}}; 46 BadChannels{4} = {{'EEG038'}, {'EEG038','EEG001','EEG016'}, {'EEG038','EEG001','EEG016'}, {'EEG038','EEG001'}, {'EEG038','EEG001','EEG016'}, {'EEG038','EEG001','EEG016'}}; 47 BadChannels{5} = {'EEG001', 'EEG001', [], [], [], []}; 48 BadChannels{6} = {'EEG068', [], 'EEG004', [], [], []}; 49 BadChannels{7} = {[], [], {'EEG004','EEG008'}, {'EEG004','EEG008'},{'EEG004','EEG008','EEG043','EEG045','EEG047'}, {'EEG004','EEG008'}}; 50 BadChannels{8} = {[], [], [], [], [], []}; 51 BadChannels{9} = {[], 'EEG004', 'EEG004', [], 'EEG004', 'EEG004'}; 52 BadChannels{10} = {[], [], [], [], [], []}; 53 BadChannels{11} = {{'EEG010','EEG050'}, 'EEG050', 'EEG050', 'EEG050', 'EEG050', 'EEG050'}; 54 BadChannels{12} = {{'EEG024','EEG057'}, {'EEG024','EEG057'}, {'EEG024','EEG057'}, {'EEG024','EEG057','EEG070'}, {'EEG024','EEG057'}, {'EEG024','EEG057','EEG070'}}; 55 BadChannels{13} = {'EEG009', 'EEG009', {'EEG009','EEG057','EEG69'}, 'EEG009', {'EEG009','EEG044'}, {'EEG009','EEG044'}}; 56 BadChannels{14} = {'EEG029', 'EEG029', 'EEG029', {'EEG004','EEG008','EEG016','EEG029'}, {'EEG004','EEG008','EEG016','EEG029'}, {'EEG004','EEG008','EEG016','EEG029'}}; 57 BadChannels{15} = {'EEG038', 'EEG038', 'EEG038', 'EEG038', {'EEG054','EEG038'}, 'EEG038'}; 58 BadChannels{16} = {'EEG008', 'EEG008', 'EEG008', 'EEG008', 'EEG008', 'EEG008'}; 59 % SSP components to remove {iSubj} = {sRun01, sRun02, sRun03, sRun03, sRun04, sRun05, sRun06}, sRun0X={ECG_GRAD,ECG_MAG} 60 SspSelect{1} = {{1,1}, {1,1}, {1,1}, {1,1}, {1,1}, {1,1}}; 61 SspSelect{2} = {{1,1}, {1,1}, {1,1}, {1,1}, {3,1}, {1,1}}; 62 SspSelect{3} = {{[],1}, {1,1}, {1,1}, {1,1}, {1,1}, {1,1}}; 63 SspSelect{4} = {{[],1}, {[],1}, {[],1}, {[],1}, {[],1}, {[],1}}; 64 SspSelect{5} = {{2,1}, {1,1}, {1,1}, {[],1}, {1,1}, {1,1}}; 65 SspSelect{6} = {{2,1}, {2,1}, {1,1}, {2,1}, {1,1}, {2,1}}; 66 SspSelect{7} = {{1,1}, {1,1}, {1,1}, {1,1}, {1,1}, {1,1}}; 67 SspSelect{8} = {{1,1}, {1,1}, {[],1}, {2,1}, {1,1}, {2,1}}; 68 SspSelect{9} = {{1,1}, {1,1}, {[],1}, {[],1}, {1,1}, {1,1}}; 69 SspSelect{10} = {{1,1}, {1,1}, {1,1}, {1,1}, {1,1}, {1,1}}; 70 SspSelect{11} = {{[],1}, {[],1}, {[],1}, {[],1}, {[],[]}, {[],[]}}; 71 SspSelect{12} = {{[1,2],[1,2]}, {1,1}, {1,1}, {1,1}, {1,1}, {1,1}}; 72 SspSelect{13} = {{[],[]}, {[],[]}, {[],[]}, {[],[]}, {[],[]}, {[],[]}}; 73 SspSelect{14} = {{1,1}, {1,1}, {1,1}, {1,1}, {1,1}, {1,1}}; 74 SspSelect{15} = {{1,1}, {1,1}, {1,1}, {1,1}, {1,1}, {1,1}}; 75 SspSelect{16} = {{1,1}, {1,1}, {1,1}, {2,1}, {1,1}, {1,1}}; 76 77 78 %% ===== CREATE PROTOCOL ===== 79 % Start brainstorm without the GUI 80 if ~brainstorm('status') 81 brainstorm nogui 82 end 83 % Output folder for reports 84 if (nargin < 2) || isempty(reports_dir) || ~isdir(reports_dir) 85 reports_dir = []; 86 end 87 % You have to specify the folder in which the tutorial dataset is unzipped 88 if (nargin < 1) || isempty(bids_dir) || ~file_exist(bids_dir) || ~file_exist(bst_fullfile(bids_dir, 'derivatives')) || ~file_exist(bst_fullfile(bids_dir, 'dataset_description.json')) 89 error('The first argument must be the full path to the tutorial folder.'); 90 end 91 % The protocol name has to be a valid folder name (no spaces, no weird characters...) 92 ProtocolName = 'TutorialVisual'; 93 % Delete existing protocol 94 gui_brainstorm('DeleteProtocol', ProtocolName); 95 % Create new protocol 96 gui_brainstorm('CreateProtocol', ProtocolName, 0, 0); 97 % Set visualization filters: 40Hz low-pass, no high-pass 98 panel_filter('SetFilters', 1, 40, 0, [], 0, [], 0, 0); 99 % Set colormap: local color scale 100 bst_colormaps('SetMaxMode', 'meg', 'local'); 101 bst_colormaps('SetMaxMode', 'eeg', 'local'); 102 103 104 %% ===== PRE-PROCESS AND IMPORT ===== 105 for iSubj = 1:16 106 % Start a new report (one report per subject) 107 bst_report('Start'); 108 disp(sprintf('\n===== IMPORT: SUBJECT #%d =====\n', iSubj)); 109 110 % If subject already exists: delete it 111 [sSubject, iSubject] = bst_get('Subject', SubjectNames{iSubj}); 112 if ~isempty(sSubject) 113 db_delete_subjects(iSubject); 114 end 115 116 % ===== FILES TO IMPORT ===== 117 % Build the path of the files to import 118 AnatDir = fullfile(bids_dir, 'derivatives', 'freesurfer', SubjectNames{iSubj}, 'ses-mri', 'anat'); 119 DataDir = fullfile(bids_dir, 'derivatives', 'meg_derivatives', SubjectNames{iSubj}, 'ses-meg', 'meg'); 120 % Check if the folder contains the required files 121 if ~file_exist(AnatDir) 122 error(['The folder "' AnatDir '" does not exist.']); 123 end 124 if ~file_exist(DataDir) 125 error(['The folder "' DataDir '" does not exist.']); 126 end 127 128 % ===== ANATOMY ===== 129 % Process: Import anatomy folder 130 bst_process('CallProcess', 'process_import_anatomy', [], [], ... 131 'subjectname', SubjectNames{iSubj}, ... 132 'mrifile', {AnatDir, 'FreeSurfer'}, ... 133 'nvertices', 15000); 134 135 % ===== PROCESS EACH RUN ===== 136 for iRun = 1:6 137 % Files to import 138 FifFile = bst_fullfile(DataDir, sprintf('%s_ses-meg_task-facerecognition_run-%02d_proc-sss_meg.fif', SubjectNames{iSubj}, iRun)); 139 140 % ===== LINK CONTINUOUS FILE ===== 141 % Process: Create link to raw file 142 sFileRaw = bst_process('CallProcess', 'process_import_data_raw', [], [], ... 143 'subjectname', SubjectNames{iSubj}, ... 144 'datafile', {FifFile, 'FIF'}, ... 145 'channelreplace', 1, ... 146 'channelalign', 0); 147 % Set acquisition date 148 panel_record('SetAcquisitionDate', sFileRaw.iStudy, AcquisitionDates{iSubj}); 149 150 % ===== PREPARE CHANNEL FILE ===== 151 % Process: Set channels type 152 bst_process('CallProcess', 'process_channel_settype', sFileRaw, [], ... 153 'sensortypes', 'EEG061, EEG064', ... 154 'newtype', 'NOSIG'); 155 bst_process('CallProcess', 'process_channel_settype', sFileRaw, [], ... 156 'sensortypes', 'EEG062', ... 157 'newtype', 'EOG'); 158 bst_process('CallProcess', 'process_channel_settype', sFileRaw, [], ... 159 'sensortypes', 'EEG063', ... 160 'newtype', 'ECG'); 161 162 % Process: Remove head points 163 sFileRaw = bst_process('CallProcess', 'process_headpoints_remove', sFileRaw, [], ... 164 'zlimit', 0); 165 % Process: Refine registration 166 sFileRaw = bst_process('CallProcess', 'process_headpoints_refine', sFileRaw, []); 167 % Process: Project electrodes on scalp 168 sFileRaw = bst_process('CallProcess', 'process_channel_project', sFileRaw, []); 169 170 % Process: Snapshot: Sensors/MRI registration 171 bst_process('CallProcess', 'process_snapshot', sFileRaw, [], ... 172 'target', 1, ... % Sensors/MRI registration 173 'modality', 1, ... % MEG (All) 174 'orient', 1, ... % left 175 'Comment', sprintf('MEG/MRI Registration: Subject #%d, Run #%d', iSubj, iRun)); 176 bst_process('CallProcess', 'process_snapshot', sFileRaw, [], ... 177 'target', 1, ... % Sensors/MRI registration 178 'modality', 4, ... % EEG 179 'orient', 1, ... % left 180 'Comment', sprintf('EEG/MRI Registration: Subject #%d, Run #%d', iSubj, iRun)); 181 182 % ===== IMPORT TRIGGERS ===== 183 % Process: Read from channel 184 bst_process('CallProcess', 'process_evt_read', sFileRaw, [], ... 185 'stimchan', 'STI101', ... 186 'trackmode', 2, ... % Bit: detect the changes for each bit independently 187 'zero', 0); 188 % Process: Group by name 189 bst_process('CallProcess', 'process_evt_groupname', sFileRaw, [], ... 190 'combine', 'Unfamiliar=3,4', ... 191 'dt', 0, ... 192 'delete', 1); 193 % Process: Rename event 194 bst_process('CallProcess', 'process_evt_rename', sFileRaw, [], ... 195 'src', '3', ... 196 'dest', 'Famous'); 197 % Process: Rename event 198 bst_process('CallProcess', 'process_evt_rename', sFileRaw, [], ... 199 'src', '5', ... 200 'dest', 'Scrambled'); 201 % Process: Add time offset 202 bst_process('CallProcess', 'process_evt_timeoffset', sFileRaw, [], ... 203 'info', [], ... 204 'eventname', 'Famous, Unfamiliar, Scrambled', ... 205 'offset', 0.0345); 206 % Process: Delete events 207 bst_process('CallProcess', 'process_evt_delete', sFileRaw, [], ... 208 'eventname', '1,2,6,7,8,9,10,11,12,13,14,15,16'); 209 % Process: Detect cHPI activity (Elekta):STI201 210 bst_process('CallProcess', 'process_evt_detect_chpi', sFileRaw, [], ... 211 'eventname', 'chpi_bad', ... 212 'channelname', 'STI201', ... 213 'method', 'off'); % Mark as bad when the HPI coils are OFF 214 215 % ===== FREQUENCY FILTERS ===== 216 % Process: Notch filter: 50Hz 100Hz 150Hz 200Hz 217 sFileClean = bst_process('CallProcess', 'process_notch', sFileRaw, [], ... 218 'freqlist', [50, 100, 150, 200], ... 219 'sensortypes', 'MEG, EEG', ... 220 'read_all', 0); 221 % Process: Power spectrum density (Welch) 222 sFilesPsd = bst_process('CallProcess', 'process_psd', [sFileRaw, sFileClean], [], ... 223 'timewindow', [], ... 224 'win_length', 4, ... 225 'win_overlap', 50, ... 226 'sensortypes', 'MEG, EEG', ... 227 'edit', struct(... 228 'Comment', 'Power', ... 229 'TimeBands', [], ... 230 'Freqs', [], ... 231 'ClusterFuncTime', 'none', ... 232 'Measure', 'power', ... 233 'Output', 'all', ... 234 'SaveKernel', 0)); 235 % Process: Snapshot: Frequency spectrum 236 bst_process('CallProcess', 'process_snapshot', sFilesPsd, [], ... 237 'target', 10, ... % Frequency spectrum 238 'Comment', sprintf('Power spctrum: Subject #%d, Run #%d', iSubj, iRun)); 239 240 % ===== BAD CHANNELS ===== 241 if ~isempty(BadChannels{iSubj}{iRun}) 242 % Process: Set bad channels 243 bst_process('CallProcess', 'process_channel_setbad', sFileClean, [], ... 244 'sensortypes', BadChannels{iSubj}{iRun}); 245 end 246 247 % ===== EEG REFERENCE ===== 248 % Process: Re-reference EEG 249 bst_process('CallProcess', 'process_eegref', sFileClean, [], ... 250 'eegref', 'AVERAGE', ... 251 'sensortypes', 'EEG'); 252 253 % ===== DETECT ARTIFACTS ====== 254 % Process: Detect heartbeats 255 bst_process('CallProcess', 'process_evt_detect_ecg', sFileClean, [], ... 256 'channelname', 'EEG063', ... 257 'timewindow', [], ... 258 'eventname', 'cardiac'); 259 % Different amplitude thresholds for different subjects 260 if strcmpi(SubjectNames{iSubj}, 'sub-05') 261 thresholdMAX = 50; 262 else 263 thresholdMAX = 100; 264 end 265 % Process: Detect: blink_BAD - Detects all events where the amplitude exceeds 100uV 266 bst_process('CallProcess', 'process_evt_detect_threshold', sFileClean, [], ... 267 'eventname', 'blink_BAD', ... 268 'channelname', 'EEG062', ... 269 'timewindow', [], ... 270 'thresholdMAX', thresholdMAX, ... 271 'units', 3, ... % uV (10^-6) 272 'bandpass', [0.3, 20], ... 273 'isAbsolute', 1, ... 274 'isDCremove', 0); 275 276 % ===== SSP COMPUTATION ===== 277 % Process: SSP ECG: cardiac 278 bst_process('CallProcess', 'process_ssp_ecg', sFileClean, [], ... 279 'eventname', 'cardiac', ... 280 'sensortypes', 'MEG GRAD', ... 281 'usessp', 1, ... 282 'select', SspSelect{iSubj}{iRun}{1}); 283 bst_process('CallProcess', 'process_ssp_ecg', sFileClean, [], ... 284 'eventname', 'cardiac', ... 285 'sensortypes', 'MEG MAG', ... 286 'usessp', 1, ... 287 'select', SspSelect{iSubj}{iRun}{2}); 288 % Process: Snapshot: SSP projectors 289 bst_process('CallProcess', 'process_snapshot', sFileClean, [], ... 290 'target', 2, ... 291 'Comment', sprintf('Subject #%d, Run #%d', iSubj, iRun)); % SSP projectors 292 293 % ===== IMPORT BAD EVENTS ===== 294 % Get bad segments: this is typically done manually, not from a script 295 BadSegments = GetBadSegments(iSubj, iRun); 296 % Process: Import from file 297 bst_process('CallProcess', 'process_evt_import', sFileClean, [], ... 298 'evtfile', {BadSegments, 'ARRAY-TIMES'}, ... 299 'evtname', 'BAD'); 300 301 % ===== IMPORT TRIALS ===== 302 % Process: Import MEG/EEG: Events 303 sFilesEpochs = bst_process('CallProcess', 'process_import_data_event', sFileClean, [], ... 304 'subjectname', SubjectNames{iSubj}, ... 305 'condition', '', ... 306 'eventname', 'Famous, Scrambled, Unfamiliar', ... 307 'timewindow', [], ... 308 'epochtime', [-0.5, 1.2], ... 309 'createcond', 0, ... 310 'ignoreshort', 1, ... 311 'usectfcomp', 1, ... 312 'usessp', 1, ... 313 'freq', [], ... 314 'baseline', [-0.5, -0.0009]); 315 316 % ===== AVERAGE: RUN ===== 317 % Process: Average: By trial group (folder average) 318 sFilesAvg = bst_process('CallProcess', 'process_average', sFilesEpochs, [], ... 319 'avgtype', 5, ... % By trial group (folder average) 320 'avg_func', 1, ... % Arithmetic average: mean(x) 321 'weighted', 0, ... 322 'keepevents', 0); 323 % Process: Snapshot: Recordings time series 324 bst_process('CallProcess', 'process_snapshot', sFilesAvg, [], ... 325 'target', 5, ... % Recordings time series 326 'modality', 4, ... % EEG 327 'time', 0.11, ... 328 'Comment', sprintf('Subject #%d, Run #%d', iSubj, iRun)); 329 % Process: Snapshot: Recordings topography 330 bst_process('CallProcess', 'process_snapshot', sFilesAvg, [], ... 331 'target', 6, ... % Recordings topography (one time) 332 'modality', 4, ... % EEG 333 'time', 0.11, ... 334 'Comment', sprintf('Subject #%d, Run #%d', iSubj, iRun)); 335 336 % ===== COMPUTE NOISECOV: EEG ===== 337 % Process: Compute covariance (noise or data) 338 bst_process('CallProcess', 'process_noisecov', sFilesEpochs, [], ... 339 'baseline', [-0.5, -0.0009], ... 340 'sensortypes', 'EEG', ... 341 'target', 1, ... % Noise covariance (covariance over baseline time window) 342 'dcoffset', 1, ... % Block by block, to avoid effects of slow shifts in data 343 'identity', 0, ... 344 'copycond', 0, ... 345 'copysubj', 0, ... 346 'replacefile', 1); % Replace 347 end 348 349 % Save report 350 ReportFile = bst_report('Save', []); 351 if ~isempty(reports_dir) && ~isempty(ReportFile) 352 bst_report('Export', ReportFile, bst_fullfile(reports_dir, ['report_' ProtocolName '_' SubjectNames{iSubj} '.html'])); 353 end 354 end 355 356 357 %% ===== EMPTY ROOM RECORDINGS ===== 358 disp(sprintf('\n===== IMPORT: EMPTY-ROOM =====\n')); 359 % Loop on all the noise sessions 360 NoiseFiles = {}; 361 for ses = {'20090409', '20090506', '20090511', '20090515', '20090518', '20090601', '20091126', '20091208'} 362 NoiseFiles{end+1} = fullfile(bids_dir, 'derivatives', 'meg_derivatives', EmptyRoomSubj, ['ses-' ses{1}], 'meg', ['sub-emptyroom_ses-' ses{1} '_task-noise_proc-sss_meg.fif']); 363 end 364 % Process: Create link to raw file 365 sFilesNoise = bst_process('CallProcess', 'process_import_data_raw', [], [], ... 366 'subjectname', EmptyRoomSubj, ... 367 'datafile', {NoiseFiles, 'FIF'}, ... 368 'channelreplace', 1, ... 369 'channelalign', 0); 370 % Process: Notch filter: 50Hz 100Hz 150Hz 200Hz 371 sFileNoiseClean = bst_process('CallProcess', 'process_notch', sFilesNoise, [], ... 372 'freqlist', [50, 100, 150, 200], ... 373 'sensortypes', 'MEG, EEG', ... 374 'read_all', 0); 375 % Process: Compute noise covariance 376 bst_process('CallProcess', 'process_noisecov', sFileNoiseClean, [], ... 377 'baseline', [], ... 378 'sensortypes', 'MEG', ... 379 'target', 1, ... % Noise covariance (covariance over baseline time window) 380 'dcoffset', 1, ... % Block by block, to avoid effects of slow shifts in data 381 'identity', 0, ... 382 'copycond', 1, ... 383 'copysubj', 1, ... 384 'copymatch', 1, ... 385 'replacefile', 2); % Merge 386 387 388 %% ===== SOURCE ESTIMATION ===== 389 % Start a new report (one report for the source estimation of all the subjects) 390 bst_report('Start'); 391 % Loop on the subjects: This loop is separated from the previous one, because we should 392 % compute the BEM surfaces after importing all the runs, so that the registration is done 393 % using the high resolution head surface, instead of the smooth scalp BEM layer. 394 for iSubj = 1:length(SubjectNames) 395 disp(sprintf('\n===== SOURCES: SUBJECT #%d =====\n', iSubj)); 396 397 % ===== BEM SURFACES ===== 398 % Process: Generate BEM surfaces 399 bst_process('CallProcess', 'process_generate_bem', [], [], ... 400 'subjectname', SubjectNames{iSubj}, ... 401 'nscalp', 1082, ... 402 'nouter', 642, ... 403 'ninner', 642, ... 404 'thickness', 4); 405 406 % ===== SELECT ALL AVERAGES ===== 407 % Process: Select data files in: */* 408 sFilesAvg = bst_process('CallProcess', 'process_select_files_data', [], [], ... 409 'subjectname', SubjectNames{iSubj}); 410 % Process: Select file comments with tag: Avg 411 sFilesAvg = bst_process('CallProcess', 'process_select_tag', sFilesAvg, [], ... 412 'tag', 'Avg'); % Select only the files with the tag 413 414 % ===== COMPUTE HEAD MODELS ===== 415 % Process: Compute head model (only for the first run of the subject) 416 bst_process('CallProcess', 'process_headmodel', sFilesAvg(1), [], ... 417 'sourcespace', 1, ... % Cortex surface 418 'meg', 3, ... % Overlapping spheres 419 'eeg', 3, ... % OpenMEEG BEM 420 'ecog', 1, ... % 421 'seeg', 1, ... % 422 'openmeeg', struct(... 423 'BemSelect', [1, 1, 1], ... 424 'BemCond', [1, 0.0125, 1], ... 425 'BemNames', {{'Scalp', 'Skull', 'Brain'}}, ... 426 'BemFiles', {{}}, ... 427 'isAdjoint', 0, ... 428 'isAdaptative', 1, ... 429 'isSplit', 0, ... 430 'SplitLength', 4000)); 431 % Get all the runs for this subject (ie the list of the study indices) 432 iStudyOther = setdiff(unique([sFilesAvg.iStudy]), sFilesAvg(1).iStudy); 433 % Copy the forward model file to the other runs 434 sHeadmodel = bst_get('HeadModelForStudy', sFilesAvg(1).iStudy); 435 for iStudy = iStudyOther 436 db_add(iStudy, sHeadmodel.FileName); 437 end 438 439 % ===== COMPUTE SOURCES: MEG ===== 440 % Process: Compute sources [2018] 441 sAvgSrcMeg = bst_process('CallProcess', 'process_inverse_2018', sFilesAvg, [], ... 442 'output', 1, ... % Kernel only: shared 443 'inverse', struct(... 444 'Comment', 'MN: MEG ALL', ... 445 'InverseMethod', 'minnorm', ... 446 'InverseMeasure', 'amplitude', ... 447 'SourceOrient', {{'fixed'}}, ... 448 'Loose', 0.2, ... 449 'UseDepth', 1, ... 450 'WeightExp', 0.5, ... 451 'WeightLimit', 10, ... 452 'NoiseMethod', 'reg', ... 453 'NoiseReg', 0.1, ... 454 'SnrMethod', 'fixed', ... 455 'SnrRms', 1e-06, ... 456 'SnrFixed', 3, ... 457 'ComputeKernel', 1, ... 458 'DataTypes', {{'MEG GRAD', 'MEG MAG'}})); 459 % Process: Snapshot: Sources (one time) - Loop only to get a correct comment for the report 460 for i = 1:length(sAvgSrcMeg) 461 bst_process('CallProcess', 'process_snapshot', sAvgSrcMeg(i), [], ... 462 'target', 8, ... % Sources (one time) 463 'orient', 4, ... % bottom 464 'time', 0.11, ... 465 'threshold', 20, ... 466 'Comment', ['MEG sources: ' sFilesAvg(i).FileName]); 467 end 468 469 % ===== COMPUTE SOURCES: EEG ===== 470 % Process: Compute sources [2018] 471 sAvgSrcEeg = bst_process('CallProcess', 'process_inverse_2018', sFilesAvg, [], ... 472 'output', 1, ... % Kernel only: shared 473 'inverse', struct(... 474 'Comment', 'MN: EEG', ... 475 'InverseMethod', 'minnorm', ... 476 'InverseMeasure', 'amplitude', ... 477 'SourceOrient', {{'fixed'}}, ... 478 'Loose', 0.2, ... 479 'UseDepth', 1, ... 480 'WeightExp', 0.5, ... 481 'WeightLimit', 10, ... 482 'NoiseMethod', 'reg', ... 483 'NoiseReg', 0.1, ... 484 'SnrMethod', 'fixed', ... 485 'SnrRms', 1e-06, ... 486 'SnrFixed', 3, ... 487 'ComputeKernel', 1, ... 488 'DataTypes', {{'EEG'}})); 489 % Process: Snapshot: Sources (one time) - Loop only to get a correct comment for the report 490 for i = 1:length(sAvgSrcEeg) 491 bst_process('CallProcess', 'process_snapshot', sAvgSrcEeg(i), [], ... 492 'target', 8, ... % Sources (one time) 493 'orient', 4, ... % bottom 494 'time', 0.11, ... 495 'threshold', 10, ... 496 'Comment', ['EEG sources: ' sFilesAvg(i).FileName]); 497 end 498 end 499 % Save report 500 ReportFile = bst_report('Save', []); 501 if ~isempty(reports_dir) && ~isempty(ReportFile) 502 bst_report('Export', ReportFile, bst_fullfile(reports_dir, ['report_' ProtocolName '_sources.html'])); 503 end 504 505 506 %% ===== TIME-FREQUENCY ===== 507 % Start a new report (one report for the time-frequency of all the subjects) 508 bst_report('Start'); 509 % List of conditions to process separately 510 AllConditions = {'Famous', 'Scrambled', 'Unfamiliar'}; 511 % Channels to display in the screen capture, by order of preference (if the first channel is bad, use the following) 512 SelChannel = {'EEG070','EEG060','EEG065','EEG050','EEG003'}; 513 % Compute one separate time-frequency average for each subject/run/condition 514 for iSubj = 1:length(SubjectNames) 515 disp(sprintf('\n===== TIME-FREQUENCY: SUBJECT #%d =====\n', iSubj)); 516 for iRun = 1:6 517 % Process: Select data files in: Subject/Run 518 sTrialsAll = bst_process('CallProcess', 'process_select_files_data', [], [], ... 519 'subjectname', SubjectNames{iSubj}, ... 520 'condition', sprintf('sub-%02d_ses-meg_task-facerecognition_run-%02d_proc-sss_meg_notch', iSubj, iRun)); 521 % Loop on the conditions 522 for iCond = 1:length(AllConditions) 523 % Comment describing this average 524 strComment = [SubjectNames{iSubj}, ' / ', sprintf('run_%02d', iRun), ' / ', AllConditions{iCond}]; 525 disp(['BST> ' strComment]); 526 % Find the first good channel in the display list 527 if isempty(BadChannels{iSubj}{iRun}) 528 iSel = 1; 529 else 530 iSel = find(~ismember(SelChannel,BadChannels{iSubj}{iRun}), 1); 531 end 532 % Process: Select file comments with tag: Avg 533 sTrialsCond = bst_process('CallProcess', 'process_select_tag', sTrialsAll, [], ... 534 'tag', [AllConditions{iCond}, '_trial'], ... 535 'search', 1, ... % Search the file names 536 'select', 1); % Select only the files with the tag 537 % Process: Time-frequency (Morlet wavelets), averaged across trials 538 sTimefreq = bst_process('CallProcess', 'process_timefreq', sTrialsCond, [], ... 539 'sensortypes', 'MEG MAG, EEG', ... 540 'edit', struct(... 541 'Comment', ['Avg: ' AllConditions{iCond} ', Power, 6-60Hz'], ... 542 'TimeBands', [], ... 543 'Freqs', [6, 6.8, 7.6, 8.6, 9.7, 11, 12.4, 14, 15.8, 17.9, 20.2, 22.8, 25.7, 29, 32.7, 37, 41.7, 47.1, 53.2, 60], ... 544 'MorletFc', 1, ... 545 'MorletFwhmTc', 3, ... 546 'ClusterFuncTime', 'none', ... 547 'Measure', 'power', ... 548 'Output', 'average', ... 549 'RemoveEvoked', 0, ... 550 'SaveKernel', 0), ... 551 'normalize', 'none'); % None: Save non-standardized time-frequency maps 552 % Process: Extract time: [-200ms,900ms] 553 sTimefreq = bst_process('CallProcess', 'process_extract_time', sTimefreq, [], ... 554 'timewindow', [-0.2, 0.9], ... 555 'overwrite', 1); 556 % Screen capture of one sensor 557 hFigTf = view_timefreq(sTimefreq.FileName, 'SingleSensor', SelChannel{iSel}); 558 bst_report('Snapshot', hFigTf, strComment, 'Time-frequency', [200, 200, 400, 250]); 559 close(hFigTf); 560 end 561 end 562 end 563 % Save report 564 ReportFile = bst_report('Save', []); 565 if ~isempty(reports_dir) && ~isempty(ReportFile) 566 bst_report('Export', ReportFile, bst_fullfile(reports_dir, ['report_' ProtocolName '_timefreq.html'])); 567 end 568 end 569 570 571 572 573 %% ===== SUPPORT FUNCTIONS ===== 574 function BadSeg = GetBadSegments(iSubj, iRun) 575 BadSegments{1} = {... 576 [247.867 248.185; 598.999 598.999; 598.999 598.999; 611.999 611.999; 612.999 612.999; 613.999 613.999; 616.999 616.999; 617.999 617.999; 623.999 623.999; 715.209 715.467], ... 577 [84.791 85.166], ... 578 [79.183 80.167], ... 579 [64.309 65.185], ... 580 [90.958 91.167; 178.005 178.355; 293.282 295.919; 312.298 316.479; 353.835 357.716], ... 581 [60.292 66.802; 69.975 71.210; 105.233 107.586; 108.822 109.506; 376.225 376.325]}; 582 BadSegments{2} = {... 583 [223.806 224.199; 279.772 279.895; 453.241 455.108; 692.423 692.593], ... 584 [65.298 66.194; 304.727 306.178; 399.165 400.732], ... 585 [203.141 205.085; 281.579 287.883; 420.395 421.128], ... 586 [387.118 388.229; 440.318 441.900; 554.825 558.744], ... 587 [71.000 80.999; 82.750 87.367; 149.528 149.667; 264.747 267.995; 368.415 371.973; 376.263 378.763; 398.334 401.551; 537.410 541.645], ... 588 [38.000 47.999; 47.825 50.046; 61.298 61.384; 249.653 253.379; 282.917 283.820; 286.135 287.616; 298.167 300.196; 328.254 329.511; 335.957 337.817; 478.277 480.707]}; 589 BadSegments{3} = {... 590 [406.312 407.207; 727.055 728.714], ... 591 [84.894 85.156; 152.028 152.946; 297.835 298.915; 418.272 421.845; 554.084 554.794], ... 592 [73.758 74.159; 378.212 378.536; 406.065 407.099; 470.541 471.698; 488.900 491.168; 529.596 530.453], ... 593 [94.874 95.152; 317.385 321.374; 325.696 327.055; 439.220 439.829; 454.473 455.175; 486.196 486.829; 518.660 522.015; 524.400 525.249; 562.417 570.325], ... 594 [96.208 97.181; 98.942 99.096; 135.005 135.754; 143.990 144.599; 250.139 250.247; 300.459 300.559; 338.265 339.322; 545.913 546.067], ... 595 [91.415 92.156; 284.843 286.525; 297.886 298.404; 317.046 317.163; 332.698 332.791; 358.946 359.402; 428.405 428.775; 478.374 478.690; 549.866 550.128]}; 596 BadSegments{4} = {... 597 [22.967 22.967; 50.036 50.098; 52.058 52.058; 156.653 156.653; 171.565 173.386; 239.544 242.105; 268.162 270.175; 268.992 268.992; 316.032 316.032; 338.283 339.000; 357.959 361.909; 370.871 370.871; 381.579 383.677; 437.731 437.731; 463.482 468.505; 476.135 479.838; 486.652 488.272; 504.860 508.999], ... 598 [309.493 311.707; 342.681 344.525; 354.019 357.321; 390.023 391.225; 393.926 395.855; 404.221 405.069; 432.522 435.932; 459.048 460.715; 471.763 478.529; 549.387 551.999; 591.087 594.143; 608.541 611.079; 624.847 626.615; 649.648 651.570], ... 599 [57.411 58.198; 88.346 88.955; 200.761 202.335; 227.016 227.688; 257.726 258.054; 356.798 359.005; 404.260 411.003], ... 600 [46.000 54.823; 61.000 70.332; 203.005 207.125; 275.875 278.121; 313.500 314.824; 337.973 338.636; 422.505 426.239], ... 601 [58.000 62.479; 78.250 85.166; 89.955 91.360; 116.322 117.888; 130.013 131.987; 149.509 150.489; 174.650 175.823; 182.030 183.334; 196.758 197.384; 204.458 204.697; 205.236 208.663; 311.028 316.383; 320.700 327.181; 332.437 335.354; 344.205 346.133; 374.208 374.865; 385.519 386.214; 441.942 444.241; 453.957 456.997; 486.039 487.004; 501.238 504.185; 512.962 514.675; 553.398 556.215], ... 602 [41.406 45.743; 58.681 59.144; 108.086 108.896; 140.633 143.750; 196.110 199.474; 210.778 210.971; 234.649 235.143; 258.081 259.632; 339.101 340.805; 390.277 390.609; 438.935 442.122; 528.221 534.031]}; 603 BadSegments{5} = {... 604 [265.539 265.778; 266.334 266.495; 268.479 268.965; 367.428 367.636; 439.655 442.779; 453.497 453.853; 504.997 505.329; 519.513 519.683; 595.674 595.982; 602.000 602.463], ... 605 [121.113 121.499; 124.971 126.213; 253.735 254.075; 272.232 272.464; 272.895 273.104; 346.368 346.645; 368.812 369.052; 406.382 406.605; 452.920 453.113; 454.903 455.112; 507.655 507.840; 508.766 509.013; 584.853 585.030; 594.831 595.656; 597.261 602.249], ... 606 [37.251 37.497; 38.825 39.056; 40.615 41.849; 43.624 44.758; 53.333 53.641; 54.698 55.076; 57.668 59.196; 79.129 79.360; 81.475 81.714; 122.658 123.375; 284.787 285.296; 288.754 288.993; 345.790 346.022; 421.212 421.459; 481.428 482.207; 503.408 503.685; 504.272 504.449; 524.451 524.714; 526.913 531.499], ... 607 [87.322 88.178; 91.085 91.325; 95.121 95.491; 114.174 114.397; 129.874 130.113; 151.220 151.544; 281.689 281.959; 532.966 533.345], ... 608 [59.176 60.218; 74.854 75.317; 308.180 309.877; 380.705 381.059], ... 609 [182.382 183.245; 196.220 196.736; 276.018 276.327; 292.490 294.086; 370.755 370.847; 435.644 436.624; 467.535 468.460; 522.838 525.847]}; 610 BadSegments{6} = {... 611 [141.690 142.424; 157.070 157.417; 355.138 356.025; 423.999 423.999; 424.999 424.999; 426.999 426.999; 427.999 427.999; 486.430 488.151; 493.999 493.999; 501.511 501.619; 501.549 501.549; 501.585 501.585; 502.999 502.999; 503.999 503.999; 540.999 540.999; 541.999 541.999; 555.999 555.999; 556.999 556.999; 561.999 561.999; 563.999 563.999; 564.999 564.999; 565.999 565.999; 567.999 567.999], ... 612 [64.898 65.161; 71.700 72.718; 226.185 226.740; 324.124 324.425; 329.062 329.301; 486.143 486.975], ... 613 [62.300 63.148; 266.254 266.639; 409.920 410.221], ... 614 [54.048 55.214; 330.893 331.255], ... 615 [185.616 186.495; 331.411 331.796; 386.843 387.028; 387.999 387.999; 389.999 389.999; 434.575 434.875; 519.802 519.995], ... 616 [44.720 45.167; 211.446 211.964; 368.955 369.172]}; 617 BadSegments{7} = {... 618 [154.966 155.144; 551.639 551.855], ... 619 [88.774 89.167; 107.999 107.999; 109.999 109.999; 110.999 110.999; 112.999 112.999; 113.999 113.999; 114.999 114.999; 119.999 119.999; 121.999 121.999; 124.223 125.465; 137.011 138.871], ... 620 [81.627 82.136; 377.953 381.046], ... 621 [241.136 242.171; 543.849 544.196; 596.639 598.553; 600.227 601.075; 603.999 603.999; 605.999 605.999; 609.999 609.999; 611.305 612.809; 614.999 614.999; 615.803 616.937; 623.694 625.877; 653.999 653.999; 655.055 655.756; 663.999 663.999], ... 622 [68.852 69.481; 74.034 75.200; 78.426 78.600; 104.497 105.963; 253.951 254.034; 256.964 257.038; 257.915 258.048; 323.254 324.156; 365.880 368.131; 369.952 370.060; 371.728 372.999; 430.931 431.965; 535.521 542.999], ... 623 [70.271 71.205; 94.441 96.445; 98.613 99.126; 112.318 112.749; 131.686 132.265; 148.935 150.615; 161.120 161.600; 205.325 208.214; 215.035 215.863; 217.403 218.818; 286.178 287.171; 399.075 404.853]}; 624 BadSegments{8} = {... 625 [238.505 238.546; 256.354 257.224; 316.116 316.167; 341.519 341.558; 356.493 356.566; 380.095 380.170; 391.906 392.048; 448.457 448.562; 469.931 470.028; 530.488 530.575; 555.180 558.136; 562.152 562.245; 588.403 588.502; 625.205 625.662; 638.019 638.438; 649.982 650.008; 650.691 651.357; 651.925 652.061; 665.445 665.472; 695.923 696.015; 706.528 706.720; 729.706 732.534], ... 626 [99.546 106.114; 113.245 114.199; 150.885 154.989; 277.486 278.075; 333.645 335.574; 339.358 340.646; 371.860 375.394; 497.459 499.156], ... 627 [49.008 50.205; 231.446 233.406; 329.590 329.659; 355.101 356.019; 360.733 360.973; 372.955 374.891; 389.283 392.068; 453.610 455.431; 464.632 465.265; 489.209 489.996; 514.777 515.295], ... 628 [178.368 179.232; 293.865 294.521; 418.252 418.314; 450.124 450.209; 480.236 480.445; 492.725 493.975; 495.170 497.624; 500.382 500.459; 504.247 504.402; 628.017 628.079; 628.827 628.905; 630.209 630.332], ... 629 [100.616 101.172; 107.691 108.539; 188.814 188.875; 193.119 193.281; 207.964 208.033; 432.254 432.385; 489.834 489.911; 517.960 518.037; 518.955 519.040; 520.938 521.062; 521.945 522.037; 523.959 524.052; 525.942 526.057; 526.945 527.015; 528.958 529.059; 531.138 531.192; 531.979 532.048; 532.951 533.028; 533.962 534.024], ... 630 [135.997 137.232; 383.565 383.657; 418.763 418.955]}; 631 BadSegments{9} = {... 632 [215.107 216.187; 262.388 262.388; 287.519 287.635; 289.895 290.135; 311.999 311.999; 350.161 351.179; 526.154 527.033; 564.999 564.999; 584.935 585.059; 587.999 587.999; 601.999 601.999; 603.999 603.999; 608.999 608.999; 612.999 612.999], ... 633 [47.667 47.775; 49.172 54.681; 67.195 70.805; 78.988 80.477; 138.701 138.948; 138.727 138.727; 138.728 138.728; 138.728 138.728; 138.734 138.734; 138.734 138.734; 138.881 138.881; 138.881 138.881; 138.907 138.907; 140.993 141.093; 141.037 141.037; 141.045 141.045; 155.795 155.864; 155.822 155.822; 155.849 155.849; 168.999 168.999; 206.999 206.999; 219.999 219.999; 225.999 225.999; 226.999 226.999; 228.999 228.999; 236.999 236.999; 242.463 242.463; 242.463 242.463; 242.487 242.487; 247.999 247.999; 251.999 251.999; 252.483 252.483; 253.315 254.163; 265.999 265.999; 267.999 267.999; 272.358 272.358; 272.410 272.410; 298.999 298.999; 300.999 300.999; 314.037 314.037; 314.047 314.047; 321.813 321.813; 321.813 321.813; 321.833 321.833; 329.117 329.117; 329.117 329.117; 329.156 329.156; 346.999 346.999; 347.999 347.999; 349.320 349.320; 349.329 349.329; 352.528 355.869; 364.040 364.040; 396.278 397.420; 404.865 404.865; 407.905 407.905; 407.905 407.905; 407.954 407.954; 418.454 418.454; 418.454 418.454; 418.486 418.486; 441.999 441.999; 444.999 444.999; 447.999 447.999; 453.550 453.650; 454.931 455.055; 457.999 457.999; 479.964 480.079; 481.999 481.999; 482.949 483.073; 488.948 489.064; 511.999 511.999; 520.999 520.999; 523.999 523.999; 526.954 527.069; 533.999 533.999; 537.999 537.999], ... 634 [82.889 83.198; 206.143 207.424; 403.873 404.096; 406.790 407.485; 413.936 414.075; 415.912 416.112; 536.621 537.532], ... 635 [182.999 182.999; 182.999 182.999; 183.999 183.999; 195.999 195.999; 208.999 208.999; 209.999 209.999; 278.601 278.955; 413.913 414.067; 415.250 417.792; 419.940 420.087; 420.999 420.999; 512.999 512.999; 514.363 516.254; 521.917 522.134; 522.999 522.999; 523.915 524.101; 533.999 533.999; 538.999 538.999; 539.892 540.062; 543.999 543.999; 548.874 549.089; 549.900 550.062; 552.755 554.075; 585.999 585.999; 587.957 588.073; 588.999 588.999; 594.999 594.999; 603.971 604.056; 604.928 605.097; 615.986 618.495; 623.999 623.999], ... 636 [53.215 54.203; 164.227 168.965; 201.433 202.775; 292.973 295.889; 303.961 304.817; 309.354 311.236; 313.123 313.639; 322.547 323.017; 331.141 334.852; 356.637 356.985; 367.855 368.079; 369.995 373.459; 377.849 378.142; 406.072 407.306; 436.164 436.665; 458.033 458.905; 516.889 518.656; 517.812 518.684], ... 637 [113.945 115.225; 198.570 198.863; 264.162 264.795; 383.705 385.641; 396.477 397.064; 399.706 406.457; 452.261 453.179; 486.338 487.102; 498.869 499.579; 507.968 508.925; 546.266 547.285; 558.825 560.128]}; 638 BadSegments{10} = {... 639 [235.104 236.184; 324.272 325.028; 330.799 331.401; 541.062 541.826; 564.747 565.072], ... 640 [100.581 101.229; 285.644 285.644; 285.644 285.644; 297.979 298.033; 298.999 298.999; 300.949 301.026; 301.999 301.999; 303.999 303.999; 304.999 304.999; 306.999 306.999; 307.999 307.999; 310.999 310.999; 311.999 311.999; 313.971 314.025; 314.999 314.999; 316.995 317.035; 317.999 317.999; 319.999 319.999; 320.923 321.046; 326.971 327.048; 327.999 327.999; 329.999 329.999; 330.999 330.999; 332.974 333.028; 333.999 333.999; 335.971 336.025; 336.999 336.999; 338.973 339.035; 339.999 339.999; 341.951 342.044; 343.999 343.999; 344.964 345.033; 346.999 346.999; 347.999 347.999; 452.015 453.411; 458.735 459.776; 467.974 468.089], ... 641 [41.266 41.675; 53.905 55.240; 159.159 159.345; 220.255 220.394], ... 642 [66.751 67.190; 201.674 201.812; 294.119 295.168; 303.188 303.528; 316.992 317.037; 317.999 317.999; 317.999 317.999; 319.999 319.999; 320.980 321.042; 322.999 322.999; 325.999 325.999; 326.955 327.048; 328.999 328.999; 333.999 333.999; 334.999 334.999; 342.999 342.999; 343.999 343.999; 351.915 352.038; 352.999 352.999; 407.979 408.056; 409.999 409.999; 411.999 411.999; 415.405 416.154; 435.999 435.999; 436.962 437.046; 468.885 469.100; 469.999 469.999; 470.999 470.999; 516.210 516.357], ... 643 [105.369 106.172; 141.468 142.178; 199.008 199.818; 201.269 201.716; 352.851 353.083; 449.865 452.041; 459.508 459.802], ... 644 [229.948 230.033; 230.999 230.999; 230.999 230.999; 259.588 259.990; 343.970 345.798; 361.999 361.999; 362.970 363.046; 364.999 364.999; 366.999 366.999; 367.962 368.031; 372.521 374.179; 405.999 405.999; 409.999 409.999; 411.999 411.999; 412.999 412.999; 434.999 434.999; 435.970 436.031; 516.999 516.999; 519.999 519.999]}; 645 BadSegments{11} = {... 646 [179.045 180.225; 323.999 323.999; 323.999 323.999; 324.999 324.999; 327.978 328.025; 328.966 329.028; 330.999 330.999; 365.999 365.999; 367.999 367.999; 370.999 370.999; 371.999 371.999; 373.999 373.999; 375.965 376.042; 377.999 377.999], ... 647 [52.107 53.156; 521.077 521.155], ... 648 [65.331 66.156], ... 649 [81.579 82.143; 108.565 108.565; 108.566 108.566; 112.176 112.176; 122.377 122.377; 122.565 122.565; 213.882 213.882; 215.305 215.305; 224.851 224.851; 224.919 224.919; 255.815 255.815; 257.893 257.893; 359.952 359.952; 361.630 361.754; 370.285 370.285; 376.853 376.853; 511.600 511.600; 513.631 513.631; 513.988 513.988; 518.215 518.215], ... 650 [63.205 64.154; 170.951 171.036; 176.841 176.841; 176.842 176.842; 177.282 177.282; 223.886 223.971; 259.963 259.963; 261.547 261.547; 341.185 341.302; 368.999 368.999; 370.999 370.999; 374.999 374.999; 382.971 383.033; 383.999 383.999; 386.999 386.999; 388.958 389.035; 390.999 390.999; 391.955 392.031; 394.955 395.040; 396.999 396.999; 398.999 398.999; 400.999 400.999; 402.999 402.999; 404.963 405.033; 406.999 406.999; 429.829 429.829; 430.346 430.346; 465.184 465.184; 470.290 470.290], ... 651 [50.195 51.145; 158.850 159.012]}; 652 BadSegments{12} = {... 653 [193.435 194.175; 500.000 501.000; 08.988 509.868; 528.999 528.999; 528.999 528.999; 529.999 529.999; 531.999 531.999; 547.999 547.999], ... 654 [133.484 134.185; 134.911 135.065; 553.999 553.999; 553.999 553.999; 554.999 554.999; 557.999 557.999; 558.999 558.999; 564.999 564.999; 565.977 566.046; 568.999 568.999; 569.951 570.028; 571.999 571.999; 579.959 580.028; 580.977 581.055; 583.971 584.033; 583.999 583.999; 585.999 585.999; 586.999 586.999; 588.980 589.026; 590.999 590.999; 591.958 592.044; 595.999 595.999], ... 655 [46.028 47.216; 129.557 130.236; 200.999 200.999; 200.999 200.999; 201.975 202.075; 203.999 203.999; 204.967 205.053; 213.627 214.515; 218.958 219.044; 222.959 228.252; 309.999 309.999; 311.897 317.537; 311.999 311.999; 351.968 353.234; 399.999 399.999; 446.508 451.454; 487.999 487.999; 512.278 512.926], ... 656 [82.535 84.062; 102.247 102.355; 134.999 134.999; 134.999 134.999; 136.999 136.999; 138.973 139.042; 147.999 147.999; 148.999 148.999; 149.999 149.999; 193.999 193.999; 194.999 194.999; 224.984 226.095; 241.954 242.077; 243.948 244.087; 280.999 280.999; 281.999 281.999; 305.000 305.451; 310.945 311.068; 328.999 328.999; 352.999 352.999; 353.999 353.999; 397.025 397.411; 415.944 418.096; 415.999 415.999; 470.999 470.999; 477.971 478.041; 483.997 484.737; 492.958 493.089; 493.999 493.999; 494.999 494.999; 522.999 522.999; 523.999 523.999; 524.955 525.039], ... 657 [175.183 176.155; 246.112 246.991; 412.005 413.340; 483.915 484.061; 485.959 486.028; 497.360 498.880; 594.457 594.944; 596.641 598.006; 615.277 618.710], ... 658 [66.900 72.232; 75.510 78.688; 543.495 545.999]}; 659 BadSegments{13} = {... 660 [307.246 308.179; 627.881 628.089; 629.941 630.049], ... 661 [171.506 172.301; 172.999 172.999; 430.999 430.999; 432.999 432.999; 434.999 434.999; 448.999 448.999; 479.999 479.999; 489.999 489.999; 490.999 490.999; 491.999 491.999], ... 662 [92.059 93.209], ... 663 [52.791 53.231; 54.999 54.999; 65.985 68.138; 91.240 91.386; 92.137 92.207; 105.346 105.493; 121.120 121.398; 146.546 146.955; 194.025 197.652; 242.985 243.571; 247.101 247.556; 269.889 270.083; 270.946 271.070; 274.408 275.866; 294.565 295.267; 319.370 319.879; 365.999 365.999; 375.913 376.044; 376.869 377.055; 377.999 377.999; 390.130 393.225; 403.965 404.035; 404.953 405.075; 419.265 419.565; 427.015 427.154; 427.879 428.118; 427.999 427.999; 428.913 429.067; 480.945 482.095; 484.285 484.571; 516.929 517.099; 517.963 518.079], ... 664 [115.921 116.060; 117.999 117.999; 120.999 120.999; 126.896 127.058; 130.955 131.039; 131.957 132.043; 132.961 133.015; 134.999 134.999; 135.950 136.043; 139.999 139.999; 143.999 143.999; 144.850 145.066; 145.999 145.999; 146.999 146.999; 160.929 161.045; 161.999 161.999; 189.086 189.310; 193.939 194.063; 195.975 196.045; 199.961 200.045; 201.952 202.059; 202.939 205.084; 210.999 210.999; 211.738 213.629; 217.954 218.061; 218.987 219.049; 219.975 220.028; 258.953 259.037; 259.952 260.045; 260.963 261.032; 261.958 262.043; 262.954 263.054; 262.999 262.999; 288.999 288.999; 295.477 295.655; 298.976 299.054; 299.979 300.018; 300.975 301.005; 336.952 337.044; 337.977 338.032; 338.988 339.027; 338.999 338.999; 339.991 340.045; 340.975 341.029; 341.978 342.016; 343.976 344.054; 361.961 362.045; 365.942 366.050; 370.999 370.999; 384.961 385.045; 409.977 410.047; 415.984 416.030; 426.944 427.059; 430.999 430.999; 436.999 436.999; 448.999 448.999; 449.500 452.131; 481.962 482.055; 482.973 483.027; 484.975 485.060; 503.999 503.999; 504.999 504.999; 507.967 508.028; 508.955 509.032; 510.999 510.999; 512.999 512.999; 518.865 520.292; 522.958 523.043; 523.999 523.999; 524.948 525.034; 525.959 526.044; 526.946 527.055; 527.942 528.027; 528.961 529.053; 529.945 530.022; 535.999 535.999; 536.957 537.058; 538.967 539.036; 539.963 540.040; 541.976 542.045; 543.999 543.999; 551.956 552.034; 552.990 553.028; 553.977 554.024; 555.968 556.022; 556.204 557.454; 557.963 558.032; 559.969 560.023; 563.973 564.035; 563.999 563.999], ... 665 [87.308 87.639; 107.039 108.189; 427.943 428.035; 437.965 438.027; 439.973 440.026; 491.275 492.571]}; 666 BadSegments{14} = {... 667 [365.982 367.194; 368.999 368.999; 368.999 368.999; 369.999 369.999; 371.999 371.999; 373.999 373.999; 375.942 376.050; 376.999 376.999; 378.999 378.999; 380.999 380.999; 382.999 382.999; 383.999 383.999; 386.999 386.999; 387.999 387.999; 418.999 418.999; 444.999 444.999; 690.178 693.218], ... 668 [101.796 102.183; 218.999 218.999; 219.999 219.999; 221.999 221.999; 222.999 222.999; 227.999 227.999; 229.999 229.999; 230.999 230.999; 232.999 232.999; 233.999 233.999; 235.999 235.999; 237.999 237.999; 238.985 239.031; 240.999 240.999; 242.999 242.999; 243.999 243.999; 246.999 246.999; 247.999 247.999; 253.999 253.999; 258.999 258.999; 259.999 259.999; 260.227 261.123; 264.999 264.999; 265.999 265.999; 268.999 268.999; 269.999 269.999; 274.999 274.999; 276.999 276.999; 277.999 277.999; 280.999 280.999; 282.966 283.021; 284.999 284.999; 285.999 285.999; 360.999 360.999; 362.973 363.026; 364.999 364.999; 365.999 365.999; 367.999 367.999; 368.985 369.024; 370.999 370.999; 371.999 371.999; 378.999 378.999; 379.999 379.999; 381.999 381.999; 383.999 383.999; 385.999 385.999; 387.999 387.999; 388.999 388.999; 398.999 398.999; 415.999 415.999; 417.999 417.999; 418.999 418.999; 421.999 421.999; 422.999 422.999], ... 669 [89.285 90.187], ... 670 [85.991 87.179; 88.999 88.999; 89.999 89.999; 92.966 93.027; 93.999 93.999; 107.999 107.999; 110.999 110.999; 111.971 112.025; 118.999 118.999; 121.999 121.999; 122.999 122.999; 166.999 166.999; 168.957 169.035; 173.999 173.999; 174.999 174.999; 175.957 176.035; 198.999 198.999; 199.999 199.999; 202.999 202.999; 203.999 203.999; 205.999 205.999; 207.999 207.999; 208.999 208.999; 210.974 211.044; 211.999 211.999; 212.999 212.999; 232.984 233.023; 234.999 234.999; 235.999 235.999; 236.999 236.999; 239.958 240.044; 240.999 240.999], ... 671 [71.132 72.227], ... 672 [98.134 98.827; 110.497 110.814; 114.000 117.272; 279.999 279.999; 279.999 279.999; 280.999 280.999; 282.999 282.999; 283.999 283.999; 284.999 284.999; 286.999 286.999; 287.999 287.999; 288.999 288.999; 289.999 289.999; 291.966 292.044; 292.999 292.999; 346.999 346.999; 437.608 437.646; 518.988 519.104; 522.969 523.015; 534.999 534.999; 536.967 537.029; 562.725 563.426]}; 673 BadSegments{15} = {... 674 [66.755 67.172; 257.988 258.042; 258.714 259.385; 260.958 261.044; 265.931 266.062; 267.968 268.022; 268.978 269.033; 270.992 271.031; 272.964 273.017; 273.968 274.030; 275.975 276.059; 276.970 277.046; 288.976 289.038; 289.984 290.015; 295.994 296.025; 296.982 297.013; 300.966 301.152; 364.730 364.800], ... 675 [46.531 46.555; 65.156 66.148; 87.535 87.642; 183.896 183.934; 294.342 294.375; 330.004 330.528; 333.785 333.815; 345.177 345.203; 399.544 399.573; 480.964 480.980], ... 676 [53.557 54.175; 148.851 149.136], ... 677 [43.681 44.214; 361.255 361.587; 409.462 411.021], ... 678 [90.868 91.130; 410.935 411.044], ... 679 [64.786 65.141; 132.385 132.786; 177.735 178.252; 278.747 278.902; 313.959 314.028; 314.970 315.031]}; 680 BadSegments{16} = {... 681 [38.958 44.335; 305.280 312.826; 324.778 326.067; 393.183 398.367; 403.410 422.854], ... 682 [49.726 50.251; 58.675 65.465; 263.918 264.088; 321.795 322.195; 522.881 523.081], ... 683 [61.245 62.325; 65.628 65.905; 315.686 317.275; 335.184 336.449; 387.870 388.117; 389.892 390.062], ... 684 [56.020 57.255; 60.711 61.096; 64.353 64.924; 73.202 73.757; 76.134 76.844; 95.625 96.859; 171.436 172.625; 178.359 178.715; 212.828 213.415; 352.425 352.617; 367.755 369.097; 488.400 489.426], ... 685 [71.665 72.513; 76.347 77.181; 127.134 128.862], ... 686 [46.190 47.209; 53.461 55.752; 194.317 194.510; 213.101 213.240; 216.356 216.442; 225.962 226.286; 245.163 245.464; 252.041 253.422; 254.648 254.856; 292.966 294.340; 340.928 341.067; 346.298 346.452]}; 687 BadSeg = BadSegments{iSubj}{iRun}'; 688 end 689

Report viewer

Click on Run to start the script.

As this process is taking screen captures, do not use your computer for something else at the same time: if another window covers the Brainstorm figures, it will not capture the right images.

At the end, the report viewer is opened to show the status of all the processes, the information messages, the list of input and output files, and the screen captures. The report is saved in your home folder ($home/.brainstorm/reports). If you close this window, you can get it back with the menu File > Report viewer.








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


Tutorials/Scripting (last edited 2016-07-21 21:35:11 by FrancoisTadel)