From a8548691ef8fa3ccf3f8acce774bf608665a3f46 Mon Sep 17 00:00:00 2001 From: Serge Koudoro Date: Thu, 28 Mar 2019 17:30:00 -0400 Subject: [PATCH 01/12] add get_dipy_workflows function --- nipype/interfaces/dipy/base.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/nipype/interfaces/dipy/base.py b/nipype/interfaces/dipy/base.py index f30af98415..d46e945e1c 100644 --- a/nipype/interfaces/dipy/base.py +++ b/nipype/interfaces/dipy/base.py @@ -211,3 +211,29 @@ def _list_outputs(self): "_run_interface": _run_interface, "_list_outputs:": _list_outputs}) return newclass + + +def get_dipy_workflows(module): + """Search for DIPY workflow class. + + Parameters + ---------- + module : object + module object + + Returns + ------- + l_wkflw : list of tuple + This a list of tuple containing 2 elements: + Worflow name, Workflow class obj + + Examples + -------- + >>> from dipy.workflows import align + >>> get_dipy_workflows(align) + + """ + return [(m, obj) for m, obj in inspect.getmembers(module) + if inspect.isclass(obj) and + issubclass(obj, module.Workflow) and + m not in ['Workflow', 'CombinedWorkflow']] From 61ebb2963237b87daf890d1e2c6e3f75fe82c7b8 Mon Sep 17 00:00:00 2001 From: Serge Koudoro Date: Thu, 28 Mar 2019 17:30:15 -0400 Subject: [PATCH 02/12] add tests --- nipype/interfaces/dipy/tests/test_base.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/nipype/interfaces/dipy/tests/test_base.py b/nipype/interfaces/dipy/tests/test_base.py index 5f769480d2..045c0a4d24 100644 --- a/nipype/interfaces/dipy/tests/test_base.py +++ b/nipype/interfaces/dipy/tests/test_base.py @@ -2,7 +2,8 @@ from collections import namedtuple from ...base import traits, TraitedSpec, BaseInterfaceInputSpec from ..base import (convert_to_traits_type, create_interface_specs, - dipy_to_nipype_interface, DipyBaseInterface, no_dipy) + dipy_to_nipype_interface, DipyBaseInterface, no_dipy, + get_dipy_workflows) def test_convert_to_traits_type(): @@ -136,6 +137,16 @@ def run(self, in_files, param1=1, out_dir='', out_ref='out1.txt'): new_specs().run() +@pytest.mark.skipif(no_dipy(), reason="DIPY is not installed") +def test_get_dipy_workflows(): + from dipy.workflows import align + + l_wkflw = get_dipy_workflows(align) + for name, obj in l_wkflw: + assert name.endswith('Flow') + assert issubclass(align.Workflow) + + if __name__ == "__main__": test_convert_to_traits_type() test_create_interface_specs() From dfef1775080274a3a5574332981ccdb4ad368e6b Mon Sep 17 00:00:00 2001 From: Serge Koudoro Date: Thu, 28 Mar 2019 17:31:06 -0400 Subject: [PATCH 03/12] add preprocessing cmd line --- nipype/interfaces/dipy/preprocess.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/nipype/interfaces/dipy/preprocess.py b/nipype/interfaces/dipy/preprocess.py index 285464847e..117351bf22 100644 --- a/nipype/interfaces/dipy/preprocess.py +++ b/nipype/interfaces/dipy/preprocess.py @@ -5,15 +5,30 @@ import os.path as op import nibabel as nb import numpy as np +from distutils.version import LooseVersion from ...utils import NUMPY_MMAP from ... import logging from ..base import (traits, TraitedSpec, File, isdefined) -from .base import DipyBaseInterface +from .base import (HAVE_DIPY, dipy_version, dipy_to_nipype_interface, + get_dipy_workflows, DipyBaseInterface) IFLOGGER = logging.getLogger('nipype.interface') +if HAVE_DIPY and LooseVersion(dipy_version()) >= LooseVersion('0.15'): + from dipy.workflows import denoise, mask + + l_wkflw = get_dipy_workflows(denoise) + get_dipy_workflows(mask) + for name, obj in l_wkflw: + new_name = name.replace('Flow', '') + globals()[new_name] = dipy_to_nipype_interface(new_name, obj) + del l_wkflw + +else: + IFLOGGER.info("We advise you to upgrade DIPY version. This upgrade will" + " open access to more function") + class ResampleInputSpec(TraitedSpec): in_file = File( From ab693cf6bc022378d931476101fc9d69e65ae088 Mon Sep 17 00:00:00 2001 From: Serge Koudoro Date: Thu, 28 Mar 2019 17:31:33 -0400 Subject: [PATCH 04/12] update reconst cmd line --- nipype/interfaces/dipy/reconstruction.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/nipype/interfaces/dipy/reconstruction.py b/nipype/interfaces/dipy/reconstruction.py index 388071cdc3..6deccd7f9f 100644 --- a/nipype/interfaces/dipy/reconstruction.py +++ b/nipype/interfaces/dipy/reconstruction.py @@ -18,12 +18,13 @@ from ... import logging from ..base import TraitedSpec, File, traits, isdefined from .base import (DipyDiffusionInterface, DipyBaseInterfaceInputSpec, - HAVE_DIPY, dipy_version, dipy_to_nipype_interface) + HAVE_DIPY, dipy_version, dipy_to_nipype_interface, + get_dipy_workflows) IFLOGGER = logging.getLogger('nipype.interface') -if HAVE_DIPY and LooseVersion(dipy_version()) >= LooseVersion('0.15'): +if HAVE_DIPY and (LooseVersion('0.15') >= LooseVersion(dipy_version()) >= LooseVersion('0.16')): from dipy.workflows.reconst import (ReconstDkiFlow, ReconstCSAFlow, ReconstCSDFlow, ReconstMAPMRIFlow, ReconstDtiFlow) @@ -33,9 +34,19 @@ DTIModel = dipy_to_nipype_interface("DTIModel", ReconstDtiFlow) CSAModel = dipy_to_nipype_interface("CSAModel", ReconstCSAFlow) CSDModel = dipy_to_nipype_interface("CSDModel", ReconstCSDFlow) + +elif HAVE_DIPY and LooseVersion(dipy_version()) >= LooseVersion('1.0'): + from dipy.workflows import reconst + + l_wkflw = get_dipy_workflows(reconst) + for name, obj in l_wkflw: + new_name = name.replace('Flow', '') + globals()[new_name] = dipy_to_nipype_interface(new_name, obj) + del l_wkflw + else: IFLOGGER.info("We advise you to upgrade DIPY version. This upgrade will" - " activate DKIModel, MapmriModel, DTIModel, CSAModel, CSDModel.") + " open access to more models") class RESTOREInputSpec(DipyBaseInterfaceInputSpec): From 2575f3de7408e9b8d69e73612248916f7ff059d2 Mon Sep 17 00:00:00 2001 From: Serge Koudoro Date: Thu, 28 Mar 2019 17:31:52 -0400 Subject: [PATCH 05/12] update registration cmd line --- nipype/interfaces/dipy/registration.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/nipype/interfaces/dipy/registration.py b/nipype/interfaces/dipy/registration.py index b1c42c7e39..6d6d023635 100644 --- a/nipype/interfaces/dipy/registration.py +++ b/nipype/interfaces/dipy/registration.py @@ -1,11 +1,12 @@ from distutils.version import LooseVersion from ... import logging -from .base import HAVE_DIPY, dipy_version, dipy_to_nipype_interface +from .base import (HAVE_DIPY, dipy_version, dipy_to_nipype_interface, + get_dipy_workflows) IFLOGGER = logging.getLogger('nipype.interface') -if HAVE_DIPY and LooseVersion(dipy_version()) >= LooseVersion('0.15'): +if HAVE_DIPY and (LooseVersion('0.15') >= LooseVersion(dipy_version()) >= LooseVersion('0.16')): from dipy.workflows.align import ResliceFlow, SlrWithQbxFlow @@ -13,6 +14,15 @@ StreamlineRegistration = dipy_to_nipype_interface("StreamlineRegistration", SlrWithQbxFlow) +elif HAVE_DIPY and LooseVersion(dipy_version()) >= LooseVersion('1.0'): + from dipy.workflows import align + + l_wkflw = get_dipy_workflows(align) + for name, obj in l_wkflw: + new_name = name.replace('Flow', '') + globals()[new_name] = dipy_to_nipype_interface(new_name, obj) + del l_wkflw + else: IFLOGGER.info("We advise you to upgrade DIPY version. This upgrade will" - " activate Reslice, StreamlineRegistration.") + " open access to more function") From 0a2ff69f60c3752c50e73bf8403206d73c06d528 Mon Sep 17 00:00:00 2001 From: Serge Koudoro Date: Thu, 28 Mar 2019 17:32:09 -0400 Subject: [PATCH 06/12] add stats cmd line --- nipype/interfaces/dipy/stats.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 nipype/interfaces/dipy/stats.py diff --git a/nipype/interfaces/dipy/stats.py b/nipype/interfaces/dipy/stats.py new file mode 100644 index 0000000000..6aba67226b --- /dev/null +++ b/nipype/interfaces/dipy/stats.py @@ -0,0 +1,20 @@ + +from distutils.version import LooseVersion +from ... import logging +from .base import (HAVE_DIPY, dipy_version, dipy_to_nipype_interface, + get_dipy_workflows) + +IFLOGGER = logging.getLogger('nipype.interface') + +if HAVE_DIPY and LooseVersion(dipy_version()) >= LooseVersion('0.15'): + from dipy.workflows import stats + + l_wkflw = get_dipy_workflows(stats) + for name, obj in l_wkflw: + new_name = name.replace('Flow', '') + globals()[new_name] = dipy_to_nipype_interface(new_name, obj) + del l_wkflw + +else: + IFLOGGER.info("We advise you to upgrade DIPY version. This upgrade will" + " open access to more function") From f1fc014bddcc4153ef660dd9bd448ae0a25408fc Mon Sep 17 00:00:00 2001 From: Serge Koudoro Date: Thu, 28 Mar 2019 17:32:43 -0400 Subject: [PATCH 07/12] update track cmd line --- nipype/interfaces/dipy/tracks.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/nipype/interfaces/dipy/tracks.py b/nipype/interfaces/dipy/tracks.py index b3d51151e2..77c4b55491 100644 --- a/nipype/interfaces/dipy/tracks.py +++ b/nipype/interfaces/dipy/tracks.py @@ -12,12 +12,12 @@ from ..base import (TraitedSpec, BaseInterfaceInputSpec, File, isdefined, traits) from .base import (DipyBaseInterface, HAVE_DIPY, dipy_version, - dipy_to_nipype_interface) + dipy_to_nipype_interface, get_dipy_workflows) IFLOGGER = logging.getLogger('nipype.interface') -if HAVE_DIPY and LooseVersion(dipy_version()) >= LooseVersion('0.15'): +if HAVE_DIPY and (LooseVersion('0.15') >= LooseVersion(dipy_version()) >= LooseVersion('0.16')): from dipy.workflows.segment import RecoBundlesFlow, LabelsBundlesFlow try: @@ -31,9 +31,18 @@ DeterministicTracking = dipy_to_nipype_interface("DeterministicTracking", DetTrackFlow) +elif HAVE_DIPY and LooseVersion(dipy_version()) >= LooseVersion('1.0'): + from dipy.workflows import segment, tracking + + l_wkflw = get_dipy_workflows(segment) + get_dipy_workflows(tracking) + for name, obj in l_wkflw: + new_name = name.replace('Flow', '') + globals()[new_name] = dipy_to_nipype_interface(new_name, obj) + del l_wkflw + else: IFLOGGER.info("We advise you to upgrade DIPY version. This upgrade will" - " activate RecoBundles, LabelsBundles, DeterministicTracking.") + " open access to more function") class TrackDensityMapInputSpec(BaseInterfaceInputSpec): From 5f2445ce76f4e3bf998bdf8f063f4df34d2acda4 Mon Sep 17 00:00:00 2001 From: Serge Koudoro Date: Thu, 28 Mar 2019 18:42:21 -0400 Subject: [PATCH 08/12] update zenodo --- .zenodo.json | 4 ++++ nipype/interfaces/dipy/stats.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.zenodo.json b/.zenodo.json index 065e188d8b..857cd9f8de 100644 --- a/.zenodo.json +++ b/.zenodo.json @@ -370,6 +370,10 @@ { "name": "Haselgrove, Christian" }, + { + "name": "Koudoro, Serge", + "affiliation": "Indiana University, IN, USA" + }, { "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.", "name": "Glatard, Tristan", diff --git a/nipype/interfaces/dipy/stats.py b/nipype/interfaces/dipy/stats.py index 6aba67226b..8f55b3322a 100644 --- a/nipype/interfaces/dipy/stats.py +++ b/nipype/interfaces/dipy/stats.py @@ -6,7 +6,7 @@ IFLOGGER = logging.getLogger('nipype.interface') -if HAVE_DIPY and LooseVersion(dipy_version()) >= LooseVersion('0.15'): +if HAVE_DIPY and LooseVersion(dipy_version()) >= LooseVersion('0.16'): from dipy.workflows import stats l_wkflw = get_dipy_workflows(stats) From 289d85669c0403218219424a8f77a36b89fd84e6 Mon Sep 17 00:00:00 2001 From: Serge Koudoro Date: Thu, 28 Mar 2019 19:09:12 -0400 Subject: [PATCH 09/12] fix tests --- nipype/interfaces/dipy/tests/test_base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nipype/interfaces/dipy/tests/test_base.py b/nipype/interfaces/dipy/tests/test_base.py index 045c0a4d24..1d475ac0f7 100644 --- a/nipype/interfaces/dipy/tests/test_base.py +++ b/nipype/interfaces/dipy/tests/test_base.py @@ -144,7 +144,7 @@ def test_get_dipy_workflows(): l_wkflw = get_dipy_workflows(align) for name, obj in l_wkflw: assert name.endswith('Flow') - assert issubclass(align.Workflow) + assert issubclass(obj, align.Workflow) if __name__ == "__main__": From 4f09bac63a7ce8276754fb5cad0a0c3c7c11bb85 Mon Sep 17 00:00:00 2001 From: Serge Koudoro Date: Thu, 28 Mar 2019 19:10:56 -0400 Subject: [PATCH 10/12] doctest skip --- nipype/interfaces/dipy/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nipype/interfaces/dipy/base.py b/nipype/interfaces/dipy/base.py index d46e945e1c..4e9b2c7e01 100644 --- a/nipype/interfaces/dipy/base.py +++ b/nipype/interfaces/dipy/base.py @@ -230,7 +230,7 @@ def get_dipy_workflows(module): Examples -------- >>> from dipy.workflows import align - >>> get_dipy_workflows(align) + >>> get_dipy_workflows(align) # doctest: +SKIP """ return [(m, obj) for m, obj in inspect.getmembers(module) From ece338be8ae976d2a0ca84037f3a5a038e54cbc4 Mon Sep 17 00:00:00 2001 From: Serge Koudoro Date: Fri, 29 Mar 2019 10:16:27 -0400 Subject: [PATCH 11/12] fix doctests error --- nipype/interfaces/dipy/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nipype/interfaces/dipy/base.py b/nipype/interfaces/dipy/base.py index 4e9b2c7e01..a86d5635fb 100644 --- a/nipype/interfaces/dipy/base.py +++ b/nipype/interfaces/dipy/base.py @@ -229,7 +229,7 @@ def get_dipy_workflows(module): Examples -------- - >>> from dipy.workflows import align + >>> from dipy.workflows import align # doctest: +SKIP >>> get_dipy_workflows(align) # doctest: +SKIP """ From bdd4d21d677ea199f345603e3d0cd25ab7d4936f Mon Sep 17 00:00:00 2001 From: Serge Koudoro Date: Thu, 18 Apr 2019 16:17:16 -0400 Subject: [PATCH 12/12] address ariel comment --- nipype/interfaces/dipy/base.py | 6 +++++- nipype/interfaces/dipy/reconstruction.py | 13 +------------ nipype/interfaces/dipy/registration.py | 9 +-------- nipype/interfaces/dipy/tracks.py | 7 +------ 4 files changed, 8 insertions(+), 27 deletions(-) diff --git a/nipype/interfaces/dipy/base.py b/nipype/interfaces/dipy/base.py index a86d5635fb..27f26e989a 100644 --- a/nipype/interfaces/dipy/base.py +++ b/nipype/interfaces/dipy/base.py @@ -10,7 +10,11 @@ from ..base import (traits, File, isdefined, LibraryBaseInterface, BaseInterfaceInputSpec, TraitedSpec) +# List of workflows to ignore +SKIP_WORKFLOWS_LIST = ['Workflow', 'CombinedWorkflow'] + HAVE_DIPY = True + try: import dipy from dipy.workflows.base import IntrospectiveArgumentParser @@ -236,4 +240,4 @@ def get_dipy_workflows(module): return [(m, obj) for m, obj in inspect.getmembers(module) if inspect.isclass(obj) and issubclass(obj, module.Workflow) and - m not in ['Workflow', 'CombinedWorkflow']] + m not in SKIP_WORKFLOWS_LIST] diff --git a/nipype/interfaces/dipy/reconstruction.py b/nipype/interfaces/dipy/reconstruction.py index 6deccd7f9f..6c7c3a847b 100644 --- a/nipype/interfaces/dipy/reconstruction.py +++ b/nipype/interfaces/dipy/reconstruction.py @@ -24,18 +24,7 @@ IFLOGGER = logging.getLogger('nipype.interface') -if HAVE_DIPY and (LooseVersion('0.15') >= LooseVersion(dipy_version()) >= LooseVersion('0.16')): - from dipy.workflows.reconst import (ReconstDkiFlow, ReconstCSAFlow, - ReconstCSDFlow, ReconstMAPMRIFlow, - ReconstDtiFlow) - - DKIModel = dipy_to_nipype_interface("DKIModel", ReconstDkiFlow) - MapmriModel = dipy_to_nipype_interface("MapmriModel", ReconstMAPMRIFlow) - DTIModel = dipy_to_nipype_interface("DTIModel", ReconstDtiFlow) - CSAModel = dipy_to_nipype_interface("CSAModel", ReconstCSAFlow) - CSDModel = dipy_to_nipype_interface("CSDModel", ReconstCSDFlow) - -elif HAVE_DIPY and LooseVersion(dipy_version()) >= LooseVersion('1.0'): +if HAVE_DIPY and LooseVersion(dipy_version()) >= LooseVersion('0.15'): from dipy.workflows import reconst l_wkflw = get_dipy_workflows(reconst) diff --git a/nipype/interfaces/dipy/registration.py b/nipype/interfaces/dipy/registration.py index 6d6d023635..e2e5c1e7ec 100644 --- a/nipype/interfaces/dipy/registration.py +++ b/nipype/interfaces/dipy/registration.py @@ -6,15 +6,8 @@ IFLOGGER = logging.getLogger('nipype.interface') -if HAVE_DIPY and (LooseVersion('0.15') >= LooseVersion(dipy_version()) >= LooseVersion('0.16')): - from dipy.workflows.align import ResliceFlow, SlrWithQbxFlow - - Reslice = dipy_to_nipype_interface("Reslice", ResliceFlow) - StreamlineRegistration = dipy_to_nipype_interface("StreamlineRegistration", - SlrWithQbxFlow) - -elif HAVE_DIPY and LooseVersion(dipy_version()) >= LooseVersion('1.0'): +if HAVE_DIPY and LooseVersion(dipy_version()) >= LooseVersion('0.15'): from dipy.workflows import align l_wkflw = get_dipy_workflows(align) diff --git a/nipype/interfaces/dipy/tracks.py b/nipype/interfaces/dipy/tracks.py index 77c4b55491..60b5127dd1 100644 --- a/nipype/interfaces/dipy/tracks.py +++ b/nipype/interfaces/dipy/tracks.py @@ -18,20 +18,15 @@ if HAVE_DIPY and (LooseVersion('0.15') >= LooseVersion(dipy_version()) >= LooseVersion('0.16')): - - from dipy.workflows.segment import RecoBundlesFlow, LabelsBundlesFlow try: from dipy.workflows.tracking import LocalFiberTrackingPAMFlow as DetTrackFlow except ImportError: # different name in 0.15 from dipy.workflows.tracking import DetTrackPAMFlow as DetTrackFlow - RecoBundles = dipy_to_nipype_interface("RecoBundles", RecoBundlesFlow) - LabelsBundles = dipy_to_nipype_interface("LabelsBundles", - LabelsBundlesFlow) DeterministicTracking = dipy_to_nipype_interface("DeterministicTracking", DetTrackFlow) -elif HAVE_DIPY and LooseVersion(dipy_version()) >= LooseVersion('1.0'): +if HAVE_DIPY and LooseVersion(dipy_version()) >= LooseVersion('0.15'): from dipy.workflows import segment, tracking l_wkflw = get_dipy_workflows(segment) + get_dipy_workflows(tracking)