From 9497627a961c9d354f57df9482c8fca1d06f799b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20M=C3=BCnker?= Date: Thu, 2 May 2024 17:26:51 +0200 Subject: [PATCH] =?UTF-8?q?improve=20error=20handling=20during=20file=20im?= =?UTF-8?q?port=20Signed-off-by:=20Christian=20M=C3=BCnker=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pyfda/libs/pyfda_io_lib.py | 14 ++++--- pyfda/plot_widgets/tran/tran_io.py | 63 ++++++++++++++++-------------- 2 files changed, 43 insertions(+), 34 deletions(-) diff --git a/pyfda/libs/pyfda_io_lib.py b/pyfda/libs/pyfda_io_lib.py index 1d119da6..46bdf241 100644 --- a/pyfda/libs/pyfda_io_lib.py +++ b/pyfda/libs/pyfda_io_lib.py @@ -729,7 +729,7 @@ def csv2array(f: TextIO): logger.error(f"Not enough data: '{data_arr}'") return None else: - return data_arr + data = data_arr elif np.ndim(data_arr) == 2: rows, cols = np.shape(data_arr) @@ -745,21 +745,24 @@ def csv2array(f: TextIO): csv2array.info_str = "T:" + csv2array.info_str if use_header: logger.info(f"Skipping header {data_arr.T[0]}") - return data_arr.T[1:] + data = data_arr.T[1:] else: - return data_arr.T + data = data_arr.T else: # column format logger.info(f"Building table with {cols} column(s) and {rows} rows.") if use_header: logger.info(f"Skipping header {data_arr[0]}") - return data_arr[1:] + data = data_arr[1:] else: - return data_arr + data = data_arr else: logger.error(f"Unsuitable data shape: ndim = {np.ndim(data_arr)}, " f"shape = { np.shape(data_arr)}") return None + csv2array.nchans = np.ndim(data) + return data + #------------------------------------------------------------------------------- def read_csv_info_old(filename): #------------------------------------------------------------------------------- @@ -999,6 +1002,7 @@ def load_data_np(file_name: str, file_type: str, fkey: str = "", as_str: bool = with open(file_name, 'r', newline=None) as f: data_arr = csv2array(f) load_data_np.info_str = csv2array.info_str + logger.error(f"load_data_np: {csv2array.info_str}") # data_arr = np.loadtxt(f, delimiter=params['CSV']['delimiter'].lower()) if data_arr is None: # an error has occurred diff --git a/pyfda/plot_widgets/tran/tran_io.py b/pyfda/plot_widgets/tran/tran_io.py index f0c7a2d6..9edfa594 100644 --- a/pyfda/plot_widgets/tran/tran_io.py +++ b/pyfda/plot_widgets/tran/tran_io.py @@ -154,6 +154,7 @@ def load_data_raw(self): When an error occurred, return -1. """ + # TODO: "test_row_ba_IIR_header.csv" fails to read, data should be unloaded file_type = (qget_cmb_box(self.ui.cmb_file_format),) # str -> tuple @@ -164,10 +165,11 @@ def load_data_raw(self): self, title="Select file for data import", mode="r", file_types=file_type) - if self.file_name is None: # operation cancelled + if self.file_name is None: # operation cancelled, restore previous settings self.file_name = file_name_prev self.file_type = file_type_prev qset_cmb_box(self.ui.cmb_file_format, self.file_type) + self.ui.set_ui_visibility() return -1 self.unload_data() # reset load and normalize button @@ -177,6 +179,7 @@ def load_data_raw(self): self.WL = None info_str = "" + err = False if self.file_type == 'wav': ret = io.read_wav_info(self.file_name) @@ -184,40 +187,51 @@ def load_data_raw(self): return -1 self.data_raw = io.load_data_np(self.file_name, 'wav') if self.data_raw is None: # an error occurred - return -1 - self.N = io.read_wav_info.N - self.nchans = io.read_wav_info.nchans - self.f_s_file = io.read_wav_info.f_S - self.WL = io.read_wav_info.WL - # info_str = f" x {self.WL * 8} bits," - info_str = f" x {io.read_wav_info.sample_format}," - self.ui.frm_f_s.setVisible(True) - self.ui.lbl_f_s_value.setText(str(self.f_s_file)) + err = True + else: + self.f_s_file = io.read_wav_info.f_S + self.WL = io.read_wav_info.WL + info_str = f" x {io.read_wav_info.sample_format}," + self.ui.lbl_f_s_value.setText(str(self.f_s_file)) elif self.file_type == 'csv': self.ui.frm_f_s.setVisible(False) self.data_raw = io.load_data_np(self.file_name, 'csv') if self.data_raw is None: - logger.error(f"Could not load '{self.file_name}'.") - qstyle_widget(self.ui.but_load, "error") - return -1 - - # self.N, self.nchans = np_shape(self.data_raw) - # if self.N in {None, 0}: # data is scalar, None or multidim - # qstyle_widget(self.ui.but_load, "error") - # logger.warning("Unsuitable data format") - # return -1 - info_str = f" ({io.load_data_np.info_str})" + err = True + else: + info_str = f" ({io.load_data_np.info_str})" else: logger.error(f"Unknown file format '{self.file_type}'") qstyle_widget(self.ui.but_load, "error") return -1 + if len(self.file_name) < 45: + self.ui.lbl_filename.setText(self.file_name) + else: + self.ui.lbl_filename.setText( + self.file_name[:10] + ' ... ' + self.file_name[-20:]) + self.ui.lbl_filename.setToolTip(self.file_name) + + if err: + logger.error(f"Could not load '{self.file_name}'.") + self.ui.lbl_shape_actual.setText("None") + qstyle_widget(self.ui.but_load, "error") + return -1 + + if np.ndim(self.data_raw) == 1: + self.N = len(self.data_raw) + self.nchans = 1 + else: + self.N = np.shape(self.data_raw)[0] + self.nchans = np.shape(self.data_raw)[1] + if self.nchans > 2: logger.warning( f"Unsuitable file format with {self.nchans} > 2 channels.") qstyle_widget(self.ui.but_load, "error") return -1 + elif self.nchans == 1: self.ui.lbl_chan_import.setVisible(False) self.ui.cmb_chan_import.setVisible(False) @@ -225,13 +239,6 @@ def load_data_raw(self): self.ui.lbl_chan_import.setVisible(True) self.ui.cmb_chan_import.setVisible(True) - if len(self.file_name) < 45: - self.ui.lbl_filename.setText(self.file_name) - else: - self.ui.lbl_filename.setText( - self.file_name[:10] + ' ... ' + self.file_name[-20:]) - - self.ui.lbl_filename.setToolTip(self.file_name) self.ui.lbl_shape_actual.setText( f"{self.nchans} x {self.N}{info_str}") return 0 @@ -274,8 +281,6 @@ def select_chan_normalize(self): logger.warning("No data loaded yet.") return None - logger.info(pprint_log(self.data_raw)) - if self.data_raw.ndim == 1: data = self.data_raw else: