Code covered by the BSD License  

Highlights from
3D Cube Slice

from 3D Cube Slice by Oren Rosen
Enables reading 2 dim slices of 3 dim matrix stored in MAT file

ReadCubeSlice(mat_filename,dim,indx)
function slc = ReadCubeSlice(mat_filename,dim,indx)
% Oren Rosen
% The MathWorks
% 11/09/2006
%
% This function will read individual 2-dim slices of a 3-dim matrix stored
% in the MAT file 'matfilename' without loading the whole file into MATLAB
% memory. The user specifices which dimension to fix ( dim = 'x','y','z' ) 
% and which particular slice ( indx = 1,2,.. ect.)
%
% NOTE: THIS REQUIRES THAT THE MAT FILE IS SAVED UNCOMPRESSED USING THE -v6
% OPTION!!!
%
% This function makes use of the MATLAB central function where.m written by
% Malcolm Lidierth. This function provides critical information regarding
% memory allocation and positioning of data within the MAT file.
%
% The algorithm for extracting the 2-dim slice is based on how a 3-dim
% matrix is stored in the MAT file. The elements are stored consecutively
% by column then row, then depth (x,y,z). This requires data to be read in
% blocks whose size and location depends on the particulars of the slice.
% The number of blocks and size of each will effect the performance of this
% function. For example, slicing along the x-axis takes the most time since
% each block is a single element. Slicing along the z-axis is most
% efficient since all the data is stored in one block. See STEP 2 for the
% details.


% STEP 1: Extract information about how data is stored in MAT file.

% data set memory information.
mem_info = where(mat_filename);

% 'dataset_location' is relative position of the actual data within the MAT file.
dataset_location = mem_info.DataOffset{1}.DiscOffset;

% 'datatype' is numeric type of numbers in the data set.
% This includes information about how the data is actually
% stored in the MAT file and how it will be stored in the MATLAB workspace.
datatype = [mem_info.DiscClass{1} '=>' mem_info.class];

% Number of bytes each element occupies in the MAT file.
num_bytes_per_element = sizeof(mem_info.DiscClass{1});

% Size of each dimension of data set.
dimx = mem_info.size(1);
dimy = mem_info.size(2);
dimz = mem_info.size(3);


% STEP 2: Extracting the appropriate 2-dim slice of data requires
% selectively reading blocks of memory out of the MAT file. Four pieces of
% information are necessary:
%
% (A) 'first_element'           - location of the first element in the slice
% (B) 'num_element_to_skip'     - number of elements between each block
% (C) 'num_element_in_block'    - number of elements in each block
% (D) 'slice_dim'               - The dimensions of the slice
%
% These all depend on which dimension the slice is taken and which
% particular slice.

switch dim
    case 'x'
        first_element = indx - 1;
        num_element_to_skip = dimx - 1;
        num_element_in_block = 1;
        slice_dim = [dimy,dimz];
    case 'y'
        first_element = (indx - 1)*dimx;
        num_element_to_skip = dimx*( dimy - 1 );
        num_element_in_block = dimx;
        slice_dim = [dimx,dimz];
    case 'z'
        first_element = (indx - 1)*dimx*dimy;
        num_element_to_skip = 0;
        num_element_in_block = dimx*dimy;
        slice_dim = [dimx,dimy];
end

% Convert this information into byte form appropriate for file IO functions
starting_point = dataset_location + num_bytes_per_element*first_element;
skip_size = num_bytes_per_element*num_element_to_skip;
block_size = [num2str(num_element_in_block) '*' datatype];


% STEP 3: Read data from MAT file.

% Open MAT file
fid = fopen(mat_filename,'r');

% Go to first element of slice in the data set.
fseek(fid,starting_point,'bof');

% Read all data at once.
slc = fread(fid,slice_dim,block_size,skip_size);

% Close MAT file
fclose(fid);

Contact us at files@mathworks.com