Source code for src.gui.object_config

"""Dialogs for setting up the main objects: actions, instruments, and graphs."""

from functools import partial
import os
import wx

from src.core import action as act
from src.core import experiment
from src.core.configuration import c
from src.core.errors import InvalidInputError
from src.core.graph import Graph
from src.gui import gui_helpers as gh

MARK_CONSTANT = experiment.MARK_CONSTANT
MARK_COLUMN = experiment.MARK_COLUMN
MARK_PARAM = experiment.MARK_PARAMETER

SUB_CONSTANT = experiment.SUB_CONSTANT
SUB_COLUMN = experiment.SUB_COLUMN
SUB_PARAMETER = experiment.SUB_PARAMETER

FILE_DIRECTIONS = ('Choose a folder to store data files using the "Browse for '
                   'Folder" button, and enter a filename for the current data '
                   'file, without any extensions.')

CALCULATE_DIRECTIONS = (('Enter an expression. Expressions may include the '
        'standard mathematical functions and any constants, parameters, or '
        'columns you have defined. Names of constants should be specified in '
        'the form %s(constant name), parameters in the form %s(parameter name) '
        'and columns in the form %s(column name).') %
        (MARK_CONSTANT, MARK_PARAM, MARK_COLUMN))

CONDITIONAL_DIRECTIONS = (('Enter a boolean expression (an expression that '
        'evaluates to true or false). The expression may include any constants '
        'columns, or parameters you have defined, the basic operations (+, -, '
        '*, /, **), the standard mathematical functions, and the standard '
        'comparison operators (==, >, >=, <, <=, !=). Names of constants '
        'should be specified in the form %s(constant name), parameters in the '
        'form %s(parameter name) and columns in the form %s(column name).') %
        (MARK_CONSTANT, MARK_PARAM, MARK_COLUMN))


# Dialog Dispatcher ------------------------------------------------------------

[docs]def getDialog(action): """Return the appropriate dialog for the supplied action. Parameters ---------- action : Action An `Action` object which the user wants to edit. Returns ------- class The appropriate dialog class (uninstantiated) for modifying `action`. """ result = None if isinstance(action, act.ActionScan): result = ScanDialog elif (isinstance(action, act.ActionLoopTimed) or isinstance(action, act.ActionLoopIterations)): result = LoopTimesDialog elif isinstance(action, act.ActionLoopWhile): result = LoopWhileDialog elif (isinstance(action, act.ActionLoopUntilInterrupt) or isinstance(action, act.ActionSimultaneous) or isinstance(action, act.ActionContainer)): result = BlankDialog elif isinstance(action, act.Action): instname = action.getInstrumentName() actdesc = action.getDescription() if instname == 'System': if actdesc == 'Set data file': result = FileDialog elif actdesc == 'Calculate': result = CalculateDialog else: result = ActionDialog elif instname == 'Postprocessor': result = BlankDialog else: result = ActionDialog if result is not None: return result className = action.__class__.__name__ myself = os.path.abspath( __file__ ) raise NotImplementedError(('%s: No dialog has been associated ' + 'with this class of actions. Please edit ' + 'the dispatcher at %s') % (className, myself)) # Action Configuration Dialogs -------------------------------------------------
[docs]class ActionDialog(gh.BaseDialog): """A dialog to configure standard actions. This dialog presents a way to configure normal `Action` objects. It presents a two-region panel. On the left are options for inputs, and on the right are options for outputs. Inputs may have both their values and their column names set here, and outputs may have their column names set. Parameters ---------- parent : wxWindow The panel or frame which owns this dialog. experiment : Experiment The experiment which owns the action being configured by this dialog. actionIn : Action The action whose parameters will be set by this dialog. """ def __init__(self, parent, expt, actionIn): self.experiment = expt self.action = actionIn self.inputs = self.action.getInputProperties() self.outputs = self.action.getOutputProperties() super(ActionDialog, self).__init__(parent, wx.ID_ANY, self.action.getDescription(), minWidth=650) mainpanel = gh.Panel(self, 'horizontal') columnFlag = wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL self.controls = [] self.inputcols = [] self.inputvals = [] self.outputcols = [] inputpanel = gh.Panel(mainpanel, 'flex_grid', 'Inputs', len(self.inputs)+1, 3, 5, 5, scrolling=True) inputpanel.addLabel('Parameter', 0, columnFlag) inputpanel.addLabel('Column Name', 0, columnFlag) inputpanel.addLabel('Value', 0, columnFlag) inputpanel.addGrowableColumn(1, 1) inputpanel.addGrowableColumn(2, 1) for dat in self.inputs: currentLabel = dat['description'] choices = [None, dat['allowed']] initialValues = [dat['column'], dat['value']] currentControls = inputpanel.addLabeledMultiCtrl(currentLabel, initialValues, choices, 0) self.inputcols.append(currentControls[0]) self.inputvals.append(currentControls[1]) outputpanel = gh.Panel(mainpanel, 'flex_grid', 'Outputs', len(self.outputs)+1, 2, 5, 5, scrolling=True) outputpanel.addLabel('Parameter', 0, columnFlag) outputpanel.addLabel('Column Name', 0, columnFlag) outputpanel.addGrowableColumn(1, 1) for dat in self.outputs: currCol = outputpanel.addLabeledText(dat['description'], dat['column']) self.outputcols.append(currCol) mainpanel.add(inputpanel, 3, wx.EXPAND|wx.ALL, 2) mainpanel.add(outputpanel, 2, wx.EXPAND|wx.ALL, 2) mainpanel.SetMinSize((600, 200)) self.setPanel(mainpanel)
[docs] def update(self): """Try to update the action to reflect changes made by this dialog.""" newincols = [] newinvals = [] for col, val in zip(self.inputcols, self.inputvals): newincols.append(col.GetValue()) newinvals.append(val.GetValue()) try: self.action.setInputValues(newinvals) self.action.setInputColumns(newincols) except InvalidInputError, err: dialog = wx.MessageDialog(self, str(err), 'Invalid Input', wx.OK|wx.ICON_ERROR) dialog.ShowModal() return False newoutcols = [] for col in self.outputcols: newoutcols.append(col.GetValue()) return True
[docs]class ScanDialog(gh.BaseDialog): """A dialog for configuring scan actions. Parameters ---------- parent : wxWindow The panel or frame which owns this dialog. expt : Experiment The experiment which owns the action being configured by this dialog. actionIn : Action The action whose parameters will be set by this dialog. """ def __init__(self, parent, expt, actionIn): self.experiment = expt self.action = actionIn self.inprop = self.action.getInputProperties()[0] super(ScanDialog, self).__init__(parent, wx.ID_ANY, title=self.action.getDescription(), minWidth=250) mainpanel = gh.Panel(self) inpanel = wx.Panel(mainpanel, wx.ID_ANY) insizer = wx.BoxSizer(wx.HORIZONTAL) inpanel.SetSizer(insizer) labelText = 'Column name for [%s]:' % self.inprop['description'] self.incol = gh.createLabeledTextControl(inpanel, insizer, label=labelText, initialValue=self.inprop['column']) self.scanPanel = gh.ScanPanel(mainpanel, initialData=self.inprop['value'], formatString=self.inprop['format_string']) self.scanPanel.SetMinSize((400, -1)) mainpanel.add(inpanel, 0, wx.EXPAND|wx.ALL, 5) mainpanel.add(self.scanPanel, 1, wx.EXPAND) self.setPanel(mainpanel)
[docs] def getData(self): """Return the data contained in the scan panel. Returns ------- list of tuple of str The scan panel data. """ return self.scanPanel.getData()
[docs] def update(self): """Try to update the action to reflect changes made by this dialog.""" try: self.action.setInputValues([self.getData()]) self.action.setInputColumns([self.incol.GetValue()]) except InvalidInputError, err: dialog = wx.MessageDialog(self, str(err), 'Invalid Input', wx.OK|wx.ICON_ERROR) dialog.ShowModal() return False return True
[docs]class LoopTimesDialog(gh.BaseDialog): """A dialog for configuring the most simple looping actions. This dialog allows configuration both of actions which loop for a specified amount of time (in seconds) and of actions which loop for a specified number of iterations. Parameters ---------- parent : wxWindow The panel or frame which owns this dialog. expt : Experiment The experiment which owns the action being configured by this dialog. actionIn : Action The action whose parameters will be set by this dialog. """ def __init__(self, parent, expt, actionIn): self.experiment = expt self.action = actionIn super(LoopTimesDialog, self).__init__(parent, wx.ID_ANY, self.action.getDescription(), minWidth=150) mainpanel = gh.Panel(self, 'horizontal') if isinstance(self.action, act.ActionLoopTimed): self.label = 'Loop time (s): ' self.value = self.action.getDuration() else: self.label = 'Number of iterations: ' self.value = self.action.getIterations() self.valueBox = mainpanel.addLabeledText(self.label, str(self.value), 3) self.setPanel(mainpanel, 0, wx.EXPAND|wx.ALL, 20)
[docs] def update(self): """Try to update the action to reflect changes made by this dialog.""" val = self.valueBox.GetValue() if isinstance(self.action, act.ActionLoopTimed): self.action.setDuration(float(val)) else: self.action.setIterations(int(val)) return True
[docs]class BlankDialog(gh.BaseDialog): """An empty dialog which closes immediately. Parameters ---------- parent : wxWindow The panel or frame which owns this dialog. expt : Experiment The experiment which owns the action being configured by this dialog. actionIn : Action The action whose parameters will be set by this dialog. """ def __init__(self, parent, expt, actionIn): super(BlankDialog, self).__init__(parent, -1) self.experiment = expt self.action = actionIn
[docs] def close(self): """Close the dialog.""" self.EndModal(wx.ID_OK) self.Destroy() # pylint: disable=W0221
[docs] def ShowModal(self, event=None): """Return immediately, so that the dialog closes.""" return wx.ID_OK # pylint: enable=W0221
[docs] def update(self): """Try to update the action to reflect changes made by this dialog.""" return True
[docs]class LoopWhileDialog(gh.BaseDialog): """A dialog for configuring a while loop action. Parameters ---------- parent : wxWindow The panel or frame which owns this dialog. expt : Experiment The experiment which will execute the action configured by this dialog. actionIn : Action The looping action whose parameters will be set by this dialog. """ def __init__(self, parent, expt, actionIn): info = ('Loop while condition holds', CONDITIONAL_DIRECTIONS) super(LoopWhileDialog, self).__init__(parent, wx.ID_ANY, 'Loop: conditional', info=info) self.experiment = expt self.action = actionIn data = self.experiment.getStorageBinNames() mainpanel = gh.Panel(self) timeoutpanel = wx.Panel(mainpanel) timeoutsizer = wx.StaticBoxSizer(wx.StaticBox(timeoutpanel, wx.ID_ANY, 'Timeout'), wx.VERTICAL) timeoutpanel.SetSizer(timeoutsizer) timeoutsubpanel = wx.Panel(timeoutpanel) timeoutsubsizer = wx.FlexGridSizer(2, 2, 5, 5) timeoutsubpanel.SetSizer(timeoutsubsizer) timeoutlabel = wx.StaticText(timeoutsubpanel, label='Timeout (s): ') timeoutenablelabel = wx.StaticText(timeoutsubpanel, label='Timeout enabled: ') self.timeoutvalue = wx.TextCtrl(timeoutsubpanel, wx.ID_ANY) self.timeoutenabled = wx.CheckBox(timeoutsubpanel, wx.ID_ANY) timeoutsubsizer.Add(timeoutlabel, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL) timeoutsubsizer.Add(self.timeoutvalue, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL) timeoutsubsizer.Add(timeoutenablelabel, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL) timeoutsubsizer.Add(self.timeoutenabled, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL) timeoutsubsizer.AddGrowableCol(1, 1) timeoutsizer.Add(timeoutsubpanel, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 5) timeoutValue = self.action.getTimeout() if timeoutValue is None: self.timeoutvalue.SetValue('') self.timeoutenabled.SetValue(False) else: self.timeoutvalue.SetValue(str(timeoutValue)) self.timeoutenabled.SetValue(True) self.exprpanel = ExpressionPanel(mainpanel, data) self.exprpanel.setExpression(self.action.getExpression()) mainpanel.add(timeoutpanel, 0, wx.EXPAND|wx.ALL, 5) mainpanel.add(self.exprpanel, 1, wx.EXPAND|wx.ALL, 5) mainpanel.SetSizeHints(-1, 300) self.setPanel(mainpanel, 1, wx.EXPAND|wx.ALL)
[docs] def update(self): """Try to update the action to reflect changes made by this dialog.""" newexpr = self.exprpanel.getExpression() if self.timeoutenabled.GetValue(): try: newto = float(self.timeoutvalue.GetValue()) except ValueError: newto = None else: newto = None self.action.setExpression(newexpr) self.action.setTimeout(newto) return True # System Instrument Dialogs and Panels -----------------------------------------
[docs]class FileDialog(gh.BaseDialog): """A dialog for setting the data filename. Parameters ---------- parent : wxWindow The panel or frame which owns this dialog. expt : Experiment The experiment which will be writing to the files. actionIn : Action The file-saving action whose parameters will be set by this dialog. """ def __init__(self, parent, expt, actionIn): super(FileDialog, self).__init__(parent, wx.ID_ANY, 'Set filename', info=('Data Files', FILE_DIRECTIONS)) self.experiment = expt self.action = actionIn mainpanel = wx.Panel(self) mainsizer = wx.BoxSizer(wx.VERTICAL) mainpanel.SetSizer(mainsizer) datpanel = gh.Panel(mainpanel, 'flex_grid', None, 2, 2, 5, 5) folderpanel = gh.Panel(datpanel, 'horizontal') self.folder = wx.TextCtrl(folderpanel) self.folder.SetEditable(False) self.folder.Disable() self.btnBrowse = wx.Button(folderpanel, wx.ID_OPEN, label='...', style=wx.BU_EXACTFIT) # self.btnBrowse.SetMinSize((20, 20)) self.btnBrowse.Bind(wx.EVT_BUTTON, self.onBrowse) folderpanel.add(self.folder, proportion=1, flag=wx.EXPAND) folderpanel.add(self.btnBrowse, proportion=0) inprops = self.action.getInputProperties() self.folder.SetValue(inprops[0]['value']) datpanel.addLabel('Data folder:', 0) datpanel.add(folderpanel, 1, wx.EXPAND) self.file = datpanel.addLabeledText('Base filename:', inprops[1]['value']) datpanel.addGrowableColumn(1, 1) # datpanel.addGrowableColumn(2, 1) scanpanel = gh.Panel(mainpanel, 'horizontal') self.scanbox = scanpanel.addLabeledText('Scan number:', inprops[2]['value'], 2) mainsizer.Add(datpanel, proportion=1, flag=wx.ALL|wx.EXPAND, border=5) mainsizer.Add(scanpanel, 0, wx.ALIGN_CENTER|wx.ALL, 5) self.setPanel(mainpanel, 1, wx.EXPAND|wx.ALL, 5)
[docs] def onBrowse(self, event): """Show a dialog to browse for a folder.""" defFolder = c.getDataFolder() dialog = wx.DirDialog(None, "Choose a directory:", defFolder, style=wx.DD_DEFAULT_STYLE | wx.DD_NEW_DIR_BUTTON) if dialog.ShowModal() == wx.ID_OK: self.folder.SetValue(dialog.GetPath()) dialog.Destroy()
[docs] def update(self): """Try to update the action to reflect changes made by this dialog.""" self.action.setInputValues([self.folder.GetValue(), self.file.GetValue(), self.scanbox.GetValue()]) return True
[docs]class CalculateDialog(gh.BaseDialog): """A dialog for configuring calculation actions. Parameters ---------- parent : wxWindow The panel or frame which owns this dialog. expt : Experiment The experiment which owns the action being configured by this dialog. actionIn : Action The action whose parameters will be set by this dialog. """ def __init__(self, parent, expt, actionIn): information = ('Evaluate expression', CALCULATE_DIRECTIONS) super(CalculateDialog, self).__init__(parent, title='Calculation', info=information) self.experiment = expt self.action = actionIn data = self.experiment.getStorageBinNames() mainpanel = gh.Panel(self) colnamepanel = gh.Panel(mainpanel, 'flex_grid', 'Column names', 2, 2, 5, 5) indat = self.action.getInputProperties()[0] outdat = self.action.getOutputProperties()[0] indesc = indat['description'] incol = indat['column'] inval = indat['value'] outdesc = outdat['description'] outcol = outdat['column'] self.incol = colnamepanel.addLabeledText(indesc, incol) self.outcol = colnamepanel.addLabeledText(outdesc, outcol) colnamepanel.addGrowableColumn(1, 1) self.exprpanel = ExpressionPanel(mainpanel, data) self.exprpanel.setExpression(inval) mainpanel.add(colnamepanel, 0, wx.EXPAND|wx.ALL, 4) mainpanel.add(self.exprpanel, proportion=1, flag=wx.EXPAND|wx.ALL) mainpanel.SetSizeHints(-1, 300) self.setPanel(mainpanel, 1, wx.EXPAND|wx.ALL)
[docs] def update(self): """Try to update the action to reflect changes made by this dialog.""" newincol = self.incol.GetValue() newoutcol = self.outcol.GetValue() newexpr = self.exprpanel.getExpression() self.action.setInputValues([newexpr]) self.action.setInputColumns([newincol]) self.action.setOutputColumns([newoutcol]) return True
[docs]class ExpressionPanel(wx.Panel): """A panel for creating and editing expressions for later evaluation. Parameters ---------- parent : wxWindow The panel or frame which contains this panel. data : tuple of list of str A three-element tuple of lists of strings. The first element of the tuple contains a list of the names of constants, the second contains a list of columns, and the last contains a list of parameters. """ def __init__(self, parent, data): super(ExpressionPanel, self).__init__(parent, size=(450, 500)) exprpanel = wx.Panel(self) exprbox = wx.StaticBox(exprpanel, wx.ID_ANY, 'Expression') exprsizer = wx.StaticBoxSizer(exprbox, wx.VERTICAL) exprpanel.SetSizer(exprsizer) self.exprbox = wx.TextCtrl(exprpanel, wx.ID_ANY, style=wx.TE_MULTILINE) exprsizer.Add(self.exprbox, 1, wx.EXPAND|wx.ALL, 1) bottompanel = wx.Panel(self) bottomsizer = wx.BoxSizer(wx.HORIZONTAL) bottompanel.SetSizer(bottomsizer) constpanel = gh.Panel(bottompanel, 'vertical', 'Constants') self.constbox = wx.ListBox(constpanel) self.constbox.SetItems(data[0]) self.constbox.Bind(wx.EVT_LISTBOX_DCLICK, self.__insertConstant) constpanel.add(self.constbox, proportion=1, flag=wx.EXPAND) colpanel = gh.Panel(bottompanel, 'vertical', 'Columns') self.colbox = wx.ListBox(colpanel) self.colbox.SetItems(data[1]) self.colbox.Bind(wx.EVT_LISTBOX_DCLICK, self.__insertColumn) colpanel.add(self.colbox, proportion=1, flag=wx.EXPAND) parampanel = gh.Panel(bottompanel, 'vertical', 'Parameters') self.parambox = wx.ListBox(parampanel) self.parambox.SetItems(data[2]) self.parambox.Bind(wx.EVT_LISTBOX_DCLICK, self.__insertParameter) parampanel.add(self.parambox, proportion=1, flag=wx.EXPAND) bottomsizer.Add(constpanel, proportion=1, flag=wx.EXPAND) bottomsizer.Add(colpanel, proportion=1, flag=wx.EXPAND) bottomsizer.Add(parampanel, proportion=1, flag=wx.EXPAND) mainsizer = wx.BoxSizer(wx.VERTICAL) mainsizer.Add(exprpanel, 1, wx.EXPAND|wx.ALL, 2) mainsizer.Add(bottompanel, 1, wx.EXPAND|wx.ALL, 2) self.SetAutoLayout(True) self.SetSizer(mainsizer) self.Layout()
[docs] def getExpression(self): """Get the value of the expression box. Returns ------- str The string expression set by the user. """ return self.exprbox.GetValue()
[docs] def setExpression(self, expression): """Set the value of the expression box. Parameters ---------- expression : str The value which should go in the expression box. The expression may, on use of `eval`, return an `int`, a `float`, or a `bool`. """ self.exprbox.SetValue(expression)
def __insertConstant(self, event): """Insert the name of the selected constant at the cursor position.""" val = self.exprbox.GetValue() insertionPoint = self.exprbox.GetInsertionPoint() pre = val[:insertionPoint] post = val[insertionPoint:] newString = SUB_CONSTANT % event.GetString() self.exprbox.SetValue(''.join([pre, newString, post])) def __insertColumn(self, event): """Insert the name of the selected column at the cursor position.""" val = self.exprbox.GetValue() insertionPoint = self.exprbox.GetInsertionPoint() pre = val[:insertionPoint] post = val[insertionPoint:] newString = SUB_COLUMN % event.GetString() self.exprbox.SetValue(''.join([pre, newString, post])) def __insertParameter(self, event): """Insert the name of the selected parameter at the cursor position.""" val = self.exprbox.GetValue() insertionPoint = self.exprbox.GetInsertionPoint() pre = val[:insertionPoint] post = val[insertionPoint:] newString = SUB_PARAMETER % event.GetString() self.exprbox.SetValue(''.join([pre, newString, post])) # Instruments ------------------------------------------------------------------
[docs]class InstrumentDialog(gh.BaseDialog): """A simple dialog for creating new instruments. """ def __init__(self, parent, inst): """Create a new instrument dialog.""" super(InstrumentDialog, self).__init__(parent, wx.ID_ANY, title='Edit instrument', minWidth=300) self.inst = inst self.spec = inst.getSpecification() setpanel = wx.Panel(self) setsizer = wx.FlexGridSizer(len(self.spec) + 1, 2, 3, 3) setpanel.SetSizer(setsizer) name = self.inst.getName() self.tbs = [] setsizer.Add(wx.StaticText(setpanel, label='Name:'), 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL) self.namefield = wx.TextCtrl(setpanel) self.namefield.SetValue(name) setsizer.Add(self.namefield, proportion=1, flag=wx.EXPAND) self.controls = [] for item in self.spec: itemLabel = wx.StaticText(setpanel, label=item.description + ':') setsizer.Add(itemLabel, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL) if item.allowed is None: control = wx.TextCtrl(setpanel) else: control = wx.ComboBox(setpanel, style=wx.CB_DROPDOWN, choices=item.allowed) control.SetValue(str(item)) control.SetMinSize((200, -1)) self.controls.append(control) setsizer.Add(control, 1, wx.EXPAND) setsizer.AddGrowableCol(1, 1) self.setPanel(setpanel)
[docs] def update(self): """Update the instrument to reflect changes.""" for item, control in zip(self.spec, self.controls): item.value = control.GetValue() self.inst.setName(self.namefield.GetValue()) self.inst.setSpecification(self.spec) return True
[docs]class RebindInstrumentDialog(gh.BaseDialog): """A dialog to change the instrument to which an action is bound. """ def __init__(self, parent, expt, action): super(RebindInstrumentDialog, self).__init__(parent, wx.ID_ANY, title='Change instrument') self.experiment = expt self.action = action self.inst = self.action.getInstrument() self.options = self.experiment.getEqualEnoughInstruments(action) self.names = [] self.initindex = None for index, option in zip(range(len(self.options)), self.options): self.names.append(option['instrument_name']) if option['instrument'] is self.inst: self.initindex = index instpanel = wx.Panel(self) instbox = wx.StaticBox(instpanel, wx.ID_ANY, "Instrument") instsizer = wx.StaticBoxSizer(instbox, wx.HORIZONTAL) instpanel.SetSizer(instsizer) self.instbox = wx.ComboBox(instpanel, style=wx.CB_READONLY) self.instbox.SetMinSize((200, -1)) self.instbox.SetItems(self.names) self.instbox.Select(self.initindex) instsizer.AddStretchSpacer(1) instsizer.Add(self.instbox, 5, wx.EXPAND|wx.TOP|wx.BOTTOM, 5) instsizer.AddStretchSpacer(1) self.setPanel(instpanel)
[docs] def update(self): """Update the action to use the new instrument.""" sel = self.instbox.GetSelection() if sel != self.initindex: self.action.setInstrument(self.options[sel]['instrument']) return True # Graphs -----------------------------------------------------------------------
[docs]class GraphDialog(gh.BaseDialog): """A dialog for editing graphs. Parameters ---------- parent : wxWindow The frame or panel which owns this dialog. experiment : Experiment The experiment which contains the graphs edited by this dialog. graphIn : Graph The graph to edit. """ def __init__(self, parent, expt, graphIn=None): super(GraphDialog, self).__init__(parent, -1, title='Edit graph', minWidth=300) self.experiment = expt self.graphIn = graphIn self.columnNames = self.experiment.getStorageBinNames()[1] self.trigNames = ['None'] + self.columnNames datapanel = gh.Panel(self, 'flex_grid', None, 3, 2, 2, 2) myCombo = partial(datapanel.addLabeledComboBox, style=wx.CB_READONLY, border=2) if self.graphIn is not None: selectedColumns = self.graphIn.getColumns() initialX = selectedColumns[0] initialY = selectedColumns[1] initialTrig = selectedColumns[2] else: initialX = self.columnNames[1] initialY = self.columnNames[0] initialTrig = None if initialTrig is None: initialTrig = 'None' self.xbox = myCombo(choices=self.columnNames, initialValue=initialX, label='X column:') self.ybox = myCombo(choices=self.columnNames, initialValue=initialY, label='Y column:') self.trigbox = myCombo(choices=self.trigNames, initialValue=initialTrig, label='Plot trigger:') datapanel.addGrowableColumn(1, 1) self.setPanel(datapanel)
[docs] def update(self): """Update the input graph or create a new graph.""" newcols = [self.xbox.GetValue(), self.ybox.GetValue(), self.trigbox.GetValue()] if self.trigbox.GetValue() == 'None': newcols[2] = None if self.graphIn is not None: self.graphIn.setColumns(newcols) self.experiment.updateGraphColumns(self.graphIn) else: self.graphIn = Graph(self.experiment, *newcols) self.experiment.addGraph(self.graphIn) cols = self.experiment.getStorageBinNames()[1] if newcols[0] in cols and newcols[1] in cols: self.graphIn.setEnabled(True) else: self.graphIn.setEnabled(False) return True