def _build_line(self):
        """Build the connectivity line."""
        pos, edges = self._pos, self._edges
        # Color either edges or nodes :
        # logger.info("    %s coloring method for connectivity" % self._color_by)
        # Switch between coloring method :
        if self._color_by in ['strength', 'count']:
            # Build line position
            nnz_x, nnz_y = np.where(~edges.mask)
            indices = np.c_[nnz_x, nnz_y].flatten()
            line_pos = pos[indices, :]
            if self._color_by == 'strength':
                nnz_values = edges.compressed()
                values = np.c_[nnz_values, nnz_values].flatten()
            elif self._color_by == 'count':
                node_count = Counter(np.ravel([nnz_x, nnz_y]))
                values = np.array([node_count[k] for k in indices])
        elif self._color_by == 'causal':
            idx = np.array(np.where(~edges.mask)).T
            # If the array is not symetric, the line needs to be drawn between
            # points. If it's symetric, line should stop a the middle point.
            # Here, we get the maske value of the symetric and use it to
            # ponderate middle point calculation :
            pond = (~np.array(edges.mask))[idx[:, 1], idx[:, 0]]
            pond = pond.astype(float).reshape(-1, 1)
            div = pond + 1.
            # Build line pos :
            line_pos = np.zeros((2 * idx.shape[0], 3), dtype=float)
            line_pos[0::2, :] = pos[idx[:, 0], :]
            line_pos[1::2, :] = (pos[idx[:, 1]] + pond * pos[idx[:, 0]]) / div
            # Build values :
            values = np.full((line_pos.shape[0], ), edges.min(), dtype=float)
            values[1::2] = edges.compressed()
        #logger.info("    %i connectivity links displayed" % line_pos.shape[0])
        self._minmax = (values.min(), values.max())
        if self._clim is None:
            self._clim = self._minmax

        # Get the color according to values :
        if isinstance(self._custom_colors, dict):  # custom color
            if None in list(self._custom_colors.keys()):  # {None : 'color'}
                color = color2vb(self._custom_colors[None], length=len(values))
            else:  # black by default
                color = np.zeros((len(values), 4), dtype=np.float32)
            for val, col in self._custom_colors.items():
                color[values == val, :] = color2vb(col)
        else:
            color = array2colormap(values, **self.to_kwargs())
        color[:, -1] = self._alpha

        # Dynamic color :
        if self._dynamic is not None:
            color[:, 3] = vector_to_opacity(values,
                                            clim=self._clim,
                                            dyn=self._dynamic,
                                            order=self._dyn_order,
                                            orientation=self._dyn_orient)

        # Send data to the connectivity object :
        self._connect.set_data(pos=line_pos, color=color)
Ejemplo n.º 2
0
    def background_color(self, color=(.1, .1, .1)):
        """Set the background color of the main canvas and the colorbar.

        The main canvas is defined as the canvas where all objects are
        displayed. The colorbar has it own canvas and the background set will
        be the same as the one of the main canvas.

        Parameters
        ----------
        color : tuple/string | (.1, .1, .1)
            The color to use for the background color of the main canvas.
            The color can either be a tuple of integers (R, G, B),
            a matplotlib color (string) or a hexadecimal color (string).

        Examples
        --------
        >>> # Define a Engram instance :
        >>> vb = Engram()
        >>> # Set the background color (using a RGB tuple) :
        >>> vb.background_color(color=(1., 1., 1.))
        >>> # Set the background color (using matplotlib format) :
        >>> vb.background_color(color='white')
        >>> # Set the background color (using hexadecimal format) :
        >>> vb.background_color(color='#ffffff')
        >>> # Show the GUI :
        >>> vb.show()
        """
        bckcolor = color2vb(color).ravel()[0:-1]
        self.view.canvas.bgcolor = bckcolor
        self.cbqt.cbviz.bgcolor = bckcolor
Ejemplo n.º 3
0
 def __init__(self, time, camera, color='#292824', width=2., parent=None,
              hconv=None):
     # Keep camera :
     self._camera = camera
     self._rect = (0., 0., 0., 0.)
     self.rect = (time.min(), -5., time.max() - time.min(), 7.)
     self.width = width
     self.n = len(time)
     self._hconv = hconv
     self._hconvinv = {v: k for k, v in self._hconv.items()}
     # Get color :
     self.color = {k: color2vb(color=i) for k, i in zip(color.keys(),
                                                        color.values())}
     # Create a default line :
     pos = np.array([[0, 0], [0, 100]])
     self.mesh = scene.visuals.Line(pos, name='hypnogram', method='gl',
                                    parent=parent, width=width)
     self.mesh._width = width
     self.mesh.set_gl_state('translucent')
     # Create a default marker (for edition):
     self.edit = Markers(parent=parent)
     # self.mesh.set_gl_state('translucent', depth_test=True)
     self.edit.set_gl_state('translucent')
     # Add grid :
     self.grid = scene.visuals.GridLines(color=(.7, .7, .7, 1.),
                                         scale=(30. * time[-1] / len(time),
                                                1.),
                                         parent=parent)
     self.grid.set_gl_state('translucent')
Ejemplo n.º 4
0
 def __init__(self, name='indicator', alpha=.3, visible=True, parent=None):
     # Create a vispy image object :
     image = color2vb('gray', alpha=alpha)[np.newaxis, ...]
     self.mesh = scene.visuals.Image(data=image, name=name,
                                     parent=parent)
     self.mesh.transform = vist.STTransform()
     self.mesh.visible = visible
Ejemplo n.º 5
0
    def __init__(self, axis=True, x_label='', name='', bgcolor=(1., 1., 1.),
                 indic_color='darkred', fcn=[]):
        """Init."""
        # Create the main canvas :
        self.canvas = scene.SceneCanvas(keys=None, bgcolor=bgcolor,
                                        show=False)
        _ = [self.canvas.connect(k) for k in fcn]  # noqa

        # Create a grid :
        grid = self.canvas.central_widget.add_grid(margin=0)
        grid.spacing = 0

        # Add x-axis :
        self.xaxis = scene.AxisWidget(orientation='bottom', text_color='black')
        if axis:
            pad = grid.add_widget(row=0, col=0)
            pad.width_max = 50
        _col = int(axis)
        grid.add_widget(self.xaxis, row=1, col=_col)

        # Main plot :
        self.wc = grid.add_view(row=0, col=_col, border_color='black')

        # Add a square indicator :
        image = color2vb(indic_color)[np.newaxis, ...]
        self.mesh = scene.visuals.Image(image, name='Time indicator')
        self.mesh.transform = vist.STTransform()
        self.mesh.parent = self.wc.scene

        # Add markers :
        pos = np.full((1, 3), -10, dtype=np.float32)
        self.markers = Markers(pos=pos, parent=self.wc.scene)
        self.markers.set_gl_state('translucent')
Ejemplo n.º 6
0
 def _update_color(self):
     """Update marker's color."""
     # Get marker's background color :
     if isinstance(self._color, str):  # color='white'
         bg_color = color2vb(self._color, length=len(self))
     elif isinstance(self._color, list):  # color=['white', 'green']
         assert len(self._color) == len(self)
         bg_color = np.squeeze(np.array([color2vb(k) for k in self._color]))
     elif isinstance(self._color, np.ndarray):  # color = [[0, 0, 0], ...]
         csh = self._color.shape
         assert (csh[0] == len(self)) and (csh[1] >= 3)
         if self._color.shape[1] == 3:  # RGB
             self._color = np.c_[self._color,
                                 np.full(len(self), self._alpha)]
         bg_color = self._color.copy()
     # Update masked marker's color :
     bg_color[self._mask, :] = self._mask_color
     self._sources._data['a_bg_color'] = bg_color
     self.update()
Ejemplo n.º 7
0
 def _fcn_set_hypno_color(self):
     """Change the color of the hypnogram."""
     if not(self._PanHypnoColor.isChecked()):
         color = {-1: '#292824', 0: '#292824', 1: '#292824',
                  2: '#292824', 3: '#292824', 4: '#292824'}
     else:
         color = self._hypcolor
     # Get color :
     zp = zip(color.keys(), color.values())
     self._hyp.color = {k: color2vb(color=i) for k, i in zp}
     # Update hypnogram
     self._hyp.set_data(self._sf, self._hypno, self._time)
Ejemplo n.º 8
0
 def __init__(self,
              name='scorwinindicator',
              alpha=.75,
              visible=True,
              parent=None,
              color='red',
              barwidth=.20):
     # width of the vertical bars
     self.barwidth = barwidth
     # Create two vispy image object for the start and end of window
     # "Start mesh" : first vertical bar
     image_start = color2vb(color, alpha=alpha)[np.newaxis, ...]
     self.mesh_start = scene.visuals.Image(data=image_start,
                                           name=name,
                                           parent=parent)
     self.mesh_start.transform = vist.STTransform()
     self.mesh_start.visible = visible
     # "End mesh" : second vertical bar
     image_end = color2vb(color, alpha=alpha)[np.newaxis, ...]
     self.mesh_end = scene.visuals.Image(data=image_end,
                                         name=name,
                                         parent=parent)
     self.mesh_end.transform = vist.STTransform()
     self.mesh_end.visible = visible
Ejemplo n.º 9
0
 def _fcn_set_hypno_color(self):
     """Change the color of the hypnogram."""
     if not (self._PanHypnoColor.isChecked()):
         color = {
             -1: '#292824',
             0: '#292824',
             1: '#292824',
             2: '#292824',
             3: '#292824',
             4: '#292824'
         }
     else:
         color = self._hypcolor
     # Get color :
     zp = zip(color.keys(), color.values())
     self._hyp.color = {k: color2vb(color=i) for k, i in zp}
     # Update hypnogram
     self._hyp.set_data(self._sf, self._hypno, self._time)
Ejemplo n.º 10
0
    def _update_radius(self, timepoint=None):
        """Update marker's radius."""
        logger.debug("Weird edge arround markers (source_obj.py)")
        if not hasattr(self, 'radius'):
            if np.unique(self._data).size == 1:
                self.radius = self._radius_min * np.ones((len(self, )))
            else:
                self.radius = normalize(self._data.copy(),
                                        tomin=self._radius_min,
                                        tomax=self._radius_max)

        if timepoint:
            self._sources._data['a_size'] = self.radius[:, int(
                timepoint)]  # fs/time
            if not hasattr(self, '_timer'):
                self._timer = visuals.Text(str(int(timepoint)),
                                           pos=[0, 100, 0],
                                           bold=True,
                                           name='Text',
                                           color=color2vb('white'),
                                           font_size=50,
                                           parent=None)  #self._node)
            self._timer.text = str(int(timepoint))
            self._timer.update()

        else:
            if len(self.radius.shape) == 2:
                self._sources._data['a_size'] = np.mean(self.radius, axis=1)
            else:
                self._sources._data['a_size'] = self.radius

        to_hide = self.hide
        # Marker size + egde width = 0 and text='' for hidden sources :
        self._sources._data['a_size'][to_hide] = 0.
        self._sources._data['a_edgewidth'][to_hide] = 0.
        if isinstance(self._mask_radius, (int, float)):
            self._sources._data['a_size'][self._mask] = self._mask_radius
        text = np.array(self._text.copy())
        text[to_hide] = ''
        self._sources_text.text = text
        self.update()
Ejemplo n.º 11
0
    def __init__(self,
                 axis=True,
                 x_label='',
                 name='',
                 bgcolor=(1., 1., 1.),
                 indic_color='darkred',
                 fcn=[]):
        """Init."""
        # Create the main canvas :
        self.canvas = scene.SceneCanvas(keys=None, bgcolor=bgcolor, show=False)
        _ = [self.canvas.connect(k) for k in fcn]  # noqa

        # Create a grid :
        grid = self.canvas.central_widget.add_grid(margin=0)
        grid.spacing = 0

        # Add x-axis :
        self.xaxis = scene.AxisWidget(orientation='bottom', text_color='black')
        if axis:
            pad = grid.add_widget(row=0, col=0)
            pad.width_max = 50
        _col = int(axis)
        grid.add_widget(self.xaxis, row=1, col=_col)

        # Main plot :
        self.wc = grid.add_view(row=0, col=_col, border_color='black')

        # Add a square indicator :
        image = color2vb(indic_color)[np.newaxis, ...]
        self.mesh = scene.visuals.Image(image, name='Time indicator')
        self.mesh.transform = vist.STTransform()
        self.mesh.parent = self.wc.scene

        # Add markers :
        pos = np.full((1, 3), -10, dtype=np.float32)
        self.markers = Markers(pos=pos, parent=self.wc.scene)
        self.markers.set_gl_state('translucent')
Ejemplo n.º 12
0
 def n3_color(self, value):
     """Set n3_color value."""
     color = np.squeeze(color2vb(value))
     self.shared_program.vert['u_n3_color'] = color
     self._n3_color = color
Ejemplo n.º 13
0
    def set_data(self, data=None, axis=None, color=None, title=None,
                 force_shape=None, plt_as='grid'):
        """Set data to the grid of signals.

        Parameters
        ----------
        data : None
            Array of data. Could be 1-D, 2-D or 3-D.
        axis : int | None
            Time axis location.
        random : array_like/string/tuple | 'random'
            Use 'random' for random colors or a color name for uniform color.
        """
        # ====================== CHECKING ======================
        # Axis :
        axis = axis if isinstance(axis, int) else self._axis
        axis = len(self._sh) - 1 if axis == -1 else axis
        # Data :
        if isinstance(data, np.ndarray):
            # -------------- (n_rows, n_cols, n_time) --------------
            if data.ndim == 1:  # 1-D array
                data = data.reshape(1, 1, -1)
                g_size = (1, 1)
            elif data.ndim == 2:  # 2-D array
                if axis == 0:  # data need to be transposed
                    data = np.swapaxes(data, 0, 1)
                    axis = 1
                g_size = (data.shape[0], 1)  # (n_row, 1)
                data = data[np.newaxis, ...]
            elif data.ndim == 3:  # 3-D array
                if axis != data.ndim - 1:  # data need to be transposed
                    data = np.swapaxes(data, axis, -1)
                    axis = data.ndim - 1
                g_size = (data.shape[0], data.shape[1])

            # -------------- Signals index --------------
            m = np.prod(list(data.shape)[0:-1])
            sig_index = np.arange(m).reshape(*g_size)

            # -------------- Plot type --------------
            if plt_as == 'row':
                force_shape = (1, g_size[0] * g_size[1])
            elif plt_as == 'col':
                force_shape = (g_size[0] * g_size[1], 1)

            # -------------- Optimal 2-D --------------
            self._data = data
            self._ori_shape = list(data.shape)[0:-1]
            if force_shape is None:
                n_rows, n_cols = ndsubplot(m)
            elif len(g_size) == 2:
                n_rows, n_cols = force_shape
            data = data.reshape(n_rows, n_cols, len(self))
            sig_index = sig_index.reshape(n_rows, n_cols)
            g_size = (n_rows, n_cols)
            self._opt_shape = list(data.shape)[0:-1]
            self._sig_index = sig_index

            # -------------- (n_rows * n_cols, n_time) --------------
            data = np.reshape(data, (m, len(self)), order='F')

            # -------------- Prepare --------------
            # Force demean / detrend of _prep :
            self._prep.demean, self._prep.detrend = False, False
            data = self._prep._prepare_data(self._sf, data, 0)
            # Demean and normalize :
            kw = {'axis': -1, 'keepdims': True}
            dmax = np.abs(data).max(**kw)
            dmax[dmax == 0.] = 1.
            data -= data.mean(**kw)
            data /= dmax
            # data /= data.max()
            self._dbuffer.set_data(vispy_array(data))
            self.g_size = g_size

        # ====================== INDEX ======================
        n, m = len(self), np.prod(g_size)
        self._sig_index = self._sig_index.reshape(n_rows, n_cols)
        idg = np.c_[np.repeat(np.repeat(np.arange(n_cols), n_rows), n),
                    np.repeat(np.tile(np.arange(n_rows), n_cols), n)[::-1],
                    np.tile(np.arange(n), m)].astype(np.float32)
        self._ibuffer.set_data(vispy_array(idg))

        # ====================== COLOR ======================
        if color is not None:
            color_1d = color2vb(color)
            self.shared_program.frag['u_color'] = color_1d.ravel()

        # ====================== TITLES ======================
        # Titles checking :
        if title is None or (len(title) != m):
            st, it = '({}, {})', product(range(n_rows), range(n_cols))
            title = [st.format(i, k) for i, k in it]
        # Set text and font size :
        if not self._txt.text:
            self._txt.text = title
        # Get titles position :
        x_factor, y_factor = 1. / n_cols, 1. / n_rows
        r_x = np.linspace(-1. + x_factor, 1. - x_factor, n_cols)
        r_x = np.tile(r_x, n_rows)
        r_y = np.linspace(-1. + y_factor, 1. - y_factor, n_rows)[::-1]
        r_y += y_factor
        r_y = np.repeat(r_y, n_cols)
        pos = np.c_[r_x, r_y, np.full_like(r_x, -10.)]
        self._txt.pos = pos.astype(np.float32)
Ejemplo n.º 14
0
    def __init__(self, channels, time, color=(.2, .2, .2), width=1.5,
                 color_detection='red', method='gl', camera=None,
                 parent=None, fcn=None):
        # Initialize PrepareData :
        PrepareData.__init__(self, axis=1)

        # Variables :
        self._camera = camera
        self._preproc_channel = -1
        self.rect = []
        self.width = width
        self.autoamp = False
        self._fcn = fcn
        self.visible = np.array([True] + [False] * (len(channels) - 1))
        self.consider = np.ones((len(channels),), dtype=bool)

        # Get color :
        self.color = color2vb(color)
        self.color_detection = color2vb(color_detection)

        # Create one line per channel :
        pos = np.zeros((1, 3), dtype=np.float32)
        self.mesh, self.report, self.grid, self.peak = [], [], [], []
        self.loc, self.node = [], []
        for i, k in enumerate(channels):
            # ----------------------------------------------
            # Create a node parent :
            node = scene.Node(name=k + 'plot')
            node.parent = parent[i].wc.scene
            self.node.append(node)

            # ----------------------------------------------
            # Create main line (for channel plot) :
            mesh = scene.visuals.Line(pos, name=k + 'plot', color=self.color,
                                      method=method, parent=node)
            mesh.set_gl_state('translucent')
            self.mesh.append(mesh)

            # ----------------------------------------------
            # Create marker peaks :
            mark = Markers(pos=np.zeros((1, 3), dtype=np.float32),
                           parent=node)
            mark.set_gl_state('translucent')
            mark.visible = False
            self.peak.append(mark)

            # ----------------------------------------------
            # Locations :
            loc = scene.visuals.Line(pos, name=k + 'location', method=method,
                                     color=(.1, .1, .1, .3), parent=node,
                                     connect='segments')
            loc.set_gl_state('translucent')
            self.loc.append(loc)

            # ----------------------------------------------
            # Create a grid :
            grid = scene.visuals.GridLines(color=(.1, .1, .1, .5),
                                           scale=(1., .1),
                                           parent=parent[i].wc.scene)
            grid.set_gl_state('translucent')
            self.grid.append(grid)
Ejemplo n.º 15
0
    def __init__(self,
                 data=None,
                 hypno=None,
                 config_file=None,
                 annotations=None,
                 channels=None,
                 sf=None,
                 downsample=100.,
                 axis=True,
                 href=['art', 'wake', 'rem', 'n1', 'n2', 'n3'],
                 preload=True,
                 use_mne=False,
                 kwargs_mne={},
                 verbose=None):
        """Init."""
        _PyQtModule.__init__(self, verbose=verbose, icon='sleep_icon.svg')
        # ====================== APP CREATION ======================
        UiInit.__init__(self)

        # Set default GUI state :
        self._set_default_state()

        # Mouse control :
        MouseEventControl.__init__(self)

        # ====================== LOAD FILE ======================
        PROFILER("Import file", as_type='title')
        ReadSleepData.__init__(self, data, channels, sf, hypno, href, preload,
                               use_mne, downsample, kwargs_mne, annotations)

        # ====================== VARIABLES ======================
        # Check all data :
        self._config_file = config_file
        self._annot_mark = np.array([])
        self._hconvinv = {v: k for k, v in self._hconv.items()}
        self._ax = axis
        # ---------- Default line width ----------
        self._lw = 1.
        self._lwhyp = 2
        self._defwin = 30.
        self._defstd = 5.
        # ---------- Default colors ----------
        self._chancolor = '#292824'
        # self._hypcolor = '#292824'
        # Hypnogram color :
        self._hypcolor = {
            -1: '#8bbf56',
            0: '#56bf8b',
            1: '#aabcce',
            2: '#405c79',
            3: '#0b1c2c',
            4: '#bf5656'
        }
        # Convert color :
        if self._hconv != self._hconvinv:
            hypc = self._hypcolor.copy()
            for k in self._hconv.keys():
                self._hypcolor[k] = hypc[self._hconvinv[k]]
        self._indicol = '#e74c3c'
        # Default spectrogram colormap :
        self._defcmap = 'viridis'
        # Spindles / REM / Peaks colors :
        self._defspin = color2vb('#d73737')
        self._defsw = color2vb('#56bf8b')
        self._defkc = color2vb('#b45a3c')
        self._defrem = color2vb('#6684e1')
        self._defmt = color2vb('#FE8625')
        self._defpeaks = '#b854d4'
        # ---------- Symbol ----------
        self._spinsym = 'x'
        self._swsym = 'o'
        self._kcsym = 'diamond'
        self._remsym = 'triangle_down'
        self._mtsym = 'star'
        self._peaksym = 'disc'
        # ---------- Custom detections ----------
        self._custom_detections = {}
        # Get some data info (min / max / std / mean)
        self._get_data_info()
        PROFILER("Data info")

        # ====================== USER & GUI INTERACTION  ======================
        # User <-> GUI :
        PROFILER("Initialize GUI interactions", as_type='title')
        UiElements.__init__(self)

        # ====================== CAMERAS ======================
        self._cam_creation()

        # ====================== OBJECTS CREATION ======================
        PROFILER("Initialize visual elements", as_type='title')
        Visuals.__init__(self)

        # ====================== FUNCTIONS ON LOAD ======================
        self._fcns_on_creation()
        PROFILER("Functions on creation")
Ejemplo n.º 16
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)

        # ==================== 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)
Ejemplo n.º 17
0
    def set_data(self, data=None, axis=None, color=None, title=None,
                 force_shape=None, plt_as='grid'):
        """Set data to the grid of signals.

        Parameters
        ----------
        data : None
            Array of data. Could be 1-D, 2-D or 3-D.
        axis : int | None
            Time axis location.
        random : array_like/string/tuple | 'random'
            Use 'random' for random colors or a color name for uniform color.
        """
        # ====================== CHECKING ======================
        # Axis :
        axis = axis if isinstance(axis, int) else self._axis
        axis = len(self._sh) - 1 if axis == -1 else axis
        # Data :
        if isinstance(data, np.ndarray):
            # -------------- (n_rows, n_cols, n_time) --------------
            if data.ndim == 1:  # 1-D array
                data = data.reshape(1, 1, -1)
                g_size = (1, 1)
            elif data.ndim == 2:  # 2-D array
                if axis == 0:  # data need to be transposed
                    data = np.swapaxes(data, 0, 1)
                    axis = 1
                g_size = (data.shape[0], 1)  # (n_row, 1)
                data = data[np.newaxis, ...]
            elif data.ndim == 3:  # 3-D array
                if axis != data.ndim - 1:  # data need to be transposed
                    data = np.swapaxes(data, axis, -1)
                    axis = data.ndim - 1
                g_size = (data.shape[0], data.shape[1])

            # -------------- Signals index --------------
            m = np.prod(list(data.shape)[0:-1])
            sig_index = np.arange(m).reshape(*g_size)

            # -------------- Plot type --------------
            if plt_as == 'row':
                force_shape = (1, g_size[0] * g_size[1])
            elif plt_as == 'col':
                force_shape = (g_size[0] * g_size[1], 1)

            # -------------- Optimal 2-D --------------
            self._data = data
            self._ori_shape = list(data.shape)[0:-1]
            if force_shape is None:
                n_rows, n_cols = ndsubplot(m)
            elif len(g_size) == 2:
                n_rows, n_cols = force_shape
            data = data.reshape(n_rows, n_cols, len(self))
            sig_index = sig_index.reshape(n_rows, n_cols)
            g_size = (n_rows, n_cols)
            self._opt_shape = list(data.shape)[0:-1]
            self._sig_index = sig_index

            # -------------- (n_rows * n_cols, n_time) --------------
            data = np.reshape(data, (m, len(self)), order='F')

            # -------------- Prepare --------------
            # Force demean / detrend of _prep :
            self._prep.demean, self._prep.detrend = False, False
            data = self._prep._prepare_data(self._sf, data, 0)
            # Demean and normalize :
            kw = {'axis': -1, 'keepdims': True}
            dmax = np.abs(data).max(**kw)
            dmax[dmax == 0.] = 1.
            data -= data.mean(**kw)
            data /= dmax
            # data /= data.max()
            self._dbuffer.set_data(vispy_array(data))
            self.g_size = g_size

        # ====================== INDEX ======================
        n, m = len(self), np.prod(g_size)
        self._sig_index = self._sig_index.reshape(n_rows, n_cols)
        idg = np.c_[np.repeat(np.repeat(np.arange(n_cols), n_rows), n),
                    np.repeat(np.tile(np.arange(n_rows), n_cols), n)[::-1],
                    np.tile(np.arange(n), m)].astype(np.float32)
        self._ibuffer.set_data(vispy_array(idg))

        # ====================== COLOR ======================
        if color is not None:
            color_1d = color2vb(color)
            self.shared_program.frag['u_color'] = color_1d.ravel()

        # ====================== TITLES ======================
        # Titles checking :
        if title is None or (len(title) != m):
            st, it = '({}, {})', product(range(n_rows), range(n_cols))
            title = [st.format(i, k) for i, k in it]
        # Set text and font size :
        if not self._txt.text:
            self._txt.text = title
        # Get titles position :
        x_factor, y_factor = 1. / n_cols, 1. / n_rows
        r_x = np.linspace(-1. + x_factor, 1. - x_factor, n_cols)
        r_x = np.tile(r_x, n_rows)
        r_y = np.linspace(-1. + y_factor, 1. - y_factor, n_rows)[::-1]
        r_y += y_factor
        r_y = np.repeat(r_y, n_cols)
        pos = np.c_[r_x, r_y, np.full_like(r_x, -10.)]
        self._txt.pos = pos.astype(np.float32)
Ejemplo n.º 18
0
    def __init__(self,
                 channels,
                 time,
                 color=(.2, .2, .2),
                 width=1.5,
                 color_detection='red',
                 method='gl',
                 camera=None,
                 parent=None,
                 fcn=None):
        # Initialize PrepareData :
        PrepareData.__init__(self, axis=1)

        # Variables :
        self._camera = camera
        self._preproc_channel = -1
        self.rect = []
        self.width = width
        self.autoamp = False
        self._fcn = fcn
        self.visible = np.array([True] + [False] * (len(channels) - 1))
        self.consider = np.ones((len(channels), ), dtype=bool)

        # Get color :
        self.color = color2vb(color)
        self.color_detection = color2vb(color_detection)

        # Create one line per channel :
        pos = np.zeros((1, 3), dtype=np.float32)
        self.mesh, self.report, self.grid, self.peak = [], [], [], []
        self.loc, self.node = [], []
        for i, k in enumerate(channels):
            # ----------------------------------------------
            # Create a node parent :
            node = scene.Node(name=k + 'plot')
            node.parent = parent[i].wc.scene
            self.node.append(node)

            # ----------------------------------------------
            # Create main line (for channel plot) :
            mesh = scene.visuals.Line(pos,
                                      name=k + 'plot',
                                      color=self.color,
                                      method=method,
                                      parent=node)
            mesh.set_gl_state('translucent')
            self.mesh.append(mesh)

            # ----------------------------------------------
            # Create marker peaks :
            mark = Markers(pos=np.zeros((1, 3), dtype=np.float32), parent=node)
            mark.set_gl_state('translucent')
            mark.visible = False
            self.peak.append(mark)

            # ----------------------------------------------
            # Locations :
            loc = scene.visuals.Line(pos,
                                     name=k + 'location',
                                     method=method,
                                     color=(.1, .1, .1, .3),
                                     parent=node,
                                     connect='segments')
            loc.set_gl_state('translucent')
            self.loc.append(loc)

            # ----------------------------------------------
            # Create a grid :
            grid = scene.visuals.GridLines(color=(.1, .1, .1, .5),
                                           scale=(1., .1),
                                           parent=parent[i].wc.scene)
            grid.set_gl_state('translucent')
            self.grid.append(grid)
Ejemplo n.º 19
0
 def edge_color(self, value):
     """Set edge_color value."""
     color = color2vb(value, alpha=self.alpha)
     self._sources._data['a_fg_color'] = color
     self._edge_color = color
     self.update()
Ejemplo n.º 20
0
    def color_sources(self,
                      analysis=None,
                      color_by=None,
                      data=None,
                      roi_to_color=None,
                      color_others='black',
                      hide_others=False,
                      cmap='viridis',
                      clim=None,
                      vmin=None,
                      vmax=None,
                      under='gray',
                      over='red'):
        """Custom color sources methods.

        This method can be used to color sources :

            * According to a data vector. In that case, source's colors are
              inferred using colormap inputs (i.e cmap, vmin, vmax, clim, under
              and over)
            * According to ROI analysis (using the `analysis` and `color_by`
              input parameters)

        Parameters
        ----------
        data : array_like | None
            A vector of data with the same length as the number os sources.
            The color is inferred from this data vector and can be controlled
            using the cmap, clim, vmin, vmax, under and over parameters.
        analysis : pandas.DataFrames | None
            ROI analysis runned using the analyse_sources method.
        color_by : string | None
            A column name of the analysis DataFrames. This columns is then used
            to identify the color to set to each source inside ROI.
        roi_to_color : dict | None
            Define custom colors to ROI. For example use {'BA4': 'red',
            'BA32': 'blue'} to define custom colors. If roi_to_color is None,
            random colors will be used instead.
        color_others : array_like/tuple/string | 'black'
            Specify how to color sources that are not found using the
            roi_to_color dictionary.
        hide_others : bool | False
            Show or hide sources that are not found using the
            roi_to_color dictionary.
        """
        if isinstance(data, np.ndarray):
            assert len(data) == len(self) and (data.ndim == 1)
            logger.info("    Color %s using a data vector" % self.name)
            kw = self._update_cbar_args(cmap, clim, vmin, vmax, under, over)
            colors = array2colormap(data, **kw)
        elif (analysis is not None) and (color_by is not None):
            # Group analysis :
            assert color_by in list(analysis.columns)
            logger.info("    Color %s according to the %s" %
                        (self.name, color_by))
            gp = analysis.groupby(color_by).groups
            # Compute color :
            if roi_to_color is None:  # random color
                # Predefined colors and define unique color for each ROI :
                colors = np.zeros((len(self), 3), dtype=np.float32)
                u_col = np.random.uniform(.1, .8, (len(gp), 3))
                u_col = u_col.astype(np.float32)
                # Assign color to the ROI :
                for k, index in enumerate(gp.values()):
                    colors[list(index), :] = u_col[k, :]
            elif isinstance(roi_to_color, dict):  # user defined colors
                colors = color2vb(color_others, length=len(self))
                keep_visible = np.zeros(len(self), dtype=bool)
                for roi_name, roi_col in roi_to_color.items():
                    if roi_name in list(gp.keys()):
                        colors[list(gp[roi_name]), :] = color2vb(roi_col)
                        keep_visible[list(gp[roi_name])] = True
                    else:
                        warn("%s not found in the %s column of analysis"
                             "." % (roi_name, color_by))
                if hide_others:
                    self.visible = keep_visible
            else:
                raise TypeError("roi_to_color must either be None or a "
                                "dictionary like {'roi_name': 'red'}.")
        self.color = colors
Ejemplo n.º 21
0
 def n3_color(self, value):
     """Set n3_color value."""
     color = np.squeeze(color2vb(value))
     self.shared_program.vert['u_n3_color'] = color
     self._n3_color = color
Ejemplo n.º 22
0
 def tcolor(self, value):
     """Set tcolor value."""
     self._txt.color = color2vb(value)
Ejemplo n.º 23
0
    def __init__(self,
                 name,
                 xyz,
                 data=None,
                 color='red',
                 alpha=1.,
                 symbol='disc',
                 radius_min=5.,
                 radius_max=10.,
                 edge_width=0.,
                 edge_color='black',
                 system='mni',
                 mask=None,
                 mask_color='gray',
                 mask_radius=5.,
                 text=None,
                 text_size=2.,
                 text_color='white',
                 text_bold=False,
                 text_translate=(0., 2., 0.),
                 visible=True,
                 transform=None,
                 parent=None,
                 verbose=None,
                 _z=-10.,
                 **kw):
        """Init."""
        VisbrainObject.__init__(self, name, parent, transform, verbose, **kw)
        # _______________________ CHECKING _______________________
        # XYZ :
        sh = xyz.shape
        assert sh[1] in [2, 3]
        self._n_sources = sh[0]
        pos = xyz if sh[1] == 3 else np.c_[xyz, np.full((len(self), ), _z)]
        logger.info('    %i sources detected' % self._n_sources)
        # Radius min and max :
        assert all(
            [isinstance(k, (int, float)) for k in (radius_min, radius_max)])
        radius_max = max(radius_min, radius_max)
        self._radius_min, self._radius_max = radius_min, radius_max
        self._mask_radius = mask_radius
        # Data :
        if data is None:
            data = np.ones((len(self), ))
        else:
            assert np.shape(data)[0] == len(self)
        self._data = vispy_array(data)
        # System :
        pos = pos if system == 'mni' else tal2mni(pos)
        self._xyz = vispy_array(pos)
        # Color :
        self._color = color
        # Edges :
        self._edge_color, self._edge_width = edge_color, edge_width
        # Mask :
        if mask is None:
            mask = [False] * len(self)
        self._mask = np.asarray(mask).ravel().astype(bool)
        assert len(self._mask) == len(self)
        self._mask_color = color2vb(mask_color)
        # Text :
        self._text_size = text_size
        self._text_color = text_color
        self._text_translate = text_translate

        # _______________________ MARKERS _______________________
        self._sources = visuals.Markers(pos=self._xyz,
                                        name='Markers',
                                        edge_color=edge_color,
                                        edge_width=edge_width,
                                        symbol=symbol,
                                        parent=self._node)
        self._sources.set_gl_state('translucent',
                                   depth_test=True,
                                   cull_face=False)

        # _______________________ TEXT _______________________
        tvisible = text is None
        self._text = [''] * len(self) if tvisible else text
        self._text = np.array(self._text)
        assert len(self._text) == len(self)
        self._sources_text = visuals.Text(self._text,
                                          pos=self._xyz,
                                          bold=text_bold,
                                          name='Text',
                                          color=color2vb(text_color),
                                          font_size=text_size,
                                          parent=self._node)
        self._sources_text.visible = not tvisible
        tr = vist.STTransform(translate=text_translate)
        self._sources_text.transform = tr

        # _______________________ UPDATE _______________________
        # Radius / color :
        self.visible = visible
        self._update_radius()
        self.alpha = alpha
        self._update_color()
Ejemplo n.º 24
0
 def mask_color(self, value):
     """Set mask_color value."""
     value = color2vb(value).ravel()
     self._mask_color = value
     self._build_bgd_texture()
Ejemplo n.º 25
0
 def mask_color(self, value):
     """Set mask_color value."""
     self._mask_color = color2vb(value)
     self._update_color()
Ejemplo n.º 26
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)

        # ==================== 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)
Ejemplo n.º 27
0
 def text_color(self, value):
     """Set text_color value."""
     color = color2vb(value)
     self._sources_text.color = color
     self._text_color = color
     self._sources_text.update()
Ejemplo n.º 28
0
 def mask_color(self, value):
     """Set mask_color value."""
     value = color2vb(value).ravel()
     self._mask_color = value
     self._build_bgd_texture()
Ejemplo n.º 29
0
 def tcolor(self, value):
     """Set tcolor value."""
     self._txt.color = color2vb(value)
Ejemplo n.º 30
0
    def set_data(self,
                 data,
                 index,
                 color='black',
                 lw=2.,
                 nbins=10,
                 symbol='disc',
                 size=10.,
                 form='line',
                 th=None,
                 norm=None,
                 window=None,
                 overlap=0.,
                 baseline=None,
                 clim=None,
                 cmap='viridis',
                 interpolation='gaussian',
                 nperseg=256,
                 noverlap=128):
        """Set data to the plot.

        Parameters
        ----------
        data : array_like
            Raw data vector of shape (N,)
        index : int | 0
            Index of the 3-d array.
        color : array_like/string/tuple | None
            Color of the plot.
        lw : float | None
            Line width (form='line').
        symbol : string | None
            Marker symbol (form='marker').
        size : float | None
            Marker size (form='marker').
        nbins : int | None
            Number of bins for the histogram (form='histogram')
        form : {'line', 'marker', 'histogram', 'tf'}
            Plotting type.
        th : tuple | None
            Tuple of floats for line thresholding.
        norm : int | None
            Normalization method for (form='tf').
        window : tuple | None
            Averaging window (form='tf').
        overlap : float | 0.
            Overlap between successive windows (form='tf').
        baseline : tuple | None
            Baseline period for the normalization (form='tf').
        """
        # Update variable :
        self.form = form
        self._index = index
        color = color2vb(color)

        # Get data index :
        if data.ndim == 1:
            idx = slice(None)
        elif data.ndim in [2, 3]:
            idx = list(self._navidx[index])
            idx.insert(self._axis, slice(None))
            idx = tuple(idx)

        # Convert data to be compatible with VisPy and prepare data :
        data_c = vispy_array(data[idx]).copy()
        _data = self._prep._prepare_data(self._sf, data_c, self._time)

        # Set data :
        if form in ['line', 'marker', 'psd', 'butterfly']:  # line and marker
            # Get position array :
            pos = np.c_[self._time, _data]
            # Send position :
            if form in ['line', 'psd']:
                if form == 'psd':
                    fmax = self._sf / 4.
                    f, pxx = welch(_data,
                                   self._sf,
                                   nperseg=nperseg,
                                   noverlap=noverlap)
                    f_sf4 = abs(f - fmax)
                    f_1 = abs(f - 1.)
                    fidx_sf4 = np.where(f_sf4 == f_sf4.min())[0][0]
                    fidx_1 = np.where(f_1 == f_1.min())[0][0]
                    pos = np.c_[f[fidx_1:-fidx_sf4], pxx[fidx_1:-fidx_sf4]]
                # Threshold :
                is_th = isinstance(th, (tuple, list, np.ndarray))
                col = color2vb(color, length=pos.shape[0])
                if is_th:
                    # Build threshold segments :
                    t_min, t_max = self._time.min(), self._time.max()
                    pos_th = np.vstack(
                        ([t_min, th[0]], [t_max,
                                          th[0]], [t_min,
                                                   th[1]], [t_max, th[1]]))
                    self._th.set_data(pos_th,
                                      connect='segments',
                                      color=color2vb('#ab4642'))
                    # Build line color :
                    col = color2vb(color, length=len(_data))
                    cond = np.logical_or(_data < th[0], _data > th[1])
                    col[cond, :] = color2vb('#ab4642')
                self._th.visible = is_th
                self._line.set_data(pos, width=lw, color=col)
                self._line.update()
            elif form == 'marker':
                self._mark.set_data(pos,
                                    face_color=color,
                                    symbol=symbol,
                                    size=size,
                                    edge_width=0.)
                self._mark.update()
            elif form == 'butterfly':
                # Get soe shape related variables :
                n, m = len(self._time), int(np.prod(data.shape))
                n_rep = int(m / n)
                data = vispy_array(data)
                # Build position :
                pos = np.c_[np.tile(self._time.ravel(), n_rep), data.ravel()]
                # Disconnect some points :
                connect = np.c_[np.arange(m - 1), np.arange(1, m)]
                to_delete = np.linspace(n - 1, m - 1, n_rep)
                connect = np.delete(connect, to_delete, axis=0)
                # Build color :
                col = color2vb(color, length=m)
                # singcol = np.random.uniform(size=(n_rep, 3), low=.2,
                #                             high=.8).astype(np.float32)
                # col = np.repeat(singcol, n, 0)
                # Send data :
                self._line.set_data(pos, width=lw, color=col, connect=connect)
                self._line.update()
            # Get camera rectangle :
            t_min, t_max = pos[:, 0].min(), pos[:, 0].max()
            d_min, d_max = pos[:, 1].min(), pos[:, 1].max()
            off = .05 * (d_max - d_min)
            self.rect = (t_min, d_min - off, t_max - t_min,
                         d_max - d_min + 2 * off)
        elif form == 'histogram':  # histogram
            # Compute the mesh :
            mesh = scene.visuals.Histogram(_data, nbins)
            # Get the vertices and faces of the mesh :
            vert = mesh.mesh_data.get_vertices()
            faces = mesh.mesh_data.get_faces()
            # Pass vertices and faces to the histogram :
            self._hist.set_data(vert, faces, color=color)
            # Compute the histogram :
            raw, xvec = np.histogram(_data, nbins)
            # Get camera rectangle :
            t_min, t_max = xvec.min(), xvec.max()
            d_min, d_max = 0.9 * raw[np.nonzero(raw)].min(), 1.01 * raw.max()
            self.rect = (t_min, d_min, t_max - t_min, d_max - d_min)
            # Update object :
            self._hist.update()
        elif form == 'tf':  # time-frequency map
            self._tf.set_data(_data,
                              self._sf,
                              cmap=cmap,
                              contrast=.5,
                              norm=norm,
                              baseline=baseline,
                              n_window=window,
                              overlap=overlap,
                              window='hanning',
                              clim=clim)
            self._tf.interpolation = interpolation
            self.rect = self._tf.rect

        # Hide non form elements :
        self._visibility()

        # Update annotations :
        self.update_annotations(str(self))
Ejemplo n.º 31
0
    def __init__(self, data=None, hypno=None, config_file=None,
                 annotations=None, channels=None, sf=None, downsample=100.,
                 axis=True, href=['art', 'wake', 'rem', 'n1', 'n2', 'n3'],
                 preload=True, use_mne=False, kwargs_mne={}, verbose=None):
        """Init."""
        _PyQtModule.__init__(self, verbose=verbose, icon='sleep_icon.svg')
        # ====================== APP CREATION ======================
        UiInit.__init__(self)

        # Set default GUI state :
        self._set_default_state()

        # Mouse control :
        MouseEventControl.__init__(self)

        # ====================== LOAD FILE ======================
        PROFILER("Import file", as_type='title')
        ReadSleepData.__init__(self, data, channels, sf, hypno, href, preload,
                               use_mne, downsample, kwargs_mne,
                               annotations)

        # ====================== VARIABLES ======================
        # Check all data :
        self._config_file = config_file
        self._annot_mark = np.array([])
        self._hconvinv = {v: k for k, v in self._hconv.items()}
        self._ax = axis
        # ---------- Default line width ----------
        self._lw = 1.
        self._lwhyp = 2
        self._defwin = 30.
        self._defstd = 5.
        # ---------- Default colors ----------
        self._chancolor = '#292824'
        # self._hypcolor = '#292824'
        # Hypnogram color :
        self._hypcolor = {-1: '#8bbf56', 0: '#56bf8b', 1: '#aabcce',
                          2: '#405c79', 3: '#0b1c2c', 4: '#bf5656'}
        # Convert color :
        if self._hconv != self._hconvinv:
            hypc = self._hypcolor.copy()
            for k in self._hconv.keys():
                self._hypcolor[k] = hypc[self._hconvinv[k]]
        self._indicol = '#e74c3c'
        # Default spectrogram colormap :
        self._defcmap = 'viridis'
        # Spindles / REM / Peaks colors :
        self._defspin = color2vb('#d73737')
        self._defsw = color2vb('#56bf8b')
        self._defkc = color2vb('#b45a3c')
        self._defrem = color2vb('#6684e1')
        self._defmt = color2vb('#FE8625')
        self._defpeaks = '#b854d4'
        # ---------- Symbol ----------
        self._spinsym = 'x'
        self._swsym = 'o'
        self._kcsym = 'diamond'
        self._remsym = 'triangle_down'
        self._mtsym = 'star'
        self._peaksym = 'disc'
        # ---------- Custom detections ----------
        self._custom_detections = {}
        # Get some data info (min / max / std / mean)
        self._get_data_info()
        PROFILER("Data info")

        # ====================== USER & GUI INTERACTION  ======================
        # User <-> GUI :
        PROFILER("Initialize GUI interactions", as_type='title')
        UiElements.__init__(self)

        # ====================== CAMERAS ======================
        self._cam_creation()

        # ====================== OBJECTS CREATION ======================
        PROFILER("Initialize visual elements", as_type='title')
        Visuals.__init__(self)

        # ====================== FUNCTIONS ON LOAD ======================
        self._fcns_on_creation()
        PROFILER("Functions on creation")