How to handle images defined in left-handed coordinate system

Small aside on this - the voxel-to-physical coordinate system that describes acquisition geometry can be left handed (e.g. axial foot-first vs head-first). ITK readers re-arrange the data to enforce right-handedness.

VTKjs supports direction vectors on image data and it was recently fixed to allow left handed matrices recently came up in vtkjs,

From this specification it seems that left-handed is not permitted in nifti (search for left-handed on the page and see also axes specification a few paragraphs above).

Is this something that has been added recently? What direction matrix do you see in Volumes module when you load the above-referenced volume into Slicer?

Yes, file formats may not support left handed coordinates - I see now that you were referring to the nifti file being invalid not that directions can’t be invalid as a general rule.

Not new, that was the original design and is still in the documentation. To be honest though I’m not sure which readers enforce it:

I’d need to dig back in, but as I recall the GDCM reader rearranges the order of the slices so that the direction turns out right-handed.

We may also end up with left-handed image coordinate system axes if a mirroring transform is applied.

Should we add a helper function in volumes logic that converts images to right-handed coordinate system (by reordering slices and flipping z axis) and call it after image import and after hardening a transform on a volume?

I think that would make sense, yes. Because we use ITK so much for processing we should try to ensure that our image data conforms to its expectations. Hardening seems like the right place to put it.

But probably easiest just to resample into an appropriate right-handed reference grid so not much special code is required.

Actually that reminds me of another issue a student had the other day. She was setting transforms manually that included shears and then hardening them, which works because the volume node can have non-orthonormal directions. But when she saved to nifti and reloaded the images were different (unfortunately in a subtle way) because nifti changes the directions to a quaternion. The workaround was to resample rather than harden.

So I think the code should detect both these cases and resample for hardening or importing.

Such Nifti files are common (e.g. MNI152 space).
Here are very useful test files with R/L marks here

User’s file (triggered this discussion) has orientation RPI (in ITK terminology, notation “from”),
file named avg152T1_LR_nifti.nii.gz from the link above has the same orientation.

Good news, both test files are correctly displayed in Slicer volume viewer and Slicer
can correctly save them in MetaImage file (not sure about all modules).
I guess because in ITK (and MetaImage format) matrices are fully defined,
this one is
1 0 0
0 -1 0
0 0 1
so there is no need to use cross product (whatever left or right handed) to get 3rd row (Z direction) from 1st and 2nd,
(remember DICOM’s direction cosines, they were in particular case 1,0,0,0,-1,0 and 3rd row (Z direction were cross product, here is a problem. But luckily not visible in classic series thanks to sorting by IPP/IOP,
resulting orientation after correct sorting were RPS (in ITK terminology).

To be sure and safe one can e.g. use ITK’s change orientation filter and
re-orient to RPS (in ITK terminology)
1 0 0
0 -1 0
0 0 -1

or LPI (in ITK terminology)
-1 0 0
0 -1 0
0 0 1

BTW, look at MHA header to see ITK’s orientation code and transform matrix:
TransformMatrix = 1 0 0 0 -1 0 0 0 1
AnatomicalOrientation = RPI


also s.