class TrainingPanel(Panel): def __init__(self, datasets, testing_panel, threads): super().__init__() if isinstance(testing_panel, TestingPanel): self.testing_panel = testing_panel else: raise TypeError('"testing_panel" must be the instance of ' '"TestingPanel"') self.datasets = datasets self.threads = threads self.__set_execution_ui() self.__set_options_ui() self.__set_outputs_ui() self.__set_graphic_ui() def __set_execution_ui(self): group_box = QGroupBox('Training Execution') inner_layout = QHBoxLayout() group_box.setLayout(inner_layout) self.data_selector = QComboBox() self.data_selector.addItems(list(self.datasets.keys())) self.data_selector.setStatusTip('Select the training dataset.') self.start_btn = QPushButton('Train') self.start_btn.setStatusTip('Start training.') self.start_btn.clicked.connect(self.__run) self.stop_btn = QPushButton('Stop') self.stop_btn.setStatusTip('Force the training stop running.') self.stop_btn.setDisabled(True) self.multicore_cb = QCheckBox('Multicore') self.multicore_cb.setStatusTip('Use multiprocessing in calculating ' 'fitting for populations.') self.multicore_cb.setChecked(True) inner_layout.addWidget(self.data_selector, 1) inner_layout.addWidget(self.start_btn) inner_layout.addWidget(self.stop_btn) inner_layout.addWidget(self.multicore_cb) self._layout.addWidget(group_box) def __set_options_ui(self): group_box = QGroupBox('Training Options') inner_layout = QFormLayout() group_box.setLayout(inner_layout) self.iter_times = QSpinBox() self.iter_times.setRange(1, 1000000) self.iter_times.setValue(200) self.iter_times.setStatusTip('The total iterating times for training.') self.population_size = QSpinBox() self.population_size.setRange(1, 100000) self.population_size.setValue(100) self.population_size.setStatusTip('The population size for the PSO.') self.inertia_weight = QDoubleSpinBox() self.inertia_weight.setRange(0, 50) self.inertia_weight.setValue(1) self.inertia_weight.setSingleStep(0.1) self.inertia_weight.setStatusTip('The inertia weight of the velocity ' ' for each individual.') self.cognitive_const_rand_upper = QDoubleSpinBox() self.cognitive_const_rand_upper.setRange(0, 50) self.cognitive_const_rand_upper.setValue(2) self.cognitive_const_rand_upper.setSingleStep(0.1) self.cognitive_const_rand_upper.setStatusTip( 'The random upper bound for cognitive accelerate constant.') self.social_const_rand_upper = QDoubleSpinBox() self.social_const_rand_upper.setRange(0, 50) self.social_const_rand_upper.setValue(3) self.social_const_rand_upper.setSingleStep(0.1) self.social_const_rand_upper.setStatusTip( 'The random upper bound for social accelerate constant.') self.v_max = QDoubleSpinBox() self.v_max.setRange(0.5, 100) self.v_max.setValue(5) self.v_max.setSingleStep(1) self.v_max.setStatusTip('The maximum of velocity for each individual.') self.nneuron = QSpinBox() self.nneuron.setRange(1, 100) self.nneuron.setValue(6) self.nneuron.setStatusTip('The number of RBFN neuron.') self.sd_max = QDoubleSpinBox() self.sd_max.setRange(0.01, 20) self.sd_max.setValue(10) self.sd_max.setSingleStep(0.1) self.sd_max.setStatusTip('The random range maximum of standard ' 'deviation of each neuron in RBFN (only for ' 'initialization).') inner_layout.addRow('Iterating Times:', self.iter_times) inner_layout.addRow('Population Size:', self.population_size) inner_layout.addRow('Inertia Weight:', self.inertia_weight) inner_layout.addRow('Cognitive Const Upper:', self.cognitive_const_rand_upper) inner_layout.addRow('Social Const Upper:', self.social_const_rand_upper) inner_layout.addRow('Maximum of Velocity:', self.v_max) inner_layout.addRow('Number of Neuron:', self.nneuron) inner_layout.addRow('Maximum of SD:', self.sd_max) self._layout.addWidget(group_box) def __set_outputs_ui(self): group_box = QGroupBox('Training Details') inner_layout = QFormLayout() group_box.setLayout(inner_layout) self.current_iter_time = QLabel('--') self.current_error = QLabel('--') self.avg_error = QLabel('--') self.global_best_error = QLabel('--') self.total_best_error = QLabel('--') self.progressbar = QProgressBar() self.current_iter_time.setAlignment(Qt.AlignCenter) self.current_error.setAlignment(Qt.AlignCenter) self.avg_error.setAlignment(Qt.AlignCenter) self.global_best_error.setAlignment(Qt.AlignCenter) self.total_best_error.setAlignment(Qt.AlignCenter) self.current_iter_time.setStatusTip('The current iterating time of ' 'the PSO.') self.current_error.setStatusTip('The current error from the fitting ' 'function. ("( )": normalized error)') self.avg_error.setStatusTip('The average error from the fitting ' 'function in current iteration. ("( )": ' 'normalized error)') self.global_best_error.setStatusTip( 'The error of global best individual from the fitting function in ' 'current iteration. ("( )": normalized error)') self.total_best_error.setStatusTip( 'The error of total best individual from the fitting function in ' 'training. ("( )": normalized error)') inner_layout.addRow('Current Iterating Time:', self.current_iter_time) inner_layout.addRow('Current Error:', self.current_error) inner_layout.addRow('Average Error:', self.avg_error) inner_layout.addRow('Global Best Error:', self.global_best_error) inner_layout.addRow('Total Best Error:', self.total_best_error) inner_layout.addRow(self.progressbar) self._layout.addWidget(group_box) def __set_graphic_ui(self): group_box = QGroupBox('Error Line Charts:') inner_layout = QVBoxLayout() group_box.setLayout(inner_layout) self.err_chart = ErrorLineChart(1) self.err_chart.setStatusTip('The history of error from the fitting ' 'of the PSO for each data.') self.__err_x = 1 self.iter_err_chart = ErrorLineChart( 3, ('Avg', 'Global Best', 'Total Best')) self.iter_err_chart.setStatusTip('The history of average and least ' 'error from the fitting of the PSO ' 'for each iteration.') self.iter_err_chart.setMinimumHeight(150) inner_layout.addWidget(QLabel('Current Error')) inner_layout.addWidget(self.err_chart) inner_layout.addWidget(QLabel('Average Error')) inner_layout.addWidget(self.iter_err_chart) self._layout.addWidget(group_box) @Slot() def __init_widgets(self): self.start_btn.setDisabled(True) self.stop_btn.setEnabled(True) self.multicore_cb.setDisabled(True) self.data_selector.setDisabled(True) self.iter_times.setDisabled(True) self.population_size.setDisabled(True) self.inertia_weight.setDisabled(True) self.cognitive_const_rand_upper.setDisabled(True) self.social_const_rand_upper.setDisabled(True) self.v_max.setDisabled(True) self.nneuron.setDisabled(True) self.sd_max.setDisabled(True) self.err_chart.clear() self.iter_err_chart.clear() self.__err_x = 1 @Slot() def __reset_widgets(self): self.start_btn.setEnabled(True) self.stop_btn.setDisabled(True) self.multicore_cb.setEnabled(True) self.data_selector.setEnabled(True) self.iter_times.setEnabled(True) self.population_size.setEnabled(True) self.inertia_weight.setEnabled(True) self.cognitive_const_rand_upper.setEnabled(True) self.social_const_rand_upper.setEnabled(True) self.v_max.setEnabled(True) self.nneuron.setEnabled(True) self.sd_max.setEnabled(True) self.progressbar.setMinimum(0) self.progressbar.setMaximum(100) @Slot() def __indicate_busy(self): self.progressbar.setMinimum(0) self.progressbar.setMaximum(0) @Slot(int) def __show_current_iter_time(self, value): self.current_iter_time.setText(str(value + 1)) self.progressbar.setValue(value + 1) @Slot(float) def __show_current_error(self, value): self.current_error.setText('{:.5f} ({:.5f})'.format(value, value / 40)) self.err_chart.append_point(self.__err_x, value) self.__err_x += 1 @Slot(float, float, float) def __show_iter_error(self, avg, glob, total): self.avg_error.setText('{:.5f} ({:.5f})'.format(avg, avg / 40)) self.global_best_error.setText( '{:.5f} ({:.5f})'.format(glob, glob / 40)) self.total_best_error.setText( '{:.5f} ({:.5f})'.format(total, total / 40)) self.iter_err_chart.append_point( int(self.current_iter_time.text()), total, 2) self.iter_err_chart.append_point( int(self.current_iter_time.text()), glob, 1) self.iter_err_chart.append_point( int(self.current_iter_time.text()), avg, 0) def __run(self): self.progressbar.setMaximum(self.iter_times.value()) self.__current_dataset = self.datasets[ self.data_selector.currentText()] self.__pso = PSO(self.iter_times.value(), self.population_size.value(), self.inertia_weight.value(), self.cognitive_const_rand_upper.value(), self.social_const_rand_upper.value(), self.v_max.value(), self.nneuron.value(), self.__current_dataset, self.sd_max.value(), is_multicore=self.multicore_cb.isChecked()) self.threads.append(self.__pso) self.stop_btn.clicked.connect(self.__pso.stop) self.__pso.started.connect(self.__init_widgets) self.__pso.finished.connect(self.__reset_widgets) self.__pso.sig_current_iter_time.connect(self.__show_current_iter_time) self.__pso.sig_current_error.connect(self.__show_current_error) self.__pso.sig_iter_error.connect(self.__show_iter_error) self.__pso.sig_indicate_busy.connect(self.__indicate_busy) self.__pso.sig_console.connect(self.testing_panel.print_console) self.__pso.sig_rbfn.connect(self.testing_panel.load_rbfn) self.__pso.start()
class ColorDialog(QDialog): def __init__(self, model, font_metric, parent=None): super().__init__(parent) self.setWindowTitle('Color Options') self.model = model self.font_metric = font_metric self.main_window = parent self.createDialogLayout() def createDialogLayout(self): self.createGeneralTab() self.cellTable = self.createDomainTable(self.main_window.cellsModel) self.matTable = self.createDomainTable(self.main_window.materialsModel) self.tabs = { 'cell': self.createDomainTab(self.cellTable), 'material': self.createDomainTab(self.matTable), 'temperature': self.createPropertyTab('temperature'), 'density': self.createPropertyTab('density') } self.tab_bar = QTabWidget() self.tab_bar.setMaximumHeight(800) self.tab_bar.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.tab_bar.addTab(self.generalTab, 'General') self.tab_bar.addTab(self.tabs['cell'], 'Cells') self.tab_bar.addTab(self.tabs['material'], 'Materials') self.tab_bar.addTab(self.tabs['temperature'], 'Temperature') self.tab_bar.addTab(self.tabs['density'], 'Density') self.createButtonBox() self.colorDialogLayout = QVBoxLayout() self.colorDialogLayout.addWidget(self.tab_bar) self.colorDialogLayout.addWidget(self.buttonBox) self.setLayout(self.colorDialogLayout) def createGeneralTab(self): main_window = self.main_window # Masking options self.maskingCheck = QCheckBox('') self.maskingCheck.stateChanged.connect(main_window.toggleMasking) button_width = self.font_metric.boundingRect("XXXXXXXXXX").width() self.maskColorButton = QPushButton() self.maskColorButton.setCursor(QtCore.Qt.PointingHandCursor) self.maskColorButton.setFixedWidth(button_width) self.maskColorButton.setFixedHeight(self.font_metric.height() * 1.5) self.maskColorButton.clicked.connect(main_window.editMaskingColor) # Highlighting options self.hlCheck = QCheckBox('') self.hlCheck.stateChanged.connect(main_window.toggleHighlighting) self.hlColorButton = QPushButton() self.hlColorButton.setCursor(QtCore.Qt.PointingHandCursor) self.hlColorButton.setFixedWidth(button_width) self.hlColorButton.setFixedHeight(self.font_metric.height() * 1.5) self.hlColorButton.clicked.connect(main_window.editHighlightColor) self.alphaBox = QDoubleSpinBox() self.alphaBox.setRange(0, 1) self.alphaBox.setSingleStep(.05) self.alphaBox.valueChanged.connect(main_window.editAlpha) self.seedBox = QSpinBox() self.seedBox.setRange(1, 999) self.seedBox.valueChanged.connect(main_window.editSeed) # General options self.bgButton = QPushButton() self.bgButton.setCursor(QtCore.Qt.PointingHandCursor) self.bgButton.setFixedWidth(button_width) self.bgButton.setFixedHeight(self.font_metric.height() * 1.5) self.bgButton.clicked.connect(main_window.editBackgroundColor) self.colorbyBox = QComboBox(self) self.colorbyBox.addItem("material") self.colorbyBox.addItem("cell") self.colorbyBox.addItem("temperature") self.colorbyBox.addItem("density") self.colorbyBox.currentTextChanged[str].connect( main_window.editColorBy) self.universeLevelBox = QComboBox(self) self.universeLevelBox.addItem('all') for i in range(self.model.max_universe_levels): self.universeLevelBox.addItem(str(i)) self.universeLevelBox.currentTextChanged[str].connect( main_window.editUniverseLevel) # Overlap plotting self.overlapCheck = QCheckBox('', self) overlap_connector = partial(main_window.toggleOverlaps) self.overlapCheck.stateChanged.connect(overlap_connector) self.overlapColorButton = QPushButton() self.overlapColorButton.setCursor(QtCore.Qt.PointingHandCursor) self.overlapColorButton.setFixedWidth(button_width) self.overlapColorButton.setFixedHeight(self.font_metric.height() * 1.5) self.overlapColorButton.clicked.connect(main_window.editOverlapColor) self.colorResetButton = QPushButton("&Reset Colors") self.colorResetButton.setCursor(QtCore.Qt.PointingHandCursor) self.colorResetButton.clicked.connect(main_window.resetColors) formLayout = QFormLayout() formLayout.setAlignment(QtCore.Qt.AlignHCenter) formLayout.setFormAlignment(QtCore.Qt.AlignHCenter) formLayout.setLabelAlignment(QtCore.Qt.AlignLeft) formLayout.addRow('Masking:', self.maskingCheck) formLayout.addRow('Mask Color:', self.maskColorButton) formLayout.addRow(HorizontalLine()) formLayout.addRow('Highlighting:', self.hlCheck) formLayout.addRow('Highlight Color:', self.hlColorButton) formLayout.addRow('Highlight Alpha:', self.alphaBox) formLayout.addRow('Highlight Seed:', self.seedBox) formLayout.addRow(HorizontalLine()) formLayout.addRow('Background Color: ', self.bgButton) formLayout.addRow(HorizontalLine()) formLayout.addRow('Show Overlaps:', self.overlapCheck) formLayout.addRow('Overlap Color:', self.overlapColorButton) formLayout.addRow(HorizontalLine()) formLayout.addRow('Color Plot By:', self.colorbyBox) formLayout.addRow('Universe Level:', self.universeLevelBox) formLayout.addRow(self.colorResetButton, None) generalLayout = QHBoxLayout() innerWidget = QWidget() generalLayout.setAlignment(QtCore.Qt.AlignVCenter) innerWidget.setLayout(formLayout) generalLayout.addStretch(1) generalLayout.addWidget(innerWidget) generalLayout.addStretch(1) self.generalTab = QWidget() self.generalTab.setLayout(generalLayout) def createDomainTable(self, domainmodel): domainTable = QTableView() domainTable.setModel(domainmodel) domainTable.setItemDelegate(DomainDelegate(domainTable)) domainTable.verticalHeader().setVisible(False) domainTable.resizeColumnsToContents() domainTable.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) domainTable.horizontalHeader().setSectionResizeMode( 1, QHeaderView.Stretch) return domainTable def createDomainTab(self, domaintable): domainTab = QWidget() domainTab.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) domainLayout = QVBoxLayout() domainLayout.addWidget(domaintable) domainTab.setLayout(domainLayout) return domainTab def createPropertyTab(self, property_kind): propertyTab = QWidget() propertyTab.property_kind = property_kind propertyTab.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) propertyLayout = QVBoxLayout() propertyTab.minMaxCheckBox = QCheckBox() propertyTab.minMaxCheckBox.setCheckable(True) connector1 = partial(self.main_window.toggleUserMinMax, property=property_kind) propertyTab.minMaxCheckBox.stateChanged.connect(connector1) propertyTab.minBox = ScientificDoubleSpinBox(self) propertyTab.minBox.setMaximum(1E9) propertyTab.minBox.setMinimum(0) propertyTab.maxBox = ScientificDoubleSpinBox(self) propertyTab.maxBox.setMaximum(1E9) propertyTab.maxBox.setMinimum(0) connector2 = partial(self.main_window.editColorbarMin, property_type=property_kind) propertyTab.minBox.valueChanged.connect(connector2) connector3 = partial(self.main_window.editColorbarMax, property_type=property_kind) propertyTab.maxBox.valueChanged.connect(connector3) propertyTab.colormapBox = QComboBox(self) cmaps = sorted(m for m in mcolormaps.datad if not m.endswith("_r")) for cmap in cmaps: propertyTab.colormapBox.addItem(cmap) connector = partial(self.main_window.editColorMap, property_type=property_kind) propertyTab.colormapBox.currentTextChanged[str].connect(connector) propertyTab.dataIndicatorCheckBox = QCheckBox() propertyTab.dataIndicatorCheckBox.setCheckable(True) connector4 = partial(self.main_window.toggleDataIndicatorCheckBox, property=property_kind) propertyTab.dataIndicatorCheckBox.stateChanged.connect(connector4) propertyTab.colorBarScaleCheckBox = QCheckBox() propertyTab.colorBarScaleCheckBox.setCheckable(True) connector5 = partial(self.main_window.toggleColorbarScale, property=property_kind) propertyTab.colorBarScaleCheckBox.stateChanged.connect(connector5) formLayout = QFormLayout() formLayout.setAlignment(QtCore.Qt.AlignHCenter) formLayout.setFormAlignment(QtCore.Qt.AlignHCenter) formLayout.setLabelAlignment(QtCore.Qt.AlignLeft) formLayout.addRow('Colormap:', propertyTab.colormapBox) formLayout.addRow('Custom Min/Max', propertyTab.minMaxCheckBox) formLayout.addRow('Data Indicator', propertyTab.dataIndicatorCheckBox) formLayout.addRow('Log Scale', propertyTab.colorBarScaleCheckBox) formLayout.addRow(HorizontalLine()) formLayout.addRow('Max: ', propertyTab.maxBox) formLayout.addRow('Min: ', propertyTab.minBox) propertyTab.setLayout(formLayout) return propertyTab def updateDataIndicatorVisibility(self): av = self.model.activeView for key, val in av.data_indicator_enabled.items(): self.tabs[key].dataIndicatorCheckBox.setChecked(val) def updateColorMaps(self): cmaps = self.model.activeView.colormaps for key, val in cmaps.items(): idx = self.tabs[key].colormapBox.findText( val, QtCore.Qt.MatchFixedString) if idx >= 0: self.tabs[key].colormapBox.setCurrentIndex(idx) def updateColorMinMax(self): minmax = self.model.activeView.user_minmax for key, val in minmax.items(): self.tabs[key].minBox.setValue(val[0]) self.tabs[key].maxBox.setValue(val[1]) custom_minmax = self.model.activeView.use_custom_minmax for key, val, in custom_minmax.items(): self.tabs[key].minMaxCheckBox.setChecked(val) self.tabs[key].minBox.setEnabled(val) self.tabs[key].maxBox.setEnabled(val) def updateColorbarScale(self): av = self.model.activeView for key, val in av.color_scale_log.items(): self.tabs[key].colorBarScaleCheckBox.setChecked(val) def createButtonBox(self): applyButton = QPushButton("Apply Changes") applyButton.clicked.connect(self.main_window.applyChanges) closeButton = QPushButton("Close") closeButton.clicked.connect(self.hide) buttonLayout = QHBoxLayout() buttonLayout.addStretch(1) buttonLayout.addWidget(applyButton) buttonLayout.addWidget(closeButton) self.buttonBox = QWidget() self.buttonBox.setLayout(buttonLayout) def updateDialogValues(self): self.updateMasking() self.updateMaskingColor() self.updateColorMaps() self.updateColorMinMax() self.updateColorbarScale() self.updateDataIndicatorVisibility() self.updateHighlighting() self.updateHighlightColor() self.updateAlpha() self.updateSeed() self.updateBackgroundColor() self.updateColorBy() self.updateUniverseLevel() self.updateDomainTabs() self.updateOverlap() self.updateOverlapColor() def updateMasking(self): masking = self.model.activeView.masking self.maskingCheck.setChecked(masking) self.maskColorButton.setDisabled(not masking) if masking: self.cellTable.showColumn(4) self.matTable.showColumn(4) else: self.cellTable.hideColumn(4) self.matTable.hideColumn(4) def updateMaskingColor(self): color = self.model.activeView.maskBackground style_values = "border-radius: 8px; background-color: rgb{}" self.maskColorButton.setStyleSheet(style_values.format(str(color))) def updateHighlighting(self): highlighting = self.model.activeView.highlighting self.hlCheck.setChecked(highlighting) self.hlColorButton.setDisabled(not highlighting) self.alphaBox.setDisabled(not highlighting) self.seedBox.setDisabled(not highlighting) if highlighting: self.cellTable.showColumn(5) self.cellTable.hideColumn(2) self.cellTable.hideColumn(3) self.matTable.showColumn(5) self.matTable.hideColumn(2) self.matTable.hideColumn(3) else: self.cellTable.hideColumn(5) self.cellTable.showColumn(2) self.cellTable.showColumn(3) self.matTable.hideColumn(5) self.matTable.showColumn(2) self.matTable.showColumn(3) def updateHighlightColor(self): color = self.model.activeView.highlightBackground style_values = "border-radius: 8px; background-color: rgb{}" self.hlColorButton.setStyleSheet(style_values.format(str(color))) def updateAlpha(self): self.alphaBox.setValue(self.model.activeView.highlightAlpha) def updateSeed(self): self.seedBox.setValue(self.model.activeView.highlightSeed) def updateBackgroundColor(self): color = self.model.activeView.domainBackground self.bgButton.setStyleSheet("border-radius: 8px;" "background-color: rgb%s" % (str(color))) def updateOverlapColor(self): color = self.model.activeView.overlap_color self.overlapColorButton.setStyleSheet("border-radius: 8px;" "background-color: rgb%s" % (str(color))) def updateOverlap(self): colorby = self.model.activeView.colorby overlap_val = self.model.activeView.color_overlaps if colorby in ('cell', 'material'): self.overlapCheck.setChecked(overlap_val) def updateColorBy(self): colorby = self.model.activeView.colorby self.colorbyBox.setCurrentText(colorby) self.overlapCheck.setEnabled(colorby in ("cell", "material")) self.universeLevelBox.setEnabled(colorby == 'cell') def updateUniverseLevel(self): level = self.model.activeView.level if level == -1: self.universeLevelBox.setCurrentText('all') else: self.universeLevelBox.setCurrentText(str(level)) def updateDomainTabs(self): self.cellTable.setModel(self.main_window.cellsModel) self.matTable.setModel(self.main_window.materialsModel)
class ColorDialog(QDialog): def __init__(self, model, FM, parent=None): super(ColorDialog, self).__init__(parent) self.setWindowTitle('Color Options') self.model = model self.FM = FM self.mw = parent self.createDialogLayout() def createDialogLayout(self): self.createGeneralTab() self.cellTable = self.createDomainTable(self.mw.cellsModel) self.matTable = self.createDomainTable(self.mw.materialsModel) self.cellTab = self.createDomainTab(self.cellTable) self.matTab = self.createDomainTab(self.matTable) self.tabs = QTabWidget() self.tabs.setMaximumHeight(800) self.tabs.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.tabs.addTab(self.generalTab, 'General') self.tabs.addTab(self.cellTab, 'Cells') self.tabs.addTab(self.matTab, 'Materials') self.createButtonBox() self.colorDialogLayout = QVBoxLayout() #self.colorDialogLayout.setContentsMargins(0, 0, 0, 0) self.colorDialogLayout.addWidget(self.tabs) self.colorDialogLayout.addWidget(self.buttonBox) self.setLayout(self.colorDialogLayout) def createGeneralTab(self): # Masking options self.maskingCheck = QCheckBox('') self.maskingCheck.stateChanged.connect(self.mw.toggleMasking) self.maskColorButton = QPushButton() self.maskColorButton.setCursor(QtCore.Qt.PointingHandCursor) self.maskColorButton.setFixedWidth(self.FM.width("XXXXXXXXXX")) self.maskColorButton.setFixedHeight(self.FM.height() * 1.5) self.maskColorButton.clicked.connect(self.mw.editMaskingColor) # Highlighting options self.hlCheck = QCheckBox('') self.hlCheck.stateChanged.connect(self.mw.toggleHighlighting) self.hlColorButton = QPushButton() self.hlColorButton.setCursor(QtCore.Qt.PointingHandCursor) self.hlColorButton.setFixedWidth(self.FM.width("XXXXXXXXXX")) self.hlColorButton.setFixedHeight(self.FM.height() * 1.5) self.hlColorButton.clicked.connect(self.mw.editHighlightColor) self.alphaBox = QDoubleSpinBox() self.alphaBox.setRange(0, 1) self.alphaBox.setSingleStep(.05) self.alphaBox.valueChanged.connect(self.mw.editAlpha) self.seedBox = QSpinBox() self.seedBox.setRange(1, 999) self.seedBox.valueChanged.connect(self.mw.editSeed) # General options self.bgButton = QPushButton() self.bgButton.setCursor(QtCore.Qt.PointingHandCursor) self.bgButton.setFixedWidth(self.FM.width("XXXXXXXXXX")) self.bgButton.setFixedHeight(self.FM.height() * 1.5) self.bgButton.clicked.connect(self.mw.editBackgroundColor) self.colorbyBox = QComboBox(self) self.colorbyBox.addItem("material") self.colorbyBox.addItem("cell") self.colorbyBox.currentTextChanged[str].connect(self.mw.editColorBy) formLayout = QFormLayout() formLayout.setAlignment(QtCore.Qt.AlignHCenter) formLayout.setFormAlignment(QtCore.Qt.AlignHCenter) formLayout.setLabelAlignment(QtCore.Qt.AlignLeft) #formLayout.setFieldGrowthPolicy(QFormLayout.AllNonFixedFieldsGrow) formLayout.addRow('Masking:', self.maskingCheck) formLayout.addRow('Mask Color:', self.maskColorButton) formLayout.addRow(HorizontalLine()) formLayout.addRow('Highlighting:', self.hlCheck) formLayout.addRow('Highlight Color:', self.hlColorButton) formLayout.addRow('Highlight Alpha:', self.alphaBox) formLayout.addRow('Highlight Seed:', self.seedBox) formLayout.addRow(HorizontalLine()) formLayout.addRow('Background Color: ', self.bgButton) formLayout.addRow('Color Plot By:', self.colorbyBox) generalLayout = QHBoxLayout() innerWidget = QWidget() generalLayout.setAlignment(QtCore.Qt.AlignVCenter) innerWidget.setLayout(formLayout) generalLayout.addStretch(1) generalLayout.addWidget(innerWidget) generalLayout.addStretch(1) self.generalTab = QWidget() self.generalTab.setLayout(generalLayout) def createDomainTable(self, domainmodel): domainTable = QTableView() domainTable.setModel(domainmodel) domainTable.setItemDelegate(DomainDelegate(domainTable)) domainTable.verticalHeader().setVisible(False) domainTable.resizeColumnsToContents() domainTable.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) domainTable.horizontalHeader().setSectionResizeMode( 1, QHeaderView.Stretch) return domainTable def createDomainTab(self, domaintable): domainTab = QWidget() domainTab.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) domainLayout = QVBoxLayout() domainLayout.addWidget(domaintable) domainTab.setLayout(domainLayout) return domainTab def createButtonBox(self): applyButton = QPushButton("Apply Changes") applyButton.clicked.connect(self.mw.applyChanges) closeButton = QPushButton("Close") closeButton.clicked.connect(self.hide) buttonLayout = QHBoxLayout() buttonLayout.addStretch(1) buttonLayout.addWidget(applyButton) buttonLayout.addWidget(closeButton) self.buttonBox = QWidget() self.buttonBox.setLayout(buttonLayout) def updateDialogValues(self): self.updateMasking() self.updateMaskingColor() self.updateHighlighting() self.updateHighlightColor() self.updateAlpha() self.updateSeed() self.updateBackgroundColor() self.updateColorBy() self.updateDomainTabs() def updateMasking(self): masking = self.model.activeView.masking self.maskingCheck.setChecked(masking) self.maskColorButton.setDisabled(not masking) if masking: self.cellTable.showColumn(4) self.matTable.showColumn(4) else: self.cellTable.hideColumn(4) self.matTable.hideColumn(4) def updateMaskingColor(self): color = self.model.activeView.maskBackground self.maskColorButton.setStyleSheet("border-radius: 8px;" "background-color: rgb%s" % (str(color))) def updateHighlighting(self): highlighting = self.model.activeView.highlighting self.hlCheck.setChecked(highlighting) self.hlColorButton.setDisabled(not highlighting) self.alphaBox.setDisabled(not highlighting) self.seedBox.setDisabled(not highlighting) if highlighting: self.cellTable.showColumn(5) self.cellTable.hideColumn(2) self.cellTable.hideColumn(3) self.matTable.showColumn(5) self.matTable.hideColumn(2) self.matTable.hideColumn(3) else: self.cellTable.hideColumn(5) self.cellTable.showColumn(2) self.cellTable.showColumn(3) self.matTable.hideColumn(5) self.matTable.showColumn(2) self.matTable.showColumn(3) def updateHighlightColor(self): color = self.model.activeView.highlightBackground self.hlColorButton.setStyleSheet("border-radius: 8px;" "background-color: rgb%s" % (str(color))) def updateAlpha(self): self.alphaBox.setValue(self.model.activeView.highlightAlpha) def updateSeed(self): self.seedBox.setValue(self.model.activeView.highlightSeed) def updateBackgroundColor(self): color = self.model.activeView.plotBackground self.bgButton.setStyleSheet("border-radius: 8px;" "background-color: rgb%s" % (str(color))) def updateColorBy(self): self.colorbyBox.setCurrentText(self.model.activeView.colorby) def updateDomainTabs(self): self.cellTable.setModel(self.mw.cellsModel) self.matTable.setModel(self.mw.materialsModel)
class NGL_HKLViewer(QWidget): def __init__(self, parent=None): super(NGL_HKLViewer, self).__init__(parent) self.verbose = 0 self.UseOSbrowser = False self.jscriptfname = "" self.devmode = False self.hklfname = "" self.handshakewait = 5 for e in sys.argv: if "verbose" in e: self.verbose = e.split("verbose=")[1] if "UseOSbrowser" in e: self.UseOSbrowser = e.split("UseOSbrowser=")[1] if "jscriptfname" in e: self.jscriptfname = e.split("jscriptfname=")[1] if "devmode" in e: self.devmode = True if 'htmlfname' in e: self.hklfname = e.split("htmlfname=")[1] if 'handshakewait' in e: self.handshakewait = e.split('handshakewait=')[1] self.zmq_context = None self.bufsize = 20000 self.originalPalette = QApplication.palette() self.openFileNameButton = QPushButton("Load reflection file") self.openFileNameButton.setDefault(True) self.openFileNameButton.clicked.connect(self.OpenReflectionsFile) self.debugbutton = QPushButton("Debug") self.debugbutton.clicked.connect(self.DebugInteractively) self.settingsbtn = QPushButton("Settings") self.settingsbtn.clicked.connect(self.SettingsDialog) self.mousemoveslider = QSlider(Qt.Horizontal) self.mousemoveslider.setMinimum(0) self.mousemoveslider.setMaximum(300) self.mousemoveslider.setValue(0) self.mousemoveslider.sliderReleased.connect( self.onFinalMouseSensitivity) self.mousemoveslider.valueChanged.connect(self.onMouseSensitivity) self.mousesensitxtbox = QLineEdit('') self.mousesensitxtbox.setReadOnly(True) self.fontspinBox = QDoubleSpinBox() self.fontspinBox.setSingleStep(1) self.fontspinBox.setRange(4, 50) self.font = QFont() self.font.setFamily(self.font.defaultFamily()) self.fontspinBox.setValue(self.font.pointSize()) #self.fontspinBox.setValue(self.font.pixelSize()) self.fontspinBox.valueChanged.connect(self.onFontsizeChanged) self.Fontsize_labeltxt = QLabel() self.Fontsize_labeltxt.setText("Font size:") self.cameraPerspectCheckBox = QCheckBox() self.cameraPerspectCheckBox.setText("Perspective camera") self.cameraPerspectCheckBox.clicked.connect(self.onCameraPerspect) self.cameraPerspectCheckBox.setCheckState(Qt.Unchecked) self.settingsform = SettingsForm(self) self.MillerComboBox = QComboBox() self.MillerComboBox.activated.connect(self.onMillerComboSelchange) #self.MillerComboBox.setSizeAdjustPolicy(QComboBox.AdjustToContents) self.MillerLabel = QLabel() self.MillerLabel.setText("Selected HKL Scene") self.HKLnameedit = QLineEdit('') self.HKLnameedit.setReadOnly(True) self.textInfo = QTextEdit() self.textInfo.setLineWrapMode(QTextEdit.NoWrap) self.textInfo.setReadOnly(True) labels = [ "Label", "Type", "no. of HKLs", "Span of HKLs", "Min Max data", "Min Max sigmas", "d_min, d_max", "Symmetry unique", "Anomalous" ] self.millertable = QTableWidget(0, len(labels)) self.millertable.setHorizontalHeaderLabels(labels) self.millertable.horizontalHeader().setDefaultAlignment(Qt.AlignLeft) # don't allow editing this table self.millertable.setEditTriggers(QTableWidget.NoEditTriggers) self.createExpansionBox() self.createFileInfoBox() self.CreateSliceTabs() self.createRadiiScaleGroupBox() self.createBinsBox() self.CreateFunctionTabs() mainLayout = QGridLayout() mainLayout.addWidget(self.FileInfoBox, 0, 0) mainLayout.addWidget(self.MillerLabel, 1, 0) mainLayout.addWidget(self.MillerComboBox, 2, 0) mainLayout.addWidget(self.functionTabWidget, 3, 0) mainLayout.addWidget(self.settingsbtn, 4, 0, 1, 1) #import code, traceback; code.interact(local=locals(), banner="".join( traceback.format_stack(limit=10) ) ) if self.UseOSbrowser == False: self.BrowserBox = QWebEngineView() mainLayout.addWidget(self.BrowserBox, 0, 1, 5, 3) self.BrowserBox.setUrl("https://cctbx.github.io/") #self.BrowserBox.setUrl("https://webglreport.com/") #self.BrowserBox.loadFinished.connect(self.onLoadFinished) mainLayout.setColumnStretch(2, 1) mainLayout.setRowStretch(0, 1) mainLayout.setRowStretch(1, 0) mainLayout.setRowStretch(2, 1) mainLayout.setRowStretch(3, 1) mainLayout.setColumnStretch(4, 0) self.setLayout(mainLayout) self.setWindowTitle("HKL-Viewer") self.cctbxproc = None self.LaunchCCTBXPython() self.out = None self.err = None self.comboviewwidth = 0 self.hklscenes_arrays = [] self.array_infotpls = [] self.matching_arrays = [] self.bin_infotpls = None self.bin_opacities = None self.html_url = "" self.spacegroups = [] self.info = [] self.infostr = "" self.fileisvalid = False self.NewFileLoaded = False self.NewHKLscenes = False self.updatingNbins = False self.binstableitemchanges = False self.show() def SettingsDialog(self): self.settingsform.show() def update(self): if self.cctbxproc: if self.cctbxproc.stdout: print(self.cctbxproc.stdout.read().decode("utf-8")) if self.cctbxproc.stderr: print(self.cctbxproc.stderr.read().decode("utf-8")) if self.out: print(self.out.decode("utf-8")) if self.err: print(self.err.decode("utf-8")) if self.zmq_context: try: msg = self.socket.recv( flags=zmq.NOBLOCK ) #To empty the socket from previous messages msgstr = msg.decode() self.infodict = eval(msgstr) #print("received from cctbx: " + str(self.infodict)) if self.infodict: if self.infodict.get("hklscenes_arrays"): self.hklscenes_arrays = self.infodict.get( "hklscenes_arrays", []) if self.infodict.get("array_infotpls"): self.array_infotpls = self.infodict.get( "array_infotpls", []) if self.infodict.get("bin_data_label"): self.BinDataComboBox.setCurrentText( self.infodict["bin_data_label"]) if self.infodict.get("bin_infotpls"): self.bin_infotpls = self.infodict["bin_infotpls"] self.nbins = len(self.bin_infotpls) self.updatingNbins = True self.Nbins_spinBox.setValue(self.nbins) self.updatingNbins = False self.binstable.clearContents() self.binstable.setRowCount(self.nbins) for row, bin_infotpl in enumerate(self.bin_infotpls): for col, elm in enumerate(bin_infotpl): # only allow changing the last column with opacity values if col != 3: item = QTableWidgetItem(str(elm)) else: item = QTableWidgetItem() item.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled) item.setCheckState(Qt.Checked) item.setFlags(item.flags() ^ Qt.ItemIsEditable) self.binstable.setItem(row, col, item) if self.bin_opacities: self.update_table_opacities() if self.infodict.get("bin_opacities"): self.bin_opacities = self.infodict["bin_opacities"] if self.binstable.rowCount() > 0: self.update_table_opacities() if self.infodict.get("html_url"): self.html_url = self.infodict["html_url"] if self.UseOSbrowser == False: self.BrowserBox.setUrl(self.html_url) # workaround for background colour bug in chromium # https://bugreports.qt.io/browse/QTBUG-41960 self.BrowserBox.page().setBackgroundColor( QColor(255, 255, 255, 0.0)) if self.infodict.get("spacegroups"): self.spacegroups = self.infodict.get("spacegroups", []) self.SpaceGroupComboBox.clear() self.SpaceGroupComboBox.addItems(self.spacegroups) if self.infodict.get("merge_data"): self.mergedata = self.infodict["merge_data"] currentinfostr = "" if self.infodict.get("info"): currentinfostr = self.infodict.get("info", []) if self.infodict.get("NewFileLoaded"): self.NewFileLoaded = self.infodict.get( "NewFileLoaded", False) if self.infodict.get("NewHKLscenes"): self.NewHKLscenes = self.infodict.get( "NewHKLscenes", False) self.fileisvalid = True #print("ngl_hkl_infodict: " + str(ngl_hkl_infodict)) if currentinfostr: #print(currentinfostr) self.infostr += currentinfostr + "\n" # display no more than self.bufsize bytes of text self.infostr = self.infostr[-self.bufsize:] self.textInfo.setPlainText(self.infostr) self.textInfo.verticalScrollBar().setValue( self.textInfo.verticalScrollBar().maximum()) if self.NewFileLoaded and self.NewHKLscenes: #if self.mergedata == True : val = Qt.CheckState.Checked #if self.mergedata == None : val = Qt.CheckState.PartiallyChecked #if self.mergedata == False : val = Qt.CheckState.Unchecked #self.mergecheckbox.setCheckState(val ) #print("got hklscenes: " + str(self.hklscenes_arrays)) self.MillerComboBox.clear() self.MillerComboBox.addItems( [e[3] for e in self.hklscenes_arrays]) self.MillerComboBox.setCurrentIndex( -1) # unselect the first item in the list self.comboviewwidth = 0 for e in self.hklscenes_arrays: self.comboviewwidth = max( self.comboviewwidth, self.MillerComboBox.fontMetrics().width(e[3])) self.MillerComboBox.view().setMinimumWidth( self.comboviewwidth) self.millertable.clearContents() self.millertable.setRowCount(len( self.hklscenes_arrays)) for n, millarr in enumerate(self.array_infotpls): for m, elm in enumerate(millarr): self.millertable.setItem( n, m, QTableWidgetItem(str(elm))) self.functionTabWidget.setDisabled(True) self.NewFileLoaded = False if self.NewHKLscenes: self.BinDataComboBox.clear() self.BinDataComboBox.addItems( ["Resolution"] + [e[3] for e in self.hklscenes_arrays]) self.BinDataComboBox.view().setMinimumWidth( self.comboviewwidth) #self.BinDataComboBox.setCurrentIndex(-1) # unselect the first item in the list self.NewHKLscenes = False except Exception as e: errmsg = str(e) if "Resource temporarily unavailable" not in errmsg: print(errmsg + traceback.format_exc(limit=10)) pass def onFinalMouseSensitivity(self): val = self.mousemoveslider.value() / 100.0 self.NGL_HKL_command( 'NGL_HKLviewer.viewer.NGL.mouse_sensitivity = %f' % val) def onMouseSensitivity(self): val = self.mousemoveslider.value() / 100.0 self.mousesensitxtbox.setText("%2.2f" % val) def onFontsizeChanged(self, val): font = app.font() font.setPointSize(val) app.setFont(font) self.settingsform.setFixedSize(self.settingsform.sizeHint()) def onCameraPerspect(self, val): if self.cameraPerspectCheckBox.isChecked(): self.NGL_HKL_command("NGL_HKLviewer.camera_type = perspective") else: self.NGL_HKL_command("NGL_HKLviewer.camera_type = orthographic") def MergeData(self): if self.mergecheckbox.checkState() == Qt.CheckState.Checked: self.NGL_HKL_command('NGL_HKLviewer.mergedata = True') if self.mergecheckbox.checkState() == Qt.CheckState.PartiallyChecked: self.NGL_HKL_command('NGL_HKLviewer.mergedata = None') if self.mergecheckbox.checkState() == Qt.CheckState.Unchecked: self.NGL_HKL_command('NGL_HKLviewer.mergedata = False') def ExpandToP1(self): if self.expandP1checkbox.isChecked(): self.NGL_HKL_command('NGL_HKLviewer.viewer.expand_to_p1 = True') else: self.NGL_HKL_command('NGL_HKLviewer.viewer.expand_to_p1 = False') def ExpandAnomalous(self): if self.expandAnomalouscheckbox.isChecked(): self.NGL_HKL_command( 'NGL_HKLviewer.viewer.expand_anomalous = True') else: self.NGL_HKL_command( 'NGL_HKLviewer.viewer.expand_anomalous = False') def showSysAbsent(self): if self.sysabsentcheckbox.isChecked(): self.NGL_HKL_command( 'NGL_HKLviewer.viewer.show_systematic_absences = True') else: self.NGL_HKL_command( 'NGL_HKLviewer.viewer.show_systematic_absences = False') def showMissing(self): if self.missingcheckbox.isChecked(): self.NGL_HKL_command('NGL_HKLviewer.viewer.show_missing = True') else: self.NGL_HKL_command('NGL_HKLviewer.viewer.show_missing = False') def showOnlyMissing(self): if self.onlymissingcheckbox.isChecked(): self.NGL_HKL_command( 'NGL_HKLviewer.viewer.show_only_missing = True') else: self.NGL_HKL_command( 'NGL_HKLviewer.viewer.show_only_missing = False') def showSlice(self): if self.showslicecheckbox.isChecked(): self.NGL_HKL_command('NGL_HKLviewer.viewer.slice_mode = True') if self.expandP1checkbox.isChecked(): self.NGL_HKL_command("""NGL_HKLviewer.viewer { expand_to_p1 = True inbrowser = False } """) if self.expandAnomalouscheckbox.isChecked(): self.NGL_HKL_command("""NGL_HKLviewer.viewer { expand_anomalous = True inbrowser = False } """) self.SliceLabelComboBox.setEnabled(True) self.sliceindexspinBox.setEnabled(True) else: self.NGL_HKL_command("""NGL_HKLviewer.viewer { slice_mode = False inbrowser = True } """) self.SliceLabelComboBox.setDisabled(True) self.sliceindexspinBox.setDisabled(True) def onSliceComboSelchange(self, i): rmin = self.array_infotpls[self.MillerComboBox.currentIndex()][3][0][i] rmax = self.array_infotpls[self.MillerComboBox.currentIndex()][3][1][i] self.sliceindexspinBox.setRange(rmin, rmax) self.NGL_HKL_command("NGL_HKLviewer.viewer.slice_axis = %s" % self.sliceaxis[i]) def onSliceIndexChanged(self, val): self.sliceindex = val self.NGL_HKL_command("NGL_HKLviewer.viewer.slice_index = %d" % self.sliceindex) def onBindataComboSelchange(self, i): if self.BinDataComboBox.currentText(): if self.BinDataComboBox.currentIndex() > 0: bin_scene_label = str(self.BinDataComboBox.currentIndex() - 1) else: bin_scene_label = "Resolution" self.NGL_HKL_command("NGL_HKLviewer.bin_scene_label = %s" % bin_scene_label) bin_opacitieslst = [] for i in range(self.nbins): bin_opacitieslst.append("1.0, %d" % i) self.bin_opacities = str(bin_opacitieslst) self.OpaqueAllCheckbox.setCheckState(Qt.Checked) #self.OpaqueAllCheckbox.setTristate(false) #self.NGL_HKL_command('NGL_HKLviewer.viewer.NGL.bin_opacities = "%s"' %self.bin_opacities) def update_table_opacities(self, allalpha=None): bin_opacitieslst = eval(self.bin_opacities) self.binstable_isready = False for binopacity in bin_opacitieslst: if not allalpha: alpha = float(binopacity.split(",")[0]) else: alpha = allalpha bin = int(binopacity.split(",")[1]) item = QTableWidgetItem() item.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled) if alpha < 0.5: item.setCheckState(Qt.Unchecked) else: item.setCheckState(Qt.Checked) item.setFlags(item.flags() ^ Qt.ItemIsEditable) self.binstable.setItem(bin, 3, item) self.binstable_isready = True def SetOpaqueAll(self): if self.binstableitemchanges: return bin_opacitieslst = eval(self.bin_opacities) nbins = len(bin_opacitieslst) sum = 0 for binopacity in bin_opacitieslst: sum += float(binopacity.split(",")[0]) if sum >= nbins: self.OpaqueAllCheckbox.setCheckState(Qt.Checked) if sum == 0: self.OpaqueAllCheckbox.setCheckState(Qt.Unchecked) if sum > 0.0 and sum < nbins: self.OpaqueAllCheckbox.setCheckState(Qt.PartiallyChecked) def onBinsTableItemChanged(self, item): row = item.row() column = item.column() try: if item.checkState() == Qt.Unchecked: newval = 0 else: newval = 1.0 if column == 3 and self.binstable_isready: # changing opacity assert (newval <= 1.0 and newval >= 0.0) bin_opacitieslst = eval(self.bin_opacities) bin_opacitieslst[row] = str(newval) + ', ' + str(row) self.bin_opacities = str(bin_opacitieslst) self.SetOpaqueAll() self.NGL_HKL_command( 'NGL_HKLviewer.viewer.NGL.bin_opacities = "%s"' % self.bin_opacities) except Exception as e: print(str(e)) #self.binstable.currentItem().setText( self.currentSelectedBinsTableVal) def onBinsTableItemSelectionChanged(self): row = self.binstable.currentItem().row() column = self.binstable.currentItem().column() self.currentSelectedBinsTableVal = self.binstable.currentItem().text() #print( "in itemSelectionChanged " + self.currentSelectedBinsTableVal) def onOpaqueAll(self): self.binstableitemchanges = True bin_opacitieslst = eval(self.bin_opacities) nbins = len(bin_opacitieslst) bin_opacitieslst = [] self.binstable_isready = False if self.OpaqueAllCheckbox.isChecked(): for i in range(nbins): bin_opacitieslst.append("1.0, %d" % i) else: for i in range(nbins): bin_opacitieslst.append("0.0, %d" % i) self.bin_opacities = str(bin_opacitieslst) self.NGL_HKL_command('NGL_HKLviewer.viewer.NGL.bin_opacities = "%s"' % self.bin_opacities) self.binstableitemchanges = False self.binstable_isready = True """ def onLoadFinished(self, val): pass #print("web page finished loading now") def onBinsTableitemActivated(self, item): row = item.row() column = item.column() currentval = item.text() #print( "in itemActivated " + currentval) def onBinsTableCellentered(self, row, col): pass #print( "in Cellentered " + self.binstable.currentItem().text() ) def onBinsTableCellPressed(self, row, col): pass #print( "in CellPressed " + self.binstable.currentItem().text() ) """ def onNbinsChanged(self, val): self.nbins = val if not self.updatingNbins: # avoid possible endless loop to cctbx self.NGL_HKL_command("NGL_HKLviewer.nbins = %d" % self.nbins) def onRadiiScaleChanged(self, val): self.radii_scale = val self.NGL_HKL_command(""" NGL_HKLviewer.viewer { nth_power_scale_radii = %f scale = %f } """ % (self.nth_power_scale, self.radii_scale)) def onPowerScaleChanged(self, val): self.nth_power_scale = val self.NGL_HKL_command(""" NGL_HKLviewer.viewer { nth_power_scale_radii = %f scale = %f } """ % (self.nth_power_scale, self.radii_scale)) def onManualPowerScale(self): if self.ManualPowerScalecheckbox.isChecked(): self.NGL_HKL_command( 'NGL_HKLviewer.viewer.nth_power_scale_radii = %f' % self.nth_power_scale) self.power_scale_spinBox.setEnabled(True) else: self.NGL_HKL_command( 'NGL_HKLviewer.viewer.nth_power_scale_radii = -1.0') self.power_scale_spinBox.setEnabled(False) self.nth_power_scale = -1.0 def OpenReflectionsFile(self): options = QFileDialog.Options() fileName, filtr = QFileDialog.getOpenFileName( self, "Load reflections file", "", "All Files (*);;MTZ Files (*.mtz);;CIF (*.cif)", "", options) if fileName: self.HKLnameedit.setText(fileName) #self.infostr = "" self.textInfo.setPlainText("") self.fileisvalid = False self.NGL_HKL_command('NGL_HKLviewer.filename = "%s"' % fileName) self.MillerComboBox.clear() self.BinDataComboBox.clear() def createExpansionBox(self): self.SpaceGroupComboBox = QComboBox() self.SpaceGroupComboBox.activated.connect(self.SpacegroupSelchange) self.SpacegroupLabel = QLabel() self.SpacegroupLabel.setText("Space Subgroups") self.mergecheckbox = QCheckBox() self.mergecheckbox.setText("Merge data") #self.mergecheckbox.setTristate (True) self.mergecheckbox.clicked.connect(self.MergeData) self.expandP1checkbox = QCheckBox() self.expandP1checkbox.setText("Expand to P1") self.expandP1checkbox.clicked.connect(self.ExpandToP1) self.expandAnomalouscheckbox = QCheckBox() self.expandAnomalouscheckbox.setText("Show Friedel pairs") self.expandAnomalouscheckbox.clicked.connect(self.ExpandAnomalous) self.sysabsentcheckbox = QCheckBox() self.sysabsentcheckbox.setText("Show Systematic Absences") self.sysabsentcheckbox.clicked.connect(self.showSysAbsent) self.missingcheckbox = QCheckBox() self.missingcheckbox.setText("Show Missing") self.missingcheckbox.clicked.connect(self.showMissing) self.onlymissingcheckbox = QCheckBox() self.onlymissingcheckbox.setText("Only Show Missing") self.onlymissingcheckbox.clicked.connect(self.showOnlyMissing) self.ExpansionBox = QGroupBox("Expansions") layout = QGridLayout() layout.addWidget(self.SpacegroupLabel, 0, 0) layout.addWidget(self.SpaceGroupComboBox, 0, 1) #layout.addWidget(self.mergecheckbox, 1, 0) layout.addWidget(self.expandP1checkbox, 1, 0) layout.addWidget(self.expandAnomalouscheckbox, 1, 1) layout.addWidget(self.sysabsentcheckbox, 2, 0) layout.addWidget(self.missingcheckbox, 3, 0) layout.addWidget(self.onlymissingcheckbox, 3, 1) layout.setRowStretch(0, 0) layout.setRowStretch(1, 0) layout.setRowStretch(2, 0) layout.setRowStretch(3, 1) self.ExpansionBox.setLayout(layout) def CreateSliceTabs(self): self.showslicecheckbox = QCheckBox() self.showslicecheckbox.setText("Show Slice") self.showslicecheckbox.clicked.connect(self.showSlice) self.sliceindexspinBox = QDoubleSpinBox() self.sliceindex = 0 self.sliceindexspinBox.setValue(self.sliceindex) self.sliceindexspinBox.setDecimals(0) self.sliceindexspinBox.setSingleStep(1) self.sliceindexspinBox.setRange(0, 20) self.sliceindexspinBox.valueChanged.connect(self.onSliceIndexChanged) self.SliceLabelComboBox = QComboBox() self.SliceLabelComboBox.activated.connect(self.onSliceComboSelchange) self.sliceaxis = ["h", "k", "l"] self.SliceLabelComboBox.addItems(self.sliceaxis) self.SliceLabelComboBox.setDisabled(True) self.sliceindexspinBox.setDisabled(True) self.sliceTabWidget = QTabWidget() tab1 = QWidget() layout1 = QGridLayout() layout1.addWidget(self.showslicecheckbox, 0, 0, 1, 1) layout1.addWidget(self.SliceLabelComboBox, 0, 1, 1, 1) layout1.addWidget(self.sliceindexspinBox, 0, 2, 1, 1) tab1.setLayout(layout1) tab2 = QWidget() layout2 = QGridLayout() self.hvec_spinBox = QDoubleSpinBox(self.sliceTabWidget) self.hvecval = 2.0 self.hvec_spinBox.setValue(self.hvecval) self.hvec_spinBox.setDecimals(2) self.hvec_spinBox.setSingleStep(0.5) self.hvec_spinBox.setRange(-100.0, 10.0) self.hvec_spinBox.valueChanged.connect(self.onHvecChanged) self.hvec_Label = QLabel() self.hvec_Label.setText("H") layout2.addWidget(self.hvec_Label, 0, 0, 1, 1) layout2.addWidget(self.hvec_spinBox, 0, 1, 1, 1) self.kvec_spinBox = QDoubleSpinBox(self.sliceTabWidget) self.kvecval = 0.0 self.kvec_spinBox.setValue(self.kvecval) self.kvec_spinBox.setDecimals(2) self.kvec_spinBox.setSingleStep(0.5) self.kvec_spinBox.setRange(-100.0, 100.0) self.kvec_spinBox.valueChanged.connect(self.onKvecChanged) self.kvec_Label = QLabel() self.kvec_Label.setText("K") layout2.addWidget(self.kvec_Label, 1, 0, 1, 1) layout2.addWidget(self.kvec_spinBox, 1, 1, 1, 1) self.lvec_spinBox = QDoubleSpinBox(self.sliceTabWidget) self.lvecval = 0.0 self.lvec_spinBox.setValue(self.lvecval) self.lvec_spinBox.setDecimals(2) self.lvec_spinBox.setSingleStep(0.5) self.lvec_spinBox.setRange(-100.0, 100.0) self.lvec_spinBox.valueChanged.connect(self.onLvecChanged) self.lvec_Label = QLabel() self.lvec_Label.setText("L") layout2.addWidget(self.lvec_Label, 2, 0, 1, 1) layout2.addWidget(self.lvec_spinBox, 2, 1, 1, 1) self.hkldist_spinBox = QDoubleSpinBox(self.sliceTabWidget) self.hkldistval = 0.0 self.hkldist_spinBox.setValue(self.hkldistval) self.hkldist_spinBox.setDecimals(2) self.hkldist_spinBox.setSingleStep(0.5) self.hkldist_spinBox.setRange(-100.0, 100.0) self.hkldist_spinBox.valueChanged.connect(self.onHKLdistChanged) self.hkldist_Label = QLabel() self.hkldist_Label.setText("Distance from Origin") layout2.addWidget(self.hkldist_Label, 3, 0, 1, 1) layout2.addWidget(self.hkldist_spinBox, 3, 1, 1, 1) self.clipwidth_spinBox = QDoubleSpinBox(self.sliceTabWidget) self.clipwidthval = 0.5 self.clipwidth_spinBox.setValue(self.clipwidthval) self.clipwidth_spinBox.setDecimals(2) self.clipwidth_spinBox.setSingleStep(0.05) self.clipwidth_spinBox.setRange(0.0, 100.0) self.clipwidth_spinBox.valueChanged.connect(self.onClipwidthChanged) self.clipwidth_Label = QLabel() self.clipwidth_Label.setText("Clip Plane Width") layout2.addWidget(self.clipwidth_Label, 4, 0, 1, 1) layout2.addWidget(self.clipwidth_spinBox, 4, 1, 1, 1) self.ClipBox = QGroupBox("Normal Vector to Clip Plane") self.ClipBox.setLayout(layout2) layout3 = QGridLayout() self.ClipPlaneChkBox = QCheckBox(self.sliceTabWidget) self.ClipPlaneChkBox.setText( "Use clip plane normal to HKL vector pointing out") self.ClipPlaneChkBox.clicked.connect(self.onClipPlaneChkBox) layout3.addWidget(self.ClipPlaneChkBox, 0, 0) layout3.addWidget(self.ClipBox, 1, 0) tab2.setLayout(layout3) self.sliceTabWidget.addTab(tab1, "Explicit Slicing") self.sliceTabWidget.addTab(tab2, "Clip Plane Slicing") self.ClipBox.setDisabled(True) def onClipPlaneChkBox(self): if self.ClipPlaneChkBox.isChecked(): self.ClipBox.setDisabled(False) philstr = """NGL_HKLviewer.normal_clip_plane { h = %s k = %s l = %s hkldist = %s clipwidth = %s } NGL_HKLviewer.viewer.NGL.fixorientation = %s """ %(self.hvecval, self.kvecval, self.lvecval, self.hkldistval, self.clipwidthval, \ str(self.fixedorientcheckbox.isChecked()) ) self.NGL_HKL_command(philstr) else: self.ClipBox.setDisabled(True) self.NGL_HKL_command( "NGL_HKLviewer.normal_clip_plane.clipwidth = None") def onClipwidthChanged(self, val): self.clipwidthval = val self.NGL_HKL_command("NGL_HKLviewer.normal_clip_plane.clipwidth = %f" % self.clipwidthval) def onHKLdistChanged(self, val): self.hkldistval = val self.NGL_HKL_command("NGL_HKLviewer.normal_clip_plane.hkldist = %f" % self.hkldistval) def onHvecChanged(self, val): self.hvecval = val self.NGL_HKL_command("NGL_HKLviewer.normal_clip_plane.h = %f" % self.hvecval) def onKvecChanged(self, val): self.kvecval = val self.NGL_HKL_command("NGL_HKLviewer.normal_clip_plane.k = %f" % self.kvecval) def onLvecChanged(self, val): self.lvecval = val self.NGL_HKL_command("NGL_HKLviewer.normal_clip_plane.l = %f" % self.lvecval) def onFixedorient(self): self.NGL_HKL_command('NGL_HKLviewer.viewer.NGL.fixorientation = %s' \ %str(self.fixedorientcheckbox.isChecked())) def onMillerComboSelchange(self, i): self.NGL_HKL_command("NGL_HKLviewer.scene_id = %d" % i) #self.MillerComboBox.setCurrentIndex(i) if self.MillerComboBox.currentText(): self.functionTabWidget.setEnabled(True) self.expandAnomalouscheckbox.setEnabled(True) # don' allow anomalous expansion for data that's already anomalous for arrayinfo in self.array_infotpls: isanomalous = arrayinfo[-1] label = arrayinfo[0] if isanomalous and label == self.MillerComboBox.currentText( )[:len(label)]: self.expandAnomalouscheckbox.setDisabled(True) else: self.functionTabWidget.setDisabled(True) self.SpaceGroupComboBox.clear() self.SpaceGroupComboBox.addItems(self.spacegroups) # need to supply issymunique flag in infotuple #if self.hklscenes_arrays[ i ][6] == 0: # self.mergecheckbox.setEnabled(True) #else: # self.mergecheckbox.setEnabled(False) def createFileInfoBox(self): self.FileInfoBox = QGroupBox("Reflection File Information") layout = QGridLayout() layout.addWidget(self.openFileNameButton, 0, 0, 1, 2) if self.devmode: layout.addWidget(self.debugbutton, 0, 2, 1, 1) layout.addWidget(self.HKLnameedit, 1, 0, 1, 3) layout.addWidget(self.millertable, 2, 0, 1, 3) layout.addWidget(self.textInfo, 3, 0, 1, 3) #layout.setColumnStretch(1, 2) self.FileInfoBox.setLayout(layout) def createRadiiScaleGroupBox(self): self.RadiiScaleGroupBox = QGroupBox("Radii Size of HKL Spheres") self.ManualPowerScalecheckbox = QCheckBox() self.ManualPowerScalecheckbox.setText( "Manual Power Scaling of Sphere Radii") self.ManualPowerScalecheckbox.clicked.connect(self.onManualPowerScale) self.power_scale_spinBox = QDoubleSpinBox(self.RadiiScaleGroupBox) self.nth_power_scale = 0.33 self.power_scale_spinBox.setValue(self.nth_power_scale) self.power_scale_spinBox.setDecimals(2) self.power_scale_spinBox.setSingleStep(0.05) self.power_scale_spinBox.setRange(0.0, 1.0) self.power_scale_spinBox.valueChanged.connect(self.onPowerScaleChanged) self.power_scale_spinBox.setEnabled(False) self.powerscaleLabel = QLabel() self.powerscaleLabel.setText("Power scale Factor") self.radii_scale_spinBox = QDoubleSpinBox(self.RadiiScaleGroupBox) self.radii_scale = 1.5 self.radii_scale_spinBox.setValue(self.radii_scale) self.radii_scale_spinBox.setDecimals(1) self.radii_scale_spinBox.setSingleStep(0.1) self.radii_scale_spinBox.setRange(0.2, 2.0) self.radii_scale_spinBox.valueChanged.connect(self.onRadiiScaleChanged) self.radiiscaleLabel = QLabel() self.radiiscaleLabel.setText("Linear Scale Factor") layout = QGridLayout() layout.addWidget(self.ManualPowerScalecheckbox, 1, 0, 1, 2) layout.addWidget(self.powerscaleLabel, 2, 0, 1, 2) layout.addWidget(self.power_scale_spinBox, 2, 1, 1, 2) layout.addWidget(self.radiiscaleLabel, 3, 0, 1, 2) layout.addWidget(self.radii_scale_spinBox, 3, 1, 1, 2) layout.setColumnStretch(0, 1) layout.setColumnStretch(1, 0) self.RadiiScaleGroupBox.setLayout(layout) def createBinsBox(self): self.binstable = QTableWidget(0, 4) self.binstable_isready = False labels = [ "no. of HKLs", "lower bin value", "upper bin value", "opacity" ] self.binstable.setHorizontalHeaderLabels(labels) self.binstable.horizontalHeader().setDefaultAlignment(Qt.AlignLeft) self.bindata_labeltxt = QLabel() self.bindata_labeltxt.setText("Data binned:") self.Nbins_spinBox = QSpinBox() self.Nbins_spinBox.setSingleStep(1) self.Nbins_spinBox.setRange(1, 40) self.Nbins_spinBox.valueChanged.connect(self.onNbinsChanged) self.Nbins_labeltxt = QLabel() self.Nbins_labeltxt.setText("Number of bins:") self.OpaqueAllCheckbox = QCheckBox() #self.OpaqueAllCheckbox.setTristate() self.OpaqueAllCheckbox.setCheckState(Qt.Checked) self.OpaqueAllCheckbox.setText("Show all data in bins") self.OpaqueAllCheckbox.clicked.connect(self.onOpaqueAll) self.binstable.itemChanged.connect(self.onBinsTableItemChanged) self.binstable.itemSelectionChanged.connect( self.onBinsTableItemSelectionChanged) self.BinDataComboBox = QComboBox() self.BinDataComboBox.activated.connect(self.onBindataComboSelchange) self.BinsGroupBox = QGroupBox("Bins") layout = QGridLayout() layout.addWidget(self.bindata_labeltxt, 0, 0) layout.addWidget(self.BinDataComboBox, 0, 1) layout.addWidget(self.Nbins_labeltxt, 0, 2) layout.addWidget(self.Nbins_spinBox, 0, 3) layout.addWidget(self.OpaqueAllCheckbox, 1, 2) layout.addWidget(self.binstable, 2, 0, 1, 4) layout.setColumnStretch(0, 0) layout.setColumnStretch(1, 2) layout.setColumnStretch(3, 1) self.BinsGroupBox.setLayout(layout) def DebugInteractively(self): import code, traceback code.interact(local=locals(), banner="".join(traceback.format_stack(limit=10))) def CreateFunctionTabs(self): self.functionTabWidget = QTabWidget() tab1 = QWidget() layout1 = QGridLayout() layout1.addWidget(self.ExpansionBox, 0, 0) layout1.setRowStretch(0, 0) tab1.setLayout(layout1) tab2 = QWidget() layout2 = QGridLayout() self.fixedorientcheckbox = QCheckBox(self.sliceTabWidget) self.fixedorientcheckbox.setText( "Fix orientation but allow zoom and translation") self.fixedorientcheckbox.clicked.connect(self.onFixedorient) layout2.addWidget(self.fixedorientcheckbox, 0, 0) layout2.addWidget(self.sliceTabWidget, 1, 0) tab2.setLayout(layout2) tab3 = QWidget() layout3 = QGridLayout() layout3.addWidget(self.RadiiScaleGroupBox, 0, 0) tab3.setLayout(layout3) tab4 = QWidget() layout4 = QGridLayout() layout4.addWidget(self.BinsGroupBox, 0, 0) tab4.setLayout(layout4) self.functionTabWidget.addTab(tab1, "Expand") self.functionTabWidget.addTab(tab2, "Slice") self.functionTabWidget.addTab(tab3, "Size") self.functionTabWidget.addTab(tab4, "Bins") self.functionTabWidget.setDisabled(True) def SpacegroupSelchange(self, i): self.NGL_HKL_command("NGL_HKLviewer.spacegroup_choice = %d" % i) def find_free_port(self): import socket s = socket.socket() s.bind(('', 0)) # Bind to a free port provided by the host. port = s.getsockname()[1] s.close() return port def LaunchCCTBXPython(self): self.sockport = self.find_free_port() self.zmq_context = zmq.Context() self.socket = self.zmq_context.socket(zmq.PAIR) self.socket.bind("tcp://127.0.0.1:%s" % self.sockport) try: msg = self.socket.recv( flags=zmq.NOBLOCK) #To empty the socket from previous messages except Exception as e: pass cmdargs = 'cctbx.python -i -c "from crys3d.hklview import cmdlineframes;' \ + ' myHKLview = cmdlineframes.HKLViewFrame(useGuiSocket=%s, high_quality=True,' %self.sockport \ + ' jscriptfname = \'%s\', ' %self.jscriptfname \ + ' verbose=%s, UseOSBrowser=%s, htmlfname=\'%s\', handshakewait=%s )"\n'\ %(self.verbose, str(self.UseOSbrowser), self.hklfname, self.handshakewait) self.cctbxproc = subprocess.Popen(cmdargs, shell=True, stdin=subprocess.PIPE, stdout=sys.stdout, stderr=sys.stderr) #time.sleep(1) def NGL_HKL_command(self, cmdstr): #print("sending:\n" + cmdstr) self.socket.send(bytes(cmdstr, "utf-8"))
class FilterGroup(AbstractProcessGroup): def __init__(self, title, fs): AbstractProcessGroup.__init__(self, title, fs) self.setupFilterLayout() def setupFilterLayout(self): filterLayout = QVBoxLayout(self) filterSettLayout = QHBoxLayout() self.filterBandChooser = QComboBox() self.filterTypeChooser = QComboBox() filterTypeLayout = QFormLayout() filterTypeLayout.addWidget(QLabel('Type')) filterTypeLayout.addWidget(self.filterBandChooser) bandTypes = { 'Low Pass': '******', 'Band Pass': '******', 'High Pass': '******', 'Band Stop': 'bandstop' } [self.filterBandChooser.addItem(i, bandTypes[i]) for i in bandTypes] self.filterBandChooser.setCurrentText('Band Pass') filterTypeLayout.addWidget(self.filterTypeChooser) filterTypes = {'Butter': 'butter', 'Bessel': 'bessel'} [ self.filterTypeChooser.addItem(i, filterTypes[i]) for i in filterTypes ] self.lowFreqEdit = QDoubleSpinBox() self.lowFreqEdit.setSuffix(' Hz') self.lowFreqEdit.setDecimals(1) self.lowFreqEdit.setRange(0.1, self.fs / 2 - 0.1) self.highFreqEdit = QDoubleSpinBox() self.highFreqEdit.setSuffix(' Hz') self.highFreqEdit.setDecimals(1) self.highFreqEdit.setLocale( QLocale(QLocale.Polish, QLocale.EuropeanUnion)) self.highFreqEdit.setRange(0.1, self.fs / 2 - 0.1) self.filterBandChooser.currentTextChanged.connect(self.setFilterBand) filterFreqLayout = QFormLayout() filterFreqLayout.addRow(QLabel('Cutoff Frequencies')) filterFreqLayout.addRow('Low', self.lowFreqEdit) filterFreqLayout.addRow('High', self.highFreqEdit) filterOrdLayout = QFormLayout() self.filterOrdEdit = QSpinBox() self.filterOrdEdit.setMinimum(1) self.filterOrdEdit.setValue(5) filterOrdLayout.addRow(QLabel('Order')) filterOrdLayout.addRow(self.filterOrdEdit) filterSettLayout.addLayout(filterTypeLayout) filterSettLayout.addSpacing(10) filterSettLayout.addLayout(filterFreqLayout) filterSettLayout.addSpacing(10) filterSettLayout.addLayout(filterOrdLayout) btn = QPushButton('Show filter response') btn.clicked.connect(self.showFilterResponse) filterLayout.addLayout(filterSettLayout) filterLayout.addWidget(btn, 0, Qt.AlignRight) def setFilterBand(self): if self.filterBandChooser.currentText() == 'Low Pass': self.lowFreqEdit.setDisabled(True) else: self.lowFreqEdit.setEnabled(True) if self.filterBandChooser.currentText() == 'High Pass': self.highFreqEdit.setDisabled(True) else: self.highFreqEdit.setEnabled(True) def calcFilter(self): bandArr = [ x.value() for x in (self.lowFreqEdit, self.highFreqEdit) if x.isEnabled() == True ] return filterCalc(order=self.filterOrdEdit.value(), bandarr=bandArr, fs=self.fs, btype=self.filterBandChooser.currentData(), ftype=self.filterTypeChooser.currentData()) def showFilterResponse(self): bandArr = [ x.value() for x in (self.lowFreqEdit, self.highFreqEdit) if x.isEnabled() == True ] b, a = self.calcFilter() w, h = signal.freqz(b, a) fig = plt.figure() ax1 = fig.add_subplot(111) ax1.set_title( label='Filter frequency response\n{}, {}, {}Hz, ord={}'.format( self.filterBandChooser.currentText(), self.filterTypeChooser.currentText(), bandArr, self.filterOrdEdit.value())) ax1.plot(w * (self.fs / (2 * np.pi)), 20 * np.log10(abs(h)), 'b') ax1.set_ylabel('Amplitude [dB]', color='b') ax1.set_xlabel('Frequency [Hz]') ax1.tick_params(axis='y', colors='b') ax2 = ax1.twinx() angles = np.unwrap(np.angle(h)) ax2.plot(w * (self.fs / (2 * np.pi)), angles, 'g') ax2.set_ylabel('Angle (radians)', color='g') ax2.tick_params(axis='y', colors='g') plt.grid() plt.axis('tight') plt.show() def process(self, inData): b, a = self.calcFilter() outData = [] progStep = 100.0 / len(inData) prog = 0 for data in inData: newData = signal.lfilter(b, a, data) outData.append(newData) prog = prog + progStep self.progress.emit(int(prog)) return outData