def calc_learned_state_trans_mat(linpos_simple, enc_settings, dec_settings): """ Calculate the point process transition matrix using the real behavior of the animal. This is the 2D matrix that defines the possible range of transitions in the position estimate. The learned values are smoothed with a gaussian kernel and a uniform offset is added, specified by the encoding config. The matrix is column normalized. Args: linpos_simple (pd.DataFrame): Linear position pandas table with no MultiIndex. enc_settings (EncodeSettings): Encoder settings from a realtime config. dec_settings (DecodeSettings): Decoder settings from a realtime config. Returns: Learned transition matrix. """ pos_num_bins = len(enc_settings.pos_bins) # Smoothing kernel for learned pos transition matrix xv, yv = np.meshgrid(np.arange(-20, 21), np.arange(-20, 21)) kernel = normal2D(xv, yv, dec_settings.trans_smooth_std) kernel /= kernel.sum() linpos_state = linpos_simple linpos_ind = np.searchsorted(enc_settings.pos_bins, linpos_state, side='right') - 1 # Create learned pos transition matrix learned_trans_mat = np.zeros([pos_num_bins, pos_num_bins]) for first_pos_ind, second_pos_ind in zip(linpos_ind[:-1], linpos_ind[1:]): learned_trans_mat[first_pos_ind, second_pos_ind] += 1 # normalize learned_trans_mat = learned_trans_mat / (learned_trans_mat.sum(axis=0)[None, :]) learned_trans_mat[np.isnan(learned_trans_mat)] = 0 # smooth learned_trans_mat = sp.signal.convolve2d(learned_trans_mat, kernel, mode='same') learned_trans_mat = apply_no_anim_boundary(enc_settings.pos_bins, enc_settings.arm_coordinates, learned_trans_mat) # uniform offset uniform_gain = dec_settings.trans_uniform_gain uniform_dist = np.ones(learned_trans_mat.shape) # no-animal boundary uniform_dist = apply_no_anim_boundary(enc_settings.pos_bins, enc_settings.arm_coordinates, uniform_dist) # normalize uniform offset uniform_dist = uniform_dist / (uniform_dist.sum(axis=0)[None, :]) uniform_dist[np.isnan(uniform_dist)] = 0 # apply uniform offset learned_trans_mat = learned_trans_mat * (1 - uniform_gain) + uniform_dist * uniform_gain # renormalize learned_trans_mat = learned_trans_mat / (learned_trans_mat.sum(axis=0)[None, :]) learned_trans_mat[np.isnan(learned_trans_mat)] = 0 return learned_trans_mat
def _create_transition_matrix(pos_delta, num_bins, arm_coor, uniform_gain=0.01): def gaussian(x, mu, sig): return np.exp(-np.power(x - mu, 2.) / (2 * np.power(sig, 2.))) # Setup transition matrix x_bins = np.linspace(0, pos_delta*(num_bins-1), num_bins) transition_mat = np.ones([num_bins, num_bins]) for bin_ii in range(num_bins): transition_mat[bin_ii, :] = gaussian(x_bins, x_bins[bin_ii], 3) # uniform offset uniform_dist = np.ones(transition_mat.shape) # apply no-animal boundary transition_mat = apply_no_anim_boundary(x_bins, arm_coor, transition_mat) uniform_dist = apply_no_anim_boundary(x_bins, arm_coor, uniform_dist) # normalize transition matrix transition_mat = transition_mat/(transition_mat.sum(axis=0)[None, :]) transition_mat[np.isnan(transition_mat)] = 0 # normalize uniform offset uniform_dist = uniform_dist/(uniform_dist.sum(axis=0)[None, :]) uniform_dist[np.isnan(uniform_dist)] = 0 # apply uniform offset transition_mat = transition_mat * (1 - uniform_gain) + uniform_dist * uniform_gain return transition_mat
def calc_uniform_trans_mat(enc_settings): """ Calculate a simple uniform point process transition matrix. Args: enc_settings (EncodeSettings): Encoder setting from realtime config. Returns (np.array): Simple uniform transition matrix. """ pos_num_bins = len(enc_settings.pos_bins) # Setup transition matrix transition_mat = np.ones([pos_num_bins, pos_num_bins]) transition_mat = apply_no_anim_boundary(enc_settings.pos_bins, enc_settings.arm_coordinates, transition_mat) # normalize transition matrix transition_mat = transition_mat / (transition_mat.sum(axis=0)[None, :]) transition_mat = np.nan_to_num(transition_mat) return transition_mat
def calc_simple_trans_mat(enc_settings): """ Calculate a simple point process transition matrix using a gaussian kernel. Args: enc_settings (EncodeSettings): Encoder setting from realtime config. Returns (np.array): Simple gaussian transition matrix. """ pos_num_bins = len(enc_settings.pos_bins) # Setup transition matrix transition_mat = np.ones([pos_num_bins, pos_num_bins]) for bin_ii in range(pos_num_bins): transition_mat[bin_ii, :] = gaussian(enc_settings.pos_bins, enc_settings.pos_bins[bin_ii], 3) transition_mat = apply_no_anim_boundary(enc_settings.pos_bins, enc_settings.arm_coordinates, transition_mat) # uniform offset uniform_gain = 0.01 uniform_dist = np.ones(transition_mat.shape) uniform_dist = apply_no_anim_boundary(enc_settings.pos_bins, enc_settings.arm_coordinates, uniform_dist) # normalize transition matrix transition_mat = transition_mat / (transition_mat.sum(axis=0)[None, :]) transition_mat[np.isnan(transition_mat)] = 0 # normalize uniform offset uniform_dist = uniform_dist / (uniform_dist.sum(axis=0)[None, :]) uniform_dist[np.isnan(uniform_dist)] = 0 # apply uniform offset transition_mat = transition_mat * ( 1 - uniform_gain) + uniform_dist * uniform_gain return transition_mat
def _calc_firing_rate_tet(observ: SpikeObservation, lin_obj: FlatLinearPosition, enc_settings: EncodeSettings): # initialize conditional intensity function firing_rate = {} enc_tet_lin_pos = (lin_obj.get_irregular_resampled(observ)) enc_tet_lin_pos['elec_grp_id'] = observ.index.get_level_values(level='elec_grp_id') tet_pos_groups = enc_tet_lin_pos.loc[:, ('elec_grp_id', 'linpos_flat')].groupby('elec_grp_id') for tet_id, tet_spikes in tet_pos_groups: tet_pos_hist, _ = np.histogram(tet_spikes, bins=enc_settings.pos_bin_edges) firing_rate[tet_id] = tet_pos_hist for fr_key in firing_rate.keys(): firing_rate[fr_key] = np.convolve(firing_rate[fr_key], enc_settings.pos_kernel, mode='same') firing_rate[fr_key] = apply_no_anim_boundary(enc_settings.pos_bins, enc_settings.arm_coordinates, firing_rate[fr_key]) firing_rate[fr_key] = firing_rate[fr_key] / (firing_rate[fr_key].sum() * enc_settings.pos_bin_delta) return firing_rate
def _calc_occupancy(lin_obj: FlatLinearPosition, enc_settings: EncodeSettings): """ Args: lin_obj (LinearPositionContainer): Linear position of the animal. enc_settings (EncodeSettings): Realtime encoding settings. Returns (np.array): The occupancy of the animal """ occupancy, occ_bin_edges = np.histogram( lin_obj['linpos_flat'], bins=enc_settings.pos_bin_edges, normed=True) occupancy = np.convolve(occupancy, enc_settings.pos_kernel, mode='same') # occupancy occupancy = apply_no_anim_boundary(enc_settings.pos_bins, enc_settings.arm_coordinates, occupancy, np.nan) occupancy += 1e-10 return occupancy