NiftiMasker in niilearn

I am going over the tutorial:
https://nilearn.github.io/auto_examples/plot_decoding_tutorial.html
and I don’t understand NiftyMasker:
What are the “features” (columns) in the generate 2D array? And what are “samples” (rows) represent? (In the figure)

Usually to have a signal extracted from the raw data, we would run preprocessing, fmriprep, etc. Does NiftyMasker replaces it?

Let’s say I want to extract the time-series activity associated with a given trial of my task, how will I do this?

Ahoi hoi @orko,

did you already have a look at the NiftiMasker section in the docs and the corresponding examples (e.g. here)?

Assuming the following example:

from nilearn.input_data import NiftiMasker

func_file = 'my_cool_image.nii.gz'
mask_file = 'my_cool-mask.nii.gz'

masker = NiftiMasker(mask_img=mask_file)

func_data = masker.fit_transform(func_file)

where func_file is a 4D file containing 150 images and mask_file is a binary mask consisting of 200 voxels, the output of the fitted NiftiMasker masker is a 2D array with the shape 150 x 200, that is 150 samples (individual images in func_file) with 200 features (values of voxels within mask_file) each.

Preprocessing itself does not extract signal from raw data (except for example extracting confound related time series like e.g. CSF, WM, etc.) but prepares your raw data for further processing like statistical analyses of any type. Classic preprocessing steps for example are motion correction, slice timing correction, registration, smoothing and what have you. This (except smoothing) and a lot of other awesome things are done by fmriprep or package specific preprocessing pipelines (but if you can and your data allows it: use fmriprep) and NiftiMasker does not replace those steps. That being said: NiftiMasker supports feature preprocessing during the conversion from 3/4 D image files to 2D arrays. In more detail, this includes standardization, smoothing, low_pass, high_pass and detrending as described here. Applied to the example above, assuming you want to standardize and detrend your features (voxels), you would need to adapt the NiftiMasker like so:

masker = NiftiMasker(mask_img=mask_file, standardize=True, detrend=True)

For that you would need additional information, describing what trial of your task was presented when (like the *_events.tsv files in BIDS). With that, you can create a mask of the trials you are interested in and use that to index your extracted 2D array accordingly. An example for that is provided here.

HTH, cheers, Peer

@PeerHerholz Thanks for the amazing answer!

Couple of things I still didn’t entirely understand:

1.On the 2D array that is generated by NiftyMasker, how can I “translate” a column to a specific brain location of this voxel? and how can I translate a row index to TR/onset/etc?

  1. I still not quiet understand what is the meaning of the mask? what does it mean

“a mask is computed in the fit step”

How? based on what? In cases where a mask is provided, how did they know which mask to give? (Do I get it as an output from the scans/fmriprep? what are the considerations for choosing a mask?) So , in your example - what does

mask_file = ‘my_cool-mask.nii.gz’

represented and how was it produced?

  1. So the NiftyMasker should be given as an input the post-fmriprep functional image ?

Thank you very much!

Hi @orko,

With regards to your second question: “I still not quite understand what is the meaning of the mask?”

In order to convert your series of 3D volumes to one 2D data-array you (always) need a brain mask that ‘tells’ which voxels are brain-voxels and which voxels are just empty space in your 3D images. So now you have two options how to do this using NiftiMasker: Either you provide a mask on your own or you set mask_img = None. If you decide for the latter case, NiftiMasker will compute a brain mask according to mask_strategy (have a look at this keyword-argument for more information). In short, there are three ways how to end up with a computed brain-mask:

  1. masking.compute_background_mask,
  2. masking.compute_epi_mask,
  3. masking.compute_gray_matter_mask

While the first two strategies are data-driven, i.e. they estimate a brain-mask build using your images, the latter one uses an already set up MNI-152 whole-brain-mask to mask your data (please have a look at this post, the function name is a little bit misleading.

how can I “translate” a column to a specific brain location of this voxel?

If I understand you correctly, it seems like you are interested in extracting regions of interest (i.e. group voxels that belong to certain brain-regions based on an atlas?): In this case, nilearn has an own function for this called NiftiLabelsMasker (https://nilearn.github.io/modules/generated/nilearn.input_data.NiftiLabelsMasker.html)

1 Like

@JohannesWiesner Great! thank you very much!