Repository: nipy/nipype

Issue:
make reports optional/configurable
ATM writing reports seems to be unconditionally invoked if I see it right.  it adds additional burden although some (majority?) of users (khe khe) not using/looking into those reports at the moment.



Discussion:
+1.  I think this can be accomplished with a few if statements in front of the calls to various write_report functions scattered throughout the Workflow and Node classes, right?


Resolving patch:
diff --git a/nipype/pipeline/engine.py b/nipype/pipeline/engine.py
--- a/nipype/pipeline/engine.py
+++ b/nipype/pipeline/engine.py
@@ -464,7 +464,8 @@ def run(self, plugin=None, plugin_args=None, updatehash=False):
             if isinstance(node, MapNode):
                 node.use_plugin = (plugin, plugin_args)
         self._configure_exec_nodes(execgraph)
-        self._write_report_info(self.base_dir, self.name, execgraph)
+        if not str2bool(self.config['execution']['create_report']):
+            self._write_report_info(self.base_dir, self.name, execgraph)
         runner.run(execgraph, updatehash=updatehash, config=self.config)
         return execgraph
 
@@ -1374,6 +1375,8 @@ def update(self, **opts):
         self.inputs.update(**opts)
 
     def write_report(self, report_type=None, cwd=None):
+        if not str2bool(self.config['execution']['create_report']):
+            return
         report_dir = os.path.join(cwd, '_report')
         report_file = os.path.join(report_dir, 'report.rst')
         if not os.path.exists(report_dir):
@@ -1585,6 +1588,8 @@ def _collate_results(self, nodes):
                                                                 '\n'.join(msg)))
 
     def write_report(self, report_type=None, cwd=None):
+        if not str2bool(self.config['execution']['create_report']):
+            return
         if report_type == 'preexec':
             super(MapNode, self).write_report(report_type=report_type, cwd=cwd)
         if report_type == 'postexec':
diff --git a/nipype/utils/config.py b/nipype/utils/config.py
--- a/nipype/utils/config.py
+++ b/nipype/utils/config.py
@@ -23,6 +23,7 @@
 log_rotate = 4
 
 [execution]
+create_report = true
 plugin = Linear
 stop_on_first_crash = false
 stop_on_first_rerun = false
diff --git a/nipype/utils/misc.py b/nipype/utils/misc.py
--- a/nipype/utils/misc.py
+++ b/nipype/utils/misc.py
@@ -139,7 +139,7 @@ def str2bool(v):
     lower = v.lower()
     if lower in ("yes", "true", "t", "1"):
         return True
-    elif lower in ("no", "false", "n", "0"):
+    elif lower in ("no", "false", "n", "f", "0"):
         return False
     else:
         raise ValueError("%s cannot be converted to bool"%v)


Test patch:
diff --git a/nipype/utils/tests/test_misc.py b/nipype/utils/tests/test_misc.py
--- a/nipype/utils/tests/test_misc.py
+++ b/nipype/utils/tests/test_misc.py
@@ -1,9 +1,9 @@
 # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*-
 # vi: set ft=python sts=4 ts=4 sw=4 et:
-from nipype.testing import assert_equal, assert_true
+from nipype.testing import assert_equal, assert_true, assert_false
 
-from nipype.utils.misc import container_to_string, \
-     getsource, create_function_from_source
+from nipype.utils.misc import (container_to_string, getsource,
+                               create_function_from_source, str2bool)
 
 def test_cont_to_str():
     # list
@@ -39,3 +39,15 @@ def func1(x):
         f_src = getsource(f)
         f_recreated = create_function_from_source(f_src)
         yield assert_equal, f(2.3), f_recreated(2.3)
+
+def test_str2bool():
+    yield assert_true, str2bool("yes")
+    yield assert_true, str2bool("true")
+    yield assert_true, str2bool("t")
+    yield assert_true, str2bool("1")
+    yield assert_false, str2bool("no")
+    yield assert_false, str2bool("false")
+    yield assert_false, str2bool("n")
+    yield assert_false, str2bool("f")
+    yield assert_false, str2bool("0")
+