<div dir="ltr">hi Arnaud, others,<div><br></div><div>Thanks for your suggestions. I played around a bit and think I found a solution that fits my data/processing pipeline a bit better. I looked at how both ft and eeglab handle the output of runica, but I'd appreciate any input to see if I didn't make any mistakes. Specific questions at the end.</div><div><br></div><div>I define my own function that accepts ft data, concatenates trials of variable length, calls runica, prepares a ft return structure (mimicking that of ft_componentanalysis), but also prepares an eeglab struct to be passed to iclabel. Simplified:</div><div><br></div><div><i>%concatenate trial data<br>dat=ft_trial_to_mat(ft_data); %custom func<br></i></div><div><i><br></i></div><div><i>%perform ica</i></div><div><i>[weights, sphere] = runica(dat, optarg{:}); %runica with some options<br></i></div><div><i><br></i></div><div><i>% calculate mixing/unmixing matrices<br>unmixing = weights * sphere; %comp x chan<br>mixing = pinv(unmixing); %chan x comp<br></i></div><div><i><br></i></div><div><i>%-----for ft return structure</i></div><div><i>comp_ft=[]</i></div><div><i>comp_ft.unmixing=unmixing;<br>comp_ft.topo = mixing;<br><br>%component activations (trial-wise)<br>Ntrials  = length(data.trial);<br>Nchans   = length(data.label);<br>for trial=1:Ntrials<br>    

comp_ft .trial{trial} = unmixing * data.trial{trial}; <br>end<br></i></div><div><i><br></i></div><div><i>%----EEGLAB structure    <br>EEG=eeg_emptyset;<br>EEG.srate=data.fsample;<br>EEG.data=dat; %concatenated data<br>EEG.chanlocs=ft_elec_to_eeglab_chanlocs(cfg.elec); %custom func<br>EEG.nbchan=Nchans;<br>EEG.trials=1;<br>EEG.pnts=data.sampleinfo(2);<br>%ICA<br>EEG.icachansind=1:Nchans;<br>EEG.icaweights=weights;<br>EEG.icasphere=sphere;<br>EEG.icawinv=mixing;<br>%EEG.icaact=unmixing*dat; %component activations (concatenated): not needed bc eeg_checkset removes them by default. ICL_feature_extractor will recompute activations (based on average ref)<br><br>EEG=eeg_checkset(EEG); <br><br>%call IClabel<br>EEG=iclabel(EEG);<br>ic_classification=EEG.etc.ic_classification.ICLabel; %to be passed back along with comp_ft for downstream rejection within fieldtrip<br></i></div><div><br></div><div>Needs much more testing but preliminary checks yield reasonable labels.</div><div><br></div><div>My questions: first, are the vars <i>weights</i>, <i>sphere</i>, <i>mixing</i>, <i>unmixing </i>all reference-independent? I suspect they are, but good to be certain. </div><div><br></div><div>Second, and related: my original data are linked-mastoids ref, but I noticed that the function <i>ICL_feature_extractor</i> rereferences to average ref before calculating EEG.icaact. In other words, the component time courses I return in comp_ft.trial are based on linked mastoids (consistent with the input data), whereas the component time courses used internally by IClabel are based on ave ref. This may well be as it should, but again I'd like to make sure that this is ok (and not that e.g. IClabel only works if the original decomposition was based on ave-ref data).</div><div><br></div><div>Many thanks,</div><div>Roy</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Mar 11, 2022 at 9:35 PM Arnaud Delorme <<a href="mailto:arnodelorme@gmail.com">arnodelorme@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">One solution below. Maybe not the most elegant. I assume you want to use ft_preprocessing to preprocess your data (otherwise you can just import the file in EEGLAB directly and convert it to Fieldtrip at the end).<br>
Pull the changes on EEGLAB git (or update the pop_fileio EEGLAB function called by fieldtrip2eeglab, as I have changed it so it would be able to convert Fieldtrip ft_raw_data structures to EEGLAB datasets <a href="https://github.com/sccn/eeglab/blob/develop/functions/popfunc/pop_fileio.m" rel="noreferrer" target="_blank">https://github.com/sccn/eeglab/blob/develop/functions/popfunc/pop_fileio.m</a>)<br>
<br>
The bottom section for conversion back to fieldtrip is a hack accessing Fieldtrip private folder. <br>
You can also use the function eeglab2fieldtrip (tailored to DIPFIT - dipole localization).<br>
<br>
Arno<br>
<br>
% preprocess file in Fieldtrip<br>
cfg = [];<br>
cfg.datafile = '~/data/matlab/eeglab/sample_data/eeglab_data.set';<br>
cfg.headerfile = '~/data/matlab/eeglab/sample_data/eeglab_data.set';<br>
my_ft_data = ft_preprocessing(cfg);<br>
<br>
% Run ICA and IC label in EEGLAB<br>
EEG = fieldtrip2eeglab(my_ft_data, my_ft_data.trial);<br>
EEG = eeg_checkset(EEG);<br>
EEG = pop_runica(EEG, 'icatype', 'runica');<br>
EEG = pop_icflag(EEG, [0 0;0 0; 0.001 1; 0 0; 0 0; 0 0; 0 0]); % see function help message<br>
rejected_comps = find(EEG.reject.gcompreject > 0);<br>
EEG = pop_subcomp(EEG, rejected_comps);<br>
EEG = eeg_checkset(EEG);<br>
<br>
% convert back to Fieldtrip<br>
curPath = pwd;<br>
p = fileparts(which('ft_read_header'));<br>
cd(fullfile(p, 'private'));<br>
hdr = read_eeglabheader( EEG );<br>
data = read_eeglabdata( EEG, 'header', hdr );<br>
event = read_eeglabevent( EEG, 'header', hdr );<br>
cd(curPath);<br>
<br>
<br>
</blockquote></div>