def _pvoc2(self, X_hat, Phi_hat=None, R=None): """ :: alternate (batch) implementation of phase vocoder - time-stretch inputs: X_hat - estimate of signal magnitude [Phi_hat] - estimate of signal phase [R] - resynthesis hop ratio output: updates self.X_hat with modified complex spectrum """ N, W, H = self.nfft, self.wfft, self.nhop R = 1.0 if R is None else R dphi = P.atleast_2d((2 * P.pi * H * P.arange(N / 2 + 1)) / N).T print("Phase Vocoder Resynthesis...", N, W, H, R) A = P.angle(self.STFT) if Phi_hat is None else Phi_hat U = P.diff(A, 1) - dphi U = U - P.np.round(U / (2 * P.pi)) * 2 * P.pi t = P.arange(0, n_cols, R) tf = t - P.floor(t) phs = P.c_[A[:, 0], U] phs += U[:, idx[1]] + dphi # Problem, what is idx ? Xh = (1 - tf) * Xh[:-1] + tf * Xh[1:] Xh *= P.exp(1j * phs) self.X_hat = Xh
def _phase_map(self): self.dphi = (2 * P.pi * self.nhop * P.arange(self.nfft / 2 + 1)) / self.nfft A = P.diff(P.angle(self.STFT), 1) # Complete Phase Map U = P.c_[P.angle(self.STFT[:, 0]), A - P.atleast_2d(self.dphi).T] U = U - P.np.round(U / (2 * P.pi)) * 2 * P.pi self.dPhi = U return U
def detector_tester(APTimes, actualTimes): """ returns percentTrueSpikes (% correct detected) and falseSpikeRate (extra APs per second of data) compares actual spikes times with detected spike times This only works if we give you the answers! """ JITTER = 0.0025 #2 ms of jitter allowed #first match the two sets of spike times. Anything within JITTER_MS #is considered a match (but only one per time frame!) #order the lists detected = np.sort(APTimes) actual = np.sort(actualTimes) #remove spikes with the same times (these are false APs) temp = np.append(detected, -1) detected = detected[plt.find(plt.diff(temp) != 0)] #find matching action potentials and mark as matched (trueDetects) trueDetects = []; for sp in actual: z = plt.find((detected >= sp-JITTER) & (detected <= sp+JITTER)) if len(z)>0: for i in z: zz = plt.find(trueDetects == detected[i]) if len(zz) == 0: trueDetects = np.append(trueDetects, detected[i]) break; percentTrueSpikes = 100.0*len(trueDetects)/len(actualTimes) #everything else is a false alarm totalTime = (actual[len(actual)-1]-actual[0]) falseSpikeRate = (len(APTimes) - len(actualTimes))/totalTime # Added this for auto-evaluation based on criteria pct_spike_eval = "PASS" if percentTrueSpikes > 90.0 else "FAIL" false_spike_eval = "PASS" if falseSpikeRate < 2.5 else "FAIL" overall_result = "FAIL" if pct_spike_eval == "FAIL" or false_spike_eval == "FAIL" else "PASS" print 'Action Potential Detector Performance performance: ' print ' Correct number of action potentials = %d' % len(actualTimes) print ' %s: Percent True Spikes = %f' % (pct_spike_eval, percentTrueSpikes) print ' %s: False Spike Rate = %f spikes/s' % (false_spike_eval, falseSpikeRate) print '' print 'Overall Evaluation: %s' % overall_result print '' return {'Percent True Spikes':percentTrueSpikes, 'False Spike Rate':falseSpikeRate}
def good_AP_finder2(time,voltage): """ This function takes the following input: time - vector where each element is a time in seconds voltage - vector where each element is a voltage at a different time We are assuming thaht he two vectors are in correspondance (meaning that at a given index, the time in one corresponds to the voltage in the other). The vectors must be the same size or the code won't run This function returns the following output: APTime - all the times where a spike (action potential) was detected """ #Let's make sure the input looks at least reasonable if (len(voltage) != len(time)): print "Can't run - the vectors aren't the same length!" APTime = [] return APTime # Pick a threshold. You can eyeball it by looking at the plot, or you can # write code to find it. Code would be better, but isn't 100% necessary. thrd = -80 # find all the indices whose corresponding voltage is lower than the threshold detectedAPIndex = plt.find(voltage < thrd) # note that now several neighboring indices could correspond to the same spike # we only want the first index for one spike # so we will throw away several frames following the first one # calculate difference of the picked neiboring indices diff_detectedAPIndex= plt.diff(detectedAPIndex) # if diff_detectedAPIndex>1, we know that it's a new spike # note that diff omits the first element, which is a spike, so I insert the first one detectedAPIndex_select = np.insert(diff_detectedAPIndex>1, 0, True) # detectedAPIndex_select is a boolean array with the same length of detectedAPIndex # we selecte the indices that correspond to the begginning frame of each spikes detectedAPIndex = detectedAPIndex[detectedAPIndex_select] # find the time im ms based on the indices APTime =list(time[i] for i in detectedAPIndex) return APTime
def _extract_onsets(self): """ :: The simplest onset detector in the world: power envelope derivative zero crossings +/- """ fp = self._check_feature_params() if not self._have_power: return None dd = P.diff(P.r_[0, self.POWER]) self.ONSETS = P.where((dd > 0) & (P.roll(dd, -1) < 0))[0] if self.verbosity: print("Extracted ONSETS") self._have_onsets = True return True
def good_AP_finder2(time, voltage): """ This function takes the following input: time - vector where each element is a time in seconds voltage - vector where each element is a voltage at a different time We are assuming thaht he two vectors are in correspondance (meaning that at a given index, the time in one corresponds to the voltage in the other). The vectors must be the same size or the code won't run This function returns the following output: APTime - all the times where a spike (action potential) was detected """ #Let's make sure the input looks at least reasonable if (len(voltage) != len(time)): print "Can't run - the vectors aren't the same length!" APTime = [] return APTime # Pick a threshold. You can eyeball it by looking at the plot, or you can # write code to find it. Code would be better, but isn't 100% necessary. thrd = -80 # find all the indices whose corresponding voltage is lower than the threshold detectedAPIndex = plt.find(voltage < thrd) # note that now several neighboring indices could correspond to the same spike # we only want the first index for one spike # so we will throw away several frames following the first one # calculate difference of the picked neiboring indices diff_detectedAPIndex = plt.diff(detectedAPIndex) # if diff_detectedAPIndex>1, we know that it's a new spike # note that diff omits the first element, which is a spike, so I insert the first one detectedAPIndex_select = np.insert(diff_detectedAPIndex > 1, 0, True) # detectedAPIndex_select is a boolean array with the same length of detectedAPIndex # we selecte the indices that correspond to the begginning frame of each spikes detectedAPIndex = detectedAPIndex[detectedAPIndex_select] # find the time im ms based on the indices APTime = list(time[i] for i in detectedAPIndex) return APTime
def detector_tester(APTimes, actualTimes): """ returns percentTrueSpikes (% correct detected) and falseSpikeRate (extra APs per second of data) compares actual spikes times with detected spike times This only works if we give you the answers! """ JITTER = 0.025 #2 ms of jitter allowed #first match the two sets of spike times. Anything within JITTER_MS #is considered a match (but only one per time frame!) #order the lists detected = np.sort(APTimes) actual = np.sort(actualTimes) #remove spikes with the same times (these are false APs) temp = np.append(detected, -1) detected = detected[plt.find(plt.diff(temp) != 0)] #find matching action potentials and mark as matched (trueDetects) trueDetects = [] for sp in actual: z = plt.find((detected >= sp - JITTER) & (detected <= sp + JITTER)) if len(z) > 0: for i in z: zz = plt.find(trueDetects == detected[i]) if len(zz) == 0: trueDetects = np.append(trueDetects, detected[i]) break percentTrueSpikes = 100.0 * len(trueDetects) / len(actualTimes) #everything else is a false alarm totalTime = (actual[len(actual) - 1] - actual[0]) falseSpikeRate = (len(APTimes) - len(actualTimes)) / totalTime print 'Action Potential Detector Performance performance: ' print ' Correct number of action potentials = ' + str(len(actualTimes)) print ' Percent True Spikes = ' + str(percentTrueSpikes) print ' False Spike Rate = ' + str(falseSpikeRate) + ' spikes/s' print return { 'Percent True Spikes': percentTrueSpikes, 'False Spike Rate': falseSpikeRate }
def detector_tester(APTimes, actualTimes): """ returns percentTrueSpikes (% correct detected) and falseSpikeRate (extra APs per second of data) compares actual spikes times with detected spike times This only works if we give you the answers! """ #print APTimes #print actualTimes JITTER = 0.0025 #2 ms of jitter allowed #first match the two sets of spike times. Anything within JITTER_MS #is considered a match (but only one per time frame!) #order the lists detected = np.sort(APTimes) actual = np.sort(actualTimes) #remove spikes with the same times (these are false APs) temp = np.append(detected, -1) detected = detected[plt.find(plt.diff(temp) != 0)] #find matching action potentials and mark as matched (trueDetects) trueDetects = []; for sp in actual: z = plt.find((detected >= sp-JITTER) & (detected <= sp+JITTER)) if len(z)>0: for i in z: zz = plt.find(trueDetects == detected[i]) if len(zz) == 0: trueDetects = np.append(trueDetects, detected[i]) break; percentTrueSpikes = 100.0*len(trueDetects)/len(actualTimes) #everything else is a false alarm totalTime = (actual[len(actual)-1]-actual[0]) falseSpikeRate = (len(APTimes) - len(actualTimes))/totalTime print 'Action Potential Detector Performance performance: ' print ' Correct number of action potentials = ' + str(len(actualTimes)) print ' Percent True Spikes = ' + str(percentTrueSpikes) print ' False Spike Rate = ' + str(falseSpikeRate) + ' spikes/s' print return {'Percent True Spikes':percentTrueSpikes, 'False Spike Rate':falseSpikeRate}
def extract(self): Features.extract(self) self.X = P.sqrt((P.diff(self.X)**2).sum(0)) / self.X.shape[0]
def detection_tester(peakTimes, refFilepath=None, delimiter=None, tolerance=0.35): """ Compares spike times from the spike_detector function to the actual spike times. The actual (validated) times should be listed in a reference text file located at refFilepath; set delimiter via the corresponding paramter, e.g. ',' for CSV. The function ouutputs and returns the percentage of true (verified) spikes that were detected along with the false spike rate (extra spikes per second of data). """ if refFilepath == None: print( "True spike times were not provided, so the spike detection perfromance cannot be evaluated" ) percentTrueSpikes, falseSpikeRate = "N/A", "N/A" return { 'percent_true_spikes': percentTrueSpikes, 'false_spike_rate': falseSpikeRate } else: # Create numpy array of the values in the reference csv file trueTimes = np.genfromtxt(refFilepath, delimiter=delimiter) # First match the two arrays of spike times. Anything within the given tolerance is a match. # Ensure times are in sequntial order peakTimes = np.sort(peakTimes) trueTimes = np.sort(trueTimes) # Remove spikes with the same times (false spikes) detected = np.append(peakTimes, -1) uniqueDetected = peakTimes[plt.find(plt.diff(detected) != 0)] # Find matching spikes and mark as true detections trueDetected = [] # Find indices of dedected spikes that are within the margin of tolerance around each true spike for spike in trueTimes: detectedWithinTol = plt.find((uniqueDetected >= spike - tolerance) & (uniqueDetected <= spike + tolerance)) # If detected spikes found... if len(detectedWithinTol) > 0: # ...for each one, check if already present in our list of true dectections, ... for i in detectedWithinTol: alreadyMarked = plt.find(trueDetected == uniqueDetected[i]) # ...and if not, append it to to that list if len(alreadyMarked) == 0: trueDetected = np.append(trueDetected, uniqueDetected[i]) percentTrueSpikes = 100.0 * len(trueDetected) / len(trueTimes) # Everything else is a false spike totalTime = (trueTimes[len(trueTimes) - 1] - trueTimes[0]) falseSpikeRate = (len(peakTimes) - len(trueTimes)) / totalTime print("\nSpike detector performance:") print("\n Number of spikes detected in test analysis =", len(peakTimes)) print(" Number of true spikes =", len(trueTimes)) print(" Percentage of true spikes detected =", percentTrueSpikes) print(" False spike rate = ", falseSpikeRate, "spikes/s") return { 'percent_true_spikes': percentTrueSpikes, 'false_spike_rate': falseSpikeRate }