def __init__(self, measurements, settings, masses, parent_settings_dialog=None): """Inits the calibration dialog class. Args: measurements: A string list representing measurements files. settings: A Settings class object. masses: A Masses class object. parent_settings_dialog: A representing from which dialog this was opened from. """ super().__init__() self.measurements = measurements # TODO: Settings should be loaded from the measurement depending on is the # calibration dialog opened from the project settings (measurement's # project settings is loaded) or the measurement specific settings # (measurement's measurement settings is loaded). This has to be done for # better architecture. self.settings = settings self.__cut_file = CutFile() self.__cut_files = {} self.ui = uic.loadUi(os.path.join("ui_files", "ui_calibration_dialog.ui"), self) self.parent_settings_dialog = parent_settings_dialog self.tof_calibration = TOFCalibration() measurement = None # Go through all the measurements and their cut files and list them. for measurement in self.measurements: item = QtGui.QTreeWidgetItem([measurement.measurement_name]) cuts, unused_cuts_elemloss = measurement.get_cut_files() # May also return a list of cut file's element losses # cut files as one of the list elements for cut_file in cuts: subitem = QtGui.QTreeWidgetItem([cut_file]) subitem.directory = measurement.directory_cuts subitem.file_name = cut_file item.addChild(subitem) cut_object = CutFile() cut_object.load_file(os.path.join(measurement.directory_cuts, cut_file)) self.__cut_files[cut_file] = cut_object self.ui.cutFilesTreeWidget.addTopLevelItem(item) item.setExpanded(True) # Resize columns to fit the content nicely for column in range(0, self.ui.cutFilesTreeWidget.columnCount()): self.ui.cutFilesTreeWidget.resizeColumnToContents(column) self.curveFittingWidget = CalibrationCurveFittingWidget(self, self.__cut_file, self.tof_calibration, self.settings, self.ui.binWidthSpinBox.value(), 1, masses) old_params = None if parent_settings_dialog: # Get old parameters from the parent dialog try: f1 = float(self.parent_settings_dialog.ui.slopeLineEdit.text()) f2 = float(self.parent_settings_dialog.ui.offsetLineEdit.text()) old_params = f1, f2 except: m = "Can't get old calibration parameters from the settings dialog." print(m) self.linearFittingWidget = CalibrationLinearFittingWidget(self, self.tof_calibration, old_params) self.ui.fittingResultsLayout.addWidget(self.curveFittingWidget) self.ui.calibrationResultsLayout.addWidget(self.linearFittingWidget) # Set up connections self.ui.cutFilesTreeWidget.itemSelectionChanged.connect( lambda: self.change_current_cut( self.ui.cutFilesTreeWidget.currentItem())) self.ui.pointsTreeWidget.itemClicked.connect(self.__set_state_for_point) self.ui.acceptPointButton.clicked.connect(self.__accept_point) self.ui.binWidthSpinBox.valueChanged.connect(self.__update_curve_fit) self.ui.binWidthSpinBox.setKeyboardTracking(False) self.ui.acceptCalibrationButton.clicked.connect(self.accept_calibration) self.ui.cancelButton.clicked.connect(self.close) self.ui.removePointButton.clicked.connect(self.remove_selected_points) self.ui.tofChannelLineEdit.editingFinished.connect( lambda: self.set_calibration_point( float(self.ui.tofChannelLineEdit.text()))) # Set the validator for lineEdit so user can't give invalid values double_validator = QtGui.QDoubleValidator() self.ui.tofChannelLineEdit.setValidator(double_validator) self.timer = QtCore.QTimer(interval=1500, timeout=self.timeout) self.exec_()
class CalibrationDialog(QtGui.QDialog): """A dialog for the time of flight calibration """ def __init__(self, measurements, settings, masses, parent_settings_dialog=None): """Inits the calibration dialog class. Args: measurements: A string list representing measurements files. settings: A Settings class object. masses: A Masses class object. parent_settings_dialog: A representing from which dialog this was opened from. """ super().__init__() self.measurements = measurements # TODO: Settings should be loaded from the measurement depending on is the # calibration dialog opened from the project settings (measurement's # project settings is loaded) or the measurement specific settings # (measurement's measurement settings is loaded). This has to be done for # better architecture. self.settings = settings self.__cut_file = CutFile() self.__cut_files = {} self.ui = uic.loadUi(os.path.join("ui_files", "ui_calibration_dialog.ui"), self) self.parent_settings_dialog = parent_settings_dialog self.tof_calibration = TOFCalibration() measurement = None # Go through all the measurements and their cut files and list them. for measurement in self.measurements: item = QtGui.QTreeWidgetItem([measurement.measurement_name]) cuts, unused_cuts_elemloss = measurement.get_cut_files() # May also return a list of cut file's element losses # cut files as one of the list elements for cut_file in cuts: subitem = QtGui.QTreeWidgetItem([cut_file]) subitem.directory = measurement.directory_cuts subitem.file_name = cut_file item.addChild(subitem) cut_object = CutFile() cut_object.load_file(os.path.join(measurement.directory_cuts, cut_file)) self.__cut_files[cut_file] = cut_object self.ui.cutFilesTreeWidget.addTopLevelItem(item) item.setExpanded(True) # Resize columns to fit the content nicely for column in range(0, self.ui.cutFilesTreeWidget.columnCount()): self.ui.cutFilesTreeWidget.resizeColumnToContents(column) self.curveFittingWidget = CalibrationCurveFittingWidget(self, self.__cut_file, self.tof_calibration, self.settings, self.ui.binWidthSpinBox.value(), 1, masses) old_params = None if parent_settings_dialog: # Get old parameters from the parent dialog try: f1 = float(self.parent_settings_dialog.ui.slopeLineEdit.text()) f2 = float(self.parent_settings_dialog.ui.offsetLineEdit.text()) old_params = f1, f2 except: m = "Can't get old calibration parameters from the settings dialog." print(m) self.linearFittingWidget = CalibrationLinearFittingWidget(self, self.tof_calibration, old_params) self.ui.fittingResultsLayout.addWidget(self.curveFittingWidget) self.ui.calibrationResultsLayout.addWidget(self.linearFittingWidget) # Set up connections self.ui.cutFilesTreeWidget.itemSelectionChanged.connect( lambda: self.change_current_cut( self.ui.cutFilesTreeWidget.currentItem())) self.ui.pointsTreeWidget.itemClicked.connect(self.__set_state_for_point) self.ui.acceptPointButton.clicked.connect(self.__accept_point) self.ui.binWidthSpinBox.valueChanged.connect(self.__update_curve_fit) self.ui.binWidthSpinBox.setKeyboardTracking(False) self.ui.acceptCalibrationButton.clicked.connect(self.accept_calibration) self.ui.cancelButton.clicked.connect(self.close) self.ui.removePointButton.clicked.connect(self.remove_selected_points) self.ui.tofChannelLineEdit.editingFinished.connect( lambda: self.set_calibration_point( float(self.ui.tofChannelLineEdit.text()))) # Set the validator for lineEdit so user can't give invalid values double_validator = QtGui.QDoubleValidator() self.ui.tofChannelLineEdit.setValidator(double_validator) self.timer = QtCore.QTimer(interval=1500, timeout=self.timeout) self.exec_() def remove_selected_points(self): '''Remove selected items from point tree widget ''' removed_something = False root = self.ui.pointsTreeWidget.invisibleRootItem() for item in self.ui.pointsTreeWidget.selectedItems(): if item and hasattr(item, 'point'): removed_something = True self.tof_calibration.remove_point(item.point) (item.parent() or root).removeChild(item) if removed_something: self.__change_selected_points() def set_calibration_point(self, tof): '''Set Cut file front edge estimation to specific value. Args: tof: Float representing front edge of linear fit estimation. ''' self.curveFittingWidget.matplotlib.set_calibration_point_externally(tof) def set_calibration_parameters_to_parent(self): '''Set calibration parameters to parent dialog's calibration parameters fields. ''' if self.parent_settings_dialog: self.parent_settings_dialog.ui.slopeLineEdit.setText( self.ui.slopeLineEdit.text()) self.parent_settings_dialog.ui.offsetLineEdit.setText( self.ui.offsetLineEdit.text()) return True return False def accept_calibration(self): '''Accept calibration (parameters). ''' calib_ok = "Calibration parameters accepted.\nYou can now close the window." calib_no = "Couldn't set parameters to\nthe settings dialog." calib_inv = "Invalid calibration parameters." results = self.tof_calibration.get_fit_parameters() if results[0] and results[1]: if self.set_calibration_parameters_to_parent(): self.ui.acceptCalibrationLabel.setText(calib_ok) else: self.ui.acceptCalibrationLabel.setText(calib_no) else: self.ui.acceptCalibrationLabel.setText(calib_inv) def change_current_cut(self, current_item): """Changes the current cut file drawn to the curve fitting widget. Args: current_item: QtGui.QTreeWidgetItem of CutFile which was selected. """ self.__change_accept_point_label("") if current_item and hasattr(current_item, 'directory') and \ hasattr(current_item, 'file_name'): self.__set_current_cut(current_item) self.__update_curve_fit() def __set_current_cut(self, current_item): """Sets the current open cut file in the calibration dialog. Args: current_item: QtGui.QTreeWidgetItem of CutFile which was selected. """ self.__cut_file = self.__cut_files[current_item.file_name] def __update_curve_fit(self): """Redraws everything in the curve fitting graph. Updates the bin width too. """ bin_width = self.ui.binWidthSpinBox.value() self.curveFittingWidget.matplotlib.change_bin_width(bin_width) self.curveFittingWidget.matplotlib.change_cut(self.__cut_file) def __set_state_for_point(self, tree_item): """Sets if the tof calibration point is drawn to the linear fit graph Args: tree_item: QtGui.QTreeWidgetItem """ if tree_item and hasattr(tree_item, 'point'): tree_item.point.point_used = tree_item.checkState(0) self.__change_selected_points() self.__enable_accept_calibration_button() def __accept_point(self): """ Called when 'accept point' button is clicked. Adds the calibration point to the point set for linear fitting and updates the treewidget of points. """ point = self.curveFittingWidget.matplotlib.tof_calibration_point if point and not self.tof_calibration.point_exists(point): self.tof_calibration.add_point(point) self.__add_point_to_tree(point) self.__change_selected_points() self.__enable_accept_calibration_button() self.__change_accept_point_label("Point accepted.") else: self.__change_accept_point_label("Point already exists.") def __change_accept_point_label(self, text): """Sets text for the 'acceptPointLabel' label and starts timer. Args: text: String to be set to the label. """ self.ui.acceptPointLabel.setText(text) self.timer.start() def timeout(self): '''Timeout eventmethod to remove label text. ''' self.ui.acceptPointLabel.setText("") self.timer.stop() def __enable_accept_calibration_button(self): # Let press accept calibration only if there are parameters available. if self.tof_calibration.slope or self.tof_calibration.offset: self.ui.acceptCalibrationButton.setEnabled(True) else: self.ui.acceptCalibrationButton.setEnabled(False) def __add_point_to_tree(self, tof_calibration_point): """Adds a ToF Calibration point to the pointsTreeWidget and sets the QTreeWidgetItem's attribute 'point' as the given TOFCalibrationPoint. """ item = QtGui.QTreeWidgetItem([tof_calibration_point.get_name()]) item.point = tof_calibration_point item.setCheckState(0, QtCore.Qt.Checked) self.ui.pointsTreeWidget.addTopLevelItem(item) def __change_selected_points(self): """Redraws the linear fitting graph. """ self.linearFittingWidget.matplotlib.on_draw() # Redraw