Unclear about signal_scaling options in FirstLevelModel


My goal is to work with data and model fit after grand mean scaling. My definition of grand mean scaling is when all voxels and time points are scaled by a single value so we can compare results across runs/subjects. My interpretation of the help for signal_scaling is 0 will simply mean scale (does that actually mean dividing by the mean or subtracting the mean? I suppose division so parameters are closer to percent signal change?), 1 will scale each time point (aka intensity normalization…similar to modeling a global mean, right?), and (0,1) says scales with respect to voxels and time, calling this Grand Mean Scaling, but this isn’t clear to me. So it isn’t combining the mean scaling over time with that over space, right? (Help is pasted in below).
Q1: Is grand mean scaling in the help the same as my definition (scale all time points and voxels by one number)?
Q2. For further analyses I need to compare the model fit to the data. Do I have access to the scaled data that served as input to the model? In this tutorial it appear the data I feed into the model are used to compare to the model fit, but I’m assuming the data I’m feeding in have not been scaled (they are output from fmriprep) and are scaled within the model fit steps somewhere.


signal_scaling False, int or (int, int), optional

If not False, fMRI signals are scaled to the mean value of scaling_axis given, which can be 0, 1 or (0, 1). 0 refers to mean scaling each voxel with respect to time, 1 refers to mean scaling each time point with respect to all voxels & (0, 1) refers to scaling with respect to voxels and time, which is known as grand mean scaling. Incompatible with standardize (standardize=False is enforced when signal_scaling is not False). Default=0.

Hi Jeannette,
‘0’ means division by per-voxel mean. Indeed it makes parameters close to psc.
‘1’ means division by image average for each time point
‘(0, 1)’ means division by global average across time and voxels.
I think that the latter corresponds to your definition of grand mean scaling.

Q2: No, I don’t think that the scaled data are stored anywhere. The problem is that we wanted to have the code memory-friendly…
But you can call directly nilearn.glm.first_level.mean_scaling after reading the data with NiftiMasker. Please open an issue if you find that behavior non-satistfactory. Best,

Thanks Bertrand!

I’ve been knee deep in the code today and that has been very useful. FWIW, the data seem to be shifted by the corresponding mean as well (if anybody cares!). Specifically (from the code)
Y = 100 * (Y / mean - 1)

I may just be using a different definition of scaling. I typically only think of it as multiplication.

Thanks again,