[pymvpa] [pynifti] NiftiDatatset bug?
Michael Hanke
michael.hanke at gmail.com
Fri Jan 9 16:58:37 UTC 2009
Hi Scott,
[taking the discussion to the new list. Please drop CC on reply ]
On Thu, Jan 08, 2009 at 04:54:34PM -0500, Scott Gorlin wrote:
<snip>
> I agree with you except that the dimension index of an ND array should
> be consistent no matter how many dimensions they have. In other words,
> shape[0] should have the same meaning for the same type of data
> regardless of how many samples (or u,v,w dims) there are. It seems self
> evident this should be the case from the pymvpa point of view at least,
> since shape[0] is always treated as the number of samples (which is 1
> for a 3d volume). With proper mapping handled in the NiftiDataset this
> is less of an issue, but it should also be easy to manipulate this
> manually when not using pymvpa - as I'm sure you intend pynifti for
> general usage.
Right. From the PyMVPA point it is that easy: shape[0] is the #samples.
That works well in non-4d cases, i.e. each sample is a 4d volume on its
own, hence your input file is 5D.
> Either that, or the data should be handled privately (in NiftiImage) in
> an intelligent way that can translate the correct dimensions into the
> actual dimensions in the data array. Perhaps a function like
> getFullData(t=True, u=False, v=False, w=False) which extracts a 4d
> (T,X,Y,Z) even if there's only one sample? Otherwise you get bugs like
> this. For instance, I don't know ahead of time if i'll be loading a 3D,
> 4D, or 4D with 1 timepoint volume (which apparently is treated
> differently, as my cludgy hack works that way) and every time i need to
> use the array I have to check for where the dimensions are.
Why? The dimensions are always the reverse of x,y,z,t,u,v,w, no?
I wonder what your '4d with 1' image header looks like. See this:
In [3]: N.arange(24).reshape(1,2,3,4).shape
Out[3]: (1, 2, 3, 4)
In [4]: nifti.NiftiImage(N.arange(24).reshape(1,2,3,4))
Out[4]: <nifti.niftiimage.NiftiImage object at 0xa529a6c>
In [5]: nim=nifti.NiftiImage(N.arange(24).reshape(1,2,3,4))
In [6]: nim.data.shape
Out[6]: (1, 2, 3, 4)
In [7]: nim.save('test.nii.gz')
In [8]: nim2=nifti.NiftiImage('test.nii.gz')
In [9]: nim2.data.shape
Out[9]: (1, 2, 3, 4)
In [10]: nim.header['dim']
Out[10]: [4, 4, 3, 2, 1, 1, 1, 1]
This is exactly what I would expect -- and if I got you right this is
what you want too, right?
> To further question this - what would happen to the Nifti data if the
> UVW dims are not 1? Presumably this is rare... but would they keep
> adding on to the beginning of the array?
Yes.
> So the number of samples now
> falls in the 2nd, 3rd, or 5th position?
No, it is always the first.
> Now perhaps I extract a subset
> of U,V,W 4-D volumes and squeeze away the preceding singleton dims - now
> there's no guarantee to the number of dims I'm left with. Or are U,V,W
> mapped after Z? And what about single-slice, or other 1d and 2d images
> encoded in an nii? It seems like wanting to squeeze out dims stands at
> ends with dim compatibility in this case.
Hmm, I did not get this.
> While I'm proposing crazy ideas, it would also be simpler if the index
> just happened to be reversed - (Z,Y,X,T,W,V,U). That way the proper
> volume is always consistent and extra dimensions can be safely dropped.
> I think in Matlab, nii's are typically loaded like this (I usually load
> using Freesurfer tools, not sure about SPM). It would also be easy to
> concatenate samples or uvw coords without having to permute the array first.
I don't see the advantage -- apart from the fact that this would change
the order of information in the file and increase IO operation time.
> I understand these ideas are probably over the top complicated in the
> face of backwards compatibility - so perhaps they can be my 'modest
> proposal'. But I hope they illustrate my point - IMHO it's crucial to
> easily extract and concatenate 3D volumes from a NiftiImage without
> having to figure out what dimension 'samples' is stored in every time
> it's necessary.
We should not confuse the needs of PyNIfTI with the ones of PyMVPA.
But in general it is quite simple: The last three dimensions/axes are
always the spatial ones, the one in front of them is the time and the
rest is something else.
> In other words - if you are heading to a new release with pynifti, yes,
> i think this issue is worth addressing there :)
Alright, but I still have no clear concept of what the 'issue' is in the
first place -- let discuss some more ;-)
> sorry if this seems like a rant - just my two drops of oil...
Don't worry -- I am German. Start ranting ;-)
Michael
--
GPG key: 1024D/3144BE0F Michael Hanke
http://apsy.gse.uni-magdeburg.de/hanke
ICQ: 48230050
More information about the Pkg-ExpPsy-PyMVPA
mailing list