diff --git a/slic/gui/daqframe.py b/slic/gui/daqframe.py index 72a8d5c0..90f0db1b 100644 --- a/slic/gui/daqframe.py +++ b/slic/gui/daqframe.py @@ -2,6 +2,7 @@ import wx from .daqpanels import ConfigPanel, StaticPanel, ScanPanel, Scan2DPanel, TweakPanel, GoToPanel from .daqpanels.special import SpecialScanPanel +from .daqpanels.sfx import SFXPanel from .daqpanels.run import RunPanel from .widgets import MainPanel, NotebookDX from .icon import get_wx_icon @@ -10,7 +11,7 @@ from .persist import Persistence class DAQFrame(wx.Frame): - def __init__(self, scanner, title="Neat DAQ", show_static=True, show_scan=True, show_spec=False, show_scan2D=True, show_tweak=True, show_goto=False, show_run=False): + def __init__(self, scanner, title="Neat DAQ", show_static=True, show_scan=True, show_spec=False, show_scan2D=True, show_tweak=True, show_goto=False, show_run=False, show_sfx=False): wx.Frame.__init__(self, None, title=title)#, size=(350,200)) self.SetIcon(get_wx_icon()) @@ -29,6 +30,7 @@ class DAQFrame(wx.Frame): panel_tweak = TweakPanel(notebook, name="Tweak") panel_goto = GoToPanel(notebook, name="GoTo") panel_run = RunPanel(notebook, acquisition, instrument, name="Run") + panel_sfx = SFXPanel(notebook, acquisition, instrument, name="SFX") notebook.AddPage(panel_config) if show_static: notebook.AddPage(panel_static) @@ -38,6 +40,7 @@ class DAQFrame(wx.Frame): if show_tweak: notebook.AddPage(panel_tweak) if show_goto: notebook.AddPage(panel_goto) if show_run: notebook.AddPage(panel_run) + if show_sfx: notebook.AddPage(panel_sfx) if show_spec: notebook.SelectPage(panel_spec) elif show_scan: notebook.SelectPage(panel_scan) diff --git a/slic/gui/daqpanels/sfx.py b/slic/gui/daqpanels/sfx.py new file mode 100644 index 00000000..1b909cc1 --- /dev/null +++ b/slic/gui/daqpanels/sfx.py @@ -0,0 +1,118 @@ +from glob import iglob +import wx + +from slic.utils import printed_exception +from slic.utils.reprate import get_pvname_reprate + +from ..widgets import STRETCH, TwoButtons, LabeledMathEntry, LabeledFilenameEntry, make_filled_vbox, post_event +from .tools import ETADisplay, correct_n_pulses, run +from ..widgets.labeled import make_labeled + + +class Choice(wx.Choice): + + def GetValue(self): + sel = self.GetSelection() + res = self.GetString(sel) + if not res: + return None + return res + + +LabeledChoice = make_labeled(Choice) + + +class SFXPanel(wx.Panel): + # filename + # detectors=None, channels=None, pvs=None + # scan_info=None + # n_pulses=100 + # continuous=False + # wait=True + + def __init__(self, parent, acquisition, instrument, *args, **kwargs): + wx.Panel.__init__(self, parent, *args, **kwargs) + + self.acquisition = acquisition + self.task = None + + # widgets: + self.cb_contin = cb_contin = wx.CheckBox(self, label="Run continuously") + cb_contin.Bind(wx.EVT_CHECKBOX, self.on_check_contin) + + self.le_npulses = le_npulses = LabeledMathEntry(self, label="#Pulses", value="100") + self.le_fname = le_fname = LabeledFilenameEntry(self, label="Filename", value="test") + + fn_pattern = f"/sf/{acquisition.instrument}/data/{acquisition.pgroup}/res/automatic/CELL/*.cell" + fns = sorted(iglob(fn_pattern)) + cell_names = [ + fn.split("/")[-1].split(".")[0] for fn in fns + ] + choices = [""] + cell_names + self.lc_cell_name = lc_cell_name = LabeledChoice(self, label="Cell Name", choices=choices) + + pvname_reprate = get_pvname_reprate(instrument) + self.eta = eta = ETADisplay(self, "Estimated time needed", pvname_reprate, le_npulses) + + self.btn_go = btn_go = TwoButtons(self) + btn_go.Bind1(wx.EVT_BUTTON, self.on_go) + btn_go.Bind2(wx.EVT_BUTTON, self.on_stop) + + # workaround: + # enable checkbox and set longer labels before fitting to avoid overlapping labels + cb_contin.SetValue(True) + self.on_check_contin(None) + + # sizers: + widgets = (STRETCH, cb_contin, le_npulses, le_fname, lc_cell_name, eta, btn_go) + vbox = make_filled_vbox(widgets, border=10) + self.SetSizerAndFit(vbox) + + # disable checkbox after fitting as default state + cb_contin.SetValue(False) + self.on_check_contin(None) + + + def on_check_contin(self, _event): + continuous = self.cb_contin.IsChecked() + suffix = " per run" if continuous else "" + self.le_npulses.label.SetLabel("#Pulses" + suffix) + self.eta.st_label.SetLabel("Estimated time needed" + suffix + ":") + + + def on_go(self, _event): + if self.task: + return + + filename = self.le_fname.GetValue() + + n_pulses = self.le_npulses.GetValue() + n_pulses = int(n_pulses) + + rate = self.eta.value + n_pulses = correct_n_pulses(rate, n_pulses) + + continuous = self.cb_contin.IsChecked() + n_repeat = None if continuous else 1 + + cell_name = self.lc_cell_name.GetValue() + + self.task = self.acquisition.acquire(filename, n_pulses=n_pulses, n_repeat=n_repeat, wait=False, cell_file=cell_name) + + def wait(): + with printed_exception: + self.task.wait() + self.task = None + post_event(wx.EVT_BUTTON, self.btn_go.btn2) + + run(wait) + + + def on_stop(self, _event): + print("stop", self.task) + if self.task: + self.task.stop() + self.task = None + + +