Skip to content

Commit 22fe74e

Browse files
committed
ENH: Add test subjects_dir config support, pass on tests
1 parent cb55949 commit 22fe74e

File tree

5 files changed

+83
-55
lines changed

5 files changed

+83
-55
lines changed

surfer/config.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
1919
[options]
2020
logging_level = INFO
21+
subjects_dir =
2122
""")
2223

2324
config = ConfigParser.ConfigParser()

surfer/io.py

Lines changed: 6 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -11,36 +11,8 @@
1111
import logging
1212
logger = logging.getLogger('surfer')
1313

14-
15-
def _get_subjects_dir(subjects_dir=None):
16-
"""Get the subjects directory from parameter or environment variable
17-
18-
Parameters
19-
----------
20-
subjects_dir : str | None
21-
The subjects directory.
22-
23-
Returns
24-
-------
25-
subjects_dir : str
26-
The subjects directory. If the subjects_dir input parameter is not
27-
None, its value will be returned, otherwise it will be obtained from
28-
the SUBJECTS_DIR environment variable.
29-
"""
30-
31-
if subjects_dir is None:
32-
if 'SUBJECTS_DIR' in os.environ:
33-
subjects_dir = os.environ['SUBJECTS_DIR']
34-
else:
35-
raise ValueError('The subjects directory has to be specified '
36-
'using either the subjects_dir parameter or the '
37-
'SUBJECTS_DIR environment variable.')
38-
39-
if not os.path.exists(subjects_dir):
40-
raise ValueError('The subjects directory %s does not exist.'
41-
% subjects_dir)
42-
43-
return subjects_dir
14+
from .config import config
15+
from .utils import _get_subjects_dir
4416

4517

4618
def read_scalar_data(filepath):
@@ -188,7 +160,7 @@ def read_stc(filepath):
188160
def project_volume_data(filepath, hemi, reg_file=None, subject_id=None,
189161
projmeth="frac", projsum="avg", projarg=[0, 1, .1],
190162
surf="white", smooth_fwhm=3, mask_label=None,
191-
target_subject=None, verbose=False):
163+
target_subject=None, verbose=None):
192164
"""Sample MRI volume onto cortical manifold.
193165
194166
Note: this requires Freesurfer to be installed with correct
@@ -220,8 +192,8 @@ def project_volume_data(filepath, hemi, reg_file=None, subject_id=None,
220192
Path to label file to constrain projection; otherwise uses cortex
221193
target_subject : string
222194
Subject to warp data to in surface space after projection
223-
verbose : bool
224-
If True, print the command used
195+
verbose : bool, str, int, or None
196+
If not None, override default verbose level (see surfer.verbose).
225197
"""
226198
# Set the basic commands
227199
cmd_list = ["mri_vol2surf",
@@ -259,8 +231,7 @@ def project_volume_data(filepath, hemi, reg_file=None, subject_id=None,
259231
# Execute the command
260232
out_file = mktemp(prefix="pysurfer-v2s", suffix='.mgz')
261233
cmd_list.extend(["--o", out_file])
262-
if verbose:
263-
print " ".join(cmd_list)
234+
logger.info(" ".join(cmd_list))
264235
p = Popen(cmd_list, stdout=PIPE, stderr=PIPE)
265236
stdout, stderr = p.communicate()
266237
out = p.returncode

surfer/tests/test_io.py

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,19 @@
1-
import os
21
from os.path import join as pjoin
32

43
import numpy as np
5-
from numpy.testing import assert_array_almost_equal, assert_equal
4+
from numpy.testing import assert_array_almost_equal
65

7-
from .. import io
6+
from surfer import io
7+
from surfer.utils import requires_fsaverage
88

9-
if 'SUBJECTS_DIR' not in os.environ:
10-
raise ValueError('Test suite relies on the definition of SUBJECTS_DIR')
11-
12-
subj_dir = os.environ["SUBJECTS_DIR"]
9+
subj_dir = io._get_subjects_dir()
1310
subject_id = 'fsaverage'
14-
# subject_id = 'sample'
1511
data_path = pjoin(subj_dir, subject_id)
1612

1713

14+
@requires_fsaverage
1815
def test_surface():
19-
"""Test of Surface class"""
16+
"""Test IO for Surface class"""
2017
for subjects_dir in [None, subj_dir]:
2118
surface = io.Surface('fsaverage', 'lh', 'inflated',
2219
subjects_dir=subjects_dir)

surfer/tests/test_viz.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,10 @@
77

88
from surfer import Brain
99
from surfer import io
10+
from surfer.utils import requires_fsaverage
1011
from mayavi import mlab
1112

12-
if 'SUBJECTS_DIR' not in os.environ:
13-
raise ValueError('Test suite relies on the definition of SUBJECTS_DIR')
14-
15-
subj_dir = os.environ["SUBJECTS_DIR"]
13+
subj_dir = io._get_subjects_dir()
1614
subject_id = 'fsaverage'
1715
std_args = [subject_id, 'lh', 'inflated']
1816
data_dir = pjoin(os.path.split(__file__)[0], '..', '..',
@@ -30,6 +28,7 @@ def has_freesurfer():
3028
'Requires FreeSurfer command line tools')
3129

3230

31+
@requires_fsaverage
3332
def test_offscreen():
3433
"""Test offscreen rendering
3534
"""
@@ -39,6 +38,7 @@ def test_offscreen():
3938
assert_array_equal(shot.shape, (800, 800, 3))
4039

4140

41+
@requires_fsaverage
4242
def test_image():
4343
"""Test image saving
4444
"""
@@ -52,6 +52,7 @@ def test_image():
5252
brain.close()
5353

5454

55+
@requires_fsaverage
5556
def test_brains():
5657
"""Test plotting of Brain with different arguments
5758
"""
@@ -67,13 +68,13 @@ def test_brains():
6768
subj_dirs = [None, subj_dir]
6869
for surf, hemi, curv, title, co, fig, sd \
6970
in zip(surfs, hemis, curvs, titles, config_opts, figs, subj_dirs):
70-
print 'hello'
7171
brain = Brain(subject_id, hemi, surf, curv, title, co, fig, sd)
7272
brain.close()
7373
assert_raises(ValueError, Brain, subject_id, 'lh', 'inflated',
7474
subjects_dir='')
7575

7676

77+
@requires_fsaverage
7778
def test_annot():
7879
"""Test plotting of annot
7980
"""
@@ -87,6 +88,7 @@ def test_annot():
8788
brain.close()
8889

8990

91+
@requires_fsaverage
9092
def test_contour():
9193
"""Test plotting of contour overlay
9294
"""
@@ -101,6 +103,7 @@ def test_contour():
101103
brain.close()
102104

103105

106+
@requires_fsaverage
104107
@requires_fs
105108
def test_data():
106109
"""Test plotting of data
@@ -114,6 +117,7 @@ def test_data():
114117
brain.close()
115118

116119

120+
@requires_fsaverage
117121
def test_foci():
118122
"""Test plotting of foci
119123
"""
@@ -134,6 +138,7 @@ def test_foci():
134138
brain.close()
135139

136140

141+
@requires_fsaverage
137142
def test_label():
138143
"""Test plotting of label
139144
"""
@@ -156,6 +161,7 @@ def test_label():
156161
brain.close()
157162

158163

164+
@requires_fsaverage
159165
def test_meg_inverse():
160166
"""Test plotting of MEG inverse solution
161167
"""
@@ -178,6 +184,7 @@ def test_meg_inverse():
178184
brain.close()
179185

180186

187+
@requires_fsaverage
181188
def test_morphometry():
182189
"""Test plotting of morphometry
183190
"""
@@ -189,6 +196,7 @@ def test_morphometry():
189196
brain.close()
190197

191198

199+
@requires_fsaverage
192200
def test_overlay():
193201
"""Test plotting of overlay
194202
"""
@@ -221,6 +229,7 @@ def test_overlay():
221229
brain.close()
222230

223231

232+
@requires_fsaverage
224233
def test_probabilistic_labels():
225234
"""Test plotting of probabilistic labels
226235
"""
@@ -246,6 +255,7 @@ def test_probabilistic_labels():
246255
brain.close()
247256

248257

258+
@requires_fsaverage
249259
def test_text():
250260
"""Test plotting of text
251261
"""
@@ -255,6 +265,7 @@ def test_text():
255265
brain.close()
256266

257267

268+
@requires_fsaverage
258269
def test_animate():
259270
"""Test animation
260271
"""
@@ -269,6 +280,7 @@ def test_animate():
269280
brain.close()
270281

271282

283+
@requires_fsaverage
272284
def test_views():
273285
"""Test showing different views
274286
"""

surfer/utils.py

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import logging
22
import warnings
33
import sys
4+
import os
45
from os import path as op
56
import inspect
67
from functools import wraps
78

89
import numpy as np
910
from scipy import sparse
1011
from scipy.spatial.distance import cdist
11-
from .io import Surface
1212
from .config import config
1313

1414
logger = logging.getLogger('surfer')
@@ -215,11 +215,11 @@ def mesh_edges(faces):
215215
nfaces = len(faces)
216216
a, b, c = faces.T
217217
edges = sparse.coo_matrix((np.ones(nfaces), (a, b)),
218-
shape=(npoints, npoints))
218+
shape=(npoints, npoints))
219219
edges = edges + sparse.coo_matrix((np.ones(nfaces), (b, c)),
220-
shape=(npoints, npoints))
220+
shape=(npoints, npoints))
221221
edges = edges + sparse.coo_matrix((np.ones(nfaces), (c, a)),
222-
shape=(npoints, npoints))
222+
shape=(npoints, npoints))
223223
edges = edges + edges.T
224224
edges = edges.tocoo()
225225
return edges
@@ -268,7 +268,7 @@ def smoothing_matrix(vertices, adj_mat, smoothing_steps=20, verbose=None):
268268
data1 = e_use * np.ones(len(idx_use))
269269
idx_use = np.where(data1)[0]
270270
scale_mat = sparse.dia_matrix((1 / data1[idx_use], 0),
271-
shape=(len(idx_use), len(idx_use)))
271+
shape=(len(idx_use), len(idx_use)))
272272

273273
smooth_mat = scale_mat * e_use[idx_use, :] * smooth_mat
274274

@@ -283,7 +283,7 @@ def smoothing_matrix(vertices, adj_mat, smoothing_steps=20, verbose=None):
283283
(idx_use[smooth_mat.row],
284284
smooth_mat.col)),
285285
shape=(n_vertices,
286-
len(vertices)))
286+
len(vertices)))
287287

288288
return smooth_mat
289289

@@ -336,3 +336,50 @@ def coord_to_label(subject_id, coord, label, hemi='lh', n_steps=30,
336336
for i in idx:
337337
x, y, z = geo.coords[i]
338338
f.write('%d %f %f %f 0.000000\n' % (i, x, y, z))
339+
340+
341+
def _get_subjects_dir(subjects_dir=None):
342+
"""Get the subjects directory from parameter or environment variable
343+
344+
Parameters
345+
----------
346+
subjects_dir : str | None
347+
The subjects directory.
348+
349+
Returns
350+
-------
351+
subjects_dir : str
352+
The subjects directory. If the subjects_dir input parameter is not
353+
None, its value will be returned, otherwise it will be obtained from
354+
the SUBJECTS_DIR environment variable. If that does not exist,
355+
it will be obtained from the configuration file.
356+
"""
357+
if subjects_dir is None:
358+
if 'SUBJECTS_DIR' in os.environ:
359+
subjects_dir = os.environ['SUBJECTS_DIR']
360+
else:
361+
subjects_dir = config.get('options', 'subjects_dir')
362+
if subjects_dir == '':
363+
raise ValueError('The subjects directory has to be specified '
364+
'using the subjects_dir parameter, the '
365+
'SUBJECTS_DIR environment variable, or the '
366+
'"subjects_dir" entry in the config file')
367+
368+
if not os.path.exists(subjects_dir):
369+
raise ValueError('The subjects directory %s does not exist.'
370+
% subjects_dir)
371+
372+
return subjects_dir
373+
374+
375+
def has_fsaverage(subjects_dir=None):
376+
"""Determine whether the user has a usable fsaverage"""
377+
fs_dir = op.join(_get_subjects_dir(subjects_dir), 'fsaverage')
378+
if not op.isdir(fs_dir):
379+
return False
380+
if not op.isdir(op.join(fs_dir, 'surf')):
381+
return False
382+
return True
383+
384+
requires_fsaverage = np.testing.dec.skipif(not has_fsaverage(),
385+
'Requires fsaverage subject data')

0 commit comments

Comments
 (0)