Example #1
0
    def setupDataDisplay(self, indices=range(1,15)):
        """requires that you have already set a number of things on self"""
        self.indices = indices
        self.displayData = DataProcessing.getDisplayData(self.rawData, self.startTime, self.endTime, self.storedAmplitude, self.lowPass, self.highPass, self.indices)
        self.setupZoom(self.displayData)
        self.channels = self.rawData.ch_names
        self.samplingRate = self.rawData.info['sfreq']
        displayChannels = [self.channels[i] for i in indices]
        displayPositions = np.linspace(0.9,-0.9,len(displayChannels))

        self.annotationTimes = []

        self.positionsToTextMap = {}
        for i in range(0,len(displayPositions)):
            self.positionsToTextMap[(-0.97,displayPositions[i])]=str(displayChannels[i])
        self.program = gloo.Program(SERIES_VERT_SHADER, SERIES_FRAG_SHADER)
        self.vertices = gloo.VertexBuffer(V)
        self.zoomBoxBuffer = gloo.VertexBuffer(V3)
        self.progAnnotations = gloo.Program(progAnnotations_vertex_shader, progAnnotations_fragment_shader)
        self.progAnnotations.bind(self.vertices)

        self.progZoom = gloo.Program(zoombox_vertex_shader, zoombox_fragment_shader)
        self.progZoom.bind(self.zoomBoxBuffer)

        self.setupZoomStep2()

        self.myTextDrawer = TextDrawer(self.physical_size[1],self.physical_size[0])
        self.myLineDrawer = LineDrawer()
        print "height " + str(self.physical_size[1])

        self.progText = gloo.Program(text_vertex_shader, text_fragment_shader)
        self.fontBMP= vispy.io.imread("FixedSys.bmp")
        tvar = np.array(self.fontBMP[:,:,0])
        self.fontBMP=np.dstack((self.fontBMP,tvar))
        self.fontTexture =gloo.Texture2D(self.fontBMP,format="rgba")

        self.textVerticesArr = self.myTextDrawer.computeTextsData(self.positionsToTextMap)
        self.updateLines()

        self.textVertices = gloo.VertexBuffer(self.textVerticesArr)
        self.progText.bind(self.textVertices)
        self.progText["myTextureSampler"] = self.fontTexture

        gloo.set_viewport(0, 0, *self.physical_size)
        self.updateTextBoxes()

        self.dragZoom = False
        self.oldPos = None
        self.newPos = None
        self.orig = None
        self.new = None
        self.posDiff = None
        self.events.mouse_press.connect((self, 'mouse_press'))
        self.events.mouse_release.connect((self, 'mouse_release'))
        self.events.mouse_move.connect((self, 'on_mouse_move'))

#      self._timer = app.Timer('auto', connect=self.on_timer, start=True)

        gloo.set_state(clear_color='black', blend=True,
                       blend_func=('src_alpha', 'one_minus_src_alpha'))
        self.update()
Example #2
0
    def setupDataDisplay(self, indices=range(1, 15)):
        """requires that you have already set a number of things on self"""
        self.indices = indices
        self.displayData = DataProcessing.getDisplayData(
            self.rawData, self.startTime, self.endTime, self.storedAmplitude,
            self.lowPass, self.highPass, self.indices)
        self.setupZoom(self.displayData)
        self.channels = self.rawData.ch_names
        self.samplingRate = self.rawData.info['sfreq']
        displayChannels = [self.channels[i] for i in indices]
        displayPositions = np.linspace(0.9, -0.9, len(displayChannels))

        self.annotationTimes = []

        self.positionsToTextMap = {}
        for i in range(0, len(displayPositions)):
            self.positionsToTextMap[(-0.97, displayPositions[i])] = str(
                displayChannels[i])
        self.program = gloo.Program(SERIES_VERT_SHADER, SERIES_FRAG_SHADER)
        self.vertices = gloo.VertexBuffer(V)
        self.zoomBoxBuffer = gloo.VertexBuffer(V3)
        self.progAnnotations = gloo.Program(progAnnotations_vertex_shader,
                                            progAnnotations_fragment_shader)
        self.progAnnotations.bind(self.vertices)

        self.progZoom = gloo.Program(zoombox_vertex_shader,
                                     zoombox_fragment_shader)
        self.progZoom.bind(self.zoomBoxBuffer)

        self.setupZoomStep2()

        self.myTextDrawer = TextDrawer(self.physical_size[1],
                                       self.physical_size[0])
        self.myLineDrawer = LineDrawer()
        print "height " + str(self.physical_size[1])

        self.progText = gloo.Program(text_vertex_shader, text_fragment_shader)
        self.fontBMP = vispy.io.imread("FixedSys.bmp")
        tvar = np.array(self.fontBMP[:, :, 0])
        self.fontBMP = np.dstack((self.fontBMP, tvar))
        self.fontTexture = gloo.Texture2D(self.fontBMP, format="rgba")

        self.textVerticesArr = self.myTextDrawer.computeTextsData(
            self.positionsToTextMap)
        self.updateLines()

        self.textVertices = gloo.VertexBuffer(self.textVerticesArr)
        self.progText.bind(self.textVertices)
        self.progText["myTextureSampler"] = self.fontTexture

        gloo.set_viewport(0, 0, *self.physical_size)
        self.updateTextBoxes()

        self.dragZoom = False
        self.oldPos = None
        self.newPos = None
        self.orig = None
        self.new = None
        self.posDiff = None
        self.events.mouse_press.connect((self, 'mouse_press'))
        self.events.mouse_release.connect((self, 'mouse_release'))
        self.events.mouse_move.connect((self, 'on_mouse_move'))

        #      self._timer = app.Timer('auto', connect=self.on_timer, start=True)

        gloo.set_state(clear_color='black',
                       blend=True,
                       blend_func=('src_alpha', 'one_minus_src_alpha'))
        self.update()
Example #3
0
class EEGCanvas(app.Canvas):
    """ defines a class which encapsulates all information and control relating to the display of EEG data on the canvas

   """
    myTextDrawer = None
    myLineDrawer = None
    rawData= None
    displayData = None
    rawData = None
    startTime = None
    endTime = None
    parentScroller = None
    indices = range(1, 15)
    annotationTimes = []

    def getDisplayWidth(self):
        if(self.endTime):
            return self.startTime
        else:
            return 0

    def getTotalWidth(self):
        if(self.rawData):
            return self.rawData.times[-1]
        else:
            return 0

    def __init__(self, startEdit, endEdit, lowEdit, highEdit):
        app.Canvas.__init__(self, title='Use your wheel to scroll!',
                            keys='interactive')
        self.startEdit = startEdit
        self.endEdit = endEdit
        self.lowEdit = lowEdit
        self.highEdit = highEdit
        self.startTime = START_TIME
        self.endTime = END_TIME
        self.storedAmplitude = 1.0
        self.lowPass = 2.0
        self.highPass = 70.0

        self.channelPositions = self.getChannelPositions()
        self.mode = 'select'
        self.xScale = 1.
        self.yScale = 1.
        self.min_scale = 0.00005
        self.max_scale = 10
        self.dragZoom = False
        self.show()

    def setupDataDisplay(self, indices=range(1,15)):
        """requires that you have already set a number of things on self"""
        self.indices = indices
        self.displayData = DataProcessing.getDisplayData(self.rawData, self.startTime, self.endTime, self.storedAmplitude, self.lowPass, self.highPass, self.indices)
        self.setupZoom(self.displayData)
        self.channels = self.rawData.ch_names
        self.samplingRate = self.rawData.info['sfreq']
        displayChannels = [self.channels[i] for i in indices]
        displayPositions = np.linspace(0.9,-0.9,len(displayChannels))

        self.annotationTimes = []

        self.positionsToTextMap = {}
        for i in range(0,len(displayPositions)):
            self.positionsToTextMap[(-0.97,displayPositions[i])]=str(displayChannels[i])
        self.program = gloo.Program(SERIES_VERT_SHADER, SERIES_FRAG_SHADER)
        self.vertices = gloo.VertexBuffer(V)
        self.zoomBoxBuffer = gloo.VertexBuffer(V3)
        self.progAnnotations = gloo.Program(progAnnotations_vertex_shader, progAnnotations_fragment_shader)
        self.progAnnotations.bind(self.vertices)

        self.progZoom = gloo.Program(zoombox_vertex_shader, zoombox_fragment_shader)
        self.progZoom.bind(self.zoomBoxBuffer)

        self.setupZoomStep2()

        self.myTextDrawer = TextDrawer(self.physical_size[1],self.physical_size[0])
        self.myLineDrawer = LineDrawer()
        print "height " + str(self.physical_size[1])

        self.progText = gloo.Program(text_vertex_shader, text_fragment_shader)
        self.fontBMP= vispy.io.imread("FixedSys.bmp")
        tvar = np.array(self.fontBMP[:,:,0])
        self.fontBMP=np.dstack((self.fontBMP,tvar))
        self.fontTexture =gloo.Texture2D(self.fontBMP,format="rgba")

        self.textVerticesArr = self.myTextDrawer.computeTextsData(self.positionsToTextMap)
        self.updateLines()

        self.textVertices = gloo.VertexBuffer(self.textVerticesArr)
        self.progText.bind(self.textVertices)
        self.progText["myTextureSampler"] = self.fontTexture

        gloo.set_viewport(0, 0, *self.physical_size)
        self.updateTextBoxes()

        self.dragZoom = False
        self.oldPos = None
        self.newPos = None
        self.orig = None
        self.new = None
        self.posDiff = None
        self.events.mouse_press.connect((self, 'mouse_press'))
        self.events.mouse_release.connect((self, 'mouse_release'))
        self.events.mouse_move.connect((self, 'on_mouse_move'))

#      self._timer = app.Timer('auto', connect=self.on_timer, start=True)

        gloo.set_state(clear_color='black', blend=True,
                       blend_func=('src_alpha', 'one_minus_src_alpha'))
        self.update()

    def updateLines(self):
        self.lineVerticesArr = self.myLineDrawer.computeLinesData(self.annotationTimes,self.startTime,self.endTime)
        self.lineVertices = gloo.VertexBuffer(self.lineVerticesArr)
        self.progAnnotations.bind(self.lineVertices)

    def loadData(self,filepath):
        self.dSetName = filepath.split("/")[-1]
        self.rawData = mne.io.read_raw_edf(str(filepath),preload=True)
        self.setupDataDisplay()
        self.parentScroller.resetScrollBarStuff()

    def setupZoom(self,displayData):
        """ this function should be called whenever a "zoom" operation is performed"""
        # Number of cols and rows in the table.
        self.nrows = len(displayData[0])
        self.ncols = 1

        # Number of signals.
        self.numSignals = self.nrows*self.ncols

        # Number of samples per signal.
        self.samplesPerSignal = len(displayData[1])

        # Generate the signals as a (m, n) array.
        #y = amplitudes * np.random.randn(m, n).astype(np.float32)
        self.signalData = np.float32(10000*np.array(displayData[0]))

        # Color of each vertex (TODO: make it more efficient by using a GLSL-based
        # color map and the index).
        self.color = np.repeat(np.random.uniform(size=(self.numSignals, 3), low=.5, high=.9),
                        self.samplesPerSignal, axis=0).astype(np.float32)

        # Signal 2D index of each vertex (row and col) and x-index (sample index
        # within each signal).
        self.index = np.c_[np.repeat(np.repeat(np.arange(self.ncols), self.nrows), self.samplesPerSignal),
                    np.repeat(np.tile(np.arange(self.nrows), self.ncols), self.samplesPerSignal),
                    np.tile(np.arange(self.samplesPerSignal), self.numSignals)].astype(np.float32)


    def setupZoomStep2(self):
        #print "y: {y}, color: {c}, index: {i}".format(y=y.shape,c=color.shape,i=index.shape)
        self.program['a_position'] = self.signalData.reshape(-1, 1)
        self.program['a_color'] = self.color
        self.program['a_index'] = self.index
        self.program['u_scale'] = (1., 1.)
        self.program['u_size'] = (self.nrows, self.ncols)
        self.program['u_n'] = self.samplesPerSignal
        #print "done with setup zoom"


    def getChannelPositions(self):
        """
        TODO:
        self.program['u_size'][0] / self.physical_size[1]

        This will get the amount of vertical space each channel
        has. This gives us a way to determine which spaces are
        selected in order to zoom.
        """

    def setMode(self, mode):
        self.mode = mode

        #[CB] this function does nothing
    def zoom(self, xFactor, yFactor):
        # gloo.set_viewport(orig[0], orig[1], size[0], size[1])
        # self.program['resolution'] = [size[0], size[1]]
        self.xScale *= xFactor
        self.yScale *= yFactor
        self.xScale = max(min(self.xScale, self.max_scale), self.min_scale)
        self.yScale = max(min(self.yScale, self.max_scale), self.min_scale)
        self.program["u_scale"] = (self.xScale, self.yScale)

        print " "

    def on_resize(self, event):
        print "in on resize {e}".format(e=event)
        if (self.myTextDrawer):
            self.myTextDrawer.onChangeDimensions(event.physical_size[1],event.physical_size[0])
            self.textVerticesArr = self.myTextDrawer.computeTextsData(self.positionsToTextMap)
            self.textVertices = gloo.VertexBuffer(self.textVerticesArr)
            self.progText.bind(self.textVertices)
        gloo.set_viewport(0, 0, *event.physical_size)

    def quickTextDraw(self,text,x,y):
        self.positionsToTextMap[(x,y)]=text
        self.textVerticesArr = self.myTextDrawer.computeTextsData(self.positionsToTextMap)
        self.textVertices = gloo.VertexBuffer(self.textVerticesArr)
        self.progText.bind(self.textVertices)

    # def on_mouse_wheel(self, event):
    #     dx = np.sign(event.delta[1]) * .05
    #     scale_x, scale_y = self.program['u_scale']
    #     #print("scale_x: {scale_x}, scale_y: {scale_y}".format(scale_x=scale_x, scale_y=scale_y))
    #     scale_x_new, scale_y_new = (scale_x * math.exp(2.5*dx),
    #                                 scale_y * math.exp(0.0*dx))
    #     self.program['u_scale'] = (max(1, scale_x_new), max(1, scale_y_new))
    #     self.update()
    def handle_scroll(self, fdx):
        dx = -fdx#-np.sign(event.delta[1])
        if((self.startTime + dx) > 0.5):
            self.startTime += dx
            self.endTime += dx
        elif ((self.startTime+dx) >= 0.0): #CB handle edge cases as we get close to beginning of dataset
            self.startTime += dx
            self.endTime += dx
        olen=len(self.displayData[0][0])
        self.displayData = DataProcessing.getDisplayData(self.rawData, self.startTime, self.endTime, self.storedAmplitude, self.lowPass, self.highPass,self.indices)
        if(len(self.displayData[0][0]) != olen):
            self.onStartEndChanged(self.startTime,self.endTime)
        self.signalData = np.float32(10000*np.array(self.displayData[0]))
        self.program['a_position'] = self.signalData.reshape(-1, 1)
        self.updateTextBoxes()
        self.updateLines()
        self.update()

    def onAmplitudeChanged(self, nAmplitude):
        self.storedAmplitude = nAmplitude;
        if(self.rawData):
            self.displayData = DataProcessing.getDisplayData(self.rawData, self.startTime, self.endTime, self.storedAmplitude, self.lowPass, self.highPass,self.indices)
            self.signalData = np.float32(10000*np.array(self.displayData[0]))
            self.program['a_position'] = self.signalData.reshape(-1, 1)
            self.update()

    def onTextBoxesChanged(self, lowPass, highPass):
        self.lowPass = lowPass;
        self.highPass = highPass;
        print "startTime: {s}, endTime: {e}, lowPass: {l}, highPass: {h}".format(s=self.startTime, e=self.endTime, l=self.lowPass, h=self.highPass)
        self.displayData = DataProcessing.getDisplayData(self.rawData, self.startTime, self.endTime, self.storedAmplitude, self.lowPass, self.highPass,self.indices)
        self.signalData = np.float32(10000*np.array(self.displayData[0]))
        self.program['a_position'] = self.signalData.reshape(-1, 1)
        self.update()

    def onStartEndChanged(self, startTime, endTime):
        self.startTime = startTime;
        self.endTime = endTime;
        self.displayData = DataProcessing.getDisplayData(self.rawData, self.startTime, self.endTime, self.storedAmplitude, self.lowPass, self.highPass,self.indices)
        self.setupZoom(self.displayData)
        # self.program.delete()
        # self.program = gloo.Program(SERIES_VERT_SHADER, SERIES_FRAG_SHADER)
        self.setupZoomStep2()
        self.updateLines()
        self.update()

    def updateTextBoxes(self):
        #print "self.startTime: {s}".format(s=self.startTime)
        self.startEdit.setText(str(self.startTime))
        self.endEdit.setText(str(self.endTime))
        self.lowEdit.setText(str(self.lowPass))
        self.highEdit.setText(str(self.highPass))

    def mouse_press(self, event):
        self.oldPos = (float(event.pos[0])/self.size[0]*2-1, -((float(event.pos[1])/self.size[1])*2-1))
        self.orig = (event.pos[0], event.pos[1])
        if(self.mode == 'zoom'):
            self.dragZoom = True

        self.update()

    def on_mouse_move(self, event):
        #print "self.size {s}".format(s=self.size)
        self.newPos = ((float(event.pos[0])/self.size[0])*2-1, -((float(event.pos[1])/self.size[1])*2-1))
        self.new = (event.pos[0], event.pos[1])
        self.update()

    def mouse_release(self, event):
        ## Uncomment to work on zoom
        # if(self.mode == 'zoom'):
        #     xDiff = self.new[0]-self.orig[0]
        #     yDiff = self.new[1]-self.orig[1]
        #     xFactor = 1. / (float(abs(xDiff)) / float(self.physical_size[0]))
        #     yFactor = 1. / (float(abs(yDiff)) / float(self.physical_size[1]))
        #     self.zoom(xFactor, yFactor)
        self.dragZoom = False
        self.update()
        #print self.program['u_size'][0]
        #print self.physical_size[1] #height

    # def on_timer(self, event):
    #     """Add some data at the end of each signal (real-time signals)."""
    #     k = 10
    #     y[:, :-k] = y[:, k:]
    #     y[:, -k:] = amplitudes * np.random.randn(m, k)

    #     self.program['a_position'].set_data(y.ravel().astype(np.float32))

    #     self.update()

    def on_draw(self, event):
        gloo.clear("black")

        if (self.dragZoom and self.mode == 'zoom'):
            xDiff = self.newPos[0]-self.oldPos[0]
            yDiff = self.newPos[1]-self.oldPos[1]
            V4 = np.zeros(6, [("position", np.float32, 3)])
            V4["position"] = np.float32([[self.oldPos[0],self.oldPos[1],0],
                                                           [self.oldPos[0]+xDiff,self.oldPos[1],0],
                                                           [self.oldPos[0],self.oldPos[1]+yDiff,0],
                                                           [self.newPos[0],self.newPos[1],0],
                                                           [self.newPos[0]-xDiff,self.newPos[1],0],
                                                           [self.newPos[0],self.newPos[1]-yDiff,0]])
            self.zoomBoxBuffer.set_data(V4)
            self.progZoom.draw("triangles")
        else:
             V2 = np.zeros(6, [("position", np.float32, 3)])
             V2["position"] = np.float32((np.random.rand(6,3)*2-1))
             self.vertices.set_data(V2)
        self.progAnnotations.draw('lines')
        self.program.draw('line_strip')
        self.progText.draw("triangles")
Example #4
0
class EEGCanvas(app.Canvas):
    """ defines a class which encapsulates all information and control relating to the display of EEG data on the canvas

   """
    myTextDrawer = None
    myLineDrawer = None
    rawData = None
    displayData = None
    rawData = None
    startTime = None
    endTime = None
    parentScroller = None
    indices = range(1, 15)
    annotationTimes = []

    def getDisplayWidth(self):
        if (self.endTime):
            return self.startTime
        else:
            return 0

    def getTotalWidth(self):
        if (self.rawData):
            return self.rawData.times[-1]
        else:
            return 0

    def __init__(self, startEdit, endEdit, lowEdit, highEdit):
        app.Canvas.__init__(self,
                            title='Use your wheel to scroll!',
                            keys='interactive')
        self.startEdit = startEdit
        self.endEdit = endEdit
        self.lowEdit = lowEdit
        self.highEdit = highEdit
        self.startTime = START_TIME
        self.endTime = END_TIME
        self.storedAmplitude = 1.0
        self.lowPass = 2.0
        self.highPass = 70.0

        self.channelPositions = self.getChannelPositions()
        self.mode = 'select'
        self.xScale = 1.
        self.yScale = 1.
        self.min_scale = 0.00005
        self.max_scale = 10
        self.dragZoom = False
        self.show()

    def setupDataDisplay(self, indices=range(1, 15)):
        """requires that you have already set a number of things on self"""
        self.indices = indices
        self.displayData = DataProcessing.getDisplayData(
            self.rawData, self.startTime, self.endTime, self.storedAmplitude,
            self.lowPass, self.highPass, self.indices)
        self.setupZoom(self.displayData)
        self.channels = self.rawData.ch_names
        self.samplingRate = self.rawData.info['sfreq']
        displayChannels = [self.channels[i] for i in indices]
        displayPositions = np.linspace(0.9, -0.9, len(displayChannels))

        self.annotationTimes = []

        self.positionsToTextMap = {}
        for i in range(0, len(displayPositions)):
            self.positionsToTextMap[(-0.97, displayPositions[i])] = str(
                displayChannels[i])
        self.program = gloo.Program(SERIES_VERT_SHADER, SERIES_FRAG_SHADER)
        self.vertices = gloo.VertexBuffer(V)
        self.zoomBoxBuffer = gloo.VertexBuffer(V3)
        self.progAnnotations = gloo.Program(progAnnotations_vertex_shader,
                                            progAnnotations_fragment_shader)
        self.progAnnotations.bind(self.vertices)

        self.progZoom = gloo.Program(zoombox_vertex_shader,
                                     zoombox_fragment_shader)
        self.progZoom.bind(self.zoomBoxBuffer)

        self.setupZoomStep2()

        self.myTextDrawer = TextDrawer(self.physical_size[1],
                                       self.physical_size[0])
        self.myLineDrawer = LineDrawer()
        print "height " + str(self.physical_size[1])

        self.progText = gloo.Program(text_vertex_shader, text_fragment_shader)
        self.fontBMP = vispy.io.imread("FixedSys.bmp")
        tvar = np.array(self.fontBMP[:, :, 0])
        self.fontBMP = np.dstack((self.fontBMP, tvar))
        self.fontTexture = gloo.Texture2D(self.fontBMP, format="rgba")

        self.textVerticesArr = self.myTextDrawer.computeTextsData(
            self.positionsToTextMap)
        self.updateLines()

        self.textVertices = gloo.VertexBuffer(self.textVerticesArr)
        self.progText.bind(self.textVertices)
        self.progText["myTextureSampler"] = self.fontTexture

        gloo.set_viewport(0, 0, *self.physical_size)
        self.updateTextBoxes()

        self.dragZoom = False
        self.oldPos = None
        self.newPos = None
        self.orig = None
        self.new = None
        self.posDiff = None
        self.events.mouse_press.connect((self, 'mouse_press'))
        self.events.mouse_release.connect((self, 'mouse_release'))
        self.events.mouse_move.connect((self, 'on_mouse_move'))

        #      self._timer = app.Timer('auto', connect=self.on_timer, start=True)

        gloo.set_state(clear_color='black',
                       blend=True,
                       blend_func=('src_alpha', 'one_minus_src_alpha'))
        self.update()

    def updateLines(self):
        self.lineVerticesArr = self.myLineDrawer.computeLinesData(
            self.annotationTimes, self.startTime, self.endTime)
        self.lineVertices = gloo.VertexBuffer(self.lineVerticesArr)
        self.progAnnotations.bind(self.lineVertices)

    def loadData(self, filepath):
        self.dSetName = filepath.split("/")[-1]
        self.rawData = mne.io.read_raw_edf(str(filepath), preload=True)
        self.setupDataDisplay()
        self.parentScroller.resetScrollBarStuff()

    def setupZoom(self, displayData):
        """ this function should be called whenever a "zoom" operation is performed"""
        # Number of cols and rows in the table.
        self.nrows = len(displayData[0])
        self.ncols = 1

        # Number of signals.
        self.numSignals = self.nrows * self.ncols

        # Number of samples per signal.
        self.samplesPerSignal = len(displayData[1])

        # Generate the signals as a (m, n) array.
        #y = amplitudes * np.random.randn(m, n).astype(np.float32)
        self.signalData = np.float32(10000 * np.array(displayData[0]))

        # Color of each vertex (TODO: make it more efficient by using a GLSL-based
        # color map and the index).
        self.color = np.repeat(np.random.uniform(size=(self.numSignals, 3),
                                                 low=.5,
                                                 high=.9),
                               self.samplesPerSignal,
                               axis=0).astype(np.float32)

        # Signal 2D index of each vertex (row and col) and x-index (sample index
        # within each signal).
        self.index = np.c_[
            np.repeat(np.repeat(np.arange(self.ncols), self.nrows), self.
                      samplesPerSignal),
            np.repeat(np.tile(np.arange(self.nrows), self.ncols), self.
                      samplesPerSignal),
            np.tile(np.arange(self.samplesPerSignal), self.numSignals)].astype(
                np.float32)

    def setupZoomStep2(self):
        #print "y: {y}, color: {c}, index: {i}".format(y=y.shape,c=color.shape,i=index.shape)
        self.program['a_position'] = self.signalData.reshape(-1, 1)
        self.program['a_color'] = self.color
        self.program['a_index'] = self.index
        self.program['u_scale'] = (1., 1.)
        self.program['u_size'] = (self.nrows, self.ncols)
        self.program['u_n'] = self.samplesPerSignal
        #print "done with setup zoom"

    def getChannelPositions(self):
        """
        TODO:
        self.program['u_size'][0] / self.physical_size[1]

        This will get the amount of vertical space each channel
        has. This gives us a way to determine which spaces are
        selected in order to zoom.
        """

    def setMode(self, mode):
        self.mode = mode

        #[CB] this function does nothing
    def zoom(self, xFactor, yFactor):
        # gloo.set_viewport(orig[0], orig[1], size[0], size[1])
        # self.program['resolution'] = [size[0], size[1]]
        self.xScale *= xFactor
        self.yScale *= yFactor
        self.xScale = max(min(self.xScale, self.max_scale), self.min_scale)
        self.yScale = max(min(self.yScale, self.max_scale), self.min_scale)
        self.program["u_scale"] = (self.xScale, self.yScale)

        print " "

    def on_resize(self, event):
        print "in on resize {e}".format(e=event)
        if (self.myTextDrawer):
            self.myTextDrawer.onChangeDimensions(event.physical_size[1],
                                                 event.physical_size[0])
            self.textVerticesArr = self.myTextDrawer.computeTextsData(
                self.positionsToTextMap)
            self.textVertices = gloo.VertexBuffer(self.textVerticesArr)
            self.progText.bind(self.textVertices)
        gloo.set_viewport(0, 0, *event.physical_size)

    def quickTextDraw(self, text, x, y):
        self.positionsToTextMap[(x, y)] = text
        self.textVerticesArr = self.myTextDrawer.computeTextsData(
            self.positionsToTextMap)
        self.textVertices = gloo.VertexBuffer(self.textVerticesArr)
        self.progText.bind(self.textVertices)

    # def on_mouse_wheel(self, event):
    #     dx = np.sign(event.delta[1]) * .05
    #     scale_x, scale_y = self.program['u_scale']
    #     #print("scale_x: {scale_x}, scale_y: {scale_y}".format(scale_x=scale_x, scale_y=scale_y))
    #     scale_x_new, scale_y_new = (scale_x * math.exp(2.5*dx),
    #                                 scale_y * math.exp(0.0*dx))
    #     self.program['u_scale'] = (max(1, scale_x_new), max(1, scale_y_new))
    #     self.update()
    def handle_scroll(self, fdx):
        dx = -fdx  #-np.sign(event.delta[1])
        if ((self.startTime + dx) > 0.5):
            self.startTime += dx
            self.endTime += dx
        elif ((self.startTime + dx) >= 0.0
              ):  #CB handle edge cases as we get close to beginning of dataset
            self.startTime += dx
            self.endTime += dx
        olen = len(self.displayData[0][0])
        self.displayData = DataProcessing.getDisplayData(
            self.rawData, self.startTime, self.endTime, self.storedAmplitude,
            self.lowPass, self.highPass, self.indices)
        if (len(self.displayData[0][0]) != olen):
            self.onStartEndChanged(self.startTime, self.endTime)
        self.signalData = np.float32(10000 * np.array(self.displayData[0]))
        self.program['a_position'] = self.signalData.reshape(-1, 1)
        self.updateTextBoxes()
        self.updateLines()
        self.update()

    def onAmplitudeChanged(self, nAmplitude):
        self.storedAmplitude = nAmplitude
        if (self.rawData):
            self.displayData = DataProcessing.getDisplayData(
                self.rawData, self.startTime, self.endTime,
                self.storedAmplitude, self.lowPass, self.highPass,
                self.indices)
            self.signalData = np.float32(10000 * np.array(self.displayData[0]))
            self.program['a_position'] = self.signalData.reshape(-1, 1)
            self.update()

    def onTextBoxesChanged(self, lowPass, highPass):
        self.lowPass = lowPass
        self.highPass = highPass
        print "startTime: {s}, endTime: {e}, lowPass: {l}, highPass: {h}".format(
            s=self.startTime, e=self.endTime, l=self.lowPass, h=self.highPass)
        self.displayData = DataProcessing.getDisplayData(
            self.rawData, self.startTime, self.endTime, self.storedAmplitude,
            self.lowPass, self.highPass, self.indices)
        self.signalData = np.float32(10000 * np.array(self.displayData[0]))
        self.program['a_position'] = self.signalData.reshape(-1, 1)
        self.update()

    def onStartEndChanged(self, startTime, endTime):
        self.startTime = startTime
        self.endTime = endTime
        self.displayData = DataProcessing.getDisplayData(
            self.rawData, self.startTime, self.endTime, self.storedAmplitude,
            self.lowPass, self.highPass, self.indices)
        self.setupZoom(self.displayData)
        # self.program.delete()
        # self.program = gloo.Program(SERIES_VERT_SHADER, SERIES_FRAG_SHADER)
        self.setupZoomStep2()
        self.updateLines()
        self.update()

    def updateTextBoxes(self):
        #print "self.startTime: {s}".format(s=self.startTime)
        self.startEdit.setText(str(self.startTime))
        self.endEdit.setText(str(self.endTime))
        self.lowEdit.setText(str(self.lowPass))
        self.highEdit.setText(str(self.highPass))

    def mouse_press(self, event):
        self.oldPos = (float(event.pos[0]) / self.size[0] * 2 - 1,
                       -((float(event.pos[1]) / self.size[1]) * 2 - 1))
        self.orig = (event.pos[0], event.pos[1])
        if (self.mode == 'zoom'):
            self.dragZoom = True

        self.update()

    def on_mouse_move(self, event):
        #print "self.size {s}".format(s=self.size)
        self.newPos = ((float(event.pos[0]) / self.size[0]) * 2 - 1,
                       -((float(event.pos[1]) / self.size[1]) * 2 - 1))
        self.new = (event.pos[0], event.pos[1])
        self.update()

    def mouse_release(self, event):
        ## Uncomment to work on zoom
        # if(self.mode == 'zoom'):
        #     xDiff = self.new[0]-self.orig[0]
        #     yDiff = self.new[1]-self.orig[1]
        #     xFactor = 1. / (float(abs(xDiff)) / float(self.physical_size[0]))
        #     yFactor = 1. / (float(abs(yDiff)) / float(self.physical_size[1]))
        #     self.zoom(xFactor, yFactor)
        self.dragZoom = False
        self.update()
        #print self.program['u_size'][0]
        #print self.physical_size[1] #height

    # def on_timer(self, event):
    #     """Add some data at the end of each signal (real-time signals)."""
    #     k = 10
    #     y[:, :-k] = y[:, k:]
    #     y[:, -k:] = amplitudes * np.random.randn(m, k)

    #     self.program['a_position'].set_data(y.ravel().astype(np.float32))

    #     self.update()

    def on_draw(self, event):
        gloo.clear("black")

        if (self.dragZoom and self.mode == 'zoom'):
            xDiff = self.newPos[0] - self.oldPos[0]
            yDiff = self.newPos[1] - self.oldPos[1]
            V4 = np.zeros(6, [("position", np.float32, 3)])
            V4["position"] = np.float32(
                [[self.oldPos[0], self.oldPos[1], 0],
                 [self.oldPos[0] + xDiff, self.oldPos[1], 0],
                 [self.oldPos[0], self.oldPos[1] + yDiff, 0],
                 [self.newPos[0], self.newPos[1], 0],
                 [self.newPos[0] - xDiff, self.newPos[1], 0],
                 [self.newPos[0], self.newPos[1] - yDiff, 0]])
            self.zoomBoxBuffer.set_data(V4)
            self.progZoom.draw("triangles")
        else:
            V2 = np.zeros(6, [("position", np.float32, 3)])
            V2["position"] = np.float32((np.random.rand(6, 3) * 2 - 1))
            self.vertices.set_data(V2)
        self.progAnnotations.draw('lines')
        self.program.draw('line_strip')
        self.progText.draw("triangles")