def switch_to_tab(self, tab): idx = tab.value if isinstance(tab, TabState) else tab if self.__tab_current_state == TabState(idx): return Logger.info("Switching to %s tab" % TabState(idx).name) self.__tab_current_state = TabState(idx) self.__widget_tab.setCurrentIndex(idx) self.tab_widget(idx).make_update() self.__action_try_switch_to_error_tab.setEnabled( TabState(idx) == TabState.Result) # Error tab is always disabled if not in "Error" self.__widget_tab.setTabEnabled(TabState.Error.value, TabState(idx) == TabState.Error) # First tab if idx == 0: self.__action_continue.setEnabled(True) self.__action_back.setEnabled(False) # Last tab elif idx == self.__widget_tab.count() - 1: self.__action_continue.setEnabled(False) self.__action_back.setEnabled(True) # Middle tab else: self.__action_continue.setEnabled(True) self.__action_back.setEnabled(True)
def make_update(self, comparison_result): Logger.info("Updating ErrorListWidget") list_of_errors = comparison_result.get_error_list() self.__widget_table.setColumnCount(4) self.__widget_table.setRowCount(len(list_of_errors)) self.__widget_table.setHorizontalHeaderLabels( ["Index", "Input (%s)" % comparison_result["input_field_name"], "Reference (%s)" % comparison_result["reference_field_name"], "Error"]) self.__widget_table.setStyleSheet( ''' QTableWidget::item:selected:active { background: transparent; border-width: 0px; } ''') self.__widget_table.horizontalHeader().resizeSections(QHeaderView.Stretch) self.__widget_table.setEditTriggers(QTableWidget.NoEditTriggers) # Sort errors list_of_errors.sort(key=lambda x: x[0][-1]) for idx in range(len(list_of_errors)): error = list_of_errors[idx] self.__widget_table.setItem(idx, 0, QTableWidgetItem( "%s" % str(error[0]) if len(error[0]) != 1 else str(error[0][0]))) self.__widget_table.setItem(idx, 1, QTableWidgetItem("%s" % error[1])) self.__widget_table.setItem(idx, 2, QTableWidgetItem("%s" % error[2])) self.__widget_table.setItem(idx, 3, QTableWidgetItem("%s" % abs(error[2] - error[1])))
def append(self, match, intent, input_stage, input_field_name, input_savepoint, input_serializer, reference_stage, reference_field_name, reference_savepoint, reference_serializer, rtol, atol, invocation_count): while (len(self.__results) - 1) < invocation_count: self.__results += [list()] self.__results[invocation_count] += [ ComparisonResult({ "intent": intent, "input_stage": input_stage, "input_stencil": self.input_stencil, "input_field_name": input_field_name, "input_savepoint": input_savepoint, "input_serializer": input_serializer, "reference_field_name": reference_field_name, "reference_savepoint": reference_savepoint, "reference_stage": reference_stage, "reference_stencil": self.reference_stencil, "reference_serializer": reference_serializer, "match": match, "rtol": rtol, "atol": atol }) ] Logger.info( "Comparing field '%s' vs. '%s' of stage '%s' [%s], result: %s" % (input_field_name, reference_field_name, input_stage, intent, match))
def draw_layer(self, error_positions, layer): Logger.info("Drawing error positions at layer: %s" % layer) data = error_positions[:, :, layer] if error_positions.ndim == 3 else error_positions # True == Error color = zeros((data.shape[0], data.shape[1], 3)) color[data == True] = ColorConverter.colors["r"] color[data == False] = ColorConverter.colors["g"] self.axes.imshow(color, interpolation='nearest') self.axes.set_xticks(arange(-.5, data.shape[1] - 1, 1), minor=True) self.axes.set_yticks(arange(-.5, data.shape[0] - 1, 1), minor=True) self.axes.set_xlabel("j (%s)" % data.shape[1]) self.axes.set_ylabel("i (%s)" % data.shape[0]) self.axes.set_xticklabels([]) self.axes.set_yticklabels([]) self.axes.grid(True, which='minor') self.draw()
def remove_field(self, name): item = self.model().findItems(name) Logger.info( "Removing item with name '%s' of StencilFieldListWidget of '%s'" % (item.text(), self.__stencil_data.name)) self.model().removeRow(item)
def update_stencil_list(self): """Update the available stencils. """ if not self.__stencil_list_changed: return Logger.info("Updating list of stencils of StencilData '%s'" % self.__serializer_data.name) serializer = self.__serializer_data.serializer if serializer and serializer.global_metainfo.has_key("stencils"): stencil_list = serializer.global_metainfo["stencils"] if stencil_list != self.__stencil_list: # Inform listener that we removed all stencils for listener in self.__stencil_list_listener: listener.remove_all_stencils() # Inform listener that we added new stencils self.__stencil_list = stencil_list for stencil in self.__stencil_list: for listener in self.__stencil_list_listener: listener.add_stencil(stencil) else: self.__stencil_list = stencil_list self.__stencil_list_changed = True for listener in self.__data_listener: listener.data_changed()
def draw_nothing(self): Logger.info("Drawing nothing") data = zeros((1, 1)) self.axes.imshow(data, interpolation='nearest') self.axes.set_xticklabels([]) self.axes.set_yticklabels([]) self.draw()
def set_field_enabled(self, name_or_idx, enable): idx = self.list_value.index(name_or_idx) if isinstance( name_or_idx, str) else name_or_idx self.list_check[ idx] = CheckState.Checked if enable else CheckState.Unchecked Logger.info( "Setting enable status of item with name '%s' of '%s' to %s" % (self.list_value[idx], self.__name, enable))
def popup_error_box(self, msg): Logger.error( msg.replace("<b>", "").replace("</b>", "").replace("<br />", ":").replace("<br/>", ":")) msg_box = QMessageBox() msg_box.setWindowTitle("Error") msg_box.setIcon(QMessageBox.Critical) msg_box.setText(msg) msg_box.setStandardButtons(QMessageBox.Ok) reply = msg_box.exec_() # Blocking
def add_field(self, name, idx=None): Logger.info( "Adding item with name '%s' to StencilFieldListWidget of '%s'" % (name, self.__stencil_data.name)) item = self.create_item(name) if idx: self.model().insertRow(idx, item) else: self.model().appendRow(item)
def __init__(self, name, directory="", prefix=""): Logger.info("Setup SerializerData of '%s'" % name) self.__name = name self.__directory = directory self.__prefix = prefix self.__serializer = None self.__data_changed = True self.__serializer_data_listeners = [] self.__serializer_data_directory_and_prefix_listeners = []
def update_serializer_data(self, serializer_data): name = serializer_data.name Logger.info("Syncing SerializerData of '%s' with Configuration" % name) try: self.__config["SerializerData"][name][ "directory"] = serializer_data.directory self.__config["SerializerData"][name][ "prefix"] = serializer_data.prefix except IndexError as e: Logger.warning("Error storing SerializerData of '%s': %s" % (name, e))
def make_update(self): if self.__result_data_state == ResulDataState.Uninitialized: Logger.info("Updating Error tab") self.__widget_input_header.make_update(self.__result_data) self.__widget_reference_header.make_update(self.__result_data) for idx in range(self.__widget_error_tab.count()): self.__widget_error_tab.widget(idx).make_update( self.__result_data) self.__result_data_state = ResulDataState.Valid
def __load_from_file_impl(self, filename): try: with open(filename, 'r') as file: self.__config = load(file) Logger.info("Loading config file from \"%s\"" % filename) except (OSError, IOError, error) as e: Logger.warning("Unable to load config file from \"%s\": %s" % (filename, e)) return False, str(e) except JSONDecodeError as e: return False, "JSON decoding error: " + str(e) return True, ""
def add_row(self): Logger.info("Adding row") minus = QStandardItem() minus.setTextAlignment(Qt.AlignCenter) minus.setText("0") plus = QStandardItem() plus.setTextAlignment(Qt.AlignCenter) plus.setText("0") self.__halo_model.appendRow([minus, plus])
def set_rtol(self, rtol): Logger.info("Setting relative tolerance to: %s" % rtol) self.__stencil_field_mapper.rtol = rtol try: float(rtol) except ValueError: self.__widget_icon_rtol.setPixmap(Pixmap("error.png")) self.__widget_icon_rtol.setToolTip( "%s cannot be converted to a valid floating point number" % rtol) return self.__widget_icon_rtol.clear()
def init(self): Logger.info("Loading StencilData of '%s'" % self.__serializer_data.name) # Possibly a new Serializer self.__stencil_list_changed = True # Get new list of stencils self.update_stencil_list() # Update the available list of fields if self.__stencil_list: self.set_selected_stencil( 0 if self.__stencil_idx_selected < 0 else self.__stencil_idx_selected)
def update_recently_used_serializer_paths(self, path): """Add a path to the recently used serializer paths :param path: Path to the serializer i.e directory :type path: str """ if "RecentlyUsedSerializerPaths" in self.__config: if not path in self.__config["RecentlyUsedSerializerPaths"]: Logger.info("Adding '%s' to recently used Serializer paths" % path) self.__config["RecentlyUsedSerializerPaths"] += [path] else: self.__config["RecentlyUsedSerializerPaths"] = [path]
def open_file_dialog(self): Logger.info("Open file dialog") open_dir = self.directory if not self.directory: open_dir = getcwd() dialog = QFileDialog(self, 'Open %s' % self.__name) dialog.setFileMode(QFileDialog.Directory) dialog.setViewMode(QFileDialog.Detail) dialog.setDirectory(open_dir) if dialog.exec_(): self.__widget_edit_directory.setText(dialog.selectedFiles()[0])
def make_update(self, result_data): Logger.info("Updating ErrorWindowHeaderWidget of '%s'" % self.__name) id = self.__name.lower() self.__widget_label_name.setText( "<b>%s (%s)</b>" % (self.__name, result_data[id + "_field_name"])) self.__widget_label_stencil.setText("Stencil: %s" % result_data[id + "_stencil"]) self.__widget_label_stage.setText("Stage: %s" % result_data[id + "_stage"]) self.__current_field_name = result_data[id + "_field_name"] self.__current_field_metainfo = result_data[ id + "_serializer"].get_field_metainfo(self.__current_field_name)
def initial_field_match(self): Logger.info("Matching fields ...") input_fields = self.__input_stencil_data.field_list input_fields_state = [False] * len(input_fields) reference_fields = self.__reference_stencil_data.field_list reference_fields_state = [False] * len(reference_fields) reference_fields_seen = [] # # 1. Sweep - Set enable state of reference and input field list # Logger.info("Set enable state of reference and input field list") for idx in range(len(input_fields)): input_field = input_fields[idx] enable = False if input_field in reference_fields: reference_fields_seen += [input_field] enable = True self.__input_stencil_data.set_field_enabled(input_field, enable) input_fields_state[idx] = enable for idx in range(len(reference_fields)): reference_field = reference_fields[idx] enable = reference_field in reference_fields_seen self.__reference_stencil_data.set_field_enabled(reference_field, enable) reference_fields_state[idx] = enable # # 2. Sweep - Move all disabled fields to the back # Logger.info("Move disabled fields of input and reference field list to the back") input_fields_reordered = input_fields[:] for idx in range(len(input_fields)): if not input_fields_state[idx]: self.__input_stencil_data.move_field(input_fields[idx], len(input_fields) - 1) input_fields_reordered.insert(len(input_fields) - 1, input_fields_reordered.pop(idx)) reference_fields_reordered = reference_fields[:] for idx in range(len(reference_fields)): if not reference_fields_state[idx]: self.__reference_stencil_data.move_field(reference_fields[idx], len(reference_fields) - 1) reference_fields_reordered.insert(len(reference_fields) - 1, reference_fields_reordered.pop(idx)) # # 3. Sweep - Move the enabled reference fields to match the input positions # Logger.info("Move reference fields to match input field list") for idx in range(input_fields_state.count(True)): reference_field = reference_fields_reordered[idx] self.__reference_stencil_data.move_field(reference_field, idx)
def get_recently_used_serializer_paths(self): """Get a list of recently used serializer paths. :return: List of recently used serializer paths :rtype: :class:`list` [:class:`str`] """ Logger.info("Query recently used Serializer paths") if "RecentlyUsedSerializerPaths" in self.__config: return [ p for p in self.__config["RecentlyUsedSerializerPaths"] if path.isdir(p) ] else: return []
def __init__(self, parent): super().__init__(parent) Logger.info("Showing about message box") self.setWindowTitle("About sdb") image = Pixmap("logo.png") image_scaled = image.scaled(self.geometry().height(), self.geometry().width(), Qt.KeepAspectRatio) self.__widget_label_image = QLabel() self.__widget_label_image.setPixmap(image_scaled) about_txt = ( "", "sdb (%s)" % Version().sdb_version(), "Serialbox (%s)" % Version().serialbox_version(), "numpy (%s)" % Version().numpy_version(), "matplotlib (%s)" % Version().matplotlib_version(), "PyQt5 (%s)" % QT_VERSION_STR, "IPython (%s)" % Version().ipython_version(), "", "Copyright (c) 2016-2017, Fabian Thuering", "", "All rights reserved.", "", "The program is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE " "WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.", "") self.__widget_label_about_txt = QLabel() self.__widget_label_about_txt.setText("\n".join(about_txt)) self.__widget_label_about_txt.setWordWrap(True) hbox = QHBoxLayout() hbox.addWidget(self.__widget_label_image) hbox.addStretch(1) hbox_button = QHBoxLayout() hbox_button.addStretch(1) cancel_button = QPushButton("Cancel") cancel_button.clicked.connect(self.close) hbox_button.addWidget(cancel_button) vbox = QVBoxLayout() vbox.addLayout(hbox) vbox.addWidget(self.__widget_label_about_txt) vbox.addLayout(hbox_button) self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum) self.setLayout(vbox) self.show()
def reload_serializer(self): Logger.info("Reloading serializers") try: self.__input_serializer_data.reload() self.__reference_serializer_data.reload() if self.__widget_tab.currentIndex() == TabState.Error.value: self.switch_to_tab(TabState.Result) self.__widget_tab.currentWidget().make_update() except RuntimeError as e: self.popup_error_box(str(e)) self.set_tab_highest_valid_state(TabState.Setup) self.switch_to_tab(TabState.Setup) self.__widget_tab.currentWidget().make_update()
def __store_to_file_impl(self, filename): try: try: dir = path.dirname(filename) makedirs(dir) except error: pass with open(filename, 'w') as file: Logger.info("Saving config file in \"%s\"" % filename) dump(self.__config, file, indent=2) except (OSError, IOError) as e: Logger.warning("Unable to save config file in \"%s\": %s" % (filename, e)) return False, str(e) return True, ""
def make_serializer(self, force=False): try: if force or self.__data_changed: Logger.info( "Creating new Serializer in SerializerData of '%s'" % self.__name) self.__serializer = Serializer(OpenModeKind.Read, self.directory, self.prefix) self.__data_changed = False for stencil_listener in self.__serializer_data_listeners: stencil_listener.reload() except SerialboxError as e: self.__serializer = None self.__data_changed = True raise RuntimeError("<b>%s:</b><br />%s" % (self.name, e))
def move_field(self, name_or_idx, idx): if isinstance(name_or_idx, str): from_idx = self.list_value.index(name_or_idx) else: from_idx = name_or_idx name = self.list_value[from_idx] check_state = self.list_check[from_idx] Logger.info("Moving item with name '%s' to index '%i' of '%s'" % (name, idx, self.__name)) del self.list_value[from_idx] del self.list_check[from_idx] self.list_value.insert(idx, name) self.list_check.insert(idx, check_state)
def set_field_enabled(self, name_or_idx, enable): if isinstance(name_or_idx, str): index_list = self.model().findItems(name_or_idx) if not index_list: return item = index_list[0] else: item = self.model().item(name_or_idx) Logger.info( "Setting enable status of item with name '%s' of StencilFieldListWidget of '%s' to %s" % (item.text(), self.__stencil_data.name, enable)) if enable: item.setCheckState(Qt.Checked) else: item.setCheckState(Qt.Unchecked)
def update_field_list(self): """Update field list according to the selected stencil """ if not self.__field_list_changed: return Logger.info("Updating field list of StencilData '%s' to match stencil '%s'" % ( self.__serializer_data.name, self.selected_stencil)) serializer = self.__serializer_data.serializer # If stencil list is empty -> exit if not self.__stencil_list: return # Get list of fields of the current stencil field_list = [] for sp in serializer.savepoint_list(): if sp.name.startswith(self.__stencil_list[self.__stencil_idx_selected]): for fields in serializer.fields_at_savepoint(sp): field_list += [fields] # Remove duplicates field_list = list(set(field_list)) # Sort alphabetically field_list = sorted(field_list) if self.__field_list != field_list: # Inform listener that we removed all fields for listener in self.__field_list_listener: listener.remove_all_fields() # Inform listener that we added new fields self.__field_list = field_list for field in self.__field_list: for listener in self.__field_list_listener: listener.add_field(field) else: self.__field_list = field_list self.__field_list_changed = False for listener in self.__data_listener: listener.data_changed()
def move_field(self, name_or_idx, idx): if isinstance(name_or_idx, str): item = self.model().findItems(name_or_idx)[0] else: item = self.model().item(name_or_idx) name = item.text() data = item.data() check_state = item.checkState() from_idx = self.model().indexFromItem(item).row() Logger.info( "Moving item with name '%s' to index '%i' of StencilFieldListWidget of '%s'" % (name, idx, self.__stencil_data.name)) self.model().removeRow(from_idx) item = self.create_item(name, data) item.setCheckState(check_state) self.model().insertRow(idx, item)