I’m running tckgen with all default options (just -maxlenght=250 and -number=100000 were explicit) and streamlines, with the exception of the loops, look generally fine for both reconstruction methods.
Looking at the documentation I’ve noted that the default theta should be 90deg x 0.1= 9deg that is less than my expectation.
I’ve tried by running FACT with custom angles (35deg and 45deg). The resulting streamlines (left for -angle 35 and right for -angle 45) are shown below. I’m really unable to understand why results are so different.

That’s a cute loop! Not sure I fully understand what you’re doing though. The fact algorithm expects a vector image as input. What happens after that is entirely dependent on how this vector file was generated. How did you produce it?

The fact that tensor_det also produces loops is not unexpected. These issues always crop up in tensor tracking (along with U-turns, etc), however hard you try to avoid them. If you set more stringent thresholds on the curvature, you end up with the kind of tracking you show with your 35° threshold: lots of false negatives, etc.

The other thing that might influence things is the termination criterion. In tensor_det, it’ll be the FA - not sure about FACT though…

To help figure this out, you’d really need to provide the full commands that were used, so we can have a better idea of what actually happened…

The loops were generated with the same commands but without the -angle option (Can I assume in this case -angle 9 (90 x stepsize/ voxelsize)? If yes, considering the loop into the first image, why a streamlines with a clear 90deg corner is allowed?

Below the streamlines carried out by Tensor_det with -angle 35 resulting really better than the FACT at the same angle.

I would expect the angle constraint to work quite differently between the tensor_det and fact algorithms, since those two algorithms themselves have a fundamental difference in their implementations.

With tensor_det, the diffusion tensor model is fitted at each sub-voxel position in space, the principal eigenvector is determined, and a small step in that direction is taken. Importantly, two streamline positions within the same voxel may yield slightly different eigenvectors, since the data used at each position is based on tri-linear interpolation of the eight surrounding voxels. Therefore, the angle constraint is applied between every consecutive step along a smoothly-varying curve. With a small step size, the angular constraint should be correspondingly small in order to restrict the minimal radius of curvature.

The fact algorithm is compatible with defining multiple fibre directions per voxel, and the number of fibres may also vary between adjacent voxels. This means that tri-linear interpolation cannot be applied. Once a streamline enters a voxel, and a fibre direction is selected within that voxel, the streamline continues precisely along that direction until the voxel is exited. This means the only time that the angular constraint ever has any influence is when the streamline moves from one voxel to another, and must select a new fibre direction. At this point, the streamline may experience a very tight curvature. So although the angle constraint is still ‘applied at each step’ in this algorithm, it is better thought of as the maximal angle between fibre directions in adjacent voxels.

Hope that sheds some light on what you’re observing
Rob

Hi Rob,
thank you for the clarification.
What is struggling me now is the observation of a non-monotonic behaviour of the FACT streamlines with increasing maximum angle. Below, as an example, the streamlines resulting from “tckgen vector.mif -algorithm FACT tractsFACT_b$SHELL.tck -seed_image $MASK -mask $MASK -angle x” that intersect the same spherical ROI are shown at different angle parameter.

I would expected, for what I’ve understood, an increase of ‘‘false positives’’ with increasing angle.
In the case of -angle 36 I’ve even obtained no streamlines (0 streamlines accepted).

OK, I had a brief chat about this with @rsmith yesterday, I think what’s going on here is that the angle threshold is set in a funny way for that algorithm, because it’s the only one that doesn’t interpolate over the source images (or rather, it uses nearest-neighbour interpolation). This means that the radius of curvature calculation shouldn’t apply here, as this would prevent sharp turns at voxel boundaries, as @rsmith mentioned previously. So for this algorithm, the calculation based on radius of curvature is ‘undone’, basically by scaling the deviation angle computed previously back up to what it would have been before that computation. This works fine when using default values, but not when the angle is set explicitly (since the radius of curvature computation is not applied in this case, the user-supplied value is used as-is).

Briefly, by default, the angle is set so that the maximum angle is 90° across a voxel, so the per-step angle threshold is set as 90 × step_size / vox_size. The FACT algorithm will take the incoming angle and scale it back up by vox_size / step_size. But if the user sets the value explicitly, this angle should be left as-is…

Clearly, we’ll need to fix this upstream. But in the meantime, you’ll need to adjust your values by a factor of 10 (assuming you use the default step size, which is 0.1 voxel). So your 9° was actually already 90°, and your 36° was 360° - this presumably wraps back around to 0°, which would explain your no-tracks problem…