Skip to content
Snippets Groups Projects
Commit 9154da72 authored by Paul McCarthy's avatar Paul McCarthy :mountain_bicyclist:
Browse files

Numbered getting_started pracs

parent 63712318
No related branches found
No related tags found
No related merge requests found
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
# Basic python # Basic python
This tutorial is aimed at briefly introducing you to the main language This tutorial is aimed at briefly introducing you to the main language
features of python, with emphasis on some of the common difficulties features of python, with emphasis on some of the common difficulties
and pitfalls that are commonly encountered when moving to python. and pitfalls that are commonly encountered when moving to python.
When going through this make sure that you _run_ each code block When going through this make sure that you _run_ each code block
and look at the output, as these are crucial for understanding the and look at the output, as these are crucial for understanding the
explanations. You can run each block by using _shift + enter_ (including the text blocks, so you can just move down the document with shift + enter). explanations. You can run each block by using _shift + enter_ (including the text blocks, so you can just move down the document with shift + enter).
--- ---
# Basic types # Basic types
Python has many different types and variables are dynamic and can change types (like MATLAB). Some of the most commonly used in-built types are: Python has many different types and variables are dynamic and can change types (like MATLAB). Some of the most commonly used in-built types are:
* integer and floating point scalars * integer and floating point scalars
* strings * strings
* tuples * tuples
* lists * lists
* dictionary * dictionary
N-dimensional arrays and other types are supported through common modules (e.g., numpy, scipy, scikit-learn). These will be covered in a subsequent exercise. N-dimensional arrays and other types are supported through common modules (e.g., numpy, scipy, scikit-learn). These will be covered in a subsequent exercise.
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
a = 4 a = 4
b = 3.6 b = 3.6
c = 'abc' c = 'abc'
d = [10, 20, 30] d = [10, 20, 30]
e = {'a' : 10, 'b': 20} e = {'a' : 10, 'b': 20}
print(a) print(a)
``` ```
%% Output
4
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
Any variable or combination of variables can be printed using the function `print()`: Any variable or combination of variables can be printed using the function `print()`:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
print(d) print(d)
print(e) print(e)
print(a, b, c) print(a, b, c)
``` ```
%% Output
[10, 20, 30]
{'b': 20, 'a': 10}
4 3.6 abc
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
> _*Python 3 versus python 2*_: > _*Python 3 versus python 2*_:
> >
> Print - for the print statement the brackets are compulsory for *python 3*, but are optional in python 2. So you will see plenty of code without the brackets but you should never use `print` without brackets, as this is incompatible with Python 3. > Print - for the print statement the brackets are compulsory for *python 3*, but are optional in python 2. So you will see plenty of code without the brackets but you should never use `print` without brackets, as this is incompatible with Python 3.
> >
> Division - in python 3 all division is floating point (like in MATLAB), even if the values are integers, but in python 2 integer division works like it does in C. > Division - in python 3 all division is floating point (like in MATLAB), even if the values are integers, but in python 2 integer division works like it does in C.
--- ---
## Strings ## Strings
Strings can be specified using single quotes *or* double quotes - as long as they are matched. Strings can be specified using single quotes *or* double quotes - as long as they are matched.
Strings can be dereferenced like lists (see later). Strings can be dereferenced like lists (see later).
For example: For example:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
s1 = "test string" s1 = "test string"
s2 = 'another test string' s2 = 'another test string'
print(s1, ' :: ', s2) print(s1, ' :: ', s2)
``` ```
%% Output
test string :: another test string
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
You can also use triple quotes to capture multi-line strings. For example: You can also use triple quotes to capture multi-line strings. For example:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
s3 = '''This is s3 = '''This is
a string over a string over
multiple lines multiple lines
''' '''
print(s3) print(s3)
``` ```
%% Output
This is
a string over
multiple lines
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
### Format ### Format
More interesting strings can be created using the `format` statement, which is very useful in print statements: More interesting strings can be created using the `format` statement, which is very useful in print statements:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
x = 1 x = 1
y = 'PyTreat' y = 'PyTreat'
s = 'The numerical value is {} and a name is {}'.format(x, y) s = 'The numerical value is {} and a name is {}'.format(x, y)
print(s) print(s)
print('A name is {} and a number is {}'.format(y, x)) print('A name is {} and a number is {}'.format(y, x))
``` ```
%% Output
The numerical value is 1 and a name is PyTreat
A name is PyTreat and a number is 1
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
There are also other options along these lines, but this is the more modern version, although you will see plenty of the other alternatives in old code (i.e., code written before last week). There are also other options along these lines, but this is the more modern version, although you will see plenty of the other alternatives in old code (i.e., code written before last week).
### String manipulation ### String manipulation
The methods `lower()` and `upper()` are useful for strings. For example: The methods `lower()` and `upper()` are useful for strings. For example:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
s = 'This is a Test String' s = 'This is a Test String'
print(s.upper()) print(s.upper())
print(s.lower()) print(s.lower())
``` ```
%% Output
THIS IS A TEST STRING
this is a test string
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
Another useful method is: Another useful method is:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
s = 'This is a Test String' s = 'This is a Test String'
s2 = s.replace('Test', 'Better') s2 = s.replace('Test', 'Better')
print(s2) print(s2)
``` ```
%% Output
This is a Better String
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
If you like regular expressions then you're in luck as these are well supported in python using the `re` module. To use this (like many other "extensions" - called _modules_ in Python - you need to `import` it). For example: If you like regular expressions then you're in luck as these are well supported in python using the `re` module. To use this (like many other "extensions" - called _modules_ in Python - you need to `import` it). For example:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
import re import re
s = 'This is a test of a Test String' s = 'This is a test of a Test String'
s1 = re.sub(r'a [Tt]est', "an example", s) s1 = re.sub(r'a [Tt]est', "an example", s)
print(s1) print(s1)
``` ```
%% Output
This is an example of an example String
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
where the `r` before the quote is used to force the regular expression specification to be a `raw string`. where the `r` before the quote is used to force the regular expression specification to be a `raw string`.
For more information on matching and substitutions, look up the regular expression module on the web. For more information on matching and substitutions, look up the regular expression module on the web.
You can also split, or tokenize, a string (to turn it into a list) like this: You can also split, or tokenize, a string (to turn it into a list) like this:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
print(s.split()) print(s.split())
``` ```
%% Output
['This', 'is', 'a', 'test', 'of', 'a', 'Test', 'String']
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
> Note that strings in python 3 are _unicode_ so can represent Chinese characters, etc, and is therefore very flexible. However, in general you can just be blissfully ignorant of this fact. > Note that strings in python 3 are _unicode_ so can represent Chinese characters, etc, and is therefore very flexible. However, in general you can just be blissfully ignorant of this fact.
--- ---
## Tuples and Lists ## Tuples and Lists
Both tuples and lists are builtin python types and are like vectors, Both tuples and lists are builtin python types and are like vectors,
but for numerical vectors and arrays it is much better to use _numpy_ but for numerical vectors and arrays it is much better to use _numpy_
arrays (or matrices), which are covered in a later tutorial. arrays (or matrices), which are covered in a later tutorial.
A tuple is like a list or a vector, but with less flexibility than a full list, however anything can be stored in either a list or tuple, without any consistency being required. For example: A tuple is like a list or a vector, but with less flexibility than a full list, however anything can be stored in either a list or tuple, without any consistency being required. For example:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
xtuple = (3, 7.6, 'str') xtuple = (3, 7.6, 'str')
xlist = [1, 'mj', -5.4] xlist = [1, 'mj', -5.4]
print(xtuple) print(xtuple)
print(xlist) print(xlist)
``` ```
%% Output
(3, 7.6, 'str')
[1, 'mj', -5.4]
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
They can also be nested: They can also be nested:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
x2 = (xtuple, xlist) x2 = (xtuple, xlist)
x3 = [xtuple, xlist] x3 = [xtuple, xlist]
print('x2 is: ', x2) print('x2 is: ', x2)
print('x3 is: ', x3) print('x3 is: ', x3)
``` ```
%% Output
x2 is: ((3, 7.6, 'str'), [1, 'mj', -5.4])
x3 is: [(3, 7.6, 'str'), [1, 'mj', -5.4]]
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
### Adding to a list ### Adding to a list
This is easy: This is easy:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
a = [10, 20, 30] a = [10, 20, 30]
a = a + [70] a = a + [70]
a += [80] a += [80]
print(a) print(a)
``` ```
%% Output
[10, 20, 30, 70, 80]
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
### Indexing ### Indexing
Square brackets are used to index tuples, lists, dictionaries, etc. For example: Square brackets are used to index tuples, lists, dictionaries, etc. For example:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
d = [10, 20, 30] d = [10, 20, 30]
print(d[1]) print(d[1])
``` ```
%% Output
20
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
> _*Pitfall:*_ > _*Pitfall:*_
> Python uses zero-based indexing, unlike MATLAB > Python uses zero-based indexing, unlike MATLAB
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
a = [10, 20, 30, 40, 50, 60] a = [10, 20, 30, 40, 50, 60]
print(a[0]) print(a[0])
print(a[2]) print(a[2])
``` ```
%% Output
10
30
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
Indices naturally run from 0 to N-1, _but_ negative numbers can be used to reference from the end (circular wrap-around). Indices naturally run from 0 to N-1, _but_ negative numbers can be used to reference from the end (circular wrap-around).
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
print(a[-1]) print(a[-1])
print(a[-6]) print(a[-6])
``` ```
%% Output
60
10
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
However, this is only true for -1 to -N. Outside of -N to N-1 will generate an `index out of range` error. However, this is only true for -1 to -N. Outside of -N to N-1 will generate an `index out of range` error.
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
print(a[-7]) print(a[-7])
``` ```
%% Output
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-78-f4cf4536701c> in <module>()
----> 1 print(a[-7])
IndexError: list index out of range
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
print(a[6]) print(a[6])
``` ```
%% Output
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-79-52d95fbe5286> in <module>()
----> 1 print(a[6])
IndexError: list index out of range
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
Length of a tuple or list is given by the `len()` function: Length of a tuple or list is given by the `len()` function:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
print(len(a)) print(len(a))
``` ```
%% Output
6
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
Nested lists can have nested indexing: Nested lists can have nested indexing:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
b = [[10, 20, 30], [40, 50, 60]] b = [[10, 20, 30], [40, 50, 60]]
print(b[0][1]) print(b[0][1])
print(b[1][0]) print(b[1][0])
``` ```
%% Output
20
40
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
but *not* an index like b[0, 1]. but *not* an index like b[0, 1].
> Note that `len` will only give the length of the top level. > Note that `len` will only give the length of the top level.
> In general, numpy arrays should be preferred to nested lists when the contents are numerical. > In general, numpy arrays should be preferred to nested lists when the contents are numerical.
### Slicing ### Slicing
A range of values for the indices can be specified to extract values from a list. For example: A range of values for the indices can be specified to extract values from a list. For example:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
print(a[0:3]) print(a[0:3])
``` ```
%% Output
[10, 20, 30]
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
> _*Pitfall:*_ > _*Pitfall:*_
> >
> Slicing syntax is different from MATLAB in that second number is > Slicing syntax is different from MATLAB in that second number is
> exclusive (i.e., one plus final index) - this is in addition to the zero index difference. > exclusive (i.e., one plus final index) - this is in addition to the zero index difference.
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
a = [10, 20, 30, 40, 50, 60] a = [10, 20, 30, 40, 50, 60]
print(a[0:3]) # same as a(1:3) in MATLAB print(a[0:3]) # same as a(1:3) in MATLAB
print(a[1:3]) # same as a(2:3) in MATLAB print(a[1:3]) # same as a(2:3) in MATLAB
``` ```
%% Output
[10, 20, 30]
[20, 30]
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
> _*Pitfall:*_ > _*Pitfall:*_
> >
> Unlike in MATLAB, you cannot use a list as indices instead of an > Unlike in MATLAB, you cannot use a list as indices instead of an
> integer or a slice (although these can be done in _numpy_). > integer or a slice (although these can be done in _numpy_).
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
b = [3, 4] b = [3, 4]
print(a[b]) print(a[b])
``` ```
%% Output
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-84-aad7915ae3d8> in <module>()
1 b = [3, 4]
----> 2 print(a[b])
TypeError: list indices must be integers or slices, not list
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
### List operations ### List operations
Multiplication can be used with lists, where multiplication implements replication. Multiplication can be used with lists, where multiplication implements replication.
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
d = [10, 20, 30] d = [10, 20, 30]
print(d * 4) print(d * 4)
``` ```
%% Output
[10, 20, 30, 10, 20, 30, 10, 20, 30, 10, 20, 30]
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
There are also other operations such as: There are also other operations such as:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
d.append(40) d.append(40)
print(d) print(d)
d.remove(20) d.remove(20)
print(d) print(d)
d.pop(0) d.pop(0)
print(d) print(d)
``` ```
%% Output
[10, 20, 30, 40]
[10, 30, 40]
[30, 40]
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
### Looping over elements in a list (or tuple) ### Looping over elements in a list (or tuple)
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
d = [10, 20, 30] d = [10, 20, 30]
for x in d: for x in d:
print(x) print(x)
``` ```
%% Output
10
20
30
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
> Note that the indentation within the loop is _*crucial*_. All python control blocks are delineated purely by indentation. > Note that the indentation within the loop is _*crucial*_. All python control blocks are delineated purely by indentation.
### Getting help ### Getting help
The function `help()` can be used to get information about any variable/object/function in python. It lists the possible operations. In `ipython` you can also just type `?<blah>` or `<blah>?` instead: The function `help()` can be used to get information about any variable/object/function in python. It lists the possible operations. In `ipython` you can also just type `?<blah>` or `<blah>?` instead:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
help(d) help(d)
``` ```
%% Output
Help on list object:
class list(object)
| list() -> new empty list
| list(iterable) -> new list initialized from iterable's items
|
| Methods defined here:
|
| __add__(self, value, /)
| Return self+value.
|
| __contains__(self, key, /)
| Return key in self.
|
| __delitem__(self, key, /)
| Delete self[key].
|
| __eq__(self, value, /)
| Return self==value.
|
| __ge__(self, value, /)
| Return self>=value.
|
| __getattribute__(self, name, /)
| Return getattr(self, name).
|
| __getitem__(...)
| x.__getitem__(y) <==> x[y]
|
| __gt__(self, value, /)
| Return self>value.
|
| __iadd__(self, value, /)
| Implement self+=value.
|
| __imul__(self, value, /)
| Implement self*=value.
|
| __init__(self, /, *args, **kwargs)
| Initialize self. See help(type(self)) for accurate signature.
|
| __iter__(self, /)
| Implement iter(self).
|
| __le__(self, value, /)
| Return self<=value.
|
| __len__(self, /)
| Return len(self).
|
| __lt__(self, value, /)
| Return self<value.
|
| __mul__(self, value, /)
| Return self*value.n
|
| __ne__(self, value, /)
| Return self!=value.
|
| __new__(*args, **kwargs) from builtins.type
| Create and return a new object. See help(type) for accurate signature.
|
| __repr__(self, /)
| Return repr(self).
|
| __reversed__(...)
| L.__reversed__() -- return a reverse iterator over the list
|
| __rmul__(self, value, /)
| Return self*value.
|
| __setitem__(self, key, value, /)
| Set self[key] to value.
|
| __sizeof__(...)
| L.__sizeof__() -- size of L in memory, in bytes
|
| append(...)
| L.append(object) -> None -- append object to end
|
| clear(...)
| L.clear() -> None -- remove all items from L
|
| copy(...)
| L.copy() -> list -- a shallow copy of L
|
| count(...)
| L.count(value) -> integer -- return number of occurrences of value
|
| extend(...)
| L.extend(iterable) -> None -- extend list by appending elements from the iterable
|
| index(...)
| L.index(value, [start, [stop]]) -> integer -- return first index of value.
| Raises ValueError if the value is not present.
|
| insert(...)
| L.insert(index, object) -- insert object before index
|
| pop(...)
| L.pop([index]) -> item -- remove and return item at index (default last).
| Raises IndexError if list is empty or index is out of range.
|
| remove(...)
| L.remove(value) -> None -- remove first occurrence of value.
| Raises ValueError if the value is not present.
|
| reverse(...)
| L.reverse() -- reverse *IN PLACE*
|
| sort(...)
| L.sort(key=None, reverse=False) -> None -- stable sort *IN PLACE*
|
| ----------------------------------------------------------------------
| Data and other attributes defined here:
|
| __hash__ = None
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
There is also a `dir()` function that gives a basic listing of the operations: There is also a `dir()` function that gives a basic listing of the operations:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
dir(d) dir(d)
``` ```
%% Output
['__add__',
'__class__',
'__contains__',
'__delattr__',
'__delitem__',
'__dir__',
'__doc__',
'__eq__',
'__format__',
'__ge__',
'__getattribute__',
'__getitem__',
'__gt__',
'__hash__',
'__iadd__',
'__imul__',
'__init__',
'__iter__',
'__le__',
'__len__',
'__lt__',
'__mul__',
'__ne__',
'__new__',
'__reduce__',
'__reduce_ex__',
'__repr__',
'__reversed__',
'__rmul__',
'__setattr__',
'__setitem__',
'__sizeof__',
'__str__',
'__subclasshook__',
'append',
'clear',
'copy',
'count',
'extend',
'index',
'insert',
'pop',
'remove',
'reverse',
'sort']
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
> Note that google is often more helpful! > Note that google is often more helpful!
--- ---
## Dictionaries ## Dictionaries
These store key-value pairs. For example: These store key-value pairs. For example:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
e = {'a' : 10, 'b': 20} e = {'a' : 10, 'b': 20}
print(len(e)) print(len(e))
print(e.keys()) print(e.keys())
print(e.values()) print(e.values())
print(e['a']) print(e['a'])
``` ```
%% Output
2
dict_keys(['b', 'a'])
dict_values([20, 10])
10
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
The keys and values can take on almost any type, even dictionaries! The keys and values can take on almost any type, even dictionaries!
Python is nothing if not flexible. However, each key must be unique Python is nothing if not flexible. However, each key must be unique
and the dictionary must be "hashable". and the dictionary must be "hashable".
### Adding to a dictionary ### Adding to a dictionary
This is very easy: This is very easy:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
e['c'] = 555 # just like in Biobank! ;) e['c'] = 555 # just like in Biobank! ;)
print(e) print(e)
``` ```
%% Output
{'c': 555, 'b': 20, 'a': 10}
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
### Removing elements from a dictionary ### Removing elements from a dictionary
There are two main approaches - `pop` and `del`: There are two main approaches - `pop` and `del`:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
e.pop('b') e.pop('b')
print(e) print(e)
del e['c'] del e['c']
print(e) print(e)
``` ```
%% Output
{'c': 555, 'a': 10}
{'a': 10}
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
### Looping over everything in a dictionary ### Looping over everything in a dictionary
Several variables can jointly work as loop variables in python, which is very convenient. For example: Several variables can jointly work as loop variables in python, which is very convenient. For example:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
e = {'a' : 10, 'b': 20, 'c':555} e = {'a' : 10, 'b': 20, 'c':555}
for k, v in e.items(): for k, v in e.items():
print((k, v)) print((k, v))
``` ```
%% Output
('c', 555)
('b', 20)
('a', 10)
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
The print statement here constructs a tuple, which is often used in python. The print statement here constructs a tuple, which is often used in python.
Another option is: Another option is:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
for k in e: for k in e:
print((k, e[k])) print((k, e[k]))
``` ```
%% Output
('c', 555)
('b', 20)
('a', 10)
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
> Note that in both cases the order is arbitrary. The `sorted` function can be used if you want keys in a sorted order; e.g. `for k in sorted(e):` ... > Note that in both cases the order is arbitrary. The `sorted` function can be used if you want keys in a sorted order; e.g. `for k in sorted(e):` ...
> >
> There are also other options if you want a dictionary with ordering. > There are also other options if you want a dictionary with ordering.
--- ---
## Copying and references ## Copying and references
In python there are immutable types (e.g. numbers) and mutable types (e.g. lists). The main thing to know is that assignment can sometimes create separate copies and sometimes create references (as in C++). In general, the more complicated types are assigned via references. For example: In python there are immutable types (e.g. numbers) and mutable types (e.g. lists). The main thing to know is that assignment can sometimes create separate copies and sometimes create references (as in C++). In general, the more complicated types are assigned via references. For example:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
a = 7 a = 7
b = a b = a
a = 2348 a = 2348
print(b) print(b)
``` ```
%% Output
7
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
As opposed to: As opposed to:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
a = [7] a = [7]
b = a b = a
a[0] = 8888 a[0] = 8888
print(b) print(b)
``` ```
%% Output
[8888]
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
But if an operation is performed then a copy might be made: But if an operation is performed then a copy might be made:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
a = [7] a = [7]
b = a * 2 b = a * 2
a[0] = 8888 a[0] = 8888
print(b) print(b)
``` ```
%% Output
[7, 7]
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
If an explicit copy is necessary then this can be made using the `list()` constructor: If an explicit copy is necessary then this can be made using the `list()` constructor:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
a = [7] a = [7]
b = list(a) b = list(a)
a[0] = 8888 a[0] = 8888
print(b) print(b)
``` ```
%% Output
[7]
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
There is a constructor for each type and this con be useful for converting between types: There is a constructor for each type and this con be useful for converting between types:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
xt = (2, 5, 7) xt = (2, 5, 7)
xl = list(xt) xl = list(xt)
print(xt) print(xt)
print(xl) print(xl)
``` ```
%% Output
(2, 5, 7)
[2, 5, 7]
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
> _*Pitfall:*_ > _*Pitfall:*_
> >
> When writing functions you need to be particularly careful about references and copies. > When writing functions you need to be particularly careful about references and copies.
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
def foo1(x): def foo1(x):
x.append(10) x.append(10)
def foo2(x): def foo2(x):
x = x + [10] x = x + [10]
def foo3(x): def foo3(x):
return x + [10] return x + [10]
a = [5] a = [5]
print(a) print(a)
foo1(a) foo1(a)
print(a) print(a)
foo2(a) foo2(a)
print(a) print(a)
foo3(a) foo3(a)
print(a) print(a)
``` ```
%% Output
[5]
[5, 10]
[5, 10]
[5, 10]
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
--- ---
## Control flow ## Control flow
### Boolean operators ### Boolean operators
There is a boolean type in python that can be `True` or `False` (note the capitals). Other values can also be used for True or False (e.g., 1 for True; 0 or None or [] or {} or "") although they are not considered 'equal' in the sense that the operator `==` would consider them the same. There is a boolean type in python that can be `True` or `False` (note the capitals). Other values can also be used for True or False (e.g., 1 for True; 0 or None or [] or {} or "") although they are not considered 'equal' in the sense that the operator `==` would consider them the same.
Relevant boolean and comparison operators include: `not`, `and`, `or`, `==` and `!=` Relevant boolean and comparison operators include: `not`, `and`, `or`, `==` and `!=`
For example: For example:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
a = True a = True
print('Not a is:', not a) print('Not a is:', not a)
print('Not 1 is:', not 1) print('Not 1 is:', not 1)
print('Not 0 is:', not 0) print('Not 0 is:', not 0)
print('Not {} is:', not {}) print('Not {} is:', not {})
print('{}==0 is:', {}==0) print('{}==0 is:', {}==0)
``` ```
%% Output
Not a is: False
Not 1 is: False
Not 0 is: True
Not {} is: True
{}==0 is: False
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
There is also the `in` test for strings, lists, etc: There is also the `in` test for strings, lists, etc:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
print('the' in 'a number of words') print('the' in 'a number of words')
print('of' in 'a number of words') print('of' in 'a number of words')
print(3 in [1, 2, 3, 4]) print(3 in [1, 2, 3, 4])
``` ```
%% Output
False
True
True
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
### If statements ### If statements
The basic syntax of `if` statements is fairly standard, though don't forget that you _*must*_ indent the statements within the conditional/loop block as this is the way of delineating blocks of code in python. For example: The basic syntax of `if` statements is fairly standard, though don't forget that you _*must*_ indent the statements within the conditional/loop block as this is the way of delineating blocks of code in python. For example:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
import random import random
a = random.uniform(-1, 1) a = random.uniform(-1, 1)
print(a) print(a)
if a>0: if a>0:
print('Positive') print('Positive')
elif a<0: elif a<0:
print('Negative') print('Negative')
else: else:
print('Zero') print('Zero')
``` ```
%% Output
0.9933407850276534
Positive
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
Or more generally: Or more generally:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
a = [] # just one of many examples a = [] # just one of many examples
if not a: if not a:
print('Variable is true, or at least not empty') print('Variable is true, or at least not empty')
``` ```
%% Output
Variable is true, or at least not empty
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
This can be useful for functions where a variety of possible input types are being dealt with. This can be useful for functions where a variety of possible input types are being dealt with.
--- ---
### For loops ### For loops
The `for` loop works like in bash: The `for` loop works like in bash:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
for x in [2, 'is', 'more', 'than', 1]: for x in [2, 'is', 'more', 'than', 1]:
print(x) print(x)
``` ```
%% Output
2
is
more
than
1
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
where a list or any other sequence (e.g. tuple) can be used. where a list or any other sequence (e.g. tuple) can be used.
If you want a numerical range then use: If you want a numerical range then use:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
for x in range(2, 9): for x in range(2, 9):
print(x) print(x)
``` ```
%% Output
2
3
4
5
6
7
8
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
Note that, like slicing, the maximum value is one less than the value specified. Also, `range` actually returns an object that can be iterated over but is not just a list of numbers. If you want a list of numbers then `list(range(2, 9))` will give you this. Note that, like slicing, the maximum value is one less than the value specified. Also, `range` actually returns an object that can be iterated over but is not just a list of numbers. If you want a list of numbers then `list(range(2, 9))` will give you this.
A very nice feature of python is that multiple variables can be assigned from a tuple or list: A very nice feature of python is that multiple variables can be assigned from a tuple or list:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
x, y = [4, 7] x, y = [4, 7]
print(x) print(x)
print(y) print(y)
``` ```
%% Output
4
7
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
and this can be combined with a function called `zip` to make very convenient dual variable loops: and this can be combined with a function called `zip` to make very convenient dual variable loops:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
alist = ['Some', 'set', 'of', 'items'] alist = ['Some', 'set', 'of', 'items']
blist = list(range(len(alist))) blist = list(range(len(alist)))
print(list(zip(alist, blist))) print(list(zip(alist, blist)))
for x, y in zip(alist, blist): for x, y in zip(alist, blist):
print(y, x) print(y, x)
``` ```
%% Output
[('Some', 0), ('set', 1), ('of', 2), ('items', 3)]
0 Some
1 set
2 of
3 items
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
This type of loop can be used with any two lists (or similar) to iterate over them jointly. This type of loop can be used with any two lists (or similar) to iterate over them jointly.
### While loops ### While loops
The syntax for this is pretty standard: The syntax for this is pretty standard:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
import random import random
n = 0 n = 0
x = 0 x = 0
while n<100: while n<100:
x += random.uniform(0, 1)**2 # where ** is a power operation x += random.uniform(0, 1)**2 # where ** is a power operation
if x>50: if x>50:
break break
n += 1 n += 1
print(x) print(x)
``` ```
%% Output
35.041627991396396
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
You can also use `continue` as in other languages. You can also use `continue` as in other languages.
--- ---
### A quick intro to conditional expressions and list comprehensions ### A quick intro to conditional expressions and list comprehensions
These are more advanced bits of python but are really useful and common, so worth having a little familiarity with at this stage. These are more advanced bits of python but are really useful and common, so worth having a little familiarity with at this stage.
#### Conditional expressions #### Conditional expressions
A general expression that can be used in python is: A `if` condition `else` B A general expression that can be used in python is: A `if` condition `else` B
For example: For example:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
import random import random
x = random.uniform(0, 1) x = random.uniform(0, 1)
y = x**2 if x<0.5 else (1 - x)**2 y = x**2 if x<0.5 else (1 - x)**2
print(x, y) print(x, y)
``` ```
%% Output
0.6576892259376057 0.11717666603919556
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
#### List comprehensions #### List comprehensions
This is a shorthand syntax for building a list like a for loop but doing it in one line, and is very popular in python. It is quite similar to mathematical set notation. For example: This is a shorthand syntax for building a list like a for loop but doing it in one line, and is very popular in python. It is quite similar to mathematical set notation. For example:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
v1 = [ x**2 for x in range(10) ] v1 = [ x**2 for x in range(10) ]
print(v1) print(v1)
v2 = [ x**2 for x in range(10) if x!=7 ] v2 = [ x**2 for x in range(10) if x!=7 ]
print(v2) print(v2)
``` ```
%% Output
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
[0, 1, 4, 9, 16, 25, 36, 64, 81]
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
You'll find that python programmers use this kind of construction _*a lot*_. You'll find that python programmers use this kind of construction _*a lot*_.
%% Cell type:code id: tags:
``` python
```
......
File moved
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
# NIfTI images and python # NIfTI images and python
The [nibabel](http://nipy.org/nibabel/) module is used to read and write NIfTI images and also some other medical imaging formats (e.g., ANALYZE, GIFTI, MINC, MGH). This module is included within the FSL python environment. The [nibabel](http://nipy.org/nibabel/) module is used to read and write NIfTI images and also some other medical imaging formats (e.g., ANALYZE, GIFTI, MINC, MGH). This module is included within the FSL python environment.
## Reading images ## Reading images
It is easy to read an image: It is easy to read an image:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
import numpy as np import numpy as np
import nibabel as nib import nibabel as nib
filename = '/usr/local/fsl/data/standard/MNI152_T1_1mm.nii.gz' filename = '/usr/local/fsl/data/standard/MNI152_T1_1mm.nii.gz'
imobj = nib.load(filename, mmap=False) imobj = nib.load(filename, mmap=False)
# display header object # display header object
imhdr = imobj.header imhdr = imobj.header
# extract data (as an numpy array) # extract data (as an numpy array)
imdat = imobj.get_data().astype(float) imdat = imobj.get_data().astype(float)
print(imdat.shape) print(imdat.shape)
``` ```
%% Output
(182, 218, 182)
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
> Make sure you use the full filename, including the .nii.gz extension. > Make sure you use the full filename, including the .nii.gz extension.
Reading the data off the disk is not done until `get_data()` is called. Reading the data off the disk is not done until `get_data()` is called.
> Pitfall: > Pitfall:
> >
> The option `mmap=False`is necessary as turns off memory mapping, which otherwise would be invoked for uncompressed NIfTI files but not for compressed files. Since some functionality behaves differently on memory mapped objects, it is advisable to turn this off. > The option `mmap=False`is necessary as turns off memory mapping, which otherwise would be invoked for uncompressed NIfTI files but not for compressed files. Since some functionality behaves differently on memory mapped objects, it is advisable to turn this off.
Once the data is read into a numpy array then it is easily manipulated. Once the data is read into a numpy array then it is easily manipulated.
> We recommend converting it to float at the start to avoid problems with integer arithmetic and overflow, though this is not compulsory. > We recommend converting it to float at the start to avoid problems with integer arithmetic and overflow, though this is not compulsory.
## Header info ## Header info
There are many methods available on the header object - for example, look at `dir(imhdr)` or `help(imhdr)` or the [nibabel webpage about NIfTI images](http://nipy.org/nibabel/nifti_images.html) There are many methods available on the header object - for example, look at `dir(imhdr)` or `help(imhdr)` or the [nibabel webpage about NIfTI images](http://nipy.org/nibabel/nifti_images.html)
### Voxel sizes ### Voxel sizes
Dimensions of the voxels, in mm, can be found from: Dimensions of the voxels, in mm, can be found from:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
voxsize = imhdr.get_zooms() voxsize = imhdr.get_zooms()
print(voxsize) print(voxsize)
``` ```
%% Output
(1.0, 1.0, 1.0)
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
### Coordinate orientations and mappings ### Coordinate orientations and mappings
Information about the NIfTI qform and sform matrices can be extracted like this: Information about the NIfTI qform and sform matrices can be extracted like this:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
sform = imhdr.get_sform() sform = imhdr.get_sform()
sformcode = imhdr['sform_code'] sformcode = imhdr['sform_code']
qform = imhdr.get_qform() qform = imhdr.get_qform()
qformcode = imhdr['qform_code'] qformcode = imhdr['qform_code']
print(qformcode) print(qformcode)
print(qform) print(qform)
``` ```
%% Output
4
[[ -1. 0. 0. 90.]
[ 0. 1. 0. -126.]
[ 0. 0. 1. -72.]
[ 0. 0. 0. 1.]]
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
## Writing images ## Writing images
If you have created a modified image by making or modifying a numpy array then you need to put this into a NIfTI image object in order to save it to a file. The easiest way to do this is to copy all the header info from an existing image like this: If you have created a modified image by making or modifying a numpy array then you need to put this into a NIfTI image object in order to save it to a file. The easiest way to do this is to copy all the header info from an existing image like this:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ```
newdata = imdat * imdat newdata = imdat * imdat
newhdr = imhdr.copy() newhdr = imhdr.copy()
newobj = nib.nifti1.Nifti1Image(newdata, None, header=newhdr) newobj = nib.nifti1.Nifti1Image(newdata, None, header=newhdr)
nib.save(newobj, "mynewname.nii.gz") nib.save(newobj, "mynewname.nii.gz")
``` ```
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
where `newdata` is the numpy array (the above is a random example only) and `imhdr` is the existing image header (as above). where `newdata` is the numpy array (the above is a random example only) and `imhdr` is the existing image header (as above).
If the dimensions of the image are different, then extra modifications will be required. For this, or for making an image from scratch, see the [nibabel documentation](http://nipy.org/nibabel/nifti_images.html) on NIfTI images. If the dimensions of the image are different, then extra modifications will be required. For this, or for making an image from scratch, see the [nibabel documentation](http://nipy.org/nibabel/nifti_images.html) on NIfTI images.
......
File moved
%% 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
```
......
File moved
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