nspyre.gui.widgets

Submodules

Package Contents

Classes

ExperimentWidget

Qt widget for automatically generating a GUI for a simple experiment.

FlexLinePlotWidget

Qt widget for flexible plotting of 1D user data.

HeatMapWidget

Qt widget for displaying 2D data using pyqtgraph ImageView.

LinePlotWidget

Qt widget that generates a pyqtgraph 1D line plot with some reasonable default settings and a variety of added features.

MainWidget

Qt widget for loading other QWidgets.

MainWidgetItem

Represents an arbitrary QWidget that can be loaded from the MainWidget.

ParamsWidget

Qt widget containing a set of GUI elements for the user to enter experiment parameters into.

SaveLoadWidget

Qt widget that transfers data (with optional modifications) between the

QHLine

Qt widget that displays a horizontal line.

QVLine

Qt widget that displays a vertical line.

sssss

Qt widget that displays the nspyre logo.

Functions

experiment_widget_process_queue(msg_queue)

Reads messages sent/received to/from a multiprocessing Queue by ExperimentWidget.

nspyre.gui.widgets.experiment_widget_process_queue(msg_queue)

Reads messages sent/received to/from a multiprocessing Queue by ExperimentWidget.

Parameters:

msg_queue – multiprocessing Queue object.

Returns:

The message received from the experiment subprocess.

Return type:

Optional[str]

class nspyre.gui.widgets.ExperimentWidget(params_config, module, cls, fun_name, constructor_args=None, constructor_kwargs=None, fun_args=None, fun_kwargs=None, title=None, kill=False, layout=None)

Qt widget for automatically generating a GUI for a simple experiment. Parameters can be entered by the user in a ParamsWidget. Buttons are generated for the user to run, stop, and kill the experiment process.

Parameters:
  • params_config (dict) – Dictionary that is passed to the constructor of ParamsWidget.

  • module (types.ModuleType) – Python module that contains cls.

  • cls (str) – Python class name as a string. An instance of this class will be created in a subprocess when the user presses the ‘Run’ button. The __enter__ and __exit__ methods will be called if implemented. In addition, if the class constructor takes keyword arguments queue_to_exp and/or queue_from_exp, multiprocessing Queue objects will be passed in that can be used to communicate with the GUI.

  • fun_name (str) – Name of function within cls to run. All of the values from the ParamsWidget will be passed as keyword arguments to this function.

  • constructor_args (Optional[list]) – Args to pass to cls.

  • constructor_kwargs (Optional[dict]) – Keyword arguments to pass to cls.

  • fun_args (Optional[list]) – Args to pass to cls.fun.

  • fun_kwargs (Optional[dict]) – Keyword arguments to pass to cls.fun.

  • title (Optional[str]) – Window title.

  • kill (bool) – Add a kill button to allow the user to forcibly kill the subprocess running the experiment function.

  • layout (pyqtgraph.Qt.QtWidgets.QLayout) – Additional Qt layout to place between the parameters and run/stop/kill buttons.

queue_to_exp: multiprocessing.Queue

multiprocessing Queue to pass to the experiment subprocess and use for sending messages to the subprocess.

queue_from_exp: multiprocessing.Queue

multiprocessing Queue to pass to the experiment subprocess and use for receiving messages from the subprocess.

additional_run_kwargs()

Users can override this function to provide additional kwargs to the experiment function. It is called when the user clicks the ‘Run’ button.

Returns:

A dict containing any additional kwargs to be passed to the experiment function.

Return type:

Dict

run()

Run the experiment function in a subprocess.

stop(log=True)

Request the experiment subprocess to stop by sending the string stop to queue_to_exp.

Parameters:

log (bool) – if True, log when stop is called but the process isn’t running.

kill()

Kill the experiment subprocess.

class nspyre.gui.widgets.FlexLinePlotWidget(timeout=1, data_processing_func=None, init_kwargs=None, add_plot_kwargs=None)

Qt widget for flexible plotting of 1D user data. It connects to an arbitrary data set stored in the DataServer, collects and processes the data, and offers a variety of user-controlled plotting options.

The user should push a dictionary containing the following key/value pairs to the corresponding DataSource object sourcing data to the DataServer:

  • key: title, value: Plot title string

  • key: xlabel, value: X label string

  • key: ylabel, value: Y label string

  • key: data_series, value: Dictionary where keys are a data series name, and values are data as a list of 2D numpy arrays of shape (2, n). The two rows represent the x and y axes, respectively, of the plot, and the n columns each represent a data point.

You may use np.NaN values in the data arrays to represent invalid entries, which won’t contribute to the data averaging. An example is given below:

from nspyre import DataSource, StreamingList

with DataSource('my_dataset') as ds:
    channel_1_data = StreamingList([np.array([[1, 2, 3], [12, 12.5, 12.25]]), np.array([[4, 5, 6], [12.6, 13, 11.2]])])
    channel_2_data = StreamingList([np.array([[1, 2, 3], [3, 3.3, 3.1]]), np.array([[4, 5, 6], [3.4, 3.6, 3.5]])])
    my_plot_data = {
        'title': 'MyVoltagePlot',
        'xlabel': 'Time (s)',
        'ylabel': 'Amplitude (V)',
        'data_series': {
            'channel_1': channel_1_data
            'channel_2': channel_2_data
        }
    }
    ds.push(my_plot_data)
Parameters:
  • timeout (float) – Timeout for pop().

  • data_processing_func (Optional[Callable]) – Function to do any post-processing of the data popped by the DataSink. Takes one argument, which is the DataSink.

  • init_kwargs (Optional[Dict]) – Keyword arguments to pass to the underlying LinePlotWidget init method.

  • add_plot_kwargs (Optional[Dict]) – Keyword arguments to pass to the underlying add_plot() method.

line_plot

Underlying LinePlotWidget.

add_plot(name, series, scan_i, scan_j, processing)

Add a new subplot. Thread safe.

Parameters:
  • name (str) – Name for the new plot.

  • series (str) – The data series name pushed by the DataSource, e.g. channel_1 for the example given in FlexLinePlotWidget

  • scan_i (str) – String value of the scan to start plotting from.

  • scan_j (str) –

    String value of the scan to stop plotting at. Use Python list indexing notation, e.g.:

    • scan_i = '-1', scan_j = '' for the last element

    • scan_i = '0', scan_j = '1' for the first element

    • scan_i = '-3', scan_j = '' for the last 3 elements.

  • processing (str) – ‘Average’ to average the x and y values of scans i through j, ‘Append’ to concatenate them.

remove_plot(name)

Remove a subplot. Thread safe.

Parameters:

name (str) – Name of the subplot.

hide_plot(name)

Hide a subplot. Thread safe.

Parameters:

name (str) – Name of the subplot.

show_plot(name)

Show a previously hidden subplot. Thread safe.

Parameters:

name (str) – Name of the subplot.

class nspyre.gui.widgets.HeatMapWidget(*args, title='', btm_label='', lft_label='', colormap=None, font=nspyre_font, **kwargs)

Qt widget for displaying 2D data using pyqtgraph ImageView.

Parameters:
  • title (str) – Plot title.

  • btm_label (str) – Plot bottom axis label.

  • lft_label (str) – Plot left axis label.

  • colormap – pyqtgraph ColorMap object.

  • font (pyqtgraph.Qt.QtGui.QFont) – Font to use in the plot title, axis labels, etc., although the font type may not be fully honored.

new_data

Qt Signal emitted when new data is available.

setup()

Subclasses should override this function to perform any setup code.

update()

Subclasses should override this function to update the plot. This function will be run in a separate Thread.

teardown()

Subclasses should override this function to perform any teardown code.

set_data(xs, ys, data, zs=None)

Queue up x,y,z and data to update the color map. Threadsafe.

Parameters:
  • name – Name of the plot.

  • xs – Array-like of data for the x-axis.

  • ys – Array-like of data for the y-axis.

  • data – 2D or 3D array with the data to be plotted. For a 2D imge, data’s rows should correspond to the y-axis and the columns should correspond to the x-axis. Moreover, xs should be the same length as the number of columns of data, and ys should be the same length as the number of rows of data. This way, when the widget attempts to display the pixel at (x, y), it looks for it in data[y][x]. In the case of a 3D array, the z-axis information should be in the last index, so that the pixel at (x, y, z) is stored in data[y][x][z].

  • zs – Optional array-like of data for the z-axis.

Raises:

ValueError – An error with the supplied arguments.

class nspyre.gui.widgets.LinePlotWidget(*args, title='', xlabel='', ylabel='', font=nspyre_font, legend=True, plot_colors=None, downsample=True, **kwargs)

Qt widget that generates a pyqtgraph 1D line plot with some reasonable default settings and a variety of added features.

Parameters:
  • args – passed to the QWidget init, like super().__init__(*args, **kwargs)

  • title (str) – Plot title.

  • xlabel (str) – Plot x-axis label.

  • ylabel (str) – Plot y-axis label.

  • font (pyqtgraph.Qt.QtGui.QFont) – Font to use in the plot title, axis labels, etc., although the font type may not be fully honored.

  • legend (bool) – If True, display a figure legend.

  • plot_colors (Optional[Any]) – Colors as a list of RGB tuples in the range 0-1 as used by matplotlib.

  • downsample (bool) – If True, utilize the pyqtgraph ‘auto’ downsampling in the ‘mean’ mode (see PlotItem docs).

  • kwargs – passed to the QWidget init, like super().__init__(*args, **kwargs)

plot_widget

pyqtgraph PlotWidget for displaying the plot.

plot_item()

Return the pyqtgraph PlotItem.

set_title(title)

Set the plot title.

Parameters:

title (str) – The new plot title.

setup()

Subclasses should override this function to perform any setup code before the update() function is called from a new thread.

update()

Subclasses should override this function to update the plot. This function will be called repeatedly from a new thread.

teardown()

Subclasses should override this function to perform any teardown code. The thread calling update() isn’t guaranteed to have exited yet.

add_plot(name, pen=None, symbolBrush=(255, 255, 255, 100), symbolPen=(255, 255, 255, 100), symbol='o', symbolSize=3, **kwargs)

Add a new plot to the PlotWidget. Thread safe.

Parameters:
remove_plot(name)

Remove a plot from the display and delete it’s associated data. Thread safe.

Parameters:

name (str) – Name of the plot.

clear_plots()

Remove all plots and delete their associated data. Thread safe.

hide_plot(name)

Remove a plot from the display, keeping its data. Thread safe.

Parameters:

name (str) – Name of the plot.

show_plot(name)

Display a previously hidden plot. Thread safe.

Parameters:

name (str) – Name of the plot.

set_data(name, xdata, ydata, blocking=True)

Queue up x/y data to update a line plot. Thread safe.

Parameters:
  • name (str) – Name of the plot.

  • xdata (Any) – Array-like of data for the x-axis.

  • ydata (Any) – Array-like of data for the y-axis.

  • blocking (bool) – Whether this method should block until the data has been plotted.

class nspyre.gui.widgets.MainWidget(widgets, font_size='18px')

Qt widget for loading other QWidgets. It displays a hierarchy of widgets for the user to select and launch, and a pyqtgraph DockArea where they are displayed. The widgets dictionary passed to __init__ can contain sub-dictionaries in order to group widgets together.

Typical usage example:

import my_module
import nspyre
from nspyre import nspyreApp
from nspyre import MainWidget
from nspyre import MainWidgetItem

# Create Qt application and apply nspyre visual settings.
app = nspyreApp()

# Create the GUI.
main_widget = MainWidget({
    'Experiments': {
        'ODMR': MainWidgetItem(my_module, 'ODMRWidget'),
    },
    'Plot': MainWidgetItem(nspyre.gui.widgets.flex_line_plot, 'FlexLinePlotWidget'),
    'Data': {
        'Save': MainWidgetItem(nspyre.gui.widgets.save_widget, 'SaveWidget'),
        'Load': MainWidgetItem(nspyre.gui.widgets.load_widget, 'LoadWidget'),
    }
})
main_widget.show()
# Run the GUI event loop.
app.exec()
Parameters:
  • widgets (Dict) – See example usage for the required form.

  • font_size (str) – Dock label font size as a string (e.g. ‘14px’).

class nspyre.gui.widgets.MainWidgetItem(module, cls, args=None, kwargs=None, stretch=None)

Represents an arbitrary QWidget that can be loaded from the MainWidget.

Parameters:
  • module (types.ModuleType) – Python module that contains cls. The module will be reloaded when the user clicks the “Load” button.

  • cls (str) – Python class name as a string. The class must descend from QWidget. An instance of this class will be created when the user tries to load the widget and it will be added to the DockArea.

  • args (Optional[list]) – Arguments to pass to cls.__init__.

  • kwargs (Optional[dict]) – Keyword arguments to pass to the cls.__init__.

  • stretch (Optional[tuple]) – The dock stretch factor (stretch_x, stretch_y) (see DockArea docs)

class nspyre.gui.widgets.ParamsWidget(params_config, get_param_value_funs=None)

Qt widget containing a set of GUI elements for the user to enter experiment parameters into.

Typical usage example:

from pyqtgraph import SpinBox
from pyqtgraph.Qt import QtWidgets

class MyWidget(QtWidgets.QWidget)
    def __init__(self):
        super().__init__()
        self.params_widget = ParamsWidget({
            'start_freq': {
                'display_text': 'Start Frequency',
                'widget': SpinBox(
                    value=3e9,
                    suffix='Hz',
                    siPrefix=True,
                    bounds=(100e3, 10e9),
                    dec=True,
                ),
            },
            'stop_freq': {
                'display_text': 'Stop Frequency',
                'widget': SpinBox(
                    value=4e9,
                    suffix='Hz',
                    siPrefix=True,
                    bounds=(100e3, 10e9),
                    dec=True,
                ),
            },
            'num_points': {
                'display_text': 'Number of Scan Points',
                'widget': SpinBox(value=100, int=True, bounds=(1, None), dec=True),
            },
            'iterations': {
                'display_text': 'Number of Experiment Repeats',
                'widget': SpinBox(value=20, int=True, bounds=(1, None), dec=True),
            },
            'dataset': {
                'display_text': 'Data Set',
                'widget': QtWidgets.QLineEdit('odmr'),
            },
        })

    ...

    def doSomething(self):
        print(f'Scanning from = {self.params_widget.start_freq} Hz to = {self.params_widget.stop_freq} Hz.'
Parameters:
  • params_config (Dict) –

    Dictionary mapping parameter names to a parameter configuration dictionary, which should contain:

    • widget: QWidget instance that represents the parameter

    • display_text [optional]: parameter text label

  • get_param_value_funs (Optional[Dict]) –

    Dictionary mapping Python classes to a function that takes an instance of that class and returns its value. This can be used to show ParamsWidget how to handle new QWidgets. There is built-in support for pyqtgraph SpinBox, QLineEdit, QComboBox, QCheckBox. E.g.:

    def get_lineedit_val(lineedit):
        return lineedit.text()
    
    pw = ParamsWidget({
                'dataset': {
                    'display_text': 'Data Set',
                    'widget': QtWidgets.QLineEdit('odmr'),
                },
                ...
            },
            get_param_value_funs={QLineEdit: get_lineedit_val}
        )
    

all_params()

Return the current value of all user parameters as a dictionary.

class nspyre.gui.widgets.SaveLoadWidget(timeout=30, file_dialog_dir=None, additional_filetypes=None)

Qt widget that transfers data (with optional modifications) between the DataServer and files.

Parameters:
  • timeout (float) – Timeout for data sink pop().

  • file_dialog_dir (Optional[Union[str, pathlib.Path]]) – Directory where the file dialog begins. If None, default to the user home directory.

  • additional_filetypes (Optional[Dict[str, tuple[list, Callable, Callable]]]) – Dictionary containing string keys that represent a file type mapping to a tuple. The first element of the tuple is a list which contains the possible file extensions for the file type. The second element is a function that will save data to a file using the associated file type. The save function should have the signature: save_fun(filename: str, data: Any). The third element is a function that will load data from a file using the associated file type. The load function should have the signature: load(filename: Union[str, Path]) -> Any. E.g.: {'FileType': (['.jpg', '.jpeg'], save_fun, load_fun)}

class nspyre.gui.widgets.QHLine

Qt widget that displays a horizontal line.

class nspyre.gui.widgets.QVLine

Qt widget that displays a vertical line.

class nspyre.gui.widgets.sssss(size=300)

Qt widget that displays the nspyre logo.

Parameters:

size – Size of the logo in pixels.