def zero_one_scale(patience_signal): print(patience_signal) res = [] for signal in patience_signal: s = MinMaxScaler().fit(signal.reshape(-1, 1)).transform( signal.reshape(-1, 1)).ravel() res.append(s) return np.asarray(res)
def DFT(signal): def dft_algo(n): return lambda i, j: cmath.e**(-( (2 * cmath.pi * np.complex(0, 1) * i * j) / n)) img_shape = signal.shape signal.reshape(-1) dft_algo_res = dft_algo(img_shape[0]) matrix = np.fromfunction(dft_algo_res, (img_shape[0], img_shape[0])) ret = np.dot(matrix, signal).reshape(img_shape) return ret
def linear_regression(time, signal, verbose=True): regr = linear_model.LinearRegression(fit_intercept=True) regr.fit(time.reshape(-1, 1), signal.reshape(-1, 1)) wsumpred = regr.predict(signal.reshape(-1, 1)) slope = regr.coef_[0] intercept = regr.intercept_[0] if verbose: print('Coefficients: \n', regr.coef_) print('Mean squared error: %.2f' % mean_squared_error(signal, wsumpred)) print('Variance score: %.2f' % r2_score(signal, wsumpred)) return slope, intercept
def DFT(signal): ##calculate the fourier transform for 1D signal T_signal = signal.reshape(len(signal), ) dft_mat = DFT_mat(len(T_signal)) F_u = T_signal.dot(dft_mat) F_u = np.reshape(F_u, signal.shape) return F_u
def analyze_spectrum(signal, npoints): """Computes FFT for the signal, discards the zero freq and the above-Nyquist freqs. Auto-pads signals nonmultple of npoints, auto-averages results from streams longer than npoints. Thus, npoints results in npoints/2 bands. Returns a numpy array, each element represents the raw amplitude of a frequency band. """ signal = signal.copy() if divmod(len(signal), npoints)[1] != 0: round_up = len(signal) / npoints * npoints + npoints signal.resize(round_up) window = scipy.signal.hanning(npoints) window_blocks = scipy.vstack([window for x in xrange(len(signal) / npoints)]) signal_blocks = signal.reshape((-1, npoints)) windowed_signals = signal_blocks * window_blocks ffts = numpy.fft.rfft(windowed_signals)[:, 1:] result = pow(abs(ffts), 2) / npoints result = result.mean(0) return result
def normalize_signal(signal): signal = np.asarray(signal) signal = signal.reshape((len(signal), 1)) scaler = MinMaxScaler(feature_range=(0, 1)) scaler = scaler.fit(signal) normalized_signal = scaler.transform(signal) return normalized_signal
def analyze_spectrum(signal, npoints): """Computes FFT for the signal, discards the zero freq and the above-Nyquist freqs. Auto-pads signals nonmultple of npoints, auto-averages results from streams longer than npoints. Thus, npoints results in npoints/2 bands. Returns a numpy array, each element represents the raw amplitude of a frequency band. """ signal = signal.copy() if divmod(len(signal), npoints)[1] != 0: round_up = len(signal) / npoints * npoints + npoints signal.resize(round_up) window = scipy.signal.hanning(npoints) window_blocks = scipy.vstack( [window for x in xrange(len(signal) / npoints)]) signal_blocks = signal.reshape((-1, npoints)) windowed_signals = signal_blocks * window_blocks ffts = numpy.fft.rfft(windowed_signals)[:, 1:] result = pow(abs(ffts), 2) / npoints result = result.mean(0) return result
def signal_xyz(self, signal, r): r"""Evaluate the signal on given points on the sphere .. math:: f(\vec x / \|\vec x\|) Parameters ---------- signal : `torch.Tensor` tensor of shape ``(*A, self.dim)`` r : `torch.Tensor` tensor of shape ``(*B, 3)`` Returns ------- `torch.Tensor` tensor of shape ``(*A, *B)`` Examples -------- >>> s = SphericalTensor(3, 1, -1) >>> s.signal_xyz(s.randn(2, 1, 3, -1), torch.randn(2, 4, 3)).shape torch.Size([2, 1, 3, 2, 4]) """ sh = o3.spherical_harmonics(self, r, normalize=True) dim = (self.lmax + 1)**2 output = torch.einsum('bi,ai->ab', sh.reshape(-1, dim), signal.reshape(-1, dim)) return output.reshape(signal.shape[:-1] + r.shape[:-1])
def distance_neighbors(signal): '''Finds Distance of each point in the timeseries from its 4 nearest neighbors Parameters ---------- signal : array The timeseries Returns ------- distances : array Distance of each point from its nearest neighbors in decreasing order ''' nn = NearestNeighbors(n_neighbors=4) # 4 nearest neighbors nbrs =nn.fit(signal.reshape(-1,1)) distances, indices = nbrs.kneighbors(signal.reshape(-1,1)) distances = sorted(distances[:,-1],reverse=True) return distances
def average_singular_signal(self, signal): """ Avarage over single signal for the length of one period """ Lperiod = len(self.beaconList[0].binarySignal) Ncycle = len(signal) // Lperiod reshaped = signal.reshape((Ncycle, Lperiod)) averaged = np.mean(np.abs(reshaped), 0) return averaged
def decode_fsk(signal, nb_echantillon, x): rest = len(signal) % nb_echantillon zero = np.zeros((nb_echantillon - rest)) signal = np.concatenate((signal,zero)) nb_trame = len(signal)/nb_echantillon signal_matrix = signal.reshape(nb_trame,nb_echantillon) message_rcv=[] for i in range(nb_trame): tmp=signal_matrix[i] if np.mean(tmp)>0.2: message_rcv.append(x) else: message_rcv.append(0) return message_rcv
def stft(signal: np.ndarray, window_size=256, copy=True, pad=True): """Return the short time Fourier transform of signal. :param signal: numpy array of shape (L, N). :param window_size: window length. :param copy: whether to make a copy of signal. :param pad: whether to zero-pad input (if True) or truncate (if False). :return: numpy array of shape (M, window_size, N). Divide signal into chunks of length window_size and compute their Fourier transforms. If signal's length is not a multiple of window_size it will be filled with zeroes if pad is True and truncated otherwise. """ assert isinstance(signal, np.ndarray) assert len(signal.shape) == 2 if copy: signal = np.copy(signal) # Zero-pad or truncate if necessary. windows, remainder = divmod(signal.shape[0], window_size) if remainder != 0: if pad: padding = window_size * (windows + 1) - signal.shape[0] signal = np.pad(signal, ((0, padding), (0, 0))) windows += 1 else: signal = signal[:(window_size * windows), :] # Reshape into "windowed view". signal = signal.reshape((windows, window_size, -1)) # Compute FFT for each channel. signal_stft = np.empty_like(signal) for c in range(signal.shape[2]): signal_stft[..., c] = np.absolute(np.fft.fft(signal[..., c])) return signal_stft
def _file_callback(self, in_data, frame_count, time_info, status): """Gets called every time a block of samples is read from a file. See pyaudio.PyAudio.open Prepares the raw audio data for analyze_signal. In particular translates the sample values into a reasonable amplitude range depending on the format of the file. For multiple channels it passes only the first channel to analyze_signal. """ data = self._wave_file.readframes(frame_count) signal = np.copy(np.frombuffer(data, self._format)) # play back a zero array if silent if self.silent: data = np.zeros_like(signal).tobytes() # we only analyze full blocks if len(signal) != self.blocksize * self._nr_channels: return data, pyaudio.paContinue signal = np.copy( signal) # frombuffer yields read only, so we need a copy # if it's not mono, use only the first channel if self._nr_channels > 1: signal = signal.reshape((self.blocksize, self._nr_channels))[:, 0] # this is my hacky method of translating sample values into reasonable amplitude values if self._format == np.float32: signal = signal / np.finfo(self._format).max * 20 else: signal = signal / np.iinfo(self._format).max * 20 self.analyze_signal(signal) return data, pyaudio.paContinue
def impdaspy(filename): """ Open a binary file written by Data Acquisition System (DAS). Parameters: ---------- filename : file or str Open file object or filename savef : boolean, optional If true, saves the binary file to a text file Returns: ------- all_sign : array_like All signals acquired with DAS. The number of signal returned is equal to the number of channels used in the acquisition. config : dict Some configuration parameters: sampling frequency, file names, acquisition hour, positivegain, negative gain """ #handing error if not filename.endswith('bin'): raise Exception("File must have binary extension -> filename.bin") try: fid = open(filename, 'rb') except IOError: print "******* %s ---> File not found" % filename return None, None dim = np.fromfile(fid, dtype='>u4', count=2) temp = np.fromfile(fid, dtype='>f', count=dim[0] * dim[1]).reshape(dim[1], dim[0], order='F').T freq = temp[0, 0] nchannels = temp[0, 1] #dgpoli = dim[1] temp = temp[1::, :] baseline = temp[0:nchannels, 0] #basenoise = temp[0:nchannels, 1] temp = temp[nchannels::, :] positivegain = np.concatenate((np.fliplr(temp[0:nchannels, :]), np.zeros((nchannels, 1))), axis=1) temp = temp[nchannels::, :] negativegain = np.concatenate((np.fliplr(temp[0:nchannels, :]), np.zeros((nchannels, 1))), axis=1) dim1 = np.fromfile(fid, dtype='>u4', count=1) name = [] name_c = [] for iter1 in xrange(dim1): name.append(np.fromfile(fid, dtype='B', count=np.fromfile(fid, dtype='>u4', count=1))) name_c.append(' '.join([chr(str_it1) for str_it1 in name[iter1]])) hour = np.fromfile(fid, dtype='B', count=np.fromfile(fid, dtype='>u4', count=1)) hour = ' '.join([chr(str_it2) for str_it2 in hour]) signal = np.fromfile(fid, dtype='>f') signal = signal.reshape(dim1, len(signal) / float(dim1), order='F') #remove baseline all_sig = np.array([signal[iter3] - baseline[iter3] for iter3 in xrange(dim1)]) config = {'fs': freq, 'hour': hour, 'names': name_c, 'posgain': positivegain, 'neggain': negativegain} #config = {'fs': freq, 'hour': hour, 'names': name_c, #'temp': temp} return all_sig, config
def calculate_loudness(signal, fs, prefiltered=False, gated=True): def K_filter(signal, fs, debug=False): # pre-filter 1 f0 = 1681.9744509555319 G = 3.99984385397 Q = 0.7071752369554193 # TODO: precompute K = np.tan(np.pi * f0 / fs) Vh = np.power(10.0, G / 20.0) Vb = np.power(Vh, 0.499666774155) a0_ = 1.0 + K / Q + K * K b0 = (Vh + Vb * K / Q + K * K) / a0_ b1 = 2.0 * (K * K - Vh) / a0_ b2 = (Vh - Vb * K / Q + K * K) / a0_ a0 = 1.0 a1 = 2.0 * (K * K - 1.0) / a0_ a2 = (1.0 - K / Q + K * K) / a0_ signal_1 = sp.signal.lfilter([b0, b1, b2], [a0, a1, a2], signal) if debug: import matplotlib.pyplot as plt plt.figure(figsize=(9, 9)) # ax1 = fig.add_subplot(111) w, h1 = sp.signal.freqz([b0, b1, b2], [a0, a1, a2], worN=8000) # np.logspace(-4, 3, 2000)) plt.semilogx((fs * 0.5 / np.pi) * w, 20 * np.log10(abs(h1))) plt.title('Pre-filter 1') plt.xlabel('Frequency [Hz]') plt.ylabel('Gain [dB]') plt.xlim([20, 20000]) plt.ylim([-10, 10]) plt.grid(True, which='both') ax = plt.axes() # ax.yaxis.set_major_locator(ticker.MultipleLocator(2)) plt.show() # pre-filter 2 f0 = 38.13547087613982 Q = 0.5003270373253953 K = np.tan(np.pi * f0 / fs) a0 = 1.0 a1 = 2.0 * (K * K - 1.0) / (1.0 + K / Q + K * K) a2 = (1.0 - K / Q + K * K) / (1.0 + K / Q + K * K) b0 = 1.0 b1 = -2.0 b2 = 1.0 signal_2 = sp.signal.lfilter([b0, b1, b2], [a0, a1, a2], signal_1) if debug: plt.figure(figsize=(9, 9)) # ax1 = fig.add_subplot(111) w, h2 = sp.signal.freqz([b0, b1, b2], [a0, a1, a2], worN=8000) plt.semilogx((fs * 0.5 / np.pi) * w, 20 * np.log10(abs(h2))) plt.title('Pre-filter 2') plt.xlabel('Frequency [Hz]') plt.ylabel('Gain [dB]') plt.xlim([10, 20000]) plt.ylim([-30, 5]) plt.grid(True, which='both') ax = plt.axes() # ax.yaxis.set_major_locator(ticker.MultipleLocator(5)) plt.show() return signal_2 # return signal passed through 2 pre-filters G = [1.0, 1.0, 1.0, 1.41, 1.41] if len(signal.shape) == 1: # if shape (N,), then make (N,1) signal = signal.reshape((signal.shape[0], 1)) # filter or not if prefiltered: if len(signal.shape) == 1: # if shape (N,), then make (N,1) signal_filtered = copy.copy(signal.reshape((signal.shape[0], 1))) else: signal_filtered = copy.copy(signal) for i in range(signal_filtered.shape[1]): signal_filtered[:, i] = K_filter(signal_filtered[:, i], fs) else: signal_filtered = signal # mean square T_g = 0.400 # 400 ms gating block Gamma_a = -70.0 # absolute threshold: -70 LKFS overlap = .75 # relative overlap (0.0-1.0) step = 1 - overlap T = signal_filtered.shape[ 0] / fs # length of measurement interval in seconds j_range = np.arange(0, (T - T_g) / (T_g * step)).astype(int) z = np.ndarray(shape=(signal_filtered.shape[1], len(j_range))) # write in explicit for-loops for readability and translatability for i in range(signal_filtered.shape[1]): # for each channel i for j in j_range: # for each window j lbound = np.round(fs * T_g * j * step).astype(int) hbound = np.round(fs * T_g * (j * step + 1)).astype(int) z[i, j] = (1 / (T_g * fs)) * np.sum( np.square(signal_filtered[lbound:hbound, i])) G_current = np.array( G[:signal_filtered. shape[1]]) # discard weighting coefficients G_i unused channels n_channels = G_current.shape[0] l = [-.691 + 10.0 * np.log10(np.sum([G_current[i] * z[i, j.astype(int)] for i in range(n_channels)])) \ for j in j_range] if gated: # Suppress warnings with warnings.catch_warnings(): warnings.simplefilter("ignore") # throw out anything below absolute threshold: indices_gated = [idx for idx, el in enumerate(l) if el > Gamma_a] z_avg = [ np.mean([z[i, j] for j in indices_gated]) for i in range(n_channels) ] Gamma_r = -.691 + 10.0 * np.log10( np.sum([G_current[i] * z_avg[i] for i in range(n_channels)])) - 10.0 # throw out anything below relative threshold: indices_gated = [idx for idx, el in enumerate(l) if el > Gamma_r] z_avg = [ np.mean([z[i, j] for j in indices_gated]) for i in range(n_channels) ] L_KG = -.691 + 10.0 * np.log10( np.sum([G_current[i] * z_avg[i] for i in range(n_channels)])) else: Gamma_a = -np.Inf Gamma_r = -np.Inf indices_gated = [idx for idx, el in enumerate(l) if el > Gamma_r] z_avg = [ np.mean([z[i, j] for j in indices_gated]) for i in range(n_channels) ] L_KG = -.691 + 10.0 * np.log10( np.sum([G_current[i] * z_avg[i] for i in range(n_channels)])) return L_KG, max(Gamma_r, Gamma_a)
def scale_signal(signal): signal = signal.values signal = signal.reshape(-1, 1) min_max_scaler = preprocessing.MinMaxScaler() scaled_signal = min_max_scaler.fit_transform(signal) return scaled_signal, min_max_scaler
def schmidt_spike_removal(signal, fs=2000): """ :param signal: 原始信号(time_step, 1) :param fs: 采样频率 :return: 移除噪音峰值的信号 本函数参考论文: S. E. Schmidt et al., "Segmentation of heart sound recordings by duration-dependent hidden Markov model," Physiol. Meas., vol. 31, no. 4, pp. 513-29, Apr. 2010. """ window_size = int(fs / 2) # 将信号按找窗口大小划分成一个个窗口,找到信号中剩余的不够一个完整窗口的采样点 trailing_samples = len(signal) % window_size # 将信号转换成一些窗口,转换后的形状(window_size, -1) sample_frames = np.reshape(signal[:-trailing_samples], (window_size, -1)) MAAs = np.max(abs(sample_frames), axis=0) is_greater = list(MAAs > (np.median(MAAs) * 3)) while is_greater.count(True) > 0: max_val = np.max(MAAs) # 找到MAAs中最大值所在的窗口位置 window_pos = np.argwhere(MAAs == max_val) # 如果等于最大值的窗口不止一个,则取第一个等于最大值的窗口 if len(window_pos) > 1: window_pos = window_pos[0] window_pos = int(window_pos) # 找到窗口内的最大值,即噪音峰值 spike_val = np.max(abs(sample_frames[:, window_pos])) spike_pos = np.argwhere(abs(sample_frames[:, window_pos]) == spike_val) if len(spike_pos) > 1: spike_pos = spike_pos[0] spike_pos = int(spike_pos) # 找到零交叉(这里可能没有实际的0值,只是从正到负的变化 sign_change = abs(np.diff(np.sign(sample_frames[:, window_pos]))) > 1 zero_crossing = np.concatenate([sign_change, np.array([False])]) # 找到峰值的开始位置,峰值位置之前最后一个零交叉点的位置 # 如果没有零交叉点,则取窗口开始的位置 zero_cross_pos = np.argwhere(zero_crossing[0:spike_pos + 1] == True) if len(zero_cross_pos) == 0: spike_start = 0 else: spike_start = np.squeeze(zero_cross_pos[-1]) # 找到峰值的结束位置,峰值位置之后第一个零交叉点的位置 # 如果没有零交叉点,则取窗口结束的位置 zero_crossing[0:spike_pos + 1] = False zero_cross_pos = np.argwhere(zero_crossing == True) if len(zero_cross_pos) == 0: spike_end = window_size else: spike_end = np.squeeze(zero_cross_pos[0]) # print("spike start pos is %d, spike pos is %d, spike end pos is %d" % (spike_start, spike_pos, spike_end)) # 将噪音峰值设置为0 sample_frames.flags.writeable = True sample_frames[spike_start:spike_end, window_pos] = 0.0001 # 重新计算 MAAs MAAs = np.max(abs(sample_frames), axis=0) is_greater = list(MAAs > (np.median(MAAs) * 3)) despike_signal = np.reshape(sample_frames, (-1, 1)) signal = signal.reshape((-1, 1)) despike_signal = np.concatenate( [despike_signal, signal[len(despike_signal):]]) return despike_signal