From 82163d36b8359b00f425fcf1656b95d033d74692 Mon Sep 17 00:00:00 2001 From: ashgillman Date: Tue, 25 Oct 2016 10:31:59 +1000 Subject: [PATCH 1/4] Add failing test demonstrating issue with deep nest graph viz --- nipype/pipeline/engine/tests/test_engine.py | 67 +++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/nipype/pipeline/engine/tests/test_engine.py b/nipype/pipeline/engine/tests/test_engine.py index 3af9c9c564..35e1a6431b 100644 --- a/nipype/pipeline/engine/tests/test_engine.py +++ b/nipype/pipeline/engine/tests/test_engine.py @@ -750,3 +750,70 @@ def func1(in1): os.chdir(cwd) rmtree(wd) + + +def test_write_graph_runs(): + cwd = os.getcwd() + wd = mkdtemp() + os.chdir(wd) + + for graph in ('orig', 'flat', 'exec', 'hierarchical', 'colored'): + for simple in (True, False): + pipe = pe.Workflow(name='pipe') + mod1 = pe.Node(interface=TestInterface(), name='mod1') + mod2 = pe.Node(interface=TestInterface(), name='mod2') + pipe.connect([(mod1, mod2, [('output1', 'input1')])]) + try: + pipe.write_graph(graph2use=graph, simple_form=simple) + except Exception: + yield assert_true, False, \ + 'Failed to plot {} {} graph'.format( + 'simple' if simple else 'detailed', graph) + + yield assert_true, os.path.exists('graph.dot') or os.path.exists('graph_detailed.dot') + try: + os.remove('graph.dot') + except OSError: + pass + try: + os.remove('graph_detailed.dot') + except OSError: + pass + + os.chdir(cwd) + rmtree(wd) + +def test_deep_nested_write_graph_runs(): + cwd = os.getcwd() + wd = mkdtemp() + os.chdir(wd) + + for graph in ('orig', 'flat', 'exec', 'hierarchical', 'colored'): + for simple in (True, False): + pipe = pe.Workflow(name='pipe') + parent = pipe + for depth in range(10): + sub = pe.Workflow(name='pipe_nest_{}'.format(depth)) + parent.add_nodes([sub]) + parent = sub + mod1 = pe.Node(interface=TestInterface(), name='mod1') + parent.add_nodes([mod1]) + try: + pipe.write_graph(graph2use=graph, simple_form=simple) + except Exception as e: + yield assert_true, False, \ + 'Failed to plot {} {} deep graph: {!s}'.format( + 'simple' if simple else 'detailed', graph, e) + + yield assert_true, os.path.exists('graph.dot') or os.path.exists('graph_detailed.dot') + try: + os.remove('graph.dot') + except OSError: + pass + try: + os.remove('graph_detailed.dot') + except OSError: + pass + + os.chdir(cwd) + rmtree(wd) From 58fc79d2bbb9100c07b14851200b6037df0c65ec Mon Sep 17 00:00:00 2001 From: ashgillman Date: Tue, 25 Oct 2016 10:32:46 +1000 Subject: [PATCH 2/4] Fix issue by cycling BRG for nested colors --- nipype/pipeline/engine/workflows.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/nipype/pipeline/engine/workflows.py b/nipype/pipeline/engine/workflows.py index 607fc6ac1c..2e8c7cae21 100644 --- a/nipype/pipeline/engine/workflows.py +++ b/nipype/pipeline/engine/workflows.py @@ -902,8 +902,13 @@ def _get_dot(self, prefix=None, hierarchy=None, colored=False, prefix = ' ' if hierarchy is None: hierarchy = [] - colorset = ['#FFFFC8', '#0000FF', '#B4B4FF', '#E6E6FF', '#FF0000', - '#FFB4B4', '#FFE6E6', '#00A300', '#B4FFB4', '#E6FFE6'] + colorset = ['#FFFFC8', # Y + '#0000FF', '#B4B4FF', '#E6E6FF', # B + '#FF0000', '#FFB4B4', '#FFE6E6', # R + '#00A300', '#B4FFB4', '#E6FFE6', # G + '#0000FF', '#B4B4FF'] # loop B + if level > len(colorset) - 2: + level = 3 # Loop back to blue dotlist = ['%slabel="%s";' % (prefix, self.name)] for node in nx.topological_sort(self._graph): @@ -942,8 +947,6 @@ def _get_dot(self, prefix=None, hierarchy=None, colored=False, colored=colored, simple_form=simple_form, level=level + 3)) dotlist.append('}') - if level == 6: - level = 2 else: for subnode in self._graph.successors_iter(node): if node._hierarchy != subnode._hierarchy: From 4c3a232b5d70da3638ff54dea173bcf3adf55acb Mon Sep 17 00:00:00 2001 From: ashgillman Date: Tue, 25 Oct 2016 16:20:12 +1000 Subject: [PATCH 3/4] Add graphviz dep to Travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index c1ee7ae10b..bd94993b84 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,7 +33,7 @@ install: conda config --add channels conda-forge && conda update --yes conda && conda update --all -y python=$TRAVIS_PYTHON_VERSION && - conda install -y nipype && + conda install -y nipype graphviz && rm -r /home/travis/miniconda/lib/python${TRAVIS_PYTHON_VERSION}/site-packages/nipype* && pip install -r requirements.txt && pip install -e .[$NIPYPE_EXTRAS] && From 7ee83ba3b18b4e6a4a2cfe08747896ffd3993962 Mon Sep 17 00:00:00 2001 From: ashgillman Date: Tue, 25 Oct 2016 16:46:57 +1000 Subject: [PATCH 4/4] Graphviz is a before_install dependency --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index bd94993b84..ba541f63f8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,12 +19,12 @@ before_install: if $INSTALL_DEB_DEPENDECIES; then sudo ln -s /run/shm /dev/shm; fi && bash <(wget -q -O- http://neuro.debian.net/_files/neurodebian-travis.sh) && sudo apt-get -y update && - sudo apt-get -y install xvfb fusefat && + sudo apt-get -y install xvfb fusefat graphviz && if $INSTALL_DEB_DEPENDECIES; then travis_retry sudo apt-get install -y -qq fsl afni elastix fsl-atlases; fi && if $INSTALL_DEB_DEPENDECIES; then source /etc/fsl/fsl.sh; - source /etc/afni/afni.sh; + source /etc/afni/afni.sh; export FSLOUTPUTTYPE=NIFTI_GZ; fi } - travis_retry bef_inst install: @@ -33,7 +33,7 @@ install: conda config --add channels conda-forge && conda update --yes conda && conda update --all -y python=$TRAVIS_PYTHON_VERSION && - conda install -y nipype graphviz && + conda install -y nipype && rm -r /home/travis/miniconda/lib/python${TRAVIS_PYTHON_VERSION}/site-packages/nipype* && pip install -r requirements.txt && pip install -e .[$NIPYPE_EXTRAS] &&