Skip to content

Commit 518dfc1

Browse files
committed
Added CSD scripts
1 parent 4f08414 commit 518dfc1

File tree

2 files changed

+351
-0
lines changed

2 files changed

+351
-0
lines changed
Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
%
2+
% Modified on 2024/04/11 to process thrive dataset flanker data
3+
%
4+
% This script was created by George Buzzell for the NDC Lab EEG Training
5+
% Workshop on 02/22. This script uses parts of the "set up" structure from
6+
% the MADE preprocessing pipeline (Debnath, Buzzell, et. al., 2020)
7+
8+
clear % clear matlab workspace
9+
clc % clear matlab command window
10+
11+
%% Setting up other things
12+
13+
%Location of MADE and ADJUSTED-ADJUST scripts
14+
% addpath(genpath([main_dir filesep 'MADE-EEG-preprocessing-pipeline']));% enter the path of the EEGLAB folder in this line
15+
addpath(genpath('/home/data/NDClab/tools/lab-devOps/scripts/MADE_pipeline_standard/eeg_preprocessing'));% enter the path of the folder in this line
16+
17+
addpath(genpath('/home/data/NDClab/analyses/thrive-theta-ddm/code/matlab/'))
18+
19+
%Location of "EEG
20+
% addpath(genpath([main_dir filesep 'eeglab13_4_4b']));% enter the path of the EEGLAB folder in this line
21+
addpath(genpath('/home/data/NDClab/tools/lab-devOps/scripts/MADE_pipeline_standard/eeglab13_4_4b'));% enter the path of the EEGLAB folder in this line
22+
23+
%remove path to octave functions inside matlab to prevent errors when
24+
% rmpath([main_dir filesep 'eeglab13_4_4b' filesep 'functions' filesep 'octavefunc' filesep 'signal'])
25+
rmpath(['/home/data/NDClab/tools/lab-devOps/scripts/MADE_pipeline_standard/eeglab13_4_4b' filesep 'functions' filesep 'octavefunc' filesep 'signal'])
26+
27+
%% setup; run this section before any other section below
28+
29+
%location of analysis folder
30+
% analysis_dir = '/Users/fzaki001/thrive-theta-ddm';
31+
analysis_dir = '/home/data/NDClab/analyses/thrive-theta-ddm';
32+
33+
%location of dataset folder
34+
% dataset_dir = '/Users/fzaki001/thrive-theta-ddm';
35+
dataset_dir = '/home/data/NDClab/datasets/thrive-dataset';
36+
% summary_csv_path = '/Users/fzaki001/thrive-theta-ddm/derivatives/behavior/summary.csv';
37+
summary_csv_path = '/home/data/NDClab/analyses/thrive-theta-ddm/derivatives/behavior/summary.csv';
38+
39+
% Setting up other things
40+
41+
% 1. Enter the path of the folder that has the data to be analyzed
42+
data_location = [dataset_dir filesep 'derivatives' filesep 'preprocessed'];
43+
44+
% 2. Enter the path of the folder where you want to save the postprocessing outputs
45+
output_location = [analysis_dir filesep 'derivatives' filesep 'preprocessed/erp_check'];
46+
47+
% 3. this is the correct channel location file BUT INCORRECT PATH!
48+
% channel_locations = loadbvef('/Users/fzaki001/Downloads/thrive/code/CACS-128-X7-FIXED-64only.bvef');
49+
channel_locations = loadbvef('/home/data/NDClab/tools/lab-devOps/scripts/MADE_pipeline_standard/eeg_preprocessing/chan_locs_files/electrode_locs_files/CACS-128-X7-FIXED-64only.bvef');
50+
51+
% %specify parameters of data to process
52+
53+
%modifying above, to account for files named differently
54+
%specify parameters of data to process
55+
task = 'all';
56+
procStage = 'processed_data';
57+
visitDirName = 's1_r1'; %visit folder does not list "e1"
58+
visitFileName = 's1_r1_e1'; %file names include "e1" designation
59+
60+
% Read files to analyses
61+
datafile_info=dir([data_location filesep 'sub-*' filesep visitDirName filesep 'eeg' filesep 'sub-*_' task '_eeg_*' procStage '_' visitFileName '.set']);
62+
datafile_info=datafile_info(~ismember({datafile_info.name},{'.', '..', '.DS_Store'}));
63+
datafile_names={datafile_info.name};
64+
datafile_paths={datafile_info.folder};
65+
[filepath,name,ext] = fileparts(char(datafile_names{1}));
66+
67+
% Check whether EEGLAB and all necessary plugins are in Matlab path.
68+
if exist('eeglab','file')==0
69+
error(['Please make sure EEGLAB is on your Matlab path. Please see EEGLAB' ...
70+
'wiki page for download and instalation instructions']);
71+
end
72+
73+
% Create output folders to save data
74+
if exist(output_location, 'dir') == 0
75+
mkdir(output_location)
76+
end
77+
78+
for site = 1:64
79+
trodes{site} = num2str(site)
80+
end
81+
Montage_64=ExtractMontage('/home/data/NDClab/analyses/thrive-theta-ddm/code/preprocessing-eeg/64ch_bv_montage_csd.csd', trodes');
82+
% MapMontage(Montage_64);
83+
[G, H] = GetGH(Montage_64);
84+
85+
%% Count trials
86+
% switch to output directory
87+
cd(output_location);
88+
89+
% %create variable names for count trials output and write to disk
90+
% outputHeader = {'id, s_resp_incon_error, s_resp_incon_corr, ns_resp_incon_error, ns_resp_incon_corr'};
91+
% dlmwrite(strcat('thrive_trialCounts_respOnly', date, '.csv'), outputHeader, 'delimiter', '', '-append');
92+
93+
diary(sprintf('erp_log_%s.log', datestr(now, 'mm-dd-yyyy_HH_MM_SS')))
94+
95+
%% pull resp-locked erp mat file
96+
97+
%read in behavioral data for participants
98+
behavior_info = readtable(summary_csv_path);
99+
100+
%specify min number of trials per condition (if file contains less than
101+
%this number for ANY condition, then they will be skipped for ALL conditions
102+
minTrials = 6;
103+
104+
%specify min accuracy per condition (if file contains less than
105+
%this number for ANY condition, then they will be skipped for ALL conditions
106+
acc_cutoff = .6;
107+
108+
%initialize participant counter variable (used for indexing into large mat
109+
%file that data is saved into)
110+
pIdx = 1;
111+
112+
%initialize matrices to hold erp data and corresponding sub ids
113+
erpDat_data = [];
114+
erpDat_subIds = [];
115+
116+
% loop through each participant in the study
117+
for subject = 1:length(datafile_names)
118+
119+
%initialize numTrials for this participant/file
120+
numTrials = [];
121+
122+
% extract participant number
123+
subNumText = datafile_names{subject}(5:11);
124+
125+
%find row in behavior file corresponding to this participant
126+
behavior_id_match_idxs = find(behavior_info{:,'sub'} == str2num(subNumText));
127+
128+
%if participant has low accuracy in either condition, skip that
129+
%participant for ALL conditions
130+
% if (behavior_info{behavior_id_match_idxs,'acc_nonsoc'} < acc_cutoff || behavior_info{behavior_id_match_idxs,'acc_soc'} < acc_cutoff)
131+
% continue
132+
% end
133+
%
134+
% if (behavior_info{behavior_id_match_idxs,'x6_or_more_err_nonsoc'} < 6 || behavior_info{behavior_id_match_idxs,'x6_or_more_err_soc'} < 6)
135+
% continue
136+
% end
137+
%load the original data set
138+
EEG = pop_loadset( 'filename', datafile_names{subject}, 'filepath', datafile_paths{subject});
139+
EEG = eeg_checkset( EEG );
140+
141+
%remove all the non-stim-locking markers (should have done already...)
142+
EEG = pop_selectevent( EEG, 'latency','-.1 <= .1','deleteevents','on');
143+
EEG = eeg_checkset( EEG );
144+
145+
for ne = 1:length(EEG.epoch)
146+
myEEG = single(EEG.data(:, :, ne));
147+
MyResults = CSD(myEEG, G, H); % compute CSD for <channels-by-samples> 2-D epoch
148+
data(:, :, ne) = MyResults;
149+
end
150+
EEG.data = data
151+
152+
data(:,:,:) = NaN;
153+
154+
% NOTE %
155+
%the logic of checking conditions and then looping over conditions
156+
%below is fairly hard-coded and could be be substantially improved to
157+
%allow for easier reuse when number of conditions or number of
158+
%variables per condition changes.
159+
%
160+
%before pulling trials of interest, for any conditions, check to make
161+
%sure this file/participant has more than minTrials for EACH condition.
162+
%If the file/participant is below minTrials for even one of the
163+
%conditions that will be pulled, then the file/participant is skipped
164+
%entirely and no condition data at all will be pulled for this specific
165+
%file (but the participant can still have data pulled for another one
166+
%of their files from another visit).
167+
%
168+
%count trials for each condition of interest and store in numTrials vector
169+
numTrials(1) = length(find( (strcmp({EEG.event.observation}, "s")) & (strcmp({EEG.event.eventType}, "resp")) & (strcmp({EEG.event.congruency}, "i")) & ([EEG.event.accuracy] == 0) & ([EEG.event.responded] == 1) & ([EEG.event.validRt] == 1) ));
170+
numTrials(2) = length(find( (strcmp({EEG.event.observation}, "s")) & (strcmp({EEG.event.eventType}, "resp")) & (strcmp({EEG.event.congruency}, "i")) & ([EEG.event.accuracy] == 1) & ([EEG.event.responded] == 1) & ([EEG.event.validRt] == 1) ));
171+
numTrials(3) = length(find( (strcmp({EEG.event.observation}, "ns")) & (strcmp({EEG.event.eventType}, "resp")) & (strcmp({EEG.event.congruency}, "i")) & ([EEG.event.accuracy] == 0) & ([EEG.event.responded] == 1) & ([EEG.event.validRt] == 1) ));
172+
numTrials(4) = length(find( (strcmp({EEG.event.observation}, "ns")) & (strcmp({EEG.event.eventType}, "resp")) & (strcmp({EEG.event.congruency}, "i")) & ([EEG.event.accuracy] == 1) & ([EEG.event.responded] == 1) & ([EEG.event.validRt] == 1) ));
173+
174+
%logical test if the number of trials for each condition (numTrials vector)
175+
%are NOTE all >= minTrials. If statement is true, then participant/file
176+
%is skipped and for loop over files continues to next file
177+
if ~(sum(numTrials >= minTrials) == length(numTrials))
178+
continue
179+
end
180+
181+
% loop through conditions of interest for this file (combo of event types)
182+
%
183+
% specify number of conditions using a seperate conditionNums var, so
184+
% that it can be referenced below when iterating idx counters (to only
185+
%iterate when c == length(conditionNums);
186+
conditionNums = 1:4;
187+
%
188+
for c = conditionNums
189+
190+
if (c==1) % social error
191+
observation = 's';
192+
eventType = 'resp';
193+
congruency = 'i';
194+
accuracy = 0;
195+
responded = 1;
196+
validRt = 1;
197+
elseif (c==2) % social correct
198+
observation = 's';
199+
eventType = 'resp';
200+
congruency = 'i';
201+
accuracy = 1;
202+
responded = 1;
203+
validRt = 1;
204+
elseif (c==3) % nonsocial error
205+
observation = 'ns';
206+
eventType = 'resp';
207+
congruency = 'i';
208+
accuracy = 0;
209+
responded = 1;
210+
validRt = 1;
211+
elseif (c==4) % nonsocial correct
212+
observation = 'ns';
213+
eventType = 'resp';
214+
congruency = 'i';
215+
accuracy = 1;
216+
responded = 1;
217+
validRt = 1;
218+
end
219+
220+
%select combintion of event types of interest based on vars above
221+
EEG1 = pop_selectevent( EEG, 'latency','-1<=1','observation',observation,'eventType',eventType,'congruency',congruency,'accuracy',accuracy,'responded',responded,'validRt',validRt,'deleteevents','on','deleteepochs','on','invertepochs','off');
222+
EEG1 = eeg_checkset( EEG1 );
223+
224+
% Average across epoch dimension
225+
% this all Channel ERP only needs to be computed once
226+
% per condition
227+
meanEpochs = mean(EEG1.data, 3);
228+
229+
%store data for this condition in array
230+
erpDat_data(pIdx,c,:,:)= meanEpochs;
231+
232+
%store participant number for corresponding row in erpdat
233+
erpDat_subIds{pIdx,1} = datafile_names{subject}(5:11);
234+
235+
%iterate idx counter IMPORTANT: ONLY ITERATE COUNTER WHEN
236+
%ON LAST CONDITION
237+
if c == length(conditionNums)%if this is the last condition of condition loop
238+
pIdx = pIdx + 1;
239+
end
240+
%end loop through conditions
241+
end
242+
%end loop through participants
243+
end
244+
245+
%save the erps and subject list
246+
save('thrive_Resp_erps_csd_min_6t_60acc.mat','erpDat_data', 'erpDat_subIds')
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
%
2+
% Modified on 2024/04/11 to process thrive dataset flanker data
3+
%
4+
% This script was created by George Buzzell for the NDC Lab EEG Training
5+
% Workshop on 02/22. This script uses parts of the "set up" structure from
6+
% the MADE preprocessing pipeline (Debnath, Buzzell, et. al., 2020)
7+
8+
clear % clear matlab workspace
9+
clc % clear matlab command window
10+
11+
%% Setting up other things
12+
13+
%Location of MADE and ADJUSTED-ADJUST scripts
14+
% addpath(genpath([main_dir filesep 'MADE-EEG-preprocessing-pipeline']));% enter the path of the EEGLAB folder in this line
15+
addpath(genpath('/home/data/NDClab/tools/lab-devOps/scripts/MADE_pipeline_standard/eeg_preprocessing'));% enter the path of the folder in this line
16+
17+
addpath(genpath('/home/data/NDClab/analyses/thrive-theta-ddm/code/matlab/'))
18+
19+
%Location of "EEG
20+
% addpath(genpath([main_dir filesep 'eeglab13_4_4b']));% enter the path of the EEGLAB folder in this line
21+
addpath(genpath('/home/data/NDClab/tools/lab-devOps/scripts/MADE_pipeline_standard/eeglab13_4_4b'));% enter the path of the EEGLAB folder in this line
22+
23+
%remove path to octave functions inside matlab to prevent errors when
24+
% rmpath([main_dir filesep 'eeglab13_4_4b' filesep 'functions' filesep 'octavefunc' filesep 'signal'])
25+
rmpath(['/home/data/NDClab/tools/lab-devOps/scripts/MADE_pipeline_standard/eeglab13_4_4b' filesep 'functions' filesep 'octavefunc' filesep 'signal'])
26+
27+
%% setup; run this section before any other section below
28+
29+
%location of analysis folder
30+
analysis_dir = '/home/data/NDClab/analyses/thrive-theta-ddm';
31+
32+
%location of dataset folder
33+
dataset_dir = '/home/data/NDClab/datasets/thrive-dataset';
34+
35+
% Setting up other things
36+
37+
% 1. Enter the path of the folder that has the data to be analyzed
38+
data_location = [dataset_dir filesep 'derivatives' filesep 'preprocessed'];
39+
40+
% 2. Enter the path of the folder where you want to save the postprocessing outputs
41+
output_location = [analysis_dir filesep 'derivatives' filesep 'preprocessed/erp_check'];
42+
save_location = [analysis_dir filesep 'derivatives' filesep 'preprocessed/csd_data'];
43+
% 3. this is the correct channel location file BUT INCORRECT PATH!
44+
45+
%modifying above, to account for files named differently
46+
%specify parameters of data to process
47+
task = 'all';
48+
procStage = 'processed_data';
49+
visitDirName = 's1_r1'; %visit folder does not list "e1"
50+
visitFileName = 's1_r1_e1'; %file names include "e1" designation
51+
52+
% Read files to analyses
53+
datafile_info=dir([data_location filesep 'sub-*' filesep visitDirName filesep 'eeg' filesep 'sub-*_' task '_eeg_*' procStage '_' visitFileName '.set']);
54+
datafile_info=datafile_info(~ismember({datafile_info.name},{'.', '..', '.DS_Store'}));
55+
datafile_names={datafile_info.name};
56+
datafile_paths={datafile_info.folder};
57+
[filepath,name,ext] = fileparts(char(datafile_names{1}));
58+
59+
% Check whether EEGLAB and all necessary plugins are in Matlab path.
60+
if exist('eeglab','file')==0
61+
error(['Please make sure EEGLAB is on your Matlab path. Please see EEGLAB' ...
62+
'wiki page for download and instalation instructions']);
63+
end
64+
65+
% Create output folders to save data
66+
if exist(save_location, 'dir') == 0
67+
mkdir(save_location);
68+
end
69+
70+
for site = 1:64;
71+
trodes{site} = num2str(site);
72+
end
73+
Montage_64=ExtractMontage('/home/data/NDClab/analyses/thrive-theta-ddm/code/preprocessing-eeg/64ch_bv_montage_csd.csd', trodes');
74+
% MapMontage(Montage_64);
75+
[G, H] = GetGH(Montage_64);
76+
77+
diary(sprintf('csd_log_%s.log', datestr(now, 'mm-dd-yyyy_HH_MM_SS')))
78+
79+
% loop through each participant in the study
80+
for subject = 1:length(datafile_names)
81+
82+
% extract participant number
83+
subNumText = datafile_names{subject}(5:11);
84+
85+
%load the original data set
86+
EEG = pop_loadset('filename', datafile_names{subject}, 'filepath', datafile_paths{subject});
87+
EEG = eeg_checkset(EEG);
88+
disp(datafile_names{subject})
89+
disp(save_location)
90+
%remove all the non-stim-locking markers (should have done already...)
91+
EEG = pop_selectevent(EEG, 'latency','-.1 <= .1','deleteevents','on');
92+
EEG = eeg_checkset(EEG);
93+
94+
for ne = 1:length(EEG.epoch)
95+
myEEG = single(EEG.data(:, :, ne));
96+
MyResults = CSD(myEEG, G, H); % compute CSD for <channels-by-samples> 2-D epoch
97+
data(:, :, ne) = MyResults;
98+
end
99+
EEG.data = data;
100+
101+
data(:,:,:) = NaN;
102+
103+
EEG = pop_editset(EEG, 'setname', datafile_names{subject});
104+
EEG = pop_saveset(EEG, 'filename', datafile_names{subject}, 'filepath', save_location);
105+
end

0 commit comments

Comments
 (0)