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
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
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()