Skip to content

Commit 66acecc

Browse files
tsalorwblair
andauthored
Finalize BIDS Atlas compliance (#1584)
Co-authored-by: Ross Blair <rosswilsonblair@gmail.com>
1 parent 64500f4 commit 66acecc

File tree

55 files changed

+1276
-2681
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+1276
-2681
lines changed

.circleci/config.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ orbs:
55
.dockersetup:
66
&dockersetup
77
docker:
8-
- image: pennlinc/xcp_d_build:0.0.22
8+
- image: pennlinc/xcp_d_build:0.0.24
99
working_directory: /src/xcp_d
1010

1111
runinstall:
@@ -77,15 +77,15 @@ jobs:
7777
steps:
7878
- checkout
7979
- restore_cache:
80-
key: schaefer100-02
80+
key: schaefer100-05
8181
- run: *runinstall
8282
- run:
8383
name: Download BIDS-Atlas dataset
8484
command: |
8585
cd /src/xcp_d/.circleci
8686
python get_data.py $PWD/data schaefer100
8787
- save_cache:
88-
key: schaefer100-02
88+
key: schaefer100-05
8989
paths:
9090
- /src/xcp_d/.circleci/data/schaefer100
9191

@@ -179,7 +179,7 @@ jobs:
179179
- restore_cache:
180180
key: fmriprepwithoutfreesurfer-03
181181
- restore_cache:
182-
key: schaefer100-02
182+
key: schaefer100-05
183183
- run: *runinstall
184184
- run:
185185
name: Run full xcp_d on nifti without freesurfer
@@ -525,7 +525,7 @@ jobs:
525525
- restore_cache:
526526
key: nibabies-04
527527
- restore_cache:
528-
key: schaefer100-02
528+
key: schaefer100-05
529529
- run: *runinstall
530530
- run:
531531
name: Run pytest on the tests directory

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM pennlinc/xcp_d_build:0.0.22
1+
FROM pennlinc/xcp_d_build:0.0.24
22

33
# Install xcp_d
44
COPY . /src/xcp_d

docs/outputs.rst

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ The *XCP-D* outputs are written out in BIDS format and consist of three main pa
2121
`BEP012: Functional preprocessing derivatives <https://github.com/bids-standard/bids-specification/pull/519>`_,
2222
`BEP017: Relationship & connectivity matrix data schema <https://docs.google.com/document/d/1ugBdUF6dhElXdj3u9vw0iWjE6f_Bibsro3ah7sRV0GA/edit?usp=sharing>`_,
2323
and
24-
`BEP038: Atlas Specification <https://docs.google.com/document/d/1RxW4cARr3-EiBEcXjLpSIVidvnUSHE7yJCUY91i5TfM/edit?usp=sharing>`_.
2524

2625
In cases where a derivative type is not covered by an existing BEP,
2726
we have simply attempted to follow the general principles of BIDS.
@@ -97,22 +96,19 @@ For more information about the 4S atlas, please see https://github.com/PennLINC/
9796
You can also skip other postprocessing steps using the ``--skip`` parameter.
9897
See :ref:`usage_cli` for more information about the ``--skip`` parameter.
9998

100-
Atlases are written out to the ``atlases`` subfolder, following BEP038.
99+
Atlases are written out to the ``atlases`` subfolder, following BIDS formatting.
101100

102101
.. code-block::
103102
104103
xcp_d/
105104
atlases/
106105
dataset_description.json
107-
atlas-<label>/
108-
atlas-<label>_dseg.json
109-
atlas-<label>_dseg.tsv
110-
111-
# NIfTI
112-
atlas-<label>_space-<label>_dseg.nii.gz
113-
114-
# CIFTI
115-
atlas-<label>_space-<label>_dseg.dlabel.nii
106+
atlas-<label>_description.json
107+
tpl-<label>/
108+
tpl-<label>_atlas-<label>[_res-<label>][_den-<label>][_desc-<label>]_dseg.json
109+
tpl-<label>_atlas-<label>[_res-<label>][_den-<label>][_desc-<label>]_dseg.tsv
110+
tpl-<label>_atlas-<label>[_res-<label>][_den-<label>][_desc-<label>]_dseg.nii.gz
111+
tpl-<label>_atlas-<label>[_res-<label>][_den-<label>][_desc-<label>]_dseg.dlabel.nii
116112
117113
118114
******************

docs/usage.rst

Lines changed: 26 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -587,31 +587,24 @@ External Atlases
587587
While *XCP-D* comes with many built-in parcellations,
588588
we understand that many users will want to use different ones.
589589

590-
As long as the parcellation is organized in a BIDS-Atlas dataset and is in
590+
As long as the parcellation is organized according to BIDS v1.11.0 and is in
591591
fsLR-32k space (for CIFTI processing) or
592592
MNIInfant, MNI152NLin6Asym, or MNI152NLin2009cAsym space (for NIfTI processing),
593593
you can use it with *XCP-D*.
594594

595-
.. warning::
596-
BIDS Extension Proposal 38 (Atlas Specification) has not been integrated in BIDS yet,
597-
so the organization and naming for atlas datasets may change in the future.
598-
599-
We have attempted to follow the proposed structure in *XCP-D*,
600-
but we cannot guarantee that this will not change.
601-
602595
.. tip::
603596
The main elements from the BIDS-Atlas dataset that *XCP-D* uses are:
604597

605-
1. There must be a dataset_description.json file with DatasetType set to "atlas".
598+
1. There must be a dataset_description.json file with DatasetType set to "derivative".
606599
2. The atlas metadata files must have the same entities as the atlas image files,
607-
as PyBIDS does not support the inheritance principle when querying BIDS-Atlas datasets (yet).
608-
3. There must be a TSV file for the atlas, with "index" and "label" columns.
600+
as PyBIDS does not support the inheritance principle when querying atlas datasets (yet).
601+
3. There must be a TSV file for the atlas, with "index" and "name" columns.
609602

610603
To do this, use the ``--datasets`` and ``--atlases`` parameters.
611604
The ``--datasets`` parameter should point to the directory containing the BIDS-Atlas dataset,
612605
and the ``--atlases`` parameter should include the names of the atlases in the dataset to use.
613606

614-
For example, consider a scenario where you have two BIDS-Atlas datasets, one containing all of the
607+
For example, consider a scenario where you have two BIDS atlas datasets, one containing all of the
615608
Schaefer 2018 resolutions and one containing the AAL atlas.
616609
These datasets are in ``/data/atlases/schaefer`` and ``/data/atlases/aal``, respectively.
617610
The file structure for these two datasets might look like this:
@@ -621,25 +614,28 @@ The file structure for these two datasets might look like this:
621614
/data/atlases/
622615
schaefer/
623616
dataset_description.json
624-
atlas-Schaefer100/
625-
atlas-Schaefer100_dseg.tsv
626-
atlas-Schaefer100_space-fsLR_den-32k_dseg.dlabel.nii
627-
atlas-Schaefer100_space-fsLR_den-32k_dseg.json
628-
atlas-Schaefer200/
629-
atlas-Schaefer200_dseg.tsv
630-
atlas-Schaefer200_space-fsLR_den-32k_dseg.dlabel.nii
631-
atlas-Schaefer200_space-fsLR_den-32k_dseg.json
617+
atlas-Schaefer100_description.json
618+
atlas-Schaefer200_description.json
632619
...
633-
atlas-Schaefer1000/
634-
atlas-Schaefer1000_dseg.tsv
635-
atlas-Schaefer1000_space-fsLR_den-32k_dseg.dlabel.nii
636-
atlas-Schaefer1000_space-fsLR_den-32k_dseg.json
620+
atlas-Schaefer1000_description.json
621+
tpl-fsLR/
622+
tpl-fsLR_atlas-Schaefer100_den-32k_dseg.dlabel.nii
623+
tpl-fsLR_atlas-Schaefer100_den-32k_dseg.json
624+
tpl-fsLR_atlas-Schaefer100_den-32k_dseg.tsv
625+
tpl-fsLR_atlas-Schaefer200_den-32k_dseg.dlabel.nii
626+
tpl-fsLR_atlas-Schaefer200_den-32k_dseg.json
627+
tpl-fsLR_atlas-Schaefer200_den-32k_dseg.tsv
628+
...
629+
tpl-fsLR_atlas-Schaefer1000_den-32k_dseg.dlabel.nii
630+
tpl-fsLR_atlas-Schaefer1000_den-32k_dseg.json
631+
tpl-fsLR_atlas-Schaefer1000_den-32k_dseg.tsv
637632
aal/
638633
dataset_description.json
639-
atlas-AAL/
640-
atlas-AAL_dseg.tsv
641-
atlas-AAL_space-fsLR_den-32k_dseg.dlabel.nii
642-
atlas-AAL_space-fsLR_den-32k_dseg.json
634+
atlas-AAL_description.json
635+
tpl-fsLR/
636+
tpl-fsLR_atlas-AAL_den-32k_dseg.dlabel.nii
637+
tpl-fsLR_atlas-AAL_den-32k_dseg.json
638+
tpl-fsLR_atlas-AAL_den-32k_dseg.tsv
643639
644640
You may want to only apply the Schaefer100 atlas from the ``schaefer`` dataset and the AAL atlas
645641
from the ``aal`` dataset, along with one of *XCP-D*'s built-in atlases (``4S156Parcels``).
@@ -653,7 +649,7 @@ Here's what the *XCP-D* call might look like:
653649
/home/user/data/path/to/output_dir \
654650
participant \ # analysis_level
655651
--mode <mode> \ # required
656-
--datasets schaefer=/home/user/data/path/to/schaefer_atlas aal==/home/user/data/path/to/aal_atlas \
652+
--datasets schaefer=/data/atlases/schaefer aal==/data/atlases/aal \
657653
--atlases Schaefer100 AAL 4S156Parcels
658654
659655
*XCP-D* will search for ``atlas-Schaefer100``, ``atlas-AAL``, and ``atlas-4S156Parcels`` across the
@@ -662,7 +658,7 @@ If the atlases are found, then they will be used for parcellation.
662658

663659
.. important::
664660

665-
Atlas names must be unique across BIDS-Atlas datasets.
661+
Atlas names must be unique across BIDS atlas datasets.
666662
If two atlases have the same name, *XCP-D* will raise an error.
667663

668664

xcp_d/cli/parser.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1181,7 +1181,7 @@ def _validate_parameters(opts, build_log, parser):
11811181
opts.skip_outputs.append('parcellation')
11821182
if opts.atlases:
11831183
if 'xcpdatlases' not in opts.datasets:
1184-
opts.datasets['xcpdatlases'] = load_data('atlases')
1184+
opts.datasets['xcpdatlases'] = Path('/XCPDAtlases')
11851185

11861186
if any(atlas.startswith('4S') for atlas in opts.atlases):
11871187
if 'xcpd4s' not in opts.datasets:

xcp_d/cli/run.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,9 @@ def main():
167167
)
168168

169169
if config.execution.atlases:
170-
write_atlas_dataset_description(config.execution.output_dir / 'atlases')
170+
write_atlas_dataset_description(
171+
config.execution.output_dir / 'derivatives' / 'atlases'
172+
)
171173

172174
# Generate reports phase
173175
failed_reports = generate_reports(

xcp_d/data/atlas_bids_config.json

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,18 @@
22
"name": "atlas",
33
"entities": [
44
{
5-
"name": "atlas",
6-
"pattern": "[/\\\\]+atlas-([a-zA-Z0-9]+)",
7-
"directory": "{atlas}"
5+
"name": "template",
6+
"pattern": "[_/\\\\]+tpl-([a-zA-Z0-9+]+)",
7+
"directory": "{template}"
8+
},
9+
{
10+
"name": "cohort",
11+
"pattern": "[_/\\\\]+cohort-([a-zA-Z0-9+]+)",
12+
"directory": "{cohort}"
813
},
914
{
10-
"name": "space",
11-
"pattern": "[_/\\\\]+space-([a-zA-Z0-9]+)"
15+
"name": "atlas",
16+
"pattern": "[_/\\\\]+atlas-([a-zA-Z0-9+]+)"
1217
},
1318
{
1419
"name": "hemi",
@@ -24,7 +29,7 @@
2429
},
2530
{
2631
"name": "desc",
27-
"pattern": "[_/\\\\]+desc-([a-zA-Z0-9]+)"
32+
"pattern": "[_/\\\\]+desc-([a-zA-Z0-9+]+)"
2833
},
2934
{
3035
"name": "suffix",
@@ -36,9 +41,9 @@
3641
}
3742
],
3843
"default_path_patterns": [
39-
"atlas-{atlas}/atlas-{atlas}[_space-{space}][_res-{res}][_desc-{desc}]_{suffix<dseg|probseg|mask>}.{extension<nii|nii.gz|json>|nii.gz}",
40-
"atlas-{atlas}/atlas-{atlas}[_space-{space}][_res-{res}][_den-{den}][_desc-{desc}]_{suffix<dseg|probseg|mask>}.{extension<dlabel.nii|json>|dlabel.nii}",
41-
"atlas-{atlas}/atlas-{atlas}[_hemi-{hemi}][_space-{space}][_den-{den}][_desc-{desc}]_{suffix<dseg|probseg|mask>}.{extension<label.gii|json>|label.gii}",
42-
"atlas-{atlas}/atlas-{atlas}[_space-{space}][_desc-{desc}]_{suffix<dseg|probseg|mask>}.{extension<tsv|json>|tsv}"
44+
"tpl-{template}/[cohort-{cohort}]/tpl-{template}[_cohort-{cohort}]_atlas-{atlas}[_res-{res}][_desc-{desc}]_{suffix<dseg|probseg|mask>}.{extension<nii|nii.gz|json>|nii.gz}",
45+
"tpl-{template}/[cohort-{cohort}]/tpl-{template}[_cohort-{cohort}]_atlas-{atlas}[_res-{res}][_den-{den}][_desc-{desc}]_{suffix<dseg|probseg|mask>}.{extension<dlabel.nii|json>|dlabel.nii}",
46+
"tpl-{template}/[cohort-{cohort}]/tpl-{template}[_cohort-{cohort}]_atlas-{atlas}[_hemi-{hemi}][_den-{den}][_desc-{desc}]_{suffix<dseg|probseg|mask>}.{extension<label.gii|json>|label.gii}",
47+
"tpl-{template}/[cohort-{cohort}]/tpl-{template}[_cohort-{cohort}]_atlas-{atlas}[_res-{res}][_den-{den}][_desc-{desc}]_{suffix<dseg|probseg|mask>}.{extension<tsv|json>|tsv}"
4348
]
4449
}

0 commit comments

Comments
 (0)