Tck2connectome -edge_statistic & sift2 questions

Dear All,

  1. I wanted to make sure that the flag for tck2connectome (example),
    -edge_statistic mean (current mrtrix3 version)
    -metric meanlength (past mrtrix versions)
    are the same (that ‘mean’ refers to mean streamline length/edge and not the mean no of streamlines/edge).

  2. If the answer to ‘1’ is ‘yes’, following SIFT2, is tck2connectome using the streamline weights via -tck_weights_in flag in the calculation of -edge_statistic mean? This is relevant if one wants to use the edge mean lengths to estimate conduction delay times. SInce SIFT2 weighs an assumedly /partially erroneous .tck input, any statistic involving this less-than-perfect input (which presumably propagates to the tck2connectome input) should also be weighed, isn’t it?
    What I mean is that for a SIFT output
    -edge_statistic mean could be (streamline 1 length+ streamline 2 length)/2
    whereas for a SIFT2 output
    -edge_statistic mean could be (streamline 1 length * weight 1+ streamline 2 length * weight 2)/2 ~

Is this the case?
Thank you,


You can think of the old -metric meanlength option as having performed the equivalent of both -scale_length and -edge_statistic mean. Literally: Get the streamline lengths, calculate the mean.

If you were to set -edge_statistic mean alone, what you would get for each edge is:

sum of streamline values (each = 1 in the absence of any other scaling)
                        number of streamlines

, which would equal 1 for every edge with at least one streamline. Not a very interesting metric…

is tck2connectome using the streamline weights via -tck_weights_in flag in the calculation of -edge_statistic mean?

Yes. The streamline weight operates as an independent parameter when provided in any MRtrix3 command that has the -tck_weights_in option. This includes calculation of weighted means.

Assuming you use -scale_length -edge_statistic mean -tck_weights_in weights.csv, what you get for an edge with 2 streamlines is:

(length_1 * weight_1) + (length_2 * weight_2)
             weight_1 + weight_2

(note denominator compared to your expression)


Dear Rob,

Thank you for your clarifications.
Two more questions about SIFT

  1. For in house comparisons between seeding options, sift and sift2, is there any random no generator in the tckgen/sift scripts or we should expect exactly the same result one two runs using same syntax/identical inputs? Did not have time to test…
  2. how should one interpret the quantisation error warning in sift. I ve read the few posts on the matter, but I am not clear. If one starts with a high bar for tckgen (100M) ~adequate sampling/seeding, why should one settle for a target sift -term_number or -term_ratio options, if the scope is connectome comparisons and excluding computational cost from consideration. If connectome specificity is desired, at face value (Zalesky A. Neuroimage. 2016
    Nov 15;142:407-420.), running the script to termination or quantisation warning would get one closest, is this true?
    Again, leaving aside other scopes/reasons of using mrtrix3 connectome construction…
    Thank you,


  1. Any random number generation in MRtrix3 is seeded using the current time, so you will not get the exact same result between two executions, even in the absence of multi-threading. This includes probabilistic seeding mechanisms and algorithms in tckgen. SIFT and SIFT2 are however deterministic algorithms.

  2. If computational cost were of no consequence, then yes, one would likely want to run SIFT for as long as possible. Though this probably shouldn’t be interpreted as enhancing “specificity”: that sounds like interpreting the SIFT algorithm as removing false positives, which is a misunderstanding I see all the time but really isn’t true. It will only remove streamlines that traverse FOD lobes for which there are too many streamlines. Running SIFT for as long as possible will simply ensure that this mismatch between fibre density and streamlines density is minimised, and hence the reconstruction biases that lead to those mismatches are removed as much as possible. But it doesn’t really provide any guarantee that the precise trajectories those individual remaining streamlines take are biologically accurate.


Sorry, just a really minor, extremely pedantic correction to the above, purely to ensure the information is accurate:

That’s only true on Windows - these days, we rely on the C++11 std::random_device interface, which should use hardware instructions to obtain truly random seeds (on modern hardware, where available) - see code here. We currently don’t use this on Windows since MSYS2 (or rather MinGW) didn’t provide support for this interface at the time. However, having just checked, it looks like it does now work, so I’m going to make the behaviour identical on all platforms, relying exclusively on the C++11 standard std::random_device API from now on.

Thank you all very much for clarifications.