Skip to content

FIX: Set TRK byte order to little-endian before filling values #782

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Aug 2, 2019

Conversation

effigies
Copy link
Member

TRK header creation is done such that the little-endian byte order is enforced after some default values are generated.

This change sets the byte order before any non-zero values are set.

Fixes #775.

@yarikoptic @sanjayankur31 If either of you has a minute to test these changes on an s390x, it would be most appreciated.

@effigies effigies added this to the 2.5.0 milestone Jul 30, 2019
@yarikoptic
Copy link
Member

Doctests fail on Travis now

Expected:
    dtype('<i2')
Got:
    '<i2'

@effigies
Copy link
Member Author

Ah right.

@effigies effigies force-pushed the fix/s390x_trk_bug branch from 13707d3 to 2434adb Compare July 30, 2019 11:43
@yarikoptic
Copy link
Member

yarikoptic commented Jul 30, 2019

This resolves the issue for me, but while testing ran into another one for a doctest of nibabel.brikhead.AFNIHeader.get_data_scaling . I will do a thorough sweep and report separately in not a fluke
(sid_s390x-dchroot)yoh@zelenka:~/nibabel$ python -m nose -s -v --with-doctest  /home/yoh/nibabel/nibabel/tests/test_scripts.py nibabel/brikhead.py
nibabel.tests.test_scripts.test_nib_ls ... ok
nibabel.tests.test_scripts.test_nib_ls(['-H', 'dim,bitpix'], ' \\[  4 128  96  24   2   1   1   1\\] 16') ... ok
nibabel.tests.test_scripts.test_nib_ls(['-c'], '', ' !1030 uniques. Use --all-counts') ... ok
nibabel.tests.test_scripts.test_nib_ls(['-c', '--all-counts'], '', ' 2:3 3:2 4:1 5:1.*') ... ok
nibabel.tests.test_scripts.test_nib_ls(['-c', '-s', '--all-counts'], '', ' \\[229725\\] \\[2, 1.2e\\+03\\] 2:3 3:2 4:1 5:1.*') ... ok
nibabel.tests.test_scripts.test_nib_ls(['-c', '-s', '-z', '--all-counts'], '', ' \\[589824\\] \\[0, 1.2e\\+03\\] 0:360099 2:3 3:2 4:1 5:1.*') ... ok
nibabel.tests.test_scripts.test_nib_ls_multiple ... SKIP: For the other tests should be able to load MINC files
nibabel.tests.test_scripts.test_help ... ok
nibabel.tests.test_scripts.test_nib_diff ... ok
nibabel.tests.test_scripts.test_nib_nifti_dx ... ok
nibabel.tests.test_scripts.test_parrec2nii ... ok
nibabel.tests.test_scripts.test_parrec2nii_with_data ... SKIP: Skipping test: test_parrec2nii_with_data: Need files in /home/yoh/nibabel/nibabel-data/nitest-balls1 for these tests
nibabel.tests.test_scripts.test_nib_trk2tck ... ok
nibabel.tests.test_scripts.test_nib_tck2trk ... ok
Doctest: nibabel.brikhead.AFNIHeader.__init__ ... ok
Doctest: nibabel.brikhead.AFNIHeader.get_affine ... ok
Doctest: nibabel.brikhead.AFNIHeader.get_data_scaling ... FAIL
Doctest: nibabel.brikhead.AFNIHeader.get_volume_labels ... ok
Doctest: nibabel.brikhead.AFNIImage ... ok
Doctest: nibabel.brikhead._unpack_var ... ok
Doctest: nibabel.brikhead.parse_AFNI_header ... ok

======================================================================
FAIL: Doctest: nibabel.brikhead.AFNIHeader.get_data_scaling
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python2.7/doctest.py", line 2224, in runTest
    raise self.failureException(self.format_failure(new.getvalue()))
AssertionError: Failed doctest test for nibabel.brikhead.AFNIHeader.get_data_scaling
  File "/home/yoh/nibabel/nibabel/brikhead.py", line 414, in get_data_scaling

----------------------------------------------------------------------
File "/home/yoh/nibabel/nibabel/brikhead.py", line 422, in nibabel.brikhead.AFNIHeader.get_data_scaling
Failed example:
    header.get_data_scaling()
Expected:
    array([  3.88336300e-08])
Got:
    array([3.883363e-08])

@effigies
Copy link
Member Author

What version of numpy is installed there?

@yarikoptic
Copy link
Member

that issue is unrelated so I will continue in #784

@effigies
Copy link
Member Author

Thanks for checking, Yarik.

@MarcCote @matthew-brett Just as a sanity check, does this make sense to you?

@codecov
Copy link

codecov bot commented Jul 31, 2019

Codecov Report

Merging #782 into master will increase coverage by <.01%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #782      +/-   ##
==========================================
+ Coverage   89.99%   89.99%   +<.01%     
==========================================
  Files          94       94              
  Lines       12009    12015       +6     
  Branches     2133     2134       +1     
==========================================
+ Hits        10807    10813       +6     
  Misses        859      859              
  Partials      343      343
Impacted Files Coverage Δ
nibabel/brikhead.py 97.48% <ø> (ø) ⬆️
nibabel/streamlines/trk.py 94.42% <100%> (+0.11%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update b356a64...927b6ce. Read the comment docs.

@@ -395,8 +396,7 @@ def save(self, fileobj):
pointing to TRK file (and ready to write from the beginning
of the TRK header data).
"""
# Enforce little-endian byte order for header
header = self._default_structarr().newbyteorder('<')
header = self._default_structarr()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know it ends up the same, but maybe cleaner keeping the endian change in the save function with

self._default_structarr().newbyteorder('<').byteswap()

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't that fail on little endian systems?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry - yes. Then maybe, for clarity, add an endianness=None kwarg to _default_structarr, and pass < from save.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That works. I followed the template in WrapStruct.default_structarr.

Let me know if you have any further comments.

@@ -283,10 +286,10 @@ def _default_structarr(cls):
return st_arr

@classmethod
def create_empty_header(cls):
def create_empty_header(cls, endianness=None):
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added this in passing, since it's the only other place _default_structarr is being called.

@effigies
Copy link
Member Author

@yarikoptic If you get a chance, could you verify that this still works on the s390x?

@yarikoptic
Copy link
Member

no good
(sid_s390x-dchroot)yoh@zelenka:~/nibabel$ git show | head
commit 3737e617d25ea1aadbd481f432ddd1a3d657a25b
Author: Christopher J. Markiewicz <[email protected]>
Date:   Wed Jul 31 07:18:24 2019 -0400

    ENH: Pass endianness as parameter to TrkFile._default_structarr

diff --git a/nibabel/streamlines/trk.py b/nibabel/streamlines/trk.py
index 3100dfe5..e43b760c 100644
--- a/nibabel/streamlines/trk.py
+++ b/nibabel/streamlines/trk.py
(sid_s390x-dchroot)yoh@zelenka:~/nibabel$ python -m nose -s -v --with-doctest  /home/yoh/nibabel/nibabel/tests/test_scripts.py:test_nib_tck2trk
nibabel.tests.test_scripts.test_nib_tck2trk ... ERROR

======================================================================
ERROR: nibabel.tests.test_scripts.test_nib_tck2trk
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python2.7/dist-packages/nose/case.py", line 197, in runTest
    self.test(*self.arg)
  File "/home/yoh/nibabel/nibabel/tests/test_scripts.py", line 488, in test_nib_tck2trk
    trk = nib.streamlines.load(standard_trk)
  File "/home/yoh/nibabel/nibabel/streamlines/__init__.py", line 96, in load
    return tractogram_file.load(fileobj, lazy_load=lazy_load)
  File "/home/yoh/nibabel/nibabel/streamlines/trk.py", line 375, in load
    arr_seqs = create_arraysequences_from_generator(trk_reader, n=3)
  File "/home/yoh/nibabel/nibabel/streamlines/array_sequence.py", line 387, in create_arraysequences_from_generator
    for data in gen:
  File "/home/yoh/nibabel/nibabel/streamlines/trk.py", line 686, in _read
    buffer=f.read(nb_pts * pts_and_scalars_size))
TypeError: buffer is too small for requested array

----------------------------------------------------------------------
Ran 1 test in 0.172s

FAILED (errors=1)

@effigies effigies force-pushed the fix/s390x_trk_bug branch from 3737e61 to 927b6ce Compare July 31, 2019 17:31
@effigies
Copy link
Member Author

@yarikoptic Woops. Forgot to actually apply the endianness. Another try?

@effigies
Copy link
Member Author

effigies commented Aug 1, 2019

@yarikoptic Just a bump on this.

@effigies
Copy link
Member Author

effigies commented Aug 1, 2019

Not sure if that's the output you meant to paste...

@yarikoptic
Copy link
Member

ha ha -- indeed... "too fast" or "too tired"... removed -- thanks for letting me know. the test has passed ;-) I repeat -- the test has passed! ;)

@effigies
Copy link
Member Author

effigies commented Aug 1, 2019

Sounds good. Thanks for confirmation.

@matthew-brett Any remaining thoughts?

@matthew-brett
Copy link
Member

Looks fine to me, thanks.

@effigies
Copy link
Member Author

effigies commented Aug 2, 2019

Great, thanks to both of you.

@effigies effigies merged commit f3d115f into nipy:master Aug 2, 2019
@effigies effigies deleted the fix/s390x_trk_bug branch August 2, 2019 00:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Test failure on s390x: test_nib_tck2trk
3 participants