Dear Joseph, et al,
I'm not sure how SPM2b interacts with the hist.orient field of the Analyze
header, so this contribution may be misguided.
Your comments assume the Analyze header orient field is a binary field with
2 possible values, but it may contain values 0-5 (see below). These values
do not specifically relate to the 'radiological' (right on left, axial view
from the feet looking up) vs 'neurological' (right on right, axial view from
the head looking down) orientation issue.
According to information from the MAYO clinic, this field contains values
from 0 to 5, which determine how to read the byte order of an *.img file
into a 3D data matrix. The *.img file is just a series of numbers, so the
header information is crucial for reading these numbers into a 3D matrix (or
4D for a time-series). The header determines the size of the matrix and the
orient field helps to order the numbers into it. The notes below guided the
development of the avw* functions available in the mri_toolbox, all source
code available from http://eeg.sourceforge.net. These functions *attempt*
to work with this field in order to load any Analyze file into the RAS
orientation in a 3D data matrix (RAS = +X right, +Y anterior, +Z superior).
As far as I know, the code is working OK for volume visualization, although
I'm no expert at this and cannot guarantee the code is faultless. I'm not
sure what the implications are for preprocessing, esp. normalisation and I
have no knowledge of the SPM code for handling Analyze orientation issues.
All I know is that SPM is designed to handle large numbers of volumes, so
memory management is important and it appears that SPM has some wrappers
that effectively manage 'virtual' files and load only the data values as
required (too complex for what I wanted).
% (Conventions gathered from e-mail with [log in to unmask])
%
% 0 transverse (axial) unflipped
% X direction first, progressing from patient right to left,
% Y direction second, progressing from patient posterior to anterior,
% Z direction third, progressing from patient inferior to superior.
% 1 coronal unflipped
% X direction first, progressing from patient right to left,
% Z direction second, progressing from patient inferior to superior,
% Y direction third, progressing from patient posterior to anterior.
% 2 sagittal unflipped
% Y direction first, progressing from patient posterior to anterior,
% Z direction second, progressing from patient inferior to superior,
% X direction third, progressing from patient right to left.
% 3 transverse (axial) flipped
% X direction first, progressing from patient right to left,
% Y direction second, progressing from patient anterior to posterior,
% Z direction third, progressing from patient inferior to superior.
% 4 coronal flipped
% X direction first, progressing from patient right to left,
% Z direction second, progressing from patient superior to inferior,
% Y direction third, progressing from patient posterior to anterior.
% 5 sagittal flipped
% Y direction first, progressing from patient posterior to anterior,
% Z direction second, progressing from patient superior to inferior,
% X direction third, progressing from patient right to left.
We can interpret the above, say 0, by noting that X changes fastest in the
right-left direction, followed by Y in the posterior-anterior direction, and
lastly we have slices in Z from inferior-superior. So we look at X and Y as
the in-plane dimensions (rows & columns), with X changing fastest. The
relevant code we get to read such a volume may look like this (from
avw_img_read)...
% read the whole .img file into matlab (faster)
fprintf('...reading %s Analyze %s image format.\n',machine,precision);
fseek(fid,0,'bof');
tmp = fread(fid,inf,sprintf('%s=>double',precision));
fclose(fid);
% Now partition the img data into xyz
% short int dim[ ]; /* Array of the image dimensions */
%
% dim[0] Number of dimensions in database; usually 4.
% dim[1] Image X dimension; number of pixels in an image row.
% dim[2] Image Y dimension; number of pixel rows in slice.
% dim[3] Volume Z dimension; number of slices in a volume.
% dim[4] Time points; number of volumes in database.
%
PixelDim = double(avw.hdr.dime.dim(2));
RowDim = double(avw.hdr.dime.dim(3));
SliceDim = double(avw.hdr.dime.dim(4));
switch double(avw.hdr.hist.orient),
case 0, % transverse/axial unflipped
% For the 'transverse unflipped' type, the voxels are stored with
% Pixels in 'x' axis (varies fastest) - from patient right to left
% Rows in 'y' axis - from patient posterior to
anterior
% Slices in 'z' axis - from patient inferior to
superior
fprintf('...image orient appears to be axial unflipped\n');
avw.img = zeros(PixelDim,RowDim,SliceDim);
n = 1;
x = 1:PixelDim;
for z = 1:SliceDim,
for y = 1:RowDim,
avw.img(x,y,z) = tmp(n:n+(PixelDim-1));
n = n + PixelDim;
end
end
...more code for the other orientations can be found in the m file for those
who are interested.
Take care, Darren
----- Original Message -----
From: "Joseph Maldjian" <[log in to unmask]>
To: <[log in to unmask]>
Sent: Friday, January 10, 2003 11:03 AM
Subject: SPM2 orient field and flip
Dear SPMers
Some further clarification on the use of the orient field in the
analyze header and the defaults.analyze.flip parameter in spm_defaults.m
would be greatly appreciated.
If the defaults.analyze.flip paramer in spm_defaults.m is set to 1, then
SPM2 flips the images during display regardless of the value in the
orient field in the analyze header.
My understanding is that the orient field describes the orientation of
the image, where 1 (meaning flipped) refers to neurologic convention,
and 0 refers to radiologic convention.
Does the defaults.analyze.flip parameter in the spm_defaults.m file
refer to the viewing convention for a particular laboratory (ie, "our
lab always view our data in Talairach space and therefore neurologic
convention"), or does it refer to the orientation of the data at the
beginning of an analysis (prior to spatial normalization, ie, "our data
always starts in radiologic convention")?
If defaults.analyze.flip refers to the orientation of the initial data,
then what is the purpose of the orient field in the header, since the
defaults.analyze.flip parameter overrides this information and always
flips the images during display if set to 1 (defaults.analyze.flip)?
If defaults.analyze.flip refers to the viewing convention for a
particular laboratory, then why does SPM2 ignore the value of the orient
field in the analyze header during display?
It seems that if the default.analyze.flip parameter is set to 1, and the
orient field in the analyze header is set to 1, SPM2 should not flip
these images as they are already "flipped".
As it is now, we may run into problems when reprocessing SPM99 data,
using SPM2 data sets outside of SPM2, or when using non-SPM2 templates.
If previously normalized SPM99 data (snr.img files) is processed
through SPM2 (the data is already flipped in neurologic convention, but
has an orient field of 0 ) the default.analyze.flip parameter needs to
be set to 0 in order to display the images properly (in neurologic
convention).
If new data is processed through SPM2 that starts in radiologic
convention, the default.analyze.flip parameter needs to be set to 1.
However, the output data, will have a value of 0 in the orient field
(and they will be right-left flipped relative to SPM99 data when viewed
outside of SPM2). This results in the unfortunate circumstance of
requiring separate hard-coded values for the defaults.analyze.flip
parameter within a lab (especially problematic with multiple users and a
single common distribution). If we wish to view/manipulate this data
outside of SPM2, there will be no intrinsic method of determining right
and left between the SPM99 data sets and the SPM2 data sets. In this
regard, the orient field would be of value for the SPM2 data sets ( 1
meaning it is in neurologic convention), as long as it does not get
ignored within SPM2 because of the defaults.analyze.flip parameter.
As another example, if we wish to use our own normalized template
(already in neurologic convention), what should the
defaults.analyze.flip parameter be set to? Setting it to 1 would be
appropriate for the input radiologic convention data, however wouldn't
this also result in the template image being flipped (since the orient
field is apparently being ignored)?
thank you
--------------------
Best Regards,
Joseph Maldjian, MD
Associate Professor of Radiology and Biomedical Engineering
Director Functional MRI
Wake Forest University School of Medicine
[log in to unmask]
phone: 336 716-2815
|