Scheduled service maintenance on November 22


On Friday, November 22, 2024, between 06:00 CET and 18:00 CET, GIN services will undergo planned maintenance. Extended service interruptions should be expected. We will try to keep downtimes to a minimum, but recommend that users avoid critical tasks, large data uploads, or DOI requests during this time.

We apologize for any inconvenience.

data_manager.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. from view.gui.custom_widgets import QTableWidgetPandasDFDeletable
  2. from PyQt5.QtWidgets import QAbstractItemView, QHeaderView, QLineEdit, QWidget
  3. from PyQt5.QtCore import pyqtSlot, QObject, pyqtSignal
  4. import pandas as pd
  5. from view.python_core.utils.deduplicator import dedupilicate
  6. from collections import OrderedDict
  7. import copy
  8. class DataManager(QObject):
  9. remove_data_signal = pyqtSignal(str, name="remove data signal")
  10. def __init__(self, parent: QWidget, flag_values_to_use: dict,
  11. p1_values_to_use: dict, label_joiner: str,
  12. default_label_cols: list, precedence_order: list):
  13. """
  14. The columns for gui-table are composed as follows: The column for the user-editable data label, followed by
  15. those defined in <p1_values_to_use>, followed by those defined in <flag_values_to_use>.
  16. The internal Dataframe variable <df> consists of the same columns, except the column for data labels. The row
  17. indices of <df> are internally generated labels.
  18. :param flag_values_to_use: dict, containing info about the flags values to store with data.
  19. Values are flag names and keys are the column names under which they will be shown
  20. :param p1_values_to_use: dict, containing info about the p1 values to store with data.
  21. Values are functions that take one argument, p1, as input and returns the string to show. Keys are the column
  22. names under which they will be shown
  23. :param label_joiner: str, which is used to join metadata values to form labels. E.g.: _ and -
  24. :param default_label_cols: list, list of column names whose values are to be joined to form the default label
  25. :param list precedence_order: these column names will be placed before others, if they are used
  26. """
  27. super().__init__()
  28. self.label_line_edits = {}
  29. self.label_col_name = "gui_label"
  30. self.label_joiner = label_joiner
  31. self.defaultLabelCols = default_label_cols
  32. self.ui_table = None
  33. self.flag_values_to_use = flag_values_to_use
  34. self.p1_values_to_use = p1_values_to_use
  35. column_headers = \
  36. [self.label_col_name] + \
  37. self.reorder_column_names(
  38. list(self.flag_values_to_use.keys()) + list(self.p1_values_to_use.keys()), precedence_order)
  39. self.init_ui(parent, column_headers)
  40. self.df = pd.DataFrame(columns=column_headers[1:])
  41. def reorder_column_names(self, column_names: list, precedence_order: list):
  42. precedence_order2retain = [x for x in precedence_order if x in column_names]
  43. other_col_names = [x for x in column_names if x not in precedence_order]
  44. return precedence_order2retain + other_col_names
  45. def init_ui(self, parent, horizontal_headers=()):
  46. self.ui_table = QTableWidgetPandasDFDeletable(parent=parent)
  47. self.ui_table.setColumnCount(len(horizontal_headers))
  48. self.ui_table.setHorizontalHeaderLabels(horizontal_headers)
  49. self.ui_table.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeToContents)
  50. self.ui_table.setSelectionBehavior(QAbstractItemView.SelectRows)
  51. self.ui_table.setSelectionMode(QAbstractItemView.SingleSelection)
  52. self.ui_table.remove_data_signal.connect(self.row_deleted)
  53. def get_item_at(self, row_ind, col_ind):
  54. if col_ind == 1:
  55. return self.ui_table.cellWidget(row_ind, col_ind).text()
  56. else:
  57. return self.ui_table.item(row_ind, col_ind).text()
  58. def add_data(self, flags, p1, label_suggestion):
  59. row = pd.Series()
  60. for k, v in self.p1_values_to_use.items():
  61. row[k] = str(v(p1))
  62. for k, v in self.flag_values_to_use.items():
  63. row[k] = str(flags[v])
  64. label = dedupilicate(value=label_suggestion, existing_values=self.get_all_internal_labels())
  65. self.ui_table.add_row(row)
  66. row.name = label
  67. self.df = self.df.append(row)
  68. le = QLineEdit(label)
  69. self.ui_table.setCellWidget(self.ui_table.rowCount() - 1, 0, le)
  70. self.label_line_edits[label] = le
  71. self.ui_table.selectRow(self.ui_table.rowCount() - 1)
  72. return label
  73. def get_selected_data_label(self):
  74. return self.df.index.values[self.ui_table.selectionModel().selectedRows()[0].row()]
  75. def get_all_internal_labels(self):
  76. return self.df.index.values.tolist()
  77. @pyqtSlot(int, name="row deleted")
  78. def row_deleted(self, row_ind):
  79. label_of_data_to_delete = self.df.index.values[row_ind]
  80. del self.label_line_edits[label_of_data_to_delete]
  81. self.df.drop(index=label_of_data_to_delete, inplace=True)
  82. self.remove_data_signal.emit(label_of_data_to_delete)