# Exporting file to .nii and .nii.gz changes the transform in the header

**URL:** <https://discourse.slicer.org/t/exporting-file-to-nii-and-nii-gz-changes-the-transform-in-the-header/24981>\
**Category:** Support\
**Tags:** transforms\
**Created:** [August 29, 2022, 4:06pm UTC](https://discourse.slicer.org/t/exporting-file-to-nii-and-nii-gz-changes-the-transform-in-the-header/24981 "2022-08-29T16:06:30Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![koeglfryderyk](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/koeglfryderyk/32/14638_2.png) [@koeglfryderyk](https://discourse.slicer.org/u/koeglfryderyk)\
**Post date:** [August 29, 2022, 4:06pm UTC](https://discourse.slicer.org/t/exporting-file-to-nii-and-nii-gz-changes-the-transform-in-the-header/24981/1 "2022-08-29T16:06:30Z")

</div>

I have an .mrb with multiple files, from which I export one to .nii.gz

When I load the file again, it doesn’t match the original file because it’s affine is changed (I loaded both files in Python with SimpleITK and saw that the voxel values were identical, only the origin and direction have changed)

This does not happen when I export this file to .nrrd.

I tried this with multiple versions of Slicer and it always kept happening.

Unfortunately I’m not allowed to share the file.

There are also no errors or warnings when exporting this file. Is there a way to debug this?

---

<div class="post-metadata">

**Author:** ![pieper](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/pieper/32/8_2.png) [@pieper](https://discourse.slicer.org/u/pieper)\
**Post date:** [August 29, 2022, 4:34pm UTC](https://discourse.slicer.org/t/exporting-file-to-nii-and-nii-gz-changes-the-transform-in-the-header/24981/2 "2022-08-29T16:34:06Z")

</div>

We’ve noticed this with other data too. The nifti1 headers that are used by default use 32bit floats for orientation and there can be rounding error. Avoid nifti if you can.

Here’s a related discussion:

> <https://github.com/OHIF/Viewers/issues/2869>
>
> Hello,
> 
> I am having issues rendering dcm segmentations in OHIF Viewer(version …number : 4.12.30).
> The segmentations come from \[ProstateX IDC collection\](https://portal.imaging.datacommons.cancer.gov/explore/filters/?collection\_id=prostatex), converted to nii using dcmqi, then converted back to dcm using dcmqi(v 1.2.5) again.
> 
> The dcm file originating from IDC buckets is rendered properly into OHIF, however the dcm file from dcmqi conversion from nii format is not rendered properly.
> 
> Here is the error reported by the OHIF Viewer :
> !\[error\_dcm\_seg\_ohif (1)\](https://user-images.githubusercontent.com/72577931/184412717-a8b74022-3cd5-4ba8-bfec-5b2f88d6204e.jpg)
> 
> !\[ohif\_console (1)\](https://user-images.githubusercontent.com/72577931/184412763-39d38b8c-8fd3-42c4-9e32-70f205ec2af7.jpg)
> 
> To reproduce this issue, please see this \[ipynb\](https://github.com/ccosmin97/IDC-Prostate\_segmentation/blob/main/prostateX\_patID0004\_dcmqi\_test.ipynb).
> 
> Additional info :
> 
> \- IDC bucket dcm
> - \[metadata\](https://www.dropbox.com/s/6ewb178mjujzidz/1.2.276.0.7230010.3.1.4.1070885483.15960.1599120307.702\_dcm\_stats?dl=0) 
> - \[dcm file\](https://www.dropbox.com/s/2fxtsd2blwwcop2/1.2.276.0.7230010.3.1.4.1070885483.15960.1599120307.702.dcm?dl=0)
> \- DCMQI converted dcm(nii -\> dcm)
> - \[metadata\](https://www.dropbox.com/s/l1rdu2315aks3xt/test\_gt\_0004\_dcm\_stats?dl=0)  
> - \[dcm file\](https://www.dropbox.com/s/xakvc4o4zg03ln2/test\_gt\_0004.dcm?dl=0)
> \- \[Diff between two dcm metadata files\](https://www.dropbox.com/s/9jszt3aa7ao5m95/diff-dcm-metadata?dl=0)
> 
> Thank you!
> 
> @fedorov

---

<div class="post-metadata">

**Author:** ![koeglfryderyk](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/koeglfryderyk/32/14638_2.png) [@koeglfryderyk](https://discourse.slicer.org/u/koeglfryderyk)\
**Post date:** [August 29, 2022, 5:20pm UTC](https://discourse.slicer.org/t/exporting-file-to-nii-and-nii-gz-changes-the-transform-in-the-header/24981/3 "2022-08-29T17:20:34Z")

</div>

ok. I have three follow-up questions

1. Is there a way of determining when the mismatch might occur?
2. Would it make sense to export to nifti2?
3. Could you elaborate on ‘Avoid nifti if you can?’

---

<div class="post-metadata">

**Author:** ![dzenanz](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/dzenanz/32/1992_2.png) [@dzenanz](https://discourse.slicer.org/u/dzenanz)\
**Post date:** [September 19, 2022, 3:57pm UTC](https://discourse.slicer.org/t/exporting-file-to-nii-and-nii-gz-changes-the-transform-in-the-header/24981/4 "2022-09-19T15:57:17Z")

</div>

[PR 6454](https://github.com/Slicer/Slicer/pull/6454) should fix this. Give it a try and report whether the problem still occurs.

---

<div class="post-metadata">

**Author:** ![dzenanz](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/dzenanz/32/1992_2.png) [@dzenanz](https://discourse.slicer.org/u/dzenanz)\
**Post date:** [September 19, 2022, 4:02pm UTC](https://discourse.slicer.org/t/exporting-file-to-nii-and-nii-gz-changes-the-transform-in-the-header/24981/5 "2022-09-19T16:02:58Z")

</div>

PR 6454 is now part of [preview release](https://download.slicer.org/).

---

<div class="post-metadata">

**Author:** ![koeglfryderyk](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/koeglfryderyk/32/14638_2.png) [@koeglfryderyk](https://discourse.slicer.org/u/koeglfryderyk)\
**Post date:** [October 16, 2022, 12:32pm UTC](https://discourse.slicer.org/t/exporting-file-to-nii-and-nii-gz-changes-the-transform-in-the-header/24981/6 "2022-10-16T12:32:02Z")

</div>

The problem persists.

I also wrote a simple Python script that uses the newest SimpleITK version (2.2.0) to export the .nrrds in question to .nii and the same change happens.

From what I understood from discussions with @pieper, the problem is rather with the NIFTI standard that doesn’t support shear in the affine matrix - and the files that I have problems have a non-zero shear component.

---

<div class="post-metadata">

**Author:** ![pieper](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/pieper/32/8_2.png) [@pieper](https://discourse.slicer.org/u/pieper)\
**Post date:** [October 16, 2022, 4:02pm UTC](https://discourse.slicer.org/t/exporting-file-to-nii-and-nii-gz-changes-the-transform-in-the-header/24981/7 "2022-10-16T16:02:32Z")

</div>

@koeglfryderyk would you be able to make an example file using the header information and synthetic pixel data? It would simplify the discussion if you provided a shareable example. Also provide a simple example script that demonstrates the exact issue (you can be inspired by [this advice](http://sscce.org/).

> [@koeglfryderyk](#):
>
> NIFTI standard that doesn’t support shear in the affine matrix

As I understand it the [nifti reference](https://nifti.nimh.nih.gov/pub/dist/src/niftilib/nifti1.h) is open to interpretation here. There are both a quaternion (no shear) and an affine matrix (could have shear) but ITK’s logic has many special cases to work with such data (e.g. see [this discussion](https://discourse.itk.org/t/saving-non-orthogonal-volume-in-nifti-format/2760). This logic may or may not match the logic used by other programs, which is why I suggest avoiding the format. If you read the nifti reference above you can see how it is very neuroimaging specific and has many special cases that have proven problematic in practice.

---

<div class="post-metadata">

**Author:** ![koeglfryderyk](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/koeglfryderyk/32/14638_2.png) [@koeglfryderyk](https://discourse.slicer.org/u/koeglfryderyk)\
**Post date:** [October 19, 2022, 2:46pm UTC](https://discourse.slicer.org/t/exporting-file-to-nii-and-nii-gz-changes-the-transform-in-the-header/24981/8 "2022-10-19T14:46:24Z")

</div>

Here are a few lines that will create an .nrrd with noise as data and with the header copied from one of the problematic files (you need to have numpy and pynrrd installed to run this) - the noise is big enough to visually see how the file changes after it was exported to .nii

```auto
from collections import OrderedDict
import numpy as np
import nrrd

# path to where the .nrrd file will be saved
path = "dummy.nrrd"

# the header is copied from one of the problematic .nrrd files
header = OrderedDict([('type', 'unsigned short'),
             ('dimension', 3),
             ('space', 'left-posterior-superior'),
             ('sizes', np.array([256, 256, 80])),
             ('space directions',
              np.array([[-0.82093026, -0.03815682, -0.03294253],
                     [-0.03818959, 0.81657389, 0.06732129],
                     [0.09523261, 0.14437391, -1.9763117]])),
             ('kinds', ['domain', 'domain', 'domain']),
             ('endian', 'little'),
             ('encoding', 'gzip'),
             ('space origin',
              np.array([110.19170784, -173.7526922 , 101.14669097]))])

# the data array has the same size as the the file from which the header was copied, but it's just noise
data = np.random.rand(256, 256, 80)

nrrd.write(path, data, header)

```

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [October 19, 2022, 4:52pm UTC](https://discourse.slicer.org/t/exporting-file-to-nii-and-nii-gz-changes-the-transform-in-the-header/24981/9 "2022-10-19T16:52:42Z")

</div>

Please spread the word: do not use Nifti in non-neuroimaging applications. The much simper NRRD file format can be used instead.

By using Nifti file format, people maintain a continuous drain of our resources via requiring lots of user support (keep explaining issues with Nifti and what to do about it) and trying to implement and maintain complex mechanisms (to deal with redundancies and ambiguities in the Nifti format), and in general by distracting our attention from more impactful work.

---

<div class="post-metadata">

**Author:** ![pieper](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/pieper/32/8_2.png) [@pieper](https://discourse.slicer.org/u/pieper)\
**Post date:** [October 19, 2022, 5:28pm UTC](https://discourse.slicer.org/t/exporting-file-to-nii-and-nii-gz-changes-the-transform-in-the-header/24981/10 "2022-10-19T17:28:26Z")

</div>

Thanks for providing the concrete example 👍 This does help further the investigation.

@koeglfryderyk this matrix does have a non-trivial shear component. Is that intended?

```auto
array([[-0.82093026, -0.03815682, -0.03294253],
       [-0.03818959, 0.81657389, 0.06732129],
       [0.09523261, 0.14437391, -1.9763117]])
>>> numpy.dot(a[0], a[1])
-0.0020246065049000987
>>> numpy.dot(a[0], a[2])
-0.018583473117743804
>>> numpy.dot(a[1], a[2])
-0.01879278211341301

```

As noted in some of the links above ITK may not be consistent in handling this case (e.g. shear may be silently dropped, and that may be what’s happening in the nifti case, so the issue might not even be related to the 32 bit precision issue).

Shear should be handled well for viewing in Slicer but some of the ITK or VTK based filters may ignore the shear.

Seeing this data makes me think we should remove the ambiguity at the Slicer level. An option could be to give users the option to factor out shear into a separate transform when loading so that the `vtkMRMLVolume*Node` classes can always expect orthogonal direction vectors. Users could resample through the transform at the desired resolution if needed to incorporate the shear.

As a general rule, I suggest that people doing any kind of non-rigid registration save the transform somewhere other than the image header whenever possible.

---

<div class="post-metadata">

**Author:** ![koeglfryderyk](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/koeglfryderyk/32/14638_2.png) [@koeglfryderyk](https://discourse.slicer.org/u/koeglfryderyk)\
**Post date:** [October 24, 2022, 9:21am UTC](https://discourse.slicer.org/t/exporting-file-to-nii-and-nii-gz-changes-the-transform-in-the-header/24981/11 "2022-10-24T09:21:29Z")

</div>

I’m not sure I would use the word ‘intended’ - that’s the data that we received from Brainlab and we only sometimes applied rigid transformations to it.

But I’ll keep saving non-rigid transformations elsewhere in mind
