SPM/BIDS

From Wikibooks, open books for an open world
< SPM
Jump to navigation Jump to search



Brain Imaging Data Structure[edit]

The Brain Imaging Data Structure (BIDS) is a simple and intuitive way to organise and describe neuroimaging and behavioural data.

Standard specification[edit]

Validator[edit]

Discussion Forums[edit]

Tutorials[edit]

Publications[edit]

The brain imaging data structure, a format for organizing and describing outputs of neuroimaging experiments. Gorgolewski K.J., Auer T., Calhoun V.D., Craddock R.C., Das S., Duff E.P., Flandin G., Ghosh S.S., Glatard T., Halchenko Y.O., Handwerker D.A., Hanke M., Keator D., Li X., Michael Z., Maumet C., Nichols B.N., Nichols T.E., Pellman J., Poline J.-B., Rokem A., Schaefer G., Sochat V., Triplett W., Turner J.A., Varoquaux G. & Poldrack R.A. Scientific Data 3, 160044 (2016).

MEG-BIDS, the brain imaging data structure extended to magnetoencephalography. Niso G., Gorgolewski K.J., Bock E., Brooks T.L., Flandin G., Gramfort A., Henson R.N., Jas M., Litvak V., Moreau J.T., Oostenveld R., Schoffelen J.-M., Tadel F., Wexler J. & Baillet S. Scientific Data 5, 180110 (2018).

BIDS apps: Improving ease of use, accessibility, and reproducibility of neuroimaging data analysis methods. Gorgolewski K.J., Alfaro-Almagro F., Auer T., Bellec P., Capota M., Chakravarty M.M., Churchill N.W., Cohen A.L., Craddock R.C., Devenyi G.A., Eklund A., Esteban O., Flandin G., Ghosh S.S., Guntupalli J.S., Jenkinson M., Keshavan A., Kiar G., Liem F., Raamana P.R., Raffelt D., Steele C.J., Quirion P.-O., Smith R.E., Strother S.C., Varoquaux G., Wang Y., Yarkoni T. & Poldrack R.A. PLoS Computational Biology 13(3):e1005209 (2017).

BIDS Tools in SPM/MATLAB[edit]

SPM provides a number of functionalities (MATLAB/Octave functions) to facilitate the creation or use of datasets formatted according to BIDS.

JSON files[edit]

A JSON file can be read/written using spm_jsonread and spm_jsonwrite.

>> type sub-01_task-rest_bold.json           

{
  "RepetitionTime": 3.0,
  "Instruction": "Lie still and keep your eyes open"
}
>> bold = spm_jsonread('sub-01_task-rest_bold.json')

bold = 

    RepetitionTime: 3
       Instruction: 'Lie still and keep your eyes open'
>> descr = struct('Name','My Dataset','BIDSVersion','1.0.2')              

descr = 

           Name: 'My Dataset'
    BIDSVersion: '1.0.2'

>> spm_jsonwrite('dataset_description.json',descr, struct('indent','  '));
>> type dataset_description.json                                          

{
  "Name": "My Dataset",
  "BIDSVersion": "1.0.2"
}

These functions are also independently available in JSONio, a JSON library for MATLAB and Octave. They are compatible with MATLAB's jsonencode and jsondecode.

TSV files[edit]

A tab-separated values (TSV) file can be read/written using spm_load and spm_save.

>> type task-Checkerboard_acq-TR645_events.tsv    

onset   duration        trial_type
0       20      Fixation
20      20      Checkerboard
40      20      Fixation
60      20      Checkerboard
80      20      Fixation
100     20      Checkerboard
>> events = spm_load('task-Checkerboard_acq-TR645_events.tsv')

events = 

         onset: [6x1 double]
      duration: [6x1 double]
    trial_type: {6x1 cell}
>> p = struct('participant_id',{{'sub-01','sub-02'}}, 'sex',{{'M','F'}}, 'age',[28 21])

p = 

    participant_id: {'sub-01'  'sub-02'}
               sex: {'M'  'F'}
               age: [28 21]

>> spm_save('participants.tsv',p)                                                      
>> type participants.tsv                                                               

participant_id  sex     age
sub-01  M       28
sub-02  F       21

These functions are compatible with MATLAB table array and handle gzip compression transparently.

>> participant_id = {'sub-01'; 'sub-02'};
>> sex = {'M'; 'F'}; 
>> age = [28 21]';  
>> p = table(participant_id,sex,age);
>> spm_save('participants.tsv.gz',p) 
>> spm_load('participants.tsv.gz')   

ans = 

    participant_id: {2x1 cell}
               sex: {2x1 cell}
               age: [2x1 double]

NIfTI files[edit]

NIfTI files can be read/written using spm_vol or @nifti.

>> S = nifti('sub-2475376__T1w.nii')
 
S = 
 
NIFTI object: 1-by-1
            dat: [256x256x192 file_array]
            mat: [4x4 double]
     mat_intent: 'Scanner'
           mat0: [4x4 double]
    mat0_intent: 'Scanner'
        descrip: 'MR'

>> F = nifti('sub-2475376_task-Checkerboard_bold.nii')
 
F = 
 
NIFTI object: 1-by-1
            dat: [4-D file_array]
            mat: [4x4 double]
     mat_intent: 'Scanner'
           mat0: [4x4 double]
    mat0_intent: 'Scanner'
         timing: [1x1 struct]
        descrip: '4D image'

>> F.timing.tspace

ans =

    1.4000

By default, SPM does not support compressed NIfTI files (.nii.gz) but MATLAB/Octave provide gzip/gunzip functions if needed and they are also available through the batch interface from BasicIO > File Operations > Gunzip Files.

BIDS parser and queries[edit]

A data directory organised according to BIDS can be parsed with spm_BIDS.

Here is an example using the ds007 dataset:

>> % Parse BIDS directory
>> BIDS = spm_BIDS('/data/BIDS-examples/ds007');

>> % Make general queries about the dataset
>> spm_BIDS(BIDS,'subjects')           
ans = 
    '01'  '02'  '03'  '04'  '05'  '06'  '07'  '08'  '09'  '10'  '11'  '12'  '13'  '14'  '15'  '16'  '17'  '18'  '19'  '20'

>> spm_BIDS(BIDS,'sessions')
ans = 
    Empty cell array: 1-by-0

>> spm_BIDS(BIDS,'runs')    
ans = 
    '01'    '02'

>> spm_BIDS(BIDS,'tasks') 
ans = 
    'stopsignalwithletternaming'    'stopsignalwithmanualresponse'    'stopsignalwithpseudowordnaming'

>> spm_BIDS(BIDS,'types')
ans = 
    'T1w'    'bold'    'events'    'inplaneT2'

>> spm_BIDS(BIDS,'modalities')
ans = 
    'anat'    'func'

>> % Make more specific queries
>> spm_BIDS(BIDS,'runs','type','T1w')     
ans = 
   Empty cell array: 1-by-0

>> spm_BIDS(BIDS,'runs','type','bold')
ans = 
    '01'    '02'

>> % Get the NIfTI file for subject '05', run '02' and task 'stopsignalwithmanualresponse':
>> spm_BIDS(BIDS,'data','sub','05','run','02','task','stopsignalwithmanualresponse','type','bold')

ans = 

    '/data/ds007/sub-05/func/sub-05_task-stopsignalwithmanualresponse_run-02_bold.nii.gz'

>> % and corresponding metadata, including TR:
>> spm_BIDS(BIDS,'metadata','sub','05','run','02','task','stopsignalwithmanualresponse','type','bold')

ans = 

    RepetitionTime: 2
          TaskName: 'stop signal with manual response'

>> % Get the T1-weighted images from all subjects:
>> spm_BIDS(BIDS,'data','type','T1w')                                                                 

ans = 

    '/data/ds007/sub-01/anat/sub-01_T1w.nii.gz'
    '/data/ds007/sub-02/anat/sub-02_T1w.nii.gz'
    '/data/ds007/sub-03/anat/sub-03_T1w.nii.gz'
    '/data/ds007/sub-04/anat/sub-04_T1w.nii.gz'
    '/data/ds007/sub-05/anat/sub-05_T1w.nii.gz'
    '/data/ds007/sub-06/anat/sub-06_T1w.nii.gz'
    '/data/ds007/sub-07/anat/sub-07_T1w.nii.gz'
    '/data/ds007/sub-08/anat/sub-08_T1w.nii.gz'
    '/data/ds007/sub-09/anat/sub-09_T1w.nii.gz'
    '/data/ds007/sub-10/anat/sub-10_T1w.nii.gz'
    '/data/ds007/sub-11/anat/sub-11_T1w.nii.gz'
    '/data/ds007/sub-12/anat/sub-12_T1w.nii.gz'
    '/data/ds007/sub-13/anat/sub-13_T1w.nii.gz'
    '/data/ds007/sub-14/anat/sub-14_T1w.nii.gz'
    '/data/ds007/sub-15/anat/sub-15_T1w.nii.gz'
    '/data/ds007/sub-16/anat/sub-16_T1w.nii.gz'
    '/data/ds007/sub-17/anat/sub-17_T1w.nii.gz'
    '/data/ds007/sub-18/anat/sub-18_T1w.nii.gz'
    '/data/ds007/sub-19/anat/sub-19_T1w.nii.gz'
    '/data/ds007/sub-20/anat/sub-20_T1w.nii.gz'

Formatting datasets into BIDS[edit]

Helper functions spm_mkdir and spm_copy might come handy, as well as previously mentionned spm_save and spm_jsonwrite.

For example, the following piece of code using spm_mkdir:

>> spm_mkdir('/data/bids',{'sub-2475376','sub-5489652'},{'ses-1','ses-2'},'func');
>> spm_mkdir('/data/bids',{'sub-2475376','sub-5489652'},'ses-1','anat');

creates this directory hierarchy:

/data
└── bids
    ├── sub-2475376
    │   ├── ses-1
    │   │   ├── anat
    │   │   └── func
    │   └── ses-2
    │       └── func
    └── sub-5489652
        ├── ses-1
        │   ├── anat
        │   └── func
        └── ses-2
            └── func

while spm_copy makes it easier to copy files and their attached metadata (e.g. sidecar JSON files) with compression on the fly.

>> ls
sub-2475376_task-rest_bold.json
sub-2475376_task-rest_bold.nii.gz
>> spm_copy('sub-2475376_task-rest_bold.nii.gz','/derivatives', 'nifti',true, 'gunzip',true)
>> ls /derivatives
sub-2475376_task-rest_bold.json
sub-2475376_task-rest_bold.nii

See also these options in the batch interface:

  • The DICOM Import batch module has an option to create metadata sidecar JSON files:
matlabbatch{1}.spm.util.import.dicom.convopts.meta = true;
  • The 3D to 4D File Conversion batch module has an option to store the TR in the NIfTI header:
matlabbatch{1}.spm.util.cat.RT = TR;

See also[edit]

SPM BIDS-App