Skip to content
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
27 changes: 25 additions & 2 deletions petprep/cli/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,8 +188,13 @@ def _bids_filter(value, parser):
'identifier (the sub- prefix can be removed)',
)
# Re-enable when option is actually implemented
# g_bids.add_argument('-s', '--session-id', action='store', default='single_session',
# help='Select a specific session to be processed')
g_bids.add_argument(
'--session-label',
nargs='+',
type=lambda label: label.removeprefix('ses-'),
help='A space delimited list of session identifiers or a single '
'identifier (the ses- prefix can be removed)',
)
# Re-enable when option is actually implemented
# g_bids.add_argument('-r', '--run-id', action='store', default='single_run',
# help='Select a specific run to be processed')
Expand Down Expand Up @@ -749,6 +754,13 @@ def parse_args(args=None, namespace=None):
config.execution.log_level = int(max(25 - 5 * opts.verbose_count, logging.DEBUG))
config.from_dict(vars(opts), init=['nipype'])

if config.execution.session_label:
config.execution.bids_filters = config.execution.bids_filters or {}
config.execution.bids_filters['pet'] = {
**config.execution.bids_filters.get('pet', {}),
'session': config.execution.session_label,
}

pvc_vals = (opts.pvc_tool, opts.pvc_method, opts.pvc_psf)
if any(val is not None for val in pvc_vals) and not all(val is not None for val in pvc_vals):
parser.error('Options --pvc-tool, --pvc-method and --pvc-psf must be used together.')
Expand Down Expand Up @@ -908,5 +920,16 @@ def parse_args(args=None, namespace=None):
f'One or more participant labels were not found in the BIDS directory: {", ".join(missing_subjects)}.'
)

if config.execution.session_label:
available_sessions = set(
config.execution.layout.get_sessions(subject=list(participant_label) or None)
)
missing_sessions = set(config.execution.session_label) - available_sessions
if missing_sessions:
parser.error(
'One or more session labels were not found in the BIDS directory: '
f'{", ".join(sorted(missing_sessions))}.'
)

config.execution.participant_label = sorted(participant_label)
config.workflow.skull_strip_template = config.workflow.skull_strip_template[0]
41 changes: 41 additions & 0 deletions petprep/cli/tests/test_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@

from argparse import ArgumentError

import nibabel as nb
import numpy as np
import pytest
from packaging.version import Version

Expand Down Expand Up @@ -225,6 +227,45 @@ def test_derivatives(tmp_path):
_reset_config()


def test_session_label_only_filters_pet(tmp_path):
bids = tmp_path / 'bids'
out_dir = tmp_path / 'out'
work_dir = tmp_path / 'work'
bids.mkdir()
(bids / 'dataset_description.json').write_text('{"Name": "Test", "BIDSVersion": "1.8.0"}')

anat_path = bids / 'sub-01' / 'anat' / 'sub-01_T1w.nii.gz'
anat_path.parent.mkdir(parents=True, exist_ok=True)
nb.Nifti1Image(np.zeros((5, 5, 5)), np.eye(4)).to_filename(anat_path)

pet_path = bids / 'sub-01' / 'ses-blocked' / 'pet' / 'sub-01_ses-blocked_pet.nii.gz'
pet_path.parent.mkdir(parents=True, exist_ok=True)
nb.Nifti1Image(np.zeros((5, 5, 5, 1)), np.eye(4)).to_filename(pet_path)
(pet_path.with_suffix('').with_suffix('.json')).write_text(
'{"FrameTimesStart": [0], "FrameDuration": [1]}'
)

try:
parse_args(
args=[
str(bids),
str(out_dir),
'participant',
'--session-label',
'blocked',
'--skip-bids-validation',
'-w',
str(work_dir),
]
)

filters = config.execution.bids_filters
assert filters.get('pet', {}).get('session') == ['blocked']
assert 'session' not in filters.get('anat', {})
finally:
_reset_config()


def test_pvc_argument_handling(tmp_path, minimal_bids):
out_dir = tmp_path / 'out'
work_dir = tmp_path / 'work'
Expand Down
2 changes: 2 additions & 0 deletions petprep/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,8 @@ class execution(_Config):
"""Unique identifier of this particular run."""
participant_label = None
"""List of participant identifiers that are to be preprocessed."""
session_label = None
"""List of session identifiers that are to be preprocessed."""
task_id = None
"""Select a particular task from all available in the dataset."""
templateflow_home = _templateflow_home
Expand Down