Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ matrix:
- os: linux

# OSX (disabled because it's slow)
# - os: osx
- os: osx

# Setup anaconda
before_install:
Expand All @@ -35,7 +35,10 @@ install:

before_script:
# Let's create a (fake) display on Travis, and let's use a funny resolution
- /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -screen 0 1400x900x24 -ac +extension GLX +render
- if [ "${TRAVIS_OS_NAME}" == "linux" ]; then
echo "Starting Xvfb...";
/sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -screen 0 1400x900x24 -ac +extension GLX +render;
fi;
- cd ~
- wget --quiet http://faculty.washington.edu/larsoner/fsaverage_min.zip
- mkdir subjects
Expand Down
15 changes: 13 additions & 2 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,33 @@ environment:
global:
PYTHON: "C:\\conda"
MINICONDA_VERSION: "latest"
CONDA_DEPENDENCIES: "numpy scipy mayavi matplotlib nose imaging"
PIP_DEPENDENCIES: "nose-timer nibabel imageio"
CONDA_DEPENDENCIES: "numpy scipy mayavi matplotlib nose imaging sphinx"
PIP_DEPENDENCIES: "nose-timer nibabel imageio sphinx-gallery numpydoc coverage"
matrix:
- PYTHON_VERSION: "2.7"
PYTHON_ARCH: "64"

install:
- "git clone git://github.com/astropy/ci-helpers.git"
- "powershell ci-helpers/appveyor/install-miniconda.ps1"
- "powershell make/get_fsaverage.ps1"
- "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%"
- "activate test"
- "python setup.py develop"
- "conda install ffmpeg -c conda-forge"
- "SET SUBJECTS_DIR=%CD%\\subjects"
- "ls %CD%\\subjects"

build: false # Not a C# project, build stuff at the test step instead.

test_script:
# Run the project tests
- "nosetests --with-timer --timer-top-n=10"
- cd doc
# The Makefile doesn't work directly on Windows PowerShell because of
# slashes (but will work e.g. in Msys-git), so for now do these manually
# make html-noplot
- sphinx-build -D plot_gallery=0 -b html -d _build\doctrees . _build\html

artifacts:
- path: doc\_build\html
46 changes: 46 additions & 0 deletions make/get_fsaverage.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Sample script to install Python and pip under Windows
# Authors: Olivier Grisel, Jonathan Helmus and Kyle Kastner
# License: CC0 1.0 Universal: http://creativecommons.org/publicdomain/zero/1.0/

$FSAVERAGE_URL = "https://staff.washington.edu/larsoner/fsaverage_min.zip"

Add-Type -AssemblyName System.IO.Compression.FileSystem
function Unzip
{
param([string]$zipfile, [string]$outpath)
[System.IO.Compression.ZipFile]::ExtractToDirectory($zipfile, $outpath)
}

function DownloadExtractFsaverage () {
$webclient = New-Object System.Net.WebClient
$basedir = $pwd.Path + "\"
$filepath = $basedir + "fsaverage_min.zip"
# Download and retry up to 3 times in case of network transient errors.
$url = $FSAVERAGE_URL
Write-Host "Downloading" $url
$retry_attempts = 2
for($i=0; $i -lt $retry_attempts; $i++){
try {
$webclient.DownloadFile($url, $filepath)
break
}
Catch [Exception]{
Start-Sleep 1
}
}
if (Test-Path $filepath) {
Write-Host "File saved at" $filepath
} else {
# Retry once to get the error message if any at the last try
$webclient.DownloadFile($url, $filepath)
}
# Now we extract
$subjects_dir = $basedir + "\subjects"
Unzip $filepath $subjects_dir
}

function main () {
DownloadExtractFsaverage
}

main
10 changes: 2 additions & 8 deletions surfer/tests/test_utils.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
from os.path import join as pjoin

import numpy as np
import nose.tools as nt
from numpy.testing import assert_array_almost_equal, assert_array_equal

from surfer import utils

subj_dir = utils._get_subjects_dir()
subject_id = 'fsaverage'
data_path = pjoin(subj_dir, subject_id)


def _slow_compute_normals(rr, tris):
"""Efficiently compute vertex normals for triangulated surface"""
Expand Down Expand Up @@ -38,6 +32,7 @@ def _slow_compute_normals(rr, tris):
@utils.requires_fsaverage
def test_surface():
"""Test IO for Surface class"""
subj_dir = utils._get_subjects_dir()
for subjects_dir in [None, subj_dir]:
surface = utils.Surface('fsaverage', 'lh', 'inflated',
subjects_dir=subjects_dir)
Expand All @@ -58,8 +53,7 @@ def test_surface():


def test_huge_cross():
"""Test cross product with lots of elements
"""
"""Test cross product with lots of elements."""
x = np.random.rand(100000, 3)
y = np.random.rand(1, 3)
z = np.cross(x, y)
Expand Down
51 changes: 34 additions & 17 deletions surfer/tests/test_viz.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
import os.path as op
from os.path import join as pjoin
import shutil
import sys
from tempfile import mkdtemp, mktemp
import warnings

from nose.tools import assert_equal, assert_in, assert_not_in
from nose.plugins.skip import SkipTest
from mayavi import mlab
import nibabel as nib
import numpy as np
Expand All @@ -16,7 +18,6 @@

warnings.simplefilter('always')

subj_dir = utils._get_subjects_dir()
subject_id = 'fsaverage'
std_args = [subject_id, 'lh', 'inflated']
data_dir = pjoin(op.dirname(__file__), '..', '..', 'examples', 'example_data')
Expand All @@ -35,10 +36,22 @@ def has_freesurfer():
'Requires FreeSurfer command line tools')


def _set_backend(backend=None):
"""Use testing backend for Windows."""
if backend is None:
backend = 'test' if sys.platform == 'win32' else 'auto'
else:
if backend != 'test' and sys.platform == 'win32':
raise SkipTest('non-testing backend crashes on Windows')
mlab.options.backend = backend


@requires_fsaverage
def test_offscreen():
"""Test offscreen rendering."""
mlab.options.backend = 'auto'
if sys.platform == 'darwin' and os.getenv('TRAVIS', 'false') == 'true':
raise SkipTest('Offscreen Travis tests fail on OSX')
_set_backend()
brain = Brain(*std_args, offscreen=True)
# Sometimes the first screenshot is rendered with a different
# resolution on OS X
Expand All @@ -53,7 +66,7 @@ def test_image():
"""Test image saving."""
tmp_name = mktemp() + '.png'

mlab.options.backend = 'auto'
_set_backend()
subject_id, _, surf = std_args
brain = Brain(subject_id, 'both', surf=surf, size=100)
brain.add_overlay(overlay_fname, hemi='lh', min=5, max=20, sign="pos")
Expand All @@ -74,7 +87,7 @@ def test_brains():
"""Test plotting of Brain with different arguments."""
# testing backend breaks when passing in a figure, so we use 'auto' here
# (shouldn't affect usability, but it makes testing more annoying)
mlab.options.backend = 'auto'
_set_backend('auto')
with warnings.catch_warnings(record=True): # traits for mlab.figure()
mlab.figure(101)
surfs = ['inflated', 'white', 'white', 'white', 'white', 'white', 'white']
Expand All @@ -91,6 +104,7 @@ def test_brains():
(0.2, 0.2, 0.2), "blue", "black"]
with warnings.catch_warnings(record=True): # traits for mlab.figure()
figs = [101, mlab.figure(), None, None, mlab.figure(), None, None]
subj_dir = utils._get_subjects_dir()
subj_dirs = [None, subj_dir, subj_dir, subj_dir,
subj_dir, subj_dir, subj_dir]
alphas = [1.0, 0.5, 0.25, 0.7, 0.5, 0.25, 0.7]
Expand All @@ -114,7 +128,7 @@ def test_brains():
@requires_fsaverage
def test_annot():
"""Test plotting of annot."""
mlab.options.backend = 'auto'
_set_backend()
annots = ['aparc', 'aparc.a2005s']
borders = [True, False, 2]
alphas = [1, 0.5]
Expand All @@ -129,7 +143,7 @@ def test_annot():
@requires_fsaverage
def test_contour():
"""Test plotting of contour overlay."""
mlab.options.backend = 'auto'
_set_backend()
brain = Brain(*std_args)
overlay_file = pjoin(data_dir, "lh.sig.nii.gz")
brain.add_contour_overlay(overlay_file)
Expand All @@ -144,7 +158,7 @@ def test_contour():
@requires_fs
def test_data():
"""Test plotting of data."""
mlab.options.backend = 'auto'
_set_backend()
brain = Brain(*std_args)
mri_file = pjoin(data_dir, 'resting_corr.nii.gz')
reg_file = pjoin(data_dir, 'register.dat')
Expand All @@ -158,13 +172,14 @@ def test_data():
@requires_fsaverage
def test_foci():
"""Test plotting of foci."""
mlab.options.backend = 'test'
_set_backend('test')
brain = Brain(*std_args)
coords = [[-36, 18, -3],
[-43, 25, 24],
[-48, 26, -2]]
brain.add_foci(coords, map_surface="white", color="gold")

subj_dir = utils._get_subjects_dir()
annot_path = pjoin(subj_dir, subject_id, 'label', 'lh.aparc.a2009s.annot')
ids, ctab, names = nib.freesurfer.read_annot(annot_path)
verts = np.arange(0, len(ids))
Expand All @@ -178,13 +193,14 @@ def test_foci():
@requires_fsaverage
def test_label():
"""Test plotting of label."""
mlab.options.backend = 'auto'
_set_backend()
subject_id = "fsaverage"
hemi = "lh"
surf = "inflated"
brain = Brain(subject_id, hemi, surf)
brain.add_label("BA1")
brain.add_label("BA1", color="blue", scalar_thresh=.5)
subj_dir = utils._get_subjects_dir()
label_file = pjoin(subj_dir, subject_id,
"label", "%s.MT.label" % hemi)
brain.add_label(label_file)
Expand All @@ -209,7 +225,7 @@ def test_label():
@requires_fsaverage
def test_meg_inverse():
"""Test plotting of MEG inverse solution."""
mlab.options.backend = 'auto'
_set_backend()
brain = Brain(*std_args)
stc_fname = os.path.join(data_dir, 'meg_source_estimate-lh.stc')
stc = io.read_stc(stc_fname)
Expand Down Expand Up @@ -261,7 +277,7 @@ def time_label(t):
@requires_fsaverage
def test_morphometry():
"""Test plotting of morphometry."""
mlab.options.backend = 'auto'
_set_backend()
brain = Brain(*std_args)
brain.add_morphometry("curv")
brain.add_morphometry("sulc", grayscale=True)
Expand All @@ -276,7 +292,7 @@ def test_movie():
import imageio

# create and setup the Brain instance
mlab.options.backend = 'auto'
_set_backend()
brain = Brain(*std_args)
stc_fname = os.path.join(data_dir, 'meg_source_estimate-lh.stc')
stc = io.read_stc(stc_fname)
Expand Down Expand Up @@ -309,7 +325,7 @@ def test_movie():
@requires_fsaverage
def test_overlay():
"""Test plotting of overlay."""
mlab.options.backend = 'auto'
_set_backend()
# basic overlay support
overlay_file = pjoin(data_dir, "lh.sig.nii.gz")
brain = Brain(*std_args)
Expand Down Expand Up @@ -344,7 +360,7 @@ def test_overlay():
@requires_fsaverage
def test_probabilistic_labels():
"""Test plotting of probabilistic labels."""
mlab.options.backend = 'auto'
_set_backend()
brain = Brain("fsaverage", "lh", "inflated",
cortex="low_contrast")

Expand All @@ -355,6 +371,7 @@ def test_probabilistic_labels():
brain.add_label("BA45", color="firebrick", borders=True)
brain.add_label("BA45", color="salmon", borders=True, scalar_thresh=.5)

subj_dir = utils._get_subjects_dir()
label_file = pjoin(subj_dir, "fsaverage", "label", "lh.BA6.label")
prob_field = np.zeros_like(brain.geo['lh'].x)
ids, probs = nib.freesurfer.read_label(label_file, read_scalars=True)
Expand All @@ -370,7 +387,7 @@ def test_probabilistic_labels():
@requires_fsaverage
def test_text():
"""Test plotting of text."""
mlab.options.backend = 'test'
_set_backend('test')
brain = Brain(*std_args)
brain.add_text(0.1, 0.1, 'Hello', 'blah')
brain.close()
Expand All @@ -379,7 +396,7 @@ def test_text():
@requires_fsaverage
def test_animate():
"""Test animation."""
mlab.options.backend = 'auto'
_set_backend('auto')
brain = Brain(*std_args, size=100)
brain.add_morphometry('curv')
tmp_name = mktemp() + '.avi'
Expand All @@ -393,7 +410,7 @@ def test_animate():
@requires_fsaverage
def test_views():
"""Test showing different views."""
mlab.options.backend = 'test'
_set_backend('test')
brain = Brain(*std_args)
brain.show_view('lateral')
brain.show_view('m')
Expand Down
26 changes: 17 additions & 9 deletions surfer/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -661,14 +661,21 @@ def _get_subjects_dir(subjects_dir=None, raise_error=True):
return subjects_dir


def has_fsaverage(subjects_dir=None):
def has_fsaverage(subjects_dir=None, raise_error=True, return_why=False):
"""Determine whether the user has a usable fsaverage"""
fs_dir = op.join(_get_subjects_dir(subjects_dir, False), 'fsaverage')
if not op.isdir(fs_dir):
return False
if not op.isdir(op.join(fs_dir, 'surf')):
return False
return True
subjects_dir = _get_subjects_dir(subjects_dir, raise_error=raise_error)
out = ''
if not op.isdir(subjects_dir):
out = 'SUBJECTS_DIR not found: %s' % (subjects_dir,)
else:
fs_dir = op.join(_get_subjects_dir(subjects_dir, False), 'fsaverage')
surf_dir = op.join(fs_dir, 'surf')
if not op.isdir(fs_dir):
out = 'fsaverage not found in SUBJECTS_DIR: %s' % (fs_dir,)
elif not op.isdir(surf_dir):
out = 'fsaverage has no "surf" directory: %s' % (surf_dir,)
out = (out == '', out) if return_why else (out == '')
return out


def has_imageio():
Expand All @@ -680,8 +687,9 @@ def has_imageio():
return True


requires_fsaverage = np.testing.dec.skipif(not has_fsaverage(),
'Requires fsaverage subject data')
_has, _why = has_fsaverage(raise_error=False, return_why=True)
requires_fsaverage = np.testing.dec.skipif(
not _has, 'Requires fsaverage subject data (%s)' % _why)

requires_imageio = np.testing.dec.skipif(not has_imageio(),
"Requires imageio package")
Loading