NiftiMasker return voxel timeseries corresponding to multiple ROIs

NiftiMasker only accepts a binary mask, however, I would like to return the voxel timeseries separated by ROIs. There is too much overhead involved with resampling the image if I instantiate a new mask for each region. For example, the code below takes about 1 hour per image:

for roi in rois:
    atlas_roi = math_img('img == %d" %roi, img=atlas_img)
    roi_mask = NiftiMasker(mask_img=atlas_roi, standardize=True)
    roi_timeseries = roi_mask.fit_transform(fmri_img)

If I binarize my current atlas, I can efficiently retrieve all of the voxels for the entire atlas, but I lose information as to which ROI each voxel belongs to. atlas_timeseries has shape (n_timesteps, n_voxels). This code takes only 3 minutes per image:

atlas_mask = NiftiMasker(mask_img=binarized_atlas_img, standardize=True)
atlas_timeseries = atlas_mask.fit_transform(fmri_img)

Ideally, I would like to only call NiftiMasker once with a non-binary mask, and return a list with dimensions (n_rois, n_timesteps, n_voxels_in_roi_i). How would this be achievable?

Hi @Jamiesonor have you looked into using either nilearn.maskers.NiftiLabelsMasker or nilearn.maskers.NiftiMapsMasker ?

You can also see this example for reference: Nilearn: Statistical Analysis for NeuroImaging in Python — Machine learning for NeuroImaging

Thanks for the response @ymzayek.

NiftiLabelsMasker and NiftiMapsMasker don’t return timeseries for individual voxels, but instead return timeseries that are aggregates of all the voxels in each region. I don’t want a single timeseries for each region, I need individual timeseries for each voxel in the atlas, such as what NiftiMasker would return, but I just need to figure out how to assign each voxel to its corresponding region.

Yes that is true. In that case I’m not sure it’s possible at the moment without looping. @bthirion can you confirm?

The easiest solution to your problem is to extract all time series from the binary mask and then select the rois using numpy indexing. For this, you need to also mask your roi image and use the resulting roi index array to extract per-roi time series. Does that makes sense ?