Issues installing nipype from git-source
Apparently, there're some compatibility issues with specific versions of pip, setuptools or combinations thereof when installing from git unstable versions of packages (experienced with nipype, but might be present for other packages).


See https://travis-ci.org/poldracklab/niworkflows/jobs/579312484:
```
if [ "$INSTALL_TYPE" == "install" ]; then
      python setup.py install
  elif [ "$INSTALL_TYPE" == "develop" ]; then
      python setup.py develop
  else
      python -m pip install $PACKAGE
  fi
  
Processing /home/travis/build/poldracklab/niworkflows
  Installing build dependencies ... done
Collecting jinja2 (from niworkflows==0.10.3rc1+78.g90dcfcb)
  Downloading https://files.pythonhosted.org/packages/1d/e7/fd8b501e7a6dfe492a433deb7b9d833d39ca74916fa8bc63dd1a4947a671/Jinja2-2.10.1-py2.py3-none-any.whl (124kB)
Collecting scikit-learn>=0.19 (from niworkflows==0.10.3rc1+78.g90dcfcb)
  Downloading https://files.pythonhosted.org/packages/9f/c5/e5267eb84994e9a92a2c6a6ee768514f255d036f3c8378acfa694e9f2c99/scikit_learn-0.21.3-cp37-cp37m-manylinux1_x86_64.whl (6.7MB)
Collecting nilearn!=0.5.0,!=0.5.1,>=0.2.6 (from niworkflows==0.10.3rc1+78.g90dcfcb)
  Downloading https://files.pythonhosted.org/packages/6e/65/ba76e7cd544dafc28960e60b099d6f906a2096034c560158beaf2ff299bc/nilearn-0.5.2-py2.py3-none-any.whl (2.3MB)
Collecting nipype@ git+https://github.com/nipy/nipype.git@4cdc60d2664ea2bd35c6870a61d93d7010eccb57 from git+https://github.com/nipy/nipype.git@4cdc60d2664ea2bd35c6870a61d93d7010eccb57 (from niworkflows==0.10.3rc1+78.g90dcfcb)
  Cloning https://github.com/nipy/nipype.git (to revision 4cdc60d2664ea2bd35c6870a61d93d7010eccb57) to /tmp/pip-install-ipn5pw3h/nipype
    Complete output from command python setup.py egg_info:
    warning: no files found matching '*.au' under directory 'tests'
    warning: no files found matching '*.gif' under directory 'tests'
    warning: no files found matching '*.txt' under directory 'tests'
    zip_safe flag not set; analyzing archive contents...
    Traceback (most recent call last):
      File "/home/travis/virtualenv/python3.7.1/lib/python3.7/site-packages/setuptools/sandbox.py", line 158, in save_modules
        yield saved
      File "/home/travis/virtualenv/python3.7.1/lib/python3.7/site-packages/setuptools/sandbox.py", line 199, in setup_context
        yield
      File "/home/travis/virtualenv/python3.7.1/lib/python3.7/site-packages/setuptools/sandbox.py", line 254, in run_setup
        _execfile(setup_script, ns)
      File "/home/travis/virtualenv/python3.7.1/lib/python3.7/site-packages/setuptools/sandbox.py", line 49, in _execfile
        exec(code, globals, locals)
      File "/tmp/easy_install-01yxk76i/future-0.17.1/setup.py", line 181, in <module>
      File "/opt/python/3.7.1/lib/python3.7/distutils/core.py", line 148, in setup
        dist.run_commands()
      File "/opt/python/3.7.1/lib/python3.7/distutils/dist.py", line 966, in run_commands
        self.run_command(cmd)
      File "/opt/python/3.7.1/lib/python3.7/distutils/dist.py", line 985, in run_command
        cmd_obj.run()
      File "/home/travis/virtualenv/python3.7.1/lib/python3.7/site-packages/setuptools/command/bdist_egg.py", line 209, in run
        os.path.join(archive_root, 'EGG-INFO'), self.zip_safe()
      File "/home/travis/virtualenv/python3.7.1/lib/python3.7/site-packages/setuptools/command/bdist_egg.py", line 245, in zip_safe
        return analyze_egg(self.bdist_dir, self.stubs)
      File "/home/travis/virtualenv/python3.7.1/lib/python3.7/site-packages/setuptools/command/bdist_egg.py", line 355, in analyze_egg
        safe = scan_module(egg_dir, base, name, stubs) and safe
      File "/home/travis/virtualenv/python3.7.1/lib/python3.7/site-packages/setuptools/command/bdist_egg.py", line 395, in scan_module
        symbols = dict.fromkeys(iter_symbols(code))
      File "/home/travis/virtualenv/python3.7.1/lib/python3.7/site-packages/setuptools/command/bdist_egg.py", line 414, in iter_symbols
        for name in code.co_names:
    AttributeError: 'str' object has no attribute 'co_names'
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/tmp/pip-install-ipn5pw3h/nipype/setup.py", line 159, in <module>
        main()
      File "/tmp/pip-install-ipn5pw3h/nipype/setup.py", line 155, in main
        '''
      File "/opt/python/3.7.1/lib/python3.7/distutils/core.py", line 108, in setup
        _setup_distribution = dist = klass(attrs)
      File "/home/travis/virtualenv/python3.7.1/lib/python3.7/site-packages/setuptools/dist.py", line 325, in __init__
        self.fetch_build_eggs(attrs['setup_requires'])
      File "/home/travis/virtualenv/python3.7.1/lib/python3.7/site-packages/setuptools/dist.py", line 426, in fetch_build_eggs
        replace_conflicting=True,
      File "/home/travis/virtualenv/python3.7.1/lib/python3.7/site-packages/pkg_resources/__init__.py", line 854, in resolve
        dist = best[req.key] = env.best_match(req, ws, installer)
      File "/home/travis/virtualenv/python3.7.1/lib/python3.7/site-packages/pkg_resources/__init__.py", line 1126, in best_match
        return self.obtain(req, installer)
      File "/home/travis/virtualenv/python3.7.1/lib/python3.7/site-packages/pkg_resources/__init__.py", line 1138, in obtain
        return installer(requirement)
      File "/home/travis/virtualenv/python3.7.1/lib/python3.7/site-packages/setuptools/dist.py", line 498, in fetch_build_egg
        return cmd.easy_install(req)
      File "/home/travis/virtualenv/python3.7.1/lib/python3.7/site-packages/setuptools/command/easy_install.py", line 672, in easy_install
        return self.install_item(spec, dist.location, tmpdir, deps)
      File "/home/travis/virtualenv/python3.7.1/lib/python3.7/site-packages/setuptools/command/easy_install.py", line 698, in install_item
        dists = self.install_eggs(spec, download, tmpdir)
      File "/home/travis/virtualenv/python3.7.1/lib/python3.7/site-packages/setuptools/command/easy_install.py", line 879, in install_eggs
        return self.build_and_install(setup_script, setup_base)
      File "/home/travis/virtualenv/python3.7.1/lib/python3.7/site-packages/setuptools/command/easy_install.py", line 1118, in build_and_install
        self.run_setup(setup_script, setup_base, args)
      File "/home/travis/virtualenv/python3.7.1/lib/python3.7/site-packages/setuptools/command/easy_install.py", line 1104, in run_setup
        run_setup(setup_script, args)
      File "/home/travis/virtualenv/python3.7.1/lib/python3.7/site-packages/setuptools/sandbox.py", line 257, in run_setup
        raise
      File "/opt/python/3.7.1/lib/python3.7/contextlib.py", line 130, in __exit__
        self.gen.throw(type, value, traceback)
      File "/home/travis/virtualenv/python3.7.1/lib/python3.7/site-packages/setuptools/sandbox.py", line 199, in setup_context
        yield
      File "/opt/python/3.7.1/lib/python3.7/contextlib.py", line 130, in __exit__
        self.gen.throw(type, value, traceback)
      File "/home/travis/virtualenv/python3.7.1/lib/python3.7/site-packages/setuptools/sandbox.py", line 170, in save_modules
        saved_exc.resume()
      File "/home/travis/virtualenv/python3.7.1/lib/python3.7/site-packages/setuptools/sandbox.py", line 145, in resume
        six.reraise(type, exc, self._tb)
      File "/home/travis/virtualenv/python3.7.1/lib/python3.7/site-packages/pkg_resources/_vendor/six.py", line 685, in reraise
        raise value.with_traceback(tb)
      File "/home/travis/virtualenv/python3.7.1/lib/python3.7/site-packages/setuptools/sandbox.py", line 158, in save_modules
        yield saved
      File "/home/travis/virtualenv/python3.7.1/lib/python3.7/site-packages/setuptools/sandbox.py", line 199, in setup_context
        yield
      File "/home/travis/virtualenv/python3.7.1/lib/python3.7/site-packages/setuptools/sandbox.py", line 254, in run_setup
        _execfile(setup_script, ns)
      File "/home/travis/virtualenv/python3.7.1/lib/python3.7/site-packages/setuptools/sandbox.py", line 49, in _execfile
        exec(code, globals, locals)
      File "/tmp/easy_install-01yxk76i/future-0.17.1/setup.py", line 181, in <module>
      File "/opt/python/3.7.1/lib/python3.7/distutils/core.py", line 148, in setup
        dist.run_commands()
      File "/opt/python/3.7.1/lib/python3.7/distutils/dist.py", line 966, in run_commands
        self.run_command(cmd)
      File "/opt/python/3.7.1/lib/python3.7/distutils/dist.py", line 985, in run_command
        cmd_obj.run()
      File "/home/travis/virtualenv/python3.7.1/lib/python3.7/site-packages/setuptools/command/bdist_egg.py", line 209, in run
        os.path.join(archive_root, 'EGG-INFO'), self.zip_safe()
      File "/home/travis/virtualenv/python3.7.1/lib/python3.7/site-packages/setuptools/command/bdist_egg.py", line 245, in zip_safe
        return analyze_egg(self.bdist_dir, self.stubs)
      File "/home/travis/virtualenv/python3.7.1/lib/python3.7/site-packages/setuptools/command/bdist_egg.py", line 355, in analyze_egg
        safe = scan_module(egg_dir, base, name, stubs) and safe
      File "/home/travis/virtualenv/python3.7.1/lib/python3.7/site-packages/setuptools/command/bdist_egg.py", line 395, in scan_module
        symbols = dict.fromkeys(iter_symbols(code))
      File "/home/travis/virtualenv/python3.7.1/lib/python3.7/site-packages/setuptools/command/bdist_egg.py", line 414, in iter_symbols
        for name in code.co_names:
    AttributeError: 'str' object has no attribute 'co_names'
```
diff --git a/.circleci/config.yml b/.circleci/config.yml
index c830a5dd..39ec289e 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -119,8 +119,8 @@ jobs:
     steps:
       - restore_cache:
           keys:
-            - regression-v1-{{ .Revision }}
-            - regression-v1-
+            - regression-v2-{{ .Revision }}
+            - regression-v2-
       - run:
           name: Get truncated BOLD series
           command: |
@@ -143,7 +143,7 @@ jobs:
               echo "Pre-computed masks were cached"
             fi
       - save_cache:
-         key: regression-v1-{{ .Revision }}-{{ epoch }}
+         key: regression-v2-{{ .Revision }}-{{ epoch }}
          paths:
             - /tmp/data
 
@@ -160,9 +160,6 @@ jobs:
             - docker-v1-{{ .Branch }}-
             - docker-v1-master-
             - docker-v1-
-      - restore_cache:
-          keys:
-            - regression-v1-{{ .Revision }}
 
       - checkout:
           path: /tmp/src/niworkflows
@@ -247,7 +244,7 @@ jobs:
             - docker-v1-
       - restore_cache:
           keys:
-            - regression-v1-{{ .Revision }}
+            - regression-v2-{{ .Revision }}
 
       - checkout:
           path: /tmp/src/niworkflows
@@ -295,6 +292,7 @@ jobs:
 
       - run:
           name: Package new masks
+          when: always
           no_output_timeout: 10m
           working_directory: /tmp/data
           command: |
@@ -315,7 +313,7 @@ jobs:
       - run: pyenv local 3.5.2
       - run:
           name: Install build depends
-          command: python3 -m pip install "setuptools>=30.3.0" "pip>=10.0.1" twine docutils
+          command: python3 -m pip install "setuptools>=30.4.0" "pip>=10.0.1" twine docutils
       - run:
           name: Build and check
           command: |
@@ -340,7 +338,7 @@ jobs:
       - run: pyenv local 3.5.2
       - run:
           name: Install build depends
-          command: python3 -m pip install "setuptools>=30.3.0" "pip>=10.0.1" twine docutils
+          command: python3 -m pip install "setuptools>=30.4.0" "pip>=10.0.1" twine docutils
       - run:
           name: Build and check
           command: |
diff --git a/.travis.yml b/.travis.yml
index f6c43f94..de35c320 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -44,8 +44,9 @@ before_install:
   - virtualenv --python=python /tmp/venv
   - source /tmp/venv/bin/activate
   - python --version
-  - pip --version
+  - python -m pip --version
   - python -m pip install --upgrade $INSTALL_DEPENDS
+  - python -m pip --version
   - |
     if [ "$INSTALL_TYPE" == "pip" ]; then
         PACKAGE="."
@@ -64,7 +65,7 @@ install:
     elif [ "$INSTALL_TYPE" == "develop" ]; then
         python setup.py develop
     else
-        pip install $PACKAGE
+        python -m pip install $PACKAGE
     fi
   - |
     INTENDED_VERSION="$(python -c 'import versioneer; print(versioneer.get_version())')"
@@ -78,7 +79,7 @@ install:
   - if [ "$CHECK_TYPE" = "install" ]; then exit 0; fi
 
 before_script:
-  - travis_retry pip install "niworkflows[$CHECK_TYPE]"
+  - travis_retry python -m pip install "niworkflows[$CHECK_TYPE]"
   - |
     if [ "$CHECK_TYPE" == "test" ]; then
         mkdir -p $HOME/.cache/stanford-crn
@@ -99,5 +100,5 @@ script:
     fi
 
 after_script:
-  - pip install codecov
+  - python -m pip install codecov
   - codecov
diff --git a/niworkflows/anat/ants.py b/niworkflows/anat/ants.py
index 7575d718..43a6bfbb 100644
--- a/niworkflows/anat/ants.py
+++ b/niworkflows/anat/ants.py
@@ -11,6 +11,7 @@ from collections import OrderedDict
 from multiprocessing import cpu_count
 from pkg_resources import resource_filename as pkgr_fn
 from packaging.version import parse as parseversion, Version
+from warnings import warn
 
 # nipype
 from nipype.pipeline import engine as pe
@@ -287,6 +288,13 @@ def init_brain_extraction_wf(name='brain_extraction_wf',
             n_iterations=[50] * 5, convergence_threshold=1e-7, shrink_factor=4,
             bspline_fitting_distance=bspline_fitting_distance),
         n_procs=omp_nthreads, name='inu_n4_final', iterfield=['input_image'])
+    if _ants_version and parseversion(_ants_version) >= Version('2.1.0'):
+        inu_n4_final.inputs.rescale_intensities = True
+    else:
+        warn("""\
+Found ANTs version %s, which is too old. Please consider upgrading to 2.1.0 or \
+greater so that the --rescale-intensities option is available with \
+N4BiasFieldCorrection.""" % _ants_version, DeprecationWarning)
 
     # Apply mask
     apply_mask = pe.MapNode(ApplyMask(), iterfield=['in_file'], name='apply_mask')
diff --git a/niworkflows/func/util.py b/niworkflows/func/util.py
index 6e4c0353..590617e7 100644
--- a/niworkflows/func/util.py
+++ b/niworkflows/func/util.py
@@ -13,7 +13,7 @@ from packaging.version import parse as parseversion, Version
 from pkg_resources import resource_filename as pkgr_fn
 
 from nipype.pipeline import engine as pe
-from nipype.interfaces import utility as niu, fsl, afni, ants
+from nipype.interfaces import utility as niu, fsl, afni
 
 from templateflow.api import get as get_template
 
@@ -22,6 +22,7 @@ from ..interfaces.ants import AI
 from ..interfaces.fixes import (
     FixHeaderRegistration as Registration,
     FixHeaderApplyTransforms as ApplyTransforms,
+    FixN4BiasFieldCorrection as N4BiasFieldCorrection,
 )
 from ..interfaces.images import ValidateImage, MatchHeader
 from ..interfaces.masks import SimpleShowMaskRPT
@@ -35,7 +36,7 @@ DEFAULT_MEMORY_MIN_GB = 0.01
 def init_bold_reference_wf(omp_nthreads, bold_file=None, pre_mask=False,
                            name='bold_reference_wf', gen_report=False):
     """
-    This workflow generates reference BOLD images for a series
+    This workflow generates reference BOLD images for a series.
 
     The raw reference image is the target of :abbr:`HMC (head motion correction)`, and a
     contrast-enhanced reference is the subject of distortion correction, as well as
@@ -251,9 +252,10 @@ def init_enhance_and_skullstrip_bold_wf(
                         run_without_submitting=True)
 
     # Run N4 normally, force num_threads=1 for stability (images are small, no need for >1)
-    n4_correct = pe.Node(ants.N4BiasFieldCorrection(
-        dimension=3, copy_header=True, bspline_fitting_distance=200),
+    n4_correct = pe.Node(N4BiasFieldCorrection(
+        dimension=3, copy_header=True, bspline_fitting_distance=200), shrink_factor=2,
         name='n4_correct', n_procs=1)
+    n4_correct.inputs.rescale_intensities = True
 
     # Create a generous BET mask out of the bias-corrected EPI
     skullstrip_first_pass = pe.Node(fsl.BET(frac=0.2, mask=True),
diff --git a/niworkflows/interfaces/fixes.py b/niworkflows/interfaces/fixes.py
index bec16313..9b4f674c 100644
--- a/niworkflows/interfaces/fixes.py
+++ b/niworkflows/interfaces/fixes.py
@@ -1,10 +1,17 @@
-# -*- coding: utf-8 -*-
 # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*-
 # vi: set ft=python sts=4 ts=4 sw=4 et:
 import os
 
+import nibabel as nb
+
+from nipype.interfaces.base import traits
+from nipype.utils.filemanip import fname_presuffix
 from nipype.interfaces.ants.resampling import ApplyTransforms
 from nipype.interfaces.ants.registration import Registration
+from nipype.interfaces.ants.segmentation import (
+    N4BiasFieldCorrection as VanillaN4,
+    N4BiasFieldCorrectionOutputSpec as VanillaN4OutputSpec,
+)
 
 from .. import __version__
 from .utils import _copyxform
@@ -58,3 +65,46 @@ class FixHeaderRegistration(Registration):
                     self.__class__.__name__, __version__))
 
         return runtime
+
+
+class FixN4BiasFieldCorrectionOutputSpec(VanillaN4OutputSpec):
+    negative_values = traits.Bool(False, usedefault=True,
+                                  desc='Indicates whether the input was corrected for '
+                                       'nonpositive values by adding a constant offset.')
+
+
+class FixN4BiasFieldCorrection(VanillaN4):
+    """Checks and fixes for nonpositive values in the input to ``N4BiasFieldCorrection``."""
+    output_spec = FixN4BiasFieldCorrectionOutputSpec
+
+    def __init__(self, *args, **kwargs):
+        """Add a private property to keep the path to the right input."""
+        self._input_image = None
+        self._negative_values = False
+        super(FixN4BiasFieldCorrection, self).__init__(*args, **kwargs)
+
+    def _format_arg(self, name, trait_spec, value):
+        if name == 'input_image':
+            return trait_spec.argstr % self._input_image
+        return super(FixN4BiasFieldCorrection, self)._format_arg(
+            name, trait_spec, value)
+
+    def _parse_inputs(self, skip=None):
+        self._input_image = self.inputs.input_image
+        # Check intensities
+        input_nii = nb.load(self.inputs.input_image)
+        datamin = input_nii.get_fdata().min()
+        if datamin < 0:
+            self._input_image = fname_presuffix(self.inputs.input_image, suffix='_scaled',
+                                                newpath=os.getcwd())
+            data = input_nii.get_fdata() - datamin
+            newnii = input_nii.__class__(data, input_nii.affine, input_nii.header)
+            newnii.to_filename(self._input_image)
+            self._negative_values = True
+
+        return super(FixN4BiasFieldCorrection, self)._parse_inputs(skip=skip)
+
+    def _list_outputs(self):
+        outputs = super(FixN4BiasFieldCorrection, self)._list_outputs()
+        outputs['negative_values'] = self._negative_values
+        return outputs
diff --git a/setup.cfg b/setup.cfg
index f5c312df..68f125f3 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -26,7 +26,7 @@ install_requires =
     scikit-learn >= 0.19
     nibabel >= 2.4.1
     nilearn >= 0.2.6, != 0.5.0, != 0.5.1
-    nipype >= 1.1.6
+    nipype >= 1.2.2
     packaging
     pandas
     pybids ~= 0.9.2
@@ -73,8 +73,8 @@ style =
     flake8 < 3.0
     flake8-putty
 test =
-    pytest
-    pytest-xdist
+    pytest >= 4.4
+    pytest-xdist >= 1.28
     pytest-cov
     coverage
 tests =
['setup.cfg', 'niworkflows/anat/ants.py', 'niworkflows/interfaces/fixes.py', 'niworkflows/func/util.py', '.travis.yml', '.circleci/config.yml']