def initialize_content(self):
        # Constraints
        for widget in [
                self._content.median_test_high_edit,
                self._content.median_test_low_edit,
                self._content.median_test_out_high_edit,
                self._content.median_test_out_low_edit,
                self._content.errorbar_crit_edit,
                self._content.ratio_var_crit_edit,
                self._content.sambkg_median_test_high_edit,
                self._content.sambkg_median_test_low_edit,
                self._content.sambkg_errorbar_crit_edit
        ]:

            dvp = QDoubleValidator(widget)
            dvp.setBottom(0.0)
            widget.setValidator(dvp)

        for widget in [self._content.tof_start_edit,
                       self._content.tof_end_edit]:
            ivp = QIntValidator(widget)
            ivp.setBottom(0)
            widget.setValidator(ivp)

        # Connections
        self._content.det_van2_browse.clicked.connect(self._det_van2_browse)
Пример #2
0
    def initialize_content(self):
        # Constraints
        dv = QDoubleValidator(self._content.ei_guess_edit)
        dv.setBottom(0.0)
        self._content.ei_guess_edit.setValidator(dv)
        if "SNS" != self._facility_name:
            util.set_valid(self._content.ei_guess_edit, False)
        self._content.tzero_guess_edit.setValidator(QDoubleValidator(self._content.tzero_guess_edit))
        self._content.etr_low_edit.setValidator(QDoubleValidator(self._content.etr_low_edit))
        self._content.etr_width_edit.setValidator(QDoubleValidator(self._content.etr_width_edit))
        self._content.etr_high_edit.setValidator(QDoubleValidator(self._content.etr_high_edit))
        self._content.monitor1_specid_edit.setValidator(QIntValidator(self._content.monitor1_specid_edit))
        self._content.monitor2_specid_edit.setValidator(QIntValidator(self._content.monitor2_specid_edit))

        # Default states
        self._handle_tzero_guess(self._content.use_ei_guess_chkbox.isChecked())

        # Connections
        self._content.sample_browse.clicked.connect(self._sample_browse)
        self._content.detcal_browse.clicked.connect(self._detcal_browse)
        self._content.hardmask_browse.clicked.connect(self._hardmask_browse)
        self._content.grouping_browse.clicked.connect(self._grouping_browse)
        self._content.use_ei_guess_chkbox.stateChanged.connect(self._handle_tzero_guess)
        self._content.savedir_browse.clicked.connect(self._savedir_browse)

        # Validated widgets
        self._connect_validated_lineedit(self._content.sample_edit)
        self._connect_validated_lineedit(self._content.ei_guess_edit)
        self._connect_validated_lineedit(self._content.savedir_edit)
Пример #3
0
    def _build_waverange_dialog(self, wave_range, line_list):

        dialog = QDialog(parent=self.centralWidget)

        loadUi(os.path.join(os.path.dirname(__file__), "ui", "linelists_waverange.ui"), dialog)

        dialog.min_text.setText("%.2f" % wave_range[0].value)
        dialog.max_text.setText("%.2f" % wave_range[1].value)

        validator = QDoubleValidator()
        validator.setBottom(0.0)
        validator.setDecimals(2)
        dialog.min_text.setValidator(validator)
        dialog.max_text.setValidator(validator)

        dialog.nlines_label = self._compute_nlines_in_waverange(line_list, dialog.min_text, dialog.max_text,
                                                                dialog.nlines_label)

        dialog.min_text.editingFinished.connect(lambda: self._compute_nlines_in_waverange(line_list,
                                                 dialog.min_text, dialog.max_text, dialog.nlines_label))
        dialog.max_text.editingFinished.connect(lambda: self._compute_nlines_in_waverange(line_list,
                                                 dialog.min_text, dialog.max_text, dialog.nlines_label))

        accepted = dialog.exec_() > 0

        amin = amax = None
        if accepted:
            return self._get_range_from_textfields(dialog.min_text, dialog.max_text)

        return (amin, amax)
Пример #4
0
    def initialize_content(self):
        # Constraints
        for widget in [
                self._content.ei_edit,
                self._content.van_mass_edit,
                self._content.sample_mass_edit,
                self._content.sample_rmm_edit,
                self._content.median_test_high_edit,
                self._content.median_test_low_edit,
                self._content.median_test_out_high_edit,
                self._content.median_test_out_low_edit,
                self._content.errorbar_crit_edit,
        ]:

            dvp = QDoubleValidator(widget)
            dvp.setBottom(0.0)
            widget.setValidator(dvp)

        # Connections
        self._content.absunits_van_browse.clicked.connect(
            self._absunits_van_browse)
        self._content.absunits_detvan_browse.clicked.connect(
            self._absunits_detvan_browse)
        self._content.grouping_file_browse.clicked.connect(
            self._grouping_file_browse)
Пример #5
0
    def initialize_content(self):
        # Constraints
        dv = QDoubleValidator(self._content.ei_guess_edit)
        dv.setBottom(0.0)
        self._content.ei_guess_edit.setValidator(dv)
        if "SNS" != self._facility_name:
            util.set_valid(self._content.ei_guess_edit, False)
        self._content.tzero_guess_edit.setValidator(QDoubleValidator(self._content.tzero_guess_edit))
        self._content.etr_low_edit.setValidator(QDoubleValidator(self._content.etr_low_edit))
        self._content.etr_width_edit.setValidator(QDoubleValidator(self._content.etr_width_edit))
        self._content.etr_high_edit.setValidator(QDoubleValidator(self._content.etr_high_edit))
        self._content.monitor1_specid_edit.setValidator(QIntValidator(self._content.monitor1_specid_edit))
        self._content.monitor2_specid_edit.setValidator(QIntValidator(self._content.monitor2_specid_edit))

        # Default states
        self._handle_tzero_guess(self._content.use_ei_guess_chkbox.isChecked())

        # Connections
        self._content.sample_browse.clicked.connect(self._sample_browse)
        self._content.detcal_browse.clicked.connect(self._detcal_browse)
        self._content.hardmask_browse.clicked.connect(self._hardmask_browse)
        self._content.grouping_browse.clicked.connect(self._grouping_browse)
        self._content.use_ei_guess_chkbox.stateChanged.connect(self._handle_tzero_guess)
        self._content.savedir_browse.clicked.connect(self._savedir_browse)

        # Validated widgets
        self._connect_validated_lineedit(self._content.sample_edit)
        self._connect_validated_lineedit(self._content.ei_guess_edit)
        self._connect_validated_lineedit(self._content.savedir_edit)
Пример #6
0
    def initialize_content(self):
        # Constraints
        for widget in [
                self._content.median_test_high_edit,
                self._content.median_test_low_edit,
                self._content.median_test_out_high_edit,
                self._content.median_test_out_low_edit,
                self._content.errorbar_crit_edit,
                self._content.ratio_var_crit_edit,
                self._content.sambkg_median_test_high_edit,
                self._content.sambkg_median_test_low_edit,
                self._content.sambkg_errorbar_crit_edit
        ]:

            dvp = QDoubleValidator(widget)
            dvp.setBottom(0.0)
            widget.setValidator(dvp)

        for widget in [
                self._content.tof_start_edit, self._content.tof_end_edit
        ]:
            ivp = QIntValidator(widget)
            ivp.setBottom(0)
            widget.setValidator(ivp)

        # Connections
        self._content.det_van2_browse.clicked.connect(self._det_van2_browse)
Пример #7
0
    def __init__(self, parent=None):
        self._parent = parent
        super().__init__(parent)
        self.setTitle("Define d₀")
        layout = QVBoxLayout()
        self.d0_grid_switch = QComboBox()
        self.d0_grid_switch.addItems(["Constant", "Field"])
        self.d0_grid_switch.currentTextChanged.connect(self.set_case)
        layout.addWidget(self.d0_grid_switch)
        self.d0_box = QWidget()
        d0_box_layout = QHBoxLayout()
        d0_box_layout.addWidget(QLabel("d₀"))
        validator = QDoubleValidator()
        validator.setBottom(0)
        self.d0 = QLineEdit()
        self.d0.setValidator(validator)
        self.d0.editingFinished.connect(self.update_d0)
        d0_box_layout.addWidget(self.d0)
        d0_box_layout.addWidget(QLabel("Δd₀"))
        self.d0e = QLineEdit()
        self.d0e.setValidator(validator)
        self.d0e.editingFinished.connect(self.update_d0)
        d0_box_layout.addWidget(self.d0e)
        self.d0_box.setLayout(d0_box_layout)
        layout.addWidget(self.d0_box)

        load_save = QWidget()
        load_save_layout = QHBoxLayout()
        self.load_grid = QPushButton("Load d₀ Grid")
        self.load_grid.clicked.connect(self.load_d0_field)
        load_save_layout.addWidget(self.load_grid)
        self.save_grid = QPushButton("Save d₀ Grid")
        self.save_grid.clicked.connect(self.save_d0_field)
        load_save_layout.addWidget(self.save_grid)
        load_save.setLayout(load_save_layout)
        layout.addWidget(load_save)
        self.d0_grid = QTableWidget()
        self.d0_grid.setColumnCount(5)
        self.d0_grid.setColumnWidth(0, 60)
        self.d0_grid.setColumnWidth(1, 60)
        self.d0_grid.setColumnWidth(2, 60)
        self.d0_grid.setColumnWidth(3, 60)
        self.d0_grid.verticalHeader().setVisible(False)
        self.d0_grid.horizontalHeader().setStretchLastSection(True)
        self.d0_grid.setHorizontalHeaderLabels(['vx', 'vy', 'vz', "d₀", "Δd₀"])
        spinBoxDelegate = SpinBoxDelegate()
        self.d0_grid.setItemDelegateForColumn(3, spinBoxDelegate)
        self.d0_grid.setItemDelegateForColumn(4, spinBoxDelegate)
        layout.addWidget(self.d0_grid)

        self.setLayout(layout)

        self.set_case('Constant')
Пример #8
0
    def createDoubleLineEdit(self, minimum=None, maximum=None, placeholder=""):
        line_edit = ClearableLineEdit(placeholder=placeholder)
        validator = QDoubleValidator()

        if minimum is not None:
            validator.setBottom(minimum)

        if maximum is not None:
            validator.setTop(maximum)

        line_edit.setValidator(validator)
        return line_edit
Пример #9
0
    def createEditor(self, parent, option, index):
        """Create editor widget"""
        model = index.model()
        # TODO: dtype should be taken from the model instead (or even from the actual value?)
        value = model.get_value(index)
        if self.dtype.name == "bool":
            # toggle value
            value = not value
            model.setData(index, to_qvariant(value))
            return
        elif value is not np.ma.masked:
            minvalue, maxvalue = self.minvalue, self.maxvalue
            if minvalue is not None and maxvalue is not None:
                msg = "value must be between %s and %s" % (minvalue, maxvalue)
            elif minvalue is not None:
                msg = "value must be >= %s" % minvalue
            elif maxvalue is not None:
                msg = "value must be <= %s" % maxvalue
            else:
                msg = None

            # Not using a QSpinBox for integer inputs because I could not find
            # a way to prevent the spinbox/editor from closing if the value is
            # invalid. Using the builtin minimum/maximum of the spinbox works
            # but that provides no message so it is less clear.
            editor = QLineEdit(parent)
            if is_number(self.dtype):
                validator = QDoubleValidator(editor) if is_float(self.dtype) \
                    else QIntValidator(editor)
                if minvalue is not None:
                    validator.setBottom(minvalue)
                if maxvalue is not None:
                    validator.setTop(maxvalue)
                editor.setValidator(validator)

                def on_editor_text_edited():
                    if not editor.hasAcceptableInput():
                        QToolTip.showText(editor.mapToGlobal(QPoint()), msg)
                    else:
                        QToolTip.hideText()

                if msg is not None:
                    editor.textEdited.connect(on_editor_text_edited)

            editor.setFont(self.font)
            editor.setAlignment(Qt.AlignRight)
            editor.destroyed.connect(self.on_editor_destroyed)
            self.editor_count += 1
            return editor
Пример #10
0
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setTitle("Mechanical Constants")

        layout = QFormLayout()
        validator = QDoubleValidator()
        validator.setBottom(0)
        self.youngModulus = QLineEdit()
        self.youngModulus.setValidator(validator)
        self.poissonsRatio = QLineEdit()
        self.poissonsRatio.setValidator(validator)
        layout.addRow(QLabel("Young Modulus, E (GPa)"), self.youngModulus)
        layout.addRow(QLabel("Poisson's ratio, ν"), self.poissonsRatio)

        self.setLayout(layout)
Пример #11
0
    def initialize_content(self):
        # Constraints
        for widget in [
                self._content.ei_edit,
                self._content.van_mass_edit,
                self._content.sample_mass_edit,
                self._content.sample_rmm_edit,
                self._content.median_test_high_edit,
                self._content.median_test_low_edit,
                self._content.median_test_out_high_edit,
                self._content.median_test_out_low_edit,
                self._content.errorbar_crit_edit,
        ]:

            dvp = QDoubleValidator(widget)
            dvp.setBottom(0.0)
            widget.setValidator(dvp)

        # Connections
        self._content.absunits_van_browse.clicked.connect(self._absunits_van_browse)
        self._content.absunits_detvan_browse.clicked.connect(self._absunits_detvan_browse)
        self._content.grouping_file_browse.clicked.connect(self._grouping_file_browse)
Пример #12
0
    def _build_waverange_dialog(self, wave_range, line_list):

        dialog = QDialog(parent=self.centralWidget)
        dialog.setWindowTitle("Wavelength range")
        dialog.setWindowModality(Qt.ApplicationModal)
        dialog.resize(370, 250)

        button_ok = QPushButton("OK")
        button_ok.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        button_cancel = QPushButton("Cancel")
        button_cancel.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)

        button_ok.clicked.connect(dialog.accept)
        button_cancel.clicked.connect(dialog.reject)

        min_text = QLineEdit("%.2f" % wave_range[0].value)
        max_text = QLineEdit("%.2f" % wave_range[1].value)

        validator = QDoubleValidator()
        validator.setBottom(0.0)
        validator.setDecimals(2)
        min_text.setValidator(validator)
        max_text.setValidator(validator)

        min_text.setFixedWidth(150)
        max_text.setFixedWidth(150)
        min_text.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        max_text.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        min_text.setToolTip("Minimum wavelength to read from list.")
        max_text.setToolTip("Maximum wavelength to read from list.")

        nlines_label = self._compute_nlines_in_waverange(
            line_list, min_text, max_text)

        min_text.editingFinished.connect(
            lambda: self._compute_nlines_in_waverange(
                line_list, min_text, max_text, label=nlines_label))
        max_text.editingFinished.connect(
            lambda: self._compute_nlines_in_waverange(
                line_list, min_text, max_text, label=nlines_label))

        # set up layouts and widgets for the dialog.
        text_pane = QWidget()
        text_layout = QGridLayout()

        text_layout.addWidget(min_text, 1, 0)
        text_layout.addWidget(QLabel("Minimum wavelength"), 0, 0)
        text_layout.addWidget(max_text, 1, 1)
        text_layout.addWidget(QLabel("Maximum wavelength"), 0, 1)

        spacerItem = QSpacerItem(40, 10, QSizePolicy.Expanding,
                                 QSizePolicy.Minimum)
        text_layout.addItem(spacerItem, 1, 2)
        text_pane.setLayout(text_layout)

        label_pane = QWidget()
        label_layout = QHBoxLayout()
        label_layout.addWidget(nlines_label)
        label_layout.addWidget(QLabel(" lines included in range."))
        label_layout.addStretch()
        label_pane.setLayout(label_layout)

        button_pane = QWidget()
        button_layout = QHBoxLayout()

        button_layout.addStretch()
        button_layout.addWidget(button_cancel)
        button_layout.addWidget(button_ok)
        button_pane.setLayout(button_layout)

        dialog_layout = QVBoxLayout()
        dialog_layout.setSizeConstraint(QLayout.SetMaximumSize)

        dialog_layout.addWidget(text_pane)
        dialog_layout.addWidget(label_pane)
        dialog_layout.addStretch()
        dialog_layout.addWidget(button_pane)

        dialog.setLayout(dialog_layout)

        button_ok.setDefault(True)
        button_cancel.setDefault(False)

        accepted = dialog.exec_() > 0

        amin = amax = None
        if accepted:
            return self._get_range_from_textfields(min_text, max_text)

        return (amin, amax)
Пример #13
0
    def _build_waverange_dialog(self, wave_range, line_list):

        dialog = QDialog()

        loadUi(os.path.join(os.path.dirname(__file__), "ui", "linelists_waverange.ui"), dialog)

        # convert from line list native units to whatever units
        # are currently being displayed in the spectral axis.
        linelist_units = wave_range[0].unit
        spectral_axis_unit = self.hub.plot_widget.spectral_axis_unit
        w0 = wave_range[0].to(spectral_axis_unit, equivalencies=u.spectral())
        w1 = wave_range[1].to(spectral_axis_unit, equivalencies=u.spectral())

        # populate labels with correct physical quantity name
        dispersion_unit = u.Unit(spectral_axis_unit or "")
        if dispersion_unit.physical_type == 'length':
            dialog.minwave_label.setText("Minimum wavelength")
            dialog.maxwave_label.setText("Maximum wavelength")
        elif dispersion_unit.physical_type == 'frequency':
            dialog.minwave_label.setText("Minimum frequency")
            dialog.maxwave_label.setText("Maximum frequency")
        elif dispersion_unit.physical_type == 'energy':
            dialog.minwave_label.setText("Minimum energy")
            dialog.maxwave_label.setText("Maximum energy")
        else:
            dialog.minwave_label.setText("Minimum disp. var.")
            dialog.maxwave_label.setText("Maximum disp. var.")

        # pick a good format to display values represented
        # in the currently selected plot units.
        if str(w0.unit) in units_formats:
            fmt = units_formats[str(w0.unit)]
        else:
            # use generic formatting for weirder units
            fmt = "%.6g"

        dialog.min_text.setText(fmt % w0.value)
        dialog.max_text.setText(fmt % w1.value)

        validator = QDoubleValidator()
        validator.setBottom(0.0)
        dialog.min_text.setValidator(validator)
        dialog.max_text.setValidator(validator)

        dialog.nlines_label = self._compute_nlines_in_waverange(line_list, dialog.min_text, dialog.max_text,
                                                                dialog.nlines_label, linelist_units, spectral_axis_unit)

        dialog.min_text.editingFinished.connect(lambda: self._compute_nlines_in_waverange(line_list,
                                                                                          dialog.min_text,
                                                                                          dialog.max_text,
                                                                                          dialog.nlines_label,
                                                                                          linelist_units,
                                                                                          spectral_axis_unit))
        dialog.max_text.editingFinished.connect(lambda: self._compute_nlines_in_waverange(line_list,
                                                                                          dialog.min_text,
                                                                                          dialog.max_text,
                                                                                          dialog.nlines_label,
                                                                                          linelist_units,
                                                                                          spectral_axis_unit))
        accepted = dialog.exec_() > 0

        amin = amax = None
        if accepted:
            return self._get_range_from_textfields(dialog.min_text, dialog.max_text,
                                                   linelist_units, spectral_axis_unit)
        return (amin, amax)
Пример #14
0
    def initialize_content(self):
        """ Initialize content/UI
        """
        # Constraints/Validator
        iv4 = QIntValidator(self._content.maxchunksize_edit)
        iv4.setBottom(0)
        self._content.maxchunksize_edit.setValidator(iv4)

        dv0 = QDoubleValidator(self._content.unwrap_edit)
        self._content.unwrap_edit.setValidator(dv0)

        dv2 = QDoubleValidator(self._content.lowres_edit)
        self._content.lowres_edit.setValidator(dv2)

        dv3 = QDoubleValidator(self._content.cropwavelengthmin_edit)
        dv3.setBottom(0.0)
        self._content.cropwavelengthmin_edit.setValidator(dv3)

        dv3b = QDoubleValidator(self._content.lineEdit_croppedWavelengthMax)
        dv3b.setBottom(0.1)
        self._content.lineEdit_croppedWavelengthMax.setValidator(dv3b)

        dv4 = QDoubleValidator(self._content.removepromptwidth_edit)
        dv4.setBottom(0.0)
        self._content.removepromptwidth_edit.setValidator(dv4)
        self._content.removepromptwidth_edit.setText("50.0")

        dv5 = QDoubleValidator(self._content.vanpeakfwhm_edit)
        dv5.setBottom(0.0)
        self._content.vanpeakfwhm_edit.setValidator(dv5)

        dv6 = QDoubleValidator(self._content.vanpeaktol_edit)
        dv6.setBottom(0.0)
        self._content.vanpeaktol_edit.setValidator(dv6)

        dv7 = QDoubleValidator(self._content.scaledata_edit)
        dv7.setBottom(0.0)
        self._content.scaledata_edit.setValidator(dv7)

        # Default states
        self._content.stripvanpeaks_chkbox.setChecked(True)
        self._syncStripVanPeakWidgets(True)

        self._content.preserveevents_checkbox.setChecked(True)

        dv8 = QDoubleValidator(self._content.filterbadpulses_edit)
        dv8.setBottom(0.0)
        self._content.filterbadpulses_edit.setValidator(dv8)
        self._content.filterbadpulses_edit.setText("95.")

        # Connections from action/event to function to handle
        self._content.stripvanpeaks_chkbox.clicked.connect(self._stripvanpeaks_clicked)

        self._content.help_button.clicked.connect(self._show_help)
        # Handler for events
        # TODO - Need to add an event handler for the change of instrument and facility

        # Validated widgets

        return
    def initialize_content(self):
        """ Initialize content/UI
        """
        # Initial value
        #   combo-boxes
        self._content.timeunit_combo.setCurrentIndex(0)
        self._content.valuechange_combo.setCurrentIndex(0)
        self._content.logbound_combo.setCurrentIndex(0)

        self._content.log_name_combo.clear()

        #   check-boxes
        self._content.timefilter_checkBox.setChecked(False)
        self._content.logvaluefilter_checkBox.setChecked(False)

        #   disable some input
        self._content.logname_edit.setEnabled(False)
        self._content.logminvalue_edit.setEnabled(False)
        self._content.logmaxvalue_edit.setEnabled(False)
        self._content.logintervalvalue_edit.setEnabled(False)
        self._content.valuechange_combo.setEnabled(False)
        self._content.logtol_edit.setEnabled(False)
        self._content.timetol_edit.setEnabled(False)
        self._content.logbound_combo.setEnabled(False)

        boolvalue = False
        self._content.timintervallength_edit.setEnabled(boolvalue)
        self._content.timeunit_combo.setEnabled(boolvalue)

        #   radio buttons
        # self._content.usesize_radiob.setChecked(True)

        # Constraints/Validator
        #   integers
        # iv0 = QIntValidator(self._content.numtimeinterval_edit)
        # iv0.setBottom(0)
        # self._content.numtimeinterval_edit.setValidator(iv0)

        iv1 = QIntValidator(self._content.run_number_edit)
        iv1.setBottom(0)
        self._content.run_number_edit.setValidator(iv1)

        #   floats
        dv0 = QDoubleValidator(self._content.starttime_edit)
        dv0.setBottom(0.)
        self._content.starttime_edit.setValidator(dv0)

        dv1 = QDoubleValidator(self._content.stoptime_edit)
        dv1.setBottom(0.)
        self._content.stoptime_edit.setValidator(dv1)

        dv2 = QDoubleValidator(self._content.timintervallength_edit)
        dv2.setBottom(0.)
        self._content.timintervallength_edit.setValidator(dv2)

        # Default states

        # Connections from action/event to function to handle
        self._content.timefilter_checkBox.stateChanged.connect(self._filterbytime_statechanged)

        self._content.logvaluefilter_checkBox.stateChanged.connect(self._filterbylogvalue_statechanged)

        self._content.load_button.clicked.connect(self._run_number_changed)

        self._content.run_number_edit.returnPressed.connect(self._run_number_changed)

        self._content.plot_log_button.clicked.connect(self._plot_log_clicked)

        self._content.syn_logname_button.clicked.connect(self._sync_logname_clicked)

        self._content.help_button.clicked.connect(self._show_help)

        # Validated widgets
        # self._connect_validated_lineedit(self._content.sample_edit)

        return
Пример #16
0
    def initialize(self):
        self.table_header_display_names = False

        self.setWindowTitle("PyXRF: Load Quantitative Calibration")
        self.setMinimumWidth(750)
        self.setMinimumHeight(400)
        self.resize(750, 600)

        self.pb_load_calib = QPushButton("Load Calibration ...")
        self.pb_load_calib.clicked.connect(self.pb_load_calib_clicked)

        self._changes_exist = False
        self._auto_update = True
        self.cb_auto_update = QCheckBox("Auto")
        self.cb_auto_update.setCheckState(
            Qt.Checked if self._auto_update else Qt.Unchecked)
        self.cb_auto_update.stateChanged.connect(
            self.cb_auto_update_state_changed)

        self.pb_update_plots = QPushButton("Update Plots")
        self.pb_update_plots.clicked.connect(self.pb_update_plots_clicked)

        self.grp_current_scan = QGroupBox(
            "Parameters of Currently Processed Scan")

        self._distance_to_sample = 0.0
        self.le_distance_to_sample = LineEditExtended()
        le_dist_validator = QDoubleValidator()
        le_dist_validator.setBottom(0)
        self.le_distance_to_sample.setValidator(le_dist_validator)
        self._set_distance_to_sample()
        self.le_distance_to_sample.editingFinished.connect(
            self.le_distance_to_sample_editing_finished)
        self.le_distance_to_sample.focusOut.connect(
            self.le_distance_to_sample_focus_out)

        hbox = QHBoxLayout()
        hbox.addWidget(QLabel("Distance-to-sample:"))
        hbox.addWidget(self.le_distance_to_sample)
        hbox.addStretch(1)
        self.grp_current_scan.setLayout(hbox)

        self.eline_rb_exclusive = [
        ]  # Holds the list of groups of exclusive radio buttons
        self._setup_tab_widget()

        vbox = QVBoxLayout()

        hbox = QHBoxLayout()
        hbox.addWidget(self.pb_load_calib)
        hbox.addStretch(1)
        hbox.addWidget(self.cb_auto_update)
        hbox.addWidget(self.pb_update_plots)
        vbox.addLayout(hbox)

        vbox.addWidget(self.tab_widget)

        vbox.addWidget(self.grp_current_scan)

        self.setLayout(vbox)

        # Display data
        self.update_all_data()

        self._set_tooltips()
Пример #17
0
class WndManageEmissionLines(SecondaryWindow):

    signal_selected_element_changed = Signal(str)
    signal_update_element_selection_list = Signal()
    signal_update_add_remove_btn_state = Signal(bool, bool)
    signal_marker_state_changed = Signal(bool)

    signal_parameters_changed = Signal()

    def __init__(self, *, gpc, gui_vars):
        super().__init__()

        # Global processing classes
        self.gpc = gpc
        # Global GUI variables (used for control of GUI state)
        self.gui_vars = gui_vars

        # Threshold used for peak removal (displayed in lineedit)
        self._remove_peak_threshold = self.gpc.get_peak_threshold()

        self._enable_events = False

        self._eline_list = [
        ]  # List of emission lines (used in the line selection combo)
        self._table_contents = [
        ]  # Keep a copy of table contents (list of dict)
        self._selected_eline = ""

        self.initialize()

        self._enable_events = True

        # Marker state is reported by Matplotlib plot in 'line_plot' model
        def cb(marker_state):
            self.signal_marker_state_changed.emit(marker_state)

        self.gpc.set_marker_reporter(cb)
        self.signal_marker_state_changed.connect(
            self.slot_marker_state_changed)

        # Update button states
        self._update_add_remove_btn_state()
        self._update_add_edit_userpeak_btn_state()
        self._update_add_edit_pileup_peak_btn_state()

    def initialize(self):
        self.setWindowTitle("PyXRF: Add/Remove Emission Lines")
        self.resize(600, 600)

        top_buttons = self._setup_select_elines()
        self._setup_elines_table()
        bottom_buttons = self._setup_action_buttons()

        vbox = QVBoxLayout()

        # Group of buttons above the table
        vbox.addLayout(top_buttons)

        # Tables
        hbox = QHBoxLayout()
        hbox.addWidget(self.tbl_elines)
        vbox.addLayout(hbox)

        vbox.addLayout(bottom_buttons)

        self.setLayout(vbox)

        self._set_tooltips()

    def _setup_select_elines(self):

        self.cb_select_all = QCheckBox("All")
        self.cb_select_all.setChecked(True)
        self.cb_select_all.toggled.connect(self.cb_select_all_toggled)

        self.element_selection = ElementSelection()

        # The following field should switched to 'editable' state from when needed
        self.le_peak_intensity = LineEditReadOnly()

        self.pb_add_eline = QPushButton("Add")
        self.pb_add_eline.clicked.connect(self.pb_add_eline_clicked)

        self.pb_remove_eline = QPushButton("Remove")
        self.pb_remove_eline.clicked.connect(self.pb_remove_eline_clicked)

        self.pb_user_peaks = QPushButton("New User Peak ...")
        self.pb_user_peaks.clicked.connect(self.pb_user_peaks_clicked)
        self.pb_pileup_peaks = QPushButton("New Pileup Peak ...")
        self.pb_pileup_peaks.clicked.connect(self.pb_pileup_peaks_clicked)

        self.element_selection.signal_current_item_changed.connect(
            self.element_selection_item_changed)

        vbox = QVBoxLayout()

        hbox = QHBoxLayout()
        hbox.addWidget(self.element_selection)
        hbox.addWidget(self.le_peak_intensity)
        hbox.addWidget(self.pb_add_eline)
        hbox.addWidget(self.pb_remove_eline)
        vbox.addLayout(hbox)

        hbox = QHBoxLayout()
        hbox.addWidget(self.cb_select_all)
        hbox.addStretch(1)
        hbox.addWidget(self.pb_user_peaks)
        hbox.addWidget(self.pb_pileup_peaks)
        vbox.addLayout(hbox)

        # Wrap vbox into hbox, because it will be inserted into vbox
        hbox = QHBoxLayout()
        hbox.addLayout(vbox)
        hbox.addStretch(1)
        return hbox

    def _setup_elines_table(self):
        """The table has only functionality necessary to demonstrate how it is going
        to look. A lot more code is needed to actually make it run."""

        self._validator_peak_height = QDoubleValidator()
        self._validator_peak_height.setBottom(0.01)

        self.tbl_elines = QTableWidget()
        self.tbl_elines.setStyleSheet(
            "QTableWidget::item{color: black;}"
            "QTableWidget::item:selected{background-color: red;}"
            "QTableWidget::item:selected{color: white;}")

        self.tbl_labels = [
            "", "Z", "Line", "E, keV", "Peak Int.", "Rel. Int.(%)", "CS"
        ]
        self.tbl_cols_editable = ["Peak Int."]
        self.tbl_value_min = {"Rel. Int.(%)": 0.1}
        tbl_cols_resize_to_content = ["", "Z", "Line"]

        self.tbl_elines.setColumnCount(len(self.tbl_labels))
        self.tbl_elines.verticalHeader().hide()
        self.tbl_elines.setHorizontalHeaderLabels(self.tbl_labels)

        self.tbl_elines.setSelectionBehavior(QTableWidget.SelectRows)
        self.tbl_elines.setSelectionMode(QTableWidget.SingleSelection)
        self.tbl_elines.itemSelectionChanged.connect(
            self.tbl_elines_item_selection_changed)
        self.tbl_elines.itemChanged.connect(self.tbl_elines_item_changed)

        header = self.tbl_elines.horizontalHeader()
        for n, lbl in enumerate(self.tbl_labels):
            # Set stretching for the columns
            if lbl in tbl_cols_resize_to_content:
                header.setSectionResizeMode(n, QHeaderView.ResizeToContents)
            else:
                header.setSectionResizeMode(n, QHeaderView.Stretch)
            # Set alignment for the columns headers (HEADERS only)
            if n == 0:
                header.setDefaultAlignment(Qt.AlignCenter)
            else:
                header.setDefaultAlignment(Qt.AlignRight)

        self.cb_sel_list = []  # List of checkboxes

    def _setup_action_buttons(self):
        self.pb_remove_rel = QPushButton("Remove Rel.Int.(%) <")
        self.pb_remove_rel.clicked.connect(self.pb_remove_rel_clicked)

        self.le_remove_rel = LineEditExtended("")
        self._validator_le_remove_rel = QDoubleValidator()
        self._validator_le_remove_rel.setBottom(0.01)  # Some small number
        self._validator_le_remove_rel.setTop(100.0)
        self.le_remove_rel.setText(
            self._format_threshold(self._remove_peak_threshold))
        self._update_le_remove_rel_state()
        self.le_remove_rel.textChanged.connect(self.le_remove_rel_text_changed)
        self.le_remove_rel.editingFinished.connect(
            self.le_remove_rel_editing_finished)

        self.pb_remove_unchecked = QPushButton("Remove Unchecked Lines")
        self.pb_remove_unchecked.clicked.connect(
            self.pb_remove_unchecked_clicked)

        hbox = QHBoxLayout()
        hbox.addWidget(self.pb_remove_rel)
        hbox.addWidget(self.le_remove_rel)
        hbox.addStretch(1)
        hbox.addWidget(self.pb_remove_unchecked)

        return hbox

    def _set_tooltips(self):
        set_tooltip(self.cb_select_all,
                    "<b>Select/Deselect All</b> emission lines in the list")
        set_tooltip(self.element_selection, "<b>Set active</b> emission line")
        set_tooltip(self.le_peak_intensity,
                    "Set or modify <b>intensity</b> of the active peak.")
        set_tooltip(self.pb_add_eline, "<b>Add</b> emission line to the list.")
        set_tooltip(self.pb_remove_eline,
                    "<b>Remove</b> emission line from the list.")
        set_tooltip(
            self.pb_user_peaks,
            "Open dialog box to add or modify parameters of the <b>user-defined peak</b>"
        )
        set_tooltip(
            self.pb_pileup_peaks,
            "Open dialog box to add or modify parameters of the <b>pileup peak</b>"
        )

        set_tooltip(self.tbl_elines,
                    "The list of the selected <b>emission lines</b>")

        # set_tooltip(self.pb_update,
        #             "Update the internally stored list of selected emission lines "
        #             "and their parameters. This button is <b>deprecated</b>, but still may be "
        #             "needed in some situations. In future releases it will be <b>removed</b> or replaced "
        #             "with 'Accept' button. Substantial changes to the computational code is needed before "
        #             "it happens.")
        # set_tooltip(self.pb_undo,
        #             "<b>Undo</b> changes to the table of selected emission lines. Doesn't always work.")
        set_tooltip(
            self.pb_remove_rel,
            "<b>Remove emission lines</b> from the list if their relative intensity is less "
            "then specified threshold.",
        )
        set_tooltip(
            self.le_remove_rel,
            "<b>Threshold</b> that controls which emission lines are removed "
            "when <b>Remove Rel.Int.(%)</b> button is pressed.",
        )
        set_tooltip(self.pb_remove_unchecked,
                    "Remove <b>unchecked</b> emission lines from the list.")

    def update_widget_state(self, condition=None):
        # Update the state of the menu bar
        state = not self.gui_vars["gui_state"]["running_computations"]
        self.setEnabled(state)

        # Hide the window if required by the program state
        state_file_loaded = self.gui_vars["gui_state"]["state_file_loaded"]
        state_model_exist = self.gui_vars["gui_state"]["state_model_exists"]
        if not state_file_loaded or not state_model_exist:
            self.hide()

        if condition == "tooltips":
            self._set_tooltips()

    def fill_eline_table(self, table_contents):
        self._table_contents = copy.deepcopy(table_contents)

        self._enable_events = False

        self.tbl_elines.clearContents()

        # Clear the list of checkboxes
        for cb in self.cb_sel_list:
            cb.stateChanged.connect(self.cb_eline_state_changed)
        self.cb_sel_list = []

        self.tbl_elines.setRowCount(len(table_contents))
        for nr, row in enumerate(table_contents):
            sel_status = row["sel_status"]
            row_data = [
                None, row["z"], row["eline"], row["energy"], row["peak_int"],
                row["rel_int"], row["cs"]
            ]

            for nc, entry in enumerate(row_data):

                label = self.tbl_labels[nc]

                # Set alternating background colors for the table rows
                #   Make background for editable items a little brighter
                brightness = 240 if label in self.tbl_cols_editable else 220
                if nr % 2:
                    rgb_bckg = (255, brightness, brightness)  # Light-red
                else:
                    rgb_bckg = (brightness, 255, brightness)  # Light-green

                if nc == 0:
                    item = QWidget()
                    cb = CheckBoxNamed(name=f"{nr}")
                    item_hbox = QHBoxLayout(item)
                    item_hbox.addWidget(cb)
                    item_hbox.setAlignment(Qt.AlignCenter)
                    item_hbox.setContentsMargins(0, 0, 0, 0)

                    css1 = get_background_css(rgb_bckg,
                                              widget="QCheckbox",
                                              editable=False)
                    css2 = get_background_css(rgb_bckg,
                                              widget="QWidget",
                                              editable=False)
                    item.setStyleSheet(css2 + css1)

                    cb.setChecked(Qt.Checked if sel_status else Qt.Unchecked)
                    cb.stateChanged.connect(self.cb_eline_state_changed)
                    cb.setStyleSheet("QCheckBox {color: black;}")
                    self.cb_sel_list.append(cb)

                    self.tbl_elines.setCellWidget(nr, nc, item)
                else:

                    s = None
                    # The case when the value (Rel. Int.) is limited from the bottom
                    #   We don't want to print very small numbers here
                    if label in self.tbl_value_min:
                        v = self.tbl_value_min[label]
                        if isinstance(entry,
                                      (float, np.float64)) and (entry < v):
                            s = f"<{v:.2f}"
                    if s is None:
                        if isinstance(entry, (float, np.float64)):
                            s = f"{entry:.2f}" if entry else "-"
                        else:
                            s = f"{entry}" if entry else "-"

                    item = QTableWidgetItem(s)

                    item.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter)

                    # Set all columns not editable (unless needed)
                    if label not in self.tbl_cols_editable:
                        item.setFlags(item.flags() & ~Qt.ItemIsEditable)

                    brush = QBrush(QColor(*rgb_bckg))
                    item.setBackground(brush)

                    self.tbl_elines.setItem(nr, nc, item)

        self._enable_events = True
        # Update the rest of the widgets
        self._update_widgets_based_on_table_state()

    @Slot()
    def update_widget_data(self):
        # This is typically a new set of emission lines. Clear the selection both
        #   in the table and in the element selection tool.
        self.element_selection.set_current_item("")
        self.tbl_elines.clearSelection()
        self._set_selected_eline("")
        # Now update the tables
        self._update_eline_selection_list()
        self.update_eline_table()
        self._update_add_remove_btn_state()

    def pb_pileup_peaks_clicked(self):
        data = {}

        eline = self._selected_eline
        if self.gpc.get_eline_name_category(eline) == "pileup":
            logger.error(
                f"Attempt to add pileup peak '{eline}' while another pileup peak is selected."
            )
            return

        energy, marker_visible = self.gpc.get_suggested_manual_peak_energy()
        best_guess = self.gpc.get_guessed_pileup_peak_components(energy=energy,
                                                                 tolerance=0.1)
        if best_guess is not None:
            el1, el2, energy = best_guess
        else:
            # No peaks were found, enter peaks manually
            el1, el2, energy = "", "", 0
        data["element1"] = el1
        data["element2"] = el2
        data["energy"] = energy
        data["range_low"], data[
            "range_high"] = self.gpc.get_selected_energy_range()

        if not marker_visible:
            # We shouldn't end up here, but this will protect from crashing in case
            #   the button was not disabled (a bug).
            msg = "Select location of the new peak center (energy)\nby clicking on the plot in 'Fit Model' tab"
            msgbox = QMessageBox(QMessageBox.Information,
                                 "User Input Required",
                                 msg,
                                 QMessageBox.Ok,
                                 parent=self)
            msgbox.exec()
        else:
            dlg = DialogPileupPeakParameters()

            def func():
                def f(e1, e2):
                    try:
                        name = self.gpc.generate_pileup_peak_name(e1, e2)
                        e = self.gpc.get_pileup_peak_energy(name)
                    except Exception:
                        e = 0
                    return e

                return f

            dlg.set_compute_energy_function(func())
            dlg.set_parameters(data)
            if dlg.exec():
                print("Pileup peak is added")
                try:
                    data = dlg.get_parameters()
                    eline1, eline2 = data["element1"], data["element2"]
                    eline = self.gpc.generate_pileup_peak_name(eline1, eline2)
                    self.gpc.add_peak_manual(eline)
                    self.update_eline_table()  # Update the table
                    self.tbl_elines_set_selection(
                        eline)  # Select new emission line
                    self._set_selected_eline(eline)
                    self._set_fit_status(False)
                    logger.info(f"New pileup peak {eline} was added")
                except RuntimeError as ex:
                    msg = str(ex)
                    msgbox = QMessageBox(QMessageBox.Critical,
                                         "Error",
                                         msg,
                                         QMessageBox.Ok,
                                         parent=self)
                    msgbox.exec()
                    # Reload the table anyway (nothing is going to be selected)
                    self.update_eline_table()

    def pb_user_peaks_clicked(self):
        eline = self._selected_eline
        # If current peak is user_defined peak
        is_userpeak = self.gpc.get_eline_name_category(eline) == "userpeak"

        if is_userpeak:
            data = {}
            data["enabled"] = True
            data["name"] = eline
            data["maxv"] = self.gpc.get_eline_intensity(eline)
            data["energy"], data[
                "fwhm"] = self.gpc.get_current_userpeak_energy_fwhm()

            dlg = DialogEditUserPeakParameters()
            dlg.set_parameters(data=data)
            if dlg.exec():
                print("Editing of user defined peak is completed")
                try:
                    eline = data["name"]
                    data = dlg.get_parameters()
                    self.gpc.update_userpeak(data["name"], data["energy"],
                                             data["maxv"], data["fwhm"])
                    self._set_fit_status(False)
                    logger.info(f"User defined peak {eline} was updated.")
                except Exception as ex:
                    msg = str(ex)
                    msgbox = QMessageBox(QMessageBox.Critical,
                                         "Error",
                                         msg,
                                         QMessageBox.Ok,
                                         parent=self)
                    msgbox.exec()
                # Reload the table anyway (nothing is going to be selected)
                self.update_eline_table()

        else:
            data = {}
            data["name"] = self.gpc.get_unused_userpeak_name()
            data[
                "energy"], marker_visible = self.gpc.get_suggested_manual_peak_energy(
                )
            if marker_visible:
                dlg = DialogNewUserPeak()
                dlg.set_parameters(data=data)
                if dlg.exec():
                    try:
                        eline = data["name"]
                        self.gpc.add_peak_manual(eline)
                        self.update_eline_table()  # Update the table
                        self.tbl_elines_set_selection(
                            eline)  # Select new emission line
                        self._set_selected_eline(eline)
                        self._set_fit_status(False)
                        logger.info(f"New user defined peak {eline} is added")
                    except RuntimeError as ex:
                        msg = str(ex)
                        msgbox = QMessageBox(QMessageBox.Critical,
                                             "Error",
                                             msg,
                                             QMessageBox.Ok,
                                             parent=self)
                        msgbox.exec()
                        # Reload the table anyway (nothing is going to be selected)
                        self.update_eline_table()
            else:
                msg = ("Select location of the new peak center (energy)\n"
                       "by clicking on the plot in 'Fit Model' tab")
                msgbox = QMessageBox(QMessageBox.Information,
                                     "User Input Required",
                                     msg,
                                     QMessageBox.Ok,
                                     parent=self)
                msgbox.exec()

    @Slot()
    def pb_add_eline_clicked(self):
        logger.debug("'Add line' clicked")
        # It is assumed that this button is active only if an element is selected from the list
        #   of available emission lines. It can't be used to add user-defined peaks or pileup peaks.
        eline = self._selected_eline
        if eline:
            try:
                self.gpc.add_peak_manual(eline)
                self.update_eline_table()  # Update the table
                self.tbl_elines_set_selection(
                    eline)  # Select new emission line
                self._set_fit_status(False)
            except RuntimeError as ex:
                msg = str(ex)
                msgbox = QMessageBox(QMessageBox.Critical,
                                     "Error",
                                     msg,
                                     QMessageBox.Ok,
                                     parent=self)
                msgbox.exec()
                # Reload the table anyway (nothing is going to be selected)
                self.update_eline_table()

    @Slot()
    def pb_remove_eline_clicked(self):
        logger.debug("'Remove line' clicked")
        eline = self._selected_eline
        if eline:
            # If currently selected line is the emission line (like Ca_K), we want
            # it to remain selected after it is deleted. This means that nothing is selected
            # in the table. For other lines, nothing should remain selected.
            self.tbl_elines.clearSelection()
            self.gpc.remove_peak_manual(eline)
            self.update_eline_table()  # Update the table
            if self.gpc.get_eline_name_category(eline) != "eline":
                eline = ""
            # This will update widgets
            self._set_selected_eline(eline)
            self._set_fit_status(False)

    def cb_select_all_toggled(self, state):
        self._enable_events = False

        eline_list, state_list = [], []

        for n_row in range(self.tbl_elines.rowCount()):
            eline = self._table_contents[n_row]["eline"]
            # Do not deselect lines in category 'other'. They probably never to be deleted.
            # They also could be deselected manually.
            if self.gpc.get_eline_name_category(
                    eline) == "other" and not state:
                to_check = True
            else:
                to_check = state
            self.cb_sel_list[n_row].setChecked(
                Qt.Checked if to_check else Qt.Unchecked)
            eline_list.append(eline)
            state_list.append(to_check)

        self.gpc.set_checked_emission_lines(eline_list, state_list)
        self._set_fit_status(False)
        self._enable_events = True

    def cb_eline_state_changed(self, name, state):
        if self._enable_events:
            n_row = int(name)
            state = state == Qt.Checked
            eline = self._table_contents[n_row]["eline"]
            self.gpc.set_checked_emission_lines([eline], [state])
            self._set_fit_status(False)

    def tbl_elines_item_changed(self, item):
        if self._enable_events:
            n_row, n_col = self.tbl_elines.row(item), self.tbl_elines.column(
                item)
            # Value was changed
            if n_col == 4:
                text = item.text()
                eline = self._table_contents[n_row]["eline"]
                if self._validator_peak_height.validate(
                        text, 0)[0] != QDoubleValidator.Acceptable:
                    val = self._table_contents[n_row]["peak_int"]
                    self._enable_events = False
                    item.setText(f"{val:.2f}")
                    self._enable_events = True
                    self._set_fit_status(False)
                else:
                    self.gpc.update_eline_peak_height(eline, float(text))
                    self.update_eline_table()

    def tbl_elines_item_selection_changed(self):
        sel_ranges = self.tbl_elines.selectedRanges()
        # The table is configured to have one or no selected ranges
        # 'Open' button should be enabled only if a range (row) is selected
        if sel_ranges:
            index = sel_ranges[0].topRow()
            eline = self._table_contents[index]["eline"]
            if self._enable_events:
                self._enable_events = False
                self._set_selected_eline(eline)
                self.element_selection.set_current_item(eline)
                self._enable_events = True

    def tbl_elines_set_selection(self, eline):
        """
        Select the row with emission line `eline` in the table. Deselect everything if
        the emission line does not exist.
        """
        index = self._get_eline_index_in_table(eline)
        self.tbl_elines.clearSelection()
        if index >= 0:
            self.tbl_elines.selectRow(index)

    def element_selection_item_changed(self, index, eline):
        self.signal_selected_element_changed.emit(eline)

        if self._enable_events:
            self._enable_events = False
            self._set_selected_eline(eline)
            self.tbl_elines_set_selection(eline)
            self._enable_events = True

    def pb_remove_rel_clicked(self):
        try:
            self.gpc.remove_peaks_below_threshold(self._remove_peak_threshold)
        except Exception as ex:
            msg = str(ex)
            msgbox = QMessageBox(QMessageBox.Critical,
                                 "Error",
                                 msg,
                                 QMessageBox.Ok,
                                 parent=self)
            msgbox.exec()
        self.update_eline_table()
        # Update the displayed estimated peak amplitude value 'le_peak_intensity'
        self._set_selected_eline(self._selected_eline)
        self._set_fit_status(False)

    def le_remove_rel_text_changed(self, text):
        self._update_le_remove_rel_state(text)

    def le_remove_rel_editing_finished(self):
        text = self.le_remove_rel.text()
        if self._validator_le_remove_rel.validate(
                text, 0)[0] == QDoubleValidator.Acceptable:
            self._remove_peak_threshold = float(text)
        else:
            self.le_remove_rel.setText(
                self._format_threshold(self._remove_peak_threshold))

    def pb_remove_unchecked_clicked(self):
        try:
            self.gpc.remove_unchecked_peaks()
        except Exception as ex:
            msg = str(ex)
            msgbox = QMessageBox(QMessageBox.Critical,
                                 "Error",
                                 msg,
                                 QMessageBox.Ok,
                                 parent=self)
            msgbox.exec()
        # Reload the table
        self.update_eline_table()
        # Update the displayed estimated peak amplitude value 'le_peak_intensity'
        self._set_selected_eline(self._selected_eline)
        self._set_fit_status(False)

    def _display_peak_intensity(self, eline):
        v = self.gpc.get_eline_intensity(eline)
        s = f"{v:.10g}" if v is not None else ""
        self.le_peak_intensity.setText(s)

    def _update_le_remove_rel_state(self, text=None):
        if text is None:
            text = self.le_remove_rel.text()
        state = self._validator_le_remove_rel.validate(
            text, 0)[0] == QDoubleValidator.Acceptable
        self.le_remove_rel.setValid(state)
        self.pb_remove_rel.setEnabled(state)

    @Slot(str)
    def slot_selection_item_changed(self, eline):
        self.element_selection.set_current_item(eline)

    @Slot(bool)
    def slot_marker_state_changed(self, state):
        # If userpeak is selected and plot is clicked (marker is set), then user
        #   should be allowed to add userpeak at a new location. So deselect the userpeak
        #   from the table (if it is selected)
        logger.debug(
            f"Vertical marker on the fit plot changed state to {state}.")
        if state:
            self._deselect_special_peak_in_table()
        # Now update state of all buttons
        self._update_add_remove_btn_state()
        self._update_add_edit_userpeak_btn_state()
        self._update_add_edit_pileup_peak_btn_state()

    def _format_threshold(self, value):
        return f"{value:.2f}"

    def _deselect_special_peak_in_table(self):
        """Deselect userpeak if a userpeak is selected"""
        if self.gpc.get_eline_name_category(
                self._selected_eline) in ("userpeak", "pileup"):
            # Clear all selections
            self.tbl_elines_set_selection("")
            self._set_selected_eline("")
            # We also want to show marker at the new position
            self.gpc.show_marker_at_current_position()

    def _update_widgets_based_on_table_state(self):
        index, eline = self._get_current_index_in_table()
        if index >= 0:
            # Selection exists. Update the state of element selection widget.
            self.element_selection.set_current_item(eline)
        else:
            # No selection, update the state based on element selection widget.
            eline = self._selected_eline
            self.tbl_elines_set_selection(eline)
        self._update_add_remove_btn_state(eline)
        self._update_add_edit_userpeak_btn_state()
        self._update_add_edit_pileup_peak_btn_state()

    def _update_eline_selection_list(self):
        self._eline_list = self.gpc.get_full_eline_list()
        self.element_selection.set_item_list(self._eline_list)
        self.signal_update_element_selection_list.emit()

    @Slot()
    def update_eline_table(self):
        """Update table of emission lines without changing anything else"""
        eline_table = self.gpc.get_selected_eline_table()
        self.fill_eline_table(eline_table)

    def _get_eline_index_in_table(self, eline):
        try:
            index = [_["eline"] for _ in self._table_contents].index(eline)
        except ValueError:
            index = -1
        return index

    def _get_eline_index_in_list(self, eline):
        try:
            index = self._eline_list.index(eline)
        except ValueError:
            index = -1
        return index

    def _get_current_index_in_table(self):
        sel_ranges = self.tbl_elines.selectedRanges()
        # The table is configured to have one or no selected ranges
        # 'Open' button should be enabled only if a range (row) is selected
        if sel_ranges:
            index = sel_ranges[0].topRow()
            eline = self._table_contents[index]["eline"]
        else:
            index, eline = -1, ""
        return index, eline

    def _get_current_index_in_list(self):
        index, eline = self.element_selection.get_current_item()
        return index, eline

    def _update_add_remove_btn_state(self, eline=None):
        if eline is None:
            index_in_table, eline = self._get_current_index_in_table()
            index_in_list, eline = self._get_current_index_in_list()
        else:
            index_in_table = self._get_eline_index_in_table(eline)
            index_in_list = self._get_eline_index_in_list(eline)
        add_enabled, remove_enabled = True, True
        if index_in_list < 0 and index_in_table < 0:
            add_enabled, remove_enabled = False, False
        else:
            if index_in_table >= 0:
                if self.gpc.get_eline_name_category(eline) != "other":
                    add_enabled = False
                else:
                    add_enabled, remove_enabled = False, False
            else:
                remove_enabled = False
        self.pb_add_eline.setEnabled(add_enabled)
        self.pb_remove_eline.setEnabled(remove_enabled)
        self.signal_update_add_remove_btn_state.emit(add_enabled,
                                                     remove_enabled)

    def _update_add_edit_userpeak_btn_state(self):

        enabled = True
        add_peak = True
        if self.gpc.get_eline_name_category(
                self._selected_eline) == "userpeak":
            add_peak = False

        # Finally check if marker is set (you need it for adding peaks)
        _, marker_set = self.gpc.get_suggested_manual_peak_energy()

        if not marker_set and add_peak:
            enabled = False

        if add_peak:
            btn_text = "New User Peak ..."
        else:
            btn_text = "Edit User Peak ..."
        self.pb_user_peaks.setText(btn_text)
        self.pb_user_peaks.setEnabled(enabled)

    def _update_add_edit_pileup_peak_btn_state(self):

        enabled = True
        if self.gpc.get_eline_name_category(self._selected_eline) == "pileup":
            enabled = False

        # Finally check if marker is set (you need it for adding peaks)
        _, marker_set = self.gpc.get_suggested_manual_peak_energy()
        # Ignore set marker for userpeaks (marker is used to display location of userpeaks)
        if self.gpc.get_eline_name_category(
                self._selected_eline) == "userpeak":
            marker_set = False

        if not marker_set:
            enabled = False

        self.pb_pileup_peaks.setEnabled(enabled)

    def _set_selected_eline(self, eline):
        self._update_add_remove_btn_state(eline)
        if eline != self._selected_eline:
            self._selected_eline = eline
            self.gpc.set_selected_eline(eline)
            self._display_peak_intensity(eline)
        else:
            # Peak intensity may change in some circumstances, so renew the displayed value.
            self._display_peak_intensity(eline)
        # Update button states after 'self._selected_eline' is set
        self._update_add_edit_userpeak_btn_state()
        self._update_add_edit_pileup_peak_btn_state()

    def _set_fit_status(self, status):
        self.gui_vars["gui_state"]["state_model_fit_exists"] = status
        self.signal_parameters_changed.emit()
Пример #18
0
    def initialize_content(self):
        """ Initialize content/UI
        """
        # Constraints/Validator
        iv4 = QIntValidator(self._content.maxchunksize_edit)
        iv4.setBottom(0)
        self._content.maxchunksize_edit.setValidator(iv4)

        dv0 = QDoubleValidator(self._content.unwrap_edit)
        self._content.unwrap_edit.setValidator(dv0)

        dv2 = QDoubleValidator(self._content.lowres_edit)
        self._content.lowres_edit.setValidator(dv2)

        dv3 = QDoubleValidator(self._content.cropwavelengthmin_edit)
        dv3.setBottom(0.0)
        self._content.cropwavelengthmin_edit.setValidator(dv3)

        dv3b = QDoubleValidator(self._content.lineEdit_croppedWavelengthMax)
        dv3b.setBottom(0.1)
        self._content.lineEdit_croppedWavelengthMax.setValidator(dv3b)

        dv4 = QDoubleValidator(self._content.removepromptwidth_edit)
        dv4.setBottom(0.0)
        self._content.removepromptwidth_edit.setValidator(dv4)
        self._content.removepromptwidth_edit.setText("50.0")

        dv5 = QDoubleValidator(self._content.vanpeakfwhm_edit)
        dv5.setBottom(0.0)
        self._content.vanpeakfwhm_edit.setValidator(dv5)

        dv6 = QDoubleValidator(self._content.vanpeaktol_edit)
        dv6.setBottom(0.0)
        self._content.vanpeaktol_edit.setValidator(dv6)

        dv7 = QDoubleValidator(self._content.scaledata_edit)
        dv7.setBottom(0.0)
        self._content.scaledata_edit.setValidator(dv7)

        # Default states
        self._content.stripvanpeaks_chkbox.setChecked(True)
        self._syncStripVanPeakWidgets(True)

        self._content.preserveevents_checkbox.setChecked(True)

        dv8 = QDoubleValidator(self._content.filterbadpulses_edit)
        dv8.setBottom(0.0)
        self._content.filterbadpulses_edit.setValidator(dv8)
        self._content.filterbadpulses_edit.setText("95.")

        # Connections from action/event to function to handle
        self._content.stripvanpeaks_chkbox.clicked.connect(
            self._stripvanpeaks_clicked)

        self._content.help_button.clicked.connect(self._show_help)
        # Handler for events
        # TODO - Need to add an event handler for the change of instrument and facility

        # Validated widgets

        return
Пример #19
0
    def initialize_content(self):
        """ Initialize content/UI
        """
        # Constraints/Validator
        iv4 = QIntValidator(self._content.maxchunksize_edit)
        iv4.setBottom(0)
        self._content.maxchunksize_edit.setValidator(iv4)

        dv0 = QDoubleValidator(self._content.unwrap_edit)
        self._content.unwrap_edit.setValidator(dv0)

        dv2 = QDoubleValidator(self._content.lowres_edit)
        self._content.lowres_edit.setValidator(dv2)

        dv3 = QDoubleValidator(self._content.cropwavelengthmin_edit)
        dv3.setBottom(0.0)
        self._content.cropwavelengthmin_edit.setValidator(dv3)

        dv3b = QDoubleValidator(self._content.lineEdit_croppedWavelengthMax)
        dv3b.setBottom(0.1)
        self._content.lineEdit_croppedWavelengthMax.setValidator(dv3b)

        dv4 = QDoubleValidator(self._content.removepromptwidth_edit)
        dv4.setBottom(0.0)
        self._content.removepromptwidth_edit.setValidator(dv4)
        self._content.removepromptwidth_edit.setText("50.0")

        dv5 = QDoubleValidator(self._content.vanpeakfwhm_edit)
        dv5.setBottom(0.0)
        self._content.vanpeakfwhm_edit.setValidator(dv5)

        dv6 = QDoubleValidator(self._content.vanpeaktol_edit)
        dv6.setBottom(0.0)
        self._content.vanpeaktol_edit.setValidator(dv6)

        dv7 = QDoubleValidator(self._content.scaledata_edit)
        dv7.setBottom(0.0)
        self._content.scaledata_edit.setValidator(dv7)

        dv8 = QDoubleValidator(self._content.numberdensity_edit)
        dv8.setBottom(0.0)
        self._content.numberdensity_edit.setValidator(dv8)
        self._content.numberdensity_edit.editingFinished.connect(
            self._calculate_packing_fraction)

        dv9 = QDoubleValidator(self._content.massdensity_edit)
        dv9.setBottom(0.0)
        self._content.massdensity_edit.setValidator(dv9)
        self._content.massdensity_edit.editingFinished.connect(
            self._calculate_packing_fraction)

        self._content.sampleformula_edit.textEdited.connect(
            self._validate_formula)
        self._content.sampleformula_edit.editingFinished.connect(
            self._calculate_packing_fraction)

        dv10 = QDoubleValidator(self._content.vanadiumradius_edit)
        dv10.setBottom(0.0)
        self._content.vanadiumradius_edit.setValidator(dv10)

        # Default states
        self._content.stripvanpeaks_chkbox.setChecked(True)
        self._syncStripVanPeakWidgets(True)

        self._content.preserveevents_checkbox.setChecked(True)

        dv8 = QDoubleValidator(self._content.filterbadpulses_edit)
        dv8.setBottom(0.0)
        self._content.filterbadpulses_edit.setValidator(dv8)
        self._content.filterbadpulses_edit.setText("95.")

        # Connections from action/event to function to handle
        self._content.stripvanpeaks_chkbox.clicked.connect(
            self._stripvanpeaks_clicked)

        self._content.help_button.clicked.connect(self._show_help)
        # Handler for events
        # TODO - Need to add an event handler for the change of instrument and facility

        self._content.material_help_button.clicked.connect(
            functools.partial(self._show_concept_help, "Materials"))
        self._content.absorption_help_button.clicked.connect(
            functools.partial(self._show_concept_help,
                              "AbsorptionAndMultipleScattering"))

        # Initialization for Caching options
        self._content.cache_dir_browse_1.clicked.connect(
            self._cache_dir_browse_1)
        self._content.cache_dir_browse_2.clicked.connect(
            self._cache_dir_browse_2)
        self._content.cache_dir_browse_3.clicked.connect(
            self._cache_dir_browse_3)

        # Validated widgets

        return
Пример #20
0
    def initialize_content(self):
        """ Initialize content/UI
        """
        # Initial value
        #   combo-boxes
        self._content.timeunit_combo.setCurrentIndex(0)
        self._content.valuechange_combo.setCurrentIndex(0)
        self._content.logbound_combo.setCurrentIndex(0)

        self._content.log_name_combo.clear()

        #   check-boxes
        self._content.timefilter_checkBox.setChecked(False)
        self._content.logvaluefilter_checkBox.setChecked(False)

        #   disable some input
        self._content.logname_edit.setEnabled(False)
        self._content.logminvalue_edit.setEnabled(False)
        self._content.logmaxvalue_edit.setEnabled(False)
        self._content.logintervalvalue_edit.setEnabled(False)
        self._content.valuechange_combo.setEnabled(False)
        self._content.logtol_edit.setEnabled(False)
        self._content.timetol_edit.setEnabled(False)
        self._content.logbound_combo.setEnabled(False)

        boolvalue = False
        self._content.timintervallength_edit.setEnabled(boolvalue)
        self._content.timeunit_combo.setEnabled(boolvalue)

        #   radio buttons
        # self._content.usesize_radiob.setChecked(True)

        # Constraints/Validator
        #   integers
        # iv0 = QIntValidator(self._content.numtimeinterval_edit)
        # iv0.setBottom(0)
        # self._content.numtimeinterval_edit.setValidator(iv0)

        iv1 = QIntValidator(self._content.run_number_edit)
        iv1.setBottom(0)
        self._content.run_number_edit.setValidator(iv1)

        #   floats
        dv0 = QDoubleValidator(self._content.starttime_edit)
        dv0.setBottom(0.)
        self._content.starttime_edit.setValidator(dv0)

        dv1 = QDoubleValidator(self._content.stoptime_edit)
        dv1.setBottom(0.)
        self._content.stoptime_edit.setValidator(dv1)

        dv2 = QDoubleValidator(self._content.timintervallength_edit)
        dv2.setBottom(0.)
        self._content.timintervallength_edit.setValidator(dv2)

        # Default states

        # Connections from action/event to function to handle
        self._content.timefilter_checkBox.stateChanged.connect(
            self._filterbytime_statechanged)

        self._content.logvaluefilter_checkBox.stateChanged.connect(
            self._filterbylogvalue_statechanged)

        self._content.load_button.clicked.connect(self._run_number_changed)

        self._content.run_number_edit.returnPressed.connect(
            self._run_number_changed)

        self._content.plot_log_button.clicked.connect(self._plot_log_clicked)

        self._content.syn_logname_button.clicked.connect(
            self._sync_logname_clicked)

        self._content.help_button.clicked.connect(self._show_help)

        # Validated widgets
        # self._connect_validated_lineedit(self._content.sample_edit)

        return