Selecting voxels within distance range

Hi all!

I have a problem that looks a bit similar to the ongoing discussion here. I will quickly provide a summary of my work and what I have done so far. I work on a project that aims to validate a toolbox the goal of which is to generate a prediction about the white matter streamlines that will be affected following ischemic injury in a cohort of patients. The lesion volumes served as input for the toolbox and we have two DTI scanning sessions that we are comparing - session 1 and session 2. The output consisted of streamlines that will be affected by the stroke for each patient for each lesion volume (mostly comprising the ipsilesional CST). We also generated control output for this by swapping the simulated streamlines to the contralateral side (contralesional CST).

So far, I performed all the preprocessing using the MRTrix functionality, and generated maps of fa, md, ad and rd in order to compare these tensor parameters and their change from session 1 to session 2 post-stroke in both hemispheres.

I wanted to have a comparison between the affected hemisphere (affected CST) and control hemisphere (control CST) so I generated masks with mrcalc. In so doing, I generated two ROIs: the simulator output and its respective control.There were also some areas where the two outputs would overlap (cross) so I created a mask for the overlap containing the bilateral areas and the inverse mask of this overlap as these regions would not be perfect as lesion/control ROIs. When generating the masks and creating the overlap mask I used the following commands and everything worked fine. Then I generated the txt. files for the tensor-derived values and everything looked good.

mrcalc riwsub01ses2_lesion_simlesion_mean.nii 1.0 -gt riwsub01ses2_lesion_simlesion_mean_mask.nii

mrcalc sub01_lesion_roi.nii sub01_control_roi.nii -add sub01_overlapping_roi.nii

mrcalc sub01_overlapping_roi.nii 2. -lt sub01_invmask_roi.nii

Now I want to make the analysis along the predicted streamlines more focused along the CST (just like what one would do when manually drawing ROIs along the length of the CST to assess changes at various distances from the primary lesion). Thus, I want to threshold the simulation output files to focus on voxels with a distance larger than 0 until the threshold of 10mm, 20 mm, etc. (>1 and <10mm).

So I repeated the former steps that worked fine and thresholded the distance of 10 mm to begin with:

mrcalc riwsub01ses2_lesion_distance.nii 1.0 -gt 10.0 -lt riwsub01ses2_lesion_distance_mask.nii

However, this does not seem to work as the generated mask does not show a portion of the CST and the subsequently generated tensor txt. values (fa, md, ad and rd) are all 0. Do you have any advice on what could have gone wrong? Do I need to use tcksample and specify distances like that?

Thank you very much for your expert advice on this!

Best wishes,

Hi Ivana,

I’ve moved your question to a new topic since while the context is similar to the earlier post, I think the problem and solution are quite distinctly different.

Firstly, I’m going to assume that you have some mechanism for generating an image where the value contained in each voxel is the distance from some reference location in the image, and that you have verified that the contents of that image are as you expect.

If that’s the case, then it seems to me that the problem is here:

mrcalc riwsub01ses2_lesion_distance.nii 1.0 -gt 10.0 -lt riwsub01ses2_lesion_distance_mask.nii

Getting anything more than a single operation to work in mrcalc requires an understanding of its stack-based syntax. But here I think I can explain the point by breaking it in two.

The first operand that mrcalc sees is “-gt” (greater than); and at that point it has two inputs on its stack, “riwsub01ses2_lesion_distance.nii” and “1.0”. Let’s imagine that we were to do just this operation as its own mrcalc call:

mrcalc riwsub01ses2_lesion_distance.nii 1.0 -gt dist_gt_1_mask.mif

Output image “dist_gt_1.mif” is a binary mask, where voxels where the first operand ("riwsub01ses2_lesion_distance.nii") is greater than the second operand ("1.0") have a value of 1, and all other voxels have a value of 0.

Now we can do the second half of the split mrcalc call:

mrcalc dist_gt_1_mask.mif 10.0 -lt riwsub01ses2_lesion_distance_mask.nii

Now the problem presents itself: the “-lt” (less than) operator also generates a binary mask, which contains 1 when the first operand ("dist_gt_1_mask.mif") is less than the second operand ("10.0"), and 0 everywhere else. But the first operand only contains the values 0 and 1, because it’s a binary mask. Hence, the “-lt” operator will return true in every single voxel, and your output image will contain such.

What you need to do for your intended operation is something like this:

mrcalc riwsub01ses2_lesion_distance.nii 1.0 -gt riwsub01ses2_lesion_distance.nii 10.0 -lt -mult riwsub01ses2_lesion_distance_mask.nii

This does the following:

  1. Generate a mask of voxels where the distance to the lesion is greater than 1mm.
  2. Generate a mask of voxels where the distance to the lesion is less than 10mm.
  3. Obtain the intersection of these two masks.

Stacks of fun, right? :sweat_smile:

Hi Rob,

Thanks a lot for your response and detailed explanation!

I actually figured by trying a few things that the whole >1 and <10 cannot be carried out in a single line and performed the operations one after the other which is essentially similar to what you are now providing as a solution:

mrcalc riwsub01ses2_lesion_distance.nii 1.0 -gt dist_gt_1_mask.nii
mrcalc riwsub01ses2_lesion_distance.nii 10.0 -lt dist_lt_10_mask.nii
And then I multiplied the dist_gt_1_mask.nii and dist_lt_10_mask.nii masks. The output looks OK, so I reckon this approach is also correct, albeit a bit more lengthy…

Thanks again and this is indeed lots of fun! :nerd_face: