[FieldTrip] R: automatic artifact rejection based on voltage threshold

eleonora parrotta eleonora_p at hotmail.it
Fri May 26 10:26:03 CEST 2023


Dear Dr. Ivaylo (Ivo) Iotchev

Thank you so much for sharing this!! May I ask you to clarify a few details about the code, please?
My questions are:
(a) Is this code supposed to eliminate trials based on a (1) peak-to-peak artifact rejection (2) based on the threshold voltage ?
Based on that, the voltage threshold would be different. For example, for the option (1) I would choose a voltage threshold that does not exceeds 100 microvolt (i.e., the difference between the maximum and minimum values) while for option (2) I would determine the artifact based on whether the voltage exceeds of either +50 or -50 microvolts.
(b) What is the difference between the absolute threshold and relative threshold specified in the code? I am referring to the variables called abs_thrs and rel_thrs, which you define before the onset of the loop.

Thank you again for your precious help,
Eleonora

Eleonora Parrotta,  Doctoral Researcher in Social Neuroscience
School of Psychology | University of Aberdeen | Aberdeen | AB24 3FX
e.parrotta.20 at abdn.ac.uk

________________________________
Da: Ivaylo Iotchev <ivaylo.iotchev at gmail.com>
Inviato: giovedì 25 maggio 2023 16:30
A: eleonora parrotta <eleonora_p at hotmail.it>
Cc: FieldTrip discussion list <fieldtrip at science.ru.nl>
Oggetto: Re: [FieldTrip] automatic artifact rejection based on voltage threshold

So this is the loop:

 data4.label                      %at this point of the script the data we are about to clean is called data4, cleaning happened after other manipulations (e.g. filter)
    chs_remaining=[5:8];   % which channels to use for the cleaning, in our case this was 5th to 8th

    excluded = [];                    %create matrix where excluded trials are collected
    for i = 1:size(data4.trial,2)   %we specify here that we are going through the trial indexes, i is defined as the number of trials
        dat=data4.trial{i}(chs_remaining,:); %we select the channels we want to clean from trial nr. i

        if any(any((dat>abs_thrs))) || any(any((dat<-abs_thrs))) % abs_thrs - absolute threshold, set at the begining of the script, this line applies thresholding
            excluded=[excluded i]; %we add a trial to excluded if above condition is met
        end

        if ~ismember(i,excluded) %the next lines select trials which survived the absolute threshold cleaning
            maxn=size(dat,2)-100;
            for n=1:maxn
                if any(max(dat(:,n:(n+100)),[],2)+abs(min(dat(:,n:(n+100)),[],2)) > rel_thrs) % rel_thrs - relative threshold, set at the begining of the script
                    excluded=[excluded i];
                end
            end
        end
    end

    cfg=[];
    cfg.trials = setdiff(1:size(data4.trial,2),excluded);
    data5=ft_redefinetrial(cfg,data4); %with these three lines we can finally integrate our cleaning with the FieldTripian ft_redefinetrial :)

I hope this helps. I can trace this work back to my colleagues Marianna Boros and Boglárka Morvai, but it is possible that these parts have an even older origin. Some additional comments were now added by me to support better understanding, to the extent to which I could do so :)

Best wishes, and success!

(Dr.) Ivaylo (Ivo) Iotchev

Am Do., 25. Mai 2023 um 16:11 Uhr schrieb eleonora parrotta <eleonora_p at hotmail.it<mailto:eleonora_p at hotmail.it>>:
That would be awesome, Dr. Ivaylo!
I've been trying to implement it for weeks!
Thank you so much for any help

Eleonora


Eleonora Parrotta,  Doctoral Researcher in Social Neuroscience
School of Psychology | University of Aberdeen | Aberdeen | AB24 3FX
e.parrotta.20 at abdn.ac.uk<mailto:e.parrotta.20 at abdn.ac.uk>

________________________________
Da: Ivaylo Iotchev <ivaylo.iotchev at gmail.com<mailto:ivaylo.iotchev at gmail.com>>
Inviato: giovedì 25 maggio 2023 14:50
A: FieldTrip discussion list <fieldtrip at science.ru.nl<mailto:fieldtrip at science.ru.nl>>
Cc: eleonora parrotta <eleonora_p at hotmail.it<mailto:eleonora_p at hotmail.it>>
Oggetto: Re: [FieldTrip] automatic artifact rejection based on voltage threshold

Hey Eleonora,

I might be able to send you some lines tomorrow which implement thresholding, these lines do not make direct use of FieldTrip I think, but they are MATLAB intern and thus can be coordinated within a script that uses Fieldtrip functions, too (basically that's what we are doing at the moment).

Best wishes,

(Dr.) Ivaylo (Ivo) Iotchev

Am Do., 25. Mai 2023 um 15:45 Uhr schrieb eleonora parrotta via fieldtrip <fieldtrip at science.ru.nl<mailto:fieldtrip at science.ru.nl>>:
Dear Fieldtrippers,
I am trying to implement an automatic artifact rejection on epoched data.
The aim of this process would be to compare the same dataset, analyzed both in fieldtrip and eeglab. To do so, I would need to efficiently implement the same EEGLAB parameters used for the artifact rejection in fieldtrip.
I have two options

  1.  eliminate the trials based on a peak-to-peak artifact rejection, which detects and remove trials in which the EEG signal exceeds of a threshold of 100 microvolt

  1.  eliminate the trials based on simple threshold voltage, that is, eliminate trials in which the voltage exceeds of +- 50 microvolts.

Both options would be fine as both are implemented in eeglab, but I do not manage to implement neither of the two into fieldtrip.
 I've tried to use both ft_artifact_threshold and ft_rejectartifact, even by combining the two.

ft_rejectartifact is not able not detect artifacts in the data, the output is always :

%artifact rejection
cfg = [];
cfg.artfctdef.channel = [1:28 31:65];
cfg.artfctdef.threshold.min = -50;
cfg.artfctdef.threshold.max = 50;
cfg.artfctdef.prestim = -0.1;
cfg.artfctdef.poststim = 0.6;
cfg.artfctdef.window = 'trial';
data_clean = ft_rejectartifact(cfg, clean_data);

the call to "ft_preprocessing" took 111 seconds
rejected   0 trials completely
rejected   0 trials partially
filled parts of   0 trials with NaNs
filled parts of   0 trials with zeros
filled parts of   0 trials with a specified value


This is an example of what I get when using the functions together..

cfg = [];
cfg.continuous = 'no';
cfg.artfctdef.channel = {'all', '-ECG1', '-ECG2', '-IO'};
cfg.dataset =clean_data.trial(:,:);
% cfg.artfctdef.threshold.min = -50;
% cfg.artfctdef.threshold.max = 50;
% cfg.artfctdef.threshold.range=100;
cfg.artfctdef.prestim = -0.1;
cfg.artfctdef.poststim = 0.6;
cfg.trl=trl;
[~, artData] = ft_artifact_threshold(cfg, clean_data);

cfg = [];
cfg.artfctdef.xxx.artifact = artData;
cfg.artfctdef.reject = 'complete';
fnData = ft_rejectartifact(cfg, clean_data);

The output seems to not be able to read the trials information, as it does not mark the trials but only segments in which there are artifacts:
searching for artifacts in 65 channels
applying preprocessing options
searching in trial 643 from 643
detected 7172 artifacts
the call to "ft_artifact_threshold" took 25 seconds
>>
cfg = [];
cfg.artfctdef.xxx.artifact = artData;
cfg.artfctdef.reject = 'complete';
fnData = ft_rejectartifact(cfg, clean_data);
detected   1 xxx artifacts
Index in position 2 exceeds array bounds. Index must not exceed 1.

Error in ft_rejectartifact (line 305)
    endsample = artifact{i}(:,2);

Please help me!!
Any support is appreciated
Thank you very much
Eleonora Parrotta,  Doctoral Researcher in Social Neuroscience
School of Psychology | University of Aberdeen | Aberdeen | AB24 3FX
e.parrotta.20 at abdn.ac.uk<mailto:e.parrotta.20 at abdn.ac.uk>

_______________________________________________
fieldtrip mailing list
https://mailman.science.ru.nl/mailman/listinfo/fieldtrip
https://urldefense.com/v3/__https://doi.org/10.1371/journal.pcbi.1002202__;!!HJOPV4FYYWzcc1jazlU!993zEvdLx9d3ghG_Xuz_1Iwj4P5K-FF-HlHz1f7Lt0M2LDh827WUJVkINZJsDACt6Pm2DhpexWjVBHniNemIhevNOsk$ 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.science.ru.nl/pipermail/fieldtrip/attachments/20230526/f423afa1/attachment.htm>


More information about the fieldtrip mailing list