Ejemplo n.º 1
0
class Annotator:
    def __init__(self, parent):
        self.parent = parent
        parent.title("Sound Annotation/Analyzation Tool")
        self.initUI()

    def initUI(self):

        self.labeldict = {}
        self.show = []
        self.timeValues = []
        self.stamp = -1
        self.stampHistory = []

        self.funclist = {
            "rms", "hfc", "complex", "complex_phase", "flux", "superflux",
            "noveltycurve", "CNNOnsetDetector", "RNNOnsetDetector",
            "modifiedKL", "weightedPhaseDev", "PhaseDev",
            "rectifiedComplexDomain", "ninos"
        }

        self.featurelist = [
            "Audio", "rms", "spectralCentroid", "spectralRolloff", "zcr",
            "spectralEntropy", "spectralFlux", "StrongDecay", "stft"
        ]
        self.hopsizes = []
        self.calculated_features_dict = {}
        self.calculated_features = []
        self.calculated_featuresParams = []

        self.defaultParams = {
            'rms': (512, 1024, 'hann'),
            'Audio': (),
            'spectralCentroid': (512, 1024, 'hann'),
            'spectralRolloff': (512, 1024, 'hann'),
            'spectralFlux': (512, 1024, 'hann'),
            'zcr': (512, 1024),
            'spectralEntropy': (512, 1024, 'hann'),
            'StrongDecay': (512, 1024),
            'stft': (512, 1024)
        }

        self.chunk_size = 2048
        self.mag = []
        self.phase = []
        self.sem = asyncio.Semaphore()

        # Info text
        self.info = StringVar()
        self.info.set("welcome")
        self.info_widget = Message(self.parent,
                                   textvariable=self.info,
                                   width=300)
        self.info_widget.grid(row=0, column=3, sticky=W + N + E + S, rowspan=2)

        # define options for opening file
        self.file_opt = options = {}
        options['defaultextension'] = '.wav'
        options['filetypes'] = [('All files', '.*'), ('Wav files', '.wav')]
        options['initialdir'] = os.getcwd() + "/sounds"
        if (options['initialdir'][-1] != '/'):
            options['initialdir'] += '/'

        # BUTTON TO SET DIRECTORY
        self.directory_button = Button(self.parent,
                                       text="Directory",
                                       command=self.set_directory)
        self.directory_button.grid(row=1, column=0, sticky=W)

        #TEXTBOX TO PRINT PATH OF THE SOUND FILE
        self.filelocation = Entry(self.parent)
        self.filelocation["width"] = 25
        self.filelocation.grid(row=0, column=0, sticky=W, padx=10)
        self.filelocation.delete(0, END)
        self.filename = ''  # initial file
        self.filelocation.insert(0,
                                 self.file_opt['initialdir'] + self.filename)

        #BUTTON TO BROWSE SOUND FILE
        self.open_file = Button(self.parent,
                                text="Browse...",
                                command=self.browse_file)
        self.open_file.grid(row=0, column=0, sticky=W, padx=(220, 6))

        #BUTTON TO PLOT SOUND FILE
        self.preview = Button(self.parent,
                              text="Plot",
                              command=self.plot,
                              bg="gray30",
                              fg="white")
        self.preview.grid(row=0, column=0, sticky=W, padx=(300, 6))

        #BUTTON TO draw  stamps
        self.draw = Button(self.parent,
                           text="Draw",
                           command=self.drawAllStamps,
                           bg="gray30",
                           fg="white")
        self.draw.grid(row=1, column=0, sticky=W, padx=(420, 6))

        # Dropdown Function Select
        self.funcname = StringVar()
        self.funcname.set("Select a function")
        self.fselect = OptionMenu(self.parent, self.funcname, *self.funclist)
        self.fselect.grid(row=1, column=2, sticky=W)

        # Button to Apply function
        self.afuncbtn = Button(self.parent,
                               text="Apply",
                               command=self.applyfunction,
                               bg="gray30",
                               fg="white")
        self.afuncbtn.grid(row=1, column=2, sticky=W, padx=(300, 6))

        # Dropdown SHOW FEATURE
        self.featurename = StringVar()
        self.featurename.set("Audio")
        self.featurename.trace("w", self.changeparams)
        self.ftselect = OptionMenu(self.parent, self.featurename,
                                   *self.featurelist)
        self.ftselect.grid(row=0, column=2, sticky=W)
        # Entry for feature params
        self.featureParamsEntry = Entry(self.parent)
        self.featureParamsEntry.grid(row=0, column=2, sticky=W, padx=(150, 6))
        self.featureParamsEntry.bind("<Enter>", self.updateinfo)
        # Button to show  feature
        self.afuncbtn = Button(self.parent,
                               text="Show",
                               command=self.showfeature,
                               bg="gray30",
                               fg="white")
        self.afuncbtn.grid(row=0, column=2, sticky=W, padx=(300, 6))

        # Button to send top feature to below plot
        self.sendbelowbtn = Button(self.parent,
                                   text="v",
                                   command=self.sendbelow)
        self.sendbelowbtn.grid(row=0, column=2, sticky=W, padx=(360, 6))
        #BUTTON TO PLAY/STOP , shortcut: spacebar
        self.play_mode = tk.BooleanVar(self.parent, False)
        self.new_sound = tk.BooleanVar(self.parent, False)
        self.playbutton = Button(self.parent,
                                 text="Play",
                                 command=self.playsound)
        self.playbutton.grid(row=0, column=0, sticky=W, padx=(350, 6))
        self.parent.bind("<space>", self.playsound)

        #BUTTON TO SAVE AND LOAD NEXT SOUND FILE
        self.saveload = Button(self.parent,
                               text="Save& Load Next",
                               command=self.saveAndNext)
        self.saveload.grid(row=0, column=1, sticky=W)

        #BUTTON TO ADD LABELS
        self.addlabel_button = Button(self.parent,
                                      text="Add/Manage Labels",
                                      command=self.addlabel_gui)
        self.addlabel_button.grid(row=0, column=0, sticky=W, padx=(420, 6))

        # BUTTON TO DISCARD CURRENT ANNOTATIONS
        self.discardbutton = Button(self.parent,
                                    text="Discard",
                                    command=self.discard)
        self.discardbutton.grid(row=0, column=4, sticky=W)

        #BUTTON TO get next
        self.load_next = Button(self.parent,
                                text="Next Sound",
                                command=self.getNext)
        self.load_next.grid(row=1, column=0, sticky=W, padx=(220, 6))

        # BUTTON TO QUIT
        self.quitbutton = Button(self.parent, text="Quit", command=self.quit)
        self.quitbutton.grid(row=3, column=4, sticky=W)

        # tickbox to autoload existing annotations
        self.ALoad = IntVar()
        self.autoload_annotations = Checkbutton(master=self.parent,
                                                text="Autoload Annotations?",
                                                variable=self.ALoad,
                                                onvalue=1,
                                                offvalue=0)
        self.autoload_annotations.grid(row=1, column=1, sticky=W)

        # tickbox to convert time to samples
        self.isTime = IntVar()
        self.timeorsamples = Checkbutton(master=self.parent,
                                         text="time?",
                                         variable=self.isTime,
                                         onvalue=1,
                                         offvalue=0)
        self.timeorsamples.grid(row=1, column=0, sticky=W, padx=(500, 6))

        # tickbox to enable discarding labels
        self.DLabels = IntVar()
        self.discardlabels_check = Checkbutton(master=self.parent,
                                               text="Discard Labels?",
                                               variable=self.DLabels,
                                               onvalue=1,
                                               offvalue=0)
        self.discardlabels_check.grid(row=1, column=4, sticky=W)

        # init figure for plotting
        self.currentplot = 0

        fig = plt.figure(figsize=(18, 7), dpi=100)
        self.mainplot = fig.add_subplot(211)
        self.secplot = fig.add_subplot(212)

        self.canvas = FigureCanvasTkAgg(fig, self.parent)
        self.canvaswidget = self.canvas.get_tk_widget()
        self.canvaswidget.grid(row=2, column=0, columnspan=5, sticky=W)

        toolbarFrame = Frame(master=self.parent)
        toolbarFrame.grid(row=3, column=0, columnspan=7)
        self.toolbar = NavigationToolbar2Tk(self.canvas, toolbarFrame)
        self.toolbar.update()

        self.canvas._tkcanvas.grid(row=2, column=0, columnspan=7, sticky=W)
        self.background = self.canvas.copy_from_bbox(self.mainplot.bbox)
        self.cursor = self.mainplot.axvline(color="k", animated=True)
        self.cursor.set_xdata(0)

        self.colors = [
            'r', 'g', 'c', 'm', 'y', '#FFBD33', '#924A03', '#D00000',
            '#D000D0', '#6800D0', '#095549', 'b', 'r', 'r'
        ]

        # modification to original handler of 'release_zoom', "release_pan" and "_update_view" from NavigationToolbar2
        # latest one is for forward, backward and home buttons
        self.release_zoom_orig = self.toolbar.release_zoom
        self.toolbar.release_zoom = self.new_release_zoom
        self.release_pan_orig = self.toolbar.release_pan
        self.toolbar.release_pan = self.new_release_pan
        self._update_view_orig = self.toolbar._update_view
        self.toolbar._update_view = self.new_update_view

        self.canvas.mpl_connect('toolbar_event', self.handle_toolbar)
        cid1 = self.canvas.mpl_connect("button_press_event", self.onclick)
        self.parent.bind("<Escape>", self.release_stamp)
        self.parent.bind("x", self.discard_last)

        self.p = pyaudio.PyAudio()

        self.parent.bind("<<playbackmove>>", self.playbackMove)

        def callbackstream(in_data, frame_count, time_info, status):
            self.sem.acquire()
            data = self.wf.readframes(frame_count)
            self.parent.event_generate("<<playbackmove>>", when="now")
            self.sem.release()
            return (data, pyaudio.paContinue)

        self._callbackstream = callbackstream

    def updateinfo(self, event, *args):
        caller = event.widget
        if str(caller) == '.!entry2':
            self.info.set(getattr(features, self.featurename.get()).__doc__)

    def applyfunction(self):
        values = getattr(libod, self.funcname.get())(self.filelocation.get())
        if len(values) == 0:
            self.info.set("No detections")
        else:
            self.labeldict[len(self.labeldict)] = self.funcname.get()
            var = IntVar()
            var.set(1)
            self.show.append(var)
            self.timeValues.append([i * 44100 for i in values])
            self.drawAllStamps()

    def set_directory(self):
        directory = tkFileDialog.askdirectory() + '/'
        self.file_opt['initialdir'] = directory

    def release_stamp(self, event=None):
        self.stamp = -1
        self.info.set("Cursor")

    def discard_last(self,
                     event=None
                     ):  # discard last annotation for current sound. button: X
        self.mainplot.lines.pop()
        self.canvas.draw()
        self.background = self.canvas.copy_from_bbox(self.mainplot.bbox)
        self.timeValues[self.stampHistory[-1]].pop()
        self.stampHistory.pop()

    def discard(self):  # discard all annotations
        self.timeValues = []
        if (self.DLabels.get() == True or self.ALoad.get() == True):
            self.labeldict = {}
            self.show = []
        else:
            for i in range(len(self.labeldict)):
                self.timeValues.append([])
        self.stamp = -1
        self.stampHistory = []
        self.mag = []
        self.phase = []
        self.hopsizes = []
        self.calculated_features_dict = {}
        self.calculated_features = []
        self.calculated_featuresParams = {}

        self.currentplot = 0

    def label(self, event):
        self.info.set(self.labeldict[int(event.char) - 1] + " is selected")
        self.stamp = int(event.char) - 1

    def addlabel(self):
        self.labeldict[len(self.labeldict)] = self.newlabel_entry.get()
        var = IntVar()
        var.set(1)
        self.show.append(var)
        self.parent.bind("%d" % len(self.labeldict), self.label)
        self.timeValues.append([])

    def deselect(self):
        for cb in self.checkbuttons:
            cb.deselect()

    def addlabel_gui(self):
        frame_addlabel = Toplevel(master=self.parent)
        frame_addlabel.geometry(
            "%dx%d%+d%+d" % (400, 100 + 33 * len(self.labeldict), 200, 200))
        frame_addlabel.title("Add Labels")
        self.newlabel_entry = Entry(frame_addlabel)
        self.newlabel_entry.grid(row=0, column=0)
        labels_text = "Current Labels:"
        w = Message(frame_addlabel, text=labels_text, width=150)
        w.grid(row=1, column=0)

        labels_text = "Display?"
        w = Message(frame_addlabel, text=labels_text, width=150)
        w.grid(row=1, column=1)

        self.checkbuttons = []
        for i in range(len(self.labeldict)):
            labels_text = '%d' % (i + 1) + '. ' + self.labeldict[i]
            w = Message(frame_addlabel, text=labels_text, width=150)
            w.grid(row=i + 2, column=0)
            check = Checkbutton(master=frame_addlabel,
                                text="",
                                variable=self.show[i],
                                onvalue=1,
                                offvalue=0)
            check.grid(row=i + 2, column=1, sticky=W)
            self.checkbuttons.append(check)

        addbutton = Button(frame_addlabel, text="Add", command=self.addlabel)
        addbutton.grid(row=0, column=1, sticky=W)

        togglebutton = Button(frame_addlabel,
                              text="Deselect",
                              command=self.deselect)
        togglebutton.grid(row=1, column=2, sticky=W)

    def quit(self):
        try:
            self.stream.close()
            self.wf.close()
            self.p.terminate()
        except:
            print("no audio init")
        finally:
            self.parent.destroy()

    def initStream(self):
        self.stream = self.p.open(format=8,
                                  channels=1,
                                  rate=44100,
                                  output=True,
                                  stream_callback=self._callbackstream,
                                  start=True,
                                  frames_per_buffer=self.chunk_size)

    def playsound(self, event=None):
        if self.sem.locked():
            return
        if self.play_mode.get() == True:
            try:
                self.playbutton.config(text="Play")
                self.stream.close()
                self.stream.close()
                self.play_mode.set(False)
            except:
                print("stop failed")
        else:
            try:
                self.initStream()
                self.play_mode.set(True)
                self.playbutton.config(text="Stop")
            except:
                print("stop failed")

    def playbackMove(self, event=None):  # move cursor by audio chunk size
        incr = (self.chunk_size) // self.hopsizes[self.currentplot]
        self.cursor.set_xdata(self.cursor.get_xdata() + incr)
        self.updateCursor()

    def new_release_zoom(self, *args, **kwargs):
        self.release_zoom_orig(*args, **kwargs)
        s = 'toolbar_event'
        event = Event(s, self)
        self.canvas.callbacks.process(s, Event('toolbar_event', self))

    def new_release_pan(self, *args, **kwargs):
        self.release_pan_orig(*args, **kwargs)
        s = 'toolbar_event'
        event = Event(s, self)
        self.canvas.callbacks.process(s, Event('toolbar_event', self))

    def new_update_view(self, *args, **kwargs):
        self._update_view_orig(*args, **kwargs)
        s = 'toolbar_event'
        event = Event(s, self)
        self.canvas.callbacks.process(s, Event('toolbar_event', self))

    def handle_toolbar(self, event):
        self.canvas.draw()
        self.background = self.canvas.copy_from_bbox(self.mainplot.bbox)

    def onclick(self, event):
        if (self.toolbar._active == 'ZOOM' or self.toolbar._active == 'PAN'):
            pass

        elif (self.stamp > -1):
            self.stampHistory.append(self.stamp)
            self.timeValues[self.stamp].append(event.xdata *
                                               self.hopsizes[self.currentplot])
            self.mainplot.draw_artist(
                self.mainplot.axvline(x=event.xdata,
                                      color=self.colors[self.stamp]))
            self.canvas.draw()
            self.background = self.canvas.copy_from_bbox(self.mainplot.bbox)
            self.info.set("Cursor")
            self.stamp = -1
        else:
            self.cursor.set_xdata(event.xdata)
            self.wf.setpos(int(event.xdata * self.hopsizes[self.currentplot]))
            self.updateCursor()

    def updateCursor(self):
        self.canvas.restore_region(self.background)
        self.mainplot.draw_artist(self.cursor)
        self.canvas.blit(self.mainplot.bbox)

    def browse_file(self):
        self.filename = os.path.basename(
            tkFileDialog.askopenfilename(**self.file_opt))
        self.filelocation.delete(0, END)
        self.filelocation.insert(0,
                                 self.file_opt['initialdir'] + self.filename)

    def changeparams(self, *args):
        self.featureParamsEntry.delete(0, END)
        try:
            self.featureParamsEntry.insert(
                0, str(self.defaultParams[self.featurename.get()]))
        except:
            self.featureParamsEntry.insert(0, "()")
            print("No default params for selected feature")

    def showfeature(self):
        self.mainplot.clear()
        featureName = self.featurename.get()
        featureParams = eval(self.featureParamsEntry.get())
        if featureName in self.calculated_features_dict and self.calculated_featuresParams[
                featureName] != featureParams:
            # if a feature is calculated before and params are the same; plot the saved result
            self.currentplot = self.calculated_features_dict[featureName]
            if len(self.calculated_features[self.currentplot].shape) == 2:
                ylim = 5000
                binToFreq = np.arange(0, ylim, 43.066)  # Fs/N
                self.mainplot.pcolormesh(
                    np.arange(
                        self.calculated_features[self.currentplot].shape[0]),
                    binToFreq, self.calculated_features[
                        self.currentplot].T[:binToFreq.size, :])
            else:
                self.mainplot.plot(self.calculated_features[self.currentplot])
            self.canvas.draw()
            self.background = self.canvas.copy_from_bbox(self.mainplot.bbox)
            hopSize = self.hopsizes[self.calculated_features_dict[featureName]]
        else:
            self.currentplot = len(self.calculated_features)
            self.calculated_features_dict[featureName] = self.currentplot
            result, hopSize = getattr(features, featureName)(self.audio,
                                                             featureParams)
            if len(result.shape) == 2:
                ylim = 5000
                binToFreq = np.arange(0, ylim, 43.066)  # Fs/N
                self.mainplot.pcolormesh(np.arange(result.shape[0]), binToFreq,
                                         result.T[:binToFreq.size, :])
            else:
                self.mainplot.plot(result)
            self.canvas.draw()
            self.background = self.canvas.copy_from_bbox(self.mainplot.bbox)
            self.calculated_features.append(result)
            self.hopsizes.append(hopSize)
            self.calculated_featuresParams[featureName] = featureParams
        self.drawAllStamps()

    def sendbelow(self):
        self.secplot.clear()
        if len(self.calculated_features[self.currentplot].shape) == 2:
            ylim = 5000
            binToFreq = np.arange(0, ylim, 43.066)  # Fs/N
            self.secplot.pcolormesh(
                np.arange(self.calculated_features[self.currentplot].shape[0]),
                binToFreq, self.calculated_features[
                    self.currentplot].T[:binToFreq.size, :])
        else:
            self.secplot.plot(self.calculated_features[self.currentplot])
            self.canvas.draw()

    def plot(self):
        self.discard()
        inputFile = self.filelocation.get()
        self.wf = wave.open(inputFile, 'rb')
        self.featurename.set("Audio")
        self.audio = MonoLoader(filename=inputFile, sampleRate=44100)()
        self.showfeature()
        self.cursor.set_xdata(0)
        self.canvaswidget.focus_set()
        if (self.ALoad.get() == 1):
            self.loadAnnotations()

    def saveAnnotations(self):
        directory = self.file_opt[
            'initialdir'] + "Annotations/" + self.filename.split('.')[
                0]  # deleting .wav
        if not os.path.exists(directory):
            os.makedirs(directory)
        for i in self.labeldict:
            with open(directory + '/%s.txt' % self.labeldict[i],
                      'w') as filehandle:
                json.dump(self.timeValues[i], filehandle)

    def loadAnnotations(self):
        directory = self.file_opt[
            'initialdir'] + "Annotations/" + self.filename.split('.')[0] + "/"
        if not os.path.exists(directory):
            print("No annotations")
        else:
            for x in sorted(os.listdir(directory)):
                with open(directory + x, 'r') as filehandle:
                    values = json.load(filehandle)
                    if self.isTime.get() == 1:
                        values = [v * 44100 for v in values]
                    self.labeldict[len(self.labeldict)] = x.split('.')[0]
                    var = IntVar()
                    var.set(1)
                    self.show.append(var)
                    self.timeValues.append(values)

    def getNext(self):
        self.discard()
        fileList = sorted(os.listdir(self.file_opt['initialdir']))
        nextIndex = fileList.index(self.filename) + 1
        if nextIndex == 0 or nextIndex == len(fileList):
            print("No more files")
        else:
            self.filename = fileList[nextIndex]
            self.filelocation.delete(0, END)
            self.filelocation.insert(
                0, self.file_opt['initialdir'] + fileList[nextIndex])
        self.plot()

    def drawAllStamps(self):
        hs = self.hopsizes[self.currentplot]
        try:
            del self.mainplot.lines[1:]
        except:
            pass
        for i in self.labeldict:
            if self.show[i].get() == 1:
                for j in self.timeValues[i]:
                    self.mainplot.draw_artist(
                        self.mainplot.axvline(x=j // hs, color=self.colors[i]))
        self.canvas.draw()
        self.background = self.canvas.copy_from_bbox(self.mainplot.bbox)

    def saveAndNext(self):
        self.saveAnnotations()
        self.getNext()
        self.plot()
Ejemplo n.º 2
0
    line, = ax.plot(evo.time, evo.data)
    ax.set_ylim([0, 100])

    ax.get_xaxis().set_animated(True)
    #ax.get_yaxis().set_animated(True)
    line.set_animated(True)
    canvas.draw()
    background = canvas.copy_from_bbox(fig.bbox)

    # now redraw and blit
    ax.draw_artist(ax.get_xaxis())
    ax.draw_artist(line)
    canvas.blit(ax.clipbox)

    while True:
        evo.update()

        line.set_xdata(evo.time)
        line.set_ydata(evo.getData())
        ax.set_xlim([evo.time[0], evo.time[-1]])
        #ax.set_ylim([max(evo.data),min(evo.data)])

        # restore the background, draw animation,blit
        canvas.restore_region(background)
        ax.draw_artist(ax.get_xaxis())
        #ax.draw_artist(ax.get_yaxis())
        ax.draw_artist(line)
        canvas.blit(ax.clipbox)
        canvas.flush_events()
Ejemplo n.º 3
0
class FittingWindow:
    
    
    def __init__(self, master,ramanspectrum =None):
        global guessplot,dataplot
        
        self.master  = master
        self.textframe= Frame(master = self.master)
        
        self.scroll = Tkinter.Scrollbar(self.textframe)
        self.scroll.grid(row=0,column=1)
        self.t = Tkinter.Text(self.textframe,yscrollcommand=self.scroll.set,width=30)
        self.scroll.config(command=self.t.yview)
        self.t.grid(row=0,column=0)
        
        self.plotframe = Frame(master = self.master)
        
        self.frame = Frame(master = self.master)
        
        self.textframe.grid(row=0,column=0,columnspan=3)
        self.plotframe.grid(row = 0, column = 3, columnspan = 11,sticky = 'ew')
        self.frame.grid(column = 1, row = 1,columnspan = 11, rowspan = 3,sticky = 'snew')
        self.buttonframe = Frame(master = self.master)
        self.buttonframe.grid(column=0, row =1)
        ##############################
        self.menubar = Menu(self.master)
        
        self.filemenu = Menu(self.menubar, tearoff=0)
        self.filemenu.add_command(label="New window", command = lambda: FittingWindow(Toplevel()))
        self.filemenu.add_command(label="Open", command = self.open_data)
        self.filemenu.add_command(label="Save",command = None)
        self.filemenu.add_command(label="SaveFig",command = None)
        self.filemenu.add_command(label="ViewNotebook",command = None)
        self.filemenu.add_command(label="Exit", command = self.quitproc)
        self.menubar.add_cascade(label="File", menu=self.filemenu)
        
        self.master.config(menu= self.menubar)
        ##############################
        
        self.fit_button = Tkinter.Button(master = self.buttonframe, command = self.fit_and_draw, width  = 5, text = 'FitNow')
        self.fit_button.grid(row = 3, column = 0)
        self.open_button =  Tkinter.Button(master = self.buttonframe, command = self.open_data, width  = 5, text = 'open')
        self.open_button.grid(row = 4, column = 0)
#        self.open_ref_button =  Tkinter.Button(master = self.buttonframe, command = self.open_ref, width  = 5, text = 'Choose reference')
#        self.open_ref_button.grid(row = 5, column = 0)
        
#        self.open_bkg_button =  Tkinter.Button(master = self.buttonframe, command = self.open_bkg, width  = 5, text = 'Choose background')
#        self.open_bkg_button.grid(row = 6, column = 0)
#        
#        self.ref_label =  Tkinter.Label(master = self.buttonframe, text = '')
#        self.ref_label.grid(row = 7, column = 0)
#        
#        self.bkg_label =  Tkinter.Label(master = self.buttonframe, text = '')
#        self.bkg_label.grid(row = 8, column = 0)
        
        self.smoothbutton = Tkinter.Button(master = self.buttonframe, command = self.smoothdata, width  = 5, text = 'Smooth')
        self.smoothbutton.grid(row = 5, column = 0)
 
       
        
        self.function_list=[
                              'OneGaussian',
                              'TwoGaussian',
                              'ThreeGaussian',
                              'FourGaussian',
                              'FiveGaussian']
        
        self.var_func = StringVar()
        self.var_func.set(self.function_list[0])
        
        
       
       
        self.MotorMenu = OptionMenu(self.buttonframe,self.var_func, *self.function_list, command = self.init_function)
        self.MotorMenu.grid(row = 3,column =1,sticky = W)
        
        self.normalization_constant = 1
        self.scale_list = []
        self.var_list = []
        
        self.fig = Figure(figsize=(5,3))
        self.ax1  = self.fig.add_subplot(111)
        dataplot = self.ax1.plot(arange(2800,3605,5),zeros((161,)),animated = True)[0]#(ax = self.ax1).lines[-1]
        
        guessplot = self.ax1.plot(arange(2800,3605,5),zeros((161,)),animated = True)[0]
        
        
        self.canvas = FigureCanvasTkAgg(self.fig,master = self.plotframe)
        
        self.canvas.show()
        
        
        self.canvas._tkcanvas.pack(side=TOP, fill = BOTH,expand =True)
        
        
        self.toolbar = NavigationToolbar2TkAgg(self.canvas, self.plotframe)
        self.toolbar.update()
        self.toolbar.pack(side= BOTTOM, fill = BOTH,expand =True)#,expand = True)#fill=BOTH)#, expand=1)
        
        self.canvas.draw()
        self.canvas.show()
        self.background = self.canvas.copy_from_bbox(self.ax1.bbox)
            
         
        self.reference = numpy.ndarray((161,))
        self.reference[:] = 1
        self.reference_name  = ''
        self.guess = list()

        self.name = ['']
        if ramanspectrum is None:
            self.a = pandas.Series(zeros(161),arange(2800,3605,5))
        else:
            self.a = copy(ramanspectrum)
            print self.a
           
            self.t.insert(END,'data multiplied by'+str(1/max(self.a)))
            self.a[:]/=max(self.a.values)
            
        self.startfreq_text = Entry(self.buttonframe,width = 5)
        self.startfreq = min(array(self.a.index))
        self.startfreq_text.insert(END,str(self.startfreq))
        self.startfreq_text.bind("<Return>", self.update_limits)
        self.startfreq_text.grid(row = 0 , column =1,sticky = W)
        
        
        self.endfreq_text = Entry(self.buttonframe,width = 5)
        self.endfreq = max(array(self.a.index))
        self.endfreq_text.insert(END,str(self.endfreq))
        self.endfreq_text.bind("<Return>", self.update_limits)
        self.endfreq_text.grid(row = 1 , column =1,sticky = W)
        
        if self.init_function('OneLorentzian') == -1:
            self.t.insert(END, 'error initializing fit function')
        
        self.ax1.cla()
        self.canvas.show()
        self.background = self.canvas.copy_from_bbox(self.ax1.bbox)
        

        dataplot = self.ax1.plot(array(self.a.index),self.a.values,animated=True)[0]
        x= array(self.a.index)
        guessplot = self.ax1.plot(x,zeros(self.a.size),animated=True)[0]
        self.ax1.set_xlim(min(self.a.index),max(self.a.index))
        self.ax1.set_ylim(min(self.a.values),1)
        
        self.canvas.show()

        
        
       
        self.raw = self.a.copy   
        self.startidx = 0
        self.endidx = -1
           
        self.update_limits(0)
        return None
        
    def nothing(self):
        return 0
    def quitproc(self):
            self.master.destroy()
            return 0
        
        
    def init_function(self,functiontype):
        global function
        import inspect
        
        if functiontype == None:
            functiontype = self.var_func.get()
        
        self.functiontype = functiontype
        
      
                    
        if functiontype == 'OneLorentzian':
            def function(x,A1,w1,G1,m,b): return m*x/1000+b + A1**2/((x-w1)**2+G1**2)
        elif functiontype == 'TwoLorentzian':
            def function(x,A1,A2,w1,w2,G1,G2,m,b): return m*x/1000+b + A1**2/((x-w1)**2+G1**2) +A2**2/((x-w2)**2+G2**2)
    
        elif functiontype == 'ThreeLorentzian':
            def function(x,A1,A2,A3,w1,w2,w3,G1,G2,G3,m,b): return m*x/1000+b + A1**2/((x-w1)**2+G1**2) +A2**2/((x-w2)**2+G2**2) +A3**2/((x-w3)**2+G3**2)
        elif functiontype == 'FourLorentzian':
            def function(x,A1,A2,A3,A4,w1,w2,w3,w4,G1,G2,G3,G4,m,b): return m*x/1000+b + A1**2/((x-w1)**2+G1**2) +A2**2/((x-w2)**2+G2**2) +A3**2/((x-w3)**2+G3**2) +A4**2/((x-w4)**2+G4**2)
             
        elif functiontype == 'FiveLorentzian':
            def function(x,A1,A2,A3,A4,A5,w1,w2,w3,w4,w5,G1,G2,G3,G4,G5,m,b): return m*x/1000+b + A1**2/((x-w1)**2+G1**2) +A2**2/((x-w2)**2+G2**2) +A3**2/((x-w3)**2+G3**2) +A4**2/((x-w4)**2+G4**2)+A5**2/((x-w5)**2+G5**2)
        elif functiontype == 'OneGaussian':
            def function(x,A1,w1,G1,m,b): return m*x/1000+b + A1*exp(-(x-w1)**2/G1)
        elif functiontype == 'TwoGaussian':
            def function(x,A1,A2,w1,w2,G1,G2,m,b): return A1*exp(-(x-w1)**2/G1) +A2*exp(-(x-w2)**2/G2) +m*x/1000+b 
    
        elif functiontype == 'ThreeGaussian':
            def function(x,A1,A2,A3,w1,w2,w3,G1,G2,G3,m,b): return m*x/1000+b + A1*exp(-(x-w1)**2/G1) +A2*exp(-(x-w2)**2/G2) +A3*exp(-(x-w3)**2/G3) 
        elif functiontype == 'FourGaussian':
            def function(x,A1,A2,A3,A4,w1,w2,w3,w4,G1,G2,G3,G4,m,b): return m*x/1000+b +A1*exp(-(x-w1)**2/G1) +A2*exp(-(x-w2)**2/G2)  +A3*exp(-(x-w3)**2/G3) +A4*exp(-(x-w4)**2/G4) 
             
        elif functiontype == 'FiveGaussian':
            def function(x,A1,A2,A3,A4,A5,w1,w2,w3,w4,w5,G1,G2,G3,G4,G5,m,b): return m*x/1000+b + (A1/G1*numpy.sqrt(2*pi))*exp(-(x-w1)**2/(2*G1**2)) +(A2/G2*numpy.sqrt(2*pi))*exp(-(x-w2)**2/(2*G2**2))  +(A3/G3*numpy.sqrt(2*pi))*exp(-(x-w3)**2/(2*G3**2))  +(A4/G4*numpy.sqrt(2*pi))*exp(-(x-w4)**2/(2*G4**2)) +(A5/G5*numpy.sqrt(2*pi))*exp(-(x-w5)**2/(2*G5**2)) 
        else:
            tkMessageBox.showerror('Not regconized function')
            def function(x,m,b): return m*x/1000+b
       
         

#==============================================================================
        self.w_name = list() 
        self.w_name = inspect.getargspec(function).args[1:]
        
        self.guess= []
       
        for w in self.w_name:
            if 'A' in w:
                self.guess.append(0.1)
            elif 'w' in w:
                self.guess.append(1000)
            elif 'G' in w:
                self.guess.append(10)
            else:
                self.guess.append(0)
#================================================================================
        
        for i in range(len(self.scale_list),len(self.w_name)):
                self.scale_list.append(Scale(master  = self.frame,command = self.guessdraw))
                
        for i in range(len(self.w_name),len(self.scale_list)):
                self.scale_list[i].grid_forget()
           
        for i in range(len(self.w_name)):
                self.scale_list[i].config(label = self.w_name[i])
                self.scale_list[i].grid(row = int(i/8), column = i%8)
                
                if self.w_name[i][0] == 'A':
                     self.scale_list[i].config(from_ =0, to =  5,resolution = 0.1)
                     
                     self.scale_list[i].set(1)
                elif self.w_name[i][0] == 'w':
                    self.scale_list[i].config(from_ = self.startfreq-20, to =  self.endfreq+20,resolution = 1)
                    self.scale_list[i].set(2800)
                elif self.w_name[i][0] == 'G':
                    self.scale_list[i].config(from_ = 1, to =  50)
                    self.scale_list[i].set(7)
                elif self.w_name[i][0] == 'm':
                    self.scale_list[i].config(from_ = -5, to =  5, resolution = 0.05)
                    self.scale_list[i].set(0)
                elif self.w_name[i][0] == 'b':
                    self.scale_list[i].config(from_ = -5, to =  5, resolution = 0.05)
                    self.scale_list[i].set(0)
                else:
                    self.t.insert(END, "Variable not recognized:", self.w_name[i] )
                self.scale_list[i].bind('<B1-Motion>',self.guessdraw)
        return 0
        
        
    def smoothdata(self):
        self.a.smoooth()
        self.guessdraw(0)
        
        
        
    def update_limits(self,extra):
        functiontype = self.var_func.get()
        
        self.startfreq = max(float(self.startfreq_text.get()),min(array(self.a.index)))
        self.endfreq = min(float(self.endfreq_text.get()),max(array(self.a.index)))
        
        
        
        self.startidx = self.a.nearest(self.startfreq)
        self.endidx =  self.a.nearest(self.endfreq)        
        
        
        for i in range(len(self.guess)):
            self.guess[i] = self.scale_list[i].get()

        self.ax1.cla()
        self.canvas.show()
        self.background = self.canvas.copy_from_bbox(self.ax1.bbox)
        

        dataplot = self.ax1.plot(array(self.a.index[self.startidx:self.endidx]),self.a.values[self.startidx:self.endidx],animated=True)[0]#(ax = self.ax1).lines[-1]
        x= array(self.a.index[self.startidx:self.endidx])
        guessplot = self.ax1.plot(x,zeros(x.size),animated=True)[0]
        
        
        #self.ax1.set_xlim(min(self.a.index),max(self.a.index))
        #self.ax1.set_ylim(min(self.a.values),1)
        
        self.canvas.show()
        self.guessdraw(0)

        
        
        return 0
            
    def open_data(self): 
        global dataplot,guessplot
        self.name = self.DisplaySpectrum()
       
        if self.name == -1:
            return 0
        try:
            self.a = RamanSpectrum(self.name)
            self.normalization_constant= 1/max(self.a)
            self.startfreq = min(array(self.a.index))
            self.startfreq_text.insert(END,str(self.startfreq))
            self.endfreq = max(array(self.a.index))
            self.endfreq_text.insert(END,str(self.endfreq))
            
        except:
            self.t.insert(END, 'error opening spectrum')
            return -1
        
        
        self.raw = self.a.copy
        self.ax1.cla()
        self.canvas.show()
        self.background = self.canvas.copy_from_bbox(self.ax1.bbox)
        

        dataplot = self.ax1.plot(array(self.a.index),self.a.values,animated=True)[0]#(ax = self.ax1).lines[-1]
        x= array(self.a.index)
        guessplot = self.ax1.plot(x,zeros(self.a.size),animated=True)[0]
        self.ax1.set_xlim(min(self.a.index),max(self.a.index))
        self.ax1.set_ylim(min(self.a.values),1)
        
        self.canvas.show()

        self.update_limits(0)
        
        
       
        
        return 0
    
    def open_ref(self):

        pass
        
        return 0 
        
    def open_bkg(self):

        pass
        return 0 
        
            
        
    def recalc_data(self):
        if self.raw.shape == self.reference.shape:
            self.a= SG_Smooth(self.raw,width = 11,order = 3)/self.reference/self.normalization_constant
            self.ax1.cla()
            plot(self.a[0],self.raw/self.reference)
            plot(self.a[0],self.a[1])
        else:
            self.t.insert(END, "reference invalid")
            self.reference_name = "No IR Reference"
            
            self.ax1.cla()
            self.ax1.plot(self.a[0],self.a[1])
            self.canvas.draw()
        
        return 0
        

    def guessdraw(self,ex):
        global function,guessplot,dataplot
        
        
        x = array(self.a.index[self.startidx:self.endidx+1])
        
        
        for i in range(len(self.guess)):
            self.guess[i] = self.scale_list[i].get()
        
        self.canvas.restore_region(self.background)
        self.ax1.lines[-1].set_xdata(x)
        self.ax1.lines[-1].set_ydata(function(x,*self.guess))
        
        
        for l in self.ax1.lines:

            self.ax1.draw_artist(l)
           
        self.canvas.blit(self.ax1.bbox)
        
        
            
        

        return 0
    def fit_and_draw(self):
        
        global function
        print type(self.a)
        if type(self.a) == pandas.core.series.Series:
            self.a = RamanSpectrum(self.a)
        #result = fitspectrum(self.a, (float(self.a.index[self.startidx]),float(self.a.index[self.endidx+1])),'Custom',self.guess,function = function)
        print self.guess
        result = fitspectrum(self.a, (self.startfreq,self.endfreq),'Custom',self.guess,function = function)
        fittingparameters = result[0]
        xfit = result[1]
        yfit = result[2]
        if result == -1:
            tkMessageBox.showerror('Fit Failed')
            return 0

        z = list(fittingparameters[0])            
        self.canvas.restore_region(self.background)
        self.ax1.lines[-1].set_xdata(xfit)
        self.ax1.lines[-1].set_ydata(yfit)
        
        
        for l in self.ax1.lines:

            self.ax1.draw_artist(l)
        for i in range(len(self.w_name)):
            #self.scale_list[i].set(result[0][i])
            if "w" in self.w_name[i]:
                self.ax1.axvline(x = z[i], ymin = 0, ymax = 1 ,color = 'r')
           
        self.canvas.blit(self.ax1.bbox)

        self.t.insert(END, "  \nResult Found for " + str(self.name))
        self.t.insert(END, " \nReferenced to IR spectrum " +self.reference_name)
        self.t.insert(END, "  \nNormalized by constant "+str(self.normalization_constant))
        for i in range(len(self.w_name)):
            self.t.insert(END, ' \n'+self.w_name[i]+': '+str(z[i]))
        
                
        
        return 0
    def DisplaySpectrum(self):
        import re
        global name_list, str_name_list
        file_opt = options = {}
        options['defaultextension'] = '.spe'
        options['filetypes'] = [('all files', '.*'),('SPE files', '.SPE'), ('csv files','.csv'),('text files','.txt')]
        options['title'] = 'Open Spectrum...'
        options['initialdir'] = '/home/chris/Documents/DataWeiss'

        str_name_list = tkFileDialog.askopenfilename(**options)
        if str_name_list == '':
            return -1
        return str_name_list                        
Ejemplo n.º 4
0
class App(Tk):
    def __init__(self):
        Tk.__init__(self)
        self.title("Baja GUI")
        
        self.grid()
        cw = 1   # cell width
        ch = 2
        
        cr = self.winfo_screenwidth() / 32
        
        print(self.winfo_screenheight())
        print(self.winfo_screenwidth())
        
        # Root level frames
        self.controlFrame = Frame(self, bg='grey', borderwidth=0, width=self.winfo_screenwidth(), height=(self.winfo_screenheight()/4))
        self.displayFrame = Frame(self, bg='grey', borderwidth=0)
        # Serial Control Frame
        self.serialFrame = Frame(self.controlFrame, borderwidth=0)  
        
        self.COMPort = StringVar()
        self.COMPortTextBox = Entry(self.serialFrame, textvariable = self.COMPort)
        self.COMPort.set('/dev/ttyUSB0')
        self.COMBaud = StringVar()
        self.COMBaudTextBox = Entry(self.serialFrame, textvariable = self.COMBaud)
        self.COMBaud.set('9600')
        self.COMButton = Button(self.serialFrame, text = "Start Serial", command = self.StartSerial)
        
        self.SerialSendButton = Button(self.serialFrame, text = "Send to Board", command = self.SendToSerial)
        self.SerialSendToDriverButton = Button(self.serialFrame, text = "Send to Driver", command = self.SendToDriver)
        self.SerialSendTextBox = Entry(self.serialFrame)

        

        # Extra Buttons
        self.SerialStopButton = Button(self.serialFrame, text = "Stop Serial", command = self.StopSerial)
        self.comeBackToPitNowButton = Button(self.controlFrame, text = "Pit Now", command = self.PitNow)
        self.comeBackToPitNextLapButton = Button(self.controlFrame, text = "Pit Next Lap", command = self.PitNextLap)

        # Informative Things
        self.dataBarFrame = Frame(self.controlFrame)
        
        self.numActiveThreads = StringVar()
        self.numThreadsLabel = Label(self.dataBarFrame, textvariable = self.numActiveThreads)
        self.numActiveThreads.set('Threads\n' + str(threading.enumerate().__len__()))
        self.numThreadsLabel.grid(column = 0, row = 0)
        
        
        self.counter = StringVar()
        self.counterLabel = Label(self.dataBarFrame, textvariable = self.counter)
        self.counter.set('Counter\n' + 'N/A')
        self.counterLabel.grid(column = 1, row = 0)
        
        self.gpsDate = StringVar()
        self.gpsDateLabel = Label(self.dataBarFrame, textvariable = self.gpsDate)
        self.gpsDate.set('Date\n' + '010100')
        self.gpsDateLabel.grid(column = 2, row = 0)
        
        self.gpsTime = StringVar()
        self.gpsTimeLabel = Label(self.dataBarFrame, textvariable = self.gpsTime)
        self.gpsTime.set('Time\n' + '00000000')
        self.gpsTimeLabel.grid(column = 3, row = 0)
        
        self.numSats = StringVar()
        self.numSatsLabel = Label(self.dataBarFrame, textvariable = self.numSats)
        self.numSats.set('Sats\n' + 'NSA')
        self.numSatsLabel.grid(column = 4, row = 0)

        self.currentLatitude = StringVar()
        self.latitudeLabel = Label(self.dataBarFrame, textvariable = self.currentLatitude)
        self.currentLatitude.set("Latitude\n" + 'Unknown')
        self.latitudeLabel.grid(column = 5, row = 0)
        
        
        self.currentLongitude = StringVar()
        self.longitudeLabel = Label(self.dataBarFrame, textvariable = self.currentLongitude)
        self.currentLongitude.set("Longitude\n" + 'Unknown')
        self.longitudeLabel.grid(column = 6, row = 0)
        
        
        self.currentSpeed = StringVar()
        self.speedLabel = Label(self.dataBarFrame, textvariable=self.currentSpeed)
        self.currentSpeed.set("Speed\n" + "86")
        self.speedLabel.grid(column = 7, row = 0)
        
        self.currentDashTemp = StringVar()
        self.dashTempLabel = Label(self.dataBarFrame, textvariable=self.currentDashTemp)
        self.currentDashTemp.set("Dash Temp\n" + "N/A")
        self.dashTempLabel.grid(column = 8, row = 0)
        
        self.batteryVoltage = StringVar()
        self.batteryVoltageLabel = Label(self.dataBarFrame, textvariable = self.batteryVoltage)
        self.batteryVoltage.set("BATT\n" + "N/A")
        self.batteryVoltageLabel.grid(column = 9, row = 0)
        
        
        self.xbeeSignalStrength = StringVar()
        self.xbeeSignalStrengthLabel = Label(self.dataBarFrame, textvariable = self.xbeeSignalStrength)
        self.xbeeSignalStrength.set("XBee\n" + "N/A")
        self.xbeeSignalStrengthLabel.grid(column = 10, row = 0)
        
        self.currentFrontBrakeAvg = StringVar()
        self.frontBrakeAvgLabel = Label(self.dataBarFrame, textvariable = self.currentFrontBrakeAvg)
        self.currentFrontBrakeAvg.set("Front Brake Avg\n" + "N/A")
        self.frontBrakeAvgLabel.grid(column = 11, row = 0)
        
        self.currentFrontBrakeMax = StringVar()
        self.frontBrakeMaxLabel = Label(self.dataBarFrame, textvariable = self.currentFrontBrakeMax)
        self.currentFrontBrakeMax.set("Front Brake Max\n" + "N/A")
        self.frontBrakeMaxLabel.grid(column = 12, row = 0)
        
        self.currentRearBrakeAvg = StringVar()
        self.rearBrakeAvgLabel = Label(self.dataBarFrame, textvariable = self.currentRearBrakeAvg)
        self.currentRearBrakeAvg.set("Rear Brake Avg\n" + "N/A")
        self.rearBrakeAvgLabel.grid(column = 13, row = 0)
        
        self.currentRearBrakeMax = StringVar()
        self.rearBrakeMaxLabel = Label(self.dataBarFrame, textvariable = self.currentRearBrakeMax)
        self.currentRearBrakeMax.set("Rear Brake Max\n" + "N/A")
        self.rearBrakeMaxLabel.grid(column = 14, row = 0)
        

        self.currentSteeringAvg = StringVar()
        self.steeringAvgLabel = Label(self.dataBarFrame, textvariable = self.currentSteeringAvg)
        self.currentSteeringAvg.set("Steering\n" + "Yes")
        self.steeringAvgLabel.grid(column = 15, row = 0)
        
        self.buttonPressed = StringVar()
        self.buttonPressedLabel = Label(self.dataBarFrame, textvariable = self.buttonPressed, borderwidth = 1)
        self.buttonPressed.set("Button\n" + "No")
        self.buttonPressedLabel.grid(column = 16, row = 0)
        
        
        self.currentPrimaryRPM = StringVar()
        self.currentSecondaryRPM = StringVar()
        
        # Accelerometer
        self.accX = [0]
        self.maxX = [0]
        self.accY = [0]
        self.maxY = [0]
        self.accZ = [0]
        self.maxZ = [0]
        
        # 
        self.rearTemp = [0]

        
        

        self.listbox = Listbox(self.controlFrame)
        
        # Set to full screen
        self.attributes('-fullscreen', True)
        
        # Bind <Return> Keypress to text boxes
        self.SerialSendTextBox.bind("<Return>", self.SendOnReturn)
        self.COMBaudTextBox.bind("<Return>", self.StartSerialOnReturn)
        
        # Pack Serial Controls into Serial Frame
        self.SerialSendTextBox.grid(column = 0, row=0, sticky=EW)
        self.SerialSendButton.grid(column = 2, row=0)
        self.SerialSendToDriverButton.grid(column = 3, row = 0)
        self.COMPortTextBox.grid(column = 4, row=0, sticky = E)
        self.COMBaudTextBox.grid(column=6, row=0, sticky = E)
        self.COMButton.grid(column = 8, row=0, sticky = NE)
        self.SerialStopButton.grid(row = 0, column = 9, sticky=NE)
        
        # Pack Control Widgets into Control Frame
        self.serialFrame.grid(row = 0, column=0, columnspan=12, sticky=EW)
        
        
        self.comeBackToPitNowButton.grid(row=0, column=10, sticky=NSEW)
        self.comeBackToPitNextLapButton.grid(row=1, column=10, sticky=NSEW)

        self.dataBarFrame.grid(row = 1, column = 0, columnspan = 10, sticky = EW)
        
        self.listbox.grid(row = 2, column = 0, columnspan=10, sticky = EW)
        
        # Pack Control Frame into root
        self.controlFrame.grid(row = 0, sticky=EW)
        
        
        # Top Level Display Frames
        self.leftDisplayFrame = Frame(self.displayFrame, bg='grey', borderwidth=0, width=(self.winfo_screenwidth()/2))
        self.rightDisplayFrame = Frame(self.displayFrame, bg='grey', borderwidth=0, width=(self.winfo_screenwidth()/2))
        
        # Inside Left Display Frames
        self.topLeftDisplayFrame = Frame(self.leftDisplayFrame, bg='grey', borderwidth=0, height=(self.winfo_screenheight()/4))
        self.middleLeftDisplayFrame = Frame(self.leftDisplayFrame, bg='grey', borderwidth=0, height=(self.winfo_screenheight()/4))
        self.bottomLeftDisplayFrame = Frame(self.leftDisplayFrame, bg='grey', borderwidth=0, height=(self.winfo_screenheight()/4))
        
        # Inside Top Left Display Frames
        
        # Inside Middle Left Display Frames
        self.brakeFrame = Frame(self.middleLeftDisplayFrame, borderwidth=0)
        
        # Inside Bottom Left Display Frames
        self.driveTrainTempFrame = Frame(self.bottomLeftDisplayFrame, borderwidth=0)
        self.driveTrainRPMFrame = Frame(self.bottomLeftDisplayFrame, borderwidth=0)
        
        # Inside Rigt Display Frames
        self.shieldTempFrame = Frame(self.rightDisplayFrame, borderwidth=0, bg='grey', height=(self.winfo_screenheight()/8))
        self.shieldHealthFrame = Frame(self.rightDisplayFrame, borderwidth=0, bg='grey')
        
        # Construct Items for Display Frame
        self.gpsFigure, self.gpsAxes = plt.subplots(figsize=(2*ch,2*ch), dpi=cr*2)
        self.speedFigure, self.speedAxes = plt.subplots(figsize=(2*ch,2*ch), dpi=cr)

        
        self.rpmFigure, self.rpmAxes = plt.subplots(figsize=(ch,ch), dpi=cr)
        self.dashTempFigure, self.dashTempAxes = plt.subplots(figsize=(2*ch,ch), dpi=cr)
        self.rearTempFigure, self.rearTempAxes = plt.subplots(figsize=(2*ch,ch), dpi=cr)
        self.gearTempFigure, self.gearTempAxes = plt.subplots(figsize=(2*ch,ch), dpi=cr)
        self.cvtTempFigure, self.cvtTempAxes = plt.subplots(figsize=(2*ch,ch), dpi=cr)
        self.battFigure, self.battAxes = plt.subplots(figsize=(ch,ch), dpi=cr)
        self.frontBrakeFigure, self.frontBrakeAxes = plt.subplots(figsize=(2*ch,ch), dpi=cr)
        self.rearBrakeFigure, self.rearBrakeAxes = plt.subplots(figsize=(2*ch,ch), dpi=cr)
        self.steeringFigure, self.steeringAxes = plt.subplots(figsize=(ch,2*ch), dpi=cr)
        self.buttonFigure, self.buttonGraph = plt.subplots(figsize=(ch,ch), dpi=cr)
        self.accFigure, self.accAxes = plt.subplots(figsize=(2*ch,2*ch), dpi=cr)
        self.zFigure, self.zAxes = plt.subplots(figsize=(ch, 2*ch), dpi=cr)
        
        
        # GPS Axes Setup
        self.gpsFigure.patch.set_visible(False)
        self.gpsAxes.set_title('GPS')
        #self.gpsAxes.set_xlim(-110.953,-110.952)
        self.gpsAxes.set_xlim(-118823207 - 3000,-118823207 + 3000)
        self.gpsAxes.set_ylim(34749085 - 3000,34749085 + 3000)
        self.gpsAxes.hold(True)
        
        self.gpsCanvas = FigureCanvasTkAgg(self.gpsFigure, master=self.rightDisplayFrame)
        self.gpsCanvas.show()
        
        
        
        
        
        # speed Axes Setup
        self.speedFigure.patch.set_visible(False)
        self.speedAxes.set_title('Speed')
        self.speedAxes.set_xlim(0,100)
        self.speedAxes.set_ylim(0,50)
        self.speedAxes.hold(True)
        
        self.speedCanvas = FigureCanvasTkAgg(self.speedFigure, master=self.topLeftDisplayFrame)
        self.speedCanvas.show()

        # Speed Textbox Setup

        
        # Dash Temperature Axes Setup
        self.dashTempFigure.patch.set_visible(False)
        self.dashTempAxes.set_title('Dash Temperature')
#        self.ten_wide = [0,1,2,3,4,5,6,7,8,9]
        self.dashTempAxes.set_xlim(0,100)
#        self.dashTempAxes.autoscale(enable=True, axis='x')
        self.dashTempAxes.set_ylim(0,100)
        self.dashTempAxes.hold(True)
        
        self.dashTempCanvas = FigureCanvasTkAgg(self.dashTempFigure, master=self.shieldTempFrame)
        self.dashTempCanvas.show()
#        self.dashTempCanvas.draw()

        
        
        # Rear Temperature Axes Setup
        self.rearTempFigure.patch.set_visible(False)
        self.rearTempAxes.set_title('Rear Temperature')
        self.rearTempAxes.set_xlim(0,500)
        self.rearTempAxes.set_ylim(0,100)
        self.rearTempAxes.hold(True)
        
        self.rearTempCanvas = FigureCanvasTkAgg(self.rearTempFigure, master=self.shieldTempFrame)
        self.rearTempCanvas.show()
#        
        
        
        # Gearbox Temperature Axes Setup
        self.gearTempFigure.patch.set_visible(False)
        self.gearTempAxes.set_title('Gearbox Temperature')
        self.gearTempAxes.set_xlim(0,500)
        self.gearTempAxes.set_ylim(0,100)
        self.gearTempAxes.hold(True)
        
        self.gearTempCanvas = FigureCanvasTkAgg(self.gearTempFigure, master=self.driveTrainTempFrame)
        self.gearTempCanvas.show()
#        
        
        
        # CVT Temperature Axes Setup
        self.cvtTempAxes.set_title('CVT Temperature')
        self.cvtTempAxes.set_xlim(0,500)
        self.cvtTempAxes.set_ylim(0,100)
        self.cvtTempAxes.hold(True)
        
        self.cvtTempCanvas = FigureCanvasTkAgg(self.cvtTempFigure, master=self.driveTrainTempFrame)
        self.cvtTempCanvas.show()
#        
        
        
        # Acceleration Axes Setup
        self.accFigure.patch.set_visible(False)
        self.accAxes.set_title('Acceleration 2-D')
        self.accAxes.set_xlim(-2, 2)
        self.accAxes.set_ylim(-2, 2)
        self.accAxes.hold(True)
        
        self.accCanvas = FigureCanvasTkAgg(self.accFigure, master=self.middleLeftDisplayFrame)
        self.accCanvas.show()
        
        self.zFigure.patch.set_visible(False)
        self.zAxes.set_title('Z-Acc')
        self.zAxes.set_xlim(-2, 2)
        self.zAxes.set_ylim(-2, 2)
        self.zAxes.hold(True)
        
        self.zCanvas = FigureCanvasTkAgg(self.zFigure, master=self.topLeftDisplayFrame)
        self.zCanvas.show()
        
        
        self.steeringFigure.patch.set_visible(False)
        self.steeringAxes.set_title('Steering')
        self.steeringAxes.set_xlim(-2, 2)
        self.steeringAxes.set_ylim(-2, 2)
        self.steeringAxes.hold(True)
        
        self.steeringCanvas = FigureCanvasTkAgg(self.steeringFigure, master=self.topLeftDisplayFrame)
        self.steeringCanvas.show()
        
        # Front Brake Axes Setup
        self.frontBrakeFigure.patch.set_visible(False)
        self.frontBrakeAxes.set_title('Front Brake Pressure')
        self.frontBrakeAxes.set_xlim(0,500)
        self.frontBrakeAxes.set_ylim(0,100)
        self.frontBrakeAxes.hold(True)
        
        self.frontBrakeCanvas = FigureCanvasTkAgg(self.frontBrakeFigure, master=self.brakeFrame)
        self.frontBrakeCanvas.show()
        
        # Rear Brake Axes Setup
        self.rearBrakeFigure.patch.set_visible(False)
        self.rearBrakeAxes.set_title('Rear Brake Pressure')
        self.rearBrakeAxes.set_xlim(0,500)
        self.rearBrakeAxes.set_ylim(0,100)
        self.rearBrakeAxes.hold(True)
        
        self.rearBrakeCanvas = FigureCanvasTkAgg(self.rearBrakeFigure, master=self.brakeFrame)
        self.rearBrakeCanvas.show()
        
        # Layout
        # Pack Brake Pressure
        self.frontBrakeCanvas.get_tk_widget().grid(column = 0, row=0, sticky=N)
#        self.frontBrakeCanvas._tkcanvas.grid(column=0, row=0, sticky=N)
        self.rearBrakeCanvas.get_tk_widget().grid(column=0, row=1, sticky=S)
#        self.rearBrakeCanvas._tkcanvas.grid(column=0, row=1, sticky=S)
        
        # Pack Drive Train RPM
        
        # Pack Drive Train Temp
        self.gearTempCanvas.get_tk_widget().grid(column = 0, row=0, sticky=W)
#        self.gearTempCanvas._tkcanvas.grid(column=0, row=0, sticky=W)
        self.cvtTempCanvas.get_tk_widget().grid(column=1, row=0, sticky=E)
#        self.cvtTempCanvas._tkcanvas.grid(column=1, row=0, sticky=E)
        
        # Pack stuff into top left
#        self.speedTextBox.grid(column=1, row=0, sticky=NSEW)
        self.zCanvas.get_tk_widget().grid(column=0, row=0, sticky=NSEW)
        self.steeringCanvas.get_tk_widget().grid(column=1, row=0, sticky=NSEW)
        self.speedCanvas.get_tk_widget().grid(column=2, row=0 , sticky=NSEW)
#        self.speedCanvas._tkcanvas.grid(column=2 , row=0 , sticky=NSEW)
        
        # Pack stuff into middle left
        self.accCanvas.get_tk_widget().grid(column=0 , row=1 , sticky=W  )
#        self.accCanvas._tkcanvas.grid(column=0 , row=1 , sticky=W  )
        self.brakeFrame.grid(column=1 , row=1 , sticky=E)
        
        # Pack stuff into bottom left
        self.driveTrainTempFrame.grid(column=0 , row=5 , sticky=N  )
        self.driveTrainRPMFrame.grid(column=0 , row=6 , sticky=S  )
        
        
        # Pack Left Display
        self.topLeftDisplayFrame.grid(column=0 , row=2 , sticky=NSEW  )
        self.middleLeftDisplayFrame.grid(column=0 , row=4 , sticky=NSEW  )
        self.bottomLeftDisplayFrame.grid(column=0 , row=6 , sticky=NSEW  )
        
        
        # Pack Shield Temp
        self.dashTempCanvas.get_tk_widget().grid(column=0 , row=5   )
#        self.dashTempCanvas._tkcanvas.grid(column=0 , row=5 , sticky=W  )
        self.rearTempCanvas.get_tk_widget().grid(column=1 , row=5   )
#        self.rearTempCanvas._tkcanvas.grid(column=1 , row=5 , sticky=E  )
        
        # Pack Shield Health
        
        # Pack stuff inside right display
        self.gpsCanvas.get_tk_widget().grid(column=4 , row=2 , sticky=NSEW  )
#        self.gpsCanvas._tkcanvas.grid(column=4 , row=2 , sticky=NSEW  )
        self.shieldTempFrame.grid(column=4 , row=5 , sticky=N  )
        self.shieldHealthFrame.grid(column=4 , row=6 , sticky=N  )
            # TODO: Button Press notification goes here...
        
        
        # Pack Display Frame
        self.leftDisplayFrame.grid(column=0 , row=3 , sticky=NS  )
        self.rightDisplayFrame.grid(column=5 , row=3 , sticky=NS  )
        
        # Pack Display Into Root
        self.displayFrame.grid(column=0 , row=2 , sticky=NSEW  )
        
        
    # Initialize Data Variables
        
        # Dash Data
#        self.counter.set(0) # Commented to preserve initial text value, left here to preserve variable order/index
#        self.gpsDate = 0
#        self.gpsTime = 0
#        self.numSats = 0
        self.latitude = [32236562]
        self.longitude = [-110952322]
        self.speed = [0]*102
        self.dashTemp = [0]*102
#        self.batteryVoltage = 0
#        self.xbeeSignalStrength = 0
        self.frontBrakeAvg = [0]
        self.frontBrakeMax = [0]
        self.rearBrakeAvg = [0]
        self.rearBrakeMax = [0]
        self.steeringAvg = [0]
#        self.buttonPressed = 0
        
        # Rear Board Data
        self.primaryRPM = 0
        self.secondaryRPM = 0
        
        
        # Accelerometer
        self.accX = [0]
        self.maxX = [0]
        self.accY = [0]
        self.maxY = [0]
        self.accZ = [0]
        self.maxZ = [0]
        
        # 
        self.rearTemp = [0]

        


        
        self.hundred_array = list(range(0,102))
        
        self.gpsBackground = self.gpsCanvas.copy_from_bbox(self.gpsAxes.bbox)
        self.speedBackground = self.speedCanvas.copy_from_bbox(self.speedAxes.bbox)
        self.dashTempBackground = self.dashTempCanvas.copy_from_bbox(self.dashTempAxes.bbox)
        
        self.gpsPlot = self.gpsAxes.plot(self.longitude, self.latitude, '-')[0]
        self.speedPlot = self.speedAxes.plot(self.hundred_array,self.speed)[0]
        self.dashTempPlot = self.dashTempAxes.plot(self.hundred_array, self.dashTemp)[0]
        
        
        # Create Queues for talking to serial line asyncronously
        self.rx = queue.Queue()
        self.tx = queue.Queue()
        
        


    def StartSerial(self):
        self.listbox.insert(0, "Baud Rate: " + self.COMBaud.get())
        self.listbox.insert(0, "COM Port: " + self.COMPort.get())
        self.numActiveThreads.set('Threads\n' + str(threading.enumerate().__len__()))
        if (threading.enumerate().__len__()!=1):
            self.serialThread.join()
        #print(threading.enumerate().__len__())
        self.numActiveThreads.set('Threads\n' + str(threading.enumerate().__len__()))
        self.serialThread = SerialThread(self.COMPort, self.COMBaud, self.rx, self.tx)
        
        self.serialThread.start()
        self.numActiveThreads.set('Threads\n' + str(threading.enumerate().__len__()))
        self.process_serial()


    def StopSerial(self):
        self.listbox.insert(0, "Serial Stopped")
        if (threading.enumerate().__len__()!=1):
            self.serialThread.join()
        self.numActiveThreads.set('Threads\n' + str(threading.enumerate().__len__()))
        
    def PitNow(self):
        self.listbox.insert(0, "Pit Now")
        self.tx.put("<PIT NOW>\n")

    def PitNextLap(self):
        self.listbox.insert(0, "Pit Next Lap")
        self.tx.put("<PIT NEXT LAP>\n")


    def SendOnReturn(self, event):
        self.SendToSerial()

    def StartSerialOnReturn(self, event):
        self.StartSerial()

    def SendToSerial(self):
        text_contents = self.SerialSendTextBox.get()
        self.listbox.insert(0, text_contents)
        self.tx.put(text_contents)
        self.SerialSendTextBox.delete(0,END)

    def SendToDriver(self):
        text_contents = self.SerialSendTextBox.get()
        self.listbox.insert(0, text_contents)
        self.tx.put('<')
        self.tx.put(text_contents)
        self.tx.put('>')
        self.SerialSendTextBox.delete(0,END)


    def process_serial(self):
        text = StringVar()
        if self.rx.qsize():
#            self.listbox.delete(0,END)
            try:
                dataString = self.rx.get()
                
            except Queue.Empty:
                pass
                
            self.listbox.insert(0, dataString)
            data = dataString.split(bytes(', ','UTF-8'))
            print(data.__len__())
            if(data.__len__()==18 or data.__len__()==28):
                try:
                    i = 0
                    # Dash Data
                    self.counter.set('Counter\n' + str(int(data[0])))
                    i = 1
                    self.gpsDate.set('Date\n' + str(int(data[1])))
                    i = 2
                    self.gpsTime.set('Time\n' + str(int(data[2])))
                    i = 3
                    self.numSats.set('Sats\n' + str(int(data[3])))
                    if (float(data[4])/1000000 < 100 and float(data[5])/1000000 < 200):
                        i = 4
                        self.latitude.append(int(data[4]))
                        self.currentLatitude.set('Latitude\n' + str(int(data[4])))
                        i = 5
                        self.longitude.append(int(data[5]))
                        self.currentLongitude.set('Longitude\n' + str(int(data[5])))
                    i = 6
                    self.speed.append(float(data[6]))
                    self.currentSpeed.set('Speed\n' + str(float(data[6])))
                    self.currentSpeed.set('Speed\n' + str(float(data[6])))
                    i = 7
                    self.dashTemp.append(float(data[7]))
                    self.currentDashTemp.set('Dash Temp\n' + str(float(data[7])) + 'C')
                    i = 8
                    self.batteryVoltage.set('Batt\n' + str(int(data[8])))
                    i = 9
                    self.xbeeSignalStrength.set('XBee\n' + str(int(data[9])))
                    i = 10
                    self.frontBrakeAvg.append(float(data[10]))
                    i = 11
                    self.frontBrakeMax.append(int(data[11]))
                    i = 12
                    self.rearBrakeAvg.append(float(data[12]))
                    i = 13
                    self.rearBrakeMax.append(int(data[13]))
                    i = 14
                    self.steeringAvg.append(float(data[14]))
                    i = 15
    #                    self.buttonPressed = int(data[15])
                    i = 16
    #                    
    #                    # Rear Board Data
    #                    self.primaryRPM = 0
    #                    self.secondaryRPM = 0
    #                    
    #                    
    #                    # Accelerometer
    #                    self.accX = [0]
    #                    self.maxX = [0]
    #                    self.accY = [0]
    #                    self.maxY = [0]
    #                    self.accZ = [0]
    #                    self.maxZ = [0]
    #                    
    #                    # 
    #                    self.rearTemp = [0]
                except:
                    print('Exception Raised!' + str(i))
                    pass
                    
 

                
                self.gpsCanvas.restore_region(self.gpsBackground)
                self.gpsPlot.set_data(self.longitude[1:], self.latitude[1:])
                self.gpsAxes.draw_artist(self.gpsPlot)
                self.gpsCanvas.blit(self.gpsAxes.bbox)
                
                self.speedCanvas.restore_region(self.speedBackground)
                self.speedPlot.set_data(self.hundred_array[-101:], self.speed[-101:])
                self.speedAxes.draw_artist(self.speedPlot)
                self.speedCanvas.blit(self.speedAxes.bbox)
                
                self.dashTempCanvas.restore_region(self.dashTempBackground)
                self.dashTempPlot.set_data(self.hundred_array[-101:], self.dashTemp[-101:])
                self.dashTempAxes.draw_artist(self.dashTempPlot)
                self.dashTempCanvas.blit(self.dashTempAxes.bbox)
                

                
        self.after(100, self.process_serial)
        
    # Graceful Exit
    def destroy(e):
        sys.exit()
Ejemplo n.º 5
0
class Viewer(tk.Frame):
    def __init__(self, parent, collection=None, with_toolbar=True):
        tk.Frame.__init__(self, parent)
        # toolbar
        if with_toolbar:
            self.create_toolbar()

        # canvas
        #canvas_frame = tk.Frame(self)
        #canvas_frame.pack(side=tk.LEFT,fill=tk.BOTH,expand=1)
        #title_frame = tk.Frame(canvas_frame)
        #title_frame.pack(side=tk.TOP,anchor=tk.NW)
        #tk.Label(title_frame,text=" Plot Title: ").pack(side=tk.LEFT)
        #self._title = tk.Entry(title_frame,width=30)
        #self._title.pack(side=tk.LEFT)
        #tk.Button(title_frame, text='Set', command=lambda: self.updateTitle()
        #        ).pack(side=tk.LEFT)

        self.fig = plt.Figure(figsize=(8, 6))
        self.ax = self.fig.add_subplot(111)
        self.canvas = FigureCanvasTkAgg(self.fig, master=self)
        self.setupMouseNavigation()
        self.navbar = ToolBar(self.canvas, self,
                              self.ax)  # for matplotlib features
        self.setupNavBarExtras(self.navbar)
        self.canvas.get_tk_widget().pack(side=tk.LEFT, fill=tk.BOTH, expand=1)
        # spectra list
        self.create_listbox()
        # toggle options
        self.mean = False
        self.median = False
        self.max = False
        self.min = False
        self.std = False

        self.spectrum_mode = False
        self.show_flagged = True
        # data
        self.collection = collection
        self.head = 0
        self.flag_filepath = os.path.abspath('./flagged_spectra.txt')
        if collection:
            self.update_artists(new_lim=True)
            self.update_list()

        # pack
        self.pack(fill=tk.BOTH, expand=1)
        self.color = '#000000'

    def returnToSelectMode(self):
        if self.ax.get_navigate_mode() == 'PAN':
            #Turn panning off
            self.navbar.pan()
        elif self.ax.get_navigate_mode() == 'ZOOM':
            #Turn zooming off
            self.navbar.zoom()

    def setupNavBarExtras(self, navbar):
        working_dir = os.path.dirname(os.path.abspath(__file__))
        img = Image.open(os.path.join(working_dir, "select.png"))
        #self.select_icon = tk.PhotoImage(file=os.path.join(working_dir,"select.png"))
        self.select_icon = tk.PhotoImage(img)

        self.select_button = tk.Button(navbar,
                                       width="24",
                                       height="24",
                                       image=img,
                                       command=self.returnToSelectMode).pack(
                                           side=tk.LEFT, anchor=tk.W)

        self.dirLbl = tk.Label(navbar, text="Viewing: None")
        self.dirLbl.pack(side=tk.LEFT, anchor=tk.W)

    def plotConfig(self):
        config = PlotConfigDialog(self,
                                  title=self.ax.get_title(),
                                  xlabel=self.ax.get_xlabel(),
                                  ylabel=self.ax.get_ylabel(),
                                  xlim=self.ax.get_xlim(),
                                  ylim=self.ax.get_ylim())
        if (config.applied):
            print(config.title)
            print(config.xlim)
            self.ax.set_title(config.title)
            self.ax.set_xlabel(config.xlabel)
            self.ax.set_ylabel(config.ylabel)
            self.ax.set_xlim(*config.xlim)
            self.ax.set_ylim(*config.ylim)
            self.canvas.draw()

    def rectangleStartEvent(self, event):
        self._rect = None
        self._rect_start = event

    def rectangleMoveEvent(self, event):
        try:
            dx = event.xdata - self._rect_start.xdata
            dy = event.ydata - self._rect_start.ydata
        except TypeError:
            #we're out of canvas bounds
            return

        if self._rect is not None:
            self._rect.remove()

        self._rect = Rectangle(
            (self._rect_start.xdata, self._rect_start.ydata),
            dx,
            dy,
            color='k',
            ls='--',
            lw=1,
            fill=False)
        self.ax.add_patch(self._rect)
        self.ax.draw_artist(self._rect)

    def rectangleEndEvent(self, event):
        if self._rect is not None:
            self._rect.remove()
        else:
            #make a small, fake rectangle
            class FakeEvent(object):
                def __init__(self, x, y):
                    self.xdata, self.ydata = x, y

            dy = (self.ax.get_ylim()[1] - self.ax.get_ylim()[0]) / 100.
            self._rect_start = FakeEvent(event.xdata - 10, event.ydata + dy)
            event = FakeEvent(event.xdata + 10, event.ydata - dy)

        if not self.collection is None:
            x0 = min(self._rect_start.xdata, event.xdata)
            x1 = max(self._rect_start.xdata, event.xdata)
            y0 = min(self._rect_start.ydata, event.ydata)
            y1 = max(self._rect_start.ydata, event.ydata)
            try:
                #if our data is sorted, we can easily isolate it
                x_data = self.collection.data.loc[x0:x1]
            except:
                #Pandas builtin throws an error, use another pandas builtin
                data = self.collection.data
                in_xrange = (data.index >= x0) & (data.index <= x1)
                x_data = data.iloc[in_xrange]

            ylim = sorted([self._rect_start.ydata, event.ydata])
            is_in_box = ((x_data > y0) & (x_data < y1)).any()

            highlighted = is_in_box.index[is_in_box].tolist()
            key_list = list(self.collection._spectra.keys())

            self.update_selected(highlighted)
            flags = self.collection.flags
            for highlight in highlighted:
                #O(n^2) woof
                if (not (highlight in flags)) or self.show_flagged:
                    pos = key_list.index(highlight)
                    self.listbox.selection_set(pos)

    def setupMouseNavigation(self):
        self.clicked = False
        self.select_mode = 'rectangle'
        self._bg_cache = None

        START_EVENTS = {'rectangle': self.rectangleStartEvent}

        MOVE_EVENTS = {'rectangle': self.rectangleMoveEvent}

        END_EVENTS = {'rectangle': self.rectangleEndEvent}

        def onMouseDown(event):
            if self.ax.get_navigate_mode() is None:
                self._bg_cache = self.canvas.copy_from_bbox(self.ax.bbox)
                self.clicked = True
                START_EVENTS[self.select_mode](event)

        def onMouseUp(event):
            if self.ax.get_navigate_mode() is None:
                self.canvas.restore_region(self._bg_cache)
                self.canvas.blit(self.ax.bbox)
                self.clicked = False
                END_EVENTS[self.select_mode](event)

        def onMouseMove(event):
            if self.ax.get_navigate_mode() is None:
                if (self.clicked):
                    self.canvas.restore_region(self._bg_cache)
                    MOVE_EVENTS[self.select_mode](event)
                    self.canvas.blit(self.ax.bbox)

        self.canvas.mpl_connect('button_press_event', onMouseDown)
        self.canvas.mpl_connect('button_release_event', onMouseUp)
        self.canvas.mpl_connect('motion_notify_event', onMouseMove)

    @property
    def head(self):
        return self._head

    @head.setter
    def head(self, value):
        if not hasattr(self, '_head'):
            self._head = 0
        else:
            self._head = value % len(self.collection)

    def set_head(self, value):
        if isinstance(value, Iterable):
            if len(value) > 0:
                value = value[0]
            else:
                value = 0
        self.head = value
        if self.spectrum_mode:
            self.update()
        self.update_selected()

    @property
    def collection(self):
        return self._collection

    @collection.setter
    def collection(self, value):
        if isinstance(value, Spectrum):
            # create new collection
            self._collection = Collection(name=Spectrum.name, spectra=[value])
        if isinstance(value, Collection):
            self._collection = value
        else:
            self._collection = None

    def move_selected_to_top(self):
        selected = self.listbox.curselection()
        keys = [self.collection.spectra[s].name for s in selected]
        for s in selected[::-1]:
            self.listbox.delete(s)
        self.listbox.insert(0, *keys)
        self.listbox.selection_set(0, len(keys))

    def unselect_all(self):
        self.listbox.selection_clear(0, tk.END)
        self.update_selected()

    def select_all(self):
        self.listbox.selection_set(0, tk.END)
        self.update_selected()

    def invert_selection(self):
        for i in range(self.listbox.size()):
            if self.listbox.selection_includes(i):
                self.listbox.selection_clear(i)
            else:
                self.listbox.selection_set(i)
        self.update_selected()

    def change_color(self):
        cpicker = ColorPickerDialog(self)
        #rgb,color = askcolor(self.color)
        if cpicker.applied:
            self.color = cpicker.color
            self.color_pick.config(bg=self.color)
            #update our list of chosen colors
            selected = self.listbox.curselection()
            selected_keys = [self.collection.spectra[s].name for s in selected]

            for key in selected_keys:
                self.colors[key] = self.color
            self.update()

    def select_by_name(self):
        pattern = self.name_filter.get()
        for i in range(self.listbox.size()):
            if pattern in self.listbox.get(i):
                self.listbox.selection_set(i)
            else:
                self.listbox.selection_clear(i)
        self.update_selected()

    def create_listbox(self):
        self._sbframe = tk.Frame(self)

        list_label = tk.Frame(self._sbframe)
        list_label.pack(side=tk.TOP, anchor=tk.N, fill=tk.X)
        tk.Label(list_label, text="Name:").pack(side=tk.LEFT, anchor=tk.W)
        self.name_filter = tk.Entry(list_label, width=14)
        self.name_filter.pack(side=tk.LEFT, anchor=tk.W)
        tk.Button(list_label,
                  text="Select",
                  command=lambda: self.select_by_name()).pack(side=tk.LEFT,
                                                              anchor=tk.W)
        self.sblabel = tk.Label(list_label, text="Showing: 0")
        self.sblabel.pack(side=tk.RIGHT)

        self.scrollbar = tk.Scrollbar(self._sbframe)
        self.listbox = tk.Listbox(self._sbframe,
                                  yscrollcommand=self.scrollbar.set,
                                  selectmode=tk.EXTENDED,
                                  width=30)
        self.scrollbar.config(command=self.listbox.yview)

        self.list_tools = tk.Frame(self._sbframe)
        tk.Button(self.list_tools,
                  text="To Top",
                  command=lambda: self.move_selected_to_top()).pack(
                      side=tk.TOP, anchor=tk.NW, fill=tk.X)
        tk.Button(self.list_tools,
                  text="Select All",
                  command=lambda: self.select_all()).pack(side=tk.TOP,
                                                          anchor=tk.NW,
                                                          fill=tk.X)
        tk.Button(self.list_tools,
                  text="Clear",
                  command=lambda: self.unselect_all()).pack(side=tk.TOP,
                                                            anchor=tk.NW,
                                                            fill=tk.X)
        tk.Button(self.list_tools,
                  text="Invert",
                  command=lambda: self.invert_selection()).pack(side=tk.TOP,
                                                                anchor=tk.NW,
                                                                fill=tk.X)

        self.color_field = tk.Frame(self.list_tools)
        tk.Label(self.color_field, text="Color:").pack(side=tk.LEFT)

        self.color_pick = tk.Button(self.color_field,
                                    text="",
                                    command=lambda: self.change_color(),
                                    bg='#000000')
        self.color_pick.pack(side=tk.RIGHT,
                             anchor=tk.NW,
                             fill=tk.X,
                             expand=True)

        self.color_field.pack(side=tk.TOP, anchor=tk.NW, fill=tk.X)

        self.list_tools.pack(side=tk.RIGHT, anchor=tk.NW)
        self.scrollbar.pack(side=tk.RIGHT, anchor=tk.E, fill=tk.Y)
        self.listbox.pack(side=tk.RIGHT, anchor=tk.E, fill=tk.Y)
        self.listbox.bind('<<ListboxSelect>>',
                          lambda x: self.set_head(self.listbox.curselection()))
        self._sbframe.pack(side=tk.RIGHT, anchor=tk.E, fill=tk.Y)

    def create_toolbar(self):
        self.toolbar = tk.Frame(self)
        tk.Button(self.toolbar, text='Read',
                  command=lambda: self.read_dir()).pack(side=tk.LEFT,
                                                        fill=tk.X,
                                                        expand=1)
        tk.Button(self.toolbar,
                  text='Mode',
                  command=lambda: self.toggle_mode()).pack(side=tk.LEFT,
                                                           fill=tk.X,
                                                           expand=1)
        tk.Button(self.toolbar,
                  text="Plot Config",
                  command=lambda: self.plotConfig()).pack(side=tk.LEFT,
                                                          fill=tk.X,
                                                          expand=1)
        tk.Button(self.toolbar,
                  text='Show/Hide Flagged',
                  command=lambda: self.toggle_show_flagged()).pack(
                      side=tk.LEFT, fill=tk.X, expand=1)
        tk.Button(self.toolbar,
                  text='Flag/Unflag',
                  command=lambda: self.toggle_flag()).pack(side=tk.LEFT,
                                                           fill=tk.X,
                                                           expand=1)
        tk.Button(self.toolbar,
                  text='Unflag all',
                  command=lambda: self.unflag_all()).pack(side=tk.LEFT,
                                                          fill=tk.X,
                                                          expand=1)
        #tk.Button(self.toolbar, text='Save Flag', command=lambda:
        #          self.save_flag()).pack(side=tk.LEFT,fill=tk.X,expand=1)
        tk.Button(self.toolbar,
                  text='Save Flags',
                  command=lambda: self.save_flag_as()).pack(side=tk.LEFT,
                                                            fill=tk.X,
                                                            expand=1)
        tk.Button(self.toolbar, text='Stitch',
                  command=lambda: self.stitch()).pack(side=tk.LEFT,
                                                      fill=tk.X,
                                                      expand=1)
        tk.Button(self.toolbar,
                  text='Jump_Correct',
                  command=lambda: self.jump_correct()).pack(side=tk.LEFT,
                                                            fill=tk.X,
                                                            expand=1)
        tk.Button(self.toolbar,
                  text='mean',
                  command=lambda: self.toggle_mean()).pack(side=tk.LEFT,
                                                           fill=tk.X,
                                                           expand=1)
        tk.Button(self.toolbar,
                  text='median',
                  command=lambda: self.toggle_median()).pack(side=tk.LEFT,
                                                             fill=tk.X,
                                                             expand=1)
        tk.Button(self.toolbar, text='max',
                  command=lambda: self.toggle_max()).pack(side=tk.LEFT,
                                                          fill=tk.X,
                                                          expand=1)
        tk.Button(self.toolbar, text='min',
                  command=lambda: self.toggle_min()).pack(side=tk.LEFT,
                                                          fill=tk.X,
                                                          expand=1)
        tk.Button(self.toolbar, text='std',
                  command=lambda: self.toggle_std()).pack(side=tk.LEFT,
                                                          fill=tk.X,
                                                          expand=1)
        self.toolbar.pack(side=tk.TOP, fill=tk.X)

    def updateTitle(self):
        print("Hello world!")
        self.ax.set_title(self._title.get())
        self.canvas.draw()

    def set_collection(self, collection):
        new_lim = True if self.collection is None else False
        self.collection = collection
        self.update_artists(new_lim=new_lim)
        self.update()
        self.update_list()

    def read_dir(self):
        try:
            directory = os.path.split(
                filedialog.askopenfilename(filetypes=(
                    ("Supported types", "*.asd *.sed *.sig *.pico"),
                    ("All files", "*"),
                )))[0]
        except:
            return
        if not directory:
            return
        c = Collection(name="collection", directory=directory)
        self.set_collection(c)
        self.dirLbl.config(text="Viewing: " + directory)

    def reset_stats(self):
        if self.mean_line:
            self.mean_line.remove()
            self.mean_line = None
            self.mean = False
        if self.median_line:
            self.median_line.remove()
            self.median_line = None
            self.median = False
        if self.max_line:
            self.max_line.remove()
            self.max_line = None
            self.max = False
        if self.min_line:
            self.min_line.remove()
            self.min_line = None
            self.min = False
        if self.std_line:
            self.std_line.remove()
            self.std_line = None
            self.std = False

    def toggle_mode(self):
        if self.spectrum_mode:
            self.spectrum_mode = False
        else:
            self.spectrum_mode = True
        self.update()

    def toggle_show_flagged(self):
        if self.show_flagged:
            self.show_flagged = False
        else:
            self.show_flagged = True
        self.update()

    def unflag_all(self):
        #new flags -> new statistics
        self.reset_stats()

        for spectrum in list(self.collection.flags):
            self.collection.unflag(spectrum)
        self.update()
        self.update_list()

    def toggle_flag(self):
        #new flags -> new statistics
        self.reset_stats()

        selected = self.listbox.curselection()
        keys = [self.listbox.get(s) for s in selected]

        for i, key in enumerate(keys):
            print(i, key)
            spectrum = key
            if spectrum in self.collection.flags:
                self.collection.unflag(spectrum)
                self.listbox.itemconfigure(selected[i], foreground='black')
            else:
                self.collection.flag(spectrum)
                self.listbox.itemconfigure(selected[i], foreground='red')
        # update figure
        self.update()

    def save_flag(self):
        ''' save flag to self.flag_filepath'''
        with open(self.flag_filepath, 'w') as f:
            for spectrum in self.collection.flags:
                print(spectrum, file=f)

    def save_flag_as(self):
        ''' modify self.flag_filepath and call save_flag()'''
        flag_filepath = filedialog.asksaveasfilename()
        if os.path.splitext(flag_filepath)[1] == '':
            flag_filepath = flag_filepath + '.txt'
        self.flag_filepath = flag_filepath
        self.save_flag()

    def update_list(self):
        self.listbox.delete(0, tk.END)
        for i, spectrum in enumerate(self.collection.spectra):
            self.listbox.insert(tk.END, spectrum.name)
            if spectrum.name in self.collection.flags:
                self.listbox.itemconfigure(i, foreground='red')
        self.update_selected()

    def ask_for_draw(self):
        #debounce canvas updates
        now = datetime.now()
        print(now - self.last_draw)
        if ((now - self.last_draw).total_seconds() > 0.5):
            self.canvas.draw()
            self.last_draw = now

    def update_artists(self, new_lim=False):
        if self.collection is None:
            return
        #update values being plotted -> redo statistics
        self.mean_line = None
        self.median_line = None
        self.max_line = None
        self.min_line = None
        self.std_line = None
        # save limits
        if new_lim == False:
            xlim = self.ax.get_xlim()
            ylim = self.ax.get_ylim()
        # plot
        self.ax.clear()
        # show statistics
        if self.spectrum_mode:
            idx = self.listbox.curselection()
            if len(idx) == 0:
                idx = [self.head]
            spectra = [self.collection.spectra[i] for i in idx]
            flags = [s.name in self.collection.flags for s in spectra]
            print("flags = ", flags)
            flag_style = ' '
            if self.show_flagged:
                flag_style = 'r'
            artists = Collection(name='selection', spectra=spectra).plot(
                ax=self.ax,
                style=list(np.where(flags, flag_style, self.color)),
                picker=1)
            self.ax.set_title('selection')
            # c = str(np.where(spectrum.name in self.collection.flags, 'r', 'k'))
            # spectrum.plot(ax=self.ax, label=spectrum.name, c=c)
        else:
            # red curves for flagged spectra
            flag_style = ' '
            if self.show_flagged:
                flag_style = 'r'
            flags = [
                s.name in self.collection.flags
                for s in self.collection.spectra
            ]
            print("flags = ", flags)
            self.collection.plot(ax=self.ax,
                                 style=list(np.where(flags, flag_style, 'k')),
                                 picker=1)
            #self.ax.set_title(self.collection.name)

        keys = [s.name for s in self.collection.spectra]
        artists = self.ax.lines
        self.artist_dict = {key: artist for key, artist in zip(keys, artists)}
        self.colors = {key: 'black' for key in keys}
        self.ax.legend().remove()
        self.navbar.setHome(self.ax.get_xlim(), self.ax.get_ylim())
        self.canvas.draw()
        self.sblabel.config(text="Showing: {}".format(len(artists)))

    def update_selected(self, to_add=None):
        """ Update, only on flaged"""
        if self.collection is None:
            return

        if to_add:
            for key in to_add:
                self.artist_dict[key].set_linestyle('--')
        else:
            keys = [s.name for s in self.collection.spectra]
            selected = self.listbox.curselection()
            selected_keys = [self.collection.spectra[s].name for s in selected]
            for key in keys:
                if key in selected_keys:
                    self.artist_dict[key].set_linestyle('--')
                else:
                    self.artist_dict[key].set_linestyle('-')
        self.canvas.draw()

    def update(self):
        """ Update the plot """
        if self.collection is None:
            return
        # show statistics
        if self.spectrum_mode:
            self.ax.clear()
            idx = self.listbox.curselection()
            if len(idx) == 0:
                idx = [self.head]
            spectra = [self.collection.spectra[i] for i in idx]
            flags = [s.name in self.collection.flags for s in spectra]
            print("flags = ", flags)
            flag_style = ' '
            if self.show_flagged:
                flag_style = 'r'
            Collection(name='selection', spectra=spectra).plot(
                ax=self.ax,
                style=list(np.where(flags, flag_style, 'k')),
                picker=1)
            self.ax.set_title('selection')
            # c = str(np.where(spectrum.name in self.collection.flags, 'r', 'k'))
            # spectrum.plot(ax=self.ax, label=spectrum.name, c=c)
        else:
            # red curves for flagged spectra

            keys = [s.name for s in self.collection.spectra]
            for key in keys:
                if key in self.collection.flags:
                    if self.show_flagged:
                        self.artist_dict[key].set_visible(True)
                        self.artist_dict[key].set_color('red')
                    else:
                        self.artist_dict[key].set_visible(False)
                else:
                    self.artist_dict[key].set_color(self.colors[key])
                    self.artist_dict[key].set_visible(True)

            if self.show_flagged:
                self.sblabel.config(
                    text="Showing: {}".format(len(self.artist_dict)))
            else:
                self.sblabel.config(text="Showing: {}".format(
                    len(self.artist_dict) - len(self.collection.flags)))
            '''
            self.collection.plot(ax=self.ax,
                                 style=list(np.where(flags, flag_style, 'k')),
                                 picker=1)
            self.ax.set_title(self.collection.name)
            '''

        if self.spectrum_mode:
            #self.ax.legend()
            pass
        else:
            #self.ax.legend().remove()
            pass
        self.ax.set_ylabel(self.collection.measure_type)
        #toggle appearance of statistics
        if self.mean_line != None: self.mean_line.set_visible(self.mean)
        if self.median_line != None: self.median_line.set_visible(self.median)
        if self.max_line != None: self.max_line.set_visible(self.max)
        if self.min_line != None: self.min_line.set_visible(self.min)
        if self.std_line != None: self.std_line.set_visible(self.std)
        self.canvas.draw()

    def next_spectrum(self):
        if not self.spectrum_mode:
            return
        self.head = (self.head + 1) % len(self.collection)
        self.update()

    def stitch(self):
        ''' 
        Known Bugs
        ----------
        Can't stitch one spectrum and plot the collection
        '''
        self.collection.stitch()
        self.update_artists()

    def jump_correct(self):
        ''' 
        Known Bugs
        ----------
        Only performs jump correction on 1000 and 1800 wvls and 1 reference
        '''
        self.collection.jump_correct([1000, 1800], 1)
        self.update_artists()

    def toggle_mean(self):
        if self.mean:
            self.mean = False

        else:
            self.mean = True
            if not self.mean_line:
                self.collection.mean().plot(ax=self.ax,
                                            c='b',
                                            label=self.collection.name +
                                            '_mean',
                                            lw=3)
                self.mean_line = self.ax.lines[-1]
        self.update()

    def toggle_median(self):
        if self.median:
            self.median = False
        else:
            self.median = True
            if not self.median_line:
                self.collection.median().plot(ax=self.ax,
                                              c='g',
                                              label=self.collection.name +
                                              '_median',
                                              lw=3)
                self.median_line = self.ax.lines[-1]
        self.update()

    def toggle_max(self):
        if self.max:
            self.max = False
        else:
            self.max = True
            if not self.max_line:
                self.collection.max().plot(ax=self.ax,
                                           c='y',
                                           label=self.collection.name + '_max',
                                           lw=3)
                self.max_line = self.ax.lines[-1]
        self.update()

    def toggle_min(self):
        if self.min:
            self.min = False
        else:
            self.min = True
            if not self.min_line:
                self.collection.min().plot(ax=self.ax,
                                           c='m',
                                           label=self.collection.name + '_min',
                                           lw=3)
                self.min_line = self.ax.lines[-1]
        self.update()

    def toggle_std(self):
        if self.std:
            self.std = False
        else:
            self.std = True
            if not self.std_line:
                self.collection.std().plot(ax=self.ax,
                                           c='c',
                                           label=self.collection.name + '_std',
                                           lw=3)
                self.std_line = self.ax.lines[-1]
        self.update()
Ejemplo n.º 6
0
class Root(Widget, Generic[_T]):
    tk_widget: Optional[tk.Frame]
    canvas: Optional[FigureCanvasTkAgg]
    background_img: Optional[FigureImage]

    def __init__(self,
                 params,
                 w: int = 1429,
                 h: int = 799,
                 dpi: int = 141,
                 color: str = '#000000',
                 **kwargs) -> None:
        Widget.__init__(self)

        self.params = params
        self.w = w
        self.h = h
        self.dpi = dpi
        self.face_color = color

        matplotlib_config()

        self.fig: plt.Figure = plt.figure(
            figsize=(self.w / self.dpi, self.h / self.dpi),
            dpi=self.dpi,
            facecolor=self.face_color,
        )

        self.gs = self.fig.add_gridspec(nrows=90,
                                        ncols=160,
                                        left=0,
                                        right=1,
                                        top=1,
                                        bottom=0,
                                        hspace=0,
                                        wspace=0)

        self.properties = kwargs
        self.artists = {}
        self.tk_widget = None
        self.canvas = None
        self.background_img = None
        self._bg = None
        self._initialized = None

        self.__post_init__()

    def for_tk(self, parent: Union[tk.Tk, tk.Frame, tk.Canvas]) -> tk.Canvas:
        self.tk_widget = parent
        self.canvas = FigureCanvasTkAgg(self.fig, master=parent)
        widget = self.canvas.get_tk_widget()
        widget.pack(fill=tk.BOTH, expand=1)
        return widget

    @staticmethod
    def load_img(fp: PATH_LIKE) -> np.array:
        return plt.imread(cbook.get_sample_data(fp))

    @timer
    def save_img(self, fp: PATH_LIKE) -> None:
        self.fig.savefig(fp, transparent=True)

    @timer
    def set_background_from_img(self, img_array: np.array) -> None:
        self.background_img = plt.figimage(img_array)
        self.background_img.set_zorder(-999)

    def update(self, iteration_data: ITERATION_DATA) -> None:
        raise NotImplementedError

    def init(self) -> None:
        self._initialized = self._initialized or self.init_results() or True
        self.reset_results()
        self._bg = self._bg or self.canvas.copy_from_bbox(
            self.canvas.figure.bbox)
        self.draw_artists()

    def draw_artists(self) -> None:
        self.canvas.restore_region(self._bg)
        list(map(self.canvas.figure.draw_artist, self.animated))
        self.canvas.blit(self.canvas.figure.bbox)

    def __call__(self, iteration_data: List[ITERATION_DATA]):
        if hasattr(iteration_data, '__iter__'):
            list(map(self.update, iteration_data))
        else:
            self.update(iteration_data)
        self.draw_artists()

    def _set_background(self) -> None:
        pass

    def populate_from_iteration(self, iteration) -> None:
        raise NotImplementedError

    def _init_results(self) -> None:
        pass

    def set_result(self, *args) -> None:
        pass

    def _reset_results(self) -> None:
        pass
Ejemplo n.º 7
0
class TensileTestView(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)  # Initialize this class as a frame
        self.animationBgCol = "black"  # Animation canvas background colour

        # Create and configure main frame
        mainArea = tk.Frame(self, bg=st.MAIN_AREA_BG)
        mainArea.grid(row=0, column=0, sticky="nsew")
        mainArea.grid_propagate(0)
        self.grid_rowconfigure(0, weight=1)
        self.grid_columnconfigure(0, weight=1)

        # Create and configure main grids
        grid = tuple([i for i in range(20)])
        mainArea.grid_columnconfigure(grid, weight=1, minsize=50)
        mainArea.grid_rowconfigure(grid, weight=1, minsize=35)

        # Create title
        label = tk.Label(mainArea,
                         text="Mechanical Workshop",
                         font=st.LARGE_FONT,
                         bg=st.MAIN_AREA_BG,
                         fg=st.TITLE_COLOUR)
        label.grid(row=0, column=14, columnspan=6, sticky='nse')

        # Create description
        label = tk.Label(
            mainArea,
            text="We are now going to perform a tensile test on the " +
            "sheet of aluminum that we cold rolled! We can see our sample of aluminum on the left side of "
            +
            "the screen as well as a stress-strain graph on the right side of the screen. "
            + "Press the start button to begin the tensile test!",
            bg=st.INPUT_BG,
            wraplength=650,
            fg='black',
            justify='left',
            relief='ridge')
        label.grid(row=1, column=6, rowspan=2, columnspan=14, sticky='nesw')

        # Canvas for graphic simulation
        self.height = 595
        self.width = 250
        self.animationWindow = tk.Canvas(mainArea,
                                         bg=self.animationBgCol,
                                         height=self.height,
                                         width=self.width,
                                         bd=0,
                                         highlightthickness=0,
                                         relief='ridge')
        self.animationWindow.grid(row=2,
                                  column=1,
                                  columnspan=5,
                                  rowspan=17,
                                  sticky='ne')

        # Create Plot
        self.f = Figure(figsize=(6, 6), dpi=100)
        self.a = self.f.add_subplot(111)
        self.a.grid(color='grey', linestyle='-', linewidth=0.3)
        self.a.set_ylabel('Stress (MPa)')
        self.a.set_xlabel('Strain (-)')
        self.line = self.a.plot([], [], "-")
        self.a.format_coord = lambda x, y: "Strain (-)={:6.4f}, Stress (MPa)={:6.3f}".format(
            x, y)

        # Create canvas for plot
        self.graphWindow = FigureCanvasTkAgg(self.f, mainArea)
        self.graphWindow.get_tk_widget().grid(row=5,
                                              column=6,
                                              rowspan=12,
                                              columnspan=12)
        self.BG = self.graphWindow.copy_from_bbox(self.a.bbox)
        self.OG = self.BG

        # Load arrow images
        self.arrow = ImageTk.PhotoImage(file=st.IMG_PATH + "left_arrow.png")
        self.arrowClicked = ImageTk.PhotoImage(file=st.IMG_PATH +
                                               "left_arrow_clicked.png")
        self.arrowDisabled = ImageTk.PhotoImage(file=st.IMG_PATH +
                                                "left_arrow_disabled.png")

        # Arrow for previous page
        self.nextPage = tk.Button(mainArea, image=self.arrow, borderwidth=0)
        self.nextPage.image = self.arrow
        self.nextPage.grid(row=9, rowspan=2, column=0, sticky='nesw')

        # Button to start simulation
        self.animationButton = ttk.Button(mainArea, text="Start")
        self.animationButton.grid(row=3,
                                  rowspan=2,
                                  column=6,
                                  columnspan=3,
                                  sticky='nesw')

        # Text for displaying cold work
        self.CW_text = tk.Label(mainArea,
                                text='',
                                borderwidth=2,
                                bg=st.INPUT_BG,
                                font=st.MEDIUM_FONT)
        self.CW_text.grid(row=0,
                          rowspan=2,
                          column=2,
                          columnspan=3,
                          sticky='nsew')

        # Draw the rod
        self.rod = Rod(self.animationWindow, self.width, self.height,
                       self.animationBgCol)
        self.rod.drawRod()

        # Create toolbar for plot
        self.toolbar = NavigationToolbar2Tk(self.graphWindow, mainArea)
        self.toolbar.update()
        self.toolbar.grid(row=17,
                          column=6,
                          rowspan=2,
                          columnspan=10,
                          sticky='nsew')

        # Draw mac logo
        logoImg = ImageTk.PhotoImage(Image.open(st.IMG_PATH + "macLogo.png"))
        canvas = tk.Canvas(mainArea,
                           bg=st.MAIN_AREA_BG,
                           width=130,
                           height=71,
                           bd=0,
                           highlightthickness=0,
                           relief='ridge')
        canvas.create_image(130 / 2, 71 / 2, image=logoImg, anchor="center")
        canvas.image = logoImg
        canvas.grid(row=17, column=17, rowspan=3, columnspan=3)

    def setGraphSize(self, x, y):
        """
		Set the graph size. Assume it is called before any other function
		"""
        self.a.set_xlim([-0.01, x + 0.3])
        self.a.set_ylim([0, y + 50])
        self.graphWindow.draw()
        self.BG = self.graphWindow.copy_from_bbox(self.a.bbox)

    def pressArrow(self):
        """
		Change arrow picture to "pressed arrow"
		"""
        self.nextPage.config(image=self.arrowClicked)
        self.nextPage.image = self.arrowClicked

    def normalArrow(self):
        """
		Change arrow picture to "normal arrow"
		"""
        self.nextPage.config(image=self.arrow)
        self.nextPage.image = self.arrow

    def disableArrow(self):
        """
		Change arrow picture to "disabled arrow"
		"""
        self.nextPage.config(image=self.arrowDisabled)
        self.nextPage.image = self.arrowDisabled

    def resetCanvas(self):
        """
		Reset the rod on canvas
		"""
        self.rod.resetRod()

    def setCW(self, val):
        """
		Set the coldwork text
		"""
        self.CW_text.config(text="%CW = " + str(val))

    def updateGraph(self, xvals, yvals):
        """
		Update the graph with xvals and yvals. This function is called at a given framerate
		"""
        self.line[0].set_data(xvals, yvals)
        self.graphWindow.restore_region(self.BG)
        self.a.draw_artist(self.line[0])
        self.graphWindow.blit(self.a.bbox)
        self.graphWindow.flush_events()

    def updateAnimation(self, elongation, widthFact, neckWidthFact,
                        neckHeightFact):
        """
		Update the canvas based on given values. This function is called at a given framerate
		"""
        self.rod.updateRod(elongation, widthFact, neckWidthFact,
                           neckHeightFact)

    def generateFracture(self, EL):
        """
		Generate a fracture in the Rod. Function is called at the end of the animation
		"""
        self.rod.drawFracture(EL)
Ejemplo n.º 8
0
class MultichannelPlot(matplotlib.figure.Figure):
    def __init__(self, master, row=0, column=0, rowspan=5, columnspan=5, width=5, height=3, update_prot="blit"):
        matplotlib.figure.Figure.__init__(self, figsize=(width, height))
        self.update_prot = update_prot
        self.frame = Frame(master=master)
        self.frame.config(bd=5)

        self.frame.grid(row=row, column=column, padx=5, pady=5)
        self.channel_list = []
        self.array_list = []
        self.color_list = ["r", "b", "g", "c", "m", "y", "k"]

        self.a = self.add_subplot(MultichannelAxis(self, 111))

        self.canvas = FigureCanvasTkAgg(self, master=self.frame)
        self.canvas.show()

        self.canvas._tkcanvas.pack(side=TOP, fill=BOTH, expand=True)

        self.toolbar = NavigationToolbar2TkAgg(self.canvas, self.frame)
        self.toolbar.update()
        self.toolbar.pack(side=BOTTOM, fill=BOTH, expand=True)  # ,expand = True)#fill=BOTH)#, expand=1)
        self.canvas.draw()
        self.background = self.canvas.copy_from_bbox(self.a.bbox)

        return None

    def AddChannel(self, spec_array, channel_type, color=None):

        if color == None or color == "":
            self.a.add_line(Channel([], [], self, spec_array, channel_type, color=self.color_list[0]))
            self.color_list.append(self.color_list[0])
            del (self.color_list[0])

        else:
            self.a.add_line(Channel([], [], self, spec_array, channel_type, color=color))
        # self.Update()
        self.Redraw()
        return self.a.lines[-1]

    def RemoveChannel(self, channel):
        self.a.lines.remove(channel)
        self.Redraw()

        return 0

    def SetChannelColor(self, channel, clr):
        if clr != "":
            channel.color = clr

        else:
            channel.color = self.color_list[0]
            self.color_list.append(self.color_list[0])
            del (self.color_list[0])

        return 0

    def ShowChannel(self, channel):
        channel.set_visible(True)

        self.Update()
        return 0

    def HideChannel(self, channel):
        channel.set_visible(False)
        self.Update()
        return 0

    def Redraw(self):

        self.a.relim()
        self.a.autoscale_view(tight=False)

        self.canvas.draw()
        self.canvas.restore_region(self.background)
        for line in self.a.lines:
            self.a.draw_artist(line)

        self.canvas.blit(self.a.bbox)

        return 0

    def SaveFigure(self, filename):

        self.f_copy = self.a
        self.f_copy.savefig("a.png")

        return 0

    def Update(self):
        if self.update_prot == "draw":
            self.canvas.draw()
            return 0

        (lower_y_lim, upper_y_lim) = self.a.get_ylim()
        (lower_x_lim, upper_x_lim) = self.a.get_xlim()
        scaley_bool = False
        scalex_bool = False
        scaley_down_bool = True

        for channel in self.a.lines:
            if channel.get_visible() == True:
                channel.ChannelUpdate()
                scaley_bool = (
                    scaley_bool or max(channel.get_ydata()) > upper_y_lim or min(channel.get_ydata()) < lower_y_lim
                )
                scaley_down_bool = scaley_down_bool and max(channel.get_ydata()) < upper_y_lim * 0.6
                scalex_bool = (
                    scalex_bool or max(channel.get_xdata()) != upper_x_lim or min(channel.get_xdata()) != lower_x_lim
                )

        if scaley_bool or scalex_bool or scaley_down_bool:

            self.Redraw()

        else:

            self.canvas.restore_region(self.background)
            for line in self.a.lines:
                self.a.draw_artist(line)

            self.canvas.blit(self.a.bbox)

        return 0
Ejemplo n.º 9
0
class PlotFrame(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master)
        self.fwidth = 512
        self.fheight = 720
        self.configure(bd=2,
                       width=self.fwidth,
                       height=self.fheight,
                       relief='sunken')
        self.grid_propagate(0)
        self.dpi = 100
        self.f = Figure(figsize=(self.fwidth / self.dpi,
                                 self.fheight / self.dpi),
                        dpi=self.dpi,
                        facecolor=(1, 1, 1, 0))
        self.canvas = FigureCanvasTkAgg(self.f, self)

        self.top = self.f.add_subplot(311)
        self.middle = self.f.add_subplot(312)
        self.bottom = self.f.add_subplot(313)

        self.xData = np.linspace(0, 100 * np.pi, 1000, endpoint=False)
        self.yDataB = np.sin(self.xData)
        self.yDataM = np.sin(self.xData) * np.sin(self.xData * 0.5 + .4)
        self.yDataT = np.sin(self.xData)**2 + np.cos(self.xData * 1.1 + 0.15)

        self.startTime = time.time()
        self.canvas.draw()
        self.backgroundB = self.canvas.copy_from_bbox(self.bottom.bbox)
        self.backgroundT = self.canvas.copy_from_bbox(self.top.bbox)
        self.backgroundM = self.canvas.copy_from_bbox(self.middle.bbox)
        self.pointsB = self.bottom.plot(self.xData, self.yDataB)[0]
        self.pointsM = self.middle.plot(self.xData, self.yDataM)[0]
        self.pointsT = self.top.plot(self.xData, self.yDataT)[0]

    def animate2(self, reScaled):
        scale = True

        if reScaled:
            self.f.clf()
            self.showCanvas.grid_forget()
            self.f = Figure(figsize=(self.fwidth / self.dpi,
                                     self.fheight / self.dpi),
                            dpi=self.dpi,
                            facecolor=(1, 1, 1, 0))
            self.canvas = FigureCanvasTkAgg(self.f, self)

            self.top = self.f.add_subplot(311)
            self.middle = self.f.add_subplot(312)
            self.bottom = self.f.add_subplot(313)

            self.canvas.draw()

            self.backgroundB = self.canvas.copy_from_bbox(self.bottom.bbox)
            self.backgroundT = self.canvas.copy_from_bbox(self.top.bbox)
            self.backgroundM = self.canvas.copy_from_bbox(self.middle.bbox)

            self.pointsB = self.bottom.plot(self.xData, self.yDataB)[0]
            self.pointsM = self.middle.plot(self.xData, self.yDataM)[0]
            self.pointsT = self.top.plot(self.xData, self.yDataT)[0]
            scale = False

        if scale:
            t = time.time() - self.startTime
            N = len(self.xData)
            currentIdx = int(N * ((t / 4) % 1))
            scalingNumber = N * 0.1
            waveShape = np.exp(-np.arange(N) / scalingNumber)[::-1]

            colorArray = np.array([(1, 0, 0, a)
                                   for a in np.roll(waveShape, currentIdx)])

            self.yDataB = np.roll(self.yDataB, 1)
            self.yDataT = np.roll(self.yDataT, 1)
            self.yDataM = np.roll(self.yDataM, 1)

            self.pointsB.set_data(self.xData, self.yDataB)
            self.pointsT.set_data(self.xData, self.yDataT)
            self.pointsM.set_data(self.xData, self.yDataM)

            self.canvas.restore_region(self.backgroundB)
            self.canvas.restore_region(self.backgroundT)
            self.canvas.restore_region(self.backgroundM)

            self.bottom.draw_artist(self.pointsB)
            self.middle.draw_artist(self.pointsM)
            self.top.draw_artist(self.pointsT)

            self.canvas.blit(self.bottom.bbox)
            self.canvas.blit(self.top.bbox)
            self.canvas.blit(self.middle.bbox)

            self.showCanvas = self.canvas.get_tk_widget()
            self.showCanvas.grid()