예제 #1
0
def test_explicit_fixed_effects():
    """ tests the fixed effects performed manually/explicitly"""
    with InTemporaryDirectory():
        shapes, rk = ((7, 8, 7, 15), (7, 8, 7, 16)), 3
        mask, fmri_data, design_matrices =\
            write_fake_fmri_data_and_design(shapes, rk)
        contrast = np.eye(rk)[1]
        # session 1
        multi_session_model = FirstLevelModel(mask_img=mask).fit(
            fmri_data[0], design_matrices=design_matrices[:1])
        dic1 = multi_session_model.compute_contrast(contrast,
                                                    output_type='all')

        # session 2
        multi_session_model.fit(fmri_data[1],
                                design_matrices=design_matrices[1:])
        dic2 = multi_session_model.compute_contrast(contrast,
                                                    output_type='all')

        # fixed effects model
        multi_session_model.fit(fmri_data, design_matrices=design_matrices)
        fixed_fx_dic = multi_session_model.compute_contrast(contrast,
                                                            output_type='all')

        # manual version
        contrasts = [dic1['effect_size'], dic2['effect_size']]
        variance = [dic1['effect_variance'], dic2['effect_variance']]
        (
            fixed_fx_contrast,
            fixed_fx_variance,
            fixed_fx_stat,
        ) = compute_fixed_effects(contrasts, variance, mask)

        assert_almost_equal(get_data(fixed_fx_contrast),
                            get_data(fixed_fx_dic['effect_size']))
        assert_almost_equal(get_data(fixed_fx_variance),
                            get_data(fixed_fx_dic['effect_variance']))
        assert_almost_equal(get_data(fixed_fx_stat),
                            get_data(fixed_fx_dic['stat']))

        # test without mask variable
        (
            fixed_fx_contrast,
            fixed_fx_variance,
            fixed_fx_stat,
        ) = compute_fixed_effects(contrasts, variance)
        assert_almost_equal(get_data(fixed_fx_contrast),
                            get_data(fixed_fx_dic['effect_size']))
        assert_almost_equal(get_data(fixed_fx_variance),
                            get_data(fixed_fx_dic['effect_variance']))
        assert_almost_equal(get_data(fixed_fx_stat),
                            get_data(fixed_fx_dic['stat']))

        # ensure that using unbalanced effects size and variance images
        # raises an error
        with pytest.raises(ValueError):
            compute_fixed_effects(contrasts * 2, variance, mask)
        del mask, multi_session_model
예제 #2
0
    def _run_interface(self, runtime):
        import nibabel as nb
        from nilearn.glm import second_level as level2
        from nilearn.glm import first_level as level1
        from nilearn.glm.contrasts import (compute_contrast,
                                           compute_fixed_effects,
                                           _compute_fixed_effects_params)

        smoothing_fwhm = self.inputs.smoothing_fwhm
        smoothing_type = self.inputs.smoothing_type
        if not isdefined(smoothing_fwhm):
            smoothing_fwhm = None
        if isdefined(smoothing_type) and smoothing_type != 'iso':
            raise NotImplementedError(
                "Only the iso smoothing type is available for the nistats estimator."
            )
        effect_maps = []
        variance_maps = []
        stat_maps = []
        zscore_maps = []
        pvalue_maps = []
        contrast_metadata = []
        out_ents = self.inputs.contrast_info[0]['entities']  # Same for all

        # Only keep files which match all entities for contrast
        stat_metadata = _flatten(self.inputs.stat_metadata)
        input_effects = _flatten(self.inputs.effect_maps)
        input_variances = _flatten(self.inputs.variance_maps)

        filtered_effects = []
        filtered_variances = []
        names = []
        for m, eff, var in zip(stat_metadata, input_effects, input_variances):
            if _match(out_ents, m):
                filtered_effects.append(eff)
                filtered_variances.append(var)
                names.append(m['contrast'])

        mat = pd.get_dummies(names)
        contrasts = prepare_contrasts(self.inputs.contrast_info, mat.columns)

        is_cifti = filtered_effects[0].endswith('dscalar.nii')
        if is_cifti:
            fname_fmt = os.path.join(runtime.cwd, '{}_{}.dscalar.nii').format
        else:
            fname_fmt = os.path.join(runtime.cwd, '{}_{}.nii.gz').format

        # Only fit model if any non-FEMA contrasts at this level
        if any(c[2] != 'FEMA' for c in contrasts):
            if len(filtered_effects) < 2:
                raise RuntimeError(
                    "At least two inputs are required for a 't' for 'F' "
                    "second level contrast")
            if is_cifti:
                effect_data = np.squeeze([
                    nb.load(effect).get_fdata(dtype='f4')
                    for effect in filtered_effects
                ])
                labels, estimates = level1.run_glm(effect_data,
                                                   mat.values,
                                                   noise_model='ols')
            else:
                model = level2.SecondLevelModel(smoothing_fwhm=smoothing_fwhm)
                model.fit(filtered_effects, design_matrix=mat)

        for name, weights, contrast_type in contrasts:
            contrast_metadata.append({
                'contrast': name,
                'stat': contrast_type,
                **out_ents
            })

            # Pass-through happens automatically as it can handle 1 input
            if contrast_type == 'FEMA':
                # Index design identity matrix on non-zero contrasts weights
                con_ix = weights[0].astype(bool)
                # Index of all input files "involved" with that contrast
                dm_ix = mat.iloc[:, con_ix].any(axis=1)

                contrast_imgs = np.array(filtered_effects)[dm_ix]
                variance_imgs = np.array(filtered_variances)[dm_ix]
                if is_cifti:
                    ffx_cont, ffx_var, ffx_t = _compute_fixed_effects_params(
                        np.squeeze([
                            nb.load(fname).get_fdata(dtype='f4')
                            for fname in contrast_imgs
                        ]),
                        np.squeeze([
                            nb.load(fname).get_fdata(dtype='f4')
                            for fname in variance_imgs
                        ]),
                        precision_weighted=False)
                    img = nb.load(filtered_effects[0])
                    maps = {
                        'effect_size':
                        dscalar_from_cifti(img, ffx_cont, "effect_size"),
                        'effect_variance':
                        dscalar_from_cifti(img, ffx_var, "effect_variance"),
                        'stat':
                        dscalar_from_cifti(img, ffx_t, "stat")
                    }

                else:
                    ffx_res = compute_fixed_effects(contrast_imgs,
                                                    variance_imgs)
                    maps = {
                        'effect_size': ffx_res[0],
                        'effect_variance': ffx_res[1],
                        'stat': ffx_res[2]
                    }
            else:
                if is_cifti:
                    contrast = compute_contrast(labels,
                                                estimates,
                                                weights,
                                                contrast_type=contrast_type)
                    img = nb.load(filtered_effects[0])
                    maps = {
                        map_type:
                        dscalar_from_cifti(img,
                                           getattr(contrast, map_type)(),
                                           map_type)
                        for map_type in [
                            'z_score', 'stat', 'p_value', 'effect_size',
                            'effect_variance'
                        ]
                    }
                else:
                    maps = model.compute_contrast(
                        second_level_contrast=weights,
                        second_level_stat_type=contrast_type,
                        output_type='all')

            for map_type, map_list in (('effect_size', effect_maps),
                                       ('effect_variance', variance_maps),
                                       ('z_score', zscore_maps),
                                       ('p_value', pvalue_maps), ('stat',
                                                                  stat_maps)):
                if map_type in maps:
                    fname = fname_fmt(name, map_type)
                    maps[map_type].to_filename(fname)
                    map_list.append(fname)

        self._results['effect_maps'] = effect_maps
        self._results['variance_maps'] = variance_maps
        self._results['stat_maps'] = stat_maps
        self._results['contrast_metadata'] = contrast_metadata

        # These are "optional" as fixed effects do not support these
        if zscore_maps:
            self._results['zscore_maps'] = zscore_maps
        if pvalue_maps:
            self._results['pvalue_maps'] = pvalue_maps

        return runtime
예제 #3
0
                       title='{0}, second session'.format(contrast_id))

#########################################################################
# Fixed effects statistics
from nilearn.glm.contrasts import compute_fixed_effects

contrast_imgs = [
    summary_statistics_session1['effect_size'],
    summary_statistics_session2['effect_size']
]
variance_imgs = [
    summary_statistics_session1['effect_variance'],
    summary_statistics_session2['effect_variance']
]

fixed_fx_contrast, fixed_fx_variance, fixed_fx_stat = compute_fixed_effects(
    contrast_imgs, variance_imgs, data['mask'])
plotting.plot_stat_map(fixed_fx_stat,
                       bg_img=mean_img_,
                       threshold=3.0,
                       cut_coords=cut_coords,
                       title='{0}, fixed effects'.format(contrast_id))

#########################################################################
# Not unexpectedly, the fixed effects version displays higher peaks than the
# input sessions. Computing fixed effects enhances the signal-to-noise ratio of
# the resulting brain maps
# Note however that, technically, the output maps of the fixed effects map is a
# t statistic (not a z statistic)

plotting.show()