def filterfit(self, sf, x_pha, x_amp=None, n_perm=200, p=.05, mcp='maxstat', edges=None, n_jobs=-1, random_state=None, verbose=None): """Filt the data then compute PAC on it. Parameters ---------- sf : float The sampling frequency. x_pha, x_amp : array_like Array of data for computing PAC. x_pha is the data used for extracting phases and x_amp, amplitudes. Both arrays must have the same shapes. If you want to compute PAC locally i.e. on the same electrode, x=x_pha=x_amp. For distant coupling, x_pha and x_amp could be different but still must to have the same shape. n_perm : int | 200 Number of surrogates to compute. p : float | 0.05 Statistical threshold mcp : {'fdr', 'bonferroni'} Correct the p-values for multiple comparisons. Use either : * 'maxstat' : maximum statistics * 'fdr' : FDR correction (need MNE-Python) * 'bonferroni' : Bonferroni correction (need MNE-Python) edges : int | None Number of samples to discard to avoid edge effects due to filtering n_jobs : int | -1 Number of jobs to compute PAC in parallel. For very large data, set this parameter to 1 in order to prevent large memory usage. random_state : int | None Fix the random state of the machine for reproducible results. Returns ------- pac : array_like Phase-Amplitude Coupling measure of shape (namp, npha, ...). Attributes ---------- pac : array_like Unormalized Phase-Amplitude Coupling measure of shape (n_amp, n_pha, n_epochs) pvalues : array_like Array of p-values of shape (n_amp, n_pha) surrogates : array_like Array of surrogates of shape (n_perm, n_amp, n_pha, n_epochs) """ # Check if amp is None : if x_amp is None: x_amp = x_pha # Shape checking : assert x_pha.shape == x_amp.shape, ("Inputs `x_pha` and `x_amp` must " "have the same shape.") # Extract phase (npha, ...) and amplitude (namp, ...) : logger.info(f" extract phases (n_pha={len(self.xvec)}) and " f"amplitudes (n_amps={len(self.yvec)})") kw = dict(keepfilt=False, edges=edges, n_jobs=1) pha = self.filter(sf, x_pha, 'phase', **kw) amp = self.filter(sf, x_amp, 'amplitude', **kw) # Special cases : if self._idpac[0] == 5: amp = np.angle(hilbertm(amp)) # Compute pac : return self.fit(pha, amp, p=p, mcp=mcp, n_perm=n_perm, n_jobs=n_jobs, random_state=random_state, verbose=verbose)
def filterfit(self, sf, x_pha, x_amp=None, n_perm=200, p=.05, n_jobs=-1, verbose=None): """Filt the data then compute PAC on it. Parameters ---------- sf : float The sampling frequency. x_pha, x_amp : array_like Array of data for computing PAC. x_pha is the data used for extracting phases and x_amp, amplitudes. Both arrays must have the same shapes. If you want to compute PAC locally i.e. on the same electrode, x=x_pha=x_amp. For distant coupling, x_pha and x_amp could be different but still must to have the same shape. n_perm : int | 200 Number of surrogates to compute. p : float | 0.05 Statistical threhold n_jobs : int | -1 Number of jobs to compute PAC in parallel. For very large data, set this parameter to 1 in order to prevent large memory usage. Returns ------- pac : array_like Phase-Amplitude Coupling measure of shape (namp, npha, ...). Attributes ---------- pac : array_like Unormalized Phase-Amplitude Coupling measure of shape (n_amp, n_pha, n_epochs) pvalues : array_like Array of p-values of shape (n_amp, n_pha) surrogates : array_like Array of surrogates of shape (n_perm, n_amp, n_pha, n_epochs) """ # Check if amp is None : if x_amp is None: x_amp = x_pha # Shape checking : assert x_pha.shape == x_amp.shape, ("Inputs `x_pha` and `x_amp` must " "have the same shape.") # Extract phase (npha, ...) and amplitude (namp, ...) : logger.info(f" Extract phases (n_pha={len(self.xvec)}) and " f"amplitudes (n_amps={len(self.yvec)})") pha = self.filter(sf, x_pha, 'phase', False, n_jobs) amp = self.filter(sf, x_amp, 'amplitude', False, n_jobs) # Special cases : if self._idpac[0] == 5: amp = np.angle(hilbertm(amp)) # Compute pac : return self.fit(pha, amp, p=p, n_perm=n_perm, n_jobs=n_jobs, verbose=verbose)
def fit(self, pha, amp, n_perm=200, p=.05, mcp='maxstat', n_jobs=-1, random_state=None, verbose=None): """Compute PAC on filtered data. Parameters ---------- pha : array_like Array of phases of shape (n_pha, n_epochs, n_times). Angles should be in rad. amp : array_like Array of amplitudes of shape (n_amp, n_epochs, n_times). n_perm : int | 200 Number of surrogates to compute. p : float | 0.05 Statistical threshold mcp : {'fdr', 'bonferroni'} Correct the p-values for multiple comparisons. Use either : * 'maxstat' : maximum statistics * 'fdr' : FDR correction (need MNE-Python) * 'bonferroni' : Bonferroni correction (need MNE-Python) n_jobs : int | -1 Number of jobs to compute PAC in parallel. For very large data, set this parameter to 1 in order to prevent large memory usage. random_state : int | None Fix the random state of the machine for reproducible results. Returns ------- pac : array_like Phase-Amplitude Coupling measure of shape (n_amp, n_pha, n_epochs) Attributes ---------- pac : array_like Unormalized Phase-Amplitude Coupling measure of shape (n_amp, n_pha, n_epochs) pvalues : array_like Array of p-values of shape (n_amp, n_pha) surrogates : array_like Array of surrogates of shape (n_perm, n_amp, n_pha, n_epochs) """ set_log_level(verbose) # --------------------------------------------------------------------- # input checking pha, amp = self._phampcheck(pha, amp) self._pvalues, self._surrogates = None, None # for the plv, extract the phase of the amplitude if self._idpac[0] == 5: amp = np.angle(hilbertm(amp)) # --------------------------------------------------------------------- # check if permutations should be computed if self._idpac[1] == 0: n_perm = None if not isinstance(n_perm, int) or not (n_perm > 0): self._idpac = (self._idpac[0], 0, 0) compute_surro = False else: compute_surro = True # --------------------------------------------------------------------- # copnorm if gaussian copula is used if self._idpac[0] == 6: logger.debug(f" copnorm the phase and the amplitude") pha = copnorm(np.stack([np.sin(pha), np.cos(pha)], axis=-2)) amp = copnorm(amp[..., np.newaxis, :]) # --------------------------------------------------------------------- # true pac estimation logger.info(f' true PAC estimation using {self.method}') fcn = get_pac_fcn(self.idpac[0], self.n_bins, p) pac = fcn(pha, amp) self._pac = pac.copy() # --------------------------------------------------------------------- # compute surrogates (if needed) if compute_surro: if random_state is None: random_state = int(np.random.randint(0, 10000, size=1)) logger.info(f" compute surrogates ({self.str_surro}, {n_perm} " f"permutations, random_state={random_state})") surro = compute_surrogates(pha, amp, self.idpac[1], fcn, n_perm, n_jobs, random_state) self._surrogates = surro # infer pvalues self.infer_pvalues(p, mcp=mcp) # --------------------------------------------------------------------- # normalize (if needed) if self._idpac[2] != 0: # Get the mean / deviation of surrogates logger.info(" normalize true PAC estimation by surrogates " f"({self.str_norm})") normalize(self.idpac[2], pac, surro) return pac
def fit(self, pha, amp, n_perm=200, p=.05, n_jobs=-1, verbose=None): """Compute PAC on filtered data. Parameters ---------- pha : array_like Array of phases of shape (n_pha, n_epochs, n_times). Angles should be in rad. amp : array_like Array of amplitudes of shape (n_amp, n_epochs, n_times). n_perm : int | 200 Number of surrogates to compute. p : float | 0.05 Statistical threhold n_jobs : int | -1 Number of jobs to compute PAC in parallel. For very large data, set this parameter to 1 in order to prevent large memory usage. Returns ------- pac : array_like Phase-Amplitude Coupling measure of shape (n_amp, n_pha, n_epochs) Attributes ---------- pac : array_like Unormalized Phase-Amplitude Coupling measure of shape (n_amp, n_pha, n_epochs) pvalues : array_like Array of p-values of shape (n_amp, n_pha) surrogates : array_like Array of surrogates of shape (n_perm, n_amp, n_pha, n_epochs) """ set_log_level(verbose) # --------------------------------------------------------------------- # input checking pha, amp = self._phampcheck(pha, amp) self._pvalues, self._surrogates = None, None # for the phase synchrony, extract the phase of the amplitude if self._idpac[0] == 5: amp = np.angle(hilbertm(amp)) # --------------------------------------------------------------------- # check if permutations should be computed if self._idpac[1] == 0: n_perm = None if not isinstance(n_perm, int) or not (n_perm > 0): self._idpac = (self._idpac[0], 0, 0) compute_surro = False else: compute_surro = True # --------------------------------------------------------------------- # copnorm if gaussian copula is used if self._idpac[0] == 6: logger.info(f" copnorm the phase and the amplitude") pha = copnorm(np.stack([np.sin(pha), np.cos(pha)], axis=-2)) amp = copnorm(amp[..., np.newaxis, :]) # --------------------------------------------------------------------- # true pac estimation logger.info(f' true PAC estimation using {self.method}') fcn = get_pac_fcn(self.idpac[0], self.n_bins, p) pac = fcn(pha, amp) self._pac = pac # --------------------------------------------------------------------- # compute surrogates (if needed) if compute_surro: logger.info(f" compute surrogates ({self.str_surro}, {n_perm} " "permutations)") surro = compute_surrogates(pha, amp, self.idpac[1], fcn, n_perm, n_jobs) self._surrogates = surro # infer pvalues self.infer_pvalues(p) # --------------------------------------------------------------------- # normalize (if needed) if self._idpac[2] != 0: # Get the mean / deviation of surrogates logger.info(" normalize true PAC estimation by surrogates " f"({self.str_norm})") normalize(self.idpac[2], pac, surro) return pac