Nilearn: Masking in NiftiLabelsMasker doesn't work.

Created on 26 Nov 2019  路  6Comments  路  Source: nilearn/nilearn

I want to use NiftiLabelsMasker to extract voxels of interest using the Destrieux-Atlas. I am working with MRI-Data (not fMRI) so the 4th dimension represents different subjects, not different time points for a single subject. I created a dummy script and tried to use NiftiLabelsMasker on the OASIS dataset (which is available through nilearn.datasets.fetch_oasis_vbm). I also played with the mask image (I tried to create a mask that reduces the atlas image to regions 1 and 2). But it seems that the masking doesn't work: Although I provide NiftiLabelsMasker with destrieux_atlas_roi_mask I get 148 data columns (which seems to be all 148 regions reported in this paper). I expect NiftiLabelsMasker to output only 2 columns. Here's my code example:

from nilearn.image import load_img
from nilearn.datasets import fetch_atlas_destrieux_2009
from nilearn.datasets import fetch_oasis_vbm
from nilearn.image import math_img

from nilearn.input_data import NiftiLabelsMasker

# niftilabels masker cache
niftilabelsmasker_cache = './niftilabelsmasker_cache/'

# fetch OASIS dataset
oasis_img_paths = fetch_oasis_vbm(n_subjects=10)['gray_matter_maps']

# load destrieux atlas
destrieux_atlas_dict = fetch_atlas_destrieux_2009()
destrieux_atlas = load_img(fetch_atlas_destrieux_2009()['maps'])

# get only region 1 and 2
destrieux_atlas_roi_mask = math_img('np.where(((img == 1) | (img == 2)),1,0)',img=destrieux_atlas)

# extract data
niftilabelsmasker = NiftiLabelsMasker(labels_img=destrieux_atlas,
                                      mask_img=destrieux_atlas_roi_mask,
                                      memory=niftilabelsmasker_cache)

img_data = niftilabelsmasker.fit_transform(oasis_img_paths)

This issue might be related to #1056 and #1257.

Pinging @bthirion here to confirm that I posted this as issue on GitHub. I originally asked this question on neurostars.

Most helpful comment

Taking a look at other masker objects (e.g. NiftiMapsMasker), they all have the mask_img argment.
I think we should thus keep it for consistency (and thus fix the bug !)

All 6 comments

Indeed the mask_img does not seem to be used. I don't understand why this parameter exists; the mask should be everywhere the labels_img is different from the background label (0 by default). to use only two regions, set the other regions to 0 in the labels image

There is a use case for this matter: take all the voxels of region that fill in a grey matter mask.

There is a use case for this matter: take all the voxels of region that fill in a grey matter mask.

But in this case doesn't it seem more natural to define the region we
actually want, by taking the intersection with the mask, before giving
that to the LabelsMasker (which can be done very easily)?

anyway since the parameter exists I agree that the bug of ignoring the
mask should be fixed, but I find this interface accepting both ROIs and
a mask a bit awkward

OK, I 'm not sure what is 'natural' here, but we agree on the diagnosis and on the necessity to fix this.

I think this is a typical trade-off question: Do I want this functionality to be built-in or is it easy enough to calculate the necessary steps outside NiftiLabelsMasker to just leave it away (avoid over-engineering). In this case I would slightly tend to the first option, but I guess, I am also biased: e.g. for my project, I use information from meta-analyses to mask my images to specific voxels, but I also want to use an atlas to parcellate the images into regions and aggregate the voxel values. So I definitely need both functionalities and (personally) would be happy to have it included out-of-the-box in NiftiLabelsMasker.

There is a use case for this matter: take all the voxels of region that fill in a grey matter mask.

I am not sure about this argument: Aren't most atlases focusing either on grey or white matter in the first place (aka. they contain either zeros in the grey or white matter areas)? And if they are whole-brain-atlases, why would I need a second mask image then (apart from my use case of course, but then we end up, where I began).

Long story short, I agree that this bug should be fixed either way (take mask_img out of NiftiLabelsMasker or keep it in but make it work).

Taking a look at other masker objects (e.g. NiftiMapsMasker), they all have the mask_img argment.
I think we should thus keep it for consistency (and thus fix the bug !)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

nilover picture nilover  路  7Comments

NicolasGensollen picture NicolasGensollen  路  4Comments

alpinho picture alpinho  路  4Comments

jdkent picture jdkent  路  7Comments

kchawla-pi picture kchawla-pi  路  5Comments