Skip to content

Commit

Permalink
Merge pull request #32 from DouweHorsthuis/2023_update
Browse files Browse the repository at this point in the history
Update part 1
  • Loading branch information
DouweHorsthuis authored May 29, 2023
2 parents 56466be + c90448f commit b2a76dd
Show file tree
Hide file tree
Showing 9 changed files with 442 additions and 222 deletions.
46 changes: 24 additions & 22 deletions src/A_merge_sets.m
Original file line number Diff line number Diff line change
@@ -1,50 +1,52 @@
% EEGLAB merge sets, and creates .set file
% by Douwe Horsthuis updated on 6/21/2021
% by Douwe Horsthuis updated on 5/29/2023
% ------------------------------------------------
subject_list = {'ID_participant1' 'ID_participant2' 'ID_etc'}; %all the IDs for the indivual particpants
home_path = 'C:\Users\dohorsth\Desktop\cued-boss\'; %place data is (something like 'C:\data\')
save_path = 'C:\Users\dohorsth\Desktop\cystinosis\cued boss\data\'; %only for the first script, in case you load your data from somewhere special but want to save it somewhere else
filename = 'cued_boss'; % if your bdf file has a name besides the ID of the participant (e.g. oddball_paradigm)
blocks = 1; % the amount of BDF files. if different participant have different amounts of blocks, run those participant separate
subject_list = {'Participant_1_ID' 'Participant_2_ID'};
home_path = 'C:\Users\whereisyourdata\'; %place data is (something like 'C:\data\')
save_path = 'D:\wheretosaveyourdatat\'; %only for the first script, in case you load your data from somewhere special but want to save it somewhere else
readme_file ='yes';%'yes' or 'no', if yes using [EEG]= readme_to_EEG(EEG, data_path) to read readme file
eye_tracking ='no';%'yes' or 'no', if yes using edf_to_figure(data_path)to create a figure with avg gaze
Pausing_yn='y'; %y or n,if you want to first only run people with one block, which is how data is usually collected in our lab, it'll pause if it finds more files
if strcmpi(readme_file,'yes') || strcmpi(eye_tracking,'yes')% if yes we need to add the functions to the file path
file_loc=[fileparts(matlab.desktop.editor.getActiveFilename),filesep];
addpath(genpath(file_loc));%adding path to your scripts so that the functions are found
file_loc=[fileparts(matlab.desktop.editor.getActiveFilename),filesep];
addpath(genpath(file_loc));%adding path to your scripts so that the functions are found
end
for s = 1:length(subject_list)
clear ALLEEG
eeglab
close all
data_path = [home_path subject_list{s} '\'];
disp([data_path subject_list{s} '_' filename '.bdf'])
save_path_indv=[save_path subject_list{s} '\'];
if blocks == 1
%if participants have only 1 block, load only this one file
EEG = pop_biosig([data_path subject_list{s} '_' filename '_1.bdf']);
else
for bdf_bl = 1:blocks
%if participants have only 1 block, load only this one file
filename_quick=dir([data_path '/*.BDF']);
if size(filename_quick,1) == 1
EEG = pop_biosig([data_path filename_quick.name]);
else
for bdf_bl = 1:size(filename_quick,1)
if strcmp(Pausing_yn,'y')
disp(['too many blocks for participant ' subject_list{s}])
pause ()
end
%if participants have more than one block, load the blocks in a row
%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)
EEG = pop_biosig([data_path subject_list{s} '_' filename '_' num2str(bdf_bl) '.bdf']);
EEG = pop_biosig([data_path filename_quick(bdf_bl).name]);
[ALLEEG, ~] = eeg_store(ALLEEG, EEG, CURRENTSET);
mkdir(save_path_indv) %if individual folders do not exist
end
%since there are more than 1 files, they need to be merged to one big .set file.
EEG = pop_mergeset( ALLEEG, 1:blocks, 0);
EEG = pop_mergeset( ALLEEG, 1:size(filename_quick,1), 0);
end
mkdir(save_path_indv) %if individual folders do not exist
%adding info to the EEG structure
if strcmpi(readme_file,'yes')
[EEG]= readme_to_EEG(EEG, data_path);
[EEG]= readme_to_EEG(EEG, data_path);
else
EEG.subject = subject_list{s}; %subject ID
EEG.subject = subject_list{s}; %subject ID
end
if strcmpi(eye_tracking,'yes')
edf_to_figure(data_path);
saveas(gcf,[data_path subject_list{s} '_ET'])
saveas(gcf,[save_path_indv subject_list{s} '_ET'])
close all
end
%save the bdf as a .set file

EEG = pop_saveset( EEG, 'filename',[subject_list{s} '.set'],'filepath',data_path);
EEG = pop_saveset( EEG, 'filename',[subject_list{s} '.set'],'filepath',save_path_indv);
end
5 changes: 5 additions & 0 deletions src/B_downs_filter_chaninfo_exclchan.m
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
% Combined and updated by Douwe Horsthuis last update 11/5/2021
% ------------------------------------------------
clear variables
eeglab
% This defines the set of subjects
subject_list = {'6209' '6239' '8103' '8110' '8110-01' '8113' '8117' '8119' '8121' '8121-01' '8128' '8128-01'}; %all the IDs for the indivual particpants
home_path = 'C:\Users\dohorsth\Desktop\cued-boss\'; %place data is (something like 'C:\data\')
Expand All @@ -11,6 +12,10 @@
avg_deleted_data=zeros(1, length(subject_list));
clean_data={'y'}; % if 'y' not only channels but also noisy moments in thedata get cleaned
individual_plots='yes';
if strcmpi(individual_plots,'yes')% if yes we need to add the functions to the file path
file_loc=[fileparts(matlab.desktop.editor.getActiveFilename),filesep];
addpath(genpath(file_loc));%adding path to your scripts so that the functions are found
end
% Loop through all subjects
for s=1:length(subject_list)
fprintf('\n******\nProcessing subject %s\n******\n\n', subject_list{s});
Expand Down
64 changes: 40 additions & 24 deletions src/C_manual_check.m
Original file line number Diff line number Diff line change
@@ -1,30 +1,46 @@
% Plotting the raw data to see if there are remaining bad or flat channels
% Created by Douwe Horsthuis last update 5/21/2021
% ------------------------------------------------
subject_list = {'some sort of ID' 'a different id for a different particpant'};
home_path = 'the main folder where you store your data';

group_del_channel=[]; %needed for the plot_group_deleted_chan_location function
for s=1:length(subject_list)
clear bad_chan;
fprintf('\n******\nProcessing subject %s\n******\n\n', subject_list{s});
data_path = [home_path subject_list{s} '\'];
EEG = pop_loadset('filename', [subject_list{s} '_exchn.set'], 'filepath', data_path);
pop_eegplot( EEG, 1, 1, 1);
prompt = 'Delete channels? If yes, input them all as strings inside {}. If none hit enter ';
bad_chan = input(prompt); %
if isempty(bad_chan) ~=1
EEG = pop_select( EEG, 'nochannel',bad_chan);
EEG = pop_saveset( EEG, 'filename',[subject_list{s} '_exchn.set'],'filepath', data_path);
eeglab
Group_list={'Name_grp1' 'Name_grp2'};
for gr=2:length(Group_list)
if strcmpi(Group_list{gr},'Name_grp1')
subject_list = {'ID_1' 'ID_2'};
elseif strcmpi(Group_list{gr},'Name_grp2')
subject_list = {'ID_3' 'ID_4'};
else
disp('not possible')
pause()
end
close all
home_path = 'D:\whereisthedata\'; %place data is (something like 'C:\data\')
%need to add the folder with the functions
file_loc=[fileparts(matlab.desktop.editor.getActiveFilename),filesep];
addpath(genpath(file_loc));%adding path to your scripts so that the functions are found

for s=1:length(subject_list)
if s==1
group_del_channel=[]; %needed for the plot_group_deleted_chan_location function
end
clear bad_chan;
fprintf('\n******\nProcessing subject %s\n******\n\n', subject_list{s});
data_path = [home_path subject_list{s} '\'];
EEG = pop_loadset('filename', [subject_list{s} '_exchn.set'], 'filepath', data_path);
pop_eegplot( EEG, 1, 1, 1);
prompt = 'Delete channels? If yes, input them all as strings inside {}. If none hit enter ';
bad_chan = input(prompt); %
if isempty(bad_chan) ~=1
EEG = pop_select( EEG, 'nochannel',bad_chan);
EEG = pop_saveset( EEG, 'filename',[subject_list{s} '_exchn.set'],'filepath', data_path);
end
close all

%% creating figures with deleted and bridged channels
EEG=plot_deleted_chan_location(EEG,data_path); %plotting the location of deleted chan
% plotting a topoplot with how many channels get for everyone
[EEG, group_del_channel]=plot_group_deleted_chan_location(EEG,group_del_channel,home_path);
%% group quality info, ID / % deleted data / seconds of data left / N - deleted channels
quality(s,:)=[str2double(subject_list{s}), EEG.deleteddata_wboundries,round(EEG.xmax), length(EEG.del_chan)];
%% creating figures with deleted and bridged channels
EEG=plot_deleted_chan_location(EEG,data_path); %plotting the location of deleted chan
% plotting a topoplot with how many channels get for everyone
[EEG, group_del_channel]=plot_group_deleted_chan_location(EEG,group_del_channel,home_path,Group_list{gr},length(subject_list));

%% group quality info, ID / % deleted data / seconds of data left / N - deleted channels
quality(s,:)=[str2double(subject_list{s}), str2double(Group_list{gr}) EEG.deleteddata_wboundries,round(EEG.xmax), length(EEG.del_chan)];
end
save([home_path 'participant_info_' Group_list{gr}], 'quality');
end
load([home_path 'participant_info']) %so we can add
save([home_path 'participant_info'], 'participant_badchan', 'quality');
19 changes: 9 additions & 10 deletions src/D_reref_exclextrn_interp_avgref_ica_autoexcom.m
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,16 @@
% uses runica to do an Independent Component Analysis
% uses IClabel to define the eye component
% Deletes these and the components also get printed.
% by Douwe Horsthuis updated on 12/22/2021
% by Douwe Horsthuis updated on 5/29/2023
% ------------------------------------------------
clear variables
eeglab
%% Subject info for each script
subject_list = {'some sort of ID' 'a different id for a different particpant'};
home_path = 'the main folder where you store your data';
subject_list = {'ID_1' 'ID_2'};
home_path = 'D:\cystinosis visual adaptation\Data\'; %place data is (something like 'C:\data\')
%% info needed for this script specific
components = num2cell(zeros(length(subject_list), 8)); %prealocationg space for speed
refchan = { }; %if you want to re-ref to a channel add the name of the channel here, if empty won't re-ref to any specific channel (for example {'EXG3' 'EXG4'} or {'Cz'})
only_eye_ic='yes'; %'yes' or 'no' : if you want to delete only eye components 'yes' if you want more 'no' see line 73 for more info
only_eye_ic='No'; %'yes' or 'no' : if you want to delete only eye components 'yes' if you want more 'no' see line 73 for more info
%% Loop through all subjects
for s=1:length(subject_list)
fprintf('\n******\nProcessing subject %s\n******\n\n', subject_list{s});
Expand Down Expand Up @@ -71,8 +70,8 @@
ICA_components(:,8) = ICA_components(:,3); %row 1 = Brain row 2 = muscle row 3= eye row 4 = Heart Row 5 = Line Noise row 6 = channel noise row 7 = other, combining this makes sure that the component also gets deleted if its a combination of all.
bad_components = find(ICA_components(:,8)>0.80 & ICA_components(:,1)<0.10); %if the new row is over 80% of the component and the component has less the 5% brain
elseif strcmpi(only_eye_ic,'no')
ICA_components(:,8) = sum(ICA_components(:,[2 3 4 5 6]),2);;
bad_components = (find((ICA_components(:,3)>0.70 | ICA_components(:,2)>0.80 | ICA_components(:,6)>0.70) & ICA_components(:,1)<0.10));
ICA_components(:,8) = sum(ICA_components(:,[2 3 4 5 6]),2);
bad_components = (find((ICA_components(:,8)>0.70) & ICA_components(:,1)<0.10)); %if the sum of all the potential bad compontens is >70 % and brain component makes up < 10 of the componenten, mark it as bad
else
error('not correctly selected how many ICs should be deleted')
end
Expand All @@ -81,11 +80,11 @@
if ceil(sqrt(length(bad_components))) == 1
pop_topoplot(EEG, 0, [bad_components bad_components] ,subject_list{s} ,0,'electrodes','on');
else
pop_topoplot(EEG, 0, [bad_components] ,subject_list{s},[ceil(sqrt(length(bad_components))) ceil(sqrt(length(bad_components)))] ,0,'electrodes','on');
pop_topoplot(EEG, 0, bad_components ,subject_list{s},[ceil(sqrt(length(bad_components))) ceil(sqrt(length(bad_components)))] ,0,'electrodes','on');
end
title(subject_list{s});
print([data_path subject_list{s} '_Bad_ICs_topos'], '-dpng' ,'-r300');
EEG = pop_subcomp( EEG, [bad_components], 0); %excluding the bad components
EEG = pop_subcomp( EEG, bad_components, 0); %excluding the bad components
close all
else %instead of only plotting bad components it will plot all components
title(subject_list{s}); text( 0.2,0.5, 'there are no eye-components found')
Expand All @@ -103,4 +102,4 @@
data_subj = [ID, All_bad_chan]; %combines IDs and Bad channels
participant_badchan(s,:) = data_subj;%combine new data with old data
end
save([home_path 'participant_info'], 'participant_badchan');
save([home_path 'participant_badchan'], 'participant_badchan');
89 changes: 89 additions & 0 deletions src/functions/plot_group_deleted_chan_location.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
function [EEG, group_del_channel]= plot_group_deleted_chan_location(EEG,group_del_channel,save_path,groupname,total_participants)
%this function plots all the deleted channel locations in on a scalp map
%Requires a EEGLAB EEG matrix, with the locations of all channels (before some got delted)
%The EEG.urchanlocs can be created using EEGLAB's chan location function.
%Requires group_del_channel=[]; before it enters the participant loop
%it should be run for several subjects on a loop
%group_del_channel will keep adding the data of the next participant in the
%loop and create a group average every time
% it overwrites the figure it creates everytime it adds a new participant

labels_all = {EEG.urchanlocs(1:64).labels}.'; %stores all the labels in a new matrix
labels_good = {EEG.chanlocs.labels}.'; %saves all the channels that are in the excom file
del_chan=setdiff(labels_all,labels_good); %figurs out the deleted channels
EEG.del_chan=[];
for chan=1:length(del_chan)
for del=1:64
if strcmp(del_chan{chan},EEG.urchanlocs(del).labels)
EEG.del_chan = [EEG.del_chan;EEG.urchanlocs(del)]; %finds locations etc
end
end
end

%creating the group channels
if isempty(EEG.del_chan) %in case there is no bad one
return
elseif isempty(group_del_channel) %in case it is the first time it is ran
group_del_channel= EEG.del_chan;
else
group_del_channel= [group_del_channel;EEG.del_chan]; %in case there is already data it'll add it together
end
% creating a matrix with all 64 channels and how often they have been deleted
for i=1:64
all_del{i}=EEG.urchanlocs(i).labels;
end

channel_amounts_deleted=zeros(1,64);
for i=1:length(group_del_channel)
for ii=1:64 %loop through every channel
if strcmpi(group_del_channel(i).labels,all_del(ii))
channel_amounts_deleted(ii)=channel_amounts_deleted(ii)+1;
end
end
end
plot_chan_labels_2=[];
for i=1:64 %all channels
if nonzeros(channel_amounts_deleted(i)) %this looks if it got at least once deleted
chan_loc=EEG.urchanlocs(i); %ifso, find location info
chan_loc.labels=channel_amounts_deleted(i); %replace name by amount deleted
plot_chan_labels_2=[plot_chan_labels_2;chan_loc] ; %store
end
end
%% wrong way of doing it
% plot_chan_labels=group_del_channel;
% for i=1:length(group_del_channel)
% n_chan=0;
% for ii=1:length(group_del_channel) %looking for each channel
% if strcmpi(group_del_channel(i).labels,group_del_channel(ii).labels) %comparing that with each channel
% n_chan=n_chan+1;
% end
% end
% %once compared to each channel we know how often that channel happens
% plot_chan_labels(i).labels=num2str(n_chan);
% end
%
% %need to delete the duplicated channels, because you can't have more than 64
% for i=length(plot_chan_labels):-1:1 %look at all channels (backwards, because we are deleting stuff and we don't want a crash)
% if plot_chan_labels(i).labels >1 %then we need to find if duplicate exist
% for ii=length(plot_chan_labels):-1:1 %looking through all existing deleted chans (backwards, because we are deleting stuff and we don't want a crash)
% if (plot_chan_labels(ii).urchan == plot_chan_labels(i).urchan) && ii~=i %if orginal chan loc is same AND we are sure we are NOT comparing the same with the same
% plot_chan_labels(i)=[]; %delete it
% break %need this or it'll crash once the channel is deleted, it should take care
% end
% end
% end
% end
%% plotting
if isempty(group_del_channel)
figure('Renderer', 'painters', 'Position', [10 10 375 225]); %this is just an empty figure
elseif length(group_del_channel)==1
plot_chan_labels_2=[plot_chan_labels_2;plot_chan_labels_2]; %need 2 to have the function work, but will just plot 2 the same one
figure; topoplot([],plot_chan_labels_2, 'style', 'fill', 'electrodes', 'labelpoint', 'chaninfo', EEG.chaninfo);
plot_chan_labels_2=plot_chan_labels_2(1);
else
figure; topoplot([],plot_chan_labels_2, 'style', 'map', 'electrodes','labels', 'chaninfo', EEG.chaninfo,'maplimits' , [-2000 2000] );
title(groupname,['Numbers represent how often that channel is deleted in ' total_participants ' participants', 'Interpreter', 'none')
end
print([save_path groupname '_deleted_channels'], '-dpng' ,'-r300');
close all
end
1 change: 1 addition & 0 deletions src/functions/plotting_bridged_channels.m
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
bridge.Bridged.Labels=strjoin(bridge.Bridged.Labels);
end
saveas(gcf,[save_path EEG_temp.subject '_bridged_channels'])
print([save_path EEG_temp.subject '_bridged_channels'], '-dpng' ,'-r300');
close all
EEG.bridged=EEG_temp.bridged;
end
Loading

0 comments on commit b2a76dd

Please sign in to comment.