Class FileNIFTI
- java.lang.Object
-
- gov.nih.mipav.model.file.FileBase
-
- gov.nih.mipav.model.file.FileNIFTI
-
public class FileNIFTI extends FileBase
The class reads and writes NIFTI files. The header is intended to be "mostly compatible" with the ANALYZE (TM) 7.5 file format. Most of the "unused" fields in that format have been taken, and some of the lesser-used fields have been co-opted for other purposes. NIFTI origin Author: William Gandler (---.cit.nih.gov) Date: 03-13-09 18:31 Are qoffset_x and srow_x[3] always meant to be an origin in the RL axis, qoffset_y and srow_y[3] always meant to be an origin in the AP axis, and are qoffset_z and srow_z[3] always meant to be an origin in the IS axis? Re: NIFTI origin Author: rick reynolds (---.nimh.nih.gov) Date: 03-16-09 11:02 Hi William, Yes. The qoffset_{x,y,z} values are explicitly LR, PA, IS, as the transformations always describe resulting coordinates in LPI (sign and order) orientation. The sign of those coordinates corresponds to LPI being the negative directions. This is much like Dicom images, which give coordinates in RAI, regardless of the actual orientation of the data on disk. There, RAI are the negative directions (2 of them opposite that of NIfTI). These offset coordinates are applied after the transformation matrix is applied, and so they must be LR, PA and IS, respectively. The same applies for the sform matrix. See the section on "ORIENTATION AND LOCATION IN SPACE" from the nifti.h standard for details: http://nifti.nimh.nih.gov/pub/dist/src/niftilib/nifti1.h - rickNIFTI can have 2 different transformation matrices associated with an image - one stored in the qform_code parameters and one stored in the sform_code parameters. While MIPAV separately stores axis orientation and matrix information, NIFTI does not store axis orientation information. NIFTI uses a routine to derive axis orientations from the upper 3 by 3 parameters of the 4 by 4 matrix. The 4 by 4 matrix in NIFTI transforms x,y,z indexes to (right, anterior, superior) coordinates where +x = Right, +y = Anterior, +z = Superior. In MIPAV the 4 by 4 matrix does not imply the axis orientations.
For qform_code > 0, which should be the normal case the NIFTI definition is: [right] [R11 R12 R13] [ pixdim[1] * i] [qoffset_right] [anterior] = [R21 R22 R23] [ pixdim[2] * j] + [qoffset_anterior] [superior] [R31 R32 R33] [qfac * pixdim[3] * k] [qoffset_superior] Now in going to MIPAV 2 changes must occur. 1.) NIFTI is L->R and P->A while MIPAV is R->L and A->P, so this would cause R11, R12, R13, qoffset_right, R21, R22, R23, and qoffset_anterior to be multiplied by -1. 2.) R13, R23, and R33 are multiplied by qfac. So we in going to MIPAV we use -R11, -R12, -R13*qfac, -qoffset_right, -R21, -R22, -R23*qfac, -qoffset_anterior, and R33*qfac. If qform_code == 0 and sform_code > 0: x = srow_x[0]* i + srow_x[1] * j + srow_x[2] * k + srow_x[3] y = srow_y[0]* i + srow_y[1] * j + srow_y[2] * k + srow_y[3] z = srow_z[0]* i + srow_z[1] * j + srow_z[2] * k + srow_z[3] In going to MIPAV we use -srow_x[0], -srow_x[1] -srow_x[2], -srow_x[3], -srow_y[0], -srow_y[1] -srow_y[2], and -srow_y[3].
MIPAV ANALYZE uses 6 for 16 bit unsigned short in the datatype field while NIFTI uses 512 for 16 bit unsigned short in the datatype field. NIFTI also has a signed char at 256, an unsigned int at 768, a LONG at 1024, an unsigned long at 1280, an 128 bit float at 1536, a 128 bit COMPLEX at 1792, and a 256 bit COMPLEX at 2048 which are not present in ANALYZE. MIPAV cannot presently handle a 128 bit float or a 256 bit COMPLEX. If scl_slope != 1.0 or scl_inter != 0.0, then source data types will be promoted to higher data types if necessary.
At location 56 our hacked anlayze has a 4 byte string for voxel units, while NIFTI has the float intent_p1. At location 60 our hacked analyze has a 4 byte string for cal units, while NIFTI has the float intent_p2. At locations 64 and 66 our hacked analyze has shorts for axis orientations 0 and 1, while NIFTI has the float intent_p3. At location 68 our hacked analyze has the short for axis orientation 2, while NIFTI has the short for intent_code.
At location 76 both ANALYZE and NIFTI have 8 floats for resolutions. In ANALYZE pixdim[0] at location 76 is unused, but in NIFTI if (pixdim[0] >= 0) qfac is taken as 1. Otherwise, if (pixdim[0] < 0) in NIFTI qfac is taken as -1. qfac is used in determining the transformation matrix in method 2. In both ANALYZE and NIFTI the x resolution pixdim[1] is found at location 80, the y resolution pixdim[2] is found at location 84, the z resolution pixdim[3] is found at location 88, and the t resolution pixdim[4] is found at location 92. In NIFTI L to R, P to A, and I to S are defined as positive directions. This differs from AFNI and MIPAV where R to L, A to P, and I to S are positive. ANALYZE 7.5 has R to L, P to A, and I to S positive. Thus, NIFTI, AFNI, and MIPAV have right handed coordinate systems, while ANALYZE has a left handed coordinate system.
At location 112 our hacked analyze has a float for origin[0], while NIFTI has the float scl_slope. At location 116 our hacked analyze has a float for origin[1], while NIFTI has the float scl_inter. The data is scaled according to: scaled_data[i] = scl_slope * unscaled_data[i] + scl_inter At location 120 our hacked analyze has a float for origin[2], while the NIFTI location 120 has short slice_end, location 122 has char slice_code, and location 123 has char xyzt_units. NIFTI has qoffset_x, qoffset_y, and qoffset_z in locations 268, 272, and 276.
- See Also:
FileIO
,FileInfoNIFTI
,FileRaw
-
-
Field Summary
Fields Modifier and Type Field Description private java.lang.String[]
afniGroupArray
private java.lang.String[]
asciiTextArray
private int[]
axisOrientation
R2L, L2R, A2P, P2A, I2S, and S2I orientations of x, y, and z axes.private int[]
axisOrientation2
When both qform_code > 0 and sform_code > 0, the axis orientation information corresponding to sform_code > 0 is placed in axisOrientation2private float[]
azimuthArray
private byte[]
bufferByte
A byte array of the size of the NIFTI header + 4 extension bytes.private float[]
bValueArray
private CBZip2InputStream
bz2in
private java.lang.String[]
caretArray
private int
coord_code
If qform_code > 0, coord_code = qform_code.private int[]
degreeArray
private int[][]
dtComponentArray
private int
ecode
private int[]
ecodeArray
private int
esize
private int[]
esizeArray
private java.io.File
file
File object and input streams needed for NIFTI compressed filesprivate java.lang.String
fileDir
DOCUMENT ME!private java.io.File
fileHeader
DOCUMENT ME!private FileInfoNIFTI
fileInfo
DOCUMENT ME!private java.lang.String
fileName
DOCUMENT ME!private java.io.FileInputStream
fis
private int
freq_dim
Bits 0 and 1 of the dim_info character contain the freq_dim information. 0 for "No frequency encoding direction is present", 1 for "Frequency encoding in the x direction", 2 for "Frequency encoding in the y direction", and 3 for "Frequency encoding in the z direction".private java.util.zip.GZIPInputStream
gzin
private int
headerSize
The size of the NIFTI-2 header must be set to 540 bytes.private ModelImage
image
DOCUMENT ME!private double
imageMax
DOCUMENT ME!private double
imageMin
DOCUMENT ME!private java.lang.String
intentName
The intent_name field provides space for a 15 character (plus 0 byte) name string for the type of data stored.private java.lang.String[]
jsonArray
private double[]
LPSOrigin
The MIPAV origin value which is obtained from qoffset_x, qoffset_y, and qoffset_z when qform_code > 0 or from srow_x[3], srow_y[3], and srow_z[3] when sform_code > 0.private double[]
LPSOrigin2
When qform_code > 0 and sform_code > 0, LPSOrigin derives the MIPAV origin from the qform information and LPSOrigin2 derives MIPAV origin from the sform information.private TransMatrix
matrix
MIPAV matrix used for storing qform or sform transformation information.private TransMatrix
matrix2
When qform_code > 0 and sform_code > 0, the qform transformation information is stored in matrix and the sform transformation information is stored in matrix2.private TransMatrix
matrixTwoDim
MIPAV matrix used for storing qform or sform transformation information for 2D images.private java.lang.String[]
mindIdentArray
private double
newMax
When the image data is rescaled by y = scl_slope * x + scl_inter, the image minimum or image maximum is rescaled to newMax.private double
newMin
When the image data is rescaled by y = scl_slope * x + scl_inter, the image minimum or image maximum is rescaled to newMin.private boolean
noReadPrivateTags
private boolean
oneFile
If true, header and data both stored in .nii file.private int[]
orderArray
private float[]
origin
DOCUMENT ME!private java.lang.String
patientOrientationString
private int
phase_dim
Bits 2 and 3 of the dim_info character contain the phase_dim information. 0 for "No phase encoding direction is present", 1 for "Phase encoding in the x direction", 2 for "Phase encoding in the y direction", and 3 for "Phase encoding in the z direction".private double[]
pixdim
qfac is stored in the otherwise unused pixdim[0].private float
qfac
The scaling factor qfac is either 1 or -1.private int
qform_code
When qform_code > 0 the (x,y,z) coordinates are given by: [ x ] [ R11 R12 R13 ] [ pixdim[1] * i ] [ qoffset_x ] [ y ] = [ R21 R22 R23 ] [ pixdim[2] * j ] + [ qoffset_y ] [ z ] [ R31 R32 R33 ] [ qfac * pixdim[3] * k ] [ qoffset_z ] where the R rotation parameters are calculated from the quaternion parameters.private double
qoffset_x
Quaternion x shiftprivate double
qoffset_y
Quaternion y shiftprivate double
qoffset_z
Quaternion z shiftprivate double
quatern_a
The orientation of the (x,y,z) axes relative to the (i,j,k) axes in 3D space is specified using a unit quaternion [a,b,c,d], where a*a+b*b+c*c+d*d=1.private double
quatern_b
Quaternion b parameterprivate double
quatern_c
Quaternion c parameterprivate double
quatern_d
Quaternion d parameterprivate double
r00
The (proper) 3x3 rotation matrix that corresponds to quaternion [a,b,c,d] is [ a*a+b*b-c*c-d*d 2*b*c-2*a*d 2*b*d+2*a*c ] R = [ 2*b*c+2*a*d a*a+c*c-b*b-d*d 2*c*d-2*a*b ] [ 2*b*d-2*a*c 2*c*d+2*a*b a*a+d*d-c*c-b*b ]private double
r01
The (proper) 3x3 rotation matrix that corresponds to quaternion [a,b,c,d] is [ a*a+b*b-c*c-d*d 2*b*c-2*a*d 2*b*d+2*a*c ] R = [ 2*b*c+2*a*d a*a+c*c-b*b-d*d 2*c*d-2*a*b ] [ 2*b*d-2*a*c 2*c*d+2*a*b a*a+d*d-c*c-b*b ]private double
r02
The (proper) 3x3 rotation matrix that corresponds to quaternion [a,b,c,d] is [ a*a+b*b-c*c-d*d 2*b*c-2*a*d 2*b*d+2*a*c ] R = [ 2*b*c+2*a*d a*a+c*c-b*b-d*d 2*c*d-2*a*b ] [ 2*b*d-2*a*c 2*c*d+2*a*b a*a+d*d-c*c-b*b ]private double
r10
private double
r11
private double
r12
private double
r20
private double
r21
private double
r22
private float[]
resolutions
NIFTI pixdim information is converted into MIPAV resolutions information Only those pixdim[i] for which the niftiExtents[i] > 1 are passed into a resolutions[j] value.private double
scl_inter
private double
scl_slope
If the scl_slope field is nonzero, then each voxel value in the dataset should be scaled as y = scl_slope * x + scl_inter where x = voxel value stored y = "true" voxel value Normally, we would expect this scaling to be used to store "true" floating values in a smaller integer datatype, but that is not required.private int
sform_code
When sform_code > 0, The (x,y,z) coordinates are given by a general affine transformation of the (i,j,k) indexes: x = srow_x[0] * i + srow_x[1] * j + srow_x[2] * k + srow_x[3] y = srow_y[0] * i + srow_y[1] * j + srow_y[2] * k + srow_y[3] z = srow_z[0] * i + srow_z[1] * j + srow_z[2] * k + srow_z[3] sform_code has values for "Arbitrary X,Y,Z coordinate system", "Scanner based anatomical coordinates", "Coordinates aligned to another file's or to anatomical truth", "Talairach X,Y,Z coordinate system", and "MNI 152 normalized X,Y,Z coordinates".private int
slice_dim
Bits 4 and 5 of the dim_info character contain the slice_dim information. 0 for "No slice acquisition direction is present", 1 for "Slice acquisition in the x direction", 2 for "Slice acquisition in the y direction", and 3 for "Slice acquisition in the z direction".private int
sliceCode
If this is nonzero, AND if slice_dim is nonzero, AND if slice_duration is positive, indicates the timing pattern of the slice acquisition.private double
sliceDuration
Time used to acquire 1 slice.private long
sliceEnd
Slice timing pattern ends with slice = (sliceEnd + 1)private long
sliceStart
Slice timing pattern starts with slice = (sliceStart + 1)private short
sourceBitPix
Source bits per pixel = sourceBitPixprivate short
sourceType
Original unscaled source data typeprivate int
spaceUnits
Bits 0, 1, and 2 of xyzt_units specify the units of pixdim[1..3], that is the spatial units of the nifti x, y, and z axes. 0 means "Spatial units are unknown", 1 means "Spatial units are meters", 2 means "Spatial units are millimeters", 3 means "Spatial units are micrometers".private double[]
srow_x
1st row affine transformprivate double[]
srow_y
2nd row affine transformprivate double[]
srow_z
3rd row affine transformprivate int
timeUnits
Bits 3, 4, and 5 of xyzt_units specify the units of pixdim[4], that is the temporal units of the nifti time axis.private double
tOffset
The toffset field can be used to indicate a nonzero start point for the time axis.private float
vox_offset
If the magic field is "n+1", then the voxel data is stored in the same file as the header.private long
vox_offset2
private float[]
zenithArray
private java.util.zip.ZipInputStream
zin
-
Fields inherited from class gov.nih.mipav.model.file.FileBase
BIG_ENDIAN, bitsPerPixel, fileNames, LITTLE_ENDIAN, pBarVisible, raFile, READ, READ_WRITE
-
-
Constructor Summary
Constructors Constructor Description FileNIFTI(java.lang.String fName, java.lang.String fDir)
Constructs new file object.
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description void
absoluteValue(ModelImage image)
Absolute value of image.void
finalize()
Prepares this class for cleanup.void
flipTopBottom(float[] buffer, FileInfoNIFTI fileInfo)
Flips image.void
flipTopBottom(ModelImage image)
Flips image.private int[]
getAxisOrientation(TransMatrix mat)
--------------------------------------------------------------------------- !byte[]
getBufferByte()
FileInfoNIFTI
getFileInfo()
Returns the FileInfoNIFTI read from the file.private byte[]
getFullBuffer(java.io.InputStream in, byte[] buff, int off, int fullBufferSize)
TransMatrix
getMatrix()
TransMatrix
getMatrix2()
private int
getOffset(FileInfoNIFTI fileInfo)
Helper method to calculate the offset for getting only the middle NIFTI image slice from the 3D file.static boolean
isNIFTI(java.lang.String fName, java.lang.String fDir)
Method determines if the image format is NIFTI, so FileIO will call the appropriate FileNIFTI read method.private double
mat33_colnorm(Jama.Matrix A)
max column norm of 3x3 matrix.private Jama.Matrix
mat33_polar(Jama.Matrix A)
Polar decomposition of a 3x3 matrix: finds the closest orthogonal matrix to input A (in both Frobenius and L2 norms).private double
mat33_rownorm(Jama.Matrix A)
max row norm of 3x3 matrix.private void
processJson(java.lang.String json, boolean noReadPrivateTags)
boolean
readHeader(java.lang.String imageFileName, java.lang.String fileDir, boolean niftiCompressed, boolean noReadPrivateTags)
Reads the NIFTI header and stores the information in fileInfo.ModelImage
readImage(boolean one, boolean niftiCompressed, boolean noImportData, boolean noReadPrivateTags)
Reads a NIFTI image file by reading the header then making a FileRaw to read the image for all filenames in the file list.void
readImage(float[] buffer)
Reads a NIFTI image file by reading the header then making a FileRaw to read the file.void
readImage(float[] buffer, long userOffset)
Reads a NIFTI image file by reading the header then making a FileRaw to read the file.void
scale(ModelImage image)
Scales image.private void
updateorigins(FileInfoBase[] fileInfo)
Updates the start locations.boolean
writeHeader(ModelImage image, int nImagesSaved, int nTimeSaved, java.lang.String fileName, java.lang.String fileDir, boolean doGzip, boolean oneFile)
Writes a NIFTI header to a separate file.private void
writeHeader3DTo2D(ModelImage image, java.lang.String fileName, java.lang.String fileDir, FileWriteOptions options, boolean oneFile)
This method is used when saving a 3D image in an array of 2D files.private void
writeHeader4DTo3D(ModelImage image, java.lang.String fileName, java.lang.String fileDir, FileWriteOptions options, boolean oneFile)
This method is used when saving a 4D image in an array of 3D files.void
writeImage(ModelImage image, FileWriteOptions options)
Writes an NIFTI format type image.-
Methods inherited from class gov.nih.mipav.model.file.FileBase
addProgressChangeListener, bytesToDouble, bytesToFloat, bytesToInt, bytesToShort, doubleToBytes, fireProgressStateChanged, fireProgressStateChanged, fireProgressStateChanged, floatToBytes, getBufferDouble, getBufferFloat, getBufferInt, getBufferLong, getBufferShort, getBufferUShort, getDataType, getDouble, getFloat, getInt, getLong, getProgressChangeListeners, getRaFile, getSignedShort, getString, getUInt, getUnsignedByte, getUnsignedShort, intToBytes, isBigEndian, isProgressBarVisible, linkProgress, longToBytes, readDouble, readFloat, readInt, readLong, readShort, readString, readUnsignedShort, removeProgressChangeListener, setBigEndian, setBufferFloat, setBufferInt, setBufferLong, setBufferShort, setBufferString, setDataType, setEndianess, shortToBytes, writeBytes, writeDouble, writeFloat, writeInt, writeLong, writeShort
-
-
-
-
Field Detail
-
axisOrientation
private int[] axisOrientation
R2L, L2R, A2P, P2A, I2S, and S2I orientations of x, y, and z axes.
-
axisOrientation2
private int[] axisOrientation2
When both qform_code > 0 and sform_code > 0, the axis orientation information corresponding to sform_code > 0 is placed in axisOrientation2
-
bufferByte
private byte[] bufferByte
A byte array of the size of the NIFTI header + 4 extension bytes.
-
coord_code
private int coord_code
If qform_code > 0, coord_code = qform_code. If qform_code <= 0 and sform_code > 0, coord_code = sform_code. coord_code has values for "Arbitrary X,Y,Z coordinate system", "Scanner based anatomical coordinates", "Coordinates aligned to another file's or to anatomical truth", "Talairach X,Y,Z coordinate system", and "MNI 152 normalized X,Y,Z coordinates".
-
fileDir
private java.lang.String fileDir
DOCUMENT ME!
-
fileHeader
private java.io.File fileHeader
DOCUMENT ME!
-
fileInfo
private FileInfoNIFTI fileInfo
DOCUMENT ME!
-
fileName
private java.lang.String fileName
DOCUMENT ME!
-
freq_dim
private int freq_dim
Bits 0 and 1 of the dim_info character contain the freq_dim information. 0 for "No frequency encoding direction is present", 1 for "Frequency encoding in the x direction", 2 for "Frequency encoding in the y direction", and 3 for "Frequency encoding in the z direction".
-
headerSize
private int headerSize
The size of the NIFTI-2 header must be set to 540 bytes.
-
image
private ModelImage image
DOCUMENT ME!
-
imageMax
private double imageMax
DOCUMENT ME!
-
imageMin
private double imageMin
DOCUMENT ME!
-
intentName
private java.lang.String intentName
The intent_name field provides space for a 15 character (plus 0 byte) name string for the type of data stored. Examples: - intent_code = NIFTI_INTENT_ESTIMATE; intent_name = "T1"; could be used to signify that the voxel values are estimates of the NMR parameter T1. - intent_code = NIFTI_INTENT_TTEST; intent_name = "House"; could be used to signify that the voxel values are t-statistics for the significance of activation response to a House stimulus. - intent_code = NIFTI_INTENT_DISPVECT; intent_name = "ToMNI152"; could be used to signify that the voxel values are a displacement vector that transforms each voxel (x,y,z) location to the corresponding location in the MNI152 standard brain. - intent_code = NIFTI_INTENT_SYMMATRIX; intent_name = "DTI"; could be used to signify that the voxel values comprise a diffusion tensor image.
-
LPSOrigin
private double[] LPSOrigin
The MIPAV origin value which is obtained from qoffset_x, qoffset_y, and qoffset_z when qform_code > 0 or from srow_x[3], srow_y[3], and srow_z[3] when sform_code > 0. The MIPAV value will equal the NIFTI value or the negative of the NIFTI value. The MIPAV value is stored using fileInfo.setOrigin(LPSOrigin) and matrix.setMatrix(LPSOrigin[0], 0, 3); matrix.setMatrix(LPSOrigin[1], 1, 3); matrix.setMatrix(LPSOrigin[2], 2, 3);
-
LPSOrigin2
private double[] LPSOrigin2
When qform_code > 0 and sform_code > 0, LPSOrigin derives the MIPAV origin from the qform information and LPSOrigin2 derives MIPAV origin from the sform information. LPSOrigin2 is derived from srow_x[3], srow_y[3], and srow_z[3]. The MIPAV value will equal the NIFTI value or the negative of the NIFTI value. MIPAV information is stored using matrix2.setMatrix(LPSOrigin2[0], 0, 3); matrix2.setMatrix(LPSOrigin2[1], 1, 3); matrix2.setMatrix(LPSOrigin2[2], 2, 3);
-
matrix
private TransMatrix matrix
MIPAV matrix used for storing qform or sform transformation information.
-
matrixTwoDim
private TransMatrix matrixTwoDim
MIPAV matrix used for storing qform or sform transformation information for 2D images.
-
matrix2
private TransMatrix matrix2
When qform_code > 0 and sform_code > 0, the qform transformation information is stored in matrix and the sform transformation information is stored in matrix2.
-
newMax
private double newMax
When the image data is rescaled by y = scl_slope * x + scl_inter, the image minimum or image maximum is rescaled to newMax.
-
newMin
private double newMin
When the image data is rescaled by y = scl_slope * x + scl_inter, the image minimum or image maximum is rescaled to newMin.
-
oneFile
private boolean oneFile
If true, header and data both stored in .nii file. If false, header stored in filename.hdr and data stored in filename.img.
-
origin
private float[] origin
DOCUMENT ME!
-
phase_dim
private int phase_dim
Bits 2 and 3 of the dim_info character contain the phase_dim information. 0 for "No phase encoding direction is present", 1 for "Phase encoding in the x direction", 2 for "Phase encoding in the y direction", and 3 for "Phase encoding in the z direction".
-
pixdim
private double[] pixdim
qfac is stored in the otherwise unused pixdim[0]. pixdim[i] = voxel width along dimension #i, i=1..dim[0] (positive) the units of pixdim can be specified with the xyzt_units field
-
qfac
private float qfac
The scaling factor qfac is either 1 or -1. The rotation matrix R defined by the quaternion parameters is "proper" (has determinant 1). This may not fit the needs of the data; for example, if the image grid is i increases from Left-to-Right j increases from Anterior-to-Posterior k increases from Inferior-to-Superior Then (i,j,k) is a left-handed triple. In this example, if qfac=1, the R matrix would have to be [ 1 0 0 ] [ 0 -1 0 ] which is "improper" (determinant = -1). [ 0 0 1 ] If we set qfac=-1, then the R matrix would be [ 1 0 0 ] [ 0 -1 0 ] which is proper. [ 0 0 -1 ] qfac is stored in the otherwise unused pixdim[0].
-
qform_code
private int qform_code
When qform_code > 0 the (x,y,z) coordinates are given by: [ x ] [ R11 R12 R13 ] [ pixdim[1] * i ] [ qoffset_x ] [ y ] = [ R21 R22 R23 ] [ pixdim[2] * j ] + [ qoffset_y ] [ z ] [ R31 R32 R33 ] [ qfac * pixdim[3] * k ] [ qoffset_z ] where the R rotation parameters are calculated from the quaternion parameters. qform_code has values for "Arbitrary X,Y,Z coordinate system", "Scanner based anatomical coordinates", "Coordinates aligned to another file's or to anatomical truth", "Talairach X,Y,Z coordinate system", and "MNI 152 normalized X,Y,Z coordinates".
-
qoffset_x
private double qoffset_x
Quaternion x shift
-
qoffset_y
private double qoffset_y
Quaternion y shift
-
qoffset_z
private double qoffset_z
Quaternion z shift
-
quatern_a
private double quatern_a
The orientation of the (x,y,z) axes relative to the (i,j,k) axes in 3D space is specified using a unit quaternion [a,b,c,d], where a*a+b*b+c*c+d*d=1. The (b,c,d) values are all that is needed, since we require that a = sqrt(1.0-(b*b+c*c+d*d)) be nonnegative.
-
quatern_b
private double quatern_b
Quaternion b parameter
-
quatern_c
private double quatern_c
Quaternion c parameter
-
quatern_d
private double quatern_d
Quaternion d parameter
-
r00
private double r00
The (proper) 3x3 rotation matrix that corresponds to quaternion [a,b,c,d] is [ a*a+b*b-c*c-d*d 2*b*c-2*a*d 2*b*d+2*a*c ] R = [ 2*b*c+2*a*d a*a+c*c-b*b-d*d 2*c*d-2*a*b ] [ 2*b*d-2*a*c 2*c*d+2*a*b a*a+d*d-c*c-b*b ]
-
r01
private double r01
The (proper) 3x3 rotation matrix that corresponds to quaternion [a,b,c,d] is [ a*a+b*b-c*c-d*d 2*b*c-2*a*d 2*b*d+2*a*c ] R = [ 2*b*c+2*a*d a*a+c*c-b*b-d*d 2*c*d-2*a*b ] [ 2*b*d-2*a*c 2*c*d+2*a*b a*a+d*d-c*c-b*b ]
-
r02
private double r02
The (proper) 3x3 rotation matrix that corresponds to quaternion [a,b,c,d] is [ a*a+b*b-c*c-d*d 2*b*c-2*a*d 2*b*d+2*a*c ] R = [ 2*b*c+2*a*d a*a+c*c-b*b-d*d 2*c*d-2*a*b ] [ 2*b*d-2*a*c 2*c*d+2*a*b a*a+d*d-c*c-b*b ]
-
r10
private double r10
-
r11
private double r11
-
r12
private double r12
-
r20
private double r20
-
r21
private double r21
-
r22
private double r22
-
patientOrientationString
private java.lang.String patientOrientationString
-
resolutions
private float[] resolutions
NIFTI pixdim information is converted into MIPAV resolutions information Only those pixdim[i] for which the niftiExtents[i] > 1 are passed into a resolutions[j] value.
-
scl_slope
private double scl_slope
If the scl_slope field is nonzero, then each voxel value in the dataset should be scaled as y = scl_slope * x + scl_inter where x = voxel value stored y = "true" voxel value Normally, we would expect this scaling to be used to store "true" floating values in a smaller integer datatype, but that is not required. That is, it is legal to use scaling even if the datatype is a float type (crazy, perhaps, but legal). - However, the scaling is to be ignored if datatype is DT_RGB24. - If datatype is a complex type, then the scaling is to be applied to both the real and imaginary parts.
-
scl_inter
private double scl_inter
-
sform_code
private int sform_code
When sform_code > 0, The (x,y,z) coordinates are given by a general affine transformation of the (i,j,k) indexes: x = srow_x[0] * i + srow_x[1] * j + srow_x[2] * k + srow_x[3] y = srow_y[0] * i + srow_y[1] * j + srow_y[2] * k + srow_y[3] z = srow_z[0] * i + srow_z[1] * j + srow_z[2] * k + srow_z[3] sform_code has values for "Arbitrary X,Y,Z coordinate system", "Scanner based anatomical coordinates", "Coordinates aligned to another file's or to anatomical truth", "Talairach X,Y,Z coordinate system", and "MNI 152 normalized X,Y,Z coordinates".
-
slice_dim
private int slice_dim
Bits 4 and 5 of the dim_info character contain the slice_dim information. 0 for "No slice acquisition direction is present", 1 for "Slice acquisition in the x direction", 2 for "Slice acquisition in the y direction", and 3 for "Slice acquisition in the z direction".
-
sliceCode
private int sliceCode
If this is nonzero, AND if slice_dim is nonzero, AND if slice_duration is positive, indicates the timing pattern of the slice acquisition. The following codes are defined: "Slice timing order is sequentially increasing", "Slice timing order is sequentially decreasing", "Slice timing order is alternately increasing", "Slice timing order is alternately decreasing", "Slice timing order is alternately increasing #2", "Slice timing order is alternately decreasing #2".
-
sliceDuration
private double sliceDuration
Time used to acquire 1 slice.
-
sliceEnd
private long sliceEnd
Slice timing pattern ends with slice = (sliceEnd + 1)
-
sliceStart
private long sliceStart
Slice timing pattern starts with slice = (sliceStart + 1)
-
sourceBitPix
private short sourceBitPix
Source bits per pixel = sourceBitPix
-
sourceType
private short sourceType
Original unscaled source data type
-
spaceUnits
private int spaceUnits
Bits 0, 1, and 2 of xyzt_units specify the units of pixdim[1..3], that is the spatial units of the nifti x, y, and z axes. 0 means "Spatial units are unknown", 1 means "Spatial units are meters", 2 means "Spatial units are millimeters", 3 means "Spatial units are micrometers".
-
srow_x
private double[] srow_x
1st row affine transform
-
srow_y
private double[] srow_y
2nd row affine transform
-
srow_z
private double[] srow_z
3rd row affine transform
-
timeUnits
private int timeUnits
Bits 3, 4, and 5 of xyzt_units specify the units of pixdim[4], that is the temporal units of the nifti time axis. Temporal units are multiples of 8. 0 means "Temporal units are unknown", 8 means "Temporal units are seconds", 16 means "Temporal units are milliseconds", 24 means "Temporal units are microseconds", 32 means "Temporal units are Hertz", 40 means "Temporal units are parts per million", 48 means "Temporal units are Radians per second."
-
tOffset
private double tOffset
The toffset field can be used to indicate a nonzero start point for the time axis. That is, time point #m is at t=toffset+m*pixdim[4] for m=0..dim[4]-1.
-
vox_offset
private float vox_offset
If the magic field is "n+1", then the voxel data is stored in the same file as the header. In this case, the voxel data starts at offset (int)vox_offset into the header file. Thus, vox_offset=352.0 means that the data starts immediately after the NIFTI-1 header. If vox_offset is greater than 352, the NIFTI-1 format does not say much about the contents of the dataset file between the end of the header and the start of the data. If the magic field is "ni1", then the voxel data is stored in the associated ".img" file, starting at offset 0 (i.e., vox_offset is not used in this case, and should be set to 0.0). In a .nii file, the vox_offset field value is interpreted as the start location of the image data bytes in that file. In a .hdr/.img file pair, the vox_offset field value is the start location of the image data bytes in the .img file. If vox_offset is less than 352 in a .nii file, it is equivalent to 352 (i.e., image data never starts before byte #352 in a .nii file). The default value for vox_offset in a .nii file is 352. In a .hdr file, the default value for vox_offset is 0. * vox_offset should be an integer multiple of 16; otherwise, some programs may not work properly (e.g., SPM). This is to allow memory-mapped input to be properly byte-aligned.
-
vox_offset2
private long vox_offset2
-
esize
private int esize
-
ecode
private int ecode
-
esizeArray
private int[] esizeArray
-
ecodeArray
private int[] ecodeArray
-
mindIdentArray
private java.lang.String[] mindIdentArray
-
bValueArray
private float[] bValueArray
-
azimuthArray
private float[] azimuthArray
-
zenithArray
private float[] zenithArray
-
dtComponentArray
private int[][] dtComponentArray
-
degreeArray
private int[] degreeArray
-
orderArray
private int[] orderArray
-
afniGroupArray
private java.lang.String[] afniGroupArray
-
asciiTextArray
private java.lang.String[] asciiTextArray
-
caretArray
private java.lang.String[] caretArray
-
jsonArray
private java.lang.String[] jsonArray
-
file
private java.io.File file
File object and input streams needed for NIFTI compressed files
-
fis
private java.io.FileInputStream fis
-
zin
private java.util.zip.ZipInputStream zin
-
gzin
private java.util.zip.GZIPInputStream gzin
-
bz2in
private CBZip2InputStream bz2in
-
noReadPrivateTags
private boolean noReadPrivateTags
-
-
Method Detail
-
isNIFTI
public static boolean isNIFTI(java.lang.String fName, java.lang.String fDir)
Method determines if the image format is NIFTI, so FileIO will call the appropriate FileNIFTI read method.- Parameters:
fName
- File name of image.fDir
- Directory.- Returns:
true
if NIFTI file,false
otherwise.
-
absoluteValue
public void absoluteValue(ModelImage image) throws java.io.IOException
Absolute value of image.- Parameters:
image
- Image to take absolute value of.- Throws:
java.io.IOException
- DOCUMENT ME!
-
flipTopBottom
public void flipTopBottom(ModelImage image) throws java.io.IOException
Flips image. NIFTI stores its data "upside down".- Parameters:
image
- Image to flip.- Throws:
java.io.IOException
- DOCUMENT ME!
-
flipTopBottom
public void flipTopBottom(float[] buffer, FileInfoNIFTI fileInfo) throws java.io.IOException
Flips image. NIFTI stores its data "upside down".- Parameters:
buffer
- Buffer holding image to flip.fileInfo
- File info structure for image to flip.- Throws:
java.io.IOException
- DOCUMENT ME!
-
finalize
public void finalize()
Prepares this class for cleanup. Calls thefinalize
method for existing elements, closes any open files and sets other elements tonull
.
-
getFileInfo
public FileInfoNIFTI getFileInfo()
Returns the FileInfoNIFTI read from the file.- Returns:
- File info read from file, or null if it has not been read.
-
getMatrix
public TransMatrix getMatrix()
- Returns:
-
getMatrix2
public TransMatrix getMatrix2()
-
readHeader
public boolean readHeader(java.lang.String imageFileName, java.lang.String fileDir, boolean niftiCompressed, boolean noReadPrivateTags) throws java.io.IOException
Reads the NIFTI header and stores the information in fileInfo.- Parameters:
imageFileName
- File name of image.fileDir
- Directory.niftiCompressed
- boolean indicating if file is a NIFTI compressed type- Returns:
- Flag to confirm a successful read.
- Throws:
java.io.IOException
- if there is an error reading the header- See Also:
FileInfoNIFTI
-
processJson
private void processJson(java.lang.String json, boolean noReadPrivateTags)
-
readImage
public ModelImage readImage(boolean one, boolean niftiCompressed, boolean noImportData, boolean noReadPrivateTags) throws java.io.IOException, java.lang.OutOfMemoryError
Reads a NIFTI image file by reading the header then making a FileRaw to read the image for all filenames in the file list. Only the one file directory (currently) supported.- Parameters:
one
- flag indicating one image of a 3D dataset should be read in.niftiCompressed
- boolean indicating if file being read is a compressed nifti .nii.gz, .nii.zip, or .nii.bz2- Returns:
- The image.
- Throws:
java.io.IOException
- if there is an error reading the filejava.lang.OutOfMemoryError
- See Also:
FileRaw
-
getFullBuffer
private byte[] getFullBuffer(java.io.InputStream in, byte[] buff, int off, int fullBufferSize) throws java.io.IOException
- Parameters:
in
-buff
-off
-fullBufferSize
-- Returns:
- Throws:
java.io.IOException
-
readImage
public void readImage(float[] buffer) throws java.io.IOException, java.lang.OutOfMemoryError
Reads a NIFTI image file by reading the header then making a FileRaw to read the file. Image data is left in buffer. If the fileInfo cannot be found, the header will be located and read first. Image is not 'flipped', and neither units of measure nor orientation are set.- Parameters:
buffer
- Image buffer to store image data into.- Throws:
java.io.IOException
- if there is an error reading the filejava.lang.OutOfMemoryError
- See Also:
FileRaw
-
readImage
public void readImage(float[] buffer, long userOffset) throws java.io.IOException, java.lang.OutOfMemoryError
Reads a NIFTI image file by reading the header then making a FileRaw to read the file. Image data is left in buffer. If the fileInfo cannot be found, the header will be located and read first. Image is not 'flipped', and neither units of measure nor orientation are set.- Parameters:
buffer
- Image buffer to store image data into.offset
- Offset a which to start reaing image, can be used to read in a specific slice/subBrick- Throws:
java.io.IOException
- if there is an error reading the filejava.lang.OutOfMemoryError
- See Also:
FileRaw
-
scale
public void scale(ModelImage image) throws java.io.IOException
Scales image.- Parameters:
image
- Image to scale.- Throws:
java.io.IOException
- DOCUMENT ME!
-
writeImage
public void writeImage(ModelImage image, FileWriteOptions options) throws java.io.IOException
Writes an NIFTI format type image.- Parameters:
image
- Image model of data to write.- Throws:
java.io.IOException
- if there is an error writing the file- See Also:
FileInfoNIFTI
,FileRaw
-
getAxisOrientation
private int[] getAxisOrientation(TransMatrix mat)
--------------------------------------------------------------------------- ! compute the (closest) orientation from a 4x4 ijk->xyz tranformation matrixInput: 4x4 matrix that transforms (i,j,k) indexes to (x,y,z) coordinates, where +x=Left, +y=Posterior, +z=Superior. (Only the upper-left 3x3 corner of R is used herein.) Note that this routine uses the MIPAV LPS convention as opposed to the NIFTI RAS convention. Output: 3 orientation codes that correspond to the closest "standard" anatomical orientation of the (i,j,k) axes. Method: Find which permutation of (x,y,z) has the smallest angle to the (i,j,k) axes directions, which are the columns of the R matrix. Errors: The codes returned will be zero.
\see "QUATERNION REPRESENTATION OF ROTATION MATRIX" in nifti1.h \see nifti_quatern_to_mat44, nifti_mat44_to_quatern, nifti_make_orthog_mat44 -------------------------------------------------------------------------
- Parameters:
mat
- DOCUMENT ME!- Returns:
- DOCUMENT ME!
-
getOffset
private int getOffset(FileInfoNIFTI fileInfo)
Helper method to calculate the offset for getting only the middle NIFTI image slice from the 3D file.- Parameters:
fileInfo
- File info.- Returns:
- offset
-
mat33_colnorm
private double mat33_colnorm(Jama.Matrix A)
max column norm of 3x3 matrix.- Parameters:
A
- DOCUMENT ME!- Returns:
- DOCUMENT ME!
-
mat33_polar
private Jama.Matrix mat33_polar(Jama.Matrix A)
Polar decomposition of a 3x3 matrix: finds the closest orthogonal matrix to input A (in both Frobenius and L2 norms). Algorithm is that from NJ Higham, SIAM JSci Stat Comput, 7:1160-1174.- Parameters:
A
- DOCUMENT ME!- Returns:
- DOCUMENT ME!
-
mat33_rownorm
private double mat33_rownorm(Jama.Matrix A)
max row norm of 3x3 matrix.- Parameters:
A
- DOCUMENT ME!- Returns:
- DOCUMENT ME!
-
updateorigins
private void updateorigins(FileInfoBase[] fileInfo)
Updates the start locations. Each image has a fileinfo where the start locations are stored. Note that the start location for the Z (3rd) dimension change with the change is the slice. The origin is in the upper left corner and we are using the right hand rule. + x -> left to right; + y -> top to bottom and + z -> into screen.- Parameters:
fileInfo
- DOCUMENT ME!
-
writeHeader
public boolean writeHeader(ModelImage image, int nImagesSaved, int nTimeSaved, java.lang.String fileName, java.lang.String fileDir, boolean doGzip, boolean oneFile) throws java.io.IOException
Writes a NIFTI header to a separate file.- Parameters:
image
- Image model of data to write.fileName
- File name.fileDir
- File directory.- Returns:
- Flag to confirm a successful read.
- Throws:
java.io.IOException
- if there is an error- See Also:
FileInfoNIFTI
-
writeHeader3DTo2D
private void writeHeader3DTo2D(ModelImage image, java.lang.String fileName, java.lang.String fileDir, FileWriteOptions options, boolean oneFile) throws java.io.IOException
This method is used when saving a 3D image in an array of 2D files. The file name has numbers appended to correctly order the images.- Parameters:
image
- the image dataset to be savedfileName
- the file namefileDir
- the file directoryoptions
- file options indicate how to save the image- Throws:
java.io.IOException
- DOCUMENT ME!
-
writeHeader4DTo3D
private void writeHeader4DTo3D(ModelImage image, java.lang.String fileName, java.lang.String fileDir, FileWriteOptions options, boolean oneFile) throws java.io.IOException
This method is used when saving a 4D image in an array of 3D files. The file name has numbers appended to correctly order the images.- Parameters:
image
- the image dataset to be savedfileName
- the file namefileDir
- the file directoryoptions
- file options indicate how to save the image- Throws:
java.io.IOException
- DOCUMENT ME!
-
getBufferByte
public byte[] getBufferByte()
-
-