Skip to content

Commit bf09adf

Browse files
Merge pull request #7 from CognitiveNeuroLab/final_code
Final code
2 parents 44870aa + ae3c813 commit bf09adf

13 files changed

+1396
-270
lines changed

2023 paper/A_bdf_merge_sets.m

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
% Restingstate pipepline (2021)
2+
% Final version of SRC code 12/6/2021
3+
% Merging script to create .set file
4+
clear all
5+
%subject_list = {'2202' '2204' '2207' '2212' '2216' '2222' '2229' '2231' '2243' '2256' '2257' '2261' '2267' '2270' '2274' '2281' '2284' '2286' '2292' '2295'};
6+
%subject_list = {'7003' '7007' '7019' '7025' '7046' '7049' '7051' '7054' '7058' '7059' '7061' '7064' '7065' '7073' '7075' '7078' '7089' '7092' '7094' '7123' '7556' '7808'};
7+
subject_list = {'10293' '10561' '10562' '10581' '10616' '10748' '10822' '10858' '10935' '12004' '12010' '12139' '12177' '12188' '12197' '12203' '12206' '12215' '12272' '12413' '12415' '12449' '12482' '12512' '12588' '12632' '12648' '12651' '12707' '12727' '12739' '12746' '12750' '12755' '12770' '12815' '12852' '12870'};
8+
filename = 'restingstate'; % if your bdf file has a name besides the ID of the participant (e.g. oddball_paradigm)
9+
home_path = '\\data.einsteinmed.org\users\Filip Ana Douwe\Resting state data\'; %place data is (something like 'C:\data\')
10+
blocks = 1; % the amount of BDF files. if different participant have different amounts of blocks, run those participant separate
11+
for s = 1:length(subject_list)
12+
clear ALLEEG
13+
eeglab
14+
close all
15+
data_path = [home_path subject_list{s} '\'];
16+
disp([data_path subject_list{s} '_' filename '.bdf'])
17+
18+
if blocks == 1
19+
%if participants have only 1 block, load only this one file
20+
EEG = pop_biosig([data_path subject_list{s} '_' filename '.bdf']);
21+
else
22+
for bdf_bl = 1:blocks
23+
%if participants have more than one block, load the blocks in a row
24+
%your files need to have the same name, except for a increasing number at the end (e.g. id#_file_1.bdf id#_file_2)
25+
EEG = pop_biosig([data_path subject_list{s} '_' filename '_' num2str(bdf_bl) '.bdf']);
26+
[ALLEEG, ~] = eeg_store(ALLEEG, EEG, CURRENTSET);
27+
end
28+
%since there are more than 1 files, they need to be merged to one big .set file.
29+
EEG = pop_mergeset( ALLEEG, 1:blocks, 0);
30+
end
31+
[ALLEEG EEG CURRENTSET] = pop_newset(ALLEEG, EEG, 0,'setname', [subject_list{s} ' restingstate paradigm'],'gui','off'); %adds a name to the internal .set file
32+
%save the bdf as a .set file
33+
mkdir( ['D:\restingstate\data\' subject_list{s}])
34+
EEG = pop_saveset( EEG, 'filename',[subject_list{s} '.set'],'filepath',['D:\restingstate\data\' subject_list{s}]);
35+
end
36+
+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
% Restingstate pipepline (2021)
2+
% Final version of SRC code 12/6/2021
3+
% Merging script to create .set file for files that were collected without
4+
% using paradigm (particpant was told to close eyes or stare at the center
5+
% of a black screen)
6+
% ------------------------------------------------
7+
clear variables
8+
subject_list = {'2260' '2201'};
9+
%subject_list = {'1101' '1164' '1808' '1852' '1855' '11014' '11094' '11151' '11170' '11275' '11349' '11516' '11558' '11583' '11647' '11729' '11735' '11768' '11783' '11820' '11912'};
10+
filename = 'restingstate'; % if your bdf file has a name besides the ID of the participant (e.g. oddball_paradigm)
11+
home_path = '\\data.einsteinmed.org\users\Filip Ana Douwe\Resting state data\'; %place data is (something like 'C:\data\')
12+
wrongconfig = zeros(1,length(subject_list)); %there are 160channel files that have a wrong config file, this is to save them
13+
for s = 1:length(subject_list)
14+
clear ALLEEG
15+
eeglab
16+
close all
17+
data_path = [home_path subject_list{s} '\'];
18+
disp([data_path subject_list{s} '.bdf'])
19+
20+
%loading file 1, adding triggers
21+
EEG = pop_biosig([data_path subject_list{s} '_open.bdf']);
22+
first = 1; %where the trigger will happen
23+
second = 10;
24+
TRIG = [first 0; second 50]; %script doesn't like only one trigger so adding 2 (first one can be ignored)
25+
%%%% Import All events back into the EEG data structure
26+
EEG = pop_importevent( EEG, 'event', TRIG, 'fields',{'latency','type'},'timeunit',NaN,'append','no');
27+
EEG = pop_editeventvals(EEG,'delete',1); %deleting the extra event
28+
EEG = eeg_checkset(EEG);
29+
[ALLEEG EEG] = eeg_store(ALLEEG, EEG, CURRENTSET);
30+
%loading file 2, adding triggers
31+
EEG = pop_biosig([data_path subject_list{s} '_closed.bdf']);
32+
first = 1; %where the trigger will happen
33+
second = 10;
34+
TRIG = [first 0; second 51]; %script doesn't like only one trigger so adding 2 (first one can be ignored)
35+
%%%% Import All events back into the EEG data structure
36+
EEG = pop_importevent( EEG, 'event', TRIG, 'fields',{'latency','type'},'timeunit',NaN,'append','no');
37+
EEG = pop_editeventvals(EEG,'delete',1); %deleting the extra event
38+
EEG = eeg_checkset(EEG);
39+
[ALLEEG EEG] = eeg_store(ALLEEG, EEG, CURRENTSET);
40+
EEG = pop_mergeset( ALLEEG, 1:2, 0);%merging into one
41+
%merging files
42+
[ALLEEG EEG CURRENTSET] = pop_newset(ALLEEG, EEG, 0,'setname', [subject_list{s} ' restingstate non-paradigm'],'gui','off'); %adds a name to the internal .set file
43+
%some files have been collected with a wrong config file, need to rename the first 64 channels to fit the 160 channel names.
44+
if strcmp(EEG.chanlocs(1).labels,'Fp1') && strcmp(EEG.chanlocs(65).labels,'C1')
45+
correct_160_chan={'A1' 'A2' 'A3' 'A4' 'A5' 'A6' 'A7' 'A8' 'A9' 'A10' 'A11' 'A12' 'A13' 'A14' 'A15' 'A16' 'A17' 'A18' 'A19' 'A20' 'A21' 'A22' 'A23' 'A24' 'A25' 'A26' 'A27' 'A28' 'A29' 'A30' 'A31' 'A32' 'B1' 'B2' 'B3' 'B4' 'B5' 'B6' 'B7' 'B8' 'B9' 'B10' 'B11' 'B12' 'B13' 'B14' 'B15' 'B16' 'B17' 'B18' 'B19' 'B20' 'B21' 'B22' 'B23' 'B24' 'B25' 'B26' 'B27' 'B28' 'B29' 'B30' 'B31' 'B32'};
46+
for n=1:64
47+
EEG.chanlocs(n).labels = correct_160_chan{n};
48+
wrongconfig(:,s)=string(subject_list(s));
49+
end
50+
disp('fixed configuration')
51+
if strcmp(subject_list{s},'10399') %collected data with 160chn config but only data in 64 ch
52+
EEG = pop_select( EEG, 'channel',{'A1','A2','A3','A4','A5','A6','A7','A8','A9','A10','A11','A12','A13','A14','A15','A16','A17','A18','A19','A20','A21','A22','A23','A24','A25','A26','A27','A28','A29','A30','A31','A32','B1','B2','B3','B4','B5','B6','B7','B8','B9','B10','B11','B12','B13','B14','B15','B16','B17','B18','B19','B20','B21','B22','B23','B24','B25','B26','B27','B28','B29','B30','B31','B32'});
53+
correct_64_chan={'Fp1' 'AF7' 'AF3' 'F1' 'F3' 'F5' 'F7' 'FT7' 'FC5' 'FC3' 'FC1' 'C1' 'C3' 'C5' 'T7' 'TP7' 'CP5' 'CP3' 'CP1' 'P1' 'P3' 'P5' 'P7' 'P9' 'PO7' 'PO3' 'O1' 'Iz' 'Oz' 'POz' 'Pz' 'CPz' 'Fpz' 'Fp2' 'AF8' 'AF4' 'AFz' 'Fz' 'F2' 'F4' 'F6' 'F8' 'FT8' 'FC6' 'FC4' 'FC2' 'FCz' 'Cz' 'C2' 'C4' 'C6' 'T8' 'TP8' 'CP6' 'CP4' 'CP2' 'P2' 'P4' 'P6' 'P8' 'P10' 'PO8' 'PO4' 'O2'};
54+
for n=1:64
55+
EEG.chanlocs(n).labels = correct_64_chan{n};
56+
wrongconfig(:,s)=string(subject_list(s));
57+
end
58+
end
59+
EEG = eeg_checkset(EEG);
60+
end
61+
%save the bdf as a .set file
62+
mkdir( ['D:\restingstate\data\' subject_list{s}])
63+
EEG = pop_saveset( EEG, 'filename',[subject_list{s} '.set'],'filepath',['D:\restingstate\data\' subject_list{s}]);
64+
end
65+
save([home_path 'participants_with_wrong_config'], 'wrongconfig');
66+

2023 paper/B_preprocess1.m

+116
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
% Restingstate pipepline (2021)
2+
% Final version of SRC code 12/6/2021
3+
% fixing channel names for people with 160 config file with only 64 channels
4+
% downsample
5+
% exclude externals
6+
% 1hz and 50hz filter
7+
% channel info
8+
% exclude channels
9+
% ------------------------------------------------
10+
clear variables
11+
eeglab
12+
group = { 'Control' '22q' 'schiz'};%
13+
lowpass_filter_hz=50; %50hz filter
14+
highpass_filter_hz=1; %1hz filter
15+
script_location= 'D:\restingstate\scripts\';
16+
17+
for g=1:length(group)
18+
if strcmp(group{g},'22q')
19+
subject_list = {'2201' '2202' '2204' '2207' '2212' '2216' '2222' '2229' '2231' '2243' '2256' '2257' '2260' '2261' '2267' '2270' '2274' '2281' '2284' '2286' '2292' '2295'};
20+
home_path = 'D:\restingstate\data\';
21+
elseif strcmp(group{g},'schiz')
22+
subject_list = {'7003' '7007' '7019' '7025' '7046' '7049' '7051' '7054' '7058' '7059' '7061' '7064' '7065' '7073' '7075' '7078' '7089' '7092' '7094' '7123' '7556' '7808'};
23+
home_path = 'D:\restingstate\data\';
24+
elseif strcmp(group{g},'Control')
25+
subject_list = {'10293' '10561' '10562' '10581' '10616' '10748' '10822' '10858' '10935' '12004' '12010' '12139' '12177' '12188' '12197' '12203' '12206' '12215' '12272' '12413' '12415' '12449' '12482' '12512' '12588' '12632' '12648' '12651' '12707' '12727' '12739' '12746' '12750' '12755' '12770' '12815' '12852' '12870'};
26+
home_path = 'D:\restingstate\data\';
27+
end
28+
deleted_channels=zeros(length(subject_list),2);
29+
deleted_data=zeros(length(subject_list),2);
30+
wrongconfig_type2 = zeros(1,length(subject_list));
31+
% Loop through all subjects
32+
for s=1:length(subject_list)
33+
fprintf('\n******\nProcessing subject %s\n******\n\n', subject_list{s});
34+
data_path = [home_path subject_list{s} '\\'];
35+
% Load original dataset (created by previous script)
36+
fprintf('\n\n\n**** %s: Loading dataset ****\n\n\n', subject_list{s});
37+
EEG = pop_loadset('filename', [subject_list{s} '.set'], 'filepath', data_path);
38+
%the following people have had a wrong config file that saved 160 channels even though only 64 have data
39+
if strcmp(subject_list{s},'1101' ) || strcmp(subject_list{s},'11583')|| strcmp(subject_list{s},'10501')
40+
EEG = pop_select( EEG, 'channel',{'A1' 'A2' 'A3' 'A4' 'A5' 'A6' 'A7' 'A8' 'A9' 'A10' 'A11' 'A12' 'A13' 'A14' 'A15' 'A16' 'A17' 'A18' 'A19' 'A20' 'A21' 'A22' 'A23' 'A24' 'A25' 'A26' 'A27' 'A28' 'A29' 'A30' 'A31' 'A32' 'B1' 'B2' 'B3' 'B4' 'B5' 'B6' 'B7' 'B8' 'B9' 'B10' 'B11' 'B12' 'B13' 'B14' 'B15' 'B16' 'B17' 'B18' 'B19' 'B20' 'B21' 'B22' 'B23' 'B24' 'B25' 'B26' 'B27' 'B28' 'B29' 'B30' 'B31' 'B32'});
41+
correct_64_chan={'Fp1' 'AF7' 'AF3' 'F1' 'F3' 'F5' 'F7' 'FT7' 'FC5' 'FC3' 'FC1' 'C1' 'C3' 'C5' 'T7' 'TP7' 'CP5' 'CP3' 'CP1' 'P1' 'P3' 'P5' 'P7' 'P9' 'PO7' 'PO3' 'O1' 'Iz' 'Oz' 'POz' 'Pz' 'CPz' 'Fpz' 'Fp2' 'AF8' 'AF4' 'AFz' 'Fz' 'F2' 'F4' 'F6' 'F8' 'FT8' 'FC6' 'FC4' 'FC2' 'FCz' 'Cz' 'C2' 'C4' 'C6' 'T8' 'TP8' 'CP6' 'CP4' 'CP2' 'P2' 'P4' 'P6' 'P8' 'P10' 'PO8' 'PO4' 'O2'};
42+
for n=1:64
43+
EEG.chanlocs(n).labels = correct_64_chan{n};
44+
wrongconfig_type2(:,s)=string(subject_list(s));
45+
end
46+
disp('fixed configuration')
47+
EEG = eeg_checkset(EEG);
48+
end
49+
if strcmp(subject_list{s},'12851') %this file was the only mobi BDF file and needs not used channels deleted
50+
EEG = pop_select( EEG, 'nochannel',{'F1' 'F2' 'F3' 'F4' 'F5' 'F6' 'F7' 'F8' 'F9' 'F10' 'F11' 'F12' 'F13' 'F14' 'F15' 'F16' 'F17' 'F18' 'F19' 'F20' 'F21' 'F22' 'F23' 'F24' 'F25' 'F26' 'F27' 'F28' 'F29' 'F30' 'F31' 'F32' 'G1' 'G2' 'G3' 'G4' 'G5' 'G6' 'G7' 'G8' 'G9' 'G10' 'G11' 'G12' 'G13' 'G14' 'G15' 'G16' 'G17' 'G18' 'G19' 'G20' 'G21' 'G22' 'G23' 'G24' 'G25' 'G26' 'G27' 'G28' 'G29' 'G30' 'G31' 'G32' 'H1' 'H2' 'H3' 'H4' 'H5' 'H6' 'H7' 'H8' 'H9' 'H10' 'H11' 'H12' 'H13' 'H14' 'H15' 'H16' 'H17' 'H18' 'H19' 'H20' 'H21' 'H22' 'H23' 'H24' 'H25' 'H26' 'H27' 'H28' 'H29' 'H30' 'H31' 'H32' 'EXG1' 'EXG2' 'EXG3' 'EXG4' 'EXG5' 'EXG6' 'EXG7' 'EXG8' 'GSR1' 'GSR2' 'Erg1' 'Erg2' 'Resp' 'Plet' 'Temp'});
51+
end
52+
EEG = eeg_checkset( EEG );
53+
%downsample
54+
EEG = pop_resample( EEG, 256); %downsample to 256hz
55+
EEG = eeg_checkset( EEG );
56+
%deleting externals
57+
EEG = pop_select( EEG,'nochannel',{'EXG1','EXG2','EXG3','EXG4','EXG5','EXG6','EXG7','EXG8' 'GSR1' 'GSR2' 'Erg1' 'Erg2' 'Resp' 'Plet' 'Temp'});
58+
EEG = pop_saveset( EEG, 'filename',[subject_list{s} '_exext.set'],'filepath', data_path);
59+
%filtering
60+
EEG.filter=table(lowpass_filter_hz,highpass_filter_hz); %adding it to subject EEG file
61+
EEG = pop_eegfiltnew(EEG, 'locutoff',highpass_filter_hz);
62+
EEG = eeg_checkset( EEG );
63+
EEG = pop_eegfiltnew(EEG, 'hicutoff',lowpass_filter_hz);
64+
close all
65+
EEG = eeg_checkset( EEG );
66+
EEG = pop_saveset( EEG, 'filename',[subject_list{s} '_downft.set'],'filepath', data_path);
67+
EEG = pop_editset(EEG, 'chanlocs', [script_location 'Functions and files\BioSemi64.sfp']); %need to first load any sort of sfp file with the correct channels (the locations will be overwritten to the correct ones later)
68+
%adding channel location
69+
EEG=pop_chanedit(EEG, 'lookup',[fileparts(which('eeglab')) '\plugins\dipfit\standard_BESA\standard-10-5-cap385.elp']); %make sure you put here the location of this file for your computer
70+
71+
EEG = pop_saveset( EEG, 'filename',[subject_list{s} '_info.set'],'filepath', data_path);
72+
old_n_chan = EEG.nbchan;
73+
old_samples=EEG.pnts;
74+
%old way, only channel rejection - used for Aging and ASD:
75+
%EEG = clean_artifacts(EEG, 'FlatlineCriterion',5,'ChannelCriterion',0.8,'LineNoiseCriterion',4,'Highpass','off','BurstCriterion','off','WindowCriterion','off','BurstRejection','on','Distance','Euclidian');
76+
%new way, also bad data (bursts) rejection:
77+
% the only thing to double check is if it will still reject eye
78+
% components in ICA or if these are pre-deleted now (which they shouldn't)
79+
%EEG = pop_clean_rawdata(EEG,
80+
%'FlatlineCriterion',5,'ChannelCriterion',0.8,'LineNoiseCriterion',4,'Highpass','off','BurstCriterion','off','WindowCriterion','off','BurstRejection','off','Distance','Euclidian');%doesn't delete bad periods
81+
%first at 'BurstCriterion',20, this caused too much data to be
82+
%deleted, second time at 'BurstCriterion',50, this caused too few data to be
83+
EEG = pop_clean_rawdata(EEG, 'FlatlineCriterion',5,'ChannelCriterion',0.8,'LineNoiseCriterion',4,'Highpass','off','BurstCriterion',35,'WindowCriterion','off','BurstRejection','on','Distance','Euclidian'); % deletes bad chns and bad periods
84+
EEG.deleteddata_wboundries=100-EEG.pnts/old_samples*100;
85+
new_n_chan = EEG.nbchan;
86+
deleted_sample=EEG.pnts;
87+
if ~isempty(EEG.event) %at least 1 participant with no events
88+
%adding one boundary at the end to stop issues, will delete later
89+
for i=1:length(EEG.event)
90+
EEG.event(i).time=EEG.event(i).latency/EEG.srate
91+
end
92+
EEG.event(length(EEG.event)+1)=EEG.event(length(EEG.event)); EEG.event(length(EEG.event)).type='temp';% EEG.event(length(EEG.event)).latency=EEG.event(length(EEG.event)).latency+100;EEG.event(length(EEG.event)).duration=EEG.event(length(EEG.event)).duration+100;
93+
94+
for i = length(EEG.event)-1:-1:1%12139 caused issue
95+
if strcmp(EEG.event(i).type, 'boundary') && strcmp(EEG.event(i+1).type, 'boundary') && EEG.event(i+1).latency/EEG.srate-EEG.event(i).latency/EEG.srate < 2 %following event is also a boundary and less then 2 seconds of "good" data between them
96+
disp(i)
97+
EEG = pop_select( EEG, 'notime',[EEG.event(i).latency/EEG.srate EEG.event(i+1).latency/EEG.srate] );
98+
if strcmp(EEG.event(length(EEG.event)).type, 'boundary')
99+
EEG.event(length(EEG.event)+1)=EEG.event(length(EEG.event)); EEG.event(length(EEG.event)).type='temp';
100+
end
101+
end
102+
end
103+
EEG.event(length(EEG.event)) = [];
104+
end
105+
% deleting the event we added before
106+
new_samples=EEG.pnts;
107+
EEG.deleteddata=100-EEG.pnts/old_samples*100;
108+
deleted_channels(s,:) = [string(subject_list{s}), old_n_chan-new_n_chan] ;
109+
deleted_data(s,:) = [string(subject_list{s}), new_samples/old_samples*100] ;
110+
EEG = pop_saveset( EEG, 'filename',[subject_list{s} '_exchn.set'],'filepath', data_path);
111+
end
112+
%saving matrixes for quality control
113+
save([home_path 'wrongconfig_type2_' group{g}], 'wrongconfig_type2');
114+
save([home_path 'deleted_channels_' group{g}], 'deleted_channels');
115+
save([home_path 'deleted_data_' group{g}] , 'deleted_data');
116+
end

2023 paper/C_manual_check.m

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
% Restingstate pipepline (2021)
2+
% Final version of SRC code 12/6/2021
3+
% Load the raw data of each participant to see if they have bad channels
4+
% Deleting remaining bad channels by eye + seeing if there is something
5+
% of note going on with the raw data of each person
6+
clear variables
7+
%subject_list = {'2201' '2202' '2204' '2207' '2212' '2216' '2222' '2229' '2231' '2243' '2256' '2257' '2260' '2261' '2267' '2270' '2274' '2281' '2284' '2286' '2292' '2295'};
8+
%subject_list = {'7003' '7007' '7019' '7025' '7046' '7049' '7051' '7054' '7058' '7059' '7061' '7064' '7065' '7073' '7075' '7078' '7089' '7092' '7094' '7123' '7556' '7808'};
9+
subject_list = {'10293' '10561' '10562' '10581' '10616' '10748' '10822' '10858' '10935' '12004' '12010' '12139' '12177' '12188' '12197' '12203' '12206' '12215' '12272' '12413' '12415' '12449' '12482' '12512' '12588' '12632' '12648' '12651' '12707' '12727' '12739' '12746' '12750' '12755' '12770' '12815' '12852' '12870'};
10+
home_path = 'D:\restingstate\data\';
11+
for s=1:length(subject_list)
12+
clear bad_chan;
13+
fprintf('\n******\nProcessing subject %s\n******\n\n', subject_list{s});
14+
data_path = [home_path subject_list{s} '\'];
15+
EEG = pop_loadset('filename', [subject_list{s} '_exchn.set'], 'filepath', data_path);
16+
pop_eegplot( EEG, 1, 1, 1);
17+
prompt = 'Delete channels? If yes, input them all as strings inside {}. If none hit enter ';
18+
bad_chan = input(prompt); %
19+
if isempty(bad_chan) ~=1
20+
EEG = pop_select( EEG, 'nochannel',bad_chan);
21+
EEG = pop_saveset( EEG, 'filename',[subject_list{s} '_exchn.set'],'filepath', data_path);
22+
end
23+
close all
24+
25+
end
26+
%2204 a lot of alpha eyes closed
27+
%7064 muscle artifact, check ICA
28+
%10561 noisy
29+
%12449 don't use only 16 chn left
30+
%12707 check n channels (seems few left)

0 commit comments

Comments
 (0)