From 3dd6a4e310934343a81f7e969f39c2f4370b65cb Mon Sep 17 00:00:00 2001 From: brahim Date: Mon, 13 Nov 2023 15:00:28 +0100 Subject: [PATCH] Names of BS numpy arrays are changed : BS_data and BS_data_section become, respectively, BS_cross_section and BS_stream_bed. In general, name of variables including data under river bottom line is composed with _cross_section. Name of variables with NaN under river bottom line is composed with _stream_bed. --- Model/acoustic_data_loader.py | 23 +- Model/acoustic_data_loader_UBSediFlow.py | 193 +++++-- View/acoustic_data_tab.py | 271 ++++++---- View/sample_data_tab.py | 36 +- View/signal_processing_tab.py | 639 +++++++++++++++-------- main.py | 67 ++- settings.py | 27 +- 7 files changed, 827 insertions(+), 429 deletions(-) diff --git a/Model/acoustic_data_loader.py b/Model/acoustic_data_loader.py index 1ad5c0d..4decd2a 100644 --- a/Model/acoustic_data_loader.py +++ b/Model/acoustic_data_loader.py @@ -10,7 +10,8 @@ from matplotlib.colors import LogNorm # path_noise_data = "/home/bmoudjed/Documents/3 SSC acoustic meas project/Graphical interface project/" \ # "Data/AcousticNoise_data/20180107121600.aqa" -class AcousticDataLoader(): + +class AcousticDataLoader: def __init__(self, path_BS_raw_data: str): @@ -48,6 +49,9 @@ class AcousticDataLoader(): self._gain_rx = self._data_BS.RxGain self._gain_tx = self._data_BS.TxGain + print(self._r[0, :][1] - self._r[1, :][0]) + print(self._kt) + # self._snr = np.array([]) # self._snr_reshape = np.array([]) # self._time_snr = np.array([]) @@ -61,11 +65,16 @@ class AcousticDataLoader(): # print(np.where((self._time) == 155)[0][0]) # fig, ax = plt.subplots(nrows=1, ncols=1) - # ax.pcolormesh(self._time, self._r, (self._BS_raw_data[:, 1, :]), + # ax.pcolormesh(self._time[0, :2200], -self._r[0, :], (self._BS_raw_data[0, :, :2200]), # cmap='viridis', + # norm=LogNorm(vmin=1e-5, vmax=np.max(self._BS_raw_data[0, :, :2200]))) # , shading='gouraud') + # ax.pcolormesh(range(self._BS_raw_data.shape[2]), range(self._BS_raw_data.shape[0]), self._BS_raw_data[:, 1, :], cmap='viridis', # norm=LogNorm(vmin=1e-5, vmax=np.max(self._BS_raw_data[:, 0, :]))) # , shading='gouraud') - # # ax.pcolormesh(range(self._BS_raw_data.shape[2]), range(self._BS_raw_data.shape[0]), self._BS_raw_data[:, 1, :], cmap='viridis', - # # norm=LogNorm(vmin=1e-5, vmax=np.max(self._BS_raw_data[:, 0, :]))) # , shading='gouraud') + # plt.show() + + # --- Plot vertical profile for bottom detection --- + # fig2, ax2 = plt.subplots(nrows=1, ncols=1, layout="constrained") + # ax2.plot(self._BS_raw_data[0, :, 1], -self._r[0], "k.-") # plt.show() # fig, ax = plt.subplots(nrows=1, ncols=1) @@ -77,6 +86,7 @@ class AcousticDataLoader(): # self.reshape_BS_raw_cross_section() # self.reshape_r() # self.reshape_t() + # self.compute_r_2D() def reshape_BS_raw_cross_section(self): BS_raw_cross_section = np.reshape(self._BS_raw_data, @@ -96,7 +106,10 @@ class AcousticDataLoader(): return r def compute_r_2D(self): - r2D = np.repeat(self._r, self._time.size, axis=1) + r2D = np.zeros((self._freq.shape[0], self._r.shape[1], self._time.shape[1])) + for f, _ in enumerate(self._freq): + r2D[f, :, :] = np.repeat(np.transpose(self._r[0, :])[:, np.newaxis], self._time.shape[1], axis=1) + print(r2D.shape) return r2D def reshape_t(self): diff --git a/Model/acoustic_data_loader_UBSediFlow.py b/Model/acoustic_data_loader_UBSediFlow.py index c506788..95f38c9 100644 --- a/Model/acoustic_data_loader_UBSediFlow.py +++ b/Model/acoustic_data_loader_UBSediFlow.py @@ -1,10 +1,12 @@ -from Model.AquascatDataLoader import RawAquascatData import numpy as np import pandas as pd import datetime import matplotlib.pyplot as plt from matplotlib.colors import LogNorm, BoundaryNorm +from copy import deepcopy + +from scipy.signal import savgol_filter from Model.udt_extract.raw_extract import raw_extract # raw_20210519_102332.udt raw_20210520_135452.udt raw_20210525_092759.udt raw_20210525_080454.udt @@ -31,7 +33,7 @@ from Model.udt_extract.raw_extract import raw_extract # "raw_20210526_153310.udt" -class AcousticDataLoaderUBSediFlow(): +class AcousticDataLoaderUBSediFlow: def __init__(self, path_BS_raw_data: str): @@ -45,6 +47,10 @@ class AcousticDataLoaderUBSediFlow(): device_name, time_begin, time_end, param_us_dicts, data_us_dicts, data_dicts, settings_dict \ = raw_extract(self.path_BS_raw_data) + print(f"device_name : {device_name}") + print(f"time_begin : {time_begin}") + print(f"settings_dict : {settings_dict}") + # --- Date and Hour of measurements read on udt data file --- filename = self.path_BS_raw_data[-23:] date_and_time = datetime.datetime(year=int(filename[4:8]), @@ -63,28 +69,47 @@ class AcousticDataLoaderUBSediFlow(): self._time = np.array([[]]) self._time_snr = np.array([[]]) self._BS_raw_data = np.array([[[]]]) - self._SNR_data = np.array([[[]]]) + # self._SNR_data = np.array([[[]]]) time_len = [] time_snr_len = [] for config in param_us_dicts.keys(): - print("-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x") - print(f"config : {config} \n") + # print("-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x") + # print(f"config : {config} \n") for channel in param_us_dicts[config].keys(): print("-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x") - print(f"channel : {channel} \n") - # print(param_us_dicts[1][1]) + # print(f"channel : {channel} \n") + print(param_us_dicts[config][channel]) # print(data_us_dicts[config][channel]['echo_avg_profile']) # --- Frequencies --- self._freq = np.append(self._freq, param_us_dicts[config][channel]['f0']) # --- Depth for each frequencies --- - depth = [param_us_dicts[config][channel]['r_cell1'] * i + print("r_dcell : ", param_us_dicts[config][channel]['r_dcell']) + print("n_cell : ", param_us_dicts[config][channel]['n_cell']) + depth = [param_us_dicts[config][channel]['r_dcell'] * i for i in list(range(param_us_dicts[config][channel]['n_cell']))] + print(f"depth : {depth}") + print(f"lenght of depth : {len(depth)}") if self._r.shape[1] == 0: self._r = np.array([depth]) else: - self._r = np.append(self._r, [depth], axis=0) + if len(depth) == self._r.shape[1]: + print("Je suis là") + print(f"depth lenght : {len(depth)}") + print(f"r shape : {self._r.shape}") + self._r = np.append(self._r, np.array([depth]), axis=0) + print("C'est encore moi") + elif len(depth) < self._r.shape[1]: + print(f"depth lenght : {len(depth)}") + self._r = self._r[:, :len(depth)] + self._r = np.append(self._r, np.array([depth]), axis=0) + print(f"r shape : {self._r.shape}") + elif len(depth) > self._r.shape[1]: + print(f"depth lenght : {len(depth)}") + self._r = np.append(self._r, np.array([depth[:self._r.shape[1]]]), axis=0) + print(f"r shape : {self._r.shape}") + print(f"self._r : {self._r.shape}") # --- BS Time for each frequencies --- time = [[(t - data_us_dicts[config][channel]['echo_avg_profile']['time'][0]).total_seconds() @@ -92,72 +117,72 @@ class AcousticDataLoaderUBSediFlow(): time_len = np.append(time_len, len(time[0])) if len(time_len) == 1: - # print(f"1 time length : {len(time[0])}") + print(f"1 time length : {len(time[0])}") self._time = np.array(time) - # print(f"self._time.shape {self._time.shape}") + print(f"self._time.shape {self._time.shape}") elif self._time.shape[1] == len(time[0]): - # print(f"2 time length : {len(time[0])}") + print(f"2 time length : {len(time[0])}") self._time = np.append(self._time, time, axis=0) - # print(f"self._time.shape {self._time.shape}") + print(f"self._time.shape {self._time.shape}") elif self._time.shape[1] > len(time[0]): - # print(f"3 time length : {len(time[0])}") + print(f"3 time length : {len(time[0])}") # print(f"self._time.shape {self._time.shape}") # print([int(np.min(time_len)) + int(i) - 1 for i in range(1, int(np.max(time_len))-int(np.min(time_len))+1)]) self._time = np.delete(self._time, [int(np.min(time_len)) + int(i) - 1 for i in range(1, int(np.max(time_len))-int(np.min(time_len))+1)], axis=1) self._time = np.append(self._time, time, axis=0) - # print(f"self._time.shape {self._time.shape}") + print(f"self._time.shape {self._time.shape}") elif self._time.shape[1] < len(time[0]): - # print(f"4 time length : {len(time[0])}") + print(f"4 time length : {len(time[0])}") time = time[:int(np.max(time_len)) - (int(np.max(time_len)) - int(np.min(time_len)))] self._time = np.append(self._time, time, axis=0) - # print(f"self._time.shape {self._time.shape}") + print(f"self._time.shape {self._time.shape}") # --- SNR Time for each frequencies --- - time_snr = [[(t - data_us_dicts[config][channel]['snr_doppler_avg_profile']['time'][0]).total_seconds() - for t in data_us_dicts[config][channel]['snr_doppler_avg_profile']['time']]] - time_snr_len = np.append(time_snr_len, len(time_snr[0])) - - if len(time_snr_len) == 1: - # print(f"1 time length : {len(time[0])}") - self._time_snr = np.array(time_snr) - # print(f"self._time.shape {self._time.shape}") - elif self._time_snr.shape[1] == len(time_snr[0]): - # print(f"2 time length : {len(time[0])}") - self._time_snr = np.append(self._time_snr, time_snr, axis=0) - # print(f"self._time.shape {self._time.shape}") - elif self._time_snr.shape[1] > len(time_snr[0]): - # print(f"3 time length : {len(time[0])}") - # print(f"self._time.shape {self._time.shape}") - # print([int(np.min(time_len)) + int(i) - 1 for i in range(1, int(np.max(time_len))-int(np.min(time_len))+1)]) - self._time_snr = np.delete(self._time_snr, - [int(np.min(time_snr_len)) + int(i) - 1 for i in - range(1, int(np.max(time_snr_len)) - int(np.min(time_snr_len)) + 1)], - axis=1) - self._time_snr = np.append(self._time_snr, time_snr, axis=0) - # print(f"self._time.shape {self._time.shape}") - elif self._time_snr.shape[1] < len(time_snr[0]): - # print(f"4 time length : {len(time[0])}") - time_snr = time_snr[:int(np.max(time_snr_len)) - (int(np.max(time_snr_len)) - int(np.min(time_snr_len)))] - self._time_snr = np.append(self._time_snr, time_snr, axis=0) - # print(f"self._time.shape {self._time.shape}") + # time_snr = [[(t - data_us_dicts[config][channel]['snr_doppler_avg_profile']['time'][0]).total_seconds() + # for t in data_us_dicts[config][channel]['snr_doppler_avg_profile']['time']]] + # time_snr_len = np.append(time_snr_len, len(time_snr[0])) + # + # if len(time_snr_len) == 1: + # # print(f"1 time length : {len(time[0])}") + # self._time_snr = np.array(time_snr) + # # print(f"self._time.shape {self._time.shape}") + # elif self._time_snr.shape[1] == len(time_snr[0]): + # # print(f"2 time length : {len(time[0])}") + # self._time_snr = np.append(self._time_snr, time_snr, axis=0) + # # print(f"self._time.shape {self._time.shape}") + # elif self._time_snr.shape[1] > len(time_snr[0]): + # # print(f"3 time length : {len(time[0])}") + # # print(f"self._time.shape {self._time.shape}") + # # print([int(np.min(time_len)) + int(i) - 1 for i in range(1, int(np.max(time_len))-int(np.min(time_len))+1)]) + # self._time_snr = np.delete(self._time_snr, + # [int(np.min(time_snr_len)) + int(i) - 1 for i in + # range(1, int(np.max(time_snr_len)) - int(np.min(time_snr_len)) + 1)], + # axis=1) + # self._time_snr = np.append(self._time_snr, time_snr, axis=0) + # # print(f"self._time.shape {self._time.shape}") + # elif self._time_snr.shape[1] < len(time_snr[0]): + # # print(f"4 time length : {len(time[0])}") + # time_snr = time_snr[:int(np.max(time_snr_len)) - (int(np.max(time_snr_len)) - int(np.min(time_snr_len)))] + # self._time_snr = np.append(self._time_snr, time_snr, axis=0) + # # print(f"self._time.shape {self._time.shape}") # --- US Backscatter raw signal + SNR data --- BS_data = np.array([[]]) if config == 1: BS_data = np.array([data_us_dicts[config][channel]['echo_avg_profile']['data'][0]]) - print("BS_data shape ", BS_data.shape) + # print("BS_data shape ", BS_data.shape) for i in range(self._time.shape[1]): BS_data = np.append(BS_data, np.array([data_us_dicts[config][channel]['echo_avg_profile']['data'][i]]), axis=0) - print("BS_data shape ", BS_data.shape) + print("0. BS_data shape ", BS_data.shape) self._BS_raw_data = np.array([BS_data[:self._time.shape[1], :].transpose()]) - print("BS_raw_data shape ", self._BS_raw_data.shape) + print("0. BS_raw_data shape ", self._BS_raw_data.shape) # fig, ax = plt.subplots(nrows=1, ncols=1, layout="constrained") # pcm = ax.pcolormesh(list(range(self._BS_raw_data.shape[2])), list(range(self._BS_raw_data.shape[1])), @@ -169,28 +194,40 @@ class AcousticDataLoaderUBSediFlow(): else: BS_data = np.array([data_us_dicts[config][channel]['echo_avg_profile']['data'][0]]) - print("BS_data shape ", BS_data.shape) + # print("BS_data shape ", BS_data.shape) for i in range(self._time.shape[1]): BS_data = np.append(BS_data, np.array( [data_us_dicts[config][channel]['echo_avg_profile']['data'][i]]), axis=0) - print("BS_data shape ", BS_data.shape) + print("1. BS_data shape ", BS_data.shape) - if BS_data.shape[0] > self._BS_raw_data.shape[2]: +#----------------------------------------------------------------------------------------------------------------------- + # Ici il faut écrire les conditions sur les tailles selon r et selon time + # donc sur BS_data.shape[0] (time) et BS_data.shape[1] (depth) +#----------------------------------------------------------------------------------------------------------------------- + + # 1- time shape > BS data shape + # <=> data recorded with the frequency are longer than data recorded with the other lower frequencies + if (BS_data.shape[0] > self._BS_raw_data.shape[2]): self._BS_raw_data = np.append(self._BS_raw_data, np.array([BS_data[:self._BS_raw_data.shape[2], :].transpose()]), axis=0) + # 2- time shape < BS data shape + # <=> data recorded with the frequency are shorter than data recorded with the other lower frequencies elif BS_data.shape[0] < self._BS_raw_data.shape[2]: self._BS_raw_data = np.append(self._BS_raw_data[config-1, :, BS_data.shape[0]], np.array([BS_data.transpose()]), axis=0) + + # 3- time shape = BS data shape + # <=> data recorded with the frequency have the same duration than data recorded with the other lower frequency else: self._BS_raw_data = np.append(self._BS_raw_data, np.array([BS_data.transpose()]), axis=0) - print("BS_raw_data shape ", self._BS_raw_data.shape) + print("1. BS_raw_data shape ", self._BS_raw_data.shape) # if f == 0: # print(np.array(data_us_dicts[config][channel]['echo_avg_profile']['data'][0]).shape) @@ -298,11 +335,11 @@ class AcousticDataLoaderUBSediFlow(): # --- Plot Backscatter US data --- # fig, ax = plt.subplots(nrows=1, ncols=1, layout="constrained") - # # pcm = ax.pcolormesh(self._time[0, :], self._r[0, :], np.log(self._BS_raw_data[0, :, :]), - # # cmap='Blues')#, shading='gouraud') - # pcm = ax.pcolormesh(list(range(self._BS_raw_data.shape[2])), list(range(self._BS_raw_data.shape[1])), - # np.log(self._BS_raw_data[0, :, :]), - # cmap='Blues') # , shading='gouraud') + # pcm = ax.pcolormesh(self._time[0, :], -self._r[0, :], np.log(self._BS_raw_data[0, :, :]), + # cmap='Blues')#, shading='gouraud') + # # pcm = ax.pcolormesh(list(range(self._BS_raw_data.shape[2])), list(range(self._BS_raw_data.shape[1])), + # # np.log(self._BS_raw_data[0, :, :]), + # # cmap='Blues') # , shading='gouraud') # # norm=LogNorm(vmin=np.min(self._BS_raw_data[f, :, :]), vmax=np.max(self._BS_raw_data[f, :, :])), shading='gouraud') # # ax.pcolormesh(range(self._BS_raw_data.shape[2]), range(self._BS_raw_data.shape[0]), self._BS_raw_data[:, 1, :], cmap='viridis', # # norm=LogNorm(vmin=1e-5, vmax=np.max(self._BS_raw_data[:, 0, :]))) # , shading='gouraud') @@ -317,12 +354,38 @@ class AcousticDataLoaderUBSediFlow(): # # pcm = ax[f].pcolormesh(list(range(self._BS_raw_data.shape[2])), list(range(self._BS_raw_data.shape[1])), # # np.log(self._BS_raw_data[f, :, :]), # # cmap='Blues', shading='gouraud') - # pcm = ax[f].pcolormesh(self._time[f, :], self._r[f, :], np.log(self._BS_raw_data[f, :, :]), - # cmap='viridis', shading='gouraud') + # pcm = ax[f].pcolormesh(self._time[f, 50:247], -self._r[f, :], np.log(self._BS_raw_data[f, :, 50:247]), + # cmap='Blues')#, shading='gouraud') # # norm=LogNorm(vmin=np.min(self._BS_raw_data[f, :, :]), vmax=np.max(self._BS_raw_data[f, :, :])), shading='gouraud') # # ax.pcolormesh(range(self._BS_raw_data.shape[2]), range(self._BS_raw_data.shape[0]), self._BS_raw_data[:, 1, :], cmap='viridis', # # norm=LogNorm(vmin=1e-5, vmax=np.max(self._BS_raw_data[:, 0, :]))) # , shading='gouraud') # fig.colorbar(pcm, ax=ax[:], shrink=1, location='right') + # # plt.show() + # + # # --- Smooth value with savgol_filter --- + # BS_smooth = deepcopy(self._BS_raw_data[0, :, :]) + # for k in range(self._time[0, :].shape[0]): + # BS_smooth[:, k] = savgol_filter(BS_smooth[:, k], 10, 2) + # + # fig1, ax1 = plt.subplots(nrows=1, ncols=1, layout="constrained") + # pcm1 = ax1.pcolormesh(self._time[0, :], -self._r[0, :], np.log(BS_smooth[:, :]), cmap='Blues') + # fig1.colorbar(pcm1, ax=ax1, shrink=1, location='right') + # + # # --- Plot vertical profile for bottom detection --- + # n = 60 + # t0 = 200 + # t1 = np.where(np.abs(self._time[0, :] - t0) == np.nanmin(np.abs(self._time[0, :] - t0)))[0][0] + # # print(np.abs(self._time[0, :] - 200)) + # # print(f"x0 = {x0}") + # r1 = 98 + # r2 = 150 + # fig2, ax2 = plt.subplots(nrows=1, ncols=n, layout="constrained") + # for i in range(n): + # ax2[i].plot(self._BS_raw_data[0, r1:r2, t1+i], -self._r[0, r1:r2], 'b') + # ax2[i].plot(BS_smooth[r1:r2, t1+i], -self._r[0, r1:r2], 'r') + # ax2[i].set_xticks([]) + # if i != 0: + # ax2[i].set_yticks([]) # plt.show() # --- Plot SNR data --- @@ -373,6 +436,7 @@ class AcousticDataLoaderUBSediFlow(): # self.reshape_BS_raw_cross_section() # self.reshape_r() # self.reshape_t() + # self.compute_r_2D() # Lecture du fichier excel @@ -425,6 +489,13 @@ class AcousticDataLoaderUBSediFlow(): # print(r.shape) return r + def compute_r_2D(self): + r2D = np.zeros((self._freq.shape[0], self._r.shape[1], self._time.shape[1])) + for f, _ in enumerate(self._freq): + r2D[f, :, :] = np.repeat(np.transpose(self._r[0, :])[:, np.newaxis], self._time.shape[1], axis=1) + print("r2D.shape ", r2D.shape) + return r2D + # def compute_r_2D(self): # r2D = np.repeat(self._r, self._time.size, axis=1) # return r2D @@ -443,6 +514,12 @@ class AcousticDataLoaderUBSediFlow(): # print(t.shape) return t + def detect_bottom(self): + rmin = 2.5 + rmax = 3.5 + + + # def concatenate_data(self): # self.reshape_BS_raw_cross_section() diff --git a/View/acoustic_data_tab.py b/View/acoustic_data_tab.py index 058a41b..852a9dc 100644 --- a/View/acoustic_data_tab.py +++ b/View/acoustic_data_tab.py @@ -22,6 +22,8 @@ from copy import deepcopy import locale locale.setlocale(locale.LC_ALL, '') +from scipy.signal import savgol_filter + # import Translation.biblio_string as bs import Translation.constant_string as cs @@ -193,20 +195,27 @@ class AcousticDataTab(QWidget): self.gridLayout_goupbox_info = QGridLayout(self.groupbox_info) + # --- Information for Aquascat --- + self.label_profiles = QLabel() self.label_profiles_per_sec = QLabel() - self.label_cells = QLabel() - self.label_cell_size = QLabel() - self.label_pulse_length = QLabel() - self.label_pings_per_sec = QLabel() - self.label_pings_per_profile = QLabel() + self.label_cells = QLabel() # n_cell in UBSediFlow parameters + self.label_cell_size = QLabel() # r_em in UBSediFlow parameters + self.label_pulse_length = QLabel() # n_p / PRF with n_p = n_ech, nb of pulses to calculate one instantaneous profile + self.label_pings_per_sec = QLabel() # PRF in UBSediFlow parameters + self.label_pings_per_profile = QLabel() # n_profile/n_avg in UBSediFlow parameters self.label_freq = QLabel() self.label_kt = QLabel() - self.label_rx = QLabel() - self.label_tx = QLabel() + self.label_rx = QLabel() # a0 in UBSediFlow parameters + self.label_tx = QLabel() # a1 in UBSediFlow parameters - # self.label_to_do = QLabel() - # self.label_to_do.setText("UBSediFlow data : to do for Oct. 20th") + # --- Information for UBSediFlow --- + self.label_tr_out = QLabel() + self.label_tr_out.setText("Channel : ") + self.label_r_cell1 = QLabel() + self.label_r_cell1.setText("1st cell size : ") + self.label_r_dcell = QLabel() + self.label_r_dcell.setText("Inter-cell distance : ") # self.groupbox_measurement_information_Aquascat() self.combobox_ABS_system_choice.currentTextChanged.connect(self.ABS_system_choice) @@ -435,8 +444,10 @@ class AcousticDataTab(QWidget): self.label_from_bathy.setText("From - ") self.gridlayout_compute_bathymetry.addWidget(self.label_from_bathy, 0, 1, 1, 1) - self.spinbox_depth_min = QSpinBox() + # self.spinbox_depth_min = QSpinBox() + self.spinbox_depth_min = QDoubleSpinBox() self.spinbox_depth_min.setRange(0, 9999) + self.spinbox_depth_min.setDecimals(2) self.gridlayout_compute_bathymetry.addWidget(self.spinbox_depth_min, 0, 2, 1, 1) self.label_depth_min_unit = QLabel() @@ -447,8 +458,10 @@ class AcousticDataTab(QWidget): self.label_to_bathy.setText("to - ") self.gridlayout_compute_bathymetry.addWidget(self.label_to_bathy, 0, 4, 1, 1) - self.spinbox_depth_max = QSpinBox() + # self.spinbox_depth_max = QSpinBox() + self.spinbox_depth_max = QDoubleSpinBox() self.spinbox_depth_max.setRange(0, 99999) + self.spinbox_depth_max.setDecimals(2) self.gridlayout_compute_bathymetry.addWidget(self.spinbox_depth_max, 0, 5, 1, 1) self.label_depth_max_unit = QLabel() @@ -681,8 +694,8 @@ class AcousticDataTab(QWidget): self.WindowNoiseLevelTailAveragedProfile().show() def open_dialog_box(self): - print(self.combobox_ABS_system_choice.currentText()) - print(self.sender().objectName()) + # print(self.combobox_ABS_system_choice.currentText()) + # print(self.sender().objectName()) # --- Open dialog box + choice directory and select file --- if self.combobox_ABS_system_choice.currentIndex() == 0: @@ -698,12 +711,12 @@ class AcousticDataTab(QWidget): "Aquascat file (*.aqa)") dir_name = path.dirname(filename[0]) name = path.basename(filename[0]) - print(dir_name, name) + # print(dir_name, name) elif self.combobox_ABS_system_choice.currentIndex() == 2: filename = QFileDialog.getOpenFileName(self, "Open file", "", "UBSediFlow file (*.udt)") dir_name = path.dirname(filename[0]) name = path.basename(filename[0]) - print(dir_name, name) + print(f"dir name : {dir_name} & file name : {name}") # --- Fill lineEdit with path and file names + load acoustic data --- @@ -738,7 +751,9 @@ class AcousticDataTab(QWidget): self.combobox_freq_choice.addItems([f for f in stg.freq_text]) if self.sender().objectName() == "pushbutton_noise_file": + print("--- 0. Je suis dans le push button noise file ---") try: + print("--- 1. Je suis dans le push button noise file ---") stg.path_BS_noise_data = dir_name stg.filename_BS_noise_data = name print("dir_name ", stg.path_BS_noise_data) @@ -764,6 +779,7 @@ class AcousticDataTab(QWidget): def load_BS_acoustic_raw_data(self): if self.combobox_ABS_system_choice.currentIndex() == 1: acoustic_data = AcousticDataLoader(stg.path_BS_raw_data + "/" + stg.filename_BS_raw_data) + stg.ABS_name = self.combobox_ABS_system_choice.currentText() stg.BS_raw_data = acoustic_data._BS_raw_data stg.BS_raw_data_reshape = acoustic_data.reshape_BS_raw_cross_section() stg.r = acoustic_data._r @@ -787,24 +803,27 @@ class AcousticDataTab(QWidget): stg.gain_tx = acoustic_data._gain_tx elif self.combobox_ABS_system_choice.currentIndex() == 2: acoustic_data = AcousticDataLoaderUBSediFlow(stg.path_BS_raw_data + "/" + stg.filename_BS_raw_data) + stg.ABS_name = self.combobox_ABS_system_choice.currentText() stg.date = acoustic_data._date stg.hour = acoustic_data._hour stg.freq = acoustic_data._freq stg.time = acoustic_data._time stg.r = acoustic_data._r + stg.r_2D = acoustic_data.compute_r_2D() stg.freq_text = acoustic_data._freq_text stg.BS_raw_data = acoustic_data._BS_raw_data stg.BS_raw_data_reshape = acoustic_data.reshape_BS_raw_cross_section() stg.r_reshape = acoustic_data.reshape_r() stg.time_reshape = acoustic_data.reshape_t() - stg.snr = acoustic_data._SNR_data + # stg.SNR_data = acoustic_data._SNR_data # stg.snr_reshape = acoustic_data.reshape_SNR_data() + # print(f"r = {stg.r}") def load_noise_data_and_compute_SNR(self): if self.combobox_ABS_system_choice.currentIndex() == 1: noise_data = AcousticDataLoader(stg.path_BS_noise_data + "/" + stg.filename_BS_noise_data) - # stg.BS_noise_data = noise_data._BS_raw_data + stg.BS_noise_raw_data = noise_data._BS_raw_data stg.date_noise = noise_data._date stg.hour_noise = noise_data._hour stg.time_snr = stg.time @@ -812,20 +831,25 @@ class AcousticDataTab(QWidget): print(stg.time_snr.shape) noise = np.zeros(stg.BS_raw_data.shape) for f, _ in enumerate(noise_data._freq): - noise[f, :, :] = np.mean(noise_data._BS_raw_data[f, :, :], axis=(0, 1)) - stg.BS_noise_data = noise - stg.snr = np.divide((stg.BS_raw_data - stg.BS_noise_data) ** 2, stg.BS_noise_data ** 2) - stg.snr_reshape = np.reshape(stg.snr, (stg.r.shape[1] * stg.time.shape[1], stg.freq.shape[0]), order="F") + noise[f, :, :] = np.mean(stg.BS_noise_raw_data[f, :, :], axis=(0, 1)) + stg.BS_noise_averaged_data = noise + stg.SNR_data = np.divide((stg.BS_raw_data - stg.BS_noise_averaged_data) ** 2, stg.BS_noise_averaged_data ** 2) + stg.SNR_reshape = np.reshape(stg.SNR_data, (stg.r.shape[1] * stg.time.shape[1], stg.freq.shape[0]), order="F") elif self.combobox_ABS_system_choice.currentIndex() == 2: noise_data = AcousticDataLoaderUBSediFlow(stg.path_BS_noise_data + "/" + stg.filename_BS_noise_data) + stg.BS_noise_raw_data = noise_data._BS_raw_data + print(f"BS noise raw data : {stg.BS_noise_raw_data}") stg.date_noise = noise_data._date + print(f"date noise : {stg.date_noise}") stg.hour_noise = noise_data._hour + print(f"hour noise : {stg.hour_noise}") stg.time_snr = noise_data._time_snr stg.time_snr_reshape = noise_data.reshape_t_snr() - stg.snr = noise_data._SNR_data - stg.snr_reshape = noise_data.reshape_SNR_data() + print(f"BS shape : {stg.BS_noise_raw_data.shape}") + # stg.SNR_data = noise_data._SNR_data + # stg.SNR_reshape = noise_data.reshape_SNR_data() def fill_measurements_information_groupbox(self): if self.combobox_ABS_system_choice.currentIndex() == 1: @@ -887,7 +911,7 @@ class AcousticDataTab(QWidget): # elif self.combobox_ABS_system_choice.currentIndex() == 1: if ((self.lineEdit_acoustic_file.text()) and (self.lineEdit_noise_file.text())): stg.DataFrame_acoustic = pd.DataFrame( - np.concatenate((stg.time_reshape, stg.BS_raw_data_reshape, stg.time_snr_reshape, stg.snr_reshape), axis=1), + np.concatenate((stg.time_reshape, stg.BS_raw_data_reshape, stg.time_snr_reshape, stg.SNR_reshape), axis=1), columns=list(map(str, ["Time BS - " + f for f in stg.freq_text] + ["BS - " + f for f in stg.freq_text] + ["Time SNR - " + f for f in stg.freq_text] + @@ -993,10 +1017,17 @@ class AcousticDataTab(QWidget): print(f"tmin {stg.tmin}") print(f"tmax {stg.tmax}") - pcm = self.axis_BS[f].pcolormesh( - stg.time[f, int(stg.tmin[f]):int(stg.tmax[f])], -stg.r[f, :], - np.log(stg.BS_raw_data[f, :, int(stg.tmin[f]):int(stg.tmax[f])]), - cmap='Blues')#, norm=LogNorm(vmin=val_min, vmax=val_max)) + if self.combobox_ABS_system_choice.currentIndex() == 1: + pcm = self.axis_BS[f].pcolormesh(stg.time[f, int(stg.tmin[f]):int(stg.tmax[f])], + -stg.r[f, :], + stg.BS_raw_data[f, :, int(stg.tmin[f]):int(stg.tmax[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[f, int(stg.tmin[f]):int(stg.tmax[f])], + -stg.r[f, :], + np.log(stg.BS_raw_data[f, :, int(stg.tmin[f]):int(stg.tmax[f])]), + cmap='Blues') self.axis_BS[f].text(1, .70, stg.freq_text[f], fontsize=14, fontweight='bold', fontname="Ubuntu", c="black", alpha=0.5, @@ -1025,7 +1056,7 @@ class AcousticDataTab(QWidget): # --- Backscatter acoustic signal is recorded for next tab --- - stg.BS_data = np.array([[[]]]) + stg.BS_cross_section = np.array([[[]]]) stg.t = np.array([[]]) for f, _ in enumerate(stg.freq): @@ -1038,17 +1069,17 @@ class AcousticDataTab(QWidget): print("stg.tmin[f] ", stg.tmin[f]) print("stg.tmax[f] ", stg.tmax[f]) print("shape of BS_raw_data ", np.array([stg.BS_raw_data[f, :, int(stg.tmin[f]):int(stg.tmax[f])]]).shape) - print("BS_data shape ", stg.BS_data.shape) - if stg.BS_data.shape[2] == 0: - stg.BS_data = np.array([stg.BS_raw_data[f, :, int(stg.tmin[f]):int(stg.tmax[f])]]) + print("BS_data shape ", stg.BS_cross_section.shape) + if stg.BS_cross_section.shape[2] == 0: + stg.BS_cross_section = np.array([stg.BS_raw_data[f, :, int(stg.tmin[f]):int(stg.tmax[f])]]) else: - stg.BS_data = np.append(stg.BS_data, np.array([stg.BS_raw_data[f, :, int(stg.tmin[f]):int(stg.tmax[f])]]), axis=0) + stg.BS_cross_section = np.append(stg.BS_cross_section, np.array([stg.BS_raw_data[f, :, int(stg.tmin[f]):int(stg.tmax[f])]]), axis=0) - # stg.BS_data = np.stack(np.array([stg.BS_raw_data[f, :, int(stg.tmin[f]):int(stg.tmax[f])]]), axis=0) - # stg.BS_data = np.append(stg.BS_data, np.array([stg.BS_raw_data[f, :, int(stg.tmin[f]):int(stg.tmax[f])]]), axis=2) - print("stg.BS_data.shape ", stg.BS_data.shape) - print("stg.BS_data.size ", stg.BS_data.size) + # stg.BS_cross_section = np.stack(np.array([stg.BS_raw_data[f, :, int(stg.tmin[f]):int(stg.tmax[f])]]), axis=0) + # stg.BS_cross_section = np.append(stg.BS_cross_section, np.array([stg.BS_raw_data[f, :, int(stg.tmin[f]):int(stg.tmax[f])]]), axis=2) + print("stg.BS_cross_section.shape ", stg.BS_cross_section.shape) + print("stg.BS_cross_section.size ", stg.BS_cross_section.size) print("stg.time shape ", stg.time.shape) print("stg.t shape ", stg.t.shape) if stg.t.shape[1] == 0: @@ -1057,21 +1088,27 @@ class AcousticDataTab(QWidget): stg.t = np.append(stg.t, np.array([stg.time[f, int(stg.tmin[f]):int(stg.tmax[f])]]), axis=0) # stg.t = np.append(stg.t, np.array([stg.time[f, int(stg.tmin[f]):int(stg.tmax[f])]]), axis=0) print("stg.t shape ", stg.t.shape) + # print(f"stg.t : {stg.t}") # stg.r_2D = stg.r_2D[:, np.where(np.round(stg.time, 2) == self.spinbox_tmin.value())[0][0]: # np.where(np.round(stg.time, 2) == self.spinbox_tmax.value())[0][0]] # print("stg.r shape ", stg.r_2D.shape) self.axis_BS[f].cla() - val_min = np.min(stg.BS_data[f, :, :]) - val_max = np.max(stg.BS_data[f, :, :]) + val_min = np.min(stg.BS_cross_section[f, :, :]) + val_max = np.max(stg.BS_cross_section[f, :, :]) if val_min == 0: val_min = 1e-5 # print("stg.t[f, :].shape ", stg.t[f]) # print("stg.r[f, :].shape ", stg.r[f, :]) - pcm = self.axis_BS[f].pcolormesh(stg.t[f, :], -stg.r[f, :], np.log(stg.BS_data[f, :, :]), - cmap='Blues')#, norm=LogNorm(vmin=val_min, vmax=val_max)) + + if self.combobox_ABS_system_choice.currentIndex() == 1: + pcm = self.axis_BS[f].pcolormesh(stg.t[f, :], -stg.r[f, :], stg.BS_cross_section[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.t[f, :], -stg.r[f, :], np.log(stg.BS_cross_section[f, :, :]), + cmap='Blues') self.axis_BS[f].text(1, .70, stg.freq_text[f], fontsize=14, fontweight='bold', fontname="Ubuntu", c="black", alpha=0.5, @@ -1179,9 +1216,9 @@ class AcousticDataTab(QWidget): y = np.append(y, np.array([y0]), axis=0) print(f"x : {x.shape}, y : {y.shape}") - val_min = np.nanmin(abs(stg.snr[f, :, :])) + val_min = np.nanmin(abs(stg.SNR_data[f, :, :])) # print(f"val_min = {val_min}") - val_max = np.nanmax(abs(stg.snr[f, :, :])) + val_max = np.nanmax(abs(stg.SNR_data[f, :, :])) # print(f"val_max = {val_max}") if int(val_min) == 0: val_min = 1e-5 @@ -1198,11 +1235,11 @@ class AcousticDataTab(QWidget): if self.combobox_ABS_system_choice.currentIndex() == 1: cf = self.axis_SNR[f].contourf(x[f, :, :], -y[f, :, :], - stg.snr[f, :, :], levels, cmap='gist_rainbow', norm=norm) + stg.SNR_data[f, :, :], levels, cmap='gist_rainbow', norm=norm) elif self.combobox_ABS_system_choice.currentIndex() == 2: - cf = self.axis_SNR[f].contourf(x[f, :, :], -y[f, :, :], stg.snr[f, :, :])#, levels, cmap='gist_rainbow', norm=norm) + cf = self.axis_SNR[f].contourf(x[f, :, :], -y[f, :, :], stg.SNR_data[f, :, :])#, levels, cmap='gist_rainbow', norm=norm) self.axis_SNR[f].text(1, .70, stg.freq_text[f], fontsize=14, fontweight='bold', fontname="Ubuntu", c="black", alpha=0.5, @@ -1232,24 +1269,24 @@ class AcousticDataTab(QWidget): stg.tmin_snr = np.array([]) stg.tmax_snr = np.array([]) - stg.SNR_data = np.array([[[]]]) + stg.SNR_cross_section = np.array([[[]]]) stg.t_snr = np.array([[]]) x = np.array([[[]]]) y = np.array([[[]]]) - print(f"x : {x.shape}, y : {y.shape}") + # print(f"x : {x.shape}, y : {y.shape}") for f, _ in enumerate(stg.freq): if x.shape[2] == 0: x, y = np.meshgrid(stg.time_snr[f, :], stg.r[f, :]) x = np.array([x]) y = np.array([y]) - print(f"x : {x.shape}, y : {y.shape}") + # print(f"x : {x.shape}, y : {y.shape}") else: x0, y0 = np.meshgrid(stg.time_snr[f, :], stg.r[f, :]) x = np.append(x, np.array([x0]), axis=0) y = np.append(y, np.array([y0]), axis=0) - print(f"x : {x.shape}, y : {y.shape}") + # print(f"x : {x.shape}, y : {y.shape}") # print(np.abs(np.round(stg.time_snr[f, :], 2) - self.spinbox_tmin.value())) # print(np.where(np.abs(np.round(stg.time_snr[f, :], 2) - self.spinbox_tmin.value()) == @@ -1269,25 +1306,25 @@ class AcousticDataTab(QWidget): 0]) ) - print("stg.tmin[f] ", stg.tmin_snr[f]) - print("stg.tmax[f] ", stg.tmax_snr[f]) + # print("stg.tmin[f] ", stg.tmin_snr[f]) + # print("stg.tmax[f] ", stg.tmax_snr[f]) - if stg.SNR_data.shape[2] == 0: - stg.SNR_data = np.array([stg.snr[f, :, int(stg.tmin_snr[f]):int(stg.tmax_snr[f])]]) + if stg.SNR_cross_section.shape[2] == 0: + stg.SNR_cross_section = np.array([stg.SNR_data[f, :, int(stg.tmin_snr[f]):int(stg.tmax_snr[f])]]) else: - stg.SNR_data = np.append(stg.SNR_data, - np.array([stg.snr[f, :, int(stg.tmin_snr[f]):int(stg.tmax_snr[f])]]), + stg.SNR_cross_section = np.append(stg.SNR_cross_section, + np.array([stg.SNR_data[f, :, int(stg.tmin_snr[f]):int(stg.tmax_snr[f])]]), axis=0) - # stg.BS_data = np.stack(np.array([stg.BS_raw_data[f, :, int(stg.tmin[f]):int(stg.tmax[f])]]), axis=0) - # stg.BS_data = np.append(stg.BS_data, np.array([stg.BS_raw_data[f, :, int(stg.tmin[f]):int(stg.tmax[f])]]), axis=2) + # stg.BS_cross_section = np.stack(np.array([stg.BS_raw_data[f, :, int(stg.tmin[f]):int(stg.tmax[f])]]), axis=0) + # stg.BS_cross_section = np.append(stg.BS_cross_section, np.array([stg.BS_raw_data[f, :, int(stg.tmin[f]):int(stg.tmax[f])]]), axis=2) if stg.t_snr.shape[1] == 0: stg.t_snr = np.array([stg.time_snr[f, int(stg.tmin_snr[f]):int(stg.tmax_snr[f])]]) else: stg.t_snr = np.append(stg.t_snr, np.array([stg.time_snr[f, int(stg.tmin_snr[f]):int(stg.tmax_snr[f])]]), axis=0) # stg.t = np.append(stg.t, np.array([stg.time[f, int(stg.tmin[f]):int(stg.tmax[f])]]), axis=0) - print("stg.t shape ", stg.t_snr.shape) + # print("stg.t shape ", stg.t_snr.shape) self.axis_SNR[f].cla() @@ -1318,9 +1355,9 @@ class AcousticDataTab(QWidget): # # elif self.combobox_ABS_system_choice.currentIndex() == 2: - val_min = np.nanmin(abs(stg.snr[f, :, :])) + val_min = np.nanmin(abs(stg.SNR_data[f, :, :])) # print(f"val_min = {val_min}") - val_max = np.nanmax(abs(stg.snr[f, :, :])) + val_max = np.nanmax(abs(stg.SNR_data[f, :, :])) # print(f"val_max = {val_max}") if int(val_min) == 0: val_min = 1e-5 @@ -1339,14 +1376,14 @@ class AcousticDataTab(QWidget): cf = self.axis_SNR[f].contourf(x[f, :, int(stg.tmin_snr[f]):int(stg.tmax_snr[f])], -y[f, :, int(stg.tmin_snr[f]):int(stg.tmax_snr[f])], - stg.snr[f, :, int(stg.tmin_snr[f]):int(stg.tmax_snr[f])], + stg.SNR_data[f, :, int(stg.tmin_snr[f]):int(stg.tmax_snr[f])], levels, cmap='gist_rainbow', norm=norm) elif self.combobox_ABS_system_choice.currentIndex() == 2: cf = self.axis_SNR[f].contourf(x[f, :, int(stg.tmin_snr[f]):int(stg.tmax_snr[f])], -y[f, :, int(stg.tmin_snr[f]):int(stg.tmax_snr[f])], - stg.snr[f, :, int(stg.tmin_snr[f]):int(stg.tmax_snr[f])]) # , levels, cmap='gist_rainbow', norm=norm) + stg.SNR_data[f, :, int(stg.tmin_snr[f]):int(stg.tmax_snr[f])]) # , levels, cmap='gist_rainbow', norm=norm) self.axis_SNR[f].text(1, .70, stg.freq_text[f], fontsize=14, fontweight='bold', fontname="Ubuntu", c="black", alpha=0.5, @@ -1392,27 +1429,52 @@ class AcousticDataTab(QWidget): stg.freq_bottom_detection = self.combobox_freq_choice.currentIndex() # Selecting the range in which we look for the bottom reflection - rmin = np.int(self.spinbox_depth_min.text()) - rmax = np.int(self.spinbox_depth_max.text()) + rmin = np.float32(self.spinbox_depth_min.text().replace(",", ".")) + rmax = np.float32(self.spinbox_depth_max.text().replace(",", ".")) + # print(f"rmin = {rmin}") + # print(f"rmax = {rmax}") # empty result arrays - r_bottom = np.zeros(stg.nb_profiles) - val_bottom = np.zeros(stg.nb_profiles) + # r_bottom = np.zeros(stg.nb_profiles) + # val_bottom = np.zeros(stg.nb_profiles) + r_bottom = np.zeros(stg.t.shape[1]) + val_bottom = np.zeros(stg.t.shape[1]) r_bottom_ind = [] + # print(f"r_bottom shape with zeros : {r_bottom.shape}") + + BS_smooth = deepcopy(stg.BS_raw_data[self.combobox_freq_choice.currentIndex(), :, :]) + # print(f"BS_smooth shape : {BS_smooth.shape}") + for k in range(stg.time.shape[1]): + BS_smooth[:, k] = savgol_filter(BS_smooth[:, k], 10, 2) + + # fig1, ax1 = plt.subplots(nrows=1, ncols=1, layout="constrained") + # pcm1 = ax1.pcolormesh(stg.time[0, :], -stg.r[0, :], np.log(BS_smooth[:, :]), cmap='Blues') + # fig1.colorbar(pcm1, ax=ax1, shrink=1, location='right') + # plt.show() + # ----------- Detecting the bottom ------------- - for d in range(stg.nb_profiles): + # for d in range(stg.nb_profiles): + for d in range(stg.t.shape[1]): # Index of the range where we look for the peak + # print(f"self.combobox_freq_choice.currentIndex() : {self.combobox_freq_choice.currentIndex()}") + # print(f"r = {stg.r}") ind_min = np.where(stg.r[int(self.combobox_freq_choice.currentIndex()), :] >= rmin)[0][0] ind_max = np.where(stg.r[int(self.combobox_freq_choice.currentIndex()), :] <= rmax)[0][-1] + # print(f"ind_min : {ind_min}") + # print(f"ind_max : {ind_max}") # Getting the peak try: - val_bottom[d] = np.nanmax(stg.BS_raw_data[self.combobox_freq_choice.currentIndex(), ind_min:ind_max, d]) + # val_bottom[d] = np.nanmax((stg.BS_raw_data[self.combobox_freq_choice.currentIndex(), ind_min:ind_max, d])) + val_bottom[d] = np.nanmax(BS_smooth[ind_min:ind_max, d]) + # print('---------------------------------------------------') + # print(f"d = {d}") + # print("stg.BS_raw_data[ind_min:ind_max] : ", stg.BS_raw_data[self.combobox_freq_choice.currentIndex(), ind_min:ind_max, d]) except ValueError as e: msgBox = QMessageBox() msgBox.setWindowTitle("Detect bottom Error") msgBox.setIcon(QMessageBox.Warning) - msgBox.setText(f"{e} : maximum value of section bottom is not found. \n " + 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() @@ -1420,26 +1482,51 @@ class AcousticDataTab(QWidget): break #msgBox.close() else: # Getting the range cell of the peak - ind_bottom = np.where(stg.BS_raw_data[self.combobox_freq_choice.currentIndex(), ind_min:ind_max, d] - == val_bottom[d])[0][0] + # ind_bottom = np.where((stg.BS_raw_data[self.combobox_freq_choice.currentIndex(), ind_min:ind_max, d]) + # == val_bottom[d])[0][0] + 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.r[self.combobox_freq_choice.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] - locale.atof(self.doublespinbox_next_cell.text()) - rmax = r_bottom[d] + locale.atof(self.doublespinbox_next_cell.text()) + # rmin = r_bottom[d] - locale.atof(self.doublespinbox_next_cell.text()) + # rmax = r_bottom[d] + locale.atof(self.doublespinbox_next_cell.text()) + rmin = r_bottom[d] - np.float32(self.doublespinbox_next_cell.text().replace(",", ".")) + rmax = r_bottom[d] + np.float32(self.doublespinbox_next_cell.text().replace(",", ".")) - BS_section_bottom = np.zeros((stg.r.shape[1], stg.time.shape[1])) + # --- Plot vertical profile for bottom detection --- + # n = 60 + # t0 = 200 + # t1 = np.where(np.abs(stg.time[0, :] - t0) == np.nanmin(np.abs(stg.time[0, :] - t0)))[0][0] + # # print(np.abs(self._time[0, :] - 200)) + # # print(f"x0 = {x0}") + # r1 = 98 + # r2 = 150 + # fig2, ax2 = plt.subplots(nrows=1, ncols=n, layout="constrained") + # for i in range(n): + # ax2[i].plot(stg.BS_raw_data[self.combobox_freq_choice.currentIndex(), r1:r2, t1 + i], + # -stg.r[0, r1:r2], 'b') + # ax2[i].plot(BS_smooth[r1:r2, t1 + i], -stg.r[0, r1:r2], 'r') + # ax2[i].scatter(val_bottom[i], -r_bottom[i], marker="o", fc="black", s=12) + # ax2[i].set_xticks([]) + # if i != 0: + # ax2[i].set_yticks([]) + # plt.show() + + + # print(f"r_bootom shape : {r_bottom.shape}") + BS_section_bottom = np.zeros((stg.r.shape[1], stg.t.shape[1])) for i in range(BS_section_bottom.shape[0]): try: + # print(f"r_bottom_ind : {r_bottom_ind}") 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"{e} : maximum value of section bottom is not found. \n " + 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() @@ -1452,10 +1539,12 @@ class AcousticDataTab(QWidget): # np.where(np.round(stg.time, 2) == self.spinbox_tmax.value())[0][0]] # stg.val_bottom = val_bottom[np.where(np.round(stg.time, 2) == self.spinbox_tmin.value())[0][0]: # np.where(np.round(stg.time, 2) == self.spinbox_tmax.value())[0][0]] - stg.r_bottom = r_bottom[int(stg.tmin[self.combobox_freq_choice.currentIndex()]): - int(stg.tmax[self.combobox_freq_choice.currentIndex()])] - stg.val_bottom = val_bottom[int(stg.tmin[self.combobox_freq_choice.currentIndex()]): - int(stg.tmax[self.combobox_freq_choice.currentIndex()])] + stg.r_bottom = r_bottom#[int(stg.tmin[self.combobox_freq_choice.currentIndex()]): + # int(stg.tmax[self.combobox_freq_choice.currentIndex()])] + stg.val_bottom = val_bottom#[int(stg.tmin[self.combobox_freq_choice.currentIndex()]): + # int(stg.tmax[self.combobox_freq_choice.currentIndex()])] + + # --- Plot transect BS with bathymetry --- for f, _ in enumerate(stg.freq): @@ -1475,8 +1564,12 @@ class AcousticDataTab(QWidget): # np.where(np.round(stg.time, 2) == self.spinbox_tmax.value())[0][0]]), # cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max)) - pcm = self.axis_BS[f].pcolormesh(stg.t[f, :], -stg.r[f, :], stg.BS_data[f, :, :], - cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max)) + if self.combobox_ABS_system_choice.currentIndex() == 1: + pcm = self.axis_BS[f].pcolormesh(stg.t[f, :], -stg.r[f, :], stg.BS_cross_section[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.t[f, :], -stg.r[f, :], np.log(stg.BS_cross_section[f, :, :]), + cmap='Blues') # self.axis_BS[f].plot( # stg.time[np.where(np.round(stg.time, 2) == self.spinbox_tmin.value())[0][0]: @@ -1485,6 +1578,8 @@ class AcousticDataTab(QWidget): # np.where(np.round(stg.time, 2) == self.spinbox_tmax.value())[0][0]], # color='black', linewidth=1, linestyle="solid") + # print("stg.t[self.combobox_freq_choice.currentIndex(), :] : ", stg.t[self.combobox_freq_choice.currentIndex(), :].shape) + # print("-stg.r_bottom : ", stg.r_bottom.shape) self.axis_BS[f].plot(stg.t[self.combobox_freq_choice.currentIndex(), :], -stg.r_bottom, color='black', linewidth=1, linestyle="solid") @@ -1504,7 +1599,7 @@ class AcousticDataTab(QWidget): x = np.array([[[]]]) y = np.array([[[]]]) - print(f"x : {x.shape}, y : {y.shape}") + # print(f"x : {x.shape}, y : {y.shape}") for f, _ in enumerate(stg.freq): @@ -1512,17 +1607,17 @@ class AcousticDataTab(QWidget): x, y = np.meshgrid(stg.time_snr[f, :], stg.r[f, :]) x = np.array([x]) y = np.array([y]) - print(f"x : {x.shape}, y : {y.shape}") + # print(f"x : {x.shape}, y : {y.shape}") else: x0, y0 = np.meshgrid(stg.time_snr[f, :], stg.r[f, :]) x = np.append(x, np.array([x0]), axis=0) y = np.append(y, np.array([y0]), axis=0) - print(f"x : {x.shape}, y : {y.shape}") + # print(f"x : {x.shape}, y : {y.shape}") self.axis_SNR[f].cla() - val_min = abs(np.nanmin(stg.snr[f, :, :])) - val_max = abs(np.nanmax(stg.snr[f, :, :])) + val_min = abs(np.nanmin(stg.SNR_data[f, :, :])) + val_max = abs(np.nanmax(stg.SNR_data[f, :, :])) if val_min == 0: val_min = 1e-5 if val_max < 1000: @@ -1544,14 +1639,14 @@ class AcousticDataTab(QWidget): cf = self.axis_SNR[f].contourf(x[f, :, int(stg.tmin_snr[f]):int(stg.tmax_snr[f])], -y[f, :, int(stg.tmin_snr[f]):int(stg.tmax_snr[f])], - stg.snr[f, :, int(stg.tmin_snr[f]):int(stg.tmax_snr[f])], + stg.SNR_data[f, :, int(stg.tmin_snr[f]):int(stg.tmax_snr[f])], levels, cmap='gist_rainbow', norm=norm) elif self.combobox_ABS_system_choice.currentIndex() == 2: cf = self.axis_SNR[f].contourf(x[f, :, int(stg.tmin_snr[f]):int(stg.tmax_snr[f])], -y[f, :, int(stg.tmin_snr[f]):int(stg.tmax_snr[f])], - stg.snr[f, :, int(stg.tmin_snr[f]):int(stg.tmax_snr[ + stg.SNR_data[f, :, int(stg.tmin_snr[f]):int(stg.tmax_snr[ f])]) # , levels, cmap='gist_rainbow', norm=norm) self.axis_SNR[f].text(1, .70, stg.freq_text[f], diff --git a/View/sample_data_tab.py b/View/sample_data_tab.py index ee0e7fa..c97b4a2 100644 --- a/View/sample_data_tab.py +++ b/View/sample_data_tab.py @@ -440,7 +440,7 @@ class SampleDataTab(QWidget): # horizontal_header = list(map(str, ["Color", "Sample"] + stg.fine_sediment_columns + # stg.sand_sediment_columns[2:])) horizontal_header = list(itertools.chain(["Color", "Sample"], - list(map(str, stg.fine_sediment_columns[:2])), + list(map(str, stg.fine_sediment_columns[[0, 2]])), list(map(str, stg.fine_sediment_columns[3:])))) for horizontal_header_text in horizontal_header: @@ -506,7 +506,7 @@ class SampleDataTab(QWidget): # horizontal_header = list(map(str, ["Color", "Sample"] + stg.fine_sediment_columns + # stg.sand_sediment_columns[2:])) horizontal_header = list(itertools.chain(["Color", "Sample"], - list(map(str, stg.sand_sediment_columns[:2])), + list(map(str, stg.sand_sediment_columns[[0, 2]])), list(map(str, stg.sand_sediment_columns[3:])))) @@ -564,7 +564,7 @@ class SampleDataTab(QWidget): self.tableWidget_sample.itemChanged.connect(self.update_plot_sample_position_on_transect) elif (self.lineEdit_fine_sediment.text()) and (self.lineEdit_sand.text()): - + print(f"stg.sample_depth.shape[0] {stg.sample_depth.shape[0]}") self.row = self.tableWidget_sample.setRowCount(stg.sample_depth.shape[0]) self.col = self.tableWidget_sample.setColumnCount(8+2*stg.radius_grain.shape[0]) @@ -572,7 +572,7 @@ class SampleDataTab(QWidget): # horizontal_header = list(map(str, ["Color", "Sample"] + stg.fine_sediment_columns + # stg.sand_sediment_columns[2:])) horizontal_header = list(itertools.chain(["Color", "Sample"], - list(map(str, stg.fine_sediment_columns[:2])), + list(map(str, stg.fine_sediment_columns[[0, 2]])), list(map(str, stg.fine_sediment_columns[3:])), list(map(str, stg.sand_sediment_columns[3:])))) @@ -792,17 +792,17 @@ class SampleDataTab(QWidget): self.canvas_plot_sample_position_on_transect = FigureCanvas(self.figure_plot_sample_position_on_transect) self.verticalLayout_groupbox_plot_sample_position.addWidget(self.canvas_plot_sample_position_on_transect) - if stg.BS_data_section.size == 0: + if stg.BS_stream_bed.size == 0: - val_min = np.nanmin(stg.BS_data[stg.freq_bottom_detection, :, :]) - val_max = np.nanmax(stg.BS_data[stg.freq_bottom_detection, :, :]) + val_min = np.nanmin(stg.BS_cross_section[stg.freq_bottom_detection, :, :]) + val_max = np.nanmax(stg.BS_cross_section[stg.freq_bottom_detection, :, :]) if val_min == 0: val_min = 1e-5 self.axis_plot_sample_position_on_transect.pcolormesh( stg.t[stg.freq_bottom_detection, :], -stg.r[stg.freq_bottom_detection, :], - stg.BS_data[stg.freq_bottom_detection, :, :], + stg.BS_cross_section[stg.freq_bottom_detection, :, :], cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max)) if stg.r_bottom.size != 0: @@ -812,15 +812,15 @@ class SampleDataTab(QWidget): else: - val_min = np.nanmin(stg.BS_data_section[stg.freq_bottom_detection, :, :]) - val_max = np.nanmax(stg.BS_data_section[stg.freq_bottom_detection, :, :]) + val_min = np.nanmin(stg.BS_stream_bed[stg.freq_bottom_detection, :, :]) + val_max = np.nanmax(stg.BS_stream_bed[stg.freq_bottom_detection, :, :]) if val_min == 0: val_min = 1e-5 self.axis_plot_sample_position_on_transect.pcolormesh( stg.t[stg.freq_bottom_detection, :], -stg.r[stg.freq_bottom_detection, :], - stg.BS_data_section[stg.freq_bottom_detection, :, :], + stg.BS_stream_bed[stg.freq_bottom_detection, :, :], cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max)) if stg.r_bottom.size != 0: @@ -854,16 +854,16 @@ class SampleDataTab(QWidget): self.axis_plot_sample_position_on_transect.set_yticks([]) self.figure_plot_sample_position_on_transect.canvas.draw_idle() - elif stg.BS_data_section.size == 0: + elif stg.BS_stream_bed.size == 0: - val_min = np.nanmin(stg.BS_data[stg.freq_bottom_detection, :, :]) - val_max = np.nanmax(stg.BS_data[stg.freq_bottom_detection, :, :]) + val_min = np.nanmin(stg.BS_cross_section[stg.freq_bottom_detection, :, :]) + val_max = np.nanmax(stg.BS_cross_section[stg.freq_bottom_detection, :, :]) if val_min == 0: val_min = 1e-5 self.axis_plot_sample_position_on_transect.pcolormesh( stg.t[stg.freq_bottom_detection, :], -stg.r[stg.freq_bottom_detection, :], - stg.BS_data[self.combobox_frequencies.currentIndex(), :, :], + stg.BS_cross_section[self.combobox_frequencies.currentIndex(), :, :], cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max)) if stg.r_bottom.size != 0: @@ -882,14 +882,14 @@ class SampleDataTab(QWidget): else: - val_min = np.nanmin(stg.BS_data_section[stg.freq_bottom_detection, :, :]) - val_max = np.nanmax(stg.BS_data_section[stg.freq_bottom_detection, :, :]) + val_min = np.nanmin(stg.BS_stream_bed[stg.freq_bottom_detection, :, :]) + val_max = np.nanmax(stg.BS_stream_bed[stg.freq_bottom_detection, :, :]) if val_min == 0: val_min = 1e-5 self.axis_plot_sample_position_on_transect.pcolormesh( stg.t[stg.freq_bottom_detection, :], -stg.r[stg.freq_bottom_detection, :], - stg.BS_data_section[self.combobox_frequencies.currentIndex(), :, :], + stg.BS_stream_bed[self.combobox_frequencies.currentIndex(), :, :], cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max)) if stg.r_bottom.size != 0: diff --git a/View/signal_processing_tab.py b/View/signal_processing_tab.py index 2902c2c..da596af 100644 --- a/View/signal_processing_tab.py +++ b/View/signal_processing_tab.py @@ -13,7 +13,7 @@ from scipy.ndimage import convolve1d import matplotlib.pyplot as plt from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolBar -from matplotlib.colors import LogNorm +from matplotlib.colors import LogNorm, BoundaryNorm from scipy import stats import Translation.constant_string as cs @@ -157,14 +157,37 @@ class SignalProcessingTab(QWidget): self.verticalLayout_groupbox_post_processing = QVBoxLayout(self.groupbox_post_processing) + self.groupbox_acoustic_profile = QGroupBox() + self.verticalLayout_groupbox_post_processing.addWidget(self.groupbox_acoustic_profile) + self.groupbox_rayleigh_criterion = QGroupBox() self.verticalLayout_groupbox_post_processing.addWidget(self.groupbox_rayleigh_criterion) self.groupbox_window_size = QGroupBox() self.verticalLayout_groupbox_post_processing.addWidget(self.groupbox_window_size) - self.groupbox_acoustic_profile = QGroupBox() - self.verticalLayout_groupbox_post_processing.addWidget(self.groupbox_acoustic_profile) + # --- Groupbox acoustic profile --- + + self.gridLayout_groupbox_acoustic_profile = QGridLayout(self.groupbox_acoustic_profile) + + # self.checkbox_SNR_criterion = QCheckBox() + self.label_SNR_criterion = QLabel() + self.gridLayout_groupbox_acoustic_profile.addWidget(self.label_SNR_criterion, 0, 0, 1, 1) + self.spinbox_SNR_criterion = QSpinBox() + self.spinbox_SNR_criterion.setRange(0, 9999) + self.spinbox_SNR_criterion.setValue(0) + # 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.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.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 Rayleigh criterion --- @@ -232,29 +255,6 @@ class SignalProcessingTab(QWidget): # self.pushbutton_average.clicked.connect(self.update_plot_profile_position_on_transect) # self.pushbutton_average.clicked.connect(self.plot_averaged_profile) - # --- Groupbox acoustic profile --- - - self.gridLayout_groupbox_acoustic_profile = QGridLayout(self.groupbox_acoustic_profile) - - # self.checkbox_SNR_criterion = QCheckBox() - self.label_SNR_criterion = QLabel() - self.gridLayout_groupbox_acoustic_profile.addWidget(self.label_SNR_criterion, 0, 0, 1, 1) - self.spinbox_SNR_criterion = QSpinBox() - self.spinbox_SNR_criterion.setRange(0, 9999) - self.spinbox_SNR_criterion.setValue(0) - # 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.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.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 --- +++ # ++++++++++++++++++++++++++++++++++++ @@ -565,7 +565,7 @@ class SignalProcessingTab(QWidget): self.slider.valueChanged.connect(self.update_lineEdit_by_moving_slider) self.slider.valueChanged.connect(self.update_plot_profile_position_on_transect) self.slider.valueChanged.connect(self.update_plot_profile) - self.slider.valueChanged.connect(self.update_plot_averaged_profile) + # self.slider.valueChanged.connect(self.update_plot_averaged_profile) self.slider.valueChanged.connect(self.update_plot_FCB) self.retranslate_signal_processing_tab() @@ -625,7 +625,7 @@ class SignalProcessingTab(QWidget): def compute_BS_data_section(self): - if stg.BS_data.size == 0: + if stg.BS_cross_section.size == 0: msgBox = QMessageBox() msgBox.setWindowTitle("Load data Error") msgBox.setIcon(QMessageBox.Warning) @@ -634,13 +634,13 @@ class SignalProcessingTab(QWidget): msgBox.exec() else: if stg.r_bottom.size == 0: - stg.BS_data_section = deepcopy(stg.BS_data) + stg.BS_stream_bed = deepcopy(stg.BS_cross_section) elif stg.r_bottom.size != 0: - stg.BS_data_section = deepcopy(stg.BS_data) + stg.BS_stream_bed = deepcopy(stg.BS_cross_section) for f, _ in enumerate(stg.freq): for k, _ in enumerate(stg.r_bottom): # print(k, np.where(stg.r >= stg.r_bottom[k])[0]) - stg.BS_data_section[f, np.where(stg.r[self.combobox_frequency.currentIndex(), :] >= stg.r_bottom[k])[0], k] = np.nan + stg.BS_stream_bed[f, np.where(stg.r[self.combobox_frequency.currentIndex(), :] >= stg.r_bottom[k])[0], k] = np.nan # --- Choose frequency (Combo box) to plot transect with profile position --- self.combobox_frequency.addItems(stg.freq_text) @@ -660,11 +660,86 @@ class SignalProcessingTab(QWidget): self.plot_profile_position_on_transect() self.plot_profile() + # ---------------------------------------- Connect Groupbox filter with SNR ---------------------------------------- + + def remove_point_with_snr_filter(self): + + 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() + + else: + + if stg.BS_stream_bed.size == 0: + + stg.BS_cross_section_SNR_filter = deepcopy(stg.BS_cross_section) + # stg.Noise_data = deepcopy(stg.BS_noise_averaged_data[:, :, :stg.t.shape[1]]) + # stg.SNR_data_average = np.divide( + # (stg.BS_stream_bed_SNR_filter - stg.Noise_data) ** 2, stg.Noise_data ** 2) + + for f, _ in enumerate(stg.freq): + stg.BS_cross_section_SNR_filter[ + f, + np.where(stg.SNR_cross_section[f, :, :] < self.spinbox_SNR_criterion.value())[0], + np.where(stg.SNR_cross_section[f, :, :] < self.spinbox_SNR_criterion.value())[1]] \ + = np.nan + + else: + + stg.BS_stream_bed_SNR_filter = deepcopy(stg.BS_stream_bed) + # stg.Noise_data = deepcopy(stg.BS_noise_averaged_data[:, :, :stg.t.shape[1]]) + # stg.SNR_data_average = np.divide( + # (stg.BS_stream_bed_SNR_filter - stg.Noise_data) ** 2, stg.Noise_data ** 2) + + for f, _ in enumerate(stg.freq): + stg.BS_stream_bed_SNR_filter[ + f, + np.where(stg.SNR_cross_section[f, :, :] < self.spinbox_SNR_criterion.value())[0], + np.where(stg.SNR_cross_section[f, :, :] < self.spinbox_SNR_criterion.value())[1]] \ + = np.nan + + + # elif stg.BS_stream_bed_averaged.size != 0: + # stg.BS_stream_bed_SNR_filter = deepcopy(stg.BS_stream_bed_averaged) + # BS_noise_cross_section = deepcopy(stg.BS_noise_averaged_data[:, :, :stg.t.shape[1]]) + # print("BS_noise_cross_section.shape ", BS_noise_cross_section.shape) + # stg.SNR_data_average = np.divide( + # (stg.BS_stream_bed_SNR_filter - BS_noise_cross_section) ** 2, BS_noise_cross_section ** 2) + # + # print(stg.SNR_data_average[0, :, :]) + + # fig, ax = plt.subplots(nrows=1, ncols=1) + # x, y = np.meshgrid(list(range(stg.SNR_data_average.shape[2])), + # list(range(stg.SNR_data_average.shape[1]))) + # levels = np.array([00.1, 1, 2, 10, 100, 1000, 1e6]) + # bounds = [00.1, 1, 2, 10, 100, 1000, 1e6, 1e6 * 1.2] + # norm = BoundaryNorm(boundaries=bounds, ncolors=300) + # cf = ax.contourf(x, -y, stg.SNR_data_average[0, :, :], cmap='gist_rainbow') # , levels, norm=norm) + # cbar = fig.colorbar(cf, ax=ax, shrink=1, location='right') + # plt.show() + # + # for f, _ in enumerate(stg.freq): + # print("----------------------------------------------") + # print(np.where(stg.SNR_data_average[f, :, :] < self.spinbox_SNR_criterion.value())[0]) + # print(np.where(stg.SNR_data_average[f, :, :] < self.spinbox_SNR_criterion.value())[1]) + # stg.BS_stream_bed_SNR_filter[ + # f, + # np.where(stg.SNR_data_average[f, :, :] < self.spinbox_SNR_criterion.value())[0], + # np.where(stg.SNR_data_average[f, :, :] < self.spinbox_SNR_criterion.value())[1]] \ + # = np.nan + + self.update_plot_profile_position_on_transect() + # self.update_plot_averaged_profile() + # ----------------------------------------- Connect Groupbox average data ----------------------------------------- def compute_averaged_profile(self): - if stg.BS_data_section.size == 0: + if stg.BS_cross_section.size == 0: msgBox = QMessageBox() msgBox.setWindowTitle("Average Backscatter signal Error") msgBox.setIcon(QMessageBox.Warning) @@ -680,21 +755,57 @@ class SignalProcessingTab(QWidget): msgBox.setStandardButtons(QMessageBox.Ok) msgBox.exec() else: - filter_convolve = np.ones( self.spinbox_average_horizontal.value()) - print(filter_convolve) - # stg.BS_data_section_averaged = np.zeros((stg.r.shape[0], stg.freq.shape[0], stg.t.shape[0])) - # stg.BS_data_section_averaged = np.zeros((stg.freq.shape[0], stg.r.shape[1], stg.t.shape[1])) - stg.BS_data_section_averaged = deepcopy(stg.BS_data_section) - for f, _ in enumerate(stg.freq): - for i in range(stg.r.shape[1]): - stg.BS_data_section_averaged[f, i, :] \ - = convolve1d(stg.BS_data_section[f, i, :], weights=filter_convolve) / filter_convolve.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_horizontal.clear() - self.label_cells_horizontal.setText( - "cells = +/- " + str((self.spinbox_average_horizontal.value() // 2)*(1/stg.nb_profiles_per_sec)) + " sec") + filter_convolve = np.ones(self.spinbox_average_horizontal.value()) + # print(filter_convolve) + + if stg.BS_stream_bed_SNR_filter.size != 0: + + # stg.BS_stream_bed_averaged = np.zeros((stg.r.shape[0], stg.freq.shape[0], stg.t.shape[0])) + # stg.BS_stream_bed_averaged = np.zeros((stg.freq.shape[0], stg.r.shape[1], stg.t.shape[1])) + stg.BS_stream_bed_averaged = deepcopy(stg.BS_stream_bed_SNR_filter) + # print(f"stg.BS_cross_section_averaged : {stg.BS_cross_section_averaged.shape}") + for f, _ in enumerate(stg.freq): + for i in range(stg.r.shape[1]): + stg.BS_stream_bed_averaged[f, i, :] \ + = convolve1d(stg.BS_stream_bed_SNR_filter[f, i, :], weights=filter_convolve)# / filter_convolve.shape[0] + # stg.BS_stream_bed_averaged[i, f, :] \ + # = convolve1d(stg.BS_cross_section[i, f, :], weights=filter_convolve) / filter_convolve.shape[0] + + elif stg.BS_cross_section_SNR_filter.size != 0: + + stg.BS_cross_section_averaged = deepcopy(stg.BS_cross_section_SNR_filter) + print(f"stg.BS_cross_section_averaged : {stg.BS_cross_section_averaged.shape}") + for f, _ in enumerate(stg.freq): + for i in range(stg.r.shape[1]): + stg.BS_stream_bed_averaged[f, i, :] \ + = convolve1d(stg.BS_cross_section_SNR_filter[f, i, :], + weights=filter_convolve) # / filter_convolve.shape[0] + + elif stg.BS_stream_bed.size != 0: + + stg.BS_stream_bed_averaged = deepcopy(stg.BS_stream_bed) + print(f"stg.BS_cross_section_averaged : {stg.BS_cross_section_averaged.shape}") + for f, _ in enumerate(stg.freq): + for i in range(stg.r.shape[1]): + stg.BS_stream_bed_averaged[f, i, :] \ + = convolve1d(stg.BS_stream_bed[f, i, :], + weights=filter_convolve) # / filter_convolve.shape[0] + + elif stg.BS_cross_section.size != 0: + + stg.BS_cross_section_averaged = deepcopy(stg.BS_cross_section) + print(f"stg.BS_cross_section_averaged : {stg.BS_cross_section_averaged.shape}") + for f, _ in enumerate(stg.freq): + for i in range(stg.r.shape[1]): + stg.BS_stream_bed_averaged[f, i, :] \ + = convolve1d(stg.BS_cross_section[f, i, :], + weights=filter_convolve) # / filter_convolve.shape[0] + + if stg.ABS_name == "Aquascat 1000R": + self.label_cells_horizontal.clear() + self.label_cells_horizontal.setText( + "cells = +/- " + str((self.spinbox_average_horizontal.value() // 2)*(1/stg.nb_profiles_per_sec)) + " sec") # self.label_cells_vertical.clear() # self.label_cells_vertical.setText( @@ -703,61 +814,21 @@ class SignalProcessingTab(QWidget): self.plot_averaged_profile() self.update_plot_profile_position_on_transect() + self.slider.valueChanged.connect(self.update_plot_averaged_profile) + # fig, ax = plt.subplots(nrows=1, ncols=1) - # val_min = np.nanmin(stg.BS_data_section_averaged[self.combobox_frequency.currentIndex(), :, :]) - # val_max = np.nanmax(stg.BS_data_section_averaged[self.combobox_frequency.currentIndex(), :, :]) + # val_min = np.nanmin(stg.BS_stream_bed_averaged[self.combobox_frequency.currentIndex(), :, :]) + # val_max = np.nanmax(stg.BS_stream_bed_averaged[self.combobox_frequency.currentIndex(), :, :]) # if val_min == 0: # val_min = 1e-5 # # ax.pcolormesh(stg.t[self.combobox_frequency.currentIndex(), :], # -stg.r[self.combobox_frequency.currentIndex(), :], - # stg.BS_data_section_averaged[self.combobox_frequency.currentIndex(), :, :], + # stg.BS_stream_bed_averaged[self.combobox_frequency.currentIndex(), :, :], # cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max)) # # plt.show() - # ---------------------------------------- Connect Groupbox filter with SNR ---------------------------------------- - - def remove_point_with_snr_filter(self): - - 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() - - else: - - 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[1]])**2, - stg.Noise_data[:, :, :stg.t.shape[1]]**2) - - for f, _ in enumerate(stg.freq): - stg.BS_data_section_SNR_filter[f, - np.where(stg.SNR_data_average[f, :, :] < self.spinbox_SNR_criterion.value())[0], - np.where(stg.SNR_data_average[f, :, :] < 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[1]]) ** 2, - stg.Noise_data[:, :, :stg.t.shape[1]] ** 2) - - for f in enumerate(stg.freq): - stg.BS_data_section_SNR_filter[ - np.where(stg.SNR_data_average[f, :, :] < self.spinbox_SNR_criterion.value())[0], - f, - np.where(stg.SNR_data_average[f, :, :] < 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 (stg.freq.size == 0) or (self.spinbox_temperature_water_attenuation.value() == 0): msgBox = QMessageBox() @@ -797,7 +868,7 @@ class SignalProcessingTab(QWidget): def range_cells_function(self): """ Computing the real cell size, that depends on the temperature """ # defaut Aquascat cell size - aquascat_cell_size = stg.r[1] - stg.r[0] + aquascat_cell_size = stg.r[0, 1] - stg.r[0, 0] # Pulse duration tau = aquascat_cell_size * 2 / 1500 # figure 2.9 1500 vitesse du son entrée pour le paramètrage des mesures aquascat # Sound speed @@ -815,7 +886,7 @@ class SignalProcessingTab(QWidget): return R_real def compute_FCB(self): - if stg.BS_data_section.size == 0: + if stg.BS_stream_bed.size == 0: msgBox = QMessageBox() msgBox.setWindowTitle("FCB Error") msgBox.setIcon(QMessageBox.Warning) @@ -824,14 +895,14 @@ class SignalProcessingTab(QWidget): msgBox.exec() else: R_real = np.repeat(self.range_cells_function()[:, :, np.newaxis], stg.t.shape[0], axis=2) - if (stg.BS_data_section_averaged.size == 0) and (stg.BS_data_section_SNR_filter.size == 0): - stg.FCB = (np.log(stg.BS_data_section) + np.log(R_real) + + if (stg.BS_stream_bed_averaged.size == 0) and (stg.BS_stream_bed_SNR_filter.size == 0): + stg.FCB = (np.log(stg.BS_stream_bed) + np.log(R_real) + 2 * stg.water_attenuation * R_real) - elif stg.BS_data_section_SNR_filter.size == 0: - stg.FCB = (np.log(stg.BS_data_section_averaged) + np.log(R_real) + + elif stg.BS_stream_bed_SNR_filter.size == 0: + stg.FCB = (np.log(stg.BS_stream_bed_averaged) + np.log(R_real) + 2 * stg.water_attenuation * R_real) else: - stg.FCB = (np.log(stg.BS_data_section_SNR_filter) + np.log(R_real) + + stg.FCB = (np.log(stg.BS_stream_bed_SNR_filter) + np.log(R_real) + 2 * stg.water_attenuation * R_real) self.plot_FCB() @@ -912,15 +983,33 @@ class SignalProcessingTab(QWidget): self.verticalLayout_groupbox_display_profile_position.addWidget(self.canvas_plot_profile_position_on_transect) # --- Plot transect with profile position --- - val_min = np.nanmin(stg.BS_data_section[stg.freq_bottom_detection, :, :]) - val_max = np.nanmax(stg.BS_data_section[stg.freq_bottom_detection, :, :]) + val_min = np.nanmin(stg.BS_stream_bed[stg.freq_bottom_detection, :, :]) + val_max = np.nanmax(stg.BS_stream_bed[stg.freq_bottom_detection, :, :]) if val_min == 0: val_min = 1e-5 - self.axis_plot_profile_position_on_transect.pcolormesh( - stg.t[stg.freq_bottom_detection, :], -stg.r[stg.freq_bottom_detection, :], - stg.BS_data_section[stg.freq_bottom_detection, :, :], - cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max)) + if stg.ABS_name == "Aquascat 1000R": + if stg.BS_stream_bed.size != 0: + self.axis_plot_profile_position_on_transect.pcolormesh( + stg.t[stg.freq_bottom_detection, :], -stg.r[stg.freq_bottom_detection, :], + stg.BS_stream_bed[stg.freq_bottom_detection, :, :], + cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max)) + else: + self.axis_plot_profile_position_on_transect.pcolormesh( + stg.t[stg.freq_bottom_detection, :], -stg.r[stg.freq_bottom_detection, :], + stg.BS_cross_section[stg.freq_bottom_detection, :, :], + cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max)) + elif stg.ABS_name == "UB-SediFlow": + if stg.BS_stream_bed.size != 0: + self.axis_plot_profile_position_on_transect.pcolormesh( + stg.t[stg.freq_bottom_detection, :], -stg.r[stg.freq_bottom_detection, :], + np.log(stg.BS_cross_section[stg.freq_bottom_detection, :, :]), + cmap='Blues') + else: + self.axis_plot_profile_position_on_transect.pcolormesh( + stg.t[stg.freq_bottom_detection, :], -stg.r[stg.freq_bottom_detection, :], + np.log(stg.BS_stream_bed[stg.freq_bottom_detection, :, :]), + cmap='Blues') if stg.r_bottom.size != 0: self.axis_plot_profile_position_on_transect.plot( @@ -953,92 +1042,156 @@ class SignalProcessingTab(QWidget): else: - if (stg.BS_data_section_averaged.size == 0) and (stg.BS_data_section_SNR_filter.size == 0): + if stg.BS_stream_bed.size != 0: - self.axis_plot_profile_position_on_transect.cla() + if (stg.BS_stream_bed_averaged.size == 0) and (stg.BS_stream_bed_SNR_filter.size == 0): - val_min = np.nanmin(stg.BS_data_section[self.combobox_frequency.currentIndex(), :, :]) - val_max = np.nanmax(stg.BS_data_section[self.combobox_frequency.currentIndex(), :, :]) - if val_min == 0: - val_min = 1e-5 + self.axis_plot_profile_position_on_transect.cla() - self.axis_plot_profile_position_on_transect.pcolormesh( - stg.t[self.combobox_frequency.currentIndex(), :], -stg.r[self.combobox_frequency.currentIndex(), :], - stg.BS_data_section[self.combobox_frequency.currentIndex(), :, :], - cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max)) + val_min = np.nanmin(stg.BS_stream_bed[self.combobox_frequency.currentIndex(), :, :]) + val_max = np.nanmax(stg.BS_stream_bed[self.combobox_frequency.currentIndex(), :, :]) + if val_min == 0: + val_min = 1e-5 - if stg.r_bottom.size != 0: - self.axis_plot_profile_position_on_transect.plot(stg.t[self.combobox_frequency.currentIndex(), :], - -stg.r_bottom, - color='black', linewidth=1, linestyle="solid") + if stg.ABS_name == "Aquascat 1000R": + self.axis_plot_profile_position_on_transect.pcolormesh( + stg.t[self.combobox_frequency.currentIndex(), :], + -stg.r[self.combobox_frequency.currentIndex(), :], + stg.BS_stream_bed[self.combobox_frequency.currentIndex(), :, :], + cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max)) + elif stg.ABS_name == "UB-SediFlow": + self.axis_plot_profile_position_on_transect.pcolormesh( + stg.t[self.combobox_frequency.currentIndex(), :], + -stg.r[self.combobox_frequency.currentIndex(), :], + np.log(stg.BS_stream_bed[self.combobox_frequency.currentIndex(), :, :]), + cmap='Blues') - self.axis_plot_profile_position_on_transect.plot( - stg.t[self.combobox_frequency.currentIndex(), self.slider.value()-1] * np.ones(stg.r.shape[1]), - -stg.r[self.combobox_frequency.currentIndex(), :], - color='red', linestyle="solid", linewidth=2) + elif (stg.BS_stream_bed_averaged.size != 0) and (stg.BS_stream_bed_SNR_filter.size == 0): - self.axis_plot_profile_position_on_transect.set_xticks([]) - self.axis_plot_profile_position_on_transect.set_yticks([]) + self.axis_plot_profile_position_on_transect.cla() - self.figure_plot_profile_position_on_transect.canvas.draw_idle() + val_min = np.nanmin(stg.BS_stream_bed_averaged[self.combobox_frequency.currentIndex(), :, :]) + val_max = np.nanmax(stg.BS_stream_bed_averaged[self.combobox_frequency.currentIndex(), :, :]) + if val_min == 0: + val_min = 1e-5 - elif (stg.BS_data_section_averaged.size != 0) and (stg.BS_data_section_SNR_filter.size == 0): + if stg.ABS_name == "Aquascat 1000R": + self.axis_plot_profile_position_on_transect.pcolormesh( + stg.t[self.combobox_frequency.currentIndex(), :], + -stg.r[self.combobox_frequency.currentIndex(), :], + stg.BS_stream_bed_averaged[self.combobox_frequency.currentIndex(), :, :], + cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max)) + elif stg.ABS_name == "UB-SediFlow": + self.axis_plot_profile_position_on_transect.pcolormesh( + stg.t[self.combobox_frequency.currentIndex(), :], + -stg.r[self.combobox_frequency.currentIndex(), :], + np.log(stg.BS_stream_bed_averaged[self.combobox_frequency.currentIndex(), :, :]), + cmap='Blues') - self.axis_plot_profile_position_on_transect.cla() + elif stg.BS_stream_bed_SNR_filter.size != 0: - val_min = np.nanmin(stg.BS_data_section_averaged[self.combobox_frequency.currentIndex(), :, :]) - val_max = np.nanmax(stg.BS_data_section_averaged[self.combobox_frequency.currentIndex(), :, :]) - if val_min == 0: - val_min = 1e-5 + self.axis_plot_profile_position_on_transect.cla() - self.axis_plot_profile_position_on_transect.pcolormesh( - stg.t[self.combobox_frequency.currentIndex(), :], -stg.r[self.combobox_frequency.currentIndex(), :], - stg.BS_data_section_averaged[self.combobox_frequency.currentIndex(), :, :], - cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max)) + val_min = np.nanmin(stg.BS_stream_bed_SNR_filter[self.combobox_frequency.currentIndex(), :, :]) + val_max = np.nanmax(stg.BS_stream_bed_SNR_filter[self.combobox_frequency.currentIndex(), :, :]) + if val_min == 0: + val_min = 1e-5 - if stg.r_bottom.size != 0: - self.axis_plot_profile_position_on_transect.plot(stg.t[self.combobox_frequency.currentIndex(), :], - -stg.r_bottom, - color='black', linewidth=1, linestyle="solid") + if stg.ABS_name == "Aquascat 1000R": + self.axis_plot_profile_position_on_transect.pcolormesh( + stg.t[self.combobox_frequency.currentIndex(), :], + -stg.r[self.combobox_frequency.currentIndex(), :], + stg.BS_stream_bed_SNR_filter[self.combobox_frequency.currentIndex(), :, :], + cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max)) + elif stg.ABS_name == "UB-SediFlow": + self.axis_plot_profile_position_on_transect.pcolormesh( + stg.t[self.combobox_frequency.currentIndex(), :], + -stg.r[self.combobox_frequency.currentIndex(), :], + np.log(stg.BS_stream_bed_SNR_filter[self.combobox_frequency.currentIndex(), :, :]), + cmap='Blues') - self.axis_plot_profile_position_on_transect.plot( + else: + + if (stg.BS_cross_section_averaged.size == 0) and (stg.BS_cross_section_SNR_filter.size == 0): + + self.axis_plot_profile_position_on_transect.cla() + + val_min = np.nanmin(stg.BS_stream_bed[self.combobox_frequency.currentIndex(), :, :]) + val_max = np.nanmax(stg.BS_stream_bed[self.combobox_frequency.currentIndex(), :, :]) + if val_min == 0: + val_min = 1e-5 + + if stg.ABS_name == "Aquascat 1000R": + self.axis_plot_profile_position_on_transect.pcolormesh( + stg.t[self.combobox_frequency.currentIndex(), :], + -stg.r[self.combobox_frequency.currentIndex(), :], + stg.BS_cross_section[self.combobox_frequency.currentIndex(), :, :], + cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max)) + elif stg.ABS_name == "UB-SediFlow": + self.axis_plot_profile_position_on_transect.pcolormesh( + stg.t[self.combobox_frequency.currentIndex(), :], + -stg.r[self.combobox_frequency.currentIndex(), :], + np.log(stg.BS_cross_section[self.combobox_frequency.currentIndex(), :, :]), + cmap='Blues') + + elif (stg.BS_cross_section_averaged.size != 0) and (stg.BS_cross_section_SNR_filter.size == 0): + + self.axis_plot_profile_position_on_transect.cla() + + val_min = np.nanmin(stg.BS_cross_section_averaged[self.combobox_frequency.currentIndex(), :, :]) + val_max = np.nanmax(stg.BS_cross_section_averaged[self.combobox_frequency.currentIndex(), :, :]) + if val_min == 0: + val_min = 1e-5 + + if stg.ABS_name == "Aquascat 1000R": + self.axis_plot_profile_position_on_transect.pcolormesh( + stg.t[self.combobox_frequency.currentIndex(), :], + -stg.r[self.combobox_frequency.currentIndex(), :], + stg.BS_cross_section_averaged[self.combobox_frequency.currentIndex(), :, :], + cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max)) + elif stg.ABS_name == "UB-SediFlow": + self.axis_plot_profile_position_on_transect.pcolormesh( + stg.t[self.combobox_frequency.currentIndex(), :], + -stg.r[self.combobox_frequency.currentIndex(), :], + np.log(stg.BS_cross_section_averaged[self.combobox_frequency.currentIndex(), :, :]), + cmap='Blues') + + elif stg.BS_cross_section_SNR_filter.size != 0: + + self.axis_plot_profile_position_on_transect.cla() + + val_min = np.nanmin(stg.BS_cross_section_SNR_filter[self.combobox_frequency.currentIndex(), :, :]) + val_max = np.nanmax(stg.BS_cross_section_SNR_filter[self.combobox_frequency.currentIndex(), :, :]) + if val_min == 0: + val_min = 1e-5 + + if stg.ABS_name == "Aquascat 1000R": + self.axis_plot_profile_position_on_transect.pcolormesh( + stg.t[self.combobox_frequency.currentIndex(), :], + -stg.r[self.combobox_frequency.currentIndex(), :], + stg.BS_cross_section_SNR_filter[self.combobox_frequency.currentIndex(), :, :], + cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max)) + elif stg.ABS_name == "UB-SediFlow": + self.axis_plot_profile_position_on_transect.pcolormesh( + stg.t[self.combobox_frequency.currentIndex(), :], + -stg.r[self.combobox_frequency.currentIndex(), :], + np.log(stg.BS_cross_section_SNR_filter[self.combobox_frequency.currentIndex(), :, :]), + cmap='Blues') + + if stg.r_bottom.size != 0: + self.axis_plot_profile_position_on_transect.plot(stg.t[self.combobox_frequency.currentIndex(), :], + -stg.r_bottom, + color='black', linewidth=1, linestyle="solid") + + self.axis_plot_profile_position_on_transect.plot( stg.t[self.combobox_frequency.currentIndex(), self.slider.value() - 1] * np.ones(stg.r.shape[1]), -stg.r[self.combobox_frequency.currentIndex(), :], color='red', linestyle="solid", linewidth=2) - self.axis_plot_profile_position_on_transect.set_xticks([]) - self.axis_plot_profile_position_on_transect.set_yticks([]) + self.axis_plot_profile_position_on_transect.set_xticks([]) + self.axis_plot_profile_position_on_transect.set_yticks([]) - self.figure_plot_profile_position_on_transect.canvas.draw_idle() - - elif stg.BS_data_section_SNR_filter.size != 0: - - self.axis_plot_profile_position_on_transect.cla() - - val_min = np.nanmin(stg.BS_data_section_SNR_filter[self.combobox_frequency.currentIndex(), :, :]) - val_max = np.nanmax(stg.BS_data_section_SNR_filter[self.combobox_frequency.currentIndex(), :, :]) - if val_min == 0: - val_min = 1e-5 - - self.axis_plot_profile_position_on_transect.pcolormesh( - stg.t[self.combobox_frequency.currentIndex(), :], -stg.r[self.combobox_frequency.currentIndex(), :], - stg.BS_data_section_SNR_filter[self.combobox_frequency.currentIndex(), :, :], - cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max)) - - if stg.r_bottom.size != 0: - self.axis_plot_profile_position_on_transect.plot(stg.t[self.combobox_frequency.currentIndex(), :], - -stg.r_bottom, - color='black', linewidth=1, linestyle="solid") - - self.axis_plot_profile_position_on_transect.plot( - stg.t[self.combobox_frequency.currentIndex(), self.slider.value() - 1] * np.ones(stg.r.shape[1]), - -stg.r[self.combobox_frequency.currentIndex(), :], - color='red', linestyle="solid", linewidth=2) - - self.axis_plot_profile_position_on_transect.set_xticks([]) - self.axis_plot_profile_position_on_transect.set_yticks([]) - - self.figure_plot_profile_position_on_transect.canvas.draw_idle() + self.figure_plot_profile_position_on_transect.canvas.draw_idle() # -------------------------------------------------- PLOT PROFILE ------------------------------------------------- @@ -1057,15 +1210,29 @@ class SignalProcessingTab(QWidget): # self.scroll_profile.setAlignment(Qt.AlignCenter) # self.verticalLayout_groupbox_plot_profile.addWidget(self.scroll_profile) - for f, _ in enumerate(stg.freq): - self.axis_profile[f].cla() - self.axis_profile[f].plot(stg.BS_data_section[f, :, self.slider.value() - 1], -stg.r[f, :], - linestyle='solid', color='k', linewidth=1) - self.axis_profile[f].text(.95, .05, stg.freq_text[f], - fontsize=10, fontweight='bold', fontname="Ubuntu", - fontstyle="normal", c="black", alpha=0.2, - horizontalalignment='right', verticalalignment='bottom', - transform=self.axis_profile[f].transAxes) + if stg.BS_stream_bed.size == 0: + + for f, _ in enumerate(stg.freq): + self.axis_profile[f].cla() + self.axis_profile[f].plot(stg.BS_cross_section[f, :, self.slider.value() - 1], -stg.r[f, :], + linestyle='solid', color='k', linewidth=1) + self.axis_profile[f].text(.95, .05, stg.freq_text[f], + fontsize=10, fontweight='bold', fontname="Ubuntu", + fontstyle="normal", c="black", alpha=0.2, + horizontalalignment='right', verticalalignment='bottom', + transform=self.axis_profile[f].transAxes) + + else: + + for f, _ in enumerate(stg.freq): + self.axis_profile[f].cla() + self.axis_profile[f].plot(stg.BS_stream_bed[f, :, self.slider.value() - 1], -stg.r[f, :], + linestyle='solid', color='k', linewidth=1) + self.axis_profile[f].text(.95, .05, stg.freq_text[f], + fontsize=10, fontweight='bold', fontname="Ubuntu", + fontstyle="normal", c="black", alpha=0.2, + horizontalalignment='right', verticalalignment='bottom', + transform=self.axis_profile[f].transAxes) self.figure_profile.supxlabel("Acoustic Backscatter Signal (V)") self.figure_profile.supylabel("Depth (m)") @@ -1118,15 +1285,30 @@ class SignalProcessingTab(QWidget): msgBox.exec() else: - for f, _ in enumerate(stg.freq): - self.axis_profile[f].cla() - self.axis_profile[f].plot(stg.BS_data_section[f, :, self.slider.value() - 1], -stg.r[f, :], - linestyle='solid', color='k', linewidth=1) - self.axis_profile[f].text(.95, .05, stg.freq_text[f], - fontsize=10, fontweight='bold', fontname="Ubuntu", - fontstyle="normal", c="black", alpha=0.2, - horizontalalignment='right', verticalalignment='bottom', - transform=self.axis_profile[f].transAxes) + + if stg.BS_stream_bed.size == 0: + + for f, _ in enumerate(stg.freq): + self.axis_profile[f].cla() + self.axis_profile[f].plot(stg.BS_cross_section[f, :, self.slider.value() - 1], -stg.r[f, :], + linestyle='solid', color='k', linewidth=1) + self.axis_profile[f].text(.95, .05, stg.freq_text[f], + fontsize=10, fontweight='bold', fontname="Ubuntu", + fontstyle="normal", c="black", alpha=0.2, + horizontalalignment='right', verticalalignment='bottom', + transform=self.axis_profile[f].transAxes) + + else: + + for f, _ in enumerate(stg.freq): + self.axis_profile[f].cla() + self.axis_profile[f].plot(stg.BS_stream_bed[f, :, self.slider.value() - 1], -stg.r[f, :], + linestyle='solid', color='k', linewidth=1) + self.axis_profile[f].text(.95, .05, stg.freq_text[f], + fontsize=10, fontweight='bold', fontname="Ubuntu", + fontstyle="normal", c="black", alpha=0.2, + horizontalalignment='right', verticalalignment='bottom', + transform=self.axis_profile[f].transAxes) self.figure_profile.supxlabel("Acoustic Backscatter Signal (V)") self.figure_profile.supylabel("Depth (m)") @@ -1136,16 +1318,31 @@ class SignalProcessingTab(QWidget): def plot_averaged_profile(self): - for f, _ in enumerate(stg.freq): - self.axis_averaged_profile[f].cla() - self.axis_averaged_profile[f].plot(stg.BS_data_section_averaged[f, :, self.slider.value()-1], -stg.r[f, :], - linestyle='solid', color='k', linewidth=1) - self.axis_averaged_profile[f].set_ylim(-np.max(stg.r[f, :]), np.min(stg.r[f, :])) - self.axis_averaged_profile[f].text(.95, .05, stg.freq_text[f], - fontsize=10, fontweight='bold', fontname="Ubuntu", - fontstyle="normal", c="black", alpha=0.2, - horizontalalignment='right', verticalalignment='bottom', - transform=self.axis_averaged_profile[f].transAxes) + if stg.BS_stream_bed_averaged.size == 0: + + for f, _ in enumerate(stg.freq): + self.axis_averaged_profile[f].cla() + self.axis_averaged_profile[f].plot(stg.BS_cross_section_averaged[f, :, self.slider.value()-1], -stg.r[f, :], + linestyle='solid', color='k', linewidth=1) + # self.axis_averaged_profile[f].set_ylim(-np.max(stg.r[f, :]), np.min(stg.r[f, :])) + self.axis_averaged_profile[f].text(.95, .05, stg.freq_text[f], + fontsize=10, fontweight='bold', fontname="Ubuntu", + fontstyle="normal", c="black", alpha=0.2, + horizontalalignment='right', verticalalignment='bottom', + transform=self.axis_averaged_profile[f].transAxes) + + else: + + for f, _ in enumerate(stg.freq): + self.axis_averaged_profile[f].cla() + self.axis_averaged_profile[f].plot(stg.BS_stream_bed_averaged[f, :, self.slider.value()-1], -stg.r[f, :], + linestyle='solid', color='k', linewidth=1) + # self.axis_averaged_profile[f].set_ylim(-np.max(stg.r[f, :]), np.min(stg.r[f, :])) + self.axis_averaged_profile[f].text(.95, .05, stg.freq_text[f], + fontsize=10, fontweight='bold', fontname="Ubuntu", + fontstyle="normal", c="black", alpha=0.2, + horizontalalignment='right', verticalalignment='bottom', + transform=self.axis_averaged_profile[f].transAxes) self.figure_averaged_profile.supxlabel("Acoustic Backscatter Signal (V)") self.figure_averaged_profile.supylabel("Depth (m)") @@ -1160,42 +1357,36 @@ class SignalProcessingTab(QWidget): msgBox.setStandardButtons(QMessageBox.Ok) msgBox.exec() - elif (stg.BS_data_section_averaged.size == 0) and (stg.BS_data_section_SNR_filter.size == 0): - pass - else: - if stg.BS_data_section_SNR_filter.size == 0: + + if stg.BS_stream_bed_averaged.size == 0: for f, _ in enumerate(stg.freq): self.axis_averaged_profile[f].cla() - self.axis_averaged_profile[f].plot(stg.BS_data_section_averaged[f, :, self.slider.value() - 1], - -stg.r[f, :], - linestyle='solid', color='k', linewidth=1) - self.axis_averaged_profile[f].set_ylim(-np.max(stg.r[f, :]), np.min(stg.r[f, :])) - self.axis_averaged_profile[f].text(.95, .05, stg.freq_text[f], - fontsize=10, fontweight='bold', fontname="Ubuntu", - fontstyle="normal", c="black", alpha=0.2, - horizontalalignment='right', verticalalignment='bottom', - transform=self.axis_averaged_profile[f].transAxes) - - self.figure_averaged_profile.supxlabel("Acoustic Backscatter Signal (V)") - self.figure_averaged_profile.supylabel("Depth (m)") - self.figure_averaged_profile.canvas.draw_idle() - - 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], + self.axis_averaged_profile[f].plot(stg.BS_cross_section_averaged[f, :, self.slider.value() - 1], -stg.r[f, :], linestyle='solid', color='k', linewidth=1) - self.axis_averaged_profile[f].set_ylim(-np.max(stg.r[f, :]), np.min(stg.r[f, :])) + # self.axis_averaged_profile[f].set_ylim(-np.max(stg.r[f, :]), np.min(stg.r[f, :])) self.axis_averaged_profile[f].text(.95, .05, stg.freq_text[f], fontsize=10, fontweight='bold', fontname="Ubuntu", fontstyle="normal", c="black", alpha=0.2, horizontalalignment='right', verticalalignment='bottom', transform=self.axis_averaged_profile[f].transAxes) + else: + + for f, _ in enumerate(stg.freq): + self.axis_averaged_profile[f].cla() + self.axis_averaged_profile[f].plot(stg.BS_stream_bed_averaged[f, :, self.slider.value() - 1], + -stg.r[f, :], + linestyle='solid', color='k', linewidth=1) + # self.axis_averaged_profile[f].set_ylim(-np.max(stg.r[f, :]), np.min(stg.r[f, :])) + self.axis_averaged_profile[f].text(.95, .05, stg.freq_text[f], + fontsize=10, fontweight='bold', fontname="Ubuntu", + fontstyle="normal", c="black", alpha=0.2, + horizontalalignment='right', verticalalignment='bottom', + transform=self.axis_averaged_profile[f].transAxes) + self.figure_averaged_profile.supxlabel("Acoustic Backscatter Signal (V)") self.figure_averaged_profile.supylabel("Depth (m)") self.figure_averaged_profile.canvas.draw_idle() diff --git a/main.py b/main.py index 8ff2a8a..8026364 100644 --- a/main.py +++ b/main.py @@ -1,4 +1,5 @@ import sys +import traceback from PyQt5.QtWidgets import QApplication, QMainWindow from PyQt5.QtCore import QCoreApplication @@ -32,37 +33,48 @@ class MainApplication(QMainWindow): height = size.height() self.resize(int(PERCENT_SCREEN_SIZE*width), int(PERCENT_SCREEN_SIZE*height)) - # ************************************************** - # -------------- Acoustic data tab --------------- + try: - self.acoustic_data_tab = AcousticDataTab(self.ui_mainwindow.tab1) + # ************************************************** + # -------------- Acoustic data tab --------------- - # Connect push buttons to download data files + self.acoustic_data_tab = AcousticDataTab(self.ui_mainwindow.tab1) + + # Connect push buttons to download data files22 + + # ************************************************** + # --------- Signal processing data tab ---------- + + self.signal_processing_tab = SignalProcessingTab(self.ui_mainwindow.tab2) + + # ************************************************** + # --------------- Sample data tab ---------------- + + self.sample_data_tab = SampleDataTab(self.ui_mainwindow.tab3) + + # ************************************************** + # ------------ Acoustic inversion tab ------------- + + self.acoustic_inversion_tab = AcousticInversionTab(self.ui_mainwindow.tab4) + + # ************************************************** + # ------------------- Note tab -------------------- + + self.note_tab = NoteTab(self.ui_mainwindow.tab5) + + # ************************************************** + # ---------------- User Manual tab ----------------- + + self.user_manual_tab = UserManualTab(self.ui_mainwindow.tab6) # ************************************************** - # --------- Signal processing data tab ---------- + # ---------------- Text File Error ----------------- - self.signal_processing_tab = SignalProcessingTab(self.ui_mainwindow.tab2) - - # ************************************************** - # --------------- Sample data tab ---------------- - - self.sample_data_tab = SampleDataTab(self.ui_mainwindow.tab3) - - # ************************************************** - # ------------ Acoustic inversion tab ------------- - - self.acoustic_inversion_tab = AcousticInversionTab(self.ui_mainwindow.tab4) - - # ************************************************** - # ------------------- Note tab -------------------- - - self.note_tab = NoteTab(self.ui_mainwindow.tab5) - - # ************************************************** - # ---------------- User Manual tab ----------------- - - self.user_manual_tab = UserManualTab(self.ui_mainwindow.tab6) + except Exception as e: + with open("Error_file.txt", "w", encoding="utf-8") as sortie: + sortie.write(str(e)) + sortie.write(traceback.format_exc()) + # traceback.TracebackException.from_exception(e).print(file=sortie) if __name__ == '__main__': @@ -72,4 +84,5 @@ if __name__ == '__main__': app = QApplication(sys.argv) window = MainApplication() window.show() - sys.exit(app.exec_()) + # sys.exit(app.exec_()) + app.exec() diff --git a/settings.py b/settings.py index e8c7f91..e5ba377 100644 --- a/settings.py +++ b/settings.py @@ -5,6 +5,9 @@ import pandas as pd import datetime # --- load raw data --- + +ABS_name = "" + path_BS_raw_data = "" filename_BS_raw_data = "" BS_raw_data = np.array([]) # BS raw data : all measurement (go and back) @@ -16,7 +19,8 @@ time = np.array([]) path_BS_noise_data = "" filename_BS_noise_data = "" -BS_noise_data = np.array([]) # BS noise data averaged (array has the same shape than BS_raw_data shape) +BS_noise_raw_data = np.array([]) # BS noise raw data : BS signal listen +BS_noise_averaged_data = np.array([]) # BS noise raw data averaged (array has the same shape than BS_raw_data shape) date = [] date_noise = [] @@ -33,7 +37,7 @@ kt = np.array([]) gain_rx = np.array([]) gain_tx = np.array([]) -snr = np.array([]) # snr is computed with BS_noise_data +SNR_data = np.array([]) # SNR is computed with BS_noise_averaged_data time_snr = np.array([]) # --- reshape raw data for table of values in Acoustic Data tab --- @@ -41,7 +45,7 @@ time_reshape = np.array([]) time_snr_reshape = np.array([]) r_reshape = np.array([]) BS_raw_data_reshape = np.array([]) -snr_reshape = np.array([]) # snr is reshape to be included in table of values in acoustic data tab +SNR_reshape = np.array([]) # snr is reshape to be included in table of values in acoustic data tab DataFrame_acoustic = pd.DataFrame() # --- Processed data in Acoustic Data Tab and used in Acoustic processing tab --- @@ -49,10 +53,11 @@ tmin = np.array([]) # minimum boundary of time (spin box tmin) tmin_snr = np.array([]) tmax = np.array([]) # maximum boundary of time (spin box tmin) tmax_snr = np.array([]) -BS_data = np.array([]) # BS data limited with tmin and tmax values of spin box -BS_data_section = np.array([]) # BS data in the section. Values NaN outside the bottom of the section are deleted -Noise_data = np.array([]) # Noise_data = BS_noise_data[:, :, tmin:tmax] -SNR_data = np.array([]) # SNR_data = snr[:, :, tmin:tmax] +BS_cross_section = np.array([]) # BS data limited with tmin and tmax values of spin box + # BS_data = stg.BS_raw_data[f, :, int(stg.tmin[f]):int(stg.tmax[f])] +BS_stream_bed = np.array([]) # BS_data_section = BS data in the section. Values NaN outside the bottom of the section are deleted +BS_noise_cross_section = np.array([]) # BS_noise_cros_section = BS_noise_data[:, :, tmin:tmax] (former Noise_data) +SNR_cross_section = np.array([]) # SNR_data = snr[:, :, tmin:tmax] t = np.array([]) t_snr = np.array([]) r_bottom = np.array([]) @@ -61,8 +66,10 @@ ind_bottom = np.array([]) freq_bottom_detection = 0 # --- Processed data in Signal Processing Tab --- -BS_data_section_SNR_filter = np.array([]) # BS data filtered with SNR values (remove point if SNR < value) -BS_data_section_averaged = np.array([]) # BS data averaged +BS_cross_section_SNR_filter = np.array([[[]]]) # BS data filtered with SNR values (remove point if SNR < value) - bottom is not detected +BS_stream_bed_SNR_filter = np.array([]) # BS data filtered with SNR values (remove point if SNR < value) - bottom is detected +BS_cross_section_averaged = np.array([[[]]]) # BS data averaged - bottom is not detected +BS_stream_bed_averaged = np.array([]) # BS data averaged - bottom is detected time_average = np.array([]) SNR_data_average = np.array([]) # SNR data computed with BS signal averaged (not with BS raw signal) @@ -119,9 +126,11 @@ kt_corrected = np.array([]) kt_corrected_2D = np.array([]) kt_corrected_3D = np.array([]) J_cross_section = np.array([]) +J_stream_bed = np.array([[[]]]) frequencies_to_compute_VBI = np.array([]) VBI_cross_section = np.array([]) +VBI_stream_bed = np.array([[[]]]) frequency_to_compute_SSC = 0 ks = 0