highspeed-bids-docs.Rmd 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. ---
  2. title: "Faster than thought: Detecting sub-second activation sequences with sequential fMRI pattern analysis"
  3. subtitle: "Short project title: highspeed"
  4. author:
  5. - Lennart Wittkuhn^[Max Planck Institute for Human Development, wittkuhn@mpib-berlin.mpg.de]
  6. - Nicolas W. Schuck^[Max Planck Institute for Human Development, schuck@mpib-berlin.mpg.de]
  7. date: "Last update: `r format(Sys.time(), '%d %B, %Y')`"
  8. output:
  9. html_document:
  10. toc: true
  11. self_contained: true
  12. toc_float: true
  13. toc_depth: 3
  14. number_sections: true
  15. highlight: pygments
  16. theme: cosmo
  17. df_print: paged
  18. fig_caption: true
  19. fig.align: "center"
  20. header-includes:
  21. - \usepackage{fontspec}
  22. - \setmainfont{AgfaRotisSansSerif}
  23. email: wittkuhn@mpib-berlin.mpg.de
  24. ---
  25. ```{r, libraries, echo=FALSE, message=FALSE, include=FALSE}
  26. if (!requireNamespace("pacman")) install.packages("pacman")
  27. packages_cran <- c("here")
  28. pacman::p_load(char = packages_cran)
  29. if (basename(here::here()) == "highspeed"){
  30. path_root = here::here("highspeed-bids")
  31. } else {
  32. path_root = here::here()
  33. }
  34. ```
  35. # BIDS conversion
  36. ## Data availability
  37. The data is freely available from https://github.com/lnnrtwttkhn/highspeed-bids and https://gin.g-node.org/lnnrtwttkhn/highspeed-bids.
  38. ## License
  39. The BIDS dataset is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 4.0.
  40. Please see https://creativecommons.org/licenses/by-nc-sa/4.0/ for details.
  41. ## Step 1: Conversion of MRI data to the Brain Imaging Data Structure (BIDS) using HeuDiConv
  42. ### Overview
  43. After MRI data was acquired at the MRI scanner, we converted all data to adhere to the [Brain Imaging Data Structure (BIDS)](http://bids.neuroimaging.io/) standard.
  44. Please see the [paper by Gorgoleski et al., 2016, *Scientific Data*](https://www.nature.com/articles/sdata201644) for details.
  45. In short, BIDS is a community standard for organizing and describing MRI datasets.
  46. ### Code and software
  47. #### `heudiconv` container, version 0.6.0
  48. We used [HeuDiConv](https://github.com/nipy/heudiconv), version 0.6.0, to convert our MRI DICOM data to the BIDS structure.
  49. First, we created a Singularity container with HeuDiConv in our cluster environment at the Max Planck Institute for Human Development, Berlin Germany.
  50. The Singularity container is separately available at [https://github.com/lnnrtwttkhn/tools](https://github.com/lnnrtwttkhn/tools) and was created using:
  51. ```bash
  52. singularity pull docker://nipy/heudiconv:0.6.0
  53. ```
  54. For the conversion of DICOM data acquired at the MRI scanner to BIDS-converted NIfTI-files the following scripts were used (these scripts can be found in the in the `code/heudiconv/` directory):
  55. #### Mapping raw DICOMS to BIDS: `highspeed-heudiconv-heuristic.py`
  56. `highspeed_heudiconv_heuristic.py` is a Python script, that creates a mapping between the DICOMS and the NIfTI-converted files in the BIDS structure.
  57. ```{python, echo=TRUE, code=readLines(file.path(path_root, "code", "heudiconv", "highspeed-heudiconv-heuristic.py")), eval=FALSE, python.reticulate=FALSE}
  58. ```
  59. #### Changing participant IDs: `highspeed-heudiconv-anonymizer.py`
  60. `highspeed-heudiconv-anonymizer.py` is an executable Python script, which is used in combination with the `--anon-cmd` flag of the `heudiconv` command that turns the original participant IDs (that we used when we ran the study in the lab) into consecutive zero-padded numbers (see [this thread on neurostars.org](https://neurostars.org/t/heudiconv-how-to-turn-subject-ids-into-consecutive-zero-padded-numbers-as-required-by-bids/2240) for details)
  61. ```{python, echo=TRUE, code=readLines(file.path(path_root, "code", "heudiconv", "highspeed-heudiconv-anonymizer.py")), eval=FALSE, python.reticulate=FALSE}
  62. ```
  63. As a side note, the last step is not really necessary since zero-padded numbers are not required by the BIDS standard.
  64. #### Running `heudiconv` on the cluster: `highspeed-heudiconv-cluster.sh`
  65. `highspeed-heudiconv-cluster.sh` is a bash script that parallelizes the HeuDiConv command for each participant on the high-performance cluster of the Max Planck Institute for Human Development Berlin, Germany.
  66. Note, that for privacy concerns we only saved the BIDS-converted data in the repo after running the defacing (see details below).
  67. ```{bash, echo=TRUE, code=readLines(file.path(path_root, "code", "heudiconv", "highspeed-heudiconv-cluster.sh")), eval=FALSE}
  68. ```
  69. We acquired both pre-normalized and non-normalized MRI data (see e.g., [here](https://practicalfmri.blogspot.com/2012/04/common-persistent-epi-artifacts-receive.html) for more information on pre-normalization).
  70. All analyses reported in the paper were based on the **pre-normalized data**.
  71. Only the pre-normalized data set is published because uploading the dataset in two versions (with- and without pre-normalization) would otherwise cause interference when running fMRIPrep (see [here](https://neurostars.org/t/addressing-multiple-t1w-images/4959)).
  72. ### Resources
  73. The following resources helped along the way (thank you, people on the internet!):
  74. * [Heudiconv documentation](https://heudiconv.readthedocs.io/en/latest/index.html)
  75. * ["Heudiconv: Example Usage" - Tutorial by James Kent](https://slides.com/jameskent/deck-3#/)
  76. * ["Heudiconv on multiple subjects" - Discussion on neurostars.org](https://neurostars.org/t/heudiconv-on-multiple-subjects/1344)
  77. * ["Heudiconv across multiple sessions" - Discussion on neurostars.org](https://neurostars.org/t/heudiconv-across-multiple-sessions/1281/9)
  78. * ["Heudiconv: How to turn subject IDs into consecutive zero-padded numbers as required by BIDS?" - Discussion on neurostars.org](https://neurostars.org/t/heudiconv-how-to-turn-subject-ids-into-consecutive-zero-padded-numbers-as-required-by-bids/2240)
  79. * ["DICOM to BIDS conversion" - A YouTube tutorial](https://www.youtube.com/watch?time_continue=4&v=pAv9WuyyF3g)
  80. * ["BIDS Tutorial Series: HeuDiConv Walkthrough" - A tutorial by the Stanford Center for Reproducible Neuroscience](http://reproducibility.stanford.edu/bids-tutorial-series-part-2a/)
  81. ## Step 2: Removal of facial features using [pydeface](https://github.com/poldracklab/pydeface)
  82. ### Overview
  83. Facial features need to be removed from structural images before sharing the data online.
  84. See the statement from [openfmri.org](https://openfmri.org/de-identification/) below regarding the importance of defacing:
  85. > *To protect the privacy of the individuals who have been scanned we require that all subjects be de-identified before publishing a dataset. For the purposes of fMRI de-facing is the preferred method de-identification of scan data. Skull stripped data will not be accepted for publication.*
  86. and a second statement from the [openneuro.org FAQs](https://openneuro.org/faq):
  87. > *Yes. We recommend using pydeface. Defacing is strongly prefered over skullstripping, because the process is more robust and yields lower chance of accidentally removing brain tissue.*
  88. ### Code and software
  89. #### `pydeface` container, version 2.0.0
  90. Defacing of all structural images was performed using [`pydeface`](https://github.com/poldracklab/pydeface), version 2.0.0. (with nipype version 1.3.0-rc1)
  91. To ensure robustness of the defacing procedure, we used a Singularity container for `pydeface`, which we installed as follows:
  92. ```bash
  93. singularity pull docker://poldracklab/pydeface:37-2e0c2d
  94. ```
  95. All scripts that we used for defacing can be found in the `code/defacing` directory.
  96. #### Defacing structural images: `highspeed-defacing-cluster.sh`
  97. First, we ran `highspeed-defacing-cluster.sh` to deface all structural images that can be found in the corresponding BIDS data set.
  98. Note, that this script was optimized to run on the high performance cluster of the Max Planck Institute for Human Development, Berlin.
  99. ```{bash, echo=TRUE, code=readLines(file.path(path_root, "code", "defacing", "highspeed-defacing-cluster.sh")), eval=FALSE}
  100. ```
  101. #### Replacing defaced with original images: `highspeed-defacing-cleanup.sh`
  102. `pydeface` creates a new file with the ending `T1w_defaced.nii.gz`.
  103. As `fMRIPrep`, `MRIQC` and other tools need to use the defaced instead of the original image, we need to replace the original with the defaced image.
  104. This can be done separately after `pydeface` was run.
  105. In order to replace the original structural images with the defaced once ([as recommended](https://neurostars.org/t/defaced-anatomical-data-fails-bids-validator/3636)), we ran `highspeed-defacing-cleanup.sh`.
  106. ```{bash, echo=TRUE, code=readLines(file.path(path_root, "code", "defacing", "highspeed-defacing-cleanup.sh")), eval=FALSE}
  107. ```
  108. ### Resources
  109. * ["Pydeface defaces structural data only?!"](https://neurostars.org/t/pydeface-defaces-structural-data-only/903) - Discussion on neurostars.org if any other data than structural acquisitions should be defaced (short answer: no!)
  110. * ["Is/how much fmriprep (freesurfer et al) is resilient to “defacing”?"](https://neurostars.org/t/is-how-much-fmriprep-freesurfer-et-al-is-resilient-to-defacing/2642) - Discussion on neurostars.org if `fMRIPrep` works well with defaced data (short answer: yes!)
  111. ## Step 3: Adding additional information to the BIDS dataset
  112. ### Code and software
  113. First, we created a virtual environment using Python version 3.8.5 to install all dependencies and required packages.
  114. A list of all required packages can be found in `requirements.txt` (created using `pip freeze > requirements.txt`) and installed via `pip install -r requirements.txt`.
  115. ```bash
  116. mkvirtualenv highspeed-bids -p $(which python3)
  117. ````
  118. ```bash
  119. (highspeed-bids) lip-osx-003854:highspeed-bids wittkuhn$ python --version
  120. Python 3.8.5
  121. ````
  122. #### Updating `dataset_description.json`: `python highspeed-bids-description.py`
  123. `highspeed-bids-description.py` is a short Python script that loads the `dataset_description.json` file that is pre-generated by HeuDiConv and populates it with the relevant study informtion.
  124. ```{python, echo=TRUE, code=readLines(file.path(path_root, "code", "bids_conversion", "highspeed-bids-description.py")), eval=FALSE, python.reticulate=FALSE}
  125. ```
  126. #### Updating the `.json` files of fieldmap data: `python highspeed-bids-fieldmaps.py`
  127. During later pre-processing of MRI data with `fMRIPrep`, we want to use our fieldmap data for distortion correction.
  128. To ensure that `fMRIPrep` detects and uses the fieldmap data, we need to add the `IntendedFor` field to the `.json` files of the fieldmap data and provide relative paths to the functional task data (see [here](https://bids-specification.readthedocs.io/en/latest/04-modality-specific-files/01-magnetic-resonance-imaging-data.html#fieldmap-data) for more information).
  129. This is done using the `code/bids_conversion/highspeed-bids-fieldmaps.py` file.
  130. To detect the provencance of the run command in our DataLad dataset, we run:
  131. ```bash
  132. datalad run -m "create IntendedFor fields in fieldmap .json files" \
  133. --input "./*/*/*/*.nii.gz" --output "./*/*/fmap/*.json" \ "python3 code/code/bids_conversion/highspeed_bids_fieldmaps.py ."
  134. ```
  135. ```{python, echo=TRUE, code=readLines(file.path(path_root, "code", "bids_conversion", "highspeed-bids-fieldmaps.py")), eval=FALSE, python.reticulate=FALSE}
  136. ```