示例#1
0
    def __init__(self, **kwargs):
        """Init."""
        # Create the main window :
        super(UiInit, self).__init__(None)
        self.setupUi(self)

        # Cameras :
        grid_rect = (0, 0, 1, 1)
        cb_rect = (-.05, -2, .8, 4.)
        cam_signal = viscam.PanZoomCamera()
        cam_grid = viscam.PanZoomCamera(rect=grid_rect)
        cam_cbar = viscam.PanZoomCamera(rect=cb_rect)

        # Canvas creation :
        cargs = {'size': (800, 600)}
        self._grid_canvas = VisbrainCanvas(axis=False,
                                           name='Grid',
                                           cargs=cargs,
                                           camera=cam_grid,
                                           **kwargs)
        self._signal_canvas = VisbrainCanvas(axis=True,
                                             name='Signal',
                                             cargs=cargs,
                                             add_cbar=True,
                                             camera=cam_signal,
                                             **kwargs)
        self._signal_canvas.wc_cbar.camera = cam_cbar

        # Add canvas to layout :
        self._GridLayout.addWidget(self._grid_canvas.canvas.native)
        self._SignalLayout.addWidget(self._signal_canvas.canvas.native)

        # Initialize shortcuts :
        GridShortcuts.__init__(self, self._grid_canvas.canvas)
        SignalShortcuts.__init__(self, self._signal_canvas.canvas)
示例#2
0
    def __init__(self, bgcolor='black', verbose=None, **kwargs):
        """Init."""
        # ====================== PyQt creation ======================
        _PyQtModule.__init__(self,
                             verbose=verbose,
                             to_describe='view.wc',
                             icon='brain_icon.svg')
        self._userobj = {}
        self._gl_scale = 100.  # fix appearance for small meshes
        self._camera = viscam.TurntableCamera(name='MainBrainCamera')

        # ====================== Canvas creation ======================
        UiInit.__init__(self, bgcolor)  # GUI creation + canvas
        PROFILER("Canvas creation")

        # ====================== App creation ======================
        PROFILER("Visual elements", as_type='title')
        Visuals.__init__(self, self.view.wc, **kwargs)

        # ====================== Ui interactions ======================
        UiElements.__init__(self)  # GUI interactions
        PROFILER("Ui interactions")
        self._shpopup.set_shortcuts(self.sh)  # shortcuts dict

        # ====================== Cameras ======================
        # Main camera :
        self.view.wc.camera = self._camera
        self._vbNode.parent = self.view.wc.scene
        self.atlas.camera = self._camera
        self.roi.camera = self._camera
        self.atlas._csize = self.view.canvas.size
        self.atlas.rotate('top')
        self.atlas.camera.set_default_state()
        PROFILER("Cameras creation")

        # ====================== Colorbar ======================
        camera = viscam.PanZoomCamera(rect=(-.2, -2.5, 1, 5))
        BrainCbar.__init__(self, camera)
        PROFILER("Colorbar and panzoom creation")
        self.background_color(bgcolor)

        # ====================== Shortcuts ======================
        BrainShortcuts.__init__(self, self.cbqt.cbviz._canvas)
        PROFILER("Set brain shortcuts")

        self._fcn_on_load()
        PROFILER("Functions on load")
示例#3
0
    def _cam_creation(self):
        """Create a set of cameras."""
        # ------------------- Channels -------------------
        self._chanCam = []
        for k in range(len(self)):
            self._chanCam.append(FixedCam())  # viscam.PanZoomCamera()
        # ------------------- Spectrogram -------------------
        self._speccam = FixedCam()  # viscam.PanZoomCamera()
        self._specCanvas.set_camera(self._speccam)
        # ------------------- Hypnogram -------------------
        self._hypcam = FixedCam()  # viscam.PanZoomCamera()
        self._hypCanvas.set_camera(self._hypcam)
        # ------------------- Topoplot -------------------
        self._topocam = viscam.PanZoomCamera()
        self._topoCanvas.set_camera(self._topocam)
        # ------------------- Time axis -------------------
        self._timecam = FixedCam()
        self._TimeAxis.set_camera(self._timecam)

        # Keep all cams :
        self._allCams = (self._chanCam, self._speccam, self._hypcam,
                         self._topocam, self._timecam)
示例#4
0
    def __init__(self, data, sf=1, **kwargs):
        """Init."""
        # Be sure to have float arguments :
        if data.dtype != np.float32:
            data = data.astype(np.float32, copy=False)
            warn("Data should be an array of float number. Use "
                 "data.astype(np.float32) before opening the interface.")
        # ====================== ui Arguments ======================
        # Background color (for all of the canvas) :
        bgcolor = kwargs.get('ui_bgcolor', (.09, .09, .09))
        nd_title = kwargs.get('nd_title', 'Nd-plot')
        nd_xlabel = kwargs.get('nd_xlabel', 'X axis')
        nd_ylabel = kwargs.get('nd_ylabel', 'Y axis')
        nd_grid = kwargs.get('nd_grid', False)
        nd_visible = kwargs.get('nd_visible', True)
        od_grid = kwargs.get('od_grid', True)
        od_visible = kwargs.get('od_visible', False)
        od_title = kwargs.get('od_title', '1d-plot')
        od_xlabel = kwargs.get('od_xlabel', 'X axis')
        od_ylabel = kwargs.get('od_ylabel', 'Y axis')
        # Default linewidth :
        self._ndlw = kwargs.get('nd_lw', 2.)
        self._1dlw = kwargs.get('od_lw', 2.)
        self._oridata = np.ascontiguousarray(data)
        self._sf = np.float32(sf)
        # print('ID 0: ', id(self._oridata))
        # Savename, extension and croping region (usefull for the screenshot) :
        self._savename = kwargs.get('ui_savename', None)
        self._extension = kwargs.get('ui_extension', '.png')
        self._crop = kwargs.get('ui_region', None)
        if self._extension not in ['png', 'tiff']:
            self._extension = 'png'

        # ====================== App creation ======================
        # Create the app and initialize all graphical elements :
        self._app = QtWidgets.QApplication(sys.argv)
        uiInit.__init__(self, bgcolor, nd_title, nd_xlabel, nd_ylabel,
                        od_title, od_xlabel, od_ylabel)

        # ====================== Objects creation ======================
        visuals.__init__(self, data, self._sf, **kwargs)

        # ====================== user & GUI interaction  ======================
        # User <-> GUI :
        uiElements.__init__(self)

        # ====================== Cameras ======================
        # Nd-plot camera :
        ndcam = viscam.PanZoomCamera(rect=(-1, -1, 2, 2))
        self._ndplt.mesh.set_camera(ndcam)
        self._ndCanvas.set_camera(ndcam)

        # 1d-plot camera :
        odcam = viscam.PanZoomCamera(rect=self._1dplt.mesh.rect)
        self._1dCanvas.set_camera(odcam)

        # Fixed colorbar camera :
        turntable = viscam.TurntableCamera(interactive=True,
                                           azimuth=0,
                                           elevation=90)
        self._cbCanvas.set_camera(turntable)
        self._cbCanvas.wc.camera.set_range(x=(-24, 24),
                                           y=(-0.5, 0.5),
                                           margin=0)
        # self._cbCanvas.wc.scene.children[0].parent = None

        # ====================== Visibility ======================
        # Nd-panel :
        self._CanVisNd.setChecked(nd_visible)
        self._NdVizPanel.setVisible(nd_visible)
        self._ndGridTog.setChecked(nd_grid)
        self._ndCanvas.visible_axis(nd_grid)
        # 1d-panel :
        self._CanVis1d.setChecked(od_visible)
        self._1dVizPanel.setVisible(od_visible)
        self._1dGridTog.setChecked(od_grid)
        self._1dCanvas.visible_axis(od_grid)

        # Finally, update each canvas and tab selection :
        self._ndCanvas.canvas.update()
        self._1dCanvas.canvas.update()
        self._fcn_QuickTabSelec()
示例#5
0
    def __init__(self, *args, **kwargs):
        """Init."""
        # ====================== ui Arguments ======================
        # Background color (for the main and the colorbar canvas) :
        bgcolor = kwargs.get('ui_bgcolor', (0., 0., 0.))
        # Savename, extension and croping region (usefull for the screenshot) :
        self._savename = kwargs.get('ui_savename', None)
        self._crop = kwargs.get('ui_region', None)
        self._autocrop = kwargs.get('ui_autocrop', True)
        self._uirez = kwargs.get('ui_resolution', 3000.)
        self._xyzRange = {
            'turntable': {
                'x': None,
                'y': (-1200, 1200),
                'z': None
            },
            'fly': {
                'x': (-120, 120),
                'y': (-100, 200),
                'z': (-90, 90)
            },
        }
        self._cbarexport = True
        self._userobj = {}

        # ====================== App creation ======================
        # Create the app and initialize all graphical elements :
        self._app = QtWidgets.QApplication(sys.argv)
        uiInit.__init__(self, bgcolor)

        # Set icon :
        # pathfile = sys.modules[__name__].__file__
        # path = os.path.join(*['brain', 'interface', 'gui', 'vbicon.png'])
        # self.setWindowIcon(QtGui.QIcon(os.path.join(pathfile.split(
        #     '/vbrain')[0], path)))

        # ====================== Objects creation ======================
        camera = viscam.TurntableCamera(azimuth=0,
                                        distance=1000,
                                        name='turntable')
        base.__init__(self, self.view.wc, self._csGrid, self.progressBar,
                      **kwargs)

        # ====================== UI to visbrain ======================
        # Link UI and visbrain function :
        uiElements.__init__(self)
        self._shpopup.set_shortcuts(self.sh)

        # ====================== Cameras ======================
        # Main camera :
        self.view.wc.camera = camera
        self.atlas.mesh.set_camera(self.view.wc.camera)
        self.pic.set_camera(self.view.wc.camera)
        self._vbNode.parent = self.view.wc.scene
        self._rotate(fixed='axial')
        self.view.wc.camera.set_default_state()

        # ====================== Colorbar ======================
        # Fixed colorbar camera :
        camera = viscam.PanZoomCamera(rect=(-.2, -2.5, 1, 5))
        # Cbar creation :
        BrainCbar.__init__(self, camera)
        # Add shortcuts on it :
        BrainShortcuts.__init__(self, self.cbqt.cbviz._canvas)

        self._fcn_on_load()
示例#6
0
    def __init__(self, bgcolor='black', verbose=None, **kwargs):
        """Init."""
        # ====================== PyQt creation ======================
        _PyQtModule.__init__(self,
                             verbose=verbose,
                             to_describe='view.wc',
                             icon='brain_icon.svg')
        self._userobj = {}
        self._gl_scale = 100.  # fix appearance for small meshes
        self._camera = viscam.TurntableCamera(name='MainEngramCamera')

        # ====================== Canvas creation ======================
        UiInit.__init__(self, bgcolor)  # GUI creation + canvas
        PROFILER("Canvas creation")

        # ====================== App creation ======================
        PROFILER("Visual elements", as_type='title')
        Visuals.__init__(self, self.view.wc, **kwargs)

        # ====================== Metadata Storage ======================
        if 'metadata' in kwargs.keys():
            self.metadata = kwargs['metadata']
        else:
            self.metadata = {}

        # ====================== Rotation Kinetics ======================
        if 'rotation' in kwargs.keys():
            self.rotation = kwargs['rotation']
        else:
            self.rotation = 0

        # ====================== Carousel Options ======================
        self.ease_xyz = False  # Between carousel options
        self.ignore_streams = True

        if 'carousel_metadata' in kwargs.keys():
            self.carousel_metadata = kwargs['carousel_metadata']
        else:
            self.carousel_metadata = {}

        # Carousel Display Method
        if 'carousel_display_method' in kwargs.keys():
            self._carousel_display_method = kwargs['carousel_display_method']
        else:
            self._carousel_display_method = 'text'

        # Carousel Options
        if 'hierarchy_lookup' in self.carousel_metadata:
            options = np.asarray(self.carousel_metadata['hierarchy_lookup'])

            self._carousel_options_inds = [np.asarray([0])]

            for dims in (range(len(options))):

                _combs = itertools.combinations(range(len(options)), dims + 1)
                _combs = list(_combs)

                for ll, comb in enumerate(_combs):
                    comb = list(comb)
                    if len(comb) > 1:
                        if ll == 0:
                            combs = [np.array(list(comb)) + 1]
                        else:
                            combs.append(np.array(list(comb)) + 1)
                    else:
                        if ll == 0:
                            combs = [np.array([comb[0] + 1])]
                        else:
                            combs.append(np.array([list(comb)[0] + 1]))

                self._carousel_options_inds.append(combs)

            self._carousel_options_inds[0] = [self._carousel_options_inds[0]]

            options = list(options)
            new_options = [np.asarray(['None'])]
            for ii in np.arange(len(options)) + 1:
                new_options.append(options[ii - 1])
            self._carousel_options = np.asarray(new_options)

        else:
            self._carousel_options_inds = [np.asarray([])]

            self._carousel_options = np.asarray(['None'])

        # Carousel Choice
        if 'carousel_choice' in kwargs.keys():
            self._carousel_choice = kwargs['carousel_choice']
            self._prev_carousel_choice = kwargs['carousel_choice']
        else:
            self._carousel_choice = [0, 0]
            self._prev_carousel_choice = [0, 0]

        # Display Method
        self.update_carousel()

        # Toggle Options
        self._userdistance = [0]
        self._uservelocity = 0

        # ====================== Control Device ======================
        if 'control_method' in kwargs.keys():
            self.control_method = kwargs['control_method']
        else:
            self.control_method = 'keyboard'

        if self.control_method is 'IR_Distance':
            self.ser = serial.Serial('/dev/cu.usbmodem144101')
            self.use_distance = True
        else:
            self.ser = None

        self.prev_rotation = 0

        def arduino_control(method='none'):
            if self.ser is not None:
                # Check Arduino inputs
                try:
                    b = self.ser.readline()  # read a byte string
                    string_n = b.decode()  # decode byte string into Unicode
                    message = string_n.rstrip()  # remove \n and \r
                    messages = message.split('|')
                    distance = messages[0]
                    command = messages[1]
                except:
                    distance = 500
                    command = 'NONE'

            if method == 'IR_Distance':

                if self.use_distance:
                    THRESHOLD = 20  # cm
                    HEIGHT = 0
                    flt = float(distance)
                    self._userdistance = np.append(
                        self._userdistance, flt)  # convert string to float

                    # Distance Selections
                    if flt < HEIGHT + THRESHOLD:
                        self._carousel_choice[0] = 0
                    if flt >= HEIGHT + (THRESHOLD) and flt < HEIGHT + (
                            2 * THRESHOLD):
                        self._carousel_choice[0] = 1
                    if flt >= HEIGHT + (2 * THRESHOLD):
                        self._carousel_choice[0] = 3

                # Remote Option

                if command != 'NONE':
                    print(command)

                if command == 'POWER':
                    sys.exit()

                if command == 'ST/REPT' and not self.use_distance:
                    if self._carousel_choice[0] < (
                            len(self._carousel_options_inds) - 1):
                        if self._carousel_choice[0] == 1:
                            self._carousel_choice[0] = 3
                        else:
                            self._carousel_choice[0] += 1
                    else:
                        self._carousel_choice[0] = 0
                    self._carousel_choice[1] = 0

                if command == 'EQ':
                    if self.use_distance:
                        self.use_distance = False
                    else:
                        self.use_distance = True

                if command == 'FUNC/STOP':
                    if self._carousel_choice[1] < (
                            len(self._carousel_options_inds[
                                self._carousel_choice[0]]) - 1):
                        self._carousel_choice[1] += 1
                    else:
                        self._carousel_choice[1] = 0

                if command == 'VOL+' or command == 'VOL-':
                    if command == 'VOL+':
                        self.view.wc.camera.distance -= 5000
                    else:
                        self.view.wc.camera.distance += 5000

                if command == 'UP':
                    self.rotation += .25

                elif command == 'DOWN':
                    self.rotation -= .25

                elif command == 'FAST BACK':
                    if np.sign(self.timescaling) == 1:
                        self.timescaling = -0.1
                    else:
                        self.timescaling -= 0.10

                elif command == 'FAST FORWARD':
                    if np.sign(self.timescaling) == -1:
                        self.timescaling = 0.1
                    else:
                        self.timescaling += 0.10

                elif command == 'PAUSE':
                    if self.timescaling == 0:
                        print('PLAY')
                        self.timescaling = self.default_timescaling
                        self.rotation = self.prev_rotation
                        self.displayed_time = self.time_cache
                        self.time_cache = None

                    else:
                        print('PAUSE')
                        self.prev_rotation = self.rotation
                        self.time_cache = self.displayed_time
                        self.rotation = 0
                        self.timescaling = 0
                        self.paused = True

                if self.paused == True:
                    if command == 'FAST FORWARD':
                        self.time_cache += .02
                    elif command == 'FAST BACK':
                        self.time_cache -= .02

                # Remote Numbers
                if command == '0':
                    self.view.wc.camera.azimuth = 0
                    self.view.wc.camera.elevation = 90

                elif command == '1':
                    self.view.wc.camera.azimuth = 0
                    self.view.wc.camera.elevation = -90

                elif command == '2':
                    self.view.wc.camera.azimuth = 90
                    self.view.wc.camera.elevation = 0

                elif command == '3':
                    self.view.wc.camera.azimuth = -90
                    self.view.wc.camera.elevation = 0

                elif command == '4':
                    self.view.wc.camera.azimuth = 0
                    self.view.wc.camera.elevation = 0

                elif command == '5':
                    self.view.wc.camera.azimuth = 180
                    self.view.wc.camera.elevation = 0

                elif command == '6':
                    self.view.wc.camera.azimuth = 45
                    self.view.wc.camera.elevation = 30

                elif command == '7':
                    self.view.wc.camera.azimuth = 45
                    self.view.wc.camera.elevation = -30

                elif command == '8':
                    self.view.wc.camera.azimuth = -45
                    self.view.wc.camera.elevation = 30

                elif command == '9':
                    self.view.wc.camera.azimuth = -45
                    self.view.wc.camera.elevation = -30

        # ====================== Timer Creation ======================

        self.loop_shift = 0
        self.start_offset = 0
        self.default_timescaling = 1 / 4
        self.timescaling = self.default_timescaling
        self.time_cache = None
        self.displayed_time = 0

        self.paused = False

        def on_timer(*args, **kwargs):

            # Change Source Radii and Connectivity Values
            if self.time_cache is None:
                time_inc = (args[0].dt * self.timescaling)
                self.displayed_time = self.loop_shift + (
                    self.displayed_time + time_inc) % (
                        (np.shape(self.sources[0].data)[1] /
                         self.metadata['fs']) - self.loop_shift)
            else:
                self.displayed_time = self.loop_shift + (self.time_cache) % (
                    (np.shape(self.sources[0].data)[1] / self.metadata['fs']) -
                    self.loop_shift)

            timepoint = int(self.displayed_time * self.metadata['fs'])
            for source in self.sources:
                source._update_radius(timepoint=timepoint)
            for connect in self.connect:
                connect._update_time(timepoint=timepoint)

            arduino_control(self.control_method)

            self.update_target_positions()
            self.update_carousel()
            self.update_visibility()
            self._prev_carousel_choice = self._carousel_choice

            if len(self._userdistance) > 2:
                self._userdistance = [-1]

            # Update Time Display
            t_str = str(round(self.displayed_time, 3)) + ' s'
            if not hasattr(self, '_time'):
                self._time = Text(t_str,
                                  parent=self.view.canvas.scene,
                                  color='white')
            else:
                self._time.text = t_str
            self._time.anchors = ('right', 'bottom')
            self._time.font_size = self.view.canvas.size[1] // 200
            self._time.pos = (49) * self.view.canvas.size[0] // 50, (
                19) * self.view.canvas.size[1] // 20
            self._time.update()

            # Ease to New Positions if Triggered
            if self.ease_xyz:
                self.ease_xyz = False
                for source in self.sources:
                    out = source._ease_to_target_position()
                    if out:
                        self.ease_xyz = True
                for connect in self.connect:
                    out = connect._ease_to_target_position()
                    if out:
                        self.ease_xyz = True

            # if hasattr(self.view.wc, 'camera'):
            #     diff_az = self.target_azimuth - self.view.wc.camera.azimuth
            #     diff_el = self.target_elevation - self.view.wc.camera.elevation

            #     # Ease scene rotation
            #     if (diff_az != 0.) | (diff_el != 0.):

            #         # Flip target and current (since I cannot find a way to update the shortcuts directly)
            #         if self.first_ease:
            #             temp_ = self.target_elevation
            #             self.target_elevation = self.view.wc.camera.elevation
            #             self.view.wc.camera.elevation = temp_
            #             temp_ = self.target_azimuth
            #             self.target_azimuth = self.view.wc.camera.azimuth
            #             self.view.wc.camera.azimuth = temp_

            #             self.first_ease = False

            #         if (abs(diff_az) > 0.001) | (abs(diff_el) > 0.001):
            #              self.view.wc.camera.azimuth += .1*(diff_az)
            #              self.view.wc.camera.elevation += .1*(diff_el)
            #              print('updating rotation')
            #              if self.first_ease:
            #                 self.first_ease = False
            #         else:
            #             self.view.wc.camera.azimuth = self.target_azimuth
            #             self.view.wc.camera.elevation = self.target_elevation
            #             self.first_ease = True

            #Iterate scene rotation
            # else:
            self.view.wc.camera.azimuth += self.rotation

            self.view.wc.canvas.update()

        kw = dict(connect=on_timer,
                  app=CONFIG['VISPY_APP'],
                  interval='auto',
                  iterations=-1)
        self._app_timer = app.Timer(**kw)
        self._app_timer.start()

        # ====================== Ui interactions ======================
        UiElements.__init__(self)  # GUI interactions
        PROFILER("Ui interactions")
        self._shpopup.set_shortcuts(self.sh)  # shortcuts dict

        # ====================== Cameras ======================
        # Main camera :
        self.view.wc.camera = self._camera
        self._vbNode.parent = self.view.wc.scene
        self.atlas.camera = self._camera
        self.roi.camera = self._camera
        self.atlas._csize = self.view.canvas.size
        self.atlas.rotate('top')
        self.atlas.camera.set_default_state()
        PROFILER("Cameras creation")

        # Set easing
        self.target_azimuth = self.view.wc.camera.azimuth
        self.target_elevation = self.view.wc.camera.elevation
        self.first_ease = True

        # ====================== Colorbar ======================
        camera = viscam.PanZoomCamera(rect=(-.2, -2.5, 1, 5))
        EngramCbar.__init__(self, camera)
        PROFILER("Colorbar and panzoom creation")
        self.background_color(bgcolor)

        # ====================== Shortcuts ======================
        EngramShortcuts.__init__(self, self.cbqt.cbviz._canvas)
        PROFILER("Set engram shortcuts")

        self._fcn_on_load()
        PROFILER("Functions on load")
示例#7
0
    def add_topoplot(self,
                     name,
                     data,
                     xyz=None,
                     channels=None,
                     system='cartesian',
                     unit='degree',
                     title=None,
                     title_color='black',
                     title_size=5.,
                     line_color='black',
                     line_width=2.,
                     chan_size=2.,
                     chan_offset=(0., 0., 0.),
                     chan_mark_color='white',
                     chan_mark_symbol='disc',
                     chan_txt_color='black',
                     bgcolor='white',
                     cbar=True,
                     cblabel=None,
                     cb_txt_size=4.,
                     levels=None,
                     level_colors='white',
                     cmap='viridis',
                     clim=None,
                     vmin=None,
                     under='gray',
                     vmax=None,
                     over='red',
                     row=0,
                     col=0,
                     row_span=1,
                     col_span=1,
                     margin=.05):
        """Add a subplot embedded in a subplot.

        For now, there's two for using coordinates to define the subplot :

            * Using the xyz input (must either be in cartesian or spherical
              coordinate system)
            * Using the channel input. The Topo class contains a list of
              existing channel names and will try to identify those in the
              channels variable.

        Parameters
        ----------
        name : string
            Name of the topographic plot.
        data : array_like
            Array of data of shape (n_channels,).
        xyz : array_like | None
            Array of source's coordinates.
        channels : list | None
            List of channel names.
        system : {'cartesian', 'spherical'}
            Coordinate system.
        unit : {'degree', 'rad'}
            If system is 'spherical', specify if angles are in degrees or
            radians.
        title : string | None
            Title of the topoplot.
        title_color : array_like/string | 'black'
            Color for the title.
        title_size : float | 20.
            Size of the title.
        line_color : array_like/string | 'black'
            Color of lines for the head, nose and eras.
        line_width : float | 4.
            Line width for the head, nose and eras.
        chan_size : float | 12.
            Size of channel names text.
        chan_mark_color : array_like/string | 'white'
            Color of channel markers.
        chan_mark_symbol : string | 'disc'
            Symbol to use for markers. Use disc, arrow, ring, clobber, square,
            diamond, vbar, hbar, cross, tailed_arrow, x, triangle_up,
            triangle_down, and star.
        chan_txt_color : array_like/string | 'black'
            Color of channel names.
        bgcolor : array_like/string | 'white'
            Background color.
        cbar : bool | True
            Attach a colorbar to the topoplot.
        cblabel : string | None
            Colorbar label.
        cb_txt_size : float | 16.
            Text size for the colorbar limits and label.
        levels : array_like/int | None
            The levels at which the isocurve is constructed.
        level_colors : string/array_like | 'white'
            The color to use when drawing the line. If a list is given, it
            must be of shape (Nlev), if an array is given, it must be of
            shape (Nlev, ...). and provide one color per level
            (rgba, colorname). By default, all levels are whites.
        cmap : string | None
            Matplotlib colormap (like 'viridis', 'inferno'...).
        clim : tuple/list | None
            Colorbar limit. Every values under / over clim will
            clip.
        vmin : float | None
            Every values under vmin will have the color defined
            using the under parameter.
        vmax : float | None
            Every values over vmin will have the color defined
            using the over parameter.
        under : tuple/string | None
            Matplotlib color under vmin.
        over : tuple/string | None
            Matplotlib color over vmax.
        row : int | 0
            The row in which to add the widget (0 is the topmost row)
        col : int | 0
            The column in which to add the widget (0 is the leftmost column)
        row_span : int | 1
            The number of rows to be occupied by the topoplot.
        col_span : int | 1
            The number of columns to be occupied by the topoplot.
        margin : float | .05
            Margin percentage between the topoplot and the edge of the subplot.
        """
        # Check if name is avaible :
        self._check_name_for(name, 'topoplot')
        # Create the topoplot and set the data :
        topo = TopoMesh(xyz, channels, system, unit, title, title_color,
                        title_size, line_color, line_width, chan_size,
                        chan_offset, chan_mark_color, chan_mark_symbol,
                        chan_txt_color, bgcolor, cbar, cb_txt_size, margin)
        topo.set_data(data, levels, level_colors, cmap, clim, vmin, under,
                      vmax, over, cblabel)
        self[name] = topo
        # Create a PanZoom camera :
        cam = viscam.PanZoomCamera(aspect=1., rect=topo.rect)
        cam.set_default_state()
        # Create a subplot and add the camera :
        self._topoGrid[name] = self._grid.add_view(row,
                                                   col,
                                                   row_span,
                                                   col_span,
                                                   bgcolor=bgcolor,
                                                   camera=cam)
        # Add the topoplot to the subplot :
        self._topoGrid[name].add(self[name].node)
示例#8
0
    def add_shared_colorbar(self,
                            name,
                            cmap='viridis',
                            clim=(0, 1),
                            vmin=None,
                            vmax=None,
                            under='gray',
                            over='red',
                            cblabel='',
                            cbtxtsz=5.,
                            cbtxtsh=2.3,
                            txtcolor='black',
                            txtsz=3.,
                            txtsh=1.2,
                            width=.17,
                            border=True,
                            bw=2.,
                            limtxt=True,
                            bgcolor='white',
                            ndigits=2,
                            row=0,
                            col=0,
                            row_span=1,
                            col_span=1,
                            rect=(-1.2, -1.2, 2.4, 2.4)):
        """Add a shared colorbar across subplots.

        Parameters
        ----------
        cmap : string | None
            Matplotlib colormap (like 'viridis', 'inferno'...).
        clim : tuple/list | None
            Colorbar limit. Every values under / over clim will
            clip.
        vmin : float | None
            Every values under vmin will have the color defined
            using the under parameter.
        vmax : float | None
            Every values over vmin will have the color defined
            using the over parameter.
        under : tuple/string | None
            Matplotlib color under vmin.
        over : tuple/string | None
            Matplotlib color over vmax.
        cblabel : string | ''
            Colorbar label.
        cbtxtsz : float | 5..
            Text size of the colorbar label.
        cbtxtsh : float | 2.3
            Shift for the colorbar label.
        txtcolor : string | 'white'
            Text color.
        txtsz : float | 3.
            Text size for clim/vmin/vmax text.
        txtsh : float | 1.2
            Shift for clim/vmin/vmax text.
        border : bool | True
            Display colorbar borders.
        bw : float | 2.
            Border width.
        limtxt : bool | True
            Display vmin/vmax text.
        bgcolor : tuple/string | (0., 0., 0.)
            Background color of the colorbar canvas.
        ndigits : int | 2
            Number of digits for the text.
        row : int | 0
            The row in which to add the widget (0 is the topmost row)
        col : int | 0
            The column in which to add the widget (0 is the leftmost column)
        row_span : int | 1
            The number of rows to be occupied by the topoplot.
        col_span : int | 1
            The number of columns to be occupied by the topoplot.
        rect : tuple | (-1.2, -1.2, 2.4, 2.4)
            The 2-D area on the screen to display. The rect input describe
            (x_start, y_start, x_width, y_height). This variable can be used
            to translate or scale.
        """
        # Check if name is avaible :
        self._check_name_for(name, 'colorbar')
        # Create a PanZoom camera :
        cam = viscam.PanZoomCamera(rect=rect)
        cam.set_default_state()
        # Create a subplot and add the camera :
        self._topoGrid[name] = self._grid.add_view(row,
                                                   col,
                                                   row_span,
                                                   col_span,
                                                   bgcolor=bgcolor,
                                                   camera=cam)
        # Get if vmin and vmax exist :
        isvmin, isvmax = vmin is not None, vmax is not None
        # Create a colorbar object :
        parent = Node(name=name)
        cbar = CbarVisual(cmap=cmap,
                          clim=clim,
                          vmin=vmin,
                          isvmin=isvmin,
                          vmax=vmax,
                          isvmax=isvmax,
                          under=under,
                          over=over,
                          cblabel=cblabel,
                          cbtxtsz=cbtxtsz,
                          cbtxtsh=cbtxtsh,
                          txtcolor=txtcolor,
                          txtsz=txtsz,
                          txtsh=txtsh,
                          width=width,
                          border=border,
                          bw=bw,
                          limtxt=limtxt,
                          bgcolor=bgcolor,
                          ndigits=ndigits,
                          parent=parent)
        self[name] = cbar
        # Add the colorbar to the subplot :
        self._topoGrid[name].add(parent)
示例#9
0
    def __init__(self,
                 data,
                 axis=-1,
                 time=None,
                 sf=1.,
                 enable_grid=True,
                 form='line',
                 color='black',
                 line_lw=1.,
                 line_smooth=False,
                 marker_symbol='disc',
                 marker_size=10.,
                 hist_nbins=10,
                 tf_norm=0,
                 tf_baseline=None,
                 tf_interp='gaussian',
                 tf_cmap='viridis',
                 tf_av_window=None,
                 tf_av_overlap=0.,
                 tf_clim=None,
                 psd_nperseg=256,
                 psd_noverlap=128,
                 display_grid=True,
                 display_signal=True,
                 annotations=None,
                 annot_txtsz=18.,
                 annot_marksz=16.,
                 annot_color='#2ecc71',
                 grid_lw=1.,
                 grid_smooth=False,
                 grid_titles=None,
                 grid_font_size=10.,
                 grid_color='random',
                 grid_shape=None,
                 grid_titles_color='black',
                 verbose=None,
                 **kwargs):
        """Init."""
        dscb = ['_grid_canvas.canvas.scene', '_signal_canvas.canvas.scene']
        PyQtModule.__init__(self, verbose=verbose, to_describe=dscb)
        self._enable_grid = enable_grid
        self._previous_form = form
        display_grid = bool(display_grid * self._enable_grid)

        # ==================== APP CREATION ====================
        UiInit.__init__(self, **kwargs)

        # ==================== DATA CHECKING ====================
        if isinstance(data, (list, tuple)):
            data = np.asarray(data)
        if not isinstance(data, np.ndarray) or (data.ndim > 3):
            raise TypeError("data must be an NumPy array with less than three "
                            "dimensions.")
        if data.ndim == 1 or not self._enable_grid:  # disable grid
            display_grid = self._enable_grid = False
            self.actionGrid.setEnabled(False)
            toggle_enable_tab(self.QuickSettings, 'Grid', False)
        self._data = data.astype(np.float32, copy=False)
        self._axis = axis

        # ==================== VISUALS ====================
        grid_parent = self._grid_canvas.wc.scene
        signal_parent = self._signal_canvas.wc.scene
        Visuals.__init__(self, data, time, sf, axis, grid_titles, grid_color,
                         grid_shape, grid_parent, signal_parent)

        # ==================== CAMERA ====================
        grid_rect = (0, 0, 1, 1)
        sig_rect = self._signal.rect
        cb_rect = (-.05, -2, .8, 4.)
        self._grid_canvas.camera = viscam.PanZoomCamera(rect=grid_rect)
        self._signal_canvas.camera = viscam.PanZoomCamera(rect=sig_rect)
        self._signal_canvas.wc_cbar.camera = viscam.PanZoomCamera(rect=cb_rect)

        # ==================== UI INIT ====================
        self._fix_elements_limits()
        # ------------- Signal -------------
        # Signal and axis color :
        self._sig_color.setText(str(color2tuple(color, astype=float)))
        ax_color = kwargs.get('axis_color', color2vb('black'))
        self._axis_color.setText(str(ax_color))
        # Title, labels and ticks :
        self._sig_title.setText(kwargs.get('title', ''))
        self._sig_title_fz.setValue(kwargs.get('title_font_size', 15.))
        self._sig_xlab.setText(kwargs.get('xlabel', ''))
        self._sig_ylab.setText(kwargs.get('ylabel', ''))
        self._sig_lab_fz.setValue(kwargs.get('axis_font_size', 12.))
        self._sig_ticks_fz.setValue(kwargs.get('tick_font_size', 8.))
        # Signal properties :
        safely_set_cbox(self._sig_form, form)
        self._sig_lw.setValue(line_lw)  # line
        self._sig_smooth.setChecked(line_smooth)  # line
        self._sig_nbins.setValue(hist_nbins)  # histogram
        self._sig_size.setValue(marker_size)  # marker
        safely_set_cbox(self._sig_symbol, marker_symbol)  # marker
        self._sig_norm.setCurrentIndex(tf_norm)
        safely_set_cbox(self._sig_tf_interp, tf_interp)
        self._sig_tf_rev.setChecked(bool(tf_cmap.find('_r') + 1))
        self._sig_tf_cmap.addItems(mpl_cmap())
        safely_set_cbox(self._sig_tf_cmap, tf_cmap.replace('_r', ''))
        if (tf_baseline is not None) and (len(tf_baseline) == 2):
            self._sig_baseline.setChecked(True)
            self._sig_base_start.setValue(tf_baseline[0])
            self._sig_base_end.setValue(tf_baseline[1])
        if isinstance(tf_av_window, int):
            self._sig_averaging.setChecked(True)
            self._sig_av_win.setValue(tf_av_window)
            self._sig_av_overlap.setValue(tf_av_overlap)
        if (tf_clim is not None) and (len(tf_clim) == 2):
            self._sig_tf_clim.setChecked(True)
            self._sig_climin.setValue(tf_clim[0])
            self._sig_climax.setValue(tf_clim[1])
        self._sig_nperseg.setValue(psd_nperseg)
        self._sig_noverlap.setValue(psd_noverlap)

        # ------------- Grid -------------
        if hasattr(self, '_grid'):
            n_rows, n_cols = self._grid.g_size
            self._grid_nrows.setValue(n_rows)
            self._grid_nrows.setMaximum(np.prod(self._grid.g_size))
            self._grid_ncols.setValue(n_cols)
            self._grid_ncols.setMaximum(np.prod(self._grid.g_size))
        gt_st = str(color2tuple(grid_titles_color, astype=float))
        self._grid_titles_fz.setValue(grid_font_size)
        self._grid_titles_color.setText(gt_st)
        self._grid_lw.setValue(grid_lw)

        # ------------- Cbar -------------
        self._signal_canvas.cbar.txtcolor = ax_color
        self._signal_canvas.cbar.border = False
        self._signal_canvas.cbar.cbtxtsz = 15.
        self._signal_canvas.cbar.txtsz = 12.

        # ------------- Settings -------------
        bgcolor = kwargs.get('bgcolor', 'white')
        self._set_bgcolor.setText(str(color2tuple(bgcolor, astype=float)))
        self._grid_smooth.setChecked(grid_smooth)

        # ------------- Annotations -------------
        self._annot_txtsz.setValue(annot_txtsz)
        self._annot_marksz.setValue(annot_marksz)
        self._annot_color.setText(str(color2tuple(annot_color, astype=float)))

        # ------------- Menu -------------
        self.actionGrid.setChecked(display_grid)
        self.actionSignal.setChecked(display_signal)

        self._fcn_on_creation()

        # ==================== USER <-> GUI ====================
        UiElements.__init__(self, **kwargs)

        # ==================== SHORTCUTS ====================
        self._shpopup.set_shortcuts(self._sh_grid + self._sh_sig)

        # ------------- Annotations -------------
        if annotations is not None:
            assert os.path.isfile(annotations)
            self._fcn_load_annotations(filename=annotations)
示例#10
0
    def __init__(self, bgcolor='black', verbose=None, **kwargs):
        """Init."""
        # ====================== PyQt creation ======================
        _PyQtModule.__init__(self,
                             verbose=verbose,
                             to_describe='view.wc',
                             icon='brain_icon.svg')
        self._userobj = {}
        self._gl_scale = 100.  # fix appearance for small meshes
        self._camera = viscam.TurntableCamera(name='MainEngramCamera')

        # ====================== Canvas creation ======================
        UiInit.__init__(self, bgcolor)  # GUI creation + canvas
        PROFILER("Canvas creation")

        # ====================== App creation ======================
        PROFILER("Visual elements", as_type='title')
        Visuals.__init__(self, self.view.wc, **kwargs)

        # ====================== Metadata Storage ======================
        if 'metadata' in kwargs.keys():
            self.metadata = kwargs['metadata']
        else:
            self.metadata = {}

        # ====================== Rotation Kinetics ======================
        if 'rotation' in kwargs.keys():
            self.rotation = kwargs['rotation']
        else:
            self.rotation = 0

        # ====================== Carousel Options ======================
        if 'carousel_metadata' in kwargs.keys():
            self.carousel_metadata = kwargs['carousel_metadata']
        else:
            self.carousel_metadata = {}

        # Carousel Display Method
        if 'carousel_display_method' in kwargs.keys():
            self._carousel_display_method = kwargs['carousel_display_method']
        else:
            self._carousel_display_method = 'text'

        # Carousel Options
        if 'hierarchy_lookup' in self.carousel_metadata:
            options = np.asarray(self.carousel_metadata['hierarchy_lookup'])

            self._carousel_options_inds = [np.asarray([0])]

            for dims in (range(len(options))):

                _combs = itertools.combinations(range(len(options)), dims + 1)
                _combs = list(_combs)

                for ll, comb in enumerate(_combs):
                    comb = list(comb)
                    if len(comb) > 1:
                        if ll == 0:
                            combs = [np.array(list(comb)) + 1]
                        else:
                            combs.append(np.array(list(comb)) + 1)
                    else:
                        if ll == 0:
                            combs = [np.array([comb[0] + 1])]
                        else:
                            combs.append(np.array([list(comb)[0] + 1]))

                self._carousel_options_inds.append(combs)

            self._carousel_options_inds[0] = [self._carousel_options_inds[0]]

            options = list(options)
            new_options = [np.asarray(['None'])]
            for ii in np.arange(len(options)) + 1:
                new_options.append(options[ii - 1])
            self._carousel_options = np.asarray(new_options)

        else:
            self._carousel_options_inds = [np.asarray([])]

            self._carousel_options = np.asarray(['None'])

        # Carousel Choice
        if 'carousel_choice' in kwargs.keys():
            self._carousel_choice = kwargs['carousel_choice']
            self._prev_carousel_choice = kwargs['carousel_choice']
        else:
            self._carousel_choice = [0, 0]
            self._prev_carousel_choice = [0, 0]

        # Display Method
        self.update_carousel()

        # ====================== Timer Creation ======================

        def on_timer(*args, **kwargs):
            if hasattr(self.view.wc, 'camera'):
                self.view.wc.camera.azimuth += self.rotation
            self.view.wc.canvas.update()
            TIMESCALING = 1 / 1
            SHIFT = 0
            t = SHIFT + (SHIFT + (args[0].elapsed * TIMESCALING)) % (
                (np.shape(self.sources[0].data)[1] / self.metadata['fs']) -
                SHIFT)
            timepoint = int(t * self.metadata['fs'])
            for source in self.sources:
                source._update_radius(timepoint=timepoint)
            for connect in self.connect:
                connect._update_time(timepoint=timepoint)
            t_str = str(round(t, 3)) + ' s'
            if not hasattr(self, '_time'):
                self._time = Text(t_str,
                                  parent=self.view.canvas.scene,
                                  color='white')
            else:
                self._time.text = t_str
            self._time.anchors = ('right', 'bottom')
            self._time.font_size = self.view.canvas.size[1] // 200
            self._time.pos = (49) * self.view.canvas.size[0] // 50, (
                19) * self.view.canvas.size[1] // 20
            self._time.update()

        kw = dict(connect=on_timer,
                  app=CONFIG['VISPY_APP'],
                  interval='auto',
                  iterations=-1)
        self._app_timer = app.Timer(**kw)
        self._app_timer.start()

        # ====================== Ui interactions ======================
        UiElements.__init__(self)  # GUI interactions
        PROFILER("Ui interactions")
        self._shpopup.set_shortcuts(self.sh)  # shortcuts dict

        # ====================== Cameras ======================
        # Main camera :
        self.view.wc.camera = self._camera
        self._vbNode.parent = self.view.wc.scene
        self.atlas.camera = self._camera
        self.roi.camera = self._camera
        self.atlas._csize = self.view.canvas.size
        self.atlas.rotate('top')
        self.atlas.camera.set_default_state()
        PROFILER("Cameras creation")

        # ====================== Colorbar ======================
        camera = viscam.PanZoomCamera(rect=(-.2, -2.5, 1, 5))
        EngramCbar.__init__(self, camera)
        PROFILER("Colorbar and panzoom creation")
        self.background_color(bgcolor)

        # ====================== Shortcuts ======================
        EngramShortcuts.__init__(self, self.cbqt.cbviz._canvas)
        PROFILER("Set engram shortcuts")

        self._fcn_on_load()
        PROFILER("Functions on load")