Tract segment coloring in mrview

Hi, I have a tck file having 100 fibers where each fiber consists of 100 equidistant segments. Those segments have different metric values. How do we display the values along the individual fibers in mrview? I know scalar file can be loaded to color individual fiber but not sure how to color multiple fiber segments in each fiber. Many Thanks for help. Justin

Hi @Jeongwon_Jeong,

If, from the sampled values along each streamline, you compute some summary statistic (e.g. mean), then you will only have one value per streamline. If you want to have a unique value per streamline vertex, then you need to store such data using the Track Scalar File (.tsf) format (unfortunately this format is not yet described in the documentation). If you are using the tcksample command, simply omit the -stat_tck option (i.e. don’t compute a summary statistic per streamline), and specify a target output file path that includes the .tsf suffix, and the command will generate such a file; this can then be loaded within the mrview tractography tool in order to colour and/or threshold the display of streamlines.

Cheers
Rob

Hi, Rob
This worked for me well. Many Thanks, Justin

Hi @rsmith,

Would it be hard to make my own .tsf file? I have a set of values calculated in matlab that I want to use to color a .tck.

My current workaround is to create a .nii with those specific values and use tcksample to create a .tsf. However, even though the values in the .tsf end up close to the values I am looking for, they are not exactly the same because for some locations I have multiple .tck vertices in 1 voxel and I can obviously give 1 voxel only 1 value.

Thank you for your input!
Emilie

Hi Emilie,

It would probably not take a great deal of effort to modify the provided [write_mrtrix_tracks()] (https://github.com/MRtrix3/mrtrix3/blob/master/matlab/write_mrtrix_tracks.m) MatLab function to write .tsf files. Ultimately a .tsf file is just a .tck file that contains one value per streamline vertex rather than three. There’s a couple of other aspects of the header data that need to be conformed to in order for MRtrix3 tools to accept such a file. If you want to give it a red hot go, we can help out with any snags; you could even contribute it to the MRtrix3 repository later :+1:

Rob

Oops, I only just saw this! Thanks for the response. It was actually pretty easy to get this working. For testing purposes I made both a read_mrtrix_tsf.m and write_mrtrix_tsf.m. Happy to share it with you!

Briefly, I changed the script so the first line in the header now says ‘mrtrix track scalars’ and changed the fwrite commands such that it outputs data in 1 column instead of 3.

There is one difference. The data offset from the .tsf file created using tcksample is 516 bytes while my data offset is 492 byte. However, it just looks like you are padding with more zeros than I am with matlab. In any case, I don’t think this matters as long as the data offset is stored correctly in the header.

Thanks again!
Emilie

The data offset from the .tsf file created using tcksample is 516 bytes while my data offset is 492 byte. However, it just looks like you are padding with more zeros than I am with matlab. In any case, I don’t think this matters as long as the data offset is stored correctly in the header.

Yes, the only requirement is that the file offset indicated in the header is consistent with where the data are stored in the file. Any empty space between the “END” directive and the start of the data are inconsequential (apart from increasing the file size). Our code may introduce a little more padding because it includes the maximal possible required space for both the count and total_count fields.

My only other piece of advice is to guarantee that the data are word-aligned.

If you’d like to share, the best way is to fork the MRtrix3 repository on GitHub, commit your changes, and then create a Pull Request on the main MRtrix3 repository to pull your changes into our development branch. That way you get full credit for the contribution! Alternatively, “Gist” on GitHub is handy for sharing stand-alone code snippets.

Thanks Rob!

  1. I added the following line to the code: data_offset=data_offset+mod(data_offset,4); Is there a specific reason for taking the modulo again like in the file_base.h (data_offset += (4 - (data_offset % 4)) % 4;) It seems unnecessary? Note that write_mrtrix_tracks does not seem to guarantee word-aligned data.

  2. I did a text compare between a .tsf file created by MRtrix and by my matlab code and I noticed one more difference. At the end of each streamline I coded in a NaN, which gets written in Hexadecimal code as 00 00 C0 FF. However the .tsf file from MRtrix seems to have 00 00 C0 7F coded in here? It’s only 1 bit different and it seems to not cause any problems, however I figured I would point it out to you.

  3. Lastly, I noticed that if you use the matlab code read_mrtrix_tracks the roi: X fields are not dealt with appropriately. The structure will only have the last header.roi=X since it overwrites the prior ones.

I will pull the changes into the development branch once I am confident!
Thanks,
Emilie

Word alignment may offer potential performance advantages, but I’m not sure they’re going to be all that noticeable (we actually load the data into RAM for streamlines, it’s more likely to be beneficial for images that are accessed via memory-mapping). I’m not sure I’d be too fussed about this. The original script certainly didn’t bother, as you noted.

I’m not sure why the word alignment adjustment in the C++ code was written like that – it’s been a while since we wrote that, I’d need to reacquaint myself with it before I can give you a coherent answer…

On the difference in the NaNs, this recent thread will probably answer that question.

And finally: yes, the MATLAB function is indeed a bit simple, and was written quite a while ago, no doubt to address some specific need at the time. We welcome contributions to improve it! :wink:

Thanks! Interesting that the representation of NaN came up twice in two weeks.

Since I am sharing the read and write_mrtrix_tsf.m functions, I believe I can make some simple changes to the existing matlab functions to fix that problem :slight_smile:
Stay tuned!

2 Likes

data_offset=data_offset+mod(data_offset,4)

This doesn’t achieve the required operation. E.g.:

  • If data_offset % 4 == 1, then one wants to add 3 to the offset, in order for data_offset % 4 == 0.

  • If data_offset % 4 == 0, then one wants to not add anything to the offset.

Hence the ugly-looking:

data_offset += (4 - (data_offset % 4)) % 4

2 Likes

Hi @EmilieMcKinnon

Did you ever make your functions available? If so, where do they live?

Regards,
Claude

Files will be included in MRtrix3 in next release, but the raw files can also be accessed on the dev branch.

1 Like