def switch_signal(self, label): # Update Lines self.signal_line.set_data(range(len(self.signal)), self.signal_amp_slider.val * self.signal) self.cutoff_freq = self.cutoff_amp_slider.val self.smoothed_signal = hb.lowpass_filter(signal = self.signal, cutoff_freq = self.cutoff_freq) self.smooth_signal_line.set_data(range(len(self.signal)), self.signal_amp_slider.val * self.smoothed_signal) self.first_line.set_data(range(len(self.signal)), (self.first_amp_slider.val * 5* self.first) + self.first_height_slider.val + 1) # T Peak self.T_point.set_offsets((self.peaks.T.data[self.index] - self.peaks.P.data[self.index], self.signal_amp_slider.val * self.smoothed_signal[self.peaks.T.data[self.index] - self.peaks.P.data[self.index]])) self.T_text.set_position((self.peaks.T.data[self.index] - self.peaks.P.data[self.index], self.signal_amp_slider.val * self.smoothed_signal[self.peaks.T.data[self.index] - self.peaks.P.data[self.index]] + 0.2)) # ST Start Peak self.ST_start_point.set_offsets((self.peaks.ST_start.data[self.index] - self.peaks.P.data[self.index], self.signal_amp_slider.val * self.smoothed_signal[self.peaks.ST_start.data[self.index] - self.peaks.P.data[self.index]])) self.ST_start_text.set_position((self.peaks.ST_start.data[self.index] - self.peaks.P.data[self.index], self.signal_amp_slider.val * self.smoothed_signal[self.peaks.ST_start.data[self.index] - self.peaks.P.data[self.index]] + 0.2)) # T'max Peak self.dT_point.set_offsets((self.peaks.dT.data[self.index] - self.peaks.P.data[self.index], self.signal_amp_slider.val * self.smoothed_signal[self.peaks.dT.data[self.index] - self.peaks.P.data[self.index]])) self.dT_text.set_position((self.peaks.dT.data[self.index] - self.peaks.P.data[self.index], self.signal_amp_slider.val * self.smoothed_signal[self.peaks.dT.data[self.index] - self.peaks.P.data[self.index]] + 0.2)) # # T''max Peak # self.ddT_point.set_offsets((self.peaks.ddT.data[self.index] - self.peaks.P.data[self.index], self.signal_amp_slider.val * self.smoothed_signal[self.peaks.ddT.data[self.index] - self.peaks.P.data[self.index]])) # self.ddT_text.set_position((self.peaks.ddT.data[self.index] - self.peaks.P.data[self.index], self.signal_amp_slider.val * self.smoothed_signal[self.peaks.ddT.data[self.index] - self.peaks.P.data[self.index]] + 0.2)) self.y = self.signal_amp_slider.val * self.smoothed_signal self.fig.canvas.draw()
def clip_signals(self): max_time = max(self.time) min_time = min(self.time) if (max_time - min_time) < self.area_around_echo_size: interval = range(np.searchsorted(self.time, min_time), np.searchsorted(self.time, max_time)) elif self.echo_time - self.area_around_echo_size/2 < min_time: interval = range(np.searchsorted(self.time, min_time), int(np.searchsorted(self.time, min_time + self.area_around_echo_size))) elif self.echo_time + self.area_around_echo_size/2 > max_time: interval = range(int(np.searchsorted(self.time, (max_time - self.area_around_echo_size))), np.searchsorted(self.time, max_time)) else: interval = range(int(np.searchsorted(self.time, self.echo_time - (self.area_around_echo_size/2))), int(np.searchsorted(self.time, self.echo_time + (self.area_around_echo_size/2)))) self.interval_near_echo = interval self.time = self.time[interval] self.signal = self.signal[interval] self.seis = self.seis[interval] self.phono = self.phono[interval] self.signal = hb.bandpass_filter(time = self.time, signal = self.signal, freqmin = 59, freqmax = 61) self.seis = hb.bandpass_filter(time = self.time, signal = self.seis, freqmin = 59, freqmax = 61) self.phono = hb.bandpass_filter(time = self.time, signal = self.phono, freqmin = 59, freqmax = 61) self.signal = hb.lowpass_filter(time = self.time, signal = self.signal, cutoff_freq = 10) self.seis = hb.lowpass_filter(time = self.time, signal = self.seis, cutoff_freq = 50)
def update_plot(self): # Update index self.i_text.set_text("Heartbeat: " + str(self.index + 1) + "/" + str(len(self.peaks.R.data) - 1)) self.signal = hb.normalize(self.peaks.signal[range(self.peaks.P.data[self.index], self.peaks.R.data[self.index + 1])]) # Pass through a Low pass self.smoothed_signal = hb.lowpass_filter(signal = self.signal, cutoff_freq = self.cutoff_freq) # Calculate first derivative self.first, _ = hb.get_derivatives(self.smoothed_signal) # Update cross hairs self.switch_signal(None) # Plot ECG, Phono and Seismo self.signal_line.set_data(range(len(self.signal)), self.signal_amp_slider.val * self.signal) self.smooth_signal_line.set_data(range(len(self.signal)), self.signal_amp_slider.val * self.smoothed_signal) self.first_line.set_data(range(len(self.signal)), (self.first_amp_slider.val * 5*self.first) + self.first_height_slider.val + 1) self.ax.set_xlim(0, len(self.signal)) # T Peak self.T_point.set_offsets((self.peaks.T.data[self.index] - self.peaks.P.data[self.index], self.signal_amp_slider.val * self.smoothed_signal[self.peaks.T.data[self.index] - self.peaks.P.data[self.index]])) self.T_text.set_position((self.peaks.T.data[self.index] - self.peaks.P.data[self.index], self.signal_amp_slider.val * self.smoothed_signal[self.peaks.T.data[self.index] - self.peaks.P.data[self.index]] + 0.2)) # ST Start Peak self.ST_start_point.set_offsets((self.peaks.ST_start.data[self.index] - self.peaks.P.data[self.index], self.signal_amp_slider.val * self.smoothed_signal[self.peaks.ST_start.data[self.index] - self.peaks.P.data[self.index]])) self.ST_start_text.set_position((self.peaks.ST_start.data[self.index] - self.peaks.P.data[self.index], self.signal_amp_slider.val * self.smoothed_signal[self.peaks.ST_start.data[self.index] - self.peaks.P.data[self.index]] + 0.2)) # T''max Peak self.dT_point.set_offsets((self.peaks.dT.data[self.index] - self.peaks.P.data[self.index], self.signal_amp_slider.val * self.smoothed_signal[self.peaks.dT.data[self.index] - self.peaks.P.data[self.index]])) self.dT_text.set_position((self.peaks.dT.data[self.index] - self.peaks.P.data[self.index], self.signal_amp_slider.val * self.smoothed_signal[self.peaks.dT.data[self.index] - self.peaks.P.data[self.index]] + 0.2)) # # T''max Peak # self.ddT_point.set_offsets((self.peaks.ddT.data[self.index] - self.peaks.P.data[self.index], self.signal_amp_slider.val * self.smoothed_signal[self.peaks.ddT.data[self.index] - self.peaks.P.data[self.index]])) # self.ddT_text.set_position((self.peaks.ddT.data[self.index] - self.peaks.P.data[self.index], self.signal_amp_slider.val * self.smoothed_signal[self.peaks.ddT.data[self.index] - self.peaks.P.data[self.index]] + 0.2)) self.fig.canvas.draw()
# Load Data time, signal, seis1, seis2, phono1, phono2 = hb.load_file_data( files, folder_name, dosage, file_number, interval_number, preloaded_signal, save_signal) # Calculate Composite lowpass_signal = hb.bandpass_filter(time = time, signal = signal, freqmin = 59, freqmax = 61) # Low-Pass filter under 10Hz lowpass_signal = hb.lowpass_filter(time = time, signal = lowpass_signal, cutoff_freq = 50) peaks = hb.get_peaks_for_composites(time = time, signal = lowpass_signal, dosage = dosage, seis1 = seis1, phono1 = phono1) peaks.get_inital_statistics() print("Time Length: ", max(time) - min(time)) print("R Peaks: ", len(peaks.R.data)) if (len(peaks.R.data) > 10): composite_peaks = CompositePeaks(peaks)
hb.plot_signal(time, signal, intervals=files[folder_name][dosage][1]["intervals"] if use_intervals else None) # View Frequency Domain if show_freq_domain == True: hb.get_fft(time=time, signal=signal, plot=True) # hb.get_spectrum(time = time, # signal = signal) # Bandblock if show_bandpass == True: bandpass_signal = hb.lowpass_filter(time=time, signal=signal, cutoff_freq=10) hb.get_fft(time=time, signal=bandpass_signal, plot=True) # View Derivatives if show_derivatives == True: bandpass_signal = hb.bandpass_filter(time=time, signal=signal, freqmin=59, freqmax=61) hb.get_derivatives(signal=bandpass_signal, plot=True) # Find Peaks if show_peaks:
def plot_signals(self): # Create figure self.fig, self.ax = plt.subplots() self.signal = hb.normalize(self.peaks.signal[range(self.peaks.P.data[self.index], self.peaks.T.data[self.index + 1])]) # Determine what cutoff freq to use self.cutoff_freq = 15 if np.mean(np.diff(self.peaks.R.data)) > 2500 else 10 # Pass through a Low pass self.smoothed_signal = hb.lowpass_filter(signal = self.signal, cutoff_freq = self.cutoff_freq) # Calculate first derivative self.first, _ = hb.get_derivatives(self.smoothed_signal) # Plot ECG, Phono and Seismo self.signal_line, = self.ax.plot(range(len(self.signal)), self.signal, linewidth = 0.75, c = "r", label = "ECG") self.smooth_signal_line, = self.ax.plot(range(len(self.signal)), self.smoothed_signal, linewidth = 1, c = "b", label = "Low Pass ECG") self.first_line, = self.ax.plot(range(len(self.signal)), 1 + 5*self.first, '--', linewidth = 0.5, c = 'k', label = "ECG 1st Derv.") self.ax.set_xlim(0, len(self.signal)) sig_min = min(self.signal) sig_max = max(self.signal) self.ax.set_ylim(sig_min - 0.2*(sig_max - sig_min), sig_max + 0.2*(sig_max - sig_min)) plt.legend(loc='upper right') # T Peak self.T_point = self.ax.scatter(self.peaks.T.data[self.index] - self.peaks.P.data[self.index], self.smoothed_signal[self.peaks.T.data[self.index] - self.peaks.P.data[self.index]], c = '#9467bd') self.T_text = self.ax.text(self.peaks.T.data[self.index] - self.peaks.P.data[self.index], self.smoothed_signal[self.peaks.T.data[self.index] - self.peaks.P.data[self.index]] + 0.2, "T", fontsize=9, horizontalalignment = 'center') # ST Start Peak self.ST_start_point = self.ax.scatter(self.peaks.ST_start.data[self.index] - self.peaks.P.data[self.index], self.smoothed_signal[self.peaks.ST_start.data[self.index] - self.peaks.P.data[self.index]], c = 'y') self.ST_start_text = self.ax.text(self.peaks.ST_start.data[self.index] - self.peaks.P.data[self.index], self.smoothed_signal[self.peaks.ST_start.data[self.index] - self.peaks.P.data[self.index]] + 0.2, "ST Start", fontsize=9, horizontalalignment = 'center') # T'max Peak self.dT_point = self.ax.scatter(self.peaks.dT.data[self.index] - self.peaks.P.data[self.index], self.smoothed_signal[self.peaks.dT.data[self.index] - self.peaks.P.data[self.index]], c = '#2ca02c') self.dT_text = self.ax.text(self.peaks.dT.data[self.index] - self.peaks.P.data[self.index], self.smoothed_signal[self.peaks.dT.data[self.index] - self.peaks.P.data[self.index]] + 0.2, "T'max", fontsize=9, horizontalalignment = 'center') # # T''max Peak # self.ddT_point = self.ax.scatter(self.peaks.ddT.data[self.index] - self.peaks.P.data[self.index], self.smoothed_signal[self.peaks.ddT.data[self.index] - self.peaks.P.data[self.index]], c = '#2ca02c') # self.ddT_text = self.ax.text(self.peaks.ddT.data[self.index] - self.peaks.P.data[self.index], self.smoothed_signal[self.peaks.ddT.data[self.index] - self.peaks.P.data[self.index]] + 0.2, "T''max", fontsize=9, horizontalalignment = 'center') # Initalize axes and data points self.x = range(len(self.signal)) self.y = self.smoothed_signal # Cross hairs self.lx = self.ax.axhline(color='k', linewidth=0.2) # the horiz line self.ly = self.ax.axvline(color='k', linewidth=0.2) # the vert line # Add data left_shift = 0.45 start = 0.96 space = 0.04 self.ax.text(0.01, start, transform = self.ax.transAxes, s = "Folder: " + self.folder_name, fontsize=12, horizontalalignment = 'left') self.ax.text(0.01, start - space, transform = self.ax.transAxes, s = "Dosage: " + str(self.dosage), fontsize=12, horizontalalignment = 'left') self.i_text = self.ax.text(0.60 - left_shift, 1.1 - space, transform = self.ax.transAxes, s = "Heartbeat: " + str(self.index + 1) + "/" + str(len(self.peaks.R.data) - 1), fontsize=12, horizontalalignment = 'left') # Add index buttons ax_prev = plt.axes([0.575 - left_shift, 0.9, 0.1, 0.075]) self.bprev = Button(ax_prev, 'Previous') self.bprev.on_clicked(self.prev) ax_next = plt.axes([0.8 - left_shift, 0.9, 0.1, 0.075]) self.b_next = Button(ax_next, 'Next') self.b_next.on_clicked(self.next) self.fig.canvas.mpl_connect('motion_notify_event', self.mouse_move) self.fig.canvas.mpl_connect('button_press_event', self.on_click) self.fig.canvas.mpl_connect('button_release_event', self.off_click) # Add Sliders start = 0.91 slider_width = 0.0075 slider_height = 0.47 self.cutoff_amp_slider = Slider(plt.axes([0.05, 0.15, 2*slider_width, slider_height]), label = "Cutoff (Hz)", valmin = 1, valmax = 50, valinit = self.cutoff_freq, orientation = 'vertical', valfmt='%0.0f') self.cutoff_amp_slider.label.set_size(8) self.cutoff_amp_slider.on_changed(self.switch_signal) self.signal_amp_slider = Slider(plt.axes([start, 0.15, slider_width, slider_height]), label = "ECG\n\nA", valmin = 0.01, valmax = 10, valinit = 1, orientation = 'vertical') self.signal_amp_slider.label.set_size(8) self.signal_amp_slider.on_changed(self.switch_signal) self.signal_amp_slider.valtext.set_visible(False) self.first_height_slider = Slider(plt.axes([start + 2*slider_width, 0.15, slider_width, slider_height]), label = " 1st\n Derv.\nH", valmin = 1.5 * min(self.signal), valmax = 1.5 * max(self.signal), valinit = 0, orientation = 'vertical') self.first_height_slider.label.set_size(8) self.first_height_slider.on_changed(self.switch_signal) self.first_height_slider.valtext.set_visible(False) self.first_amp_slider = Slider(plt.axes([start + 3*slider_width, 0.15, slider_width, slider_height]), label = "\nA", valmin = 0.01, valmax = 10, valinit = 1, orientation = 'vertical') self.first_amp_slider.label.set_size(8) self.first_amp_slider.on_changed(self.switch_signal) self.first_amp_slider.valtext.set_visible(False) # Maximize frame mng = plt.get_current_fig_manager() mng.full_screen_toggle() plt.show()