[Eeglablist] [FieldTrip] convert fieldtrip components to eeglab for IClabel

Roy Cox roycox.roycox at gmail.com
Tue Mar 15 06:43:29 PDT 2022


hi Arnaud, others,

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.

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:



*%concatenate trial datadat=ft_trial_to_mat(ft_data); %custom func*

*%perform ica*

*[weights, sphere] = runica(dat, optarg{:}); %runica with some options*




*% calculate mixing/unmixing matricesunmixing = weights * sphere; %comp x
chanmixing = pinv(unmixing); %chan x comp*

*%-----for ft return structure*
*comp_ft=[]*









*comp_ft.unmixing=unmixing;comp_ft.topo = mixing;%component activations
(trial-wise)Ntrials  = length(data.trial);Nchans   = length(data.label);for
trial=1:Ntrials     comp_ft .trial{trial} = unmixing * data.trial{trial};
end*





















*%----EEGLAB structure
 EEG=eeg_emptyset;EEG.srate=data.fsample;EEG.data=dat; %concatenated
dataEEG.chanlocs=ft_elec_to_eeglab_chanlocs(cfg.elec); %custom
funcEEG.nbchan=Nchans;EEG.trials=1;EEG.pnts=data.sampleinfo(2);%ICAEEG.icachansind=1:Nchans;EEG.icaweights=weights;EEG.icasphere=sphere;EEG.icawinv=mixing;%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)EEG=eeg_checkset(EEG); %call
IClabelEEG=iclabel(EEG);ic_classification=EEG.etc.ic_classification.ICLabel;
%to be passed back along with comp_ft for downstream rejection within
fieldtrip*

Needs much more testing but preliminary checks yield reasonable labels.

My questions: first, are the vars *weights*, *sphere*, *mixing*, *unmixing *all
reference-independent? I suspect they are, but good to be certain.

Second, and related: my original data are linked-mastoids ref, but I
noticed that the function *ICL_feature_extractor* 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).

Many thanks,
Roy

On Fri, Mar 11, 2022 at 9:35 PM Arnaud Delorme <arnodelorme at gmail.com>
wrote:

> 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).
> 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
> https://urldefense.proofpoint.com/v2/url?u=https-3A__github.com_sccn_eeglab_blob_develop_functions_popfunc_pop-5Ffileio.m&d=DwIBaQ&c=-35OiAkTchMrZOngvJPOeA&r=kB5f6DjXkuOQpM1bq5OFA9kKiQyNm1p6x6e36h3EglE&m=j3DRW8gQaRD2BqkIUHE1EH9udpuomsRhtWbcF5mUWTikNNjdC1xFehjJMEQ0JITO&s=2woOr72emNiDviPMLBbLOX0zMjddbqwo4RXAqAui8Yc&e= 
> )
>
> The bottom section for conversion back to fieldtrip is a hack accessing
> Fieldtrip private folder.
> You can also use the function eeglab2fieldtrip (tailored to DIPFIT -
> dipole localization).
>
> Arno
>
> % preprocess file in Fieldtrip
> cfg = [];
> cfg.datafile = '~/data/matlab/eeglab/sample_data/eeglab_data.set';
> cfg.headerfile = '~/data/matlab/eeglab/sample_data/eeglab_data.set';
> my_ft_data = ft_preprocessing(cfg);
>
> % Run ICA and IC label in EEGLAB
> EEG = fieldtrip2eeglab(my_ft_data, my_ft_data.trial);
> EEG = eeg_checkset(EEG);
> EEG = pop_runica(EEG, 'icatype', 'runica');
> EEG = pop_icflag(EEG, [0 0;0 0; 0.001 1; 0 0; 0 0; 0 0; 0 0]); % see
> function help message
> rejected_comps = find(EEG.reject.gcompreject > 0);
> EEG = pop_subcomp(EEG, rejected_comps);
> EEG = eeg_checkset(EEG);
>
> % convert back to Fieldtrip
> curPath = pwd;
> p = fileparts(which('ft_read_header'));
> cd(fullfile(p, 'private'));
> hdr = read_eeglabheader( EEG );
> data = read_eeglabdata( EEG, 'header', hdr );
> event = read_eeglabevent( EEG, 'header', hdr );
> cd(curPath);
>
>
>



More information about the eeglablist mailing list