Compare commits

..

No commits in common. "60b367b7ef0ebce0ff6bac3c5d170b1dbcf1e618" and "225c40c6c1c49612528defaa3a5f3a1d58163a7c" have entirely different histories.

7 changed files with 184 additions and 230 deletions

View File

@ -2,9 +2,7 @@
AcouSed for **Acou**stic Backscattering for Concentration of Suspended **Sed**iments in Rivers is a software developped by INRAE, in collaboation with CNR. AcouSed for **Acou**stic Backscattering for Concentration of Suspended **Sed**iments in Rivers is a software developped by INRAE, in collaboation with CNR.
<p> ![](icons/Logo-INRAE.jpg)
<img src="logos/AcouSed.png" align="center" width=20% height=20% >
</p>
It is divided in six tabs: It is divided in six tabs:
- Acoustic data : acoustic raw data are downloaded and visualised - Acoustic data : acoustic raw data are downloaded and visualised
@ -15,39 +13,14 @@ It is divided in six tabs:
## Installation ## Installation
### Standalone software
AcouSed can be launched with python installation. An executable is available on [River Hydraulics](https://riverhydraulics.riverly.inrae.fr/outils/logiciels-pour-la-mesure/acoused) teams website.
The user needs to download the folder "acoused-packaging" including :
- icons and logos folder
- _internal folder (python packages)
- executable file
- calibration constant file
- documentation
Acoused.exe file must be launched from this folder.
Test data can be dowloaded from the [INRAE nextcloud](https://nextcloud.inrae.fr/s/3zZdieztrx7nwYa)
### Python environment
Acoused is developped for Linux and Windows on Python version 3.8 or Acoused is developped for Linux and Windows on Python version 3.8 or
greater. By default, Acoused is developped with Pypi package greater. By default, Acoused is developped with Pypi package
dependencies, but is also possible to use Guix package manager to run dependencies, but is also possible to use Guix package manager to run
Acoused. Acoused.
#### Windows ### **TODO** Windows
You can use Pypi to get correct software environment and run the ### Linux
program.
```shell
python -m venv env
env\Scripts\activate.bat
python -m pip install -U -r ..\virtualenv\requirements.txt
python main.py
```
#### Linux
You can use Pypi to get correct software environment and run the You can use Pypi to get correct software environment and run the
program. program.
@ -59,7 +32,7 @@ program.
python3 main.py python3 main.py
``` ```
#### Linux with Guix ### Linux with Guix
To run Acoused within a [GNU Guix](https://guix.gnu.org/) software To run Acoused within a [GNU Guix](https://guix.gnu.org/) software
environment, you need Guix installed on your computer and run the environment, you need Guix installed on your computer and run the
@ -89,44 +62,15 @@ script `guix.sh` to run the program.
If you have any questions or suggestions, please contact us to celine.berni@inrae.fr and/or jerome.lecoz@inrae.fr. If you have any questions or suggestions, please contact us to celine.berni@inrae.fr and/or jerome.lecoz@inrae.fr.
## Acknowledgment ## Acknowledgment (Funding)
This study was conducted within the [Rhône Sediment Observatory](https://observatoire-sediments-rhone.fr/) (OSR), a multi-partner research program funded through the Plan Rhône by the European Regional Development Fund (ERDF), Agence de lEau RMC, CNR, EDF and three regional councils (Auvergne-Rhône-Alpes, PACA and Occitanie).
<p>
<img src="logos/OSR.png" align="center" width=10% height=10% >
</p>
## Industrial partners
[CNR](https://www.cnr.tm.fr/)
<p>
<img src="logos/CNR.png" align="center" width=10% height=10% >
</p>
[UBERTONE](https://ubertone.com/)
<p>
<img src="logos/Ubertone.jpeg" align="center" width=10% height=10% >
</p>
[EDF](https://www.edf.fr/hydraulique-isere-drome)
<p>
<img src="logos/EDF.png" align="center" width=10% height=10% >
</p>
This study was conducted within the [Rhône Sediment Observatory](https://observatoire-sediments-rhone.fr/) (OSR), a multi-partner research program funded through the Plan Rhône by the European Regional Development Fund (ERDF), Agence de lEau RMC, CNR, EDF and three regional councils (Auvergne-Rhône-Alpes, PACA and Occitanie). It was also support by CNR.
## License ## License
AcouSed AcouSed
Copyright (C) 2024-2025 - INRAE Copyright (C) 2024-2025 - INRAE
<p>
<img src="logos/BlocMarque-INRAE-Inter.jpg" align="center" width=10% height=10% >
</p>
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

View File

@ -1569,10 +1569,6 @@ class SedimentCalibrationTab(QWidget):
self._data_validity_message_box() self._data_validity_message_box()
return return
if len(stg.fine_sample_profile) == 0:
self._data_validity_message_box()
return
data_choice = self.combobox_acoustic_data_choice\ data_choice = self.combobox_acoustic_data_choice\
.currentIndex() .currentIndex()
@ -1663,8 +1659,8 @@ class SedimentCalibrationTab(QWidget):
.scaledToHeight(32, Qt.SmoothTransformation) .scaledToHeight(32, Qt.SmoothTransformation)
) )
msgBox.setText( msgBox.setText(
"Please select and valid the find and sand" "Please select and valid the sample data with"
+ "sample data with click on 'sample plot' button" + "click on 'sample plot' button"
) )
msgBox.setStandardButtons(QMessageBox.Ok) msgBox.setStandardButtons(QMessageBox.Ok)
msgBox.exec() msgBox.exec()

View File

@ -462,20 +462,18 @@ class SignalProcessingTab(QWidget):
self.pushbutton_clear_noise_data.clicked.connect(self.clear_noise_data) self.pushbutton_clear_noise_data.clicked.connect(self.clear_noise_data)
self.pushbutton_plot_profile_tail.clicked.connect(self.compute_average_profile_tail) self.pushbutton_plot_profile_tail.clicked.connect(self.compute_average_profile_tail)
self.pushbutton_plot_profile_tail.clicked.connect(self.replot) self.pushbutton_plot_profile_tail.clicked.connect(self.plot_averaged_profile_tail)
self.pushbutton_apply_noise_from_profile_tail.clicked.connect(self.plot_averaged_profile_tail)
self.pushbutton_apply_noise_from_profile_tail.clicked.connect(self.compute_noise_from_profile_tail_value) self.pushbutton_apply_noise_from_profile_tail.clicked.connect(self.compute_noise_from_profile_tail_value)
self.pushbutton_apply_noise_from_profile_tail.clicked.connect(self.replot)
self.combobox_freq_noise_from_profile_tail.currentIndexChanged.connect(self.compute_average_profile_tail) self.combobox_freq_noise_from_profile_tail.currentIndexChanged.connect(self.compute_average_profile_tail)
self.combobox_freq_noise_from_profile_tail.currentIndexChanged.connect(self.plot_averaged_profile_tail) self.combobox_freq_noise_from_profile_tail.currentIndexChanged.connect(self.plot_averaged_profile_tail)
self.pushbutton_Apply_SNR_filter.clicked.connect(self.remove_point_with_snr_filter) self.pushbutton_Apply_SNR_filter.clicked.connect(self.remove_point_with_snr_filter)
self.pushbutton_Apply_SNR_filter.clicked.connect(self.replot)
self.lineEdit_horizontal_average.returnPressed.connect(self.update_label_cells_sec) self.lineEdit_horizontal_average.returnPressed.connect(self.update_label_cells_sec)
self.pushbutton_average.clicked.connect(self.compute_averaged_BS_data) self.pushbutton_average.clicked.connect(self.compute_averaged_BS_data)
self.pushbutton_average.clicked.connect(self.replot)
self.pushbutton_slider_left_to_begin.clicked.connect(self.slide_profile_number_to_begin) self.pushbutton_slider_left_to_begin.clicked.connect(self.slide_profile_number_to_begin)
@ -554,34 +552,14 @@ class SignalProcessingTab(QWidget):
stg.freq_text[data_id] stg.freq_text[data_id]
) )
self.recompute() self.compute_average_profile_tail()
self.replot() self.plot_averaged_profile_tail()
logger.debug("Update the Signal preprocessing tab... Done") logger.debug("Update the Signal preprocessing tab... Done")
self.combobox_freq_noise_from_profile_tail.blockSignals(False) self.combobox_freq_noise_from_profile_tail.blockSignals(False)
self.combobox_acoustic_data_choice.blockSignals(False) self.combobox_acoustic_data_choice.blockSignals(False)
def recompute(self):
data_id = self.combobox_acoustic_data_choice.currentIndex()
self.compute_average_profile_tail()
if stg.noise_method[data_id] == 0:
if stg.filename_BS_noise_data[data_id] != "":
self.load_noise_data_and_compute_SNR()
elif stg.noise_method[data_id] == 1:
self.compute_noise_from_profile_tail_value()
self.remove_point_with_snr_filter()
self.compute_averaged_BS_data()
def replot(self):
self.plot_averaged_profile_tail()
self.plot_transect_with_SNR_data()
self.plot_pre_processed_BS_signal()
self.plot_pre_processed_profile()
def activate_list_of_pre_processed_data(self): def activate_list_of_pre_processed_data(self):
for i in range(self.combobox_acoustic_data_choice.count()): for i in range(self.combobox_acoustic_data_choice.count()):
eval("self.lineEdit_list_pre_processed_data_" + str(i) + ".setDisabled(True)") eval("self.lineEdit_list_pre_processed_data_" + str(i) + ".setDisabled(True)")
@ -646,7 +624,8 @@ class SignalProcessingTab(QWidget):
self.animation_groupbox_option_profile_tail.start() self.animation_groupbox_option_profile_tail.start()
# ------------------------------------------------------ # ------------------------------------------------------
def compute_average_profile_tail(self): @trace
def compute_average_profile_tail(self, *args):
data_id = self.combobox_acoustic_data_choice.currentIndex() data_id = self.combobox_acoustic_data_choice.currentIndex()
freq_noise_id = self.combobox_freq_noise_from_profile_tail.currentIndex() freq_noise_id = self.combobox_freq_noise_from_profile_tail.currentIndex()
@ -711,7 +690,11 @@ class SignalProcessingTab(QWidget):
) )
) )
def plot_averaged_profile_tail(self): if stg.BS_noise_raw_data[data_id].shape != (0,):
self.compute_noise_from_profile_tail_value()
@trace
def plot_averaged_profile_tail(self, *args):
# --- Plot averaged signal --- # --- Plot averaged signal ---
@ -778,19 +761,20 @@ class SignalProcessingTab(QWidget):
# ------------------------------------------------------ # ------------------------------------------------------
def combobox_acoustic_data_choice_change_index(self): def combobox_acoustic_data_choice_change_index(self):
self.combobox_frequency_profile.blockSignals(True)
self.compute_average_profile_tail() self.compute_average_profile_tail()
self.plot_averaged_profile_tail()
self.lineEdit_SNR_criterion.setText(str(stg.SNR_filter_value[self.combobox_acoustic_data_choice.currentIndex()])) self.lineEdit_SNR_criterion.setText(str(stg.SNR_filter_value[self.combobox_acoustic_data_choice.currentIndex()]))
self.plot_transect_with_SNR_data()
self.plot_pre_processed_BS_signal()
self.lineEdit_horizontal_average.setText(str(stg.Nb_cells_to_average_BS_signal[self.combobox_acoustic_data_choice.currentIndex()])) self.lineEdit_horizontal_average.setText(str(stg.Nb_cells_to_average_BS_signal[self.combobox_acoustic_data_choice.currentIndex()]))
self.combobox_frequency_profile.clear() self.combobox_frequency_profile.clear()
self.combobox_frequency_profile.addItems( self.combobox_frequency_profile.addItems(
[f for f in stg.freq_text[self.combobox_acoustic_data_choice.currentIndex()]]) [f for f in stg.freq_text[self.combobox_acoustic_data_choice.currentIndex()]])
self.plot_pre_processed_profile()
self.replot()
if self.combobox_acoustic_data_choice.count() > 0: if self.combobox_acoustic_data_choice.count() > 0:
@ -800,11 +784,12 @@ class SignalProcessingTab(QWidget):
eval("self.lineEdit_list_pre_processed_data_" + str( eval("self.lineEdit_list_pre_processed_data_" + str(
self.combobox_acoustic_data_choice.currentIndex()) + ".setEnabled(True)") self.combobox_acoustic_data_choice.currentIndex()) + ".setEnabled(True)")
self.combobox_frequency_profile.blockSignals(False)
def clear_noise_data(self): def clear_noise_data(self):
if len(stg.filename_BS_raw_data) == 0: if len(stg.filename_BS_raw_data) == 0:
pass pass
else: else:
stg.BS_noise_raw_data[self.combobox_acoustic_data_choice.currentIndex()] = np.array([]) stg.BS_noise_raw_data[self.combobox_acoustic_data_choice.currentIndex()] = np.array([])
@ -1044,7 +1029,7 @@ class SignalProcessingTab(QWidget):
stg.SNR_cross_section[self.combobox_acoustic_data_choice.currentIndex()] = ( stg.SNR_cross_section[self.combobox_acoustic_data_choice.currentIndex()] = (
np.divide((stg.BS_cross_section[self.combobox_acoustic_data_choice.currentIndex()] np.divide((stg.BS_cross_section[self.combobox_acoustic_data_choice.currentIndex()]
- stg.BS_noise_raw_data[self.combobox_acoustic_data_choice.currentIndex()]) ** 2, - stg.BS_noise_raw_data[self.combobox_acoustic_data_choice.currentIndex()]) ** 2,
stg.BS_noise_raw_data[self.combobox_acoustic_data_choice.currentIndex()] ** 2)) # stg.BS_noise_raw_data[self.combobox_acoustic_data_choice.currentIndex()] ** 2))
else: else:
@ -1075,9 +1060,14 @@ class SignalProcessingTab(QWidget):
else: else:
self.slider.setMaximum(stg.time[self.combobox_acoustic_data_choice.currentIndex()].shape[1]) self.slider.setMaximum(stg.time[self.combobox_acoustic_data_choice.currentIndex()].shape[1])
self.plot_transect_with_SNR_data()
self.plot_pre_processed_BS_signal()
self.plot_pre_processed_profile()
# self.activate_list_of_pre_processed_data() # self.activate_list_of_pre_processed_data()
def plot_noise(self): @trace
def plot_noise(self, *args):
self.horizontalLayout_groupbox_plot_noise_data.removeWidget(self.canvas_noise) self.horizontalLayout_groupbox_plot_noise_data.removeWidget(self.canvas_noise)
self.fig_noise, self.axis_noise = plt.subplots(nrows=1, ncols=1, layout="constrained") self.fig_noise, self.axis_noise = plt.subplots(nrows=1, ncols=1, layout="constrained")
@ -1108,7 +1098,8 @@ class SignalProcessingTab(QWidget):
self.axis_noise.tick_params(axis='both', which='minor', labelsize=10) self.axis_noise.tick_params(axis='both', which='minor', labelsize=10)
def plot_transect_with_SNR_data(self): @trace
def plot_transect_with_SNR_data(self, *args):
# --- Condition if table is not filled --- # --- Condition if table is not filled ---
# if not self.lineEdit_noise_file.text(): # if not self.lineEdit_noise_file.text():
if len(stg.BS_noise_raw_data) == 0: if len(stg.BS_noise_raw_data) == 0:
@ -1300,8 +1291,6 @@ class SignalProcessingTab(QWidget):
self.verticalLayout_groupbox_plot_SNR.addWidget(self.scroll_SNR) self.verticalLayout_groupbox_plot_SNR.addWidget(self.scroll_SNR)
def remove_point_with_snr_filter(self): def remove_point_with_snr_filter(self):
if self.lineEdit_SNR_criterion.text() == '':
return
if len(stg.filename_BS_raw_data) == 0: if len(stg.filename_BS_raw_data) == 0:
msgBox = QMessageBox() msgBox = QMessageBox()
@ -1320,34 +1309,33 @@ class SignalProcessingTab(QWidget):
msgBox.exec() msgBox.exec()
else: else:
data_id = self.combobox_acoustic_data_choice.currentIndex()
stg.SNR_filter_value[data_id] = ( stg.SNR_filter_value[self.combobox_acoustic_data_choice.currentIndex()] = (
float(self.lineEdit_SNR_criterion.text().replace(",", "."))) float(self.lineEdit_SNR_criterion.text().replace(",", ".")))
if stg.BS_stream_bed[data_id].shape != (0,): if stg.BS_stream_bed[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):
stg.BS_stream_bed_pre_process_SNR = deepcopy(stg.BS_stream_bed) stg.BS_stream_bed_pre_process_SNR = deepcopy(stg.BS_stream_bed)
for f, _ in enumerate(stg.freq[data_id]): for f, _ in enumerate(stg.freq[self.combobox_acoustic_data_choice.currentIndex()]):
stg.BS_stream_bed_pre_process_SNR[data_id][ stg.BS_stream_bed_pre_process_SNR[self.combobox_acoustic_data_choice.currentIndex()][
f, f,
np.where(stg.SNR_stream_bed[data_id][f, :, :] < np.where(stg.SNR_stream_bed[self.combobox_acoustic_data_choice.currentIndex()][f, :, :] <
float(self.lineEdit_SNR_criterion.text().replace(",", ".")))[0], float(self.lineEdit_SNR_criterion.text().replace(",", ".")))[0],
np.where(stg.SNR_stream_bed[data_id][f, :, :] < np.where(stg.SNR_stream_bed[self.combobox_acoustic_data_choice.currentIndex()][f, :, :] <
float(self.lineEdit_SNR_criterion.text().replace(",", ".")))[1]] \ float(self.lineEdit_SNR_criterion.text().replace(",", ".")))[1]] \
= np.nan = np.nan
elif stg.BS_cross_section[data_id].shape != (0,): elif stg.BS_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):
stg.BS_cross_section_pre_process_SNR = deepcopy(stg.BS_cross_section) stg.BS_cross_section_pre_process_SNR = deepcopy(stg.BS_cross_section)
for f, _ in enumerate(stg.freq[data_id]): for f, _ in enumerate(stg.freq[self.combobox_acoustic_data_choice.currentIndex()]):
stg.BS_cross_section_pre_process_SNR[data_id][ stg.BS_cross_section_pre_process_SNR[self.combobox_acoustic_data_choice.currentIndex()][
f, f,
np.where(stg.SNR_cross_section[data_id][f, :, np.where(stg.SNR_cross_section[self.combobox_acoustic_data_choice.currentIndex()][f, :,
:] < float(self.lineEdit_SNR_criterion.text().replace(",", ".")))[0], :] < float(self.lineEdit_SNR_criterion.text().replace(",", ".")))[0],
np.where(stg.SNR_cross_section[data_id][f, :, np.where(stg.SNR_cross_section[self.combobox_acoustic_data_choice.currentIndex()][f, :,
:] < float(self.lineEdit_SNR_criterion.text().replace(",", ".")))[1]] \ :] < float(self.lineEdit_SNR_criterion.text().replace(",", ".")))[1]] \
= np.nan = np.nan
@ -1355,18 +1343,20 @@ class SignalProcessingTab(QWidget):
stg.BS_raw_data_pre_process_SNR = deepcopy(stg.BS_raw_data) stg.BS_raw_data_pre_process_SNR = deepcopy(stg.BS_raw_data)
for f, _ in enumerate(stg.freq[data_id]): for f, _ in enumerate(stg.freq[self.combobox_acoustic_data_choice.currentIndex()]):
stg.BS_raw_data_pre_process_SNR[data_id][ stg.BS_raw_data_pre_process_SNR[self.combobox_acoustic_data_choice.currentIndex()][
f, f,
np.where(stg.SNR_raw_data[data_id][f, :, np.where(stg.SNR_raw_data[self.combobox_acoustic_data_choice.currentIndex()][f, :,
:] < float(self.lineEdit_SNR_criterion.text().replace(",", ".")))[0], :] < float(self.lineEdit_SNR_criterion.text().replace(",", ".")))[0],
np.where(stg.SNR_raw_data[data_id][f, :, np.where(stg.SNR_raw_data[self.combobox_acoustic_data_choice.currentIndex()][f, :,
:] < float(self.lineEdit_SNR_criterion.text().replace(",", ".")))[1]] \ :] < float(self.lineEdit_SNR_criterion.text().replace(",", ".")))[1]] \
= np.nan = np.nan
self.compute_averaged_BS_data() self.compute_averaged_BS_data()
self.update_plot_pre_processed_profile()
def plot_pre_processed_BS_signal(self): @trace
def plot_pre_processed_BS_signal(self, *args):
data_id = self.combobox_acoustic_data_choice.currentIndex() data_id = self.combobox_acoustic_data_choice.currentIndex()
self.lineEdit_horizontal_average.setText( self.lineEdit_horizontal_average.setText(
@ -1410,31 +1400,31 @@ class SignalProcessingTab(QWidget):
x_time = stg.time[data_id] x_time = stg.time[data_id]
y_depth = stg.depth[data_id] y_depth = stg.depth[data_id]
logger.debug(f"x_time: {x_time[data_id].shape}")
logger.debug(f"y_depth: {y_depth[data_id].shape}")
for f, _ in enumerate(stg.freq[data_id]): for f, _ in enumerate(stg.freq[data_id]):
bed = False
if stg.BS_stream_bed_pre_process_average[data_id].shape != (0,): if stg.BS_stream_bed_pre_process_average[data_id].shape != (0,):
BS_data = stg.BS_stream_bed_pre_process_average BS_data = stg.BS_stream_bed_pre_process_average
bed = True
elif stg.BS_cross_section_pre_process_average[data_id].shape != (0,): elif stg.BS_cross_section_pre_process_average[data_id].shape != (0,):
BS_data = stg.BS_cross_section_pre_process_average BS_data = stg.BS_cross_section_pre_process_average
elif stg.BS_raw_data_pre_process_average[data_id].shape != (0,): elif stg.BS_raw_data_pre_process_average[data_id].shape != (0,):
BS_data = stg.BS_raw_data_pre_process_average BS_data = stg.BS_raw_data_pre_process_average
elif stg.BS_stream_bed_pre_process_SNR[data_id].shape != (0,): elif stg.BS_stream_bed_pre_process_SNR[data_id].shape != (0,):
BS_data = stg.BS_stream_bed_pre_process_SNR BS_data = stg.BS_stream_bed_pre_process_SNR
bed = True
elif stg.BS_cross_section_pre_process_SNR[data_id].shape != (0,): elif stg.BS_cross_section_pre_process_SNR[data_id].shape != (0,):
BS_data = stg.BS_cross_section_pre_process_SNR BS_data = stg.BS_cross_section_pre_process_SNR
elif stg.BS_raw_data_pre_process_SNR[data_id].shape != (0,): elif stg.BS_raw_data_pre_process_SNR[data_id].shape != (0,):
BS_data = stg.BS_raw_data_pre_process_SNR BS_data = stg.BS_raw_data_pre_process_SNR
elif stg.BS_stream_bed[data_id].shape != (0,): elif stg.BS_stream_bed[data_id].shape != (0,):
BS_data = stg.BS_stream_bed BS_data = stg.BS_stream_bed
bed = True
elif stg.BS_cross_section[data_id].shape != (0,): elif stg.BS_cross_section[data_id].shape != (0,):
BS_data = stg.BS_cross_section BS_data = stg.BS_cross_section
elif stg.BS_raw_data[data_id].shape != (0,): elif stg.BS_raw_data[data_id].shape != (0,):
BS_data = stg.BS_raw_data BS_data = stg.BS_raw_data
logger.debug(f"BS_data: {BS_data[data_id].shape}")
val_min = np.nanmin( val_min = np.nanmin(
BS_data[data_id][f, :, :] BS_data[data_id][f, :, :]
) )
@ -1451,7 +1441,7 @@ class SignalProcessingTab(QWidget):
cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max) cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max)
) )
if stg.depth_bottom[data_id].shape != (0,): if bed:
self.axis_BS[f].plot( self.axis_BS[f].plot(
x_time[f, :], -stg.depth_bottom[data_id], x_time[f, :], -stg.depth_bottom[data_id],
color='black', linewidth=1, linestyle="solid" color='black', linewidth=1, linestyle="solid"
@ -1499,6 +1489,7 @@ class SignalProcessingTab(QWidget):
.addWidget(self.scroll_BS) .addWidget(self.scroll_BS)
def update_label_cells_sec(self): def update_label_cells_sec(self):
print("Je change la valeur du moyennage") print("Je change la valeur du moyennage")
print(stg.nb_profiles_per_sec) print(stg.nb_profiles_per_sec)
print(stg.nb_profiles_per_sec[self.combobox_acoustic_data_choice.currentIndex()][0]) print(stg.nb_profiles_per_sec[self.combobox_acoustic_data_choice.currentIndex()][0])
@ -1511,6 +1502,7 @@ class SignalProcessingTab(QWidget):
" sec") " sec")
def compute_averaged_BS_data(self): def compute_averaged_BS_data(self):
if len(stg.filename_BS_raw_data) == 0: if len(stg.filename_BS_raw_data) == 0:
msgBox = QMessageBox() msgBox = QMessageBox()
msgBox.setWindowTitle("Compute noise from profile tail error") msgBox.setWindowTitle("Compute noise from profile tail error")
@ -1518,6 +1510,7 @@ class SignalProcessingTab(QWidget):
msgBox.setText("Download acoustic data in previous tab before applying SNR filter") msgBox.setText("Download acoustic data in previous tab before applying SNR filter")
msgBox.setStandardButtons(QMessageBox.Ok) msgBox.setStandardButtons(QMessageBox.Ok)
msgBox.exec() msgBox.exec()
elif len(stg.BS_noise_raw_data) == 0: elif len(stg.BS_noise_raw_data) == 0:
msgBox = QMessageBox() msgBox = QMessageBox()
msgBox.setWindowTitle("SNR filter Error") msgBox.setWindowTitle("SNR filter Error")
@ -1525,96 +1518,111 @@ class SignalProcessingTab(QWidget):
msgBox.setText("Define noise data (file or profile tail) before using SNR filter") msgBox.setText("Define noise data (file or profile tail) before using SNR filter")
msgBox.setStandardButtons(QMessageBox.Ok) msgBox.setStandardButtons(QMessageBox.Ok)
msgBox.exec() msgBox.exec()
else: else:
data_id = self.combobox_acoustic_data_choice.currentIndex() data_id = self.combobox_acoustic_data_choice.currentIndex()
kernel_avg = np.ones( kernel_avg = np.ones(2 * int(float(self.lineEdit_horizontal_average.text().replace(",", "."))) + 1)
2 * int( print(kernel_avg)
float(
self.lineEdit_horizontal_average\
.text()\
.replace(",", ".")
)
) + 1
)
logger.debug(f"kernel_avg: {kernel_avg}")
stg.Nb_cells_to_average_BS_signal[data_id] = ( stg.Nb_cells_to_average_BS_signal[data_id] = (
float( float(self.lineEdit_horizontal_average.text().replace(",", ".")))
self.lineEdit_horizontal_average\
.text().replace(",", ".")
)
)
if stg.time_cross_section[data_id].shape != (0,): if stg.time_cross_section[data_id].shape != (0,):
if stg.depth_cross_section[data_id].shape != (0,): if stg.depth_cross_section[data_id].shape != (0,):
x_time = stg.time_cross_section[data_id] x_time = stg.time_cross_section[data_id]
y_depth = stg.depth_cross_section[data_id] y_depth = stg.depth_cross_section[data_id]
elif stg.depth[data_id].shape != (0,): elif stg.depth[data_id].shape != (0,):
x_time = stg.time_cross_section[data_id] x_time = stg.time_cross_section[data_id]
y_depth = stg.depth[data_id] y_depth = stg.depth[data_id]
else: else:
if stg.depth_cross_section[data_id].shape != (0,): if stg.depth_cross_section[data_id].shape != (0,):
x_time = stg.time[data_id] x_time = stg.time[data_id]
y_depth = stg.depth_cross_section[data_id] y_depth = stg.depth_cross_section[data_id]
elif stg.depth[data_id].shape != (0,): elif stg.depth[data_id].shape != (0,):
x_time = stg.time[data_id] x_time = stg.time[data_id]
y_depth = stg.depth[data_id] y_depth = stg.depth[data_id]
BS = [ if stg.BS_stream_bed_pre_process_SNR[data_id].shape != (0,):
stg.BS_stream_bed_pre_process_SNR,
stg.BS_cross_section_pre_process_SNR,
stg.BS_raw_data_pre_process_SNR,
stg.BS_stream_bed,
stg.BS_cross_section,
stg.BS_raw_data,
]
BS_ppa = [ stg.BS_stream_bed_pre_process_average[data_id] = (deepcopy(
stg.BS_stream_bed_pre_process_average, stg.BS_stream_bed_pre_process_SNR[data_id]))
stg.BS_cross_section_pre_process_average,
stg.BS_raw_data_pre_process_average,
stg.BS_stream_bed_pre_process_average,
stg.BS_cross_section_pre_process_average,
stg.BS_raw_data_pre_process_average,
]
time_shape, = x_time[data_id].shape for f, _ in enumerate(stg.freq[data_id]):
depth_shape, = y_depth[data_id].shape for i in range(y_depth.shape[1]):
logger.debug(f"time_shape: {time_shape}")
logger.debug(f"depth_shape: {depth_shape}")
BS_data = stg.BS_raw_data stg.BS_stream_bed_pre_process_average[data_id][f, i, :] = (
BS_data_ppa = stg.BS_raw_data_pre_process_average convolve(stg.BS_stream_bed_pre_process_SNR[data_id][f, i, :],
for i in range(len(BS)): kernel_avg))
bs = BS[i]
logger.debug(f"BS data shape {bs[data_id].shape}")
if bs[data_id].shape == (0,):
continue
x, y, z = bs[data_id].shape elif stg.BS_cross_section_pre_process_SNR[data_id].shape != (0,):
if y == depth_shape and z == time_shape:
BS_data = bs
BS_data_ppa = BS_ppa[i]
break
logger.debug(f"BS_data: {BS_data[data_id].shape}") stg.BS_cross_section_pre_process_average[data_id] = (deepcopy(
stg.BS_cross_section_pre_process_SNR[data_id]))
BS_data_ppa[data_id] = deepcopy(BS_data[data_id]) for f, _ in enumerate(stg.freq[data_id]):
for i in range(y_depth.shape[1]):
for f, _ in enumerate(stg.freq[data_id]): stg.BS_cross_section_pre_process_average[data_id][f, i, :] = (
for i in range(y_depth.shape[1]): convolve(stg.BS_cross_section_pre_process_SNR[data_id][f, i, :],
BS_data_ppa[data_id][f, i, :] = ( kernel_avg))
convolve(
BS_data[data_id][f, i, :],
kernel_avg
)
)
logger.debug( elif stg.BS_raw_data_pre_process_SNR[data_id].shape != (0,):
f"BS_data_ppa: {BS_data_ppa[data_id].shape}"
)
def plot_pre_processed_profile(self): stg.BS_raw_data_pre_process_average[data_id] = (deepcopy(
stg.BS_raw_data_pre_process_SNR[data_id]))
for f, _ in enumerate(stg.freq[data_id]):
for i in range(y_depth.shape[1]):
stg.BS_raw_data_pre_process_average[data_id][f, i, :] = (
convolve(stg.BS_raw_data_pre_process_SNR[data_id][f, i, :],
kernel_avg))
elif stg.BS_stream_bed[data_id].shape != (0,):
stg.BS_stream_bed_pre_process_average[data_id] = (deepcopy(
stg.BS_stream_bed[data_id]))
for f, _ in enumerate(stg.freq[data_id]):
for i in range(y_depth.shape[1]):
stg.BS_stream_bed_pre_process_average[data_id][f, i, :] = (
convolve(stg.BS_stream_bed[data_id][f, i, :], kernel_avg))
elif stg.BS_cross_section[data_id].shape != (0,):
stg.BS_cross_section_pre_process_average[data_id] = (deepcopy(
stg.BS_cross_section[data_id]))
for f, _ in enumerate(stg.freq[data_id]):
for i in range(y_depth.shape[1]):
stg.BS_cross_section_pre_process_average[data_id][f, i, :] = (
convolve(stg.BS_cross_section[data_id][f, i, :],
kernel_avg))
elif stg.BS_raw_data[data_id].shape != (0,):
stg.BS_raw_data_pre_process_average[data_id] = (deepcopy(
stg.BS_raw_data[data_id]))
for f, _ in enumerate(stg.freq[data_id]):
for i in range(y_depth.shape[1]):
stg.BS_raw_data_pre_process_average[data_id][f, i, :] = (
convolve(stg.BS_raw_data[data_id][f, i, :], kernel_avg))
self.plot_pre_processed_BS_signal()
self.update_plot_pre_processed_profile()
@trace
def plot_pre_processed_profile(self, *args):
data_id = self.combobox_acoustic_data_choice.currentIndex() data_id = self.combobox_acoustic_data_choice.currentIndex()
if ((data_id != -1) and if ((data_id != -1) and

View File

@ -1,5 +0,0 @@
@ECHO OFF
start cmd /c test3\Acoused.exe

View File

@ -1,35 +0,0 @@
@ECHO OFF
rem Python environment (-U = update python packages / -r = texte file)
python -m pip install -U -r ..\virtualenv\requirements.txt
rem Build windows version
mkdir acoused_packaging
pyinstaller --name "acoused" ..\main.py -y
rem Icons
mkdir acoused_packaging\icons
copy /y ..\icons\*.png acoused_packaging\icons
rem Logos
mkdir acoused_packaging\logos
copy /y ..\logos\* acoused_packaging\logos
rem Doc
copy /y ..\ABS_calibration_constant_kt.xlsx acoused_packaging
copy /y ..\AcouSed_UserManual.pdf acoused_packaging
copy /y ..\Acoustic_Inversion_theory.pdf acoused_packaging
copy /y ..\Tutorial_AQUAscat_software.pdf acoused_packaging
rem move exe
move /y dist\AcouSed\acoused.exe acoused_packaging
move /y dist\acoused\_internal acoused_packaging
copy debug.bat acoused_packaging
rmdir /s /q build
rmdir /s /q dist
del /q AcouSed.spec
set PATH=%PATH%;C:\Program Files (x86)/7-Zip
7z a -tzip acoused_packaging.zip acoused_packaging

13
requirements.txt Normal file
View File

@ -0,0 +1,13 @@
matplotlib==3.6.3
numpy==1.23.5
pandas==1.5.3
PyQt5==5.15.9
PyQt5-Qt5==5.15.2
PyQt5-sip==12.11.0
python-dateutil==2.8.2
scikit-learn==1.2.1
scipy==1.10.0
pyqt-file-list-widget==0.0.1
qtrangeslider==0.1.5
astropy==6.1.7
odfpy==1.4.1

View File

@ -0,0 +1,33 @@
contourpy==1.0.7
cycler==0.11.0
defusedxml==0.7.1
et-xmlfile==1.1.0
fonttools==4.38.0
importlib-resources==5.12.0
joblib==1.2.0
kiwisolver==1.4.4
llvmlite==0.39.1
matplotlib==3.6.3
numba==0.56.4
numpy==1.23.5
odfpy==1.4.1
openpyxl==3.0.10
packaging==23.0
pandas==1.5.3
Pillow==9.4.0
profilehooks==1.12.0
pyparsing==3.0.9
pyqt-checkbox-table-widget==0.0.14
PyQt5==5.15.9
PyQt5-Qt5==5.15.2
PyQt5-sip==12.11.0
python-dateutil==2.8.2
pytz==2022.7.1
scikit-learn==1.2.1
scipy==1.10.0
six==1.16.0
threadpoolctl==3.1.0
utm==0.7.0
xlrd==2.0.1
xmltodict==0.13.0
zipp==3.15.0