Format of track file


The track point data is stored as one binary file, with the filename extension of .trk. The first 1000 bytes consist a header with the following structure -

struct TRACK_HEADER
{
    char           id_string[6];      // first 5 chars must be "TRACK"
    short int	   dim[3];	      // dimensions
    float	   voxel_size[3];     // voxel size
    float	   origin[3]	      // origin. default is 0,0,0.
    short int	   n_scalars;	      // number of scalars saved per point besides xyz coordinates. 
    char	   pad1;
    unsigned char  has_max_min;       // indicate there are max and min values of the scalars stored in the header
    float	   max[10];	      // maximum and minimum values of all the scalars. can store up to 10 pairs
    float	   min[10];	      // these are yet to be implemented
    char	   reserved[868];
    int		   n_count;	      // total number of tracks. if 0, number of tracks was not recorded.
    int		   version;           // version number
    int		   hdr_size;	      // size of the header. used to determine byte swap
};

Following the header are the track point data, in a formation of one integer (with value of n, for example) followed by n tuples. Each tuple consists of 3 float numbers (or 3+n_scalars float numbers if n_scalars is not 0, while the first 3 numbers always represent x/y/z coordinates of the point). And repeat on till the end of the file.


Download C++ code to read and write track file. (WARNING: There is absolutely no warranty or liability for this code. Use it at your own risk.)

TrackIO.h
TrackIO.cpp
ByteSwap.h

Here are a few sample lines to read track file -

include "TrackIO.h"
      
...

CTrackReader reader;
TRACK_HEADER header;
if (!reader.Open("foo.trk", &header))
{
	printf(reader.GetLastErrorMessage());
	return;
}
...
          
int cnt;
if (ignore_scalars)
{
        // The DTI task card does not save any scalar values to track file.
        // So scalars are always ignored while reading DTI task card generated track files.
	while (reader.GetNextPointCount(&cnt))
	{
		float* pts = new float[cnt*3];
		reader.GetNextTrackData(cnt, pts);
		...
		process_point_data(...);
		...
		delete[] pts;
	}
}
else
{
	while (reader.GetNextPointCount(&cnt))
	{
		float* pts = new float[cnt*3];
		float* scalars = new float[cnt*header.n_scalars];
		reader.GetNextTrackData(cnt, pts, scalars);
		...
		process_point_and_scalar_data(...);
		...
		delete[] pts;
		delete[] scalars;
	}
}

reader.Close();