14
14
>>> os.chdir(datadir)
15
15
16
16
"""
17
+ from os .path import join , dirname
17
18
from .. import logging
18
19
from .base import (traits ,
19
20
DynamicTraitedSpec ,
24
25
Undefined )
25
26
26
27
try :
27
- from bids .grabbids import BIDSLayout
28
+ from bids import grabbids as gb
29
+ import json
28
30
except ImportError :
29
31
have_pybids = False
30
32
else :
@@ -57,40 +59,34 @@ class BIDSDataGrabber(BaseInterface):
57
59
>>> from os.path import basename
58
60
>>> import pprint
59
61
60
- Select all files from a BIDS project
62
+ By default, the BIDSDataGrabber fetches anatomical and functional images
63
+ from a project, and makes BIDS entities (e.g. subject) available for
64
+ filtering outputs.
61
65
62
66
>>> bg = BIDSDataGrabber()
63
67
>>> bg.inputs.base_dir = 'ds005/'
64
- >>> results = bg.run()
65
- >>> len(results.outputs.outfield) # doctest: +ALLOW_UNICODE
66
- 135
67
-
68
- Using dynamically created, user-defined input fields,
69
- filter files based on BIDS entities.
70
-
71
- >>> bg = BIDSDataGrabber(infields = ['subject', 'run'])
72
- >>> bg.inputs.base_dir = 'ds005/'
73
68
>>> bg.inputs.subject = '01'
74
- >>> bg.inputs.run = '01'
75
69
>>> results = bg.run()
76
- >>> basename(results.outputs.outfield[0]) # doctest: +ALLOW_UNICODE
70
+ >>> basename(results.outputs.anat[0]) # doctest: +ALLOW_UNICODE
71
+ 'sub-01_T1w.nii.gz'
72
+
73
+ >>> basename(results.outputs.func[0]) # doctest: +ALLOW_UNICODE
77
74
'sub-01_task-mixedgamblestask_run-01_bold.nii.gz'
78
75
79
- Using user-defined output fields, return different types of outputs,
80
- filtered on common entities
81
- filter files based on BIDS entities.
82
76
83
- >>> bg = BIDSDataGrabber(infields = ['subject'], outfields = ['func', 'anat'])
77
+ Dynamically created, user-defined output fields can also be defined to
78
+ return different types of outputs from the same project. All outputs
79
+ are filtered on common entities, which can be explicitly defined as
80
+ infields.
81
+
82
+ >>> bg = BIDSDataGrabber(infields = ['subject'], outfields = ['dwi'])
84
83
>>> bg.inputs.base_dir = 'ds005/'
85
84
>>> bg.inputs.subject = '01'
86
- >>> bg.inputs.output_query['func'] = dict(modality='func')
87
- >>> bg.inputs.output_query['anat'] = dict(modality='anat')
85
+ >>> bg.inputs.output_query['dwi'] = dict(modality='dwi')
88
86
>>> results = bg.run()
89
- >>> basename(results.outputs.func [0]) # doctest: +ALLOW_UNICODE
90
- 'sub-01_task-mixedgamblestask_run-01_bold .nii.gz'
87
+ >>> basename(results.outputs.dwi [0]) # doctest: +ALLOW_UNICODE
88
+ 'sub-01_dwi .nii.gz'
91
89
92
- >>> basename(results.outputs.anat[0]) # doctest: +ALLOW_UNICODE
93
- 'sub-01_T1w.nii.gz'
94
90
"""
95
91
input_spec = BIDSDataGrabberInputSpec
96
92
output_spec = DynamicTraitedSpec
@@ -107,51 +103,53 @@ def __init__(self, infields=None, outfields=None, **kwargs):
107
103
Indicates output fields to be dynamically created.
108
104
If no matching items, returns Undefined.
109
105
"""
110
- if not outfields :
111
- outfields = []
112
- if not infields :
113
- infields = []
114
-
115
106
super (BIDSDataGrabber , self ).__init__ (** kwargs )
116
- undefined_traits = {}
117
- # used for mandatory inputs check
107
+ if not have_pybids :
108
+ raise ImportError ("The BIDSEventsGrabber interface requires pybids."
109
+ " Please make sure it is installed." )
110
+
111
+ # If outfields is None use anat and func as default
112
+ if outfields is None :
113
+ outfields = ['func' , 'anat' ]
114
+ self .inputs .output_query = {
115
+ "func" : {"modality" : "func" },
116
+ "anat" : {"modality" : "anat" }}
117
+ else :
118
+ self .inputs .output_query = {}
119
+
120
+ # If infields is None, use all BIDS entities
121
+ if infields is None :
122
+ bids_config = join (dirname (gb .__file__ ), 'config' , 'bids.json' )
123
+ bids_config = json .load (open (bids_config , 'r' ))
124
+ infields = [i ['name' ] for i in bids_config ['entities' ]]
125
+
118
126
self ._infields = infields
119
127
self ._outfields = outfields
128
+
129
+ # used for mandatory inputs check
130
+ undefined_traits = {}
120
131
for key in infields :
121
132
self .inputs .add_trait (key , traits .Any )
122
133
undefined_traits [key ] = Undefined
123
134
124
- if not isdefined (self .inputs .output_query ):
125
- self .inputs .output_query = {}
126
-
127
135
self .inputs .trait_set (trait_change_notify = False , ** undefined_traits )
128
136
129
137
def _run_interface (self , runtime ):
130
- if not have_pybids :
131
- raise ImportError ("The BIDSEventsGrabber interface requires pybids."
132
- " Please make sure it is installed." )
133
138
return runtime
134
139
135
140
def _list_outputs (self ):
136
- if not self ._outfields :
137
- self ._outfields = ['outfield' ]
138
- self .inputs .output_query = {'outfield' : {}}
139
- else :
140
- for key in self ._outfields :
141
- if key not in self .inputs .output_query :
142
- raise ValueError ("Define query for all outputs" )
141
+ layout = gb .BIDSLayout (self .inputs .base_dir )
142
+
143
+ for key in self ._outfields :
144
+ if key not in self .inputs .output_query :
145
+ raise ValueError ("Define query for all outputs" )
143
146
147
+ # If infield is not given nm input value, silently ignore
148
+ filters = {}
144
149
for key in self ._infields :
145
150
value = getattr (self .inputs , key )
146
- if not isdefined (value ):
147
- msg = "%s requires a value for input '%s' because" \
148
- " it was listed in 'infields'" % \
149
- (self .__class__ .__name__ , key )
150
- raise ValueError (msg )
151
-
152
- layout = BIDSLayout (self .inputs .base_dir )
153
-
154
- filters = {i : getattr (self .inputs , i ) for i in self ._infields }
151
+ if isdefined (value ):
152
+ filters [key ] = value
155
153
156
154
outputs = {}
157
155
for key , query in self .inputs .output_query .items ():
0 commit comments