EEG and epilepsy

Authors: Francois Tadel, Elizabeth Bock, John C. Mosher, Marcel Heers.

This tutorial introduces some concepts that are specific to the management of EEG recordings in the Brainstorm environment. It also describes a standard pipeline for analyzing epilepsy recordings. It is based on a clinical case from the Epilepsy Center at the University Hospital of Freiburg, Germany. The anonymized dataset can be downloaded directly from the Brainstorm download page.

Note that the operations used here are not detailed, the goal of this tutorial is not to introduce Brainstorm to new users. For in-depth explanations of the interface and theoretical foundations, please refer to the introduction tutorials. This page is the new version where shared channel files are not used anymore - if you really want to use shared channel files, see the ?old version.

NOT FOR CLINICAL USE:
The performance characteristics of the methods and software implentation presented in this tutorial have not been certified as medical devices and should be used for research purposes only.

Dataset description

License

This tutorial dataset (EEG and MRI data) remains proprietary of the Epilepsy Centre, University Hospital Freiburg, Germany. Its use and transfer outside the Brainstorm tutorial, e.g. for research purposes, is prohibited without written consent from the Epilepsy Centre in Freiburg. For questions please contact A. Schulze-Bonhage, MD, PhD: andreas.schulze-bonhage@uniklinik-freiburg.de

Clinical description

This tutorial dataset was acquired in a patient who suffered from focal epilepsy with focal sensory, dyscognitive and secondarily generalized seizures since the age of eight years. He does not have any typical risk factors for epilepsy. The high resolution 3T epilepsy MRI including postprocessing was found to be normal. FDG-PET of the brain did not show any pathological changes in the glucose metabolism. Non-invasive telemetry revealed left fronto-central sharp waves, polyspikes and bursts of beta band activity (max. amplitude FC1, Cz) especially during sleep. The tutorial dataset was acquired during one night of the non-invasive telemetry recording at the Epilepsy Center Freiburg, Germany.

Afterwards the patient underwent invasive EEG to identify the epileptogenic area and to map functionally important cortex. Details about invasive EEG and source localization from invasive EEG in this patient are reported in Dümpelmann, et al. (2011). Subsequently a left frontal tailored resection was performed. The histological analysis revealed a focal cortical dysplasia type IIB according to the classification of Palmini, et al. (2004). The postsurgical outcome is Engel 1A with a follow-up of 5 years.

The EEG data distributed here was recorded at 256Hz, using a Neurofile NT digital video-EEG system with 128 channels and a 16-bit A/D converter. The signal was filtered in the recording system with a high-pass filter with a time constant of 1 second (cutoff frequency ~ 0.16Hz) and a low-pass filter with a cutoff frequency of 344 Hz. The spikes were marked with Brainstorm by the epileptologists at the Epilepsy Center in Freiburg.

Overview of the data processing

The proper identification of epileptiform discharges ("spikes") is a complicated topic beyond the scope of this tutorial. Residents in Neurology train intensively on how to identify true interictal and ictal discharges, particularly as distinct from so-called "normal variants" that can be abundant. Sleep and drowsy states of the brain can generate "vertex waves," "K-complexes," "positive occipital sharp transients of sleep" (POSTS), and "wickets," to name a few variants, none of which are epileptic. A good overview of terminology and application can be found, for example, on the Medscape website, Epileptiform Discharges.

With this caveat, we nonetheless give an overview of the processing approach. Although automation has been proposed for decades, "spike hunting" is often done by manual inspection of the recorded EEG waveforms (whether scalp, subdural, or depths). The classic scalp sensor arrangement is the International 10-20 System (Wikipedia Site, Bioelectromagnetism Book, Chapter 13.3) arranged at 10 percent and 20 percent distances about the circumference of the head. Each of these 21 electrodes is acquired with respect to some reference (as all potentials must be). In reviewing the recordings, however, several "montages" are traditionally recommended that digitally "re-reference" the original recordings into new linear combinations of electrodes.

A classic montage is the "double banana" (Google Search) which emphasizes local changes in the scalp EEG by forming sequential bipolar pairs, such as "Fp1-F3", "F3-C3." Because F3 is found twice in this montage and of opposite sign, then an epileptic spike centered under F3 will appear as a reversed polarity in these two channels, a visual cue the trained epileptologist seeks when rapidly scanning through hours of recordings. This montage is more formally known as "LB-18.3" or "Longitudinal Bipolar 3" in the nomenclature of the American Clinical Neurophysiology Society (ACNS) Guidelines (see References Below).

ACNS guidelines suggest using both "longitudinal" and "transversal" bipolar montages to survey your data. For temporal epilepsy cases, you may also add a "temporal ring" montage. European neurologists often prefer to review the recordings using an average reference montage. Brainstorm provides several variations of all these montages, allows the users full flexibility in creating their own, and can run different montages simultaneously in multiple windows.

The user has to step along through the data, look for abnormal brain activity, then use Brainstorm's event markers to tag suspect intervals. With the suspected events marked and saved, the user can return later to perform source analyses on these intervals. With this brief overview, we detail below an exercise with the sample epilepsy data.

Note that the aim of this tutorial is not to train you on how to do spike recognition itself, but rather to illustrate how to manipulate the Brainstorm interface to build an environment adapted to this task. The formal data reviewing should be done by clinical neurophysiologists or other experienced personnel, with specialized training in separating true epileptic activity from other more normal variants of brain activity.

References

Dümpelmann M, Ball T, Schulze-Bonhage A (2011)
sLORETA allows reliable distributed source reconstruction based on subdural strip and grid recordings. Human Brain Mapping.

Palmini A, Najm I, Avanzini G, Babb T, Guerrini R, Foldvary-Schaefer N, Jackson G, Luders HO, Prayson R, Spreafico R, Vinters HV (2004) Terminology and classification of the cortical dysplasias.
Neurology, 62:S2-8.

Standard montages recommended by the American Clinical Neurophysiology Society:

Download and installation

Import the anatomy

Without the individual MRI

If you do not have access to an individual MR scan of the subject (or if its quality is too low to be processed with FreeSurfer), but if you have digitized the head shape of the subject using a tracking system, you have an alternative: deform one of the Brainstorm templates (Colin27 or ICBM152) to match the shape of the subject's head. For more information, read the tutorials: Warping default anatomy, Using the anatomy templates

Access the recordings

Prepare the channel file

Register electrodes with MRI

Review EEG recordings

Display the recordings

Frequency filters

Go to the Filter tab to enable some display frequency filters. General recommendations are:

Time and amplitude resolution

The resolutions of the time and amplitude axes have a lot of importance for the visual detection of epileptic spikes. The shapes we are looking for are altered by the horizontal and vertical scaling. The distance unit on a screen is the pixel, we can set how much time is represented by one pixel horizontally and how much amplitude is represented by one pixel vertically.

In the Brainstorm interface, this resolution is usually set implicitly: you can set the size of the window, the duration or recordings reviewed at once (text box "duration" in tab Record) and the maximum amplitude to show in the figure (buttons [...] and [AS] on the right of the time series figure). From there, you can also zoom in time ([<], [>], mouse wheel) or amplitude ([^], [v], Shift+mouse wheel). These parameters are convenient to explore the recordings interactively but don't allow us to have reproducible displays with constant time and amplitude resolutions.

To set the figure resolution explicitly: right-click on the figure > Figure > Set axes resolution. Note that this interface does not store the input values, it just modifies the other parameters (figure size, time window, max amplitude) to fit the resolution objectives. If you modify these parameters (resize the figure, keep the button [AS] selected and scroll in time, etc) the resolution is lost, you have to set it again manually. In particular, make sure you disable the auto-scaling ([AS] button in the time series figure) if you want to preserve the aspect ratio while you scroll through the data.

This operation typically has to be repeated everytime you open a new file. For a faster access to this option, use the keyboard shortcut Ctrl+O. The option window offers by default the last values that you entered, just press Enter to apply them again.

Recommendations for this dataset are:

User setups

This preparation of the reviewing environment requires a large number of operations, and would become quickly annoying if you have to repeat it every time you open a file. You can use the menu "User setups" to save a window configuration and reload it in one click later. In the menu "Window layout", at the top-right of the Brainstorm window, select User setup > New setup. Enter a name of your choice for this particular window arrangement.

This operation will also disable the automatic window arrangement (Window layout > None). To reload it later, open one figure on the dataset you want to review and then select your new entry in the User setup menu.

Multiple montages

It may be interesting for some cases to display different groups of sensors in multiple windows (eg. with an MEG system with 300 sensors), or some complicated epilepsy cases where you would like to review at the same time multiple montages (eg. longitudinal and transversal bipolar montages).

Scalp current density

In the example below, see how the montage Scalp current density can enhance the visual detection of spikes. More information.

Mark spikes

Detect heartbeats

When you have a clean ECG signal for your patient, you can automatically identify all the heartbeats in the recordings. Because heartbeats can cause sharp waves in some EEG traces, it helps the reviewing process to have all the cardiac events marked in the recordings.

Import the spike markers

Some spikes were marked by the epileptologists at the Epilepsy Center in Freiburg and saved in an external text file. We are going to import this file manually.

Manual marking

If you are marking the events by yourself, you could follow this procedure:

Pre-process recordings

Two of the typical pre-processing steps consist in removing the power lines artifacts (50 Hz or 60Hz) and the frequencies we are not interested in (a low-pass filter to remove the high-frequency noise and a high-pass filter to remove the very slow components of the signals). Let's start with a spectral evaluation of this file.

Power spectrum

Band-pass filter

The filters we selected for reviewing the recordings were for visualization only, they were not applied to the file. In order to apply these filters permanently to the recordings, we need to do the following:

Average reference

The average reference montage we used to review the recordings was for visualization only, it did not modify the file. To apply this transformation permanently, we need to run the re-referencing process.

Average reference and bad channels

You should be careful with the average reference when adding or removing bad channels. Changing the number of channels modifies the way the average reference is computed.

Montage: When using the montage "Average reference" to change only the visulization, the average reference operator is computed dynamically, it always takes into account the bad channels at the moment you review the recordings. Therefore the average reference for display is always correct, you do not have to modify anything if you change the list of bad channels.

Permanent re-referencing: When using the process "Re-reference EEG" to alter permanently the recordings, the average reference operator is computed using the channels that are marked as bad at the moment of the computation, and saved in the file. If later you modify the list of bad channels, this operator will become incorrect, you will have to delete it and recompute it. To avoid any confusion, always compute the average reference after marking the bad channels.

Evaluate the modifications

Artifact cleaning with ICA

The standard cleaning pipeline presented in the introduction tutorials recommends to use the SSP approach to remove the cardiac and blink artifacts. This is valid in most MEG experiments.

In EEG, there is usually not such a clear artifact caused by the heartbeats: cleaning for cardiac artifacts is not part of the standard processing pipeline. Eye movements typically cause huge artifacts on the frontal channels and need to be marked as bad or corrected. In the present case, the patient is sleeping, therefore there are no blinks, but we can observe a lot of fast eye movements during the periods of REM sleep, and other slower eye movements in the rest of the recordings.

The SSP technique is not adapted for cleaning events for which we cannot set markers, and in general it is not suitable for low-density EEG. The topographies are a lot smoother in EEG than in MEG, it is more difficult to identify a spatial filter that targets one specific artifact with a simple spatial PCA decomposition, especially with a low number of sensors.

The ICA approach (Independent Component Analysis) is much more popular in the EEG community. It relies on the the same logic as the SSP: identifying spatial topographies that are specific from an artifact and then removing them from the recordings. But instead of simply identifying the most powerful spatial components with a PCA decomposition, it tries to identify components that are independent in time. Using the information from the time dimension makes it possible to work with a lower number of sensors, and to identify some components of the signal that are completely uncorrelated with the others.

The ICA analysis can also be used to identify the signals from a few brain sources of interest: in this case, select a few components and remove all the others.

Various algorithms are available from the ICA process. You can explore the documentation of all these methods for reference documentation on ICA:

We will now illustrate how to compute some projectors to remove the contaminations from the eye movements with the Picard algorithm.

Import the recordings

Epoching

Now we want to extract all the spikes from this filtered file and import them in the database.

You can overlay one or more electrodes from multiple files with the tab "Cluster":

Alternatively, you can display all the trials as an image, for one sensor at a time:

Averaging spikes

Source analysis: Surface

Head model

Noise covariance matrix

Inverse model

(Advanced) Source analysis: MEM inverse solution

The maximum of entropy on the mean (MEM) framework solution gathers several source localization techniques dedicated to estimate accurately the spatial extent of the EEG/MEG generators, a very important property in the context of localizing the generators of epileptic discharges, for which it is known that a relatively extended brain region should be involved (several cm2) to detect these discharges from the scalp. You can read more information on MEM in the Brain entropy in space and time (BEst) in the BEst tutorial.

Here are the steps to perform MEM localization on epileptic spikes.

Regions of interest

Source analysis: Volume

If the results you obtain are not satisfying with the surface-based source estimation, you can run again the same analysis with a different source space, sampling the entire head volume instead. More information about this method in the Volume source estimation tutorial. We will use this new example to estimate the dipole scanning tools.

Head model

Dipole scanning

Dipole fitting

The dipole scanning approach presented in the previous section estimates the activity of a fixed grid of dipoles and selects the most significant one at each time. Another option to represent the source activity as a sequence of moving dipoles is to use the FieldTrip function ft_dipolefitting.m to run a non-linear dipole fit at each time point. This process requires that you install FieldTrip on your computer first. Note that it works only with a spherical head model.

Time-frequency

We will illustrate two ways of computing time-frequency maps. Exploring the continuous recordings in time-frequency space can help with the detection of the epileptic activity, while computing the average of the time-frequency power of a few epochs can help understanding the dynamic of the event.

Continuous recordings

Spike average

Additional documentation

Forum posts

Minimum number of electrodes for EEG source modeling

Inverse models in epilepsy

MEM in clinical epilepsy

Related methodological developments:

Ability of MEM to recover the spatial extent of epileptic spikes:

Multimodal concordance on clinical cases:

Background readings: Epilepsy and EEG/MEG

Scripting

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

1 function tutorial_epilepsy(tutorial_dir, reports_dir) 2 % TUTORIAL_EPILEPSY: Script that reproduces the results of the online tutorial "EEG/Epilepsy". 3 % 4 % CORRESPONDING ONLINE TUTORIALS: 5 % https://neuroimage.usc.edu/brainstorm/Tutorials/Epilepsy 6 % 7 % INPUTS: 8 % - tutorial_dir: Directory where the sample_epilepsy.zip file has been unzipped 9 % - reports_dir : Directory where to save the execution report (instead of displaying it) 10 11 % @============================================================================= 12 % This function is part of the Brainstorm software: 13 % https://neuroimage.usc.edu/brainstorm 14 % 15 % Copyright (c) University of Southern California & McGill University 16 % This software is distributed under the terms of the GNU General Public License 17 % as published by the Free Software Foundation. Further details on the GPLv3 18 % license can be found at http://www.gnu.org/copyleft/gpl.html. 19 % 20 % FOR RESEARCH PURPOSES ONLY. THE SOFTWARE IS PROVIDED "AS IS," AND THE 21 % UNIVERSITY OF SOUTHERN CALIFORNIA AND ITS COLLABORATORS DO NOT MAKE ANY 22 % WARRANTY, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF 23 % MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, NOR DO THEY ASSUME ANY 24 % LIABILITY OR RESPONSIBILITY FOR THE USE OF THIS SOFTWARE. 25 % 26 % For more information type "brainstorm license" at command prompt. 27 % =============================================================================@ 28 % 29 % Author: Francois Tadel, 2014-2022 30 31 32 % ===== FILES TO IMPORT ===== 33 % Output folder for reports 34 if (nargin < 2) || isempty(reports_dir) || ~isdir(reports_dir) 35 reports_dir = []; 36 end 37 % You have to specify the folder in which the tutorial dataset is unzipped 38 if (nargin == 0) || isempty(tutorial_dir) || ~file_exist(tutorial_dir) 39 error('The first argument must be the full path to the tutorial dataset folder.'); 40 end 41 % Build the path of the files to import 42 AnatDir = fullfile(tutorial_dir, 'sample_epilepsy', 'anatomy'); 43 RawFile = fullfile(tutorial_dir, 'sample_epilepsy', 'data', 'tutorial_eeg.bin'); 44 ElcFile = fullfile(tutorial_dir, 'sample_epilepsy', 'data', 'tutorial_electrodes.elc'); 45 SpikeFile = fullfile(tutorial_dir, 'sample_epilepsy', 'data', 'tutorial_spikes.txt'); 46 % Check if the folder contains the required files 47 if ~file_exist(RawFile) 48 error(['The folder ' tutorial_dir ' does not contain the folder from the file sample_epilepsy.zip.']); 49 end 50 % Subject name 51 SubjectName = 'sepi01'; 52 53 54 % ===== CREATE PROTOCOL ===== 55 % The protocol name has to be a valid folder name (no spaces, no weird characters...) 56 ProtocolName = 'TutorialEpilepsy'; 57 % Start brainstorm without the GUI 58 if ~brainstorm('status') 59 brainstorm nogui 60 end 61 % Delete existing protocol 62 gui_brainstorm('DeleteProtocol', ProtocolName); 63 % Create new protocol 64 gui_brainstorm('CreateProtocol', ProtocolName, 0, 0); 65 % Start a new report 66 bst_report('Start'); 67 68 69 % ===== IMPORT ANATOMY ===== 70 % Process: Import anatomy folder 71 bst_process('CallProcess', 'process_import_anatomy', [], [], ... 72 'subjectname', SubjectName, ... 73 'mrifile', {AnatDir, 'FreeSurfer-fast'}, ... 74 'nvertices', 15000); 75 76 % ===== ACCESS THE RECORDINGS ===== 77 % Process: Create link to raw file 78 sFilesRaw = bst_process('CallProcess', 'process_import_data_raw', [], [], ... 79 'subjectname', SubjectName, ... 80 'datafile', {RawFile, 'EEG-DELTAMED'}, ... 81 'channelreplace', 1, ... 82 'channelalign', 0); 83 84 % Process: Add EEG positions 85 bst_process('CallProcess', 'process_channel_addloc', sFilesRaw, [], ... 86 'channelfile', {ElcFile, 'XENSOR'}, ... 87 'fixunits', 1, ... 88 'vox2ras', 0); 89 % Process: Refine registration 90 bst_process('CallProcess', 'process_headpoints_refine', sFilesRaw, []); 91 % Process: Project electrodes on scalp 92 bst_process('CallProcess', 'process_channel_project', sFilesRaw, []); 93 94 % Process: Snapshot: Sensors/MRI registration 95 bst_process('CallProcess', 'process_snapshot', sFilesRaw, [], ... 96 'target', 1, ... % Sensors/MRI registration 97 'modality', 4, ... % EEG 98 'orient', 1, ... % left 99 'Comment', 'MEG/MRI Registration'); 100 101 102 % ===== EVENTS: SPIKES AND HEARTBEATS ===== 103 % Process: Detect heartbeats 104 bst_process('CallProcess', 'process_evt_detect_ecg', sFilesRaw, [], ... 105 'channelname', 'ECG', ... 106 'timewindow', [], ... 107 'eventname', 'cardiac'); 108 % Process: Events: Import from file 109 bst_process('CallProcess', 'process_evt_import', sFilesRaw, [], ... 110 'evtfile', {SpikeFile, 'ARRAY-TIMES'}, ... 111 'evtname', 'SPIKE'); 112 113 114 % ===== PRE-PROCESSING ===== 115 % Process: Power spectrum density (Welch) 116 sFilesPsd = bst_process('CallProcess', 'process_psd', sFilesRaw, [], ... 117 'timewindow', [], ... 118 'win_length', 10, ... 119 'win_overlap', 50, ... 120 'sensortypes', 'EEG', ... 121 'edit', struct(... 122 'Comment', 'Power', ... 123 'TimeBands', [], ... 124 'Freqs', [], ... 125 'ClusterFuncTime', 'none', ... 126 'Measure', 'power', ... 127 'Output', 'all', ... 128 'SaveKernel', 0)); 129 % Process: Snapshot: Frequency spectrum 130 bst_process('CallProcess', 'process_snapshot', sFilesPsd, [], ... 131 'target', 10, ... % Frequency spectrum 132 'Comment', 'Power spectrum density'); 133 134 % Process: Band-pass:0.5-80Hz 135 sFilesRaw = bst_process('CallProcess', 'process_bandpass', sFilesRaw, [], ... 136 'sensortypes', 'EEG', ... 137 'highpass', 0.5, ... 138 'lowpass', 80, ... 139 'attenuation', 'strict', ... % 60dB 140 'mirror', 0); 141 142 % Process: Re-reference EEG 143 bst_process('CallProcess', 'process_eegref', sFilesRaw, [], ... 144 'eegref', 'AVERAGE', ... 145 'sensortypes', 'EEG'); 146 147 % Process: Power spectrum density (Welch) 148 sFilesPsdClean = bst_process('CallProcess', 'process_psd', sFilesRaw, [], ... 149 'timewindow', [], ... 150 'win_length', 10, ... 151 'win_overlap', 50, ... 152 'sensortypes', 'EEG', ... 153 'edit', struct(... 154 'Comment', 'Power', ... 155 'TimeBands', [], ... 156 'Freqs', [], ... 157 'ClusterFuncTime', 'none', ... 158 'Measure', 'power', ... 159 'Output', 'all', ... 160 'SaveKernel', 0)); 161 % Process: Snapshot: Frequency spectrum 162 bst_process('CallProcess', 'process_snapshot', sFilesPsdClean, [], ... 163 'target', 10, ... % Frequency spectrum 164 'Comment', 'Power spectrum density'); 165 166 167 % ===== ICA ===== 168 % Process: ICA components: Infomax 169 bst_process('CallProcess', 'process_ica', sFilesRaw, [], ... 170 'timewindow', [500, 700], ... 171 'eventname', '', ... 172 'eventtime', [], ... 173 'sensortypes', 'EEG', ... 174 'ignorebad', 1, ... 175 'bandpass', [0, 0], ... 176 'resample', 0, ... 177 'usessp', 1, ... 178 'method', 'picard', ... % Picard: Ablin, Cardoso & Gramfort (IEEE TSP 2018) 179 'nicacomp', 0, ... 180 'icasort', 'EOG, ECG', ... 181 'saveerp', 0, ... 182 'select', [1 2]); % Force the selection: components #1 and #2 183 184 185 % ===== IMPORT RECORDINGS ===== 186 % Process: Import MEG/EEG: Events 187 sFilesEpochs = bst_process('CallProcess', 'process_import_data_event', sFilesRaw, [], ... 188 'subjectname', SubjectName, ... 189 'condition', '', ... 190 'eventname', 'SPIKE', ... 191 'timewindow', [], ... 192 'epochtime', [-0.3, 0.5], ... 193 'createcond', 1, ... 194 'ignoreshort', 1, ... 195 'usectfcomp', 1, ... 196 'usessp', 1, ... 197 'freq', [], ... 198 'baseline', []); 199 200 % Process: Average: By condition (subject average) 201 sFilesAvg = bst_process('CallProcess', 'process_average', sFilesEpochs, [], ... 202 'avgtype', 3, ... 203 'avg_func', 1, ... % Arithmetic average: mean(x) 204 'weighted', 0, ... 205 'keepevents', 0); 206 207 % Configure the display so that the negative values points up 208 bst_set('FlipYAxis', 1); 209 % Process: Snapshot: Recordings time series 210 bst_process('CallProcess', 'process_snapshot', sFilesAvg, [], ... 211 'target', 5, ... % Recordings time series 212 'modality', 4, ... % EEG 213 'Comment', 'Average spike'); 214 % Process: Snapshot: Recordings topography (contact sheet) 215 bst_process('CallProcess', 'process_snapshot', sFilesAvg, [], ... 216 'target', 7, ... % Recordings topography (contact sheet) 217 'modality', 4, ... % EEG 218 'contact_time', [-0.040, 0.110], ... 219 'contact_nimage', 16, ... 220 'Comment', 'Average spike'); 221 222 223 % ===== SOURCE ANALYSIS: SURFACE ===== 224 % Process: Generate BEM surfaces 225 bst_process('CallProcess', 'process_generate_bem', [], [], ... 226 'subjectname', SubjectName, ... 227 'nscalp', 642, ... 228 'nouter', 482, ... 229 'ninner', 482, ... 230 'thickness', 4, ... 231 'method', 'brainstorm'); 232 % Process: Compute head model 233 bst_process('CallProcess', 'process_headmodel', sFilesAvg, [], ... 234 'sourcespace', 1, ... % Cortex surface 235 'eeg', 3, ... % OpenMEEG BEM 236 'openmeeg', struct(... 237 'BemSelect', [0, 0, 1], ... 238 'BemCond', [1, 0.0125, 1], ... 239 'BemNames', {{'Scalp', 'Skull', 'Brain'}}, ... 240 'BemFiles', {{}}, ... 241 'isAdjoint', 1, ... 242 'isAdaptative', 1, ... 243 'isSplit', 0, ... 244 'SplitLength', 4000)); 245 246 % Process: Compute noise covariance 247 bst_process('CallProcess', 'process_noisecov', sFilesRaw, [], ... 248 'baseline', [110, 160], ... 249 'sensortypes', 'EEG', ... 250 'target', 1, ... % Noise covariance (covariance over baseline time window) 251 'dcoffset', 1, ... % Block by block, to avoid effects of slow shifts in data 252 'identity', 0, ... 253 'copycond', 1, ... 254 'copysubj', 0, ... 255 'replacefile', 1); % Replace 256 257 % Process: Compute sources [2018] 258 sAvgSrc = bst_process('CallProcess', 'process_inverse_2018', sFilesAvg, [], ... 259 'output', 1, ... % Kernel only: shared 260 'inverse', struct(... 261 'Comment', 'sLORETA: EEG', ... 262 'InverseMethod', 'minnorm', ... 263 'InverseMeasure', 'sloreta', ... 264 'SourceOrient', {{'free'}}, ... 265 'Loose', 0.2, ... 266 'UseDepth', 0, ... 267 'WeightExp', 0.5, ... 268 'WeightLimit', 10, ... 269 'NoiseMethod', 'reg', ... 270 'NoiseReg', 0.1, ... 271 'SnrMethod', 'fixed', ... 272 'SnrRms', 1e-06, ... 273 'SnrFixed', 3, ... 274 'ComputeKernel', 1, ... 275 'DataTypes', {{'EEG'}})); 276 % Process: Snapshot: Sources (one time) 277 bst_process('CallProcess', 'process_snapshot', sAvgSrc, [], ... 278 'target', 8, ... % Sources (one time) 279 'modality', 1, ... % MEG (All) 280 'orient', 3, ... % top 281 'time', 0, ... 282 'threshold', 60, ... 283 'Comment', 'Average spike'); 284 285 286 % Install and Load Brain Entropy plugin 287 [isInstalled, errMsg] = bst_plugin('Install', 'brainentropy'); 288 if isInstalled 289 % Use default options of cMEM 290 mem_option = be_pipelineoptions(be_main, 'cMEM'); 291 mem_option.optional = struct_copy_fields(mem_option.optional, ... 292 struct(... 293 'TimeSegment', [-0.30078, 0.5], ... 294 'BaselineType', {{'within-data'}}, ... 295 'Baseline', [], ... 296 'BaselineHistory', {{'within'}}, ... 297 'BaselineSegment', [-0.30078, -0.10156], ... 298 'groupAnalysis', 0, ... 299 'display', 0)); 300 % Process: Compute sources: BEst 301 sAvgSrcMEM = bst_process('CallProcess', 'process_inverse_mem', sFilesAvg, [], ... 302 'comment', 'MEM', ... 303 'mem', struct('MEMpaneloptions', mem_option), ... 304 'sensortypes', 'EEG'); 305 % Process: Snapshot: Sources (one time) 306 bst_process('CallProcess', 'process_snapshot', sAvgSrcMEM, [], ... 307 'target', 8, ... % Sources (one time) 308 'modality', 1, ... % MEG (All) 309 'orient', 3, ... % top 310 'time', 0, ... 311 'threshold', 30, ... 312 'Comment', 'Average spike (cMEM)'); 313 else 314 bst_report('Error', [], [], errMsg); 315 end 316 317 318 % ===== SOURCE ANALYSIS: VOLUME ===== 319 % Process: Compute head model 320 bst_process('CallProcess', 'process_headmodel', sFilesAvg, [], ... 321 'sourcespace', 2, ... % MRI volume 322 'volumegrid', struct(... 323 'Method', 'adaptive', ... 324 'nLayers', 17, ... 325 'Reduction', 3, ... 326 'nVerticesInit', 4000, ... 327 'Resolution', 0.005, ... 328 'FileName', []), ... 329 'eeg', 2); % 3-shell sphere 330 331 % Process: Compute sources [2018] 332 sAvgSrcVol = bst_process('CallProcess', 'process_inverse_2018', sFilesAvg, [], ... 333 'output', 1, ... % Kernel only: shared 334 'inverse', struct(... 335 'Comment', 'Dipoles: EEG', ... 336 'InverseMethod', 'gls', ... 337 'InverseMeasure', 'performance', ... 338 'SourceOrient', {{'free'}}, ... 339 'Loose', 0.2, ... 340 'UseDepth', 1, ... 341 'WeightExp', 0.5, ... 342 'WeightLimit', 10, ... 343 'NoiseMethod', 'reg', ... 344 'NoiseReg', 0.1, ... 345 'SnrMethod', 'rms', ... 346 'SnrRms', 1e-06, ... 347 'SnrFixed', 3, ... 348 'ComputeKernel', 1, ... 349 'DataTypes', {{'EEG'}})); 350 % Process: Snapshot: Sources (one time) 351 bst_process('CallProcess', 'process_snapshot', sAvgSrcVol, [], ... 352 'target', 8, ... % Sources (one time) 353 'modality', 1, ... % MEG (All) 354 'orient', 3, ... % top 355 'time', 0, ... 356 'threshold', 0, ... 357 'Comment', 'Dipole modeling'); 358 359 % Process: Dipole scanning 360 sDipScan = bst_process('CallProcess', 'process_dipole_scanning', sAvgSrcVol, [], ... 361 'timewindow', [-0.040, 0.100], ... 362 'scouts', {}); 363 % Process: Snapshot: Dipoles 364 bst_process('CallProcess', 'process_snapshot', sDipScan, [], ... 365 'target', 13, ... % Dipoles 366 'orient', 3, ... % top 367 'threshold', 90, ... 368 'Comment', 'Dipole scanning'); 369 % Process: Snapshot: Dipoles 370 bst_process('CallProcess', 'process_snapshot', sDipScan, [], ... 371 'target', 13, ... % Dipoles 372 'orient', 1, ... % left 373 'threshold', 90, ... 374 'Comment', 'Dipole scanning'); 375 376 % Process: FieldTrip: ft_dipolefitting 377 sDipFit = bst_process('CallProcess', 'process_ft_dipolefitting', sFilesAvg, [], ... 378 'timewindow', [-0.040, 0.100], ... 379 'sensortypes', 'EEG', ... 380 'dipolemodel', 1, ... % Moving dipole 381 'numdipoles', 1, ... 382 'volumegrid', [], ... 383 'symmetry', 0, ... 384 'filetag', ''); 385 % Process: Snapshot: Dipoles 386 bst_process('CallProcess', 'process_snapshot', sDipFit, [], ... 387 'target', 13, ... % Dipoles 388 'orient', 3, ... % top 389 'threshold', 95, ... 390 'Comment', 'Dipole fitting'); 391 % Process: Snapshot: Dipoles 392 bst_process('CallProcess', 'process_snapshot', sDipFit, [], ... 393 'target', 13, ... % Dipoles 394 'orient', 1, ... % left 395 'threshold', 95, ... 396 'Comment', 'Dipole fitting'); 397 398 399 % ===== TIME-FREQUENCY ===== 400 % Process: Import MEG/EEG: Time 401 sRawImport = bst_process('CallProcess', 'process_import_data_time', sFilesRaw, [], ... 402 'subjectname', SubjectName, ... 403 'condition', '', ... 404 'timewindow', [1890, 1900], ... 405 'split', 0, ... 406 'ignoreshort', 1, ... 407 'usectfcomp', 1, ... 408 'usessp', 1); 409 % Process: Time-frequency (Morlet wavelets) 410 sRawTf = bst_process('CallProcess', 'process_timefreq', sRawImport, [], ... 411 'sensortypes', 'EEG', ... 412 'edit', struct(... 413 'Comment', 'Power,2-80Hz', ... 414 'TimeBands', [], ... 415 'Freqs', [2, 2.5, 3.1, 3.7, 4.3, 5, 5.7, 6.4, 7.2, 8.1, 9, 9.9, 10.9, 12, 13.1, 14.3, 15.6, 17, 18.4, 19.9, 21.6, 23.3, 25.1, 27, 29.1, 31.3, 33.6, 36, 38.6, 41.4, 44.3, 47.4, 50.7, 54.1, 57.8, 61.8, 65.9, 70.3, 75, 80], ... 416 'MorletFc', 1, ... 417 'MorletFwhmTc', 3, ... 418 'ClusterFuncTime', 'none', ... 419 'Measure', 'power', ... 420 'Output', 'all', ... 421 'SaveKernel', 0), ... 422 'normalize', 'multiply'); % 1/f compensation: Multiply output values by frequency 423 % Process: Snapshot: Time-frequency maps 424 bst_process('CallProcess', 'process_snapshot', sRawTf, [], ... 425 'target', 14, ... % Time-frequency maps 426 'rowname', 'FC1'); 427 428 % Process: Time-frequency (Morlet wavelets) 429 sAvgTf = bst_process('CallProcess', 'process_timefreq', sFilesEpochs, [], ... 430 'sensortypes', 'EEG', ... 431 'edit', struct(... 432 'Comment', 'Avg,Power,2-80Hz', ... 433 'TimeBands', [], ... 434 'Freqs', [2, 2.5, 3.1, 3.7, 4.3, 5, 5.7, 6.4, 7.2, 8.1, 9, 9.9, 10.9, 12, 13.1, 14.3, 15.6, 17, 18.4, 19.9, 21.6, 23.3, 25.1, 27, 29.1, 31.3, 33.6, 36, 38.6, 41.4, 44.3, 47.4, 50.7, 54.1, 57.8, 61.8, 65.9, 70.3, 75, 80], ... 435 'MorletFc', 1, ... 436 'MorletFwhmTc', 3, ... 437 'ClusterFuncTime', 'none', ... 438 'Measure', 'power', ... 439 'Output', 'average', ... 440 'RemoveEvoked', 0, ... 441 'SaveKernel', 0), ... 442 'normalize', 'none'); % None: Save non-standardized time-frequency maps 443 % Process: Event-related perturbation (ERS/ERD): [-199ms,-102ms] 444 sAvgTfNorm = bst_process('CallProcess', 'process_baseline_norm', sAvgTf, [], ... 445 'baseline', [-0.200, -0.100], ... 446 'method', 'ersd', ... % Event-related perturbation (ERS/ERD): x_std = (x - μ) / μ * 100 447 'overwrite', 0); 448 % Process: Snapshot: Time-frequency maps 449 bst_process('CallProcess', 'process_snapshot', sAvgTfNorm, [], ... 450 'target', 14, ... % Time-frequency maps 451 'rowname', 'FC1'); 452 453 454 % Save and display report 455 ReportFile = bst_report('Save', []); 456 if ~isempty(reports_dir) && ~isempty(ReportFile) 457 bst_report('Export', ReportFile, reports_dir); 458 else 459 bst_report('Open', ReportFile); 460 end 461 462 disp([10 'BST> tutorial_epilepsy: Done.' 10]); 463





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


Tutorials/Epilepsy (last edited 2024-07-15 18:45:46 by ?EdouardDelaire)