Skip to content

Commit 8a7eeef

Browse files
committed
Merge branch 'master' of https://github.com/nistats/nistats into improve-reporting
* 'master' of https://github.com/nistats/nistats: Replace numpy's deprecated dec with pytest's skipif (nilearn#423) Replace Nosetest library calls with Pytest in code (nilearn#422) Replace Nosetests with Pytest as test runner (nilearn#419) Removed Appveyor config (Azure Pipelines does the windows tests now) (nilearn#420) All-resolution inference (nilearn#414) Fix: Missing variables in localizerd dataset are no longer None, but n/a (nilearn#415) # Conflicts: # nistats/tests/test_thresholding.py # nistats/thresholding.py
2 parents 77e91bd + a10c5fe commit 8a7eeef

27 files changed

+811
-590
lines changed

.travis.yml

+3-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ matrix:
2929
- env: DISTRIB="conda" PYTHON_VERSION="2.7"
3030
NUMPY_VERSION="1.11.2" SCIPY_VERSION="0.19"
3131
SCIKIT_LEARN_VERSION="0.18" MATPLOTLIB_VERSION="1.5.1"
32-
NIBABEL_VERSION="2.0.2" PANDAS_VERSION="*" COVERAGE="true"
32+
NIBABEL_VERSION="2.0.2" PANDAS_VERSION="*"
33+
COVERAGE="true"
3334
# Python 3.4 with intermediary versions
3435
- env: DISTRIB="conda" PYTHON_VERSION="3.4"
3536
NUMPY_VERSION="1.11.0" SCIPY_VERSION="0.17"
@@ -47,6 +48,7 @@ matrix:
4748
PANDAS_VERSION="*" BOTO3=true
4849
install:
4950
- source continuous_integration/install.sh
51+
- pip install pytest>3.9 pytest-cov
5052

5153
before_script:
5254
- make clean

Makefile

+4-7
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
PYTHON ?= python
66
CYTHON ?= cython
7-
NOSETESTS ?= nosetests
7+
TESTRUNNER ?= nosetests
88
CTAGS ?= ctags
99

1010
all: clean test doc-plot pdf
@@ -29,16 +29,13 @@ inplace:
2929
$(PYTHON) setup.py build_ext -i
3030

3131
test-code:
32-
$(NOSETESTS) -s nistats
32+
python -m pytest --pyargs nistats --cov=nistats
3333
test-doc:
34-
$(NOSETESTS) -s --with-doctest --doctest-tests --doctest-extension=rst \
35-
--doctest-extension=inc --doctest-fixtures=_fixture doc/ \
36-
34+
pytest --doctest-glob='*.rst' `find doc/ -name '*.rst'`
3735

3836
test-coverage:
3937
rm -rf coverage .coverage
40-
$(NOSETESTS) -s --with-coverage --cover-html --cover-html-dir=coverage \
41-
--cover-package=nistats nistats
38+
pytest --pyargs nistats --showlocals --cov=nistats --cov-report=html:coverage
4239

4340
test: test-code test-doc
4441

appveyor.yml

-54
This file was deleted.

continuous_integration/install.sh

+1-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ create_new_venv() {
2222
deactivate
2323
virtualenv --system-site-packages testvenv
2424
source testvenv/bin/activate
25-
pip install nose
25+
pip install nose pytest==3.9.1 pytest-cov
2626
}
2727

2828
print_conda_requirements() {
@@ -112,7 +112,6 @@ elif [[ "$DISTRIB" == "conda" ]]; then
112112
fi
113113
pip install nilearn
114114

115-
116115
else
117116
echo "Unrecognized distribution ($DISTRIB); cannot setup travis environment."
118117
exit 1

doc/whats_new.rst

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ New
1212
* Use :func:`nistats.reporting.make_glm_report` to easily generate HTML reports from fitted first and second level models and contrasts.
1313
* New dataset fetcher, :func:`nistats.datasets.fetch_language_localizer_demo_dataset` , BIDS 1.2 compatible.
1414
* New example showcasing the use of a GLM to get beta maps for decoding experiments (aka beta-regression).
15-
See it `here :ref:sphx_glr_auto_examples_05_plot_haxby_block_classification.py`_
15+
* Addition of all-resolution inference, ie statistically grounded of true positive in given clusters, in :func:`nistats.thresholding.map_threshold`
1616

1717
Changes
1818
-------
@@ -30,7 +30,7 @@ Fixes
3030
* Explicit method for fixed effects to support image-based summary
3131
statistics approach.
3232
* FIR delays are now integers.
33-
33+
3434
Contributors
3535
------------
3636

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
"""
2+
Second-level fMRI model: true positive proportion in clusters
3+
=============================================================
4+
5+
This script showcases the so-called "All resolution inference"
6+
procedure, in which the proportion of true discoveries in arbitrary
7+
clusters is estimated. The clusters can be defined from the input
8+
image, i.e. in a circular way, as the error control accounts for
9+
arbitrary cluster selection.
10+
11+
Rosenblatt JD, Finos L, Weeda WD, Solari A, Goeman JJ. All-Resolutions
12+
Inference for brain imaging. Neuroimage. 2018 Nov 1;181:786-796. doi:
13+
10.1016/j.neuroimage.2018.07.060
14+
15+
"""
16+
17+
#########################################################################
18+
# Fetch dataset
19+
# --------------
20+
# We download a list of left vs right button press contrasts from a
21+
# localizer dataset. Note that we fetch individual t-maps that represent the
22+
# BOLD activity estimate divided by the uncertainty about this estimate.
23+
from nilearn.datasets import fetch_localizer_contrasts
24+
n_subjects = 16
25+
data = fetch_localizer_contrasts(["left vs right button press"], n_subjects,
26+
get_tmaps=True)
27+
28+
from nilearn import plotting
29+
import matplotlib.pyplot as plt
30+
31+
############################################################################
32+
# Estimate second level model
33+
# ---------------------------
34+
# We define the input maps and the design matrix for the second level model
35+
# and fit it.
36+
import pandas as pd
37+
second_level_input = data['cmaps']
38+
design_matrix = pd.DataFrame([1] * len(second_level_input),
39+
columns=['intercept'])
40+
41+
############################################################################
42+
# Model specification and fit
43+
from nistats.second_level_model import SecondLevelModel
44+
second_level_model = SecondLevelModel(smoothing_fwhm=8.0)
45+
second_level_model = second_level_model.fit(second_level_input,
46+
design_matrix=design_matrix)
47+
48+
##########################################################################
49+
# To estimate the contrast is very simple. We can just provide the column
50+
# name of the design matrix.
51+
z_map = second_level_model.compute_contrast(output_type='z_score')
52+
53+
###########################################################################
54+
# We threshold the second level contrast at uncorrected p < 0.001 and plot
55+
from scipy.stats import norm
56+
p_val = 0.001
57+
p001_uncorrected = norm.isf(p_val)
58+
59+
from nistats.thresholding import cluster_level_inference
60+
proportion_true_discoveries_img = cluster_level_inference(z_map, threshold=[3, 4, 5], alpha=.05)
61+
62+
plotting.plot_stat_map(
63+
proportion_true_discoveries_img, threshold=0., colorbar=True, display_mode='z',
64+
title='group left-right button press, proportion true positives', vmax=1)
65+
66+
plotting.plot_stat_map(
67+
z_map, threshold=p001_uncorrected, colorbar=True, display_mode='z',
68+
title='group left-right button press (uncorrected p < 0.001)')
69+
70+
71+
plotting.show()

examples/03_second_level_models/plot_second_level_association_test.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
##############################################################################
3535
# Quality check / Remove subjects with bad tested variate
3636
import numpy as np
37-
mask_quality_check = np.where(tested_var != b'None')[0]
37+
mask_quality_check = np.where(tested_var != b'n/a')[0]
3838
n_samples = mask_quality_check.size
3939
contrast_map_filenames = [localizer_dataset.cmaps[i]
4040
for i in mask_quality_check]

nistats/conftest.py

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
from distutils.version import LooseVersion
2+
3+
import numpy as np
4+
import pytest
5+
6+
from _pytest.doctest import DoctestItem
7+
from nilearn.datasets import func, utils
8+
from nilearn.datasets.tests import test_utils as tst
9+
10+
try:
11+
import matplotlib
12+
except ImportError:
13+
collect_ignore = ['reporting',
14+
'tests/test_glm_reporter.py',
15+
'tests/test_reporting.py',
16+
'tests/test_sphinx_report.py',
17+
]
18+
else:
19+
matplotlib # Prevents flake8 erring due to unused entities.
20+
21+
22+
def pytest_collection_modifyitems(items):
23+
# numpy changed the str/repr formatting of numpy arrays in 1.14. We want to
24+
# run doctests only for numpy >= 1.14.Adapted from scikit-learn
25+
if LooseVersion(np.__version__) < LooseVersion('1.14'):
26+
reason = 'doctests are only run for numpy >= 1.14'
27+
skip_doctests = True
28+
else:
29+
skip_doctests = False
30+
31+
if skip_doctests:
32+
skip_marker = pytest.mark.skip(reason=reason)
33+
for item in items:
34+
if isinstance(item, DoctestItem):
35+
item.add_marker(skip_marker)
36+
37+
38+
@pytest.fixture()
39+
def request_mocker():
40+
tst.setup_mock(utils, func)
41+
yield
42+
tst.teardown_mock(utils, func)

nistats/hemodynamic_models.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -494,10 +494,8 @@ def compute_regressor(exp_condition, hrf_model, frame_times, con_id='cond',
494494
# fir_delays should be integers
495495
if fir_delays is not None:
496496
fir_delays = [int(x) for x in fir_delays]
497-
498-
# oversampling should be an integer
499497
oversampling = int(oversampling)
500-
498+
501499
# this is the average tr in this session, not necessarily the true tr
502500
tr = float(frame_times.max()) / (np.size(frame_times) - 1)
503501

nistats/reporting/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
from ._get_clusters_table import get_clusters_table
2121
from ._plot_matrices import plot_contrast_matrix, plot_design_matrix
2222
from .glm_reporter import make_glm_report
23-
from.sphinx_report import _ReportScraper
23+
from .sphinx_report import _ReportScraper
2424

2525
__all__ = [compare_niimgs,
2626
get_clusters_table,

nistats/tests/test_check_events_file_uses_tab_separators.py

+9-12
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
import pandas as pd
2+
import pytest
23

34
from nibabel.tmpdirs import InTemporaryDirectory
4-
from nose.tools import (assert_raises,
5-
assert_true,
6-
)
7-
85
from nistats.utils import _check_events_file_uses_tab_separators
96

107

@@ -34,11 +31,11 @@ def _create_test_file(temp_csv, test_data, delimiter):
3431

3532
def _run_test_for_invalid_separator(filepath, delimiter_name):
3633
if delimiter_name not in ('tab', 'comma'):
37-
with assert_raises(ValueError):
34+
with pytest.raises(ValueError):
3835
_check_events_file_uses_tab_separators(events_files=filepath)
3936
else:
4037
result = _check_events_file_uses_tab_separators(events_files=filepath)
41-
assert_true(result is None)
38+
assert result is None
4239

4340

4441
def test_for_invalid_separator():
@@ -59,7 +56,7 @@ def test_with_2D_dataframe():
5956
events_pandas_dataframe = pd.DataFrame(data_for_pandas_dataframe)
6057
result = _check_events_file_uses_tab_separators(
6158
events_files=events_pandas_dataframe)
62-
assert_true(result is None)
59+
assert result is None
6360

6461

6562
def test_with_1D_dataframe():
@@ -68,19 +65,19 @@ def test_with_1D_dataframe():
6865
events_pandas_dataframe = pd.DataFrame(dataframe_)
6966
result = _check_events_file_uses_tab_separators(
7067
events_files=events_pandas_dataframe)
71-
assert_true(result is None)
68+
assert result is None
7269

7370
def test_for_invalid_filepath():
7471
filepath = 'junk_file_path.csv'
7572
result = _check_events_file_uses_tab_separators(events_files=filepath)
76-
assert_true(result is None)
73+
assert result is None
7774

7875

7976
def test_for_pandas_dataframe():
8077
events_pandas_dataframe = pd.DataFrame([['a', 'b', 'c'], [0, 1, 2]])
8178
result = _check_events_file_uses_tab_separators(
8279
events_files=events_pandas_dataframe)
83-
assert_true(result is None)
80+
assert result is None
8481

8582

8683
def test_binary_opening_an_image():
@@ -91,7 +88,7 @@ def test_binary_opening_an_image():
9188
temp_img_file = 'temp_img.gif'
9289
with open(temp_img_file, 'wb') as temp_img_obj:
9390
temp_img_obj.write(img_data)
94-
with assert_raises(ValueError):
91+
with pytest.raises(ValueError):
9592
_check_events_file_uses_tab_separators(
9693
events_files=temp_img_file)
9794

@@ -102,7 +99,7 @@ def test_binary_bytearray_of_ints_data():
10299
temp_bin_file = 'temp_bin.bin'
103100
with open(temp_bin_file, 'wb') as temp_bin_obj:
104101
temp_bin_obj.write(temp_data_bytearray_from_ints)
105-
with assert_raises(ValueError):
102+
with pytest.raises(ValueError):
106103
_check_events_file_uses_tab_separators(
107104
events_files=temp_bin_file)
108105

0 commit comments

Comments
 (0)