Trigger-based trial selection

This tutorial describes how to define epochs-of-interest (trials) from your recorded MEG-data, and how to apply the different preprocessing steps. This tutorial does not show yet how to analyze (e.g. average) your data.

If you are interested in how to do preprocessing on your data prior to segmenting it into trials, you can check the Preprocessing - Reading continuous data tutorial. There, you can also find information about how to preprocess EEG data. If you want to learn how to segment EEG data into trials, check the tutorial on Preprocessing of EEG data and computing ERPs.

In FieldTrip the preprocessing of data refers to the reading of the data, segmenting the data around interesting events such as triggers, temporal filtering and optionally rereferencing. The ft_preprocessing function takes care of all these steps, i.e., it reads the data and applies the preprocessing options.

There are largely two alternative approaches for preprocessing, which especially differ in the amount of memory required. The first approach is to read all data from the file into memory, apply filters, and subsequently cut the data into interesting segments. The second approach is to first identify the interesting segments, read those segments from the data file and apply the filters to those segments only. The remainder of this tutorial explains the second approach, as that is the most appropriate for large data sets such as the MEG data used in this tutorial. The approach for reading and filtering continuous data and segmenting afterwards is explained in another tutorial.

Preprocessing involves several steps including identifying individual trials from the dataset, filtering and artifact rejections. This tutorial covers how to identify trials using the trigger signal. Defining data segments of interest can be done

  • according to a specified trigger channel
  • according to your own criteria when you write your own trial function

Examples for both ways are described in this tutorial, and both ways depend on ft_definetrial.

The output of ft_definetrial is a configuration structure containing the field cfg.trl. This is a matrix representing the relevant parts of the raw datafile which are to be selected for further processing. Each row in the trl-matrix represents a single epoch-of-interest, and the trl-matrix has at least 3 columns. The first column defines (in samples) the beginpoint of each epoch with respect to how the data are stored in the raw datafile. The second column defines (in samples) the endpoint of each epoch, and the third column specifies the offset (in samples) of the first sample within each epoch with respect to timepoint 0 within that epoch.

The MEG data set used in the tutorials is from a language study on semantically congruent and incongruent sentences that is described in detail in Wang et al. (2012). Three types of sentences were used in the experiment. In the fully congruent condition (FC) the sentences ended with a high-cloze probability word, e.g. De klimmers bereikten eindelijk de top van de berg (The climbers finally reached the top of the mountain) In the fully incongruent condition (FIC) sentences ended with a semantically anomalous word which was totally unexpected given the sentential context, e.g., De klimmers bereikten eindelijk de top van de tulp (The climbers finally reached the top of the tulip). The third type of sentences ended with a semantically anomalous word that had the same initial phonemes (and lexical stress) as the high-cloze words from the congruent condition: initially congruent (IC). There were 87 trials per condition for each of the three conditions, and a set of 87 filler sentences were added. From the EEG literature it is known that a stronger negative potential is produced following incongruent compared to congruent sentence endings about 300-500 ms after the word onset. This response is termed the N400 effect¹ ². For more information about the materials take a look at the published EEG experiment using the same sentence materials³.

In the study applied here, the subjects were seated in a relaxed position under the MEG helmet. Their task was to attentively listen to spoken sentences. They were informed that some of the sentences would be semantically anomalous. Acoustic transducers were used to deliver the auditory stimuli. After a 300-ms warning tone, followed by a 1200 ms pause, a sentence was presented. Every next trial began 4100 ms after the offset of the previous sentence. To reduce eye blinks and movements in the time interval in which the sentence was presented, subjects were instructed to fixate on an asterisk presented visually 1000 ms prior to the beginning of the sentence. The asterisk remained on the screen until 1600 ms after the onset of the spoken sentence. Subjects were encouraged to blink when the asterisk was not displayed on the screen.

MEG signals were recorded with a 151 sensor CTF Omega System (VSM MedTech Ltd.,Port Coquitlam, Canada). In addition, the EOG was recorded to later discard trials contaminated by eye movements and blinks. The ongoing MEG and EOG signals were lowpass filtered at 100 Hz, digitized at 300 Hz and stored for off-line analysis. To measure the head position with respect to the sensors, three coils were placed at anatomical landmarks of the head (nasion, left and right ear canal). While the subjects were seated under the MEG helmet, the positions of the coils were determined before and after the experiment by measuring the magnetic signals produced by currents passed through the coils.

The MEG data are stored as epochs or trials of fixed length around each stimulus trigger, i.e. the file does not represent a continuous record of the data and the data in the inter-trial-interval is not stored. The consequence is that the data cannot be represented as a continuous record, as at the epoch boundaries there is a discontinuity. See also the background on the CTF system.

Magnetic resonance images (MRIs) were obtained with a 1.5 T Siemens system. During the MRI scans ear molds with small containers filled with vitamin E marked the same anatomical landmarks. This allows for realignment of the MRIs to the MEG coordinate system according to the anatomical landmarks.

  1. Kutas M, Hillyard SA. (1980) Reading senseless sentences: brain potentials reflect semantic incongruity. Science. 207(4427):203-5
  2. Kutas M, Federmeier KD. (2000) Electrophysiology reveals semantic memory use in language comprehension. Trends Cogn Sci. 4(12):463-470
  3. van den Brink D, Brown CM, & Hagoort P. (2001). Electrophysiological evidence for early contextual influences during spoken-word recognition: N200 versus N400 effects. J Cogn Neurosci. 13(7):967-985
  4. Wang L, Jensen O, van den Brink D, Weder N, Schoffelen JM, Magyari L, Hagoort P, Bastiaansen M. (2012) Beta oscillations relate to the N400m during language comprehension. Hum Brain Mapp. 2012 Dec;33(12):2898-912.
2009/03/17 14:00

The following steps are taken in this tutorial:

Using the FieldTrip function ft_definetrial you can define the pieces of data that will be read in for preprocessing. Trials are defined by their begin and end sample in the data file and each trial has an offset that defines where the relative t=0 point (usually the point of the stimulus-trigger) is for that trial.

The ft_definetrial and ft_preprocessing functions require the original MEG dataset, which is available at

Do the trial definition for the fully incongruent (FIC) condition:

  cfg                         = [];
  cfg.dataset                 = 'Subject01.ds';
  cfg.trialfun                = 'ft_trialfun_general'; % this is the default
  cfg.trialdef.eventtype      = 'backpanel trigger';
  cfg.trialdef.eventvalue     = 3; % the value of the stimulus trigger for fully incongruent (FIC).
  cfg.trialdef.prestim        = 1; % in seconds
  cfg.trialdef.poststim       = 2; % in seconds
  cfg = ft_definetrial(cfg);

This results in a cfg.trl in which the beginning, the trigger offset and the end of each trial relative to the beginning of the raw data is defined.

The output of ft_definetrial can be used for ft_preprocessing.    = {'MEG' 'EOG'};
cfg.continuous = 'yes';
dataFIC = ft_preprocessing(cfg);

Save the preprocessed data to disk:

save PreprocData dataFIC

The output of ft_preprocessing is the structure dataFIC which has the following fields:

dataFIC = 
           hdr: [1x1 struct]
         label: {152x1 cell}
          time: {1x87 cell}
         trial: {1x87 cell}
       fsample: 300
    sampleinfo: [87x2 double]
     trialinfo: [87x1 double]
          grad: [1x1 struct]
           cfg: [1x1 struct]

The most important fields are dataFIC.trial containing the individual trials and dataFIC.time containing the time vector for each trial. To visualize the single trial data (trial 1) on one channel (channel 130) do the following:

  plot(dataFIC.time{1}, dataFIC.trial{1}(130,:))

The preprocessing steps will be repeated for the other conditions as well.

The initially congruent (IC) condition:

cfg                         = [];
cfg.dataset                 = 'Subject01.ds';
cfg.trialdef.eventtype      = 'backpanel trigger';  
cfg.trialdef.eventvalue     = 5; % the value of the stimulus trigger for initially congruent (IC).
cfg.trialdef.prestim        = 1; % in seconds
cfg.trialdef.poststim       = 2; % in seconds

cfg = ft_definetrial(cfg);    = {'MEG' 'EOG'};
cfg.continuous = 'yes';
dataIC = ft_preprocessing(cfg);

Save the preprocessed data to disk:

save PreprocData dataIC -append

And the fully congruent (FC) condition:

cfg                         = [];
cfg.dataset                 = 'Subject01.ds';
cfg.trialdef.eventtype      = 'backpanel trigger';
cfg.trialdef.eventvalue     = 9; % the value of the stimulus trigger for fully congruent (FC).
cfg.trialdef.prestim        = 1; % in seconds
cfg.trialdef.poststim       = 2; % in seconds
cfg = ft_definetrial(cfg);    = {'MEG' 'EOG'};
cfg.continuous = 'yes';
dataFC = ft_preprocessing(cfg);

Save the preprocessed data to disk:

save PreprocData dataFC -append

These functions demonstrate how to extract trials from a dataset based on trigger information. Note that some of these trials will be contaminated with various artifact such as eye blinks or MEG sensor jumps. Artifact rejection is described in Preprocessing - Visual artifact rejection

There are often cases in which it is not sufficient to define a trial only according to a given trigger signal. For instance you might want to accept or reject a trial according to a button response recorded by the trigger channel as well. Another example might be that you want the signals from the EMG or A/D channel being part of the trial selection. In those cases it is necessary to define a specialized function for trial selections. Below is an example which can be adapted to your needs.

function trl = mytrialfun(cfg);

% this function requires the following fields to be specified
% cfg.dataset
% cfg.trialdef.eventtype
% cfg.trialdef.eventvalue
% cfg.trialdef.prestim
% cfg.trialdef.poststim

hdr   = ft_read_header(cfg.dataset);
event = ft_read_event(cfg.dataset);
trl = [];
for i=1:length(event)
  if strcmp(event(i).type, cfg.trialdef.eventtype)
    % it is a trigger, see whether it has the right value
    if ismember(event(i).value, cfg.trialdef.eventvalue)
      % add this to the trl definition
      begsample     = event(i).sample - cfg.trialdef.prestim*hdr.Fs;
      endsample     = event(i).sample + cfg.trialdef.poststim*hdr.Fs - 1;
      offset        = -cfg.trialdef.prestim*hdr.Fs;  
      trigger       = event(i).value; % remember the trigger (=condition) for each trial
      trl(end+1, :) = [round([begsample endsample offset])  trigger]; 

Save the trial function together with your other scripts as mytrialfun.m. To ensure that ft_preprocessing is making use of the new trial function use the commands

cfg = [];
cfg.dataset  = 'Subject01.ds'; 
cfg.trialfun = 'mytrialfun'; % ft_definetrial will call your function and pass on the cfg
cfg.trialdef.eventtype  = 'backpanel trigger';
cfg.trialdef.eventvalue = [3 5 9]; % read all conditions at once
cfg.trialdef.prestim    = 1; % in seconds
cfg.trialdef.poststim   = 2; % in seconds
cfg = ft_definetrial(cfg); = {'MEG' 'STIM'};
dataMytrialfun = ft_preprocessing(cfg);

When you do not specify cfg.trialfun, ft_definetrial will call a function named trialfun_general as default. Then trials will be defined as we have seen it in the earlier section (Reading and preprocessing the interesting trials).

The output dataMytrialfun now contains all of the trials of the three conditions (since we specified all three triggers values: 3, 5 and 9). It also contains a field dataMytrialfun.trialinfo, which contains the 4th column of the trl (trial definition) which contains the trigger values, i.e., it tells you to which condition each trial belongs:

dataMytrialfun = 

           hdr: [1x1 struct]
         label: {152x1 cell}
          time: {1x261 cell}
         trial: {1x261 cell}
       fsample: 300
    sampleinfo: [261x2 double]
     trialinfo: [261x1 double]
          grad: [1x1 struct]
           cfg: [1x1 struct]

More on the trialinfo field can be found in the faq.

After having finished this tutorial on preprocessing, you can continue with the event related averaging or with the time-frequency analysis tutorial.

If you have more questions about preprocessing, you can also read the following faq-s:

2010/04/06 15:58 Robert Oostenveld
2009/11/11 15:59  
2013/03/17 12:22 Robert Oostenveld
2012/12/24 11:39 Robert Oostenveld
2014/10/30 17:37  
2009/02/17 15:13 Robert Oostenveld
2010/09/29 12:27 Cristiano Micheli
2011/08/25 21:39 Robert Oostenveld
2010/03/31 15:59 Robert Oostenveld
2009/06/29 12:23 Robert Oostenveld
2015/06/25 10:53 Robert Oostenveld
2014/09/25 19:55  
2009/02/17 15:15 Robert Oostenveld
2010/06/25 13:40 Jan-Mathijs Schoffelen
2009/03/25 09:23  
2009/02/17 15:17 Robert Oostenveld
2009/02/17 15:13 Robert Oostenveld
2009/02/17 15:15 Robert Oostenveld
2015/02/18 15:36 Robert Oostenveld
2010/07/27 10:27 Jan-Mathijs Schoffelen
2010/12/21 21:50 Jan-Mathijs Schoffelen
2010/12/03 13:50 Robert Oostenveld

Or you can also read the example scripts:

This tutorial was last tested with version 20120501 of FieldTrip using MATLAB 2009b on a 64-bit Linux platform.