Skip to content

Commit ba34191

Browse files
authored
Merge pull request #2905 from skoudoro/add-all-dipy-wkflw
[ENH] Add all DIPY workflows dynamically
2 parents 44ed184 + bdd4d21 commit ba34191

File tree

8 files changed

+115
-28
lines changed

8 files changed

+115
-28
lines changed

.zenodo.json

+4
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,10 @@
375375
{
376376
"name": "Haselgrove, Christian"
377377
},
378+
{
379+
"name": "Koudoro, Serge",
380+
"affiliation": "Indiana University, IN, USA"
381+
},
378382
{
379383
"affiliation": "1 McGill Centre for Integrative Neuroscience (MCIN), Ludmer Centre for Neuroinformatics and Mental Health, Montreal Neurological Institute (MNI), McGill University, Montr\u00e9al, 3801 University Street, WB-208, H3A 2B4, Qu\u00e9bec, Canada. 2 University of Lyon, CNRS, INSERM, CREATIS., Villeurbanne, 7, avenue Jean Capelle, 69621, France.",
380384
"name": "Glatard, Tristan",

nipype/interfaces/dipy/base.py

+30
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,11 @@
1010
from ..base import (traits, File, isdefined, LibraryBaseInterface,
1111
BaseInterfaceInputSpec, TraitedSpec)
1212

13+
# List of workflows to ignore
14+
SKIP_WORKFLOWS_LIST = ['Workflow', 'CombinedWorkflow']
15+
1316
HAVE_DIPY = True
17+
1418
try:
1519
import dipy
1620
from dipy.workflows.base import IntrospectiveArgumentParser
@@ -211,3 +215,29 @@ def _list_outputs(self):
211215
"_run_interface": _run_interface,
212216
"_list_outputs:": _list_outputs})
213217
return newclass
218+
219+
220+
def get_dipy_workflows(module):
221+
"""Search for DIPY workflow class.
222+
223+
Parameters
224+
----------
225+
module : object
226+
module object
227+
228+
Returns
229+
-------
230+
l_wkflw : list of tuple
231+
This a list of tuple containing 2 elements:
232+
Worflow name, Workflow class obj
233+
234+
Examples
235+
--------
236+
>>> from dipy.workflows import align # doctest: +SKIP
237+
>>> get_dipy_workflows(align) # doctest: +SKIP
238+
239+
"""
240+
return [(m, obj) for m, obj in inspect.getmembers(module)
241+
if inspect.isclass(obj) and
242+
issubclass(obj, module.Workflow) and
243+
m not in SKIP_WORKFLOWS_LIST]

nipype/interfaces/dipy/preprocess.py

+16-1
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,30 @@
55
import os.path as op
66
import nibabel as nb
77
import numpy as np
8+
from distutils.version import LooseVersion
89

910
from ...utils import NUMPY_MMAP
1011

1112
from ... import logging
1213
from ..base import (traits, TraitedSpec, File, isdefined)
13-
from .base import DipyBaseInterface
14+
from .base import (HAVE_DIPY, dipy_version, dipy_to_nipype_interface,
15+
get_dipy_workflows, DipyBaseInterface)
1416

1517
IFLOGGER = logging.getLogger('nipype.interface')
1618

19+
if HAVE_DIPY and LooseVersion(dipy_version()) >= LooseVersion('0.15'):
20+
from dipy.workflows import denoise, mask
21+
22+
l_wkflw = get_dipy_workflows(denoise) + get_dipy_workflows(mask)
23+
for name, obj in l_wkflw:
24+
new_name = name.replace('Flow', '')
25+
globals()[new_name] = dipy_to_nipype_interface(new_name, obj)
26+
del l_wkflw
27+
28+
else:
29+
IFLOGGER.info("We advise you to upgrade DIPY version. This upgrade will"
30+
" open access to more function")
31+
1732

1833
class ResampleInputSpec(TraitedSpec):
1934
in_file = File(

nipype/interfaces/dipy/reconstruction.py

+11-11
Original file line numberDiff line numberDiff line change
@@ -18,24 +18,24 @@
1818
from ... import logging
1919
from ..base import TraitedSpec, File, traits, isdefined
2020
from .base import (DipyDiffusionInterface, DipyBaseInterfaceInputSpec,
21-
HAVE_DIPY, dipy_version, dipy_to_nipype_interface)
21+
HAVE_DIPY, dipy_version, dipy_to_nipype_interface,
22+
get_dipy_workflows)
2223

2324

2425
IFLOGGER = logging.getLogger('nipype.interface')
2526

2627
if HAVE_DIPY and LooseVersion(dipy_version()) >= LooseVersion('0.15'):
27-
from dipy.workflows.reconst import (ReconstDkiFlow, ReconstCSAFlow,
28-
ReconstCSDFlow, ReconstMAPMRIFlow,
29-
ReconstDtiFlow)
30-
31-
DKIModel = dipy_to_nipype_interface("DKIModel", ReconstDkiFlow)
32-
MapmriModel = dipy_to_nipype_interface("MapmriModel", ReconstMAPMRIFlow)
33-
DTIModel = dipy_to_nipype_interface("DTIModel", ReconstDtiFlow)
34-
CSAModel = dipy_to_nipype_interface("CSAModel", ReconstCSAFlow)
35-
CSDModel = dipy_to_nipype_interface("CSDModel", ReconstCSDFlow)
28+
from dipy.workflows import reconst
29+
30+
l_wkflw = get_dipy_workflows(reconst)
31+
for name, obj in l_wkflw:
32+
new_name = name.replace('Flow', '')
33+
globals()[new_name] = dipy_to_nipype_interface(new_name, obj)
34+
del l_wkflw
35+
3636
else:
3737
IFLOGGER.info("We advise you to upgrade DIPY version. This upgrade will"
38-
" activate DKIModel, MapmriModel, DTIModel, CSAModel, CSDModel.")
38+
" open access to more models")
3939

4040

4141
class RESTOREInputSpec(DipyBaseInterfaceInputSpec):
+10-7
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
11

22
from distutils.version import LooseVersion
33
from ... import logging
4-
from .base import HAVE_DIPY, dipy_version, dipy_to_nipype_interface
4+
from .base import (HAVE_DIPY, dipy_version, dipy_to_nipype_interface,
5+
get_dipy_workflows)
56

67
IFLOGGER = logging.getLogger('nipype.interface')
78

8-
if HAVE_DIPY and LooseVersion(dipy_version()) >= LooseVersion('0.15'):
99

10-
from dipy.workflows.align import ResliceFlow, SlrWithQbxFlow
10+
if HAVE_DIPY and LooseVersion(dipy_version()) >= LooseVersion('0.15'):
11+
from dipy.workflows import align
1112

12-
Reslice = dipy_to_nipype_interface("Reslice", ResliceFlow)
13-
StreamlineRegistration = dipy_to_nipype_interface("StreamlineRegistration",
14-
SlrWithQbxFlow)
13+
l_wkflw = get_dipy_workflows(align)
14+
for name, obj in l_wkflw:
15+
new_name = name.replace('Flow', '')
16+
globals()[new_name] = dipy_to_nipype_interface(new_name, obj)
17+
del l_wkflw
1518

1619
else:
1720
IFLOGGER.info("We advise you to upgrade DIPY version. This upgrade will"
18-
" activate Reslice, StreamlineRegistration.")
21+
" open access to more function")

nipype/interfaces/dipy/stats.py

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
2+
from distutils.version import LooseVersion
3+
from ... import logging
4+
from .base import (HAVE_DIPY, dipy_version, dipy_to_nipype_interface,
5+
get_dipy_workflows)
6+
7+
IFLOGGER = logging.getLogger('nipype.interface')
8+
9+
if HAVE_DIPY and LooseVersion(dipy_version()) >= LooseVersion('0.16'):
10+
from dipy.workflows import stats
11+
12+
l_wkflw = get_dipy_workflows(stats)
13+
for name, obj in l_wkflw:
14+
new_name = name.replace('Flow', '')
15+
globals()[new_name] = dipy_to_nipype_interface(new_name, obj)
16+
del l_wkflw
17+
18+
else:
19+
IFLOGGER.info("We advise you to upgrade DIPY version. This upgrade will"
20+
" open access to more function")

nipype/interfaces/dipy/tests/test_base.py

+12-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
from collections import namedtuple
33
from ...base import traits, TraitedSpec, BaseInterfaceInputSpec
44
from ..base import (convert_to_traits_type, create_interface_specs,
5-
dipy_to_nipype_interface, DipyBaseInterface, no_dipy)
5+
dipy_to_nipype_interface, DipyBaseInterface, no_dipy,
6+
get_dipy_workflows)
67

78

89
def test_convert_to_traits_type():
@@ -136,6 +137,16 @@ def run(self, in_files, param1=1, out_dir='', out_ref='out1.txt'):
136137
new_specs().run()
137138

138139

140+
@pytest.mark.skipif(no_dipy(), reason="DIPY is not installed")
141+
def test_get_dipy_workflows():
142+
from dipy.workflows import align
143+
144+
l_wkflw = get_dipy_workflows(align)
145+
for name, obj in l_wkflw:
146+
assert name.endswith('Flow')
147+
assert issubclass(obj, align.Workflow)
148+
149+
139150
if __name__ == "__main__":
140151
test_convert_to_traits_type()
141152
test_create_interface_specs()

nipype/interfaces/dipy/tracks.py

+12-8
Original file line numberDiff line numberDiff line change
@@ -12,28 +12,32 @@
1212
from ..base import (TraitedSpec, BaseInterfaceInputSpec, File, isdefined,
1313
traits)
1414
from .base import (DipyBaseInterface, HAVE_DIPY, dipy_version,
15-
dipy_to_nipype_interface)
15+
dipy_to_nipype_interface, get_dipy_workflows)
1616

1717
IFLOGGER = logging.getLogger('nipype.interface')
1818

1919

20-
if HAVE_DIPY and LooseVersion(dipy_version()) >= LooseVersion('0.15'):
21-
22-
from dipy.workflows.segment import RecoBundlesFlow, LabelsBundlesFlow
20+
if HAVE_DIPY and (LooseVersion('0.15') >= LooseVersion(dipy_version()) >= LooseVersion('0.16')):
2321
try:
2422
from dipy.workflows.tracking import LocalFiberTrackingPAMFlow as DetTrackFlow
2523
except ImportError: # different name in 0.15
2624
from dipy.workflows.tracking import DetTrackPAMFlow as DetTrackFlow
2725

28-
RecoBundles = dipy_to_nipype_interface("RecoBundles", RecoBundlesFlow)
29-
LabelsBundles = dipy_to_nipype_interface("LabelsBundles",
30-
LabelsBundlesFlow)
3126
DeterministicTracking = dipy_to_nipype_interface("DeterministicTracking",
3227
DetTrackFlow)
3328

29+
if HAVE_DIPY and LooseVersion(dipy_version()) >= LooseVersion('0.15'):
30+
from dipy.workflows import segment, tracking
31+
32+
l_wkflw = get_dipy_workflows(segment) + get_dipy_workflows(tracking)
33+
for name, obj in l_wkflw:
34+
new_name = name.replace('Flow', '')
35+
globals()[new_name] = dipy_to_nipype_interface(new_name, obj)
36+
del l_wkflw
37+
3438
else:
3539
IFLOGGER.info("We advise you to upgrade DIPY version. This upgrade will"
36-
" activate RecoBundles, LabelsBundles, DeterministicTracking.")
40+
" open access to more function")
3741

3842

3943
class TrackDensityMapInputSpec(BaseInterfaceInputSpec):

0 commit comments

Comments
 (0)