Subversion Repositories Projects

Rev

Rev 606 | Rev 608 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

#!/usr/bin/env python
# -*- coding: iso-8859-15 -*-
# generated by wxGlade 0.6.3 on Thu Sep 24 15:46:36 2009

import sys
import os
import wx
import wx.lib
import wx.lib.plot
import ConfigParser

# Needs Numeric or numarray or NumPy
try:
    import numpy.oldnumeric as _Numeric
except:
    try:
        import numarray as _Numeric  #if numarray is used it is renamed Numeric
    except:
        try:
            import Numeric as _Numeric
        except:
            msg= """
            This module requires the Numeric/numarray or NumPy module,
            which could not be imported.  It probably is not installed
            (it's not part of the standard Python distribution). See the
            Numeric Python site (http://numpy.scipy.org) for information on
            downloading source or binaries."""
            raise ImportError, "Numeric,numarray or NumPy not found. \n" + msg

# begin wxGlade: extracode
# end wxGlade



class SettingsDialog(wx.Dialog):
    def __init__(self, *args, **kwds):
        # begin wxGlade: SettingsDialog.__init__
        kwds["style"] = wx.DEFAULT_DIALOG_STYLE
        wx.Dialog.__init__(self, *args, **kwds)
        self.label_5_copy = wx.StaticText(self, -1, "COM Port ", style=wx.ALIGN_RIGHT)
        self.comPortCtrl_copy = wx.TextCtrl(self, -1, "")
        self.button_5_copy = wx.Button(self, wx.ID_CANCEL, "")
        self.button_6_copy = wx.Button(self, wx.ID_OK, "")

        self.__set_properties()
        self.__do_layout()
        # end wxGlade

    def __set_properties(self):
        # begin wxGlade: SettingsDialog.__set_properties
        self.SetTitle("Settings")
        # end wxGlade

    def __do_layout(self):
        # begin wxGlade: SettingsDialog.__do_layout
        sizer_5_copy = wx.BoxSizer(wx.VERTICAL)
        grid_sizer_3_copy = wx.GridSizer(1, 2, 0, 0)
        sizer_6_copy = wx.BoxSizer(wx.HORIZONTAL)
        grid_sizer_2_copy = wx.GridSizer(1, 2, 4, 4)
        sizer_5_copy.Add((20, 20), 0, 0, 0)
        sizer_6_copy.Add((20, 20), 0, 0, 0)
        grid_sizer_2_copy.Add(self.label_5_copy, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0)
        grid_sizer_2_copy.Add(self.comPortCtrl_copy, 0, 0, 0)
        sizer_6_copy.Add(grid_sizer_2_copy, 0, 0, 0)
        sizer_6_copy.Add((20, 20), 0, 0, 0)
        sizer_5_copy.Add(sizer_6_copy, 1, wx.EXPAND, 0)
        sizer_5_copy.Add((20, 20), 0, 0, 0)
        grid_sizer_3_copy.Add(self.button_5_copy, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 0)
        grid_sizer_3_copy.Add(self.button_6_copy, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 0)
        sizer_5_copy.Add(grid_sizer_3_copy, 0, wx.EXPAND, 0)
        sizer_5_copy.Add((20, 20), 0, 0, 0)
        self.SetSizer(sizer_5_copy)
        sizer_5_copy.Fit(self)
        self.Layout()
        # end wxGlade

# end of class SettingsDialog


class SettingsFrame(wx.Frame):
    def __init__(self, *args, **kwds):
        # content of this block not found: did you rename this class?
        pass

    def __set_properties(self):
        # content of this block not found: did you rename this class?
        pass

    def __do_layout(self):
        # content of this block not found: did you rename this class?
        pass

# end of class SettingsFrame


class MenuBar(wx.MenuBar):
    def __init__(self, *args, **kwds):
        # content of this block not found: did you rename this class?
        pass

    def __set_properties(self):
        # content of this block not found: did you rename this class?
        pass

    def __do_layout(self):
        # content of this block not found: did you rename this class?
        pass

# end of class MenuBar


class wxFrame(wx.Panel):
    def __init__(self, *args, **kwds):
        # content of this block not found: did you rename this class?
        pass

    def __set_properties(self):
        # content of this block not found: did you rename this class?
        pass

    def __do_layout(self):
        # content of this block not found: did you rename this class?
        pass

# end of class wxFrame


class MyFrame(wx.Frame):
    def __init__(self, *args, **kwds):
        # content of this block not found: did you rename this class?
        pass

    def __set_properties(self):
        # content of this block not found: did you rename this class?
        pass

    def __do_layout(self):
        # content of this block not found: did you rename this class?
        pass

# end of class MyFrame


class MainFrame(wx.Frame):
    def __init__(self, *args, **kwds):
        # begin wxGlade: MainFrame.__init__
        kwds["style"] = wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self, *args, **kwds)
        
        # Menu Bar
        self.frame_1_menubar = wx.MenuBar()
        wxglade_tmp_menu = wx.Menu()
        wxglade_tmp_menu.Append(101, "Settings", "", wx.ITEM_NORMAL)
        wxglade_tmp_menu.Append(150, "Exit", "", wx.ITEM_NORMAL)
        self.frame_1_menubar.Append(wxglade_tmp_menu, "File")
        wxglade_tmp_menu = wx.Menu()
        wxglade_tmp_menu.Append(301, "Clear", "", wx.ITEM_NORMAL)
        wxglade_tmp_menu.Append(302, "Import", "", wx.ITEM_NORMAL)
        self.frame_1_menubar.Append(wxglade_tmp_menu, "TestSet")
        wxglade_tmp_menu = wx.Menu()
        self.frame_1_menubar.Append(wxglade_tmp_menu, "MK")
        wxglade_tmp_menu = wx.Menu()
        self.frame_1_menubar.Append(wxglade_tmp_menu, "Help")
        self.SetMenuBar(self.frame_1_menubar)
        # Menu Bar end
        self.Description = wx.StaticText(self, -1, "Description")
        self.text_ctrl_6 = wx.TextCtrl(self, -1, "Test")
        self.label_37 = wx.StaticText(self, -1, "Speed(s)")
        self.text_ctrl_9 = wx.TextCtrl(self, -1, "100-200:10")
        self.label_35 = wx.StaticText(self, -1, "Motor(s)")
        self.text_ctrl_7 = wx.TextCtrl(self, -1, "1")
        self.label_38 = wx.StaticText(self, -1, "")
        self.text_ctrl_10 = wx.TextCtrl(self, -1, "")
        self.label_36 = wx.StaticText(self, -1, "Channel")
        self.text_ctrl_8 = wx.TextCtrl(self, -1, "6")
        self.label_39 = wx.StaticText(self, -1, "")
        self.text_ctrl_11 = wx.TextCtrl(self, -1, "")
        self.button_4 = wx.Button(self, -1, "Start")
        self.GraphPanel = wx.Panel(self, -1)
        self.label_40 = wx.StaticText(self, -1, "Graph Type ")
        self.graphTypeChoice = wx.Choice(self, -1, choices=["Raw Signal", "Filtered Signal", "Spectrum"])
        self.label_41 = wx.StaticText(self, -1, "Y Axis Range ")
        self.yAxisChoice = wx.Choice(self, -1, choices=["25", "50", "100", "200"])
        self.TestListCtrl = wx.ListCtrl(self, -1, style=wx.LC_REPORT|wx.SUNKEN_BORDER)

        self.__set_properties()
        self.__do_layout()

        self.Bind(wx.EVT_MENU, self.OnSettings, id=101)
        self.Bind(wx.EVT_MENU, self.onClear, id=301)
        self.Bind(wx.EVT_MENU, self.OnImport, id=302)
        self.Bind(wx.EVT_CHOICE, self.onGraphTypeChange, self.graphTypeChoice)
        self.Bind(wx.EVT_CHOICE, self.onYAxisChange, self.yAxisChoice)
        # end wxGlade

    def setApp(self, app):
        self.app = app

    def __set_properties(self):
        # begin wxGlade: MainFrame.__set_properties
        self.SetTitle("VibrationTest")
        self.SetSize((850, 700))
        self.Description.SetMinSize((53, 13))
        self.button_4.SetMinSize((80, 80))
        self.GraphPanel.SetMinSize((800,300))
        self.graphTypeChoice.SetSelection(0)
        self.yAxisChoice.SetSelection(1)
        self.TestListCtrl.SetMinSize((800,300))
        # end wxGlade

    def __do_layout(self):
        # begin wxGlade: MainFrame.__do_layout
        sizer_3 = wx.BoxSizer(wx.HORIZONTAL)
        sizer_8 = wx.BoxSizer(wx.VERTICAL)
        sizer_11 = wx.BoxSizer(wx.VERTICAL)
        sizer_12 = wx.BoxSizer(wx.HORIZONTAL)
        sizer_9 = wx.BoxSizer(wx.HORIZONTAL)
        sizer_10 = wx.BoxSizer(wx.HORIZONTAL)
        grid_sizer_1 = wx.GridSizer(3, 4, 4, 5)
        sizer_3.Add((20, 20), 0, 0, 0)
        sizer_8.Add((20, 20), 0, 0, 0)
        grid_sizer_1.Add(self.Description, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0)
        grid_sizer_1.Add(self.text_ctrl_6, 0, 0, 0)
        grid_sizer_1.Add(self.label_37, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0)
        grid_sizer_1.Add(self.text_ctrl_9, 0, 0, 0)
        grid_sizer_1.Add(self.label_35, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0)
        grid_sizer_1.Add(self.text_ctrl_7, 0, 0, 0)
        grid_sizer_1.Add(self.label_38, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0)
        grid_sizer_1.Add(self.text_ctrl_10, 0, 0, 0)
        grid_sizer_1.Add(self.label_36, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0)
        grid_sizer_1.Add(self.text_ctrl_8, 0, 0, 0)
        grid_sizer_1.Add(self.label_39, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0)
        grid_sizer_1.Add(self.text_ctrl_11, 0, 0, 0)
        sizer_9.Add(grid_sizer_1, 0, 0, 0)
        sizer_10.Add((50, 20), 0, 0, 0)
        sizer_10.Add(self.button_4, 0, wx.ALIGN_CENTER_VERTICAL, 0)
        sizer_9.Add(sizer_10, 1, wx.EXPAND, 0)
        sizer_8.Add(sizer_9, 0, 0, 0)
        sizer_8.Add((20, 30), 0, 0, 0)
        sizer_11.Add(self.GraphPanel, 1, wx.EXPAND, 0)
        sizer_11.Add((20, 5), 0, 0, 0)
        sizer_12.Add(self.label_40, 0, wx.ALIGN_CENTER_VERTICAL, 0)
        sizer_12.Add(self.graphTypeChoice, 0, 0, 0)
        sizer_12.Add((40, 20), 0, 0, 0)
        sizer_12.Add(self.label_41, 0, wx.ALIGN_CENTER_VERTICAL, 0)
        sizer_12.Add(self.yAxisChoice, 0, 0, 0)
        sizer_11.Add(sizer_12, 0, 0, 0)
        sizer_8.Add(sizer_11, 0, 0, 0)
        sizer_8.Add((20, 30), 0, 0, 0)
        sizer_8.Add(self.TestListCtrl, 1, 0, 0)
        sizer_8.Add((20, 20), 0, 0, 0)
        sizer_3.Add(sizer_8, 1, wx.EXPAND, 0)
        self.SetSizer(sizer_3)
        self.Layout()
        self.SetSize((850, 700))
        # end wxGlade

        # List events
        self.TestListCtrl.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnTestSelected, self.TestListCtrl)

        # Configure Graph
        self.client = wx.lib.plot.PlotCanvas(self.GraphPanel, size=(800,300))
        
        self.client.SetPointLabelFunc(self.DrawPointLabel)
        
        self.client.SetFont(wx.Font(10,wx.SWISS,wx.NORMAL,wx.NORMAL))
        self.client.SetFontSizeAxis(10)
        self.client.SetFontSizeLegend(7)
        self.client.setLogScale((False,False))


        # Configure TestListCtrl
        self.TestListCtrl.InsertColumn(0, "Description")
        self.TestListCtrl.InsertColumn(1, "Speed")
        self.TestListCtrl.InsertColumn(2, "Channel")
        self.TestListCtrl.InsertColumn(3, "Vibration Value")
        self.TestListCtrl.SetColumnWidth(3, 500)

    def DrawPointLabel(self, dc, mDataDict):
        """This is the fuction that defines how the pointLabels are plotted
            dc - DC that will be passed
            mDataDict - Dictionary of data that you want to use for the pointLabel

            As an example I have decided I want a box at the curve point
            with some text information about the curve plotted below.
            Any wxDC method can be used.
        """
        # ----------
        dc.SetPen(wx.Pen(wx.BLACK))
        dc.SetBrush(wx.Brush( wx.BLACK, wx.SOLID ) )
        
        sx, sy = mDataDict["scaledXY"] #scaled x,y of closest point
        dc.DrawRectangle( sx-5,sy-5, 10, 10)  #10by10 square centered on point
        px,py = mDataDict["pointXY"]
        cNum = mDataDict["curveNum"]
        pntIn = mDataDict["pIndex"]
        legend = mDataDict["legend"]
        #make a string to display
        s = "Crv# %i, '%s', Pt. (%.2f,%.2f), PtInd %i" %(cNum, legend, px, py, pntIn)
        dc.DrawText(s, sx , sy+1)
        # -----------


    def onNewTest(self, test):
        index = self.TestListCtrl.InsertStringItem(sys.maxint, test.descr)
        self.TestListCtrl.SetStringItem(index, 1, str(test.speed))
        self.TestListCtrl.SetStringItem(index, 2, test.channel)

        vv = int(test.getVibValue())
        vvs = "|%s| (%d)" % ("----------------------------------------------------------------------------------------------------"[0:min(vv,100)], vv)
        self.TestListCtrl.SetStringItem(index, 3, vvs)
        if (index == 0):
            self.TestListCtrl.Select(index)


    def OnTestSelected(self, event):
         testId = event.m_itemIndex
         print "Test Selected id=%d" % (testId)
         self.activeTestId = testId
         self.drawGraph()

    def drawGraph(self):
         
         y = int(self.yAxisChoice.GetStringSelection())

         nbSelected = self.TestListCtrl.SelectedItemCount

         if nbSelected > 1:
             self.graphTypeChoice.Disable()
             x = 1
             data = []
             idx = self.TestListCtrl.GetFirstSelected()
             while idx != -1:
                 data.append([x,self.app.getTest(idx).getVibValue()])
                 x += 1
                 idx = self.TestListCtrl.GetNextSelected(idx)
             line = wx.lib.plot.PolyLine(data, legend= 'Vibrations', colour='red', width=2)
             markers = wx.lib.plot.PolyMarker(data, legend= '', colour='red', marker='circle',size=2)
             title = "Comparing tests" 
             self.client.Draw(wx.lib.plot.PlotGraphics([line, markers], title, "Test", "Vibration Value"), xAxis=(1,max(x,10)), yAxis=(0,y))
             self.client.SetEnableGrid('Horizontal')

         else:
             self.graphTypeChoice.Enable()
             vibTest = self.app.getTest(self.activeTestId)
             nb = vibTest.getDataLen()

             if self.graphTypeChoice.GetSelection() == 0:
                 xydata = _Numeric.linspace(0,0.09*nb,2*nb)
                 xydata.shape = (nb, 2)
                 xydata[:,1] = vibTest.getRawData()
                 line = wx.lib.plot.PolyLine(xydata, legend= 'Raw Data', colour='red', width=2)
        
                 title = "Raw Signal: %s %s %d" %(vibTest.descr, vibTest.channel, vibTest.speed)
                 self.client.Draw(wx.lib.plot.PlotGraphics([line], title, "Time (ms)", "Acc"), yAxis= (-y,y))
                 self.client.SetEnableGrid('Horizontal')
    
             if self.graphTypeChoice.GetSelection() == 1:
                 xydata = _Numeric.linspace(0,0.09*nb,2*nb)
                 xydata.shape = (nb, 2)
                 xydata[:,1] = vibTest.getFilteredData()
                 line = wx.lib.plot.PolyLine(xydata, legend= 'Raw Data', colour='red', width=2)
        
                 title = "Filtered Signal: %s %s %d" %(vibTest.descr, vibTest.channel, vibTest.speed)
                 self.client.Draw(wx.lib.plot.PlotGraphics([line], title, "Time (ms)", "Acc"), yAxis= (-y,y))
                 self.client.SetEnableGrid('Horizontal')
    
             elif self.graphTypeChoice.GetSelection() == 2:
                 xydata = _Numeric.linspace(0,5555,nb)
                 xydata.shape = (nb/2, 2)
                 
                 xydata[:,1] = vibTest.getSpectrum()
    
                 line = wx.lib.plot.PolyLine(xydata, legend= 'Spectrum', colour='red')
                 markers = wx.lib.plot.PolyMarker(xydata, legend= '', colour='red', marker='circle',size=2)
        
                 title = "Spectrum: %s %s %d" %(vibTest.descr, vibTest.channel, vibTest.speed)
                 self.client.Draw(wx.lib.plot.PlotGraphics([line,markers], title, "Freq (Hz)", "Acc"), xAxis=(0,200), yAxis= (-0,y))
                 self.client.SetEnableGrid(True)


    def OnImport(self, event): # wxGlade: MainFrame.<event_handler>
        dlg = wx.FileDialog(
            self, message="Choose a file",
            defaultDir=os.getcwd(), 
            defaultFile="*.txt",
            wildcard="",
            style=wx.OPEN | wx.CHANGE_DIR
            )
        if dlg.ShowModal() == wx.ID_OK:
            paths = dlg.GetPaths();
            self.app.Import(paths[0])
        dlg.Destroy()

    def onYAxisChange(self, event): # wxGlade: MainFrame.<event_handler>
        self.drawGraph()

    def onGraphTypeChange(self, event): # wxGlade: MainFrame.<event_handler>
        self.drawGraph()

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

    def OnSettings(self, event): # wxGlade: MainFrame.<event_handler>
        dlg = SettingsDialog(self, -1, "Sample Dialog", size=(350, 200),
                         #style=wx.CAPTION | wx.SYSTEM_MENU | wx.THICK_FRAME,
                         style=wx.DEFAULT_DIALOG_STYLE, # & ~wx.CLOSE_BOX
                         )
        dlg.CenterOnScreen()

        # this does not return until the dialog is closed.
        val = dlg.ShowModal()

        dlg.Destroy()

# end of class MainFrame

class Setting:
    def __init__(self, descr, defaultValue):
        self.descr = descr
        self.value = defaultValue

class VibTest:
    def __init__(self, descr, motor, speed, channel, rawData):
        self.descr = descr
        self.motor = motor
        self.speed = speed
        self.channel = channel

        self.dataLen = len(rawData)

        self.rawData = _Numeric.array(rawData)
        self.dc = self.rawData.mean()
        self.rawData -= self.dc

        self.fft = _Numeric.fft.rfft(self.rawData)

        self.spectrum = None
        self.filteredData = None
        
        self.vibValue = None
        
    def getDescr(self):
        return self.Descr

    def getRawData(self):
        return self.rawData

    def getDataLen(self):
        return self.dataLen

    def getSpectrum(self):
        if self.spectrum == None:
            self.spectrum = _Numeric.absolute(self.fft[1:self.dataLen/2+1]) / (self.dataLen/2)
        return self.spectrum

    def getFilteredData(self):
        if self.filteredData == None:
            tmpfft = self.fft.copy()
            for i in range(0,5):
                tmpfft[i] = 0
            for i in range(30, len(tmpfft)):
                tmpfft[i] = 0
            self.filteredData = _Numeric.fft.irfft(tmpfft)
        return self.filteredData
        
    def getVibValue(self):
      if self.vibValue == None:
        fd = self.getFilteredData();
        self.vibValue = max(fd)-min(fd)
      return self.vibValue



class App(wx.App):

    SETTINGSFILE = "settings.cfg"

    def __init__(self, par):
        self.VibTests = []
        wx.App.__init__(self, par)

        # Init settings
        self.settings={}
        self.settings["serialPort"] = Setting("SerialPort", "COM1")
        self.settings["hpf"] = Setting("HP Filter cutoff (Hz)", 50)
        self.settings["lpf"] = Setting("LP Filter cutoff (Hz)", 400)

        self.readSettings()

        if len(sys.argv)>1:
            self.Import(sys.argv[1])


    def readSettings(self):
        print "Reading settings"
        cp = ConfigParser.ConfigParser()

        try:
            cp.read(App.SETTINGSFILE)
            for setting in cp.items("DEFAULT"):
                print " ",setting
                try:
                    self.settings[setting[0]].value = setting[1] 
                except:
                    print "WARNING, unknown setting"
        except:
            print "ERROR reading settingsfile"


    def storeSettings(self):
        print "Storing settings"

        cp = ConfigParser.ConfigParser()
        for setting in self.settings.iteritems():
            cp.set("", setting[0], setting[1].value)

        file = open(App.SETTINGSFILE, "w")
        cp.write(file)
        file.close()

    def AddTest(self, descr, motor, speed, channel, rawData):
        test = VibTest(descr, motor, speed, channel, rawData)
        self.VibTests.append(test)
        self.frame_1.onNewTest(test)

    def getTest(self, testId):
        return self.VibTests[testId]

    def OnInit(self):
        wx.InitAllImageHandlers()
        self.frame_1 = MainFrame(None, -1, "")
        self.frame_1.setApp(self);
        self.SetTopWindow(self.frame_1)

        self.frame_1.CenterOnScreen()
        self.frame_1.Show()
        return 1

    def Import(self, filePath):
        
        print "Importing file \"%s\"" % filePath

        logfile = open(filePath, "r")
        data = None

        headers = (logfile.readline()).split(',')
        nbCols = len(headers)
        print "NbCols =", nbCols

        data = []
        descr = [] 
        speed = []
        channel = []
        for c in range(nbCols): 
            data.append([])
            h = headers[c].split(' ')
            descr.append(h[0]);
            speed.append(h[1]);
            channel.append(h[2]);

        for line in logfile:
            values = line.split(',')
            for i in range(nbCols):
                data[i].append(int(values[i]))
        logfile.close()

        for c in range(nbCols):
            if (len(data[c]) % 2) != 0:
                data[c].append(data[c][-1])
            self.AddTest(descr[c], 0, int(speed[c]), channel[c], data[c])
        
        
            

        
# end of class App

if __name__ == "__main__":
    VibrationTestGui = App(0)
    VibrationTestGui.MainLoop()