Yes, this is a feature that is specific to the MRtrix3
mif format, and not found in NIfTI. What volume-contiguous storage allows is to have for example all the DWI values for a given voxel co-located on disk and/or in RAM, which makes it much easier for the system to stream all these data in one go from the disk into RAM and then into the CPU - no need to seek to different locations, and the CPU cache can be used more efficiently. So this is particularly advantageous in applications where 4D datasets need to be processed voxel-wise. For this reason, you’ll note that applications like
tckgen will explicitly pre-load the data into RAM if the data are not already stored in volume-contiguous format (it does this to re-order the data to make it volume-contiguous): during tracking, every step requires all the SH coefficients for the voxels near the relevant spatial location (those used in the interpolator), so helping the system to load them efficiently makes a fair difference to performance.
You can avoid this preload if the data happen to already be in the right order (and in 32-bit floating point format) – the application can access the data directly via memory-mapping in this case. This is why for instance
dwi2fod will produce its output in 32-bit floating-point format in volume-contiguous order: it’s immediately in the right format for
tckgen to use.
Yes, I appreciate that. However, this is not a problem for
mrstats, or any other MRtrix3 command: the whole MRtrix3 backend is designed to handle this transparently. See here for a description of what happens.
But it will indeed be a problem for
Well, if you think about it, this
-keep_strides idea is actually the default already: we keep the strides of the input image… What you mean by ‘keep strides’ here is actually ‘take the strides from the template image’ (note that
-template is an option,
mrtransform can and will operate without it). And you’re right that one of the uses of
mrtransform is to regrid one image onto another, but it’s by no means the only use.
In NIfTI, you’re right that the voxel grid is also defined by the order of the axes. In MRtrix3 however, that is kept logically distinct: you can have images with different strides (and hence different ordering of the axes; or equivalently, rotated 90° in various ways; or equivalently, stored e.g. RAS, LPI, PSL, …) that nonetheless map onto the same exact voxel grid in real space. And MRtrix3 is designed to behave as expected in these situations: if the images map onto each other voxel-for-voxel in the viewer, they will also map onto each other in other computations. This is actually an issue that has been debated quite a bit amongst ourselves, and dates back from the very early days of MRtrix (well before its initial release back in 2008…). Have a look here for some of the background if you’re really interested…
Yes, this is an issue that you have raised in the past, and we made quite a few changes to ensure these issues were kept to a minimum. So converting between NIfTI & mif format should preserve the strides, and even computations that do involve changing the stride to volume contiguous storage should preserve the strides if converted to NIfTI. You’ve hit on one of those cases where there’s an ambiguity, since there’s two legitimate sources for that information – and I can see the rationale for expecting the axis ordering to follow the template, especially if coming from a NIfTI perspective. But like I said, I’m not convinced either one is more ‘correct’, without knowledge of the specific use case that the user has in mind. So given all of these considerations, I reckon we’re going to go with the approach suggested… although it’s not black & white, I’m still open to different opinions on that one!
Also, when you say that having NIfTI files with different voxel ordering is not a good idea, I agree that users should keep an eye on this and make sure all their data maintain consistent strides, for the reasons you mention. But this is not something we can easily enforce at the software level: MRtrix used to force NIfTI-standard 0,1,2 ordering in its output, irrespective of the input strides, but as I’m sure you’ll recall from this old conversation, this caused very similar issues to those you’ve raised here…