def getSpeedThreshold(halldata, ripDf, speedTh=3): # load speed and position data posSpeed = np.array([]) posTime = np.array([]) for hall in halldata: hallmap = np.load(hall, allow_pickle=True).item() for k in hallmap.keys(): s = hallmap[k]['speed'] t = hallmap[k]['intantime'] if k == 1 and len(posSpeed) < 1 and len(posTime) < 1: posSpeed = s posTime = t else: posSpeed = np.concatenate((posSpeed, s)) posTime = np.concatenate((posTime, t)) sortidx = np.argsort(posTime) posTime = posTime[sortidx] posSpeed = posSpeed[sortidx] isOffline = [] speed = [] for r in range(len(ripDf)): rip = ripDf.iloc[r] stind, _ = mea.find_le(posTime, rip['start_time']) etind, _ = mea.find_ge(posTime, rip['end_time']) speedrip = np.nanmin(posSpeed[stind:etind]) speed.append(speedrip) isOffline.append(speedrip <= speedTh) isOffline = np.array(isOffline) speed = np.array(speed) drop_index = np.where(isOffline == False)[0] return drop_index, speed
def getSpikeSumThreshold(spktimefname, times, fs, ripDf, dt=0.01): # load the raw data spiketimes = np.load(spktimefname, allow_pickle=True) # bin spike count in 10ms to get the Q matrix total_time = times[-1] spike_time_bins = np.arange(np.min(times) / fs, total_time, dt) spike_counts = np.zeros((len(spiketimes), len(spike_time_bins) - 1)) for ind, st in enumerate(spiketimes): spike_counts[ind, :], _ = np.histogram(st, bins=spike_time_bins) sum_spike_counts = np.sum(spike_counts, axis=0) threshold_spiking = np.nanmedian(sum_spike_counts) + np.nanstd( sum_spike_counts) isHSE = [] countHSE = [] for r in range(len(ripDf)): rip = ripDf.iloc[r] stind, _ = mea.find_le(spike_time_bins, rip['start_time']) etind, _ = mea.find_ge(spike_time_bins, rip['end_time']) spkcount = np.nanmax(sum_spike_counts[stind:etind]) countHSE.append(spkcount) isHSE.append(spkcount >= threshold_spiking) isHSE = np.array(isHSE) countHSE = np.array(countHSE) drop_index = np.where(isHSE == False)[0] return drop_index, countHSE, spike_counts, sum_spike_counts, spike_time_bins
kc_peakamp_delta): thresholded_sig = min(abs(0.05 * amp), falloffThresh) # find the left and right falloff points for individual KC idx_max = int(pind + fs) idx_min = int(pind - fs) # check on boundary condition if idx_min < 0: idx_min = 0 if idx_max > len(filt_sig_delta): idx_max = len(filt_sig_delta) - 1 # select the subset of KC event to find boundaries filt_sig_delta_sub = filt_sig_delta[idx_min:idx_max] idx_falloff = np.where(filt_sig_delta_sub >= falloffThresh)[0] idx_falloff += idx_min # find the start and end index for individual ripple _, startidx = mea.find_le(idx_falloff, pind) _, endidx = mea.find_ge(idx_falloff, pind) # accounting for some edge conditions by throwing them out if startidx is not None and endidx is not None: # duration CHECK! duration = np.round(times[endidx] - times[startidx], 3) dur.append(duration) if duration <= 1.25 and duration >= 0.01: kc_start_idx = np.append(kc_start_idx, startidx) kc_end_idx = np.append(kc_end_idx, endidx) kc_peak_idx = np.append(kc_peak_idx, pind) kc_start_time = np.append(kc_start_time, times[startidx]) kc_end_time = np.append(kc_end_time, times[endidx]) kc_peak_time = np.append(kc_peak_time, times[pind]) kc_duration = np.append(kc_duration, duration) kc_peak_amp = np.append(kc_peak_amp, filt_sig_delta[pind])
def findRipple(signal, times, fs, ripple_power, spksumtime, spksum, spdtime, speed, f_ripple=(150, 250), duration=[0.015, 0.5], lookaheadtime=0.5, peakTh=4, falloffTh=1, activityRatio=0.35, speedTh=20): # calculate mean and standard deviation of the ripple power mean_rms = np.nanmean(ripple_power) std_rms = np.nanstd(ripple_power) minThreshTime = duration[0] # minimum duration threshold in seconds maxThreshTime = duration[1] # maximum duration threshold in seconds ripplePowerThresh = mean_rms + peakTh * std_rms #peak power threshold falloffThresh = mean_rms + falloffTh * std_rms # data to hold the variables ripple_duration = [] ripple_start_time = [] ripple_start_idx = [] ripple_end_time = [] ripple_end_idx = [] ripple_peak_time = [] ripple_peak_idx = [] ripple_peak_amp = [] ripple_act = [] # iterate to find the ripple peaks idx = 0 while idx < len(times): # exclude first and last 300ms data if idx / fs >= 0.3 and idx / fs <= times[-1] - 0.3 and ripple_power[ idx] >= ripplePowerThresh: # nice trick: no point looking beyond +/- 300ms of the peak # since the ripple cannot be longer than that idx_max = idx + int(lookaheadtime * fs) idx_min = idx - int(lookaheadtime * fs) # find the left and right falloff points for individual ripple ripple_power_sub = ripple_power[idx_min:idx_max] idx_falloff = np.where(ripple_power_sub <= falloffThresh)[0] idx_falloff += idx_min # find the start and end index for individual ripple _, startidx = mea.find_le(idx_falloff, idx) _, endidx = mea.find_ge(idx_falloff, idx) if startidx is not None and endidx is not None: # duration CHECK! dur = times[endidx] - times[startidx] spkstind, _ = mea.find_le(spksumtime, times[startidx] - 0.15) spketind, _ = mea.find_ge(spksumtime, times[endidx] + 0.15) cellactiveratio = np.nanmax( spksum[spkstind:spketind]) / np.nanmax(spksum) spdstind, _ = mea.find_le(spdtime, times[startidx]) spdetind, _ = mea.find_ge(spdtime, times[endidx]) spd_ = speed[spdstind:spdetind] if len(spd_) > 0: spd_ = np.nanmin(spd_) else: spd_ = 0 if dur >= minThreshTime and dur <= maxThreshTime and cellactiveratio >= activityRatio and spd_ <= speedTh: ripple_duration.append(dur) ripple_start_idx.append(startidx) ripple_end_idx.append(endidx) ripple_peak_idx.append(idx) ripple_start_time.append(times[startidx]) ripple_end_time.append(times[endidx]) ripple_peak_time.append(times[idx]) ripple_peak_amp.append(ripple_power[idx]) ripple_act.append(cellactiveratio) idx = endidx + 1 else: idx += 1 else: idx += 1 ripple = {} ripple['amp'] = ripple_peak_amp ripple['duration'] = ripple_duration ripple['start_time'] = ripple_start_time ripple['end_time'] = ripple_end_time ripple['peak_time'] = ripple_peak_time # ripple['start_idx'] = ripple_start_idx # ripple['end_idx'] = ripple_end_idx # ripple['peak_idx'] = ripple_peak_idx ripple['duration'] = np.array(ripple_end_time) - np.array( ripple_start_time) ripple['act_ratio'] = ripple_act ripple = pd.DataFrame(ripple) return ripple
mpd=.1 * fs) # iterate over each peak for idx in idx_peak: # nice trick: no point looking beyond +/- 300ms of the peak # since the ripple cannot be longer than that idx_max = idx + int(maxThreshTime * fs) idx_min = idx - int(maxThreshTime * fs) # boundary check if idx_min < 0: idx_min = 0 # find the left and right falloff points for individual ripple ripple_power_sub = ripple_power[idx_min:idx_max] idx_falloff = np.where(ripple_power_sub <= falloffThresh)[0] idx_falloff += idx_min # find the start and end index for individual ripple _, startidx = mea.find_le(idx_falloff, idx) _, endidx = mea.find_ge(idx_falloff, idx) # accounting for some boundary conditions if startidx is None: th = (maxThreshTime + minThreshTime) // 2 startidx = idx - int(th * fs) if endidx is None: endidx = 2 * idx - startidx # duration CHECK! dur = time[endidx] - time[startidx] # print(time[idx], time[endidx], time[startidx], dur, dur>=minThreshTime and dur<=maxThreshTime) # add the ripple to saved data if it passes duration threshold if dur >= minThreshTime and dur <= maxThreshTime: ripple_duration.append(dur) ripple_start_idx.append(startidx) ripple_end_idx.append(endidx)
def findRippleMK(signal, times, fs, f_ripple=(150, 250), duration=[0.015, 0.5], lookaheadtime=0.5, peakTh=4, falloffTh=0): # filter signal in ripple range filt_rip_sig = mea.get_bandpass_filter_signal(signal, fs, f_ripple) # Root mean square (RMS) ripple power calculation ripple_power = mea.window_rms(filt_rip_sig, 10) ripple_power = scnd.gaussian_filter1d(ripple_power, 0.004 * fs) # calculate mean and standard deviation of the ripple power mean_rms = np.nanmean(ripple_power) std_rms = np.nanstd(ripple_power) minThreshTime = duration[0] # minimum duration threshold in seconds maxThreshTime = duration[1] # maximum duration threshold in seconds ripplePowerThresh = mean_rms + peakTh * std_rms #peak power threshold falloffThresh = mean_rms + falloffTh * std_rms # data to hold the variables ripple_duration = [] ripple_start_time = [] ripple_start_idx = [] ripple_end_time = [] ripple_end_idx = [] ripple_peak_time = [] ripple_peak_idx = [] ripple_peak_amp = [] # iterate to find the ripple peaks idx = 0 while idx < len(times): # exclude first and last 300ms data if idx / fs >= 0.3 and idx / fs <= times[-1] - 0.3 and ripple_power[ idx] >= ripplePowerThresh: # nice trick: no point looking beyond +/- 300ms of the peak # since the ripple cannot be longer than that idx_max = idx + int(lookaheadtime * fs) idx_min = idx - int(lookaheadtime * fs) # find the left and right falloff points for individual ripple ripple_power_sub = ripple_power[idx_min:idx_max] idx_falloff = np.where(ripple_power_sub <= falloffThresh)[0] idx_falloff += idx_min # find the start and end index for individual ripple _, startidx = mea.find_le(idx_falloff, idx) _, endidx = mea.find_ge(idx_falloff, idx) if startidx is not None and endidx is not None: dur = times[endidx] - times[startidx] # duration CHECK! dur = time[endidx] - time[startidx] if dur >= minThreshTime and dur <= maxThreshTime: ripple_duration.append(dur) ripple_start_idx.append(startidx) ripple_end_idx.append(endidx) ripple_peak_idx.append(idx) ripple_start_time.append(times[startidx]) ripple_end_time.append(times[endidx]) ripple_peak_time.append(times[idx]) ripple_peak_amp.append(ripple_power[idx]) idx = endidx + 1 else: idx += 1 else: idx += 1 ripple = {} ripple['amp'] = ripple_peak_amp ripple['duration'] = ripple_duration ripple['start_time'] = ripple_start_time ripple['end_time'] = ripple_end_time ripple['peak_time'] = ripple_peak_time ripple['start_idx'] = ripple_start_idx ripple['end_idx'] = ripple_end_idx ripple['peak_idx'] = ripple_peak_idx ripple['duration'] = np.array(ripple_end_time) - np.array( ripple_start_time) ripple = pd.DataFrame(ripple) return ripple, filt_rip_sig, ripple_power