diff --git a/View/acoustic_inversion_tab.py b/View/acoustic_inversion_tab.py index 5d8a016..099eb38 100644 --- a/View/acoustic_inversion_tab.py +++ b/View/acoustic_inversion_tab.py @@ -21,6 +21,7 @@ # -*- coding: utf-8 -*- import os +import gc import logging import numpy as np import pandas as pd @@ -408,7 +409,7 @@ class AcousticInversionTab(QWidget): self.pushbutton_run_inversion\ .clicked.connect(self.function_run_inversion) self.pushbutton_save_result\ - .clicked.connect(self.save_result_in_excel_file) + .clicked.connect(self.save_result) self.pushbutton_left_to_begin_fine\ .clicked.connect(self.slider_profile_number_to_begin_fine) @@ -601,6 +602,7 @@ class AcousticInversionTab(QWidget): if self.figure_SSC_fine is not None: self.figure_SSC_fine.clear() + plt.close(fig=self.figure_SSC_fine) self.figure_SSC_fine, self.axis_SSC_fine = plt.subplots( nrows=1, ncols=1, layout="constrained" @@ -729,6 +731,7 @@ class AcousticInversionTab(QWidget): if self.figure_vertical_profile_SSC_fine is not None: self.figure_vertical_profile_SSC_fine.clear() + plt.close(fig=self.figure_vertical_profile_SSC_fine) fig, ax = plt.subplots(nrows=1, ncols=1, layout="constrained") self.figure_vertical_profile_SSC_fine = fig @@ -1013,6 +1016,7 @@ class AcousticInversionTab(QWidget): else: if self.figure_measured_vs_inverted_fine is not None: self.figure_measured_vs_inverted_fine.clear() + plt.close(fig=self.figure_measured_vs_inverted_fine) fig, ax = plt.subplots(nrows=1, ncols=1, layout="constrained") @@ -1156,6 +1160,7 @@ class AcousticInversionTab(QWidget): else: if self.figure_SSC_sand is not None: self.figure_SSC_sand.clear() + plt.close(fig=self.figure_SSC_sand) self.figure_SSC_sand, self.axis_SSC_sand = plt.subplots( nrows=1, ncols=1, layout="constrained" @@ -1283,6 +1288,7 @@ class AcousticInversionTab(QWidget): if self.figure_vertical_profile_SSC_sand is not None: self.figure_vertical_profile_SSC_sand.clear() + plt.close(fig=self.figure_vertical_profile_SSC_sand) fig, ax = plt.subplots( nrows=1, ncols=1, layout="constrained" @@ -1573,6 +1579,7 @@ class AcousticInversionTab(QWidget): if self.figure_measured_vs_inverted_sand is not None: self.figure_measured_vs_inverted_sand.clear() + plt.close(fig=self.figure_measured_vs_inverted_sand) fig, ax = plt.subplots(nrows=1, ncols=1, layout="constrained") self.figure_measured_vs_inverted_sand = fig @@ -1663,24 +1670,50 @@ class AcousticInversionTab(QWidget): self.figure_measured_vs_inverted_sand.canvas.draw_idle() - def save_result_in_excel_file(self): - if self.combobox_acoustic_data_choice.count() > 0: - name, _ = QFileDialog.getSaveFileName( - caption="Save As - Inversion results", - directory="", - filter="Excel Files (*.xlsx)", - options=QFileDialog.DontUseNativeDialog - ) + def save_result(self): + if self.combobox_acoustic_data_choice.count() <= 0: + return - if name == '': - return + file_type = { + "CSV Files (*.csv)": (self.save_result_in_csv_file, ".csv"), + "Excel Files (*.xlsx)": (self.save_result_in_excel_file, ".xlsx"), + # "LibreOffice Calc Files (*.ods)": (self.save_result_in_excel_file, ".ods"), + } - dirname = os.path.dirname(name) - filename = os.path.basename(name) - os.chdir(dirname) + name, type_ext = QFileDialog.getSaveFileName( + caption="Save As - Inversion results", + directory="", + filter=";;".join(file_type), + options=QFileDialog.DontUseNativeDialog + ) - results = [] + if name == '': + return + dirname = os.path.dirname(name) + filename = os.path.basename(name) + _, ext = os.path.splitext(filename) + + os.chdir(dirname) + + fun, t_ext = file_type[type_ext] + if t_ext not in filename: + filename += t_ext + + logger.info(f"Export results to {os.path.join(dirname, filename)}") + fun(dirname, filename) + logger.info(f"... export done") + + def save_result_in_excel_file(self, dirname, filename): + if ".ods" in filename: + engine = "odf" + else: + engine = 'xlsxwriter' + + with pd.ExcelWriter( + os.path.join(dirname, filename), + engine=engine + ) as writer: for k in range(self.combobox_acoustic_data_choice.count()): if stg.time_cross_section[k].shape != (0,): time_data = stg.time_cross_section @@ -1705,41 +1738,99 @@ class AcousticInversionTab(QWidget): for j in range(depth_data[k].shape[1]): r_id = i * depth_data[k].shape[1] + j - r[r_id] = ( - depth_data[k][ - int(stg.frequency_for_inversion[1]), j - ] - ) + r[r_id] = depth_data[k][ + int(stg.frequency_for_inversion[1]), j + ] if stg.SSC_fine[k].shape == (0,): stg.SSC_fine[k] = np.zeros(r.shape[0]) if stg.SSC_sand[k].shape == (0,): stg.SSC_sand[k] = np.zeros(r.shape[0]) - results.append( - pd.DataFrame( - { - 'Time (sec)': list(t), - 'Depth (m)': list(r), - 'SSC_fine (g/L)': list( - stg.SSC_fine[k].reshape(t.shape[0]) - ), - 'SSC_sand (g/L)': list( - stg.SSC_sand[k].reshape(t.shape[0]) - ), - } - ) + result = pd.DataFrame( + { + 'Time (sec)': list(t), + 'Depth (m)': list(r), + 'SSC_fine (g/L)': list( + stg.SSC_fine[k].reshape(t.shape[0]) + ), + 'SSC_sand (g/L)': list( + stg.SSC_sand[k].reshape(t.shape[0]) + ), + } ) - if os.path.splitext(filename)[1] != ".xlsx": - filename += ".xlsx" + gc.collect() # Force garbade collection - with pd.ExcelWriter( - os.path.join(dirname, filename) - ) as writer: - for k in range(self.combobox_acoustic_data_choice.count()): - results[k].to_excel( - writer, index=False, - engine='xlsxwriter', na_rep='NA', - sheet_name=stg.data_preprocessed[k], + result.to_excel( + writer, index=False, na_rep='NA', + sheet_name=stg.data_preprocessed[k], + ) + + def save_result_in_csv_file(self, dirname, filename): + d_id = [] + t = [] + r = [] + ssc_fine = [] + ssc_sand = [] + + for k in range(self.combobox_acoustic_data_choice.count()): + if stg.time_cross_section[k].shape != (0,): + time_data = stg.time_cross_section + else: + time_data = stg.time + + if stg.depth_cross_section[k].shape != (0,): + depth_data = stg.depth_cross_section + else: + depth_data = stg.depth + + time_shape = time_data[k].shape[1] + depth_shape = depth_data[k].shape[1] + + d_id += np.repeat(k, depth_shape * time_shape).tolist() + + tmp_t = np.repeat( + time_data[k][stg.frequency_for_inversion[1]], + depth_shape + ) + + tmp_r = np.zeros( + depth_shape * time_shape + ) + + for i in range(time_shape): + for j in range(depth_shape): + r_id = i * depth_shape + j + + tmp_r[r_id] = ( + depth_data[k][ + int(stg.frequency_for_inversion[1]), j + ] ) + + t += tmp_t.tolist() + r += tmp_r.tolist() + + if stg.SSC_fine[k].shape == (0,): + stg.SSC_fine[k] = np.zeros(tmp_r.shape[0]) + if stg.SSC_sand[k].shape == (0,): + stg.SSC_sand[k] = np.zeros(tmp_r.shape[0]) + + ssc_fine += stg.SSC_fine[k].reshape(tmp_r.shape[0]).tolist() + ssc_sand += stg.SSC_sand[k].reshape(tmp_r.shape[0]).tolist() + + results = pd.DataFrame( + { + 'acoustic data': d_id, + 'Time (sec)': t, + 'Depth (m)': r, + 'SSC_fine (g/L)': ssc_fine, + 'SSC_sand (g/L)': ssc_sand, + } + ) + + results.to_csv( + os.path.join(dirname, filename), + index=False + )