-
Notifications
You must be signed in to change notification settings - Fork 533
[ENH] Update BIDSDataGrabber for pybids 0.7 #2737
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
Changes from 10 commits
ffd0d8e
8db5111
801b295
1d267c8
b0121c0
cc89c58
b8aacce
a0e92f1
0f94d9d
77a0510
26a57a6
2a84cab
5590d4d
3c21466
d2e53fb
b75bf7c
7105cb5
09a1a43
75a5a2b
139c163
b623cdd
aeda06a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -92,7 +92,7 @@ function generate_main_dockerfile() { | |
conda_install='python=${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR} | ||
icu=58.1 libxml2 libxslt matplotlib mkl numpy paramiko | ||
pandas psutil scikit-learn scipy traits=4.6.0' \ | ||
pip_install="grabbit==0.1.2 https://github.com/INCF/pybids/tarball/0.6.5" \ | ||
pip_install="grabbit==0.2.6 https://github.com/bids-standard/pybids/tarball/0.7.0" \ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is going to have conflicts when #2856 is merged. Also, for tests to work, this will need to be installed in editable mode. Perhaps add - pip_install="/src/nipype[all]" \
+ pip_install="/src/nipype[all] https://github.com/bids-standard/pybids/tarball/0.7.0" \ |
||
activate=true \ | ||
--copy docker/files/run_builddocs.sh docker/files/run_examples.sh \ | ||
docker/files/run_pytests.sh nipype/external/fsl_imglob.py /usr/bin/ \ | ||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -2721,18 +2721,25 @@ def _list_outputs(self): | |||||
|
||||||
|
||||||
class BIDSDataGrabberInputSpec(DynamicTraitedSpec): | ||||||
base_dir = Directory(exists=True, | ||||||
desc='Path to BIDS Directory.', | ||||||
mandatory=True) | ||||||
output_query = traits.Dict(key_trait=Str, | ||||||
value_trait=traits.Dict, | ||||||
desc='Queries for outfield outputs') | ||||||
raise_on_empty = traits.Bool(True, usedefault=True, | ||||||
desc='Generate exception if list is empty ' | ||||||
'for a given field') | ||||||
return_type = traits.Enum('file', 'namedtuple', usedefault=True) | ||||||
strict = traits.Bool(desc='Return only BIDS "proper" files (e.g., ' | ||||||
'ignore derivatives/, sourcedata/, etc.)') | ||||||
base_dir = Directory( | ||||||
exists=True, | ||||||
desc='Path to BIDS Directory.', | ||||||
mandatory=True) | ||||||
output_query = traits.Dict( | ||||||
key_trait=Str, | ||||||
value_trait=traits.Dict, | ||||||
desc='Queries for outfield outputs') | ||||||
raise_on_empty = traits.Bool( | ||||||
True, usedefault=True, | ||||||
desc='Generate exception if list is empty for a given field') | ||||||
return_type = traits.Enum( | ||||||
'file', 'namedtuple', usedefault=True) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Have we tested There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I tested
I got the following error traceback:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll remove that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You were going to remove |
||||||
index_derivatives = traits.Bool( | ||||||
False, usedefault=True, | ||||||
adelavega marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
desc='Index derivatives/ sub-directory') | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok! |
||||||
extra_derivatives = traits.List( | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. when using the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
(Requires importing |
||||||
Directory(exists=True), | ||||||
desc='Additional derivative directories to index') | ||||||
|
||||||
|
||||||
class BIDSDataGrabber(LibraryBaseInterface, IOBase): | ||||||
|
@@ -2758,10 +2765,10 @@ class BIDSDataGrabber(LibraryBaseInterface, IOBase): | |||||
are filtered on common entities, which can be explicitly defined as | ||||||
infields. | ||||||
|
||||||
>>> bg = BIDSDataGrabber(infields = ['subject'], outfields = ['dwi']) | ||||||
>>> bg = BIDSDataGrabber(infields = ['subject']) | ||||||
>>> bg.inputs.base_dir = 'ds005/' | ||||||
>>> bg.inputs.subject = '01' | ||||||
>>> bg.inputs.output_query['dwi'] = dict(modality='dwi') | ||||||
>>> bg.inputs.output_query['dwi'] = dict(datatype='dwi') | ||||||
>>> results = bg.run() # doctest: +SKIP | ||||||
|
||||||
""" | ||||||
|
@@ -2781,18 +2788,17 @@ def __init__(self, infields=None, **kwargs): | |||||
|
||||||
if not isdefined(self.inputs.output_query): | ||||||
self.inputs.output_query = { | ||||||
"func": {"modality": "func", 'extensions': ['nii', '.nii.gz']}, | ||||||
"anat": {"modality": "anat", 'extensions': ['nii', '.nii.gz']}, | ||||||
"bold": {"datatype": "func", "suffix": "bold", | ||||||
"extensions": ["nii", ".nii.gz"]}, | ||||||
"T1w": {"datatype": "anat", "suffix": "T1w", | ||||||
"extensions": ["nii", ".nii.gz"]}, | ||||||
} | ||||||
|
||||||
# If infields is empty, use all BIDS entities | ||||||
if infields is None: | ||||||
# Version resilience | ||||||
try: | ||||||
from bids import layout as bidslayout | ||||||
except ImportError: | ||||||
from bids import grabbids as bidslayout | ||||||
bids_config = join(dirname(bidslayout.__file__), 'config', 'bids.json') | ||||||
from bids import layout as bidslayout | ||||||
bids_config = join( | ||||||
dirname(bidslayout.__file__), 'config', 'bids.json') | ||||||
bids_config = json.load(open(bids_config, 'r')) | ||||||
infields = [i['name'] for i in bids_config['entities']] | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we replace all of this with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That command ( I do not know of a better way (but I didn't look extremely hard) Another comment: I think it would be nice to include There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, sorry, I meant that in a pseudocode sense of the entities attribute of an instantiated object, not that that snippet would work. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, maybe I can reorganize this to set up the layout first, before setting the output traits. Is there any problem with instantiating the layout in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The biggest problem is that inputs can change between instantiation and running. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's a pretty big problem! So I think for now instantiating a layout just to get entities does not work. Adding a helper function to pybids and then changing this later is a better option. |
||||||
|
||||||
|
@@ -2807,15 +2813,12 @@ def __init__(self, infields=None, **kwargs): | |||||
self.inputs.trait_set(trait_change_notify=False, **undefined_traits) | ||||||
|
||||||
def _list_outputs(self): | ||||||
# Version resilience | ||||||
try: | ||||||
from bids import BIDSLayout | ||||||
except ImportError: | ||||||
from bids.grabbids import BIDSLayout | ||||||
exclude = None | ||||||
if self.inputs.strict: | ||||||
exclude = ['derivatives/', 'code/', 'sourcedata/'] | ||||||
layout = BIDSLayout(self.inputs.base_dir, exclude=exclude) | ||||||
from bids import BIDSLayout | ||||||
layout = BIDSLayout(self.inputs.base_dir, | ||||||
derivatives=self.inputs.index_derivatives) | ||||||
|
||||||
if isdefined(self.inputs.extra_derivatives): | ||||||
layout.add_derivatives(self.inputs.extra_derivatives) | ||||||
|
||||||
# If infield is not given nm input value, silently ignore | ||||||
filters = {} | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -591,9 +591,9 @@ def test_bids_grabber(tmpdir): | |
bg.inputs.base_dir = os.path.join(datadir, 'ds005') | ||
bg.inputs.subject = '01' | ||
results = bg.run() | ||
assert 'sub-01_T1w.nii.gz' in map(os.path.basename, results.outputs.anat) | ||
assert 'sub-01_T1w.nii.gz' in map(os.path.basename, results.outputs.T1w) | ||
assert 'sub-01_task-mixedgamblestask_run-01_bold.nii.gz' in \ | ||
map(os.path.basename, results.outputs.func) | ||
map(os.path.basename, results.outputs.bold) | ||
|
||
|
||
@pytest.mark.skipif(not have_pybids, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we remove the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah I guess... |
||
|
@@ -607,7 +607,7 @@ def test_bids_fields(tmpdir): | |
bg = nio.BIDSDataGrabber(infields = ['subject'], outfields = ['dwi']) | ||
bg.inputs.base_dir = os.path.join(datadir, 'ds005') | ||
bg.inputs.subject = '01' | ||
bg.inputs.output_query['dwi'] = dict(modality='dwi') | ||
bg.inputs.output_query['dwi'] = dict(datatype='dwi') | ||
results = bg.run() | ||
assert 'sub-01_dwi.nii.gz' in map(os.path.basename, results.outputs.dwi) | ||
|
||
|
@@ -633,9 +633,9 @@ def test_bids_infields_outfields(tmpdir): | |
for outfield in outfields: | ||
assert(outfield in bg._outputs().traits()) | ||
|
||
# now try without defining outfields, we should get anat and func for free | ||
# now try without defining outfields | ||
bg = nio.BIDSDataGrabber() | ||
for outfield in ['anat', 'func']: | ||
for outfield in ['T1w', 'bold']: | ||
assert outfield in bg._outputs().traits() | ||
|
||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tests skip unless it's installed in editable mode.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is by design because when you install in editable mode you get the data that is needed for the tests
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right. So we need to switch back to editable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I thought it was editable, not sure why that changed.