Model Specification for 1st-Level fMRI Analysis

Nipype provides also an interfaces to create a first level Model for an fMRI analysis. Such a model is needed to specify the study specific information, such as condition, their onsets and durations. For more information, make sure to check out Model Specificaton and nipype.algorithms.modelgen

Simple Example

Let's consider a simple experiment, where we have three different stimuli such as 'faces', 'houses' and 'scrambled pix'. Now each of those three conditions has different stimuli onsets, but all of them have a stimuli presentation duration of 3 seconds.

So to summarize:

conditions = ['faces', 'houses', 'scrambled pix']
onsets = [[0, 30, 60, 90],
          [10, 40, 70, 100],
          [20, 50, 80, 110]]
durations = [[3], [3], [3]]

The way we would create this model with Nipype is almsot as simple as that. The only step that is missing is to put this all into a Bunch object. This can be done as follows:


In [ ]:
from nipype.interfaces.base import Bunch

conditions = ['faces', 'houses', 'scrambled pix']
onsets = [[0, 30, 60, 90],
          [10, 40, 70, 100],
          [20, 50, 80, 110]]
durations = [[3], [3], [3]]

subject_info = Bunch(conditions=conditions,
                     onsets=onsets,
                     durations=durations)

It's also possible to specify additional regressors. For this you need to additionally specify:

  • regressors: list of regressors that you want to include in the model (must correspond to the number of volumes in the functional run)
  • regressor_names: name of the regressors that you want to include

Example based on dataset

Now let's look at a TSV file from our tutorial dataset.


In [ ]:
!cat /data/ds000114/task-fingerfootlips_events.tsv


onset	duration	weight	trial_type
10	15.0		1	Finger
40	15.0		1	Foot
70	15.0		1	Lips
100	15.0		1	Finger
130	15.0		1	Foot
160	15.0		1	Lips
190	15.0		1	Finger
220	15.0		1	Foot
250	15.0		1	Lips
280	15.0		1	Finger
310	15.0		1	Foot
340	15.0		1	Lips
370	15.0		1	Finger
400	15.0		1	Foot
430	15.0		1	Lips

We can also use pandas to create a data frame from our dataset.


In [ ]:
import pandas as pd
trialinfo = pd.read_table('/data/ds000114/task-fingerfootlips_events.tsv')
trialinfo.head()


Out[ ]:
onset duration weight trial_type
0 10 15.0 1 Finger
1 40 15.0 1 Foot
2 70 15.0 1 Lips
3 100 15.0 1 Finger
4 130 15.0 1 Foot

Before we can use the onsets, we first need to split them into the three conditions:


In [ ]:
for group in trialinfo.groupby('trial_type'):
    print(group)


('Finger',     onset  duration  weight trial_type
0      10      15.0       1     Finger
3     100      15.0       1     Finger
6     190      15.0       1     Finger
9     280      15.0       1     Finger
12    370      15.0       1     Finger)
('Foot',     onset  duration  weight trial_type
1      40      15.0       1       Foot
4     130      15.0       1       Foot
7     220      15.0       1       Foot
10    310      15.0       1       Foot
13    400      15.0       1       Foot)
('Lips',     onset  duration  weight trial_type
2      70      15.0       1       Lips
5     160      15.0       1       Lips
8     250      15.0       1       Lips
11    340      15.0       1       Lips
14    430      15.0       1       Lips)

The last thing we now need to to is to put this into a Bunch object and we're done:


In [ ]:
from nipype.interfaces.base import Bunch

conditions = []
onsets = []
durations = []

for group in trialinfo.groupby('trial_type'):
    conditions.append(group[0])
    onsets.append(group[1].onset.tolist())
    durations.append(group[1].duration.tolist())

subject_info = Bunch(conditions=conditions,
                     onsets=onsets,
                     durations=durations)
subject_info.items()


Out[ ]:
[('conditions', ['Finger', 'Foot', 'Lips']),
 ('onsets',
  [[10, 100, 190, 280, 370],
   [40, 130, 220, 310, 400],
   [70, 160, 250, 340, 430]]),
 ('durations',
  [[15.0, 15.0, 15.0, 15.0, 15.0],
   [15.0, 15.0, 15.0, 15.0, 15.0],
   [15.0, 15.0, 15.0, 15.0, 15.0]])]