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 nipype.algorithms.modelgen.

General purpose model specification

The SpecifyModel provides a generic mechanism for model specification. A mandatory input called subject_info provides paradigm specification for each run corresponding to a subject. This has to be in the form of a Bunch or a list of Bunch objects (one for each run). Each Bunch object contains the following attributes.

Required for most designs

  • conditions : list of names
  • onsets : lists of onsets corresponding to each condition
  • durations : lists of durations corresponding to each condition. Should be left to a single 0 if all events are being modeled as impulses.

Optional

  • regressor_names: list of names corresponding to each column. Should be None if automatically assigned.
  • regressors: list of lists. values for each regressor - must correspond to the number of volumes in the functional run
  • amplitudes: lists of amplitudes for each event. This will be ignored by SPM's Level1Design.

The following two (tmod, pmod) will be ignored by any Level1Design class other than SPM:

  • tmod: lists of conditions that should be temporally modulated. Should default to None if not being used.

  • pmod: list of Bunch corresponding to conditions

    • name: name of parametric modulator
    • param: values of the modulator
    • poly: degree of modulation

Together with this information, one needs to specify:

  • whether the durations and event onsets are specified in terms of scan volumes or secs.

  • the high-pass filter cutoff,

  • the repetition time per scan

  • functional data files corresponding to each run.

Optionally you can specify realignment parameters, outlier indices. Outlier files should contain a list of numbers, one per row indicating which scans should not be included in the analysis. The numbers are 0-based

Example

An example Bunch definition:

In [ ]:
from nipype.interfaces.base import Bunch
condnames = ['Tapping', 'Speaking', 'Yawning']
event_onsets = [[0, 10, 50],
                [20, 60, 80],
                [30, 40, 70]]
durations = [[0],[0],[0]]

subject_info = Bunch(conditions=condnames,
                     onsets = event_onsets,
                     durations = durations)
In [ ]:
subject_info
Out[ ]:
Bunch(conditions=['Tapping', 'Speaking', 'Yawning'],
      durations=[[0], [0], [0]],
      onsets=[[0, 10, 50], [20, 60, 80], [30, 40, 70]])

Input via textfile

Alternatively, you can provide condition, onset, duration and amplitude information through event files. The event files have to be in 1, 2 or 3 column format with the columns corresponding to Onsets, Durations and Amplitudes and they have to have the name event_name.run e.g.: Words.run001.txt.

The event_name part will be used to create the condition names. Words.run001.txt may look like:

# Word Onsets Durations
0   10
20   10
...

or with amplitudes:

# Word Onsets Durations Amplitudes
0    10     1
20   10    1
...

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]])]

Sparse model specification

In addition to standard models, SpecifySparseModel allows model generation for sparse and sparse-clustered acquisition experiments. Details of the model generation and utility are provided in Ghosh et al. (2009) OHBM 2009

Home | github | Nipype