Skip to content
Snippets Groups Projects
Commit 1614bb48 authored by Michiel Cottaar's avatar Michiel Cottaar
Browse files

ENH: created practical on using jupyter/ipython

parent b763b77d
No related branches found
No related tags found
No related merge requests found
%% Cell type:markdown id: tags:
# Jupyter notebook and IPython
Our main interaction with python so far has been through the [Jupyter notebook](http://jupyter.org/).
These notebooks are extremely popular these days within the python scientific community, however they support many more languages, such as R and octave (and even matlab with the right [plugin](https://github.com/Calysto/matlab_kernel)).
They allow for interactive analysis of your data interspersed by explanatory notes (including LaTeX) with inline plotting.
However, they can not be called as scripts on the command line or be imported from other python code, which makes them rather stand-alone.
This makes them more useful for analysis that needs to be reproducible, but does not need to be replicated on different datasets (e.g., making a plot for a paper).
For more ad-hoc analysis it can be useful to just use the command line (i.e., a REPL).
We strongly recommend to use the IPython (available as `ipython` in the terminal after you install `ipython` using `pip` or `conda`) rather than default python REPL (available through `python` or `fslpython`)
Both Ipython and the jupyter notebook offer a whole range of magic commands, which all start with a `%` sign.
* A magic command starting with a single `%` sign will only affect the single line.
* A magic command starting with two '%' signs will affect the whole block of code.
Note that the normal python interpreter will not understand these magic commands, so you will have to take them out when writing a python script or library.
Here we will discuss some of the many features available to you in Ipython and the Jupyter notebook
---
## Getting help
To get the documentation for any object or method simply append a question mark
%% Cell type:code id: tags:
```
import string
string.capwords?
```
%% Cell type:markdown id: tags:
Alternatively you can put two questions marks to get the complete code for the method or object class
%% Cell type:code id: tags:
```
import string
string.capwords??
```
%% Cell type:markdown id: tags:
Both Ipython and Jupyter also come with autocomplete, which is available at any time by pressing <tab>
---
## Running shell commands
Commands starting with a `!` will be sent to the shell rather than the python interpreter.
%% Cell type:code id: tags:
```
!fslstats ${FSLDIR}/data/standard/FMRIB58_FA_1mm.nii.gz -r
```
%% Cell type:markdown id: tags:
---
## Running other programming languages
In the notebook you can include a whole code block using another language by using `%%<language>` (for many languages you will have to install a toolkit first, just google your favorite language besides python)
%% Cell type:code id: tags:
```
%%bash
for filename in `ls *.md` ; do
head -n 1 ${filename}
done
```
%% Cell type:markdown id: tags:
---
## Timing code
We can time a line of code with `%time` or a whole code block using `%%time`.
To get the time needed to calculate the sine of a million random numbers:
%% Cell type:code id: tags:
```
import numpy as np
numbers = np.random.rand(int(1e6))
%time np.sin(numbers)
```
%% Cell type:markdown id: tags:
For very fast evaluation, you might need to run it multiple times to get an accurate estimate. The `%timeit` (or `%%timeit` for a code block) takes care of this for you.
%% Cell type:code id: tags:
```
import numpy as np
numbers = np.random.rand(10)
%timeit np.sin(numbers)
```
%% Cell type:markdown id: tags:
---
## Debugging
Despite your best efforts in many cases some error will crop up
%% Cell type:code id: tags:
```
import numpy as np
def total(a_list):
# create local copy befor changing the input
local_list = list(a_list)
total = 0.
while len(local_list) > 0:
total += local_list.pop(1) # returns element at index=1 and removes it
return total
print(total([2, 3, 4]))
```
%% Cell type:markdown id: tags:
You can always open a debugger at the location of the last error by using the `%debug` magic command. You can find a list of commands available in the debugger [here](http://www.georgejhunt.com/olpc/pydebug/pydebug/ipdb.html)
%% Cell type:code id: tags:
```
%debug
```
%% Cell type:markdown id: tags:
Try to check the value of `a_list` and `local_list` from within the debugger.
If you always want to enter the debugger when an error is raised you can call `%pdb on` at any time (call `%pdf off` to rever this)
---
## Enabling plotting
By far the most popular scientific plotting library is [matplotlib](https://matplotlib.org/).
You can enable plotting in Ipython or the jupyter notebook using `%matplotlib <backend>`, where [backend](https://matplotlib.org/faq/usage_faq.html#what-is-a-backend) is the system that will be used to display the plots.
When failing to provide a backend it will simply use the default (which is usually fine).
* In the jupyter notebook use the `nbagg` backend for interactive plots or the `inline` backend for non-interactive plots
* Otherwise on Mac OSx use the `macosx` backend
%% Cell type:code id: tags:
```
%matplotlib nbagg
```
%% Cell type:markdown id: tags:
> Keep in mind that as soon as you have started plotting you can no longer change your backend without restarting python.
To do the equivalent in a python script would look like
%% Cell type:code id: tags:
```
import matplotlib as mpl
mpl.use(<backend>)
```
%% Cell type:markdown id: tags:
For interactive use it can be handy to have all the `numpy` numeric functions and `matplotlib` plotting functions directly available without importing them explicitly.
This can be achieved using the `%pylab <backend>` magic command.
%% Cell type:code id: tags:
```
%pylab nbagg
```
%% Cell type:markdown id: tags:
This is equivalent in python code to:
%% Cell type:code id: tags:
```
import matplotlib as mpl
mpl.use(<backend>)
from matplotlib.pylab import *
```
%% Cell type:markdown id: tags:
I start most of my notebooks or terminals with the `%pylab` command, because afterwards I can just do stuff like:
%% Cell type:code id: tags:
```
x = linspace(0, pi, 301)
y = sin(x)
plot(x, y, 'r-')
```
%% Cell type:markdown id: tags:
---
## Exporting code from the Jupyter notebook
If you have a code cell in the jupyter notebook, that you want to convert into a script, you can use the %%writefile
%% Cell type:code id: tags:
```
%%writefile script_from_notebook.py
# a bunch of imports
import numpy as np
from datetime import datetime
```
%% Cell type:markdown id: tags:
Any additional code cells need to contain the `-a` flag to stop jupyter from overwriting the original code
%% Cell type:code id: tags:
```
%%writefile -a script_from_notebook.py
print('today is ', datetime.now())
print('sin(3) is ', np.sin(3))
```
%% Cell type:markdown id: tags:
We can now run this script
%% Cell type:code id: tags:
```
!python script_from_notebook.py
```
%% Cell type:markdown id: tags:
---
## Exporting code from the Ipython terminal
You can access the full history of your session using `%history`.
To save the history to a file use `%history -f <filename>`
You will probably have to clean a lot of erroneous commands you typed from that file before you are able to run it as a script.
# Jupyter notebook and IPython
Our main interaction with python so far has been through the [Jupyter notebook](http://jupyter.org/).
These notebooks are extremely popular these days within the python scientific community, however they support many more languages, such as R and octave (and even matlab with the right [plugin](https://github.com/Calysto/matlab_kernel)).
They allow for interactive analysis of your data interspersed by explanatory notes (including LaTeX) with inline plotting.
However, they can not be called as scripts on the command line or be imported from other python code, which makes them rather stand-alone.
This makes them more useful for analysis that needs to be reproducible, but does not need to be replicated on different datasets (e.g., making a plot for a paper).
For more ad-hoc analysis it can be useful to just use the command line (i.e., a REPL).
We strongly recommend to use the IPython (available as `ipython` in the terminal after you install `ipython` using `pip` or `conda`) rather than default python REPL (available through `python` or `fslpython`)
Both Ipython and the jupyter notebook offer a whole range of magic commands, which all start with a `%` sign.
* A magic command starting with a single `%` sign will only affect the single line.
* A magic command starting with two '%' signs will affect the whole block of code.
Note that the normal python interpreter will not understand these magic commands, so you will have to take them out when writing a python script or library.
Here we will discuss some of the many features available to you in Ipython and the Jupyter notebook
---
## Getting help
To get the documentation for any object or method simply append a question mark
```
import string
string.capwords?
```
Alternatively you can put two questions marks to get the complete code for the method or object class
```
import string
string.capwords??
```
Both Ipython and Jupyter also come with autocomplete, which is available at any time by pressing <tab>
---
## Running shell commands
Commands starting with a `!` will be sent to the shell rather than the python interpreter.
```
!fslstats ${FSLDIR}/data/standard/FMRIB58_FA_1mm.nii.gz -r
```
---
## Running other programming languages
In the notebook you can include a whole code block using another language by using `%%<language>` (for many languages you will have to install a toolkit first, just google your favorite language besides python)
```
%%bash
for filename in `ls *.md` ; do
head -n 1 ${filename}
done
```
---
## Timing code
We can time a line of code with `%time` or a whole code block using `%%time`.
To get the time needed to calculate the sine of a million random numbers:
```
import numpy as np
numbers = np.random.rand(int(1e6))
%time np.sin(numbers)
```
For very fast evaluation, you might need to run it multiple times to get an accurate estimate. The `%timeit` (or `%%timeit` for a code block) takes care of this for you.
```
import numpy as np
numbers = np.random.rand(10)
%timeit np.sin(numbers)
```
---
## Debugging
Despite your best efforts in many cases some error will crop up
```
import numpy as np
def total(a_list):
# create local copy befor changing the input
local_list = list(a_list)
total = 0.
while len(local_list) > 0:
total += local_list.pop(1) # returns element at index=1 and removes it
return total
print(total([2, 3, 4]))
```
You can always open a debugger at the location of the last error by using the `%debug` magic command. You can find a list of commands available in the debugger [here](http://www.georgejhunt.com/olpc/pydebug/pydebug/ipdb.html)
```
%debug
```
Try to check the value of `a_list` and `local_list` from within the debugger.
If you always want to enter the debugger when an error is raised you can call `%pdb on` at any time (call `%pdf off` to rever this)
---
## Enabling plotting
By far the most popular scientific plotting library is [matplotlib](https://matplotlib.org/).
You can enable plotting in Ipython or the jupyter notebook using `%matplotlib <backend>`, where [backend](https://matplotlib.org/faq/usage_faq.html#what-is-a-backend) is the system that will be used to display the plots.
When failing to provide a backend it will simply use the default (which is usually fine).
* In the jupyter notebook use the `nbagg` backend for interactive plots or the `inline` backend for non-interactive plots
* Otherwise on Mac OSx use the `macosx` backend
```
%matplotlib nbagg
```
> Keep in mind that as soon as you have started plotting you can no longer change your backend without restarting python.
To do the equivalent in a python script would look like
```
import matplotlib as mpl
mpl.use(<backend>)
```
For interactive use it can be handy to have all the `numpy` numeric functions and `matplotlib` plotting functions directly available without importing them explicitly.
This can be achieved using the `%pylab <backend>` magic command.
```
%pylab nbagg
```
This is equivalent in python code to:
```
import matplotlib as mpl
mpl.use(<backend>)
from matplotlib.pylab import *
```
I start most of my notebooks or terminals with the `%pylab` command, because afterwards I can just do stuff like:
```
x = linspace(0, pi, 301)
y = sin(x)
plot(x, y, 'r-')
```
---
## Exporting code from the Jupyter notebook
If you have a code cell in the jupyter notebook, that you want to convert into a script, you can use the %%writefile
```
%%writefile script_from_notebook.py
# a bunch of imports
import numpy as np
from datetime import datetime
```
Any additional code cells need to contain the `-a` flag to stop jupyter from overwriting the original code
```
%%writefile -a script_from_notebook.py
print('today is ', datetime.now())
print('sin(3) is ', np.sin(3))
```
We can now run this script
```
!python script_from_notebook.py
```
---
## Exporting code from the Ipython terminal
You can access the full history of your session using `%history`.
To save the history to a file use `%history -f <filename>`
You will probably have to clean a lot of erroneous commands you typed from that file before you are able to run it as a script.
...@@ -9,6 +9,5 @@ This directory contains the "Getting started" practical. ...@@ -9,6 +9,5 @@ This directory contains the "Getting started" practical.
4. Numpy (PM) 4. Numpy (PM)
5. Nifti images (MJ) 5. Nifti images (MJ)
6. Image manipulation (MC) 6. Image manipulation (MC)
7. Moving from the Jupyter notebook to a text editor and terminal (MC) 7. Jupyter notebook and Ipython(MC)
8. Writing a callable script (MJ) 8. Writing a callable script (MJ)
9. Debugging (MC)
...@@ -483,13 +483,13 @@ ...@@ -483,13 +483,13 @@
{ {
"ename": "IndexError", "ename": "IndexError",
"evalue": "list index out of range", "evalue": "list index out of range",
"output_type": "error",
"traceback": [ "traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mIndexError\u001b[0m Traceback (most recent call last)", "\u001b[0;31mIndexError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-78-f4cf4536701c>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m7\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;32m<ipython-input-78-f4cf4536701c>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m7\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;31mIndexError\u001b[0m: list index out of range" "\u001b[0;31mIndexError\u001b[0m: list index out of range"
] ],
"output_type": "error"
} }
], ],
"source": [ "source": [
...@@ -504,13 +504,13 @@ ...@@ -504,13 +504,13 @@
{ {
"ename": "IndexError", "ename": "IndexError",
"evalue": "list index out of range", "evalue": "list index out of range",
"output_type": "error",
"traceback": [ "traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mIndexError\u001b[0m Traceback (most recent call last)", "\u001b[0;31mIndexError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-79-52d95fbe5286>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m6\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;32m<ipython-input-79-52d95fbe5286>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m6\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;31mIndexError\u001b[0m: list index out of range" "\u001b[0;31mIndexError\u001b[0m: list index out of range"
] ],
"output_type": "error"
} }
], ],
"source": [ "source": [
...@@ -647,13 +647,13 @@ ...@@ -647,13 +647,13 @@
{ {
"ename": "TypeError", "ename": "TypeError",
"evalue": "list indices must be integers or slices, not list", "evalue": "list indices must be integers or slices, not list",
"output_type": "error",
"traceback": [ "traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-84-aad7915ae3d8>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mb\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;36m3\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m4\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mb\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;32m<ipython-input-84-aad7915ae3d8>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mb\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;36m3\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m4\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mb\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;31mTypeError\u001b[0m: list indices must be integers or slices, not list" "\u001b[0;31mTypeError\u001b[0m: list indices must be integers or slices, not list"
] ],
"output_type": "error"
} }
], ],
"source": [ "source": [
......
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
# Callable scripts in python # Callable scripts in python
In this tutorial we will cover how to write simple stand-alone scripts in python that can be used as alternatives to bash scripts. In this tutorial we will cover how to write simple stand-alone scripts in python that can be used as alternatives to bash scripts.
There are some code blocks within this webpage, but we recommend that you write the code in an IDE or editor instead and then run the scripts from a terminal. There are some code blocks within this webpage, but we recommend that you write the code in an IDE or editor instead and then run the scripts from a terminal.
## Basic script ## Basic script
The first line of a python script is usually: The first line of a python script is usually:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` ``` python
#!/usr/bin/env python #!/usr/bin/env python
``` ```
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
which invokes whichever version of python can be found by `/usr/bin/env` since python can be located in many different places. which invokes whichever version of python can be found by `/usr/bin/env` since python can be located in many different places.
For FSL scripts we use an alternative, to ensure that we pick up the version of python (and associated packages) that we ship with FSL. To do this we use the line: For FSL scripts we use an alternative, to ensure that we pick up the version of python (and associated packages) that we ship with FSL. To do this we use the line:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` ``` python
#!/usr/bin/env fslpython #!/usr/bin/env fslpython
``` ```
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
After this line the rest of the file just uses regular python syntax, as in the other tutorials. Make sure you make the file executable - just like a bash script. After this line the rest of the file just uses regular python syntax, as in the other tutorials. Make sure you make the file executable - just like a bash script.
## Calling other executables ## Calling other executables
The most essential call that you need to use to replicate the way a bash script calls executables is `subprocess.run()`. A simple call looks like this: The most essential call that you need to use to replicate the way a bash script calls executables is `subprocess.run()`. A simple call looks like this:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` ``` python
import subprocess as sp import subprocess as sp
sp.run(['ls', '-la']) sp.run(['ls', '-la'])
``` ```
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
To suppress the output do this: To suppress the output do this:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` ``` python
spobj = sp.run(['ls'], stdout = sp.PIPE) spobj = sp.run(['ls'], stdout = sp.PIPE)
``` ```
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
To store the output do this: To store the output do this:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` ``` python
spobj = sp.run('ls -la'.split(), stdout = sp.PIPE) spobj = sp.run('ls -la'.split(), stdout = sp.PIPE)
sout = spobj.stdout.decode('utf-8') sout = spobj.stdout.decode('utf-8')
print(sout) print(sout)
``` ```
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
> Note that the `decode` call in the middle line converts the string from a byte string to a normal string. In Python 3 there is a distinction between strings (sequences of characters, possibly using multiple bytes to store each character) and bytes (sequences of bytes). The world has moved on from ASCII, so in this day and age, this distinction is absolutely necessary, and Python does a fairly good job of it. > Note that the `decode` call in the middle line converts the string from a byte string to a normal string. In Python 3 there is a distinction between strings (sequences of characters, possibly using multiple bytes to store each character) and bytes (sequences of bytes). The world has moved on from ASCII, so in this day and age, this distinction is absolutely necessary, and Python does a fairly good job of it.
If the output is numerical then this can be extracted like this: If the output is numerical then this can be extracted like this:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` ``` python
import os import os
fsldir = os.getenv('FSLDIR') fsldir = os.getenv('FSLDIR')
spobj = sp.run([fsldir+'/bin/fslstats', fsldir+'/data/standard/MNI152_T1_1mm_brain', '-V'], stdout = sp.PIPE) spobj = sp.run([fsldir+'/bin/fslstats', fsldir+'/data/standard/MNI152_T1_1mm_brain', '-V'], stdout = sp.PIPE)
sout = spobj.stdout.decode('utf-8') sout = spobj.stdout.decode('utf-8')
vol_vox = float(sout.split()[0]) vol_vox = float(sout.split()[0])
vol_mm = float(sout.split()[1]) vol_mm = float(sout.split()[1])
print('Volumes are: ', vol_vox, ' in voxels and ', vol_mm, ' in mm') print('Volumes are: ', vol_vox, ' in voxels and ', vol_mm, ' in mm')
``` ```
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
An alternative way to run a set of commands would be like this: An alternative way to run a set of commands would be like this:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` ``` python
commands = """ commands = """
{fsldir}/bin/fslmaths {t1} -bin {t1_mask} {fsldir}/bin/fslmaths {t1} -bin {t1_mask}
{fsldir}/bin/fslmaths {t2} -mas {t1_mask} {t2_masked} {fsldir}/bin/fslmaths {t2} -mas {t1_mask} {t2_masked}
""" """
fsldirpath = os.getenv('FSLDIR') fsldirpath = os.getenv('FSLDIR')
commands = commands.format(t1 = 't1.nii.gz', t1_mask = 't1_mask', t2 = 't2', t2_masked = 't2_masked', fsldir = fsldirpath) commands = commands.format(t1 = 't1.nii.gz', t1_mask = 't1_mask', t2 = 't2', t2_masked = 't2_masked', fsldir = fsldirpath)
sout=[] sout=[]
for cmd in commands.split('\n'): for cmd in commands.split('\n'):
if cmd: # avoids empty strings getting passed to sp.run() if cmd: # avoids empty strings getting passed to sp.run()
print('Running command: ', cmd) print('Running command: ', cmd)
spobj = sp.run(cmd.split(), stdout = sp.PIPE) spobj = sp.run(cmd.split(), stdout = sp.PIPE)
sout.append(spobj.stdout.decode('utf-8')) sout.append(spobj.stdout.decode('utf-8'))
``` ```
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
## Command line arguments ## Command line arguments
The simplest way of dealing with command line arguments is use the module `sys`, which gives access to an `argv` list: The simplest way of dealing with command line arguments is use the module `sys`, which gives access to an `argv` list:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` ``` python
import sys import sys
print(len(sys.argv)) print(len(sys.argv))
print(sys.argv[0]) print(sys.argv[0])
``` ```
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
For more sophisticated argument parsing you can use `argparse` - good documentation and examples of this can be found on the web. For more sophisticated argument parsing you can use `argparse` - good documentation and examples of this can be found on the web.
## Example script ## Example script
Here is a simple bash script (it masks an image and calculates volumes - just as a random example). DO NOT execute the code blocks here within the notebook/webpage: Here is a simple bash script (it masks an image and calculates volumes - just as a random example). DO NOT execute the code blocks here within the notebook/webpage:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` ``` python
%%bash
#!/bin/bash #!/bin/bash
if [ $# -lt 2 ] ; then if [ $# -lt 2 ] ; then
echo "Usage: $0 <input image> <output image>" echo "Usage: $0 <input image> <output image>"
exit 1 exit 1
fi fi
infile=$1 infile=$1
outfile=$2 outfile=$2
# mask input image with MNI # mask input image with MNI
$FSLDIR/bin/fslmaths $infile -mas $FSLDIR/data/standard/MNI152_T1_1mm_brain $outfile $FSLDIR/bin/fslmaths $infile -mas $FSLDIR/data/standard/MNI152_T1_1mm_brain $outfile
# calculate volumes of masked image # calculate volumes of masked image
vv=`$FSLDIR/bin/fslstats $outfile -V` vv=`$FSLDIR/bin/fslstats $outfile -V`
vol_vox=`echo $vv | awk '{ print $1 }'` vol_vox=`echo $vv | awk '{ print $1 }'`
vol_mm=`echo $vv | awk '{ print $2 }'` vol_mm=`echo $vv | awk '{ print $2 }'`
echo "Volumes are: $vol_vox in voxels and $vol_mm in mm" echo "Volumes are: $vol_vox in voxels and $vol_mm in mm"
``` ```
%% Output
Usage: bash <input image> <output image>
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
And an alternative in python: And an alternative in python:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` ``` python
#!/usr/bin/env fslpython #!/usr/bin/env fslpython
import os, sys import os, sys
import subprocess as sp import subprocess as sp
fsldir=os.getenv('FSLDIR') fsldir=os.getenv('FSLDIR')
if len(sys.argv)<2: if len(sys.argv)<2:
print('Usage: ', sys.argv[0], ' <input image> <output image>') print('Usage: ', sys.argv[0], ' <input image> <output image>')
sys.exit(1) sys.exit(1)
infile = sys.argv[1] infile = sys.argv[1]
outfile = sys.argv[2] outfile = sys.argv[2]
# mask input image with MNI # mask input image with MNI
spobj = sp.run([fsldir+'/bin/fslmaths', infile, '-mas', fsldir+'/data/standard/MNI152_T1_1mm_brain', outfile], stdout = sp.PIPE) spobj = sp.run([fsldir+'/bin/fslmaths', infile, '-mas', fsldir+'/data/standard/MNI152_T1_1mm_brain', outfile], stdout = sp.PIPE)
# calculate volumes of masked image # calculate volumes of masked image
spobj = sp.run([fsldir+'/bin/fslstats', outfile, '-V'], stdout = sp.PIPE) spobj = sp.run([fsldir+'/bin/fslstats', outfile, '-V'], stdout = sp.PIPE)
sout = spobj.stdout.decode('utf-8') sout = spobj.stdout.decode('utf-8')
vol_vox = float(sout.split()[0]) vol_vox = float(sout.split()[0])
vol_mm = float(sout.split()[1]) vol_mm = float(sout.split()[1])
print('Volumes are: ', vol_vox, ' in voxels and ', vol_mm, ' in mm') print('Volumes are: ', vol_vox, ' in voxels and ', vol_mm, ' in mm')
``` ```
%% Output
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-2-f7378930c369> in <module>()
13 spobj = sp.run([fsldir+'/bin/fslstats', outfile, '-V'], stdout = sp.PIPE)
14 sout = spobj.stdout.decode('utf-8')
---> 15 vol_vox = float(sout.split()[0])
16 vol_mm = float(sout.split()[1])
17 print('Volumes are: ', vol_vox, ' in voxels and ', vol_mm, ' in mm')
IndexError: list index out of range
%% Cell type:code id: tags:
``` python
```
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment