예제 #1
0
class TelemetrySoftware(wx.Frame):
    def __init__(self):
        super(TelemetrySoftware, self).__init__(None, title="URSS Telemetry")

        # initial data values
        self.voltage = MAX_VOLTAGE
        self.amperage = MIN_AMPERAGE
        self.rpm = MIN_RPM
        self.controllerTemp = MIN_CONTROLLER_TEMP

        # plot data
        self.voltage_values = []
        self.amperage_values = []
        self.timestamps = []
        self.goalVoltageLineDisplayed = False

        # fake telemetry flag
        self.fake_telemetry = True
        self.fake_telemetry_counter = 0

        self.Maximize(True)
        self.InitUI()
        self.InitTelemetryThread()
        self.Centre()
        self.Show()

    def InitUI(self):
        panelRoot = wx.Panel(self)
        panelRootSizer = wx.BoxSizer(wx.VERTICAL)

        topSplitter = wx.SplitterWindow(panelRoot,
                                        style=wx.SP_LIVE_UPDATE | wx.SP_3DSASH)
        topVerticalSplitter = wx.SplitterWindow(topSplitter,
                                                style=wx.SP_LIVE_UPDATE
                                                | wx.SP_3DSASH)

        #############################################
        #   TOP-LEFT PANEL (STATUS AND CONTROLS)    #
        #############################################

        panelTopLeft = wx.Panel(topVerticalSplitter)
        panelTopLeftSizer = wx.BoxSizer(wx.VERTICAL)

        # create gauges and set initial values
        self.voltageGauge = wx.Gauge(panelTopLeft, -1,
                                     MAX_VOLTAGE - MIN_VOLTAGE, (0, 0),
                                     (250, 25))
        self.voltageGauge.SetValue(self.voltage - MIN_VOLTAGE)

        self.amperageGauge = wx.Gauge(panelTopLeft, -1,
                                      MAX_AMPERAGE - MIN_AMPERAGE, (0, 0),
                                      (250, 25))
        self.amperageGauge.SetValue(self.amperage - MIN_AMPERAGE)

        self.rpmGauge = wx.Gauge(panelTopLeft, -1, MAX_RPM - MIN_RPM, (0, 0),
                                 (250, 25))
        self.rpmGauge.SetValue(self.rpm - MIN_RPM)

        self.controllerTempGauge = wx.Gauge(
            panelTopLeft, -1, MAX_CONTROLLER_TEMP - MIN_CONTROLLER_TEMP,
            (0, 0), (250, 25))
        self.controllerTempGauge.SetValue(self.controllerTemp -
                                          MIN_CONTROLLER_TEMP)

        # create labels
        self.voltageLabel = wx.StaticText(
            panelTopLeft, -1, "Voltage (" + str(self.voltage) + ")")
        self.amperagLabel = wx.StaticText(
            panelTopLeft, -1, "Amperage (" + str(self.amperage) + ")")
        self.rpmLabel = wx.StaticText(panelTopLeft, -1,
                                      "RPM (" + str(self.rpm) + ")")
        self.controllerTempLabel = wx.StaticText(
            panelTopLeft, -1,
            "Controller Temperature (" + str(self.controllerTemp) + ")")

        # Add voltage Gauge and label to BoxSizer
        panelTopLeftSizer.Add(self.voltageLabel, 0, wx.ALIGN_CENTRE_HORIZONTAL)
        panelTopLeftSizer.Add(self.voltageGauge, 1, wx.ALIGN_CENTRE_HORIZONTAL)
        # Add amperage Gauge and label to BoxSizer
        panelTopLeftSizer.Add(self.amperagLabel, 0, wx.ALIGN_CENTRE_HORIZONTAL)
        panelTopLeftSizer.Add(self.amperageGauge, 1,
                              wx.ALIGN_CENTRE_HORIZONTAL)
        # Add RPM Gauge and label to BoxSizer
        panelTopLeftSizer.Add(self.rpmLabel, 0, wx.ALIGN_CENTRE_HORIZONTAL)
        panelTopLeftSizer.Add(self.rpmGauge, 1, wx.ALIGN_CENTRE_HORIZONTAL)
        # Add controller temp Gauge and label to BoxSizer
        panelTopLeftSizer.Add(self.controllerTempLabel, 0,
                              wx.ALIGN_CENTRE_HORIZONTAL)
        panelTopLeftSizer.Add(self.controllerTempGauge, 1,
                              wx.ALIGN_CENTRE_HORIZONTAL)

        # Add BoxSizer to panel
        panelTopLeft.SetSizer(panelTopLeftSizer)

        ################################
        #   TOP-RIGHT PANEL (GRAPH)    #
        ################################

        panelTopRight = wx.Panel(topVerticalSplitter)
        panelTopRightSizer = wx.BoxSizer(wx.VERTICAL)

        # create top button bar
        topButtonPanel = wx.Panel(panelTopRight, -1)
        topButtonSizer = wx.BoxSizer(wx.HORIZONTAL)

        goalVoltageLabel = wx.StaticText(
            topButtonPanel, -1, '    End Goal Voltage Value (V):    ')
        self.goalEndVoltage = FloatCtrl(topButtonPanel,
                                        size=(100, -1),
                                        value=34.5,
                                        precision=1)
        endTimeLabel = wx.StaticText(topButtonPanel, -1,
                                     '    End Time (min):    ')
        self.endTime = FloatCtrl(topButtonPanel,
                                 size=(100, -1),
                                 value=120,
                                 precision=0)
        plotGoalVoltageButton = wx.Button(topButtonPanel,
                                          -1,
                                          'Plot Goal Voltage',
                                          size=(250, -1))
        plotGoalVoltageButton.Bind(wx.EVT_BUTTON, self.OnPlotGoalVoltage)

        topButtonSizer.Add(goalVoltageLabel)
        topButtonSizer.Add(self.goalEndVoltage)
        topButtonSizer.Add(endTimeLabel)
        topButtonSizer.Add(self.endTime)
        topButtonSizer.Add(plotGoalVoltageButton)

        topButtonPanel.SetSizer(topButtonSizer)
        topButtonSizer.Fit(topButtonPanel)

        # create plot panel

        self.plotPanel = PlotPanel(panelTopRight)

        # create bottom button bar

        bottomButtonPanel = wx.Panel(panelTopRight, -1)
        bottomButtonSizer = wx.BoxSizer(wx.HORIZONTAL)

        exportButton = wx.Button(bottomButtonPanel,
                                 -1,
                                 'Export Plot to CSV',
                                 size=(250, -1))
        exportButton.Bind(wx.EVT_BUTTON, self.ExportPlotDataToCSV)
        resetButton = wx.Button(bottomButtonPanel,
                                -1,
                                'Reset Graph',
                                size=(250, -1))
        resetButton.Bind(wx.EVT_BUTTON, self.ResetGraph)

        bottomButtonSizer.Add(exportButton, 1)
        bottomButtonSizer.Add(resetButton, 1)

        bottomButtonPanel.SetSizer(bottomButtonSizer)
        bottomButtonSizer.Fit(bottomButtonPanel)

        # Add panels to top right sizer
        panelTopRightSizer.Add(topButtonPanel, 0, wx.EXPAND | wx.ALL)
        panelTopRightSizer.Add(self.plotPanel, 1, wx.EXPAND | wx.ALL)
        panelTopRightSizer.Add(bottomButtonPanel, 0)

        # Add BoxSizer to panel
        panelTopRight.SetSizer(panelTopRightSizer)

        # add top panels to vertical splitter
        topVerticalSplitter.SplitVertically(panelTopLeft, panelTopRight)
        topVerticalSplitter.SetSashGravity(0.25)

        #############################################
        #   BOTTOM PANEL (LOG & TELEMETRY INPUT)    #
        #############################################

        panelBottom = wx.Panel(topSplitter)
        panelBottomSizer = wx.BoxSizer(wx.VERTICAL)

        self.logPane = LogPane(panelBottom)

        logPaneLabel = wx.StaticText(
            panelBottom,
            label="Telemetry Message Log (Last 100 messages shown):")
        logPaneLabel.SetFont(
            wx.Font(14, wx.FONTFAMILY_TELETYPE, wx.NORMAL, wx.BOLD))
        panelBottomSizer.Add(logPaneLabel, 0, wx.ALIGN_TOP)
        panelBottomSizer.Add(self.logPane, 1, wx.EXPAND | wx.ALL)

        panelBottom.SetSizer(panelBottomSizer)

        topSplitter.SplitHorizontally(topVerticalSplitter, panelBottom)
        topSplitter.SetSashGravity(0.75)

        panelRootSizer.Add(topSplitter, 1, wx.EXPAND | wx.ALL)
        panelRoot.SetSizer(panelRootSizer)

    def InitTelemetryThread(self):
        print("Initializing telemetry thread...")

        if not self.fake_telemetry:
            success = False
            try:
                self.serial = serial.Serial("/dev/cu.usbserial-DN01236H",
                                            57600)
                success = True
                if not self.serial.is_open:
                    success = False
            except Exception:
                print("Could not open serial radio!")

            if not success:
                # If we fail to connect to serial, display error and then quitself.
                dial = wx.MessageDialog(
                    None,
                    'Could not connect to serial radio. Please plug in the serial radio adapter and restart your computer!',
                    'Error', wx.OK | wx.ICON_ERROR)
                dial.ShowModal()
                exit(0)

        thread = threading.Thread(target=self.TelemetryThread)
        thread.start()

        print("Done.")

    def TelemetryCallback(self, message):
        timestamp = int(round(time.time()))
        if len(self.timestamps) == 0:
            self.t0 = timestamp

        self.logPane.AddLine(message)

        if not self.fake_telemetry:
            # parse JSON message
            m = json.loads(message)
            split_message = m['message'].split(',')
            if split_message[0] == 'BATTERY':
                self.voltage = float(split_message[2][2:]) / 1000
                self.amperage = float(split_message[4][2:]) / 1000 * -1

        # add values to lists
        self.voltage_values.append(self.voltage)
        self.amperage_values.append(self.amperage)
        self.timestamps.append(timestamp - self.t0)

        # update gauges and plot
        self.UpdateGauges()
        self.UpdatePlot()

    def UpdateGauges(self):
        self.voltageGauge.SetValue(self.voltage - MIN_VOLTAGE)
        self.voltageLabel.SetLabel("Voltage (" + str(self.voltage) + "/" +
                                   str(MAX_VOLTAGE) + ")")
        self.amperageGauge.SetValue(self.amperage - MIN_AMPERAGE)
        self.amperagLabel.SetLabel("Amperage (" + str(self.amperage) + "/" +
                                   str(MAX_AMPERAGE) + ")")
        self.rpmGauge.SetValue(self.rpm - MIN_RPM)
        self.rpmLabel.SetLabelText("RPM (" + str(self.rpm) + "/" +
                                   str(MAX_RPM) + ")")
        self.controllerTempGauge.SetValue(self.controllerTemp -
                                          MIN_CONTROLLER_TEMP)
        self.controllerTempLabel.SetLabelText("Controller Temperature (" +
                                              str(self.controllerTemp) + ")")

    def UpdatePlot(self):
        v_n = len(self.voltage_values)
        tdat = np.array(self.timestamps)
        vdat = np.array(self.voltage_values)
        adat = np.array(self.amperage_values)
        if v_n <= 2:
            self.plotPanel.plot(tdat,
                                vdat,
                                xlabel='Time (s from start)',
                                ylabel='Voltage (V)',
                                label='Voltage',
                                style='solid')
            self.plotPanel.oplot(tdat,
                                 adat,
                                 y2label='Amperage (A)',
                                 side='right',
                                 label='Amperage',
                                 style='long dashed',
                                 show_legend=True)
        else:
            self.plotPanel.update_line(0, tdat, vdat, draw=True)
            self.plotPanel.update_line(1, tdat, adat, draw=True)

    def OnPlotGoalVoltage(self, event=None):
        v = float(self.goalEndVoltage.GetValue())
        t = int(self.endTime.GetValue()) * 60
        if len(self.voltage_values) > 2 and v <= self.voltage and t >= 0:
            tdat = np.linspace(0, t, t)
            vdat = np.linspace(self.voltage_values[0], v, t)
            if not self.goalVoltageLineDisplayed:
                self.goalVoltageLineDisplayed = True
                self.plotPanel.oplot(tdat,
                                     vdat,
                                     label='Goal Voltage',
                                     style='short dashed')
            else:
                self.plotPanel.update_line(2, tdat, vdat, draw=True)

    def ResetGraph(self, event=None):
        del self.timestamps[:]
        del self.voltage_values[:]
        del self.amperage_values[:]
        self.goalVoltageLineDisplayed = False

    def ExportPlotDataToCSV(self, event=None):
        filename = 'exported_data_' + str(int(round(
            time.time() * 1000))) + '.csv'
        with open(filename, 'wb') as datafile:
            w = csv.writer(datafile)
            w.writerow(['Time (s)', 'Voltage (V)', 'Amperage (A)'])
            for i in range(len(self.timestamps)):
                w.writerow([
                    str(self.timestamps[i]),
                    str(self.voltage_values[i]),
                    str(self.amperage_values[i])
                ])

    def TelemetryThread(self):
        while True:
            if self.fake_telemetry:
                self.fake_telemetry_counter += 1
                wx.CallAfter(
                    self.TelemetryCallback, "Fake Telemetry Element " +
                    str(self.fake_telemetry_counter) + "\n")
                time.sleep(0.5)
            else:
                line = self.serial.readline()
                wx.CallAfter(self.TelemetryCallback, line)
예제 #2
0
class AthenaImporter(wx.Frame) :
    """Import Athena File"""
    def __init__(self, parent, filename=None, read_ok_cb=None,
                 size=(725, 450), _larch=None):
        self.parent = parent
        self.filename = filename
        self.larch = _larch
        self.read_ok_cb = read_ok_cb

        self.colors = GUIColors()

        wx.Frame.__init__(self, parent, -1,   size=size, style=FRAMESTYLE)
        splitter  = wx.SplitterWindow(self, style=wx.SP_LIVE_UPDATE)
        splitter.SetMinimumPaneSize(200)

        leftpanel = wx.Panel(splitter)
        ltop = wx.Panel(leftpanel)

        sel_none = Button(ltop, 'Select None', size=(100, 30), action=self.onSelNone)
        sel_all  = Button(ltop, 'Select All', size=(100, 30), action=self.onSelAll)
        sel_imp  = Button(ltop, 'Import Selected Groups', size=(200, 30), action=self.onOK)

        self.select_imported = sel_imp
        self.grouplist = FileCheckList(leftpanel, select_action=self.onShowGroup)

        tsizer = wx.GridBagSizer(2, 2)
        tsizer.Add(sel_all, (0, 0), (1, 1), LCEN, 0)
        tsizer.Add(sel_none,  (0, 1), (1, 1), LCEN, 0)
        tsizer.Add(sel_imp,  (1, 0), (1, 2), LCEN, 0)

        pack(ltop, tsizer)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(ltop, 0, LCEN|wx.GROW, 1)
        sizer.Add(self.grouplist, 1, LCEN|wx.GROW|wx.ALL, 1)
        pack(leftpanel, sizer)

        # right hand side
        rightpanel = wx.Panel(splitter)

        self.SetTitle("Reading Athena Project '%s'" % self.filename)
        self.title = SimpleText(rightpanel, self.filename, font=Font(13),
                                colour=self.colors.title, style=LCEN)

        self.plotpanel = PlotPanel(rightpanel, messenger=self.plot_messages)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.title, 0, LCEN, 2)
        sizer.Add(self.plotpanel, 0, LCEN, 2)
        pack(rightpanel, sizer)

        splitter.SplitVertically(leftpanel, rightpanel, 1)

        self.statusbar = self.CreateStatusBar(2, 0)
        self.statusbar.SetStatusWidths([-3, -1])
        statusbar_fields = [self.filename, ""]
        for i in range(len(statusbar_fields)):
            self.statusbar.SetStatusText(statusbar_fields[i], i)

        self.a_project = read_athena(self.filename, do_bkg=False, do_fft=False,
                                     _larch=_larch)
        self.allgroups = []
        for item in dir(self.a_project):
            if not item.startswith('_athena_'):
                self.allgroups.append(item)
                self.grouplist.Append(item)
        self.Show()
        self.Raise()

    def plot_messages(self, msg, panel=1):
        self.SetStatusText(msg, panel)

    def onOK(self, event=None):
        """generate script to import groups"""
        namelist = [str(n) for n in self.grouplist.GetCheckedStrings()]
        if len(namelist) == 0:

            cancel = Popup(self, """No data groups selected.
        Cancel import from this project?""", 'Cancel Import?',
                           style=wx.YES_NO)
            if wx.ID_YES == cancel:
                self.Destroy()
            else:
                return

        if self.read_ok_cb is not None:
            self.read_ok_cb(self.filename, namelist)

        self.Destroy()

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

    def onSelAll(self, event=None):
        self.grouplist.SetCheckedStrings(self.allgroups)

    def onSelNone(self, event=None):
        self.grouplist.SetCheckedStrings([])

    def onShowGroup(self, event=None):
        """column selections changed calc xdat and ydat"""
        gname = event.GetString()
        grp = getattr(self.a_project, gname)
        glist = list(self.grouplist.GetCheckedStrings())
        if gname not in glist:
            glist.append(gname)
        self.grouplist.SetCheckedStrings(glist)
        if hasattr(grp, 'energy') and hasattr(grp, 'mu'):
            self.plotpanel.plot(grp.energy, grp.mu,
                                xlabel='Energy', ylabel='mu',title=gname)
예제 #3
0
class AthenaImporter(wx.Frame):
    """Import Athena File"""
    def __init__(self,
                 parent,
                 filename=None,
                 read_ok_cb=None,
                 size=(725, 450),
                 _larch=None):
        self.parent = parent
        self.filename = filename
        self.larch = _larch
        self.read_ok_cb = read_ok_cb

        self.colors = GUIColors()

        wx.Frame.__init__(self, parent, -1, size=size, style=FRAMESTYLE)
        splitter = wx.SplitterWindow(self, style=wx.SP_LIVE_UPDATE)
        splitter.SetMinimumPaneSize(200)

        leftpanel = wx.Panel(splitter)
        ltop = wx.Panel(leftpanel)

        sel_none = Button(ltop,
                          'Select None',
                          size=(100, 30),
                          action=self.onSelNone)
        sel_all = Button(ltop,
                         'Select All',
                         size=(100, 30),
                         action=self.onSelAll)
        sel_imp = Button(ltop,
                         'Import Selected Groups',
                         size=(200, 30),
                         action=self.onOK)

        self.select_imported = sel_imp
        self.select_imported.Disable()

        self.grouplist = FileCheckList(leftpanel,
                                       select_action=self.onShowGroup)
        self.grouplist.SetBackgroundColour(wx.Colour(255, 255, 255))

        tsizer = wx.GridBagSizer(2, 2)
        tsizer.Add(sel_all, (0, 0), (1, 1), LCEN, 0)
        tsizer.Add(sel_none, (0, 1), (1, 1), LCEN, 0)
        tsizer.Add(sel_imp, (1, 0), (1, 2), LCEN, 0)

        pack(ltop, tsizer)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(ltop, 0, LCEN | wx.GROW, 1)
        sizer.Add(self.grouplist, 1, LCEN | wx.GROW | wx.ALL, 1)
        pack(leftpanel, sizer)

        # right hand side
        rightpanel = wx.Panel(splitter)

        self.SetTitle("Reading Athena Project '%s'" % self.filename)
        self.title = SimpleText(rightpanel,
                                self.filename,
                                font=Font(13),
                                colour=self.colors.title,
                                style=LCEN)

        self.plotpanel = PlotPanel(rightpanel, messenger=self.plot_messages)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.title, 0, LCEN, 2)
        sizer.Add(self.plotpanel, 0, LCEN, 2)
        pack(rightpanel, sizer)

        splitter.SplitVertically(leftpanel, rightpanel, 1)

        self.statusbar = self.CreateStatusBar(2, 0)
        self.statusbar.SetStatusWidths([-3, -1])
        statusbar_fields = [self.filename, ""]
        for i in range(len(statusbar_fields)):
            self.statusbar.SetStatusText(statusbar_fields[i], i)

        self.all = read_athena(self.filename,
                               do_bkg=False,
                               do_fft=False,
                               with_journal=False,
                               _larch=_larch)
        for item in dir(self.all):
            self.grouplist.Append(item)
        self.Show()
        self.Raise()

    def plot_messages(self, msg, panel=1):
        self.SetStatusText(msg, panel)

    def onOK(self, event=None):
        """generate script to import groups"""
        namelist = [str(n) for n in self.grouplist.GetCheckedStrings()]

        if self.read_ok_cb is not None and len(namelist) > 0:
            self.read_ok_cb(self.filename, namelist)

        self.Destroy()

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

    def onSelAll(self, event=None):
        self.grouplist.SetCheckedStrings(dir(self.all))
        self.select_imported.Enable()

    def onSelNone(self, event=None):
        self.grouplist.SetCheckedStrings([])
        self.select_imported.Disable()

    def onShowGroup(self, event=None):
        """column selections changed calc xdat and ydat"""
        self.select_imported.Enable()
        gname = event.GetString()
        grp = getattr(self.all, gname)
        glist = list(self.grouplist.GetCheckedStrings())
        if gname not in glist:
            glist.append(gname)
        self.grouplist.SetCheckedStrings(glist)
        if hasattr(grp, 'energy') and hasattr(grp, 'mu'):
            self.plotpanel.plot(grp.energy,
                                grp.mu,
                                xlabel='Energy',
                                ylabel='mu',
                                title=gname)
예제 #4
0
class ColumnDataFileFrame(wx.Frame):
    """Column Data File, select columns"""
    def __init__(self,
                 parent,
                 filename=None,
                 groupname=None,
                 last_array_sel=None,
                 read_ok_cb=None,
                 edit_groupname=True,
                 _larch=None):
        self.parent = parent
        self._larch = _larch
        self.path = filename

        group = self.initgroup = self.read_column_file(self.path)
        self.subframes = {}
        self.workgroup = Group(raw=group)
        for attr in ('path', 'filename', 'groupname', 'datatype',
                     'array_labels'):
            setattr(self.workgroup, attr, getattr(group, attr, None))

        arr_labels = [l.lower() for l in self.initgroup.array_labels]

        if self.workgroup.datatype is None:
            self.workgroup.datatype = 'raw'
            if ('energ' in arr_labels[0] or 'energ' in arr_labels[1]):
                self.workgroup.datatype = 'xas'

        self.read_ok_cb = read_ok_cb
        self.array_sel = {
            'xpop': '',
            'xarr': None,
            'ypop': '',
            'yop': '/',
            'yarr1': None,
            'yarr2': None,
            'use_deriv': False
        }

        if last_array_sel is not None:
            self.array_sel.update(last_array_sel)

        if self.array_sel['yarr2'] is None and 'i0' in arr_labels:
            self.array_sel['yarr2'] = 'i0'

        if self.array_sel['yarr1'] is None:
            if 'itrans' in arr_labels:
                self.array_sel['yarr1'] = 'itrans'
            elif 'i1' in arr_labels:
                self.array_sel['yarr1'] = 'i1'
        message = "Data Columns for %s" % group.filename
        wx.Frame.__init__(self,
                          None,
                          -1,
                          'Build Arrays from Data Columns for %s' %
                          group.filename,
                          style=FRAMESTYLE)

        self.SetFont(Font(10))

        panel = wx.Panel(self)
        self.SetMinSize((600, 600))
        self.colors = GUIColors()

        # title row
        title = SimpleText(panel,
                           message,
                           font=Font(13),
                           colour=self.colors.title,
                           style=LCEN)

        opts = dict(action=self.onUpdate, size=(120, -1))
        yarr_labels = self.yarr_labels = arr_labels + ['1.0', '0.0', '']
        xarr_labels = self.xarr_labels = arr_labels + ['_index']

        self.xarr = Choice(panel, choices=xarr_labels, **opts)
        self.yarr1 = Choice(panel, choices=arr_labels, **opts)
        self.yarr2 = Choice(panel, choices=yarr_labels, **opts)
        self.yerr_arr = Choice(panel, choices=yarr_labels, **opts)
        self.yerr_arr.Disable()

        self.datatype = Choice(panel, choices=DATATYPES, **opts)
        self.datatype.SetStringSelection(self.workgroup.datatype)

        opts['size'] = (50, -1)
        self.yop = Choice(panel, choices=ARR_OPS, **opts)

        opts['size'] = (120, -1)

        self.use_deriv = Check(panel,
                               label='use derivative',
                               default=self.array_sel['use_deriv'],
                               **opts)

        self.xpop = Choice(panel, choices=XPRE_OPS, **opts)
        self.ypop = Choice(panel, choices=YPRE_OPS, **opts)

        opts['action'] = self.onYerrChoice
        self.yerr_op = Choice(panel, choices=YERR_OPS, **opts)
        self.yerr_op.SetSelection(0)

        self.yerr_const = FloatCtrl(panel, value=1, precision=4, size=(90, -1))

        ylab = SimpleText(panel, 'Y = ')
        xlab = SimpleText(panel, 'X = ')
        yerr_lab = SimpleText(panel, 'Yerror = ')
        self.xsuf = SimpleText(panel, '')
        self.ysuf = SimpleText(panel, '')

        self.xpop.SetStringSelection(self.array_sel['xpop'])
        self.ypop.SetStringSelection(self.array_sel['ypop'])
        self.yop.SetStringSelection(self.array_sel['yop'])
        if '(' in self.array_sel['ypop']:
            self.ysuf.SetLabel(')')

        ixsel, iysel, iy2sel = 0, 1, len(yarr_labels) - 1
        if self.array_sel['xarr'] in xarr_labels:
            ixsel = xarr_labels.index(self.array_sel['xarr'])
        if self.array_sel['yarr1'] in arr_labels:
            iysel = arr_labels.index(self.array_sel['yarr1'])
        if self.array_sel['yarr2'] in yarr_labels:
            iy2sel = yarr_labels.index(self.array_sel['yarr2'])
        self.xarr.SetSelection(ixsel)
        self.yarr1.SetSelection(iysel)
        self.yarr2.SetSelection(iy2sel)

        bpanel = wx.Panel(panel)
        bsizer = wx.BoxSizer(wx.HORIZONTAL)
        _ok = Button(bpanel, 'OK', action=self.onOK)
        _cancel = Button(bpanel, 'Cancel', action=self.onCancel)
        _edit = Button(bpanel, 'Edit Array Names', action=self.onEditNames)
        bsizer.Add(_ok)
        bsizer.Add(_cancel)
        bsizer.Add(_edit)
        _ok.SetDefault()
        pack(bpanel, bsizer)

        sizer = wx.GridBagSizer(4, 8)
        sizer.Add(title, (0, 0), (1, 7), LCEN, 5)

        ir = 1
        sizer.Add(xlab, (ir, 0), (1, 1), LCEN, 0)
        sizer.Add(self.xpop, (ir, 1), (1, 1), CEN, 0)
        sizer.Add(self.xarr, (ir, 2), (1, 1), CEN, 0)
        sizer.Add(self.xsuf, (ir, 3), (1, 1), CEN, 0)

        ir += 1
        sizer.Add(ylab, (ir, 0), (1, 1), LCEN, 0)
        sizer.Add(self.ypop, (ir, 1), (1, 1), CEN, 0)
        sizer.Add(self.yarr1, (ir, 2), (1, 1), CEN, 0)
        sizer.Add(self.yop, (ir, 3), (1, 1), CEN, 0)
        sizer.Add(self.yarr2, (ir, 4), (1, 1), CEN, 0)
        sizer.Add(self.ysuf, (ir, 5), (1, 1), CEN, 0)
        sizer.Add(self.use_deriv, (ir, 6), (1, 1), LCEN, 0)

        ir += 1
        sizer.Add(yerr_lab, (ir, 0), (1, 1), LCEN, 0)
        sizer.Add(self.yerr_op, (ir, 1), (1, 1), CEN, 0)
        sizer.Add(self.yerr_arr, (ir, 2), (1, 1), CEN, 0)
        sizer.Add(SimpleText(panel, 'Value:'), (ir, 3), (1, 1), CEN, 0)
        sizer.Add(self.yerr_const, (ir, 4), (1, 2), CEN, 0)

        ir += 1
        sizer.Add(SimpleText(panel, 'Data Type:'), (ir, 0), (1, 1), LCEN, 0)
        sizer.Add(self.datatype, (ir, 1), (1, 2), LCEN, 0)

        ir += 1
        self.wid_groupname = wx.TextCtrl(panel,
                                         value=group.groupname,
                                         size=(240, -1))
        if not edit_groupname:
            self.wid_groupname.Disable()

        sizer.Add(SimpleText(panel, 'Group Name:'), (ir, 0), (1, 1), LCEN, 0)
        sizer.Add(self.wid_groupname, (ir, 1), (1, 2), LCEN, 0)

        ir += 1
        sizer.Add(bpanel, (ir, 0), (1, 5), LCEN, 3)

        pack(panel, sizer)

        self.nb = fnb.FlatNotebook(self, -1, agwStyle=FNB_STYLE)
        self.nb.SetTabAreaColour(wx.Colour(248, 248, 240))
        self.nb.SetActiveTabColour(wx.Colour(254, 254, 195))
        self.nb.SetNonActiveTabTextColour(wx.Colour(40, 40, 180))
        self.nb.SetActiveTabTextColour(wx.Colour(80, 0, 0))

        self.plotpanel = PlotPanel(self, messenger=self.plot_messages)
        textpanel = wx.Panel(self)
        ftext = wx.TextCtrl(textpanel,
                            style=wx.TE_MULTILINE | wx.TE_READONLY,
                            size=(400, 250))

        ftext.SetValue(group.text)
        ftext.SetFont(Font(10))

        textsizer = wx.BoxSizer(wx.VERTICAL)
        textsizer.Add(ftext, 1, LCEN | wx.GROW, 1)
        pack(textpanel, textsizer)

        self.nb.AddPage(textpanel, ' Text of Data File ', True)
        self.nb.AddPage(self.plotpanel, ' Plot of Selected Arrays ', True)

        mainsizer = wx.BoxSizer(wx.VERTICAL)
        mainsizer.Add(panel, 0, wx.GROW | wx.ALL, 2)
        mainsizer.Add(self.nb, 1, LCEN | wx.GROW, 2)
        pack(self, mainsizer)

        self.statusbar = self.CreateStatusBar(2, 0)
        self.statusbar.SetStatusWidths([-1, -1])
        statusbar_fields = [group.filename, ""]
        for i in range(len(statusbar_fields)):
            self.statusbar.SetStatusText(statusbar_fields[i], i)

        self.Show()
        self.Raise()
        self.onUpdate(self)

    def read_column_file(self, path):
        """read column file, generally as initial read"""
        parent, filename = os.path.split(path)
        with open(path, 'r') as fh:
            lines = fh.readlines()

        text = ''.join(lines)
        line1 = lines[0].lower()

        reader = 'read_ascii'
        if 'epics stepscan file' in line1:
            reader = 'read_gsexdi'
        elif 'xdi' in line1:
            reader = 'read_xdi'
        elif 'epics scan' in line1:
            reader = 'read_gsescan'

        tmpname = '_tmp_file_'
        read_cmd = "%s = %s('%s')" % (tmpname, reader, path)
        self.reader = reader
        deeplarch = self._larch._larch
        try:
            deeplarch.eval(read_cmd, add_history=False)
        except:
            pass
        if deeplarch.error:
            # self._larch.input.clear()
            msg = ["Error trying to read '%s':" % path, ""]
            for err in deeplarch.error:
                exc_name, errmsg = err.get_error()
                msg.append(errmsg)

            title = "Cannot read %s" % path
            r = Popup(self.parent, "\n".join(msg), title)
            return None

        group = self._larch.symtable.get_symbol(tmpname)
        self._larch.symtable.del_symbol(tmpname)

        group.text = text
        group.path = path
        group.filename = filename
        group.groupname = file2groupname(filename,
                                         symtable=self._larch.symtable)
        return group

    def show_subframe(self, name, frameclass, **opts):
        shown = False
        if name in self.subframes:
            try:
                self.subframes[name].Raise()
                shown = True
            except:
                del self.subframes[name]
        if not shown:
            self.subframes[name] = frameclass(self, **opts)

    def onEditNames(self, evt=None):
        self.show_subframe('editcol',
                           EditColumnFrame,
                           group=self.workgroup,
                           on_ok=self.set_array_labels)

    def set_array_labels(self, arr_labels):
        self.workgroup.array_labels = arr_labels
        yarr_labels = self.yarr_labels = arr_labels + ['1.0', '0.0', '']
        xarr_labels = self.xarr_labels = arr_labels + ['_index']

        def update(wid, choices):
            curstr = wid.GetStringSelection()
            curind = wid.GetSelection()
            wid.SetChoices(choices)
            if curstr in choices:
                wid.SetStringSelection(curstr)
            else:
                wid.SetSelection(curind)

        update(self.xarr, xarr_labels)
        update(self.yarr1, yarr_labels)
        update(self.yarr2, yarr_labels)
        update(self.yerr_arr, yarr_labels)
        self.onUpdate()

    def onOK(self, event=None):
        """ build arrays according to selection """
        if self.wid_groupname is not None:
            groupname = fix_varname(self.wid_groupname.GetValue())

        yerr_op = self.yerr_op.GetStringSelection().lower()
        yerr_expr = '1'
        if yerr_op.startswith('const'):
            yerr_expr = "%f" % self.yerr_const.GetValue()
        elif yerr_op.startswith('array'):
            yerr_expr = '%%s.data[%i, :]' % self.yerr_arr.GetSelection()
        elif yerr_op.startswith('sqrt'):
            yerr_expr = 'sqrt(%s.ydat)'
        self.expressions['yerr'] = yerr_expr

        # generate script to pass back to calling program:
        labels = ', '.join(self.workgroup.array_labels)
        read_cmd = "%s('{path:s}', labels='%s')" % (self.reader, labels)

        buff = ["{group:s} = %s" % read_cmd, "{group:s}.path = '{path:s}'"]

        for attr in ('datatype', 'plot_xlabel', 'plot_ylabel'):
            val = getattr(self.workgroup, attr)
            buff.append("{group:s}.%s = '%s'" % (attr, val))

        for aname in ('xdat', 'ydat', 'yerr'):
            expr = self.expressions[aname].replace('%s', '{group:s}')
            buff.append("{group:s}.%s = %s" % (aname, expr))

        if getattr(self.workgroup, 'datatype', 'raw') == 'xas':
            if self.reader == 'read_gsescan':
                buff.append("{group:s}.energy = {group:s}.x")
            else:
                buff.append("{group:s}.energy = {group:s}.xdat")
            buff.append("{group:s}.mu = {group:s}.ydat")

        script = "\n".join(buff)

        if self.read_ok_cb is not None:
            self.read_ok_cb(script,
                            self.path,
                            groupname=groupname,
                            array_sel=self.array_sel)

        self.Destroy()

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

    def onYerrChoice(self, evt=None):
        yerr_choice = evt.GetString()
        self.yerr_arr.Disable()
        self.yerr_const.Disable()
        if 'const' in yerr_choice.lower():
            self.yerr_const.Enable()
        elif 'array' in yerr_choice.lower():
            self.yerr_arr.Enable()
        self.onUpdate()

    def onUpdate(self, value=None, evt=None):
        """column selections changed calc xdat and ydat"""
        # dtcorr = self.dtcorr.IsChecked()
        # print("Column Frame on Update ")

        dtcorr = False
        use_deriv = self.use_deriv.IsChecked()
        rawgroup = self.initgroup
        workgroup = self.workgroup
        rdata = self.initgroup.data

        # print("onUpdate ", dir(rawgroup))
        ix = self.xarr.GetSelection()
        xname = self.xarr.GetStringSelection()

        exprs = dict(xdat=None, ydat=None, yerr=None)

        ncol, npts = rdata.shape
        if xname.startswith('_index') or ix >= ncol:
            workgroup.xdat = 1.0 * np.arange(npts)
            xname = '_index'
            exprs['xdat'] = 'arange(%i)' % npts
        else:
            workgroup.xdat = rdata[ix, :]
            exprs['xdat'] = '%%s.data[%i, : ]' % ix

        workgroup.datatype = self.datatype.GetStringSelection().strip().lower()

        def pre_op(opwid, arr):
            opstr = opwid.GetStringSelection().strip()
            suf = ''
            if opstr in ('-log(', 'log('):
                suf = ')'
                if opstr == 'log(':
                    arr = np.log(arr)
                elif opstr == '-log(':
                    arr = -np.log(arr)
            return suf, opstr, arr

        try:
            xsuf, xpop, workgroup.xdat = pre_op(self.xpop, workgroup.xdat)
            self.xsuf.SetLabel(xsuf)
            exprs['xdat'] = '%s%s%s' % (xpop, exprs['xdat'], xsuf)
        except:
            return
        try:
            xunits = rawgroup.array_units[ix].strip()
            xlabel = '%s (%s)' % (xname, xunits)
        except:
            xlabel = xname

        yname1 = self.yarr1.GetStringSelection().strip()
        yname2 = self.yarr2.GetStringSelection().strip()
        iy1 = self.yarr1.GetSelection()
        iy2 = self.yarr2.GetSelection()
        yop = self.yop.GetStringSelection().strip()

        ylabel = yname1
        if len(yname2) == 0:
            yname2 = '1.0'
        else:
            ylabel = "%s%s%s" % (ylabel, yop, yname2)

        if yname1 == '0.0':
            yarr1 = np.zeros(npts) * 1.0
            yexpr1 = 'zeros(%i)' % npts
        elif len(yname1) == 0 or yname1 == '1.0' or iy1 >= ncol:
            yarr1 = np.ones(npts) * 1.0
            yexpr1 = 'ones(%i)' % npts
        else:
            yarr1 = rdata[iy1, :]
            yexpr1 = '%%s.data[%i, : ]' % iy1

        if yname2 == '0.0':
            yarr2 = np.zeros(npts) * 1.0
            yexpr2 = '0.0'
        elif len(yname2) == 0 or yname2 == '1.0' or iy2 >= ncol:
            yarr2 = np.ones(npts) * 1.0
            yexpr2 = '1.0'
        else:
            yarr2 = rdata[iy2, :]
            yexpr2 = '%%s.data[%i, : ]' % iy2

        workgroup.ydat = yarr1
        exprs['ydat'] = yexpr1
        if yop in ('+', '-', '*', '/'):
            exprs['ydat'] = "%s %s %s" % (yexpr1, yop, yexpr2)
            if yop == '+':
                workgroup.ydat = yarr1.__add__(yarr2)
            elif yop == '-':
                workgroup.ydat = yarr1.__sub__(yarr2)
            elif yop == '*':
                workgroup.ydat = yarr1.__mul__(yarr2)
            elif yop == '/':
                workgroup.ydat = yarr1.__truediv__(yarr2)

        ysuf, ypop, workgroup.ydat = pre_op(self.ypop, workgroup.ydat)
        self.ysuf.SetLabel(ysuf)
        exprs['ydat'] = '%s%s%s' % (ypop, exprs['ydat'], ysuf)

        yerr_op = self.yerr_op.GetStringSelection().lower()
        exprs['yerr'] = '1'
        if yerr_op.startswith('const'):
            yerr = self.yerr_const.GetValue()
            exprs['yerr'] = '%f' % yerr
        elif yerr_op.startswith('array'):
            iyerr = self.yerr_arr.GetSelection()
            yerr = rdata[iyerr, :]
            exprs['yerr'] = '%%s.data[%i, :]' % iyerr
        elif yerr_op.startswith('sqrt'):
            yerr = np.sqrt(workgroup.ydat)
            exprs['yerr'] = 'sqrt(%s.ydat)'

        if use_deriv:
            try:
                workgroup.ydat = (np.gradient(workgroup.ydat) /
                                  np.gradient(workgroup.xdat))
                exprs['ydat'] = 'deriv(%s)/deriv(%s)' % (exprs['ydat'],
                                                         exprs['xdat'])
            except:
                pass

        self.expressions = exprs
        self.array_sel = {
            'xpop': xpop,
            'xarr': xname,
            'ypop': ypop,
            'yop': yop,
            'yarr1': yname1,
            'yarr2': yname2,
            'use_deriv': use_deriv
        }

        try:
            npts = min(len(workgroup.xdat), len(workgroup.ydat))
        except AttributeError:
            return

        workgroup.filename = rawgroup.filename
        workgroup.npts = npts
        workgroup.plot_xlabel = xlabel
        workgroup.plot_ylabel = ylabel
        workgroup.xdat = np.array(workgroup.xdat[:npts])
        workgroup.ydat = np.array(workgroup.ydat[:npts])
        workgroup.y = workgroup.ydat
        workgroup.yerr = yerr
        if isinstance(yerr, np.ndarray):
            workgroup.yerr = np.array(yerr[:npts])

        if workgroup.datatype == 'xas':
            workgroup.energy = workgroup.xdat
            workgroup.mu = workgroup.ydat

        path, fname = os.path.split(workgroup.filename)
        popts = dict(marker='o',
                     markersize=4,
                     linewidth=1.5,
                     title=fname,
                     ylabel=ylabel,
                     xlabel=xlabel,
                     label="%s: %s" % (fname, workgroup.plot_ylabel))

        self.plotpanel.plot(workgroup.xdat, workgroup.ydat, **popts)

        for i in range(self.nb.GetPageCount()):
            if 'plot' in self.nb.GetPageText(i).lower():
                self.nb.SetSelection(i)

    def plot_messages(self, msg, panel=1):
        self.SetStatusText(msg, panel)
예제 #5
0
class StripChartFrame(wx.Frame):
    def __init__(self, parent, ID, **kws):
        kws["style"] = wx.DEFAULT_FRAME_STYLE | wx.RESIZE_BORDER | wx.TAB_TRAVERSAL

        wx.Frame.__init__(self, parent, ID, '', wx.DefaultPosition,
                          wx.Size(-1, -1), **kws)
        self.SetTitle("wxmplot StripChart Demo")

        self.tmin = 15.0

        self.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.BOLD, False))
        menu = wx.Menu()
        ID_EXIT = wx.NewId()
        ID_TIMER = wx.NewId()

        menu_exit = menu.Append(ID_EXIT, "E&xit", "Terminate the program")

        menuBar = wx.MenuBar()
        menuBar.Append(menu, "&File")
        self.SetMenuBar(menuBar)

        self.Bind(wx.EVT_MENU, self.OnExit, menu_exit)
        self.Bind(wx.EVT_CLOSE, self.OnExit)

        sbar = self.CreateStatusBar(2, wx.CAPTION)
        sfont = sbar.GetFont()
        sfont.SetWeight(wx.BOLD)
        sfont.SetPointSize(11)
        sbar.SetFont(sfont)
        self.SetStatusWidths([-3, -1])
        self.SetStatusText('', 0)

        mainsizer = wx.BoxSizer(wx.VERTICAL)

        btnpanel = wx.Panel(self, -1)
        btnsizer = wx.BoxSizer(wx.HORIZONTAL)

        b_on = wx.Button(btnpanel, -1, 'Start', size=(-1, -1))
        b_off = wx.Button(btnpanel, -1, 'Stop', size=(-1, -1))

        b_on.Bind(wx.EVT_BUTTON, self.onStartTimer)
        b_off.Bind(wx.EVT_BUTTON, self.onStopTimer)

        tlabel = wx.StaticText(btnpanel, -1, '  Time range:')
        self.time_range = FloatCtrl(btnpanel,
                                    size=(100, -1),
                                    value=abs(self.tmin),
                                    precision=1)

        btnsizer.Add(b_on, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER | wx.LEFT, 0)
        btnsizer.Add(b_off, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER | wx.LEFT, 0)
        btnsizer.Add(
            tlabel, 1,
            wx.GROW | wx.ALL | wx.ALIGN_LEFT | wx.ALIGN_CENTER | wx.LEFT, 0)
        btnsizer.Add(self.time_range, 0,
                     wx.ALIGN_LEFT | wx.ALIGN_CENTER | wx.LEFT, 0)

        btnpanel.SetSizer(btnsizer)
        btnsizer.Fit(btnpanel)

        self.plotpanel = PlotPanel(self, messenger=self.write_message)
        self.plotpanel.BuildPanel()
        self.plotpanel.set_xlabel('Time from Present (s)')
        mainsizer.Add(btnpanel, 0,
                      wx.GROW | wx.ALIGN_LEFT | wx.ALIGN_CENTER | wx.LEFT, 0)
        mainsizer.Add(
            self.plotpanel, 1,
            wx.GROW | wx.ALL | wx.ALIGN_LEFT | wx.ALIGN_CENTER | wx.LEFT, 0)
        self.SetSizer(mainsizer)
        mainsizer.Fit(self)

        self.Bind(wx.EVT_TIMER, self.onTimer)
        self.timer = wx.Timer(self)
        self.count = 0
        self.Refresh()
        wx.CallAfter(self.onStartTimer)

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

    def onStartTimer(self, event=None):
        self.count = 0
        t0, y0 = next_data()
        self.ylist = [y0]
        self.tlist = [t0]
        self.tmin_last = -10000
        self.time0 = time.time()
        self.timer.Start(50)

    def onStopTimer(self, event=None):
        self.timer.Stop()

    def onTimer(self, event):
        self.count += 1
        etime = time.time() - self.time0
        self.tmin = float(self.time_range.GetValue())
        t1, y1 = next_data()
        self.tlist.append(t1)
        self.ylist.append(y1)
        tdat = np.array(self.tlist) - t1
        mask = np.where(tdat > -abs(self.tmin))
        ydat = np.array(self.ylist)

        n = len(self.ylist)
        if n <= 2:
            self.plotpanel.plot(tdat, ydat)
        else:
            self.plotpanel.update_line(0, tdat, ydat, draw=True)
            self.write_message(" %i points in %8.4f s" % (n, etime))

        lims = self.plotpanel.get_viewlimits()
        try:
            ymin, ymax = ydat[mask].min(), ydat[mask].max()
        except:
            ymin, ymax = ydat.min(), ydat.max()
        tmin = max(int(min(tdat)) - 1.0, -self.tmin)
        if (ymin < lims[2] or ymax > lims[3] or tmin != self.tmin_last
                or time.time() - self.last_update > 2):
            self.tmin_last = tmin
            self.last_update = time.time()
            self.plotpanel.set_xylims((tmin, 0, ymin, ymax))

    def OnAbout(self, event):
        dlg = wx.MessageDialog(self, "wxmplot example: stripchart app",
                               "About WXMPlot test",
                               wx.OK | wx.ICON_INFORMATION)
        dlg.ShowModal()
        dlg.Destroy()

    def OnExit(self, event):
        self.Destroy()
예제 #6
0
class AthenaImporter(wx.Frame):
    """Import Athena File"""
    def __init__(self,
                 parent,
                 filename=None,
                 read_ok_cb=None,
                 size=(725, 450),
                 _larch=None):
        self.parent = parent
        self.filename = filename
        self.larch = _larch
        self.read_ok_cb = read_ok_cb

        self.colors = GUIColors()

        wx.Frame.__init__(self, parent, -1, size=size, style=FRAMESTYLE)
        splitter = wx.SplitterWindow(self, style=wx.SP_LIVE_UPDATE)
        splitter.SetMinimumPaneSize(200)

        leftpanel = wx.Panel(splitter)
        ltop = wx.Panel(leftpanel)

        sel_none = Button(ltop,
                          'Select None',
                          size=(100, 30),
                          action=self.onSelNone)
        sel_all = Button(ltop,
                         'Select All',
                         size=(100, 30),
                         action=self.onSelAll)
        sel_imp = Button(ltop,
                         'Import Selected Groups',
                         size=(200, 30),
                         action=self.onOK)

        self.grouplist = FileCheckList(leftpanel,
                                       select_action=self.onShowGroup)
        self.grouplist.SetBackgroundColour(wx.Colour(255, 255, 255))

        tsizer = wx.GridBagSizer(2, 2)
        tsizer.Add(sel_all, (0, 0), (1, 1), LCEN, 0)
        tsizer.Add(sel_none, (0, 1), (1, 1), LCEN, 0)
        tsizer.Add(sel_imp, (1, 0), (1, 2), LCEN, 0)

        pack(ltop, tsizer)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(ltop, 0, LCEN | wx.GROW, 1)
        sizer.Add(self.grouplist, 1, LCEN | wx.GROW | wx.ALL, 1)
        pack(leftpanel, sizer)

        # right hand side
        rightpanel = wx.Panel(splitter)

        self.SetTitle("Reading Athena Project '%s'" % self.filename)
        self.title = SimpleText(rightpanel,
                                self.filename,
                                font=Font(13),
                                colour=self.colors.title,
                                style=LCEN)

        self.plotpanel = PlotPanel(rightpanel, messenger=self.plot_messages)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.title, 0, LCEN, 2)
        sizer.Add(self.plotpanel, 0, LCEN, 2)
        pack(rightpanel, sizer)

        splitter.SplitVertically(leftpanel, rightpanel, 1)

        self.statusbar = self.CreateStatusBar(2, 0)
        self.statusbar.SetStatusWidths([-3, -1])
        statusbar_fields = [self.filename, ""]
        for i in range(len(statusbar_fields)):
            self.statusbar.SetStatusText(statusbar_fields[i], i)

        self.all = read_athena(filename,
                               do_bkg=False,
                               do_fft=False,
                               _larch=_larch)
        for item in dir(self.all):
            self.grouplist.Append(item)

        self.Show()
        self.Raise()

    def plot_messages(self, msg, panel=1):
        self.SetStatusText(msg, panel)

    def onOK(self, event=None):
        """ import groups """
        for name in self.grouplist.GetCheckedStrings():
            rawgroup = getattr(self.all, name)
            npts = len(rawgroup.energy)
            outgroup = Group(datatype='xas',
                             path="%s::%s" % (self.filename, name),
                             filename=name,
                             groupname=fix_varname(name),
                             raw=rawgroup,
                             xdat=rawgroup.energy,
                             ydat=rawgroup.mu,
                             y=rawgroup.mu,
                             yerr=1.0,
                             npts=npts,
                             _index=1.0 * np.arange(npts),
                             plot_xlabel='Energy (eV)',
                             plot_ylabel='mu')

            if self.read_ok_cb is not None:
                self.read_ok_cb(outgroup, array_sel=None, overwrite=True)

        self.Destroy()

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

    def onSelAll(self, event=None):
        self.grouplist.SetCheckedStrings(dir(self.all))

    def onSelNone(self, event=None):
        self.grouplist.SetCheckedStrings([])

    def onShowGroup(self, event=None):
        """column selections changed calc xdat and ydat"""
        gname = event.GetString()
        grp = getattr(self.all, gname)
        if hasattr(grp, 'energy') and hasattr(grp, 'mu'):
            self.plotpanel.plot(grp.energy,
                                grp.mu,
                                xlabel='Energy',
                                ylabel='mu',
                                title=gname)
예제 #7
0
class StripChartFrame(wx.Frame):
    def __init__(self, parent, ID, **kws):
        kws["style"] = wx.DEFAULT_FRAME_STYLE|wx.RESIZE_BORDER|wx.TAB_TRAVERSAL

        wx.Frame.__init__(self, parent, ID, '',
                         wx.DefaultPosition, wx.Size(-1,-1), **kws)
        self.SetTitle("wxmplot StripChart Demo")

        self.tmin = 15.0

        self.SetFont(wx.Font(12,wx.SWISS,wx.NORMAL,wx.BOLD,False))
        menu = wx.Menu()
        ID_EXIT  = wx.NewId()
        ID_TIMER = wx.NewId()

        menu_exit = menu.Append(ID_EXIT, "E&xit",
                                "Terminate the program")

        menuBar = wx.MenuBar()
        menuBar.Append(menu, "&File");
        self.SetMenuBar(menuBar)

        self.Bind(wx.EVT_MENU,  self.OnExit, menu_exit)
        self.Bind(wx.EVT_CLOSE, self.OnExit)

        sbar = self.CreateStatusBar(2,wx.CAPTION)
        sfont = sbar.GetFont()
        sfont.SetWeight(wx.BOLD)
        sfont.SetPointSize(11)
        sbar.SetFont(sfont)
        self.SetStatusWidths([-3,-1])
        self.SetStatusText('',0)

        mainsizer = wx.BoxSizer(wx.VERTICAL)

        btnpanel = wx.Panel(self, -1)
        btnsizer = wx.BoxSizer(wx.HORIZONTAL)

        b_on  = wx.Button(btnpanel, -1, 'Start',   size=(-1,-1))
        b_off = wx.Button(btnpanel, -1, 'Stop',    size=(-1,-1))

        b_on.Bind(wx.EVT_BUTTON, self.onStartTimer)
        b_off.Bind(wx.EVT_BUTTON, self.onStopTimer)

        tlabel = wx.StaticText(btnpanel, -1, '  Time range:')
        self.time_range = FloatCtrl(btnpanel,  size=(100, -1),
                                    value=abs(self.tmin), precision=1)

        btnsizer.Add(b_on,   0, wx.ALIGN_LEFT|wx.ALIGN_CENTER|wx.LEFT, 0)
        btnsizer.Add(b_off,  0, wx.ALIGN_LEFT|wx.ALIGN_CENTER|wx.LEFT, 0)
        btnsizer.Add(tlabel, 1, wx.GROW|wx.ALL|wx.ALIGN_LEFT|wx.ALIGN_CENTER|wx.LEFT, 0)
        btnsizer.Add(self.time_range, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER|wx.LEFT, 0)

        btnpanel.SetSizer(btnsizer)
        btnsizer.Fit(btnpanel)

        self.plotpanel = PlotPanel(self, messenger=self.write_message)
        self.plotpanel.BuildPanel()
        self.plotpanel.set_xlabel('Time from Present (s)')
        mainsizer.Add(btnpanel,       0,
                      wx.GROW|wx.ALIGN_LEFT|wx.ALIGN_CENTER|wx.LEFT, 0)
        mainsizer.Add(self.plotpanel, 1,
                      wx.GROW|wx.ALL|wx.ALIGN_LEFT|wx.ALIGN_CENTER|wx.LEFT, 0)
        self.SetSizer(mainsizer)
        mainsizer.Fit(self)

        self.Bind(wx.EVT_TIMER, self.onTimer)
        self.timer = wx.Timer(self)
        self.count    = 0
        self.Refresh()
        wx.CallAfter(self.onStartTimer)

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

    def onStartTimer(self,event=None):
        self.count    = 0
        t0,y0 = next_data()
        self.ylist = [y0]
        self.tlist = [t0]
        self.tmin_last = -10000
        self.time0    = time.time()
        self.timer.Start(50)

    def onStopTimer(self,event=None):
        self.timer.Stop()

    def onTimer(self, event):
        self.count += 1
        etime = time.time() - self.time0
        self.tmin = float(self.time_range.GetValue())
        t1, y1 = next_data()
        self.tlist.append(t1)
        self.ylist.append(y1)
        tdat = np.array(self.tlist) - t1
        mask = np.where(tdat > -abs(self.tmin))
        ydat = np.array(self.ylist)

        n = len(self.ylist)
        if n <= 2:
            self.plotpanel.plot(tdat, ydat)
        else:
            self.plotpanel.update_line(0, tdat, ydat, draw=True)
            self.write_message(" %i points in %8.4f s" % (n,etime))

        lims = self.plotpanel.get_viewlimits()
        try:
            ymin, ymax = ydat[mask].min(), ydat[mask].max()
        except:
            ymin, ymax = ydat.min(), ydat.max()
        tmin = max(int(min(tdat)) - 1.0, -self.tmin)
        if (ymin < lims[2] or ymax >  lims[3] or
            tmin != self.tmin_last or time.time()-self.last_update > 2):
            self.tmin_last = tmin
            self.last_update = time.time()
            self.plotpanel.set_xylims((tmin, 0, ymin, ymax))

    def OnAbout(self, event):
        dlg = wx.MessageDialog(self, "wxmplot example: stripchart app",
                              "About WXMPlot test", wx.OK | wx.ICON_INFORMATION)
        dlg.ShowModal()
        dlg.Destroy()

    def OnExit(self, event):
        self.Destroy()
예제 #8
0
class AthenaImporter(wx.Frame) :
    """Import Athena File"""
    def __init__(self, parent, filename=None, read_ok_cb=None,
                 size=(725, 450), _larch=None):
        self.parent = parent
        self.filename = filename
        self.larch = _larch
        self.read_ok_cb = read_ok_cb

        self.colors = GUIColors()

        wx.Frame.__init__(self, parent, -1,   size=size, style=FRAMESTYLE)
        splitter  = wx.SplitterWindow(self, style=wx.SP_LIVE_UPDATE)
        splitter.SetMinimumPaneSize(200)

        leftpanel = wx.Panel(splitter)
        ltop = wx.Panel(leftpanel)

        sel_none = Button(ltop, 'Select None', size=(100, 30), action=self.onSelNone)
        sel_all  = Button(ltop, 'Select All', size=(100, 30), action=self.onSelAll)
        sel_imp  = Button(ltop, 'Import Selected Groups', size=(200, 30), action=self.onOK)

        self.grouplist = FileCheckList(leftpanel, select_action=self.onShowGroup)
        self.grouplist.SetBackgroundColour(wx.Colour(255, 255, 255))

        tsizer = wx.GridBagSizer(2, 2)
        tsizer.Add(sel_all, (0, 0), (1, 1), LCEN, 0)
        tsizer.Add(sel_none,  (0, 1), (1, 1), LCEN, 0)
        tsizer.Add(sel_imp,  (1, 0), (1, 2), LCEN, 0)

        pack(ltop, tsizer)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(ltop, 0, LCEN|wx.GROW, 1)
        sizer.Add(self.grouplist, 1, LCEN|wx.GROW|wx.ALL, 1)
        pack(leftpanel, sizer)

        # right hand side
        rightpanel = wx.Panel(splitter)

        self.SetTitle("Reading Athena Project '%s'" % self.filename)
        self.title = SimpleText(rightpanel, self.filename, font=Font(13),
                                colour=self.colors.title, style=LCEN)

        self.plotpanel = PlotPanel(rightpanel, messenger=self.plot_messages)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.title, 0, LCEN, 2)
        sizer.Add(self.plotpanel, 0, LCEN, 2)
        pack(rightpanel, sizer)

        splitter.SplitVertically(leftpanel, rightpanel, 1)

        self.statusbar = self.CreateStatusBar(2, 0)
        self.statusbar.SetStatusWidths([-3, -1])
        statusbar_fields = [self.filename, ""]
        for i in range(len(statusbar_fields)):
            self.statusbar.SetStatusText(statusbar_fields[i], i)

        self.all = read_athena(filename, do_bkg=False, do_fft=False, _larch=_larch)
        for item in dir(self.all):
            self.grouplist.Append(item)

        self.Show()
        self.Raise()

    def plot_messages(self, msg, panel=1):
        self.SetStatusText(msg, panel)

    def onOK(self, event=None):
        """ import groups """
        for name in self.grouplist.GetCheckedStrings():
            rawgroup = getattr(self.all, name)
            npts = len(rawgroup.energy)
            outgroup = Group(datatype='xas',
                            path="%s::%s" %(self.filename, name),
                            filename=name,
                            groupname = fix_varname(name),
                            raw=rawgroup,
                            xdat=rawgroup.energy,
                            ydat=rawgroup.mu,
                            y=rawgroup.mu,
                            yerr=1.0,
                            npts=npts, _index=1.0*np.arange(npts),
                            plot_xlabel='Energy (eV)',
                            plot_ylabel='mu')

            self.read_ok_cb(outgroup, array_sel=None, overwrite=True)

        self.Destroy()

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

    def onSelAll(self, event=None):
        self.grouplist.SetCheckedStrings(dir(self.all))

    def onSelNone(self, event=None):
        self.grouplist.SetCheckedStrings([])

    def onShowGroup(self, event=None):
        """column selections changed calc xdat and ydat"""
        gname = event.GetString()
        grp = getattr(self.all, gname)
        if hasattr(grp, 'energy') and hasattr(grp, 'mu'):
            self.plotpanel.plot(grp.energy, grp.mu,
                                xlabel='Energy', ylabel='mu',title=gname)
예제 #9
0
class ColumnDataFileFrame(wx.Frame) :
    """Column Data File, select columns"""
    def __init__(self, parent, filename=None, groupname=None,
                 last_array_sel=None, read_ok_cb=None,
                 edit_groupname=True, _larch=None):
        self.parent = parent
        self._larch = _larch
        self.path = filename
        self.extra_sums = {}

        group = self.initgroup = self.read_column_file(self.path)

        self.subframes = {}
        self.workgroup  = Group(raw=group)
        for attr in ('path', 'filename', 'groupname', 'datatype',
                     'array_labels', 'data'):
            setattr(self.workgroup, attr, getattr(group, attr, None))

        arr_labels = [l.lower() for l in self.initgroup.array_labels]

        if self.workgroup.datatype is None:
            self.workgroup.datatype = 'raw'
            for arrlab in arr_labels[:4]:
                if 'energ' in arrlab:
                    self.workgroup.datatype = 'xas'

        self.read_ok_cb = read_ok_cb
        self.array_sel = {'xpop': '',  'xarr': None,
                          'ypop': '',  'yop': '/',
                          'yarr1': None, 'yarr2': None, 'use_deriv': False}

        if last_array_sel is not None:
            self.array_sel.update(last_array_sel)

        if self.array_sel['yarr2'] is None and 'i0' in arr_labels:
            self.array_sel['yarr2'] = 'i0'

        if self.array_sel['yarr1'] is None:
            if 'itrans' in arr_labels:
                self.array_sel['yarr1'] = 'itrans'
            elif 'i1' in arr_labels:
                self.array_sel['yarr1'] = 'i1'
        message = "Data Columns for %s" % group.filename
        wx.Frame.__init__(self, None, -1,
                          'Build Arrays from Data Columns for %s' % group.filename,
                          style=FRAMESTYLE)

        self.SetFont(Font(10))

        panel = wx.Panel(self)
        self.SetMinSize((600, 600))
        self.colors = GUIColors()

        # title row
        title = SimpleText(panel, message, font=Font(13),
                           colour=self.colors.title, style=LCEN)

        opts = dict(action=self.onUpdate, size=(120, -1))
        yarr_labels = self.yarr_labels = arr_labels + ['1.0', '0.0', '']
        xarr_labels = self.xarr_labels = arr_labels + ['_index']

        self.xarr   = Choice(panel, choices=xarr_labels, **opts)
        self.yarr1  = Choice(panel, choices= arr_labels, **opts)
        self.yarr2  = Choice(panel, choices=yarr_labels, **opts)
        self.yerr_arr = Choice(panel, choices=yarr_labels, **opts)
        self.yerr_arr.Disable()

        self.datatype = Choice(panel, choices=DATATYPES, **opts)
        self.datatype.SetStringSelection(self.workgroup.datatype)


        opts['size'] = (50, -1)
        self.yop =  Choice(panel, choices=ARR_OPS, **opts)

        opts['size'] = (150, -1)

        self.use_deriv = Check(panel, label='use derivative',
                               default=self.array_sel['use_deriv'], **opts)

        self.xpop = Choice(panel, choices=XPRE_OPS, **opts)
        self.ypop = Choice(panel, choices=YPRE_OPS, **opts)

        opts['action'] = self.onYerrChoice
        self.yerr_op = Choice(panel, choices=YERR_OPS, **opts)
        self.yerr_op.SetSelection(0)

        self.yerr_const = FloatCtrl(panel, value=1, precision=4, size=(90, -1))

        ylab = SimpleText(panel, 'Y = ')
        xlab = SimpleText(panel, 'X = ')
        yerr_lab = SimpleText(panel, 'Yerror = ')
        self.xsuf = SimpleText(panel, '')
        self.ysuf = SimpleText(panel, '')
        self.message = SimpleText(panel, '', font=Font(11),
                           colour=self.colors.title, style=LCEN)

        self.xpop.SetStringSelection(self.array_sel['xpop'])
        self.ypop.SetStringSelection(self.array_sel['ypop'])
        self.yop.SetStringSelection(self.array_sel['yop'])
        if '(' in self.array_sel['ypop']:
            self.ysuf.SetLabel(')')

        ixsel, iysel, iy2sel = 0, 1, len(yarr_labels)-1
        if self.array_sel['xarr'] in xarr_labels:
            ixsel = xarr_labels.index(self.array_sel['xarr'])
        if self.array_sel['yarr1'] in arr_labels:
            iysel = arr_labels.index(self.array_sel['yarr1'])
        if self.array_sel['yarr2'] in yarr_labels:
            iy2sel = yarr_labels.index(self.array_sel['yarr2'])
        self.xarr.SetSelection(ixsel)
        self.yarr1.SetSelection(iysel)
        self.yarr2.SetSelection(iy2sel)

        bpanel = wx.Panel(panel)
        bsizer = wx.BoxSizer(wx.HORIZONTAL)
        _ok    = Button(bpanel, 'OK', action=self.onOK)
        _cancel = Button(bpanel, 'Cancel', action=self.onCancel)
        _edit   = Button(bpanel, 'Edit Array Names', action=self.onEditNames)
        _add    = Button(bpanel, 'Select Columns to Sum', action=self.onAddColumns)

        bsizer.Add(_ok)
        bsizer.Add(_cancel)
        bsizer.Add(_edit)
        bsizer.Add(_add)
        _ok.SetDefault()
        pack(bpanel, bsizer)

        sizer = wx.GridBagSizer(4, 8)
        sizer.Add(title,     (0, 0), (1, 7), LCEN, 5)

        ir = 1
        sizer.Add(xlab,      (ir, 0), (1, 1), LCEN, 0)
        sizer.Add(self.xpop, (ir, 1), (1, 1), CEN, 0)
        sizer.Add(self.xarr, (ir, 2), (1, 1), CEN, 0)
        sizer.Add(self.xsuf, (ir, 3), (1, 1), CEN, 0)

        ir += 1
        sizer.Add(ylab,       (ir, 0), (1, 1), LCEN, 0)
        sizer.Add(self.ypop,  (ir, 1), (1, 1), CEN, 0)
        sizer.Add(self.yarr1, (ir, 2), (1, 1), CEN, 0)
        sizer.Add(self.yop,   (ir, 3), (1, 1), CEN, 0)
        sizer.Add(self.yarr2, (ir, 4), (1, 1), CEN, 0)
        sizer.Add(self.ysuf,  (ir, 5), (1, 1), CEN, 0)
        sizer.Add(self.use_deriv, (ir, 6), (1, 1), LCEN, 0)

        ir += 1
        sizer.Add(yerr_lab,      (ir, 0), (1, 1), LCEN, 0)
        sizer.Add(self.yerr_op,  (ir, 1), (1, 1), CEN, 0)
        sizer.Add(self.yerr_arr, (ir, 2), (1, 1), CEN, 0)
        sizer.Add(SimpleText(panel, 'Value:'), (ir, 3), (1, 1), CEN, 0)
        sizer.Add(self.yerr_const, (ir, 4), (1, 2), CEN, 0)

        ir += 1
        sizer.Add(SimpleText(panel, 'Data Type:'),  (ir, 0), (1, 1), LCEN, 0)
        sizer.Add(self.datatype,                    (ir, 1), (1, 2), LCEN, 0)

        ir += 1
        self.wid_groupname = wx.TextCtrl(panel, value=group.groupname,
                                         size=(200, -1))
        if not edit_groupname:
            self.wid_groupname.Disable()

        sizer.Add(SimpleText(panel, 'Group Name:'), (ir, 0), (1, 1), LCEN, 0)
        sizer.Add(self.wid_groupname,               (ir, 1), (1, 2), LCEN, 0)
        sizer.Add(self.message,                     (ir, 3), (1, 4), LCEN, 0)


        ir += 1
        sizer.Add(bpanel,     (ir, 0), (1, 5), LCEN, 3)

        pack(panel, sizer)

        self.nb = fnb.FlatNotebook(self, -1, agwStyle=FNB_STYLE)
        self.nb.SetTabAreaColour(wx.Colour(248,248,240))
        self.nb.SetActiveTabColour(wx.Colour(254,254,195))
        self.nb.SetNonActiveTabTextColour(wx.Colour(40,40,180))
        self.nb.SetActiveTabTextColour(wx.Colour(80,0,0))

        self.plotpanel = PlotPanel(self, messenger=self.plot_messages)
        textpanel = wx.Panel(self)
        ftext = wx.TextCtrl(textpanel, style=wx.TE_MULTILINE|wx.TE_READONLY,
                               size=(400, 250))

        ftext.SetValue(group.text)
        ftext.SetFont(Font(10))

        textsizer = wx.BoxSizer(wx.VERTICAL)
        textsizer.Add(ftext, 1, LCEN|wx.GROW, 1)
        pack(textpanel, textsizer)

        self.nb.AddPage(textpanel, ' Text of Data File ', True)
        self.nb.AddPage(self.plotpanel, ' Plot of Selected Arrays ', True)

        mainsizer = wx.BoxSizer(wx.VERTICAL)
        mainsizer.Add(panel, 0, wx.GROW|wx.ALL, 2)
        mainsizer.Add(self.nb, 1, LCEN|wx.GROW,   2)
        pack(self, mainsizer)

        self.statusbar = self.CreateStatusBar(2, 0)
        self.statusbar.SetStatusWidths([-1, -1])
        statusbar_fields = [group.filename, ""]
        for i in range(len(statusbar_fields)):
            self.statusbar.SetStatusText(statusbar_fields[i], i)

        self.Show()
        self.Raise()
        self.onUpdate(self)

    def read_column_file(self, path):
        """read column file, generally as initial read"""
        parent, filename = os.path.split(path)
        with open(path, 'r') as fh:
            lines = fh.readlines()

        text = ''.join(lines)
        line1 = lines[0].lower()

        reader = 'read_ascii'
        if 'epics stepscan file' in line1:
            reader = 'read_gsexdi'
        elif 'xdi' in line1:
            reader = 'read_xdi'
        elif 'epics scan' in line1:
            reader = 'read_gsescan'

        tmpname = '_tmp_file_'
        read_cmd = "%s = %s('%s')" % (tmpname, reader, path)
        self.reader = reader
        _larch = self._larch
        if (not isinstance(_larch, larch.Interpreter) and
            hasattr(_larch, '_larch')):
            _larch = _larch._larch
        try:
            _larch.eval(read_cmd, add_history=False)
        except:
            pass
        if _larch.error:
            msg = ["Error trying to read '%s':" % path, ""]
            for err in _larch.error:
                exc_name, errmsg = err.get_error()
                msg.append(errmsg)

            title = "Cannot read %s" % path
            r = Popup(self.parent, "\n".join(msg), title)
            return None

        group = _larch.symtable.get_symbol(tmpname)
        _larch.symtable.del_symbol(tmpname)

        group.text = text
        group.path = path
        group.filename = filename
        group.groupname = file2groupname(filename,
                                         symtable=self._larch.symtable)
        return group

    def show_subframe(self, name, frameclass, **opts):
        shown = False
        if name in self.subframes:
            try:
                self.subframes[name].Raise()
                shown = True
            except:
                del self.subframes[name]
        if not shown:
            self.subframes[name] = frameclass(self, **opts)

    def onAddColumns(self, event=None):
        self.show_subframe('addcol', AddColumnsFrame,
                           group=self.workgroup,
                           on_ok=self.add_columns)

    def add_columns(self, label, selection):
        new_labels = self.workgroup.array_labels
        self.set_array_labels(new_labels)
        self.yarr1.SetStringSelection(new_labels[-1])
        self.extra_sums[label] = selection
        self.onUpdate()

    def onEditNames(self, evt=None):
        self.show_subframe('editcol', EditColumnFrame,
                           group=self.workgroup,
                           on_ok=self.set_array_labels)



    def set_array_labels(self, arr_labels):
        self.workgroup.array_labels = arr_labels
        yarr_labels = self.yarr_labels = arr_labels + ['1.0', '0.0', '']
        xarr_labels = self.xarr_labels = arr_labels + ['_index']
        def update(wid, choices):
            curstr = wid.GetStringSelection()
            curind = wid.GetSelection()
            wid.SetChoices(choices)
            if curstr in choices:
                wid.SetStringSelection(curstr)
            else:
                wid.SetSelection(curind)
        update(self.xarr,  xarr_labels)
        update(self.yarr1, yarr_labels)
        update(self.yarr2, yarr_labels)
        update(self.yerr_arr, yarr_labels)
        self.onUpdate()

    def onOK(self, event=None):
        """ build arrays according to selection """
        if self.wid_groupname is not None:
            groupname = fix_varname(self.wid_groupname.GetValue())

        yerr_op = self.yerr_op.GetStringSelection().lower()
        yerr_expr = '1'
        if yerr_op.startswith('const'):
            yerr_expr = "%f" % self.yerr_const.GetValue()
        elif yerr_op.startswith('array'):
            yerr_expr = '%%s.data[%i, :]' % self.yerr_arr.GetSelection()
        elif yerr_op.startswith('sqrt'):
            yerr_expr = 'sqrt(%s.ydat)'
        self.expressions['yerr'] = yerr_expr

        # generate script to pass back to calling program:
        labels = ', '.join(self.workgroup.array_labels)
        read_cmd = "%s('{path}', labels='%s')" % (self.reader, labels)

        buff = ["{group} = %s" % read_cmd,
                "{group}.path = '{path}'",
                "{group}.is_frozen = False"]

        for label, selection in self.extra_sums.items():
            buff.append("{group}.array_labels.append('%s')" % label)
            buff.append("_tmparr = {group}.data[%s, :].sum(axis=0)" % repr(selection))
            buff.append("_tmpn   = len(_tmparr)")
            buff.append("{group}.data = append({group}.data, _tmparr.reshape(1, _tmpn), axis=0)")
            buff.append("del _tmparr, _tmpn")


        for attr in ('datatype', 'plot_xlabel', 'plot_ylabel'):
            val = getattr(self.workgroup, attr)
            buff.append("{group}.%s = '%s'" % (attr, val))

        for aname in ('xdat', 'ydat', 'yerr'):
            expr = self.expressions[aname].replace('%s', '{group:s}')
            buff.append("{group}.%s = %s" % (aname, expr))

        if getattr(self.workgroup, 'datatype', 'raw') == 'xas':
            if self.reader == 'read_gsescan':
                buff.append("{group}.energy = {group}.x")
            else:
                buff.append("{group}.energy = {group}.xdat")
            buff.append("{group}.mu = {group}.ydat")
            buff.append("sort_xafs({group}, overwrite=True, fix_repeats=True)")

        script = "\n".join(buff)

        if self.read_ok_cb is not None:
            self.read_ok_cb(script, self.path, groupname=groupname,
                            array_sel=self.array_sel)

        for f in self.subframes.values():
            try:
                f.Destroy()
            except:
                pass
        self.Destroy()

    def onCancel(self, event=None):
        self.workgroup.import_ok = False
        for f in self.subframes.values():
            try:
                f.Destroy()
            except:
                pass
        self.Destroy()

    def onYerrChoice(self, evt=None):
        yerr_choice = evt.GetString()
        self.yerr_arr.Disable()
        self.yerr_const.Disable()
        if 'const' in yerr_choice.lower():
            self.yerr_const.Enable()
        elif 'array' in yerr_choice.lower():
            self.yerr_arr.Enable()
        self.onUpdate()


    def onUpdate(self, value=None, evt=None):
        """column selections changed calc xdat and ydat"""
        # dtcorr = self.dtcorr.IsChecked()
        # print("Column Frame on Update ")

        dtcorr = False
        use_deriv = self.use_deriv.IsChecked()
        rawgroup = self.initgroup
        workgroup = self.workgroup
        rdata = self.initgroup.data

        ix  = self.xarr.GetSelection()
        xname = self.xarr.GetStringSelection()

        exprs = dict(xdat=None, ydat=None, yerr=None)

        ncol, npts = rdata.shape
        workgroup.index = 1.0*np.arange(npts)
        if xname.startswith('_index') or ix >= ncol:
            workgroup.xdat = 1.0*np.arange(npts)
            xname = '_index'
            exprs['xdat'] = 'arange(%i)' % npts
        else:
            workgroup.xdat = rdata[ix, :]
            exprs['xdat'] = '%%s.data[%i, : ]' % ix

        workgroup.datatype = self.datatype.GetStringSelection().strip().lower()

        def pre_op(opwid, arr):
            opstr = opwid.GetStringSelection().strip()
            suf = ''
            if opstr in ('-log(', 'log('):
                suf = ')'
                if opstr == 'log(':
                    arr = np.log(arr)
                elif opstr == '-log(':
                    arr = -np.log(arr)
            return suf, opstr, arr

        try:
            xsuf, xpop, workgroup.xdat = pre_op(self.xpop, workgroup.xdat)
            self.xsuf.SetLabel(xsuf)
            exprs['xdat'] = '%s%s%s' % (xpop, exprs['xdat'], xsuf)
        except:
            return
        try:
            xunits = rawgroup.array_units[ix].strip()
            xlabel = '%s (%s)' % (xname, xunits)
        except:
            xlabel = xname

        yname1  = self.yarr1.GetStringSelection().strip()
        yname2  = self.yarr2.GetStringSelection().strip()
        iy1    = self.yarr1.GetSelection()
        iy2    = self.yarr2.GetSelection()
        yop = self.yop.GetStringSelection().strip()

        ylabel = yname1
        if len(yname2) == 0:
            yname2 = '1.0'
        else:
            ylabel = "%s%s%s" % (ylabel, yop, yname2)

        if yname1 == '0.0':
            yarr1 = np.zeros(npts)*1.0
            yexpr1 = 'zeros(%i)' % npts
        elif len(yname1) == 0 or yname1 == '1.0' or iy1 >= ncol:
            yarr1 = np.ones(npts)*1.0
            yexpr1 = 'ones(%i)' % npts
        else:
            yarr1 = rdata[iy1, :]
            yexpr1 = '%%s.data[%i, : ]' % iy1

        if yname2 == '0.0':
            yarr2 = np.zeros(npts)*1.0
            yexpr2 = '0.0'
        elif len(yname2) == 0 or yname2 == '1.0' or iy2 >= ncol:
            yarr2 = np.ones(npts)*1.0
            yexpr2 = '1.0'
        else:
            yarr2 = rdata[iy2, :]
            yexpr2 = '%%s.data[%i, : ]' % iy2

        workgroup.ydat = yarr1

        exprs['ydat'] = yexpr1
        if yop in ('+', '-', '*', '/'):
            exprs['ydat'] = "%s %s %s" % (yexpr1, yop, yexpr2)
            if yop == '+':
                workgroup.ydat = yarr1.__add__(yarr2)
            elif yop == '-':
                workgroup.ydat = yarr1.__sub__(yarr2)
            elif yop == '*':
                workgroup.ydat = yarr1.__mul__(yarr2)
            elif yop == '/':
                workgroup.ydat = yarr1.__truediv__(yarr2)

        ysuf, ypop, workgroup.ydat = pre_op(self.ypop, workgroup.ydat)
        self.ysuf.SetLabel(ysuf)
        exprs['ydat'] = '%s%s%s' % (ypop, exprs['ydat'], ysuf)

        yerr_op = self.yerr_op.GetStringSelection().lower()
        exprs['yerr'] = '1'
        if yerr_op.startswith('const'):
            yerr = self.yerr_const.GetValue()
            exprs['yerr'] = '%f' % yerr
        elif yerr_op.startswith('array'):
            iyerr = self.yerr_arr.GetSelection()
            yerr = rdata[iyerr, :]
            exprs['yerr'] = '%%s.data[%i, :]' % iyerr
        elif yerr_op.startswith('sqrt'):
            yerr = np.sqrt(workgroup.ydat)
            exprs['yerr'] = 'sqrt(%s.ydat)'

        if use_deriv:
            try:
                workgroup.ydat = (np.gradient(workgroup.ydat) /
                                 np.gradient(workgroup.xdat))
                exprs['ydat'] = 'deriv(%s)/deriv(%s)' % (exprs['ydat'],
                                                         exprs['xdat'])
            except:
                pass

        self.expressions = exprs
        self.array_sel = {'xpop': xpop, 'xarr': xname,
                          'ypop': ypop, 'yop': yop,
                          'yarr1': yname1, 'yarr2': yname2,
                          'use_deriv': use_deriv}

        try:
            npts = min(len(workgroup.xdat), len(workgroup.ydat))
        except AttributeError:
            return
        except ValueError:
            return

        en = workgroup.xdat
        if ((workgroup.datatype == 'xas') and
            ((len(en) > 1000 or any(np.diff(en) < 0) or
              ((max(en)-min(en)) > 350 and
               (np.diff(en[:100]).mean() < 1.0))))):
            self.message.SetLabel("Warning: XAS data may need to be rebinned!")
        else:
            self.message.SetLabel("")

        workgroup.filename    = rawgroup.filename
        workgroup.npts        = npts
        workgroup.plot_xlabel = xlabel
        workgroup.plot_ylabel = ylabel
        workgroup.xdat        = np.array(workgroup.xdat[:npts])
        workgroup.ydat        = np.array(workgroup.ydat[:npts])
        workgroup.y           = workgroup.ydat
        workgroup.yerr        = yerr
        if isinstance(yerr, np.ndarray):
            workgroup.yerr    = np.array(yerr[:npts])

        if workgroup.datatype == 'xas':
            workgroup.energy = workgroup.xdat
            workgroup.mu     = workgroup.ydat

        path, fname = os.path.split(workgroup.filename)
        popts = dict(marker='o', markersize=4, linewidth=1.5,
                     title=fname, ylabel=ylabel, xlabel=xlabel,
                     label="%s: %s" % (fname, workgroup.plot_ylabel))

        self.plotpanel.plot(workgroup.xdat, workgroup.ydat, **popts)

        for i in range(self.nb.GetPageCount()):
            if 'plot' in self.nb.GetPageText(i).lower():
                self.nb.SetSelection(i)

    def plot_messages(self, msg, panel=1):
        self.SetStatusText(msg, panel)
예제 #10
0
class Runner(noname.MyFrame1):

    power_rendered = False
    data = data.Data

    def __init__(self, parent):
        noname.MyFrame1.__init__(self, parent)

    def render_input_sound(self, event):

        if wx.Event.GetEventType(event) == 10084 or wx.Event.GetEventType(
                event) == 10161:

            self.m_panel2.Refresh()

            self.canvas1 = PlotPanel(self.m_panel2,
                                     size=(self.m_panel2.GetSize()))

            if hasattr(self.data, 'time') and hasattr(self.data,
                                                      'input_sound'):
                self.canvas1.plot(self.data.time, self.data.input_sound)

            return

        else:
            self.canvas1.update_line(0,
                                     self.data.time,
                                     self.data.input_sound,
                                     draw=True)
            return

    def render_power(self, event):
        if wx.Event.GetEventType(event) == 10084 or wx.Event.GetEventType(
                event) == 10161:

            if (self.power_rendered):
                self.canvas2.update_line(0,
                                         self.data.truncated_frequency,
                                         self.data.truncated_power,
                                         draw=True)
            else:
                self.canvas2 = PlotPanel(self.m_panel3,
                                         size=(self.m_panel3.GetSize()))

                if hasattr(self.data, 'truncated_frequency') and hasattr(
                        self.data, 'truncated_power'):
                    self.canvas2.plot(self.data.truncated_frequency,
                                      self.data.truncated_power, 'r')
                    self.canvas2.oplot(
                        self.data.truncated_frequency,
                        np.full((len(self.data.truncated_frequency)),
                                self.data.min))
                    self.power_rendered = True

            return

        # For slider
        else:

            p = backend.get_cutoff_value(self.data.min, self.data.slope,
                                         self.m_slider1.GetValue())
            if (self.power_rendered):
                self.canvas2.update_line(
                    1,
                    self.data.truncated_frequency,
                    np.full((len(self.data.truncated_frequency)), p),
                    draw=True)

            else:
                self.canvas2 = PlotPanel(self.m_panel3,
                                         size=(self.m_panel3.GetSize()))
                self.canvas2.plot(self.data.truncated_frequency,
                                  self.data.truncated_power, 'r')
                self.canvas2.oplot(
                    self.data.truncated_frequency,
                    np.full((len(self.data.truncated_frequency)),
                            self.data.min))
                self.power_rendered = True

            return

    def render_output(self, event):

        if wx.Event.GetEventType(event) == 10084 or wx.Event.GetEventType(
                event) == 10161:

            self.m_panel4.Refresh()

            self.canvas3 = PlotPanel(self.m_panel4,
                                     size=(self.m_panel4.GetSize()))

            if hasattr(self.data, 'time') and hasattr(self.data, 'ifft'):
                self.canvas3.plot(self.data.time, self.data.ifft)

            return

        else:

            self.canvas3.update_line(0,
                                     self.data.time,
                                     self.data.ifft,
                                     draw=True)
            return

    def loadAudio(self, event):
        ''' 
        Loads audio from path and calls render functions.\n
        wx event: 10161
        '''

        self.data.load_sound(location=self.m_filePicker1.GetPath())
        self.data.load_power_graph()
        # Fire screen refresh event
        self.render_input_sound(event)
        self.render_power(event)
        self.render_output(event)

        return

    def slider_move(self, event):
        self.render_power(event)

        self.data.load_output(
            backend.get_cutoff_value(self.data.min, self.data.slope,
                                     self.m_slider1.GetValue()))

        self.render_output(event)

    def export(self, event):
        self.data.export()

    def play(self, event):
        sd.play(self.data.ifft, self.data.fs)
        time.sleep(len(self.data.input_sound) / self.data.fs)
        sd.stop()

    def add_noise(self, event):
        self.data.add_noise()
        self.render_input_sound(event)
        self.render_power(event)
        self.render_output(event)
예제 #11
0
class EditColumnFrame(wx.Frame) :
    """Set Column Labels for a file"""
    def __init__(self, parent, group=None, last_array_sel=None,
                 read_ok_cb=None, edit_groupname=True, with_smooth=False,
                 _larch=None):
        self.parent = parent
        self.larch = _larch
        self.rawgroup = group
        self.with_smooth = with_smooth
        self.outgroup  = Group(raw=group)
        for attr in ('path', 'filename', 'groupname', 'datatype'):
            setattr(self.outgroup, attr, getattr(group, attr, None))

        if self.outgroup.datatype is None:
            self.outgroup.datatype = 'raw'
            if ('energ' in self.rawgroup.array_labels[0].lower() or
                'energ' in self.rawgroup.array_labels[1].lower()):
                self.outgroup.datatype = 'xas'

        self.read_ok_cb = read_ok_cb

        self.array_sel = {'xpop': '', 'xarr': None,
                          'ypop': '', 'yop': '/',
                          'yarr1': None, 'yarr2': None,
                          'use_deriv': False}
        if last_array_sel is not None:
            self.array_sel.update(last_array_sel)

        if self.array_sel['yarr2'] is None and 'i0' in self.rawgroup.array_labels:
            self.array_sel['yarr2'] = 'i0'

        if self.array_sel['yarr1'] is None:
            if 'itrans' in self.rawgroup.array_labels:
                self.array_sel['yarr1'] = 'itrans'
            elif 'i1' in self.rawgroup.array_labels:
                self.array_sel['yarr1'] = 'i1'
        message = "Data Columns for %s" % self.rawgroup.filename
        wx.Frame.__init__(self, None, -1,
                          'Build Arrays from Data Columns for %s' % self.rawgroup.filename,
                          style=FRAMESTYLE)

        self.SetFont(Font(10))

        panel = wx.Panel(self)
        self.SetMinSize((600, 600))
        self.colors = GUIColors()

        # title row
        title = SimpleText(panel, message, font=Font(13),
                           colour=self.colors.title, style=LCEN)

        opts = dict(action=self.onUpdate, size=(120, -1))

        arr_labels = self.rawgroup.array_labels
        yarr_labels = arr_labels + ['1.0', '0.0', '']
        xarr_labels = arr_labels + ['<index>']

        self.xarr   = Choice(panel, choices=xarr_labels, **opts)
        self.yarr1  = Choice(panel, choices= arr_labels, **opts)
        self.yarr2  = Choice(panel, choices=yarr_labels, **opts)
        self.yerr_arr = Choice(panel, choices=yarr_labels, **opts)
        self.yerr_arr.Disable()

        self.datatype = Choice(panel, choices=DATATYPES, **opts)
        self.datatype.SetStringSelection(self.outgroup.datatype)


        opts['size'] = (50, -1)
        self.yop =  Choice(panel, choices=ARR_OPS, **opts)

        opts['size'] = (120, -1)

        self.use_deriv = Check(panel, label='use derivative',
                               default=self.array_sel['use_deriv'], **opts)

        self.xpop = Choice(panel, choices=XPRE_OPS, **opts)
        self.ypop = Choice(panel, choices=YPRE_OPS, **opts)

        opts['action'] = self.onYerrChoice
        self.yerr_op = Choice(panel, choices=YERR_OPS, **opts)
        self.yerr_op.SetSelection(0)

        self.yerr_const = FloatCtrl(panel, value=1, precision=4, size=(90, -1))

        if with_smooth:
            opts['action'] = self.onSmoothChoice
            self.smooth_op = Choice(panel, choices=SMOOTH_OPS, **opts)
            self.smooth_op.SetSelection(0)

            opts['size'] = (100, -1)

            opts['action'] = self.onUpdate
            smooth_panel = wx.Panel(panel)
            smooth_sizer = wx.BoxSizer(wx.HORIZONTAL)
            self.smooth_conv = Choice(smooth_panel, choices=CONV_OPS, **opts)
            opts['size'] =  (30, -1)
            self.smooth_c0 = FloatCtrl(smooth_panel, value=3, precision=0, **opts)
            self.smooth_c1 = FloatCtrl(smooth_panel, value=1, precision=0, **opts)
            opts['size'] =  (75, -1)
            self.smooth_sig = FloatCtrl(smooth_panel, value=1, precision=4, **opts)
            self.smooth_c0.Disable()
            self.smooth_c1.Disable()
            self.smooth_sig.Disable()
            self.smooth_conv.SetSelection(0)
            self.smooth_conv.Disable()


        ylab = SimpleText(panel, 'Y = ')
        xlab = SimpleText(panel, 'X = ')
        yerr_lab = SimpleText(panel, 'Yerror = ')
        self.xsuf = SimpleText(panel, '')
        self.ysuf = SimpleText(panel, '')

        self.xpop.SetStringSelection(self.array_sel['xpop'])
        self.ypop.SetStringSelection(self.array_sel['ypop'])
        self.yop.SetStringSelection(self.array_sel['yop'])
        if '(' in self.array_sel['ypop']:
            self.ysuf.SetLabel(')')

        ixsel, iysel, iy2sel = 0, 1, len(yarr_labels)-1
        if self.array_sel['xarr'] in xarr_labels:
            ixsel = xarr_labels.index(self.array_sel['xarr'])
        if self.array_sel['yarr1'] in arr_labels:
            iysel = arr_labels.index(self.array_sel['yarr1'])
        if self.array_sel['yarr2'] in yarr_labels:
            iy2sel = yarr_labels.index(self.array_sel['yarr2'])
        self.xarr.SetSelection(ixsel)
        self.yarr1.SetSelection(iysel)
        self.yarr2.SetSelection(iy2sel)


        bpanel = wx.Panel(panel)
        bsizer = wx.BoxSizer(wx.HORIZONTAL)
        bsizer.Add(Button(bpanel, 'OK', action=self.onOK), 4)
        bsizer.Add(Button(bpanel, 'Cancel', action=self.onCancel), 4)
        pack(bpanel, bsizer)

        sizer = wx.GridBagSizer(4, 8)
        sizer.Add(title,     (0, 0), (1, 7), LCEN, 5)

        ir = 1
        sizer.Add(xlab,      (ir, 0), (1, 1), LCEN, 0)
        sizer.Add(self.xpop, (ir, 1), (1, 1), CEN, 0)
        sizer.Add(self.xarr, (ir, 2), (1, 1), CEN, 0)
        sizer.Add(self.xsuf, (ir, 3), (1, 1), CEN, 0)

        ir += 1
        sizer.Add(ylab,       (ir, 0), (1, 1), LCEN, 0)
        sizer.Add(self.ypop,  (ir, 1), (1, 1), CEN, 0)
        sizer.Add(self.yarr1, (ir, 2), (1, 1), CEN, 0)
        sizer.Add(self.yop,   (ir, 3), (1, 1), CEN, 0)
        sizer.Add(self.yarr2, (ir, 4), (1, 1), CEN, 0)
        sizer.Add(self.ysuf,  (ir, 5), (1, 1), CEN, 0)
        sizer.Add(self.use_deriv, (ir, 6), (1, 1), LCEN, 0)

        ir += 1
        sizer.Add(yerr_lab,      (ir, 0), (1, 1), LCEN, 0)
        sizer.Add(self.yerr_op,  (ir, 1), (1, 1), CEN, 0)
        sizer.Add(self.yerr_arr, (ir, 2), (1, 1), CEN, 0)
        sizer.Add(SimpleText(panel, 'Value:'), (ir, 3), (1, 1), CEN, 0)
        sizer.Add(self.yerr_const, (ir, 4), (1, 2), CEN, 0)

        if with_smooth:
            ir += 1
            sizer.Add(SimpleText(panel, 'Smoothing:'), (ir, 0), (1, 1), LCEN, 0)
            sizer.Add(self.smooth_op,  (ir, 1), (1, 1), CEN, 0)

            smooth_sizer.Add(SimpleText(smooth_panel, ' n='), 0, LCEN, 1)
            smooth_sizer.Add(self.smooth_c0,  0, LCEN, 1)
            smooth_sizer.Add(SimpleText(smooth_panel, ' order='), 0, LCEN, 1)
            smooth_sizer.Add(self.smooth_c1,  0, LCEN, 1)
            smooth_sizer.Add(SimpleText(smooth_panel, ' form='), 0, LCEN, 1)
            smooth_sizer.Add(self.smooth_conv,  0, LCEN, 1)
            smooth_sizer.Add(SimpleText(smooth_panel, ' sigma='), 0, LCEN, 1)
            smooth_sizer.Add(self.smooth_sig,  0, LCEN, 1)
            pack(smooth_panel, smooth_sizer)

            sizer.Add(smooth_panel,  (ir, 2), (1, 5), LCEN, 1)

        ir += 1
        sizer.Add(SimpleText(panel, 'Data Type:'),  (ir, 0), (1, 1), LCEN, 0)
        sizer.Add(self.datatype,                    (ir, 1), (1, 2), LCEN, 0)

        ir += 1
        self.wid_groupname = wx.TextCtrl(panel, value=self.rawgroup.groupname,
                                         size=(120, -1))
        if not edit_groupname:
            self.wid_groupname.Disable()

        sizer.Add(SimpleText(panel, 'Group Name:'), (ir, 0), (1, 1), LCEN, 0)
        sizer.Add(self.wid_groupname,               (ir, 1), (1, 1), LCEN, 0)


        ir += 1
        sizer.Add(bpanel,     (ir, 0), (1, 5), LCEN, 3)

        pack(panel, sizer)

        self.nb = fnb.FlatNotebook(self, -1, agwStyle=FNB_STYLE)
        self.nb.SetTabAreaColour(wx.Colour(248,248,240))
        self.nb.SetActiveTabColour(wx.Colour(254,254,195))
        self.nb.SetNonActiveTabTextColour(wx.Colour(40,40,180))
        self.nb.SetActiveTabTextColour(wx.Colour(80,0,0))

        self.plotpanel = PlotPanel(self, messenger=self.plot_messages)
        textpanel = wx.Panel(self)
        ftext = wx.TextCtrl(textpanel, style=wx.TE_MULTILINE|wx.TE_READONLY,
                               size=(400, 250))
        try:
            m = open(self.rawgroup.filename, 'r')
            text = m.read()
            m.close()
        except:
            text = "The file '%s'\n could not be read" % self.rawgroup.filename
        ftext.SetValue(text)
        ftext.SetFont(Font(11))

        textsizer = wx.BoxSizer(wx.VERTICAL)
        textsizer.Add(ftext, 1, LCEN|wx.GROW, 1)
        pack(textpanel, textsizer)

        self.nb.AddPage(textpanel, ' Text of Data File ', True)
        self.nb.AddPage(self.plotpanel, ' Plot of Selected Arrays ', True)

        mainsizer = wx.BoxSizer(wx.VERTICAL)
        mainsizer.Add(panel, 0, wx.GROW|wx.ALL, 2)
        mainsizer.Add(self.nb, 1, LCEN|wx.GROW,   2)
        pack(self, mainsizer)

        self.statusbar = self.CreateStatusBar(2, 0)
        self.statusbar.SetStatusWidths([-1, -1])
        statusbar_fields = [self.rawgroup.filename, ""]
        for i in range(len(statusbar_fields)):
            self.statusbar.SetStatusText(statusbar_fields[i], i)


        self.Show()
        self.Raise()
        self.onUpdate(self)

    def onOK(self, event=None):
        """ build arrays according to selection """
        if self.wid_groupname is not None:
            self.outgroup.groupname = fix_varname(self.wid_groupname.GetValue())

        yerr_op = self.yerr_op.GetStringSelection().lower()
        if yerr_op.startswith('const'):
            self.outgroup.yerr = self.yerr_const.GetValue()
        elif yerr_op.startswith('array'):
            yerr = self.yerr_arr.GetStringSelection().strip()
            self.outgroup.yerr = get_data(rawgroup, yerr)
        elif yerr_op.startswith('sqrt'):
            self.outgroup.yerr = np.sqrt(outgroup.ydat)

        if self.read_ok_cb is not None:
            self.read_ok_cb(self.outgroup, array_sel=self.array_sel)
        self.Destroy()

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

    def onYerrChoice(self, evt=None):
        yerr_choice = evt.GetString()
        self.yerr_arr.Disable()
        self.yerr_const.Disable()
        if 'const' in yerr_choice.lower():
            self.yerr_const.Enable()
        elif 'array' in yerr_choice.lower():
            self.yerr_arr.Enable()
        self.onUpdate()

    def onSmoothChoice(self, evt=None):
        choice = self.smooth_op.GetStringSelection().lower()
        conv  = self.smooth_conv.GetStringSelection()
        self.smooth_c0.Disable()
        self.smooth_c1.Disable()
        self.smooth_conv.Disable()
        self.smooth_sig.Disable()

        if choice.startswith('box'):
            self.smooth_c0.Enable()
        elif choice.startswith('savi'):
            self.smooth_c0.Enable()
            self.smooth_c1.Enable()
        elif choice.startswith('conv'):
            self.smooth_conv.Enable()
            self.smooth_sig.Enable()
        self.onUpdate()

    def onUpdate(self, value=None, evt=None):
        """column selections changed calc xdat and ydat"""
        # dtcorr = self.dtcorr.IsChecked()
        dtcorr = False
        use_deriv = self.use_deriv.IsChecked()
        rawgroup = self.rawgroup
        outgroup = self.outgroup

        ix  = self.xarr.GetSelection()
        xname = self.xarr.GetStringSelection()
        if xname == '<index>':
            xname = self.rawgroup.array_labels[0]
            outgroup._index = 1.0*np.arange(len(getattr(rawgroup, xname)))
            xname = '_index'

        outgroup.datatype = self.datatype.GetStringSelection().strip().lower()
        outgroup.xdat = getattr(rawgroup, xname)

        def pre_op(opwid, arr):
            opstr = opwid.GetStringSelection().strip()
            suf = ''
            if opstr in ('-log(', 'log('):
                suf = ')'
                if opstr == 'log(':
                    arr = np.log(arr)
                elif opstr == '-log(':
                    arr = -np.log(arr)
            return suf, opstr, arr

        try:
            xsuf, xpop, outgroup.xdat = pre_op(self.xpop, outgroup.xdat)
            self.xsuf.SetLabel(xsuf)
        except:
            return
        try:
            xunits = rawgroup.array_units[ix].strip()
            xlabel = '%s (%s)' % (xname, xunits)
        except:
            xlabel = xname


        def get_data(grp, arrayname, correct=False):
            if hasattr(grp, 'get_data'):
                return grp.get_data(arrayname, correct=correct)
            return getattr(grp, arrayname, None)

        yname1  = self.yarr1.GetStringSelection().strip()
        yname2  = self.yarr2.GetStringSelection().strip()
        yop = self.yop.GetStringSelection().strip()

        ylabel = yname1
        if len(yname2) == 0:
            yname2 = '1.0'
        else:
            ylabel = "%s%s%s" % (ylabel, yop, yname2)

        yarr1 = get_data(rawgroup, yname1, correct=dtcorr)

        if yname2 in ('0.0', '1.0'):
            yarr2 = float(yname2)
            if yop == '/': yarr2 = 1.0
        else:
            yarr2 = get_data(rawgroup, yname2, correct=dtcorr)

        outgroup.ydat = yarr1
        if yop == '+':
            outgroup.ydat = yarr1.__add__(yarr2)
        elif yop == '-':
            outgroup.ydat = yarr1.__sub__(yarr2)
        elif yop == '*':
            outgroup.ydat = yarr1.__mul__(yarr2)
        elif yop == '/':
            outgroup.ydat = yarr1.__truediv__(yarr2)

        yerr_op = self.yerr_op.GetStringSelection().lower()
        if yerr_op.startswith('const'):
            yerr = self.yerr_const.GetValue()
        elif yerr_op.startswith('array'):
            yerr = self.yerr_arr.GetStringSelection().strip()
            yerr = get_data(rawgroup, yerr)
        elif yerr_op.startswith('sqrt'):
            yerr = np.sqrt(outgroup.ydat)


        ysuf, ypop, outgroup.ydat = pre_op(self.ypop, outgroup.ydat)
        self.ysuf.SetLabel(ysuf)

        if use_deriv:
            try:
                outgroup.ydat = (np.gradient(outgroup.ydat) /
                                 np.gradient(outgroup.xdat))
            except:
                pass

        # apply smoothhing here
        if self.with_smooth:
            smoother = self.smooth_op.GetStringSelection().lower()
            if smoother.startswith('box'):
                n = int(self.smooth_c0.GetValue())
                outgroup.ydat = boxcar(outgroup.ydat, n)
            elif smoother.startswith('savit'):
                n = int(self.smooth_c0.GetValue())
                win_size = 2*n + 1
                order = int(self.smooth_c1.GetValue())
                outgroup.ydat = savitzky_golay(outgroup.ydat, win_size, order)
            elif smoother.startswith('conv'):
                sigma = float(self.smooth_sig.GetValue())
                form  = str(self.smooth_conv.GetStringSelection()).lower()
                outgroup.ydat = smooth(outgroup.xdat, outgroup.ydat,
                                       sigma=sigma, form=form)

        self.array_sel = {'xpop': xpop, 'xarr': xname,
                     'ypop': ypop, 'yop': yop,
                     'yarr1': yname1, 'yarr2': yname2,
                     'use_deriv': use_deriv}

        try:
            npts = min(len(outgroup.xdat), len(outgroup.ydat))
        except AttributeError:
            return

        outgroup.filename    = rawgroup.filename
        outgroup.npts        = npts
        outgroup.plot_xlabel = xlabel
        outgroup.plot_ylabel = ylabel
        outgroup.xdat        = np.array(outgroup.xdat[:npts])
        outgroup.ydat        = np.array(outgroup.ydat[:npts])
        outgroup.y           = outgroup.ydat
        outgroup.yerr        = yerr
        if isinstance(yerr, np.ndarray):
            outgroup.yerr    = np.array(yerr[:npts])

        if outgroup.datatype == 'xas':
            outgroup.energy = outgroup.xdat
            outgroup.mu     = outgroup.ydat

        popts = {}
        path, fname = os.path.split(outgroup.filename)
        popts['label'] = "%s: %s" % (fname, outgroup.plot_ylabel)
        popts['title']  = fname
        popts['ylabel'] = outgroup.plot_ylabel
        popts['xlabel'] = outgroup.plot_xlabel

        self.plotpanel.plot(outgroup.xdat, outgroup.ydat, **popts)

        for i in range(self.nb.GetPageCount()):
            if 'plot' in self.nb.GetPageText(i).lower():
                self.nb.SetSelection(i)

    def plot_messages(self, msg, panel=1):
        self.SetStatusText(msg, panel)
예제 #12
0
class MainFrame(wx.Frame):  #

    monitor_address = 'C3/hr_monitor/1'
    yellow_alrm_thrsh = 0.25
    red_alrm_thrsh = 0.5
    sleep_time = 5

    def __init__(self, *args, **kwds):
        # begin wxGlade: MainFrame.__init__
        kwds["style"] = wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self, *args, **kwds)
        self.alarm_plt = PlotPanel(self)
        #self.timestamp_sld = wx.Slider(self, -1, 0, 0, 10)
        self.avg_hr_title_lbl = wx.StaticText(self, -1, "Current avg. HR:")
        self.avg_hr_lbl = wx.StaticText(self, -1, "nan")
        self.panel_1 = wx.Panel(self, -1)
        self.avg_acc_title_lbl = wx.StaticText(self, -1,
                                               "Current avg. Acceleration:")
        self.avg_acc_lbl = wx.StaticText(self, -1, "nan")
        self.panel_2 = wx.Panel(self, -1)
        self.anomaly_lvl_curr_title_lbl = wx.StaticText(
            self, -1, "Anomaly level: Current:")
        self.anomaly_lvl_curr_lbl = wx.StaticText(self, -1, "nan")
        self.panel_3 = wx.Panel(self, -1)
        self.anomaly_lvl_max_title_lbl = wx.StaticText(
            self, -1, "                                 Max:")
        self.anomaly_lvl_max_lbl = wx.StaticText(self, -1, "nan")
        self.red_alarm_lbl = wx.Panel(self, -1)
        self.anomaly_lvl_min_title_lbl = wx.StaticText(
            self, -1, "                                 Min:")
        self.anomaly_lvl_min_lbl = wx.StaticText(self, -1, "nan")
        self.yellow_alarm_lbl = wx.Panel(self, -1)
        self.anomaly_lvl_avg_title_lbl = wx.StaticText(
            self, -1, "                                 Average:")
        self.anomaly_lvl_avg_lbl = wx.StaticText(self, -1, "nan")
        self.green_alarm_lbl = wx.Panel(self, -1)
        self.collect_btn = wx.Button(self, -1, "Collect data")

        self.__set_properties()
        self.__do_layout()

        #self.Bind(wx.EVT_COMMAND_SCROLL, self.timestamp_sld_scroll, self.timestamp_sld)
        self.Bind(wx.EVT_BUTTON, self.collect_btn_click, self.collect_btn)
        # end wxGlade
        self.timer_thread = Timer(target=self.timer_tick)
        self.proxy = DeviceProxy(MainFrame.monitor_address)
        self.alarms = set()

    def __set_properties(self):
        # begin wxGlade: MainFrame.__set_properties
        self.SetTitle("HRMonitor GUI")
        self.red_alarm_lbl.SetBackgroundColour(wx.NullColor)
        self.yellow_alarm_lbl.SetBackgroundColour(wx.NullColor)
        self.green_alarm_lbl.SetBackgroundColour(wx.NullColor)
        # end wxGlade

    def __do_layout(self):
        # begin wxGlade: MainFrame.__do_layout
        sizer_1 = wx.BoxSizer(wx.VERTICAL)
        sizer_2 = wx.BoxSizer(wx.VERTICAL)
        sizer_3 = wx.BoxSizer(wx.HORIZONTAL)
        grid_sizer_2 = wx.GridSizer(6, 3, 0, 0)
        sizer_1.Add(self.alarm_plt, 1, wx.EXPAND, 0)
        #sizer_1.Add(self.timestamp_sld, 0, wx.EXPAND, 0)
        grid_sizer_2.Add(self.avg_hr_title_lbl, 0, 0, 0)
        grid_sizer_2.Add(self.avg_hr_lbl, 0, 0, 0)
        grid_sizer_2.Add(self.panel_1, 1, wx.EXPAND, 0)
        grid_sizer_2.Add(self.avg_acc_title_lbl, 0, 0, 0)
        grid_sizer_2.Add(self.avg_acc_lbl, 0, 0, 0)
        grid_sizer_2.Add(self.panel_2, 1, wx.EXPAND, 0)
        grid_sizer_2.Add(self.anomaly_lvl_curr_title_lbl, 0, 0, 0)
        grid_sizer_2.Add(self.anomaly_lvl_curr_lbl, 0, 0, 0)
        grid_sizer_2.Add(self.panel_3, 1, wx.EXPAND, 0)
        grid_sizer_2.Add(self.anomaly_lvl_max_title_lbl, 0, 0, 0)
        grid_sizer_2.Add(self.anomaly_lvl_max_lbl, 0, 0, 0)
        grid_sizer_2.Add(self.red_alarm_lbl, 0, wx.EXPAND, 0)
        grid_sizer_2.Add(self.anomaly_lvl_min_title_lbl, 0, 0, 0)
        grid_sizer_2.Add(self.anomaly_lvl_min_lbl, 0, 0, 0)
        grid_sizer_2.Add(self.yellow_alarm_lbl, 0, wx.EXPAND, 0)
        grid_sizer_2.Add(self.anomaly_lvl_avg_title_lbl, 0, 0, 0)
        grid_sizer_2.Add(self.anomaly_lvl_avg_lbl, 0, 0, 0)
        grid_sizer_2.Add(self.green_alarm_lbl, 0, wx.EXPAND, 0)
        sizer_2.Add(grid_sizer_2, 9, wx.EXPAND, 0)
        sizer_3.Add(self.collect_btn, 0, wx.ALL, 0)
        sizer_2.Add(sizer_3, 1, wx.EXPAND | wx.SHAPED, 0)
        sizer_1.Add(sizer_2, 1, wx.EXPAND, 0)
        self.SetSizer(sizer_1)
        sizer_1.Fit(self)
        self.Layout()
        # end wxGlade

    # wxGlade: MainFrame.<event_handler>
    def timestamp_sld_scroll(self, event):
        print("Event handler `timestamp_sld_scroll' not implemented")
        event.Skip()

    # wxGlade: MainFrame.<event_handler>
    def collect_btn_click(self, event):
        if self.collect_btn.GetLabel() == "Stop collecting":
            self.collect_btn.SetLabel("Collect data")
            self.timer_thread.stop()
            del self.timer_thread
            self.timer_thread = Timer(target=self.timer_tick)
        else:
            self.collect_btn.SetLabel("Stop collecting")
            self.timer_thread.start()
        event.Skip()


# end of class MainFrame

    def timer_tick(self):
        timer = current_thread()
        proxy = self.proxy
        while not timer.stopped():
            try:
                avg_hr_idx = proxy.command_inout_asynch('get_avg_hr', 4)
                avg_acc_idx = proxy.command_inout_asynch('get_avg_acc', 4)
                alarms_idx = proxy.command_inout_asynch(
                    'get_current_alarms', 4)
                init = datetime.now()
                avg_hr = proxy.command_inout_reply(avg_hr_idx, timeout=0)
                avg_acc = proxy.command_inout_reply(avg_acc_idx, timeout=0)
                alarms = proxy.command_inout_reply(alarms_idx, timeout=0)
                sleep_time = timedelta(seconds=MainFrame.sleep_time)
                sleep_time -= (datetime.now() - init)
                sleep_time = max(sleep_time, timedelta(0)).total_seconds()
                alarms[0], alarms[1] = alarms[1], alarms[0]
                alarms[0] = [
                    float(
                        datetime.strptime(
                            x, '%Y-%m-%d %H:%M:%S.%f').strftime('%s.%f'))
                    for x in alarms[0]
                ]
                alarms[0] = [x % 100000 for x in alarms[0]]
                if not isnan(avg_hr):
                    wx.CallAfter(self.avg_hr_lbl.SetLabel, str(avg_hr))
                if not isnan(avg_acc):
                    wx.CallAfter(self.avg_acc_lbl.SetLabel, str(avg_acc))
                if len(alarms[0]) > 0:
                    self.alarms.update(zip(*alarms))
                    wx.CallAfter(self.set_alarm_text)

                data = sorted(self.alarms)
                if len(data) > 0:
                    wx.CallAfter(self.plot, zip(*data))
                    wx.CallAfter(self.set_alarm_color, max(data)[1])
                sleep(sleep_time)
            except ConnectionFailed:
                wx.CallAfter(self.collect_btn_click, None)
                break
        del proxy

    def plot(self, data):
        x_data, y_data = data
        self.alarm_plt.plot(x_data, y_data, title="Alarm Level History")

    def set_alarm_text(self):
        alarms = sorted(self.alarms)
        if len(alarms) > 0:
            vals = [x for _, x in alarms]
        else:
            vals = [nan]
            alarms = [(nan, nan)]
        avg = sum(vals) / len(vals)
        self.anomaly_lvl_curr_lbl.SetLabel(str(alarms[-1][1]))
        self.anomaly_lvl_max_lbl.SetLabel(str(max(vals)))
        self.anomaly_lvl_min_lbl.SetLabel(str(min(vals)))
        self.anomaly_lvl_avg_lbl.SetLabel(str(avg))

    def set_alarm_color(self, alarm_lvl):
        if alarm_lvl < MainFrame.yellow_alrm_thrsh:
            self.red_alarm_lbl.SetBackgroundColour(wx.NullColor)
            self.yellow_alarm_lbl.SetBackgroundColour(wx.NullColor)
            self.green_alarm_lbl.SetBackgroundColour('Green')
        elif MainFrame.yellow_alrm_thrsh <= alarm_lvl < MainFrame.red_alrm_thrsh:
            self.red_alarm_lbl.SetBackgroundColour(wx.NullColor)
            self.yellow_alarm_lbl.SetBackgroundColour('Yellow')
            self.green_alarm_lbl.SetBackgroundColour(wx.NullColor)
        else:
            self.red_alarm_lbl.SetBackgroundColour('Red')
            self.yellow_alarm_lbl.SetBackgroundColour(wx.NullColor)
            self.green_alarm_lbl.SetBackgroundColour(wx.NullColor)
        # get a color between green and red, going through yellow
        # offset = 0.2
        # adjusted_lvl = min(alarm_lvl + offset, 1)
        # r, g, b = hsv_to_rgb((1 - adjusted_lvl) / 3, 1, 1)
        # r = int(255 * r)
        # g = int(255 * g)
        # b = int(255 * b)
        # color = wx.Color(r, g, b)
        # self.green_alarm_lbl.SetBackgroundColour(color)
        self.red_alarm_lbl.Refresh()
        self.yellow_alarm_lbl.Refresh()
        self.green_alarm_lbl.Refresh()
        self.Refresh()