Skip to content

Volumetric mixed effects #342

@danjgale

Description

@danjgale

I am trying to run a mixed effects model using Brainstat with volumetric data (NIFTIs). I was under the impression that Brainstat can do analyses on volumes (as per the companion paper and the documentation landing page). However, I'm not really sure how to go about this, as the tutorials and documentation are surface-centric.

Is the statistics module strictly surface data after all? If not, then what's the way to go about using SLM with volumetric data?

My code resembles this following basic example, with the ??? indicating where I am confused with regards to volumetric input:

from nilearn.maskers import NiftiMasker
from brainstat.stats.terms import FixedEffect, MixedEffect
from brainstat.stats.SLM import SLM

mask = # a binary brain mask NIFTI file

design = # a pandas dataframe of the design matrix with columns 'time', 'condition', and 'subject'

time = FixedEffect(design['time'])
condition = FixedEffect(design['condition'])
subject = MixedEffect(design['subject'])
model = condition + time + subject

contrast_condition = design['condition']
slm = SLM(
    model,
    contrast_condition,
    surf=???,
    mask=???,
    correction=["fdr", "rft"],
    cluster_threshold=0.01,
)

# get input voxel array required by .fit()
masker = NiftiMasker(mask_img=mask)
voxels = masker.fit_transform(imgs)

# pass in voxel array, which I think I should be doing?
slm.fit(voxels)

The last line raises an internal type error if I set surf=mask in SLM. If I take out surf and mask completely in SLM, I still get internal type errors. What am I missing in order for it to run on volumetric data, unless I am totally mistaken?

Example of the type error I get regardless:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[22], line 1
----> 1 slm.fit(voxels)

File ~/miniconda/envs/nhp-model2/lib/python3.10/site-packages/brainstat/stats/SLM.py:154, in SLM.fit(self, Y)
    152     Y_masked = Y.copy()
    153 self._linear_model(Y_masked)
--> 154 self._t_test()
    155 if self.mask is not None:
    156     self._unmask()

File ~/miniconda/envs/nhp-model2/lib/python3.10/site-packages/brainstat/stats/_t_test.py:45, in _t_test(self)
     42         sys.exit("Contrast is not estimable :-(")
     44 else:
---> 45     c = np.dot(pinvX, self.contrast)
     46     r = self.contrast - np.dot(self.X, c)
     48     if np.square(np.ravel(r, "F")).sum() / np.square(
     49         np.ravel(self.contrast, "F")
     50     ).sum() > np.spacing(1):

File <__array_function__ internals>:180, in dot(*args, **kwargs)

TypeError: can't multiply sequence by non-int of type 'float'

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions