Possible Bug: tckstats with tcknormalise


#1

Dear all,

I have been trying to calculate the normalised streamline length of fibers. The most obvious way to do this would be to first normalise the tck file using tcknormalise and then calculate the length with tckstats.

When looking further into the results, however, this process does not significantly change any of the streamline lengths. I suspect that this is because the tcknormalise procedure does not edit the step size (which is presumably used for the length calculation).

Does anyone have any good ideas of how to workaround this bug? Unless I am missing something, in which case I would be delighted if someone could point out my error.

Regards,
Claude


#2

Hi Claude,

Yes, you’re right. When step size information is present in the track file header, this is used to calculate the length of each streamline more quickly; but if the streamlines have undergone a non-linear transformation, such an approach is no longer accurate.

(The reason the lengths are not precisely equivalent is because the length of the first and last steps of the streamline are not guaranteed to be equal to the step size, so these two are always calculated explicitly, and those lengths will vary slightly between tracks with and without the normalisation applied)

If you’re feeling adventurous, you could use a hex editor to modify the track file header information: Set the values for both step_size and output_step_size to 0, making sure that the length of the header remains unchanged and the delimiters between key-value pairs remain intact. If performed correctly, that should cause tckstats to explicitly calculate the length of each streamline the slow way, i.e. summing the distance between each successive point along the entire length of each streamline.

I suspect it will be necessary in the future for tcknormalise to erase the step_size and output_step_size fields…

Rob


#3

Hi Rob,

Thanks for this.

explicitly calculate the length of each streamline the slow way, i.e. summing the distance between each successive point along the entire length of each streamline.

I have run something similar to this by loading the tracks into matlab and then doing the explicit length calculation using pdist. I might try to modify the header later and see what that does for me :slight_smile:

Cheers,
Claude


#4

Should anyone else want the matlab function used to calculate the tract lengths I am attaching it below (it’s rough but may be found useful):

function [streamline_length, mean_length, std_length, max_length, min_length]=get_tract_lengths(tract , file)

  % Distributed under the terms of the MIT license
  % function that accepts MRTrix track file into matlab and outputs length
  % statistics
  %
  % if a second input (file) is used (any value can be inputted), the function
  % will output a file with the track lengths

track=read_mrtrix_tracks(tract);

for i = 1:length(track.data)
    s=squareform(pdist(track.data{i}, 'euclidean')); 
    streamline_length(i) = sum(diag(s,1));
end

streamline_length=streamline_length';
mean_length = mean(streamline_length);
std_length = std(streamline_length);
max_length = max(streamline_length);
min_length = min(streamline_length);

if nargin > 1

    fid=fopen(file ,'w');
    formatSpec='%.3f\n';
    fprintf(fid,formatSpec,streamline_length);

    fseek(fid, -1, 'eof');
    fprintf(fid, ' ');
    fclose(fid);

end