Skip to content

Commit cb5b1bc

Browse files
committed
Add dvars exercise and solution
Read the files: * `findoutlie/metrics.py` and * `findoutlie/tests/test_dvars.py` and complete the `findoutlie/metrics.py` to make the tests pass.
1 parent 01a038b commit cb5b1bc

File tree

5 files changed

+117
-0
lines changed

5 files changed

+117
-0
lines changed

findoutlie/metrics.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
""" Scan outlier metrics
2+
"""
3+
4+
# Any imports you need
5+
# +++your code here+++
6+
7+
8+
def dvars(img):
9+
""" Calculate dvars metric on Nibabel image `img`
10+
11+
The dvars calculation between two volumes is defined as the square root of
12+
(the mean of the (voxel differences squared)).
13+
14+
Parameters
15+
----------
16+
img : nibabel image
17+
18+
Returns
19+
-------
20+
dvals : 1D array
21+
One-dimensional array with n-1 elements, where n is the number of
22+
volumes in `img`.
23+
"""
24+
# Hint: remember 'axis='. For example:
25+
# In [2]: arr = np.array([[2, 3, 4], [5, 6, 7]])
26+
# In [3]: np.mean(arr, axis=1)
27+
# Out[2]: array([3., 6.])
28+
#
29+
# You may be be able to solve this in four lines, without a loop.
30+
# But solve it any way you can.
31+
# This is a placeholder, replace it to write your solution.
32+
raise NotImplementedError('Code up this function')

findoutlie/tests/test_dvars.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
""" Test dvars implementation
2+
3+
You can run the tests from the root directory (containing ``README.md``) with::
4+
5+
python3 -m pytest .
6+
"""
7+
8+
import numpy as np
9+
10+
import nibabel as nib
11+
12+
import nipraxis as npx
13+
14+
from findoutlie.metrics import dvars
15+
16+
17+
TEST_FNAME = npx.fetch_file('ds114_sub009_t2r1.nii')
18+
19+
20+
def test_dvars():
21+
img = nib.load(TEST_FNAME)
22+
n_trs = img.shape[-1]
23+
n_voxels = np.prod(img.shape[:-1])
24+
dvals = dvars(img)
25+
assert len(dvals) == n_trs - 1
26+
# Calculate the values the long way round
27+
data = img.get_fdata()
28+
prev_vol = data[..., 0]
29+
long_dvals = []
30+
for i in range(1, n_trs):
31+
this_vol = data[..., i]
32+
d = this_vol - prev_vol
33+
long_dvals.append(np.sqrt(np.sum(d ** 2) / n_voxels))
34+
prev_vol = this_vol
35+
assert np.allclose(dvals, long_dvals)

solutions/.solutions.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
# Where the exercises etc go, given the solutions
22

3+
[solution.metrics]
4+
out_path = '{one_down}/findoutlie/metrics.py'
5+
36
[solution.validate_data]
47
out_path = '{one_down}/scripts/validate_data.py'

solutions/.write_dvars.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/bin/bash
2+
nxt-proc-solutions write-solutions
3+
pytest findoutlie
4+
nxt-proc-solutions write

solutions/metrics.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
""" Scan outlier metrics
2+
"""
3+
4+
# Any imports you need
5+
# LAB(begin solution)
6+
import numpy as np
7+
# LAB(replace solution)
8+
# +++your code here+++
9+
# LAB(end solution)
10+
11+
12+
def dvars(img):
13+
""" Calculate dvars metric on Nibabel image `img`
14+
15+
The dvars calculation between two volumes is defined as the square root of
16+
(the mean of the (voxel differences squared)).
17+
18+
Parameters
19+
----------
20+
img : nibabel image
21+
22+
Returns
23+
-------
24+
dvals : 1D array
25+
One-dimensional array with n-1 elements, where n is the number of
26+
volumes in `img`.
27+
"""
28+
# Hint: remember 'axis='. For example:
29+
# In [2]: arr = np.array([[2, 3, 4], [5, 6, 7]])
30+
# In [3]: np.mean(arr, axis=1)
31+
# Out[2]: array([3., 6.])
32+
#
33+
# You may be be able to solve this in four lines, without a loop.
34+
# But solve it any way you can.
35+
# LAB(begin solution)
36+
data = img.get_fdata()
37+
vx_by_time = np.reshape(data, (-1, data.shape[-1]))
38+
time_diffs = np.diff(vx_by_time, axis=1)
39+
return np.sqrt(np.mean(time_diffs ** 2, axis=0))
40+
# LAB(replace solution)
41+
# This is a placeholder, replace it to write your solution.
42+
raise NotImplementedError('Code up this function')
43+
# LAB(end solution)

0 commit comments

Comments
 (0)