Skip to content

Commit beb42b6

Browse files
committed
add limo
1 parent 10ab296 commit beb42b6

19 files changed

+1090
-3
lines changed

code/plugins/reformat_plugin.py

+10
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ def reformat_wiki_pages(filepath, filename, parent, output_file, wiki_input_dir=
4545
append_text += '''
4646
title: {title}
4747
long_title: {title}
48+
render_with_liquid: false
4849
'''.format(title=title)
4950

5051
append_text += 'nav_order: {order}\n'.format(order=order+1)
@@ -58,13 +59,22 @@ def reformat_wiki_pages(filepath, filename, parent, output_file, wiki_input_dir=
5859

5960
with open(filepath) as f:
6061
text = f.read()
62+
if parent == "LIMO":
63+
text = format_text_limo(text)
6164
text = append_text + text
6265
outputfilename = clean_filename(os.path.basename(output_file))
6366
outputfilepath = os.path.dirname(output_file)
6467

6568
with open(f"{outputfilepath}/{outputfilename}", 'w') as out:
6669
out.write(text)
6770

71+
def format_text_limo(text):
72+
# find in the text the line containing ```matlab and append a line before it
73+
text = text.replace('https://github.com/', 'https://raw.githubusercontent.com/')
74+
text = text.replace('blob/', '')
75+
76+
return text
77+
6878
def reformat_plugin_dir(plugin_input_dir, plugin_name, formatted_name, order, link, plugin_type='wiki'):
6979
# plugins_output_dir = '/Users/dtyoung/Documents/EEGLAB/sccn.github.io/plugins'
7080
plugin_output_dir = os.path.join('../../plugins', plugin_name)

code/plugins/update_plugins.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -42,21 +42,21 @@ def update_repo(repo, formatted_name, order, plugin_type='readme', plugin_link="
4242
print('Error: plugins.json not found.')
4343
sys.exit(1)
4444
plugin_info = json.load(open('plugins.json'))
45-
plugins = [plugin['plugin'] for plugin in plugin_info]
45+
plugins = [plugin['name'] for plugin in plugin_info]
4646
# wiki_plugins = ['SIFT', 'get_chanlocs', 'NFT', 'EEG-BIDS', 'nsgportal', 'clean_rawdata', 'amica', 'LIMO']
4747
# readme_plugins = ['ARfitStudio', 'roiconnect', 'trimOutlier', 'PACT', 'groupSIFT', 'nwbio', 'ICLabel', 'dipfit', 'eegstats', 'PowPowCAT', 'PACTools', 'zapline-plus', 'fMRIb', 'relica', 'std_dipoleDensity', 'imat', 'viewprops', 'cleanline','NIMA', 'firfilt']
4848
# ordering = ['ICLabel', 'dipfit', 'EEG-BIDS', 'roiconnect', 'amica', 'cleanline', 'clean_rawdata', 'SIFT', 'zapline-plus', 'eegstats', 'trimOutlier', 'fMRIb', 'imat', 'nwbio', 'NIMA', 'PACT', 'NFT', 'PACTools', 'ARfitStudio', 'PowPowCAT', 'relica', 'std_dipoleDensity', 'viewprops', 'firfilt', 'groupSIFT', 'get_chanlocs', 'nsgportal']
4949

5050
if len(sys.argv) == 1:
5151
for plugin in plugin_info:
52-
update_repo(plugin['plugin'], plugin['name'], plugins.index(plugin['plugin']), plugin['type'], plugin['link'])
52+
update_repo(plugin['name'], plugin['name'], plugins.index(plugin['name']), plugin['type'], plugin['link'])
5353
elif len(sys.argv) == 2:
5454
plugin_name = sys.argv[1]
5555
if plugin_name not in plugins:
5656
print(f"Plugin {plugin_name} not found.")
5757
sys.exit(1)
5858
plugin = plugin_info[plugins.index(plugin_name)]
59-
update_repo(plugin['plugin'], plugin['name'], plugins.index(plugin['plugin']), plugin['type'], plugin['link'])
59+
update_repo(plugin['name'], plugin['name'], plugins.index(plugin['name']), plugin['type'], plugin['link'])
6060
else:
6161
print('Usage: python update_plugins.py <plugin_name>')
6262
sys.exit(1)

plugins/limo/1.-Preprocessing.md

+123
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
---
2+
layout: default
3+
parent: LIMO
4+
grand_parent: Plugins
5+
6+
title: Preprocessing
7+
long_title: Preprocessing
8+
render_with_liquid: false
9+
nav_order: 3
10+
---
11+
# Data for the tutorial
12+
13+
This tutorial aims at teaching how to use [LIMO MEEG](https://raw.githubusercontent.com/LIMO-EEG-Toolbox/limo_tools/wiki), in conjunction with [EEGLAB STUDY](https://sccn.ucsd.edu/wiki/Chapter_02:_STUDY_Creation). To get started, you must be familiar with [EEGLAB](https://sccn.ucsd.edu/eeglab/index.php). Also, make sure LIMO tools subdirectories are listed in the Matlab path.
14+
15+
The data used in this tutorial come from [Wakeman and Henson (2015)](https://www.nature.com/articles/sdata20151). In this experiment, MEG-EEG data were collected while subjects viewed famous, unfamiliar and scrambled faces. Each image was repeated twice (immediately in 50% of cases and 5–10 stimuli apart for the other 50%) and subjects pressed one of two keys with their left or right index finger indicating how symmetric they regarded each image relative to the average.
16+
17+
The data were prepared (i.e. EEG extracted, timing corrected, electrode position re-oriented, event recorded) by Dung Truong, Ramon Martinez & Arnaud Delorme and can be downloaded from [OpenNeuro](https://openneuro.org/datasets/ds002718/versions/1.0.2).
18+
19+
# Data pre-processing pipeline script
20+
21+
The data are organized according to the [Brain Imaging Data Structure](https://bids.neuroimaging.io/), in particular the [EEG BIDS extension](https://www.nature.com/articles/s41597-019-0104-8). It is worthwhile spending a bit of time looking at how files are organized and named, as we will follow this convention throughout. EEGLAB also has dedicated [BIDS tools called bids-matlab-tools](https://raw.githubusercontent.com/sccn/bids-matlab-tools) to create files, export and import BIDS dataset. This is available using the EEGLAB plugin manager and must be installed before running the code below.
22+
23+
Once you have downloaded the data, you can run the code below - can copy and paste to a file (changing Xs with your specific path) to get descent pre-processed data. Alternatively download the [code located here](https://raw.githubusercontent.com/LIMO-EEG-Toolbox/limo_meeg/master/resources/code/henson_wakeman_preprocess.m). Be patient, this step will take several hours.
24+
25+
```matlab
26+
% start EEGLAB
27+
clear variables
28+
[ALLEEG, EEG, CURRENTSET, ALLCOM] = eeglab;
29+
30+
% import BIDS
31+
bidsfolder = 'F:\WakemanHenson_Faces\eeg';
32+
[STUDY, ALLEEG] = pop_importbids(bidsfolder, 'bidsevent','on','bidschanloc','on', ...
33+
'eventtype', 'trial_type', 'outputdir' ,fullfile(bidsfolder,'newderivatives'), 'studyName','Face_detection');
34+
ALLEEG = pop_select( ALLEEG, 'nochannel',{'061','062','063','064'});
35+
CURRENTSTUDY = 1; EEG = ALLEEG; CURRENTSET = 1:length(EEG);
36+
37+
% reorient if using previous version of the data
38+
EEG = pop_chanedit(EEG,'nosedir','+Y');
39+
40+
% Clean data - just the bad channels
41+
EEG = pop_clean_rawdata( EEG,'FlatlineCriterion',5,'ChannelCriterion',0.8,...
42+
'LineNoiseCriterion',4,'Highpass',[0.25 0.75] ,...
43+
'BurstCriterion','off','WindowCriterion','off','BurstRejection','off',...
44+
'Distance','Euclidian','WindowCriterionTolerances','off' );
45+
46+
% Rereference using average reference
47+
EEG = pop_reref( EEG,[],'interpchan',[]);
48+
49+
% Run ICA and flag artifactual components using IClabel
50+
for s=1:size(EEG,2)
51+
EEG(s) = pop_runica(EEG(s), 'icatype','runica','concatcond','on','options',{'pca',EEG(s).nbchan-1});
52+
EEG(s) = pop_iclabel(EEG(s),'default');
53+
EEG(s) = pop_icflag(EEG(s),[NaN NaN;0.8 1;0.8 1;NaN NaN;NaN NaN;NaN NaN;NaN NaN]);
54+
EEG(s) = pop_subcomp(EEG(s), find(EEG(s).reject.gcompreject), 0);
55+
end
56+
57+
% clear data using ASR - just the bad epochs
58+
EEG = pop_clean_rawdata( EEG,'FlatlineCriterion','off','ChannelCriterion','off',...
59+
'LineNoiseCriterion','off','Highpass','off','BurstCriterion',20,...
60+
'WindowCriterion',0.25,'BurstRejection','on','Distance','Euclidian',...
61+
'WindowCriterionTolerances',[-Inf 7] );
62+
63+
% Extract data epochs (no baseline removed)
64+
EEG = pop_epoch( EEG,{'famous_new','famous_second_early','famous_second_late','scrambled_new','scrambled_second_early','scrambled_second_late','unfamiliar_new','unfamiliar_second_early','unfamiliar_second_late'},...
65+
[-0.5 1] ,'epochinfo','yes');
66+
EEG = eeg_checkset(EEG);
67+
EEG = pop_saveset(EEG, 'savemode', 'resave');
68+
ALLEEG = EEG;
69+
70+
% Create study design
71+
STUDY = std_checkset(STUDY, ALLEEG);
72+
STUDY = std_makedesign(STUDY, EEG, 1, 'name','STUDY.FaceRepetition','delfiles','off','defaultdesign','off','variable1','type','values1',{});
73+
eeglab redraw
74+
```
75+
76+
# Loading the pre-processed EEGLAB STUDY
77+
78+
After data preprocessing, data should be clean, epochs marked, and a STUDY created. Load the study from the EEGLAB menu (File --> Load existing study - [figure 1](https://raw.githubusercontent.com/LIMO-EEG-Toolbox/limo_meeg/master/resources/images/1.jpg)) and check that all the data are there (Study --> edit study info - [figure 2](https://raw.githubusercontent.com/LIMO-EEG-Toolbox/limo_meeg/master/resources/images/1.jpg)). In total there are 18 subjects, named sub-002 to sub-019.
79+
80+
![Figure 1. Loading EEGLAB STUDY](https://raw.githubusercontent.com/LIMO-EEG-Toolbox/limo_meeg/master/resources/images/1.jpg)
81+
_Figure 1. Loading EEGLAB STUDY_
82+
83+
![Figure 2. Wakeman_Henson STUDY](https://raw.githubusercontent.com/LIMO-EEG-Toolbox/limo_meeg/master/resources/images/2.jpg)
84+
_Figure 2. Wakeman_Henson STUDY_
85+
86+
# Precompute STUDY measures
87+
88+
LIMO MEEG models data using a hierarchical approach with a general linear model at the subject level and then testing, at the group level, parameters obtained with robust methods. You can think of it as generating averages per condition at the subject level and do statistics on those averages at the group level. The difference (and advantage) is that subject-specific baselines are removed, among trial variance accounted for, and bad subjects are accounted for. For more details see the [San Diego 2016 lecture as pdf](https://raw.githubusercontent.com/LIMO-EEG-Toolbox/limo_meeg/master/resources/2016_SanDiego_StatisticalanalysisofEEGdata.pdf) and/or on [YouTube](https://youtu.be/KfnN51frbuI).
89+
90+
## Step 1 – precompute single-trial measure(s)
91+
92+
No matter the design, using LIMO MEEG means we need single trials to obtain condition related parameters for each subject. EEGLAB will export all trial data measures and, depending on the design, will pass on only relevant ones to LIMO EEG (even if this is only the mean as for comparing spectra between groups).
93+
94+
Create ERPs and/or Spectra and/or ERSP (Study --> Precompute channel measures – [figure 3]((https://raw.githubusercontent.com/LIMO-EEG-Toolbox/limo_meeg/master/resources/images/3.jpg))). Note you could set limits to your epoch at this stage (using ‘timelim’ and ‘freqlim’) or limit the statistical analysis at the next stage (which is what we will do). For ERPs, baseline correction can be added using `[-200 0]`. Note that ERSP can take a long time. You can start with ERP and Spectra only (of course if you do that, you will not be able to use LIMO on ERSP in the next sections).
95+
96+
![Figure 3. Precompute channel measures](https://raw.githubusercontent.com/LIMO-EEG-Toolbox/limo_meeg/master/resources/images/3.jpg)
97+
_Figure 3. Precompute channel measures_
98+
99+
All single trials (erp, spectrum, ersp) can also be generated in command line using:
100+
101+
```matlab
102+
% Precompute ERP and Spectrum measures
103+
[STUDY, EEG] = std_precomp(STUDY, EEG, {}, 'savetrials','on','interp','on','recompute','on',...
104+
'erp','on','erpparams', {'rmbase' [-200 0]}, 'spec','on',...
105+
'ersp','on','itc','on', 'specparams',{'specmode','fft','logtrials','off'});
106+
```
107+
108+
## Step 2 – create your design
109+
110+
From a set of available conditions and trial information, there are many options available. In this tutorial, we’ll review the most common ones. For example, we can select the independent variable "face_type" that takes 3 categorical values (famous, scambled and unfamiliar faces). We will start by using this simple design and create more complex ones as we go along the tutorial (Study --> Select/Edit study designs(s) – [figure 4](https://raw.githubusercontent.com/LIMO-EEG-Toolbox/limo_meeg/master/resources/images/4.jpg)).
111+
112+
![Figure 4. Select/Edit study design(s)](https://raw.githubusercontent.com/LIMO-EEG-Toolbox/limo_meeg/master/resources/images/4.jpg)
113+
_Figure 4. Select/Edit study design(s)_
114+
115+
Every design can be generated from here, and the following sections will show you each time a different design. For now, let’s have a look at the ‘List of factors’ ([figure 5](https://raw.githubusercontent.com/LIMO-EEG-Toolbox/limo_meeg/master/resources/images/5.jpg)). This lists all categorical variables from which we can make a design (this list appears if you select "list factors" for the independent variable). This list of factors is the list LIMO will use at the first level. In the next section, we will do a 1-way ANOVA testing the effect of familiarity (all famous vs. all unfamiliar vs. all scrambled faces).
116+
117+
![Figure 5. List of categorical variables](https://raw.githubusercontent.com/LIMO-EEG-Toolbox/limo_meeg/master/resources/images/5.jpg)
118+
_Figure 5. List of categorical variables_
119+
120+
# Note on using LIMO default and sampling rate
121+
122+
By default, LIMO EEG uses a Weighted least Squares approach for each trial, which means you should aim to have more trials than time frames (for ERP and ERSP) or frequency frames (for Spectrum), while not mandatory. The data here are at 250Hz which is fine.
123+
+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
---
2+
layout: default
3+
parent: LIMO
4+
grand_parent: Plugins
5+
6+
title: Two sample t-tests
7+
long_title: Two sample t-tests
8+
render_with_liquid: false
9+
nav_order: 14
10+
---
11+
Given the (non-significant) group effect observed in the between subjects’ ANOVA with repeated factor, we can also do a simple two samples t-tests between groups 1 and 2. From the 2nd level GUI ([figure 9](https://raw.githubusercontent.com/LIMO-EEG-Toolbox/limo_meeg/master/resources/images/9.jpg)), click on two samples t-test, and select the beta files for group 1 and group 2. Let’s select parameter 1, i.e. famous faces ([figure 38](https://raw.githubusercontent.com/LIMO-EEG-Toolbox/limo_meeg/master/resources/images/38.jpg)). Parameter question dialogue is repeated because you could for instance compare groups from 2 different studies, i.e. with different 1st level designs.
12+
13+
![Figure 38. Regression](https://raw.githubusercontent.com/LIMO-EEG-Toolbox/limo_meeg/master/resources/images/38.jpg)
14+
_Figure 38. Selection of files for 2 samples t-test._
15+
16+
These steps can be executed in command line as:
17+
```matlab
18+
chanlocs = XXX\derivatives\limo_gp_level_chanlocs.mat';
19+
Files{1} = ‘XXX\LIMO_Face_detection\Beta_files_Gp1_Faces_GLM_Channels_Frequency_WLS.txt';
20+
Files{2} = 'XXX\LIMO_Face_detection\Beta_files_Gp2_Faces_GLM_Channels_Frequency_WLS.txt';
21+
LIMOPath = limo_random_select('two-samples t-test',chanlocs,'LIMOfiles',Files,...
22+
'analysis_type','Full scalp analysis', 'type','Channels','parameter',[1;1],'nboot',1000,'tfce',0);
23+
```
24+
25+
You should obtain results display on figure 39 for [ERP](https://raw.githubusercontent.com/LIMO-EEG-Toolbox/limo_meeg/master/resources/images/39a.jpg), [Spectrum](https://raw.githubusercontent.com/LIMO-EEG-Toolbox/limo_meeg/master/resources/images/39b.jpg) and [ERSP](https://raw.githubusercontent.com/LIMO-EEG-Toolbox/limo_meeg/master/resources/images/39c.jpg).
26+
27+
![Figure 39. Regression ERP](https://raw.githubusercontent.com/LIMO-EEG-Toolbox/limo_meeg/master/resources/images/39a.jpg)
28+
![Figure 39. Regression Spectrum](https://raw.githubusercontent.com/LIMO-EEG-Toolbox/limo_meeg/master/resources/images/39b.jpg)
29+
![Figure 39. Regression ERSP](https://raw.githubusercontent.com/LIMO-EEG-Toolbox/limo_meeg/master/resources/images/39c.jpg)
30+
_Figure 39. Results of the 2 samples t-test young vs old for famous faces._
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
---
2+
layout: default
3+
parent: LIMO
4+
grand_parent: Plugins
5+
6+
title: Regression among subjects
7+
long_title: Regression among subjects
8+
render_with_liquid: false
9+
nav_order: 16
10+
---
11+
In the [between subjects’ ANOVA with repeated factor](https://raw.githubusercontent.com/LIMO-EEG-Toolbox/limo_meeg/wiki/Between-subjects%E2%80%99-ANOVAs-with-repeated-factors), we artificially split subjects into young and old subjects. Such post-hoc splitting is not recommended and typically create spurious results. Instead, we could test how much age influences face perception. For this, we will use the contrast faces vs scrambled computed previously in the [one-sample t-test](https://raw.githubusercontent.com/LIMO-EEG-Toolbox/limo_meeg/wiki/5.-One-sample-t-test-(contrasting-Full-Faces-vs-Scrambled-Faces-at-the-subject-level)).
12+
13+
You can either create the age variable from the participants.tsv file, or we can load values from STUDY. Don’t worry about the missing values, LIMO will simply remove those subjects for which there are no values.
14+
15+
In command window type:
16+
```matlab
17+
age_regressor = cell2mat(arrayfun(@(x) x.age,STUDY.datasetinfo,'UniformOutput',false))';
18+
save('age_regressor.mat','age_regressor')
19+
```
20+
21+
From the second level GUI ([figure 9](https://raw.githubusercontent.com/LIMO-EEG-Toolbox/limo_meeg/master/resources/images/9.jpg)), select regression, full scalp analysis and pick-up the contrast faces>scrambled computed for one-sample t-test (should be con4), finally select the age_regressor.mat we just created ([figure 40](https://raw.githubusercontent.com/LIMO-EEG-Toolbox/limo_meeg/master/resources/images/40.jpg)). WARNING: it is suggested to set the bootstrap to 0 as this is very long to compute since we use here an Iterative Reweighted Least Squares (IRLS) solution that weights subjects for each electrode and time frame.
22+
23+
![Figure 40. Regression](https://raw.githubusercontent.com/LIMO-EEG-Toolbox/limo_meeg/master/resources/images/40.jpg)
24+
_Figure 40. Create a 2nd level regression analysis with age._
25+
26+
These steps can be executed in command line as:
27+
```matlab
28+
chanlocs = XXX\derivatives\limo_gp_level_chanlocs.mat';
29+
LIMOPath = limo_random_select('regression',chanlocs,'LIMOfiles',...
30+
'XXX\LIMO_Face_detection\con4_files_FaceRepAll_GLM_Channels_Time_WLS.txt', ...
31+
'analysis type','Full scalp analysis', type','Channels','nboot',0,'tfce',0,'regressor',...
32+
'XXX\LIMO_Face_detection\2nd_level\regression\age_regressor.mat',...
33+
'zscore','Yes','skip design check','Yes')
34+
```
35+
36+
Results can be appreciated using ‘image all’ and ‘course plot’. Here, because we have a continuous variable we can visualize how subjects data vary along with the variable of interest (figure 41 for [ERP](https://raw.githubusercontent.com/LIMO-EEG-Toolbox/limo_meeg/master/resources/images/41a.jpg), [Spectrum](https://raw.githubusercontent.com/LIMO-EEG-Toolbox/limo_meeg/master/resources/images/41b.jpg), [ERSP](https://raw.githubusercontent.com/LIMO-EEG-Toolbox/limo_meeg/master/resources/images/41c.jpg)). You can either look at the raw data, modelled (best option here) or adjusted.
37+
38+
![Figure 41. Regression ERP](https://raw.githubusercontent.com/LIMO-EEG-Toolbox/limo_meeg/master/resources/images/41a.jpg)
39+
![Figure 41. Regression Spectrum](https://raw.githubusercontent.com/LIMO-EEG-Toolbox/limo_meeg/master/resources/images/41b.jpg)
40+
![Figure 41. Regression ERSP](https://raw.githubusercontent.com/LIMO-EEG-Toolbox/limo_meeg/master/resources/images/41c.jpg)
41+
_Figure 41. Results of the regression analysis of age on the contrast faces>scrambled._
42+
43+
44+

0 commit comments

Comments
 (0)