From 24f270a2a479696a00240d7b9479f9125518f82e Mon Sep 17 00:00:00 2001 From: Pierre-Antoine Rouby Date: Thu, 17 Apr 2025 17:54:18 +0200 Subject: [PATCH] Acoustic data: Add bottom detection setting to SQL and refactoring. --- Model/create_table_for_save_as.py | 14 +- Model/read_table_for_open.py | 27 +- View/acoustic_data_tab.py | 580 +++++++++++++----------------- settings.py | 8 +- 4 files changed, 286 insertions(+), 343 deletions(-) diff --git a/Model/create_table_for_save_as.py b/Model/create_table_for_save_as.py index bdb675c..3bf2d3c 100644 --- a/Model/create_table_for_save_as.py +++ b/Model/create_table_for_save_as.py @@ -106,7 +106,11 @@ class CreateTableForSaveAs: rmax_index FLOAT, rmax_value FLOAT, freq_bottom_detection_index FLOAT, freq_bottom_detection_value STRING, - SNR_filter_value FLOAT, Nb_cells_to_average_BS_signal FLOAT + depth_bottom_detection_min FLOAT, + depth_bottom_detection_max FLOAT, + depth_bottom_detection_inverval FLOAT, + SNR_filter_value FLOAT, + Nb_cells_to_average_BS_signal FLOAT ) """ @@ -435,9 +439,12 @@ class CreateTableForSaveAs: tmin_index, tmin_value, tmax_index, tmax_value, rmin_index, rmin_value, rmax_index, rmax_value, freq_bottom_detection_index, freq_bottom_detection_value, + depth_bottom_detection_min, + depth_bottom_detection_max, + depth_bottom_detection_inverval, SNR_filter_value, Nb_cells_to_average_BS_signal ) - VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) """, ( stg.acoustic_data[i], stg.temperature, @@ -448,6 +455,9 @@ class CreateTableForSaveAs: stg.rmax[i][0], stg.rmax[i][1], stg.freq_bottom_detection[i][0], stg.freq_bottom_detection[i][1], + stg.depth_bottom_detection_min, + stg.depth_bottom_detection_max, + stg.depth_bottom_detection_interval, stg.SNR_filter_value[i], stg.Nb_cells_to_average_BS_signal[i] ) diff --git a/Model/read_table_for_open.py b/Model/read_table_for_open.py index e0b80f3..85673c3 100644 --- a/Model/read_table_for_open.py +++ b/Model/read_table_for_open.py @@ -497,23 +497,30 @@ class ReadTableForOpen: tmin_index, tmin_value, tmax_index, tmax_value, rmin_index, rmin_value, rmax_index, rmax_value, freq_bottom_detection_index, freq_bottom_detection_value, + depth_bottom_detection_min, + depth_bottom_detection_max, + depth_bottom_detection_inverval, SNR_filter_value, Nb_cells_to_average_BS_signal FROM Settings WHERE (acoustic_data = {s}) ''' data = self.execute(query3) - x = data[0] + it = iter(data[0]) - stg.temperature = [x[1]][0] - stg.distance_from_ABS_to_free_surface.append(x[2]) - stg.tmin.append((x[3], x[4])) - stg.tmax.append((x[5], x[6])) - stg.rmin.append((x[7], x[8])) - stg.rmax.append((x[9], x[10])) - stg.freq_bottom_detection.append((x[11], x[12])) - stg.SNR_filter_value.append(x[13]) - stg.Nb_cells_to_average_BS_signal.append(x[14]) + acoustic_data = next(it) + stg.temperature = [next(it)][0] + stg.distance_from_ABS_to_free_surface.append(next(it)) + stg.tmin.append((next(it), next(it))) + stg.tmax.append((next(it), next(it))) + stg.rmin.append((next(it), next(it))) + stg.rmax.append((next(it), next(it))) + stg.freq_bottom_detection.append((next(it), next(it))) + stg.depth_bottom_detection_min = next(it) + stg.depth_bottom_detection_max = next(it) + stg.depth_bottom_detection_interval = next(it) + stg.SNR_filter_value.append(next(it)) + stg.Nb_cells_to_average_BS_signal.append(next(it)) logger.debug(f"stg.temperature: {stg.temperature}") logger.debug(f"stg.tmin: {stg.tmin}") diff --git a/View/acoustic_data_tab.py b/View/acoustic_data_tab.py index b955433..01cccd3 100644 --- a/View/acoustic_data_tab.py +++ b/View/acoustic_data_tab.py @@ -750,7 +750,10 @@ class AcousticDataTab(QWidget): self.fill_table() self.plot_backscattered_acoustic_signal_recording() self.plot_profile() + self.update_frequency_combobox() + self.update_bottom_detection_settings() + self.water_attenuation() self.compute_tmin_tmax() self.compute_rmin_rmax() @@ -2445,7 +2448,6 @@ class AcousticDataTab(QWidget): self.fig_BS.canvas.draw_idle() def update_plot_backscattered_acoustic_signal_recording(self): - # --- Condition if table is filled but transect is not plotted # --- => Error message if spin box values of tmin or tmax is change if self.canvas_BS == None: @@ -2455,116 +2457,85 @@ class AcousticDataTab(QWidget): msgBox.setText("Plot transect before change x-axis value") msgBox.setStandardButtons(QMessageBox.Ok) msgBox.exec() + return - else: + data_id = self.fileListWidget.currentRow() - if self.fileListWidget.currentRow() != -1: - if len(self.axis_BS.tolist()) != stg.freq[self.fileListWidget.currentRow()].shape[0]: - self.fig_BS, self.axis_BS = plt.subplots(nrows=stg.freq[self.fileListWidget.currentRow()].shape[0], - ncols=1, - sharex=False, sharey=False, layout="constrained") + if data_id == -1: + return - for f, _ in enumerate(stg.freq[self.fileListWidget.currentRow()]): - self.axis_BS[f].cla() + if len(self.axis_BS.tolist()) != stg.freq[data_id].shape[0]: + self.fig_BS, self.axis_BS = plt.subplots( + nrows=stg.freq[data_id].shape[0], + ncols=1, + sharex=False, sharey=False, + layout="constrained" + ) - if stg.BS_cross_section[self.fileListWidget.currentRow()].shape != (0,): + for f, _ in enumerate(stg.freq[data_id]): + self.axis_BS[f].cla() - val_min = np.nanmin(stg.BS_cross_section[self.fileListWidget.currentRow()][f, :, :]) - val_max = np.nanmax(stg.BS_cross_section[self.fileListWidget.currentRow()][f, :, :]) - if val_min == 0: - val_min = 1e-5 + if stg.BS_cross_section[data_id].shape != (0,): + BS_data = stg.BS_cross_section + time_data = stg.time_cross_section + depth_data = stg.depth_cross_section + else: + BS_data = stg.BS_raw_data + time_data = stg.time + depth_data = stg.depth - if self.combobox_ABS_system_choice.currentIndex() == 1: - pcm = self.axis_BS[f].pcolormesh( - stg.time_cross_section[self.fileListWidget.currentRow()][f, :], - -stg.depth_cross_section[self.fileListWidget.currentRow()][f, :], - stg.BS_cross_section[self.fileListWidget.currentRow()][f, :, :], - cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max)) - elif self.combobox_ABS_system_choice.currentIndex() == 2: - pcm = self.axis_BS[f].pcolormesh( - stg.time_cross_section[self.fileListWidget.currentRow()][f, :], - -stg.depth_cross_section[self.fileListWidget.currentRow()][f, :], - np.log(stg.BS_cross_section[self.fileListWidget.currentRow()][f, :, - :]), - cmap='Blues') + val_min = np.nanmin(BS_data[data_id][f, :, :]) + val_max = np.nanmax(BS_data[data_id][f, :, :]) - # --- Plot red solid line on transect to visualize position of plotted profile --- - slider_value = \ - [self.slider.value() - 1 if self.slider.value() - 1 <= - stg.time_cross_section[self.fileListWidget.currentRow()].shape[ - 1] - 1 - else np.max(stg.time_cross_section[self.fileListWidget.currentRow()].shape[1] - 1)][0] + if val_min == 0: + val_min = 1e-5 - self.axis_BS[self.combobox_frequency_profile.currentIndex()].plot( - stg.time_cross_section[self.fileListWidget.currentRow()][ - 0, # self.combobox_frequency_profile.currentIndex(), - slider_value] * np.ones( - stg.depth_cross_section[self.fileListWidget.currentRow()].shape[1]), - -stg.depth_cross_section[self.fileListWidget.currentRow()][ - self.combobox_frequency_profile.currentIndex(), :], - color='red', linestyle="solid", linewidth=2) + if self.combobox_ABS_system_choice.currentIndex() == 1: + pcm = self.axis_BS[f].pcolormesh( + time_data[data_id][f, :], + -depth_data[data_id][f, :], + BS_data[data_id][f, :, :], + cmap='viridis', + norm=LogNorm(vmin=val_min, vmax=val_max) + ) + elif self.combobox_ABS_system_choice.currentIndex() == 2: + pcm = self.axis_BS[f].pcolormesh( + time_data[data_id][f, :], + -depth_data[data_id][f, :], + np.log(BS_data[data_id][f, :, :]), + cmap='Blues' + ) - # --- Plot river bottom line --- - if stg.depth_bottom[self.fileListWidget.currentRow()].shape != (0,): + # --- Plot red solid line on transect to visualize position of plotted profile --- + slider_value = [ + self.slider.value() - 1 + if self.slider.value() - 1 <= time_data[data_id].shape[1] - 1 + else np.max(time_data[data_id].shape[1] - 1) + ][0] - self.axis_BS[f].plot(stg.time_cross_section[self.fileListWidget.currentRow()][ - self.combobox_frequency_bathymetry.currentIndex(), :], - -stg.depth_bottom[self.fileListWidget.currentRow()], - color='black', linewidth=1, linestyle="solid") + freq_id = self.combobox_frequency_profile.currentIndex() - else: + self.axis_BS[freq_id].plot( + time_data[data_id][0, slider_value] * np.ones( + depth_data[data_id].shape[1] + ), + -depth_data[data_id][freq_id, :], + color='red', linestyle="solid", linewidth=2 + ) - val_min = np.nanmin(stg.BS_raw_data[self.fileListWidget.currentRow()][f, :, :]) - val_max = np.nanmax(stg.BS_raw_data[self.fileListWidget.currentRow()][f, :, :]) - if val_min == 0: - val_min = 1e-5 + # --- Plot river bottom line --- + if stg.depth_bottom[data_id].shape != (0,): + self.axis_BS[f].plot( + time_data[data_id][ + self.combobox_frequency_bathymetry.currentIndex(), : + ], + -stg.depth_bottom[data_id], + color='black', linewidth=1, linestyle="solid" + ) - if self.combobox_ABS_system_choice.currentIndex() == 1: - pcm = self.axis_BS[f].pcolormesh(stg.time[self.fileListWidget.currentRow()][f, :], - -stg.depth[self.fileListWidget.currentRow()][f, - :], - stg.BS_raw_data[self.fileListWidget.currentRow()][f, :, - :], - cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max)) - - elif self.combobox_ABS_system_choice.currentIndex() == 2: - pcm = self.axis_BS[f].pcolormesh(stg.time[self.fileListWidget.currentRow()][f, :], - -stg.depth[self.fileListWidget.currentRow()][f, - :], - np.log( - stg.BS_raw_data[self.fileListWidget.currentRow()][f, - :, :]), - cmap='Blues') - - # --- Plot red solid line on transect to visualize position of plotted profile --- - slider_value = \ - [self.slider.value() - 1 if self.slider.value() - 1 <= - stg.time[self.fileListWidget.currentRow()].shape[ - 1] - 1 - else np.max(stg.time[self.fileListWidget.currentRow()].shape[1] - 1)][0] - - self.axis_BS[self.combobox_frequency_profile.currentIndex()].plot( - stg.time[self.fileListWidget.currentRow()][0, slider_value] * - np.ones(stg.depth[self.fileListWidget.currentRow()].shape[1]), - -stg.depth[self.fileListWidget.currentRow()][ - self.combobox_frequency_profile.currentIndex(), :], - color='red', linestyle="solid", linewidth=2) - - # --- Plot river bottom line --- - if stg.depth_bottom[self.fileListWidget.currentRow()].shape != (0,): - self.axis_BS[f].plot(stg.time[self.fileListWidget.currentRow()][ - self.combobox_frequency_bathymetry.currentIndex(), :], - -stg.depth_bottom[self.fileListWidget.currentRow()], - color='black', linewidth=1, linestyle="solid") - - self.axis_BS[f].text(1, .70, stg.freq_text[self.fileListWidget.currentRow()][f], - fontsize=14, fontweight='bold', fontname="DejaVu Sans", c="black", alpha=0.5, - horizontalalignment='right', verticalalignment='bottom', - transform=self.axis_BS[f].transAxes) - - self.fig_BS.supxlabel('Time (sec)', fontsize=10) - self.fig_BS.supylabel('Depth (m)', fontsize=10) - self.fig_BS.canvas.draw_idle() + self.fig_BS.supxlabel('Time (sec)', fontsize=10) + self.fig_BS.supylabel('Depth (m)', fontsize=10) + self.fig_BS.canvas.draw_idle() def plot_profile(self): if self.fileListWidget.currentRow() != -1: @@ -2782,7 +2753,33 @@ class AcousticDataTab(QWidget): str(stg.time[self.fileListWidget.currentRow()][self.combobox_frequency_profile.currentIndex(), self.slider.value()-1])) + def update_bottom_detection_settings(self): + self.lineEdit_depth_min_bathy.setText( + str(stg.depth_bottom_detection_min) + ) + + self.lineEdit_depth_max_bathy.setText( + str(stg.depth_bottom_detection_max) + ) + + self.lineEdit_next_cell_bathy.setText( + str(stg.depth_bottom_detection_interval) + ) + + def save_bottom_detection_settings(self): + stg.depth_bottom_detection_min = float( + self.lineEdit_depth_min_bathy.text() + ) + stg.depth_bottom_detection_max = float( + self.lineEdit_depth_max_bathy.text() + ) + stg.depth_bottom_detection_interval = float( + self.lineEdit_next_cell_bathy.text() + ) + def detect_bottom(self): + self.save_bottom_detection_settings() + if self.fileListWidget.count() == 0: msgBox = QMessageBox() msgBox.setWindowTitle("Detect bottom Error") @@ -2790,7 +2787,7 @@ class AcousticDataTab(QWidget): msgBox.setText("Load data before compute bathymety algorithm") msgBox.setStandardButtons(QMessageBox.Ok) msgBox.exec() - + return elif self.canvas_BS == None: msgBox = QMessageBox() msgBox.setWindowTitle("Detect bottom Error") @@ -2798,258 +2795,187 @@ class AcousticDataTab(QWidget): msgBox.setText("Plot transect before compute bathymety algorithm") msgBox.setStandardButtons(QMessageBox.Ok) msgBox.exec() - + return elif self.lineEdit_next_cell_bathy.text() == "0.00": + return - pass + self.detect_bottom_compute() - else: + def detect_bottom_compute(self): + data_id = self.fileListWidget.currentRow() + freq_id = self.combobox_frequency_bathymetry.currentIndex() + freq_text = self.combobox_frequency_bathymetry.currentText() - if stg.BS_cross_section[self.fileListWidget.currentRow()].shape != (0,): + if stg.BS_cross_section[data_id].shape != (0,): + BS_data = stg.BS_cross_section + time_data = stg.time_cross_section + depth_data = stg.depth_cross_section + elif stg.BS_raw_data[data_id].shape != (0,): + BS_data = stg.BS_raw_data + time_data = stg.time + depth_data = stg.depth - stg.freq_bottom_detection[self.fileListWidget.currentRow()] = \ - (self.combobox_frequency_bathymetry.currentIndex(), self.combobox_frequency_bathymetry.currentText()) + stg.freq_bottom_detection[data_id] = (freq_id, freq_text) - rmin = float("".join(findall("[.0-9]", self.lineEdit_depth_max_bathy.text()))) - rmax = float("".join(findall("[.0-9]", self.lineEdit_depth_min_bathy.text()))) + rmin = float( + "".join(findall( + "[.0-9]", + self.lineEdit_depth_max_bathy.text() + )) + ) + rmax = float( + "".join(findall( + "[.0-9]", self.lineEdit_depth_min_bathy.text() + )) + ) - r_bottom = np.zeros(stg.time_cross_section[self.fileListWidget.currentRow()].shape[1]) - val_bottom = np.zeros(stg.time_cross_section[self.fileListWidget.currentRow()].shape[1]) + r_bottom = np.zeros(time_data[data_id].shape[1]) + val_bottom = np.zeros(time_data[data_id].shape[1]) - r_bottom_ind = [] + r_bottom_ind = [] - BS_smooth = deepcopy(stg.BS_cross_section[self.fileListWidget.currentRow()][self.combobox_frequency_bathymetry.currentIndex(), :, :]) + BS_smooth = deepcopy(BS_data[data_id][freq_id, :, :]) - for k in range(stg.time_cross_section[self.fileListWidget.currentRow()].shape[1]): - BS_smooth[:, k] = savgol_filter(BS_smooth[:, k], 10, 2) + for k in range(time_data[data_id].shape[1]): + BS_smooth[:, k] = savgol_filter(BS_smooth[:, k], 10, 2) - # ----------- Detecting the bottom ------------- - for d in range(stg.time_cross_section[self.fileListWidget.currentRow()].shape[1]): + # ----------- Detecting the bottom ------------- + for d in range(time_data[data_id].shape[1]): + ind_min = np.where( + depth_data[data_id][freq_id, :] + >= rmin + )[0][0] + ind_max = np.where( + depth_data[data_id][freq_id, :] + <= rmax + )[0][-1] - ind_min = np.where(stg.depth_cross_section[self.fileListWidget.currentRow()][int(self.combobox_frequency_bathymetry.currentIndex()), :] >= rmin)[0][0] - ind_max = np.where(stg.depth_cross_section[self.fileListWidget.currentRow()][int(self.combobox_frequency_bathymetry.currentIndex()), :] <= rmax)[0][-1] + # Getting the peak + try: + val_bottom[d] = np.nanmax(BS_smooth[ind_min:ind_max, d]) + except ValueError as e: + msgBox = QMessageBox() + msgBox.setWindowTitle("Detect bottom Error") + msgBox.setIcon(QMessageBox.Warning) + msgBox.setText( + f"1/ {e} : maximum value of section bottom is not found. \n " + f"Please change parameter of algorithm" + ) + msgBox.setStandardButtons(QMessageBox.Ok) + msgBox_return = msgBox.exec() + if msgBox_return == msgBox.Ok: + break + else: + ind_bottom = np.where( + (BS_smooth[ind_min:ind_max, d]) + == val_bottom[d] + )[0][0] + np.append(stg.ind_bottom, ind_bottom) + r_bottom[d] = depth_data[data_id][ + freq_id, ind_bottom + ind_min + ] + r_bottom_ind.append(ind_bottom + ind_min) - # Getting the peak - try: - val_bottom[d] = np.nanmax(BS_smooth[ind_min:ind_max, d]) + # Updating the range where we will look for the peak (in the next cell) + rmin = r_bottom[d] - float( + "".join(findall( + "[.0-9]", self.lineEdit_next_cell_bathy.text() + )) + ) + rmax = r_bottom[d] + float( + "".join(findall( + "[.0-9]", self.lineEdit_next_cell_bathy.text() + )) + ) - except ValueError as e: - msgBox = QMessageBox() - msgBox.setWindowTitle("Detect bottom Error") - msgBox.setIcon(QMessageBox.Warning) - msgBox.setText(f"1/ {e} : maximum value of section bottom is not found. \n " - f"Please change parameter of algorithm") - msgBox.setStandardButtons(QMessageBox.Ok) - msgBox_return = msgBox.exec() - if msgBox_return == msgBox.Ok: - break - else: + BS_section_bottom = np.zeros(( + depth_data[data_id].shape[1], + time_data[data_id].shape[1] + )) - ind_bottom = np.where((BS_smooth[ind_min:ind_max, d]) == val_bottom[d])[0][0] - np.append(stg.ind_bottom, ind_bottom) + for i in range(BS_section_bottom.shape[0]): + try: + BS_section_bottom[r_bottom_ind[i]][i] = 1 + except IndexError as e: + msgBox = QMessageBox() + msgBox.setWindowTitle("Detect bottom Error") + msgBox.setIcon(QMessageBox.Warning) + msgBox.setText( + f"2/ {e} : maximum value of section bottom is not found. \n " + f"Please change parameter of algorithm" + ) + msgBox.setStandardButtons(QMessageBox.Ok) + msgBox_return = msgBox.exec() + if msgBox_return == msgBox.Ok: + break - r_bottom[d] = stg.depth_cross_section[self.fileListWidget.currentRow()][self.combobox_frequency_bathymetry.currentIndex(), ind_bottom + ind_min] - r_bottom_ind.append(ind_bottom + ind_min) - # Updating the range where we will look for the peak (in the next cell) - rmin = r_bottom[d] - float("".join(findall("[.0-9]", self.lineEdit_next_cell_bathy.text()))) - rmax = r_bottom[d] + float("".join(findall("[.0-9]", self.lineEdit_next_cell_bathy.text()))) + if BS_section_bottom.sum() > 2: + stg.depth_bottom[data_id] = r_bottom + stg.val_bottom[data_id] = val_bottom + stg.ind_bottom[data_id] = r_bottom_ind - BS_section_bottom = np.zeros((stg.depth_cross_section[self.fileListWidget.currentRow()].shape[1], - stg.time_cross_section[self.fileListWidget.currentRow()].shape[1])) + BS_stream_bed_copy = deepcopy(BS_data[data_id]) + for f, _ in enumerate(stg.freq[data_id]): + for k, _ in enumerate(stg.depth_bottom[data_id]): + BS_stream_bed_copy[ + f, np.where( + depth_data[data_id][freq_id, :] + >= stg.depth_bottom[data_id][k] + )[0], k + ] = np.nan - for i in range(BS_section_bottom.shape[0]): - try: - BS_section_bottom[r_bottom_ind[i]][i] = 1 - except IndexError as e: - msgBox = QMessageBox() - msgBox.setWindowTitle("Detect bottom Error") - msgBox.setIcon(QMessageBox.Warning) - msgBox.setText(f"2/ {e} : maximum value of section bottom is not found. \n " - f"Please change parameter of algorithm") - msgBox.setStandardButtons(QMessageBox.Ok) - msgBox_return = msgBox.exec() - if msgBox_return == msgBox.Ok: - break + stg.BS_stream_bed[data_id] = BS_stream_bed_copy - if BS_section_bottom.sum() > 2: + self.detect_bottom_compute_plot_BS_with_bathymetry( + BS_data, time_data, depth_data + ) - stg.depth_bottom[self.fileListWidget.currentRow()] = r_bottom + # --- Update plot profile --- + self.update_plot_profile() + self.fig_BS.canvas.draw_idle() - stg.val_bottom[self.fileListWidget.currentRow()] = val_bottom + def detect_bottom_compute_plot_BS_with_bathymetry( + self, BS_data, time_data, depth_data + ): + data_id = self.fileListWidget.currentRow() + freq_id = self.combobox_frequency_bathymetry.currentIndex() - stg.ind_bottom[self.fileListWidget.currentRow()] = r_bottom_ind + for f, _ in enumerate(stg.freq[data_id]): + self.axis_BS[f].cla() + val_min = np.min(stg.BS_raw_data[data_id][f, :, :]) + val_max = np.max(stg.BS_raw_data[data_id][f, :, :]) + if val_min == 0: + val_min = 1e-5 - BS_stream_bed_copy = deepcopy(stg.BS_cross_section[self.fileListWidget.currentRow()]) - for f, _ in enumerate(stg.freq[self.fileListWidget.currentRow()]): - for k, _ in enumerate(stg.depth_bottom[self.fileListWidget.currentRow()]): - BS_stream_bed_copy[ - f, np.where(stg.depth_cross_section[self.fileListWidget.currentRow()][self.combobox_frequency_bathymetry.currentIndex(), :] - >= stg.depth_bottom[self.fileListWidget.currentRow()][k])[ - 0], k] = np.nan + if self.combobox_ABS_system_choice.currentIndex() == 1: + pcm = self.axis_BS[f].pcolormesh( + time_data[data_id][f, :], + -depth_data[data_id][f, :], + BS_data[data_id][f, :, :], + cmap='viridis', + norm=LogNorm(vmin=val_min, vmax=val_max) + ) + elif self.combobox_ABS_system_choice.currentIndex() == 2: + pcm = self.axis_BS[f].pcolormesh( + time_data[data_id][f, :], + -depth_data[data_id][f, :], + np.log(BS_data[data_id][f, :, :]), + cmap='Blues' + ) - stg.BS_stream_bed[self.fileListWidget.currentRow()] = BS_stream_bed_copy + self.axis_BS[f].plot( + time_data[data_id][freq_id, :], + -stg.depth_bottom[data_id], + color='black', linewidth=1, linestyle="solid" + ) - # --- Plot transect BS with bathymetry --- - for f, _ in enumerate(stg.freq[self.fileListWidget.currentRow()]): - self.axis_BS[f].cla() - - val_min = np.min(stg.BS_raw_data[self.fileListWidget.currentRow()][f, :, :]) - val_max = np.max(stg.BS_raw_data[self.fileListWidget.currentRow()][f, :, :]) - if val_min == 0: - val_min = 1e-5 - - if self.combobox_ABS_system_choice.currentIndex() == 1: - pcm = self.axis_BS[f].pcolormesh(stg.time_cross_section[self.fileListWidget.currentRow()][f, :], - -stg.depth_cross_section[self.fileListWidget.currentRow()][f, :], - stg.BS_cross_section[self.fileListWidget.currentRow()][f, :, :], - cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max)) - elif self.combobox_ABS_system_choice.currentIndex() == 2: - pcm = self.axis_BS[f].pcolormesh(stg.time_cross_section[self.fileListWidget.currentRow()][f, :], - -stg.depth_cross_section[self.fileListWidget.currentRow()][f, :], - np.log(stg.BS_cross_section[self.fileListWidget.currentRow()][f, :, :]), - cmap='Blues') - - self.axis_BS[f].plot(stg.time_cross_section[self.fileListWidget.currentRow()][self.combobox_frequency_bathymetry.currentIndex(), :], - -stg.depth_bottom[self.fileListWidget.currentRow()], - color='black', linewidth=1, linestyle="solid") - - self.axis_BS[f].text(1, .70, stg.freq_text[self.fileListWidget.currentRow()][f], - fontsize=14, fontweight='bold', fontname="DejaVu Sans", c="black", alpha=0.5, - horizontalalignment='right', verticalalignment='bottom', - transform=self.axis_BS[f].transAxes) - - # --- Update plot profile --- - self.update_plot_profile() - - self.fig_BS.canvas.draw_idle() - - elif stg.BS_raw_data[self.fileListWidget.currentRow()].shape != (0,): - - stg.freq_bottom_detection[self.fileListWidget.currentRow()] = ( - self.combobox_frequency_bathymetry.currentIndex(), self.combobox_frequency_bathymetry.currentText()) - - # Selecting the range in which we look for the bottom reflection - rmin = float("".join(findall("[.0-9]", self.lineEdit_depth_max_bathy.text()))) - rmax = float("".join(findall("[.0-9]", self.lineEdit_depth_min_bathy.text()))) - - # empty result arrays - r_bottom = np.zeros(stg.time[self.fileListWidget.currentRow()].shape[1]) - val_bottom = np.zeros(stg.time[self.fileListWidget.currentRow()].shape[1]) - - r_bottom_ind = [] - - BS_smooth = deepcopy(stg.BS_raw_data[self.fileListWidget.currentRow()][ - self.combobox_frequency_bathymetry.currentIndex(), :, :]) - for k in range(stg.time[self.fileListWidget.currentRow()].shape[1]): - BS_smooth[:, k] = savgol_filter(BS_smooth[:, k], 10, 2) - - # ----------- Detecting the bottom ------------- - for d in range(stg.time[self.fileListWidget.currentRow()].shape[1]): - # Index of the range where we look for the peak - ind_min = np.where(stg.depth[self.fileListWidget.currentRow()][ - int(self.combobox_frequency_bathymetry.currentIndex()), :] >= rmin)[0][0] - ind_max = np.where(stg.depth[self.fileListWidget.currentRow()][ - int(self.combobox_frequency_bathymetry.currentIndex()), :] <= rmax)[0][-1] - - # Getting the peak - try: - val_bottom[d] = np.nanmax(BS_smooth[ind_min:ind_max, d]) - - except ValueError as e: - msgBox = QMessageBox() - msgBox.setWindowTitle("Detect bottom Error") - msgBox.setIcon(QMessageBox.Warning) - msgBox.setText(f"1/ {e} : maximum value of section bottom is not found. \n " - f"Please change parameter of algorithm") - msgBox.setStandardButtons(QMessageBox.Ok) - msgBox_return = msgBox.exec() - if msgBox_return == msgBox.Ok: - break # msgBox.close() - else: - # Getting the range cell of the peak - ind_bottom = np.where((BS_smooth[ind_min:ind_max, d]) == val_bottom[d])[0][0] - np.append(stg.ind_bottom, ind_bottom) - - r_bottom[d] = stg.depth[self.fileListWidget.currentRow()][ - self.combobox_frequency_bathymetry.currentIndex(), ind_bottom + ind_min] - r_bottom_ind.append(ind_bottom + ind_min) - - # Updating the range where we will look for the peak (in the next cell) - rmin = r_bottom[d] - float("".join(findall("[.0-9]", self.lineEdit_next_cell_bathy.text()))) - rmax = r_bottom[d] + float("".join(findall("[.0-9]", self.lineEdit_next_cell_bathy.text()))) - - BS_section_bottom = np.zeros((stg.depth[self.fileListWidget.currentRow()].shape[1], - stg.time[self.fileListWidget.currentRow()].shape[1])) - - for i in range(BS_section_bottom.shape[0]): - try: - BS_section_bottom[r_bottom_ind[i]][i] = 1 - except IndexError as e: - msgBox = QMessageBox() - msgBox.setWindowTitle("Detect bottom Error") - msgBox.setIcon(QMessageBox.Warning) - msgBox.setText(f"2/ {e} : maximum value of section bottom is not found. \n " - f"Please change parameter of algorithm") - msgBox.setStandardButtons(QMessageBox.Ok) - msgBox_return = msgBox.exec() - if msgBox_return == msgBox.Ok: - break # msgBox.close() - - if BS_section_bottom.sum() > 2: - # --- Record r_bottom for other tabs --- - stg.depth_bottom[self.fileListWidget.currentRow()] = r_bottom - - stg.val_bottom[self.fileListWidget.currentRow()] = val_bottom - - stg.ind_bottom[self.fileListWidget.currentRow()] = r_bottom_ind - - BS_stream_bed_copy = deepcopy(stg.BS_raw_data[self.fileListWidget.currentRow()]) - for f, _ in enumerate(stg.freq[self.fileListWidget.currentRow()]): - for k, _ in enumerate(stg.depth_bottom[self.fileListWidget.currentRow()]): - BS_stream_bed_copy[ - f, np.where(stg.depth[self.fileListWidget.currentRow()][ - self.combobox_frequency_bathymetry.currentIndex(), :] - >= stg.depth_bottom[self.fileListWidget.currentRow()][k])[ - 0], k] = np.nan - - stg.BS_stream_bed[self.fileListWidget.currentRow()] = BS_stream_bed_copy - - # --- Plot transect BS with bathymetry --- - for f, _ in enumerate(stg.freq[self.fileListWidget.currentRow()]): - self.axis_BS[f].cla() - - val_min = np.min(stg.BS_raw_data[self.fileListWidget.currentRow()][f, :, :]) - val_max = np.max(stg.BS_raw_data[self.fileListWidget.currentRow()][f, :, :]) - if val_min == 0: - val_min = 1e-5 - - if self.combobox_ABS_system_choice.currentIndex() == 1: - pcm = self.axis_BS[f].pcolormesh( - stg.time[self.fileListWidget.currentRow()][f, :], - -stg.depth[self.fileListWidget.currentRow()][f, :], - stg.BS_raw_data[self.fileListWidget.currentRow()][f, :, :], - cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max)) - elif self.combobox_ABS_system_choice.currentIndex() == 2: - pcm = self.axis_BS[f].pcolormesh( - stg.time[self.fileListWidget.currentRow()][f, :], - -stg.depth[self.fileListWidget.currentRow()][f, :], - np.log(stg.BS_raw_data[self.fileListWidget.currentRow()][f, :, :]), - cmap='Blues') - - self.axis_BS[f].plot(stg.time[self.fileListWidget.currentRow()][ - self.combobox_frequency_bathymetry.currentIndex(), :], - -stg.depth_bottom[self.fileListWidget.currentRow()], - color='black', linewidth=1, linestyle="solid") - - self.axis_BS[f].text(1, .70, stg.freq_text[self.fileListWidget.currentRow()][f], - fontsize=14, fontweight='bold', fontname="DejaVu Sans", c="black", - alpha=0.5, - horizontalalignment='right', verticalalignment='bottom', - transform=self.axis_BS[f].transAxes) - - # --- Update plot profile --- - self.update_plot_profile() - - self.fig_BS.canvas.draw_idle() + self.axis_BS[f].text( + 1, .70, stg.freq_text[data_id][f], + fontsize=14, fontweight='bold', + fontname="DejaVu Sans", c="black", alpha=0.5, + horizontalalignment='right', + verticalalignment='bottom', + transform=self.axis_BS[f].transAxes + ) diff --git a/settings.py b/settings.py index 7c7e589..424a4c4 100644 --- a/settings.py +++ b/settings.py @@ -105,11 +105,11 @@ BS_stream_bed = [] # BS data (raw or cross_section) with detected b depth_bottom = [] # Depth value of th bottom : 1D array # List of arrays val_bottom = [] # Level of the BS signal on the bottom : 1D array # List of arrays ind_bottom = [] # Index of bottom in depth array : list of int # List of lists -freq_bottom_detection = [] # Frequency use to detect the bottom : (index, string) # List of tuple -# depth_bottom_detection_min = [] # Min value to detect bottom on the first vertical # List of float -# depth_bottom_detection_max = [] # Max value to detect bottom on the first vertical # List of float -# depth_bottom_detection_1st_int_area = [] # interval for searching area # List of float +freq_bottom_detection = [] # Frequency use to detect the bottom : (index, string) # List of tuple +depth_bottom_detection_min = [] # Min value to detect bottom on the first vertical # List of float +depth_bottom_detection_max = [] # Max value to detect bottom on the first vertical # List of float +depth_bottom_detection_interval = [] # interval for searching area # List of float # ---------------------------------------------------------------------------------------------------------------------- # =========================================================