Limit mask to 2000 most significant voxels?

I’m interested in creating a mask that contains the 2000 most significant voxels in one of my stats subbricks. A sluggish way to do this would be to go back and forth adjusting the threshold slider in the AFNI gui and adjusting the cluster threshold until I get a few clusters that remain that add up to 2000 voxels total and save this as a mask via the report window, but I’m hoping for something more efficient, as I will be doing this for 20 subjects. Is there a command I could run in the command line for this?

Thank you!

3dROIMaker should have a couple of options for doing so, depending on whether you want the top 2000 contiguous voxels, or the top 2000 located in any ol’ spot around the masked region:

From the function’s help:

-only_some_top N :after '-volthr' but before any ref-matching or
                       inflating, one can restrict each found region
                       to keep only N voxels with the highest inset values.
                       (If an ROI has <N voxels, then all would be kept.)
                       This option can result in unconnected pieces.
     -only_conn_top N :similar-ish to preceding option, but instead of just
                       selecting only N max voxels, do the following
                       algorithm: start the ROI with the peak voxel; search
                       the ROI's neighbors for the highest value; add that
                       voxel to the ROI; continue until either the ROI has 
                       reached N voxels or whole region has been  added.
                       The returned ROI is contiguous and 'locally' maximal
                       but not necessarily globally so within the original

Note: I’ve only ever tried this on a much smaller number N, so I don’t know how long it would take to calculate. And running it myself to find out would be way too much work.


Hi. I’m working with empracht on this project. Her goal is to identify the 2,000 most strongly activated voxels across multiple regions within a mask for pattern classification purposes. It looks like 3dROIMaker has a limit to the distance a voxel can be from a region to be considered a part of that region. So the “top 2,000” gets applied to each cluster separately rather than across all voxels in the mask. Is there a way to make 3dROIMaker (or another program) identify the top 2,000 without distance constraints?


I see, I didn’t realize you had discontiguous regions to start with-- yes, 3dROIMaker would call those separate ROIs.

However, if you run 3dROIMaker with “-refset WHOLEBRAIN_MASK” included, then I think it will actually label all of the regions within the whole brain mask as a single region, and then you should be all set for getting the top 2k within that archipelago?

Please let me know how that goes.


We’re getting closer. It assigned all voxels a value of 1, but still seems to be treating the clusters as separate, and we are still left with well over 2000 voxels total.

I see, yes, I guess internally the distinct clusters are still treated as separate ROIs when the search for high values is on, and then they get labelled contiguously after. I have a cheating way that might work:

In tcsh, it would be:

set thr = [VALUE]
3dcalc -a [DSET_IN] -expr "a*step(a-$thr)+0.01*${thr}*not(step(a-$thr))" -prefix [DSET_INTERMED]
3dROIMaker -inset [DSET_INTERMED] -prefix [TOP2000_DSET] -only_some_top 2000

Basically, the 3dcalc command thresholds your data set at the value you want, and then “pads” around it with tiny, subthreshold values so that the threshold islands aren’t actually separated, but the value in the padding will by definition be much less than the threshold value so none of that part will be included in your top 2000 values (as long as the total number of voxels in your thresholded islands is >=2000!!).

You can check that your “top 2000” values are in the islands (making hte islands with 3dROIMaker as usual), and making sure there are 2000 voxels in both outputs from these tests:

3dBrickStat -sum -non-zero -mask [TOP2000_DSET]  [TOP2000_DSET]  
3dBrickStat -sum -non-zero -mask [islands from regular 3dROIMaker thresholding of DSET_IN]  [TOP2000_DSET]


And note, I’m assuming that the threshold value is >0 here. Otherwise, I’d have to do more tests.


Paul’s 3dROIMaker probably will make this an easy task. If not, 3dRank might be useful here. See this old thread about using that for finding the n top voxels.,77586,77717#msg-77717

That appears to have worked!! Thank you SO much!!

-Emily & Phil

Thanks for posting this. I’ve seen a post that refers to that post in the past, but the link to the useful information was broken, and I couldn’t find it.

Rockin’, glad that worked.