NIFTI images can be stored in both left- or right- handed orientations,
and this information is saved in the NIFTI headers. Therefore,
spm_flip_analyze_images is only used for reading non-NIFTI images that
don't have a .mat file containing a Mat field.
The vol.mat is treated as correct. The function is only used for
determining the mat field when handedness info isn't available from the
header or .mat file.
Mayotonifti is called for reading ANALYZE format images, and just
converts the internal representation of the old headers into the
representation of new NIFTI headers. There was a special modification
made to it for reading images from FSL, whereby spm_flip_analyze_images
is ignored for images where the first voxel dimension is negative in the
.hdr file. These images are assumed to be from FSL and of a known
orientation.
Spm_flip_analyze_images is only used for reading certain headers, and
for (sometimes) specifying the storage convention of the output images.
I had hoped that people wouldn't be mixing data in different
orientation.
I didn't actually want to spend that much time on the reorient.m
function, as it was something that was requested by a few people who
want to use software that does not understand the orientation
information of SPM. It's not a core part of the SPM software.
As for the reorient.m function, the important thing is that the headers
are written in a consistent way to the image data. A bit further down
the file, you'll see the mat field is modified according to the desired
orientation of the data:
% Voxel-to-world transform of output image
if spm_flip_analyze_images, mat = diag([-1 1 1 1])*mat; end;
VO.mat = mat;
The reading of the original image data is a function of this matrix:
% Mapping from slice i of the output image,
% to voxels of the input image
M = inv(spm_matrix([0 0 -i])*inv(VO.mat)*V.mat);
% Extract this slice according to the mapping
img = spm_slice_vol(V,M,dim(1:2),1);
In SPM5, spm_flip_analyze_images is only called in three different
places, and is ignored when writing images (because having the
handedness saved in the headers makes it redundant).
@nifti/nifti.m - for compatibility with SPM99 .mat
files
@nifti/private/decode_qform0.m - NIFTI headers with missing information
@nifti/private/mayo2nifti.m - for compatibility with SPM99/SPM2
headers
Best regards,
-John
-----Original Message-----
From: SPM (Statistical Parametric Mapping) [mailto:[log in to unmask]]
On Behalf Of Ged Ridgway
Sent: Friday, May 04, 2007 5:54 PM
To: [log in to unmask]
Subject: [SPM] spm_flip_analyze_images (etc) in SPM5
Hi John or anyone else who can help,
Can you clarify the behaviour of spm_flip_analyze_images (set from
defaults.analyze.flip or to 1 if the defaults global variable doesn't
exist) in SPM5?
Should it ever be used after spm_vol has returned a structure with a
matrix? For writing images for example? Or is the vol.mat treated as
correct, once this has been set from spm_vol.
Is it only used on true Analyze images, and not on single volume .nii
or on two-volume hdr/img NIfTI pairs?
It appears not to be used if the second pixdim is negative, (judging
from @nifti/private/mayo2nifti1.m) but I'm not exactly sure for which
images mayo2nifti1 is called, or where this pixdim comes from.
It seems to me that an image should remain the same if the voxel data
is flipped AND the matrix is also altered, but as far as I can tell
from mayo2nifti1 this behaviour could break down if someone had
defaults.analzye.flip = 1. If image1 has negative pixdim, SPM will
read it without flipping, but if image2 has flipped voxel data and a
flipped matrix (hence should be equivalent to image1) SPM will flip
the image, giving the wrong handedness cf. image1.
This is a bit of a special case, I know, but I just wanted to check...
Also, in John's reorient.m
http://www.sph.umich.edu/~nichols/JG5/reorient.m
and consequently in my previous version of resize_img.m which was
based on this, there is the following:
tc = V.mat(1:3,1:4)*c;
if spm_flip_analyze_images, tc(1,:) = -tc(1,:); end;
this seems wrong to me now, since if the flipping behaviour has been
used already to set V.mat, then tc would seem to be correct, before it
is altered.
Relatedly, there seems to be a problem with the bbvox_from_V function
in spm_defs.m, for matrices with negative determinant (true e.g. for
spm5/tpm/grey.nii) the sqrt(sum(sqr())) approach misses the negative
voxel dimension and reverses the bounding box. This is not noticeable
with e.g. grey.nii since the bounding box is symmetric in x, but if
you reorient a copy of grey.nii shifting it to the right, the bounding
box from bbvox_from_V seems incorrect.
I seem to get the right behaviour -- also for rotated images, which I
don't think bbvox_from_V handles (?) -- with my new version of:
http://www.cs.ucl.ac.uk/staff/gridgway/vbm/world_bb.m
which doesn't use spm_flip_analyze_images; but I want to double-check
that this sounds like it should be correct in general.
One last thing (sorry to go on about this) reorient.m and my current
resize_img, also have a line:
if spm_flip_analyze_images, mat = diag([-1 1 1 1])*mat; end;
after forcing the vox sizes to be positive. I think this is okay,
since this output matrix is used both in writing the headers and in
reading the data from the existing image, so the physical orientation
of the output should be correct. But I wonder if it is a better idea
to set the voxel sizes from spm_imatrix (without abs() to force them
positive), derive the output matrix from these, and then ignore
analyze.flip, since this should mean that the resliced image matrix
has the same sign determinant as the input. Right? I like the fact
that this approach would just let spm_vol worry about analyze.flip,
and assume that it does the right thing, but perhaps I am missing a
reason why it is important to reconsider analyze.flip when reslicing?
Sorry for such a long (and boring -- I know everyone hates orientation
issues) email, thanks very much for any help anyone can offer,
Ged.
|