Skip to content

Commit 80dfc86

Browse files
authored
Merge pull request #2737 from adelavega/update-pybids
[ENH] Update BIDSDataGrabber for pybids 0.7
2 parents 74eb5e5 + aeda06a commit 80dfc86

File tree

7 files changed

+112
-49
lines changed

7 files changed

+112
-49
lines changed

.travis.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,8 @@ before_install:
8989
fi;
9090

9191
- travis_retry pip install -r requirements.txt
92-
- travis_retry pip install grabbit==0.1.2
93-
- travis_retry git clone -b 0.6.5 https://github.com/INCF/pybids.git ${HOME}/pybids && pip install -e ${HOME}/pybids
92+
- travis_retry pip install grabbit==0.2.6
93+
- travis_retry pip install -e git+https://github.com/bids-standard/pybids.git@0.7.0#egg=pybids
9494

9595
install:
9696
- travis_retry pip install $EXTRA_PIP_FLAGS -e .[$NIPYPE_EXTRAS]

docker/generate_dockerfiles.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ function generate_main_dockerfile() {
107107
--user neuro \
108108
--miniconda use_env=neuro \
109109
pip_opts="-e" \
110-
pip_install="/src/nipype[all]" \
110+
pip_install="/src/nipype[all] https://github.com/bids-standard/pybids/tarball/0.7.0" \
111111
--workdir /work \
112112
--label org.label-schema.build-date='$BUILD_DATE' \
113113
org.label-schema.name="NIPYPE" \

nipype/info.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ def get_nipype_gitversion():
172172
'profiler': ['psutil>=5.0'],
173173
'duecredit': ['duecredit'],
174174
'xvfbwrapper': ['xvfbwrapper'],
175-
'pybids': ['pybids==0.6.5'],
175+
'pybids': ['pybids>=0.7.0'],
176176
'ssh': ['paramiko'],
177177
# 'mesh': ['mayavi'] # Enable when it works
178178
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT
2+
from __future__ import unicode_literals
3+
from ..epi import EddyQuad
4+
5+
6+
def test_EddyQuad_inputs():
7+
input_map = dict(
8+
args=dict(argstr='%s', ),
9+
base_name=dict(
10+
argstr='%s',
11+
position=0,
12+
usedefault=True,
13+
),
14+
bval_file=dict(
15+
argstr='--bvals=%s',
16+
mandatory=True,
17+
),
18+
bvec_file=dict(argstr='--bvecs=%s', ),
19+
environ=dict(
20+
nohash=True,
21+
usedefault=True,
22+
),
23+
field=dict(argstr='--field=%s', ),
24+
idx_file=dict(
25+
argstr='--eddyIdx=%s',
26+
mandatory=True,
27+
),
28+
mask_file=dict(
29+
argstr='--mask=%s',
30+
mandatory=True,
31+
),
32+
output_dir=dict(
33+
argstr='--output-dir=%s',
34+
name_source=['base_name'],
35+
name_template='%s.qc',
36+
),
37+
output_type=dict(),
38+
param_file=dict(
39+
argstr='--eddyParams=%s',
40+
mandatory=True,
41+
),
42+
slice_spec=dict(argstr='--slspec=%s', ),
43+
verbose=dict(argstr='--verbose', ),
44+
)
45+
inputs = EddyQuad.input_spec()
46+
47+
for key, metadata in list(input_map.items()):
48+
for metakey, value in list(metadata.items()):
49+
assert getattr(inputs.traits()[key], metakey) == value
50+
def test_EddyQuad_outputs():
51+
output_map = dict(
52+
avg_b0_pe_png=dict(),
53+
avg_b_png=dict(),
54+
clean_volumes=dict(),
55+
cnr_png=dict(),
56+
qc_json=dict(),
57+
qc_pdf=dict(),
58+
residuals=dict(),
59+
vdm_png=dict(),
60+
)
61+
outputs = EddyQuad.output_spec()
62+
63+
for key, metadata in list(output_map.items()):
64+
for metakey, value in list(metadata.items()):
65+
assert getattr(outputs.traits()[key], metakey) == value

nipype/interfaces/io.py

+33-32
Original file line numberDiff line numberDiff line change
@@ -2721,18 +2721,23 @@ def _list_outputs(self):
27212721

27222722

27232723
class BIDSDataGrabberInputSpec(DynamicTraitedSpec):
2724-
base_dir = Directory(exists=True,
2725-
desc='Path to BIDS Directory.',
2726-
mandatory=True)
2727-
output_query = traits.Dict(key_trait=Str,
2728-
value_trait=traits.Dict,
2729-
desc='Queries for outfield outputs')
2730-
raise_on_empty = traits.Bool(True, usedefault=True,
2731-
desc='Generate exception if list is empty '
2732-
'for a given field')
2733-
return_type = traits.Enum('file', 'namedtuple', usedefault=True)
2734-
strict = traits.Bool(desc='Return only BIDS "proper" files (e.g., '
2735-
'ignore derivatives/, sourcedata/, etc.)')
2724+
base_dir = Directory(
2725+
exists=True,
2726+
desc='Path to BIDS Directory.',
2727+
mandatory=True)
2728+
output_query = traits.Dict(
2729+
key_trait=Str,
2730+
value_trait=traits.Dict,
2731+
desc='Queries for outfield outputs')
2732+
raise_on_empty = traits.Bool(
2733+
True, usedefault=True,
2734+
desc='Generate exception if list is empty for a given field')
2735+
index_derivatives = traits.Bool(
2736+
False, mandatory=True, usedefault=True,
2737+
desc='Index derivatives/ sub-directory')
2738+
extra_derivatives = traits.List(
2739+
Directory(exists=True),
2740+
desc='Additional derivative directories to index')
27362741

27372742

27382743
class BIDSDataGrabber(LibraryBaseInterface, IOBase):
@@ -2758,10 +2763,10 @@ class BIDSDataGrabber(LibraryBaseInterface, IOBase):
27582763
are filtered on common entities, which can be explicitly defined as
27592764
infields.
27602765
2761-
>>> bg = BIDSDataGrabber(infields = ['subject'], outfields = ['dwi'])
2766+
>>> bg = BIDSDataGrabber(infields = ['subject'])
27622767
>>> bg.inputs.base_dir = 'ds005/'
27632768
>>> bg.inputs.subject = '01'
2764-
>>> bg.inputs.output_query['dwi'] = dict(modality='dwi')
2769+
>>> bg.inputs.output_query['dwi'] = dict(datatype='dwi')
27652770
>>> results = bg.run() # doctest: +SKIP
27662771
27672772
"""
@@ -2781,18 +2786,17 @@ def __init__(self, infields=None, **kwargs):
27812786

27822787
if not isdefined(self.inputs.output_query):
27832788
self.inputs.output_query = {
2784-
"func": {"modality": "func", 'extensions': ['nii', '.nii.gz']},
2785-
"anat": {"modality": "anat", 'extensions': ['nii', '.nii.gz']},
2789+
"bold": {"datatype": "func", "suffix": "bold",
2790+
"extensions": ["nii", ".nii.gz"]},
2791+
"T1w": {"datatype": "anat", "suffix": "T1w",
2792+
"extensions": ["nii", ".nii.gz"]},
27862793
}
27872794

27882795
# If infields is empty, use all BIDS entities
27892796
if infields is None:
2790-
# Version resilience
2791-
try:
2792-
from bids import layout as bidslayout
2793-
except ImportError:
2794-
from bids import grabbids as bidslayout
2795-
bids_config = join(dirname(bidslayout.__file__), 'config', 'bids.json')
2797+
from bids import layout as bidslayout
2798+
bids_config = join(
2799+
dirname(bidslayout.__file__), 'config', 'bids.json')
27962800
bids_config = json.load(open(bids_config, 'r'))
27972801
infields = [i['name'] for i in bids_config['entities']]
27982802

@@ -2807,15 +2811,12 @@ def __init__(self, infields=None, **kwargs):
28072811
self.inputs.trait_set(trait_change_notify=False, **undefined_traits)
28082812

28092813
def _list_outputs(self):
2810-
# Version resilience
2811-
try:
2812-
from bids import BIDSLayout
2813-
except ImportError:
2814-
from bids.grabbids import BIDSLayout
2815-
exclude = None
2816-
if self.inputs.strict:
2817-
exclude = ['derivatives/', 'code/', 'sourcedata/']
2818-
layout = BIDSLayout(self.inputs.base_dir, exclude=exclude)
2814+
from bids import BIDSLayout
2815+
layout = BIDSLayout(self.inputs.base_dir,
2816+
derivatives=self.inputs.index_derivatives)
2817+
2818+
if isdefined(self.inputs.extra_derivatives):
2819+
layout.add_derivatives(self.inputs.extra_derivatives)
28192820

28202821
# If infield is not given nm input value, silently ignore
28212822
filters = {}
@@ -2828,7 +2829,7 @@ def _list_outputs(self):
28282829
for key, query in self.inputs.output_query.items():
28292830
args = query.copy()
28302831
args.update(filters)
2831-
filelist = layout.get(return_type=self.inputs.return_type, **args)
2832+
filelist = layout.get(return_type='file', **args)
28322833
if len(filelist) == 0:
28332834
msg = 'Output key: %s returned no files' % key
28342835
if self.inputs.raise_on_empty:

nipype/interfaces/tests/test_auto_BIDSDataGrabber.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,13 @@
66
def test_BIDSDataGrabber_inputs():
77
input_map = dict(
88
base_dir=dict(mandatory=True, ),
9+
extra_derivatives=dict(),
10+
index_derivatives=dict(
11+
mandatory=True,
12+
usedefault=True,
13+
),
914
output_query=dict(),
1015
raise_on_empty=dict(usedefault=True, ),
11-
return_type=dict(usedefault=True, ),
12-
strict=dict(),
1316
)
1417
inputs = BIDSDataGrabber.input_spec()
1518

nipype/interfaces/tests/test_io.py

+5-11
Original file line numberDiff line numberDiff line change
@@ -581,8 +581,6 @@ def test_jsonsink(tmpdir, inputs_attributes):
581581
# There are three reasons these tests will be skipped:
582582
@pytest.mark.skipif(not have_pybids,
583583
reason="Pybids is not installed")
584-
@pytest.mark.skipif(sys.version_info < (3, 0),
585-
reason="Pybids no longer supports Python 2")
586584
@pytest.mark.skipif(not dist_is_editable('pybids'),
587585
reason="Pybids is not installed in editable mode")
588586
def test_bids_grabber(tmpdir):
@@ -591,31 +589,27 @@ def test_bids_grabber(tmpdir):
591589
bg.inputs.base_dir = os.path.join(datadir, 'ds005')
592590
bg.inputs.subject = '01'
593591
results = bg.run()
594-
assert 'sub-01_T1w.nii.gz' in map(os.path.basename, results.outputs.anat)
592+
assert 'sub-01_T1w.nii.gz' in map(os.path.basename, results.outputs.T1w)
595593
assert 'sub-01_task-mixedgamblestask_run-01_bold.nii.gz' in \
596-
map(os.path.basename, results.outputs.func)
594+
map(os.path.basename, results.outputs.bold)
597595

598596

599597
@pytest.mark.skipif(not have_pybids,
600598
reason="Pybids is not installed")
601-
@pytest.mark.skipif(sys.version_info < (3, 0),
602-
reason="Pybids no longer supports Python 2")
603599
@pytest.mark.skipif(not dist_is_editable('pybids'),
604600
reason="Pybids is not installed in editable mode")
605601
def test_bids_fields(tmpdir):
606602
tmpdir.chdir()
607603
bg = nio.BIDSDataGrabber(infields = ['subject'], outfields = ['dwi'])
608604
bg.inputs.base_dir = os.path.join(datadir, 'ds005')
609605
bg.inputs.subject = '01'
610-
bg.inputs.output_query['dwi'] = dict(modality='dwi')
606+
bg.inputs.output_query['dwi'] = dict(datatype='dwi')
611607
results = bg.run()
612608
assert 'sub-01_dwi.nii.gz' in map(os.path.basename, results.outputs.dwi)
613609

614610

615611
@pytest.mark.skipif(not have_pybids,
616612
reason="Pybids is not installed")
617-
@pytest.mark.skipif(sys.version_info < (3, 0),
618-
reason="Pybids no longer supports Python 2")
619613
@pytest.mark.skipif(not dist_is_editable('pybids'),
620614
reason="Pybids is not installed in editable mode")
621615
def test_bids_infields_outfields(tmpdir):
@@ -633,9 +627,9 @@ def test_bids_infields_outfields(tmpdir):
633627
for outfield in outfields:
634628
assert(outfield in bg._outputs().traits())
635629

636-
# now try without defining outfields, we should get anat and func for free
630+
# now try without defining outfields
637631
bg = nio.BIDSDataGrabber()
638-
for outfield in ['anat', 'func']:
632+
for outfield in ['T1w', 'bold']:
639633
assert outfield in bg._outputs().traits()
640634

641635

0 commit comments

Comments
 (0)