def test_definition(self): """Test workflow definition.""" y, gt = sim_mi_cc(x, snr=1.) dt = DatasetEphy(x, y, roi, times=time) wf = WfMi(mi_type='cc', inference='rfx') wf.fit(dt, **kw_mi) wf.tvalues
def test_no_stat(self): """Test on no stats / no permutations / don't repeat computations.""" y, gt = sim_mi_cc(x, snr=1.) dt = DatasetEphy(x, y, roi, times=time) # compute permutations but not statistics kernel = np.hanning(3) wf = WfMi('cc', 'ffx', kernel=kernel, verbose=False) assert isinstance(wf.wf_stats, WfStats) wf.fit(dt, mcp='nostat', **kw_mi) assert len(wf.mi) == len(wf.mi_p) == n_roi assert len(wf.mi_p[0].shape) != 0 # don't compute permutations nor stats wf = WfMi('cc', 'ffx', verbose=False) mi, pv = wf.fit(dt, mcp=None, **kw_mi) assert wf.mi_p[0].shape == (0, ) assert pv.min() == pv.max() == 1. # don't compute permutations twice wf = WfMi('cc', 'ffx', verbose=False) t_start_1 = tst() wf.fit(dt, mcp='fdr', **kw_mi) t_end_1 = tst() t_start_2 = tst() wf.fit(dt, mcp='maxstat', **kw_mi) t_end_2 = tst() assert t_end_1 - t_start_1 > t_end_2 - t_start_2
def test_conjunction_analysis(self): """Test the conjunction analysis.""" y, gt = sim_mi_cc(x, snr=1.) dt = DatasetEphy(x, y, roi, times=time) wf = WfMi(mi_type='cc', inference='rfx') mi, pv = wf.fit(dt, **kw_mi) cj_ss, cj = wf.conjunction_analysis(dt) assert cj_ss.shape == (n_subjects, n_times, n_roi) assert cj.shape == (n_times, n_roi)
else: mcp = "cluster" estimator = GCMIEstimator(mi_type='cd', copnorm=True, biascorrect=True, demeaned=False, tensor=True, gpu=False, verbose=None) wf = WfMi(mi_type, inference, verbose=True, kernel=kernel, estimator=estimator) kw = dict(n_jobs=20, n_perm=200) cluster_th = None # {float, None, 'tfce'} mi, pvalues = wf.fit(dt, mcp=mcp, cluster_th=cluster_th, **kw) ############################################################################### # Saving results ############################################################################### # Path to results folder _RESULTS = os.path.join(_ROOT, "Results/lucy/mutual_information/network/") path_mi = os.path.join(_RESULTS, f"mi_{metric}_{feat}_avg_{avg}_{mcp}.nc") path_tv = os.path.join(_RESULTS, f"tval_{metric}_{feat}_avg_{avg}_{mcp}.nc") path_pv = os.path.join(_RESULTS, f"pval_{metric}_{feat}_avg_{avg}_{mcp}.nc") mi.to_netcdf(path_mi) wf.tvalues.to_netcdf(path_tv) pvalues.to_netcdf(path_pv)
############################################################################### # Define the electrophysiological dataset # --------------------------------------- # # Now we define an instance of :class:`frites.dataset.DatasetEphy` dt = DatasetEphy(x, y=y, roi=roi, times=time) ############################################################################### # Compute the mutual information # ------------------------------ # # Once we have the dataset instance, we can then define an instance of workflow # :class:`frites.workflow.WfMi`. This instance is used to compute the mutual # information # mutual information type ('cd' = continuous / discret) mi_type = 'cd' # define the workflow wf = WfMi(mi_type=mi_type, verbose=False) # compute the mutual information mi, _ = wf.fit(dt, mcp=None, n_jobs=1) # plot the information shared between the data and the regressor y plt.plot(time, mi) plt.xlabel("Time (s)"), plt.ylabel("MI (bits)") plt.title('I(C; D)') plt.show()
_x = xr.DataArray(x_single_suj, dims=('trials', 'roi', 'freqs', 'times'), coords=(y_single_suj, ['roi_0'], freqs, times)) x += [_x] # define an instance of DatasetEphy ds = DatasetEphy(x, y='trials', roi='roi', times='times') ############################################################################### # Compute the mutual information ############################################################################### # Then we compute the quantity of information shared by the time-frequency data # and the continuous regressor # compute the mutual information wf = WfMi(inference='ffx', mi_type='cc') mi, pv = wf.fit(ds, n_perm=200, mcp='cluster', random_state=0, n_jobs=1) ############################################################################### # plot the mutual information and p-values plt.figure(figsize=(10, 4)) plt.subplot(1, 2, 1) mi.squeeze().plot.pcolormesh(vmin=0, cmap='inferno') plt.title('Mutual information') plt.subplot(1, 2, 2) pv.squeeze().plot.pcolormesh(cmap='Blues_r') plt.title('Significant p-values (p<0.05, cluster-corrected)') plt.tight_layout() plt.show()
############################################################################### # Compute the mutual information # ------------------------------ # # Once we have the dataset instance, we can then define an instance of workflow # :class:`frites.workflow.WfMi`. This instance is used to compute the mutual # information # mutual information type ('cc' = continuous / continuous) mi_type = 'cc' # define the workflow wf = WfMi(mi_type, inference='ffx') # compute the mutual information without permutations mi, _ = wf.fit(dt, mcp=None) # plot the information shared between the data and the regressor y plt.plot(time, mi) plt.xlabel("Time (s)"), plt.ylabel("MI (bits)") plt.title('I(C; C)') plt.show() ############################################################################### # Multivariate regressor # ---------------------- # # Example above uses a univariate regressor (i.e a single column vector). But # multivariate regressors are also supported. Here is an example # of multivariate regressor
plt.show() ############################################################################### # Stimulus-specificity of the nodes of the network # ------------------------------------------------ # # In order to determine if the activity of each node is modulated according # to the stimulus, we then compute the mutual information between the # high-gamma and the stimulus variable. # define an electrophysiological dataset ds = DatasetEphy(x.copy(), y='trials', times='times', roi='roi') # define a workflow of mutual information wf = WfMi(mi_type='cd', inference='rfx') # run the workflow mi, pv = wf.fit(ds, n_perm=200, n_jobs=1, random_state=0) ############################################################################### # define the MI plotting function def plot_mi(mi, pv): # figure definition n_subs = len(mi['roi'].data) space_single_sub = 4 fig, gs = plt.subplots(1, 3, sharex='all', sharey='all', figsize=(n_subs * space_single_sub, 4)) for n_r, r in enumerate(mi['roi'].data): # select mi and p-values for a single roi mi_r, pv_r = mi.sel(roi=r), pv.sel(roi=r) # set to nan when it's not significant
############################################################################### # Define the electrophysiological dataset # --------------------------------------- # # Now we define an instance of :class:`frites.dataset.DatasetEphy` dt = DatasetEphy(x, y, roi) ############################################################################### # Compute the mutual information # ------------------------------ # # Once we have the dataset instance, we can then define an instance of workflow # :class:`frites.workflow.WfMi`. This instance is used to compute the mutual # information # mutual information type ('cd' = continuous / discret) mi_type = 'cd' # define the workflow wf = WfMi(mi_type) # compute the mutual information mi, _ = wf.fit(dt, mcp=None) # plot the information shared between the data and the regressor y plt.plot(time, mi) plt.xlabel("Time (s)"), plt.ylabel("MI (bits)") plt.title('I(C; D)') plt.show()
############################################################################### # Compute the mutual information # ------------------------------ # # Once we have the dataset instance, we can then define an instance of workflow # :class:`frites.workflow.WfMi`. This instance is used to compute the mutual # information # mutual information type ('cc' = continuous / continuous) mi_type = 'cc' inference = 'rfx' # don't use 'ffx' for assessing conjunction analysis ! # define the workflow wf = WfMi(mi_type) # compute the mutual information mi, pv = wf.fit(dt, mcp='cluster', n_perm=200, n_jobs=1, random_state=0) n_roi = len(mi.roi.data) # plot where there's significant values of mi fig = plt.figure(figsize=(16, 4)) for n_r, r in enumerate(mi.roi.data): # select the mi and p-values a specific roi mi_r, pv_r = mi.sel(roi=r), pv.sel(roi=r) # make a copy of the mi and set to nan everywhere it's not significant mi_sr = mi_r.copy() mi_sr.data[pv_r >= .05] = np.nan # superimpose mi and significant mi plt.subplot(1, n_roi, n_r + 1) plt.plot(times, mi_r) plt.plot(times, mi_sr, lw=4) plt.xlabel('Times'), plt.ylabel('MI (bits)')