Utility Functions

Utility functions for typhos

class typhos.utils.DeviceConnectionMonitorThread(device, include_lazy=False, **kwargs)[source]

Monitor connection status in a background thread

Parameters:
  • device (ophyd.Device) – The device to grab signals from

  • include_lazy (bool, optional) – Include lazy signals as well

connection_update

Connection update signal with signature:

(signal, connected, metadata_dict)
Type:

QtCore.Signal

run(self)[source]
stop(*, wait_ms: int = 1000)[source]

Stop the background thread and clean up.

Parameters:

wait_ms (int, optional) – Time to wait for the background thread to exit. Set to 0 to disable.

class typhos.utils.GrabKindItem(attr, component, signal)
attr

Alias for field number 0

component

Alias for field number 1

signal

Alias for field number 2

class typhos.utils.ObjectConnectionMonitorThread(objects=None, **kwargs)[source]

Monitor connection status in a background thread

connection_update

Connection update signal with signature:

(signal, connected, metadata_dict)
Type:

QtCore.Signal

run(self)[source]
stop(*, wait_ms: int = 1000)[source]

Stop the background thread and clean up.

Parameters:

wait_ms (int, optional) – Time to wait for the background thread to exit. Set to 0 to disable.

class typhos.utils.ThreadPoolWorker(func, *args, **kwargs)[source]

Worker thread helper

Parameters:
  • func (callable) – The function to call during run()

  • *args – Arguments for the function call

  • **kwargs – Keyword rarguments for the function call

run(self)[source]
class typhos.utils.TyphosBase(*args, **kwargs)[source]

Base widget for all Typhos widgets that interface with devices

class typhos.utils.TyphosLoading(timeout_message, *, parent=None, **kwargs)[source]

A QLabel with an animation for loading status.

LOADING_TIMEOUT_MS

The timeout value in milliseconds for when to stop the animation and replace it with a default timeout message.

Type:

int

contextMenuEvent(self, ev: QContextMenuEvent)[source]
class typhos.utils.WeakPartialMethodSlot(signal_owner: QObject, signal: pyqtSignal, method: method, *args, **kwargs)[source]

A PyQt-compatible slot for a partial method.

This utility handles deleting the connection when the method class instance gets garbage collected. This avoids cycles in the garbage collector that would prevent the instance from being garbage collected prior to the program exiting.

Parameters:
  • signal_owner (QtCore.QObject) – The owner of the signal.

  • signal (QtCore.Signal) – The signal instance itself.

  • method (instance method) – The method slot to call when the signal fires.

  • *args – Arguments to pass to the method.

  • **kwargs – Keyword arguments to pass to the method.

typhos.utils.apply_standard_stylesheets(dark: bool = False, paths: Iterable[str] | None = None, include_pydm: bool = True, widget: QtWidgets.QWidget | None = None) None[source]

Apply all the stylesheets at once, along with the Fusion style.

Applies stylesheets with the following priority order: - Any existing stylesheet data on the widget - User stylesheets in the paths argument - User stylesheets in PYDM_STYLESHEET (which behaves as a path) - Typhos’s stylesheet (either the dark or the light variant) - PyDM’s built-in stylesheet, if PYDM_STYLESHEET_INCLUDE_DEFAULT is set.

The Fusion style can only be applied to a QApplication.

Parameters:
  • dark (bool, optional) – Whether or not to use the QDarkStyleSheet theme. By default the light theme is chosen.

  • paths (iterable of str, optional) – User-provided paths to stylesheets to apply.

  • include_pydm (bool, optional) – Whether or not to use the stylesheets defined in the pydm environment variables. Defaults to True.

  • widget (QWidget, optional) – The widget to apply the stylesheet to. If omitted, apply to the whole QApplication.

typhos.utils.channel_from_signal(signal, read=True)[source]

Create a PyDM address from arbitrary signal type

typhos.utils.channel_name(pv, protocol='ca')[source]

Create a valid PyDM channel from a PV name

typhos.utils.clean_attr(attr)[source]

Create a nicer, human readable alias from a Python attribute name

typhos.utils.clean_name(device, strip_parent=True)[source]

Create a human readable name for a device

Parameters:
  • device (ophyd.Device) –

  • strip_parent (bool or Device) – Remove the parent name of the device from name. If strip_parent is True, the name of the direct parent of the device is stripped. If a device is provided the name of that device is used. This allows specification for removal at any point of the device schema

typhos.utils.clear_layout(layout)[source]

Clear a QLayout

typhos.utils.code_from_device(device)[source]

Generate code required to load device in another process

typhos.utils.code_from_device_repr(device)[source]

Return code to create a device from its repr information.

Parameters:

device (ophyd.Device) –

typhos.utils.compose_stylesheets(stylesheets: Iterable[str | pathlib.Path]) str[source]

Combine multiple qss stylesheets into one qss stylesheet.

If two stylesheets make conflicting specifications, the one passed into this function first will take priority.

This is accomplished by placing the text from the highest-priority stylesheets at the bottom of the combined stylesheet. Stylesheets are evaluated in order from top to bottom, and newer elements on the bottom will override elements at the top.

Parameters:

stylesheets (iterable of str or pathlib.Path) – An itetable, such as a list, of the stylesheets to combine. Each element can either be a fully-loaded stylesheet or a full path to a stylesheet. Stylesheet paths must end in the .qss suffix. In the unlikely event that a string is both a valid path and a valid stylesheet, it will be interpretted as a path, even if no file exists at that path.

Returns:

composed_style – A string suitable for passing into QWidget.setStylesheet that incorporates all of the input stylesheets.

Return type:

str

Raises:
  • OSError – If any error is encountered while reading a file

  • TypeError – If the input is not a valid type

typhos.utils.connection_status_monitor(*signals, callback)[source]

[Context manager] Monitor connection status from a number of signals

Filters out any other metadata updates, only calling once connected/disconnected

Parameters:
  • *signals (ophyd.OphydObj) – Signals to monitor

  • callback (callable) – Callback to run, with same signature as that of ophyd.OphydObj.subscribe(). obj and connected are guaranteed kwargs.

typhos.utils.dump_grid_layout(layout, rows=None, cols=None, *, cell_width=60)[source]

Dump the layout of a QtWidgets.QGridLayout to file.

Parameters:
  • layout (QtWidgets.QGridLayout) – The layout

  • rows (int) – Number of rows to iterate over

  • cols (int) – Number of columns to iterate over

Returns:

table – The text for the summary table

Return type:

str

typhos.utils.find_file_in_paths(filename, *, paths=None)[source]

Search for filename filename in the list of paths paths

Parameters:
  • filename (str or pathlib.Path) – The filename

  • paths (list or iterable, optional) – List of paths to search. Defaults to DISPLAY_PATHS.

Yields:

All filenames that match in the given paths

typhos.utils.find_parent_with_class(widget, cls=<class 'PyQt5.QtWidgets.QWidget'>)[source]

Finds the first parent of a widget that is an instance of klass

Parameters:
  • widget (QWidget) – The widget from which to start the search

  • cls (type, optional) – The class which the parent must be an instance of

typhos.utils.find_templates_for_class(cls, view_type, paths, *, extensions=None, include_mro=True)[source]

Given a class cls and a view type (such as ‘detailed’), search paths for potential templates to show.

Parameters:
  • cls (class) – Search for templates with this class name

  • view_type ({'detailed', 'engineering', 'embedded'}) – The view type

  • paths (iterable) – Iterable of paths to be expanded, de-duplicated, and searched

  • extensions (str or list, optional) – The template filename extension (default is '.ui' or '.py')

  • include_mro (bool, optional) – Include superclasses - those in the MRO - of cls as well

Yields:

path (pathlib.Path) – A matching path, ordered from most-to-least specific.

typhos.utils.flatten_tree(param)[source]

Flatten a tree of parameters

typhos.utils.get_all_signals_from_device(device, include_lazy=False, filter_by=None)[source]

Get all signals in a given device

Parameters:
  • device (ophyd.Device) – ophyd Device to monitor

  • include_lazy (bool, optional) – Include lazy signals as well

  • filter_by (callable, optional) – Filter signals, with signature callable(ophyd.Device.ComponentWalk)

typhos.utils.get_component(obj)[source]

Get the component that made the given object.

Parameters:

obj (ophyd.OphydItem) – The ophyd item for which to get the component.

Returns:

component – The component, if available.

Return type:

ophyd.Component

typhos.utils.get_device_from_fake_class(cls)[source]

Return the non-fake class, given a fake class

That is:

fake_cls = ophyd.sim.make_fake_device(cls)
get_device_from_fake_class(fake_cls)  # -> cls
Parameters:

cls (type) – The fake class

typhos.utils.get_variety_metadata(cpt)[source]

Get “variety” metadata from a component or signal.

Parameters:

cpt (ophyd.Component or ophyd.OphydItem) – The component / ophyd item to get the metadata for.

Returns:

metadata – The metadata, if set. Otherwise an empty dictionary. This metadata is guaranteed to be valid according to the known schemas.

Return type:

dict

typhos.utils.is_fake_device_class(cls)[source]

Is cls a fake device from ophyd.sim.make_fake_device()?

typhos.utils.is_signal_ro(signal)[source]

Return whether the signal is read-only, based on its class.

In the future this may be easier to do through improvements to introspection in the ophyd library. Until that day we need to check classes

typhos.utils.is_standard_template(template)[source]

Is the template a core one provided with typhos?

Parameters:

template (str or pathlib.Path) –

Registers the signal with PyDM, and sets the widget channel.

Parameters:
  • signal (ophyd.OphydObj) – The signal to use.

  • widget (QtWidgets.QWidget) – The widget with which to connect the signal.

typhos.utils.linked_attribute(property_attr, widget_attr, hide_unavailable=False)[source]

Decorator which connects a device signal with a widget.

Retrieves the signal from the device, registers it with PyDM, and sets the widget channel.

Parameters:
  • property_attr (str) – This is one level of indirection, allowing for the component attribute to be configurable by way of designable properties. In short, this looks like: getattr(self.device, getattr(self, property_attr)) The component attribute name may include multiple levels (e.g., 'cpt1.cpt2.low_limit').

  • widget_attr (str) – The attribute name of the widget, referenced from self. The component attribute name may include multiple levels (e.g., 'ui.low_limit').

  • hide_unavailable (bool) – Whether or not to hide widgets for which the device signal is not available

typhos.utils.load_suite(path, cfg=None)[source]

” Load a file saved via Typhos

Parameters:
  • path (str) – Path to file describing the TyphosSuite. This needs to be of the format created by the save_suite() function.

  • cfg (str, optional) – Location of happi configuration file to use to load devices. If not entered the $HAPPI_CFG environment variable will be used.

Returns:

suite

Return type:

TyphosSuite

typhos.utils.make_identifier(name)[source]

Make a Python string into a valid Python identifier

typhos.utils.no_device_lazy_load()[source]

Context manager which disables the ophyd.device.Device lazy_wait_for_connection behavior and later restore its value.

typhos.utils.nullcontext()[source]

Stand-in for py3.7’s contextlib.nullcontext

typhos.utils.patch_connect_slots()[source]

Patches QtCore.QMetaObject.connectSlotsByName to catch SystemErrors.

typhos.utils.pyqt_class_from_enum(enum)[source]

Create an inheritable base class from a Python Enum, which can also be used for Q_ENUMS.

typhos.utils.raise_window(widget)[source]

Bring a widget’s window into focus and on top of the window stack.

If the window is minimized, unminimize it.

Different window managers respond differently to the various methods called here, the chosen sequence was intended for good behavior on as many systems as possible.

typhos.utils.random_color()[source]

Return a random hex color description

typhos.utils.reload_widget_stylesheet(widget, cascade=False)[source]

Reload the stylesheet of the provided widget

typhos.utils.remove_duplicate_items(list_)[source]

Return a de-duplicated list/tuple of items in list_, retaining order

typhos.utils.save_suite(suite, file_or_buffer)[source]

Create a file capable of relaunching the TyphosSuite

Parameters:
  • suite (TyphosSuite) –

  • file_or_buffer (str or file-like) – Either a path to the file or a handle that supports write

typhos.utils.subscription_context(*objects, callback, event_type=None, run=True)[source]

[Context manager] Subscribe to a specific event from all objects

Unsubscribes all signals before exiting

Parameters:
  • *objects (ophyd.OphydObj) – Ophyd objects (signals) to monitor

  • callback (callable) – Callback to run, with same signature as that of ophyd.OphydObj.subscribe().

  • event_type (str, optional) – The event type to subscribe to

  • run (bool, optional) – Run the previously cached subscription immediately

typhos.utils.subscription_context_device(device, callback, event_type=None, run=True, *, include_lazy=False, filter_by=None)[source]

[Context manager] Subscribe to event_type from signals in device

Unsubscribes all signals before exiting

Parameters:
  • device (ophyd.Device) – ophyd Device to monitor

  • callback (callable) – Callback to run, with same signature as that of ophyd.OphydObj.subscribe()

  • event_type (str, optional) – The event type to subscribe to

  • run (bool, optional) – Run the previously cached subscription immediately

  • include_lazy (bool, optional) – Include lazy signals as well

  • filter_by (callable, optional) – Filter signals, with signature callable(ophyd.Device.ComponentWalk)

typhos.utils.use_stylesheet(dark: bool = False, widget: QtWidgets.QWidget | None = None) None[source]

Use the Typhos stylesheet

This is no longer used directly in typhos in favor of apply_standard_stylesheets.

This can still be used if you want the legacy behavior of ignoring PyDM environment variables. The function is unchanged.

Parameters:

dark (bool, optional) – Whether or not to use the QDarkStyleSheet theme. By default the light theme is chosen.

typhos.utils.widget_to_image(widget, fill_color=19)[source]

Paint the given widget in a new QtGui.QImage.

Returns:

The display, as an image.

Return type:

QtGui.QImage

Cache Utilities

Path caching

typhos.cache.get_global_display_path_cache()[source]

Get the _GlobalDisplayPathCache singleton.

class typhos.cache._GlobalDisplayPathCache[source]

A cache for all configured display paths.

All paths from utils.DISPLAY_PATHS will be included:
  1. Environment variable PYDM_DISPLAYS_PATH.

  2. Typhos package built-in paths.

add_path(path)[source]

Add a path to be searched during glob.

Parameters:

path (pathlib.Path or str) – The path to add.

update()[source]

Force a reload of all paths in the cache.

Ophyd Object Description Caching

typhos.cache.get_global_describe_cache()[source]

Get the _GlobalDescribeCache singleton.

class typhos.cache._GlobalDescribeCache[source]

Cache of ophyd object descriptions.

obj.describe() is called in a thread from the global QThreadPool, and new results are marked by the Signal new_description.

To access a description, call get(). If available, it will be returned immediately. Otherwise, wait for the new_description Signal.

connect_thread

The thread which monitors connection status.

Type:

ObjectConnectionMonitorThread

cache

The cache holding descriptions, keyed on obj.

Type:

dict

clear()[source]

Clear the cache.

get(obj)[source]

To access a description, call this method. If available, it will be returned immediately. Otherwise, upon connection and successful describe() call, the new_description Signal will be emitted.

Parameters:

obj (ophyd.OphydObj) – The object to get the description of.

Returns:

desc – If available in the cache, the description will be returned.

Return type:

dict or None

Ophyd Object to Widget Type Cache

typhos.cache.get_global_widget_type_cache()[source]

Get the _GlobalWidgetTypeCache singleton.

class typhos.cache._GlobalWidgetTypeCache[source]

Cache of ophyd object Typhos widget types.

obj.describe() is called using _GlobalDescribeCache and are therefore threaded and run in the background. New results are marked by the Signal widgets_determined.

To access a set of widget types, call get(). If available, it will be returned immediately. Otherwise, wait for the widgets_determined Signal.

describe_cache

The describe cache, used for determining widget types.

Type:

_GlobalDescribeCache

cache

The cache holding widget type information. Keyed on obj, the values are SignalWidgetInfo tuples.

Type:

dict

clear()[source]

Clear the cache.

get(obj)[source]

To access widget types, call this method. If available, it will be returned immediately. Otherwise, upon connection and successful describe() call, the widgets_determined Signal will be emitted.

Parameters:

obj (ophyd.OphydObj) – The object to get the widget types.

Returns:

desc – If available in the cache, the information will be returned.

Return type:

SignalWidgetInfo or None