Skip to content
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

affine matrix issue while saving trackvis files #704

Open
daniel-ge opened this issue Dec 20, 2018 · 6 comments

Comments

Projects
None yet
4 participants
@daniel-ge
Copy link

commented Dec 20, 2018

I am attempting to write files in Trackvis-Format (trk). So loading a trk-file and saving it without any further changes should work. But unfortunately it fails in the following example:

Failing example

import nibabel.streamlines.trk as nitrk 
from numpy.testing import assert_equal, assert_almost_equal
import numpy as np
from numpy.linalg import inv
import urllib

trkname = "/tmp/myfile.trk"
trkname_clone = "/tmp/myfile_clone.trk"

# please let me know if the link of the example file is expired
url = "https://gigamove.rz.rwth-aachen.de/d/id/4hd7gVeFc4GweS/dd/100"
urllib.URLopener().retrieve(url, trkname)

trk = nitrk.TrkFile.load(trkname) # just loading...
trk.save(trkname_clone) # ... and saving
trk_clone = nitrk.TrkFile.load(trkname_clone) # let's load the content for comparison

# the contents of the files should be equal:
assert_equal(trk.header,trk_clone.header)
for i in range(len(trk.streamlines)):
    assert_almost_equal(trk.streamlines[i],
                        trk_clone.streamlines[i], decimal=4)
"""
AssertionError: 
Arrays are not almost equal to 4 decimals

(mismatch 100.0%)
 x: array([[-111.3645,  160.6524,   40.247 ],
       [-112.3261,  161.0878,   40.6915],
       [-112.4026,  161.1225,   40.7269],...
 y: array([[-4416.592 ,  4464.1333,  4995.547 ],
       [-4387.707 ,  4434.735 ,  4961.6387],
       [-4385.4077,  4432.3945,  4958.94  ],...
"""

Working example

I figured out that this error is related to the creation of the affine transformation in get_affine_rasmm_to_trackvis. After redefinition of this function the saved file contains the same data as the original one.

def f(hdr):
    T = nitrk.get_affine_trackvis_to_rasmm(hdr)
    T2 = np.eye(4)
    T2[:3,:3] = inv(T[:3,:3])
    T3 = np.eye(4)
    T3[:3,3:4] = T[:3,3:4]*-1
    return np.dot(T2,T3)

nitrk.get_affine_rasmm_to_trackvis = f

trk = nitrk.TrkFile.load(trkname)
trk.tractogram.affine_to_rasmm = np.eye(4) # because it was only ROUGHLY eye(4)
trk.save(trkname_clone)
trk_clone = nitrk.TrkFile.load(trkname_clone)

# the contents of the files should be equal:
assert_equal(trk.header,trk_clone.header)
for i in range(len(trk.streamlines)):
    assert_almost_equal(trk.streamlines[i],
                        trk_clone.streamlines[i], decimal=4)

"""
No Error :)
"""
@effigies

This comment has been minimized.

Copy link
Member

commented Dec 31, 2018

Hi @daniel-ge, thanks for the report. I don't have any experience with these file formats, so I'll leave evaluation to others. Would you have any interest in submitting a pull request? We almost certainly have round-trip tests, so adding your failing file to the battery would be a useful addition, along with fixes to ensure that your file is correctly loaded (if valid) or rejected (if actually invalid).

@MarcCote Do you have time to check on this and potentially review a PR?

@MarcCote

This comment has been minimized.

Copy link
Contributor

commented Jan 5, 2019

Hi, I can have a closer look next week. I'd be happy to review a PR fixing that issue.

@MarcCote

This comment has been minimized.

Copy link
Contributor

commented Jan 11, 2019

@daniel-ge the link to the data is now invalid.

@effigies

This comment has been minimized.

Copy link
Member

commented Mar 13, 2019

Hi @daniel-ge, can you update this issue with a fresh link?

@effigies effigies added the bug label Mar 13, 2019

@effigies

This comment has been minimized.

Copy link
Member

commented Apr 25, 2019

@daniel-ge Just a bump on this. Can the data be made available again? I can grab it so we're less sensitive to delays next time.

@sitek

This comment has been minimized.

Copy link

commented May 13, 2019

I may be having a related issue where nibabel.streamlines.save appears to be overwriting the given affine with np.eye(4). I described the issue on neurostars, with help from @arokem : https://neurostars.org/t/dipy-streamlines-not-aligning-with-image-space/3889/5

The key part is this:

I set the DWI-derived affine as the new affine:

tractogram = Tractogram(sl, affine_to_rasmm=affine)
tractogram.affine_to_rasmm                                                                 
Out[25]: 
array([[  -1.04999995,    0.        ,    0.        ,   90.        ],
       [   0.        ,    1.04999995,    0.        , -126.        ],
       [   0.        ,    0.        ,    1.04999995,  -72.        ],
       [   0.        ,    0.        ,    0.        ,    1.        ]])

and I saved it:

save(tractogram, 'tractogram_affine-fa.trk')

but when I load this new .trk file, the affine is back to an eye:

In [17]: sl_aff_fa, hdr_aff_fa = load_trk('tractogram_affine-fa.trk')                     
In [18]: hdr_aff_fa['voxel_to_rasmm']                                                               
Out[18]: 
array([[1., 0., 0., 0.],
       [0., 1., 0., 0.],
       [0., 0., 1., 0.],
       [0., 0., 0., 1.]], dtype=float32)

EDIT: my issue is not a nibabel bug – I resolved it by creating a header and feeding it to save() along with the tractogram object (see this dipy issue)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.