Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

'queue-monitor' app: add menu items to save plan history to local file #195

Merged
merged 4 commits into from
Mar 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .github/workflows/isort.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Check Code Style - ISORT

on: [push, pull_request]

jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
- name: Install Dependencies
run: |
# These packages are installed in the base environment but may be older
# versions. Explicitly upgrade them because they often create
# installation problems if out of date.
python -m pip install --upgrade pip setuptools numpy

pip install isort
- name: Run ISort
run: |
isort . -c
5 changes: 5 additions & 0 deletions .isort.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[settings]
line_length = 115
multi_line_output = 3
include_trailing_comma = True
profile = black
2 changes: 1 addition & 1 deletion bluesky_widgets/_matplotlib_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import logging

from .models.plot_specs import Axes, Line, Image
from .models.plot_specs import Axes, Image, Line


class MatplotlibAxes:
Expand Down
2 changes: 1 addition & 1 deletion bluesky_widgets/apps/queue_monitor/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

from bluesky_widgets.qt import gui_qt

from .viewer import Viewer
from .settings import SETTINGS
from .viewer import Viewer


def main(argv=None):
Expand Down
48 changes: 45 additions & 3 deletions bluesky_widgets/apps/queue_monitor/viewer.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import os

from qtpy.QtWidgets import QAction, QFileDialog

from bluesky_widgets.models.run_engine_client import RunEngineClient
from bluesky_widgets.qt import Window

from .widgets import QtViewer
from .settings import SETTINGS

from qtpy.QtWidgets import QAction
from .widgets import QtViewer


class ViewerModel:
Expand Down Expand Up @@ -32,6 +34,8 @@ def __init__(self, *, show=True, title="Demo App"):
# TODO Where does title thread through?
super().__init__()

self._work_dir = os.path.expanduser("~")

self._widget = QtViewer(self)
self._window = Window(self._widget, show=show)

Expand All @@ -43,6 +47,17 @@ def __init__(self, *, show=True, title="Demo App"):
self.action_activate_env_destroy.triggered.connect(self._activate_env_destroy_triggered)
menu_item_control.addAction(self.action_activate_env_destroy)

menu_item_save = menu_bar.addMenu("Save and Backup")
self.action_save_history_as_txt = QAction("Save Plan History (as .txt)", self._window._qt_window)
self.action_save_history_as_txt.triggered.connect(self._save_history_as_txt_triggered)
menu_item_save.addAction(self.action_save_history_as_txt)
self.action_save_history_as_json = QAction("Save Plan History (as .json)", self._window._qt_window)
self.action_save_history_as_json.triggered.connect(self._save_history_as_json_triggered)
menu_item_save.addAction(self.action_save_history_as_json)
self.action_save_history_as_yaml = QAction("Save Plan History (as .yaml)", self._window._qt_window)
self.action_save_history_as_yaml.triggered.connect(self._save_history_as_yaml_triggered)
menu_item_save.addAction(self.action_save_history_as_yaml)

self._widget.model.run_engine.events.status_changed.connect(self.on_update_widgets)

def _update_action_env_destroy_state(self):
Expand All @@ -53,6 +68,33 @@ def _activate_env_destroy_triggered(self):
env_destroy_activated = self._widget.model.run_engine.env_destroy_activated
self._widget.model.run_engine.activate_env_destroy(not env_destroy_activated)

def _save_history_as_txt_triggered(self):
self._save_history_to_file("txt")

def _save_history_as_json_triggered(self):
self._save_history_to_file("json")

def _save_history_as_yaml_triggered(self):
self._save_history_to_file("yaml")

def _save_history_to_file(self, file_format):
try:
fln_pattern = f"{file_format.upper()} (*.{file_format.lower()});; All (*)"
file_path_init = os.path.join(self._work_dir, "plan_history." + file_format.lower())
file_path_tuple = QFileDialog.getSaveFileName(
self._widget, "Save Plan History to File", file_path_init, fln_pattern
)
file_path = file_path_tuple[0]
if file_path:
file_path = file_path_tuple[0]
self._work_dir = os.path.dirname(file_path)
self._widget.model.run_engine.save_plan_history_to_file(
file_path=file_path, file_format=file_format
)
print(f"Plan history was successfully saved to file {file_path!r}")
except Exception as ex:
print(f"Failed to save data to file: {ex}")

def on_update_widgets(self, event):
self._update_action_env_destroy_state()

Expand Down
24 changes: 9 additions & 15 deletions bluesky_widgets/apps/queue_monitor/widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,21 @@
Extendeding and supplementing the widgets import bluesky-widgets
"""

from qtpy.QtCore import Qt
from qtpy.QtWidgets import QFrame, QHBoxLayout, QSplitter, QTabWidget, QVBoxLayout, QWidget

from bluesky_widgets.qt.run_engine_client import (
QtReConsoleMonitor,
QtReEnvironmentControls,
QtReManagerConnection,
QtReQueueControls,
QtReExecutionControls,
QtReStatusMonitor,
QtRePlanQueue,
QtReManagerConnection,
QtRePlanEditor,
QtRePlanHistory,
QtRePlanQueue,
QtReQueueControls,
QtReRunningPlan,
QtRePlanEditor,
QtReConsoleMonitor,
)
from qtpy.QtWidgets import (
QWidget,
QHBoxLayout,
QVBoxLayout,
QTabWidget,
QFrame,
QSplitter,
QtReStatusMonitor,
)
from qtpy.QtCore import Qt


class QtOrganizeQueueWidgets(QSplitter):
Expand Down
18 changes: 8 additions & 10 deletions bluesky_widgets/examples/advanced/qt_viewer_with_search.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,16 @@
python -m bluesky_widgets.examples.advanced.qt_viewer_with_search localhost:XXXXX
"""

from bluesky_widgets.qt import Window
from bluesky_widgets.qt import gui_qt
from bluesky_widgets.models.search import SearchList, Search
from qtpy.QtWidgets import QHBoxLayout, QPushButton, QVBoxLayout, QWidget

from bluesky_widgets.examples.utils.add_search_mixin import columns
from bluesky_widgets.examples.utils.generate_msgpack_data import get_catalog
from bluesky_widgets.models.auto_plot_builders import AutoLines
from bluesky_widgets.qt.search import QtSearches
from bluesky_widgets.models.search import Search, SearchList
from bluesky_widgets.qt import Window, gui_qt
from bluesky_widgets.qt.figures import QtFigures
from bluesky_widgets.qt.search import QtSearches
from bluesky_widgets.utils.event import Event
from bluesky_widgets.examples.utils.generate_msgpack_data import get_catalog
from bluesky_widgets.examples.utils.add_search_mixin import columns
from qtpy.QtWidgets import QWidget, QPushButton, QHBoxLayout, QVBoxLayout


class SearchListWithButton(SearchList):
Expand Down Expand Up @@ -121,9 +121,7 @@ def main(argv):
# Optional: Receive live streaming data.
if len(argv) > 1:
from bluesky_widgets.qt.zmq_dispatcher import RemoteDispatcher
from bluesky_widgets.utils.streaming import (
stream_documents_into_runs,
)
from bluesky_widgets.utils.streaming import stream_documents_into_runs

address = argv[1]
dispatcher = RemoteDispatcher(address)
Expand Down
15 changes: 8 additions & 7 deletions bluesky_widgets/examples/advanced/qt_with_RE_worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,17 @@
python -m bluesky_widgets.examples.advanced.qt_with_RE_worker tcp://localhost:60615 localhost:5578
""" # noqa E501

from bluesky_widgets.utils.streaming import stream_documents_into_runs
from bluesky_widgets.qt.zmq_dispatcher import RemoteDispatcher
from bluesky_widgets.models.plot_builders import Lines
from bluesky_widgets.qt.figures import QtFigure
from bluesky_widgets.qt import gui_qt
import sys
import time

from bluesky_queueserver.manager.comms import ZMQCommSendThreads
from bluesky_queueserver_api._defaults import default_user_group

import sys
import time
from bluesky_widgets.models.plot_builders import Lines
from bluesky_widgets.qt import gui_qt
from bluesky_widgets.qt.figures import QtFigure
from bluesky_widgets.qt.zmq_dispatcher import RemoteDispatcher
from bluesky_widgets.utils.streaming import stream_documents_into_runs


def main():
Expand Down
8 changes: 4 additions & 4 deletions bluesky_widgets/examples/headless_figures.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@

from bluesky import RunEngine
from bluesky.plans import scan
from ophyd.sim import motor, det
from ophyd.sim import det, motor

from bluesky_widgets.utils.streaming import stream_documents_into_runs
from bluesky_widgets.models.auto_plot_builders import AutoLines
from bluesky_widgets.headless.figures import HeadlessFigures
from bluesky_widgets.examples.utils.generate_msgpack_data import get_catalog
from bluesky_widgets.headless.figures import HeadlessFigures
from bluesky_widgets.models.auto_plot_builders import AutoLines
from bluesky_widgets.utils.streaming import stream_documents_into_runs

model = AutoLines(max_runs=3)
view = HeadlessFigures(model.figures)
Expand Down
6 changes: 3 additions & 3 deletions bluesky_widgets/examples/ipy_qt_figure.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@

from bluesky import RunEngine
from bluesky.plans import scan
from ophyd.sim import motor, det
from ophyd.sim import det, motor

from bluesky_widgets.utils.streaming import stream_documents_into_runs
from bluesky_widgets.examples.utils.generate_msgpack_data import get_catalog
from bluesky_widgets.models.plot_builders import Lines
from bluesky_widgets.qt.figures import QtFigure
from bluesky_widgets.examples.utils.generate_msgpack_data import get_catalog
from bluesky_widgets.utils.streaming import stream_documents_into_runs

model = Lines("motor", ["det"], max_runs=3)
view = QtFigure(model.figure)
Expand Down
6 changes: 3 additions & 3 deletions bluesky_widgets/examples/ipy_qt_figures.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@

from bluesky import RunEngine
from bluesky.plans import scan
from ophyd.sim import motor, det
from ophyd.sim import det, motor

from bluesky_widgets.utils.streaming import stream_documents_into_runs
from bluesky_widgets.examples.utils.generate_msgpack_data import get_catalog
from bluesky_widgets.models.auto_plot_builders import AutoLines
from bluesky_widgets.qt.figures import QtFigures
from bluesky_widgets.examples.utils.generate_msgpack_data import get_catalog
from bluesky_widgets.utils.streaming import stream_documents_into_runs

model = AutoLines(max_runs=3)
view = QtFigures(model.figures)
Expand Down
2 changes: 1 addition & 1 deletion bluesky_widgets/examples/jupyter_viewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
python -m bluesky_widgets.examples.qt_viewer_with_search localhost:XXXXX
"""

from bluesky_widgets.models.auto_plot_builders import AutoLines
from bluesky_widgets.jupyter.figures import JupyterFigures
from bluesky_widgets.models.auto_plot_builders import AutoLines


class ExampleApp:
Expand Down
6 changes: 3 additions & 3 deletions bluesky_widgets/examples/kafka_figures.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,18 @@
directory. The filepaths will be printed to the stdout, one per line.
"""

from functools import partial
import os
import tempfile
from functools import partial

import msgpack
import msgpack_numpy as mpn
from bluesky_kafka import RemoteDispatcher

from bluesky_widgets.utils.streaming import stream_documents_into_runs
from bluesky_widgets.models.plot_builders import AutoLines
from bluesky_widgets.headless.figures import HeadlessFigures
from bluesky_widgets.models.plot_builders import AutoLines
from bluesky_widgets.models.utils import run_is_live_and_not_completed
from bluesky_widgets.utils.streaming import stream_documents_into_runs


def export_thumbnails_when_complete(run):
Expand Down
4 changes: 2 additions & 2 deletions bluesky_widgets/examples/napari_dock_widgets.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import napari
from qtpy.QtWidgets import QPushButton, QVBoxLayout, QWidget

from bluesky_widgets.examples.utils.add_search_mixin import extract_results_row_from_run
from bluesky_widgets.examples.utils.generate_msgpack_data import get_catalog
from bluesky_widgets.examples.utils.get_run_images import generate_thumbnail
from bluesky_widgets.models.search import Search, SearchList
from bluesky_widgets.utils.event import Event
from qtpy.QtWidgets import QWidget, QPushButton, QVBoxLayout
from bluesky_widgets.qt.search import QtSearches
from bluesky_widgets.utils.event import Event


class SearchListWithButton(SearchList):
Expand Down
23 changes: 10 additions & 13 deletions bluesky_widgets/examples/pyFAI_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,12 @@
__date__ = "21/01/2020"
__status__ = "production"

import datetime
import logging
import os
import sys
import datetime
from argparse import ArgumentParser

import logging

logging.basicConfig(level=logging.INFO)
logging.captureWarnings(True)
logger = logging.getLogger(__name__)
Expand All @@ -57,10 +56,10 @@

logger_uncaught = logging.getLogger("pyFAI-calib2.UNCAUGHT")

import pyFAI.resources
import pyFAI.calibrant
import pyFAI.detectors
import pyFAI.io.image
import pyFAI.resources
from pyFAI.io.ponifile import PoniFile

try:
Expand Down Expand Up @@ -568,10 +567,9 @@ def setup_model(model, options):
args = options.args

# The module must not import the GUI
from pyFAI.gui.utils import units

# TODO: This should be removed
import pyFAI.gui.cli_calibration
from pyFAI.gui.utils import units

# Settings
settings = model.experimentSettingsModel()
Expand Down Expand Up @@ -793,8 +791,8 @@ def setup_model(model, options):

if options.npt:
try:
from pyFAI.gui.helper import model_transform
from pyFAI.control_points import ControlPoints
from pyFAI.gui.helper import model_transform

controlPoints = ControlPoints(filename=options.npt)
peakSelectionModel = model.peakSelectionModel()
Expand Down Expand Up @@ -842,8 +840,8 @@ def main():

# Make sure matplotlib is loaded first by silx
import silx.gui.plot.matplotlib
from pyFAI.gui.CalibrationWindow import CalibrationWindow
from pyFAI.gui.CalibrationContext import CalibrationContext
from pyFAI.gui.CalibrationWindow import CalibrationWindow

sys.excepthook = logUncaughtExceptions
if options.qtargs is None:
Expand All @@ -863,13 +861,12 @@ def main():

# Begin modifications for bluesky_widgets

from qtpy.QtWidgets import QDialog
from qtpy.QtWidgets import QAction, QDialog, QHBoxLayout, QPushButton, QVBoxLayout, QWidget

from bluesky_widgets.examples.utils.add_search_mixin import columns
from bluesky_widgets.examples.utils.generate_msgpack_data import get_catalog
from bluesky_widgets.models.search import Search
from bluesky_widgets.qt.search import QtSearch
from bluesky_widgets.examples.utils.generate_msgpack_data import get_catalog
from bluesky_widgets.examples.utils.add_search_mixin import columns

from qtpy.QtWidgets import QAction, QHBoxLayout, QPushButton, QVBoxLayout, QWidget

example_catalog = get_catalog()

Expand Down
Loading
Loading