Git Product home page Git Product logo

typhos's Introduction

Typhos

Automated User Interface Creation from Ophyd Devices

EPICS is a flexible and powerful controls system that gives access to experimental information, however, the relation and meaning of process variables is often obscure. Many of the user interfaces for EPICS information reflect this, as walls of buttons and flashing lights bombard the user with little thought to structure or cohesion.

Typhos addresses this by providing an automated way to generate screens based on a provided hierarchy of devices and signals. Built using PyDM, a PyQt based display manager developed at SLAC National Laboratory, Typhos utilizes a large toolkit of widgets to display EPICS information. For each process variable, a corresponding widget is created based on; the importance to the average operator, the type of value the EPICS PV will return, and whether a user should be allowed to write to the variable. These widgets are then placed in a convenient tab-based system to only show the necessary information for basic function, but still allow access to more advanced signals.

Instead of reinventing a new way to specify device structures, Typhos uses Ophyd, a library to abstract EPICS information into consistently structured Python objects. Originally built for scripting experimental procedures at NSLSII, Ophyd represents devices as combinations of components which are either signals or nested devices. Then, either at runtime or by using the defaults of the representative Python class, these signals are sorted into different categories based on their relevance to operators. Typhos uses this information to craft user interfaces.

Installation

Recommended installation on Linux:

conda install typhos -c conda-forge -c pcds-tag

All -tag channels have -dev counterparts for bleeding edge installations. Both requirements.txt and optional dev-requirements.txt are kept up to date as well for those who prefer installation via pip

typhos utilizes PyDM's designer widget entrypoints. This means that if you have PyDM working correctly with the Qt Designer, typhos widgets will also be available. No further customization or environment settings are required.

happi is an optional dependency but is recommended. This must be installed manually if not using the CONDA recipe.

Qt Installation

There have been some observed inconsistencies between installations of Qt available on pip, defaults and conda-forge. It is recommended that if you want to use the full typhos feature to install via conda-forge. We have found this the most reliable, especially when it comes to using the QtDesigner. It is worth noting that since this library uses qtpy as an interface layer to the various options for Qt Python bindings, the bare requirements will not install a specific one for you. The testing suite runs using PyQt5.

Getting Started

Creating your first typhos panel for anophyd.Device only takes two lines:

import sys
from ophyd.sim import motor
from qtpy.QtWidgets import QApplication
import typhos

# Create our application
app = QApplication.instance() or QApplication(sys.argv)
typhos.use_stylesheet()  # Optional
suite = typhos.TyphosSuite.from_device(motor)

# Launch
suite.show()
app.exec_()

Available Widgets

Typhos has three major building blocks that combine into the final display seen by the operator:

  • TyphosSuite: The overall view for a Typhos window. It allows the operator to view all of the loaded components and tools

  • TyphosDeviceDisplay: This is the widget created for a standard ophyd.Device. Signals are organized based on their Kind and description.

  • typhos.tools: These are widgets that interface with external applications. While you may have other GUIs for these systems, typhos.tools are built especially to handle the handshaking between all the information stored on your device and the tool you are interfacing with. This saves your operator clicks and ensures consistency in use.

Initialization Pattern

All three of the widgets listed above share a similar API for creation. Instantiating the object by itself handles loading the container widgets and placing them in the correct place, but these do not accept ophyd.Device arguments. The reason for this is to ensure that we can use all of the typhos screens as templates, and regardless or not of whether you have an ophyd.Device you can always populate the screens by hand. If you do in fact have an ophyd.Device every class has an add_device method and alternatively and be constructed using the from_device classmethod.

Related Projects

PyDM - PyQT Display Manager for EPICS information

Ophyd - Device abstraction for Experimental Control

typhos's People

Contributors

anleslac avatar canismarko avatar hhslepicka avatar klauer avatar nrwslac avatar tacaswell avatar tangkong avatar zllentz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

typhos's Issues

PositionerBase Screens

Expected Behavior

Ophyd Devices that inherit from PositionerBase should have a special screen made for them.

Current Behavior

These are currently treated as regular devices, even though we know much more about them.

Possible Solution

Have a subclass of DeviceDisplay called PositionerDisplay that uses the same format, but also includes all the parameters of the PositionerBase

Command Recognition

Expected Behavior

There should be a way to detect if a PV is a command or not. For instance something like the motor record .TWF should not be a QComboBox. This should be represented by a QPushButton.

Current Behavior

If it has enum_strs it will make a QComboBox, otherwise it will make a QLineEdit

Possible Solution

Detect this is a command, make a QPushButton.

Device Display Refactor

Expected Behavior

Currently there is an assumption that you give the DeviceDisplay a single device and the entire widget is automatically generated. We should convert this to a classmethod and have the base device display be a little more passive. This allows a user to add arbitrary devices to the screen even if they are not technically part of the same Ophyd device

Current Behavior

A single device is ripped apart and added to the display in __init__

Possible Solution

This should be converted to a classmethod. The __init__ statement should do much less. Have a way to set the main device once, as well as adding the correct sub devices

Add functions to existing TabWidget

Expected Behavior

Instead of creating a new "Panel" with methods on these should go in the same tab that has the configuration and miscellaneous PVs.

Allow Python properties to be be shown in the UI

Expected Behavior

A widget that was capable of polling a Python variable and broadcasting changes to the screen. Just like we currently support add_pv and add_signal, we could support add_property. This would not be done automatically, but would be specified by the user similar to methods.

Current Behavior

Not supported

Possible Solution

The simplest solution seems to make a PyDM py:// plugin if it does not exist.

Enum Inputs to functions

Expected Behavior

Display a QComboBox to allow control of Enum type function parameters

Possible Solution

If we find an Enum in the function signature. Take the values and make a QComboBox that has the same ducktyping interface ParamLineEdit, ParamCheckBox

Nuanced Control of Sub-Devices

Expected Behavior

Right now, there are simple buttons that allow access to the subdevices. This could be a fancier panel that displays the hints of each subdevice.

Current Behavior

QPushButton changes the index of QStackedWidget

Possible Solution

Vertical layout of automatically generated miniature device widgets, when one is clicked the subdevice screen is raised in the QStackedWidget.

SignalPlugin should handle enum_strs

Expected Behavior

Generic Ophyd signals can have enum_strs as well. We should make sure we send these to PyDM to make proper use of QComboBox e.t.c

QtConsole Tool

Expected Behavior

Add a QtConsole Typhon Tool for a shell inside your GUI. Maybe automatically have some objects populated there (like a RunEngine)

Create QSS file

Expected Behavior

Typhon will have a custom stylesheet. This should be specfied in qss format and will live in the ui directory.

Save generated user interfaces

Expected Behavior

Save the automatically generated user interfaces to disk. This allows for later access without having to instantiate an ophyd devices.

Possible Solution

Since the Panel class rips out the PV names and uses them directly, these can be saved as is. However, all the function references will need to be wiped clean. Later, we could imagine a way that an ophyd device can be reinstantiated (maybe through a subclass of TyphonApplication`. However, this not necessary for the first prototype

Plot Tool

A PyDMTimePlot where you can add and remove channels.

RunEngine Widget

Expected Behavior

Basci RunEngine control.

  • Start / Stop / Pause
  • Displays current state

Typhon Designer Plugin

Expected Behavior

Create a Typhon Designer Plugin so that the DeviceDisplay can be used in a drag and drop editor.

Current Behavior

Widgets are not available in Designer

Possible Solution

Typhon Designer Plugin that takes an Ophyd plugin specification for each widget

Testing IOC

Expected Behavior

We should create a testing IOC. This way we can see what our screens look like with connected widgets. This can either be in caproto or pcaspy

Current Behavior

Tests run on disconnected widgets

Device Widget

Complete device widget that displays read_attrs, configuration_attrs in shrinkable panels

SignalDisplay

Base widget to display an EpicsSignal or EpicsSignalRO

Inclusion of Renderings

Expected Behavior

Be able to display CAD renderings next to devices. Each subdevice could show a more indepth view of the system

Current Behavior

No images displayed

Possible Solution

Add device has a kwarg that allows you to pass in the path to a png file.

PyDMComboBox for PVs with enum_strs

Expected Behavior

Create a PyDMComboBox based on the enum_strs of a given write pv

Current Behavior

Currently, a PyDMLineEdit is provided which is awkward for enum PVs

Possible Solution

Check if a PV has enum_strs, if so create a PyDMComboBox, otherwise create a PyDMLineEdit

SignalPlugin

Expected Behavior

A plugin that uses Ophyd's subscription system to connect to the standard PyDMChannel slots. The channel will be specified with sig://{signal_type}/{args}/{kwargs}.

Current Behavior

Signals are examined and then the pvnames are ripped out of them and stuffed in channel access.

Context

The current setup precludes the ability to display any other kind of signal. It also depends on the API of which ever Ophyd control_layer you choose to use. We should keep the abstraction at the Ophyd layer and not make assumptions about the control_layer underneath.

Class Based Display

Expected Behavior

Often we will want to create a display that can be reused for all devices of the same class. typhon should be capable of creating a static ui file that can be then reloaded with arbitrary macros identical to the kwargs of the original class.

Current Behavior

Currently only previously instantiated Ophyd objects can be used.

Possible Solution

Create a screen with a dummy device with macros substituted in for important args and kwargs, then save this as a UI file

Function Display

Create a PushButton and fields in order to allow an arbitrary Python function to be run by the UI

EpicsSignal Assumption

Expected Behavior

Breaks with signals that do not derive from EpicsSignalBase.

Current Behavior

The automated widget creation assumes that all signals will have _read_pv and _write_pv attributes.

Possible Solution

Either just have a PyDM Signal plugin #38 or be more intelligent about checking for signal types.

Add PV not EpicsSignal

Expected Behavior

Add a PV or a combination of read and write pvs to the SignalPanel. Right now this is only done via an EpicsSignal. Instead, the add_signal function should call add_pv with the correct arguments.

Current Behavior

Currently you can only provide and EpicsSignal object. This will limit users who want to use typhon, but not necessarily be limited to what is in their ophyd objects

Possible Solution

Create a function that looks like

def add_pv(self, read_pv, write_pv=None, enum=False):

That is eventually called by add_signal

ReadPanel

Panel to display read attributes with a PyDMPlot where a user can select which values to plot

Replace main plot with PyDMDrawingImage

Abandon the idea of the single rotating image for different subcomponents. Instead just have a small image embedded in the main DeviceDisplay if desired by the user.

Reconfigure Component Selection

Currently we make ugly little embedded widgets for subcomponents. This should be a cleaner indexed list that is more extendable for tools e.t.c

Panel

Base panel to display an arbitrary set of signals in a grid. Correct widgets should be chosen based on whether widget is read-only, has a separate read and write pvs, e.t.c

Tests should have some form of mock pvs

Expected Behavior

We should have some form of mock_pvs available. Currently there are a few sections in typhon where I check if a PV is connected. Typhon should not care. They are only there so that functions work offline which is not a requirement.

Current Behavior

We check if pv.connected before important function calls

Possible Solution

Use some combination of using_fake_epics_pv and maybe a caproto IOC. The ladder would be more difficult, but probably more beneficial to the development process in general.

Logging Interface

Expected Behavior

Create a standard widget to display log stream. This could ideally be configured to go to the terminal, display in the widget or write to disk. The user should also have the option to change the logging configuration from within the UI itself.

Possible Solution

Ideally this is just a drop down menu standard on all screens. This might even be worth a PR directly into PyDM? This way it could be a menu item on the PyDMMainWindow

Scrollbar on DeviceDisplay TabWidget

Description

The tabbed widget in the DeviceDisplay should be a fixed size and instead have a vertical scrollbar if the widget size exceeds the vertical space.

Ophyd Plugin

Expected Behavior

Create a PyDM Ophyd Plugin

Current Behavior

No ophyd plugin available

Possible Solution

Specify an ophyd device class, args and kwargs in the channel anme then create the DeviceDisplay with the proper instantiated device behind it.

Unify Signal to Channel Conversion

There are a few places where we have signals and want to quickly grab the channel that would spawn them. This is implemented slightly different when we need write_pv and depending on what type of signal. This should be standardized across the library.

Display return value of functions in displays

Expected Behavior

Display the result of the last function call in the UI. This could also watch for ophyd Status objects and change window colors based on completion of the method

Possible Solution

If the function signature tells us that it will return a value that can be displayed (int, float, str), place a label in the FunctionDisplay that shows the output of the function. This can even be extended to include any objects that have a reasonable __str__ method

Documentation

Sphinx documentation with:

  • README explaining motivation and examples
  • General description of we use the different attribute categories
  • More in-depth description on how to use the function generation

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.