highspeed-bids-docs.Rmd 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. ```{r, echo=FALSE, message=FALSE, include=FALSE}
  2. if (!requireNamespace("pacman")) install.packages("pacman")
  3. packages_cran <- c("here")
  4. pacman::p_load(char = packages_cran)
  5. if (basename(here::here()) == "highspeed"){
  6. path_root = here::here("highspeed-bids")
  7. } else {
  8. path_root = here::here()
  9. }
  10. ```
  11. ## MRI data to BIDS
  12. ### Overview
  13. #### Data availability
  14. The data is freely available from https://github.com/lnnrtwttkhn/highspeed-bids and https://gin.g-node.org/lnnrtwttkhn/highspeed-bids.
  15. #### License
  16. The dataset is licensed under Creative Commons Attribution-ShareAlike 4.0.
  17. Please see https://creativecommons.org/licenses/by-sa/4.0/ for details.
  18. ### Step 1: Conversion of MRI data to the Brain Imaging Data Structure (BIDS) using HeuDiConv
  19. #### Overview
  20. 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.
  21. Please see the [paper by Gorgoleski et al., 2016, *Scientific Data*](https://www.nature.com/articles/sdata201644) for details.
  22. In short, BIDS is a community standard for organizing and describing MRI datasets.
  23. #### Container: `heudiconv` container, version 0.6.0
  24. We used [HeuDiConv](https://github.com/nipy/heudiconv), version 0.6.0, to convert our MRI DICOM data to the BIDS structure.
  25. First, we created a Singularity container with HeuDiConv in our cluster environment at the Max Planck Institute for Human Development, Berlin Germany.
  26. The Singularity container is separately available at [https://github.com/lnnrtwttkhn/tools](https://github.com/lnnrtwttkhn/tools) and was created using:
  27. ```bash
  28. singularity pull docker://nipy/heudiconv:0.6.0
  29. ```
  30. 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):
  31. #### Mapping raw DICOMS to BIDS: `highspeed-heudiconv-heuristic.py`
  32. `highspeed_heudiconv_heuristic.py` is a Python script, that creates a mapping between the DICOMS and the NIfTI-converted files in the BIDS structure.
  33. ```{python, echo=TRUE, code=readLines(file.path(path_root, "code", "heudiconv", "highspeed-heudiconv-heuristic.py")), eval=FALSE, python.reticulate=FALSE}
  34. ```
  35. #### Changing participant IDs: `highspeed-heudiconv-anonymizer.py`
  36. `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)
  37. ```{python, echo=TRUE, code=readLines(file.path(path_root, "code", "heudiconv", "highspeed-heudiconv-anonymizer.py")), eval=FALSE, python.reticulate=FALSE}
  38. ```
  39. As a side note, the last step is not really necessary since zero-padded numbers are not required by the BIDS standard.
  40. #### Running `heudiconv` on the cluster: `highspeed-heudiconv-cluster.sh`
  41. `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.
  42. Note, that for privacy concerns we only saved the BIDS-converted data in the repo after running the defacing (see details below).
  43. ```{bash, echo=TRUE, code=readLines(file.path(path_root, "code", "heudiconv", "highspeed-heudiconv-cluster.sh")), eval=FALSE}
  44. ```
  45. 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).
  46. All analyses reported in the paper were based on the **pre-normalized data**.
  47. 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)).
  48. #### Resources
  49. The following resources helped along the way (thank you, people on the internet!):
  50. * [Heudiconv documentation](https://heudiconv.readthedocs.io/en/latest/index.html)
  51. * ["Heudiconv: Example Usage" - Tutorial by James Kent](https://slides.com/jameskent/deck-3#/)
  52. * ["Heudiconv on multiple subjects" - Discussion on neurostars.org](https://neurostars.org/t/heudiconv-on-multiple-subjects/1344)
  53. * ["Heudiconv across multiple sessions" - Discussion on neurostars.org](https://neurostars.org/t/heudiconv-across-multiple-sessions/1281/9)
  54. * ["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)
  55. * ["DICOM to BIDS conversion" - A YouTube tutorial](https://www.youtube.com/watch?time_continue=4&v=pAv9WuyyF3g)
  56. * ["BIDS Tutorial Series: HeuDiConv Walkthrough" - A tutorial by the Stanford Center for Reproducible Neuroscience](http://reproducibility.stanford.edu/bids-tutorial-series-part-2a/)
  57. ### Step 2: Removal of facial features using [pydeface](https://github.com/poldracklab/pydeface)
  58. #### Overview
  59. Facial features need to be removed from structural images before sharing the data online.
  60. See the statement from [openfmri.org](https://openfmri.org/de-identification/) below regarding the importance of defacing:
  61. > *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.*
  62. and a second statement from the [openneuro.org FAQs](https://openneuro.org/faq):
  63. > *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.*
  64. #### Container: `pydeface` container, version 2.0.0
  65. 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)
  66. To ensure robustness of the defacing procedure, we used a Singularity container for `pydeface`, which we installed as follows:
  67. ```bash
  68. singularity pull docker://poldracklab/pydeface:37-2e0c2d
  69. ```
  70. All scripts that we used for defacing can be found in the `code/defacing` directory.
  71. #### Defacing structural images: `highspeed-defacing-cluster.sh`
  72. First, we ran `highspeed-defacing-cluster.sh` to deface all structural images that can be found in the corresponding BIDS data set.
  73. Note, that this script was optimized to run on the high performance cluster of the Max Planck Institute for Human Development, Berlin.
  74. ```{bash, echo=TRUE, code=readLines(file.path(path_root, "code", "defacing", "highspeed-defacing-cluster.sh")), eval=FALSE}
  75. ```
  76. #### Replacing defaced with original images: `highspeed-defacing-cleanup.sh`
  77. `pydeface` creates a new file with the ending `T1w_defaced.nii.gz`.
  78. 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.
  79. This can be done separately after `pydeface` was run.
  80. 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`.
  81. ```{bash, echo=TRUE, code=readLines(file.path(path_root, "code", "defacing", "highspeed-defacing-cleanup.sh")), eval=FALSE}
  82. ```
  83. #### Resources
  84. * ["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!)
  85. * ["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!)
  86. ### Step 3: Adding BIDS `*events.tsv` files
  87. #### Overview
  88. According to the [BIDS specification](https://bids-specification.readthedocs.io/en/stable/04-modality-specific-files/05-task-events.html) ...
  89. > The purpose of this file is to describe timing and other properties of events recorded during the scan.
  90. Thus, we transformed all behavioral data that was acquired during the scanning sessions to run-specific `*events.tsv` files that are compatible with the BIDS standard.
  91. #### Code and software
  92. We mainly used two MATLAB files that were run in MATLAB version R2017b. The code takes the original behavioral data files acquired during scanning as input and returns run-specific BIDS-compatible `*events.tsv` files.
  93. ```{octave, echo=TRUE, code=readLines(file.path(path_root, "code", "events", "highspeed_bids_events.m")), eval=FALSE}
  94. ```
  95. ```{octave, echo=TRUE, code=readLines(file.path(path_root, "code", "events", "extract_bids_events.m")), eval=FALSE}
  96. ```
  97. ### Step 4: Adding additional information to the BIDS dataset
  98. #### Code and software
  99. First, we created a virtual environment using Python version 3.8.5 to install all dependencies and required packages.
  100. 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`.
  101. ```bash
  102. mkvirtualenv highspeed-bids -p $(which python3)
  103. ````
  104. ```bash
  105. $ python --version
  106. Python 3.8.5
  107. ````
  108. #### Updating `dataset_description.json`: `python highspeed-bids-description.py`
  109. `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.
  110. ```bash
  111. datalad run -m "create dataset_description.json" --output "dataset_description.json" "python3 code/bids_conversion/highspeed-bids-description.py"
  112. ```
  113. ```{python, echo=TRUE, code=readLines(file.path(path_root, "code", "bids_conversion", "highspeed-bids-description.py")), eval=FALSE, python.reticulate=FALSE}
  114. ```
  115. #### Updating the `.json` files of fieldmap data: `python highspeed-bids-fieldmaps.py`
  116. During later pre-processing of MRI data with `fMRIPrep`, we want to use our fieldmap data for distortion correction.
  117. 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).
  118. This is done using the `code/bids_conversion/highspeed-bids-fieldmaps.py` file.
  119. To detect the provencance of the run command in our DataLad dataset, we run:
  120. ```bash
  121. datalad run -m "create IntendedFor fields in fieldmap .json files" \
  122. --input "./*/*/*/*.nii.gz" --output "./*/*/fmap/*.json" \
  123. "python3 code/code/bids_conversion/highspeed_bids_fieldmaps.py"
  124. ```
  125. ```{python, echo=TRUE, code=readLines(file.path(path_root, "code", "bids_conversion", "highspeed-bids-fieldmaps.py")), eval=FALSE, python.reticulate=FALSE}
  126. ```
  127. #### Creating the `participants.tsv` and `participants.json` files
  128. According to the [BIDS specification, version 1.1.0](https://bids.neuroimaging.io/bids_spec1.1.0.pdf) ...
  129. > [...] the purpose of this file is to describe properties of participants such as age, handedness, sex, etc. In case of single session studies this file has one compulsory column participant_id that consists of sub-<participant_label> , followed by a list of optional columns describing participants. Each participant needs to be described by one and only one row.
  130. In our case, this information was saved in the original behavioral data files that were created when participants performed the task during scanning.
  131. To extract this information from the behavioral files into the `participants.tsv` file we use the `code/events/highspeed_bids_participants.m` file.
  132. Since wrapping the execution of this script into a `datalad` run command appeared challenging, we just ran the script with paths not self-contained and just saved the changes in files.
  133. First, we had to unlock the `participants.tsv` file using `datalad unlock participants.tsv`
  134. The we ran `highspeed_bids_participants.m` using MATLAB version R2017b and saved the changes using `datalad save`.
  135. ```{octave, echo=TRUE, code=readLines(file.path(path_root, "code", "events", "highspeed_bids_participants.m")), eval=FALSE}
  136. ```
  137. Finally, we create the `participants.json` file using:
  138. ```bash
  139. datalad run -m "create participants.json" \
  140. --output "participants.json" \
  141. "python3 code/bids_conversion/highspeed-bids-participants.py"
  142. ```
  143. ```{python, echo=TRUE, code=readLines(file.path(path_root, "code", "bids_conversion", "highspeed-bids-participants.py")), eval=FALSE, python.reticulate=FALSE}
  144. ```