Skip to content

Commit

Permalink
Merge pull request #195 from dmgav/save-history
Browse files Browse the repository at this point in the history
'queue-monitor' app: add menu items to save plan history to local file
  • Loading branch information
dmgav authored Mar 18, 2024
2 parents d8e940e + f405a9c commit 08b98c2
Show file tree
Hide file tree
Showing 65 changed files with 311 additions and 273 deletions.
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

0 comments on commit 08b98c2

Please sign in to comment.