Extracting volumes from a 4D nifti file

With the introduction of the Nifti format, a series of functional MRI volumes can now be stored as a single 4D (3D space + 1D time) nifti file. This is very handy especially when an experiment involves hundreds of image volumes. However, there are times when some of the volumes within this 4D image file need to be excluded in the analysis. An example is when we need to exclude volumes with high levels of head motion in a process called scrubbing. In this case, some of the volumes associated with high motion need to be removed from the 4D nifti file. Another example is when few initial volumes are excluded in the analysis to account for the initial scanner inhomogeneity.

In this post, I will describe a Matlab script that can be used to extract volumes from a 4D nifti file and saved the extracted volumes into another 4D nifti file. This script will use some functions from SPM to read the header information from the 4D nifti file and write back the extracted volumes into another 4D nifti file. So make sure that SPM is in your Matlab path before running this script. The full script is given below.

function abk_xtract4D(fname,xvols,ofn)
% function abk_xtract4D(fnames,xvols,ofn)
%
% Extracts volumes from a 4D nifti file and store them in another 
% 4D nifti file.
%
% fname = the filename of the original 4D nifti file
% xvols = a vector containing the volumes to extract
% ofn = output filename (optional). If not specified, the output filename
% will be the same as the input but with an 'x' affix to the filename.

% check if the 2 required input parameters are given, if not return
if nargin < 2
    fprintf('USAGE: abk_xtract4D(fname,xvols)\n');
    return;
end

% check if output filename is specified, if not use input filename
if nargin < 3
    [dn,fn,ext] = fileparts(fname);    
    ofn = fullfile(dn, ['x' fn ext]);
end

% check if file exist
if exist(fname,'file') == 2
    mx = max(xvols);
    vol = spm_vol(fname);
    len = length(vol);
    if mx > len
        fprintf('Less volume in %s than requested\n',fname);
        return;
    end
    
    tvol = vol(xvols);
    spm_file_merge(tvol,ofn,0);
else
    fprintf('File %s not found\n',fname);
end
end

The script accepts two required parameters, fname and xvols. fname is the filename of the 4D image where the volumes will be extracted. xvols is a vector containing the volumes to extract specified by the volume’s index in the 4D file. For example, 1 for the 1st volume, 2 for the 2nd, and so on. The file also accepts a 3rd optional parameter, ofn, which will be used as the filename of the 4D nifti file containing the extracted volumes. If this parameter is not specified, the output filename is the same as the input filename with the letter ‘x’ affix to the original.

Line 1 in the code is the usual function declaration in Matlab. This is followed by several lines of comments starting with the % character (lines 2 – 10). In line 13, the number of supplied parameters is checked. If less than 2, a message regarding the proper usage of the function is displayed and the function returns or quits (lines 14 – 15). In line 19, the script checks if the 3rd optional parameter is supplied. If not, the output filename is set to be the same as that of the input with the letter ‘x’ affixed. In line 25, the script checks whether the specified input file exist. If the file exist, the script first identifies the maximum volume number that will be extracted (line 26) from xvols, then reads the header information of the 4D nifti file (line 27), identifies the total number of volumes in the file (line 28), and checks if the maximum volume number requested does not exceed the total number of volumes in the original file (line 29). If it does, a message is displayed and the function returns. Otherwise, the header information of the requested volumes is copied into tvol from the vol variable (line 34). Now that we have the header information for the volumes we need, we only need to write the image back using SPM’s spm_file_merge() function, specifying the header information in tvol, the output filename in ofn, and 0 for the data type to indicate to the function to use the same data type as specified in tvol.

To use this function, just type in Matlab the function name with the appropriate input parameters, for example,

>> abk_xtract4D('input4D.nii', [6:180])

This will output a 4D nifti file containing the 6th volume up to the 180th volume of input4D.nii into a file called xinput4D.nii.

And that’s it. Have questions, leave a comment.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.