def run(self): target = self._run_widget.target_case() source = self._run_widget.source_case() if len(target) == 0: self._report_empty_target() return try: analyse(self.ert, target, source) error = None except ErtAnalysisError as e: error = str(e) except Exception as e: error = f"Uknown exception occured with error: {str(e)}" msg = QMessageBox() msg.setWindowTitle("Run analysis") msg.setStandardButtons(QMessageBox.Ok) if not error: msg.setIcon(QMessageBox.Information) msg.setText(f"Successfully ran analysis for case '{source}'.") msg.exec_() else: msg.setIcon(QMessageBox.Warning) msg.setText(f"Unable to run analysis for case '{source}'.\n" f"The following error occured: {error}") msg.exec_() return self.notifier.ertChanged.emit() self._dialog.accept()
def mirror_navi(self, uisignals=None, shared_nav=False): # Select signals if uisignals is None: uisignals = self.ui.get_selected_wrappers() if len(uisignals) < 2: mb = QMessageBox( QMessageBox.Information, tr("Select two or more"), tr("You need to select two or more signals" + " to mirror"), QMessageBox.Ok) mb.exec_() return signals = [s.signal for s in uisignals] # hyperspy closes, and then recreates figures when mirroring # the navigators. To keep UI from flickering, we suspend updates. # SignalWrapper also saves and then restores window geometry self.ui.setUpdatesEnabled(False) try: if shared_nav: navs = ["auto"] navs.extend([None] * (len(signals) - 1)) hyperspy.utils.plot.plot_signals(signals, sync=True, navigator_list=navs) else: hyperspy.utils.plot.plot_signals(signals, sync=True) finally: self.ui.setUpdatesEnabled(True) # Continue updating UI
def show_about(self): """Show About dialog.""" msg_box = QMessageBox(self) text = (f"<img src='{image_path('mnelab_logo.png')}'>" f"<p>MNELAB {__version__}</p>") msg_box.setText(text) mnelab_url = "github.com/cbrnr/mnelab" mne_url = "github.com/mne-tools/mne-python" pkgs = [] for key, value in have.items(): if value: pkgs.append(f"{key} ({value})") else: pkgs.append(f"{key} (not installed)") text = (f'<nobr><p>This program uses Python ' f'{".".join(str(k) for k in version_info[:3])} and the ' f'following packages:</p></nobr>' f'<p>{", ".join(pkgs)}</p>' f'<nobr><p>MNELAB repository: ' f'<a href=https://{mnelab_url}>{mnelab_url}</a></p></nobr>' f'<nobr><p>MNE repository: ' f'<a href=https://{mne_url}>{mne_url}</a></p></nobr>' f'<p>Licensed under the BSD 3-clause license.</p>' f'<p>Copyright 2017-2020 by Clemens Brunner.</p>') msg_box.setInformativeText(text) msg_box.exec_()
def load_files(self): dial = MultipleLoadDialog(self.load_register, self.settings.get_path_history()) dial.setDirectory( self.settings.get("io.multiple_open_directory", str(Path.home()))) dial.selectNameFilter( self.settings.get("io.multiple_open_filter", next(iter(self.load_register.keys())))) self.error_list = [] if dial.exec_(): result = dial.get_result() load_dir = os.path.dirname(result.load_location[0]) self.settings.set("io.multiple_open_directory", load_dir) self.settings.add_path_history(load_dir) self.settings.set("io.multiple_open_filter", result.selected_filter) dial_fun = ExecuteFunctionDialog( self.execute_load_files, [result], exception_hook=load_data_exception_hook) dial_fun.exec_() if self.error_list: errors_message = QMessageBox() errors_message.setText("There are errors during load files") errors_message.setInformativeText( "During load files cannot found some of files on disc") errors_message.setStandardButtons(QMessageBox.Ok) text = "\n".join("File: " + x[0] + "\n" + str(x[1]) for x in self.error_list) errors_message.setDetailedText(text) errors_message.exec_()
def show_error(error=None): """This class create error dialog and show it""" if error is None: return if isinstance(error, TiffFileException): mess = QMessageBox() mess.setIcon(QMessageBox.Critical) mess.setText("During read file there is an error: " + error.args[0]) mess.setWindowTitle("Tiff error") mess.exec_() return if isinstance(error, SegmentationLimitException): mess = QMessageBox() mess.setIcon(QMessageBox.Critical) mess.setText( "During segmentation process algorithm meet limitations:\n" + "\n".join(error.args)) mess.setWindowTitle("Segmentation limitations") mess.exec_() return from PartSeg.common_gui.error_report import ErrorDialog dial = ErrorDialog(error, "Exception during program run") dial.exec_()
def _show_about_dialog(self): msg_box = QMessageBox() msg_box.setIcon(QMessageBox.Information) msg_box.setText("Pybonacci app v -37.3") msg_box.setWindowTitle("Ejemplo de Slot") msg_box.setStandardButtons(QMessageBox.Close) msg_box.exec_()
def run(self): target = self._run_widget.target_case() source = self._run_widget.source_case() if len(target) == 0: self._report_empty_target() return success = analyse(target, source) msg = QMessageBox() msg.setWindowTitle("Run Analysis") msg.setStandardButtons(QMessageBox.Ok) if success: msg.setIcon(QMessageBox.Information) msg.setText( "Successfully ran analysis for case '{}'.".format(source)) msg.exec_() else: msg.setIcon(QMessageBox.Warning) msg.setText("Unable to run analysis for case '{}'.".format(source)) msg.exec_() return ert_shared.ERT.ertChanged.emit() self._dialog.accept()
def raise_to_operator(exc, execute=True): """ Utility function to show a Python Exception in QMessageBox The type and representation of the Exception are shown in a pop-up QMessageBox. The entire traceback is available via a drop-down detailed text box in the QMessageBox Parameters ---------- exc: Exception execute: bool, optional Whether to execute the QMessageBox """ # Assemble QMessageBox with Exception details err_msg = QMessageBox() err_msg.setText(f'{exc.__class__.__name__}: {exc}') err_msg.setWindowTitle(type(exc).__name__) err_msg.setIcon(QMessageBox.Critical) # Format traceback as detailed text with io.StringIO() as handle: traceback.print_tb(exc.__traceback__, file=handle) handle.seek(0) err_msg.setDetailedText(handle.read()) if execute: # Execute err_msg.exec_() return err_msg
def validate_password(self): """ If the widget is ```passwordProtected```, this method will propmt the user for the correct password. Returns ------- bool True in case the password was correct of if the widget is not password protected. """ if not self._password_protected: return True pwd, ok = QInputDialog().getText(None, "Authentication", "Please enter your password:"******"") pwd = str(pwd) if not ok or pwd == "": return False sha = hashlib.sha256() sha.update(pwd.encode()) pwd_encrypted = sha.hexdigest() if pwd_encrypted != self._protected_password: msg = QMessageBox() msg.setIcon(QMessageBox.Critical) msg.setText("Invalid password.") msg.setWindowTitle("Error") msg.setStandardButtons(QMessageBox.Ok) msg.setDefaultButton(QMessageBox.Ok) msg.setEscapeButton(QMessageBox.Ok) msg.exec_() return False return True
def mirror_navi(self, uisignals=None, shared_nav=False): # Select signals if uisignals is None: uisignals = self.ui.get_selected_wrappers() if len(uisignals) < 2: mb = QMessageBox(QMessageBox.Information, tr("Select two or more"), tr("You need to select two or more signals" + " to mirror"), QMessageBox.Ok) mb.exec_() return signals = [s.signal for s in uisignals] # hyperspy closes, and then recreates figures when mirroring # the navigators. To keep UI from flickering, we suspend updates. # SignalWrapper also saves and then restores window geometry self.ui.setUpdatesEnabled(False) try: if shared_nav: navs = ["auto"] navs.extend([None] * (len(signals)-1)) hyperspy.utils.plot.plot_signals(signals, sync=True, navigator_list=navs) else: hyperspy.utils.plot.plot_signals(signals, sync=True) finally: self.ui.setUpdatesEnabled(True) # Continue updating UI
def copyCellsToClipboard(self): """Concatenate the text content of all cells into a string using tabulations and newlines to keep the table structure. Put this text into the clipboard. """ data_model = self.table.model() copied_text = "" for row in range(data_model.rowCount()): for col in range(data_model.columnCount()): index = data_model.index(row, col) cell_text = data_model.data(index) flags = data_model.flags(index) if cell_text is not None: try: copied_text += cell_text except: # Only works for text cells msgBox = QMessageBox(parent=self.table) msgBox.setText(_NONTEXTCELL) msgBox.exec_() return False return if self.cut and (flags & Qt.ItemIsEditable): data_model.setData(index, "") copied_text += col_separator # remove the right-most tabulation copied_text = copied_text[:-len(col_separator)] # add a newline copied_text += row_separator # remove final newline copied_text = copied_text[:-len(row_separator)] # put this text into clipboard qapp = QApplication.instance() qapp.clipboard().setText(copied_text)
def load_from_file(self, fname): try: self.I_meas, self.sigma = np.loadtxt( fname, skiprows=2, unpack=True) except (ValueError, TypeError): msg = QMessageBox() msg.setIcon(QMessageBox.Warning) msg.setText("Could not Load File") msg.setInformativeText( "The chosen file does not match the formatting.") msg.setWindowTitle("Warning") msg.resize(900, 300) msg.exec_() return with open(fname, 'r') as f: self.plane_meas = f.readline().split()[-1] if self.plane_meas == 'x': self.line_sigmax.set_xdata(self.I_meas) self.line_sigmax.set_ydata(np.array(self.sigma)*1e3) else: self.line_sigmay.set_xdata(self.I_meas) self.line_sigmay.set_ydata(np.array(self.sigma)*1e3) self.fig_sigma.figure.axes[0].set_xlim( [min(self.I_meas)*(1-DT*10), max(self.I_meas)*(1+DT*10)]) self.fig_sigma.figure.axes[0].set_ylim( [min(self.sigma)*(1-DT)*1e3, max(self.sigma)*(1+DT)*1e3]) self.fig_sigma.figure.canvas.draw()
def load_fod_input(self): _current_folder = self.parent.parent.current_folder [_table_file, _] = QFileDialog.getOpenFileName( parent=self.parent, caption="Input inp File", directory=_current_folder, filter=("inp files (*.inp);; All Files (*.*)")) if not _table_file: return try: fod_inputs = open(_table_file, "r") except IOError: self.err_messenger("Permission denied! Choose another input file!") return lines = fod_inputs.readlines() fod_inputs.close() for line in lines: try: if line.strip(): self.parameters[line.split('#')[1].strip()]=line.split('#')[0].strip() except IndexError: pass try: self.parent.ui.sample_1_title.setText(self.parameters['sample_1_title']) self.parent.ui.sample_2_title.setText(self.parameters['sample_2_title']) self.parent.ui.bkg_title.setText(self.parameters['background_title']) self.parent.ui.bkg_scans.setText(self.parameters['background scannrs']) self.parent.ui.sample_1_scans.setText(self.parameters['sample_1_scannrs']) self.parent.ui.sample_2_scans.setText(self.parameters['sample_2_scannrs']) self.parent.ui.secondary_scattering_ratio.setText(self.parameters['secondary_scattering_ratio']) self.parent.ui.plazcek_fit_range_min.setText(self.parameters['pla_range'].split(',')[0].strip()) self.parent.ui.plazcek_fit_range_max.setText(self.parameters['pla_range'].split(',')[1].strip()) if ',' in self.parameters['substitution_type']: self.parent.ui.subs_init.setText(self.parameters['substitution_type'].split(',')[0].strip()) self.parent.ui.subs_rep.setText(self.parameters['substitution_type'].split(',')[1].strip()) elif '/' in self.parameters['substitution_type']: self.parent.ui.subs_init.setText(self.parameters['substitution_type'].split('/')[0].strip()) self.parent.ui.subs_rep.setText(self.parameters['substitution_type'].split('/')[1].strip()) self.parent.ui.ft_qrange.setText(self.parameters['qrangeft']) self.parent.ui.ff_rrange.setText(self.parameters['fourier_range_r']) try: self.parent.ui.ff_qrange.setText(self.parameters['fourier_range_q']) except KeyError: self.parent.ui.ff_qrange.setText(self.parameters['fourier_range_Q']) except (IndexError, KeyError): msgBox = QMessageBox() msgBox.setIcon(QMessageBox.Critical) msgBox.setText("Error in FOD input file!") msgBox.setWindowTitle("Error") msgBox.setStandardButtons(QMessageBox.Ok) msgBox.exec_() return return
def handle_timeout(self): """ Handles the timeout event for the timer. Decreases the time remaining counter until 0 and when it is time, cleans up the event filter and closes the window. """ if is_qt_designer(): return # Decrease remaining time self._time_rem_ms -= self._timer.interval() # Update screen label with new remaining time self._update_label() if self._time_rem_ms > 0: self.start() return QApplication.instance().removeEventFilter(self) if self._window: logger.debug('Time to close the window') self._window.close() msg = QMessageBox() msg.setIcon(QMessageBox.Warning) msg.setText( "Your window was closed due to inactivity for {}.".format( self._get_time_text(self.timeout))) msg.setStandardButtons(QMessageBox.Ok) msg.setDefaultButton(QMessageBox.Ok) msg.exec_()
def report_error(self, text, error): heading = _('Error message:') msgbox = QMessageBox( QMessageBox.Critical, _('Restore'), _('<b>{}</b><br><br>{}<br>{}').format(text, heading, error), parent=self) msgbox.exec_()
def handle_capture(window, capture): email, ok = QInputDialog.getText( window, 'Email', 'Enter your employee ID or email:', flags=Qt.FramelessWindowHint | Qt.Popup) while ok and not get_email(email): email, ok = QInputDialog.getText( window, 'Email', 'Enter a valid employee ID or email:', flags=Qt.FramelessWindowHint | Qt.Popup) if ok: print('Send email to %s' % email) pb = None try: pb = QProgressDialog("Sending...", "", 0, 0, window, Qt.FramelessWindowHint | Qt.Popup) pb.setWindowModality(Qt.WindowModal) pb.setRange(0, 0) pb.setMinimumDuration(0) pb.setCancelButton(None) pb.show() nongui(send_image)(email, capture, cache_dir=IMAGE_CACHE_DIR) except Exception: import traceback traceback.print_exc() msg = QMessageBox(window) msg.setIcon(QMessageBox.Critical) msg.setText('Error sending email.') msg.setWindowFlags(Qt.FramelessWindowHint | Qt.Popup) msg.exec_() finally: if pb: pb.close()
def _report_empty_target(self): msg = QMessageBox() msg.setWindowTitle("Invalid Target") msg.setIcon(QMessageBox.Warning) msg.setText("Target case can not be empty") msg.setStandardButtons(QMessageBox.Ok) msg.exec_()
def show_error_message(message, title, parent=None): box = QMessageBox(parent=parent) box.setIcon(QMessageBox.Warning) box.setText(message) box.setWindowTitle(title) box.setStandardButtons(QMessageBox.Ok) box.exec_()
def err_messenger(self, message): msgBox = QMessageBox() msgBox.setIcon(QMessageBox.Critical) msgBox.setText(message) msgBox.setWindowTitle("Error") msgBox.setStandardButtons(QMessageBox.Ok) msgBox.exec_() return
def _plotting_error(self, msg, trace): msg_box = QMessageBox(self) msg_box.setIcon(QMessageBox.Critical) msg_box.setText('Plotting Error') msg_box.setInformativeText(msg) msg_box.setDetailedText(trace) msg_box.setStandardButtons(QMessageBox.Close) msg_box.exec_()
def __init__( self, config_folder: Union[str, Path, None] = None, title="PartSeg", settings: Optional[BaseSettings] = None, load_dict: Optional[Register] = None, signal_fun=None, ): if settings is None: if config_folder is None: raise ValueError("wrong config folder") if not os.path.exists(config_folder): import_config() settings: BaseSettings = self.get_setting_class()(config_folder) errors = settings.load() if errors: errors_message = QMessageBox() errors_message.setText("There are errors during start") errors_message.setInformativeText( "During load saved state some of data could not be load properly\n" "The files has prepared backup copies in " " state directory (Help > State directory)") errors_message.setStandardButtons(QMessageBox.Ok) text = "\n".join("File: " + x[0] + "\n" + str(x[1]) for x in errors) errors_message.setDetailedText(text) errors_message.exec_() super().__init__() if signal_fun is not None: self.show_signal.connect(signal_fun) self.settings = settings self._load_dict = load_dict self.viewer_list: List[Viewer] = [] self.files_num = 1 self.setAcceptDrops(True) self.setWindowTitle(title) self.title_base = title app = QApplication.instance() if app is not None: app.setStyleSheet(settings.style_sheet) self.settings.theme_changed.connect(self.change_theme) self.channel_info = "" self.multiple_files = None self.settings.request_load_files.connect(self.read_drop) self.recent_file_menu = QMenu("Open recent") self._refresh_recent() self.settings.connect_(FILE_HISTORY, self._refresh_recent) self.settings.napari_settings.appearance.events.theme.connect( self.change_theme) self.settings.set_parent(self) self.console = None self.console_dock = QDockWidget("console", self) self.console_dock.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.BottomDockWidgetArea) # self.console_dock.setWidget(self.console) self.console_dock.hide() self.addDockWidget(Qt.BottomDockWidgetArea, self.console_dock)
def update_check(self, silent=False): """ Checks for updates to hyperspy and hyperspyUI. If the packages are not source installs, it checks for a new version on PyPI. Parameters ---------- silent: bool If not silent (default), a message box will appear if no updates are available, with a message to that fact. """ self._check_git() available = {} for Name, (enabled, url) in self.packages.items(): name = Name.lower() if enabled: if (check_git_repo(name) and self.settings['check_for_git_updates', bool]): # TODO: Check for commits to pull pass else: import xmlrpc.client pypi = xmlrpc.client.ServerProxy( 'https://pypi.python.org/pypi') found = pypi.package_releases(name) if not found: # Try to capitalize pkg name if name == 'hyperspyui': found = pypi.package_releases('hyperspyUI', True) else: found = pypi.package_releases(Name, True) if found: import pip dist = [ d for d in pip.get_installed_distributions() if d.project_name.lower() == name ] if dist[0].version < found[0]: available[name] = found[0] if available: w = self._get_update_list(available.keys()) diag = self.ui.show_okcancel_dialog("Updates available", w) if diag.result() == QDialog.Accepted: for chk in w.children(): if isinstance(chk, QtWidgets.QCheckBox): name = chk.text() if available[name]: name += '==' + available[name] self._perform_update(name) elif not silent: mb = QMessageBox(QMessageBox.Information, tr("No updates"), tr("No new updates were found."), parent=self.ui) mb.exec_()
def show_about_dialog(self): ## NUEVA LÍNEA msg_box = QMessageBox() msg_box.setIcon(QMessageBox.Information) msg_box.setText( "Aplicación de Scrapper y búsqueda en 20 Minutos, El Mundo y El Pais \n\n por Ignacio Triguero y Alexey Zhelezov" ) msg_box.setWindowTitle("Acerca de") msg_box.setStandardButtons(QMessageBox.Close) msg_box.exec_()
def display_message_box(self, title, message, details): msg = QMessageBox(self) msg.setIcon(QMessageBox.Warning) msg.setText(message) msg.setWindowTitle(title) msg.setDetailedText(details) msg.setStandardButtons(QMessageBox.Ok) msg.setDefaultButton(QMessageBox.Ok) msg.setEscapeButton(QMessageBox.Ok) msg.exec_()
def get_real_image(self, signal=None): if signal is None: signal = self.ui.get_selected_signal() if not isinstance(signal, hs.signals.ComplexSignal): mb = QMessageBox(QMessageBox.Information, tr("Real and imaginary"), tr("A complex signal is required."), QMessageBox.Ok) mb.exec_() signal.real.plot() signal.imag.plot()
def update_check(self, silent=False): """ Checks for updates to hyperspy and hyperspyUI. If the packages are not source installs, it checks for a new version on PyPI. Parameters ---------- silent: bool If not silent (default), a message box will appear if no updates are available, with a message to that fact. """ self._check_git() available = {} for Name, (enabled, url) in self.packages.items(): name = Name.lower() if enabled: if (check_git_repo(name) and self.settings['check_for_git_updates', bool]): # TODO: Check for commits to pull pass else: import xmlrpc.client pypi = xmlrpc.client.ServerProxy( 'https://pypi.python.org/pypi') found = pypi.package_releases(name) if not found: # Try to capitalize pkg name if name == 'hyperspyui': found = pypi.package_releases('hyperspyUI', True) else: found = pypi.package_releases(Name, True) if found: import pip dist = [d for d in pip.get_installed_distributions() if d.project_name.lower() == name] if dist[0].version < found[0]: available[name] = found[0] if available: w = self._get_update_list(available.keys()) diag = self.ui.show_okcancel_dialog("Updates available", w) if diag.result() == QDialog.Accepted: for chk in w.children(): if isinstance(chk, QtWidgets.QCheckBox): name = chk.text() if available[name]: name += '==' + available[name] self._perform_update(name) elif not silent: mb = QMessageBox(QMessageBox.Information, tr("No updates"), tr("No new updates were found."), parent=self.ui) mb.exec_()
def get_amplitude_phase(self, signal=None): if signal is None: signal = self.ui.get_selected_signal() if not isinstance(signal, hs.signals.ComplexSignal): mb = QMessageBox(QMessageBox.Information, tr("Amplitude and phase"), tr("A complex signal is required."), QMessageBox.Ok) mb.exec_() signal.amplitude.plot() signal.phase.plot()
def image_capture(self): self.freeze = self.image.copy() # prevent background update try: self.capture_handler(self, self.freeze) except Exception: msg = QMessageBox(self) msg.setIcon(QMessageBox.Critical) msg.setText('Error during capture.') msg.setWindowFlags(Qt.FramelessWindowHint | Qt.Popup) msg.exec_() self.freeze = None
def pb_analyse_data_clicked(self): if self.I_meas is None or self.sigma is None: msg = QMessageBox() msg.setIcon(QMessageBox.Warning) msg.setText("Could Perform Analysis") msg.setInformativeText( "No data in memory. Please make a measurement or load the data.") msg.setWindowTitle("Warning") msg.resize(900, 300) msg.exec_() return self._perform_analysis()
def pasteCellFromClipboard(self): """Paste text from clipboard into the table. :return: *True* in case of success, *False* if pasting data failed. """ selected_idx = self.table.selectedIndexes() if len(selected_idx) != 1: msgBox = QMessageBox(parent=self.table) msgBox.setText(_PASTE1) msgBox.exec_() return False data_model = self.table.model() selected_row = selected_idx[0].row() selected_col = selected_idx[0].column() qapp = QApplication.instance() clipboard_text = qapp.clipboard().text() table_data = _parseTextAsTable(clipboard_text) protected_cells = 0 out_of_range_cells = 0 # paste table data into cells, using selected cell as origin for row_offset in range(len(table_data)): for col_offset in range(len(table_data[row_offset])): target_row = selected_row + row_offset target_col = selected_col + col_offset if target_row >= data_model.rowCount() or\ target_col >= data_model.columnCount(): out_of_range_cells += 1 continue index = data_model.index(target_row, target_col) flags = data_model.flags(index) # ignore empty strings if table_data[row_offset][col_offset] != "": if not flags & Qt.ItemIsEditable: protected_cells += 1 continue data_model.setData(index, table_data[row_offset][col_offset]) # item.setText(table_data[row_offset][col_offset]) if protected_cells or out_of_range_cells: msgBox = QMessageBox(parent=self.table) msgBox.setText(_PASTEFAIL) msgBox.exec_() return False return True
def show_structure(self): if self.file_name: f = dicom.read_file(self.file_name) #l = QtWidgets.QLabel(str(f)) #l.show() msgBox = QMessageBox(parent=self) msgBox.setWindowTitle('Informacion') msgBox.setText(str(f)) msgBox.exec_() print(str(f))
def _check_rows(self, rows, only_one=False): """Checks how many items are in ``rows`` and alerts user if not right. Checks the number of indices in ``rows``, alerts the user with a popup box if there are no items in ``rows``. Alternatively if the kwarg ``only_one`` is ``True`` also alerts users that too many rows are selected. Returns ``True`` if the right number(s) of items are in ``rows`` otherwise it returns ``False``. Parameters ---------- rows : [row indices] A list of row indices to be checked. only_one : Bool, optional A boolean that indicates if more than one row is allowed, default is ``False``. Returns ------- Ok : Bool A boolean to indicate if the number of items in row is Ok. """ Ok = True if not rows: # if no cell is selected Ok = False warning = QMessageBox() warning.setIcon(QMessageBox.Information) warning.setWindowTitle('Row(s) must be selected') warning.setText('Action not performed as no row is selected') warning.setDetailedText('This warning generally occurs ' 'because no row is selected, select a row' ' and try again') warning.setStandardButtons(QMessageBox.Ok) warning.exec_() elif len(rows) > 1 and only_one: Ok = False warning = QMessageBox() warning.setIcon(QMessageBox.Information) warning.setWindowTitle('More than one row is selected') warning.setText('Action not performed as more than one row is ' 'selected') warning.setDetailedText('This warning generally occurs ' 'because there are more than one row ' 'selected, unselect some rows and try ' 'again') warning.setStandardButtons(QMessageBox.Ok) warning.exec_() return Ok
def checkout_branch(branch, stream=None): """ If `branch` is a string, assume it is archive url. Try to install by pip. Otherwise `branch` is assumed by a branch object from the `git` package, which will be attempted to be checked out. """ if branch is None: return if isinstance(branch, str): import pip import sys class WrapDownloadProgressBar(pip.download.DownloadProgressBar): def __init__(self, *args, **kwargs): super(WrapDownloadProgressBar, self).__init__( *args, **kwargs) self.file = stream class WrapDownloadProgressBarSpinner( pip.download.DownloadProgressSpinner): def __init__(self, *args, **kwargs): super(WrapDownloadProgressBarSpinner, self).__init__( *args, **kwargs) self.file = stream ic = pip.commands.InstallCommand() ic.log_streams = (stream, stream) old_classes = (pip.download.DownloadProgressBar, pip.download.DownloadProgressSpinner) pip.download.DownloadProgressBar = WrapDownloadProgressBar pip.download.DownloadProgressSpinner = WrapDownloadProgressBarSpinner stdout_set = False if sys.__stdout__ is None: sys.__stdout__ = sys.stdout stdout_set = True try: ic.main(['--no-deps', '-I', branch]) ic.main([branch]) finally: if stdout_set: sys.__stdout__ = None # Let's leave things as we found them. (pip.download.DownloadProgressBar, pip.download.DownloadProgressSpinner) = old_classes else: try: branch.checkout() except git.GitCommandError as e: mb = QMessageBox(QMessageBox.Critical, tr("Git checkout failed"), e.stderr) mb.exec_() raise ValueError()
def exception(parent, ex, buttons=QMessageBox.Ok, defaultButton=QMessageBox.NoButton): title = type(ex).__name__ message = str(ex) tb = StringIO() if hasattr(ex, '__traceback__'): exc_traceback = ex.__traceback__ else: exc_traceback = sys.exc_info()[2] traceback.print_tb(exc_traceback, file=tb) msgbox = QMessageBox(QMessageBox.Critical, title, message, buttons, parent) msgbox.setDefaultButton(defaultButton) msgbox.setDetailedText(tb.getvalue()) msgbox.exec_()
def show_mongo_query_help(self): "Launch a Message Box with instructions for custom queries." msg = QMessageBox() msg.setIcon(QMessageBox.Information) msg.setText("For advanced search capability, enter a valid Mongo query.") msg.setInformativeText(""" Examples: {'plan_name': 'scan'} {'proposal': 1234}, {'$and': ['proposal': 1234, 'sample_name': 'Ni']} """) msg.setWindowTitle("Custom Mongo Query") msg.setStandardButtons(QMessageBox.Ok) msg.exec_()
def dialog(title, text, icon, setting=None, default=None): if not getattr(settings, setting.upper()): return True check = QCheckBox() check.setText('Dont show this message again (can be reset via the preferences)') info = QMessageBox() info.setIcon(icon) info.setText(title) info.setInformativeText(text) info.setCheckBox(check) info.setStandardButtons(info.Cancel | info.Ok) if default == 'Cancel': info.setDefaultButton(info.Cancel) result = info.exec_() if result == info.Cancel: return False if check.isChecked(): setattr(settings, setting.upper(), False) save_settings() return True
def save_list_to_file(self): filename, filters = QFileDialog.getSaveFileName(self, "Save connection list", "", "Text Files (*.txt)") try: with open(filename, "w") as f: for conn in self.table_view.model().connections: f.write( "{p}://{a}\n".format(p=conn.protocol, a=conn.address)) self.save_status_label.setText("File saved to {}".format(filename)) except Exception as e: msgBox = QMessageBox() msgBox.setText("Couldn't save connection list to file.") msgBox.setInformativeText("Error: {}".format(str(e))) msgBox.setStandardButtons(QMessageBox.Ok) msgBox.exec_()
def exceptions(parent, exs, buttons=QMessageBox.Ok, defaultButton=QMessageBox.NoButton): title = 'Exception(s)' message = '\n'.join(map(str, exs)) tracebacks = [] for ex in exs: tb = StringIO() if not hasattr(ex, '__traceback__'): continue exc_traceback = ex.__traceback__ traceback.print_tb(exc_traceback, file=tb) tracebacks.append(tb.getvalue()) msgbox = QMessageBox(QMessageBox.Critical, title, message, buttons, parent) msgbox.setDefaultButton(defaultButton) msgbox.setDetailedText('\n'.join(tracebacks)) msgbox.exec_()
def _on_reset(self): """ Callback for reset button. Prompts user for confirmation, then proceeds to reset settings to default values if confirmed, before updating controls and applying any changes (emits change signal if any changes). """ mb = QMessageBox(QMessageBox.Warning, tr("Reset all settings"), tr("This will reset all settings to their default " + "values. Are you sure you want to continue?"), QMessageBox.Yes | QMessageBox.No) mb.setDefaultButton(QMessageBox.No) dr = mb.exec_() if dr == QMessageBox.Yes: # This clears all settings, and recreates only those values # initialized with set_default this session. Settings.restore_from_defaults() # Now we update controls: s = QSettings(self.ui) keys = list(self._initial_values.keys()) # Use copy, as we may modify for k in keys: # Check if setting is still present if s.contains(k): # Present, update to new value (triggers _on_change) v = s.value(k) w = self._lut[k] if isinstance(w, QLineEdit): w.setText(v) elif isinstance(w, QCheckBox): w.setChecked(v.lower() == "true") elif isinstance(w, (QSpinBox, QDoubleSpinBox)): w.setValue(v) else: # Setting was removed, remove editor w = self._lut[k] layout = w.parent().layout() label = layout.labelForField(w) layout.removeWidget(w) w.close() if label is not None: layout.removeWidget(label) label.close() del self._lut[k] del self._initial_values[k] self._changes[k] = None # Check whether all editors for tab was removed if layout.count() == 0: wrap = w.parent() self.tabs.removeTab(self.tabs.indexOf(wrap)) # Finally apply changes (update _initial_values, and emit signal) self.apply_changes()
def get_selected_wrapper(self, error_on_multiple=False): signals = self.get_selected_wrappers() if signals is None or len(signals) < 1: return None elif len(signals) == 1: return signals[0] else: if error_on_multiple: mb = QMessageBox(QMessageBox.Information, tr("Select one signal only"), tr("You can only select one signal at the " + "time for this function. Currently, " + "several are selected"), QMessageBox.Ok) mb.exec_() raise RuntimeError() w = self.main_frame.activeSubWindow() s = [hyperspyui.util.win2sig(w, self.signals)] if s in signals: return s else: return signals[0]
def permission_box_to_prepend_import(): msg_box = QMessageBox() msg_box.setWindowTitle("Mantid Workbench") msg_box.setWindowIcon(QIcon(':/images/MantidIcon.ico')) msg_box.setText("It looks like this python file uses a Mantid " "algorithm but does not import the Mantid API.") msg_box.setInformativeText("Would you like to add a line to import " "the Mantid API?") msg_box.setStandardButtons(QMessageBox.Yes | QMessageBox.No) msg_box.setDefaultButton(QMessageBox.Yes) permission = msg_box.exec_() if permission == QMessageBox.Yes: return True return False
def confirm_dialog(self): """ Show the confirmation dialog with the proper message in case ```showConfirmMessage``` is True. Returns ------- bool True if the message was confirmed or if ```showCofirmMessage``` is False. """ if self._show_confirm_dialog: if self._confirm_message == "": self._confirm_message = PyDMPushButton.DEFAULT_CONFIRM_MESSAGE msg = QMessageBox() msg.setIcon(QMessageBox.Question) msg.setText(self._confirm_message) msg.setStandardButtons(QMessageBox.Yes | QMessageBox.No) msg.setDefaultButton(QMessageBox.No) ret = msg.exec_() if ret == QMessageBox.No: return False return True
def show(self): """ Parses the current plot window information and displays the unit change dialog with the appropriate available units to which the current plot's units can be changed. """ # If there is no plot item, don't even try to process unit info if self.hub.plot_item is None or len(self.hub.visible_plot_items) == 0: message_box = QMessageBox() message_box.setText("No item plotted, cannot parse unit information.") message_box.setIcon(QMessageBox.Warning) message_box.setInformativeText( "There is currently no items plotted. Please plot an item " "before changing unit.") message_box.exec_() return # Prevents duplicate units from showing up each time this is executed self.ui.comboBox_units.clear() self.ui.comboBox_spectral.clear() # If the units in PlotWidget are not set, do not allow the user to click the OK button if not self.hub.plot_widget.data_unit: self.ui.comboBox_units.setEnabled(False) if not self.hub.plot_widget.spectral_axis_unit: self.ui.comboBox_spectral.setEnabled(False) if not (self.hub.plot_widget.data_unit or self.hub.plot_widget.spectral_axis_unit): self.ui.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) # Gets all possible conversions from current spectral_axis_unit self.spectral_axis_unit_equivalencies = u.Unit( self.hub.data_item.spectral_axis.unit).find_equivalent_units( equivalencies=u.spectral()) # Gets all possible conversions for flux from current spectral axis and corresponding units # np.sum for spectral_axis so that it does not return a Quantity with zero scale self.data_unit_equivalencies = u.Unit( self.hub.plot_widget.data_unit).find_equivalent_units( equivalencies=u.spectral_density(np.sum(self.hub.data_item.spectral_axis)), include_prefix_units=False) # Current data unit and spectral axis unit self.current_data_unit = self.hub.plot_widget.data_unit self.current_spectral_axis_unit = self.hub.plot_widget.spectral_axis_unit # Add current spectral axis units to equivalencies if u.Unit(self.hub.plot_widget.spectral_axis_unit) not in self.spectral_axis_unit_equivalencies: self.spectral_axis_unit_equivalencies.append(u.Unit(self.hub.plot_widget.spectral_axis_unit)) # Add original spectral axis units to equivalencies if u.Unit(self.hub.data_item.spectral_axis.unit) not in self.spectral_axis_unit_equivalencies: self.spectral_axis_unit_equivalencies.append(u.Unit(self.hub.data_item.spectral_axis.unit)) # Add current data units to equivalencies if u.Unit(self.hub.plot_widget.data_unit) not in self.data_unit_equivalencies: self.data_unit_equivalencies.append(u.Unit(self.hub.plot_widget.data_unit)) # Add original flux units to equivalencies if u.Unit(self.hub.data_item.flux.unit) not in self.data_unit_equivalencies: self.data_unit_equivalencies.append(u.Unit(self.hub.data_item.flux.unit)) # Sort units by to_string() self.spectral_axis_unit_equivalencies = sorted(self.spectral_axis_unit_equivalencies, key=lambda x: x.to_string()) self.data_unit_equivalencies = sorted(self.data_unit_equivalencies, key=lambda y: y.to_string()) # Create lists with the "pretty" versions of unit names self.spectral_axis_unit_equivalencies_titles = [ u.Unit(unit).name if u.Unit(unit) == u.Unit("Angstrom") else u.Unit(unit).long_names[0].title() if (hasattr(u.Unit(unit), "long_names") and len(u.Unit(unit).long_names) > 0) else u.Unit(unit).to_string() for unit in self.spectral_axis_unit_equivalencies] self.data_unit_equivalencies_titles = [ u.Unit(unit).name if u.Unit(unit) == u.Unit("Angstrom") else u.Unit(unit).long_names[0].title() if (hasattr(u.Unit(unit), "long_names") and len(u.Unit(unit).long_names) > 0) else u.Unit(unit).to_string() for unit in self.data_unit_equivalencies] # This gives the user the option to use their own units. These units are checked by u.Unit() # and PlotDataItem.is_spectral_axis_unit_compatible(spectral_axis_unit) and # PlotDataItem.is_data_unit_compatible(data_unit) self.spectral_axis_unit_equivalencies_titles.append("Custom") self.data_unit_equivalencies_titles.append("Custom") self.setup_ui() self.setup_connections() super().show()
class MainWindow(QMainWindow): """ Class of Main Window (top) """ _errMsgWindow = None def __init__(self, parent=None): """ Initialization and set up """ # Base class QMainWindow.__init__(self, parent) # Mantid configuration config = ConfigService.Instance() self._instrument = config["default.instrument"] # Central widget self.centralwidget = QWidget(self) # UI Window (from Qt Designer) self.ui = load_ui(__file__, 'MainWindow.ui', baseinstance=self) mpl_layout = QVBoxLayout() self.ui.graphicsView.setLayout(mpl_layout) self.fig = Figure() self.canvas = FigureCanvas(self.fig) self.ui.mainplot = self.fig.add_subplot(111, projection='mantid') mpl_layout.addWidget(self.canvas) # Do initialize plotting vecx, vecy, xlim, ylim = self.computeMock() self.mainline = self.ui.mainplot.plot(vecx, vecy, 'r-') leftx = [xlim[0], xlim[0]] lefty = [ylim[0], ylim[1]] self.leftslideline = self.ui.mainplot.plot(leftx, lefty, 'b--') rightx = [xlim[1], xlim[1]] righty = [ylim[0], ylim[1]] self.rightslideline = self.ui.mainplot.plot(rightx, righty, 'g--') upperx = [xlim[0], xlim[1]] uppery = [ylim[1], ylim[1]] self.upperslideline = self.ui.mainplot.plot(upperx, uppery, 'b--') lowerx = [xlim[0], xlim[1]] lowery = [ylim[0], ylim[0]] self.lowerslideline = self.ui.mainplot.plot(lowerx, lowery, 'g--') self.canvas.mpl_connect('button_press_event', self.on_mouseDownEvent) # Set up horizontal slide (integer) and string value self._leftSlideValue = 0 self._rightSlideValue = 99 self.ui.horizontalSlider.setRange(0, 100) self.ui.horizontalSlider.setValue(self._leftSlideValue) self.ui.horizontalSlider.setTracking(True) self.ui.horizontalSlider.setTickPosition(QSlider.NoTicks) self.ui.horizontalSlider.valueChanged.connect(self.move_leftSlider) self.ui.horizontalSlider_2.setRange(0, 100) self.ui.horizontalSlider_2.setValue(self._rightSlideValue) self.ui.horizontalSlider_2.setTracking(True) self.ui.horizontalSlider_2.setTickPosition(QSlider.NoTicks) self.ui.horizontalSlider_2.valueChanged.connect(self.move_rightSlider) # self.connect(self.ui.lineEdit_3, QtCore.SIGNAL("textChanged(QString)"), # self.set_startTime) self.ui.lineEdit_3.setValidator(QDoubleValidator(self.ui.lineEdit_3)) self.ui.pushButton_setT0.clicked.connect(self.set_startTime) # self.connect(self.ui.lineEdit_4, QtCore.SIGNAL("textChanged(QString)"), # self.set_stopTime) self.ui.lineEdit_4.setValidator(QDoubleValidator(self.ui.lineEdit_4)) self.ui.pushButton_setTf.clicked.connect(self.set_stopTime) # File loader self.scanEventWorkspaces() self.ui.pushButton_refreshWS.clicked.connect(self.scanEventWorkspaces) self.ui.pushButton_browse.clicked.connect(self.browse_File) self.ui.pushButton_load.clicked.connect(self.load_File) self.ui.pushButton_3.clicked.connect(self.use_existWS) # Set up time self.ui.lineEdit_3.setValidator(QDoubleValidator(self.ui.lineEdit_3)) self.ui.lineEdit_4.setValidator(QDoubleValidator(self.ui.lineEdit_4)) # Filter by time self.ui.pushButton_filterTime.clicked.connect(self.filterByTime) # Filter by log value self.ui.lineEdit_5.setValidator(QDoubleValidator(self.ui.lineEdit_5)) self.ui.lineEdit_6.setValidator(QDoubleValidator(self.ui.lineEdit_6)) self.ui.lineEdit_7.setValidator(QDoubleValidator(self.ui.lineEdit_7)) self.ui.lineEdit_8.setValidator(QDoubleValidator(self.ui.lineEdit_8)) self.ui.lineEdit_9.setValidator(QDoubleValidator(self.ui.lineEdit_9)) self.ui.lineEdit_5.textChanged.connect(self.set_minLogValue) self.ui.lineEdit_6.textChanged.connect(self.set_maxLogValue) dirchangeops = ["Both", "Increase", "Decrease"] self.ui.comboBox_4.addItems(dirchangeops) logboundops = ["Centre", "Left"] self.ui.comboBox_5.addItems(logboundops) self.ui.pushButton_4.clicked.connect(self.plotLogValue) self.ui.pushButton_filterLog.clicked.connect(self.filterByLogValue) # Set up help button self.ui.helpBtn.clicked.connect(self.helpClicked) # Set up vertical slide self._upperSlideValue = 99 self._lowerSlideValue = 0 self.ui.verticalSlider.setRange(0, 100) self.ui.verticalSlider.setValue(self._upperSlideValue) self.ui.verticalSlider.setTracking(True) self.ui.verticalSlider.valueChanged.connect(self.move_upperSlider) self.ui.verticalSlider_2.setRange(0, 100) self.ui.verticalSlider_2.setValue(self._lowerSlideValue) self.ui.verticalSlider_2.setTracking(True) self.ui.verticalSlider_2.valueChanged.connect(self.move_lowerSlider) # Set up for filtering (advanced setup) self._tofcorrection = False self.ui.checkBox_fastLog.setChecked(False) self.ui.checkBox_filterByPulse.setChecked(False) self.ui.checkBox_from1.setChecked(False) self.ui.checkBox_groupWS.setChecked(True) self.ui.comboBox_tofCorr.currentIndexChanged.connect(self.showHideEi) self.ui.pushButton_refreshCorrWSList.clicked.connect(self._searchTableWorkspaces) self.ui.lineEdit_Ei.setValidator(QDoubleValidator(self.ui.lineEdit_Ei)) self.ui.label_Ei.hide() self.ui.lineEdit_Ei.hide() self.ui.label_Ei_2.hide() self.ui.comboBox_corrWS.hide() self.ui.pushButton_refreshCorrWSList.hide() # Set up for workspaces self._dataWS = None self._sampleLogNames = [] self._sampleLog = None # Side information self.ui.label_mean.hide() self.ui.label_meanvalue.hide() self.ui.label_avg.hide() self.ui.label_timeAvgValue.hide() self.ui.label_freq.hide() self.ui.label_freqValue.hide() self.ui.label_logname.hide() self.ui.label_lognamevalue.hide() self.ui.label_logsize.hide() self.ui.label_logsizevalue.hide() # Default self._defaultdir = os.getcwd() # register startup mantid.UsageService.registerFeatureUsage("Interface", "EventFilter", False) def on_mouseDownEvent(self, event): """ Respond to pick up a value with mouse down event """ x = event.xdata y = event.ydata if x is not None and y is not None: msg = "You've clicked on a bar with coords:\n %f, %f" % (x, y) QMessageBox.information(self, "Click!", msg) def computeMock(self): """ Compute vecx and vecy as mocking """ x0 = 0. xf = 1. dx = 0.1 vecx = [] vecy = [] x = x0 while x < xf: y = 0.0 vecx.append(x) vecy.append(y) x += dx xlim = [x0, xf] ylim = [-1., 1] return (vecx, vecy, xlim, ylim) def move_leftSlider(self): """ Re-setup left range line in figure. Triggered by a change in Qt Widget. NO EVENT is required. """ newx = self.ui.horizontalSlider.value() if newx <= self._rightSlideValue and newx != self._leftSlideValue: # Allowed value: move the value bar self._leftSlideValue = newx # Move the vertical line xlim = self.ui.mainplot.get_xlim() newx = xlim[0] + newx*(xlim[1] - xlim[0])*0.01 leftx = [newx, newx] lefty = self.ui.mainplot.get_ylim() setp(self.leftslideline, xdata=leftx, ydata=lefty) self.canvas.draw() # Change value self.ui.lineEdit_3.setText(str(newx)) else: # Reset the value to original value self.ui.horizontalSlider.setValue(self._leftSlideValue) def set_startTime(self): """ Set the starting time and left slide bar """ inps = str(self.ui.lineEdit_3.text()) info_msg = "Starting time = %s" % (inps) Logger("Filter_Events").information(info_msg) xlim = self.ui.mainplot.get_xlim() if inps == "": # Empty. Use default newtime0 = xlim[0] else: newtime0 = float(inps) # Convert to integer slide value ileftvalue = int((newtime0-xlim[0])/(xlim[1] - xlim[0])*100) debug_msg = "iLeftSlide = %s" % str(ileftvalue) Logger("Filter_Events").debug(debug_msg) # Skip if same as origina if ileftvalue == self._leftSlideValue: return # Set the value if out of range resetT = True if ileftvalue < 0: # Minimum value as 0 ileftvalue = 0 elif ileftvalue > self._rightSlideValue: # Maximum value as right slide value ileftvalue = self._rightSlideValue else: resetT = False if resetT is True: newtime0 = xlim[0] + ileftvalue*(xlim[1]-xlim[0])*0.01 info_msg = 'Corrected iLeftSlide = {} (vs. right = {})'.format(ileftvalue, self._rightSlideValue) Logger("Filter_Events").information(info_msg) # Move the slide bar (left) self._leftSlideValue = ileftvalue # Move the vertical line leftx = [newtime0, newtime0] lefty = self.ui.mainplot.get_ylim() setp(self.leftslideline, xdata=leftx, ydata=lefty) self.canvas.draw() # Set the value to left slider self.ui.horizontalSlider.setValue(self._leftSlideValue) # Reset the value of line edit if resetT is True: self.ui.lineEdit_3.setText(str(newtime0)) def move_rightSlider(self): """ Re-setup left range line in figure. Triggered by a change in Qt Widget. NO EVENT is required. """ newx = self.ui.horizontalSlider_2.value() if newx >= self._leftSlideValue and newx != self._rightSlideValue: # Allowed value: move the value bar self._rightSlideValue = newx xlim = self.ui.mainplot.get_xlim() newx = xlim[0] + newx*(xlim[1] - xlim[0])*0.01 leftx = [newx, newx] lefty = self.ui.mainplot.get_ylim() setp(self.rightslideline, xdata=leftx, ydata=lefty) self.canvas.draw() # Change value self.ui.lineEdit_4.setText(str(newx)) else: # Reset the value self.ui.horizontalSlider_2.setValue(self._rightSlideValue) def set_stopTime(self): """ Set the starting time and left slide bar """ inps = str(self.ui.lineEdit_4.text()) Logger("Filter_Events").information('Stopping time = {}'.format(inps)) xlim = self.ui.mainplot.get_xlim() if inps == "": # Empty. Use default newtimef = xlim[1] else: # Parse newtimef = float(inps) # Convert to integer slide value irightvalue = int((newtimef-xlim[0])/(xlim[1] - xlim[0])*100) Logger("Filter_Events").information('iRightSlide = {}'.format(irightvalue)) # Return if no change if irightvalue == self._rightSlideValue: return # Correct value resetT = True if irightvalue > 100: irightvalue = 100 elif irightvalue < self._leftSlideValue: irightvalue = self._leftSlideValue else: resetT = False if resetT is True: newtimef = xlim[0] + irightvalue*(xlim[1]-xlim[0])*0.01 # Move the slide bar (right) self._rightSlideValue = irightvalue # Move the vertical line rightx = [newtimef, newtimef] righty = self.ui.mainplot.get_ylim() setp(self.rightslideline, xdata=rightx, ydata=righty) self.canvas.draw() # Set the value to left slider self.ui.horizontalSlider_2.setValue(self._rightSlideValue) # Reset to line edit if resetT: self.ui.lineEdit_4.setText(str(newtimef)) def move_lowerSlider(self): """ Re-setup upper range line in figure. Triggered by a change in Qt Widget. NO EVENT is required. """ inewy = self.ui.verticalSlider_2.value() debug_msg = 'LowerSlFider is set with value {} vs. class variable {}'.format(inewy, self._lowerSlideValue) Logger("Filter_Events").debug(debug_msg) # Return with no change if inewy == self._lowerSlideValue: # No change return if inewy >= self._upperSlideValue: # Out of upper range inewy = self._upperSlideValue - 1 if inewy == 0 and self._lowerSlideValue < 0: setLineEdit = False else: setLineEdit = True # Move the lower vertical bar ylim = self.ui.mainplot.get_ylim() newy = ylim[0] + inewy*(ylim[1] - ylim[0])*0.01 lowerx = self.ui.mainplot.get_xlim() lowery = [newy, newy] setp(self.lowerslideline, xdata=lowerx, ydata=lowery) self.canvas.draw() # Set line edit input if setLineEdit is True: # Change value to line edit (5) self.ui.lineEdit_5.setText(str(newy)) # Reset the class variable self._lowerSlideValue = inewy def set_minLogValue(self): """ Set the starting time and left slide bar """ debug_msg = 'Minimum Log Value = {}'.format(self.ui.lineEdit_5.text()) Logger("Filter_Events").debug(debug_msg) ylim = self.ui.mainplot.get_ylim() if str(self.ui.lineEdit_5.text()) == "": # Empty. Default to minY newminY = ylim[0] else: # Non empty. Parse newminY = float(self.ui.lineEdit_5.text()) # Convert to integer slide value iminlogval = int((newminY-ylim[0])/(ylim[1] - ylim[0])*100) Logger("Filter_Events").debug('ilowerSlide = {}'.format(iminlogval)) # Return if no change if iminlogval == self._lowerSlideValue: return # Set value if out of range resetL = True if iminlogval >= self._upperSlideValue: iminlogval = self._upperSlideValue - 1 else: resetL = False if resetL is True: newminY = ylim[0] + iminlogval * (ylim[1]-ylim[0]) * 0.01 # Move the vertical line lowerx = self.ui.mainplot.get_xlim() lowery = [newminY, newminY] setp(self.lowerslideline, xdata=lowerx, ydata=lowery) self.canvas.draw() # Move the slide bar (lower) self._lowerSlideValue = iminlogval debug_msg = 'LineEdit5 set slide to {}'.format(self._lowerSlideValue) Logger("Filter_Events").debug(debug_msg) self.ui.verticalSlider_2.setValue(self._lowerSlideValue) # Reset line Edit if using default if resetL is True: self.ui.lineEdit_5.setText(str(newminY)) def move_upperSlider(self): """ Re-setup upper range line in figure. Triggered by a change in Qt Widget. NO EVENT is required. """ inewy = self.ui.verticalSlider.value() # Return w/o change if inewy == self._upperSlideValue: return # Set to boundary value if inewy <= self._lowerSlideValue: inewy = self._lowerSlideValue + 1 # Reset line editor? if inewy == 100 and self._upperSlideValue > 100: setLineEdit = False else: setLineEdit = True # Move the upper value bar: upperx and uppery are # real value (float but not (0,100)) of the figure ylim = self.ui.mainplot.get_ylim() newy = ylim[0] + inewy*(ylim[1] - ylim[0])*0.01 upperx = self.ui.mainplot.get_xlim() uppery = [newy, newy] setp(self.upperslideline, xdata=upperx, ydata=uppery) self.canvas.draw() # Change value if setLineEdit is True: self.ui.lineEdit_6.setText(str(newy)) self._upperSlideValue = inewy def set_maxLogValue(self): """ Set maximum log value from line-edit """ inps = str(self.ui.lineEdit_6.text()) debug_msg = 'Maximum Log Value = {}'.format(inps) Logger("Filter_Events").debug(debug_msg) ylim = self.ui.mainplot.get_ylim() if inps == "": # Empty. Default to minY newmaxY = ylim[1] else: # Parse newmaxY = float(inps) # Convert to integer slide value imaxlogval = int((newmaxY-ylim[0])/(ylim[1] - ylim[0])*100) debug_msg = 'iUpperSlide = {}'.format(imaxlogval) Logger("Filter_Events").debug(debug_msg) # Return if no change if imaxlogval == self._upperSlideValue: return # Set to default if out of range resetL = True # if imaxlogval >= 100: # imaxlogval = 100 if imaxlogval < self._lowerSlideValue: imaxlogval = self._lowerSlideValue + 1 else: resetL = False # Set newmaxY if necessary if resetL is True: newmaxY = ylim[0] + imaxlogval * (ylim[1] - ylim[0]) * 0.01 # Move the vertical line upperx = self.ui.mainplot.get_xlim() uppery = [newmaxY, newmaxY] setp(self.upperslideline, xdata=upperx, ydata=uppery) self.canvas.draw() # Set the value to upper slider self._upperSlideValue = imaxlogval self.ui.verticalSlider.setValue(self._upperSlideValue) # Set the value to editor if necessary if resetL is True: self.ui.lineEdit_6.setText(str(newmaxY)) def browse_File(self): """ Open a file dialog to get file """ filename = QFileDialog.getOpenFileName(self, 'Input File Dialog', self._defaultdir, "Data (*.nxs *.dat);;All files (*)") if isinstance(filename, tuple): filename = filename[0] self.ui.lineEdit.setText(filename) Logger("Filter_Events").information('Selected file: "{}"'.format(filename)) def load_File(self): """ Load the file by file name or run number """ # Get file name from line editor filename = str(self.ui.lineEdit.text()) dataws = self._loadFile(str(filename)) if dataws is None: error_msg = 'Unable to locate run {} in default directory {}.'.format(filename, self._defaultdir) Logger("Filter_Events").error(error_msg) self._setErrorMsg(error_msg) else: self._importDataWorkspace(dataws) self._defaultdir = os.path.dirname(str(filename)) # Reset GUI self._resetGUI(resetfilerun=False) def use_existWS(self): """ Set up workspace to an existing one """ wsname = str(self.ui.comboBox.currentText()) try: dataws = AnalysisDataService.retrieve(wsname) self._importDataWorkspace(dataws) except KeyError: pass # Reset GUI self._resetGUI(resetfilerun=True) def plotLogValue(self): """ Plot log value """ # Get log value logname = str(self.ui.comboBox_2.currentText()) if len(logname) == 0: # return due to the empty one is chozen return samplelog = self._dataWS.getRun().getProperty(logname) vectimes = samplelog.times vecvalue = samplelog.value # check if len(vectimes) == 0: error_msg = "Empty log!" Logger("Filter_Events").error(error_msg) # Convert absolute time to relative time in seconds t0 = self._dataWS.getRun().getProperty("proton_charge").times[0] # append 1 more log if original log only has 1 value tf = self._dataWS.getRun().getProperty("proton_charge").times[-1] vectimes = numpy.append(vectimes, tf) vecvalue = numpy.append(vecvalue, vecvalue[-1]) vecreltimes = (vectimes - t0) / numpy.timedelta64(1, 's') # Set to plot xlim = [vecreltimes.min(), vecreltimes.max()] ylim = [vecvalue.min(), vecvalue.max()] self.ui.mainplot.set_xlim(xlim[0], xlim[1]) self.ui.mainplot.set_ylim(ylim[0], ylim[1]) setp(self.mainline, xdata=vecreltimes, ydata=vecvalue) samunit = samplelog.units if len(samunit) == 0: ylabel = logname else: ylabel = "%s (%s)" % (logname, samunit) self.ui.mainplot.set_ylabel(ylabel, fontsize=13) # assume that all logs are on almost same X-range. Only Y need to be reset setp(self.leftslideline, ydata=ylim) setp(self.rightslideline, ydata=ylim) # reset the log value limit as previous one does not make any sense setp(self.lowerslideline, xdata=xlim, ydata=[ylim[0], ylim[0]]) self._lowerSlideValue = 0 self.ui.verticalSlider_2.setValue(self._lowerSlideValue) self.ui.lineEdit_5.setText("") setp(self.upperslideline, xdata=xlim, ydata=[ylim[1], ylim[1]]) self._upperSlideValue = 100 self.ui.verticalSlider.setValue(self._upperSlideValue) self.ui.lineEdit_6.setText("") self.canvas.draw() # Load property's statistic and give suggestion on parallel and fast log timeavg = samplelog.timeAverageValue() numentries = samplelog.size() stat = samplelog.getStatistics() duration = stat.duration mean = stat.mean freq = float(numentries)/float(duration) self.ui.label_mean.show() self.ui.label_meanvalue.show() self.ui.label_avg.show() self.ui.label_timeAvgValue.show() self.ui.label_freq.show() self.ui.label_freqValue.show() self.ui.label_logname.show() self.ui.label_lognamevalue.show() self.ui.label_logsize.show() self.ui.label_logsizevalue.show() self.ui.label_meanvalue.setText("%.5e" % (mean)) self.ui.label_timeAvgValue.setText("%.5e" % (timeavg)) self.ui.label_freqValue.setText("%.5e" % (freq)) self.ui.label_lognamevalue.setText(logname) self.ui.label_logsizevalue.setText(str(numentries)) # Set suggested processing scheme if numentries > HUGE_FAST: self.ui.checkBox_fastLog.setCheckState(True) if numentries > HUGE_PARALLEL: self.ui.checkBox_doParallel.setCheckState(True) else: self.ui.checkBox_doParallel.setCheckState(False) else: self.ui.checkBox_fastLog.setCheckState(False) self.ui.checkBox_doParallel.setCheckState(False) return def _importDataWorkspace(self, dataws): """ Import data workspace for filtering """ if dataws is None: return # Plot time counts errmsg = self._plotTimeCounts(dataws) if errmsg is not None: errmsg = 'Workspace {} has invalid sample logs for splitting. Loading \ failure! \n{}\n'.format(dataws, errmsg) self._setErrorMsg(errmsg) return False # Import log self._sampleLogNames = [""] run = dataws.getRun() plist = run.getProperties() for p in plist: try: times = p.times if len(times) > 1 and numpy.isreal(p.value[0]): self._sampleLogNames.append(p.name) # This is here for FloatArrayProperty. If a log value is of this type it does not have times except AttributeError: pass # ENDFOR(p) # Set up sample log self.ui.comboBox_2.clear() self.ui.comboBox_2.addItems(self._sampleLogNames) # Side information self.ui.label_mean.hide() self.ui.label_meanvalue.hide() self.ui.label_avg.hide() self.ui.label_timeAvgValue.hide() self.ui.label_freq.hide() self.ui.label_freqValue.hide() # Hide 'log name' above the graphic view self.ui.label_logname.hide() self.ui.label_lognamevalue.hide() # Set dataws to class variable self._dataWS = dataws return True def scanEventWorkspaces(self): """ """ wsnames = AnalysisDataService.getObjectNames() eventwsnames = [] for wsname in wsnames: wksp = AnalysisDataService.retrieve(wsname) if wksp.__class__.__name__.count("Event") == 1: eventwsnames.append(wsname) # ENDFOR if len(eventwsnames) > 0: self.ui.comboBox.clear() self.ui.comboBox.addItems(eventwsnames) def _loadFile(self, filename): """ Load file or run File will be loaded to a workspace shown in MantidPlot """ config = ConfigService # Check input file name and output workspace name if filename.isdigit() is True: # Construct a file name from run number runnumber = int(filename) if runnumber <= 0: error_msg = 'Run number cannot be less or equal to zero. User gives {}.'.format(filename) Logger("Filter_Events").error(error_msg) return None else: ishort = config.getInstrument(self._instrument).shortName() filename = '{}_{}'.format(ishort, filename) wsname = filename + "_event" elif filename.count(".") > 0: # A proper file name wsname = os.path.splitext(os.path.split(filename)[1])[0] elif filename.count("_") == 1: # A short one as instrument_runnumber iname = filename.split("_")[0] str_runnumber = filename.split("_")[1] if str_runnumber.isdigit() is True and int(str_runnumber) > 0: # Accepted format ishort = config.getInstrument(iname).shortName() wsname = '{}_{}_event'.format(ishort, str_runnumber) else: # Non-supported error_msg = 'File name / run number in such format {} is not supported.'.format(filename) Logger("Filter_Events").error(error_msg) return None else: # Unsupported format error_msg = 'File name / run number in such format {} is not supported.'.format(filename) Logger("Filter_Events").error(error_msg) return None # Load try: ws = api.Load(Filename=filename, OutputWorkspace=wsname) except RuntimeError as e: ws = None return str(e) return ws def _plotTimeCounts(self, wksp): """ Plot time/counts """ import datetime # Rebin events by pulse time try: # Get run start and run stop if wksp.getRun().hasProperty("run_start"): runstart = wksp.getRun().getProperty("run_start").value else: runstart = wksp.getRun().getProperty("proton_charge").times[0] runstop = wksp.getRun().getProperty("proton_charge").times[-1] runstart = str(runstart).split(".")[0].strip() runstop = str(runstop).split(".")[0].strip() t0 = datetime.datetime.strptime(runstart, "%Y-%m-%dT%H:%M:%S") tf = datetime.datetime.strptime(runstop, "%Y-%m-%dT%H:%M:%S") # Calculate dt = tf-t0 timeduration = dt.days*3600*24 + dt.seconds timeres = float(timeduration)/MAXTIMEBINSIZE if timeres < 1.0: timeres = 1.0 sumwsname = '_Summed_{}'.format(wksp) if AnalysisDataService.doesExist(sumwsname) is False: sumws = api.SumSpectra(InputWorkspace=wksp, OutputWorkspace=sumwsname) sumws = api.RebinByPulseTimes(InputWorkspace=sumws, OutputWorkspace=sumwsname, Params='{}'.format(timeres)) sumws = api.ConvertToPointData(InputWorkspace=sumws, OutputWorkspace=sumwsname) else: sumws = AnalysisDataService.retrieve(sumwsname) except RuntimeError as e: return str(e) vecx = sumws.readX(0) vecy = sumws.readY(0) xmin = min(vecx) xmax = max(vecx) ymin = min(vecy) ymax = max(vecy) # Reset graph self.ui.mainplot.set_xlim(xmin, xmax) self.ui.mainplot.set_ylim(ymin, ymax) self.ui.mainplot.set_xlabel('Time (seconds)', fontsize=13) self.ui.mainplot.set_ylabel('Counts', fontsize=13) # Set up main line setp(self.mainline, xdata=vecx, ydata=vecy) # Reset slide newslidery = [min(vecy), max(vecy)] newleftx = xmin + (xmax-xmin)*self._leftSlideValue*0.01 setp(self.leftslideline, xdata=[newleftx, newleftx], ydata=newslidery) newrightx = xmin + (xmax-xmin)*self._rightSlideValue*0.01 setp(self.rightslideline, xdata=[newrightx, newrightx], ydata=newslidery) self.canvas.draw() def filterByTime(self): """ Filter by time """ # Generate event filters kwargs = {} if self.ui.lineEdit_3.text() != "": rel_starttime = float(self.ui.lineEdit_3.text()) kwargs["StartTime"] = str(rel_starttime) if self.ui.lineEdit_4.text() != "": rel_stoptime = float(self.ui.lineEdit_4.text()) kwargs["StopTime"] = str(rel_stoptime) if self.ui.lineEdit_timeInterval.text() != "": interval = float(self.ui.lineEdit_timeInterval.text()) kwargs["TimeInterval"] = interval splitwsname = str(self._dataWS) + "_splitters" splitinfowsname = str(self._dataWS) + "_info" title = str(self.ui.lineEdit_title.text()) fastLog = self.ui.checkBox_fastLog.isChecked() splitws, infows = api.GenerateEventsFilter(InputWorkspace=self._dataWS, UnitOfTime="Seconds", TitleOfSplitters=title, OutputWorkspace=splitwsname, FastLog=fastLog, InformationWorkspace=splitinfowsname, **kwargs) self.splitWksp(splitws, infows) def filterByLogValue(self): """ Filter by log value """ # Generate event filter kwargs = {} samplelog = str(self.ui.comboBox_2.currentText()) if len(samplelog) == 0: error_msg = "No sample log is selected!" Logger("Filter_Events").error(error_msg) return if self.ui.lineEdit_3.text() != "": rel_starttime = float(self.ui.lineEdit_3.text()) kwargs["StartTime"] = str(rel_starttime) if self.ui.lineEdit_4.text() != "": rel_stoptime = float(self.ui.lineEdit_4.text()) kwargs["StopTime"] = str(rel_stoptime) if self.ui.lineEdit_5.text() != "": minlogvalue = float(self.ui.lineEdit_5.text()) kwargs["MinimumLogValue"] = minlogvalue if self.ui.lineEdit_6.text() != "": maxlogvalue = float(self.ui.lineEdit_6.text()) kwargs["MaximumLogValue"] = maxlogvalue if self.ui.lineEdit_7.text() != "": logvalueintv = float(self.ui.lineEdit_7.text()) kwargs["LogValueInterval"] = logvalueintv logvalchangedir = str(self.ui.comboBox_4.currentText()) kwargs["FilterLogValueByChangingDirection"] = logvalchangedir if self.ui.lineEdit_9.text() != "": logvalueintv = float(self.ui.lineEdit_9.text()) kwargs["TimeTolerance"] = logvalueintv logboundtype = str(self.ui.comboBox_5.currentText()) kwargs["LogBoundary"] = logboundtype if self.ui.lineEdit_8.text() != "": logvaluetol = float(self.ui.lineEdit_8.text()) kwargs["LogValueTolerance"] = logvaluetol splitwsname = str(self._dataWS) + "_splitters" splitinfowsname = str(self._dataWS) + "_info" fastLog = self.ui.checkBox_fastLog.isChecked() title = str(self.ui.lineEdit_title.text()) splitws, infows = api.GenerateEventsFilter(InputWorkspace=self._dataWS, UnitOfTime="Seconds", TitleOfSplitters=title, OutputWorkspace=splitwsname, LogName=samplelog, FastLog=fastLog, InformationWorkspace=splitinfowsname, **kwargs) try: self.splitWksp(splitws, infows) except RuntimeError as e: self._setErrorMsg("Splitting Failed!\n %s" % (str(e))) def splitWksp(self, splitws, infows): """ Run FilterEvents """ dogroupws = self.ui.checkBox_groupWS.isChecked() filterbypulse = self.ui.checkBox_filterByPulse.isChecked() startfrom1 = self.ui.checkBox_from1.isChecked() splitsamplelog = self.ui.checkBox_splitLog.isChecked() corr2sample = str(self.ui.comboBox_tofCorr.currentText()) how2skip = str(self.ui.comboBox_skipSpectrum.currentText()) kwargs = {} if corr2sample == "Direct": ei = float(self.ui.lineEdit_Ei.text()) kwargs["IncidentEnergy"] = ei elif corr2sample == "Customized": corrws = str(self.ui.comboBox_corrWS.currentText()) kwargs["DetectorTOFCorrectionWorkspace"] = corrws # Output workspace name outbasewsname = str(self.ui.lineEdit_outwsname.text()) if len(outbasewsname) == 0: outbasewsname = "tempsplitted" self.ui.lineEdit_outwsname.setText(outbasewsname) api.FilterEvents(InputWorkspace=self._dataWS, SplitterWorkspace=splitws, InformationWorkspace=infows, OutputWorkspaceBaseName=outbasewsname, GroupWorkspaces=dogroupws, FilterByPulseTime=filterbypulse, CorrectionToSample=corr2sample, SpectrumWithoutDetector=how2skip, SplitSampleLogs=splitsamplelog, OutputWorkspaceIndexedFrom1=startfrom1, OutputTOFCorrectionWorkspace='TOFCorrTable', **kwargs) def showHideEi(self): """ """ corrtype = str(self.ui.comboBox_tofCorr.currentText()) # Incident energy if corrtype == "Direct": self.ui.label_Ei.show() self.ui.lineEdit_Ei.show() else: self.ui.label_Ei.hide() self.ui.lineEdit_Ei.hide() # Workspace if corrtype == "Customized": self.ui.label_Ei_2.show() self.ui.comboBox_corrWS.show() self.ui.pushButton_refreshCorrWSList.show() # Search for table workspace self._searchTableWorkspaces() else: self.ui.label_Ei_2.hide() self.ui.comboBox_corrWS.hide() self.ui.pushButton_refreshCorrWSList.hide() def _searchTableWorkspaces(self): """ Search table workspaces and add to 'comboBox_corrWS' """ wsnames = AnalysisDataService.getObjectNames() tablewsnames = [] for wsname in wsnames: wksp = AnalysisDataService.retrieve(wsname) if isinstance(wksp, mantid.api.ITableWorkspace): tablewsnames.append(wsname) # ENDFOR self.ui.comboBox_corrWS.clear() if len(tablewsnames) > 0: self.ui.comboBox_corrWS.addItems(tablewsnames) def _setErrorMsg(self, errmsg): """ Clear error message """ self._errMsgWindow = QMessageBox() self._errMsgWindow.setIcon(QMessageBox.Critical) self._errMsgWindow.setWindowTitle('Error') self._errMsgWindow.setStandardButtons(QMessageBox.Ok) self._errMsgWindow.setText(errmsg) result = self._errMsgWindow.exec_() return result def helpClicked(self): try: from pymantidplot.proxies import showCustomInterfaceHelp showCustomInterfaceHelp("Filter Events") except ImportError: url = ("http://docs.mantidproject.org/nightly/interfaces/{}.html" "".format("Filter Events")) QDesktopServices.openUrl(QUrl(url)) def _resetGUI(self, resetfilerun=False): """ Reset GUI including all text edits and etc. """ if resetfilerun is True: self.ui.lineEdit.clear() # Plot related self.ui.lineEdit_3.clear() self.ui.lineEdit_4.clear() self.ui.horizontalSlider.setValue(0) self.ui.horizontalSlider_2.setValue(100) self.ui.lineEdit_outwsname.clear() self.ui.lineEdit_title.clear() # Filter by log value self.ui.lineEdit_5.clear() self.ui.lineEdit_6.clear() self.ui.verticalSlider_2.setValue(0) self.ui.verticalSlider.setValue(100) ylim = self.ui.mainplot.get_ylim() miny = ylim[0] maxy = ylim[1] xlim = self.ui.mainplot.get_xlim() setp(self.lowerslideline, xdata=xlim, ydata=[miny, miny]) setp(self.upperslideline, xdata=xlim, ydata=[maxy, maxy]) self.ui.lineEdit_7.clear() self.ui.lineEdit_8.clear() self.ui.lineEdit_9.clear() # Filter by time self.ui.lineEdit_timeInterval.clear() # Advanced setup self.ui.comboBox_tofCorr.setCurrentIndex(0) self.ui.lineEdit_Ei.clear() self.ui.checkBox_fastLog.setCheckState(False) self.ui.checkBox_doParallel.setCheckState(False) self.ui.comboBox_skipSpectrum.setCurrentIndex(0) self.ui.checkBox_filterByPulse.setCheckState(False) self.ui.checkBox_from1.setCheckState(False) self.ui.checkBox_groupWS.setCheckState(True) self.ui.checkBox_splitLog.setCheckState(False) self.canvas.draw()
def errormessage(self, message): msg = QMessageBox() msg.setText(str(message)) msg.setStandardButtons(QMessageBox.Ok) msg.exec_()