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 - rick

NIFTI 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] invalid input: '<' 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:
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    private String[]
     
    private String[]
     
    private int[]
    R2L, L2R, A2P, P2A, I2S, and S2I orientations of x, y, and z axes.
    private int[]
    When both qform_code > 0 and sform_code > 0, the axis orientation information corresponding to sform_code > 0 is placed in axisOrientation2
    private float[]
     
    private byte[]
    A byte array of the size of the NIFTI header + 4 extension bytes.
    private float[]
     
     
    private String[]
     
    private int
    If qform_code > 0, coord_code = qform_code.
    private int[]
     
    private int[][]
     
    private int
     
    private int[]
     
    private int
     
    private int[]
     
    private File
    File object and input streams needed for NIFTI compressed files
    private String
    DOCUMENT ME!
    private File
    DOCUMENT ME!
    DOCUMENT ME!
    private String
    DOCUMENT ME!
     
    private int
    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 int
    The size of the NIFTI-2 header must be set to 540 bytes.
    private ModelImage
    DOCUMENT ME!
    private double
    DOCUMENT ME!
    private double
    DOCUMENT ME!
    private String
    The intent_name field provides space for a 15 character (plus 0 byte) name string for the type of data stored.
    private String[]
     
    private double[]
    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[]
    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
    MIPAV matrix used for storing qform or sform transformation information.
    private TransMatrix
    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
    MIPAV matrix used for storing qform or sform transformation information for 2D images.
    private String[]
     
    private double
    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
    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
     
    private boolean
    If true, header and data both stored in .nii file.
    private int[]
     
    private float[]
    DOCUMENT ME!
    private String
     
    private int
    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[]
    qfac is stored in the otherwise unused pixdim[0].
    private float
    The scaling factor qfac is either 1 or -1.
    private int
    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
    Quaternion x shift
    private double
    Quaternion y shift
    private double
    Quaternion z shift
    private double
    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
    Quaternion b parameter
    private double
    Quaternion c parameter
    private double
    Quaternion d parameter
    private double
    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
    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
    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
     
    private double
     
    private double
     
    private double
     
    private double
     
    private double
     
    private float[]
    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
     
    private double
    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
    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
    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
    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
    Time used to acquire 1 slice.
    private long
    Slice timing pattern ends with slice = (sliceEnd + 1)
    private long
    Slice timing pattern starts with slice = (sliceStart + 1)
    private short
    Source bits per pixel = sourceBitPix
    private short
    Original unscaled source data type
    private int
    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[]
    1st row affine transform
    private double[]
    2nd row affine transform
    private double[]
    3rd row affine transform
    private int
    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
    The toffset field can be used to indicate a nonzero start point for the time axis.
    private float
    If the magic field is "n+1", then the voxel data is stored in the same file as the header.
    private long
     
    private float[]
     
     

    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(String fName, String fDir)
    Constructs new file object.
  • Method Summary

    Modifier and Type
    Method
    Description
    void
    Absolute value of image.
    void
    Prepares this class for cleanup.
    void
    flipTopBottom(float[] buffer, FileInfoNIFTI fileInfo)
    Flips image.
    void
    Flips image.
    private int[]
    --------------------------------------------------------------------------- !
    byte[]
     
    Returns the FileInfoNIFTI read from the file.
    private byte[]
    getFullBuffer(InputStream in, byte[] buff, int off, int fullBufferSize)
     
     
     
    private int
    Helper method to calculate the offset for getting only the middle NIFTI image slice from the 3D file.
    static boolean
    isNIFTI(String fName, 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(String json, boolean noReadPrivateTags)
     
    boolean
    readHeader(String imageFileName, String fileDir, boolean niftiCompressed, boolean noReadPrivateTags)
    Reads the NIFTI header and stores the information in fileInfo.
    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
    Scales image.
    private void
    Updates the start locations.
    boolean
    writeHeader(ModelImage image, int nImagesSaved, int nTimeSaved, String fileName, String fileDir, boolean doGzip, boolean oneFile)
    Writes a NIFTI header to a separate file.
    private void
    writeHeader3DTo2D(ModelImage image, String fileName, 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, String fileName, String fileDir, FileWriteOptions options, boolean oneFile)
    This method is used when saving a 4D image in an array of 3D files.
    void
    Writes an NIFTI format type image.

    Methods inherited from class java.lang.Object

    clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

    • 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 invalid input: '<'= 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 String fileDir
      DOCUMENT ME!
    • fileHeader

      private File fileHeader
      DOCUMENT ME!
    • fileInfo

      private FileInfoNIFTI fileInfo
      DOCUMENT ME!
    • fileName

      private 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 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 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 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 String[] afniGroupArray
    • asciiTextArray

      private String[] asciiTextArray
    • caretArray

      private String[] caretArray
    • jsonArray

      private String[] jsonArray
    • file

      private File file
      File object and input streams needed for NIFTI compressed files
    • fis

      private FileInputStream fis
    • zin

      private ZipInputStream zin
    • gzin

      private GZIPInputStream gzin
    • bz2in

      private CBZip2InputStream bz2in
    • noReadPrivateTags

      private boolean noReadPrivateTags
  • Constructor Details

    • FileNIFTI

      public FileNIFTI(String fName, String fDir)
      Constructs new file object.
      Parameters:
      fName - File name.
      fDir - File directory.
  • Method Details

    • isNIFTI

      public static boolean isNIFTI(String fName, 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 IOException
      Absolute value of image.
      Parameters:
      image - Image to take absolute value of.
      Throws:
      IOException - DOCUMENT ME!
    • flipTopBottom

      public void flipTopBottom(ModelImage image) throws IOException
      Flips image. NIFTI stores its data "upside down".
      Parameters:
      image - Image to flip.
      Throws:
      IOException - DOCUMENT ME!
    • flipTopBottom

      public void flipTopBottom(float[] buffer, FileInfoNIFTI fileInfo) throws 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:
      IOException - DOCUMENT ME!
    • finalize

      public void finalize()
      Prepares this class for cleanup. Calls the finalize method for existing elements, closes any open files and sets other elements to null.
      Overrides:
      finalize in class FileBase
    • 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(String imageFileName, String fileDir, boolean niftiCompressed, boolean noReadPrivateTags) throws 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:
      IOException - if there is an error reading the header
      See Also:
    • processJson

      private void processJson(String json, boolean noReadPrivateTags)
    • readImage

      public ModelImage readImage(boolean one, boolean niftiCompressed, boolean noImportData, boolean noReadPrivateTags) throws IOException, 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:
      IOException - if there is an error reading the file
      OutOfMemoryError
      See Also:
    • getFullBuffer

      private byte[] getFullBuffer(InputStream in, byte[] buff, int off, int fullBufferSize) throws IOException
      Parameters:
      in -
      buff -
      off -
      fullBufferSize -
      Returns:
      Throws:
      IOException
    • readImage

      public void readImage(float[] buffer) throws IOException, 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:
      IOException - if there is an error reading the file
      OutOfMemoryError
      See Also:
    • readImage

      public void readImage(float[] buffer, long userOffset) throws IOException, 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:
      IOException - if there is an error reading the file
      OutOfMemoryError
      See Also:
    • scale

      public void scale(ModelImage image) throws IOException
      Scales image.
      Parameters:
      image - Image to scale.
      Throws:
      IOException - DOCUMENT ME!
    • writeImage

      public void writeImage(ModelImage image, FileWriteOptions options) throws IOException
      Writes an NIFTI format type image.
      Parameters:
      image - Image model of data to write.
      Throws:
      IOException - if there is an error writing the file
      See Also:
    • getAxisOrientation

      private int[] getAxisOrientation(TransMatrix mat)
      --------------------------------------------------------------------------- ! compute the (closest) orientation from a 4x4 ijk->xyz tranformation matrix
             Input:  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, String fileName, String fileDir, boolean doGzip, boolean oneFile) throws 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:
      IOException - if there is an error
      See Also:
    • writeHeader3DTo2D

      private void writeHeader3DTo2D(ModelImage image, String fileName, String fileDir, FileWriteOptions options, boolean oneFile) throws 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 saved
      fileName - the file name
      fileDir - the file directory
      options - file options indicate how to save the image
      Throws:
      IOException - DOCUMENT ME!
    • writeHeader4DTo3D

      private void writeHeader4DTo3D(ModelImage image, String fileName, String fileDir, FileWriteOptions options, boolean oneFile) throws 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 saved
      fileName - the file name
      fileDir - the file directory
      options - file options indicate how to save the image
      Throws:
      IOException - DOCUMENT ME!
    • getBufferByte

      public byte[] getBufferByte()