-
Notifications
You must be signed in to change notification settings - Fork 533
nipype_cmd - run any Interface from a command line #795
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
Merged
Merged
Changes from all commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
d6767be
OPEN - task 788: Add support for running interface from commandline
chrisgorgo 9770dfb
switched to argparse
chrisgorgo a3c7bd8
The command now runs.
chrisgorgo ff9f298
added listing interfaces
chrisgorgo f0114c3
removed the .py extension
chrisgorgo 4153c97
fixed --help on top level
chrisgorgo 00aac83
make nipype_cmd executable
chrisgorgo a056a8b
refactor, added tests
chrisgorgo f971e0e
Added more tests
chrisgorgo 2e3ef31
fixed runtime naming
chrisgorgo d753840
added argparse as a dependency
chrisgorgo 2871bff
added argparse dependency on travis
chrisgorgo 6e442d0
Fixed casting
chrisgorgo 742d649
Revert "added argparse dependency on travis"
chrisgorgo 97cd37c
Revert "added argparse as a dependency"
chrisgorgo 55022bc
added documentation
chrisgorgo 49f2bd9
updated change log
chrisgorgo e4ed610
added missing doc file
chrisgorgo a58af1f
Improved input options description.
chrisgorgo f4b94a4
make the tests more robust
chrisgorgo fbe186d
and even more robust...
chrisgorgo File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
#!/usr/bin/env python | ||
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- | ||
# vi: set ft=python sts=4 ts=4 sw=4 et: | ||
import sys | ||
from nipype.utils.nipype_cmd import main | ||
|
||
if __name__ == '__main__': | ||
main(sys.argv) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,6 +37,7 @@ | |
saving_workflows | ||
spmmcr | ||
mipav | ||
nipypecmd | ||
|
||
|
||
|
||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
.. _nipypecmd: | ||
|
||
============================================================ | ||
Running Nipype Interfaces from the command line (nipype_cmd) | ||
============================================================ | ||
|
||
The primary use of Nipype_ is to build automated non-interactive pipelines. | ||
However, sometimes there is a need to run some interfaces quickly from the command line. | ||
This is especially useful when running Interfaces wrapping code that does not have | ||
command line equivalents (nipy or SPM). Being able to run Nipype interfaces opens new | ||
possibilities such as inclusion of SPM processing steps in bash scripts. | ||
|
||
To run Nipype Interafces you need to use the nipype_cmd tool that should already be installed. | ||
The tool allows you to list Interfaces available in a certain package: | ||
|
||
.. testcode:: | ||
|
||
|
||
$nipype_cmd nipype.interfaces.nipy | ||
|
||
Available Interfaces: | ||
SpaceTimeRealigner | ||
Similarity | ||
ComputeMask | ||
FitGLM | ||
EstimateContrast | ||
FmriRealign4d | ||
|
||
After selecting a particular Interface you can learn what inputs it requires: | ||
|
||
.. testcode:: | ||
|
||
|
||
$nipype_cmd nipype.interfaces.nipy ComputeMask --help | ||
|
||
usage:nipype_cmd nipype.interfaces.nipy ComputeMask [-h] [--M M] [--cc CC] | ||
[--ignore_exception IGNORE_EXCEPTION] | ||
[--m M] | ||
[--reference_volume REFERENCE_VOLUME] | ||
mean_volume | ||
|
||
Run ComputeMask | ||
|
||
positional arguments: | ||
mean_volume mean EPI image, used to compute the threshold for the | ||
mask | ||
|
||
optional arguments: | ||
-h, --help show this help message and exit | ||
--M M upper fraction of the histogram to be discarded | ||
--cc CC Keep only the largest connected component | ||
--ignore_exception IGNORE_EXCEPTION | ||
Print an error message instead of throwing an | ||
exception in case the interface fails to run | ||
--m M lower fraction of the histogram to be discarded | ||
--reference_volume REFERENCE_VOLUME | ||
reference volume used to compute the mask. If none is | ||
give, the mean volume is used. | ||
|
||
Finally you can run run the Interface: | ||
|
||
.. testcode:: | ||
|
||
$nipype_cmd nipype.interfaces.nipy ComputeMask mean.nii.gz | ||
|
||
All that from the command line without having to start python interpreter manually. | ||
|
||
.. include:: ../links_names.txt |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import os | ||
import argparse | ||
import inspect | ||
import sys | ||
from nipype.interfaces.base import Interface | ||
|
||
|
||
def listClasses(module=None): | ||
if module: | ||
__import__(module) | ||
pkg = sys.modules[module] | ||
print "Available Interfaces:" | ||
for k,v in pkg.__dict__.items(): | ||
if inspect.isclass(v) and issubclass(v, Interface): | ||
print "\t%s"%k | ||
|
||
def add_options(parser=None, module=None, function=None): | ||
interface = None | ||
if parser and module and function: | ||
__import__(module) | ||
interface = getattr(sys.modules[module],function)() | ||
|
||
inputs = interface.input_spec() | ||
for name, spec in sorted(interface.inputs.traits(transient=None).items()): | ||
desc = "\n".join(interface._get_trait_desc(inputs, name, spec))[len(name)+2:] | ||
if hasattr(spec, "mandatory") and spec.mandatory: | ||
parser.add_argument(name, help=desc) | ||
else: | ||
parser.add_argument("--%s"%name, dest=name, | ||
help=desc) | ||
return parser, interface | ||
|
||
def run_instance(interface, options): | ||
if interface: | ||
print "setting function inputs" | ||
|
||
for input_name, _ in interface.inputs.items(): | ||
if getattr(options, input_name) != None: | ||
value = getattr(options, input_name) | ||
#traits cannot cast from string to float or int | ||
try: | ||
value = float(value) | ||
except: | ||
pass | ||
|
||
try: | ||
setattr(interface.inputs, input_name, | ||
value) | ||
except ValueError, e: | ||
print "Error when setting the value of %s: '%s'"%(input_name, str(e)) | ||
|
||
print interface.inputs | ||
res = interface.run() | ||
print res.outputs | ||
|
||
|
||
def main(argv): | ||
|
||
if len(argv) == 2 and not argv[1].startswith("-"): | ||
listClasses(argv[1]) | ||
sys.exit(0) | ||
|
||
parser = argparse.ArgumentParser(description='Nipype interface runner', prog=argv[0]) | ||
parser.add_argument("module", type=str, help="Module name") | ||
parser.add_argument("interface", type=str, help="Interface name") | ||
parsed = parser.parse_args(args=argv[1:3]) | ||
|
||
_, prog = os.path.split(argv[0]) | ||
interface_parser = argparse.ArgumentParser(description="Run %s"%parsed.interface, prog=" ".join([prog] + argv[1:3])) | ||
interface_parser, interface = add_options(interface_parser, parsed.module, parsed.interface) | ||
args = interface_parser.parse_args(args=argv[3:]) | ||
run_instance(interface, args) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
#!/usr/bin/env python | ||
|
||
from StringIO import StringIO | ||
import unittest, sys | ||
from nipype.utils import nipype_cmd | ||
from contextlib import contextmanager | ||
|
||
@contextmanager | ||
def capture_sys_output(): | ||
caputure_out, capture_err = StringIO(), StringIO() | ||
current_out, current_err = sys.stdout, sys.stderr | ||
try: | ||
sys.stdout, sys.stderr = caputure_out, capture_err | ||
yield caputure_out, capture_err | ||
finally: | ||
sys.stdout, sys.stderr = current_out, current_err | ||
|
||
|
||
class TestNipypeCMD(unittest.TestCase): | ||
|
||
def test_main_returns_2_on_empty(self): | ||
with self.assertRaises(SystemExit) as cm: | ||
with capture_sys_output() as (stdout, stderr): | ||
nipype_cmd.main(['nipype_cmd']) | ||
|
||
exit_exception = cm.exception | ||
self.assertEqual(exit_exception.code, 2) | ||
|
||
self.assertEqual(stderr.getvalue(), | ||
"""usage: nipype_cmd [-h] module interface | ||
nipype_cmd: error: too few arguments | ||
""") | ||
self.assertEqual(stdout.getvalue(), '') | ||
|
||
def test_main_returns_0_on_help(self): | ||
with self.assertRaises(SystemExit) as cm: | ||
with capture_sys_output() as (stdout, stderr): | ||
nipype_cmd.main(['nipype_cmd', '-h']) | ||
|
||
exit_exception = cm.exception | ||
self.assertEqual(exit_exception.code, 0) | ||
|
||
self.assertEqual(stderr.getvalue(), '') | ||
self.assertEqual(stdout.getvalue(), | ||
"""usage: nipype_cmd [-h] module interface | ||
|
||
Nipype interface runner | ||
|
||
positional arguments: | ||
module Module name | ||
interface Interface name | ||
|
||
optional arguments: | ||
-h, --help show this help message and exit | ||
""") | ||
|
||
def test_list_nipy_interfacesp(self): | ||
with self.assertRaises(SystemExit) as cm: | ||
with capture_sys_output() as (stdout, stderr): | ||
nipype_cmd.main(['nipype_cmd', 'nipype.interfaces.nipy']) | ||
|
||
exit_exception = cm.exception | ||
self.assertEqual(exit_exception.code, 0) | ||
|
||
self.assertEqual(stderr.getvalue(), '') | ||
self.assertEqual(stdout.getvalue(), | ||
"""Available Interfaces: | ||
SpaceTimeRealigner | ||
Similarity | ||
ComputeMask | ||
FitGLM | ||
EstimateContrast | ||
FmriRealign4d | ||
""") | ||
|
||
def test_run_4d_realign_without_arguments(self): | ||
with self.assertRaises(SystemExit) as cm: | ||
with capture_sys_output() as (stdout, stderr): | ||
nipype_cmd.main(['nipype_cmd', 'nipype.interfaces.nipy', 'FmriRealign4d']) | ||
|
||
exit_exception = cm.exception | ||
self.assertEqual(exit_exception.code, 2) | ||
|
||
self.assertEqual(stderr.getvalue(), | ||
"""usage: nipype_cmd nipype.interfaces.nipy FmriRealign4d [-h] | ||
[--between_loops BETWEEN_LOOPS] | ||
[--ignore_exception IGNORE_EXCEPTION] | ||
[--loops LOOPS] | ||
[--slice_order SLICE_ORDER] | ||
[--speedup SPEEDUP] | ||
[--start START] | ||
[--time_interp TIME_INTERP] | ||
[--tr_slices TR_SLICES] | ||
in_file tr | ||
nipype_cmd nipype.interfaces.nipy FmriRealign4d: error: too few arguments | ||
""") | ||
self.assertEqual(stdout.getvalue(), '') | ||
|
||
def test_run_4d_realign_help(self): | ||
with self.assertRaises(SystemExit) as cm: | ||
with capture_sys_output() as (stdout, stderr): | ||
nipype_cmd.main(['nipype_cmd', 'nipype.interfaces.nipy', 'FmriRealign4d', '-h']) | ||
|
||
exit_exception = cm.exception | ||
self.assertEqual(exit_exception.code, 0) | ||
|
||
self.assertEqual(stderr.getvalue(), '') | ||
self.assertTrue("Run FmriRealign4d" in stdout.getvalue()) | ||
|
||
if __name__ == '__main__': | ||
unittest.main() |
This file was deleted.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
this file is missing.
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.
fixed
On Wed, Mar 18, 2015 at 3:49 PM, Satrajit Ghosh notifications@github.com
wrote: