diff --git a/View/acoustic_data_tab.py b/View/acoustic_data_tab.py index 2c6871b..bf10f0d 100644 --- a/View/acoustic_data_tab.py +++ b/View/acoustic_data_tab.py @@ -486,6 +486,7 @@ class AcousticDataTab(QWidget): # self.verticalLayout_groupbox_transect_2Dplot_raw_BS_data.setSpacing(0) self.canvas_BS = None + self.scroll_BS = None # self.fig_BS, self.axis_BS = plt.subplots(nrows=4, ncols=1, sharex=True, sharey=False, layout="constrained") # self.fig, self.ax = plt.subplots(4, 1) @@ -503,6 +504,7 @@ class AcousticDataTab(QWidget): self.verticalLayout_groupbox_transect_2Dplot_snr_data = QVBoxLayout(self.groupbox_transect_2Dplot_snr_data) self.canvas_SNR = None + self.scroll_SNR = None # self.figure, self.axis = plt.subplots(nrows=4, ncols=1, sharex=True, sharey=False, layout="constrained") # # self.canvas_snrdata = FigureCanvas(self.figure) @@ -841,10 +843,12 @@ class AcousticDataTab(QWidget): # --- => Then plot transect for each frequency by pressing the button "Plot transect" elif (self.tableModel.rowCount(1) > 10) and (self.canvas_BS == None): + self.fig_BS, self.axis_BS = plt.subplots(nrows=stg.freq.shape[0], ncols=1, sharex=True, sharey=False, layout="constrained") self.canvas_BS = FigureCanvas(self.fig_BS) # self.verticalLayout_groupbox_transect_2Dplot_raw_BS_data.addWidget(self.canvas_BS) + self.verticalLayout_groupbox_transect_2Dplot_raw_BS_data.removeWidget(self.scroll_BS) self.scroll_BS = QScrollArea() self.scroll_BS.setWidget(self.canvas_BS) self.scroll_BS.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) @@ -959,6 +963,7 @@ class AcousticDataTab(QWidget): self.canvas_SNR = FigureCanvas(self.fig_SNR) self.verticalLayout_groupbox_transect_2Dplot_snr_data.addWidget(self.canvas_SNR) + self.verticalLayout_groupbox_transect_2Dplot_snr_data.removeWidget(self.scroll_SNR) self.scroll_SNR = QScrollArea() self.scroll_SNR.setWidget(self.canvas_SNR) self.scroll_SNR.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) diff --git a/View/signal_processing_tab.py b/View/signal_processing_tab.py index 32787ca..d7b289c 100644 --- a/View/signal_processing_tab.py +++ b/View/signal_processing_tab.py @@ -84,8 +84,8 @@ class SignalProcessingTab(QWidget): self.pushbutton_load_data = QPushButton() self.horizontalLayout_pushbutton_load_data_plot_bottom_line.addWidget(self.pushbutton_load_data) self.pushbutton_load_data.clicked.connect(self.compute_BS_data_section) - self.pushbutton_load_data.clicked.connect(self.plot_profile_position_on_transect) - self.pushbutton_load_data.clicked.connect(self.plot_profile) + # self.pushbutton_load_data.clicked.connect(self.plot_profile_position_on_transect) + # self.pushbutton_load_data.clicked.connect(self.plot_profile) self.combobox_frequency = QComboBox() self.horizontalLayout_pushbutton_load_data_plot_bottom_line.addWidget(self.combobox_frequency) @@ -195,15 +195,16 @@ class SignalProcessingTab(QWidget): self.label_cells = QLabel() self.horizontalLayout_groupbox_window_size.addWidget(self.label_cells) - self.spinbox_average.valueChanged.connect(self.compute_averaged_profile) + # self.spinbox_average.valueChanged.connect(self.compute_averaged_profile) self.pushbutton_average = QPushButton() self.pushbutton_average.setText("Apply averaging") # self.pushbutton_snr_filter.setDisabled(True) self.horizontalLayout_groupbox_window_size.addWidget(self.pushbutton_average) - self.pushbutton_average.clicked.connect(self.update_plot_profile_position_on_transect) - self.pushbutton_average.clicked.connect(self.plot_averaged_profile) + self.pushbutton_average.clicked.connect(self.compute_averaged_profile) + # self.pushbutton_average.clicked.connect(self.update_plot_profile_position_on_transect) + # self.pushbutton_average.clicked.connect(self.plot_averaged_profile) # --- Groupbox acoustic profile --- @@ -218,14 +219,15 @@ class SignalProcessingTab(QWidget): # self.spinbox_SNR_criterion.setDisabled(True) self.gridLayout_groupbox_acoustic_profile.addWidget(self.spinbox_SNR_criterion, 0, 1, 1, 1) - self.spinbox_SNR_criterion.valueChanged.connect(self.remove_point_with_snr_filter) + # self.spinbox_SNR_criterion.valueChanged.connect(self.remove_point_with_snr_filter) self.pushbutton_snr_filter = QPushButton() self.pushbutton_snr_filter.setText("Apply SNR") self.gridLayout_groupbox_acoustic_profile.addWidget(self.pushbutton_snr_filter, 0, 2, 1, 1) - self.pushbutton_snr_filter.clicked.connect(self.update_plot_profile) - self.pushbutton_snr_filter.clicked.connect(self.update_plot_profile_position_on_transect) + self.pushbutton_snr_filter.clicked.connect(self.remove_point_with_snr_filter) + # self.pushbutton_snr_filter.clicked.connect(self.update_plot_profile) + # self.pushbutton_snr_filter.clicked.connect(self.update_plot_profile_position_on_transect) # ++++++++++++++++++++++++++++++++++++ # +++ --- GroupBox FCB options --- +++ @@ -581,57 +583,108 @@ class SignalProcessingTab(QWidget): def compute_BS_data_section(self): + if stg.BS_data.size == 0: + msgBox = QMessageBox() + msgBox.setWindowTitle("Load data Error") + msgBox.setIcon(QMessageBox.Warning) + msgBox.setText("Please check acoustic data Tab") + msgBox.setStandardButtons(QMessageBox.Ok) + msgBox.exec() + else: + if stg.r_bottom.size == 0: + stg.BS_data_section = deepcopy(stg.BS_data) + elif stg.r_bottom.size != 0: + stg.BS_data_section = deepcopy(stg.BS_data) + for f in range(stg.freq.shape[0]): + for k in range(stg.r_bottom.shape[0]): + # print(k, np.where(stg.r >= stg.r_bottom[k])[0]) + stg.BS_data_section[np.where(stg.r >= stg.r_bottom[k])[0], f, k] = np.nan - if stg.r_bottom.size == 0: - stg.BS_data_section = deepcopy(stg.BS_data) - elif stg.r_bottom.size != 0: - stg.BS_data_section = deepcopy(stg.BS_data) - for f in range(stg.freq.shape[0]): - for k in range(stg.r_bottom.shape[0]): - # print(k, np.where(stg.r >= stg.r_bottom[k])[0]) - stg.BS_data_section[np.where(stg.r >= stg.r_bottom[k])[0], f, k] = np.nan + # --- Choose frequency (Combo box) to plot transect with profile position --- + self.combobox_frequency.addItems(stg.freq_text) + self.combobox_frequency.currentTextChanged.connect(self.update_plot_profile_position_on_transect) + + # --- Choose frequency (Combo box) to compute water attenuation --- + self.combobox_freq_for_water_attenuation.addItems(stg.freq_text) + + # --- Choose frequency (Combo box) to compute sediment attenuation --- + self.combobox_frequency_compute_alphaS.addItems(stg.freq_text) + + # --- Fix maximum value of slider + Edit Label Profile number --- + self.slider.setMaximum(stg.t.shape[0]) + self.label_profile_number.clear() + self.label_profile_number.setText("Profile " + str(self.slider.value()) + " / " + str(self.slider.maximum())) + + self.plot_profile_position_on_transect() + self.plot_profile() # ----------------------------------------- Connect Groupbox average data ----------------------------------------- def compute_averaged_profile(self): - filter_convolve = np.ones(self.spinbox_average.value()) - stg.BS_data_section_averaged = np.zeros((stg.r.shape[0], stg.freq.shape[0], stg.t.shape[0])) - for f in range(stg.freq.shape[0]): - for i in range(stg.r.shape[0]): - stg.BS_data_section_averaged[i, f, :] \ - = convolve1d(stg.BS_data_section[i, f, :], weights=filter_convolve) / filter_convolve.shape[0] + if stg.BS_data_section.size == 0: + msgBox = QMessageBox() + msgBox.setWindowTitle("Average Backscatter signal Error") + msgBox.setIcon(QMessageBox.Warning) + msgBox.setText("Load data from acoustic data tab before averaging backscatter signal") + msgBox.setStandardButtons(QMessageBox.Ok) + msgBox.exec() + else: + filter_convolve = np.ones(self.spinbox_average.value()) - self.label_cells.clear() - self.label_cells.setText("cells = +/- " + str((self.spinbox_average.value() // 2)*(1/stg.nb_profiles_per_sec)) + " sec") + stg.BS_data_section_averaged = np.zeros((stg.r.shape[0], stg.freq.shape[0], stg.t.shape[0])) + for f in range(stg.freq.shape[0]): + for i in range(stg.r.shape[0]): + stg.BS_data_section_averaged[i, f, :] \ + = convolve1d(stg.BS_data_section[i, f, :], weights=filter_convolve) / filter_convolve.shape[0] + + self.label_cells.clear() + self.label_cells.setText("cells = +/- " + str((self.spinbox_average.value() // 2)*(1/stg.nb_profiles_per_sec)) + " sec") + + self.plot_averaged_profile() + self.update_plot_profile_position_on_transect() # ---------------------------------------- Connect Groupbox filter with SNR ---------------------------------------- def remove_point_with_snr_filter(self): - if stg.BS_data_section_averaged.size == 0: - stg.BS_data_section_SNR_filter = deepcopy(stg.BS_data_section) - stg.SNR_data_average = np.divide( - (stg.BS_data_section_SNR_filter - stg.Noise_data[:, :, :stg.t.shape[0]])**2, - stg.Noise_data[:, :, :stg.t.shape[0]]**2) - for f in range(stg.freq.shape[0]): - stg.BS_data_section_SNR_filter[np.where(stg.SNR_data_average[:, 0, :] < self.spinbox_SNR_criterion.value())[0], - f, - np.where(stg.SNR_data_average[:, 0, :] < self.spinbox_SNR_criterion.value())[1]] \ - = np.nan + if stg.SNR_data.size == 0: + msgBox = QMessageBox() + msgBox.setWindowTitle("SNR filter Error") + msgBox.setIcon(QMessageBox.Warning) + msgBox.setText("Load Noise data from acoustic data tab before using SNR filter") + msgBox.setStandardButtons(QMessageBox.Ok) + msgBox.exec() - elif stg.BS_data_section_averaged.size != 0: - stg.BS_data_section_SNR_filter = deepcopy(stg.BS_data_section_averaged) - stg.SNR_data_average = np.divide( - (stg.BS_data_section_SNR_filter - stg.Noise_data[:, :, :stg.t.shape[0]]) ** 2, - stg.Noise_data[:, :, :stg.t.shape[0]] ** 2) + else: - for f in range(stg.freq.shape[0]): - stg.BS_data_section_SNR_filter[ - np.where(stg.SNR_data_average[:, 0, :] < self.spinbox_SNR_criterion.value())[0], - f, - np.where(stg.SNR_data_average[:, 0, :] < self.spinbox_SNR_criterion.value())[1]] \ - = np.nan + if stg.BS_data_section_averaged.size == 0: + stg.BS_data_section_SNR_filter = deepcopy(stg.BS_data_section) + stg.SNR_data_average = np.divide( + (stg.BS_data_section_SNR_filter - stg.Noise_data[:, :, :stg.t.shape[0]])**2, + stg.Noise_data[:, :, :stg.t.shape[0]]**2) + + for f in range(stg.freq.shape[0]): + stg.BS_data_section_SNR_filter[np.where(stg.SNR_data_average[:, 0, :] < self.spinbox_SNR_criterion.value())[0], + f, + np.where(stg.SNR_data_average[:, 0, :] < self.spinbox_SNR_criterion.value())[1]] \ + = np.nan + + elif stg.BS_data_section_averaged.size != 0: + stg.BS_data_section_SNR_filter = deepcopy(stg.BS_data_section_averaged) + stg.SNR_data_average = np.divide( + (stg.BS_data_section_SNR_filter - stg.Noise_data[:, :, :stg.t.shape[0]]) ** 2, + stg.Noise_data[:, :, :stg.t.shape[0]] ** 2) + + for f in range(stg.freq.shape[0]): + stg.BS_data_section_SNR_filter[ + np.where(stg.SNR_data_average[:, 0, :] < self.spinbox_SNR_criterion.value())[0], + f, + np.where(stg.SNR_data_average[:, 0, :] < self.spinbox_SNR_criterion.value())[1]] \ + = np.nan + + self.update_plot_profile_position_on_transect() + self.update_plot_averaged_profile() def compute_water_attenuation(self): if self.combobox_water_attenuation_model.currentIndex() == 0: @@ -662,22 +715,6 @@ class SignalProcessingTab(QWidget): def plot_profile_position_on_transect(self): - # --- Choose frequency (Combo box) to plot transect with profile position --- - self.combobox_frequency.addItems(stg.freq_text) - self.combobox_frequency.currentTextChanged.connect(self.update_plot_profile_position_on_transect) - - # --- Choose frequency (Combo box) to compute water attenuation --- - self.combobox_freq_for_water_attenuation.addItems(stg.freq_text) - - # --- Choose frequency (Combo box) to compute sediment attenuation --- - self.combobox_frequency_compute_alphaS.addItems(stg.freq_text) - - # --- Fix maximum value of slider + Edit Label Profile number --- - self.slider.setMaximum(stg.t.shape[0]) - self.label_profile_number.clear() - self.label_profile_number.setText( - "Profile " + str(self.slider.value()) + " / " + str(self.slider.maximum())) - # --- Create Matplotlib canvas (with figure and axis) to plot transect --- self.canvas_plot_profile_position_on_transect = FigureCanvas() self.figure_plot_profile_position_on_transect, self.axis_plot_profile_position_on_transect = \ @@ -718,13 +755,13 @@ class SignalProcessingTab(QWidget): if self.canvas_plot_profile_position_on_transect is None: msgBox = QMessageBox() - msgBox.setWindowTitle("Plot transect Error") + msgBox.setWindowTitle("Plot Error") msgBox.setIcon(QMessageBox.Warning) - msgBox.setText("Load and Plot transect before post process") + msgBox.setText("Load and post-process data before plotting transect with profile position") msgBox.setStandardButtons(QMessageBox.Ok) msgBox.exec() - elif self.canvas_plot_profile_position_on_transect != None: + else: if (stg.BS_data_section_averaged.size == 0) and (stg.BS_data_section_SNR_filter.size == 0): @@ -835,13 +872,21 @@ class SignalProcessingTab(QWidget): self.verticalLayout_groupbox_plot_FCB_profile.addWidget(self.canvas_FCB_profile) def update_plot_profile(self): + if self.canvas_profile is None: + msgBox = QMessageBox() + msgBox.setWindowTitle("Plot Error") + msgBox.setIcon(QMessageBox.Warning) + msgBox.setText("Load and post-process data before plotting profiles") + msgBox.setStandardButtons(QMessageBox.Ok) + msgBox.exec() - for f in range(stg.freq.shape[0]): - self.axis_profile[f].cla() - self.axis_profile[f].plot(stg.BS_data_section[:, f, self.slider.value() - 1], -stg.r, - linestyle='solid', color='k', linewidth=1) + else: + for f in range(stg.freq.shape[0]): + self.axis_profile[f].cla() + self.axis_profile[f].plot(stg.BS_data_section[:, f, self.slider.value() - 1], -stg.r, + linestyle='solid', color='k', linewidth=1) - self.figure_profile.canvas.draw_idle() + self.figure_profile.canvas.draw_idle() # --------------------------------- PLOT AVERAGED PROFILE FILTERED OR NOT WITH SNR --------------------------------- @@ -856,26 +901,34 @@ class SignalProcessingTab(QWidget): self.figure_averaged_profile.canvas.draw_idle() def update_plot_averaged_profile(self): + if self.canvas_averaged_profile is None: + msgBox = QMessageBox() + msgBox.setWindowTitle("Plot Error") + msgBox.setIcon(QMessageBox.Warning) + msgBox.setText("Load and post-process data before plotting averaged profiles") + msgBox.setStandardButtons(QMessageBox.Ok) + msgBox.exec() - if stg.BS_data_section_SNR_filter.size == 0: + else: + if stg.BS_data_section_SNR_filter.size == 0: - for f in range(stg.freq.shape[0]): - self.axis_averaged_profile[f].cla() - self.axis_averaged_profile[f].plot(stg.BS_data_section_averaged[:, f, self.slider.value() - 1], -stg.r, - linestyle='solid', color='k', linewidth=1) - self.axis_averaged_profile[f].set_ylim(-np.max(stg.r), np.min(stg.r)) + for f in range(stg.freq.shape[0]): + self.axis_averaged_profile[f].cla() + self.axis_averaged_profile[f].plot(stg.BS_data_section_averaged[:, f, self.slider.value() - 1], -stg.r, + linestyle='solid', color='k', linewidth=1) + self.axis_averaged_profile[f].set_ylim(-np.max(stg.r), np.min(stg.r)) - self.figure_averaged_profile.canvas.draw_idle() + self.figure_averaged_profile.canvas.draw_idle() - elif stg.BS_data_section_SNR_filter.size != 0: + elif stg.BS_data_section_SNR_filter.size != 0: - for f in range(stg.freq.shape[0]): - self.axis_averaged_profile[f].cla() - self.axis_averaged_profile[f].plot(stg.BS_data_section_SNR_filter[:, f, self.slider.value() - 1], -stg.r, - linestyle='solid', color='k', linewidth=1) - self.axis_averaged_profile[f].set_ylim(-np.max(stg.r), np.min(stg.r)) + for f in range(stg.freq.shape[0]): + self.axis_averaged_profile[f].cla() + self.axis_averaged_profile[f].plot(stg.BS_data_section_SNR_filter[:, f, self.slider.value() - 1], -stg.r, + linestyle='solid', color='k', linewidth=1) + self.axis_averaged_profile[f].set_ylim(-np.max(stg.r), np.min(stg.r)) - self.figure_averaged_profile.canvas.draw_idle() + self.figure_averaged_profile.canvas.draw_idle() # def plot_transect_bottom_with_profile_position(self, profile_position): # frequency = self.model.Freq[0]