def loc_auto_corr_down(self, ftimes, other_spatial, other_ftimes, **kwargs): """ Calculate auto correlation after downsampling. Calculates the two-dimensional correlation of firing map which is the map of the firing rate of the animal with respect to its location Parameters ---------- ftimes : ndarray Timestamps of the spiking activity of a unit other_spatial : NSpatial The spatial data to downsample to. other_ftimes : list or ndarray The firing times of the cell in other spatial. **kwargs Keyword arguments Returns ------- dict Graphical data of the analysis """ graph_data = {} minPixel = kwargs.get('minPixel', 20) pixel = kwargs.get('pixel', 3) if 'update' in kwargs.keys(): del kwargs['update'] placeData = self.downsample_place( ftimes, other_spatial, other_ftimes, update=False, **kwargs) fmap = placeData['smoothMap'] fmap[np.isnan(fmap)] = 0 leny, lenx = fmap.shape xshift = np.arange(-(lenx - 1), lenx) yshift = np.arange(-(leny - 1), leny) corrMap = np.zeros((yshift.size, xshift.size)) for J, ysh in enumerate(yshift): for I, xsh in enumerate(xshift): if ysh >= 0: map1YInd = np.arange(ysh, leny) map2YInd = np.arange(leny - ysh) elif ysh < 0: map1YInd = np.arange(leny + ysh) map2YInd = np.arange(-ysh, leny) if xsh >= 0: map1XInd = np.arange(xsh, lenx) map2XInd = np.arange(lenx - xsh) elif xsh < 0: map1XInd = np.arange(lenx + xsh) map2XInd = np.arange(-xsh, lenx) map1 = fmap[tuple(np.meshgrid(map1YInd, map1XInd))] map2 = fmap[tuple(np.meshgrid(map2YInd, map2XInd))] if map1.size < minPixel: corrMap[J, I] = -1 else: corrMap[J, I] = corr_coeff(map1, map2) graph_data['corrMap'] = corrMap graph_data['xshift'] = xshift * pixel graph_data['yshift'] = yshift * pixel return graph_data
def grid_down(self, ftimes, other_spatial, other_ftimes, **kwargs): """ Perform grid cell analysis after downsampling. Analysis of Grid cells characterised by formation of grid-like pattern of high activity in the firing-rate map Parameters ---------- ftimes : ndarray Timestamps of the spiking activity of a unit other_spatial : NSpatial The spatial data to downsample to. other_ftimes : list or ndarray The firing times of the cell in other spatial. **kwargs Keyword arguments Returns ------- dict Graphical data of the analysis """ _results = oDict() tol = kwargs.get('angtol', 2) binsize = kwargs.get('binsize', 3) bins = np.arange(0, 360, binsize) graph_data = self.loc_auto_corr_down( ftimes, other_spatial, other_ftimes, update=False, **kwargs) corrMap = graph_data['corrMap'] corrMap[np.isnan(corrMap)] = 0 xshift = graph_data['xshift'] yshift = graph_data['yshift'] pixel = np.int(np.diff(xshift).mean()) ny, nx = corrMap.shape rpeaks = np.zeros(corrMap.shape, dtype=bool) cpeaks = np.zeros(corrMap.shape, dtype=bool) for j in np.arange(ny): rpeaks[j, extrema(corrMap[j, :])[1]] = True for i in np.arange(nx): cpeaks[extrema(corrMap[:, i])[1], i] = True ymax, xmax = find2d(np.logical_and(rpeaks, cpeaks)) peakDist = np.sqrt((ymax - find(yshift == 0))**2 + (xmax - find(xshift == 0))**2) sortInd = np.argsort(peakDist) ymax, xmax, peakDist = ymax[sortInd], xmax[sortInd], peakDist[sortInd] ymax, xmax, peakDist = ( ymax[1:7], xmax[1:7], peakDist[1:7]) if ymax.size >= 7 else ([], [], []) theta = np.arctan2(yshift[ymax], xshift[xmax]) * 180 / np.pi theta[theta < 0] += 360 sortInd = np.argsort(theta) ymax, xmax, peakDist, theta = ( ymax[sortInd], xmax[sortInd], peakDist[sortInd], theta[sortInd]) graph_data['ymax'] = yshift[ymax] graph_data['xmax'] = xshift[xmax] meanDist = peakDist.mean() X, Y = np.meshgrid(xshift, yshift) distMat = np.sqrt(X**2 + Y**2) / pixel maskInd = np.logical_and( distMat > 0.5 * meanDist, distMat < 1.5 * meanDist) rotCorr = np.array([corr_coeff(rot_2d(corrMap, theta)[ maskInd], corrMap[maskInd]) for k, theta in enumerate(bins)]) ramax, rimax, ramin, rimin = extrema(rotCorr) mThetaPk, mThetaTr = (np.diff(bins[rimax]).mean(), np.diff( bins[rimin]).mean()) if rimax.size and rimin.size else (None, None) graph_data['rimax'] = rimax graph_data['rimin'] = rimin graph_data['anglemax'] = bins[rimax] graph_data['anglemin'] = bins[rimin] graph_data['rotAngle'] = bins graph_data['rotCorr'] = rotCorr if mThetaPk is not None and mThetaTr is not None: isGrid = True if 60 - tol < mThetaPk < 60 + \ tol and 60 - tol < mThetaTr < 60 + tol else False else: isGrid = False meanAlpha = np.diff(theta).mean() psi = theta[np.array([2, 3, 4, 5, 0, 1])] - theta psi[psi < 0] += 360 meanPsi = psi.mean() _results["First Check"] = (len(ymax) == np.logical_and( peakDist > 0.75 * meanDist, peakDist < 1.25 * meanDist).sum()) _results['Is Grid'] = isGrid and 120 - tol < meanPsi < 120 + \ tol and 60 - tol < meanAlpha < 60 + tol _results['Grid Mean Alpha'] = meanAlpha _results['Grid Mean Psi'] = meanPsi _results['Grid Spacing'] = meanDist * pixel # Difference between highest Pearson R at peaks and lowest at troughs _results['Grid Score'] = rotCorr[rimax].max() - \ rotCorr[rimin].min() _results['Grid Orientation'] = theta[0] self.update_result(_results) return graph_data
def always_grid(self, ftimes, **kwargs): """ This outputs grid cell statistics even if the cell is clearly not grid. Recommended to use NeuroChaTs method, this was to test the values in non grid situations. Analysis of Grid cells characterised by formation of grid-like pattern of high activity in the firing-rate map. Parameters ---------- ftimes : ndarray Timestamps of the spiking activity of a unit **kwargs Keyword arguments Returns ------- dict Graphical data of the analysis """ _results = oDict() tol = kwargs.get("angtol", 2) binsize = kwargs.get("binsize", 3) bins = np.arange(0, 360, binsize) graph_data = self.loc_auto_corr(ftimes, update=False, **kwargs) corrMap = graph_data["corrMap"] corrMap[np.isnan(corrMap)] = 0 xshift = graph_data["xshift"] yshift = graph_data["yshift"] pixel = np.int(np.diff(xshift).mean()) ny, nx = corrMap.shape rpeaks = np.zeros(corrMap.shape, dtype=bool) cpeaks = np.zeros(corrMap.shape, dtype=bool) for j in np.arange(ny): rpeaks[j, extrema(corrMap[j, :])[1]] = True for i in np.arange(nx): cpeaks[extrema(corrMap[:, i])[1], i] = True ymax, xmax = find2d(np.logical_and(rpeaks, cpeaks)) peakDist = np.sqrt((ymax - find(yshift == 0))**2 + (xmax - find(xshift == 0))**2) sortInd = np.argsort(peakDist) ymax, xmax, peakDist = ymax[sortInd], xmax[sortInd], peakDist[sortInd] ymax, xmax, peakDist = ((ymax[1:7], xmax[1:7], peakDist[1:7]) if ymax.size >= 7 else ([], [], [])) theta = np.arctan2(yshift[ymax], xshift[xmax]) * 180 / np.pi theta[theta < 0] += 360 sortInd = np.argsort(theta) ymax, xmax, peakDist, theta = ( ymax[sortInd], xmax[sortInd], peakDist[sortInd], theta[sortInd], ) graph_data["ymax"] = yshift[ymax] graph_data["xmax"] = xshift[xmax] meanDist = peakDist.mean() X, Y = np.meshgrid(xshift, yshift) distMat = np.sqrt(X**2 + Y**2) / pixel _results["First Check"] = (len(ymax) == np.logical_and( peakDist > 0.75 * meanDist, peakDist < 1.25 * meanDist).sum()) maskInd = np.logical_and(distMat > 0.5 * meanDist, distMat < 1.5 * meanDist) rotCorr = np.array([ corr_coeff(rot_2d(corrMap, theta)[maskInd], corrMap[maskInd]) for k, theta in enumerate(bins) ]) ramax, rimax, ramin, rimin = extrema(rotCorr) mThetaPk, mThetaTr = ((np.diff(bins[rimax]).mean(), np.diff( bins[rimin]).mean()) if rimax.size and rimin.size else (None, None)) graph_data["rimax"] = rimax graph_data["rimin"] = rimin graph_data["anglemax"] = bins[rimax] graph_data["anglemin"] = bins[rimin] graph_data["rotAngle"] = bins graph_data["rotCorr"] = rotCorr if mThetaPk is not None and mThetaTr is not None: isGrid = (True if 60 - tol < mThetaPk < 60 + tol and 60 - tol < mThetaTr < 60 + tol else False) else: isGrid = False meanAlpha = np.diff(theta).mean() psi = theta[np.array([2, 3, 4, 5, 0, 1])] - theta psi[psi < 0] += 360 meanPsi = psi.mean() _results["Is Grid"] = (isGrid and 120 - tol < meanPsi < 120 + tol and 60 - tol < meanAlpha < 60 + tol) _results["Grid Mean Alpha"] = meanAlpha _results["Grid Mean Psi"] = meanPsi _results["Grid Spacing"] = meanDist * pixel # Difference between highest Pearson R at peaks and lowest at troughs _results["Grid Score"] = rotCorr[rimax].max() - rotCorr[rimin].min() _results["Grid Orientation"] = theta[0] self.update_result(_results) return graph_data