def verify_roi_lists_equal(self, roi1, roi2): if len(roi1) != len(roi2): raise BrainObservatoryAnalysisException( "Error -- ROI lists are of different length") for i in range(len(roi1)): if roi1[i] != roi2[i]: raise BrainObservatoryAnalysisException( "Error -- ROI lists have different entries")
def verify_roi_lists_equal(self, roi1, roi2): """ TODO: replace this with simpler numpy comparisons """ if len(roi1) != len(roi2): raise BrainObservatoryAnalysisException( "Error -- ROI lists are of different length") for i in range(len(roi1)): if roi1[i] != roi2[i]: raise BrainObservatoryAnalysisException( "Error -- ROI lists have different entries")
def get_speed_tuning(self, binsize): """ Calculates speed tuning, spontaneous versus visually driven. The return is a 5-tuple of speed and dF/F histograms. binned_dx_sp: (bins,2) np.ndarray of running speeds binned during spontaneous activity stimulus. The first bin contains all speeds below 1 cm/s. Dimension 0 is mean running speed in the bin. Dimension 1 is the standard error of the mean. binned_cells_sp: (bins,2) np.ndarray of fluorescence during spontaneous activity stimulus. First bin contains all data for speeds below 1 cm/s. Dimension 0 is mean fluorescence in the bin. Dimension 1 is the standard error of the mean. binned_dx_vis: (bins,2) np.ndarray of running speeds outside of spontaneous activity stimulus. The first bin contains all speeds below 1 cm/s. Dimension 0 is mean running speed in the bin. Dimension 1 is the standard error of the mean. binned_cells_vis: np.ndarray of fluorescence outside of spontaneous activity stimulu. First bin contains all data for speeds below 1 cm/s. Dimension 0 is mean fluorescence in the bin. Dimension 1 is the standard error of the mean. peak_run: pd.DataFrame of speed-related properties of a cell. Returns ------- tuple: binned_dx_sp, binned_cells_sp, binned_dx_vis, binned_cells_vis, peak_run """ StimulusAnalysis._log.info( 'Calculating speed tuning, spontaneous vs visually driven') celltraces_trimmed = np.delete(self.dfftraces, range(len(self.dxcm), np.size(self.dfftraces, 1)), axis=1) # pull out spontaneous epoch(s) spontaneous = self.data_set.get_stimulus_table('spontaneous') peak_run = pd.DataFrame( index=range(self.numbercells), columns=('speed_max_sp', 'speed_min_sp', 'ptest_sp', 'mod_sp', 'speed_max_vis', 'speed_min_vis', 'ptest_vis', 'mod_vis')) dx_sp = self.dxcm[spontaneous.start.iloc[-1]:spontaneous.end.iloc[-1]] celltraces_sp = celltraces_trimmed[:, spontaneous.start. iloc[-1]:spontaneous.end.iloc[-1]] dx_vis = np.delete( self.dxcm, np.arange(spontaneous.start.iloc[-1], spontaneous.end.iloc[-1])) celltraces_vis = np.delete(celltraces_trimmed, np.arange(spontaneous.start.iloc[-1], spontaneous.end.iloc[-1]), axis=1) if len(spontaneous) > 1: dx_sp = np.append( dx_sp, self.dxcm[spontaneous.start.iloc[-2]:spontaneous.end.iloc[-2]], axis=0) celltraces_sp = np.append( celltraces_sp, celltraces_trimmed[:, spontaneous.start.iloc[-2]:spontaneous. end.iloc[-2]], axis=1) dx_vis = np.delete( dx_vis, np.arange(spontaneous.start.iloc[-2], spontaneous.end.iloc[-2])) celltraces_vis = np.delete(celltraces_vis, np.arange(spontaneous.start.iloc[-2], spontaneous.end.iloc[-2]), axis=1) celltraces_vis = celltraces_vis[:, ~np.isnan(dx_vis)] dx_vis = dx_vis[~np.isnan(dx_vis)] nbins = 1 + len(np.where(dx_sp >= 1)[0]) / binsize dx_sorted = dx_sp[np.argsort(dx_sp)] celltraces_sorted_sp = celltraces_sp[:, np.argsort(dx_sp)] binned_cells_sp = np.zeros((self.numbercells, nbins, 2)) binned_dx_sp = np.zeros((nbins, 2)) for i in range(nbins): if np.all(np.isnan(dx_sorted)): raise BrainObservatoryAnalysisException( "dx is filled with NaNs") offset = findlevel(dx_sorted, 1, 'up') if offset is None: logging.info( "dx never crosses 1, all speed data going into single bin") offset = len(dx_sorted) if i == 0: binned_dx_sp[i, 0] = np.mean(dx_sorted[:offset]) binned_dx_sp[i, 1] = np.std(dx_sorted[:offset]) / np.sqrt(offset) binned_cells_sp[:, i, 0] = np.mean(celltraces_sorted_sp[:, :offset], axis=1) binned_cells_sp[:, i, 1] = np.std(celltraces_sorted_sp[:, :offset], axis=1) / np.sqrt(offset) else: start = offset + (i - 1) * binsize binned_dx_sp[i, 0] = np.mean(dx_sorted[start:start + binsize]) binned_dx_sp[i, 1] = np.std( dx_sorted[start:start + binsize]) / np.sqrt(binsize) binned_cells_sp[:, i, 0] = np.mean( celltraces_sorted_sp[:, start:start + binsize], axis=1) binned_cells_sp[:, i, 1] = np.std( celltraces_sorted_sp[:, start:start + binsize], axis=1) / np.sqrt(binsize) binned_cells_shuffled_sp = np.empty((self.numbercells, nbins, 2, 200)) for shuf in range(200): celltraces_shuffled = celltraces_sp[:, np.random.permutation( np.size(celltraces_sp, 1))] celltraces_shuffled_sorted = celltraces_shuffled[:, np.argsort(dx_sp)] for i in range(nbins): offset = findlevel(dx_sorted, 1, 'up') if offset is None: logging.info( "dx never crosses 1, all speed data going into single bin" ) offset = celltraces_shuffled_sorted.shape[1] if i == 0: binned_cells_shuffled_sp[:, i, 0, shuf] = np.mean( celltraces_shuffled_sorted[:, :offset], axis=1) binned_cells_shuffled_sp[:, i, 1, shuf] = np.std( celltraces_shuffled_sorted[:, :offset], axis=1) else: start = offset + (i - 1) * binsize binned_cells_shuffled_sp[:, i, 0, shuf] = np.mean( celltraces_shuffled_sorted[:, start:start + binsize], axis=1) binned_cells_shuffled_sp[:, i, 1, shuf] = np.std( celltraces_shuffled_sorted[:, start:start + binsize], axis=1) nbins = 1 + len(np.where(dx_vis >= 1)[0]) / binsize dx_sorted = dx_vis[np.argsort(dx_vis)] celltraces_sorted_vis = celltraces_vis[:, np.argsort(dx_vis)] binned_cells_vis = np.zeros((self.numbercells, nbins, 2)) binned_dx_vis = np.zeros((nbins, 2)) for i in range(nbins): offset = findlevel(dx_sorted, 1, 'up') if i == 0: binned_dx_vis[i, 0] = np.mean(dx_sorted[:offset]) binned_dx_vis[i, 1] = np.std(dx_sorted[:offset]) / np.sqrt(offset) binned_cells_vis[:, i, 0] = np.mean( celltraces_sorted_vis[:, :offset], axis=1) binned_cells_vis[:, i, 1] = np.std(celltraces_sorted_vis[:, :offset], axis=1) / np.sqrt(offset) else: start = offset + (i - 1) * binsize binned_dx_vis[i, 0] = np.mean(dx_sorted[start:start + binsize]) binned_dx_vis[i, 1] = np.std( dx_sorted[start:start + binsize]) / np.sqrt(binsize) binned_cells_vis[:, i, 0] = np.mean( celltraces_sorted_vis[:, start:start + binsize], axis=1) binned_cells_vis[:, i, 1] = np.std( celltraces_sorted_vis[:, start:start + binsize], axis=1) / np.sqrt(binsize) binned_cells_shuffled_vis = np.empty((self.numbercells, nbins, 2, 200)) for shuf in range(200): celltraces_shuffled = celltraces_vis[:, np.random.permutation( np. size(celltraces_vis, 1))] celltraces_shuffled_sorted = celltraces_shuffled[:, np.argsort(dx_vis )] for i in range(nbins): offset = findlevel(dx_sorted, 1, 'up') if i == 0: binned_cells_shuffled_vis[:, i, 0, shuf] = np.mean( celltraces_shuffled_sorted[:, :offset], axis=1) binned_cells_shuffled_vis[:, i, 1, shuf] = np.std( celltraces_shuffled_sorted[:, :offset], axis=1) else: start = offset + (i - 1) * binsize binned_cells_shuffled_vis[:, i, 0, shuf] = np.mean( celltraces_shuffled_sorted[:, start:start + binsize], axis=1) binned_cells_shuffled_vis[:, i, 1, shuf] = np.std( celltraces_shuffled_sorted[:, start:start + binsize], axis=1) shuffled_variance_sp = binned_cells_shuffled_sp[:, :, 0, :].std(axis=1)**2 variance_threshold_sp = np.percentile(shuffled_variance_sp, 99.9, axis=1) response_variance_sp = binned_cells_sp[:, :, 0].std(axis=1)**2 shuffled_variance_vis = binned_cells_shuffled_vis[:, :, 0, :].std(axis=1)**2 variance_threshold_vis = np.percentile(shuffled_variance_vis, 99.9, axis=1) response_variance_vis = binned_cells_vis[:, :, 0].std(axis=1)**2 for nc in range(self.numbercells): if response_variance_vis[nc] > variance_threshold_vis[nc]: peak_run.mod_vis[nc] = True if response_variance_vis[nc] <= variance_threshold_vis[nc]: peak_run.mod_vis[nc] = False if response_variance_sp[nc] > variance_threshold_sp[nc]: peak_run.mod_sp[nc] = True if response_variance_sp[nc] <= variance_threshold_sp[nc]: peak_run.mod_sp[nc] = False temp = binned_cells_sp[nc, :, 0] start_max = temp.argmax() peak_run.speed_max_sp[nc] = binned_dx_sp[start_max, 0] start_min = temp.argmin() peak_run.speed_min_sp[nc] = binned_dx_sp[start_min, 0] if peak_run.speed_max_sp[nc] > peak_run.speed_min_sp[nc]: test_values = celltraces_sorted_sp[nc, start_max * binsize:(start_max + 1) * binsize] other_values = np.delete( celltraces_sorted_sp[nc, :], range(start_max * binsize, (start_max + 1) * binsize)) (_, peak_run.ptest_sp[nc]) = st.ks_2samp(test_values, other_values) else: test_values = celltraces_sorted_sp[nc, start_min * binsize:(start_min + 1) * binsize] other_values = np.delete( celltraces_sorted_sp[nc, :], range(start_min * binsize, (start_min + 1) * binsize)) (_, peak_run.ptest_sp[nc]) = st.ks_2samp(test_values, other_values) temp = binned_cells_vis[nc, :, 0] start_max = temp.argmax() peak_run.speed_max_vis[nc] = binned_dx_vis[start_max, 0] start_min = temp.argmin() peak_run.speed_min_vis[nc] = binned_dx_vis[start_min, 0] if peak_run.speed_max_vis[nc] > peak_run.speed_min_vis[nc]: test_values = celltraces_sorted_vis[nc, start_max * binsize:(start_max + 1) * binsize] other_values = np.delete( celltraces_sorted_vis[nc, :], range(start_max * binsize, (start_max + 1) * binsize)) else: test_values = celltraces_sorted_vis[nc, start_min * binsize:(start_min + 1) * binsize] other_values = np.delete( celltraces_sorted_vis[nc, :], range(start_min * binsize, (start_min + 1) * binsize)) (_, peak_run.ptest_vis[nc]) = st.ks_2samp(test_values, other_values) return binned_dx_sp, binned_cells_sp, binned_dx_vis, binned_cells_vis, peak_run
def get_peak(self): ''' Computes metrics related to each cell's peak response condition. Returns ------- Panda data frame with the following fields (_sg suffix is for static grating): * ori_sg (orientation) * sf_sg (spatial frequency) * phase_sg * response_variability_sg * osi_sg (orientation selectivity index) * peak_dff_sg (peak dF/F) * ptest_sg * time_to_peak_sg * duration_sg ''' StaticGratings._log.info('Calculating peak response properties') peak = pd.DataFrame(index=range(self.numbercells), columns=('ori_sg', 'sf_sg', 'phase_sg', 'response_reliability_sg', 'osi_sg', 'peak_dff_sg', 'ptest_sg', 'time_to_peak_sg', 'duration_sg', 'cell_specimen_id')) cids = self.data_set.get_cell_specimen_ids() for nc in range(self.numbercells): cell_peak = np.where(self.response[:, 1:, :, nc, 0] == np.nanmax( self.response[:, 1:, :, nc, 0])) pref_ori = cell_peak[0][0] pref_sf = cell_peak[1][0] + 1 pref_phase = cell_peak[2][0] peak.cell_specimen_id.iloc[nc] = cids[nc] peak.ori_sg[nc] = pref_ori peak.sf_sg[nc] = pref_sf peak.phase_sg[nc] = pref_phase peak.response_reliability_sg[nc] = self.response[ pref_ori, pref_sf, pref_phase, nc, 2] / 0.48 # TODO: check number of trials pref = self.response[pref_ori, pref_sf, pref_phase, nc, 0] orth = self.response[ np.mod(pref_ori + 3, 6), pref_sf, pref_phase, nc, 0] peak.osi_sg[nc] = (pref - orth) / (pref + orth) peak.peak_dff_sg[nc] = pref groups = [] for ori in self.orivals: for sf in self.sfvals[1:]: for phase in self.phasevals: groups.append(self.mean_sweep_response[(self.stim_table.spatial_frequency == sf) & ( self.stim_table.orientation == ori) & (self.stim_table.phase == phase)][str(nc)]) groups.append(self.mean_sweep_response[ self.stim_table.spatial_frequency == 0][str(nc)]) _, p = st.f_oneway(*groups) peak.ptest_sg[nc] = p test_rows = (self.stim_table.orientation == self.orivals[pref_ori]) & \ (self.stim_table.spatial_frequency == self.sfvals[pref_sf]) & \ (self.stim_table.phase == self.phasevals[pref_phase]) if len(test_rows) < 2: msg = "Static grating p value requires at least 2 trials at the preferred " "orientation/spatial frequency/phase. Cell %d (%f, %f, %f) has %d." % \ (int(nc), self.orivals[pref_ori], self.sfvals[pref_sf], self.phasevals[pref_phase], len(test_rows)) raise BrainObservatoryAnalysisException(msg) test = self.sweep_response[test_rows][str(nc)].mean() peak.time_to_peak_sg[nc] = ( np.argmax(test) - self.interlength) / self.acquisition_rate test2 = np.where(test < (test.max() / 2))[0] try: peak.duration_sg[nc] = np.ediff1d( test2).max() / self.acquisition_rate except: pass return peak
def get_peak(self): """ Implemented by subclasses. """ raise BrainObservatoryAnalysisException("get_peak not implemented")