Beispiel #1
0
def Update(dsviewer):
    image = dsviewer.image
    if "events" in dir(image) and len(image.events) > 0:
        st = image.mdh.getEntry("StartTime")
        if "EndTime" in image.mdh.getEntryNames():
            et = image.mdh.getEntry("EndTime")
        else:
            et = piecewiseMapping.framesToTime(image.data.getNumSlices(), image.events, image.mdh)

        dsviewer.elv.SetRange([0, et - st])
Beispiel #2
0
def Update(dsviewer):
    image = dsviewer.image
    if 'events' in dir(image) and len(image.events) > 0:
        st = image.mdh.getEntry('StartTime')
        if 'EndTime' in image.mdh.getEntryNames():
            et = image.mdh.getEntry('EndTime')
        else:
            et = piecewiseMapping.framesToTime(image.data.getNumSlices(),
                                               image.events, image.mdh)

        dsviewer.elv.SetRange([0, et - st])
Beispiel #3
0
def Plug(dsviewer):
    image = dsviewer.image
    if 'events' in dir(image) and len(image.events) > 0:
        st = image.mdh.getEntry('StartTime')
        if 'EndTime' in image.mdh.getEntryNames():
            et = image.mdh.getEntry('EndTime')
        else:
            et = piecewiseMapping.framesToTime(image.data.getNumSlices(),
                                               image.events, image.mdh)
        dsviewer.elv = eventLogViewer.eventLogTPanel(dsviewer, image.events,
                                                     image.mdh, [0, et - st])
        dsviewer.AddPage(dsviewer.elv, False, 'Events')

        charts = []

        if 'ProtocolFocus' in dsviewer.elv.evKeyNames:
            dsviewer.zm = piecewiseMapping.GeneratePMFromEventList(
                dsviewer.elv.eventSource, image.mdh,
                image.mdh.getEntry('StartTime'),
                image.mdh.getEntry('Protocol.PiezoStartPos'))
            charts.append(('Focus [um]', dsviewer.zm, 'ProtocolFocus'))

        if 'ScannerXPos' in dsviewer.elv.evKeyNames:
            x0 = 0
            if 'Positioning.Stage_X' in image.mdh.getEntryNames():
                x0 = image.mdh.getEntry('Positioning.Stage_X')
            dsviewer.xm = piecewiseMapping.GeneratePMFromEventList(
                dsviewer.elv.eventSource, image.mdh,
                image.mdh.getEntry('StartTime'), x0, 'ScannerXPos', 0)
            charts.append(('XPos [um]', dsviewer.xm, 'ScannerXPos'))

        if 'ScannerYPos' in dsviewer.elv.evKeyNames:
            y0 = 0
            if 'Positioning.Stage_Y' in image.mdh.getEntryNames():
                y0 = image.mdh.getEntry('Positioning.Stage_Y')
            dsviewer.ym = piecewiseMapping.GeneratePMFromEventList(
                dsviewer.elv.eventSource, image.mdh,
                image.mdh.getEntry('StartTime'), y0, 'ScannerYPos', 0)
            charts.append(('YPos [um]', dsviewer.ym, 'ScannerYPos'))

        if 'ScannerZPos' in dsviewer.elv.evKeyNames:
            z0 = 0
            if 'Positioning.PIFoc' in image.mdh.getEntryNames():
                z0 = image.mdh.getEntry('Positioning.PIFoc')
            dsviewer.zm = piecewiseMapping.GeneratePMFromEventList(
                dsviewer.elv.eventSource, image.mdh,
                image.mdh.getEntry('StartTime'), z0, 'ScannerZPos', 0)
            charts.append(('ZPos [um]', dsviewer.zm, 'ScannerZPos'))

        dsviewer.elv.SetCharts(charts)

        dsviewer.updateHooks.append(Update)
Beispiel #4
0
def Plug(dsviewer):
    image = dsviewer.image
    if "events" in dir(image) and len(image.events) > 0:
        st = image.mdh.getEntry("StartTime")
        if "EndTime" in image.mdh.getEntryNames():
            et = image.mdh.getEntry("EndTime")
        else:
            et = piecewiseMapping.framesToTime(image.data.getNumSlices(), image.events, image.mdh)
        dsviewer.elv = eventLogViewer.eventLogTPanel(dsviewer, image.events, image.mdh, [0, et - st])
        dsviewer.AddPage(dsviewer.elv, False, "Events")

        charts = []

        if "ProtocolFocus" in dsviewer.elv.evKeyNames:
            dsviewer.zm = piecewiseMapping.GeneratePMFromEventList(
                dsviewer.elv.eventSource,
                image.mdh,
                image.mdh.getEntry("StartTime"),
                image.mdh.getEntry("Protocol.PiezoStartPos"),
            )
            charts.append(("Focus [um]", dsviewer.zm, "ProtocolFocus"))

        if "ScannerXPos" in dsviewer.elv.evKeyNames:
            x0 = 0
            if "Positioning.Stage_X" in image.mdh.getEntryNames():
                x0 = image.mdh.getEntry("Positioning.Stage_X")
            dsviewer.xm = piecewiseMapping.GeneratePMFromEventList(
                dsviewer.elv.eventSource, image.mdh, image.mdh.getEntry("StartTime"), x0, "ScannerXPos", 0
            )
            charts.append(("XPos [um]", dsviewer.xm, "ScannerXPos"))

        if "ScannerYPos" in dsviewer.elv.evKeyNames:
            y0 = 0
            if "Positioning.Stage_Y" in image.mdh.getEntryNames():
                y0 = image.mdh.getEntry("Positioning.Stage_Y")
            dsviewer.ym = piecewiseMapping.GeneratePMFromEventList(
                dsviewer.elv.eventSource, image.mdh, image.mdh.getEntry("StartTime"), y0, "ScannerYPos", 0
            )
            charts.append(("YPos [um]", dsviewer.ym, "ScannerYPos"))

        if "ScannerZPos" in dsviewer.elv.evKeyNames:
            z0 = 0
            if "Positioning.PIFoc" in image.mdh.getEntryNames():
                z0 = image.mdh.getEntry("Positioning.PIFoc")
            dsviewer.zm = piecewiseMapping.GeneratePMFromEventList(
                dsviewer.elv.eventSource, image.mdh, image.mdh.getEntry("StartTime"), z0, "ScannerZPos", 0
            )
            charts.append(("ZPos [um]", dsviewer.zm, "ScannerZPos"))

        dsviewer.elv.SetCharts(charts)

        dsviewer.updateHooks.append(Update)
Beispiel #5
0
    def DoPaint(self, dc):
        dc.Clear()

        hpadding = 10
        barWidth = 20
        tickSize = 5

        lastEvY = 0

        eventTextWidth = 100

        dc.SetFont(wx.NORMAL_FONT)
        textHeight = dc.GetTextExtent("test")[1]

        self.textHeight = textHeight

        frameLabelSize = max(dc.GetTextExtent("%3.4g" % self.frameRange[1])[0], dc.GetTextExtent("N")[0])

        tPerFrame = self.metaData.getEntry("Camera.CycleTime")

        # maxT = tPerFrame*self.frameRange[1]
        maxT = framesToTime(self.frameRange[1], self.eventSource, self.metaData) - self.startTime
        # minT = tPerFrame*self.frameRange[0]
        minT = framesToTime(self.frameRange[0], self.eventSource, self.metaData) - self.startTime

        timeLabelSize = max(dc.GetTextExtent("%3.4g" % maxT)[0], dc.GetTextExtent("[s]" % maxT)[0])

        # labels
        dc.DrawText("N", hpadding + frameLabelSize / 2 - dc.GetTextExtent("N")[0] / 2, 0)
        dc.DrawText(
            "[s]", frameLabelSize + 3 * hpadding + barWidth + timeLabelSize / 2 - dc.GetTextExtent("[s]")[0] / 2, 0
        )

        # dc.SetFont(wx.NORMAL_FONT)
        # bar
        # dc.SetPen(wx.GREEN_PEN)
        dc.SetBrush(wx.MEDIUM_GREY_BRUSH)

        x0 = frameLabelSize + 2 * hpadding
        y0 = 2 * textHeight
        dc.DrawRectangle(x0, y0, barWidth, self.Size[1] - 3 * textHeight)

        if self.frameRange[0] > self.maxRange[0]:
            pl = [(x0 + 2, y0 - 3), (x0 + barWidth / 2, y0 - barWidth / 2 - 1), (x0 + barWidth - 2, y0 - 3)]
            dc.DrawPolygon(pl)

        if self.frameRange[1] < self.maxRange[1]:
            y0 = y0 + self.Size[1] - 3 * textHeight
            pl = [(x0 + 2, y0 + 2), (x0 + barWidth / 2, y0 + barWidth / 2), (x0 + barWidth - 2, y0 + 2)]
            dc.DrawPolygon(pl)

        # ticks
        dc.SetPen(wx.BLACK_PEN)

        ##frame # ticks
        nFrames = self.frameRange[1] - self.frameRange[0]
        pixPerFrame = float(self.Size[1] - 3 * textHeight) / nFrames
        pixPerS = pixPerFrame / tPerFrame

        self.pixPerFrame = pixPerFrame

        nTicksTarget = self.Size[1] / (7.5 * textHeight)
        tickSpacing = nFrames / nTicksTarget
        # round to 1sf
        tickSpacing = round(tickSpacing / (10 ** np.floor(np.log10(tickSpacing)))) * (
            10 ** np.floor(np.log10(tickSpacing))
        )
        tickStart = np.ceil(self.frameRange[0] / tickSpacing) * tickSpacing
        ticks = np.arange(tickStart, self.frameRange[1] + 0.01, tickSpacing)
        tickTimes = framesToTime(ticks, self.eventSource, self.metaData) - self.startTime

        for t, tt in zip(ticks, tickTimes):
            # y = (t -self.frameRange[0])*pixPerFrame + 2*textHeight
            y = (tt - minT) * pixPerS + 2 * textHeight
            dc.DrawText("%3.4g" % t, hpadding, y - 0.5 * textHeight)
            dc.DrawLine(frameLabelSize + 2 * hpadding - tickSize, y, frameLabelSize + 2 * hpadding, y)

        #        #### Time # ticks
        tickSpacingTime = tPerFrame * tickSpacing
        # round to 1sf
        tickSpacingTime = round(tickSpacingTime / (10 ** np.floor(np.log10(tickSpacingTime)))) * (
            10 ** np.floor(np.log10(tickSpacingTime))
        )
        tickStartTime = np.ceil(minT / tickSpacingTime) * tickSpacingTime
        ticks = np.arange(tickStartTime, maxT + 0.0001, tickSpacingTime)
        #
        #        #print minT, maxT, tickSpacingTime
        #
        for t in ticks:
            y = (t - minT) * pixPerS + 2 * textHeight
            dc.DrawText("%2.4g" % t, frameLabelSize + 3 * hpadding + barWidth, y - 0.5 * textHeight)
            dc.DrawLine(
                frameLabelSize + 2 * hpadding + barWidth, y, frameLabelSize + 2 * hpadding + barWidth + tickSize, y
            )

        tTickPositions = (ticks - minT) * pixPerS + 2 * textHeight

        startT = self.metaData.getEntry("StartTime")

        x0 = frameLabelSize + 2 * hpadding
        x1 = x0 + 3 * hpadding + barWidth + timeLabelSize
        x2 = x1 + hpadding
        x3 = x2 + hpadding

        numSkipped = 0

        for e in self.eventSource:
            t = e["Time"] - startT
            if t > minT and t < maxT:
                y = (t - minT) * pixPerS + 2 * textHeight
                dc.SetPen(wx.Pen(self.lineColours[e["EventName"]]))
                dc.SetTextForeground(self.lineColours[e["EventName"]])
                if y < (lastEvY + 2) or (numSkipped > 0 and y < (lastEvY + 1.2 * textHeight)):  # no room - skip
                    if ((tTickPositions - y) ** 2).min() < (0.3 * textHeight) ** 2:
                        dc.DrawLine(x0, y, x0 + barWidth, y)
                        dc.DrawLine(x1 - 2 * hpadding, y, x1 - 2 * (1 + 1 * numSkipped), y)
                    else:
                        dc.DrawLine(x0, y, x1 - 2 * (1 + 1 * numSkipped), y)
                    dc.DrawLine(
                        x1 - 2 * (1 + 1 * numSkipped),
                        y,
                        x1 - 2 * (1 + 1 * numSkipped),
                        lastEvY + 0.5 * textHeight + 1 + 2 * numSkipped,
                    )
                    dc.DrawLine(
                        x1 - 2 * (1 + 1 * numSkipped),
                        lastEvY + 0.5 * textHeight + 1 + 2 * numSkipped,
                        x3 + 200,
                        lastEvY + 0.5 * textHeight + 1 + 2 * numSkipped,
                    )
                    numSkipped += 1
                else:
                    if ((tTickPositions - y) ** 2).min() < (0.3 * textHeight) ** 2:
                        dc.DrawLine(x0, y, x0 + barWidth, y)
                        dc.DrawLine(x1 - 2 * hpadding, y, x1, y)
                    else:
                        dc.DrawLine(x0, y, x1, y)
                    if y < (lastEvY + 1.2 * textHeight):
                        dc.DrawLine(x1, y, x1, lastEvY + 1.2 * textHeight)
                        y = lastEvY + 1.2 * textHeight

                    dc.DrawLine(x1, y, x2, y)
                    eventText = "%6.2fs\t" % t + "%(EventName)s\t%(EventDescr)s" % e

                    etw = dc.GetTextExtent(eventText)[0]

                    etwMax = self.Size[0] - (x3 + 2 * hpadding + 80 * len(self.charts))

                    if etw > etwMax:
                        newLen = int((float(etwMax) / etw) * len(eventText))
                        eventText = eventText[: (newLen - 4)] + " ..."

                    eventTextWidth = max(eventTextWidth, dc.GetTextExtent(eventText)[0])
                    dc.DrawText(eventText, x3, y - 0.5 * textHeight)
                    lastEvY = y
                    numSkipped = 0

        dc.SetTextForeground(wx.BLACK)
        dc.SetPen(wx.BLACK_PEN)

        x4 = x3 + eventTextWidth + 2 * hpadding
        chartWidth = (self.Size[0] - x4) / max(len(self.charts), 1) - 2 * hpadding

        for c in self.charts:
            cname = c[0]
            cmapping = c[1]
            sourceEv = c[2]

            dc.SetTextForeground(self.lineColours[sourceEv])

            dc.DrawText(cname, x4 + chartWidth / 2 - dc.GetTextExtent(cname)[0] / 2, 0)

            xv = np.array(
                [self.frameRange[0]]
                + [x for x in cmapping.xvals if x > self.frameRange[0] and x < self.frameRange[1]]
                + [self.frameRange[1]]
            )
            vv = cmapping(xv)

            vmin = vv.min()
            vmax = vv.max()
            if vmax == vmin:
                vsc = 0
            else:
                vsc = chartWidth / float(vmax - vmin)

            dc.DrawText("%3.2f" % vmin, x4 - dc.GetTextExtent("%3.2f" % vmin)[0] / 2, 1 * textHeight)
            dc.DrawText("%3.2f" % vmax, x4 + chartWidth - dc.GetTextExtent("%3.2f" % vmax)[0] / 2, 1 * textHeight)

            dc.SetPen(wx.BLACK_PEN)
            dc.DrawLine(x4, 2 * textHeight, x4, 2 * textHeight + tickSize)
            dc.DrawLine(x4 + chartWidth, 2 * textHeight, x4 + chartWidth, 2 * textHeight + tickSize)

            # dc.SetPen(wx.Pen(wx.BLUE, 2))
            dc.SetPen(wx.Pen(self.lineColours[sourceEv], 2))

            x_0 = xv[0]
            v_0 = vv[0]

            yp_ = (x_0 - self.frameRange[0]) * pixPerFrame + 2 * textHeight
            xp_ = x4 + (v_0 - vmin) * vsc

            for x, v in zip(xv[1:-1], vv[1:-1]):
                yp = (x - self.frameRange[0]) * pixPerFrame + 2 * textHeight
                xp = x4 + (v - vmin) * vsc
                dc.DrawLine(xp_, yp_, xp_, yp)
                dc.DrawLine(xp_, yp, xp, yp)
                xp_ = xp
                yp_ = yp

            yp = (xv[-1] - self.frameRange[0]) * pixPerFrame + 2 * textHeight
            xp = x4 + (vv[-1] - vmin) * vsc
            dc.DrawLine(xp_, yp_, xp_, yp)

            x4 = x4 + chartWidth + hpadding

        # pm = piecewiseMapping.GeneratePMFromEventList(elv.eventSource, md.Camera.CycleTime*1e-3, md.StartTime, md.Protocol.PiezoStartPos)
        #        if self.dragging == 'upper':
        #            dc.SetPen(wx.Pen(wx.GREEN, 2))
        #        else:
        #            dc.SetPen(wx.Pen(wx.RED, 2))

        dc.SetTextForeground(wx.BLACK)

        dc.SetPen(wx.NullPen)
        dc.SetBrush(wx.NullBrush)
        dc.SetFont(wx.NullFont)
Beispiel #6
0
    def DoPaint(self, dc):
        dc.Clear()

        hpadding = 10
        barWidth = 20
        tickSize = 5

        lastEvY = 0

        eventTextWidth = 100

        dc.SetFont(wx.NORMAL_FONT)
        textHeight = dc.GetTextExtent("test")[1]

        self.textHeight = textHeight

        timeLabelSize = max(dc.GetTextExtent("%3.4g" % self.timeRange[1])[0], dc.GetTextExtent("N")[0])

        # tPerFrame = self.metaData.getEntry('Camera.CycleTime')
        minT, maxT = self.timeRange

        pixPerS = float(self.Size[1] - 3 * textHeight) / (maxT - minT)
        self.pixPerS = pixPerS

        maxF = timeToFrames(maxT + self.startTime, self.eventSource, self.metaData)  # - self.startTime
        minF = timeToFrames(minT + self.startTime, self.eventSource, self.metaData)  # - self.startTime

        # print minF, maxF

        if (maxF < minF) < 30:  # show when camera was actually recording
            fTimes = framesToTime(np.arange(minF, maxF + 0.1), self.eventSource, self.metaData) - self.startTime
            tPerFrame = self.metaData.getEntry("Camera.CycleTime")

            old_pen = dc.GetPen()
            dc.SetPen(wx.TRANSPARENT_PEN)
            dc.SetBrush(wx.TheBrushList.FindOrCreateBrush(wx.Colour(220, 255, 200)))

            for ft in fTimes:
                y0 = (ft - minT) * pixPerS + 2 * textHeight
                bh = tPerFrame * pixPerS

                dc.DrawRectangle(0, y0, self.Size[0], bh)

            dc.SetPen(old_pen)

        frameLabelSize = max(dc.GetTextExtent("%3.4g" % maxF)[0], dc.GetTextExtent("[s]" % maxF)[0])

        # labels
        dc.DrawText("N", hpadding + frameLabelSize / 2 - dc.GetTextExtent("N")[0] / 2, 0)
        dc.DrawText(
            "[s]", frameLabelSize + 3 * hpadding + barWidth + timeLabelSize / 2 - dc.GetTextExtent("[s]")[0] / 2, 0
        )

        dc.SetBrush(wx.MEDIUM_GREY_BRUSH)

        x0 = frameLabelSize + 2 * hpadding
        y0 = 2 * textHeight
        dc.DrawRectangle(x0, y0, barWidth, self.Size[1] - 3 * textHeight)

        if self.timeRange[0] > self.maxRange[0]:
            pl = [(x0 + 2, y0 - 3), (x0 + barWidth / 2, y0 - barWidth / 2 - 1), (x0 + barWidth - 2, y0 - 3)]
            dc.DrawPolygon(pl)

        if self.timeRange[1] < self.maxRange[1]:
            y0 = y0 + self.Size[1] - 3 * textHeight
            pl = [(x0 + 2, y0 + 2), (x0 + barWidth / 2, y0 + barWidth / 2), (x0 + barWidth - 2, y0 + 2)]
            dc.DrawPolygon(pl)

        # ticks
        dc.SetPen(wx.BLACK_PEN)

        ##frame # ticks
        nFrames = maxF - minF

        # pixPerS = pixPerFrame/tPerFrame

        # self.pixPerFrame = pixPerFrame

        nTicksTarget = self.Size[1] / (5.5 * textHeight)
        tickSpacing = np.floor(nFrames / nTicksTarget)
        # round to 1sf
        # tickSpacing = round(tickSpacing/(10**np.floor(np.log10(tickSpacing))))*(10**np.floor(np.log10(tickSpacing)))
        tickStart = np.ceil(minF / tickSpacing) * tickSpacing
        ticks = np.arange(tickStart, maxF + 0.01, tickSpacing)
        tickTimes = framesToTime(ticks, self.eventSource, self.metaData) - self.startTime

        # print minT, maxT,nFrames, nTicksTarget, tickStart, tickSpacing

        for t, tt in zip(ticks, tickTimes):
            # y = (t -self.frameRange[0])*pixPerFrame + 2*textHeight
            y = (tt - minT) * pixPerS + 2 * textHeight
            # print t, hpadding, y - 0.5*textHeight
            dc.DrawText("%3.4g" % t, hpadding, y - 0.5 * textHeight)
            dc.DrawLine(frameLabelSize + 2 * hpadding - tickSize, y, frameLabelSize + 2 * hpadding, y)

        #        #### Time # ticks
        tickSpacingTime = (maxT - minT) / nTicksTarget
        # round to 1sf
        tickSpacingTime = round(tickSpacingTime / (10 ** np.floor(np.log10(tickSpacingTime)))) * (
            10 ** np.floor(np.log10(tickSpacingTime))
        )
        tickStartTime = np.ceil(minT / tickSpacingTime) * tickSpacingTime
        ticks = np.arange(tickStartTime, maxT + 0.0001, tickSpacingTime)
        #
        # print minT, maxT, tickSpacingTime
        #
        for t in ticks:
            y = (t - minT) * pixPerS + 2 * textHeight
            dc.DrawText("%2.4g" % t, frameLabelSize + 3 * hpadding + barWidth, y - 0.5 * textHeight)
            dc.DrawLine(
                frameLabelSize + 2 * hpadding + barWidth, y, frameLabelSize + 2 * hpadding + barWidth + tickSize, y
            )

        tTickPositions = (ticks - minT) * pixPerS + 2 * textHeight

        startT = self.metaData.getEntry("StartTime")

        x0 = frameLabelSize + 2 * hpadding
        x1 = x0 + 3 * hpadding + barWidth + timeLabelSize
        x2 = x1 + hpadding
        x3 = x2 + hpadding

        numSkipped = 0

        evts = self.eventSource[
            (self.eventSource["Time"] > (minT + self.startTime)) * (self.eventSource["Time"] < (maxT + self.startTime))
        ]
        ets = evts["Time"] - self.startTime
        eys = (ets - minT) * pixPerS + 2 * textHeight
        dys = np.hstack([np.diff(eys), [100]])

        # special hack for co-incident events
        for i in range(len(dys)):
            if dys[i] == 0:
                j = i + 1
                while dys[j] == 0:  # find the next non-zero step
                    j += 1

                if dys[j] > 1.2 * textHeight:  # we have room to expand
                    dys[i] += 1.2 * textHeight
                    dys[j] -= 1.2 * textHeight

        lastLineY = 0

        for i, e in enumerate(evts):
            y = eys[i]
            t = ets[i]
            # print y
            dc.SetPen(wx.Pen(self.lineColours[e["EventName"]]))
            dc.SetTextForeground(self.lineColours[e["EventName"]])
            if (y < (lastLineY + 2) or (numSkipped > 0 and y < (lastLineY + 1.2 * textHeight))) and dys[i] < (
                1.2 * textHeight + 2 * numSkipped
            ):  # no room - skip
                if ((tTickPositions - y) ** 2).min() < (0.3 * textHeight) ** 2:
                    dc.DrawLine(x0, y, x0 + barWidth, y)
                    dc.DrawLine(x1 - 2 * hpadding, y, x1 - 2 * (1 + 1 * numSkipped), y)
                else:
                    dc.DrawLine(x0, y, x1 - 2 * (1 + 1 * numSkipped), y)
                dc.DrawLine(
                    x1 - 2 * (1 + 1 * numSkipped),
                    y,
                    x1 - 2 * (1 + 1 * numSkipped),
                    lastEvY + 0.5 * textHeight + 1 + 2 * numSkipped,
                )
                dc.DrawLine(
                    x1 - 2 * (1 + 1 * numSkipped),
                    lastEvY + 0.5 * textHeight + 1 + 2 * numSkipped,
                    x3 + 200,
                    lastEvY + 0.5 * textHeight + 1 + 2 * numSkipped,
                )
                numSkipped += 1
                lastLineY += 2
            else:
                if ((tTickPositions - y) ** 2).min() < (0.3 * textHeight) ** 2:
                    dc.DrawLine(x0, y, x0 + barWidth, y)
                    dc.DrawLine(x1 - 2 * hpadding, y, x1 - 2 * (1 + 1 * numSkipped), y)
                else:
                    dc.DrawLine(x0, y, x1 - 2 * (1 + 1 * numSkipped), y)
                if y < (lastLineY + 1.2 * textHeight):
                    dc.DrawLine(
                        x1 - 2 * (1 + 1 * numSkipped), y, x1 - 2 * (1 + 1 * numSkipped), lastLineY + 1.2 * textHeight
                    )
                    y = lastLineY + 1.2 * textHeight

                dc.DrawLine(x1 - 2 * (1 + 1 * numSkipped), y, x2, y)
                eventText = "%6.2fs\t" % t + "%(EventName)s\t%(EventDescr)s" % e

                etw = dc.GetTextExtent(eventText)[0]

                etwMax = self.Size[0] - (x3 + 2 * hpadding + 80 * len(self.charts))

                if etw > etwMax:
                    newLen = int((float(etwMax) / etw) * len(eventText))
                    eventText = eventText[: (newLen - 4)] + " ..."

                eventTextWidth = max(eventTextWidth, dc.GetTextExtent(eventText)[0])
                dc.DrawText(eventText, x3, y - 0.5 * textHeight)
                lastEvY = y
                lastLineY = y
                numSkipped = 0

        dc.SetTextForeground(wx.BLACK)
        dc.SetPen(wx.BLACK_PEN)

        x4 = x3 + eventTextWidth + 2 * hpadding
        chartWidth = (self.Size[0] - x4) / max(len(self.charts), 1) - 2 * hpadding

        for c in self.charts:
            cname = c[0]
            cmapping = c[1]
            sourceEv = c[2]

            dc.SetTextForeground(self.lineColours[sourceEv])

            dc.DrawText(cname, x4 + chartWidth / 2 - dc.GetTextExtent(cname)[0] / 2, 0)

            xv = np.array([max(minF, 0)] + [x for x in cmapping.xvals if x > minF and x < maxF] + [maxF])
            vv = cmapping(xv)

            vmin = vv.min()
            vmax = vv.max()

            ml = dc.GetTextExtent("%3.2f" % vmin)[0] / 2
            mr = dc.GetTextExtent("%3.2f" % vmax)[0] / 2

            chartWidthInternal = chartWidth - ml - mr

            if vmax == vmin:
                vsc = 0
            else:
                vsc = chartWidthInternal / float(vmax - vmin)

            dc.DrawText("%3.2f" % vmin, x4, 1 * textHeight)
            dc.DrawText("%3.2f" % vmax, x4 + chartWidth - 2 * mr, 1 * textHeight)

            dc.SetPen(wx.BLACK_PEN)
            dc.DrawLine(x4 + ml, 2 * textHeight, x4 + ml, 2 * textHeight + tickSize)
            dc.DrawLine(x4 + chartWidth - mr, 2 * textHeight, x4 + chartWidth - mr, 2 * textHeight + tickSize)

            # dc.SetPen(wx.Pen(wx.BLUE, 2))
            dc.SetPen(wx.Pen(self.lineColours[sourceEv], 2))

            xvt = framesToTime(xv, self.eventSource, self.metaData) - self.startTime

            x_0 = xvt[0]
            v_0 = vv[0]

            yp_ = (x_0 - minT) * pixPerS + 2 * textHeight
            xp_ = x4 + ml + (v_0 - vmin) * vsc

            for x, v in zip(xvt[1:-1], vv[1:-1]):
                yp = (x - minT) * pixPerS + 2 * textHeight
                xp = x4 + ml + (v - vmin) * vsc
                dc.DrawLine(xp_, yp_, xp_, yp)
                dc.DrawLine(xp_, yp, xp, yp)
                xp_ = xp
                yp_ = yp

            yp = (xvt[-1] - minT) * pixPerS + 2 * textHeight
            xp = x4 + ml + (vv[-1] - vmin) * vsc
            dc.DrawLine(xp_, yp_, xp_, yp)

            x4 = x4 + chartWidth + hpadding

        # pm = piecewiseMapping.GeneratePMFromEventList(elv.eventSource, md.Camera.CycleTime*1e-3, md.StartTime, md.Protocol.PiezoStartPos)
        #        if self.dragging == 'upper':
        #            dc.SetPen(wx.Pen(wx.GREEN, 2))
        #        else:
        #            dc.SetPen(wx.Pen(wx.RED, 2))

        dc.SetTextForeground(wx.BLACK)

        dc.SetPen(wx.NullPen)
        dc.SetBrush(wx.NullBrush)
        dc.SetFont(wx.NullFont)
    def DoPaint(self, dc):
        dc.Clear()

        hpadding = 10
        barWidth = 20
        tickSize = 5

        lastEvY = 0

        eventTextWidth = 100
        
        dc.SetFont(wx.NORMAL_FONT)
        textHeight = dc.GetTextExtent('test')[1]

        self.textHeight = textHeight

        frameLabelSize = max(dc.GetTextExtent('%3.4g' % self.frameRange[1])[0], dc.GetTextExtent('N')[0])

        tPerFrame = self.metaData.getEntry('Camera.CycleTime')

        #maxT = tPerFrame*self.frameRange[1]
        maxT = framesToTime(self.frameRange[1], self.eventSource, self.metaData) - self.startTime
        #minT = tPerFrame*self.frameRange[0]
        minT = framesToTime(self.frameRange[0], self.eventSource, self.metaData) - self.startTime

        timeLabelSize = max(dc.GetTextExtent('%3.4g' % maxT)[0], dc.GetTextExtent('[s]' % maxT)[0])

        #labels
        dc.DrawText('N', hpadding + frameLabelSize/2 - dc.GetTextExtent('N')[0]/2, 0)
        dc.DrawText('[s]', frameLabelSize + 3*hpadding + barWidth + timeLabelSize/2 - dc.GetTextExtent('[s]')[0]/2 , 0)

        #dc.SetFont(wx.NORMAL_FONT)
        #bar
        #dc.SetPen(wx.GREEN_PEN)
        dc.SetBrush(wx.MEDIUM_GREY_BRUSH)

        x0 = frameLabelSize + 2*hpadding
        y0 = 2*textHeight
        dc.DrawRectangle(x0, y0, barWidth, self.Size[1] - 3*textHeight)

        if self.frameRange[0] > self.maxRange[0]:
            pl = [(x0 + 2,y0 - 3), (x0 + barWidth/2, y0 - barWidth/2 - 1), (x0 + barWidth - 2, y0 - 3)]
            dc.DrawPolygon(pl)

        if self.frameRange[1] < self.maxRange[1]:
            y0 = y0 + self.Size[1] - 3*textHeight
            pl = [(x0 + 2,y0 + 2), (x0 + barWidth/2, y0 + barWidth/2), (x0 + barWidth - 2, y0 + 2)]
            dc.DrawPolygon(pl)

        #ticks
        dc.SetPen(wx.BLACK_PEN)

        ##frame # ticks
        nFrames = self.frameRange[1] - self.frameRange[0]
        pixPerFrame = float(self.Size[1] - 3*textHeight)/nFrames
        pixPerS = pixPerFrame/tPerFrame

        self.pixPerFrame = pixPerFrame

        nTicksTarget = self.Size[1]/(7.5*textHeight)
        tickSpacing = nFrames/nTicksTarget
        #round to 1sf
        tickSpacing = round(tickSpacing/(10**np.floor(np.log10(tickSpacing))))*(10**np.floor(np.log10(tickSpacing)))
        tickStart = np.ceil(self.frameRange[0]/tickSpacing)*tickSpacing
        ticks = np.arange(tickStart, self.frameRange[1]+.01, tickSpacing)
        tickTimes = framesToTime(ticks, self.eventSource, self.metaData) - self.startTime

        for t, tt in zip(ticks, tickTimes):
            #y = (t -self.frameRange[0])*pixPerFrame + 2*textHeight
            y = (tt -minT)*pixPerS + 2*textHeight
            dc.DrawText('%3.4g' % t, hpadding, y - 0.5*textHeight)
            dc.DrawLine(frameLabelSize + 2*hpadding - tickSize, y, frameLabelSize + 2*hpadding, y)


#        #### Time # ticks
        tickSpacingTime = tPerFrame * tickSpacing
        #round to 1sf
        tickSpacingTime = round(tickSpacingTime/(10**np.floor(np.log10(tickSpacingTime))))*(10**np.floor(np.log10(tickSpacingTime)))
        tickStartTime = np.ceil(minT/tickSpacingTime)*tickSpacingTime
        ticks = np.arange(tickStartTime, maxT+.0001, tickSpacingTime)
#
#        #print minT, maxT, tickSpacingTime
#
        for t in ticks:
            y = (t -minT)*pixPerS + 2*textHeight
            dc.DrawText('%2.4g' % t, frameLabelSize + 3*hpadding + barWidth, y - 0.5*textHeight)
            dc.DrawLine(frameLabelSize + 2*hpadding + barWidth, y, frameLabelSize + 2*hpadding + barWidth + tickSize, y)

        tTickPositions = (ticks -minT)*pixPerS + 2*textHeight


        startT = self.metaData.getEntry('StartTime')

        x0 = frameLabelSize + 2*hpadding
        x1 = x0 + 3*hpadding + barWidth + timeLabelSize
        x2 = x1 + hpadding
        x3 = x2 + hpadding

        numSkipped = 0

        for e in self.eventSource:
            t = e['Time'] - startT
            if t > minT and t < maxT:
                y = (t -minT)*pixPerS + 2*textHeight
                
                dc.SetPen(wx.Pen(self.lineColours[e['EventName']]))
                dc.SetTextForeground(self.lineColours[e['EventName']])
                
                if y < (lastEvY + 2) or (numSkipped > 0 and y < (lastEvY + 1.2*textHeight)): #no room - skip
                    if ((tTickPositions - y)**2).min() < (0.3*textHeight)**2:
                        #line will occlude time text, draw as two segments
                        dc.DrawLine(x0, y, x0 + barWidth, y)
                        dc.DrawLine(x1 - 2*hpadding, y, x1 - 2*(1 + 1*numSkipped), y)
                    else:
                        dc.DrawLine(x0, y, x1 - 2*(1 + 1*numSkipped), y)
                        
                    dc.DrawLine(x1- 2*(1 + 1*numSkipped), y, x1- 2*(1 + 1*numSkipped), lastEvY + 0.5*textHeight + 1 + 2*numSkipped)
                    dc.DrawLine(x1- 2*(1 + 1*numSkipped),lastEvY + 0.5*textHeight + 1 + 2*numSkipped, x3 + 200, lastEvY+ 0.5*textHeight + 1 + 2*numSkipped)
                    numSkipped +=1
                else: #Don't skip - draw nomally
                    if ((tTickPositions - y)**2).min() < (0.3*textHeight)**2:
                        #line will occlude time text, draw as two segments
                        dc.DrawLine(x0, y, x0 + barWidth, y)
                        dc.DrawLine(x1 - 2*hpadding, y, x1, y)
                    else:
                        dc.DrawLine(x0, y, x1, y)
                        
                    if y < (lastEvY + 1.2*textHeight):
                        #label will overlap with previous - move down
                        dc.DrawLine(x1, y, x1, lastEvY + 1.2*textHeight)
                        y = lastEvY + 1.2*textHeight

                    dc.DrawLine(x1, y, x2, y)
                    eventText = '%6.2fs\t' % t + '%(EventName)s\t%(EventDescr)s' % e

                    etw = dc.GetTextExtent(eventText)[0]

                    etwMax = self.Size[0] - (x3 + 2*hpadding + 80*len(self.charts))

                    if etw >  etwMax:
                        newLen = int((float(etwMax)/etw)*len(eventText))
                        eventText = eventText[:(newLen - 4)] + ' ...'

                    eventTextWidth = max(eventTextWidth, dc.GetTextExtent(eventText)[0])
                    dc.DrawText(eventText, x3, y - 0.5*textHeight)
                    lastEvY = y
                    numSkipped = 0

        dc.SetTextForeground(wx.BLACK)
        dc.SetPen(wx.BLACK_PEN)

        
        x4 = x3 + eventTextWidth + 2*hpadding
        chartWidth = (self.Size[0] - x4)/max(len(self.charts), 1) - 2*hpadding

        for c in self.charts:
            cname = c[0]
            cmapping = c[1]
            sourceEv = c[2]

            dc.SetTextForeground(self.lineColours[sourceEv])

            dc.DrawText(cname, x4 + chartWidth/2 - dc.GetTextExtent(cname)[0]/2, 0)

            xv = np.array([self.frameRange[0],] + [x for x in cmapping.xvals if x > self.frameRange[0] and x < self.frameRange[1]] + [self.frameRange[1],])
            vv = cmapping(xv)

            vmin = vv.min()
            vmax = vv.max()
            if vmax == vmin:
                vsc = 0
            else:
                vsc = chartWidth/float(vmax - vmin)

            dc.DrawText('%3.2f'% vmin, x4 - dc.GetTextExtent('%3.2f'% vmin)[0]/2, 1*textHeight)
            dc.DrawText('%3.2f'% vmax, x4 + chartWidth - dc.GetTextExtent('%3.2f'% vmax)[0]/2, 1*textHeight)

            dc.SetPen(wx.BLACK_PEN)
            dc.DrawLine(x4, 2*textHeight, x4, 2*textHeight + tickSize)
            dc.DrawLine(x4 + chartWidth, 2*textHeight, x4 + chartWidth, 2*textHeight + tickSize)
            
            #dc.SetPen(wx.Pen(wx.BLUE, 2))
            dc.SetPen(wx.Pen(self.lineColours[sourceEv],2))

            x_0 = xv[0]
            v_0 = vv[0]

            yp_ = (x_0 -self.frameRange[0])*pixPerFrame + 2*textHeight
            xp_ = x4 + (v_0 - vmin)*vsc

            for x,v in zip(xv[1:-1], vv[1:-1]):
                yp = (x -self.frameRange[0])*pixPerFrame + 2*textHeight
                xp = x4 + (v - vmin)*vsc
                dc.DrawLine(xp_, yp_, xp_, yp)
                dc.DrawLine(xp_, yp, xp, yp)
                xp_ = xp
                yp_ = yp

            yp = (xv[-1] -self.frameRange[0])*pixPerFrame + 2*textHeight
            xp = x4 + (vv[-1] - vmin)*vsc
            dc.DrawLine(xp_, yp_, xp_, yp)

            x4 = x4 + chartWidth + hpadding

                
        #pm = piecewiseMapping.GeneratePMFromEventList(elv.eventSource, md.Camera.CycleTime*1e-3, md.StartTime, md.Protocol.PiezoStartPos)
#        if self.dragging == 'upper':
#            dc.SetPen(wx.Pen(wx.GREEN, 2))
#        else:
#            dc.SetPen(wx.Pen(wx.RED, 2))

        dc.SetTextForeground(wx.BLACK)

        dc.SetPen(wx.NullPen)
        dc.SetBrush(wx.NullBrush)
        dc.SetFont(wx.NullFont)
    def DoPaint(self, dc):
        dc.Clear()

        hpadding = 10
        barWidth = 20
        tickSize = 5

        lastEvY = 0

        eventTextWidth = 100

        dc.SetFont(wx.NORMAL_FONT)
        textHeight = dc.GetTextExtent('test')[1]

        self.textHeight = textHeight

        timeLabelSize = max(dc.GetTextExtent('%3.4g' % self.timeRange[1])[0], dc.GetTextExtent('N')[0])

        #tPerFrame = self.metaData.getEntry('Camera.CycleTime')
        minT, maxT = self.timeRange

        pixPerS = float(self.Size[1] - 3*textHeight)/(maxT - minT)
        self.pixPerS = pixPerS

        maxF = timeToFrames(maxT+ self.startTime, self.eventSource, self.metaData) #- self.startTime
        minF = timeToFrames(minT+ self.startTime, self.eventSource, self.metaData) #- self.startTime

        #print minF, maxF

        if (maxF < minF) < 30: #show when camera was actually recording
            fTimes = framesToTime(np.arange(minF, maxF + .1), self.eventSource, self.metaData) - self.startTime
            tPerFrame = self.metaData.getEntry('Camera.CycleTime')

            old_pen = dc.GetPen()
            dc.SetPen(wx.TRANSPARENT_PEN)
            dc.SetBrush(wx.TheBrushList.FindOrCreateBrush(wx.Colour(220, 255, 200)))

            for ft in fTimes:
                y0 = (ft -minT)*pixPerS + 2*textHeight
                bh = tPerFrame*pixPerS

                dc.DrawRectangle(0, y0, self.Size[0], bh)

            dc.SetPen(old_pen)



        frameLabelSize = max(dc.GetTextExtent('%3.4g' % maxF)[0], dc.GetTextExtent('[s]' % maxF)[0])

        #labels
        dc.DrawText('N', hpadding + frameLabelSize/2 - dc.GetTextExtent('N')[0]/2, 0)
        dc.DrawText('[s]', frameLabelSize + 3*hpadding + barWidth + timeLabelSize/2 - dc.GetTextExtent('[s]')[0]/2 , 0)

        dc.SetBrush(wx.MEDIUM_GREY_BRUSH)

        x0 = frameLabelSize + 2*hpadding
        y0 = 2*textHeight
        dc.DrawRectangle(x0, y0, barWidth, self.Size[1] - 3*textHeight)

        if self.timeRange[0] > self.maxRange[0]:
            pl = [(x0 + 2,y0 - 3), (x0 + barWidth/2, y0 - barWidth/2 - 1), (x0 + barWidth - 2, y0 - 3)]
            dc.DrawPolygon(pl)

        if self.timeRange[1] < self.maxRange[1]:
            y0 = y0 + self.Size[1] - 3*textHeight
            pl = [(x0 + 2,y0 + 2), (x0 + barWidth/2, y0 + barWidth/2), (x0 + barWidth - 2, y0 + 2)]
            dc.DrawPolygon(pl)

        #ticks
        dc.SetPen(wx.BLACK_PEN)

        ##frame # ticks
        nFrames = maxF - minF
        
        #pixPerS = pixPerFrame/tPerFrame

        #self.pixPerFrame = pixPerFrame

        nTicksTarget = self.Size[1]/(5.5*textHeight)
        tickSpacing = max(np.floor(nFrames/nTicksTarget), 1)
        #round to 1sf
        #tickSpacing = round(tickSpacing/(10**np.floor(np.log10(tickSpacing))))*(10**np.floor(np.log10(tickSpacing)))
        tickStart = np.ceil(minF/tickSpacing)*tickSpacing
        #print(tickStart, maxF+.01, tickSpacing)
        ticks = np.arange(tickStart, maxF+.01, tickSpacing)
        tickTimes = framesToTime(ticks, self.eventSource, self.metaData) - self.startTime

        #print minT, maxT,nFrames, nTicksTarget, tickStart, tickSpacing

        for t, tt in zip(ticks, tickTimes):
            #y = (t -self.frameRange[0])*pixPerFrame + 2*textHeight
            y = (tt -minT)*pixPerS + 2*textHeight
            #print t, hpadding, y - 0.5*textHeight
            dc.DrawText('%3.4g' % t, hpadding, y - 0.5*textHeight)
            dc.DrawLine(frameLabelSize + 2*hpadding - tickSize, y, frameLabelSize + 2*hpadding, y)


#        #### Time # ticks
        tickSpacingTime = (maxT - minT)/nTicksTarget
        #round to 1sf
        tickSpacingTime = round(tickSpacingTime/(10**np.floor(np.log10(tickSpacingTime))))*(10**np.floor(np.log10(tickSpacingTime)))
        tickStartTime = np.ceil(minT/tickSpacingTime)*tickSpacingTime
        ticks = np.arange(tickStartTime, maxT+.0001, tickSpacingTime)
#
        #print minT, maxT, tickSpacingTime
#
        for t in ticks:
            y = (t -minT)*pixPerS + 2*textHeight
            dc.DrawText('%2.4g' % t, frameLabelSize + 3*hpadding + barWidth, y - 0.5*textHeight)
            dc.DrawLine(frameLabelSize + 2*hpadding + barWidth, y, frameLabelSize + 2*hpadding + barWidth + tickSize, y)

        tTickPositions = (ticks -minT)*pixPerS + 2*textHeight


        startT = self.metaData.getEntry('StartTime')

        x0 = frameLabelSize + 2*hpadding
        x1 = x0 + 3*hpadding + barWidth + timeLabelSize
        x2 = x1 + hpadding
        x3 = x2 + hpadding

        numSkipped = 0

        evts = self.eventSource[(self.eventSource['Time'] > (minT + self.startTime))*(self.eventSource['Time'] < (maxT + self.startTime))]
        ets = evts['Time'] - self.startTime
        eys = (ets -minT)*pixPerS + 2*textHeight
        dys = np.hstack([np.diff(eys), [100]])

        #special hack for co-incident events
        for i in range(len(dys)):
            if dys[i] == 0:
                j = i+1
                while dys[j] == 0: #find the next non-zero step
                    j += 1

                if dys[j] > 1.2*textHeight: #we have room to expand
                    dys[i] += 1.2*textHeight
                    dys[j] -= 1.2*textHeight

        lastLineY = 0

        for i, e in enumerate(evts):
            y = eys[i]
            t = ets[i]
            #print y
            dc.SetPen(wx.Pen(self.lineColours[e['EventName']]))
            dc.SetTextForeground(self.lineColours[e['EventName']])
            if (y < (lastLineY + 2)  or (numSkipped > 0 and y < (lastLineY + 1.2*textHeight))) and dys[i] < (1.2*textHeight + 2*numSkipped): #no room - skip
                if ((tTickPositions - y)**2).min() < (0.3*textHeight)**2:
                    dc.DrawLine(x0, y, x0 + barWidth, y)
                    dc.DrawLine(x1 - 2*hpadding, y, x1 - 2*(1 + 1*numSkipped), y)
                else:
                    dc.DrawLine(x0, y, x1 - 2*(1 + 1*numSkipped), y)
                dc.DrawLine(x1- 2*(1 + 1*numSkipped), y, x1- 2*(1 + 1*numSkipped), lastEvY + 0.5*textHeight + 1 + 2*numSkipped)
                dc.DrawLine(x1- 2*(1 + 1*numSkipped),lastEvY + 0.5*textHeight + 1 + 2*numSkipped, x3 + 200, lastEvY+ 0.5*textHeight + 1 + 2*numSkipped)
                numSkipped +=1
                lastLineY += 2
            else:
                if ((tTickPositions - y)**2).min() < (0.3*textHeight)**2:
                    dc.DrawLine(x0, y, x0 + barWidth, y)
                    dc.DrawLine(x1 - 2*hpadding, y, x1- 2*(1 + 1*numSkipped), y)
                else:
                    dc.DrawLine(x0, y, x1- 2*(1 + 1*numSkipped), y)
                if y < (lastLineY + 1.2*textHeight):
                    dc.DrawLine(x1- 2*(1 + 1*numSkipped), y, x1- 2*(1 + 1*numSkipped), lastLineY + 1.2*textHeight)
                    y = lastLineY + 1.2*textHeight

                dc.DrawLine(x1- 2*(1 + 1*numSkipped), y, x2, y)
                eventText = '%6.2fs\t' % t + '%(EventName)s\t%(EventDescr)s' % e

                etw = dc.GetTextExtent(eventText)[0]

                etwMax = self.Size[0] - (x3 + 2*hpadding + 80*len(self.charts))

                if etw >  etwMax:
                    newLen = int((float(etwMax)/etw)*len(eventText))
                    eventText = eventText[:(newLen - 4)] + ' ...'

                eventTextWidth = max(eventTextWidth, dc.GetTextExtent(eventText)[0])
                dc.DrawText(eventText, x3, y - 0.5*textHeight)
                lastEvY = y
                lastLineY = y
                numSkipped = 0

        dc.SetTextForeground(wx.BLACK)
        dc.SetPen(wx.BLACK_PEN)


        x4 = x3 + eventTextWidth + 2*hpadding
        chartWidth = (self.Size[0] - x4)/max(len(self.charts), 1) - 2*hpadding

        for c in self.charts:
            cname = c[0]
            cmapping = c[1]
            sourceEv = c[2]

            dc.SetTextForeground(self.lineColours[sourceEv])

            dc.DrawText(cname, x4 + chartWidth/2 - dc.GetTextExtent(cname)[0]/2, 0)

            xv = np.array([max(minF, 0),] + [x for x in cmapping.xvals if x > minF and x < maxF] + [maxF,])
            vv = cmapping(xv)

            vmin = vv.min()
            vmax = vv.max()

            ml = dc.GetTextExtent('%3.2f'% vmin)[0]/2
            mr = dc.GetTextExtent('%3.2f'% vmax)[0]/2

            chartWidthInternal = chartWidth - ml - mr

            if vmax == vmin:
                vsc = 0
            else:
                vsc = chartWidthInternal/float(vmax - vmin)

            

            dc.DrawText('%3.2f'% vmin, x4 , 1*textHeight)
            dc.DrawText('%3.2f'% vmax, x4 + chartWidth - 2*mr, 1*textHeight)

            dc.SetPen(wx.BLACK_PEN)
            dc.DrawLine(x4 + ml, 2*textHeight, x4 + ml, 2*textHeight + tickSize)
            dc.DrawLine(x4 + chartWidth - mr, 2*textHeight, x4 + chartWidth - mr, 2*textHeight + tickSize)

            #dc.SetPen(wx.Pen(wx.BLUE, 2))
            dc.SetPen(wx.Pen(self.lineColours[sourceEv],2))

            xvt = framesToTime(xv, self.eventSource, self.metaData) - self.startTime
            
            #print xv,xvt, vv

            x_0 = xvt[0]
            v_0 = vv[0]

            yp_ = (x_0 -minT)*pixPerS + 2*textHeight
            xp_ = x4  + ml + (v_0 - vmin)*vsc

            for x,v in zip(xvt[1:-1], vv[1:-1]):
                yp = (x -minT)*pixPerS + 2*textHeight
                xp = x4 + ml + (v - vmin)*vsc
                dc.DrawLine(xp_, yp_, xp_, yp)
                dc.DrawLine(xp_, yp, xp, yp)
                xp_ = xp
                yp_ = yp

            yp = (xvt[-1] -minT)*pixPerS + 2*textHeight
            xp = x4 + ml + (vv[-1] - vmin)*vsc
            dc.DrawLine(xp_, yp_, xp_, yp)

            x4 = x4 + chartWidth + hpadding


        #pm = piecewiseMapping.GeneratePMFromEventList(elv.eventSource, md.Camera.CycleTime*1e-3, md.StartTime, md.Protocol.PiezoStartPos)
#        if self.dragging == 'upper':
#            dc.SetPen(wx.Pen(wx.GREEN, 2))
#        else:
#            dc.SetPen(wx.Pen(wx.RED, 2))

        dc.SetTextForeground(wx.BLACK)

        dc.SetPen(wx.NullPen)
        dc.SetBrush(wx.NullBrush)
        dc.SetFont(wx.NullFont)