From 0ecbf8d769b7bcefdd281930322cf3aac75ec275 Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Wed, 4 Mar 2020 22:08:43 -0500 Subject: [PATCH 1/6] CI: Fail test if docs do not build --- .travis.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 622a19db32..b01dd09709 100644 --- a/.travis.yml +++ b/.travis.yml @@ -121,8 +121,7 @@ script: flake8 nibabel elif [ "${CHECK_TYPE}" == "doc" ]; then cd doc - make html; - make doctest; + make html && make doctest elif [ "${CHECK_TYPE}" == "test" ]; then # Change into an innocuous directory and find tests from installation mkdir for_testing From cc20e28c3214b0db92de44060256f5c93bcafbe1 Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Wed, 4 Mar 2020 22:25:29 -0500 Subject: [PATCH 2/6] PY3: Drop Python 2 guards, use runpy instead of exec --- doc/source/conf.py | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/doc/source/conf.py b/doc/source/conf.py index 8225f67e8a..d3e75237ab 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -21,10 +21,8 @@ import sys import os -try: - from configparser import ConfigParser -except ImportError: - from ConfigParser import ConfigParser # PY2 +from runpy import run_path +from configparser import ConfigParser # Check for external Sphinx extensions we depend on try: @@ -51,9 +49,7 @@ # -- General configuration ---------------------------------------------------- # We load the nibabel release info into a dict by explicit execution -rel = {} -with open(os.path.join('..', '..', 'nibabel', 'info.py'), 'r') as fobj: - exec(fobj.read(), rel) +rel = run_path(os.path.join('..', '..', 'nibabel', 'info.py')) # Write long description from info with open('_long_description.inc', 'wt') as fobj: @@ -62,10 +58,7 @@ # Load metadata from setup.cfg config = ConfigParser() config.read(os.path.join('..', '..', 'setup.cfg')) -try: - metadata = config['metadata'] -except AttributeError: - metadata = dict(config.items('metadata')) # PY2 +metadata = config['metadata'] # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones. From 03c6c31f52068465e21981b885983ee4b5385ec2 Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Wed, 4 Mar 2020 22:25:36 -0500 Subject: [PATCH 3/6] DOC: Attempt to find versioneer version when building docs --- doc/tools/build_modref_templates.py | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/doc/tools/build_modref_templates.py b/doc/tools/build_modref_templates.py index 3b988a2135..c3d08ef0b4 100755 --- a/doc/tools/build_modref_templates.py +++ b/doc/tools/build_modref_templates.py @@ -5,6 +5,7 @@ # stdlib imports import sys import re +import os from os.path import join as pjoin # local imports @@ -48,12 +49,25 @@ def abort(error): installed_version = V(module.__version__) - info_file = pjoin('..', package, 'info.py') - info_lines = open(info_file).readlines() - source_version = '.'.join([v.split('=')[1].strip(" '\n.") - for v in info_lines if re.match( - '^_version_(major|minor|micro|extra)', v - )]) + version_file = pjoin('..', package, '_version.py') + source_version = None + if os.path.exists(version_file): + # Versioneer + from runpy import run_path + try: + source_version = run_path(version_file)['get_versions']()['version'] + except (FileNotFoundError, KeyError): + pass + if source_version == '0+unknown': + source_version = None + if source_version is None: + # Legacy fall-back + info_file = pjoin('..', package, 'info.py') + info_lines = open(info_file).readlines() + source_version = '.'.join([v.split('=')[1].strip(" '\n.") + for v in info_lines if re.match( + '^_version_(major|minor|micro|extra)', v + )]) print('***', source_version) if source_version != installed_version: From 92dc3f1299c56b9de44aa5375e2e816828c158b0 Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Thu, 5 Mar 2020 08:16:57 -0500 Subject: [PATCH 4/6] DOC: Skip py3k --- doc/tools/build_modref_templates.py | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/tools/build_modref_templates.py b/doc/tools/build_modref_templates.py index c3d08ef0b4..da752b6c42 100755 --- a/doc/tools/build_modref_templates.py +++ b/doc/tools/build_modref_templates.py @@ -82,6 +82,7 @@ def abort(error): r'.*test.*$', r'\.info.*$', r'\.pkg_info.*$', + r'\.py3k.*$', ] docwriter.write_api_docs(outdir) docwriter.write_index(outdir, 'index', relative_to=outdir) From b57cf1bbeec3f041c55b579190aa57289ac90445 Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Thu, 5 Mar 2020 08:18:17 -0500 Subject: [PATCH 5/6] DOC: Fix "``s" pattern in changelog --- Changelog | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Changelog b/Changelog index c79a23f895..1209447219 100644 --- a/Changelog +++ b/Changelog @@ -79,7 +79,7 @@ Enhancements Bug fixes --------- -* Sliced ``Tractogram``s no longer ``apply_affine`` to the original +* Sliced ``Tractogram``\s no longer ``apply_affine`` to the original ``Tractogram``'s streamlines. (pr/811) (MC, reviewed by Serge Koudoro, Philippe Poulin, CM, MB) * Change strings with invalid escapes to raw strings (pr/827) (EL, reviewed @@ -98,7 +98,7 @@ Maintenance API changes and deprecations ---------------------------- * Fully remove deprecated ``checkwarns`` and ``minc`` modules. (pr/852) (CM) -* The ``keep_file_open`` argument to file load operations and ``ArrayProxy``s +* The ``keep_file_open`` argument to file load operations and ``ArrayProxy``\s no longer acccepts the value ``"auto"``, raising a ``ValueError``. (pr/852) (CM) * Deprecate ``ArraySequence.data`` in favor of ``ArraySequence.get_data()``, @@ -420,7 +420,7 @@ New features * Support for MRtrix TCK streamlines file format (pr/486) (MC, reviewed by MB, Arnaud Bore, J-Donald Tournier, Jean-Christophe Houde) * Added ``get_fdata()`` as default method to retrieve scaled floating point - data from ``DataobjImage``s (pr/551) (MB, reviewed by CM, SG) + data from ``DataobjImage``\s (pr/551) (MB, reviewed by CM, SG) Enhancements ------------ From 4ac98210d0ff3887746324dfbab8360103aec250 Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Thu, 5 Mar 2020 08:19:08 -0500 Subject: [PATCH 6/6] DOC: Address warnings and improve formatting --- nibabel/affines.py | 2 +- nibabel/brikhead.py | 5 +++-- nibabel/cifti2/__init__.py | 2 +- nibabel/cifti2/cifti2.py | 6 +++--- nibabel/cifti2/cifti2_axes.py | 4 ++-- nibabel/gifti/gifti.py | 15 +++++++++------ nibabel/nifti1.py | 24 ++++++++++++------------ nibabel/streamlines/tck.py | 10 ++++------ nibabel/streamlines/tractogram.py | 16 ++++++++-------- 9 files changed, 43 insertions(+), 41 deletions(-) diff --git a/nibabel/affines.py b/nibabel/affines.py index 9a37cc9e49..c2b2a3b1d0 100644 --- a/nibabel/affines.py +++ b/nibabel/affines.py @@ -306,7 +306,7 @@ def obliquity(affine): This implementation is inspired by `AFNI's implementation `_. For further details about *obliquity*, check `AFNI's documentation - _. + `_. Parameters ---------- diff --git a/nibabel/brikhead.py b/nibabel/brikhead.py index 41bfc54c4d..13bb999f2d 100644 --- a/nibabel/brikhead.py +++ b/nibabel/brikhead.py @@ -250,7 +250,7 @@ def __init__(self, file_like, header, mmap=True, keep_file_open=None): a new file handle is created every time the image is accessed. If ``file_like`` refers to an open file handle, this setting has no effect. The default value (``None``) will result in the value of - ``nibabel.arrayproxy.KEEP_FILE_OPEN_DEFAULT` being used. + ``nibabel.arrayproxy.KEEP_FILE_OPEN_DEFAULT`` being used. """ super(AFNIArrayProxy, self).__init__(file_like, header, @@ -533,7 +533,7 @@ def from_file_map(klass, file_map, mmap=True, keep_file_open=None): a new file handle is created every time the image is accessed. If ``file_like`` refers to an open file handle, this setting has no effect. The default value (``None``) will result in the value of - ``nibabel.arrayproxy.KEEP_FILE_OPEN_DEFAULT` being used. + ``nibabel.arrayproxy.KEEP_FILE_OPEN_DEFAULT`` being used. """ with file_map['header'].get_prepare_fileobj('rt') as hdr_fobj: hdr = klass.header_class.from_fileobj(hdr_fobj) @@ -553,6 +553,7 @@ def filespec_to_file_map(klass, filespec): afni.nimh.nih.gov/pub/dist/doc/program_help/README.compression.html. Thus, if you have AFNI files my_image.HEAD and my_image.BRIK.gz and you want to load the AFNI BRIK / HEAD pair, you can specify: + * The HEAD filename - e.g., my_image.HEAD * The BRIK filename w/o compressed extension - e.g., my_image.BRIK * The full BRIK filename - e.g., my_image.BRIK.gz diff --git a/nibabel/cifti2/__init__.py b/nibabel/cifti2/__init__.py index 9dc6dd68b8..c0933c9041 100644 --- a/nibabel/cifti2/__init__.py +++ b/nibabel/cifti2/__init__.py @@ -26,4 +26,4 @@ Cifti2TransformationMatrixVoxelIndicesIJKtoXYZ, Cifti2Vertices, Cifti2Volume, CIFTI_BRAIN_STRUCTURES, Cifti2HeaderError, CIFTI_MODEL_TYPES, load, save) -from .cifti2_axes import (Axis, BrainModelAxis, ParcelsAxis, SeriesAxis, LabelAxis, ScalarAxis) \ No newline at end of file +from .cifti2_axes import (Axis, BrainModelAxis, ParcelsAxis, SeriesAxis, LabelAxis, ScalarAxis) diff --git a/nibabel/cifti2/cifti2.py b/nibabel/cifti2/cifti2.py index 1a5307eba5..9bac6a0e5b 100644 --- a/nibabel/cifti2/cifti2.py +++ b/nibabel/cifti2/cifti2.py @@ -172,7 +172,7 @@ def _to_xml_element(self): class Cifti2LabelTable(xml.XmlSerializable, MutableMapping): - """ CIFTI-2 label table: a sequence of ``Cifti2Label``s + """ CIFTI-2 label table: a sequence of ``Cifti2Label``\s * Description - Used by NamedMap when IndicesMapToDataType is "CIFTI_INDEX_TYPE_LABELS" in order to associate names and display colors @@ -927,8 +927,8 @@ class Cifti2MatrixIndicesMap(xml.XmlSerializable, MutableSequence): * Text Content: [NA] * Parent Element - Matrix - Attribute - --------- + Attributes + ---------- applies_to_matrix_dimension : list of ints Dimensions of this matrix that follow this mapping indices_map_to_data_type : str one of CIFTI_MAP_TYPES diff --git a/nibabel/cifti2/cifti2_axes.py b/nibabel/cifti2/cifti2_axes.py index 05ab84e6ab..c4c47007db 100644 --- a/nibabel/cifti2/cifti2_axes.py +++ b/nibabel/cifti2/cifti2_axes.py @@ -23,7 +23,7 @@ (except for SeriesAxis objects, which have to remain monotonically increasing or decreasing). Creating new CIFTI-2 axes ------------------------ +------------------------- New Axis objects can be constructed by providing a description for what is contained in each row/column of the described tensor. For each Axis sub-class this descriptor is: @@ -250,7 +250,7 @@ def __init__(self, name, voxel=None, vertex=None, affine=None, factory methods: - :py:meth:`~BrainModelAxis.from_mask`: creates surface or volumetric BrainModelAxis axis - from respectively 1D or 3D masks + from respectively 1D or 3D masks - :py:meth:`~BrainModelAxis.from_surface`: creates a surface BrainModelAxis axis The resulting BrainModelAxis axes can be concatenated by adding them together. diff --git a/nibabel/gifti/gifti.py b/nibabel/gifti/gifti.py index b423ec48dd..0497556a2d 100644 --- a/nibabel/gifti/gifti.py +++ b/nibabel/gifti/gifti.py @@ -207,18 +207,21 @@ class GiftiCoordSystem(xml.XmlSerializable): Attributes ---------- dataspace : int - From the spec: "Contains the stereotaxic space of a DataArray's data + From the spec: Contains the stereotaxic space of a DataArray's data prior to application of the transformation matrix. The stereotaxic space should be one of: - NIFTI_XFORM_UNKNOWN - NIFTI_XFORM_SCANNER_ANAT - NIFTI_XFORM_ALIGNED_ANAT - NIFTI_XFORM_TALAIRACH - NIFTI_XFORM_MNI_152" + + - NIFTI_XFORM_UNKNOWN + - NIFTI_XFORM_SCANNER_ANAT + - NIFTI_XFORM_ALIGNED_ANAT + - NIFTI_XFORM_TALAIRACH + - NIFTI_XFORM_MNI_152 + xformspace : int Spec: "Contains the stereotaxic space of a DataArray's data after application of the transformation matrix. See the DataSpace element for a list of stereotaxic spaces." + xform : array-like shape (4, 4) Affine transformation matrix """ diff --git a/nibabel/nifti1.py b/nibabel/nifti1.py index 3979f5b96c..352837f86e 100644 --- a/nibabel/nifti1.py +++ b/nibabel/nifti1.py @@ -1775,18 +1775,18 @@ def __init__(self, dataobj, affine, header=None, self._affine2header() # Copy docstring __init__.__doc__ = analyze.AnalyzeImage.__init__.__doc__ + ''' - Notes - ----- - - If both a `header` and an `affine` are specified, and the `affine` does - not match the affine that is in the `header`, the `affine` will be used, - but the ``sform_code`` and ``qform_code`` fields in the header will be - re-initialised to their default values. This is performed on the basis - that, if you are changing the affine, you are likely to be changing the - space to which the affine is pointing. The :meth:`set_sform` and - :meth:`set_qform` methods can be used to update the codes after an image - has been created - see those methods, and the :ref:`manual - ` for more details. ''' + Notes + ----- + + If both a `header` and an `affine` are specified, and the `affine` does + not match the affine that is in the `header`, the `affine` will be used, + but the ``sform_code`` and ``qform_code`` fields in the header will be + re-initialised to their default values. This is performed on the basis + that, if you are changing the affine, you are likely to be changing the + space to which the affine is pointing. The :meth:`set_sform` and + :meth:`set_qform` methods can be used to update the codes after an image + has been created - see those methods, and the :ref:`manual + ` for more details. ''' def update_header(self): ''' Harmonize header with image data and affine diff --git a/nibabel/streamlines/tck.py b/nibabel/streamlines/tck.py index ffcd2e437a..5decf9e831 100644 --- a/nibabel/streamlines/tck.py +++ b/nibabel/streamlines/tck.py @@ -30,9 +30,9 @@ class TckFile(TractogramFile): ----- MRtrix (so its file format: TCK) considers streamlines coordinates to be in world space (RAS+ and mm space). MRtrix refers to that space - as the "real" or "scanner" space [1]_. + as the "real" or "scanner" space [#]_. - Moreover, when streamlines are mapped back to voxel space [2]_, a + Moreover, when streamlines are mapped back to voxel space [#]_, a streamline point located at an integer coordinate (i,j,k) is considered to be at the center of the corresponding voxel. This is in contrast with TRK's internal convention where it would have referred to a corner. @@ -40,10 +40,8 @@ class TckFile(TractogramFile): NiBabel's streamlines internal representation follows the same convention as MRtrix. - References - ---------- - [1] http://www.nitrc.org/pipermail/mrtrix-discussion/2014-January/000859.html - [2] http://nipy.org/nibabel/coordinate_systems.html#voxel-coordinates-are-in-voxel-space + .. [#] http://www.nitrc.org/pipermail/mrtrix-discussion/2014-January/000859.html + .. [#] http://nipy.org/nibabel/coordinate_systems.html#voxel-coordinates-are-in-voxel-space """ # Constants MAGIC_NUMBER = "mrtrix tracks" diff --git a/nibabel/streamlines/tractogram.py b/nibabel/streamlines/tractogram.py index 3d01d8426e..e8ecbac4ff 100644 --- a/nibabel/streamlines/tractogram.py +++ b/nibabel/streamlines/tractogram.py @@ -263,9 +263,9 @@ class Tractogram(object): choice as long as you provide the correct `affine_to_rasmm` matrix, at construction time. When applied to streamlines coordinates, that transformation matrix should bring the streamlines back to world space - (RAS+ and mm space) [1]_. + (RAS+ and mm space) [#]_. - Moreover, when streamlines are mapped back to voxel space [2]_, a + Moreover, when streamlines are mapped back to voxel space [#]_, a streamline point located at an integer coordinate (i,j,k) is considered to be at the center of the corresponding voxel. This is in contrast with other conventions where it might have referred to a corner. @@ -292,8 +292,8 @@ class Tractogram(object): References ---------- - [1] http://nipy.org/nibabel/coordinate_systems.html#naming-reference-spaces - [2] http://nipy.org/nibabel/coordinate_systems.html#voxel-coordinates-are-in-voxel-space + .. [#] http://nipy.org/nibabel/coordinate_systems.html#naming-reference-spaces + .. [#] http://nipy.org/nibabel/coordinate_systems.html#voxel-coordinates-are-in-voxel-space """ def __init__(self, streamlines=None, data_per_streamline=None, @@ -515,9 +515,9 @@ class LazyTractogram(Tractogram): choice as long as you provide the correct `affine_to_rasmm` matrix, at construction time. When applied to streamlines coordinates, that transformation matrix should bring the streamlines back to world space - (RAS+ and mm space) [1]_. + (RAS+ and mm space) [#]_. - Moreover, when streamlines are mapped back to voxel space [2]_, a + Moreover, when streamlines are mapped back to voxel space [#]_, a streamline point located at an integer coordinate (i,j,k) is considered to be at the center of the corresponding voxel. This is in contrast with other conventions where it might have referred to a corner. @@ -553,8 +553,8 @@ class LazyTractogram(Tractogram): References ---------- - [1] http://nipy.org/nibabel/coordinate_systems.html#naming-reference-spaces - [2] http://nipy.org/nibabel/coordinate_systems.html#voxel-coordinates-are-in-voxel-space + .. [#] http://nipy.org/nibabel/coordinate_systems.html#naming-reference-spaces + .. [#] http://nipy.org/nibabel/coordinate_systems.html#voxel-coordinates-are-in-voxel-space """ def __init__(self, streamlines=None, data_per_streamline=None,