Exemple #1
0
    def build_btnpanel(self):
        panel = self.btnpanel = wx.Panel(self, )
        panel.SetBackgroundColour(wx.Colour(*BGCOL))

        btnsizer = wx.BoxSizer(wx.HORIZONTAL)
        self.pause_btn  = wx.Button(panel, label='Pause',  size=(100, 30))
        self.resume_btn = wx.Button(panel, label='Resume', size=(100, 30))
        self.resume_btn.Disable()

        self.pause_btn.Bind(wx.EVT_BUTTON, self.onPause)
        self.resume_btn.Bind(wx.EVT_BUTTON, self.onPause)

        time_label = SimpleText(panel, '    Time Range: ',  minsize=(85, -1),
                                style=LSTY)
        self.time_choice = MyChoice(panel, size=(120, -1),
                                    choices=('seconds', 'minutes', 'hours'))
        self.time_choice.SetStringSelection(self.timelabel)
        self.time_choice.Bind(wx.EVT_CHOICE,   self.onTimeChoice)

        self.time_ctrl  = FloatCtrl(panel, value=-self.tmin, precision=2,
                                    size=(90, -1), action=self.onDisplayTimeVal)

        btnsizer.Add(self.pause_btn,   0, wx.ALIGN_LEFT|wx.ALIGN_CENTER, 2)
        btnsizer.Add(self.resume_btn,  0, wx.ALIGN_LEFT|wx.ALIGN_CENTER, 2)
        btnsizer.Add(time_label,       1, wx.ALIGN_CENTER_HORIZONTAL,    2)
        btnsizer.Add(self.time_ctrl,   0, wx.ALIGN_LEFT|wx.ALIGN_CENTER, 2)
        btnsizer.Add(self.time_choice, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER, 2)

        panel.SetAutoLayout(True)
        panel.SetSizer(btnsizer)
        btnsizer.Fit(panel)
Exemple #2
0
class StripChart(wx.Frame):
    default_colors = ((0, 0, 0), (0, 0, 255), (255, 0, 0), (0, 0, 0),
                      (255, 0, 255), (0, 125, 0))

    help_msg = """Quick help:

Left-Click: to display X,Y coordinates
Left-Drag: to zoom in on plot region
Right-Click: display popup menu with choices:
Zoom out 1 level
Zoom all the way out
--------------------
Configure
Save Image

Also, these key bindings can be used
(For Mac OSX, replace 'Ctrl' with 'Apple'):

Ctrl-S: save plot image to file
Ctrl-C: copy plot image to clipboard
Ctrl-K: Configure Plot
Ctrl-Q: quit

"""

    about_msg = """Epics PV Strip Chart version 0.1
Matt Newville <*****@*****.**>
"""

    def __init__(self, parent=None):
        self.pvdata = {}
        self.pvlist = [' -- ']
        self.pvwids = [None]
        self.pvchoices = [None]
        self.colorsels = []
        self.plots_drawn = [False] * 10
        self.needs_refresh = False
        self.needs_refresh = False
        self.paused = False

        self.tmin = -60.0
        self.timelabel = 'seconds'

        self.create_frame(parent)

        self.timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.onUpdatePlot, self.timer)
        self.timer.Start(POLLTIME)

    def create_frame(self, parent, size=(750, 450), **kwds):
        self.parent = parent

        kwds['style'] = wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL
        kwds['size'] = size
        wx.Frame.__init__(self, parent, -1, 'Epics PV Strip Chart', **kwds)

        self.build_statusbar()

        self.plotpanel = PlotPanel(self,
                                   trace_color_callback=self.onTraceColor)
        self.plotpanel.BuildPanel()
        self.plotpanel.messenger = self.write_message

        self.build_pvpanel()
        self.build_btnpanel()
        self.build_menus()
        self.SetBackgroundColour(wx.Colour(*BGCOL))

        mainsizer = wx.BoxSizer(wx.VERTICAL)

        p1 = wx.Panel(self)
        p1.SetBackgroundColour(wx.Colour(*BGCOL))
        s1 = wx.BoxSizer(wx.HORIZONTAL)
        n = LabelEntry(p1,
                       '',
                       labeltext=' Add PV: ',
                       size=300,
                       action=self.onPVname)
        self.pvmsg = SimpleText(p1,
                                ' ',
                                minsize=(75, -1),
                                style=LSTY | wx.EXPAND)
        s1.Add(n.label, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER, 10)
        s1.Add(n, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER, 10)
        s1.Add(self.pvmsg, 1, wx.ALIGN_LEFT | wx.ALIGN_CENTER, 10)
        p1.SetAutoLayout(True)
        p1.SetSizer(s1)
        s1.Fit(p1)

        mainsizer.Add(p1, 0, wx.GROW | wx.EXPAND, 5)
        mainsizer.Add(
            wx.StaticLine(self, size=(250, -1), style=wx.LI_HORIZONTAL), 0,
            wx.EXPAND | wx.GROW, 8)
        mainsizer.Add(self.pvpanel, 0, wx.EXPAND, 5)
        mainsizer.Add(
            wx.StaticLine(self, size=(250, -1), style=wx.LI_HORIZONTAL), 0,
            wx.EXPAND | wx.GROW, 8)
        mainsizer.Add(self.btnpanel, 0, wx.EXPAND, 5)
        mainsizer.Add(self.plotpanel, 1, wx.EXPAND, 5)
        self.SetAutoLayout(True)
        self.SetSizer(mainsizer)
        self.Fit()

        try:
            self.SetIcon(wx.Icon(ICON_FILE, wx.BITMAP_TYPE_ICO))
        except:
            pass

        self.Refresh()

    def build_statusbar(self):
        sbar = self.CreateStatusBar(2, wx.CAPTION | wx.THICK_FRAME)
        sfont = sbar.GetFont()
        sfont.SetWeight(wx.BOLD)
        sfont.SetPointSize(10)
        sbar.SetFont(sfont)
        self.SetStatusWidths([-5, -2])
        self.SetStatusText('', 0)

    def build_pvpanel(self):
        panel = self.pvpanel = wx.Panel(self)
        panel.SetBackgroundColour(wx.Colour(*BGCOL))
        sizer = self.pvsizer = wx.GridBagSizer(4, 5)

        name = SimpleText(panel, ' PV: ', minsize=(75, -1), style=LSTY)
        colr = SimpleText(panel, ' Color ', minsize=(50, -1), style=LSTY)
        logs = SimpleText(panel, ' Log Scale?', minsize=(85, -1), style=LSTY)
        ymin = SimpleText(panel, ' Y Minimum ', minsize=(85, -1), style=LSTY)
        ymax = SimpleText(panel, ' Y Maximum ', minsize=(85, -1), style=LSTY)

        sizer.Add(name, (0, 0), (1, 1), LSTY | wx.EXPAND, 2)
        sizer.Add(colr, (0, 1), (1, 1), LSTY, 1)
        sizer.Add(logs, (0, 2), (1, 1), LSTY, 1)
        sizer.Add(ymin, (0, 3), (1, 1), LSTY, 1)
        sizer.Add(ymax, (0, 4), (1, 1), LSTY, 1)

        self.npv_rows = 0
        for i in range(4):
            self.AddPV_row()

        panel.SetAutoLayout(True)
        panel.SetSizer(sizer)
        sizer.Fit(panel)

    def build_btnpanel(self):
        panel = self.btnpanel = wx.Panel(self, )
        panel.SetBackgroundColour(wx.Colour(*BGCOL))

        btnsizer = wx.BoxSizer(wx.HORIZONTAL)
        self.pause_btn = wx.Button(panel, label='Pause', size=(100, 30))
        self.resume_btn = wx.Button(panel, label='Resume', size=(100, 30))
        self.resume_btn.Disable()

        self.pause_btn.Bind(wx.EVT_BUTTON, self.onPause)
        self.resume_btn.Bind(wx.EVT_BUTTON, self.onPause)

        time_label = SimpleText(panel,
                                ' Time Range: ',
                                minsize=(85, -1),
                                style=LSTY)
        self.time_choice = MyChoice(panel,
                                    size=(120, -1),
                                    choices=('seconds', 'minutes', 'hours'))
        self.time_choice.SetStringSelection(self.timelabel)
        self.time_choice.Bind(wx.EVT_CHOICE, self.onTimeChoice)

        self.time_ctrl = FloatCtrl(panel,
                                   value=-self.tmin,
                                   precision=2,
                                   size=(90, -1),
                                   action=self.onTimeVal)

        btnsizer.Add(self.pause_btn, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER, 2)
        btnsizer.Add(self.resume_btn, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER, 2)
        btnsizer.Add(time_label, 1, wx.ALIGN_CENTER_HORIZONTAL, 2)
        btnsizer.Add(self.time_ctrl, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER, 2)
        btnsizer.Add(self.time_choice, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER, 2)

        panel.SetAutoLayout(True)
        panel.SetSizer(btnsizer)
        btnsizer.Fit(panel)

    def build_menus(self):
        mbar = wx.MenuBar()

        mfile = wx.Menu()
        mfile.Append(MENU_SAVE_DAT, "&Save Data\tCtrl+S",
                     "Save PNG Image of Plot")
        mfile.Append(MENU_SAVE_IMG, "Save Plot Image\t",
                     "Save PNG Image of Plot")
        mfile.Append(MENU_CLIPB, "&Copy Image to Clipboard\tCtrl+C",
                     "Copy Plot Image to Clipboard")
        mfile.AppendSeparator()
        mfile.Append(MENU_PSETUP, 'Page Setup...', 'Printer Setup')
        mfile.Append(MENU_PREVIEW, 'Print Preview...', 'Print Preview')
        mfile.Append(MENU_PRINT, "&Print\tCtrl+P", "Print Plot")
        mfile.AppendSeparator()
        mfile.Append(MENU_EXIT, "E&xit\tCtrl+Q", "Exit the 2D Plot Window")

        mopt = wx.Menu()
        mopt.Append(MENU_CONFIG, "Configure Plot\tCtrl+K",
                    "Configure Plot styles, colors, labels, etc")
        mopt.AppendSeparator()
        mopt.Append(MENU_UNZOOM, "Zoom Out\tCtrl+Z",
                    "Zoom out to full data range")

        mhelp = wx.Menu()
        mhelp.Append(MENU_HELP, "Quick Reference", "Quick Reference for MPlot")
        mhelp.Append(MENU_ABOUT, "About", "About MPlot")

        mbar.Append(mfile, "File")
        mbar.Append(mopt, "Options")
        mbar.Append(mhelp, "&Help")

        self.SetMenuBar(mbar)
        self.Bind(wx.EVT_MENU, self.onSaveData, id=MENU_SAVE_DAT)
        self.Bind(wx.EVT_MENU, self.onHelp, id=MENU_HELP)
        self.Bind(wx.EVT_MENU, self.onAbout, id=MENU_ABOUT)
        self.Bind(wx.EVT_MENU, self.onExit, id=MENU_EXIT)
        self.Bind(wx.EVT_CLOSE, self.onExit)

        pp = self.plotpanel
        self.Bind(wx.EVT_MENU, pp.configure, id=MENU_CONFIG)
        self.Bind(wx.EVT_MENU, pp.unzoom_all, id=MENU_UNZOOM)
        self.Bind(wx.EVT_MENU, pp.save_figure, id=MENU_SAVE_IMG)
        self.Bind(wx.EVT_MENU, pp.Print, id=MENU_PRINT)
        self.Bind(wx.EVT_MENU, pp.PrintSetup, id=MENU_PSETUP)
        self.Bind(wx.EVT_MENU, pp.PrintPreview, id=MENU_PREVIEW)
        self.Bind(wx.EVT_MENU, pp.canvas.Copy_to_Clipboard, id=MENU_CLIPB)

    def AddPV_row(self):
        i = self.npv_rows = self.npv_rows + 1

        panel = self.pvpanel
        sizer = self.pvsizer
        pvchoice = MyChoice(panel, choices=self.pvlist, size=(200, -1))
        pvchoice.SetSelection(0)
        logs = MyChoice(panel)
        logs.SetSelection(0)
        ymin = wx.TextCtrl(panel, -1, '', size=(75, -1))
        ymax = wx.TextCtrl(panel, -1, '', size=(75, -1))
        if i > 2:
            logs.Disable()
            ymin.Disable()
            ymax.Disable()

        colval = (0, 0, 0)
        if i < len(self.default_colors):
            colval = self.default_colors[i]
        colr = csel.ColourSelect(panel, -1, '', colval)
        self.colorsels.append(colr)

        sizer.Add(pvchoice, (i, 0), (1, 1), LSTY, 3)
        sizer.Add(colr, (i, 1), (1, 1), CSTY, 3)
        sizer.Add(logs, (i, 2), (1, 1), CSTY, 3)
        sizer.Add(ymin, (i, 3), (1, 1), CSTY, 3)
        sizer.Add(ymax, (i, 4), (1, 1), CSTY, 3)

        pvchoice.Bind(wx.EVT_CHOICE, Closure(self.onPVchoice, row=i))
        colr.Bind(csel.EVT_COLOURSELECT, Closure(self.onPVcolor, row=i))
        logs.Bind(wx.EVT_CHOICE, self.onPVwid)
        ymin.Bind(wx.EVT_TEXT_ENTER, self.onPVwid)
        ymax.Bind(wx.EVT_TEXT_ENTER, self.onPVwid)

        self.pvchoices.append(pvchoice)
        self.pvwids.append((logs, colr, ymin, ymax))

    def onTraceColor(self, trace, color, **kws):
        irow = self.get_current_traces()[trace][0] - 1
        self.colorsels[irow].SetColour(color)

    def onPVshow(self, event=None, row=0):
        if not event.IsChecked():
            trace = self.plotpanel.conf.get_mpl_line(row)
            trace.set_data([], [])
            self.plotpanel.canvas.draw()
        self.needs_refresh = True

    def onPVname(self, event=None):
        try:
            name = event.GetString()
        except AttributeError:
            return
        self.addPV(name)

    @EpicsFunction
    def addPV(self, name):
        if name is not None and name not in self.pvlist:
            pv = PV(str(name), callback=self.onPVChange)
            pv.get()
            conn = False
            if pv is not None:
                if not pv.connected:
                    pv.wait_for_connection()
                conn = pv.connected

            msg = 'PV not found: %s' % name
            if conn:
                msg = 'PV found: %s' % name
            self.pvmsg.SetLabel(msg)
            if not conn:
                return
            self.pvlist.append(name)
            self.pvdata[name] = [(time.time(), pv.get())]

            i_new = len(self.pvdata)
            new_shown = False
            for choice in self.pvchoices:
                if choice is None:
                    continue
                cur = choice.GetSelection()
                choice.Clear()
                choice.SetItems(self.pvlist)
                choice.SetSelection(cur)
                if cur == 0 and not new_shown:
                    choice.SetSelection(i_new)
                    new_shown = True
            self.needs_refresh = True

    @DelayedEpicsCallback
    def onPVChange(self, pvname=None, value=None, timestamp=None, **kw):
        if timestamp is None:
            timestamp = time.time()
        self.pvdata[pvname].append((timestamp, value))
        self.needs_refresh = True

    def onPVchoice(self, event=None, row=None, **kws):
        self.needs_refresh = True
        for i in range(len(self.pvlist) + 1):
            try:
                trace = self.plotpanel.conf.get_mpl_line(row - 1)
                trace.set_data([], [])
            except:
                pass
        if row == 1:
            self.plotpanel.set_y2label('')
        self.plotpanel.canvas.draw()

    def onPVcolor(self, event=None, row=None, **kws):
        self.plotpanel.conf.set_trace_color(hexcolor(event.GetValue()),
                                            trace=row - 1)
        self.needs_refresh = True

    def onPVwid(self, event=None, row=None, **kws):
        self.needs_refresh = True

    def onTimeVal(self, event=None, value=None, **kws):
        new = -abs(value)
        if abs(new) < 0.1:
            new = -0.1
        if abs(new - self.tmin) > 1.e-3 * max(new, self.tmin):
            self.tmin = new
            self.needs_refresh = True

    def onTimeChoice(self, event=None, **kws):
        newval = event.GetString()
        denom, num = 1.0, 1.0
        if self.timelabel != newval:
            if self.timelabel == 'hours':
                denom = 3600.
            elif self.timelabel == 'minutes':
                denom = 60.0
            if newval == 'hours':
                num = 3600.
            elif newval == 'minutes':
                num = 60.0

            self.timelabel = newval
            timeval = self.time_ctrl.GetValue()
            self.time_ctrl.SetValue(timeval * denom / num)
            self.plotpanel.set_xlabel('Elapsed Time (%s)' % self.timelabel)
        self.needs_refresh = True

    def onPause(self, event=None):
        if self.paused:
            self.pause_btn.Enable()
            self.resume_btn.Disable()
        else:
            self.pause_btn.Disable()
            self.resume_btn.Enable()
        self.paused = not self.paused

    def write_message(self, s, panel=0):
        """write a message to the Status Bar"""
        self.SetStatusText(s, panel)

    def onSaveData(self, event=None):
        dlg = wx.FileDialog(self,
                            message='Save Data to File...',
                            defaultDir=os.getcwd(),
                            defaultFile='PVStripChart.dat',
                            style=wx.SAVE | wx.CHANGE_DIR)
        if dlg.ShowModal() == wx.ID_OK:
            path = dlg.GetPath()
            self.SaveDataFiles(path)
            self.write_message('Saved data to %s' % path)
        dlg.Destroy()

    def SaveDataFiles(self, path):
        basename, ext = os.path.splitext(path)
        if len(ext) < 2:
            ext = '.dat'
        if ext.startswith('.'):
            ext = ext[1:]

        for pvname, data in self.pvdata.items():
            tnow = time.time()
            tmin = data[0][0]
            fname = []
            for s in pvname:
                if s not in FILECHARS:
                    s = '_'
                fname.append(s)
            fname = os.path.join("%s_%s.%s" % (basename, ''.join(fname), ext))

            buff = ["# Epics PV Strip Chart Data for PV: %s " % pvname]
            buff.append("# Current Time = %s " % time.ctime(tnow))
            buff.append("# Earliest Time = %s " % time.ctime(tmin))
            buff.append("#------------------------------")
            buff.append("# Timestamp Value Time-Current_Time(s)")
            for tx, yval in data:
                buff.append(" %.3f %16g %.3f" % (tx, yval, tx - tnow))

            fout = open(fname, 'w')
            fout.write("\n".join(buff))
            fout.close()
            #dat = tnow, func(tnow)

    def onAbout(self, event=None):
        dlg = wx.MessageDialog(self, self.about_msg,
                               "About Epics PV Strip Chart",
                               wx.OK | wx.ICON_INFORMATION)
        dlg.ShowModal()
        dlg.Destroy()

    def onHelp(self, event=None):
        dlg = wx.MessageDialog(self, self.help_msg,
                               "Epics PV Strip Chart Help",
                               wx.OK | wx.ICON_INFORMATION)
        dlg.ShowModal()
        dlg.Destroy()

    def onExit(self, event=None):
        try:
            self.plotpanel.win_config.Close(True)
            self.plotpanel.win_config.Destroy()
        except:
            pass

        self.Destroy()

    def get_current_traces(self):
        "return list of current traces"
        traces = []  # to be shown
        for irow, s in enumerate(self.pvchoices):
            if s is not None:
                ix = s.GetSelection()
                if ix > 0:
                    name = self.pvlist[ix]
                    logs = 1 == self.pvwids[irow][0].GetSelection()
                    color = self.pvwids[irow][1].GetColour()
                    ymin = get_bound(self.pvwids[irow][2].GetValue())
                    ymax = get_bound(self.pvwids[irow][3].GetValue())
                    traces.append((irow, name, logs, color, ymin, ymax))
        return traces

    def onUpdatePlot(self, event=None):
        if self.paused or not self.needs_refresh:
            return

        tnow = time.time()
        # set timescale sec/min/hour
        timescale = 1.0
        if self.time_choice.GetSelection() == 1:
            timescale = 1. / 60
        elif self.time_choice.GetSelection() == 2:
            timescale = 1. / 3600

        ylabelset, y2labelset = False, False
        xlabel = 'Elapsed Time (%s)' % self.timelabel
        itrace = -1
        update_failed = False
        hasplot = False
        span1 = (1, 0)
        did_update = False
        left_axes = self.plotpanel.axes
        right_axes = self.plotpanel.get_right_axes()

        for irow, pname, uselog, color, ymin, ymax in self.get_current_traces(
        ):
            if pname not in self.pvdata:
                continue
            itrace += 1
            if len(self.plots_drawn) < itrace:
                self.plots_drawn.extend([False] * 3)
            side = 'left'
            if itrace == 1:
                side = 'right'
            data = self.pvdata[pname][:]
            if len(data) < 2:
                update_failed = True
                continue
            tdat = timescale * (array([i[0] for i in data]) - tnow)
            mask = where(tdat > self.tmin)
            if (len(mask[0]) < 2
                    or ((abs(min(tdat)) / abs(1 - self.tmin)) > 0.1)):
                data.append((time.time(), data[0][-1]))
                tdat = timescale * (array([i[0] for i in data]) - tnow)
                mask = where(tdat > self.tmin)

            i0 = mask[0][0]
            if i0 > 0:
                i0 = i0 - 1
            i1 = mask[0][-1] + 1
            tdat = timescale * (array([i[0] for i in data[i0:i1]]) - tnow)
            ydat = array([i[1] for i in data[i0:i1]])

            if len(ydat) < 2:
                update_failed = True
                continue
            if ymin is None:
                ymin = min(ydat)
            if ymax is None:
                ymax = max(ydat)

            # for more that 2 plots, scale to left hand axis
            if itrace == 0:
                span1 = (ymax - ymin, ymin)
                if span1[0] * ymax < 1.e-6:
                    update_failed = True
                    continue
            elif itrace > 1:
                yr = abs(ymax - ymin)
                if yr > 1.e-9:
                    ydat = span1[1] + 0.99 * (ydat - ymin) * span1[0] / yr
                ymin, ymax = min(ydat), max(ydat)

            if self.needs_refresh:
                if itrace == 0:
                    self.plotpanel.set_ylabel(pname)
                elif itrace == 1:
                    self.plotpanel.set_y2label(pname)
                if not self.plots_drawn[itrace]:
                    plot = self.plotpanel.oplot
                    if itrace == 0:
                        plot = self.plotpanel.plot
                    try:
                        plot(tdat,
                             ydat,
                             drawstyle='steps-post',
                             side=side,
                             ylog_scale=uselog,
                             color=color,
                             xmin=self.tmin,
                             xmax=0,
                             xlabel=xlabel,
                             label=pname,
                             autoscale=False)
                        self.plots_drawn[itrace] = True
                    except:
                        update_failed = True
                else:
                    try:
                        self.plotpanel.update_line(itrace,
                                                   tdat,
                                                   ydat,
                                                   draw=False)
                        self.plotpanel.set_xylims((self.tmin, 0, ymin, ymax),
                                                  side=side,
                                                  autoscale=False)
                        did_update = True
                    except:
                        update_failed = True
                axes = left_axes
                if itrace == 1:
                    axes = right_axes
                if uselog and min(ydat) > 0:
                    axes.set_yscale('log', basey=10)
                else:
                    axes.set_yscale('linear')

        self.plotpanel.set_title(
            time.strftime("%Y-%b-%d %H:%M:%S", time.localtime()))
        if did_update:
            self.plotpanel.canvas.draw()
        self.needs_refresh = update_failed
        return
    def __init__(self,
                 parent,
                 image_panel=None,
                 camera_id=0,
                 center_cb=None,
                 xhair_cb=None,
                 **kws):
        super(ConfPanel_Fly2, self).__init__(parent,
                                             center_cb=center_cb,
                                             xhair_cb=xhair_cb)
        self.image_panel = image_panel
        self.camera_id = camera_id
        self.camera = self.image_panel.camera

        wids = self.wids
        sizer = self.sizer

        self.title = self.txt("PyCapture2: ", size=285)
        self.title2 = self.txt(" ", size=285)

        sizer.Add(self.title, (0, 0), (1, 3), LEFT)
        sizer.Add(self.title2, (1, 0), (1, 3), LEFT)
        next_row = self.show_position_info(row=2)

        self.__initializing = True
        i = next_row + 1
        #('Sharpness', '%', 100), ('Hue', 'deg', 100), ('Saturation', '%', 100),
        for dat in (
            ('shutter', 'ms', 50, 0, 70),
            ('gain', 'dB', 0, -2, 24),
                # ('brightness', '%', 0,  0,  6),
            ('gamma', '', 1, 0.5, 4)):

            key, units, defval, minval, maxval = dat
            wids[key] = FloatCtrl(self,
                                  value=defval,
                                  minval=minval,
                                  maxval=maxval,
                                  precision=1,
                                  action=self.onValue,
                                  act_on_losefocus=True,
                                  action_kw={'prop': key},
                                  size=(75, -1))
            label = '%s' % (key.title())
            if len(units) > 0:
                label = '%s (%s)' % (key.title(), units)
            sizer.Add(self.txt(label), (i, 0), (1, 1), LEFT)
            sizer.Add(wids[key], (i, 1), (1, 1), LEFT)

            akey = '%s_auto' % key
            wids[akey] = wx.CheckBox(self, -1, label='auto')
            wids[akey].SetValue(0)
            wids[akey].Bind(wx.EVT_CHECKBOX, Closure(self.onAuto, prop=key))
            sizer.Add(wids[akey], (i, 2), (1, 1), LEFT)
            i = i + 1

        for color in ('blue', 'red'):
            key = 'wb_%s' % color
            wids[key] = FloatCtrl(self,
                                  value=0,
                                  maxval=1024,
                                  precision=0,
                                  action=self.onValue,
                                  act_on_losefocus=True,
                                  action_kw={'prop': key},
                                  size=(75, -1))
            label = 'White Balance (%s)' % (color)
            sizer.Add(self.txt(label), (i, 0), (1, 1), LEFT)
            sizer.Add(wids[key], (i, 1), (1, 1), LEFT)

            if color == 'blue':
                akey = 'wb_auto'
                wids[akey] = wx.CheckBox(self, -1, label='auto')
                wids[akey].SetValue(0)
                wids[akey].Bind(wx.EVT_CHECKBOX, Closure(self.onAuto,
                                                         prop=key))
                sizer.Add(wids[akey], (i, 2), (1, 1), LEFT)
            i += 1

        datapush_time = "%.1f" % self.image_panel.datapush_delay
        wids['dpush_time'] = FloatCtrl(self,
                                       value=datapush_time,
                                       maxval=1e6,
                                       precision=1,
                                       minval=0,
                                       action=self.onValue,
                                       act_on_losefocus=True,
                                       action_kw={'prop': 'autosave_time'},
                                       size=(75, -1))

        label = 'AutoSave Time (sec)'
        sizer.Add(self.txt(label), (i, 0), (1, 1), LEFT)
        sizer.Add(wids['dpush_time'], (i, 1), (1, 1), LEFT)

        # wids['datapush'].SetValue(1)
        # wids['datapush'].Bind(wx.EVT_CHECKBOX, self.onEnableDataPush)
        # sizer.Add(wids['datapush'], (i+1, 0), (1, 3), LEFT)

        pack(self, sizer)
        self.__initializing = False
        self.timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.onTimer, self.timer)
        wx.CallAfter(self.onConnect)
Exemple #4
0
class OverlayFrame(wx.Frame):
    """ settings for overlays and pixel calibration"""
    shapes = ('None', 'line', 'circle')

    def __init__(self, image_panel=None, config=None, **kws):
        wx.Frame.__init__(self, None, -1, style=wx.DEFAULT_FRAME_STYLE, **kws)
        self.image_panel = image_panel
        img_x, img_y = self.image_panel.full_size
        self.wids = wids = []
        self.config = config

        panel = wx.Panel(self)
        self.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD, 0, ""))

        ok_button = add_button(panel,
                               "Apply",
                               action=self.onApply,
                               size=(75, -1))
        done_button = add_button(panel,
                                 "Done",
                                 action=self.onClose,
                                 size=(75, -1))

        try:
            pix_x = float(config['camera']['calib_x'])
            pix_y = float(config['camera']['calib_y'])
        except:
            pix_x = 1.000
            pix_y = 1.000

        olays = config['overlays']
        sbar = [float(x) for x in olays['scalebar'].split()]
        circ = [float(x) for x in olays['circle'].split()]

        ssiz, sx, sy, swid, scolr, scolg, scolb = sbar
        csiz, cx, cy, cwid, ccolr, ccolg, ccolb = circ

        scol = wx.Colour(int(scolr), int(scolg), int(scolb))
        ccol = wx.Colour(int(ccolr), int(ccolg), int(ccolb))

        opts = dict(minval=0, maxval=1, precision=3, size=(60, -1))
        wopts = dict(minval=0, maxval=10, precision=1, size=(60, -1))
        sopts = dict(minval=0, maxval=1000, precision=0, size=(60, -1))
        popts = dict(minval=-1000, maxval=1000, precision=3, size=(60, -1))

        self.pix_x = FloatCtrl(panel, value=pix_x, **popts)
        self.pix_y = FloatCtrl(panel, value=pix_y, **popts)

        self.scalebar_col = csel.ColourSelect(panel,
                                              -1,
                                              "",
                                              scol,
                                              size=(75, 25))
        self.circle_col = csel.ColourSelect(panel, -1, "", ccol, size=(75, 25))

        self.scalebar_size = FloatCtrl(panel, value=ssiz, **sopts)
        self.scalebar_x = FloatCtrl(panel, value=sx, **opts)
        self.scalebar_y = FloatCtrl(panel, value=sy, **opts)
        self.scalebar_wid = FloatCtrl(panel, value=swid, **wopts)

        self.circle_size = FloatCtrl(panel, value=csiz, **sopts)
        self.circle_x = FloatCtrl(panel, value=cx, **opts)
        self.circle_y = FloatCtrl(panel, value=cy, **opts)
        self.circle_wid = FloatCtrl(panel, value=cwid, **wopts)

        sizer = wx.GridBagSizer(10, 7)
        sizer.SetVGap(5)
        sizer.SetHGap(5)

        def txt(label, size=-1):
            return SimpleText(panel, label, size=(size, -1))

        sizer.Add(txt(" Configure Image Overlays: "), (0, 0), (1, 4), CEN, 3)
        sizer.Add(txt(" Pixel Size (um)  X, Y: "), (1, 0), (1, 2), LEFT, 2)
        sizer.Add(self.pix_x, (1, 2), (1, 1), CEN, 1)
        sizer.Add(self.pix_y, (1, 3), (1, 1), CEN, 1)

        sizer.Add(txt(" Object "), (2, 0), (1, 1), LEFT, 2)
        sizer.Add(txt("Color"), (2, 1), (1, 1), LEFT, 2)
        sizer.Add(txt("Size (um)"), (2, 2), (1, 1), LEFT, 2)
        sizer.Add(txt("X (fraction)"), (2, 3), (1, 1), LEFT, 2)
        sizer.Add(txt("Y (fraction)"), (2, 4), (1, 1), LEFT, 2)
        sizer.Add(txt("Line width"), (2, 5), (1, 1), LEFT, 2)

        sizer.Add(txt(" Scalebar "), (3, 0), (1, 1), LEFT, 2)
        sizer.Add(self.scalebar_col, (3, 1), (1, 1), CEN, 1)
        sizer.Add(self.scalebar_size, (3, 2), (1, 1), CEN, 1)
        sizer.Add(self.scalebar_x, (3, 3), (1, 1), CEN, 1)
        sizer.Add(self.scalebar_y, (3, 4), (1, 1), CEN, 1)
        sizer.Add(self.scalebar_wid, (3, 5), (1, 1), CEN, 1)

        sizer.Add(txt(" Target "), (4, 0), (1, 1), LEFT, 2)
        sizer.Add(self.circle_col, (4, 1), (1, 1), CEN, 1)
        sizer.Add(self.circle_size, (4, 2), (1, 1), CEN, 1)
        sizer.Add(self.circle_x, (4, 3), (1, 1), CEN, 1)
        sizer.Add(self.circle_y, (4, 4), (1, 1), CEN, 1)
        sizer.Add(self.circle_wid, (4, 5), (1, 1), CEN, 1)

        sizer.Add(wx.StaticLine(panel, size=(220, 2)), (5, 0), (1, 6),
                  wx.ALL | wx.GROW | wx.ALIGN_CENTER, 1)

        sizer.Add(ok_button, (6, 0), (1, 1),
                  wx.ALL | wx.GROW | wx.ALIGN_CENTER, 1)
        sizer.Add(done_button, (6, 1), (1, 1),
                  wx.ALL | wx.GROW | wx.ALIGN_CENTER, 1)

        panel.SetSizer(sizer)
        sizer.Fit(panel)
        self.SetSize((500, 225))
        self.Bind(wx.EVT_CLOSE, self.onClose)
        self.Show()
        self.Raise()

    def onApply(self, event=None):
        pix_x = float(self.pix_x.GetValue())
        pix_y = float(self.pix_y.GetValue())
        self.config['camera']['calib_x'] = "%.4f" % pix_x
        self.config['camera']['calib_y'] = "%.4f" % pix_y

        img_x, img_y = self.image_panel.full_size

        iscale = 0.5 / abs(pix_x * img_x)

        scol = self.scalebar_col.GetColour()
        swid = self.scalebar_wid.GetValue()
        sx = self.scalebar_x.GetValue()
        sy = self.scalebar_y.GetValue()
        ssiz = self.scalebar_size.GetValue()

        ccol = self.circle_col.GetColour()
        cwid = self.circle_wid.GetValue()
        csiz = self.circle_size.GetValue()
        cx = self.circle_x.GetValue()
        cy = self.circle_y.GetValue()

        cargs = [cx, cy, csiz * iscale]
        sargs = [sx - ssiz * iscale, sy, sx + ssiz * iscale, sy]

        dobjs = [
            dict(shape='Line',
                 width=swid,
                 style=wx.SOLID,
                 color=scol,
                 args=sargs),
            dict(shape='Circle',
                 width=cwid,
                 style=wx.SOLID,
                 color=ccol,
                 args=cargs)
        ]

        ofmt = "%.1f %.3f %.3f %.1f %i %i %i"
        olays = self.config['overlays']
        olays['scalebar'] = ofmt % (ssiz, sx, sy, swid, scol[0], scol[1],
                                    scol[2])
        olays['circle'] = ofmt % (csiz, cx, cy, cwid, ccol[0], ccol[1],
                                  ccol[2])
        self.image_panel.draw_objects = dobjs

    def onClose(self, event=None):
        self.Destroy()
Exemple #5
0
    def __init__(self, image_panel=None, config=None, **kws):
        wx.Frame.__init__(self, None, -1, style=wx.DEFAULT_FRAME_STYLE, **kws)
        self.image_panel = image_panel
        img_x, img_y = self.image_panel.full_size
        self.wids = wids = []
        self.config = config

        panel = wx.Panel(self)
        self.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD, 0, ""))

        ok_button = add_button(panel,
                               "Apply",
                               action=self.onApply,
                               size=(75, -1))
        done_button = add_button(panel,
                                 "Done",
                                 action=self.onClose,
                                 size=(75, -1))

        try:
            pix_x = float(config['camera']['calib_x'])
            pix_y = float(config['camera']['calib_y'])
        except:
            pix_x = 1.000
            pix_y = 1.000

        olays = config['overlays']
        sbar = [float(x) for x in olays['scalebar'].split()]
        circ = [float(x) for x in olays['circle'].split()]

        ssiz, sx, sy, swid, scolr, scolg, scolb = sbar
        csiz, cx, cy, cwid, ccolr, ccolg, ccolb = circ

        scol = wx.Colour(int(scolr), int(scolg), int(scolb))
        ccol = wx.Colour(int(ccolr), int(ccolg), int(ccolb))

        opts = dict(minval=0, maxval=1, precision=3, size=(60, -1))
        wopts = dict(minval=0, maxval=10, precision=1, size=(60, -1))
        sopts = dict(minval=0, maxval=1000, precision=0, size=(60, -1))
        popts = dict(minval=-1000, maxval=1000, precision=3, size=(60, -1))

        self.pix_x = FloatCtrl(panel, value=pix_x, **popts)
        self.pix_y = FloatCtrl(panel, value=pix_y, **popts)

        self.scalebar_col = csel.ColourSelect(panel,
                                              -1,
                                              "",
                                              scol,
                                              size=(75, 25))
        self.circle_col = csel.ColourSelect(panel, -1, "", ccol, size=(75, 25))

        self.scalebar_size = FloatCtrl(panel, value=ssiz, **sopts)
        self.scalebar_x = FloatCtrl(panel, value=sx, **opts)
        self.scalebar_y = FloatCtrl(panel, value=sy, **opts)
        self.scalebar_wid = FloatCtrl(panel, value=swid, **wopts)

        self.circle_size = FloatCtrl(panel, value=csiz, **sopts)
        self.circle_x = FloatCtrl(panel, value=cx, **opts)
        self.circle_y = FloatCtrl(panel, value=cy, **opts)
        self.circle_wid = FloatCtrl(panel, value=cwid, **wopts)

        sizer = wx.GridBagSizer(10, 7)
        sizer.SetVGap(5)
        sizer.SetHGap(5)

        def txt(label, size=-1):
            return SimpleText(panel, label, size=(size, -1))

        sizer.Add(txt(" Configure Image Overlays: "), (0, 0), (1, 4), CEN, 3)
        sizer.Add(txt(" Pixel Size (um)  X, Y: "), (1, 0), (1, 2), LEFT, 2)
        sizer.Add(self.pix_x, (1, 2), (1, 1), CEN, 1)
        sizer.Add(self.pix_y, (1, 3), (1, 1), CEN, 1)

        sizer.Add(txt(" Object "), (2, 0), (1, 1), LEFT, 2)
        sizer.Add(txt("Color"), (2, 1), (1, 1), LEFT, 2)
        sizer.Add(txt("Size (um)"), (2, 2), (1, 1), LEFT, 2)
        sizer.Add(txt("X (fraction)"), (2, 3), (1, 1), LEFT, 2)
        sizer.Add(txt("Y (fraction)"), (2, 4), (1, 1), LEFT, 2)
        sizer.Add(txt("Line width"), (2, 5), (1, 1), LEFT, 2)

        sizer.Add(txt(" Scalebar "), (3, 0), (1, 1), LEFT, 2)
        sizer.Add(self.scalebar_col, (3, 1), (1, 1), CEN, 1)
        sizer.Add(self.scalebar_size, (3, 2), (1, 1), CEN, 1)
        sizer.Add(self.scalebar_x, (3, 3), (1, 1), CEN, 1)
        sizer.Add(self.scalebar_y, (3, 4), (1, 1), CEN, 1)
        sizer.Add(self.scalebar_wid, (3, 5), (1, 1), CEN, 1)

        sizer.Add(txt(" Target "), (4, 0), (1, 1), LEFT, 2)
        sizer.Add(self.circle_col, (4, 1), (1, 1), CEN, 1)
        sizer.Add(self.circle_size, (4, 2), (1, 1), CEN, 1)
        sizer.Add(self.circle_x, (4, 3), (1, 1), CEN, 1)
        sizer.Add(self.circle_y, (4, 4), (1, 1), CEN, 1)
        sizer.Add(self.circle_wid, (4, 5), (1, 1), CEN, 1)

        sizer.Add(wx.StaticLine(panel, size=(220, 2)), (5, 0), (1, 6),
                  wx.ALL | wx.GROW | wx.ALIGN_CENTER, 1)

        sizer.Add(ok_button, (6, 0), (1, 1),
                  wx.ALL | wx.GROW | wx.ALIGN_CENTER, 1)
        sizer.Add(done_button, (6, 1), (1, 1),
                  wx.ALL | wx.GROW | wx.ALIGN_CENTER, 1)

        panel.SetSizer(sizer)
        sizer.Fit(panel)
        self.SetSize((500, 225))
        self.Bind(wx.EVT_CLOSE, self.onClose)
        self.Show()
        self.Raise()
    def __init__(self,
                 parent,
                 image_panel=None,
                 camera_id=0,
                 center_cb=None,
                 xhair_cb=None,
                 **kws):
        super(ConfPanel_PySpin, self).__init__(parent,
                                               center_cb=center_cb,
                                               xhair_cb=xhair_cb,
                                               **kws)
        self.image_panel = image_panel
        self.camera_id = camera_id
        self.camera = self.image_panel.camera
        wids = self.wids
        sizer = self.sizer
        with_color_conv = False

        self.title = self.txt("PySpinnaker: ", size=285)
        self.title2 = self.txt(" ", size=285)
        self.title3 = self.txt(" ", size=285)
        btn_start = add_button(self,
                               "Restart Camera",
                               action=self.onRestart,
                               size=(250, -1))
        next_row = self.show_position_info(row=0)

        sizer.Add(self.title, (next_row, 0), (1, 3), LEFT)
        sizer.Add(self.title2, (next_row + 1, 0), (1, 3), LEFT)
        sizer.Add(self.title3, (next_row + 2, 0), (1, 3), LEFT)
        self.__initializing = True
        i = next_row + 3

        for dat in (('exposure', 'ms', 50, 0.03, MAX_EXPOSURE_TIME),
                    ('gain', 'dB', 5, 0, 40)):
            # ('gamma', '',       1, 0.5, 4)):

            key, units, defval, minval, maxval = dat
            wids[key] = FloatCtrl(self,
                                  value=defval,
                                  minval=minval,
                                  maxval=maxval,
                                  precision=2,
                                  action=self.onValue,
                                  act_on_losefocus=True,
                                  action_kw={'prop': key},
                                  size=(75, -1))
            label = '%s' % (key.title())
            if len(units) > 0:
                label = '%s (%s)' % (key.title(), units)
            sizer.Add(self.txt(label), (i, 0), (1, 1), LEFT)
            sizer.Add(wids[key], (i, 1), (1, 1), LEFT)

            if key != 'gamma':
                akey = '%s_auto' % key
                wids[akey] = wx.CheckBox(self, -1, label='auto')
                wids[akey].SetValue(0)
                wids[akey].Bind(wx.EVT_CHECKBOX, Closure(self.onAuto,
                                                         prop=key))
                sizer.Add(wids[akey], (i, 2), (1, 1), LEFT)
            i = i + 1

        for color in ('blue', 'red'):
            key = 'wb_%s' % color
            wids[key] = FloatCtrl(self,
                                  value=0,
                                  minval=0.3,
                                  maxval=4,
                                  precision=3,
                                  action=self.onValue,
                                  act_on_losefocus=True,
                                  action_kw={'prop': key},
                                  size=(75, -1))
            wids[key].Disable()
            label = 'White Balance (%s)' % (color)
            sizer.Add(self.txt(label), (i, 0), (1, 1), LEFT)
            sizer.Add(wids[key], (i, 1), (1, 1), LEFT)
            if color == 'blue':
                akey = 'wb_auto'
                wids[akey] = wx.CheckBox(self, -1, label='auto')
                wids[akey].SetValue(0)
                wids[akey].Bind(wx.EVT_CHECKBOX, Closure(self.onAuto,
                                                         prop=key))
                sizer.Add(wids[akey], (i, 2), (1, 1), LEFT)
            i += 1

        datapush_time = "%.1f" % self.image_panel.datapush_delay
        wids['dpush_time'] = FloatCtrl(self,
                                       value=datapush_time,
                                       maxval=1e6,
                                       precision=1,
                                       minval=0,
                                       action=self.onValue,
                                       act_on_losefocus=True,
                                       action_kw={'prop': 'autosave_time'},
                                       size=(75, -1))

        label = 'AutoSave Time (sec)'
        sizer.Add(self.txt(label), (i, 0), (1, 1), LEFT)
        sizer.Add(wids['dpush_time'], (i, 1), (1, 1), LEFT)
        i = i + 1
        sizer.Add(btn_start, (i, 0), (1, 2), LEFT)

        if with_color_conv:
            conv_choices = ('DEFAULT', 'NO_COLOR_PROCESSING',
                            'NEAREST_NEIGHBOR', 'EDGE_SENSING', 'HQ_LINEAR',
                            'RIGOROUS', 'IPP', 'DIRECTIONAL_FILTER',
                            'WEIGHTED_DIRECTIONAL_FILTER')
            wids['color_conv'] = wx.Choice(self,
                                           -1,
                                           choices=conv_choices,
                                           size=(150, -1))
            wids['color_conv'].Bind(wx.EVT_CHOICE, self.onColorConv)
            i += 1
            sizer.Add(self.txt('Conversion: '), (i, 0), (1, 1), LEFT)
            sizer.Add(wids['color_conv'], (i, 1), (1, 1), LEFT)

        # wids['datapush'].SetValue(1)
        # wids['datapush'].Bind(wx.EVT_CHECKBOX, self.onEnableDataPush)
        # sizer.Add(wids['datapush'], (i+1, 0), (1, 3), LEFT)

        pack(self, sizer)
        self.__initializing = False
        self.read_props_timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.onTimer, self.read_props_timer)
        wx.CallAfter(self.onConnect)
Exemple #7
0
    def build_dialog(self):
        positions = self.instdb.get_positionlist(self.offline)
        panel = scrolled.ScrolledPanel(self)
        self.checkboxes = OrderedDict()
        sizer = wx.GridBagSizer(len(positions) + 5, 4)
        sizer.SetVGap(2)
        sizer.SetHGap(3)
        bkws = dict(size=(95, -1))
        btn_ok = add_button(panel, "Copy Selected", action=self.onOK, **bkws)
        btn_all = add_button(panel, "Select All", action=self.onAll, **bkws)
        btn_none = add_button(panel, "Select None", action=self.onNone, **bkws)

        brow = wx.BoxSizer(wx.HORIZONTAL)
        brow.Add(btn_all, 0, ALL_EXP | wx.ALIGN_LEFT, 1)
        brow.Add(btn_none, 0, ALL_EXP | wx.ALIGN_LEFT, 1)
        brow.Add(btn_ok, 0, ALL_EXP | wx.ALIGN_LEFT, 1)

        self.suffix = wx.TextCtrl(panel, value="", size=(150, -1))
        self.xoff = FloatCtrl(panel, value=0, precision=3, size=(75, -1))
        self.yoff = FloatCtrl(panel, value=0, precision=3, size=(75, -1))
        self.zoff = FloatCtrl(panel, value=0, precision=3, size=(75, -1))

        irow = 0
        sizer.Add(brow, (irow, 0), (1, 4), LEFT_CEN, 2)

        irow += 1
        sizer.Add(SimpleText(panel, ' Add Suffix:'), (irow, 0), (1, 1),
                  LEFT_CEN, 2)
        sizer.Add(self.suffix, (irow, 1), (1, 3), LEFT_CEN, 2)

        irow += 1
        sizer.Add(SimpleText(panel, 'Offsets X, Y, Z:'), (irow, 0), (1, 1),
                  LEFT_CEN, 2)
        sizer.Add(self.xoff, (irow, 1), (1, 1), LEFT_CEN, 2)
        sizer.Add(self.yoff, (irow, 2), (1, 1), LEFT_CEN, 2)
        sizer.Add(self.zoff, (irow, 3), (1, 1), LEFT_CEN, 2)

        irow += 1
        sizer.Add(SimpleText(panel, ' Position Name'), (irow, 0), (1, 1),
                  LEFT_CEN, 2)
        sizer.Add(SimpleText(panel, 'Copy?'), (irow, 1), (1, 1), LEFT_CEN, 2)
        sizer.Add(SimpleText(panel, ' Position Name'), (irow, 2), (1, 1),
                  LEFT_CEN, 2)
        sizer.Add(SimpleText(panel, 'Copy?'), (irow, 3), (1, 1), LEFT_CEN, 2)

        irow += 1
        sizer.Add(wx.StaticLine(panel, size=(500, 2)), (irow, 0), (1, 4),
                  LEFT_CEN, 2)

        for ip, pname in enumerate(positions):
            cbox = self.checkboxes[pname] = wx.CheckBox(panel, -1, "")
            cbox.SetValue(True)

            if ip % 2 == 0:
                irow += 1
                icol = 0
            else:
                icol = 2
            sizer.Add(SimpleText(panel, "  %s  " % pname), (irow, icol),
                      (1, 1), LEFT_CEN, 2)
            sizer.Add(cbox, (irow, icol + 1), (1, 1), LEFT_CEN, 2)
        irow += 1
        sizer.Add(wx.StaticLine(panel, size=(500, 2)), (irow, 0), (1, 4),
                  LEFT_CEN, 2)

        pack(panel, sizer)
        panel.SetMinSize((700, 550))

        panel.SetupScrolling()

        mainsizer = wx.BoxSizer(wx.VERTICAL)
        mainsizer.Add(panel, 1, ALL_EXP | wx.GROW | wx.ALIGN_LEFT, 1)
        pack(self, mainsizer)

        self.SetMinSize((700, 550))
        self.Raise()
        self.Show()
Exemple #8
0
class TransferPositionsDialog(wx.Frame):
    """ transfer positions from offline microscope"""
    def __init__(self, offline, instname=None, instdb=None, parent=None):
        wx.Frame.__init__(self,
                          None,
                          -1,
                          title="Copy Positions from Offline Microscope")
        self.offline = offline
        self.instname = instname
        self.parent = parent
        self.instdb = instdb
        self.build_dialog()

    def build_dialog(self):
        positions = self.instdb.get_positionlist(self.offline)
        panel = scrolled.ScrolledPanel(self)
        self.checkboxes = OrderedDict()
        sizer = wx.GridBagSizer(len(positions) + 5, 4)
        sizer.SetVGap(2)
        sizer.SetHGap(3)
        bkws = dict(size=(95, -1))
        btn_ok = add_button(panel, "Copy Selected", action=self.onOK, **bkws)
        btn_all = add_button(panel, "Select All", action=self.onAll, **bkws)
        btn_none = add_button(panel, "Select None", action=self.onNone, **bkws)

        brow = wx.BoxSizer(wx.HORIZONTAL)
        brow.Add(btn_all, 0, ALL_EXP | wx.ALIGN_LEFT, 1)
        brow.Add(btn_none, 0, ALL_EXP | wx.ALIGN_LEFT, 1)
        brow.Add(btn_ok, 0, ALL_EXP | wx.ALIGN_LEFT, 1)

        self.suffix = wx.TextCtrl(panel, value="", size=(150, -1))
        self.xoff = FloatCtrl(panel, value=0, precision=3, size=(75, -1))
        self.yoff = FloatCtrl(panel, value=0, precision=3, size=(75, -1))
        self.zoff = FloatCtrl(panel, value=0, precision=3, size=(75, -1))

        irow = 0
        sizer.Add(brow, (irow, 0), (1, 4), LEFT_CEN, 2)

        irow += 1
        sizer.Add(SimpleText(panel, ' Add Suffix:'), (irow, 0), (1, 1),
                  LEFT_CEN, 2)
        sizer.Add(self.suffix, (irow, 1), (1, 3), LEFT_CEN, 2)

        irow += 1
        sizer.Add(SimpleText(panel, 'Offsets X, Y, Z:'), (irow, 0), (1, 1),
                  LEFT_CEN, 2)
        sizer.Add(self.xoff, (irow, 1), (1, 1), LEFT_CEN, 2)
        sizer.Add(self.yoff, (irow, 2), (1, 1), LEFT_CEN, 2)
        sizer.Add(self.zoff, (irow, 3), (1, 1), LEFT_CEN, 2)

        irow += 1
        sizer.Add(SimpleText(panel, ' Position Name'), (irow, 0), (1, 1),
                  LEFT_CEN, 2)
        sizer.Add(SimpleText(panel, 'Copy?'), (irow, 1), (1, 1), LEFT_CEN, 2)
        sizer.Add(SimpleText(panel, ' Position Name'), (irow, 2), (1, 1),
                  LEFT_CEN, 2)
        sizer.Add(SimpleText(panel, 'Copy?'), (irow, 3), (1, 1), LEFT_CEN, 2)

        irow += 1
        sizer.Add(wx.StaticLine(panel, size=(500, 2)), (irow, 0), (1, 4),
                  LEFT_CEN, 2)

        for ip, pname in enumerate(positions):
            cbox = self.checkboxes[pname] = wx.CheckBox(panel, -1, "")
            cbox.SetValue(True)

            if ip % 2 == 0:
                irow += 1
                icol = 0
            else:
                icol = 2
            sizer.Add(SimpleText(panel, "  %s  " % pname), (irow, icol),
                      (1, 1), LEFT_CEN, 2)
            sizer.Add(cbox, (irow, icol + 1), (1, 1), LEFT_CEN, 2)
        irow += 1
        sizer.Add(wx.StaticLine(panel, size=(500, 2)), (irow, 0), (1, 4),
                  LEFT_CEN, 2)

        pack(panel, sizer)
        panel.SetMinSize((700, 550))

        panel.SetupScrolling()

        mainsizer = wx.BoxSizer(wx.VERTICAL)
        mainsizer.Add(panel, 1, ALL_EXP | wx.GROW | wx.ALIGN_LEFT, 1)
        pack(self, mainsizer)

        self.SetMinSize((700, 550))
        self.Raise()
        self.Show()

    def onAll(self, event=None):
        for cbox in self.checkboxes.values():
            cbox.SetValue(True)

    def onNone(self, event=None):
        for cbox in self.checkboxes.values():
            cbox.SetValue(False)

    def onOK(self, event=None):
        if self.instname is not None and self.instdb is not None:
            suff = self.suffix.GetValue()

            idb = self.instdb
            uscope = idb.get_instrument(self.offline)
            sample = idb.get_instrument(self.instname)
            uname = uscope.name.replace(' ', '_')
            sname = sample.name.replace(' ', '_')
            conf_name = "CoordTrans:%s:%s" % (uname, sname)

            conf = json.loads(idb.scandb.get_config(conf_name).notes)
            source_pvs = conf['source']
            dest_pvs = conf['dest']
            rotmat = np.array(conf['rotmat'])
            upos = OrderedDict()
            for pname, cbox in self.checkboxes.items():
                if cbox.IsChecked():
                    v = idb.get_position_vals(self.offline, pname)
                    upos[pname] = [v[pvn] for pvn in source_pvs]

            newnames = upos.keys()
            vals = np.ones((4, len(upos)))
            for i, pname in enumerate(newnames):
                vals[0, i] = upos[pname][0]
                vals[1, i] = upos[pname][1]
                vals[2, i] = upos[pname][2]

            pred = np.dot(rotmat, vals)

            poslist = idb.get_positionlist(self.instname)
            saved_temp = None
            if len(poslist) < 1 and self.parent is not None:
                saved_temp = '__tmp__'
                if saved_temp in newnames:
                    saved_temp = '__tmp_a0012AZqspkwx9827nf917+o,ppa+'
                self.parent.onSave(saved_temp)
                time.sleep(3.0)
                poslist = idb.get_positionlist(self.instname)

            pos0 = idb.get_position_vals(self.instname, poslist[0])
            pvs = pos0.keys()
            pvs.sort()
            spos = OrderedDict()
            for pvname in pvs:
                spos[pvname] = 0.000

            xoffset = self.xoff.GetValue()
            yoffset = self.yoff.GetValue()
            zoffset = self.zoff.GetValue()
            xpv, ypv, zpv = dest_pvs
            for i, pname in enumerate(newnames):
                spos[xpv] = pred[0, i] + xoffset
                spos[ypv] = pred[1, i] + yoffset
                spos[zpv] = pred[2, i] + zoffset
                nlabel = '%s%s' % (pname, suff)
                idb.save_position(self.instname, nlabel, spos)
            if saved_temp is not None:
                self.parent.onErase(posname=saved_temp, query=False)
        self.Destroy()

    def onCancel(self, event=None):
        self.Destroy()