-
-
Notifications
You must be signed in to change notification settings - Fork 675
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
Accidental itk::NiftiImageIO metadata behaviour change wrt pixDim[0]
#3241
Comments
@hjmjohnson I'd appreciate your thoughts on this one... Here's my WIP: #3242 |
This could go into https://github.com/InsightSoftwareConsortium/ITK/blob/master/Documentation/ITK5MigrationGuide.md.
I agree this is silly. Returning something more meaningful is better. Finally, maybe other people were not really directly using NiftiImageIO, so no one noticed the change? |
The only thing 'more meaningful' would be to return the value from the
It also affect only some Nifti files. I suspect not too many people are introspecting these metadata fields. |
…iftiImageIO metadata bug InsightSoftwareConsortium#3241: In f38b1dd I accidentally changed some behaviour. Specifically, the value of pixdim[0] in itk::NiftiImageIO metadata is different before and after the change. Previous to the change, SetImageIOMetadataFromNIfTI() was populated from the nifti_1_header structure. After the change, it is populated from the nifti_image structure. The latter is created from the former with nifti_convert_nhdr2nim(). Most of the fields used in SetImageIOMetadataFromNIfTI() have 1-to-1 correspondences in these two structures. I expected all 8 elements of the pixdim array were the same in both structures, but in fact no; element 0 is special. nifti_convert_nhdr2nim() unconditionally sets pixdim[0] to 0.0 (by virtue of allocating the structure with calloc). In my own app, I was using pixdim[0] (retrieved from itk::NiftiImageIO) as the last parameter to nifti_quatern_to_mat44(). I see now looking at niftilib itself that I should be passing qfac as the last parameter. But the itk::MetaDataObject doesn't include it, so this commit adds qfac to the metadata dictionary. Additionally, we now include the whole qto_xyz matrix, so that ITK clients that call nifti_quatern_to_mat44() don't even need to. This plugs a leaky abstraction and allows my own app for example to not even know that ITK is implemented via niftilib, and never need to call down to it. Note that the behaviour change of f38b1dd is not being reverted, because it's been four years now, no one else has noticed, and some people may be relying on this behaviour now.
…iftiImageIO metadata bug InsightSoftwareConsortium#3241: In f38b1dd I accidentally changed some behaviour. Specifically, the value of pixdim[0] in itk::NiftiImageIO metadata is different before and after the change. Previous to the change, SetImageIOMetadataFromNIfTI() was populated from the nifti_1_header structure. After the change, it is populated from the nifti_image structure. The latter is created from the former with nifti_convert_nhdr2nim(). Most of the fields used in SetImageIOMetadataFromNIfTI() have 1-to-1 correspondences in these two structures. I expected all 8 elements of the pixdim array were the same in both structures, but in fact no; element 0 is special. nifti_convert_nhdr2nim() unconditionally sets pixdim[0] to 0.0 (by virtue of allocating the structure with calloc). In my own app, I was using pixdim[0] (retrieved from itk::NiftiImageIO) as the last parameter to nifti_quatern_to_mat44(). I see now looking at niftilib itself that I should be passing qfac as the last parameter. But the itk::MetaDataObject doesn't include it, so this commit adds qfac to the metadata dictionary. Additionally, we now include the whole qto_xyz matrix, so that ITK clients that call nifti_quatern_to_mat44() don't even need to. This plugs a leaky abstraction and allows my own app for example to not even know that ITK is implemented via niftilib, and never need to call down to it. Note that the behaviour change of f38b1dd is not being reverted, because it's been four years now, no one else has noticed, and some people may be relying on this behaviour now.
bug #3241: In f38b1dd I accidentally changed some behaviour. Specifically, the value of pixdim[0] in itk::NiftiImageIO metadata is different before and after the change. Previous to the change, SetImageIOMetadataFromNIfTI() was populated from the nifti_1_header structure. After the change, it is populated from the nifti_image structure. The latter is created from the former with nifti_convert_nhdr2nim(). Most of the fields used in SetImageIOMetadataFromNIfTI() have 1-to-1 correspondences in these two structures. I expected all 8 elements of the pixdim array were the same in both structures, but in fact no; element 0 is special. nifti_convert_nhdr2nim() unconditionally sets pixdim[0] to 0.0 (by virtue of allocating the structure with calloc). In my own app, I was using pixdim[0] (retrieved from itk::NiftiImageIO) as the last parameter to nifti_quatern_to_mat44(). I see now looking at niftilib itself that I should be passing qfac as the last parameter. But the itk::MetaDataObject doesn't include it, so this commit adds qfac to the metadata dictionary. Additionally, we now include the whole qto_xyz matrix, so that ITK clients that call nifti_quatern_to_mat44() don't even need to. This plugs a leaky abstraction and allows my own app for example to not even know that ITK is implemented via niftilib, and never need to call down to it. Note that the behaviour change of f38b1dd is not being reverted, because it's been four years now, no one else has noticed, and some people may be relying on this behaviour now.
In f38b1dd I accidentally changed some behaviour. Specifically, the value of
pixdim[0]
initk::NiftiImageIO
metadata is different before and after the change.Previous to the change,
SetImageIOMetadataFromNIfTI()
was populated from thenifti_1_header
structure. After the change, it is populated from thenifti_image
structure. The latter is created from the former withnifti_convert_nhdr2nim()
. Most of the fields used inSetImageIOMetadataFromNIfTI()
have 1-to-1 correspondences in these two structures. I expected all 8 elements of thepixdim
array were the same in both structures, but in fact no; element 0 is special.nifti_convert_nhdr2nim()
unconditionally setspixdim[0]
to 0.0 (by virtue of allocating the structure withcalloc
).In my own app, I was using
pixdim[0]
(retrieved fromitk::NiftiImageIO
) as the last parameter tonifti_quatern_to_mat44()
. I see now that I should be passingqfac
as the last parameter. But theitk::MetaDataObject
doesn't include it, so my first proposal here is to start including it.Then I got to thinking that me even needing to call
nifti_quatern_to_mat44()
in my app is really a layering violation (leaking ITK's use of niftilib) and that it'd be nice ifqto_xyz
were also part of the metadata, so I added that too.There remains the question of whether to actually revert my accidental behaviour change. There are pros and cons.
pixdim[0]
is now always 0.0 and returning something that never changes is kinda silly.SetImageIOMetadataFromNIfTI()
now comes fromnifti_image
, changing one field to be fromnifti_1_header
would be kinda weird. Now that I review all this, there are other fields that can be subtly different between the structs, even when they have identical names. For examplenifti_convert_nhdr2nim()
does things like this:nim->intent_p1 = FIXED_FLOAT( nhdr.intent_p1 ) ;
Given that this change is now 4 years old, I'm inclined to keep this new/current behaviour but:
qfac
to the metadataqto_xyz
to the metadataThe text was updated successfully, but these errors were encountered: