Interactions across hemispheres in prefrontal cortex reflect global cognitive processing.
The 20 matches · 5 of them tie a paragraph to a whole file, not to given lines: weak matches, whose lines are not tinted
- [1] § Methods › Behavioral task ↔ ex/ex_SimpleTaskDemo.m, lines 1–25 · score 0.80 · memory guided saccade, go cue, target flash, saccade initiation, radius, locations
- [2] § Methods › Behavioral task ↔ ex/ex_SimpleJoystickTaskDemo.m, lines 112–259 · score 0.74 · target flash, saccade initiation, target location, go, reward, cue
- [3] § Methods › Fitting pCCA-FA and pCCA to simulated data ↔ pcca_fa_mdl.py, lines 11–54 · score 0.74 · EM algorithm, cross validated, area dimensionalities, pCCA FA model, latent variables, dshared
- [4] § Methods › Fitting pCCA-FA ↔ pcca_fa_mdl.py, lines 519–601 · score 0.74 · fold cross validation, area dimensionalities, pCCA FA model, likelihood, integer, d1
- [5] § Methods › Fitting pCCA-FA ↔ pcca_fa_mdl.py, lines 11–54 · score 0.70 · expectation maximization, EM algorithm, pCCA FA model, orthogonal, fit, matrix
- [6] § Methods › Preprocessing of neural activity ↔ ex_bci/utils/getChannelsKeepWithDat.m, the whole file · a weak match · score 0.67 · low firing rates, Fano factor, coincident, electrodes, binned, spikes
- [7] § Methods › Computing signal correlation ↔ main_analyses/compute_rsc.py, lines 29–78 · score 0.66 · signal correlation, area rsc, permutation, opposite, tuning, raw
- [8] § Methods › Separation of slow and fast components ↔ plot_figureS1.ipynb, lines 18–67 · score 0.66 · timescale component, remove slow timescale, slow component, fast, correlation, activity
- [9] § Methods › Preprocessing of neural activity ↔ ex_bci/utils/preprocessDatWithNoStimTrial.m, the whole file · a weak match · score 0.66 · low firing rates, Fano factor, coincident, Preprocessing, binned, spikes
- [10] § Methods › Simulated data generation ↔ sim_pcca_fa.py, lines 25–167 · score 0.65 · area co fluctuation, model parameters, orthogonalized, simulated, vector, matrix
- [11] § Methods › Fitting pCCA-FA and pCCA to simulated data ↔ pcca_fa_mdl.py, lines 519–601 · score 0.64 · EM algorithm, cross validated, area dimensionality, pCCA FA, fit, model
- [12] § Methods › Preprocessing of pupil diameter ↔ main_analyses/compile_pupil_data.m, the whole file · a weak match · score 0.62 · delay period, subtracted, smoothed, pupil, noise, window
- [13] § Methods › Probabilistic canonical correlation analysis - factor analysis (pCCA-FA) ↔ sim_pcca_fa.py, lines 25–167 · score 0.61 · independent variance, area latent variables, area component, n1, d1, d2
- [14] § Methods › Preprocessing of pupil diameter ↔ ex_control/samp.m, the whole file · a weak match · score 0.59 · EyeLink, Eye position, smoothed, tracking, pupil, window
- [15] § Results › Across-area latent variables were related to pupil diameter ↔ main_analyses/compile_pupil_data.m, the whole file · a weak match · score 0.56 · event related, target onset, delay period, pupil
- [16] § Methods › Pupil diameter regression ↔ main_analyses/compute_pupil_pred_1d.py, lines 47–98 · score 0.54 · linear regression, trial pupil, r2, pCCA FA, latent, model
- [17] § Methods › Pupil diameter regression ↔ main_analyses/compute_pupil_pred.py, lines 47–96 · score 0.54 · linear regression, trial pupil, r2, pCCA FA, latent, model
- [18] § Results › pCCA-FA partitions across- and within-area shared variance ↔ plot_figure3.ipynb, lines 173–255 · score 0.52 · ground truth sv, model validation, dshared, pCCA FA, dimensionality, variance
- [19] § Methods › Probabilistic canonical correlation analysis - factor analysis (pCCA-FA) ↔ ex_bci/oldBci/FA_distanceBCIsystemBlock/calibrateDistanceBCIFA.m, lines 101–207 · score 0.52 · low rank, covariance matrices, correlation, FA, neurons
- [20] § Methods › Probabilistic canonical correlation analysis - factor analysis (pCCA-FA) ↔ ex_bci/oldBci/FA_distanceBCIsystemBlock2BCI/calibrateDistanceBCIFA.m, lines 79–195 · score 0.52 · low rank, covariance matrices, correlation, FA, neurons
Paper
Loaded from Europe PMC by your browser, not stored by OSCR: doi.org · Europe PMC
The paper is loaded when this pane is shown.
The authors' code
Python · 984 lines · 45 KB · Apache-2.0 · 4 matches
- import numpy as np
- import cca.prob_cca as pcca
- import fa.factor_analysis as fa_mdl
- import scipy.linalg as slin
- import sklearn.model_selection as ms
- from joblib import Parallel,delayed
- from functools import partial
- from psutil import cpu_count
- from tqdm import tqdm
- class pcca_fa:
- '''
- pCCA-FA is a dimensionality reduction framework that combines probabilistic canonical correlation analysis (pCCA)
- and factor analysis (FA) to model across- and within- dataset interactions.
- This class implements the pCCA-FA model, stores parameters, and contains methods for fitting the model to data and computing model metrics.
- Methods
- -------
- train()
- Fit a pCCA-FA model to data using expectation-maximization (EM) algorithm.
- get_loading_matrices()
- Get across- and within-area loading matrices of the fit model.
- get_canonical_directions()
- Get canonical directions from the parameters of the fit model, as in canonical correlation analysis (CCA).
- get_correlative_modes()
- Transforms across-area loading matrices to their correlative modes.
- get_params()
- Get parameters of the fit model.
- set_params()
- Set parameters of the model.
- estep()
- Compute expectation of the posterior, according to the E-step of the EM algorithm.
- orthogonalize()
- Orthogonalize across- and within-area loading matrices using singular value decomposition.
- orthogonalize_latents()
- Orthogonalize latent variables (posterior means) using singular value decomposition.
- crossvalidate()
- Perform k-fold cross-validation to select hyperparameters (optimal across- and within-area dimensionality),
- then fit a pCCA-FA model with the selected hyperparameters.
- Model metric methods
- -------
- compute_load_sim()
- Compute loading similarity in each across- and within-area loading matrix.
- compute_dshared()
- Compute shared dimensionality (d_shared) in each across- and within-area loading matrix.
- compute_part_ratio()
- Compute part ratio in each across- and within-area loading matrix.
- compute_psv()
- Compute percentage of shared variance (%sv) in each across- and within-area loading matrix.
- compute_metrics()
- Wrapper to compute loading similarity, d_shared, part ratio, %sv, and canonical correlations.
- '''
- def __init__(self,min_var=0.01):
- '''
- Initialize pCCA-FA model class.
- Parameters:
- min_var (float): Used to set the variance floor, to prevent numerical underflow.
- '''
- self.params = []
- self.min_var = min_var
- def train(self,X_1,X_2,d,d1,d2,tol=1e-6,max_iter=int(1e6),verbose=False,rand_seed=None,warmstart=True,X_1_early_stop=None,X_2_early_stop=None,start_params=None,parallelize=True):
- '''
- Fit a pCCA-FA model to data using expectation-maximization (EM) algorithm.
- Parameters:
- X_1 (array): Array of size N (trials) x n1 (neurons), spike counts in area 1
- X_2 (array): Array of size N (trials) x n2 (neurons), spike counts in area 2
- d (int): Across-area dimensionality
- d1 (int): Within-area dimensionality for area 1
- d2 (int): Within-area dimensionality for area 2
- tol (float): Tolerance for convergence of the EM algorithm
- max_iter (int): Maximum number of iterations of the EM algorithm
- verbose (bool): Flag to print out updates during training
- rand_seed (int): Seed for random number generator, provide to ensure reproducibility
- warmstart (bool): Whether to initialize starting parameters of EM algorithm using pCCA and FA
- X_1_early_stop (array): Array of size N (trials) x n1 (neurons), test spike counts in area 1
- X_2_early_stop (array): Array of size N (trials) x n2 (neurons), test spike counts in area 2
- start_params (dict): Dictionary containing pCCA-FA model parameters to initialize EM algorithm
- use_process (bool): Whether to run training in a separate process for better performance
- Returns:
- LL (array): Training data log likelihood at each iteration of EM algorithm
- testLL (array): If using early_stop test data, contains test data log likelihood at each iteration of EM algorithm. Empty array otherwise.
- '''
- if parallelize:
- # Define function to run in parallel
- def _train_wrapper(X_1, X_2, d, d1, d2, min_var, tol, max_iter, verbose, rand_seed,
- warmstart, X_1_early_stop, X_2_early_stop, start_params):
- model = pcca_fa(min_var=min_var)
- LL, testLL = model.train(X_1, X_2, d, d1, d2,
- tol=tol, max_iter=max_iter,
- verbose=verbose, rand_seed=rand_seed,
- warmstart=warmstart,
- X_1_early_stop=X_1_early_stop,
- X_2_early_stop=X_2_early_stop,
- start_params=start_params,
- parallelize=False)
- return LL, testLL, model.get_params()
- # Run in parallel with all arguments explicitly passed
- result = Parallel(n_jobs=cpu_count(logical=False), backend='loky')([
- delayed(_train_wrapper)(X_1, X_2, d, d1, d2, self.min_var, tol, max_iter,
- verbose, rand_seed, warmstart, X_1_early_stop,
- X_2_early_stop, start_params)]
- )[0]
- LL, testLL, self.params = result
- return LL, testLL
- # Regular in-process training
- # set random seed
- if not(rand_seed is None):
- np.random.seed(rand_seed)
- early_stop = not(X_1_early_stop is None) and not(X_2_early_stop is None)
- # set some useful parameters
- N,n1 = X_1.shape
- _,n2 = X_2.shape
- mu_x1,mu_x2 = X_1.mean(axis=0),X_2.mean(axis=0)
- X_1c,X_2c = (X_1-mu_x1), (X_2-mu_x2)
- X_total = np.concatenate((X_1c,X_2c),axis=1)
- covX_1 = 1/N * (X_1c.T).dot(X_1c)
- covX_2 = 1/N * (X_2c.T).dot(X_2c)
- sampleCov = 1/N * (X_total.T).dot(X_total)
- var_floor = self.min_var*np.diag(sampleCov)
- Iz = np.identity(d+d1+d2)
- const = (n1+n2)*np.log(2*np.pi)
- if early_stop:
- X_1c_test,X_2c_test = X_1_early_stop - mu_x1, X_2_early_stop - mu_x2
- X_total_test = np.concatenate((X_1c_test,X_2c_test),axis=1)
- cov_test = (1/N)*(X_total_test.T.dot(X_total_test))
- # check that covariance is full rank
- if np.linalg.matrix_rank(sampleCov)==(n1+n2):
- x1_scale = np.exp(2/n1*np.sum(np.log(np.diag(slin.cholesky(covX_1)))))
- x2_scale = np.exp(2/n2*np.sum(np.log(np.diag(slin.cholesky(covX_2)))))
- else:
- raise np.linalg.LinAlgError(f'Covariance matrix is low rank ({np.linalg.matrix_rank(sampleCov):d}, should be {n1+n2:d})')
- # initialize parameters
- if warmstart:
- # get across-area loading matrices from pCCA and within-area loading matrices from FA
- tmp = pcca.prob_cca()
- tmp.train_maxLL(X_1,X_2,d)
- W_1 = tmp.get_params()['W_x']
- W_2 = tmp.get_params()['W_y']
- tmp = fa_mdl.factor_analysis()
- tmp.train(X_1,d1,rand_seed=rand_seed)
- L_1 = tmp.get_params()['L']
- tmp = fa_mdl.factor_analysis()
- tmp.train(X_2,d2,rand_seed=rand_seed)
- L_2 = tmp.get_params()['L']
- Psi = np.diag(sampleCov)
- elif not(start_params is None):
- # allow for specifying parameter initialization
- W_1 = start_params['W_1']
- W_2 = start_params['W_2']
- L_1 = start_params['L_1']
- L_2 = start_params['L_2']
- Psi = np.abs(np.append(start_params['psi_1'], start_params['psi_2']))
- else:
- if d > 0:
- W_1 = np.random.randn(n1,d) * np.sqrt(x1_scale/d)
- W_2 = np.random.randn(n2,d) * np.sqrt(x2_scale/d)
- else:
- W_1 = np.random.randn(n1,d)
- W_2 = np.random.randn(n2,d)
- if d1 > 0:
- L_1 = np.random.randn(n1,d1) * np.sqrt(x1_scale/d1)
- else:
- L_1 = np.random.randn(n1,d1)
- if d2 > 0:
- L_2 = np.random.randn(n2,d2) * np.sqrt(x2_scale/d2)
- else:
- L_2 = np.random.randn(n2,d2)
- Psi = np.diag(sampleCov)
- # define L_total - joint loading matrix
- L_top = np.concatenate((W_1,L_1,np.zeros((n1,d2))),axis=1)
- L_bottom = np.concatenate((W_2,np.zeros((n2,d1)),L_2),axis=1)
- L_total = np.concatenate((L_top,L_bottom),axis=0)
- L_mask = np.ones(L_total.shape)
- L_mask[:n1,(d+d1):] = np.zeros((n1,d2))
- L_mask[n1:,d:(d+d1)] = np.zeros((n2,d1))
- # EM algorithm
- LL = []
- testLL = []
- for i in range(max_iter):
- # E-step: set q(z) = p(z,zx,zy|x,y)
- iPsi = np.diag(1/Psi)
- iPsiL = iPsi.dot(L_total)
- if d==0 and d1==0 and d2==0:
- iSig = iPsi
- else:
- iSig = iPsi - iPsiL.dot(slin.inv(Iz+(L_total.T).dot(iPsiL))).dot(iPsiL.T)
- iSigL = iSig.dot(L_total)
- cov_iSigL = sampleCov.dot(iSigL)
- E_zz = Iz - (L_total.T).dot(iSigL) + (iSigL.T).dot(cov_iSigL)
- # compute log likelihood
- logDet = 2*np.sum(np.log(np.diag(slin.cholesky(iSig))))
- curr_LL = -N/2 * (const - logDet + np.trace(iSig.dot(sampleCov)))
- LL.append(curr_LL)
- if early_stop:
- curr_testLL = -N/2 * (const - logDet + np.trace(iSig.dot(cov_test)))
- testLL.append(curr_testLL)
- if verbose:
- print('EM iteration ',i,', LL={:.2f}'.format(curr_LL))
- # check for convergence (training LL increases by less than tol, or testLL decreases)
- if i>1:
- if (LL[-1]-LL[-2])<tol or (early_stop and testLL[-1]<testLL[-2]):
- break
- # M-step: compute new L and Psi
- if not(d==0 and d1==0 and d2==0):
- L_total = cov_iSigL.dot(slin.inv(E_zz))
- L_total = L_total * L_mask
- Psi = np.diag(sampleCov) - np.diag(cov_iSigL.dot(L_total.T))
- Psi = np.maximum(Psi,var_floor)
- # get final parameters after convergence or max_iter
- W_1, W_2 = L_total[:n1,:d], L_total[n1:,:d]
- L_1, L_2 = L_total[:n1,d:(d+d1)], L_total[n1:,(d+d1):]
- psi_1, psi_2 = Psi[:n1], Psi[n1:]
- # create parameter dict
- self.params = {
- 'mu_x1':mu_x1,'mu_x2':mu_x2, # estimated mean per neuron
- 'L_total':L_total, # maximum likelihood estimated matrix
- 'W_1':W_1,'W_2':W_2, # across-area loading matrices
- 'L_1':L_1,'L_2':L_2, # within-area loading matrices
- 'psi_1':psi_1,'psi_2':psi_2, # private variance per neuron
- 'd':d,'d1':d1,'d2':d2, # selected dimensionalities
- }
- return np.array(LL), np.array(testLL)
- def get_loading_matrices(self):
- '''
- Get across- and within-area loading matrices of the fit model.
- Returns:
- W_1 (array): Array of size n1 (neurons) x d (latents) containing the loadings for across-area latent variables onto neurons in area 1
- W_2 (array): Array of size n2 (neurons) x d (latents) containing the loadings for across-area latent variables onto neurons in area 2
- L_1 (array): Array of size n1 (neurons) x d1 (latents) containing the loadings for within-area latent variables onto neurons in area 1
- L_2 (array): Array of size n2 (neurons) x d2 (latents) containing the loadings for within-area latent variables onto neurons in area 2
- '''
- n1 = len(self.params['mu_x1'])
- d, d1 = self.params['d'], self.params['d1']
- L_total = self.params['L_total']
- # get final parameters
- W_1, W_2 = L_total[:n1,:d], L_total[n1:,:d]
- L_1, L_2 = L_total[:n1,d:(d+d1)], L_total[n1:,(d+d1):]
- return W_1, W_2, L_1, L_2
- def get_canonical_directions(self):
- '''
- Get canonical directions from the parameters of the fit model, as in canonical correlation analysis (CCA).
- Returns:
- canonical_dirs_x (array): Array of size n1 (neurons) x d (latents) whose columns contain the canonical directions for area 1
- canonical_dirs_y (array): Array of size n2 (neurons) x d (latents) whose columns contain the canonical directions for area 2
- rho (array): Array of size d (latents) x 1 containing the corresponding canonical correlations
- '''
- W_1, W_2, L_1, L_2 = self.get_loading_matrices()
- psi_1, psi_2 = self.params['psi_1'], self.params['psi_2']
- d = self.params['d']
- # compute canonical correlations
- est_covX_1 = W_1.dot(W_1.T) + L_1.dot(L_1.T) + np.diag(psi_1)
- est_covX_2 = W_2.dot(W_2.T) + L_2.dot(L_2.T) + np.diag(psi_2)
- est_covX_1X_2 = W_1.dot(W_2.T)
- inv_sqrt_covX_1 = slin.inv(slin.sqrtm(est_covX_1))
- inv_sqrt_covX_2 = slin.inv(slin.sqrtm(est_covX_2))
- K = inv_sqrt_covX_1.dot(est_covX_1X_2).dot(inv_sqrt_covX_2)
- u,s,vt = slin.svd(K)
- rho = s[0:d]
- canonical_dirs_x = slin.inv(slin.sqrtm(est_covX_1)) @ u[:,:d]
- canonical_dirs_y = slin.inv(slin.sqrtm(est_covX_2)) @ vt[:d,:].T
- return (canonical_dirs_x, canonical_dirs_y), rho
- def get_correlative_modes(self):
- '''
- Transforms across-area loading matrices to their correlative modes.
- Follows equations in Bach & Jordan, 2005.
- Returns:
- CorrModes_x (array): Array of size n1 (neurons) x d (latents) whose columns contain the correlative modes for area 1
- CorrModes_y (array): Array of size n2 (neurons) x d (latents) whose columns contain the correlative modes for area 2
- '''
- W_1, W_2, L_1, L_2 = self.get_loading_matrices()
- psi_1, psi_2 = self.params['psi_1'], self.params['psi_2']
- d = self.params['d']
- # compute canonical correlations
- est_covX_1 = W_1.dot(W_1.T) + L_1.dot(L_1.T) + np.diag(psi_1)
- est_covX_2 = W_2.dot(W_2.T) + L_2.dot(L_2.T) + np.diag(psi_2)
- est_covX_1X_2 = W_1.dot(W_2.T)
- inv_sqrt_covX_1 = slin.inv(slin.sqrtm(est_covX_1))
- inv_sqrt_covX_2 = slin.inv(slin.sqrtm(est_covX_2))
- K = inv_sqrt_covX_1.dot(est_covX_1X_2).dot(inv_sqrt_covX_2)
- u,s,vt = slin.svd(K)
- rho = s[0:d]
- # order W_1, W_2 by canon corrs
- pd = np.diag(np.sqrt(rho))
- CorrModes_x = slin.sqrtm(est_covX_1).dot(u[:,0:d]).dot(pd)
- CorrModes_y = slin.sqrtm(est_covX_2).dot(vt[0:d,:].T).dot(pd)
- return CorrModes_x, CorrModes_y
- def get_params(self):
- '''
- Get parameters of the fit model.
- Returns:
- params (dict): Dictionary containing each parameter of the pCCA-FA model
- '''
- return self.params
- def set_params(self,params):
- '''
- Set parameters of the model.
- Parameters:
- params (dict): Dictionary containing each parameter of the pCCA-FA model
- '''
- self.params = params
- def estep(self,X_1,X_2):
- '''
- Compute expectation of the posterior, according to the E-step of the EM algorithm.
- Parameters:
- X_1 (array): Array of size N (trials) x n1 (neurons), spike counts in area 1
- X_2 (array): Array of size N (trials) x n2 (neurons), spike counts in area 2
- Returns:
- z (dict): Dictionary containing the mean and covariance of the posterior
- LL (float): Log likelihood of the provided spike counts X_1 and X_2 under the fit model parameters
- '''
- N,n1 = X_1.shape
- _,n2 = X_2.shape
- d,d1,d2 = self.params['d'],self.params['d1'],self.params['d2']
- # get model parameters
- mu_x1,mu_x2 = self.params['mu_x1'],self.params['mu_x2']
- L_total = self.params['L_total']
- psi_1 = self.params['psi_1']
- psi_2 = self.params['psi_2']
- Psi = np.diag(np.concatenate((psi_1,psi_2)))
- # center data and compute covariances
- X_1c = X_1-mu_x1
- X_2c = X_2-mu_x2
- X_total = np.concatenate((X_1c,X_2c),axis=1)
- sampleCov = 1/N * (X_total.T).dot(X_total)
- # compute z
- Iz = np.identity(d+d1+d2)
- C = L_total.dot(L_total.T) + Psi
- invC = slin.inv(C)
- z_mu = X_total.dot(invC).dot(L_total)
- z_cov = np.diag(np.diag(Iz - (L_total.T).dot(invC).dot(L_total)))
- # compute LL
- const = (n1+n2)*np.log(2*np.pi)
- logDet = 2*np.sum(np.log(np.diag(slin.cholesky(C))))
- LL = -N/2 * (const + logDet + np.trace(invC.dot(sampleCov)))
- # return posterior and LL
- z = {
- 'z_mu':z_mu[:,:d],
- 'z_cov':z_cov[:d,:d],
- 'zx1_mu':z_mu[:,d:(d+d1)],
- 'zx1_cov':z_cov[d:(d+d1),d:(d+d1)],
- 'zx2_mu':z_mu[:,(d+d1):],
- 'zx2_cov':z_cov[(d+d1):,(d+d1):],
- }
- return z, LL
- def orthogonalize(self,across_mode='paired'):
- '''
- Orthogonalize across- and within-area loading matrices using singular value decomposition.
- Note: this also transforms loading matrices to be in covariant modes (as opposed to correlative modes)
- Parameters:
- across_mode (str): Parameter to indicate whether to orthogonalize the across-area loading matrices jointly ('paired') or individually in each area ('unpaired')
- Returns:
- W_1_norm (array): Array of size n1 (neurons) x d (latents) containing orthogonal columns with the loadings for across-area latent variables onto neurons in area 1
- W_2_norm (array): Array of size n2 (neurons) x d (latents) containing orthogonal columns the loadings for across-area latent variables onto neurons in area 2
- L_1_norm (array): Array of size n1 (neurons) x d1 (latents) containing orthogonal columns the loadings for within-area latent variables onto neurons in area 1
- L_2_norm (array): Array of size n2 (neurons) x d2 (latents) containing orthogonal columns the loadings for within-area latent variables onto neurons in area 2
- '''
- n1 = len(self.params['mu_x1'])
- W_1, W_2, L_1, L_2 = self.get_loading_matrices() # output from maximum likelihood estimation
- # within-area loading matrices
- u,s,_ = slin.svd(L_1,full_matrices=False)
- L_1_norm = u @ np.diag(s)
- u,s,_ = slin.svd(L_2,full_matrices=False)
- L_2_norm = u @ np.diag(s)
- # across-area loading matrices
- if across_mode == 'paired':
- W_total = np.concatenate((W_1,W_2),axis=0)
- u,s,_ = slin.svd(W_total,full_matrices=False)
- W_1_norm = u[:n1,:] @ np.diag(s)
- W_2_norm = u[n1:,:] @ np.diag(s)
- elif across_mode == 'unpaired':
- u,s,_ = slin.svd(W_1,full_matrices=False)
- W_1_norm = u @ np.diag(s)
- u,s,_ = slin.svd(W_2,full_matrices=False)
- W_2_norm = u @ np.diag(s)
- else:
- raise ValueError('across-mode must be "paired" or "unpaired"')
- return W_1_norm, W_2_norm, L_1_norm, L_2_norm
- def orthogonalize_latents(self,zx_mu,zy_mu,do_across=False,z_mu=None,across_mode='paired'):
- '''
- Orthogonalize latent variables (posterior means) using singular value decomposition.
- Parameters:
- zx_mu (array): Array of size N (trials) x d1 (latents) containing the within-area latent variables or posterior mean in area 1
- zy_mu (array): Array of size N (trials) x d2 (latents) containing the within-area latent variables or posterior mean in area 2
- do_across (bool): Whether to orthogonalize the across-area latent variables (True) or not (False)
- z_mu (array): Array of size N (trials) x d (latents) containing the across-area latent variables or posterior mean. Only used if do_across is True
- across_mode (str): Parameter to indicate whether to orthogonalize the across-area latent variables jointly ('paired') or individually in each area ('unpaired'). Only used if do_across is True
- Returns:
- z_orth (dict): Dictionary containing the orthogonalized latent variables
- W_orth (dict): Dictionary containing the orthogonalized loading matrices
- '''
- W_1, W_2, L_1, L_2 = self.get_loading_matrices() # output from maximum likelihood estimation
- n1 = L_1.shape[0]
- # orthogonalize zx
- u,s,vt = slin.svd(L_1,full_matrices=False)
- L_1_orth = u
- TT = np.diag(s).dot(vt)
- z_x1 = (TT.dot(zx_mu.T)).T
- # orthogonalize zy
- u,s,vt = slin.svd(L_2,full_matrices=False)
- L_2_orth = u
- TT = np.diag(s).dot(vt)
- z_x2 = (TT.dot(zy_mu.T)).T
- # orthogonalize across-area
- across_z_orth = {}
- if do_across:
- if across_mode == 'paired':
- # orthogonalize across-area latents using both area's loading matrix
- W_total = np.concatenate((W_1,W_2),axis=0)
- u,s,vt = slin.svd(W_total,full_matrices=False)
- W_1_orth = u[:n1,:]
- W_2_orth = u[n1:,:]
- TT = np.diag(s).dot(vt)
- z = (TT.dot(z_mu.T)).T
- across_z_orth['area1'] = z
- across_z_orth['area2'] = z
- elif across_mode == 'unpaired':
- # orthogonalize across-area latents using each area's loading matrix
- u,s,vt = slin.svd(W_1,full_matrices=False)
- W_1_orth = u
- TT = np.diag(s).dot(vt)
- z = (TT.dot(z_mu.T)).T
- across_z_orth['area1'] = z
- u,s,vt = slin.svd(W_2,full_matrices=False)
- W_2_orth = u
- TT = np.diag(s).dot(vt)
- z = (TT.dot(z_mu.T)).T
- across_z_orth['area2'] = z
- else:
- raise ValueError('across-mode must be "paired" or "unpaired"')
- # return z_orth, W_orth
- z_orth = {
- 'z':across_z_orth, # across area latent variables, empty if do_across is False
- 'z1':z_x1, # within-area latent variables for area 1
- 'z2':z_x2 # within-area latent variables for area 2
- }
- W_orth = {
- 'W_1':W_1_orth, # across-area loading matrix for area 1
- 'W_2':W_2_orth, # across-area loading matrix for area 2
- 'L_1':L_1_orth, # within-area loading matrix for area 1
- 'L_2':L_2_orth # within-area loading matrix for area 2
- }
- return z_orth, W_orth
- def crossvalidate(self,X_1,X_2,d_list=np.linspace(0,8,9),d1_list=np.linspace(0,8,9),d2_list=np.linspace(0,8,9),n_folds=10,verbose=True,max_iter=int(1e6),tol=1e-6,warmstart=True,rand_seed=None,parallelize=False,early_stop=False):
- '''
- Perform k-fold cross-validation to select hyperparameters (optimal across- and within-area dimensionality), then fit a pCCA-FA model with the selected hyperparameters.
- Parameters:
- X_1 (array): Array of size N (trials) x n1 (neurons), spike counts in area 1
- X_2 (array): Array of size N (trials) x n2 (neurons), spike counts in area 2
- d_list (array): 1-dimensional array containing the across-area dimensionalities to test
- d1_list (array): 1-dimensional array containing the within-area dimensionalities to test for area 1
- d2_list (array): 1-dimensional array containing the within-area dimensionalities to test for area 2
- n_folds (int): The number of folds (k) for cross-validation
- verbose (bool): Flag to print out updates during training
- max_iter (int): Maximum number of iterations of the EM algorithm
- tol (float): Tolerance for convergence of the EM algorithm
- warmstart (bool): Whether to initialize starting parameters of EM algorithm using pCCA and FA
- rand_seed (int): Seed for random number generator, provide to ensure reproducibility
- parallelize (bool): Whether to parallelize cross-validation folds (True) or not (False), to reduce run time
- early_stop (bool): Whether to use early_stop (True) or not (False) on the testing data of each cross-validation fold
- Returns:
- results (dict): Dictionary containing the lists of tested dimensionalities and their corresponding cross-validated data log likelihood and prediction errors,
- as well as the selected dimensionalities and its corresponding cross-validated log likelihood
- '''
- # set random seed
- if not(rand_seed is None):
- np.random.seed(rand_seed)
- # make sure z dims are integers
- d_list,d1_list,d2_list = np.meshgrid(d_list.astype(int),d1_list.astype(int),d2_list.astype(int))
- d_list = np.matrix.flatten(d_list)
- d1_list = np.matrix.flatten(d1_list)
- d2_list = np.matrix.flatten(d2_list)
- results = {'d_list':d_list,'d1_list':d1_list,'d2_list':d2_list}
- # create k-fold iterator
- if verbose:
- print('Crossvalidating pCCA-FA model to choose # of dims...')
- cv_kfold = ms.KFold(n_splits=n_folds,shuffle=True,random_state=rand_seed)
- # iterate through train/test splits
- i = 0
- LLs,PEs = np.zeros([n_folds,len(d_list)]),np.zeros([n_folds,len(d_list)])
- for train_idx,test_idx in cv_kfold.split(X_1):
- if verbose:
- print(' Fold ',i+1,' of ',n_folds,'...')
- X_1_train,X_1_test = X_1[train_idx], X_1[test_idx]
- X_2_train,X_2_test = X_2[train_idx], X_2[test_idx]
- # iterate through each d, provide training and testing trials to the helper function
- func = partial(self._cv_helper,X_1train=X_1_train,X_2train=X_2_train,X_1test=X_1_test,X_2test=X_2_test,\
- rand_seed=rand_seed,max_iter=max_iter,tol=tol,warmstart=warmstart,early_stop=early_stop)
- if parallelize:
- tmp = Parallel(n_jobs=cpu_count(logical=False),backend='loky')\
- (delayed(func)(d_list[j],d1_list[j],d2_list[j]) for j in range(len(d_list)))
- LLs[i,:] = [val[0] for val in tmp]
- PEs[i,:] = [val[1] for val in tmp]
- else:
- for j in tqdm(range(len(d_list))):
- tmp = func(d_list[j],d1_list[j],d2_list[j])
- LLs[i,j],PEs[i,j] = tmp[0],tmp[1]
- i = i+1
- sum_LLs = LLs.sum(axis=0)
- sum_SEs = PEs.sum(axis=0)
- results['LLs'] = sum_LLs
- results['PEs'] = sum_SEs
- # find the best # of z dimensions and train final pCCA-FA model
- max_idx = np.argmax(sum_LLs)
- d,d1,d2 = d_list[max_idx],d1_list[max_idx],d2_list[max_idx]
- results['d']=d
- results['d1']=d1
- results['d2']=d2
- results['final_LL'] = sum_LLs[max_idx]
- self.train(X_1,X_2,d,d1,d2) # sets params of the final model
- self.compute_cv_canonical_corrs(X_1,X_2,n_folds=n_folds,verbose=verbose,max_iter=max_iter,tol=tol,warmstart=warmstart,rand_seed=rand_seed)
- self.cv_results = results
- return results
- def _cv_helper(self,d,d1,d2,X_1train,X_2train,X_1test,X_2test,rand_seed=None,max_iter=int(1e5),tol=1e-6,warmstart=True,early_stop=False):
- '''
- Helper function for crossvalidate().
- Runs one train-test split and computes the log-likelihood and prediction error on the testing data.
- Parameters:
- d (int): Across-area dimensionality
- d1 (int): Within-area dimensionality for area 1
- d2 (int): Across-area dimensionality for area 2
- X_1train (array): Array of size Ntrain (trials) x n1 (neurons), training spike counts in area 1
- X_2train (array): Array of size Ntrain (trials) x n2 (neurons), training spike counts in area 2
- X_1test (array): Array of size Ntest (trials) x n1 (neurons), testing spike counts in area 1
- X_2test (array): Array of size Ntest (trials) x n2 (neurons), testing spike counts in area 2
- rand_seed (int): Seed for random number generator, provide to ensure reproducibility
- max_iter (int): Maximum number of iterations of the EM algorithm
- tol (float): Tolerance for convergence of the EM algorithm
- warmstart (bool): Whether to initialize starting parameters of EM algorithm using pCCA and FA
- early_stop (bool): Whether to use early_stop (True) or not (False) on the testing data
- Returns:
- LL (float): Cross-validated data log likelihood of the testing data
- PE (float): Prediction error of the testing data using leave-one-out prediction
- '''
- tmp = pcca_fa()
- if early_stop:
- tmp.train(X_1train,X_2train,d,d1,d2,rand_seed=rand_seed,max_iter=max_iter,tol=tol,warmstart=warmstart,X_1_early_stop=X_1test,X_2_early_stop=X_2test,parallelize=False)
- else:
- tmp.train(X_1train,X_2train,d,d1,d2,rand_seed=rand_seed,max_iter=max_iter,tol=tol,warmstart=warmstart,parallelize=False)
- # log-likelihood
- _,LL = tmp.estep(X_1test,X_2test)
- # prediction error
- X_1test_pred,X_2test_pred = tmp._leaveoneout_pred(X_1test,X_2test)
- PE = np.sum(np.square(X_1test_pred - X_1test)) + np.sum(np.square(X_2test_pred - X_2test))
- return (LL,PE)
- def _leaveoneout_pred(self,X_1,X_2):
- '''
- Helper function for crossvalidate().
- Runs leave-one-out prediction on provided data.
- Parameters:
- X_1 (array): Array of size N (trials) x n1 (neurons), spike counts in area 1
- X_2 (array): Array of size N (trials) x n2 (neurons), spike counts in area 2
- Returns:
- pred_x (array): Array of size N (trials) x n1 (neurons) containing the prediction errors for area 1
- pred_y (array): Array of size N (trials) x n2 (neurons) containing the prediction errors for area 2
- '''
- N,n1 = X_1.shape # trials x neurons
- n2 = X_2.shape[1]
- X_total = np.concatenate((X_1,X_2),axis=1)
- # extract model parameters
- Psi = np.concatenate((self.params['psi_1'],self.params['psi_2']),axis=0)
- mu = np.concatenate((self.params['mu_x1'],self.params['mu_x2']),axis=0)
- L_total = self.params['L_total']
- # compute covariances
- mdl_cov = L_total.dot(L_total.T) + np.diag(Psi)
- inv_cov = slin.inv(mdl_cov)
- # compute conditional expectations (predictions)
- n_total = n1+n2
- pred_total = np.zeros((N,n_total))
- for i in range(n_total):
- E = np.delete(np.delete(inv_cov,i,axis=0),i,axis=1)
- f = np.delete(inv_cov[:,i],i,axis=0)
- h = inv_cov[i,i]
- inv_term = E - (1/h)*np.outer(f,f)
- proj_term = np.delete(mdl_cov[i,:],i) # 1 x n_total-1
- mean_term = np.delete(X_total,i,axis=1) - np.delete(mu,i,axis=0).T # N x n_total-1
- pred = mu[i] + proj_term.dot(inv_term.dot(mean_term.T)) # 1 x N
- pred_total[:,i] = pred.T
- pred_x = pred_total[:,:n1] # predictions for neurons in area 1
- pred_y = pred_total[:,n1:] # predictions for neurons in area 2
- return pred_x,pred_y
- def compute_cv_canonical_corrs(self,X_1,X_2,n_folds=10,verbose=False,max_iter=int(1e5),tol=1e-6,warmstart=True,rand_seed=None):
- '''
- Get cross-validated canonical correlations from the fit model.
- Parameters:
- Parameters:
- X_1 (array): Array of size N (trials) x n1 (neurons), spike counts in area 1
- X_2 (array): Array of size N (trials) x n2 (neurons), spike counts in area 2
- n_folds (int): The number of folds (k) for cross-validation
- verbose (bool): Flag to print out updates during training
- max_iter (int): Maximum number of iterations of the EM algorithm
- tol (float): Tolerance for convergence of the EM algorithm
- warmstart (bool): Whether to initialize starting parameters of EM algorithm using pCCA and FA
- rand_seed (int): Seed for random number generator, provide to ensure reproducibility
- Returns:
- cv_rho (array): Array of size d (latents) x 1 containing the cross-validated canonical correlations
- '''
- # set random seed
- if not(rand_seed is None):
- np.random.seed(rand_seed)
- # check if model has been fit
- if not self.params:
- raise ValueError('Model must be fit before computing cross-validated canonical correlations. Run train() or crossvalidate() first.')
- # cross-validate to get cross-validated canonical correlations
- if verbose:
- print('Crossvalidating pCCA-FA model to compute canon corrs...')
- # set up needed parameters
- d,d1,d2 = self.params['d'],self.params['d1'],self.params['d2']
- N = X_1.shape[0]
- cv_kfold = ms.KFold(n_splits=n_folds,shuffle=True,random_state=rand_seed)
- zx1,zx2 = np.zeros((2,N,d))
- i=0
- for train_idx,test_idx in cv_kfold.split(X_1):
- if verbose:
- print(' Fold ',i+1,' of ',n_folds,'...')
- X_1_train,X_1_test = X_1[train_idx], X_1[test_idx]
- X_2_train,X_2_test = X_2[train_idx], X_2[test_idx]
- tmp = pcca_fa()
- tmp.train(X_1_train,X_2_train,d,d1,d2,rand_seed=rand_seed,max_iter=max_iter,tol=tol,warmstart=warmstart)
- W_1,W_2,L_1,L_2 = tmp.get_loading_matrices() # take direct EM outputs to compute E-step
- tmp_params = tmp.get_params()
- # compute pCCA E-step: E[z|x] and E[z|y]
- X_1c = X_1_test - tmp_params['mu_x1']
- Cx1 = W_1 @ W_1.T + (L_1 @ L_1.T + np.diag(tmp_params['psi_1']))
- invCx1 = slin.inv(Cx1)
- zx1_mu = X_1c.dot(invCx1).dot(W_1)
- X_2c = X_2_test - tmp_params['mu_x2']
- Cx2 = W_2 @ W_2.T + (L_2 @ L_2.T + np.diag(tmp_params['psi_2']))
- invCx2 = slin.inv(Cx2)
- zx2_mu = X_2c.dot(invCx2).dot(W_2)
- zx1[test_idx,:] = zx1_mu
- zx2[test_idx,:] = zx2_mu
- i+=1
- cv_rho = np.zeros(d)
- for i in range(d):
- tmp = np.corrcoef(zx1[:,i],zx2[:,i])
- cv_rho[i] = tmp[0,1]
- self.params['cv_rho'] = cv_rho
- return cv_rho
- def compute_load_sim(self):
- '''
- Compute loading similarity in each across- and within-area loading matrix.
- Returns:
- ls (dict): Dictionary containing the loading similarity for each across- and within-area loading matrix
- '''
- n1 = self.params['W_1'].shape[0]
- n2 = self.params['W_2'].shape[0]
- # first, orthonormalize each loading matrix
- W_1,_,_ = slin.svd(self.params['W_1'],full_matrices=False)
- W_2,_,_ = slin.svd(self.params['W_2'],full_matrices=False)
- L_1,_,_ = slin.svd(self.params['L_1'],full_matrices=False)
- L_2,_,_ = slin.svd(self.params['L_2'],full_matrices=False)
- # calculate loading similarity - following equation in Umakantha, Morina, Cowley, et al., 2021.
- ls_W_1 = 1 - n1*W_1.var(axis=0,ddof=0)
- ls_W_2 = 1 - n2*W_2.var(axis=0,ddof=0)
- ls_L_1 = 1 - n1*L_1.var(axis=0,ddof=0)
- ls_L_2 = 1 - n2*L_2.var(axis=0,ddof=0)
- ls = {
- 'ls_W_1':ls_W_1, # across-area loading similarity for area 1, involves W_1
- 'ls_W_2':ls_W_2, # across-area loading similarity for area 2, involves W_2
- 'ls_L_1':ls_L_1, # within-area loading similarity for area 1, involves L_1
- 'ls_L_2':ls_L_2 # within-area loading similarity for area 2, involves L_2
- }
- return ls
- def compute_dshared(self,cutoff_thresh=0.95):
- '''
- Compute shared dimensionality (d_shared) in each across- and within-area loading matrix.
- Parameters:
- cutoff_thresh (float): Cutoff percentage (0-1) of across- or within-area shared variance to explain for selecting d_shared
- Returns:
- dshared (dict): Dictionary containing the across- and within-area d_shared for each area
- '''
- W_1,W_2,L_1,L_2 = self.get_loading_matrices()
- # for across-area
- if self.params['d'] > 0:
- # area 1
- shared = W_1.dot(W_1.T)
- s = slin.svdvals(shared) # eigenvalues of WWT
- var_exp = np.cumsum(s)/np.sum(s)
- dims = np.where(var_exp >= (cutoff_thresh - 1e-9))[0]
- dshared_W_1 = dims[0]+1
- # area 2
- shared = W_2.dot(W_2.T)
- s = slin.svdvals(shared) # eigenvalues of WWT
- var_exp = np.cumsum(s)/np.sum(s)
- dims = np.where(var_exp >= (cutoff_thresh - 1e-9))[0]
- dshared_W_2 = dims[0]+1
- # overall
- W_total = np.concatenate((W_1,W_2),axis=0)
- shared = W_total.dot(W_total.T)
- s = slin.svdvals(shared) # eigenvalues of WWT
- var_exp = np.cumsum(s)/np.sum(s)
- dims = np.where(var_exp >= (cutoff_thresh - 1e-9))[0]
- dshared_W_total = dims[0]+1
- else:
- dshared_W_1 = 0
- dshared_W_2 = 0
- dshared_W_total = 0
- # for within area 1
- if self.params['d1'] > 0:
- shared = L_1.dot(L_1.T)
- s = slin.svdvals(shared) # eigenvalues of LLT
- var_exp = np.cumsum(s)/np.sum(s)
- dims = np.where(var_exp >= (cutoff_thresh - 1e-9))[0]
- dshared_L_1 = dims[0]+1
- else:
- dshared_L_1 = 0
- # for within area 2
- if self.params['d2'] > 0:
- shared = L_2.dot(L_2.T)
- s = slin.svdvals(shared) # eigenvalues of LLT
- var_exp = np.cumsum(s)/np.sum(s)
- dims = np.where(var_exp >= (cutoff_thresh - 1e-9))[0]
- dshared_L_2 = dims[0]+1
- else:
- dshared_L_2 = 0
- dshared = {
- 'dshared_W_1':dshared_W_1, # d_shared for across-area shared variance in area 1, involves W_1
- 'dshared_W_2':dshared_W_2, # d_shared for across-area shared variance in area 2, involves W_2
- 'dshared_L_1':dshared_L_1, # d_shared for within-area shared variance in area 1, involves L_1
- 'dshared_L_2':dshared_L_2, # d_shared for within-area shared variance in area 2, involves L_2
- 'dshared_W_total':dshared_W_total # d_shared for across-area shared variance jointly for area 1 and 2, involves W_1 and W_2
- }
- return dshared
- def compute_part_ratio(self):
- '''
- Compute part ratio in each across- and within-area loading matrix.
- Returns:
- pr (dict): Dictionary containing the part ratio for each across- and within-area loading matrix
- '''
- W_1,W_2,L_1,L_2 = self.get_loading_matrices()
- # for across-area
- shared = W_1.dot(W_1.T)
- s = slin.svdvals(shared)
- pr_W_1 = np.square(s.sum()) / np.square(s).sum()
- shared = W_2.dot(W_2.T)
- s = slin.svdvals(shared)
- pr_W_2 = np.square(s.sum()) / np.square(s).sum()
- # overall
- W_total = np.concatenate((W_1,W_2),axis=0)
- shared = W_total.dot(W_total.T)
- s = slin.svdvals(shared)
- pr_W_total = np.square(s.sum()) / np.square(s).sum()
- # for within area 1
- shared = L_1.dot(L_1.T)
- s = slin.svdvals(shared)
- pr_L_1 = np.square(s.sum()) / np.square(s).sum()
- # for within area 2
- shared = L_2.dot(L_2.T)
- s = slin.svdvals(shared)
- pr_L_2 = np.square(s.sum()) / np.square(s).sum()
- pr = {
- 'pr_W_1':pr_W_1, # part ratio for across-area loading matrix in area 1, involves W_1
- 'pr_W_2':pr_W_2, # part ratio for across-area loading matrix in area 2, involves W_2
- 'pr_L_1':pr_L_1, # part ratio for within-area loading matrix in area 1, involves L_1
- 'pr_L_2':pr_L_2, # part ratio for within-area loading matrix in area 2, involves L_2
- 'pr_W_total':pr_W_total # part ratio for across-area loading matrix jointly for area 1 and 2, involves W_1 and W_2
- }
- return pr
- def compute_psv(self):
- '''
- Compute percentage of shared variance (%sv) in each across- and within-area loading matrix.
- Returns:
- psv (dict): Dictionary containing the across- and within-area %sv for neurons in each area
- '''
- W_1,W_2,L_1,L_2 = self.get_loading_matrices()
- psi_1,psi_2 = self.params['psi_1'],self.params['psi_2']
- shared_across_x1 = np.diag(W_1.dot(W_1.T))
- shared_across_x2 = np.diag(W_2.dot(W_2.T))
- shared_within_x1 = np.diag(L_1.dot(L_1.T))
- shared_within_x2 = np.diag(L_2.dot(L_2.T))
- total_x = shared_across_x1 + shared_within_x1 + psi_1
- total_y = shared_across_x2 + shared_within_x2 + psi_2
- # for area 1
- psv_W_1 = (shared_across_x1 / total_x).flatten() * 100
- psv_L_1 = (shared_within_x1 / total_x).flatten() * 100
- ind_var_x1 = (psi_1 / total_x).flatten() * 100
- avg_psv_W_1 = np.mean(psv_W_1)
- avg_psv_L_1 = np.mean(psv_L_1)
- # for area 2
- psv_W_2 = (shared_across_x2 / total_y).flatten() * 100
- psv_L_2 = (shared_within_x2 / total_y).flatten() * 100
- ind_var_x2 = (psi_2 / total_y).flatten() * 100
- avg_psv_W_2 = np.mean(psv_W_2)
- avg_psv_L_2 = np.mean(psv_L_2)
- # overall
- avg_psv_W_total = np.mean(np.concatenate((psv_W_1,psv_W_2)))
- avg_psv_L_total = np.mean(np.concatenate((psv_L_1,psv_L_2)))
- psv = {
- 'psv_W_1':psv_W_1, # percent of across-area shared variance for each neuron in area 1
- 'psv_W_2':psv_W_2, # percent of across-area shared variance for each neuron in area 2
- 'psv_L_1':psv_L_1, # percent of within-area shared variance for each neuron in area 1
- 'psv_L_2':psv_L_2, # percent of within-area shared variance for each neuron in area 2
- 'avg_psv_W_1':avg_psv_W_1, # percent of across-area shared variance, averaged across neurons in area 1
- 'avg_psv_W_2':avg_psv_W_2, # percent of across-area shared variance, averaged across neurons in area 1
- 'avg_psv_L_1':avg_psv_L_1, # percent of across-area shared variance, averaged across neurons in area 1
- 'avg_psv_L_2':avg_psv_L_2, # percent of across-area shared variance, averaged across neurons in area 1
- 'ind_var_x1':ind_var_x1, # percent of independent variance for each neuron in area 1
- 'ind_var_x2':ind_var_x2, # percent of independent variance for each neuron in area 2
- 'avg_psv_W_total':avg_psv_W_total, # percent of across-area shared variance, averaged across all neurons
- 'avg_psv_L_total':avg_psv_L_total, # percent of within-area shared variance, averaged across all neurons
- }
- return psv
- def compute_metrics(self,cutoff_thresh=0.95):
- '''
- Wrapper to compute loading similarity, d_shared, part ratio, %sv, and canonical correlations.
- Returns:
- metrics (dict): Dictionary containing the computed metrics (loading similarity, d_shared, part ratio, %sv, and canonical correlations)
- '''
- dshared = self.compute_dshared(cutoff_thresh=cutoff_thresh)
- psv = self.compute_psv()
- pr = self.compute_part_ratio()
- ls = self.compute_load_sim()
- _,rho = self.get_canonical_directions()
- metrics = {
- 'dshared':dshared, # dictionary of d_shared metric
- 'psv':psv, # dictionary of %sv metric
- 'part_ratio':pr, # dictionary of part ratio metric
- 'load_sim':ls, # dictionary of loading similarity metric
- 'rho':rho # array of canonical correlations
- }
- if 'cv_rho' in self.params:
- metrics['cv_rho'] = self.params['cv_rho'] # array of cross-validated canonical correlations (if crossvalidate() was called)
- return metrics
pcca_fa_mdl.py at commit d13882e, under Apache-2.0 · at the source
Overview
- Neuroscience Institute, Carnegie Mellon University, Pittsburgh, PA USA
- Center for the Neural Basis of Cognition, Carnegie Mellon University & University of Pittsburgh, Pittsburgh, PA USA
- Machine Learning Department, Carnegie Mellon University, Pittsburgh, PA USA
- School of Medicine, University of Pittsburgh, Pittsburgh, PA USA
- Department of Biomedical Engineering, Carnegie Mellon University, Pittsburgh, PA USA
- Department of Electrical and Computer Engineering, Carnegie Mellon University, Pittsburgh, PA USA
Abstract
The abstract is not reproduced here: the paper's license (CC BY-NC-ND) does not allow it. Read it in the paper, at the publisher or on Europe PMC.
Repositories
Its files are read in the Code ↔ Paper reader above, with 20 matches between paragraphs and lines of code.
meganmcd13/figures-dual-pfc
3b59632fb5b84c377d82a16ae7dd491e70eba4b5, 9 March 2026Availability: 1 check, the latest on 29 September 2026: the link answers
- 29 September 2026: the link answers
45 files
- helpers/
binSpikeCounts.m , MATLAB, 49 lines - helpers/
get_good_channels.m , MATLAB, 39 lines - helpers/
histcn.m , MATLAB, 138 lines - helpers/
normCoincidence.m , MATLAB, 23 lines - helpers/
rm_crosstalk_channels.m , MATLAB, 22 lines - helpers/
startParPool.m , MATLAB, 16 lines - helpers/
unpadded_medfilt1.m , MATLAB, 11 lines - main_analyses/
compile_behav_neural_dat , MATLAB, 175 linesa.m - main_analyses/
compile_pupil_data.m , MATLAB, 84 lines, 2 matches - main_analyses/
compute_evoked_pupil_pre , Python, 127 linesd.py - main_analyses/
compute_evoked_pupil_pre , Python, 129 linesd_1d.py - main_analyses/
compute_evoked_resid_pup , Python, 113 linesil_pred.py - main_analyses/
compute_pupil_pred.py , Python, 126 lines, 1 match - main_analyses/
compute_pupil_pred_1d.py , Python, 128 lines, 1 match - main_analyses/
compute_rsc.py , Python, 140 lines, 1 match - main_analyses/
create_fig3_dataset_vary , Python, 72 linesN.py - main_analyses/
create_fig5_dataset.py , Python, 151 lines - main_analyses/
create_figS2_dataset_var , Python, 73 linesyDim.py - main_analyses/
create_figS2_dataset_var , Python, 71 linesySv.py - main_analyses/
create_figS3_dataset_var , Python, 54 linesyTheta.py - main_analyses/
create_figS9_dataset_var , Python, 110 linesyThetaSubsample.py - main_analyses/
dual_pfc_funcs.py , Python, 196 lines - main_analyses/
fit_alt_models.py , Python, 89 lines - main_analyses/
fit_flip_pccafa_models.p , Python, 74 linesy - main_analyses/
fit_pccafa_models.py , Python, 60 lines - main_analyses/
fit_shuffle_pccafa.py , Python, 69 lines - main_analyses/
fit_slow_pccafa_models.p , Python, 57 linesy - main_analyses/
fit_zsc_pccafa.py , Python, 80 lines - plot_figure1.ipynb, Jupyter, 39 lines
- plot_figure2.ipynb, Jupyter, 256 lines
- plot_figure3.ipynb, Jupyter, 308 lines, 1 match
- plot_figure4.ipynb, Jupyter, 278 lines
- plot_figure5.ipynb, Jupyter, 176 lines
- plot_figure6.ipynb, Jupyter, 152 lines
- plot_figureS1.ipynb, Jupyter, 215 lines, 1 match
- plot_figureS10.ipynb, Jupyter, 367 lines
- plot_figureS2.ipynb, Jupyter, 247 lines
- plot_figureS3.ipynb, Jupyter, 152 lines
- plot_figureS4.ipynb, Jupyter, 234 lines
- plot_figureS5.ipynb, Jupyter, 106 lines
- plot_figureS6.ipynb, Jupyter, 135 lines
- plot_figureS7.ipynb, Jupyter, 188 lines
- plot_figureS8.ipynb, Jupyter, 128 lines
- plot_figureS9.ipynb, Jupyter, 118 lines
- README.md, Text, 63 lines
SmithLabNeuro/pcca_fa
d13882eca2eee8cdb5e6ee4b0047b32b01f08754, 8 March 2026Availability: 1 check, the latest on 29 September 2026: the link answers
- 29 September 2026: the link answers
5 files
- pcca_fa_mdl.py, Python, 984 lines, 4 matches
- sim_pcca_fa.py, Python, 326 lines, 2 matches
- tutorial.ipynb, Jupyter, 168 lines
- LICENSE, License, 201 lines
- README.md, Text, 45 lines
SmithLabNeuro/Ex
1a97dc0873abf4a2450f42ed8575305feaff7a16, 28 August 2026Availability: 1 check, the latest on 29 September 2026: the link answers
- 29 September 2026: the link answers
427 files
- ex/
ex_SimpleJoystickTaskDem , MATLAB, 260 lines, 1 matcho.m - ex/
ex_SimpleTaskDemo.m , MATLAB, 270 lines, 1 match - ex/
ex_demotest.m , MATLAB, 155 lines - ex/
ex_kalmanVelocityDemoBci , MATLAB, 226 lines.m - ex/
ex_timingtest.m , MATLAB, 58 lines - ex_bci/
bciCalibration/ , MATLAB, 312 linescalibrateKalmanVelocityD emoDecoderForBci.m - ex_bci/
calibrationBci.m , MATLAB, 211 lines - ex_bci/
decoders/ , MATLAB, 22 lineskalmanVelocityDemoDecode r.m - ex_bci/
export_fig/ , Java, 38 linesImageSelection.java - ex_bci/
export_fig/ , MATLAB, 81 linesappend_pdfs.m - ex_bci/
export_fig/ , MATLAB, 51 linescopyfig.m - ex_bci/
export_fig/ , MATLAB, 157 linescrop_borders.m - ex_bci/
export_fig/ , MATLAB, 191 lineseps2pdf.m - ex_bci/
export_fig/ , MATLAB, 1,333 linesexport_fig.m - ex_bci/
export_fig/ , MATLAB, 151 linesfix_lines.m - ex_bci/
export_fig/ , MATLAB, 196 linesghostscript.m - ex_bci/
export_fig/ , MATLAB, 186 linesim2gif.m - ex_bci/
export_fig/ , MATLAB, 130 linesisolate_axes.m - ex_bci/
export_fig/ , MATLAB, 51 linespdf2eps.m - ex_bci/
export_fig/ , MATLAB, 167 linespdftops.m - ex_bci/
export_fig/ , MATLAB, 259 linesprint2array.m - ex_bci/
export_fig/ , MATLAB, 530 linesprint2eps.m - ex_bci/
export_fig/ , MATLAB, 37 linesread_write_entire_textfi le.m - ex_bci/
export_fig/ , MATLAB, 105 linesuser_string.m - ex_bci/
export_fig/ , MATLAB, 36 linesusing_hg2.m - ex_bci/
note.m , MATLAB, 3 lines - ex_bci/
oldBci/ , MATLAB, 369 lines, 1 matchFA_distanceBCIsystemBloc k/ calibrateDistanceBCIFA.m - ex_bci/
oldBci/ , MATLAB, 53 linesFA_distanceBCIsystemBloc k/ computeBCIOutputs.m - ex_bci/
oldBci/ , MATLAB, 42 linesFA_distanceBCIsystemBloc k/ distanceBCIstruct.m - ex_bci/
oldBci/ , MATLAB, 686 linesFA_distanceBCIsystemBloc k/ ex_DistanceBCIBlock.m - ex_bci/
oldBci/ , MATLAB, 7 linesFA_distanceBCIsystemBloc k/ makeShamDat.m - ex_bci/
oldBci/ , MATLAB, 23 linesFA_distanceBCIsystemBloc k/ myXcorr.m - ex_bci/
oldBci/ , MATLAB, 637 linesFA_distanceBCIsystemBloc k/ onlineDistanceBCI.m - ex_bci/
oldBci/ , MATLAB, 24 linesFA_distanceBCIsystemBloc k/ smoothCounts.m - ex_bci/
oldBci/ , MATLAB, 14 linesFA_distanceBCIsystemBloc k/ testXippmexCrash.m - ex_bci/
oldBci/ , MATLAB, 12 linesFA_distanceBCIsystemBloc k/ updateLatent.m - ex_bci/
oldBci/ , MATLAB, 288 lines, 1 matchFA_distanceBCIsystemBloc k2BCI/ calibrateDistanceBCIFA.m - ex_bci/
oldBci/ , MATLAB, 34 linesFA_distanceBCIsystemBloc k2BCI/ compileTemps.m - ex_bci/
oldBci/ , MATLAB, 63 linesFA_distanceBCIsystemBloc k2BCI/ computeBCIOutputs.m - ex_bci/
oldBci/ , MATLAB, 43 linesFA_distanceBCIsystemBloc k2BCI/ computeCountFromLog.m - ex_bci/
oldBci/ , MATLAB, 7 linesFA_distanceBCIsystemBloc k2BCI/ deltaBCIDistMetric.m - ex_bci/
oldBci/ , MATLAB, 42 linesFA_distanceBCIsystemBloc k2BCI/ distanceBCIstruct.m - ex_bci/
oldBci/ , MATLAB, 718 linesFA_distanceBCIsystemBloc k2BCI/ ex_DistanceBCIBlock2BCI. m - ex_bci/
oldBci/ , MATLAB, 54 linesFA_distanceBCIsystemBloc k2BCI/ findCrossTalk.m - ex_bci/
oldBci/ , MATLAB, 49 linesFA_distanceBCIsystemBloc k2BCI/ fixlog.m - ex_bci/
oldBci/ , MATLAB, 107 linesFA_distanceBCIsystemBloc k2BCI/ latentplot.m - ex_bci/
oldBci/ , MATLAB, 23 linesFA_distanceBCIsystemBloc k2BCI/ myXcorr.m - ex_bci/
oldBci/ , MATLAB, 16 linesFA_distanceBCIsystemBloc k2BCI/ normCoincidence.m - ex_bci/
oldBci/ , MATLAB, 638 linesFA_distanceBCIsystemBloc k2BCI/ onlineDistanceBCI.m - ex_bci/
oldBci/ , MATLAB, 12 linesFA_distanceBCIsystemBloc k2BCI/ updateLatent.m - ex_bci/
oldBci/ , MATLAB, 273 linesFA_distanceBCIsystemBloc k2BCI/ waitForMSmatlabUDP_dista nceBCI.m - ex_bci/
oldBci/ , MATLAB, 112 linesMGSBCIBlock/ bcihelpers/ assignopts.m - ex_bci/
oldBci/ , MATLAB, 95 linesMGSBCIBlock/ bcihelpers/ computeDistanceModel.m - ex_bci/
oldBci/ , MATLAB, 38 linesMGSBCIBlock/ bcihelpers/ findBCIFileName.m - ex_bci/
oldBci/ , MATLAB, 46 linesMGSBCIBlock/ bcihelpers/ findBadTrialsSpikeCounts .m - ex_bci/
oldBci/ , MATLAB, 597 linesMGSBCIBlock/ onlineMGSBCIBlock.m - ex_bci/
oldBci/ , MATLAB, 292 linesMGSBCIBlock/ waitForMSmatlabUDP_MGSBC I.m - ex_bci/
oldBci/ , MATLAB, not shown herebciHMM/ ._calib_script.m - ex_bci/
oldBci/ , MATLAB, not shown herebciHMM/ ._posterior2pos.m - ex_bci/
oldBci/ , MATLAB, not shown herebciHMM/ ._train_lda.m - ex_bci/
oldBci/ , MATLAB, not shown herebciHMM/ ._train_lowdHmm.m - ex_bci/
oldBci/ , MATLAB, 112 linesbciHMM/ assignopts.m - ex_bci/
oldBci/ , MATLAB, 102 linesbciHMM/ calib_script.m - ex_bci/
oldBci/ , MATLAB, not shown herebciHMM/ goodchans/ ._get_good_channels.m - ex_bci/
oldBci/ , MATLAB, not shown herebciHMM/ goodchans/ ._normCoincidence.m - ex_bci/
oldBci/ , MATLAB, not shown herebciHMM/ goodchans/ ._rm_crosstalk_channels. m - ex_bci/
oldBci/ , MATLAB, 38 linesbciHMM/ goodchans/ get_good_channels.m - ex_bci/
oldBci/ , MATLAB, 27 linesbciHMM/ goodchans/ normCoincidence.m - ex_bci/
oldBci/ , MATLAB, 23 linesbciHMM/ goodchans/ rm_crosstalk_channels.m - ex_bci/
oldBci/ , MATLAB, 54 linesbciHMM/ heldoutFilter_hmm.m - ex_bci/
oldBci/ , MATLAB, 50 linesbciHMM/ hmm_filter.m - ex_bci/
oldBci/ , MATLAB, 36 linesbciHMM/ hmm_onlineFilter.m - ex_bci/
oldBci/ , MATLAB, not shown herebciHMM/ nev2bcistruct/ ._nev2bcistruct.m - ex_bci/
oldBci/ , MATLAB, not shown herebciHMM/ nev2bcistruct/ helpers/ ._assignopts.m - ex_bci/
oldBci/ , MATLAB, not shown herebciHMM/ nev2bcistruct/ helpers/ ._convertOri.m - ex_bci/
oldBci/ , MATLAB, not shown herebciHMM/ nev2bcistruct/ helpers/ ._detectMissingStartEndC ode.m - ex_bci/
oldBci/ , MATLAB, not shown herebciHMM/ nev2bcistruct/ helpers/ ._driftchoicebinspikes.m - ex_bci/
oldBci/ , MATLAB, not shown herebciHMM/ nev2bcistruct/ helpers/ ._driftchoiceextractpara m.m - ex_bci/
oldBci/ , MATLAB, not shown herebciHMM/ nev2bcistruct/ helpers/ ._getDatParams.m - ex_bci/
oldBci/ , MATLAB, not shown herebciHMM/ nev2bcistruct/ helpers/ ._histcn.m - ex_bci/
oldBci/ , MATLAB, not shown herebciHMM/ nev2bcistruct/ helpers/ ._prepCalibCounts.m - ex_bci/
oldBci/ , MATLAB, not shown herebciHMM/ nev2bcistruct/ helpers/ ._prepspikecounts.m - ex_bci/
oldBci/ , MATLAB, not shown herebciHMM/ nev2bcistruct/ helpers/ ._psth2017.m - ex_bci/
oldBci/ , MATLAB, not shown herebciHMM/ nev2bcistruct/ helpers/ ._smoothSparse.m - ex_bci/
oldBci/ , MATLAB, not shown herebciHMM/ nev2bcistruct/ helpers/ ._testBinarySearch.m - ex_bci/
oldBci/ , MATLAB, not shown herebciHMM/ nev2bcistruct/ helpers/ ._unpackSpikes.m - ex_bci/
oldBci/ , MATLAB, 112 linesbciHMM/ nev2bcistruct/ helpers/ assignopts.m - ex_bci/
oldBci/ , C, 457 linesbciHMM/ nev2bcistruct/ helpers/ binarySearch.c - ex_bci/
oldBci/ , MATLAB, 13 linesbciHMM/ nev2bcistruct/ helpers/ convertOri.m - ex_bci/
oldBci/ , MATLAB, 24 linesbciHMM/ nev2bcistruct/ helpers/ detectMissingStartEndCod e.m - ex_bci/
oldBci/ , MATLAB, 34 linesbciHMM/ nev2bcistruct/ helpers/ driftchoicebinspikes.m - ex_bci/
oldBci/ , MATLAB, 15 linesbciHMM/ nev2bcistruct/ helpers/ driftchoiceextractparam. m - ex_bci/
oldBci/ , MATLAB, 24 linesbciHMM/ nev2bcistruct/ helpers/ getDatParams.m - ex_bci/
oldBci/ , MATLAB, 138 linesbciHMM/ nev2bcistruct/ helpers/ histcn.m - ex_bci/
oldBci/ , MATLAB, 71 linesbciHMM/ nev2bcistruct/ helpers/ prepCalibCounts.m - ex_bci/
oldBci/ , MATLAB, 54 linesbciHMM/ nev2bcistruct/ helpers/ prepspikecounts.m - ex_bci/
oldBci/ , MATLAB, 37 linesbciHMM/ nev2bcistruct/ helpers/ psth2017.m - ex_bci/
oldBci/ , MATLAB, 47 linesbciHMM/ nev2bcistruct/ helpers/ smoothSparse.m - ex_bci/
oldBci/ , MATLAB, 126 linesbciHMM/ nev2bcistruct/ helpers/ testBinarySearch.m - ex_bci/
oldBci/ , MATLAB, 4 linesbciHMM/ nev2bcistruct/ helpers/ unpackSpikes.m - ex_bci/
oldBci/ , MATLAB, 89 linesbciHMM/ nev2bcistruct/ nev2bcistruct.m - ex_bci/
oldBci/ , MATLAB, 15 linesbciHMM/ posterior2pos.m - ex_bci/
oldBci/ , MATLAB, 55 linesbciHMM/ train_hmm.m - ex_bci/
oldBci/ , MATLAB, 47 linesbciHMM/ train_lda.m - ex_bci/
oldBci/ , MATLAB, 128 linesbciHMM/ train_lowdHmm.m - ex_bci/
oldBci/ , MATLAB, not shown herebciKF/ ._calib_script.m - ex_bci/
oldBci/ , MATLAB, not shown herebciKF/ ._kf_filter.m - ex_bci/
oldBci/ , MATLAB, not shown herebciKF/ ._kf_onlineFilter.m - ex_bci/
oldBci/ , MATLAB, not shown herebciKF/ ._train_lowd_kf.m - ex_bci/
oldBci/ , MATLAB, 120 linesbciKF/ calib_script.m - ex_bci/
oldBci/ , MATLAB, not shown herebciKF/ factor_analysis/ ._crossvalidate_fa.m - ex_bci/
oldBci/ , MATLAB, not shown herebciKF/ factor_analysis/ ._fastfa.m - ex_bci/
oldBci/ , MATLAB, not shown herebciKF/ goodchans/ ._get_good_channels.m - ex_bci/
oldBci/ , MATLAB, not shown herebciKF/ goodchans/ ._normCoincidence.m - ex_bci/
oldBci/ , MATLAB, not shown herebciKF/ goodchans/ ._rm_crosstalk_channels. m - ex_bci/
oldBci/ , MATLAB, 38 linesbciKF/ goodchans/ get_good_channels.m - ex_bci/
oldBci/ , MATLAB, 27 linesbciKF/ goodchans/ normCoincidence.m - ex_bci/
oldBci/ , MATLAB, 23 linesbciKF/ goodchans/ rm_crosstalk_channels.m - ex_bci/
oldBci/ , MATLAB, 31 linesbciKF/ kf_filter.m - ex_bci/
oldBci/ , MATLAB, 37 linesbciKF/ kf_onlineFilter.m - ex_bci/
oldBci/ , MATLAB, not shown herebciKF/ nev2bcistruct/ ._nev2bcistruct.m - ex_bci/
oldBci/ , MATLAB, not shown herebciKF/ nev2bcistruct/ helpers/ ._assignopts.m - ex_bci/
oldBci/ , MATLAB, not shown herebciKF/ nev2bcistruct/ helpers/ ._convertOri.m - ex_bci/
oldBci/ , MATLAB, not shown herebciKF/ nev2bcistruct/ helpers/ ._detectMissingStartEndC ode.m - ex_bci/
oldBci/ , MATLAB, not shown herebciKF/ nev2bcistruct/ helpers/ ._driftchoicebinspikes.m - ex_bci/
oldBci/ , MATLAB, not shown herebciKF/ nev2bcistruct/ helpers/ ._driftchoiceextractpara m.m - ex_bci/
oldBci/ , MATLAB, not shown herebciKF/ nev2bcistruct/ helpers/ ._getDatParams.m - ex_bci/
oldBci/ , MATLAB, not shown herebciKF/ nev2bcistruct/ helpers/ ._histcn.m - ex_bci/
oldBci/ , MATLAB, not shown herebciKF/ nev2bcistruct/ helpers/ ._prepCalibCounts.m - ex_bci/
oldBci/ , MATLAB, not shown herebciKF/ nev2bcistruct/ helpers/ ._prepspikecounts.m - ex_bci/
oldBci/ , MATLAB, not shown herebciKF/ nev2bcistruct/ helpers/ ._psth2017.m - ex_bci/
oldBci/ , MATLAB, not shown herebciKF/ nev2bcistruct/ helpers/ ._smoothSparse.m - ex_bci/
oldBci/ , MATLAB, not shown herebciKF/ nev2bcistruct/ helpers/ ._testBinarySearch.m - ex_bci/
oldBci/ , MATLAB, not shown herebciKF/ nev2bcistruct/ helpers/ ._unpackSpikes.m - ex_bci/
oldBci/ , MATLAB, 112 linesbciKF/ nev2bcistruct/ helpers/ assignopts.m - ex_bci/
oldBci/ , C, 457 linesbciKF/ nev2bcistruct/ helpers/ binarySearch.c - ex_bci/
oldBci/ , MATLAB, 13 linesbciKF/ nev2bcistruct/ helpers/ convertOri.m - ex_bci/
oldBci/ , MATLAB, 24 linesbciKF/ nev2bcistruct/ helpers/ detectMissingStartEndCod e.m - ex_bci/
oldBci/ , MATLAB, 34 linesbciKF/ nev2bcistruct/ helpers/ driftchoicebinspikes.m - ex_bci/
oldBci/ , MATLAB, 15 linesbciKF/ nev2bcistruct/ helpers/ driftchoiceextractparam. m - ex_bci/
oldBci/ , MATLAB, 21 linesbciKF/ nev2bcistruct/ helpers/ getDatParams.m - ex_bci/
oldBci/ , MATLAB, 138 linesbciKF/ nev2bcistruct/ helpers/ histcn.m - ex_bci/
oldBci/ , MATLAB, 71 linesbciKF/ nev2bcistruct/ helpers/ prepCalibCounts.m - ex_bci/
oldBci/ , MATLAB, 54 linesbciKF/ nev2bcistruct/ helpers/ prepspikecounts.m - ex_bci/
oldBci/ , MATLAB, 37 linesbciKF/ nev2bcistruct/ helpers/ psth2017.m - ex_bci/
oldBci/ , MATLAB, 47 linesbciKF/ nev2bcistruct/ helpers/ smoothSparse.m - ex_bci/
oldBci/ , MATLAB, 126 linesbciKF/ nev2bcistruct/ helpers/ testBinarySearch.m - ex_bci/
oldBci/ , MATLAB, 4 linesbciKF/ nev2bcistruct/ helpers/ unpackSpikes.m - ex_bci/
oldBci/ , MATLAB, 89 linesbciKF/ nev2bcistruct/ nev2bcistruct.m - ex_bci/
oldBci/ , MATLAB, 72 linesbciKF/ train_lowd_kf.m - ex_bci/
oldBci/ , MATLAB, 65 linescalib_online/ calibBCI_online.m - ex_bci/
oldBci/ , MATLAB, 101 linescalib_online/ calibBCI_online_discrete .m - ex_bci/
oldBci/ , MATLAB, 185 linescalib_online/ calibBCI_online_discrete _hmm.m - ex_bci/
oldBci/ , MATLAB, 125 linescalib_online/ dat2Traj.m - ex_bci/
oldBci/ , MATLAB, 106 linescalib_online/ dirselNeuronToKeep.m - ex_bci/
oldBci/ , MATLAB, 54 linescalib_online/ excludeCrossChannelNoise .m - ex_bci/
oldBci/ , MATLAB, 36 linescalib_online/ fitCosineTuning.m - ex_bci/
oldBci/ , MATLAB, 27 linescalib_online/ getTuningCurves.m - ex_bci/
oldBci/ , MATLAB, 29 linescalib_online/ modelPNB.m - ex_bci/
oldBci/ , MATLAB, 70 linescalib_online/ neuronToKeep.m - ex_bci/
oldBci/ , MATLAB, 71 linescalib_online/ neuronToKeep2.m - ex_bci/
oldBci/ , MATLAB, 23 linescalib_online/ positionStates.m - ex_bci/
oldBci/ , MATLAB, 57 linescalib_online/ prepCalibCounts2.m - ex_bci/
oldBci/ , MATLAB, 35 linescalib_online/ ps9applyKF.m - ex_bci/
oldBci/ , MATLAB, 52 linescalib_online/ ps9kftrain.m - ex_bci/
oldBci/ , MATLAB, 9 linescomputePostNBP.m - ex_bci/
oldBci/ , MATLAB, 5 linescomputePostNBP2.m - ex_bci/
oldBci/ , MATLAB, 75 linesdailyPlots/ dailyDiagnosticScript.m - ex_bci/
oldBci/ , MATLAB, 79 linesdailyPlots/ dailyDiagnostics/ aggregatePlots.m - ex_bci/
oldBci/ , MATLAB, 112 linesdailyPlots/ dailyDiagnostics/ bayesClassifier/ assignopts.m - ex_bci/
oldBci/ , MATLAB, 68 linesdailyPlots/ dailyDiagnostics/ bayesClassifier/ crossvalidate_nb.m - ex_bci/
oldBci/ , MATLAB, 11 linesdailyPlots/ dailyDiagnostics/ bayesClassifier/ example.m - ex_bci/
oldBci/ , MATLAB, 54 linesdailyPlots/ dailyDiagnostics/ bayesClassifier/ predict_nb.m - ex_bci/
oldBci/ , MATLAB, 126 linesdailyPlots/ dailyDiagnostics/ bayesClassifier/ train_nb.m - ex_bci/
oldBci/ , MATLAB, 77 linesdailyPlots/ dailyDiagnostics/ bayesClassifier/ update_nb.m - ex_bci/
oldBci/ , MATLAB, 17 linesdailyPlots/ dailyDiagnostics/ bciFeedbackSignal.m - ex_bci/
oldBci/ , MATLAB, 47 linesdailyPlots/ dailyDiagnostics/ binData.m - ex_bci/
oldBci/ , MATLAB, 363 linesdailyPlots/ dailyDiagnostics/ dailyDiagnostic.m - ex_bci/
oldBci/ , MATLAB, 14 linesdailyPlots/ dailyDiagnostics/ expSmoothing.m - ex_bci/
oldBci/ , MATLAB, 24 linesdailyPlots/ dailyDiagnostics/ findBciCorrect.m - ex_bci/
oldBci/ , MATLAB, 46 linesdailyPlots/ dailyDiagnostics/ getOnlineCounts.m - ex_bci/
oldBci/ , MATLAB, 22 linesdailyPlots/ dailyDiagnostics/ myMovMean.m - ex_bci/
oldBci/ , MATLAB, 30 linesdailyPlots/ dailyDiagnostics/ sepBCIdat.m - ex_bci/
oldBci/ , MATLAB, 340 linesdailyPlots/ dailyDiagnostics/ stabilityDiagnostic.m - ex_bci/
oldBci/ , MATLAB, 94 linesdailyPlots/ otherPlots/ bciSlowDrift.m - ex_bci/
oldBci/ , MATLAB, 17 linesdailyPlots/ otherPlots/ otherDailyPlots.m - ex_bci/
oldBci/ , MATLAB, 67 linesdailyPlots/ otherPlots/ plotSmoothBCIAcquisition Time.m - ex_bci/
oldBci/ , MATLAB, 75 linesdailyPlots/ otherPlots/ plotSmoothBCICorrect.m - ex_bci/
oldBci/ , MATLAB, 64 linesdailyPlots/ otherPlots/ plotSmoothBCIPupilDiamet er.m - ex_bci/
oldBci/ , MATLAB, 224 linesdistanceBCIsystem/ calibrateDistanceBCI.m - ex_bci/
oldBci/ , MATLAB, 241 linesdistanceBCIsystem/ calibrateDistanceBCIgaus ecounts.m - ex_bci/
oldBci/ , MATLAB, 42 linesdistanceBCIsystem/ distanceBCIstruct.m - ex_bci/
oldBci/ , MATLAB, 565 linesdistanceBCIsystem/ onlineDistanceBCI.m - ex_bci/
oldBci/ , MATLAB, 24 linesdistanceBCIsystem/ smoothCounts.m - ex_bci/
oldBci/ , MATLAB, 14 linesdistanceBCIsystem/ testXippmexCrash.m - ex_bci/
oldBci/ , MATLAB, 248 linesdistanceBCIsystem/ waitForMSmatlabUDP_dista nceBCI.m - ex_bci/
oldBci/ , MATLAB, 152 linesdistinguishable_colors/ distinguishable_colors.m - ex_bci/
oldBci/ , MATLAB, 30 linesevalPNBmodel.m - ex_bci/
oldBci/ , MATLAB, 43 linesexcludeCrossChannelNoise .m - ex_bci/
oldBci/ , MATLAB, 32 linesinterpolateRGB2Gray.m - ex_bci/
oldBci/ , MATLAB, 335 linesonlineBCI.m - ex_bci/
oldBci/ , MATLAB, 347 linesonlineBCI_directtoshowex .m - ex_bci/
oldBci/ , MATLAB, 421 linesonlineBCI_discrete.m - ex_bci/
oldBci/ , MATLAB, 618 linesonlineBCI_discrete_hmm.m - ex_bci/
oldBci/ , MATLAB, 34 linesslowdriftMGSBCI/ compileTemps.m - ex_bci/
oldBci/ , MATLAB, 738 linesslowdriftMGSBCI/ ex_SlowDriftBCI.m - ex_bci/
oldBci/ , MATLAB, 716 linesslowdriftMGSBCI/ onlineSlowDriftBCI.m - ex_bci/
oldBci/ , MATLAB, 11 linesslowdriftMGSBCI/ prepMGSbcistruct.m - ex_bci/
oldBci/ , MATLAB, 17 linesslowdriftMGSBCI/ slowdriftRewardFun.m - ex_bci/
oldBci/ , MATLAB, 20 linesslowdriftMGSBCI/ slowdriftRewardFun2.m - ex_bci/
oldBci/ , MATLAB, 24 linesslowdriftMGSBCI/ smoothCounts.m - ex_bci/
oldBci/ , MATLAB, 12 linesslowdriftMGSBCI/ updateLatent.m - ex_bci/
oldBci/ , MATLAB, 24 linessmoothCounts.m - ex_bci/
oldBci/ , MATLAB, 24 linestestneuralnetsort.m - ex_bci/
oldBci/ , MATLAB, 15 linestesttimebug.m - ex_bci/
oldBci/ , MATLAB, 38 linestestxippmexdelay.m - ex_bci/
oldBci/ , MATLAB, 26 linestestxippmextime.m - ex_bci/
photoDiodeSetBci.m , MATLAB, 99 lines - ex_bci/
rtex.m , MATLAB, 102 lines - ex_bci/
utils/ , MATLAB, 59 linesbcidemo_alignmentTimesFa ctory.m - ex_bci/
utils/ , MATLAB, 41 linesbcidemo_binRaster.m - ex_bci/
utils/ , MATLAB, 25 linesbcidemo_calculateRasters .m - ex_bci/
utils/ , MATLAB, 48 linesbcidemo_getCCSpiking.m - ex_bci/
utils/ , MATLAB, 18 linesbcidemo_getChanFF.m - ex_bci/
utils/ , MATLAB, 19 linesbcidemo_getChanRate.m - ex_bci/
utils/ , MATLAB, 119 linesbcidemo_getData.m - ex_bci/
utils/ , MATLAB, 22 linesbcidemo_getTrialSpikesBy Chan.m - ex_bci/
utils/ , MATLAB, 383 linesboundedBci.m - ex_bci/
utils/ , MATLAB, 16 linescheckForControlMsgs.m - ex_bci/
utils/ , MATLAB, 9 linescheckIfBciEnd.m - ex_bci/
utils/ , MATLAB, 9 linescheckIfBciEndOrMsg.m - ex_bci/
utils/ , MATLAB, 13 linescheckIfControlComputerCo mmunicationNeedsReinitia lization.m - ex_bci/
utils/ , MATLAB, 5 linescountBinnedSpikesOverall .m - ex_bci/
utils/ , MATLAB, 59 linescountBinnedSpikesPerChan nel.m - ex_bci/
utils/ , MATLAB, 158 lines, 1 matchgetChannelsKeepWithDat.m - ex_bci/
utils/ , MATLAB, 27 linesinitializeControlCompute rCommunication.m - ex_bci/
utils/ , MATLAB, 9 linesloadNasNet.m - ex_bci/
utils/ , MATLAB, 421 linesmultiboundedBci.m - ex_bci/
utils/ , MATLAB, 502 linesmultiboundedMiSOBci.m - ex_bci/
utils/ , MATLAB, 132 linespreprocessDat.m - ex_bci/
utils/ , MATLAB, 137 lines, 1 matchpreprocessDatWithNoStimT rial.m - ex_bci/
utils/ , MATLAB, 15 linesprinangle.m - ex_bci/
utils/ , MATLAB, 37 linesprocessBciControlMessage .m - ex_bci/
utils/ , MATLAB, 34 linesprocessMiSOControlMessag e.m - ex_bci/
utils/ , MATLAB, 9 linesreceiveBciDecoderInforma tion.m - ex_bci/
utils/ , MATLAB, 22 linesreceiveMessageSendAck.m - ex_bci/
utils/ , MATLAB, 6 linesrunNASNetContinuous.m - ex_bci/
utils/ , MATLAB, 27 linessendMessageWaitAck.m - ex_bci/
utils/ , MATLAB, 89 linesvarycolor.m - ex_bci/
utils/ , MATLAB, 22 lineswaitForData.m - ex_control/
ChangeLog.m , MATLAB, 129 lines - ex_control/
TimingTest.m , MATLAB, 23 lines - ex_control/
combn.m , MATLAB, 131 lines - ex_control/
communications/ , MATLAB, 311 linescalibrateBciOnDataComput er.m - ex_control/
communications/ , MATLAB, 34 linesexRecordExperiment.m - ex_control/
communications/ , MATLAB, 22 linesreceiveMessageSendAck.m - ex_control/
communications/ , MATLAB, 27 linessendMessageWaitAck.m - ex_control/
communications/ , MATLAB, 60 linesstartNevRecording.m - ex_control/
communications/ , MATLAB, 22 lineswaitForData.m - ex_control/
createOrdering.m , MATLAB, 38 lines - ex_control/
database/ , MATLAB, 30 linesconfirmExperimenterNameW ithDatabase.m - ex_control/
database/ , MATLAB, 31 linesconfirmOrAddSubjectToDat abase.m - ex_control/
database/ , MATLAB, 100 linesmigrations/ database_v0.m - ex_control/
database/ , MATLAB, 88 linesmigrations/ database_v1.m - ex_control/
database/ , MATLAB, 44 linesmigrations/ database_v2.m - ex_control/
database/ , MATLAB, 48 linesmigrations/ database_v3.m - ex_control/
database/ , MATLAB, 50 linesmigrations/ database_v4.m - ex_control/
database/ , MATLAB, 85 linesmigrations/ database_v5.m - ex_control/
database/ , MATLAB, 19 linesmigrations/ database_v6.m - ex_control/
database/ , MATLAB, 27 linesreadExperimentInfoFromDa tabase.m - ex_control/
database/ , MATLAB, 28 linesupdateExperimentSessionI nDatabase.m - ex_control/
database/ , MATLAB, 36 lineswriteExperimentInfoToDat abase.m - ex_control/
database/ , MATLAB, 144 lineswriteExperimentSessionTo Database.m - ex_control/
deg2pix.m , MATLAB, 27 lines - ex_control/
drawCalibration.m , MATLAB, 16 lines - ex_control/
drawFixationWindows.m , MATLAB, 113 lines - ex_control/
drawTrialData.m , MATLAB, 27 lines - ex_control/
eventCheckingFunctions/ , MATLAB, 13 linesfixationAcquire.m - ex_control/
eventCheckingFunctions/ , MATLAB, 30 linesfixationHold.m - ex_control/
eventCheckingFunctions/ , MATLAB, 50 linesfixationHoldForMs.m - ex_control/
eventCheckingFunctions/ , MATLAB, 26 linesjoystickAcquire.m - ex_control/
eventCheckingFunctions/ , MATLAB, 52 linesjoystickHold.m - ex_control/
eventCheckingFunctions/ , MATLAB, 35 linesjoystickMove.m - ex_control/
eventCheckingFunctions/ , MATLAB, 32 linesjoystickMoveToTarget.m - ex_control/
exCatstruct.m , MATLAB, 131 lines - ex_control/
exDecode.m , MATLAB, 36 lines - ex_control/
exGlobals.m , MATLAB, 275 lines - ex_control/
exSaccadeTaskRewardProbF , MATLAB, 115 linesun.m - ex_control/
gazeIsInWindow.m , MATLAB, 29 lines - ex_control/
getNearestUCDpulse.m , MATLAB, 30 lines - ex_control/
getParamInfo.m , MATLAB, 40 lines - ex_control/
giveJuice.m , MATLAB, 90 lines - ex_control/
interpolateRGB2Gray.m , MATLAB, 32 lines - ex_control/
keyboardEvents.m , MATLAB, 25 lines - ex_control/
matlabUDP2.c , C, 307 lines - ex_control/
matlabUDP2.h , C/C++, 66 lines - ex_control/
microStim.m , MATLAB, 22 lines - ex_control/
msg.m , MATLAB, 27 lines - ex_control/
msgAndWait.m , MATLAB, 31 lines - ex_control/
parseExperiment.m , MATLAB, 132 lines - ex_control/
pix2deg.m , MATLAB, 28 lines - ex_control/
playTone.m , MATLAB, 52 lines - ex_control/
plotDisplay.m , MATLAB, 203 lines - ex_control/
plotDisplaytemp.m , MATLAB, 66 lines - ex_control/
projectCalibration.m , MATLAB, 17 lines - ex_control/
readExperiment.m , MATLAB, 374 lines - ex_control/
readUserXML.m , MATLAB, 128 lines - ex_control/
readUserXML_rig.m , MATLAB, 77 lines - ex_control/
runex.m , MATLAB, 1,448 lines - ex_control/
runex_test.m , MATLAB, 1,122 lines - ex_control/
samp.m , MATLAB, 148 lines, 1 match - ex_control/
sampleHallEffectJoystick , MATLAB, 40 lines.m - ex_control/
sendCode.m , MATLAB, 19 lines - ex_control/
sendStruct.m , MATLAB, 36 lines - ex_control/
setWindowBackground.m , MATLAB, 68 lines - ex_control/
slowdriftRewardFun.m , MATLAB, 17 lines - ex_control/
slowdriftRewardFun2.m , MATLAB, 20 lines - ex_control/
timerDebugError.m , MATLAB, 10 lines - ex_control/
unixGetAnalogInput.c , C, 94 lines - ex_control/
unixGetEyes.c , C, 118 lines - ex_control/
unixGetPupil.c , C, 82 lines - ex_control/
unixSendByte.c , C, 181 lines - ex_control/
unixSendPulse.c , C, 100 lines - ex_control/
unixSetLevel.c , C, 79 lines - ex_control/
utils/ , MATLAB, 15 linesautoJuice.m - ex_control/
utils/ , MATLAB, 11 linescheckWithinTolerance.m - ex_control/
utils/ , MATLAB, 29 linesconnectToJoysticks.m - ex_control/
utils/ , MATLAB, 36 linesdigcode_timingtest.m - ex_control/
utils/ , MATLAB, 42 linesdiode_loop_control.m - ex_control/
utils/ , MATLAB, 14 linesinitAudio.m - ex_control/
utils/ , MATLAB, 21 linesplayTone.m - ex_control/
utils/ , MATLAB, 78 linesrequestStimParamPost.m - ex_control/
utils/ , MATLAB, 56 linesrequestStimParamPre.m - ex_control/
utils/ , MATLAB, 34 linessendTrialParam.m - ex_control/
utils/ , MATLAB, 32 linesudp_test_control.m - ex_control/
utils/ , MATLAB, 65 linesunix_matlabUDP2_BCI_test .m - ex_control/
utils/ , MATLAB, 58 linesunix_matlabUDP2_Display_ test.m - ex_control/
utils/ , MATLAB, 103 linesunix_matlabUDP2_test.m - ex_control/
utils/ , MATLAB, 23 lineswrapUpSession.m - ex_control/
utils/ , MATLAB, 159 linesxippmex_test.m - ex_control/
waitFor.m , MATLAB, 33 lines - ex_control/
waitForDisplay.m , MATLAB, 61 lines - ex_control/
waitForEvent.m , MATLAB, 211 lines - ex_control/
waitForFixation.m , MATLAB, 73 lines - ex_control/
waitForJoystick.m , MATLAB, 288 lines - ex_control/
waitForJoystickMove.m , MATLAB, 45 lines - ex_control/
waitForJoystickWhileFix. , MATLAB, 220 linesm - ex_control/
waitForMS.m , MATLAB, 94 lines - ex_control/
waitForMSJoystick.m , MATLAB, 70 lines - ex_control/
waitForMSJoystickAndFix. , MATLAB, 85 linesm - ex_control/
waitForMSmatlabUDP.m , MATLAB, 253 lines - ex_control/
waitForMSmatlabUDP1.m , MATLAB, 203 lines - ex_control/
waitForMSmatlabUDP_MGSBC , MATLAB, 310 linesI.m - ex_control/
waitForMSmatlabUDP_discr , MATLAB, 307 linesete.m - ex_control/
waitForMSmatlabUDP_dista , MATLAB, 275 linesnceBCI.m - ex_control/
waitForMSmatlabUDP_slowd , MATLAB, 273 linesriftBCI.m - ex_control/
waitForMSmatlabUDP_temp. , MATLAB, 166 linesm - ex_control/
waitForMSxippmex.m , MATLAB, 148 lines - ex_control/
xippmexNotes.m , MATLAB, 146 lines - ex_control/
xippmexStimCmd.m , MATLAB, 196 lines - ex_control/
xippmexStimCmd_micro.m , MATLAB, 184 lines - ex_control/
xml2struct.m , MATLAB, 66 lines - ex_data/
recordex.m , MATLAB, 316 lines - ex_data/
recordex_dummy.m , MATLAB, 120 lines - ex_data/
utils/ , MATLAB, 29 linessendStructAsAscii.m - ex_data/
utils/ , MATLAB, 12 lineswaitForMessage.m - ex_disp/
Hello.m , MATLAB, 3 lines - ex_disp/
makeGammaTable.m , MATLAB, 108 lines - ex_disp/
showex.m , MATLAB, 517 lines - ex_disp/
utils/ , MATLAB, 67 linesctxNoise.m - ex_disp/
utils/ , MATLAB, 94 linesdiode_loop_disp.m - ex_disp/
utils/ , MATLAB, 44 linesgaussNoise.m - ex_disp/
utils/ , MATLAB, 45 linesgaussNoiseMtx.m - ex_disp/
utils/ , MATLAB, 26 linesloadcx_movie.m - ex_disp/
utils/ , MATLAB, 8 linesmakeGaussNoise.m - ex_disp/
utils/ , MATLAB, 70 linesmeasureSquarePixels.m - ex_disp/
utils/ , MATLAB, 21 linesmonitor_calibration/ calib_all.m - ex_disp/
utils/ , MATLAB, 148 linesmonitor_calibration/ calibrateMonitor.m - ex_disp/
utils/ , MATLAB, 15 linesmonitor_calibration/ pullOutNumber.m - ex_disp/
utils/ , MATLAB, 94 linesmonitor_calibration/ readUDT471.m - ex_disp/
utils/ , MATLAB, 40 linesmonitor_calibration/ testSquare.m - ex_disp/
utils/ , MATLAB, 71 linessavecx_movie.m - ex_disp/
utils/ , MATLAB, 23 linesudp_test_display.m - misc/
exlocal_template/ , MATLAB, 262 linesex/ ex_SaccadeTask.m - misc/
exlocal_template/ , MATLAB, 219 linesex/ ex_activeFixation.m - misc/
exlocal_template/ , MATLAB, 414 linesex/ ex_driftchoice.m - stim/
stim_annulus.m , MATLAB, 53 lines - stim/
stim_arc.m , MATLAB, 37 lines - stim/
stim_blank.m , MATLAB, 27 lines - stim/
stim_circular_letters.m , MATLAB, 372 lines - stim/
stim_circulargrid.m , MATLAB, 168 lines - stim/
stim_contrastgrating.m , MATLAB, 112 lines - stim/
stim_fef_dots.m , MATLAB, 101 lines - stim/
stim_fef_dots2.m , MATLAB, 96 lines - stim/
stim_fef_dotsPeri.m , MATLAB, 83 lines - stim/
stim_fef_dotsPost.m , MATLAB, 83 lines - stim/
stim_fef_dotsPre.m , MATLAB, 92 lines - stim/
stim_gabor.m , MATLAB, 76 lines - stim/
stim_grating.m , MATLAB, 84 lines - stim/
stim_grating_alpha.m , MATLAB, 99 lines - stim/
stim_movie.m , MATLAB, 77 lines - stim/
stim_movie_morph.m , MATLAB, 217 lines - stim/
stim_moviewithmask.m , MATLAB, 77 lines - stim/
stim_movingoval.m , MATLAB, 49 lines - stim/
stim_oval.m , MATLAB, 35 lines - stim/
stim_plaid.m , MATLAB, 89 lines - stim/
stim_radialcheck.m , MATLAB, 99 lines - stim/
stim_radialcheck2.m , MATLAB, 145 lines - stim/
stim_rect.m , MATLAB, 35 lines - stim/
stim_rgbgrating.m , MATLAB, 109 lines - stim/
stim_rotpoly.m , MATLAB, 43 lines - stim/
stim_squarecheck.m , MATLAB, 130 lines - stim/
stim_squaregrid.m , MATLAB, 103 lines - xippmex/
attime_example.m , MATLAB, 92 lines - xippmex/
biphasic_example.m , MATLAB, 22 lines - xippmex/
biphasic_example_many_el , MATLAB, 56 linesec.m - xippmex/
biphasic_example_narrow. , MATLAB, 53 linesm - xippmex/
get_stim_cmd.m , MATLAB, 13 lines - xippmex/
get_stim_word.m , MATLAB, 46 lines - xippmex/
stim_ampl_mod.m , MATLAB, 193 lines - xippmex/
stim_freq_mod.m , MATLAB, 195 lines - xippmex/
stim_param_to_string.m , MATLAB, 45 lines - xippmex/
stim_pw_mod.m , MATLAB, 266 lines - xippmex/
stim_sin.m , MATLAB, 140 lines - xippmex/
xippmex.m , MATLAB, 28 lines - xippmex/
xippmex_walkthrough.m , MATLAB, 169 lines - README.md, Text, 64 lines
Zenodo 18913386
Availability: 1 check, the latest on 29 September 2026: the link answers (HTTP 200)
- 29 September 2026: the link answers (HTTP 200)
5 files
- pcca_fa_mdl.py, Python, 984 lines
- sim_pcca_fa.py, Python, 326 lines
- tutorial.ipynb, Jupyter, 168 lines
- LICENSE, License, 201 lines
- README.md, Text, 43 lines
Zenodo 18929016
Availability: 1 check, the latest on 29 September 2026: the link answers (HTTP 200)
- 29 September 2026: the link answers (HTTP 200)
45 files
- helpers/
binSpikeCounts.m , MATLAB, 49 lines - helpers/
get_good_channels.m , MATLAB, 39 lines - helpers/
histcn.m , MATLAB, 138 lines - helpers/
normCoincidence.m , MATLAB, 23 lines - helpers/
rm_crosstalk_channels.m , MATLAB, 22 lines - helpers/
startParPool.m , MATLAB, 16 lines - helpers/
unpadded_medfilt1.m , MATLAB, 11 lines - main_analyses/
compile_behav_neural_dat , MATLAB, 175 linesa.m - main_analyses/
compile_pupil_data.m , MATLAB, 84 lines - main_analyses/
compute_evoked_pupil_pre , Python, 127 linesd.py - main_analyses/
compute_evoked_pupil_pre , Python, 129 linesd_1d.py - main_analyses/
compute_evoked_resid_pup , Python, 113 linesil_pred.py - main_analyses/
compute_pupil_pred.py , Python, 126 lines - main_analyses/
compute_pupil_pred_1d.py , Python, 128 lines - main_analyses/
compute_rsc.py , Python, 140 lines - main_analyses/
create_fig3_dataset_vary , Python, 72 linesN.py - main_analyses/
create_fig5_dataset.py , Python, 151 lines - main_analyses/
create_figS2_dataset_var , Python, 73 linesyDim.py - main_analyses/
create_figS2_dataset_var , Python, 71 linesySv.py - main_analyses/
create_figS3_dataset_var , Python, 54 linesyTheta.py - main_analyses/
create_figS9_dataset_var , Python, 110 linesyThetaSubsample.py - main_analyses/
dual_pfc_funcs.py , Python, 196 lines - main_analyses/
fit_alt_models.py , Python, 89 lines - main_analyses/
fit_flip_pccafa_models.p , Python, 74 linesy - main_analyses/
fit_pccafa_models.py , Python, 60 lines - main_analyses/
fit_shuffle_pccafa.py , Python, 69 lines - main_analyses/
fit_slow_pccafa_models.p , Python, 57 linesy - main_analyses/
fit_zsc_pccafa.py , Python, 80 lines - plot_figure1.ipynb, Jupyter, 39 lines
- plot_figure2.ipynb, Jupyter, 256 lines
- plot_figure3.ipynb, Jupyter, 308 lines
- plot_figure4.ipynb, Jupyter, 278 lines
- plot_figure5.ipynb, Jupyter, 176 lines
- plot_figure6.ipynb, Jupyter, 152 lines
- plot_figureS1.ipynb, Jupyter, 215 lines
- plot_figureS10.ipynb, Jupyter, 367 lines
- plot_figureS2.ipynb, Jupyter, 247 lines
- plot_figureS3.ipynb, Jupyter, 152 lines
- plot_figureS4.ipynb, Jupyter, 234 lines
- plot_figureS5.ipynb, Jupyter, 106 lines
- plot_figureS6.ipynb, Jupyter, 135 lines
- plot_figureS7.ipynb, Jupyter, 188 lines
- plot_figureS8.ipynb, Jupyter, 128 lines
- plot_figureS9.ipynb, Jupyter, 118 lines
- README.md, Text, 61 lines
Zenodo 18913385
Availability: 1 check, the latest on 29 September 2026: the link answers (HTTP 200)
- 29 September 2026: the link answers (HTTP 200)
5 files
- pcca_fa_mdl.py, Python, 984 lines
- sim_pcca_fa.py, Python, 326 lines
- tutorial.ipynb, Jupyter, 168 lines
- LICENSE, License, 201 lines
- README.md, Text, 43 lines
Code availability statement
The paper has a code availability statement. Its license (CC BY-NC-ND) does not allow reproducing it here; in short, from what the harvester recognized in it:
- it points to the authors' code: meganmcd13/
figures-dual-pfc , SmithLabNeuro/Ex , SmithLabNeuro/pcca_fa , Zenodo 18913386, Zenodo 18929016
Read it in the paper: doi.org/10.1038/s41467-026-71725-0.
Tracing map
Proposed by the machine: these links were found in the paper and verified at the source, without human review. The map will receive a Zenodo DOI once one of the paper's authors has validated it with their ORCID.
What the map holds:
- 6 repositories of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
- 523 scripts, each with its path and the digest of its content;
- 20 matches between paragraphs of the paper and lines of the code (method lexical-v1);
- neither the text of the paper nor the code itself.
Its JSON (tracing-map.json) is deposited on Zenodo with its DOI once the map is validated.
Data
No dataset and no data link were found in the paper.
Data availability statement
The paper has a data availability statement. Its license (CC BY-NC-ND) does not allow reproducing it here; in short, from what the harvester recognized in it:
- no repository, dataset or request procedure was recognized in it
Read it in the paper: doi.org/10.1038/s41467-026-71725-0.
Versions
The history of this record: each version stored by the harvester or made by a correction of its authors or of the maintainers of its code, and what changed in its facts. The texts of the paper (its abstract, its availability statements) are not part of it; versions that changed only those are not listed.
Version 1, 29 September 2026: the first record
Recorded: type, language, journal, volume, issue, pages, dates, 5 authors, 2 keywords, 7 MeSH terms, 10 funders, 137 references.
Cite
This paper
McDonnell, M. E., Umakantha, A., Williamson, R. C., Smith, M. A., & Yu, B. M. (2026). Interactions across hemispheres in prefrontal cortex reflect global cognitive processing. Nature communications, 17(1), 5088. https://
BibTeX
@article{mcdonnell2026in
author = {McDonnell, Megan E and Umakantha, Akash and Williamson, Ryan C and Smith, Matthew A and Yu, Byron M},
title = {{Interactions across hemispheres in prefrontal cortex reflect global cognitive processing}},
journal = {Nature communications},
year = {2026},
month = apr,
volume = {17},
number = {1},
pages = {5088},
publisher = {Nature Publishing Group},
issn = {2041-1723},
doi = {10.1038/
url = {https://
pmid = {41965893},
pmcid = {PMC13247044}
}
RIS
TY - JOUR
AU - McDonnell, Megan E
AU - Umakantha, Akash
AU - Williamson, Ryan C
AU - Smith, Matthew A
AU - Yu, Byron M
TI - Interactions across hemispheres in prefrontal cortex reflect global cognitive processing
T2 - Nature communications
J2 - Nat Commun
PY - 2026
DA - 2026/
VL - 17
IS - 1
SP - 5088
SN - 2041-1723
PB - Nature Publishing Group
DO - 10.1038/
UR - https://
LA - en
ER -
CSL-JSON
{
"id": "10.1038/
"type": "article-journal",
"title": "Interactions across hemispheres in prefrontal cortex reflect global cognitive processing",
"container-title": "Nature communications",
"author": [
{
"family": "McDonnell",
"given": "Megan E"
},
{
"family": "Umakantha",
"given": "Akash"
},
{
"family": "Williamson",
"given": "Ryan C"
},
{
"family": "Smith",
"given": "Matthew A"
},
{
"family": "Yu",
"given": "Byron M"
}
],
"container-title-short":
"volume": "17",
"issue": "1",
"page": "5088",
"DOI": "10.1038/
"PMID": "41965893",
"PMCID": "PMC13247044",
"ISSN": "2041-1723",
"publisher": "Nature Publishing Group",
"URL": "https://
"language": "en",
"issued": {
"date-parts": [
[
2026,
4,
11
]
]
}
}
The tracing map gets a citation of its own once an author has validated it and it has a DOI.
Similar papers
The papers with a page that share the most with this one: the tools found in their code, their categories, datasets, cited references and authors, the rarest counting most.
- [1] doi:10.1016/j.neuron.2026.07.016 [code]
- Inferring brain-wide interactions using data-constrained recurrent neural network models.Journal: NeuronIn common: Parallel Computing Toolbox, Image Processing Toolbox, Statistics and Machine Learning Toolbox, 2 other tools, 14 references
- [2] doi:10.7554/elife.99278 [code]
- Brain-wide arousal signals are segregated from movement planning in the superior colliculus of the macaque.Journal: eLifeIn common: NumPy, non-human primate, 11 references, author Matthew A Smith
- [3] doi:10.1038/s41467-026-75347-4 [code]
- Sleep reveals dynamics integrating and segregating movement and stimulus representations in V1.Journal: Nature communicationsIn common: export_fig, Optimization Toolbox, Parallel Computing Toolbox, 8 other tools, 7 references
- [4] doi:10.1371/journal.pbio.3003915 [code]
- Noise-invariant representations of sound emerge along the canonical cortical hierarchy.Journal: PLoS biologyIn common: Optimization Toolbox, Statistics and Machine Learning Toolbox, scikit-learn, 4 other tools, 9 references
- [5] doi:10.1038/s41467-026-75705-2 [code]
- Redundant prefrontal hemispheres adapt storage strategy to working memory demands.Journal: Nature communicationsIn common: scikit-learn, pandas, SciPy, 2 other tools, non-human primate, cognitive, 6 references, author Matthew A Smith
- [6] doi:10.1126/sciadv.adz6495
- Pupil-linked arousal heterogeneously modulates cell-type-specific sensory processing.Journal: Science advancesIn common: 13 references
- [7] doi:10.1038/s41598-026-55225-1 [code]
- Benchmarking criteria to determine latent linear dimensionality in neural data.Journal: Scientific reportsIn common: Statistics and Machine Learning Toolbox, pandas, 11 references
- [8] doi:10.1038/s41586-026-10631-3 [code]
- A prognostic human brain network for diffuse midline glioma.Journal: NatureIn common: export_fig, Psychtoolbox, Optimization Toolbox, 9 other tools
- [9] doi:10.1126/sciadv.adv5652 [code]
- The anterior cingulate cortex modulates pupil-linked arousal.Journal: Science advancesIn common: pandas, SciPy, Matplotlib, 1 other tool, 9 references
- [10] doi:10.1002/hbm.70602 [code]
- Neuroimaging Correlates of Post-Stroke Pain After Ischemic Stroke: Secondary Analysis of the INSPiRE-TMS Trial.Journal: Human brain mappingIn common: export_fig, Psychtoolbox, Optimization Toolbox, 8 other tools
Contribute
The authors of this paper can claim it, correct its record and validate its tracing map, and the maintainers of its code (its owner, or a public member of its organization) correct what it says of their repository; anyone signed in can ask for its removal. Every request goes to OSCR's own machine, which answers it; your account page follows them.
Sign in with ORCID to claim this paper as one of its authors, correct its record or validate its tracing map: when the paper's metadata lists your ORCID iD, you are recognized at once. Maintainers of its code: sign in with GitHub, then claim the repository on your account page.
Claim this paper
Correct its record
Say what each link of this record is, remove the ones that are not the paper's, add the ones that are missing. The correction becomes a new version of the record, in its Versions section.
Validate its tracing map
You validate the map as this page shows it: 6 repositories of the authors' code, each at its verified commit and with its license, 523 scripts, and 20 matches between paragraphs and code (see the Code and Map sections). It then receives a DOI on Zenodo, with you (your ORCID iD) and OSCR as its creators; the code itself is not deposited.
The map's fingerprint: sha256:7d7d5e2d4d30c6a2…
Add the badge to its README
The badge links the code to this page. Copy one of these into the README of the paper's code: only you decide where it goes, and nothing is changed for you.
Markdown
[, paste the snippet at the top, then “Commit changes…” and, to review it first, “Create a new branch and start a pull request”. You open the pull request; OSCR asks for no permission.
Request its removal
To ask OSCR to remove this record, the copies of its authors' scripts or its tracing map, use the removal request page: signed in, you say who you are, what to remove and why, then review and confirm the request. Published rules decide every request (how).
Discussion, reproductions, activity
Discussion: questions and error reports about this paper and its code, from signed-in readers and its authors. It opens with sign-in.
Reproductions: reports from readers who ran the authors' code: what they reproduced, with which environment, commit and data. It opens with sign-in.
Activity: what happens around this paper: new versions of its record, its map's validation, discussions and reproductions. It opens with sign-in.
