Friday, April 26, 2013

working with NIfTI files in R: oro.nifti code


In the previous post I introduced a few ideas and conventions useful for working with NIfTI files (and most other neuroimaging formats). In this post I'll show how to read and write NIfTI files using R code, specifically, oro.nifti methods. The R code is available here, along with the nifti file it generates.

creating the NIfTI file

Before we write the NIfTI file, we need some data. For this demo, I copied the location of a few clusters from a real fMRI image, both the i,j,k coordinates (which cells of the 3d array correspond to the clusters) and the header information that puts those coordinates in the correct location in MNI space (copied from the spm-generated .nii containing the clusters).

Here is the NIfTI header information in the SPM8-generated image I used as the basis of the example, as shown in MRIcroN. I know that the image has been spatially normalized to match the MNI template.

In R, I start by making an empty 3d array to hold my data:  
img <- array(0, c(40,48,34));
I picked this size by reading off the i, j, k space dimensions of my template image.Then, we can set some numbers in the array to represent "activation clusters". See the code for the full version, but this just consists of change array values, like img[21,15,19] <- 1;.

Now, we have a 3d array of numbers.  The nifti function in the oro.nifti package collects the array and the header information to make a nifti that will be displayed properly. Again, see the code for the commented version, but here are the options I believe are correct for this image:
out.img <- nifti(img, datatype=64, dim=dim(img), 
srow_x=c(4,0,0,-78), srow_y=c(0,4,0,-112), srow_z=c(0,0,4,-50),
qoffset_x=-78, qoffset_y=-112, qoffset_z=-50, xyzt_units=2);
out.img@sform_code <- 4; 

out.img@qform_code <- 4;
pixdim(out.img)[1:8] <- c(1, 4,4,4,1, 1,1,1);  
# pixdim: qFactor, size in mm, num of frames, 1,1,1

Once the header information has been set, we create the image:
writeNIfTI(out.img, "d:/temp/fakeBrain");

reading the NIfTI file

Now we can read the nifti file back into R in.img <- readNIfTI("d:/temp/fakeBrain.nii.gz", reorient=FALSE); Once it's in R you can refer to the voxels by array location, as when creating the image (see the code for examples)

And, the image can be viewed in mricron (or other image viewers):

Above, you can see that the value at particular array indices match in R and MRIcroN. We can also display the clusters on the MNI template image, as below:

Notice that the X,Y,Z coordinates at the top of the window now refer to the template underlay, not the coordinates of the overlay. The voxel values at the bottom are correct, however.

warning

Always check the orientation of images, particularly after manipulating them in R. It is exceptionally easy for them to get left/right flipped, from handedness problems, software incompatibilities, incorrect header settings, etc.

update 2 April 2015: A HopStat and Jump Away has a post with many examples using oro.nifti functions, illustrating functions and procedures I didn't cover here.

update 21 January 2016: Changed the example code to have datatype=64 and just one row for the pixdim call.

update 29 August 2019: John Muschelli's neurobase vignette describes working with oro.nifti, plus the wrapped neurobase functions. RNifti can be MUCH faster for reading large NIfTI images.

No comments:

Post a Comment