Subversion Repositories Projects

Rev

Rev 602 | Rev 607 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
584 FredericG 1
#!/usr/bin/env python
2
# -*- coding: iso-8859-15 -*-
3
# generated by wxGlade 0.6.3 on Thu Sep 24 15:46:36 2009
4
 
586 FredericG 5
import sys
606 FredericG 6
import os
584 FredericG 7
import wx
585 FredericG 8
import wx.lib
9
import wx.lib.plot
584 FredericG 10
 
585 FredericG 11
# Needs Numeric or numarray or NumPy
12
try:
13
    import numpy.oldnumeric as _Numeric
14
except:
15
    try:
16
        import numarray as _Numeric  #if numarray is used it is renamed Numeric
17
    except:
18
        try:
19
            import Numeric as _Numeric
20
        except:
21
            msg= """
22
            This module requires the Numeric/numarray or NumPy module,
23
            which could not be imported.  It probably is not installed
24
            (it's not part of the standard Python distribution). See the
25
            Numeric Python site (http://numpy.scipy.org) for information on
26
            downloading source or binaries."""
27
            raise ImportError, "Numeric,numarray or NumPy not found. \n" + msg
28
 
584 FredericG 29
# begin wxGlade: extracode
30
# end wxGlade
31
 
32
 
33
 
601 FredericG 34
class SettingsFrame(wx.Frame):
35
    def __init__(self, *args, **kwds):
36
        # begin wxGlade: SettingsFrame.__init__
37
        kwds["style"] = wx.DEFAULT_FRAME_STYLE
38
        wx.Frame.__init__(self, *args, **kwds)
39
        self.label_5 = wx.StaticText(self, -1, "COM Port ", style=wx.ALIGN_RIGHT)
40
        self.comPortCtrl = wx.TextCtrl(self, -1, "")
41
        self.button_5 = wx.Button(self, wx.ID_CANCEL, "")
42
        self.button_6 = wx.Button(self, wx.ID_OK, "")
43
 
44
        self.__set_properties()
45
        self.__do_layout()
46
        # end wxGlade
47
 
48
    def __set_properties(self):
49
        # begin wxGlade: SettingsFrame.__set_properties
50
        self.SetTitle("Settings")
51
        # end wxGlade
52
 
53
    def __do_layout(self):
54
        # begin wxGlade: SettingsFrame.__do_layout
55
        sizer_5 = wx.BoxSizer(wx.VERTICAL)
56
        grid_sizer_3 = wx.GridSizer(1, 2, 0, 0)
57
        sizer_6 = wx.BoxSizer(wx.HORIZONTAL)
58
        grid_sizer_2 = wx.GridSizer(1, 2, 4, 4)
59
        sizer_5.Add((20, 20), 0, 0, 0)
60
        sizer_6.Add((20, 20), 0, 0, 0)
61
        grid_sizer_2.Add(self.label_5, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0)
62
        grid_sizer_2.Add(self.comPortCtrl, 0, 0, 0)
63
        sizer_6.Add(grid_sizer_2, 0, 0, 0)
64
        sizer_6.Add((20, 20), 0, 0, 0)
65
        sizer_5.Add(sizer_6, 1, wx.EXPAND, 0)
66
        sizer_5.Add((20, 20), 0, 0, 0)
67
        grid_sizer_3.Add(self.button_5, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 0)
68
        grid_sizer_3.Add(self.button_6, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 0)
69
        sizer_5.Add(grid_sizer_3, 0, wx.EXPAND, 0)
70
        sizer_5.Add((20, 20), 0, 0, 0)
71
        self.SetSizer(sizer_5)
72
        sizer_5.Fit(self)
73
        self.Layout()
74
        # end wxGlade
75
 
76
# end of class SettingsFrame
77
 
78
 
587 FredericG 79
class MenuBar(wx.MenuBar):
80
    def __init__(self, *args, **kwds):
81
        # content of this block not found: did you rename this class?
82
        pass
83
 
84
    def __set_properties(self):
85
        # content of this block not found: did you rename this class?
86
        pass
87
 
88
    def __do_layout(self):
89
        # content of this block not found: did you rename this class?
90
        pass
91
 
92
# end of class MenuBar
93
 
94
 
585 FredericG 95
class wxFrame(wx.Panel):
96
    def __init__(self, *args, **kwds):
586 FredericG 97
        # content of this block not found: did you rename this class?
98
        pass
585 FredericG 99
 
100
    def __set_properties(self):
586 FredericG 101
        # content of this block not found: did you rename this class?
585 FredericG 102
        pass
103
 
104
    def __do_layout(self):
586 FredericG 105
        # content of this block not found: did you rename this class?
585 FredericG 106
        pass
107
 
108
# end of class wxFrame
109
 
110
 
111
class MyFrame(wx.Frame):
112
    def __init__(self, *args, **kwds):
113
        # content of this block not found: did you rename this class?
114
        pass
115
 
116
    def __set_properties(self):
117
        # content of this block not found: did you rename this class?
118
        pass
119
 
120
    def __do_layout(self):
121
        # content of this block not found: did you rename this class?
122
        pass
123
 
124
# end of class MyFrame
125
 
126
 
584 FredericG 127
class MainFrame(wx.Frame):
128
    def __init__(self, *args, **kwds):
129
        # begin wxGlade: MainFrame.__init__
130
        kwds["style"] = wx.DEFAULT_FRAME_STYLE
131
        wx.Frame.__init__(self, *args, **kwds)
587 FredericG 132
 
133
        # Menu Bar
134
        self.frame_1_menubar = wx.MenuBar()
135
        wxglade_tmp_menu = wx.Menu()
136
        wxglade_tmp_menu.Append(wx.NewId(), "Exit", "", wx.ITEM_NORMAL)
137
        self.frame_1_menubar.Append(wxglade_tmp_menu, "File")
138
        wxglade_tmp_menu = wx.Menu()
601 FredericG 139
        self.frame_1_menubar.Append(wxglade_tmp_menu, "Settings")
140
        wxglade_tmp_menu = wx.Menu()
587 FredericG 141
        wxglade_tmp_menu.Append(wx.NewId(), "Clear", "", wx.ITEM_NORMAL)
142
        wxglade_tmp_menu.Append(wx.NewId(), "Import", "", wx.ITEM_NORMAL)
143
        self.frame_1_menubar.Append(wxglade_tmp_menu, "TestSet")
144
        wxglade_tmp_menu = wx.Menu()
145
        self.frame_1_menubar.Append(wxglade_tmp_menu, "MK")
146
        wxglade_tmp_menu = wx.Menu()
147
        self.frame_1_menubar.Append(wxglade_tmp_menu, "Help")
148
        self.SetMenuBar(self.frame_1_menubar)
149
        # Menu Bar end
600 FredericG 150
        self.Description = wx.StaticText(self, -1, "Description")
151
        self.text_ctrl_6 = wx.TextCtrl(self, -1, "Test")
152
        self.label_37 = wx.StaticText(self, -1, "Speed(s)")
153
        self.text_ctrl_9 = wx.TextCtrl(self, -1, "100-200:10")
154
        self.label_35 = wx.StaticText(self, -1, "Motor(s)")
155
        self.text_ctrl_7 = wx.TextCtrl(self, -1, "1")
156
        self.label_38 = wx.StaticText(self, -1, "")
157
        self.text_ctrl_10 = wx.TextCtrl(self, -1, "")
158
        self.label_36 = wx.StaticText(self, -1, "Channel")
159
        self.text_ctrl_8 = wx.TextCtrl(self, -1, "6")
160
        self.label_39 = wx.StaticText(self, -1, "")
161
        self.text_ctrl_11 = wx.TextCtrl(self, -1, "")
162
        self.button_4 = wx.Button(self, -1, "Start")
163
        self.GraphPanel = wx.Panel(self, -1)
164
        self.label_40 = wx.StaticText(self, -1, "Graph Type ")
165
        self.graphTypeChoice = wx.Choice(self, -1, choices=["Raw Signal", "Filtered Signal", "Spectrum"])
166
        self.label_41 = wx.StaticText(self, -1, "Y Axis Range ")
167
        self.yAxisChoice = wx.Choice(self, -1, choices=["25", "50", "100", "200"])
586 FredericG 168
        self.TestListCtrl = wx.ListCtrl(self, -1, style=wx.LC_REPORT|wx.SUNKEN_BORDER)
584 FredericG 169
 
170
        self.__set_properties()
171
        self.__do_layout()
587 FredericG 172
 
601 FredericG 173
        self.Bind(wx.EVT_MENU, self.onClear, id=-1)
587 FredericG 174
        self.Bind(wx.EVT_MENU, self.OnImport, id=-1)
600 FredericG 175
        self.Bind(wx.EVT_CHOICE, self.onGraphTypeChange, self.graphTypeChoice)
176
        self.Bind(wx.EVT_CHOICE, self.onYAxisChange, self.yAxisChoice)
584 FredericG 177
        # end wxGlade
178
 
587 FredericG 179
    def setApp(self, app):
180
        self.app = app
585 FredericG 181
 
584 FredericG 182
    def __set_properties(self):
183
        # begin wxGlade: MainFrame.__set_properties
587 FredericG 184
        self.SetTitle("VibrationTest")
600 FredericG 185
        self.SetSize((850, 700))
186
        self.Description.SetMinSize((53, 13))
601 FredericG 187
        self.button_4.SetMinSize((80, 80))
600 FredericG 188
        self.GraphPanel.SetMinSize((800,300))
189
        self.graphTypeChoice.SetSelection(0)
190
        self.yAxisChoice.SetSelection(1)
191
        self.TestListCtrl.SetMinSize((800,300))
584 FredericG 192
        # end wxGlade
193
 
194
    def __do_layout(self):
195
        # begin wxGlade: MainFrame.__do_layout
600 FredericG 196
        sizer_3 = wx.BoxSizer(wx.HORIZONTAL)
197
        sizer_8 = wx.BoxSizer(wx.VERTICAL)
198
        sizer_11 = wx.BoxSizer(wx.VERTICAL)
199
        sizer_12 = wx.BoxSizer(wx.HORIZONTAL)
200
        sizer_9 = wx.BoxSizer(wx.HORIZONTAL)
201
        sizer_10 = wx.BoxSizer(wx.HORIZONTAL)
202
        grid_sizer_1 = wx.GridSizer(3, 4, 4, 5)
203
        sizer_3.Add((20, 20), 0, 0, 0)
204
        sizer_8.Add((20, 20), 0, 0, 0)
205
        grid_sizer_1.Add(self.Description, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0)
584 FredericG 206
        grid_sizer_1.Add(self.text_ctrl_6, 0, 0, 0)
600 FredericG 207
        grid_sizer_1.Add(self.label_37, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0)
208
        grid_sizer_1.Add(self.text_ctrl_9, 0, 0, 0)
209
        grid_sizer_1.Add(self.label_35, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0)
584 FredericG 210
        grid_sizer_1.Add(self.text_ctrl_7, 0, 0, 0)
600 FredericG 211
        grid_sizer_1.Add(self.label_38, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0)
212
        grid_sizer_1.Add(self.text_ctrl_10, 0, 0, 0)
213
        grid_sizer_1.Add(self.label_36, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0)
584 FredericG 214
        grid_sizer_1.Add(self.text_ctrl_8, 0, 0, 0)
600 FredericG 215
        grid_sizer_1.Add(self.label_39, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0)
216
        grid_sizer_1.Add(self.text_ctrl_11, 0, 0, 0)
217
        sizer_9.Add(grid_sizer_1, 0, 0, 0)
218
        sizer_10.Add((50, 20), 0, 0, 0)
219
        sizer_10.Add(self.button_4, 0, wx.ALIGN_CENTER_VERTICAL, 0)
220
        sizer_9.Add(sizer_10, 1, wx.EXPAND, 0)
221
        sizer_8.Add(sizer_9, 0, 0, 0)
222
        sizer_8.Add((20, 30), 0, 0, 0)
223
        sizer_11.Add(self.GraphPanel, 1, wx.EXPAND, 0)
224
        sizer_11.Add((20, 5), 0, 0, 0)
225
        sizer_12.Add(self.label_40, 0, wx.ALIGN_CENTER_VERTICAL, 0)
226
        sizer_12.Add(self.graphTypeChoice, 0, 0, 0)
227
        sizer_12.Add((40, 20), 0, 0, 0)
228
        sizer_12.Add(self.label_41, 0, wx.ALIGN_CENTER_VERTICAL, 0)
229
        sizer_12.Add(self.yAxisChoice, 0, 0, 0)
230
        sizer_11.Add(sizer_12, 0, 0, 0)
231
        sizer_8.Add(sizer_11, 0, 0, 0)
232
        sizer_8.Add((20, 30), 0, 0, 0)
233
        sizer_8.Add(self.TestListCtrl, 1, 0, 0)
234
        sizer_8.Add((20, 20), 0, 0, 0)
235
        sizer_3.Add(sizer_8, 1, wx.EXPAND, 0)
236
        self.SetSizer(sizer_3)
584 FredericG 237
        self.Layout()
600 FredericG 238
        self.SetSize((850, 700))
584 FredericG 239
        # end wxGlade
240
 
590 FredericG 241
        # List events
242
        self.TestListCtrl.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnTestSelected, self.TestListCtrl)
243
 
586 FredericG 244
        # Configure Graph
593 FredericG 245
        self.client = wx.lib.plot.PlotCanvas(self.GraphPanel, size=(800,300))
246
 
585 FredericG 247
        self.client.SetPointLabelFunc(self.DrawPointLabel)
248
 
249
        self.client.SetFont(wx.Font(10,wx.SWISS,wx.NORMAL,wx.NORMAL))
250
        self.client.SetFontSizeAxis(10)
251
        self.client.SetFontSizeLegend(7)
252
        self.client.setLogScale((False,False))
253
 
586 FredericG 254
 
255
        # Configure TestListCtrl
594 FredericG 256
        self.TestListCtrl.InsertColumn(0, "Description")
257
        self.TestListCtrl.InsertColumn(1, "Speed")
258
        self.TestListCtrl.InsertColumn(2, "Channel")
602 FredericG 259
        self.TestListCtrl.InsertColumn(3, "VibrationValue")
586 FredericG 260
 
585 FredericG 261
    def DrawPointLabel(self, dc, mDataDict):
262
        """This is the fuction that defines how the pointLabels are plotted
263
            dc - DC that will be passed
264
            mDataDict - Dictionary of data that you want to use for the pointLabel
265
 
266
            As an example I have decided I want a box at the curve point
267
            with some text information about the curve plotted below.
268
            Any wxDC method can be used.
269
        """
270
        # ----------
271
        dc.SetPen(wx.Pen(wx.BLACK))
272
        dc.SetBrush(wx.Brush( wx.BLACK, wx.SOLID ) )
273
 
274
        sx, sy = mDataDict["scaledXY"] #scaled x,y of closest point
275
        dc.DrawRectangle( sx-5,sy-5, 10, 10)  #10by10 square centered on point
276
        px,py = mDataDict["pointXY"]
277
        cNum = mDataDict["curveNum"]
278
        pntIn = mDataDict["pIndex"]
279
        legend = mDataDict["legend"]
280
        #make a string to display
281
        s = "Crv# %i, '%s', Pt. (%.2f,%.2f), PtInd %i" %(cNum, legend, px, py, pntIn)
282
        dc.DrawText(s, sx , sy+1)
283
        # -----------
284
 
596 FredericG 285
 
286
    def onNewTest(self, test):
287
        index = self.TestListCtrl.InsertStringItem(sys.maxint, test.descr)
288
        self.TestListCtrl.SetStringItem(index, 1, str(test.speed))
289
        self.TestListCtrl.SetStringItem(index, 2, test.channel)
602 FredericG 290
        self.TestListCtrl.SetStringItem(index, 3, str(test.getVibValue()))
606 FredericG 291
        if (index == 0):
292
            self.TestListCtrl.Select(index)
596 FredericG 293
 
294
 
590 FredericG 295
    def OnTestSelected(self, event):
296
         testId = event.m_itemIndex
297
         print "Test Selected id=%d" % (testId)
592 FredericG 298
         self.activeTestId = testId
299
         self.drawGraph()
590 FredericG 300
 
592 FredericG 301
    def drawGraph(self):
302
         vibTest = self.app.getTest(self.activeTestId)
590 FredericG 303
         nb = vibTest.getDataLen()
600 FredericG 304
         y = int(self.yAxisChoice.GetStringSelection())
590 FredericG 305
 
600 FredericG 306
         if self.graphTypeChoice.GetSelection() == 0:
599 FredericG 307
             xydata = _Numeric.linspace(0,0.09*nb,2*nb)
308
             xydata.shape = (nb, 2)
309
             xydata[:,1] = vibTest.getRawData()
600 FredericG 310
             line = wx.lib.plot.PolyLine(xydata, legend= 'Raw Data', colour='red', width=2)
599 FredericG 311
 
312
             title = "Raw Signal: %s %s %d" %(vibTest.descr, vibTest.channel, vibTest.speed)
313
             self.client.Draw(wx.lib.plot.PlotGraphics([line], title, "Time (ms)", "Acc"), yAxis= (-y,y))
314
             self.client.SetEnableGrid('Horizontal')
596 FredericG 315
 
600 FredericG 316
         if self.graphTypeChoice.GetSelection() == 1:
317
             xydata = _Numeric.linspace(0,0.09*nb,2*nb)
318
             xydata.shape = (nb, 2)
319
             xydata[:,1] = vibTest.getFilteredData()
320
             line = wx.lib.plot.PolyLine(xydata, legend= 'Raw Data', colour='red', width=2)
321
 
322
             title = "Filtered Signal: %s %s %d" %(vibTest.descr, vibTest.channel, vibTest.speed)
323
             self.client.Draw(wx.lib.plot.PlotGraphics([line], title, "Time (ms)", "Acc"), yAxis= (-y,y))
324
             self.client.SetEnableGrid('Horizontal')
325
 
326
         elif self.graphTypeChoice.GetSelection() == 2:
599 FredericG 327
             xydata = _Numeric.linspace(0,5555,nb)
328
             xydata.shape = (nb/2, 2)
329
 
330
             xydata[:,1] = vibTest.getSpectrum()
590 FredericG 331
 
599 FredericG 332
             line = wx.lib.plot.PolyLine(xydata, legend= 'Spectrum', colour='red')
600 FredericG 333
             markers = wx.lib.plot.PolyMarker(xydata, legend= '', colour='red', marker='circle',size=2)
599 FredericG 334
 
335
             title = "Spectrum: %s %s %d" %(vibTest.descr, vibTest.channel, vibTest.speed)
602 FredericG 336
             self.client.Draw(wx.lib.plot.PlotGraphics([line,markers], title, "Freq (Hz)", "Acc"), xAxis=(0,200), yAxis= (-0,y))
600 FredericG 337
             self.client.SetEnableGrid(True)
590 FredericG 338
 
599 FredericG 339
 
587 FredericG 340
    def OnImport(self, event): # wxGlade: MainFrame.<event_handler>
606 FredericG 341
        dlg = wx.FileDialog(
342
            self, message="Choose a file",
343
            defaultDir=os.getcwd(),
344
            defaultFile="*.txt",
345
            wildcard="",
346
            style=wx.OPEN | wx.CHANGE_DIR
347
            )
348
        if dlg.ShowModal() == wx.ID_OK:
349
            paths = dlg.GetPaths();
350
            self.app.Import(paths[0])
351
        dlg.Destroy()
587 FredericG 352
 
599 FredericG 353
    def onYAxisChange(self, event): # wxGlade: MainFrame.<event_handler>
592 FredericG 354
        self.drawGraph()
355
 
600 FredericG 356
    def onGraphTypeChange(self, event): # wxGlade: MainFrame.<event_handler>
599 FredericG 357
        self.drawGraph()
358
 
601 FredericG 359
    def onClear(self, event): # wxGlade: MainFrame.<event_handler>
360
        print "Event handler `onClear' not implemented"
361
        event.Skip()
362
 
584 FredericG 363
# end of class MainFrame
364
 
365
 
586 FredericG 366
class VibTest:
596 FredericG 367
    def __init__(self, descr, motor, speed, channel, rawData):
594 FredericG 368
        self.descr = descr
369
        self.motor = motor
370
        self.speed = speed
596 FredericG 371
        self.channel = channel
599 FredericG 372
 
373
        self.dataLen = len(rawData)
374
 
590 FredericG 375
        self.rawData = _Numeric.array(rawData)
376
        self.dc = self.rawData.mean()
377
        self.rawData -= self.dc
586 FredericG 378
 
600 FredericG 379
        self.fft = _Numeric.fft.rfft(self.rawData)
380
 
381
        self.spectrum = None
382
        self.filteredData = None
599 FredericG 383
 
602 FredericG 384
        self.vibValue = None
385
 
594 FredericG 386
    def getDescr(self):
387
        return self.Descr
587 FredericG 388
 
590 FredericG 389
    def getRawData(self):
390
        return self.rawData
391
 
392
    def getDataLen(self):
393
        return self.dataLen
394
 
599 FredericG 395
    def getSpectrum(self):
600 FredericG 396
        if self.spectrum == None:
397
            self.spectrum = _Numeric.absolute(self.fft[1:self.dataLen/2+1]) / (self.dataLen/2)
398
        return self.spectrum
590 FredericG 399
 
600 FredericG 400
    def getFilteredData(self):
401
        if self.filteredData == None:
402
            tmpfft = self.fft.copy()
602 FredericG 403
            for i in range(0,5):
600 FredericG 404
                tmpfft[i] = 0
405
            for i in range(30, len(tmpfft)):
406
                tmpfft[i] = 0
407
            self.filteredData = _Numeric.fft.irfft(tmpfft)
408
        return self.filteredData
602 FredericG 409
 
410
    def getVibValue(self):
411
      if self.vibValue == None:
412
        fd = self.getFilteredData();
413
        self.vibValue = max(fd)-min(fd)
414
      return self.vibValue
599 FredericG 415
 
584 FredericG 416
class App(wx.App):
586 FredericG 417
    def __init__(self, par):
418
        self.VibTests = []
419
 
420
        wx.App.__init__(self, par)
421
 
606 FredericG 422
        if len(sys.argv)>1:
423
            self.Import(sys.argv[1])
586 FredericG 424
 
606 FredericG 425
 
596 FredericG 426
    def AddTest(self, descr, motor, speed, channel, rawData):
427
        test = VibTest(descr, motor, speed, channel, rawData)
586 FredericG 428
        self.VibTests.append(test)
596 FredericG 429
        self.frame_1.onNewTest(test)
586 FredericG 430
 
590 FredericG 431
    def getTest(self, testId):
432
        return self.VibTests[testId]
433
 
584 FredericG 434
    def OnInit(self):
435
        wx.InitAllImageHandlers()
586 FredericG 436
        self.frame_1 = MainFrame(None, -1, "")
587 FredericG 437
        self.frame_1.setApp(self);
586 FredericG 438
        self.SetTopWindow(self.frame_1)
439
 
587 FredericG 440
        self.frame_1.Show()
441
        return 1
442
 
606 FredericG 443
    def Import(self, filePath):
596 FredericG 444
 
606 FredericG 445
        print "Importing file \"%s\"" % filePath
596 FredericG 446
 
447
        logfile = open(filePath, "r")
590 FredericG 448
        data = None
596 FredericG 449
 
450
        headers = (logfile.readline()).split(',')
451
        nbCols = len(headers)
452
        print "NbCols =", nbCols
453
 
454
        data = []
455
        descr = []
456
        speed = []
457
        channel = []
458
        for c in range(nbCols):
459
            data.append([])
460
            h = headers[c].split(' ')
461
            descr.append(h[0]);
462
            speed.append(h[1]);
463
            channel.append(h[2]);
464
 
590 FredericG 465
        for line in logfile:
466
            values = line.split(',')
596 FredericG 467
            for i in range(nbCols):
468
                data[i].append(int(values[i]))
590 FredericG 469
        logfile.close()
596 FredericG 470
 
471
        for c in range(nbCols):
599 FredericG 472
            if (len(data[c]) % 2) != 0:
473
                data[c].append(data[c][-1])
596 FredericG 474
            self.AddTest(descr[c], 0, int(speed[c]), channel[c], data[c])
590 FredericG 475
 
476
 
477
 
586 FredericG 478
 
590 FredericG 479
 
584 FredericG 480
# end of class App
481
 
482
if __name__ == "__main__":
483
    VibrationTestGui = App(0)
484
    VibrationTestGui.MainLoop()