View on GitHub

BIDS workshop

resources for a BIDS workshop

BIDS apps

Note that if you do not have a BIDS dataset at hand, you can use one of BIDS dataset from SPM12 tutorials.

Table of content

BIDS apps are software packages that take a BIDS dataset as input. For a longer definition, see the nipreps documentation.

They also have the same way to be called from the command line.

app_name    bids_dir output_dir analysis_level \
            [app specific arguments and parameters]

The list of existing BIDS apps is available here: https://bids-apps.neuroimaging.io/apps/

Note that most BIDS apps will have a --help flag that you can use to get information about all the possible arguments and parameters that you can use.

Containerized BIDS apps: docker

To make them easier to install most BIDS apps are “containerized” using Docker.

You can learn more about containers, on the Turing way jupyter book and on the nipreps website.

You can then download the app by “pulling its image” by running a command like:

docker pull app_repository/app_name:version

An image is pretty much a virtual machine that contains all the software needed to run the app.

To see all the images you have on your computer, you can run:

docker images

This can give an output that looks like this:

REPOSITORY         TAG       IMAGE ID       CREATED         SIZE
nipreps/fmriprep   latest    bff6645c2142   12 days ago     12GB
nipreps/mriqc      latest    7ed42219c6f9   4 weeks ago     15.6GB

This shows that we have MRIQC which is a Quality Control pipeline for MRI data and FMRIprep which is a preprocessing pipeline for fMRI data.

When running a BIDS app by using its docker image you need to call docker run in the following way:

docker  run \
        [docker arguments and parameters] \
        app_repository/app_name:version \
        bids_dir output_dir analysis_level \
        [app specific arguments and parameters]

Typical docker arguments and parameters are:

Another options that can be useful for “debugging” is the --entrypoint parameter followed by a command to run. That can be used to start bash terminal in the container to explore its content.

For example, to start a bash terminal in the MRIQC container you can

docker  run -it --rm \
        --entrypoint /bin/bash \
        nipreps/mriqc:latest

Your terminal default prompt should have changed now show you something like this:

root@17c3eeb3fc5a:/tmp#

You can get out of the container by typing exit.

Note that your are by default a “root” user in the container, pretty much meaning that you have “administrator” rights when inside the container.

“Mapping” folders inside the container

When running a BIDS app using docker, you need to “map” some folders from your computer inside the container.

This would be done with then -v flag followed by

For example:

docker  run -it --rm \
        -v /path/to/bids_dataset:/bids_dataset \
        app_repository/app_name:version \
        /bids_dataset /output_dir participant

Let’s try again using the MRIQC image:

docker  run -it --rm \
        --entrypoint /bin/bash \
        -v ~/:/home/me \
        nipreps/mriqc:latest

The ~/ is a shortcut for your “home” folder on your computer.

The /home/me is the absolute path to the folder in the container.

Once you have run this command this should have opened a bash terminal in the container and you can now list the content of this folder using the ls command:

ls /home/me

and it should show you the content of your home folder on your computer.

You can now add a file to this folder and then list the content of the folder again by rerunning the same command.

This file should also appear in the container.

Exit the container by typing exit.

Running a docker as non-root user

Relaunch the MRIQC container:

docker  run -it --rm \
        --entrypoint /bin/bash \
        -v ~/:/home/me \
        nipreps/mriqc:latest

Now try to create an empty test file in the /home/me folder using the touch command:

touch /home/me/test.txt

If you now try to open and edit this file on your computer you will see that you cannot save it, because you do not have “write” permission to this file because it was created by a root user from inside the container.

This can be annoying when working with BIDS apps because it makes it harder to work with the files that are created by the app.

Exit the container by typing exit and reopen it with the following command with the --user "$(id -u):$(id -g)" parameter:

docker  run -it --rm \
        --user "$(id -u):$(id -g)" \
        --entrypoint /bin/bash \
        -v ~/:/home/me \
        nipreps/mriqc:latest

If you now try to create an empty test file in the /home/me:

touch /home/me/test_2.txt

You will see that you can edit AND save this file.

Running a BIDS app using docker

Now we can start running a BIDS app using docker.

The general command would look like this:

docker  run -it --rm \
        --user "$(id -u):$(id -g)" \
        -v /path/to/bids_dataset:/bids_dataset \
        -v /path/to/output_dir:/output_dir \
        app_repository/app_name:version \
        /bids_dataset /output_dir analysis_level

Writing those commands can be a bit tedious, and getting all the paths right is usually the main source of errors.

To help with this, it can help to always use the same folder structure to organize where you put your data and where you run your BIDS apps from.

You for example use something like the following one that is very similar to the “YODA” structure recommended by the datalad team.

├── code
│   └── README.md
├── inputs
│   └── raw             # this is your BIDS dataset
└── outputs

There is template for such folder in the template directory.

In this case, if you are running commands from within the code folder, you would run a bids docker container like this by using relative paths:

docker  run -it --rm \
        --user "$(id -u):$(id -g)" \
        -v $PWD/../inputs/raw:/bids_dataset \
        -v $PWD/../outputs:/output_dir \
        app_repository/app_name:version \
        /bids_dataset /output_dir analysis_level

Note that $PWD refers to a terminal varible that means ‘Present Working Directory’.

So to run MRIQC we would then do:

docker  run -it --rm \
        --user "$(id -u):$(id -g)" \
        -v $PWD/../inputs/raw:/bids_dataset \
        -v $PWD/../outputs/mriqc:/output_dir \
        nipreps/mriqc:latest \
        /bids_dataset /output_dir participant

App specific arguments and parameters

MRIQC

Check the MRIQC options either by using the --help flag or checking the online documentation.

docker  run -it --rm \
        nipreps/mriqc:latest \
        /bids_dataset /output_dir participant \
        --help

Some of the most frequent options would will be using are:

For example:

docker  run -it --rm \
        --user "$(id -u):$(id -g)" \
        -v $PWD/../inputs/raw:/bids_dataset \
        -v $PWD/../outputs/mriqc:/output_dir \
        nipreps/mriqc:latest \
        /bids_dataset /output_dir participant \
        --participant-labels 01 \
        --task-id auditory

If you find that MRIQC is “too quiet” and you are afraid that something has crashed you can always run it in verbose mode by using the --verbose or -v flag

docker  run -it --rm \
        --user "$(id -u):$(id -g)" \
        -v $PWD/../inputs/raw:/bids_dataset \
        -v $PWD/../outputs/mriqc:/output_dir \
        nipreps/mriqc:latest \
        /bids_dataset /output_dir participant \
        --verbose \
        --participant-labels 01 \
        --task-id auditory

MRIQC outputs follows filenaming patterns and for each file it provides you with a nice HTML report that you can open in your browser.

Specific quality metrics are also provided in a json file.

This would be an example output you can get after running MRIQC.

├── logs
├── sub-01
│   ├── anat
│   │   └── sub-01_T1w.json
│   └── func
│       └── sub-01_task-auditory_bold.json
├── README.md
├── dataset_description.json
├── sub-01_T1w.html
└── sub-01_task-auditory_bold.html

fMRIPrep

Running fMRIprep is very similar to running MRIQC.

Once again either use the --help flag or check the online documentation to find out more about the options.

One of the important options for fMRIprep is the --fs-license-file option that you use to specify where to find the Freesurfer license file. More information in the online documentation.

Here what we can do is put the license in the code folder and then mount the code folder in the container.

One major difference with MRIQC is that fMRIPrep takes much longer to run because it must run the entire Freesurfer processing pipeline (usually around 6 hours).

Because running fMRIprep takes so long it can be a good thing to keep the intermediate results that fmriprep generates so you don’t start from 0 if it crashes.

To do this we can mount a temporary folder into the container and define it as a working directory for fMRIprep to use by making use of the -w parameter.

So we can launch the following command from within the code folder.

docker  run -it --rm \
        --user "$(id -u):$(id -g)" \
        -v $PWD:/code \
        -v $PWD/../inputs/raw:/bids_dataset \
        -v $PWD/../outputs/fmriprep:/output_dir \
        -v $PWD/../outputs/tmp:/tmp \
        nipreps/fmriprep:latest \
        /bids_dataset /output_dir participant \
        --verbose \
        --participant-label 01 \
        --task-id auditory \
        --fs-license-file /code/license.txt \
        --work-dir /tmp

If you want to see what the output would look like, you can download an example of the output of fMRIPrep here.

fMRIprep outputs is also BIDS compliant dataset and you can find extensive additional information about the output in the documentation.

The fmriprep/logs/CITATION.md file contains a standardised method section that describre the preprocessing that you should use when publishing your results.