Tcksift with "seed masking"

Hi all,
I’m currently trying to use tckgen and tcksift output to create a connectome based on AAL atlas (I’m creating the conectome itself with a different tool).
The problem is that right now I get tracts with endpoints both within and outside the atlas regions, meaning the final connectome will have a varying amount of tracts, depending on how many were generated inside the mask.
I would like to be able to generate the tracts on a whole-brain basis, but then screen out only the ones that start and end inside a given mask so that I get sifted tracts that are all inside my connectome nodes.

I know I can do one of the folowing:

  1. use tckgen with the -seed_image option
    ~~ edit~~:
    seems like -seed_image affects the seeds but doesn’t help me with endpoints inside the mask. is there an option that lets me define both endpoints of the tract to be in a mask?
    ~~
  2. use tckgen, then manually choose only the tracts with endpoints in the mask, and only then use tcksift for a set number of tracts.

I was wondering if there is a way to achieve this (a set number of sifted tracts with endpoints in a given mask) during the sift stage, and not during the tract generating stage.

many thanks

(I’m creating the conectome itself with a different tool)

:sob:

I would like to be able to generate the tracts on a whole-brain basis, but then screen out only the ones that start and end inside a given mask so that I get sifted tracts that are all inside my connectome nodes.

If I could maybe rephrase this slightly: you want only those streamlines for which both endpoints are inside one of the connectome parcels?

If that’s the case, then:

seems like -seed_image affects the seeds but doesn’t help me with endpoints inside the mask

-seed_image - combined with -seed_unidirectional - will guarantee that the first point of the streamline lies within the seed image.

The trouble then is how to select only streamlines for which the endpoint lies inside one of the regions. tckedit does have the -ends_only option, but that will accept any streamlines for which either the starting vertex or the ending vertex is inside the -include region.

I was wondering if there is a way to achieve this (a set number of sifted tracts with endpoints in a given mask) during the sift stage, and not during the tract generating stage.

I think this is in fact possible; it just requires some gymnastics:

  1. tck2connectome, using -assignment_end_voxels so that for each streamline only the voxels in which the two endpoints reside will be checked for parcellation nodes, and also using the -out_assignments option;

  2. connectome2tck, using -files single and -keep_self and no other options.

This should - I think - give you a new track file that contains only those streamlines that were successfully assigned to a parcel at both endpoints. You’d want to verify this yourself though.

thanks for the answer!

you want only those streamlines for which both endpoints are inside one of the connectome parcels?

that is correct. I also need a set number of streamlines, so that all connectomes are based on the same sized data.

I think this is in fact possible; it just requires some gymnastics:

  1. tck2connectome , using -assignment_end_voxels so that for each streamline only the voxels in which the two endpoints reside will be checked for parcellation nodes, and also using the -out_assignments option;
  2. connectome2tck , using -files single and -keep_self and no other options.

this makes sense. I’m assuming I’ll still have to sift the results after that, though?
I tried doing this on a smaller set of tracts (as a test) but seem to still get some tracts that end outside the nodes:
image .

I also tried extracting the streamlines that start and end in a node with an external python code I wrote (usinf nibabel). that actually seemed to work, but then I get the following error during the sift phase:

tcksift: [WARNING] filtering has reached quantisation error but desired termination criterion has not been met;
tcksift: [WARNING] disabling cost function quantisation check
tcksift: [WARNING] algorithm terminated before any user-specified termination criterion was met

I assumed this has to do with the fact that i start off with much less tracts than before, but generating more tracts didn’t seem to solve this.

I think this is in fact possible; it just requires some gymnastics:

  1. tck2connectome , using -assignment_end_voxels so that for each streamline only the voxels in which the two endpoints reside will be checked for parcellation nodes, and also using the -out_assignments option;
  2. connectome2tck , using -files single and -keep_self and no other options.

rechecked that. It still gives me any tract with any endpoint in a node, and not both :frowning:
in case anyone else tries to do this, I solved this by using the -nodes and -exclusive options, giving a list of all my nodes as -nodes. this works for the connectome, but still results in a quantisation error during sifting, which I don’t quite understand.

I also need a set number of streamlines, so that all connectomes are based on the same sized data.

Technically you could do this using -term_number in tcksift. It would however mean that the “extent” of filtering may differ between subjects. Could you not simply e.g. calculate the fraction of total streamlines for each subject that are within each edge, which would essentially “regress out” differences in total streamline count?

I’m assuming I’ll still have to sift the results after that, though?

Assuming you want the benefits of SIFT, then yes. Otherwise, what you’re doing here is an independent step within a set of steps in your processing chain, and should be considered as such. There’s potential interactions between this step and the assumptions underlying the SIFT model that should be considered; what’s being done here is typically done implicitly during the connectome construction step, effectively interpreting that streamlines not included in the connectome may potentially represent valid white matter connections but for which the corresponding parcels are not defined in the atlas, whereas in your approach such connections are removed entirely prior to imposing the SIFT model, which is equivalent to asserting that there are no white matter connections outside of your prescribed parcellation.

I get the following error during the sift phase:

Whether or not you receive these warnings depends principally on the ratio between the number of input and output streamlines. The first tends to kick in at ratios over 10; the latter is usually pretty hard to hit, because it means that the algorithm literally cannot find a single streamline that it can remove that would reduce the cost function.

rechecked that. It still gives me any tract with any endpoint in a node, and not both :frowning:
in case anyone else tries to do this, I solved this by using the -nodes and -exclusive options, giving a list of all my nodes as -nodes.

Yes, that was going to be my next suggestion if the first didn’t do as intended. You should be able to exploit the number sequence notation to avoid explicitly listing every single node number.

Thank you so much for the tips and help! this solved most of the problems I was healing with.