I am using the Schaefer-Yeo 400 atlas (2018) and I was wondering if anyone has an easy implementation to find the number of voxels in each of these ROIs across 300 subjects. I can do this by looping over 400 individual ROI masks for each subject, but that seems very inefficient and I would be grateful for a more elegant solution. Does anyone have a good nipype/nilearn solution?
Thanks for this, I noticed a few rois with null values because of imperfect registration probably due to susceptibility distortion or movement. Do you know what tool I can use to extract voxel info from all ROIs in one go? Essentially, I am trying to do something like NiftiLabelsMasker but at the voxel level, or like NiftiMasker but extracting all voxel time-series for all ROIs rather than one at a time.
You can cast your subject’s masked mean EPI to boolean, use NiftiLabelsMasker to fit_transform it, and that will give you a number between 0 and 1 for each ROI which corresponds to the ratio of non-zero voxels to all voxels. You multiply that by the number of voxels in each ROI (as in my previous answer) and you will have the number of voxels within each mask that are not 0.
Hi Dangom, this seems to almost be working. The only thing is that voxel-ratios is binary rather than a continuous value between 0 and 1. This is because the sub_mean_mask gives binary values. Do you know how can I adjust this to get a ratio?
Also, roi_counts will count the background 0 too, so make sure to account for that.
And maybe test on an example where you know the voxel counts, just to make sure the code is doing what you expect.
for subject in fmri_files:
sub_id = os.path.basename(subject)[:7]
# mean EPI
sub_mean = image.mean_img(subject)
# cast mean EPI to boolean
sub_mean_mask = image.math_img("1. * i.astype(bool)", i=sub_mean)
# transform to atlas
masker = NiftiLabelsMasker(atlas_img)
voxel_ratios = masker.fit_transform([sub_mean_mask])
# multiple by the number of voxels in each ROI
n_voxels = voxel_ratios[0,:] * roi_counts[1:]
print(sub_id)
print(n_voxels)