diff --git a/gui/qt_window.py b/gui/qt_window.py index eb7ca92..ab1a34b 100644 --- a/gui/qt_window.py +++ b/gui/qt_window.py @@ -28,7 +28,6 @@ def capture(command): out, err, exitcode = capture([f'python', f'{pypef_root}/run.py', '--version']) version = re.findall(r"[-+]?(?:\d*\.*\d.*\d+)", str(out))[0] - button_style = """ QPushButton { border: 2px solid rgb(52, 59, 72); @@ -66,6 +65,7 @@ def __init__( else: self.pypef_root = pypef_root self.n_cores = 1 + self.regression_model = 'PLS' self.c = 0 self.setMinimumSize(QSize(200, 100)) self.setWindowTitle("PyPEF GUI") @@ -74,6 +74,8 @@ def __init__( # Texts ############################################################################# layout = QtWidgets.QGridLayout(self) self.version_text = QtWidgets.QLabel(f"PyPEF v. {version}", alignment=QtCore.Qt.AlignRight) + self.ncores_text = QtWidgets.QLabel("Single-/multiprocessing") + self.regression_model_text = QtWidgets.QLabel("Regression model") self.utils_text = QtWidgets.QLabel("Utilities") self.dca_text = QtWidgets.QLabel("DCA (Unsupervised)") self.hybrid_text = QtWidgets.QLabel("Hybrid") @@ -82,8 +84,11 @@ def __init__( self.hybrid_text = QtWidgets.QLabel("Hybrid (DCA-Supervised)") self.supervised_text = QtWidgets.QLabel("Supervised") - for txt in [self.version_text, self.utils_text, self.dca_text, self.hybrid_text, self.supervised_text, - self.hybrid_text_train_test, self.hybrid_text_predict, self.hybrid_text]: + for txt in [ + self.version_text, self.ncores_text, self.regression_model_text, + self.utils_text, self.dca_text, self.hybrid_text, self.supervised_text, + self.hybrid_text_train_test, self.hybrid_text_predict, self.hybrid_text + ]: txt.setStyleSheet(text_style) self.textedit_out = QtWidgets.QTextEdit(readOnly=True) @@ -95,9 +100,14 @@ def __init__( # Boxes ############################################################################# self.box_multicore = QtWidgets.QComboBox() self.box_multicore.addItems(['Single core', 'Multi core']) - self.box_multicore.currentIndexChanged.connect(self.selectionchange) + self.box_multicore.currentIndexChanged.connect(self.selection_ncores) self.box_multicore.setStyleSheet("color:white;background-color:rgb(54, 69, 79);") + self.box_regression_model = QtWidgets.QComboBox() + self.regression_models = ['PLS', 'PLS_LOOCV', 'Ridge', 'Lasso', 'ElasticNet', 'SVR', 'RF', 'MLP'] + self.box_regression_model.addItems(self.regression_models) + self.box_regression_model.currentIndexChanged.connect(self.selection_regression_model) + self.box_regression_model.setStyleSheet("color:white;background-color:rgb(54, 69, 79);") # Buttons ########################################################################### # Utilities self.button_help = QtWidgets.QPushButton("Help") @@ -120,63 +130,63 @@ def __init__( self.button_dca_inference_gremlin.clicked.connect(self.pypef_gremlin) self.button_dca_inference_gremlin.setStyleSheet(button_style) - self.button_dca_test_gremlin = QtWidgets.QPushButton("Test (GREMLIN)") - self.button_dca_test_gremlin.setMinimumWidth(80) - self.button_dca_test_gremlin.setToolTip( + self.button_dca_test_dca = QtWidgets.QPushButton("Test (DCA)") + self.button_dca_test_dca.setMinimumWidth(80) + self.button_dca_test_dca.setToolTip( "Test performance on any test dataset using the MSA-optimized GREMLIN model" ) - self.button_dca_test_gremlin.clicked.connect(self.pypef_gremlin_dca_test) - self.button_dca_test_gremlin.setStyleSheet(button_style) + self.button_dca_test_dca.clicked.connect(self.pypef_dca_test) + self.button_dca_test_dca.setStyleSheet(button_style) - self.button_dca_predict_gremlin = QtWidgets.QPushButton("Predict (GREMLIN)") - self.button_dca_predict_gremlin.setMinimumWidth(80) - self.button_dca_predict_gremlin.setToolTip( + self.button_dca_predict_dca = QtWidgets.QPushButton("Predict (DCA)") + self.button_dca_predict_dca.setMinimumWidth(80) + self.button_dca_predict_dca.setToolTip( "Predict any dataset using the MSA-optimized GREMLIN model" ) - self.button_dca_predict_gremlin.clicked.connect(self.pypef_gremlin_dca_predict) - self.button_dca_predict_gremlin.setStyleSheet(button_style) + self.button_dca_predict_dca.clicked.connect(self.pypef_dca_predict) + self.button_dca_predict_dca.setStyleSheet(button_style) # Hybrid - self.button_hybrid_train_gremlin = QtWidgets.QPushButton("Training (GREMLIN)") - self.button_hybrid_train_gremlin.setMinimumWidth(80) - self.button_hybrid_train_gremlin.setToolTip( + self.button_hybrid_train_dca = QtWidgets.QPushButton("Training (DCA)") + self.button_hybrid_train_dca.setMinimumWidth(80) + self.button_hybrid_train_dca.setToolTip( "Optimize the GREMLIN model by supervised training on variant-fitness labels" ) - self.button_hybrid_train_gremlin.clicked.connect(self.pypef_gremlin_hybrid_train) - self.button_hybrid_train_gremlin.setStyleSheet(button_style) + self.button_hybrid_train_dca.clicked.connect(self.pypef_dca_hybrid_train) + self.button_hybrid_train_dca.setStyleSheet(button_style) - self.button_hybrid_train_test_gremlin = QtWidgets.QPushButton("Train-Test (GREMLIN)") - self.button_hybrid_train_test_gremlin.setMinimumWidth(80) - self.button_hybrid_train_test_gremlin.setToolTip( + self.button_hybrid_train_test_dca = QtWidgets.QPushButton("Train-Test (DCA)") + self.button_hybrid_train_test_dca.setMinimumWidth(80) + self.button_hybrid_train_test_dca.setToolTip( "Optimize the GREMLIN model by supervised training on variant-fitness labels" ) - self.button_hybrid_train_test_gremlin.clicked.connect(self.pypef_gremlin_hybrid_train_test) - self.button_hybrid_train_test_gremlin.setStyleSheet(button_style) + self.button_hybrid_train_test_dca.clicked.connect(self.pypef_dca_hybrid_train_test) + self.button_hybrid_train_test_dca.setStyleSheet(button_style) - self.button_hybrid_train_test_gremlin = QtWidgets.QPushButton("Train-Test (GREMLIN)") - self.button_hybrid_train_test_gremlin.setMinimumWidth(80) - self.button_hybrid_train_test_gremlin.setToolTip( + self.button_hybrid_train_test_dca = QtWidgets.QPushButton("Train-Test (DCA)") + self.button_hybrid_train_test_dca.setMinimumWidth(80) + self.button_hybrid_train_test_dca.setToolTip( "Optimize the GREMLIN model by supervised training on variant-fitness labels and testing the model on a test set" ) - self.button_hybrid_train_test_gremlin.clicked.connect(self.pypef_gremlin_hybrid_train_test) - self.button_hybrid_train_test_gremlin.setStyleSheet(button_style) + self.button_hybrid_train_test_dca.clicked.connect(self.pypef_dca_hybrid_train_test) + self.button_hybrid_train_test_dca.setStyleSheet(button_style) - self.button_hybrid_test_gremlin = QtWidgets.QPushButton("Test (GREMLIN)") - self.button_hybrid_test_gremlin.setMinimumWidth(80) - self.button_hybrid_test_gremlin.setToolTip( + self.button_hybrid_test_dca = QtWidgets.QPushButton("Test (DCA)") + self.button_hybrid_test_dca.setMinimumWidth(80) + self.button_hybrid_test_dca.setToolTip( "Test the trained hybrid DCA model on a test set" ) - self.button_hybrid_test_gremlin.clicked.connect(self.pypef_gremlin_hybrid_test) - self.button_hybrid_test_gremlin.setStyleSheet(button_style) + self.button_hybrid_test_dca.clicked.connect(self.pypef_dca_hybrid_test) + self.button_hybrid_test_dca.setStyleSheet(button_style) # Supervised - self.button_supervised_train_test_gremlin = QtWidgets.QPushButton("Train-Test (DCA)") - self.button_supervised_train_test_gremlin.setMinimumWidth(80) - self.button_supervised_train_test_gremlin.setToolTip( + self.button_supervised_train_test_dca = QtWidgets.QPushButton("Train-Test (DCA)") + self.button_supervised_train_test_dca.setMinimumWidth(80) + self.button_supervised_train_test_dca.setToolTip( "Purely supervised DCA (GREMLIN or PLMC) model training on variant-fitness labels" ) - self.button_supervised_train_test_gremlin.clicked.connect(self.pypef_gremlin_supervised_train_test) - self.button_supervised_train_test_gremlin.setStyleSheet(button_style) + self.button_supervised_train_test_dca.clicked.connect(self.pypef_dca_supervised_train_test) + self.button_supervised_train_test_dca.setStyleSheet(button_style) self.button_supervised_train_test_onehot = QtWidgets.QPushButton("Train-Test (One-hot)") self.button_supervised_train_test_onehot.setMinimumWidth(80) @@ -189,28 +199,30 @@ def __init__( # Layout widgets #################################################################### # int fromRow, int fromColumn, int rowSpan, int columnSpan layout.addWidget(self.version_text, 0, 0, 1, -1) - layout.addWidget(self.box_multicore, 0, 0, 1, 1) - - layout.addWidget(self.utils_text, 1, 0, 1, 1) - layout.addWidget(self.button_help, 2, 0, 1, 1) - layout.addWidget(self.button_mklsts, 3, 0, 1, 1) + layout.addWidget(self.ncores_text, 1, 0, 1, 1) + layout.addWidget(self.box_multicore, 2, 0, 1, 1) - layout.addWidget(self.dca_text, 1, 1, 1, 1) - layout.addWidget(self.button_dca_inference_gremlin, 2, 1, 1, 1) - layout.addWidget(self.button_dca_test_gremlin, 3, 1, 1, 1) - layout.addWidget(self.button_dca_predict_gremlin, 4, 1, 1, 1) + layout.addWidget(self.utils_text, 3, 0, 1, 1) + layout.addWidget(self.button_help, 4, 0, 1, 1) + layout.addWidget(self.button_mklsts, 5, 0, 1, 1) - layout.addWidget(self.hybrid_text, 1, 2, 1, 1) - layout.addWidget(self.button_hybrid_train_gremlin, 2, 2, 1, 1) - layout.addWidget(self.button_hybrid_train_test_gremlin, 3, 2, 1, 1) - layout.addWidget(self.button_hybrid_test_gremlin, 4, 2, 1, 1) + layout.addWidget(self.dca_text, 3, 1, 1, 1) + layout.addWidget(self.button_dca_inference_gremlin, 4, 1, 1, 1) + layout.addWidget(self.button_dca_test_dca, 5, 1, 1, 1) + layout.addWidget(self.button_dca_predict_dca, 6, 1, 1, 1) - layout.addWidget(self.supervised_text, 1, 3, 1, 1) - layout.addWidget(self.button_supervised_train_test_gremlin, 2, 3, 1, 1) - layout.addWidget(self.button_supervised_train_test_onehot, 3, 3, 1, 1) + layout.addWidget(self.hybrid_text, 3, 2, 1, 1) + layout.addWidget(self.button_hybrid_train_dca, 4, 2, 1, 1) + layout.addWidget(self.button_hybrid_train_test_dca, 5, 2, 1, 1) + layout.addWidget(self.button_hybrid_test_dca, 6, 2, 1, 1) - layout.addWidget(self.textedit_out, 5, 0, 1, -1) + layout.addWidget(self.regression_model_text, 1, 3, 1, 1) + layout.addWidget(self.box_regression_model, 2, 3, 1, 1) + layout.addWidget(self.supervised_text, 3, 3, 1, 1) + layout.addWidget(self.button_supervised_train_test_dca, 4, 3, 1, 1) + layout.addWidget(self.button_supervised_train_test_onehot, 5, 3, 1, 1) + layout.addWidget(self.textedit_out, 7, 0, 1, -1) self.process = QtCore.QProcess(self) self.process.setProcessChannelMode(QtCore.QProcess.MergedChannels) @@ -221,18 +233,18 @@ def __init__( self.process.finished.connect(lambda: self.button_mklsts.setEnabled(True)) self.process.started.connect(lambda: self.button_dca_inference_gremlin.setEnabled(False)) self.process.finished.connect(lambda: self.button_dca_inference_gremlin.setEnabled(True)) - self.process.started.connect(lambda: self.button_dca_test_gremlin.setEnabled(False)) - self.process.finished.connect(lambda: self.button_dca_test_gremlin.setEnabled(True)) - self.process.started.connect(lambda: self.button_dca_predict_gremlin.setEnabled(False)) - self.process.finished.connect(lambda: self.button_dca_predict_gremlin.setEnabled(True)) - self.process.started.connect(lambda: self.button_hybrid_train_gremlin.setEnabled(False)) - self.process.finished.connect(lambda: self.button_hybrid_train_gremlin.setEnabled(True)) - self.process.started.connect(lambda: self.button_hybrid_train_test_gremlin.setEnabled(False)) - self.process.finished.connect(lambda: self.button_hybrid_train_test_gremlin.setEnabled(True)) - self.process.started.connect(lambda: self.button_hybrid_test_gremlin.setEnabled(False)) - self.process.finished.connect(lambda: self.button_hybrid_test_gremlin.setEnabled(True)) - self.process.started.connect(lambda: self.button_supervised_train_test_gremlin.setEnabled(False)) - self.process.finished.connect(lambda: self.button_supervised_train_test_gremlin.setEnabled(True)) + self.process.started.connect(lambda: self.button_dca_test_dca.setEnabled(False)) + self.process.finished.connect(lambda: self.button_dca_test_dca.setEnabled(True)) + self.process.started.connect(lambda: self.button_dca_predict_dca.setEnabled(False)) + self.process.finished.connect(lambda: self.button_dca_predict_dca.setEnabled(True)) + self.process.started.connect(lambda: self.button_hybrid_train_dca.setEnabled(False)) + self.process.finished.connect(lambda: self.button_hybrid_train_dca.setEnabled(True)) + self.process.started.connect(lambda: self.button_hybrid_train_test_dca.setEnabled(False)) + self.process.finished.connect(lambda: self.button_hybrid_train_test_dca.setEnabled(True)) + self.process.started.connect(lambda: self.button_hybrid_test_dca.setEnabled(False)) + self.process.finished.connect(lambda: self.button_hybrid_test_dca.setEnabled(True)) + self.process.started.connect(lambda: self.button_supervised_train_test_dca.setEnabled(False)) + self.process.finished.connect(lambda: self.button_supervised_train_test_dca.setEnabled(True)) self.process.started.connect(lambda: self.button_supervised_train_test_onehot.setEnabled(False)) self.process.finished.connect(lambda: self.button_supervised_train_test_onehot.setEnabled(True)) @@ -243,17 +255,23 @@ def on_readyReadStandardOutput(self): self.textedit_out.append(text.strip()) - def selectionchange(self, i): + def selection_ncores(self, i): if i == 0: self.n_cores = 1 elif i == 1: self.n_cores = os.cpu_count() + + def selection_regression_model(self, i): + self.regression_model = [r.lower() for r in self.regression_models][i] + + @QtCore.Slot() def pypef_help(self): self.version_text.setText("Getting help...") self.exec_pypef(f'mklsts --help') + @QtCore.Slot() def pypef_mklsts(self): wt_fasta_file = QtWidgets.QFileDialog.getOpenFileName(self, "Select WT FASTA File")[0] @@ -262,40 +280,46 @@ def pypef_mklsts(self): self.version_text.setText("Running MKLSTS...") self.exec_pypef(f'mklsts --wt {wt_fasta_file} --input {csv_variant_file}') + @QtCore.Slot() def pypef_gremlin(self): wt_fasta_file = QtWidgets.QFileDialog.getOpenFileName(self, "Select WT FASTA File")[0] - msa_file = QtWidgets.QFileDialog.getOpenFileName(self, "Select Multiple Sequence Alignment (MSA) file (in FASTA or A2M format)")[0] + msa_file = QtWidgets.QFileDialog.getOpenFileName( + self, "Select Multiple Sequence Alignment (MSA) file (in FASTA or A2M format)")[0] if wt_fasta_file and msa_file: self.version_text.setText("Running GREMLIN (DCA) optimization on MSA...") self.exec_pypef(f'param_inference --wt {wt_fasta_file} --msa {msa_file}') # --opt_iter 100 + @QtCore.Slot() - def pypef_gremlin_dca_test(self): + def pypef_dca_test(self): test_set_file = QtWidgets.QFileDialog.getOpenFileName(self, "Select Test Set File in \"FASL\" format")[0] - params_pkl_file = QtWidgets.QFileDialog.getOpenFileName(self, "GREMLIN parameter Pickle file")[0] + params_pkl_file = QtWidgets.QFileDialog.getOpenFileName(self, "Parameter Pickle file")[0] if test_set_file and params_pkl_file: - self.version_text.setText("Testing GREMLIN (DCA) performance on provided test set...") + self.version_text.setText("Testing DCA performance on provided test set...") self.exec_pypef(f'hybrid --ts {test_set_file} -m {params_pkl_file} --params {params_pkl_file}') + @QtCore.Slot() - def pypef_gremlin_dca_predict(self): + def pypef_dca_predict(self): prediction_file = QtWidgets.QFileDialog.getOpenFileName(self, "Select Prediction Set File in FASTA format")[0] - params_pkl_file = QtWidgets.QFileDialog.getOpenFileName(self, "Select GREMLIN parameter Pickle file")[0] + params_pkl_file = QtWidgets.QFileDialog.getOpenFileName(self, "Select DCA parameter Pickle file")[0] if prediction_file and params_pkl_file: - self.version_text.setText("Predicting using the GREMLIN (DCA) model on provided prediction set...") + self.version_text.setText("Predicting using the DCA model on provided prediction set...") self.exec_pypef(f'hybrid --ps {prediction_file} -m {params_pkl_file} --params {params_pkl_file}') + @QtCore.Slot() - def pypef_gremlin_hybrid_train(self): + def pypef_dca_hybrid_train(self): training_file = QtWidgets.QFileDialog.getOpenFileName(self, "Select Training Set File in \"FASL\" format")[0] - params_pkl_file = QtWidgets.QFileDialog.getOpenFileName(self, "Select GREMLIN parameter Pickle file")[0] + params_pkl_file = QtWidgets.QFileDialog.getOpenFileName(self, "Select DCA parameter Pickle file")[0] if training_file and params_pkl_file: self.version_text.setText("Hybrid (DCA-supervised) model training...") self.exec_pypef(f'hybrid --ls {training_file} --ts {training_file} -m {params_pkl_file} --params {params_pkl_file}') + @QtCore.Slot() - def pypef_gremlin_hybrid_train_test(self): + def pypef_dca_hybrid_train_test(self): training_file = QtWidgets.QFileDialog.getOpenFileName(self, "Select Training Set File in \"FASL\" format")[0] test_file = QtWidgets.QFileDialog.getOpenFileName(self, "Select Test Set File in \"FASL\" format")[0] model_pkl_file = QtWidgets.QFileDialog.getOpenFileName(self, "Select DCA model Pickle file")[0] @@ -304,8 +328,9 @@ def pypef_gremlin_hybrid_train_test(self): self.version_text.setText("Hybrid (DCA-supervised) model training and testing...") self.exec_pypef(f'hybrid --ls {training_file} --ts {test_file} -m {model_pkl_file} --params {params_pkl_file}') + @QtCore.Slot() - def pypef_gremlin_hybrid_test(self): + def pypef_dca_hybrid_test(self): test_file = QtWidgets.QFileDialog.getOpenFileName(self, "Select Test Set File in \"FASL\" format")[0] model_file = QtWidgets.QFileDialog.getOpenFileName(self, "Select Hybrid Model file in Pickle format")[0] params_pkl_file = QtWidgets.QFileDialog.getOpenFileName(self, "Select DCA parameter Pickle file")[0] @@ -313,14 +338,17 @@ def pypef_gremlin_hybrid_test(self): self.version_text.setText("Hybrid (DCA-supervised) model training and testing...") self.exec_pypef(f'hybrid --ts {test_file} -m {model_file} --params {params_pkl_file}') + @QtCore.Slot() - def pypef_gremlin_supervised_train_test(self): + def pypef_dca_supervised_train_test(self): training_file = QtWidgets.QFileDialog.getOpenFileName(self, "Select Training Set File in \"FASL\" format")[0] test_file = QtWidgets.QFileDialog.getOpenFileName(self, "Select Test Set File in \"FASL\" format")[0] - params_pkl_file = QtWidgets.QFileDialog.getOpenFileName(self, "Select GREMLIN parameter Pickle file")[0] + params_pkl_file = QtWidgets.QFileDialog.getOpenFileName(self, "Select DCA parameter Pickle file")[0] if training_file and test_file and params_pkl_file: self.version_text.setText("Hybrid (DCA-supervised) model training and testing...") - self.exec_pypef(f'ml --encoding dca --ls {training_file} --ts {test_file} --params {params_pkl_file} --threads {self.n_cores}') + self.exec_pypef(f'ml --encoding dca --ls {training_file} --ts {test_file} --params {params_pkl_file} ' + f'--threads {self.n_cores} --regressor {self.regression_model}') + @QtCore.Slot() def pypef_onehot_supervised_train_test(self): @@ -328,7 +356,8 @@ def pypef_onehot_supervised_train_test(self): test_file = QtWidgets.QFileDialog.getOpenFileName(self, "Select Test Set File in \"FASL\" format")[0] if training_file and test_file: self.version_text.setText("Hybrid (DCA-supervised) model training and testing...") - self.exec_pypef(f'ml --encoding onehot --ls {training_file} --ts {test_file} --threads {self.n_cores}') + self.exec_pypef(f'ml --encoding onehot --ls {training_file} --ts {test_file} ' + f'--threads {self.n_cores} --regressor {self.regression_model}') def exec_pypef(self, cmd): @@ -337,12 +366,12 @@ def exec_pypef(self, cmd): if self.c > 0: self.textedit_out.append("=" * 104 + "\n") + def process_finished(self): self.version_text.setText("Finished...") #self.process = None - if __name__ == "__main__": app = QtWidgets.QApplication([]) widget = MainWindow() diff --git a/pypef/dca/gremlin_inference.py b/pypef/dca/gremlin_inference.py index 2d786f5..61d9599 100644 --- a/pypef/dca/gremlin_inference.py +++ b/pypef/dca/gremlin_inference.py @@ -214,7 +214,7 @@ def get_msa_ori(self): and removes those sequences from the MSA. """ msa_ori = [] - for i, (seq, seq_id) in enumerate(zip(self.seqs, self.seq_ids)): + for i, (seq, _seq_id) in enumerate(zip(self.seqs, self.seq_ids)): if i < self.max_msa_seqs: msa_ori.append([self.aa2int(aa.upper()) for aa in seq]) else: @@ -228,7 +228,7 @@ def filt_gaps(self, msa_ori): tmp = (msa_ori == self.states - 1).astype(float) non_gaps = np.where(np.sum(tmp.T, -1).T / msa_ori.shape[0] < self.gap_cutoff)[0] gaps = np.where(np.sum(tmp.T, -1).T / msa_ori.shape[0] >= self.gap_cutoff)[0] - self.gaps_1_indexed = [g+1 for g in gaps] + self.gaps_1_indexed = [int(g+1) for g in gaps] logger.info(f'Gap positions (removed from MSA; 1-indexed):\n{self.gaps_1_indexed}') ncol_trimmed = len(non_gaps) logger.info(f'Positions remaining: {ncol_trimmed} of {np.shape(msa_ori)[1]} ' diff --git a/pypef/dca/hybrid_model.py b/pypef/dca/hybrid_model.py index 5666ac7..343cbab 100644 --- a/pypef/dca/hybrid_model.py +++ b/pypef/dca/hybrid_model.py @@ -906,7 +906,7 @@ def generate_model_and_save_pkl( variants_splitted = split_variants(variants, substitution_sep) variants, ys_true, sequences = get_seqs_from_var_name(wt_seq, variants_splitted, ys_true) - xs, variants, sequences, ys_true, x_wt, model, model_type = plmc_or_gremlin_encoding( + xs, variants, sequences, ys_true, x_wt, _model, model_type = plmc_or_gremlin_encoding( variants, sequences, ys_true, params_file, substitution_sep, threads) logger.info( diff --git a/pypef/utils/variant_data.py b/pypef/utils/variant_data.py index 8415d1a..73b4b5b 100644 --- a/pypef/utils/variant_data.py +++ b/pypef/utils/variant_data.py @@ -17,6 +17,8 @@ import numpy as np import pandas as pd +import logging +logger = logging.getLogger('pypef.utils.variant_data') amino_acids = [ 'A', 'C', 'D', 'E', 'F', @@ -394,6 +396,7 @@ def generate_dataframe_and_save_csv( if save_df_as_csv: filename = f'{get_basename(csv_file)}_{encoding_type}_encoded.csv' df_dca.to_csv(filename, sep=';', index=False) + logger.info(f"Saved encoded CSV file as {os.path.abspath(filename)}...") return df_dca