def corr_circular_linear(alpha, X): # Authors: Jean-Remi King <*****@*****.**> # # Licence : BSD-simplified """ Parameters ---------- alpha : numpy.array, shape (n_angles,) The angular data (if n_dims == 1, repeated across all x dimensions) X : numpy.array, shape (n_angles, n_dims) The linear data Returns ------- R : numpy.array, shape (n_dims) R values R2 : numpy.array, shape (n_dims) R square values p_val : numpy.array, shape (n_dims) P values Adapted from: Circular Statistics Toolbox for Matlab By Philipp Berens, 2009 [email protected] - www.kyb.mpg.de/~berens/circStat.html Equantion 27.47 """ from scipy.stats import chi2 from jr.utils import pairwise import numpy as np # computes correlation for sin and cos separately # WIP Applies repeated correlation if X is vector # TODO: deals with non repeated correlations (X * ALPHA) if alpha.ndim > 1: rxs = repeated_corr(np.sin(alpha), X) rxc = repeated_corr(np.cos(alpha), X) rcs = np.zeros_like(alpha[0, :]) rcs = pairwise(np.sin(alpha), np.cos(alpha), func=_loop_corr, n_jobs=-1) else: # WIP Applies repeated correlation if alpha is vector rxs = repeated_corr(X, np.sin(alpha)) rxc = repeated_corr(X, np.cos(alpha)) rcs = repeated_corr(np.sin(alpha), np.cos(alpha)) # Adapted from equation 27.47 R = (rxc ** 2 + rxs ** 2 - 2 * rxc * rxs * rcs) / (1 - rcs ** 2) # JR adhoc way of having a sign.... R = np.sign(rxs) * np.sign(rxc) * R R2 = np.sqrt(R ** 2) # Get degrees of freedom n = len(X) pval = 1 - chi2.cdf(n * R2, 2) return R, R2, pval
def nested_analysis(X, df, condition, function=None, query=None, single_trial=False, y=None, n_jobs=-1): """ Apply a nested set of analyses. Parameters ---------- X : np.array, shape(n_samples, ...) Data array. df : pandas.DataFrame Condition DataFrame condition : str | list If string, get the samples for each unique value of df[condition] If list, nested call nested_analysis. query : str | None, optional To select a subset of trial using pandas.DataFrame.query() function : function Computes across list of evoked. Must be of the form: function(X[:], y[:]) y : np.array, shape(n_conditions) n_jobs : int Number of core to compute the function. Defaults to -1. Returns ------- scores : np.array, shape(...) The results of the function sub : dict() Contains results of sub levels. """ import numpy as np from jr.utils import pairwise if isinstance(condition, str): # Subselect data using pandas.DataFrame queries sel = range(len(X)) if query is None else df.query(query).index X = X.take(sel, axis=0) y = np.array(df[condition][sel]) # Find unique conditions values = list() for ii in np.unique(y): if (ii is not None) and (ii not in [np.nan]): try: if np.isnan(ii): continue else: values.append(ii) except TypeError: values.append(ii) # Subsubselect for each unique condition y_sel = [np.where(y == value)[0] for value in values] # Mean condition: X_mean = np.zeros(np.hstack((len(y_sel), X.shape[1:]))) y_mean = np.zeros(len(y_sel)) for ii, sel_ in enumerate(y_sel): X_mean[ii, ...] = np.mean(X[sel_, ...], axis=0) if isinstance(y[sel_[0]], str): y_mean[ii] = ii else: y_mean[ii] = y[sel_[0]] if single_trial: X = X.take(np.hstack(y_sel), axis=0) # ERROR COME FROM HERE y = y.take(np.hstack(y_sel), axis=0) else: X = X_mean y = y_mean # Store values to keep track sub_list = dict(X=X_mean, y=y_mean, sel=sel, query=query, condition=condition, values=values, single_trial=single_trial) elif isinstance(condition, list): # If condition is a list, we must recall the function to gather # the results of the lower levels sub_list = list() X_list = list() # FIXME use numpy array for subcondition in condition: scores, sub = nested_analysis( X, df, subcondition['condition'], n_jobs=n_jobs, function=subcondition.get('function', None), query=subcondition.get('query', None)) X_list.append(scores) sub_list.append(sub) X = np.array(X_list) if y is None: y = np.arange(len(condition)) if len(y) != len(X): raise ValueError('X and y must be of identical shape: ' + '%s <> %s') % (len(X), len(y)) sub_list = dict(X=X, y=y, sub=sub_list, condition=condition) # Default function function = _default_analysis if function is None else function scores = pairwise(X, y, function, n_jobs=n_jobs) return scores, sub_list