Skip to content
Snippets Groups Projects
Commit cb422081 authored by Paul McCarthy's avatar Paul McCarthy :mountain_bicyclist:
Browse files

Merge branch 'bf/typo' into 'master'

BF,RF: Fix a few bugs, adjust `evalHeader` routine

See merge request !41
parents 42192593 1f1b86ea
No related branches found
No related tags found
1 merge request!41BF,RF: Fix a few bugs, adjust `evalHeader` routine
Pipeline #27048 passed
......@@ -2,6 +2,16 @@
=====================
0.14.1 (Friday 31st January 2025)
---------------------------------
* Fixed a few bugs introduced in the previous release.
* Adjusted the ``evalHeader`` routine - now it compares ``dim`` and ``pixdim``
for all valid dimensions by default. The ``alldims`` parameter has been
replaced with a ``ndims`` parameter, allowing the number of dimensions to
be set (e.g. when you only want to compare the first three dimensions).
0.14.0 (Friday 31st January 2025)
---------------------------------
......
......@@ -5,7 +5,7 @@
# Author: Paul McCarthy <pauldmccarthy@gmail.com>
#
__version__ = '0.14.0'
__version__ = '0.14.1'
"""The pyfeeds version number. """
......
......@@ -45,10 +45,10 @@ def tempdir():
prevdir = os.getcwd()
with tempfile.TemporaryDirectory(delete=True) as td:
with tempfile.TemporaryDirectory() as td:
try:
os.chdir(testdir)
yield td.name
os.chdir(td)
yield td
finally:
os.chdir(prevdir)
......
......@@ -413,22 +413,24 @@ def loadImage(pyf, filename):
return pyf.imageCache[filename]
else:
img = nib.load(filename)
if isinstance(image, nib.Nifti1Image):
data = np.asanyarray(image.dataobj)
if isinstance(img, nib.Nifti1Image):
data = np.asanyarray(img.dataobj)
else:
data = None
return img, data
def evalHeader(testfile, benchmark, alldims=True, pyf=None):
def evalHeader(testfile, benchmark, ndims=None, pyf=None):
"""Evaluation routine which compares the header fields of two NIFTI
images.
images. By default the dim/pixdim values for every dimension are compared,
but the ``ndims`` argument can be used if you only want to compare the
first three dimensions for instance.
Returns 0 if they all match, 1 otherwise.
"""
img1 = loadImage(testfile)[0]
img2 = loadImage(benchmark)[0]
img1 = loadImage(pyf, testfile)[0]
img2 = loadImage(pyf, benchmark)[0]
hdr1 = img1.header
hdr2 = img2.header
fields = ['dim', 'pixdim', 'intent_code',
......@@ -437,14 +439,17 @@ def evalHeader(testfile, benchmark, alldims=True, pyf=None):
'qoffset_x', 'qoffset_y', 'qoffset_z',
'srow_x', 'srow_y', 'srow_z']
if ndims is None:
ndims = max(img1.header['dim'][0],
img2.header['dim'][0])
for f in fields:
f1 = hdr1[f]
f2 = hdr2[f]
if (not alldims) and (f in ('dim', 'pixdim')):
ndim = img1.header['dim'][0]
f1 = f1[:ndim + 1]
f2 = f2[:ndim + 1]
if f in ('dim', 'pixdim'):
f1 = f1[:ndims + 1]
f2 = f2[:ndims + 1]
if not np.all(np.isclose(f1, f2)):
return 1
......@@ -453,14 +458,8 @@ def evalHeader(testfile, benchmark, alldims=True, pyf=None):
def evalHeaderRestrictDims(testfile, benchmark, pyf=None):
"""Evaluation routine which compares the header fields of two NIFTI
images. For the `dim` and `pixdim` fields, only the entries which
are expected to be valid (e.g. `dim1`, `dim2`, and `dim3` for a 3D image)
are compared.
Returns 0 if they all match, 1 otherwise.
"""
return evalHeader(testfile, benchmark, alldims=False, pyf=pyf)
"""Legacy alias for ``evalHeader``. """
return evalHeader(testfile, benchmark, pyf=pyf)
def evalImage(testfile, benchmark, pyf=None):
......
......@@ -77,7 +77,7 @@ class ImageCache:
returned value will be ``None``.
"""
imagefile = op.realpath(op.abspath(imagefile))
imagefile = str(op.realpath(op.abspath(imagefile)))
image = self.__images.get(imagefile, None)
if image is not None:
......@@ -108,7 +108,7 @@ class ImageCache:
# it in this way because all keys
# passed to __getitem__ get
# transformed in the same way.
imagefile = op.realpath(op.abspath(imagefile))
imagefile = str(op.realpath(op.abspath(imagefile)))
imagesize = size(image)
self.__images[ imagefile] = image, data
self.__imagesizes[imagefile] = imagesize
......
......@@ -9,8 +9,6 @@
import os
import sys
import os.path as op
import contextlib
import tempfile
from io import StringIO
......@@ -61,17 +59,6 @@ class CaptureStdout(object):
return self.__mock_stderr.read()
@contextlib.contextmanager
def tempdir():
prevdir = os.getcwd()
with tempfile.TemporaryDirectory() as td:
try:
os.chdir(td)
yield td
finally:
os.chdir(prevdir)
def makepaths(paths):
for path in paths:
dirname = op.dirname(path)
......
......@@ -13,7 +13,7 @@ from unittest import mock
import pyfeeds.main as main
from pyfeeds.tests import tempdir
from pyfeeds.common import tempdir
def test_loadPyfeedsConfig():
......
......@@ -11,9 +11,10 @@ import os.path as op
import numpy as np
import nibabel as nib
from . import tempdir, makepaths, maketest, makepyfeeds, CaptureStdout
from . import makepaths, maketest, makepyfeeds, CaptureStdout
from pyfeeds import testing, evaluate
from pyfeeds.common import tempdir
def test_evaluateTestAgainstBenchmark():
......@@ -79,6 +80,9 @@ def test_evalVectorImage():
assert evaluate.evalVectorImage(fname1, fname1, pyf=pyf) == 0
assert evaluate.evalVectorImage(fname2, fname2, pyf=pyf) == 0
assert evaluate.evalVectorImage(fname1, fname2, pyf=pyf) != 0
assert evaluate.evalVectorImage(fname1, fname1) == 0
assert evaluate.evalVectorImage(fname2, fname2) == 0
assert evaluate.evalVectorImage(fname1, fname2) != 0
def test_evalImage():
......@@ -98,3 +102,102 @@ def test_evalImage():
assert evaluate.evalImage(fname1, fname1, pyf=pyf) == 0
assert evaluate.evalImage(fname2, fname2, pyf=pyf) == 0
assert evaluate.evalImage(fname1, fname2, pyf=pyf) != 0
assert evaluate.evalImage(fname1, fname1) == 0
assert evaluate.evalImage(fname2, fname2) == 0
assert evaluate.evalImage(fname1, fname2) != 0
def test_evalHeader():
arr1 = -1 + 2 * np.random.random((10, 10, 10, 10))
arr2 = -1 + 2 * np.random.random((10, 10, 10, 10))
arr3 = -1 + 2 * np.random.random((10, 10, 10, 20))
arr4 = -1 + 2 * np.random.random(( 5, 5, 5, 20))
with tempdir():
pyf = makepyfeeds()
fname1 = 'image1.nii.gz'
fname2 = 'image2.nii.gz'
fname3 = 'image3.nii.gz'
fname4 = 'image4.nii.gz'
nib.Nifti1Image(arr1, np.eye(4)).to_filename(fname1)
nib.Nifti1Image(arr2, np.eye(4)).to_filename(fname2)
nib.Nifti1Image(arr3, np.eye(4)).to_filename(fname3)
nib.Nifti1Image(arr4, np.eye(4)).to_filename(fname4)
assert evaluate.evalHeader(fname1, fname1, pyf=pyf) == 0
assert evaluate.evalHeader(fname2, fname2, pyf=pyf) == 0
assert evaluate.evalHeader(fname3, fname3, pyf=pyf) == 0
assert evaluate.evalHeader(fname4, fname4, pyf=pyf) == 0
assert evaluate.evalHeader(fname1, fname1) == 0
assert evaluate.evalHeader(fname2, fname2) == 0
assert evaluate.evalHeader(fname3, fname3) == 0
assert evaluate.evalHeader(fname4, fname4) == 0
assert evaluate.evalHeader(fname1, fname2) == 0
assert evaluate.evalHeader(fname1, fname3) != 0
assert evaluate.evalHeader(fname1, fname4) != 0
assert evaluate.evalHeader(fname1, fname3, ndims=3) == 0
assert evaluate.evalHeader(fname3, fname4) != 0
assert evaluate.evalHeader(fname3, fname4, ndims=3) != 0
assert evaluate.evalHeaderRestrictDims(fname1, fname2, pyf=pyf) == 0
assert evaluate.evalHeaderRestrictDims(fname1, fname3, pyf=pyf) != 0
assert evaluate.evalHeaderRestrictDims(fname1, fname2) == 0
assert evaluate.evalHeaderRestrictDims(fname1, fname3) != 0
def test_evalImageMaxDiff():
arr1 = np.zeros((10, 10, 10))
arr2 = np.zeros((10, 10, 10))
arr1[0, 0, 0] = 100
with tempdir():
pyf = makepyfeeds()
fname1 = 'image1.nii.gz'
fname2 = 'image2.nii.gz'
nib.Nifti1Image(arr1, np.eye(4)).to_filename(fname1)
nib.Nifti1Image(arr2, np.eye(4)).to_filename(fname2)
assert evaluate.evalImageMaxDiff(fname1, fname1, pyf=pyf) == 0
assert evaluate.evalImageMaxDiff(fname1, fname1) == 0
assert evaluate.evalImageMaxDiff(fname1, fname2) == 100
def test_evalNumericalText():
arr1 = np.random.random(100)
arr2 = np.random.random(100) * 4
with tempdir():
pyf = makepyfeeds()
fname1 = 'data1.txt'
fname2 = 'data2.txt'
np.savetxt(fname1, arr1)
np.savetxt(fname2, arr2)
assert evaluate.evalNumericalText(fname1, fname1, pyf=pyf) == 0
assert evaluate.evalNumericalText(fname1, fname1) == 0
assert evaluate.evalNumericalText(fname1, fname2) != 0
def test_evalMD5():
arr1 = np.random.random(100)
arr2 = np.random.random(100) * 4
with tempdir():
pyf = makepyfeeds()
fname1 = 'data1.txt'
fname2 = 'data2.txt'
np.savetxt(fname1, arr1)
np.savetxt(fname2, arr2)
assert evaluate.evalMD5(fname1, fname1, pyf=pyf) == 0
assert evaluate.evalMD5(fname1, fname1) == 0
assert evaluate.evalMD5(fname1, fname2) != 0
......@@ -13,8 +13,9 @@ import os.path as op
import time
from pyfeeds import hashing, testing
from pyfeeds.common import tempdir
from . import CaptureStdout, makepyfeeds, maketest, makepaths, tempdir
from . import CaptureStdout, makepyfeeds, maketest, makepaths
def test_genHashes():
......
......@@ -10,9 +10,10 @@ import os
import datetime
import os.path as op
from . import tempdir, makepaths, maketest, makepyfeeds, CaptureStdout
from . import makepaths, maketest, makepyfeeds, CaptureStdout
from pyfeeds import testing
from pyfeeds.common import tempdir
def test_findTestDirs():
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment