quickstart.Rmd
bidser
bidser
is an R package for working with the BIDS neuroimaging projects. The goal of the package is to allow one to query files that are stored in a hierarchical BIDS structure. Below we load in a BIDS example project, which is stored and accessed through a bids_project
object.
There is a Python package called pybids that can be used to work with BIDS in Python and is more developed.
#> Loading bidser
library(bidser)
library(tibble)
library(gluedown)
proj_path <- system.file("inst/extdata/ds001", package="bidser")
proj <- bids_project(proj_path)
print(proj)
#> project: ds001
#> participants (n): 16
#> tasks: balloonanalogrisktask
#> image types: func
#> modalities:
#> keys: folder, kind, subid, suffix, type, run, task
We can see that this is a project with 16 participants with anatomical and functional scans and a task called balloonanalogrisktask.
We can also make some basic queries of the project to gather information. For example, does the project have any “sessions”?
sessions(proj)
#> NULL
No sessions. And what are the participant ids?
sids <- participants(proj)
Does it have task event files?
fnames <- head(basename(event_files(proj)), n=3)
## print the first three event files
Lets now search for some arbitrary files. For example, we wish to retrieve all the “T1w” anatomical images.
Now we search for any scans containing the string “bold”.
bold <- search_files(proj, "bold")
## take the first 5 files, since there are alot.
bold <- head(bold, 5)
If we are only interested in functional bolds scans (rather than any file with “bold” in it), there is a special function called func_scans
to return such files
fscans <- func_scans(proj)
## take the first 5 files, since there are alot.
fscans <- head(bold, 5)
Suppose though that we only want the scans from subject “16”?
fscans_16 <- func_scans(proj, subid="16")
BIDS event files describe the event-structure of fmri experiments. They can be easy read in to R as a set of data.frame
s using the read_events
function. As can be seen in the output below, read_events
returns a data.frame
with four columns: .subid
, .run
, .task
, data
. The data
is nested in the table because there is no guantee that all events files have the same columns (for example, event files associated with different tasks).
evs <- read_events(proj)
head(evs)
#> # A tibble: 6 x 4
#> # Groups: .subid, .run, .task [6]
#> .subid .run .task data
#> <chr> <chr> <chr> <list>
#> 1 01 01 balloonanalogrisktask <tibble [158 × 8]>
#> 2 01 02 balloonanalogrisktask <tibble [156 × 8]>
#> 3 01 03 balloonanalogrisktask <tibble [149 × 8]>
#> 4 02 01 balloonanalogrisktask <tibble [185 × 8]>
#> 5 02 02 balloonanalogrisktask <tibble [184 × 8]>
#> 6 02 03 balloonanalogrisktask <tibble [186 × 8]>
Now we can filter the table as we like, for example, to extract the data only from the first participant. We can then “unnest” the data
variable to access the actual event structure.
library(tidyr)
#>
#> Attaching package: 'tidyr'
#> The following object is masked from 'package:bidser':
#>
#> one_of
#> The following object is masked from 'package:testthat':
#>
#> matches
ev1 <- evs %>% filter(.subid == "01") %>% unnest(cols=c(data))
head(ev1)
#> # A tibble: 6 x 11
#> # Groups: .subid, .run, .task [1]
#> .subid .run .task onset duration trial_type cash_demean control_pumps_d…
#> <chr> <chr> <chr> <dbl> <dbl> <chr> <dbl> <dbl>
#> 1 01 01 balloon… 0.061 0.772 pumps_deme… NA NA
#> 2 01 01 balloon… 4.96 0.772 pumps_deme… NA NA
#> 3 01 01 balloon… 7.18 0.772 pumps_deme… NA NA
#> 4 01 01 balloon… 10.4 0.772 pumps_deme… NA NA
#> 5 01 01 balloon… 13.4 0.772 pumps_deme… NA NA
#> 6 01 01 balloon… 16.8 0.772 explode_de… NA NA
#> # … with 3 more variables: explode_demean <dbl>, pumps_demean <dbl>,
#> # response_time <dbl>
If you have processed a dataset with FMRIPrep, bidser
can be used to read in the many of the resultant derivative files. If a project has an FMRIPrep derivatives folder, then we can read in the BIDS hierarchy plus derivatives as follows:
proj_path <- system.file("inst/extdata/phoneme_stripped", package="bidser")
proj <- bids_project(proj_path, fmriprep=TRUE)
#> Warning in bids_project(proj_path, fmriprep = TRUE): dataset_description.json is
#> missing
print(proj)
#> project: phoneme_stripped
#> participants (n): 24
#> tasks: phoneme rest
#> fmriprep: derivatives/fmriprep
#> image types: func funcprep
#> modalities: bold
#> keys: folder, kind, subid, suffix, type, run, task, modality, space, label
By default it is assumed that the FMRIPrep files are in ‘derivatives/fmriprep’.
Now we can access various derivative files with convenience functions. For example, to read in “preproc” scans we can use the preproc_scans
function.
pscans <- preproc_scans(proj, subid="1001")
print(as.character(pscans))
#> [1] "derivatives/fmriprep/sub-1001/func/sub-1001_task-phoneme_run-01_bold_space-MNI152NLin2009cAsym_preproc.nii.gz"
#> [2] "derivatives/fmriprep/sub-1001/func/sub-1001_task-phoneme_run-02_bold_space-MNI152NLin2009cAsym_preproc.nii.gz"
#> [3] "derivatives/fmriprep/sub-1001/func/sub-1001_task-phoneme_run-03_bold_space-MNI152NLin2009cAsym_preproc.nii.gz"
#> [4] "derivatives/fmriprep/sub-1001/func/sub-1001_task-phoneme_run-04_bold_space-MNI152NLin2009cAsym_preproc.nii.gz"
#> [5] "derivatives/fmriprep/sub-1001/func/sub-1001_task-phoneme_run-05_bold_space-MNI152NLin2009cAsym_preproc.nii.gz"
#> [6] "derivatives/fmriprep/sub-1001/func/sub-1001_task-phoneme_run-06_bold_space-MNI152NLin2009cAsym_preproc.nii.gz"
#> [7] "derivatives/fmriprep/sub-1001/func/sub-1001_task-phoneme_run-07_bold_space-MNI152NLin2009cAsym_preproc.nii.gz"
#> [8] "derivatives/fmriprep/sub-1001/func/sub-1001_task-phoneme_run-08_bold_space-MNI152NLin2009cAsym_preproc.nii.gz"
#> [9] "derivatives/fmriprep/sub-1001/func/sub-1001_task-phoneme_run-09_bold_space-MNI152NLin2009cAsym_preproc.nii.gz"
#> [10] "derivatives/fmriprep/sub-1001/func/sub-1001_task-phoneme_run-10_bold_space-MNI152NLin2009cAsym_preproc.nii.gz"