Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FIX: Re-add cohort identifier to template name #416

Merged
merged 9 commits into from
Feb 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ dependencies = [
"matplotlib >= 2.2.0",
"nibabel >= 4.0.1",
"nipype >= 1.7.0",
"niworkflows >= 1.8.0",
"niworkflows @ git+https://github.com/nipreps/niworkflows.git@master",
"numpy",
"packaging",
"pybids >= 0.11.1",
Expand Down Expand Up @@ -138,6 +138,8 @@ source = [

[tool.ruff]
line-length = 99

[tool.ruff.lint]
extend-select = [
"F",
"E",
Expand All @@ -162,10 +164,10 @@ extend-select = [
"Q",
]

[tool.ruff.flake8-quotes]
[tool.ruff.lint.flake8-quotes]
inline-quotes = "single"

[tool.ruff.extend-per-file-ignores]
[tool.ruff.lint.extend-per-file-ignores]
"*/test_*.py" = ["S101"]

[tool.ruff.format]
Expand Down
8 changes: 4 additions & 4 deletions smriprep/data/io_spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@
"forward": {
"datatype": "anat",
"extension": [
"h5",
"txt"
".h5",
".txt"
],
"from": "T1w",
"to": null,
Expand All @@ -61,8 +61,8 @@
"reverse": {
"datatype": "anat",
"extension": [
"h5",
"txt"
".h5",
".txt"
],
"from": null,
"to": "T1w",
Expand Down
37 changes: 20 additions & 17 deletions smriprep/utils/bids.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from pathlib import Path

from bids.layout import BIDSLayout
from niworkflows.data import load as nwf_load

from ..data import load_resource

Expand All @@ -39,36 +40,38 @@ def collect_derivatives(derivatives_dir, subject_id, std_spaces, spec=None, patt
if patterns is None:
patterns = _patterns

layout = BIDSLayout(derivatives_dir, config=['bids', 'derivatives'], validate=False)
deriv_config = nwf_load('nipreps.json')
layout = BIDSLayout(derivatives_dir, config=deriv_config, validate=False)

derivs_cache = {}
for k, q in spec['baseline'].items():
q['subject'] = subject_id
item = layout.get(return_type='filename', **q)
for key, qry in spec['baseline'].items():
qry['subject'] = subject_id
item = layout.get(return_type='filename', **qry)
if not item:
continue

derivs_cache['t1w_%s' % k] = item[0] if len(item) == 1 else item
derivs_cache[f't1w_{key}'] = item[0] if len(item) == 1 else item

transforms = derivs_cache.setdefault('transforms', {})
for space in std_spaces:
for k, q in spec['transforms'].items():
q = q.copy()
q['subject'] = subject_id
q['from'] = q['from'] or space
q['to'] = q['to'] or space
item = layout.get(return_type='filename', **q)
for _space in std_spaces:
space = _space.replace(':cohort-', '+')
for key, qry in spec['transforms'].items():
qry = qry.copy()
qry['subject'] = subject_id
qry['from'] = qry['from'] or space
qry['to'] = qry['to'] or space
item = layout.get(return_type='filename', **qry)
if not item:
continue
transforms.setdefault(space, {})[k] = item[0] if len(item) == 1 else item
transforms.setdefault(_space, {})[key] = item[0] if len(item) == 1 else item

for k, q in spec['surfaces'].items():
q['subject'] = subject_id
item = layout.get(return_type='filename', **q)
for key, qry in spec['surfaces'].items():
qry['subject'] = subject_id
item = layout.get(return_type='filename', **qry)
if not item or len(item) != 2:
continue

derivs_cache[k] = sorted(item)
derivs_cache[key] = sorted(item)

return derivs_cache

Expand Down
5 changes: 5 additions & 0 deletions smriprep/utils/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from niworkflows.data import Loader

load_data = Loader(__package__)

DERIV_SKELETON = load_data('derivatives.yml')
101 changes: 101 additions & 0 deletions smriprep/utils/tests/derivatives.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
dataset_description:
Name: smriprep-outputs
BIDSVersion: 1.9.0
DatasetType: derivative
'01':
anat:
- suffix: mask
desc: brain
- suffix: T1w
desc: preproc
- suffix: dseg
- suffix: probseg
label: CSF
- suffix: probseg
label: GM
- suffix: probseg
label: WM
- suffix: xfm
from: MNI152NLin2009cAsym
to: T1w
mode: image
extension: .h5
- suffix: xfm
from: T1w
to: MNI152NLin2009cAsym
mode: image
extension: .h5
- suffix: xfm
from: T1w
to: MNIPediatricAsym+3
mode: image
extension: .h5
- suffix: xfm
from: MNIPediatricAsym+3
to: T1w
mode: image
extension: .h5
- suffix: white
hemi: L
extension: .surf.gii
- suffix: white
hemi: R
extension: .surf.gii
- suffix: pial
hemi: L
extension: .surf.gii
- suffix: pial
hemi: R
extension: .surf.gii
- suffix: midthickness
hemi: L
extension: .surf.gii
- suffix: midthickness
hemi: R
extension: .surf.gii
- suffix: sphere
hemi: L
extension: .surf.gii
- suffix: sphere
hemi: R
extension: .surf.gii
- suffix: sphere
hemi: L
desc: reg
extension: .surf.gii
- suffix: sphere
hemi: R
desc: reg
extension: .surf.gii
- suffix: sphere
hemi: L
space: fsLR
desc: reg
extension: .surf.gii
- suffix: sphere
hemi: R
space: fsLR
desc: reg
extension: .surf.gii
- suffix: sphere
hemi: L
space: fsLR
desc: msmsulc
extension: .surf.gii
- suffix: sphere
hemi: R
space: fsLR
desc: msmsulc
extension: .surf.gii
- suffix: thickness
hemi: L
extension: .shape.gii
- suffix: thickness
hemi: R
extension: .shape.gii
- suffix: sulc
hemi: L
extension: .shape.gii
- suffix: sulc
hemi: R
extension: .shape.gii
30 changes: 30 additions & 0 deletions smriprep/utils/tests/test_bids.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from niworkflows.utils.testing import generate_bids_skeleton

from ..bids import collect_derivatives
from . import DERIV_SKELETON


def test_collect_derivatives(tmp_path):
deriv_dir = tmp_path / 'derivatives'
generate_bids_skeleton(deriv_dir, str(DERIV_SKELETON))
output_spaces = ['MNI152NLin2009cAsym', 'MNIPediatricAsym:cohort-3']
collected = collect_derivatives(deriv_dir, '01', output_spaces)
for suffix in ('preproc', 'mask', 'dseg'):
assert collected[f't1w_{suffix}']
assert len(collected['t1w_tpms']) == 3
xfms = collected['transforms']
for space in output_spaces:
assert xfms[space]['reverse']
assert xfms[space]['forward']
for surface in (
'white',
'pial',
'midthickness',
'sphere',
'thickness',
'sulc',
'sphere_reg',
'sphere_reg_fsLR',
'sphere_reg_msm',
):
assert len(collected[surface]) == 2
19 changes: 18 additions & 1 deletion smriprep/workflows/fit/registration.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,12 @@
mem_gb=2,
)

fmt_cohort = pe.Node(
niu.Function(function=_fmt_cohort, output_names=['template', 'spec']),
name='fmt_cohort',
run_without_submitting=True,
)

# fmt:off
workflow.connect([
(inputnode, split_desc, [('template', 'template')]),
Expand All @@ -202,8 +208,12 @@
]),
(trunc_mov, registration, [
('output_image', 'moving_image')]),
(split_desc, outputnode, [
(split_desc, fmt_cohort, [
('name', 'template'),
('spec', 'spec'),
]),
(fmt_cohort, outputnode, [
('template', 'template'),
('spec', 'template_spec'),
]),
(registration, outputnode, [
Expand All @@ -225,3 +235,10 @@
workflow.connect([(pout, out, [(f, f) for f in out_fields])])
return pout
return pe.Node(niu.IdentityInterface(fields=out_fields), name='outputnode')


def _fmt_cohort(template, spec):
cohort = spec.pop('cohort', None)

Check warning on line 241 in smriprep/workflows/fit/registration.py

View check run for this annotation

Codecov / codecov/patch

smriprep/workflows/fit/registration.py#L241

Added line #L241 was not covered by tests
if cohort is not None:
template = f'{template}:cohort-{cohort}'
return template, spec

Check warning on line 244 in smriprep/workflows/fit/registration.py

View check run for this annotation

Codecov / codecov/patch

smriprep/workflows/fit/registration.py#L243-L244

Added lines #L243 - L244 were not covered by tests
Loading