Skip to content

Commit 54364ec

Browse files
committed
Merge remote-tracking branch 'nipy/master'
2 parents c88baff + 5427538 commit 54364ec

36 files changed

+1080
-296
lines changed

.travis.yml

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -10,36 +10,38 @@ env:
1010
- INSTALL_DEB_DEPENDECIES=false
1111
- INSTALL_DEB_DEPENDECIES=true DUECREDIT_ENABLE=yes
1212
before_install:
13-
- wget http://repo.continuum.io/miniconda/Miniconda${TRAVIS_PYTHON_VERSION:0:1}-latest-Linux-x86_64.sh
14-
-O /home/travis/.cache/miniconda.sh
15-
- bash /home/travis/.cache/miniconda.sh -b -p /home/travis/miniconda
16-
- export PATH=/home/travis/miniconda/bin:$PATH
17-
- if $INSTALL_DEB_DEPENDECIES; then sudo rm -rf /dev/shm; fi
18-
- if $INSTALL_DEB_DEPENDECIES; then sudo ln -s /run/shm /dev/shm; fi
19-
- bash <(wget -q -O- http://neuro.debian.net/_files/neurodebian-travis.sh)
20-
- sudo apt-get -y update
21-
- sudo apt-get -y install xvfb fusefat
22-
- if $INSTALL_DEB_DEPENDECIES; then travis_retry sudo apt-get install -y -qq
23-
fsl afni elastix fsl-atlases; fi
24-
- if $INSTALL_DEB_DEPENDECIES; then
25-
source /etc/fsl/fsl.sh;
26-
source /etc/afni/afni.sh; fi
27-
- export FSLOUTPUTTYPE=NIFTI_GZ
13+
- function bef_inst {
14+
wget http://repo.continuum.io/miniconda/Miniconda${TRAVIS_PYTHON_VERSION:0:1}-latest-Linux-x86_64.sh
15+
-O /home/travis/.cache/miniconda.sh &&
16+
bash /home/travis/.cache/miniconda.sh -b -p /home/travis/miniconda &&
17+
export PATH=/home/travis/miniconda/bin:$PATH &&
18+
if $INSTALL_DEB_DEPENDECIES; then sudo rm -rf /dev/shm; fi &&
19+
if $INSTALL_DEB_DEPENDECIES; then sudo ln -s /run/shm /dev/shm; fi &&
20+
bash <(wget -q -O- http://neuro.debian.net/_files/neurodebian-travis.sh) &&
21+
sudo apt-get -y update &&
22+
sudo apt-get -y install xvfb fusefat &&
23+
if $INSTALL_DEB_DEPENDECIES; then travis_retry sudo apt-get install -y -qq
24+
fsl afni elastix fsl-atlases; fi &&
25+
if $INSTALL_DEB_DEPENDECIES; then
26+
source /etc/fsl/fsl.sh;
27+
source /etc/afni/afni.sh; fi &&
28+
export FSLOUTPUTTYPE=NIFTI_GZ; }
29+
- travis_retry bef_inst
2830
install:
29-
- conda config --add channels conda-forge
30-
- conda update --yes conda
31-
- conda update --all -y python=$TRAVIS_PYTHON_VERSION
32-
# - if [[ "${INSTALL_DEB_DEPENDECIES}" == "true" && ${TRAVIS_PYTHON_VERSION:0:1} == "2" ]]; then
33-
# conda install -y vtk mayavi; fi
34-
- conda install -y nipype matplotlib nitime
35-
- pip install python-coveralls coverage doctest-ignore-unicode
36-
- if [ ! -z "$DUECREDIT_ENABLE"]; then pip install duecredit; fi
37-
- rm -r /home/travis/miniconda/lib/python${TRAVIS_PYTHON_VERSION}/site-packages/nipype*
38-
- pip install -r requirements.txt
39-
- pip install -e .
40-
- export COVERAGE_PROCESS_START=$(pwd)/.coveragerc
41-
- export COVERAGE_DATA_FILE=$(pwd)/.coverage
42-
- echo "data_file = ${COVERAGE_DATA_FILE}" >> ${COVERAGE_PROCESS_START}
31+
- function inst {
32+
conda config --add channels conda-forge &&
33+
conda update --yes conda &&
34+
conda update --all -y python=$TRAVIS_PYTHON_VERSION &&
35+
conda install -y nipype matplotlib nitime &&
36+
pip install python-coveralls coverage doctest-ignore-unicode &&
37+
if [ ! -z "$DUECREDIT_ENABLE"]; then pip install duecredit; fi &&
38+
rm -r /home/travis/miniconda/lib/python${TRAVIS_PYTHON_VERSION}/site-packages/nipype* &&
39+
pip install -r requirements.txt &&
40+
pip install -e . &&
41+
export COVERAGE_PROCESS_START=$(pwd)/.coveragerc &&
42+
export COVERAGE_DATA_FILE=$(pwd)/.coverage &&
43+
echo "data_file = ${COVERAGE_DATA_FILE}" >> ${COVERAGE_PROCESS_START}; }
44+
- travis_retry inst
4345
script:
4446
- python -W once:FSL:UserWarning:nipype `which nosetests` --with-doctest --with-doctest-ignore-unicode --with-cov --cover-package nipype --logging-level=DEBUG --verbosity=3
4547
after_success:

CHANGES

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
Upcoming release 0.13
22
=====================
33

4+
* FIX: Minor bugfixes related to unicode literals (https://github.com/nipy/nipype/pull/1656)
45
* ENH: Add a DVARS calculation interface (https://github.com/nipy/nipype/pull/1606)
6+
* ENH: New interface to b0calc of FSL-POSSUM (https://github.com/nipy/nipype/pull/1399)
57
* ENH: Convenient load/save of interface inputs (https://github.com/nipy/nipype/pull/1591)
68
* ENH: Add a Framewise Displacement calculation interface (https://github.com/nipy/nipype/pull/1604)
79
* FIX: Use builtins open and unicode literals for py3 compatibility (https://github.com/nipy/nipype/pull/1572)
@@ -124,14 +126,14 @@ Release 0.11.0 (September 15, 2015)
124126
* FIX: Bug crashed 'make api' (https://github.com/nipy/nipype/pull/1026)
125127
* ENH: Updated antsIntroduction to handle RA and RI registrations (https://github.com/nipy/nipype/pull/1009)
126128
* ENH: Updated N4BiasCorrection input spec to include weight image and spline order. Made
127-
argument formatting consistent. Cleaned ants.segmentation according to PEP8.
128-
(https://github.com/nipy/nipype/pull/990/files)
129+
argument formatting consistent. Cleaned ants.segmentation according to PEP8.
130+
(https://github.com/nipy/nipype/pull/990/files)
129131
* ENH: SPM12 Normalize interface (https://github.com/nipy/nipype/pull/986)
130132
* FIX: Utility interface test dir (https://github.com/nipy/nipype/pull/986)
131133
* FIX: IPython engine directory reset after crash (https://github.com/nipy/nipype/pull/987)
132134
* ENH: Resting state fMRI example with NiPy realignment and no SPM (https://github.com/nipy/nipype/pull/992)
133135
* FIX: Corrected Freesurfer SegStats _list_outputs to avoid error if summary_file is
134-
undefined (issue #994)(https://https://github.com/nipy/nipype/pull/996)
136+
undefined (issue #994)(https://https://github.com/nipy/nipype/pull/996)
135137
* FIX: OpenfMRI support and FSL 5.0.7 changes (https://github.com/nipy/nipype/pull/1006)
136138
* FIX: Output prefix in SPM Normalize with modulation (https://github.com/nipy/nipype/pull/1023)
137139
* ENH: Usability improvements in cluster environments (https://github.com/nipy/nipype/pull/1025)
@@ -213,11 +215,11 @@ Release 0.9.0 (December 20, 2013)
213215
* ENH: AFNI interfaces refactor, prefix, suffix are replaced by
214216
"flexible_%s_templates"
215217
* ENH: New SPM interfaces:
216-
- spm.ResliceToReference,
217-
- spm.DicomImport
218+
- spm.ResliceToReference,
219+
- spm.DicomImport
218220
* ENH: New AFNI interfaces:
219-
- afni.AFNItoNIFTI
220-
- afni.TCorr1D
221+
- afni.AFNItoNIFTI
222+
- afni.TCorr1D
221223
* ENH: Several new interfaces related to Camino were added:
222224
- camino.SFPICOCalibData
223225
- camino.Conmat
@@ -231,13 +233,13 @@ Release 0.9.0 (December 20, 2013)
231233
- mrtrix.FindShPeaks
232234
- mrtrix.Directions2Amplitude
233235
* ENH: New FSL interfaces:
234-
- fsl.PrepareFieldmap
235-
- fsl.TOPUP
236-
- fsl.ApplyTOPUP
237-
- fsl.Eddy
236+
- fsl.PrepareFieldmap
237+
- fsl.TOPUP
238+
- fsl.ApplyTOPUP
239+
- fsl.Eddy
238240
* ENH: New misc interfaces:
239-
- FuzzyOverlap,
240-
- P2PDistance
241+
- FuzzyOverlap,
242+
- P2PDistance
241243
* ENH: New workflows: nipype.workflows.dmri.fsl.epi.[fieldmap_correction&topup_correction]
242244
* ENH: Added simplified outputname generation for command line interfaces.
243245
* ENH: Allow ants use a single mask image
@@ -295,7 +297,7 @@ Release 0.7.0 (Dec 18, 2012)
295297
afni.AutoTcorrelate, DcmStack
296298
* ENH: New workflows: ants template building (both using 'ANTS' and the new 'antsRegistration')
297299
* ENH: New examples: how to use ANTS template building workflows (smri_ants_build_tmeplate),
298-
how to set SGE specific options (smri_ants_build_template_new)
300+
how to set SGE specific options (smri_ants_build_template_new)
299301
* ENH: added no_flatten option to Merge
300302
* ENH: added versioning option and checking to traits
301303
* ENH: added deprecation metadata to traits
@@ -357,9 +359,9 @@ Release 0.5 (Mar 10, 2012)
357359
* API: Canned workflows are now all under a different package structure
358360
* API: SpecifyModel event_info renamed to event_files
359361
* API: DataGrabber is always being rerun (unless overwrite is set to False on
360-
Node level)
362+
Node level)
361363
* API: "stop_on_first_rerun" does not stop for DataGrabber (unless overwrite is
362-
set to True on Node level)
364+
set to True on Node level)
363365
* API: Output prefix can be set for spm nodes (SliceTiming, Realign, Coregister,
364366
Normalize, Smooth)
365367

codecov.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
coverage:
22
range: "0...100"
33
status:
4+
patch:
5+
default:
6+
target: 0
7+
threshold: 100
48
project:
59
default:
610
target: 0

doc/users/grabbing_and_sinking.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ when using multiple nested iterables.
235235
Substitutions
236236
-------------
237237

238-
The `substitutions` and `substitutions_regexp` inputs allow users to modify the
238+
The ``substitutions`` and ``regexp_substitutions`` inputs allow users to modify the
239239
output destination path and name of a file. Substitutions are a list of 2-tuples
240240
and are carried out in the order in which they were entered. Assuming that the
241241
output path of a file is:

nipype/algorithms/confounds.py

Lines changed: 37 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,18 @@
1212
1313
'''
1414
from __future__ import print_function, division, unicode_literals, absolute_import
15-
from builtins import str, zip, range, open
15+
from builtins import range
1616

1717
import os
1818
import os.path as op
1919

2020
import nibabel as nb
2121
import numpy as np
22-
from scipy import linalg
23-
from scipy.special import legendre
22+
from numpy.polynomial import Legendre
23+
from scipy import linalg, signal
2424

2525
from .. import logging
26-
from ..external.due import due, Doi, BibTeX
26+
from ..external.due import BibTeX
2727
from ..interfaces.base import (traits, TraitedSpec, BaseInterface,
2828
BaseInterfaceInputSpec, File, isdefined,
2929
InputMultiPath)
@@ -160,8 +160,8 @@ def _run_interface(self, runtime):
160160
'dvars_nstd', ext=self.inputs.figformat)
161161
fig = plot_confound(dvars[1], self.inputs.figsize, 'DVARS', series_tr=tr)
162162
fig.savefig(self._results['fig_nstd'], dpi=float(self.inputs.figdpi),
163-
format=self.inputs.figformat,
164-
bbox_inches='tight')
163+
format=self.inputs.figformat,
164+
bbox_inches='tight')
165165
fig.clf()
166166

167167
if self.inputs.save_vxstd:
@@ -175,8 +175,8 @@ def _run_interface(self, runtime):
175175
fig = plot_confound(dvars[2], self.inputs.figsize, 'Voxelwise std DVARS',
176176
series_tr=tr)
177177
fig.savefig(self._results['fig_vxstd'], dpi=float(self.inputs.figdpi),
178-
format=self.inputs.figformat,
179-
bbox_inches='tight')
178+
format=self.inputs.figformat,
179+
bbox_inches='tight')
180180
fig.clf()
181181

182182
if self.inputs.save_all:
@@ -192,7 +192,7 @@ def _list_outputs(self):
192192

193193

194194
class FramewiseDisplacementInputSpec(BaseInterfaceInputSpec):
195-
in_plots = File(exists=True, desc='motion parameters as written by FSL MCFLIRT')
195+
in_plots = File(exists=True, mandatory=True, desc='motion parameters as written by FSL MCFLIRT')
196196
radius = traits.Float(50, usedefault=True,
197197
desc='radius in mm to calculate angular FDs, 50mm is the '
198198
'default since it is used in Power et al. 2012')
@@ -313,6 +313,19 @@ class CompCor(BaseInterface):
313313
'''
314314
input_spec = CompCorInputSpec
315315
output_spec = CompCorOutputSpec
316+
references_ = [{'entry': BibTeX("@article{compcor_2007,"
317+
"title = {A component based noise correction method (CompCor) for BOLD and perfusion based},"
318+
"volume = {37},"
319+
"number = {1},"
320+
"doi = {10.1016/j.neuroimage.2007.04.042},"
321+
"urldate = {2016-08-13},"
322+
"journal = {NeuroImage},"
323+
"author = {Behzadi, Yashar and Restom, Khaled and Liau, Joy and Liu, Thomas T.},"
324+
"year = {2007},"
325+
"pages = {90-101},}"
326+
),
327+
'tags': ['method', 'implementation']
328+
}]
316329

317330
def _run_interface(self, runtime):
318331
imgseries = nb.load(self.inputs.realigned_file).get_data()
@@ -324,18 +337,13 @@ def _run_interface(self, runtime):
324337
# from paper:
325338
# "The constant and linear trends of the columns in the matrix M were
326339
# removed [prior to ...]"
327-
if self.inputs.use_regress_poly:
328-
voxel_timecourses = regress_poly(self.inputs.regress_poly_degree,
329-
voxel_timecourses)
330-
voxel_timecourses = voxel_timecourses - np.mean(voxel_timecourses,
331-
axis=1)[:, np.newaxis]
340+
degree = self.inputs.regress_poly_degree if self.inputs.use_regress_poly else 0
341+
voxel_timecourses = regress_poly(degree, voxel_timecourses)
332342

333343
# "Voxel time series from the noise ROI (either anatomical or tSTD) were
334344
# placed in a matrix M of size Nxm, with time along the row dimension
335345
# and voxels along the column dimension."
336346
M = voxel_timecourses.T
337-
numvols = M.shape[0]
338-
numvoxels = M.shape[1]
339347

340348
# "[... were removed] prior to column-wise variance normalization."
341349
M = M / self._compute_tSTD(M, 1.)
@@ -399,7 +407,6 @@ def _run_interface(self, runtime):
399407
# defined as the standard deviation of the time series after the removal
400408
# of low-frequency nuisance terms (e.g., linear and quadratic drift)."
401409
imgseries = regress_poly(2, imgseries)
402-
imgseries = imgseries - np.mean(imgseries, axis=1)[:, np.newaxis]
403410

404411
time_voxels = imgseries.T
405412
num_voxels = np.prod(time_voxels.shape[1:])
@@ -475,7 +482,7 @@ def _run_interface(self, runtime):
475482
data = data.astype(np.float32)
476483

477484
if isdefined(self.inputs.regress_poly):
478-
data = regress_poly(self.inputs.regress_poly, data)
485+
data = regress_poly(self.inputs.regress_poly, data, remove_mean=False)
479486
img = nb.Nifti1Image(data, img.get_affine(), header)
480487
nb.save(img, op.abspath(self.inputs.detrended_file))
481488

@@ -500,28 +507,33 @@ def _list_outputs(self):
500507
outputs['detrended_file'] = op.abspath(self.inputs.detrended_file)
501508
return outputs
502509

503-
def regress_poly(degree, data):
510+
def regress_poly(degree, data, remove_mean=True, axis=-1):
504511
''' returns data with degree polynomial regressed out.
505-
The last dimension (i.e. data.shape[-1]) should be time.
512+
Be default it is calculated along the last axis (usu. time).
513+
If remove_mean is True (default), the data is demeaned (i.e. degree 0).
514+
If remove_mean is false, the data is not.
506515
'''
507516
datashape = data.shape
508-
timepoints = datashape[-1]
517+
timepoints = datashape[axis]
509518

510519
# Rearrange all voxel-wise time-series in rows
511520
data = data.reshape((-1, timepoints))
512521

513522
# Generate design matrix
514-
X = np.ones((timepoints, 1))
523+
X = np.ones((timepoints, 1)) # quick way to calc degree 0
515524
for i in range(degree):
516-
polynomial_func = legendre(i+1)
525+
polynomial_func = Legendre.basis(i + 1)
517526
value_array = np.linspace(-1, 1, timepoints)
518527
X = np.hstack((X, polynomial_func(value_array)[:, np.newaxis]))
519528

520529
# Calculate coefficients
521530
betas = np.linalg.pinv(X).dot(data.T)
522531

523532
# Estimation
524-
datahat = X[:, 1:].dot(betas[1:, ...]).T
533+
if remove_mean:
534+
datahat = X.dot(betas).T
535+
else: # disregard the first layer of X, which is degree 0
536+
datahat = X[:, 1:].dot(betas[1:, ...]).T
525537
regressed_data = data - datahat
526538

527539
# Back to original shape
@@ -556,7 +568,6 @@ def compute_dvars(in_file, in_mask, remove_zerovariance=False):
556568
:return: the standardized DVARS
557569
558570
"""
559-
import os.path as op
560571
import numpy as np
561572
import nibabel as nb
562573
from nitime.algorithms import AR_est_YW
@@ -581,7 +592,7 @@ def compute_dvars(in_file, in_mask, remove_zerovariance=False):
581592
mfunc = func[idx[0], idx[1], idx[2], :]
582593

583594
# Demean
584-
mfunc -= mfunc.mean(axis=1).astype(np.float32)[..., np.newaxis]
595+
mfunc = regress_poly(0, mfunc, remove_mean=True).astype(np.float32)
585596

586597
# Compute (non-robust) estimate of lag-1 autocorrelation
587598
ar1 = np.apply_along_axis(AR_est_YW, 1, mfunc, 1)[:, 0]

nipype/algorithms/modelgen.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -547,7 +547,7 @@ def _generate_design(self, infolist=None):
547547
out = np.array([])
548548

549549
if out.size > 0:
550-
iflogger.debug('fname=%s, out=%s, nscans=%s', filename, out, repr(sum(nscans[0:i])))
550+
iflogger.debug('fname=%s, out=%s, nscans=%d', filename, out, sum(nscans[0:i]))
551551
sumscans = out.astype(int) + sum(nscans[0:i])
552552

553553
if out.size == 1:
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT
2+
from ...testing import assert_equal
3+
from ..confounds import CompCor
4+
5+
6+
def test_CompCor_inputs():
7+
input_map = dict(components_file=dict(mandatory=False,
8+
usedefault=True,
9+
),
10+
ignore_exception=dict(nohash=True,
11+
usedefault=True,
12+
),
13+
mask_file=dict(mandatory=False,
14+
),
15+
num_components=dict(usedefault=True,
16+
),
17+
realigned_file=dict(mandatory=True,
18+
),
19+
regress_poly_degree=dict(usedefault=True,
20+
),
21+
use_regress_poly=dict(usedefault=True,
22+
),
23+
)
24+
inputs = CompCor.input_spec()
25+
26+
for key, metadata in list(input_map.items()):
27+
for metakey, value in list(metadata.items()):
28+
yield assert_equal, getattr(inputs.traits()[key], metakey), value
29+
30+
31+
def test_CompCor_outputs():
32+
output_map = dict(components_file=dict(),
33+
)
34+
outputs = CompCor.output_spec()
35+
36+
for key, metadata in list(output_map.items()):
37+
for metakey, value in list(metadata.items()):
38+
yield assert_equal, getattr(outputs.traits()[key], metakey), value

0 commit comments

Comments
 (0)