예제 #1
0
    def __init__(self, parent=None, parent_sp=None, visible=True, cmap='gray'):
        """Init."""
        CrossSectionsSplit.__init__(self, parent_sp)
        self._visible_cs = visible
        self._cmap_cs = cmap
        #######################################################################
        #                           TRANFORMATIONS
        #######################################################################
        # Translations :
        self._tr_coron = vist.STTransform()
        self._tr_sagit = vist.STTransform()
        self._tr_axial = vist.STTransform()
        # Rotations :
        rot_m90x = vist.MatrixTransform(rotate(-90, [1, 0, 0]))
        rot_180x = vist.MatrixTransform(rotate(180, [1, 0, 0]))
        rot_90y = vist.MatrixTransform(rotate(90, [0, 1, 0]))
        rot_m90y = vist.MatrixTransform(rotate(-90, [0, 1, 0]))
        rot_m180y = vist.MatrixTransform(rotate(-180, [0, 1, 0]))
        rot_90z = vist.MatrixTransform(rotate(90, [0, 0, 1]))
        # Tranformations :
        tf_sagit = [self._tr_sagit, rot_90z, rot_m90y, rot_m90x]
        tf_coron = [self._tr_coron, rot_90z, rot_180x, rot_90y]
        tf_axial = [self._tr_axial, rot_m180y, rot_90z]

        #######################################################################
        #                            ELEMENTS
        #######################################################################
        # Create a root node :
        self._node_cs = scene.Node(name='Cross-Sections')
        self._node_cs.parent = parent
        self._node_cs.visible = visible
        # Axial :
        self.axial = ImageSection(parent=self._node_cs, name='Axial')
        self.axial.transform = vist.ChainTransform(tf_axial)
        # Coronal :
        self.coron = ImageSection(parent=self._node_cs, name='Coronal')
        self.coron.transform = vist.ChainTransform(tf_coron)
        # Sagittal :
        self.sagit = ImageSection(parent=self._node_cs, name='Sagittal')
        self.sagit.transform = vist.ChainTransform(tf_sagit)
        # Set GL state :
        kwargs = {
            'depth_test': True,
            'cull_face': False,
            'blend': False,
            'blend_func': ('src_alpha', 'one_minus_src_alpha')
        }
        self.sagit.set_gl_state('translucent', **kwargs)
        self.coron.set_gl_state('translucent', **kwargs)
        self.axial.set_gl_state('translucent', **kwargs)
예제 #2
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
예제 #3
0
    def __init__(
            self,
            hidden=False):  # hidden=true useful for speed when creating video
        self.canvas = scene.SceneCanvas(keys='interactive',
                                        size=(1900, 1145),
                                        show=not hidden,
                                        config=dict(samples=4),
                                        resizable=True,
                                        always_on_top=True,
                                        bgcolor='white',
                                        vsync=True)

        # Set up a viewbox to display the cube with interactive arcball
        self.view = self.canvas.central_widget.add_view()
        self.view.bgcolor = '#efefef'
        self.view.camera = TurntableCamera(fov=60.0,
                                           elevation=30.0,
                                           azimuth=280.0)

        # add a colored 3D axis for orientation
        axis = scene.visuals.XYZAxis(parent=self.view.scene)
        self.cfs = []
        self.spheres = []
        self.crumbs = []
        self.markers = scene.visuals.Markers(parent=self.view.scene)
        self.markers.transform = transforms.STTransform()
        self.obstacles = []
예제 #4
0
 def set_data(self,
              tox=None,
              width=None,
              time=None,
              unit='seconds',
              markers=None):
     """Move the main square."""
     # Get factor according to unit :
     if unit == 'seconds':
         fact = 1.
     elif unit == 'minutes':
         fact = 60.
     elif unit == 'hours':
         fact = 3660.
     # Move the square
     if (tox, width, time) != (None, None, None):
         self.mesh.transform = vist.STTransform(translate=tox / fact,
                                                scale=width / fact)
         # Update camera :
         self.wc.camera.rect = (0, 0, (time.max() - time.min()) / fact, 1)
     # Set markers :
     if markers is not None:
         if markers.size:
             pos = np.zeros((len(markers), 3), dtype=np.float32)
             pos[:, 0] = markers / fact
             pos[:, 1] = .5
             pos[:, 2] = -10
         else:
             pos = np.full((1, 3), -10, dtype=np.float32)
         self.markers.set_data(pos=pos,
                               symbol='triangle_down',
                               size=20.,
                               face_color='#42ab46',
                               edge_width=0.)
예제 #5
0
 def _rescale(self):
     height, width = self._data.shape[:2]
     vscale = -2. / height
     hscale = 2. / width
     zdepth = -0.01 * self._order
     transform = transforms.STTransform(scale=(hscale, vscale),
                                        translate=(-1, 1, zdepth))
     self.visual.transform = transform
예제 #6
0
def test_st_mapping():
    p1 = [[5., 7.], [23., 8.]]
    p2 = [[-1.3, -1.4], [1.1, 1.2]]

    t = tr.STTransform()
    t.set_mapping(p1, p2)

    assert np.allclose(t.map(p1)[:, :len(p2)], p2)
예제 #7
0
    def __init__(self, scale, coo):
        self.obj = scene.visuals.Box(width=1, height=1, edge_color='black')

        self.obj.transform = transforms.STTransform(translate=(0., 0., 0.),
                                                    scale=(scale, scale,
                                                           scale))

        self.coo = coo
예제 #8
0
    def __init__(self):
        app.Canvas.__init__(self, keys='interactive')
        self.size = (800, 800)
        global pos
        self.visuals = []
        polygon = visuals.PolygonVisual(pos=pos,
                                        color=(0.8, .2, 0, 1),
                                        border_color=(1, 1, 1, 1))
        polygon.transform = transforms.STTransform(scale=(200, 200),
                                                   translate=(600, 600))
        self.visuals.append(polygon)

        ellipse = visuals.EllipseVisual(pos=(0, 0, 0),
                                        radius=(100, 100),
                                        color=(0.2, 0.2, 0.8, 1),
                                        border_color=(1, 1, 1, 1),
                                        start_angle=180.,
                                        span_angle=150.)
        ellipse.transform = transforms.STTransform(scale=(0.9, 1.5),
                                                   translate=(200, 200))
        self.visuals.append(ellipse)

        rect = visuals.RectangleVisual(pos=(600, 200, 0),
                                       height=200.,
                                       width=300.,
                                       radius=[30., 30., 0., 0.],
                                       color=(0.5, 0.5, 0.2, 1),
                                       border_color='white')
        rect.transform = transforms.NullTransform()
        self.visuals.append(rect)

        rpolygon = visuals.RegularPolygonVisual(pos=(200., 600., 0),
                                                radius=160,
                                                color=(0.2, 0.8, 0.2, 1),
                                                border_color=(1, 1, 1, 1),
                                                sides=6)
        rpolygon.transform = transforms.NullTransform()
        self.visuals.append(rpolygon)

        for v in self.visuals:
            v.tr_sys = transforms.TransformSystem(self)
            v.tr_sys.visual_to_document = v.transform

        self.show()
        self._timer = app.Timer('auto', connect=self.on_timer, start=True)
예제 #9
0
    def __init__(self):
        app.Canvas.__init__(self, keys='interactive', size=(800, 800))
        global pos
        self.visuals = []
        polygon = visuals.PolygonVisual(pos=pos,
                                        color=(0.8, .2, 0, 1),
                                        border_color=(1, 1, 1, 1),
                                        border_width=3)
        polygon.transform = transforms.STTransform(scale=(200, 200),
                                                   translate=(600, 600))
        self.visuals.append(polygon)

        ellipse = visuals.EllipseVisual(center=(0, 0, 0),
                                        radius=(100, 150),
                                        color=(0.2, 0.2, 0.8, 1),
                                        border_color=(1, 1, 1, 1),
                                        border_width=3,
                                        start_angle=180.,
                                        span_angle=150.)
        ellipse.transform = transforms.STTransform(scale=(0.9, 1.5),
                                                   translate=(200, 300))
        self.visuals.append(ellipse)

        rect = visuals.RectangleVisual(center=(600, 200, 0),
                                       height=200.,
                                       width=300.,
                                       radius=[30., 30., 0., 0.],
                                       color=(0.5, 0.5, 0.2, 1),
                                       border_width=3,
                                       border_color='white')
        rect.transform = transforms.NullTransform()
        self.visuals.append(rect)

        rpolygon = visuals.RegularPolygonVisual(center=(200., 600., 0),
                                                radius=160,
                                                color=(0.2, 0.8, 0.2, 1),
                                                border_color=(1, 1, 1, 1),
                                                border_width=3,
                                                sides=6)
        rpolygon.transform = transforms.NullTransform()
        self.visuals.append(rpolygon)

        self.show()
예제 #10
0
    def __init__(self,
                 name,
                 data,
                 xyz,
                 select=None,
                 line_width=1.5,
                 color='white',
                 ts_amp=6.,
                 ts_width=20.,
                 alpha=1.,
                 antialias=False,
                 translate=(0., 0., 1.),
                 transform=None,
                 parent=None,
                 verbose=None,
                 _z=-10.,
                 **kw):
        """Init."""
        # Init Visbrain object base class :
        VisbrainObject.__init__(self, name, parent, transform, verbose, **kw)
        # _______________________ CHECKING _______________________
        # Data :
        assert isinstance(data, np.ndarray) and data.ndim == 2
        self._n_nodes, self._n_pts = data.shape
        self._data = data
        # XYZ :
        sh = xyz.shape
        assert sh[1] in [2, 3]
        xyz = xyz if sh[1] == 3 else np.c_[xyz, np.full((len(self), ), _z)]
        self._xyz = xyz.astype(np.float32)
        # Select :
        select = np.arange(len(self)) if select is None else select
        assert isinstance(select, (list, np.ndarray))
        self._select = select
        # Amplitude / width :
        assert isinstance(ts_amp, float) and isinstance(ts_width, float)
        self._ts_amp, self._ts_width = ts_amp, ts_width
        # Translate :
        assert len(translate) == 3
        tr = vist.STTransform(translate=translate)
        self._translate = translate
        # Line width :
        self._line_width = line_width
        # Color :
        self._color = color2vb(color, alpha=alpha)
        self._alpha = alpha

        # _______________________ LINE _______________________
        self._ts = visuals.Line(name='TimeSeriesObjLine',
                                parent=self._node,
                                width=line_width,
                                color=self._color,
                                antialias=antialias)
        self._ts.transform = tr
        self._build_line()
예제 #11
0
 def _define_transformation(self):
     sh = self._sh
     r90 = vist.MatrixTransform()
     r90.rotate(90, (0, 0, 1))
     rx180 = vist.MatrixTransform()
     rx180.rotate(180, (1, 0, 0))
     # Sagittal transformation :
     norm_sagit = vist.STTransform(scale=(1. / sh[1], 1. / sh[2], 1.),
                                   translate=(-1., 0., 0.))
     tf_sagit = vist.ChainTransform([norm_sagit, r90, rx180])
     self._im_sagit.transform = tf_sagit
     # Coronal transformation :
     norm_coron = vist.STTransform(scale=(1. / sh[0], 1. / sh[2], 1.),
                                   translate=(0., 0., 0.))
     tf_coron = vist.ChainTransform([norm_coron, r90, rx180])
     self._im_coron.transform = tf_coron
     # Axial transformation :
     norm_axis = vist.STTransform(scale=(2. / sh[1], 2. / sh[0], 1.),
                                  translate=(-1., 0., 0.))
     tf_axial = vist.ChainTransform([norm_axis, rx180])
     self._im_axial.transform = tf_axial
예제 #12
0
    def __init__(self,
                 name,
                 data,
                 xyz,
                 select=None,
                 pic_width=7.,
                 pic_height=7.,
                 alpha=1.,
                 cmap='viridis',
                 clim=None,
                 vmin=None,
                 vmax=None,
                 under='gray',
                 over='red',
                 translate=(0., 0., 1.),
                 transform=None,
                 parent=None,
                 verbose=None,
                 _z=-10.,
                 **kw):
        """Init."""
        VisbrainObject.__init__(self, name, parent, transform, verbose, **kw)
        self._update_cbar_args(cmap, clim, vmin, vmax, under, over)

        # _______________________ CHECKING _______________________
        # Data :
        assert isinstance(data, np.ndarray) and data.ndim == 3.
        self._n_nodes = data.shape[0]
        self._minmax = (data.min(), data.max())
        # XYZ :
        sh = xyz.shape
        assert (sh[1] in [2, 3]) and (sh[0] == len(self))
        xyz = xyz if sh[1] == 3 else np.c_[xyz, np.full((len(self), ), _z)]
        self._xyz = xyz.astype(np.float32)
        # Select :
        assert (select is None) or isinstance(select, (list, np.ndarray))
        # Width, height :
        assert all(
            [isinstance(k, (int, float)) for k in (pic_height, pic_width)])
        self._pic_width, self._pic_height = pic_width, pic_height
        # Translate :
        assert len(translate) == 3
        tr = vist.STTransform(translate=translate)
        self._translate = translate
        # Alpha :
        assert isinstance(alpha, (int, float)) and (0. <= alpha <= 1.)
        self._alpha = alpha

        # _______________________ IMAGE _______________________
        self._pic = PicMesh(data, xyz, pic_width, pic_height, translate,
                            select, **self.to_kwargs())
        self._pic.transform = tr
        self._pic.parent = self._node
예제 #13
0
 def on_resize(self, event):
     gloo.set_viewport(0, 0, *event.physical_size)
     vp = (0, 0, self.physical_size[0], self.physical_size[1])
     self.context.set_viewport(*vp)
     for visual in self.visuals:
         # TODO on Retina display, this needs to be 0.5, due to Hi-DPI, otherwise
         # lines are not shown where expected
         scale = 0.5
         visual.transform = transforms.STTransform(scale=(vp[2] * scale,
                                                          vp[3] * scale,
                                                          1.))
         visual.transforms.configure(canvas=self, viewport=vp)
예제 #14
0
def test_st_transform():
    # Check that STTransform maps exactly like MatrixTransform
    pts = np.random.normal(size=(10, 4))

    scale = (1, 7.5, -4e-8)
    translate = (1e6, 0.2, 0)
    st = tr.STTransform(scale=scale, translate=translate)
    at = tr.MatrixTransform()
    at.scale(scale)
    at.translate(translate)

    assert np.allclose(st.map(pts), at.map(pts))
    assert np.allclose(st.inverse.map(pts), at.inverse.map(pts))
예제 #15
0
def test_isocurve(ctx):
  ctx = VispyCtx(display_status=True)

  scale = 0.1
  cx = np.arange(-100, 100, scale)
  data = np.meshgrid(cx, cx)
  ff = f(data)
  levels = [0, 10]

  image = Image(ff, parent=ctx.view.scene)
  # move image behind curves
  image.transform = transforms.STTransform(scale=(scale, scale), translate=(0, 0, 0.5))
  color_lev = ['r', 'black']
  curve = Isocurve(ff, levels=levels, color_lev=color_lev, parent=ctx.view.scene)
  curve.transform = transforms.STTransform(scale=(scale, scale))

  # Set 2D camera
  ctx.view.camera = PanZoomCamera(aspect=1)
  # the camera will scale to the contents in the scene
  ctx.view.camera.set_range()
  ctx.run(cam=False)
  return ctx
예제 #16
0
    def set_data(self, xlim, ylim):
        """Move the visual indicator.

        Args:
            xlim: tuple
                A tuple of two float indicating where xlim start and xlim end.

            ylim: tuple
                A tuple of two floats indicating where ylim start and ylim end.
        """
        tox = (xlim[0], ylim[0], -1.)
        sc = (xlim[1] - xlim[0], ylim[1] - ylim[0], 1.)
        # Move the square
        self.mesh.transform = vist.STTransform(translate=tox, scale=sc)
예제 #17
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
예제 #18
0
    def __init__(self, camera, parent=None, fcn=None):
        # Initialize PrepareData :
        PrepareData.__init__(self, axis=0)

        # Keep camera :
        self._camera = camera
        self._rect = (0., 0., 0., 0.)
        self._fcn = fcn

        # Time-frequency map
        self.tf = TFmapsMesh(parent=parent)
        # Spectrogram
        self.mesh = scene.visuals.Image(np.zeros((2, 2)), parent=parent,
                                        name='Fourier transform')
        self.mesh.transform = vist.STTransform()
예제 #19
0
 def __init__(self, parent=None):
     """Init."""
     # Create two dictionaries (for coordinates and text) :
     self._annotations = {}
     self._annotations_txt = {}
     # Create markers for annotations :
     pos = np.random.rand(2, 3)
     self._annot_mark = scene.visuals.Markers(pos=pos, parent=parent)
     self._annot_mark.visible = False
     # Create text for annotations :
     self._annot_text = scene.visuals.Text(parent=parent,
                                           anchor_x='left',
                                           bold=True,
                                           font_size=14.)
     tr = (self._time.max() - self._time.min()) / 50.
     self._annot_text.transform = vist.STTransform(translate=(tr, 0., 0.))
     self._annot_text.visible = False
예제 #20
0
    def get_st_transform(self, z, x, y):
        """
        Return the STTransform for the current zoom, x, and y tile.
        """

        bbox = mercantile.xy_bounds(x, y, z)
        scale = (bbox.right - bbox.left) / 256
        scale = scale, scale, 1

        # place the tiles up high, so that everything will show up correctly
        # TODO: figure out why setting z super high works!  Not sure if it's
        # expected behavior or just a detail of the current Vispy
        # implementation.  Seems like setting order would be a better way,
        # but it doesn't work.
        # If we ever switch to a different type of camera probably nothing
        # will work.
        translate = bbox.left, bbox.bottom, 9e5 - z
        return transforms.STTransform(scale=scale, translate=translate)
예제 #21
0
    def plot(self):
        with open("./episode_1.pkl", "rb") as f:
            self.data = pickle.load(f)
        canvas = vispy.scene.SceneCanvas(keys="interactive",
                                         show=True,
                                         bgcolor="white")
        view = canvas.central_widget.add_view()

        self.idx = 0
        colors = cm.get_cmap("tab10")(np.linspace(0.0, 1.0, 10))
        self.color_id = colors[self.data["particle_ids"][0, self.idx, :, 1]]
        self.data["flex_states"][:, :, :, [0, 1, 2]] = self.data[
            "flex_states"][:, :, :, [0, 2, 1]]
        pos = self.data["flex_states"][0, self.idx, :, :3]
        self.scatter = visuals.Markers()
        self.scatter.set_data(pos,
                              edge_color=None,
                              face_color=self.color_id,
                              size=5)
        floor = visuals.Plane(width=5, height=5)
        wall = visuals.Plane(width=5,
                             height=1,
                             direction="+x",
                             width_segments=4,
                             height_segments=10)
        wall._mesh.color = "green"

        view.add(wall)
        wall.transform = transforms.STTransform(translate=(-2.5, 0.0, 0.5))
        view.add(self.scatter)
        view.add(floor)

        view.camera = "turntable"  # or try 'arcball'

        # add a colored 3D axis for orientation
        axis = visuals.XYZAxis(parent=view.scene)

        self.reverse = False

        timer = app.Timer(interval="1.1")
        timer.connect(self.update)
        timer.start(0.04)
        vispy.app.run()
예제 #22
0
    def text_plot(self):
        """Plot some text for each source.

        The text is then translate to not cover the source. If no text is
        detected, a empty text object is created.
        """
        if self.stext is not None:
            # Create text object :
            self.stextmesh = visu.Text(text=self.stext, color=self.stextcolor,
                                       font_size=self.stextsize, pos=self.xyz,
                                       bold=True, name='SourcesText')

            # Set text texture :
            self.stextmesh.set_gl_state('translucent', depth_test=True)

            # Apply a transformation to text elements to not cover sources :
            self.stextmesh.transform = vist.STTransform(
                translate=self.stextshift)
        else:
            self.stextmesh = visu.Text(name='NoneText')
예제 #23
0
    def _fcn_textupdate(self):
        """Update text of each sources.

        This method can be used to set text visible / hide, to translate the
        text in order to not cover the source sphere and to change the color /
        fontsize of each text. Finally, this method update the text according
        to selected properties.
        """
        # Text visible :
        self.sources.stextmesh.visible = self.grpText.isChecked()
        # Translate text (do not cover the source):
        t = vist.STTransform(translate=list(
            [self.x_text.value(),
             self.y_text.value(),
             self.z_text.value()]))
        self.sources.stextmesh.transform = t
        # Color and fontsize :
        _, self.sources.stextcolor = textline2color(
            str(self.q_stextcolor.text()))
        self.sources.stextsize = self.q_stextsize.value()
        # Update text :
        self.sources.text_update()
예제 #24
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')
예제 #25
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', text=None, text_size=3.,
                 text_color='black', 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)]
        # 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
        # Data :
        if data is None:
            data = np.ones((len(self),))
        else:
            data = np.asarray(data).ravel()
            assert len(data) == 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)

        # _______________________ 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._update_color()
        self.alpha = alpha
예제 #26
0
    def __init__(self, parent=None, **kwargs):
        """Init."""
        # _____________________ INIT _____________________
        self._n = 1000
        self._ratio = 4 / 5
        CbarBase.__init__(self, **kwargs)

        # _____________________ CANVAS _____________________
        if parent is None:
            # Define a canvas :
            self._canvas = scene.SceneCanvas(keys='interactive',
                                             show=False,
                                             resizable=True,
                                             dpi=600,
                                             bgcolor=self._bgcolor,
                                             size=(300, 900))
            self._wc = self._canvas.central_widget.add_view()
            parent = self._wc.scene
            # Define the camera :
            self._camera = FixedCam(rect=(-1.2, -1.2, 2.4, 2.4))
            self._wc.camera = self._camera
        self.parent = parent

        # _____________________ OBJECTS _____________________
        # --------------------- Node ---------------------
        # Define node parent and limit node :
        self._cbNode = Node(name='Colorbar', parent=parent)
        self._limNode = Node(name='Limits', parent=self._cbNode)
        # Rescale between (-1., 1.) :
        self._rsc = vist.STTransform(scale=(self._width, 2 / self._n, 1),
                                     translate=(0, -1., 0))
        # Set transformation to the node :
        self._cbNode.transform = self._rsc

        # --------------------- Image ---------------------
        self._mImage = visuals.Image(parent=self._cbNode, name='image')

        # --------------------- Border ---------------------
        pos = np.array([[0., 0., -3.], [1., 0., -3.], [1., 0., -3.],
                        [1., self._n, -3.], [1., self._n, -3.],
                        [0., self._n, -3.], [0., self._n, -3.], [0., 0., -3.]])
        self._mBorder = visuals.Line(parent=self._cbNode, name='Border')
        self._mBorder.set_data(pos=pos,
                               width=2.,
                               connect='segments',
                               color=self._txtcolor)
        self._mBorder.visible = self._border

        # --------------------- Labels ---------------------
        # Clim labels :
        self._mClimM = visuals.Text(parent=self._limNode,
                                    color=self._txtcolor,
                                    font_size=self._txtsz,
                                    name='Clim_M',
                                    anchor_x='left')
        self._mClimm = visuals.Text(parent=self._limNode,
                                    color=self._txtcolor,
                                    font_size=self._txtsz,
                                    name='Clim_m',
                                    anchor_x='left')

        # Cblabel :
        self._mcblabel = visuals.Text(parent=self._limNode,
                                      name='Cblabel',
                                      color=self._txtcolor,
                                      anchor_x='center',
                                      font_size=self._cbtxtsz)
        self._mcblabel.rotation = -90

        # Vmin/Vmax :
        self._vmMNode = Node(name='VminVmax', parent=self._limNode)
        self._mVm = visuals.Text(parent=self._vmMNode,
                                 color=self._txtcolor,
                                 font_size=self._ratio * self._txtsz,
                                 name='Vmin',
                                 anchor_x='left')
        self._mVM = visuals.Text(parent=self._vmMNode,
                                 color=self._txtcolor,
                                 font_size=self._ratio * self._txtsz,
                                 name='Vmax',
                                 anchor_x='left')

        # Build colorbar :
        self._build(True, 'all')
예제 #27
0
def test_transform_chain():
    # Make dummy classes for easier distinguishing the transforms

    class DummyTrans(tr.BaseTransform):
        glsl_map = "vec4 trans(vec4 pos) {return pos;}"
        glsl_imap = "vec4 trans(vec4 pos) {return pos;}"

    class TransA(DummyTrans):
        pass

    class TransB(DummyTrans):
        pass

    class TransC(DummyTrans):
        pass

    # Create test transforms
    a, b, c = TransA(), TransB(), TransC()

    # Test Chain creation
    assert tr.ChainTransform().transforms == []
    assert tr.ChainTransform(a).transforms == [a]
    assert tr.ChainTransform(a, b).transforms == [a, b]
    assert tr.ChainTransform(a, b, c, a).transforms == [a, b, c, a]

    # Test composition by multiplication
    assert_chain_objects(a * b, tr.ChainTransform(a, b))
    assert_chain_objects(a * b * c, tr.ChainTransform(a, b, c))
    assert_chain_objects(a * b * c * a, tr.ChainTransform(a, b, c, a))

    # Test adding/prepending to transform
    chain = tr.ChainTransform()
    chain.append(a)
    assert chain.transforms == [a]
    chain.append(b)
    assert chain.transforms == [a, b]
    chain.append(c)
    assert chain.transforms == [a, b, c]
    chain.prepend(b)
    assert chain.transforms == [b, a, b, c]
    chain.prepend(c)
    assert chain.transforms == [c, b, a, b, c]

    # Test simplifying
    t1 = tr.STTransform(scale=(2, 3))
    t2 = tr.STTransform(translate=(3, 4))
    t3 = tr.STTransform(translate=(3, 4))
    # Create multiplied versions
    t123 = t1 * t2 * t3
    t321 = t3 * t2 * t1
    c123 = tr.ChainTransform(t1, t2, t3)
    c321 = tr.ChainTransform(t3, t2, t1)
    c123s = c123.simplified
    c321s = c321.simplified
    #
    assert isinstance(t123, tr.STTransform)  # or the test is useless
    assert isinstance(t321, tr.STTransform)  # or the test is useless
    assert isinstance(c123s, tr.ChainTransform)  # or the test is useless
    assert isinstance(c321s, tr.ChainTransform)  # or the test is useless

    # Test Mapping
    t1 = tr.STTransform(scale=(2, 3))
    t2 = tr.STTransform(translate=(3, 4))
    chain1 = tr.ChainTransform(t1, t2)
    chain2 = tr.ChainTransform(t2, t1)
    #
    assert chain1.transforms == [t1, t2]  # or the test is useless
    assert chain2.transforms == [t2, t1]  # or the test is useless
    #
    m12 = (t1 * t2).map((1, 1)).tolist()
    m21 = (t2 * t1).map((1, 1)).tolist()
    m12_ = chain1.map((1, 1)).tolist()
    m21_ = chain2.map((1, 1)).tolist()
    #
    #print(m12, m21, m12_, m21_)
    assert m12 != m21
    assert m12 == m12_
    assert m21 == m21_

    # Test shader map
    t1 = tr.STTransform(scale=(2, 3))
    t2 = tr.STTransform(translate=(3, 4))
    chain = tr.ChainTransform(t1, t2)
    #
    funcs = chain.shader_map().dependencies()
    funcsi = chain.shader_imap().dependencies()
    #
    assert t1.shader_map() in funcs
    assert t2.shader_map() in funcs
    assert t1.shader_imap() in funcsi
    assert t2.shader_imap() in funcsi
예제 #28
0
    def set_data(self,
                 data,
                 levels=None,
                 level_colors='white',
                 cmap='viridis',
                 clim=None,
                 vmin=None,
                 under='gray',
                 vmax=None,
                 over='red',
                 cblabel=None):
        """Set data to the topoplot.

        Parameters
        ----------
        data : array_like
            Array of data of shape (n_channels)
        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.
        cblabel : string | None
            Colorbar label.
        """
        # ================== XYZ / CHANNELS / DATA ==================
        xyz = self._xyz[self._keeponly]
        channels = list(np.array(self._channels)[self._keeponly])
        data = np.asarray(data, dtype=float).ravel()
        if len(data) == len(self):
            data = data[self._keeponly]

        # =================== CHANNELS ===================
        # Markers :
        radius = normalize(data, 10., 30.)
        self.chanMarkers.set_data(pos=xyz,
                                  size=radius,
                                  edge_color='black',
                                  face_color=self._chan_mark_color,
                                  symbol=self._chan_mark_symbol)
        # Names :
        if channels is not None:
            self.chanText.text = channels
            self.chanText.pos = xyz

        # =================== GRID ===================
        pos_x, pos_y = xyz[:, 0], xyz[:, 1]
        xmin, xmax = pos_x.min(), pos_x.max()
        ymin, ymax = pos_y.min(), pos_y.max()
        xi = np.linspace(xmin, xmax, self._pix)
        yi = np.linspace(ymin, ymax, self._pix)
        xh, yi = np.meshgrid(xi, yi)
        grid = self._griddata(pos_x, pos_y, data, xh, yi)

        # =================== INTERPOLATION ===================
        if self._interp is not None:
            grid = self._grid_interpolation(grid)
        csize = max(self._pix, grid.shape[0])
        # Variables :
        l = csize / 2  # noqa
        y, x = np.ogrid[-l:l, -l:l]
        mask = x**2 + y**2 < l**2
        nmask = np.invert(mask)

        # =================== DISC ===================
        # Force min < off-disc values < max :
        grid[nmask] = data.mean()
        grid = normalize(grid, data.min(), data.max())
        clim = (data.min(), data.max()) if clim is None else clim
        image = array2colormap(grid,
                               cmap=cmap,
                               clim=clim,
                               vmin=vmin,
                               vmax=vmax,
                               under=under,
                               over=over)
        image[nmask] = self._bgcolor
        self.disc.set_data(image)

        # =================== COLORBAR ===================
        if hasattr(self, 'cbar'):
            self.cbar.clim = clim
            self.cbar.cmap = cmap
            self.cbar.isvmin = vmin is not None
            self.cbar.vmin = vmin
            self.cbar.under = under
            self.cbar.isvmax = vmax is not None
            self.cbar.vmax = vmax
            self.cbar.over = over
            self.cbar.cblabel = cblabel

        # =================== LEVELS ===================
        if levels is not None:
            if isinstance(levels, int):
                levels = np.linspace(grid.min(), grid.max(), levels)
            if isinstance(level_colors, str):
                # Get colormaps :
                cmaps = mpl_cmap(bool(level_colors.find('_r') + 1))
                if level_colors in cmaps:
                    level_colors = array2colormap(levels, cmap=level_colors)
            grid[nmask] = np.inf
            self.iso = visuals.Isocurve(data=grid,
                                        parent=self.node_head,
                                        levels=levels,
                                        color_lev=level_colors,
                                        width=2.)
            self.iso.transform = vist.STTransform(translate=(0., 0., -5.))
예제 #29
0
    def __init__(self, canvas, **kwargs):
        """Init."""
        # Create a root node :
        self._vbNode = scene.Node(name='Engram')
        self._vbNode.transform = vist.STTransform(scale=[self._gl_scale] * 3)
        logger.debug("Engram rescaled " + str([self._gl_scale] * 3))
        PROFILER("Root node", level=1)

        # ========================= SOURCES =========================
        self.sources = CombineSources(kwargs.get('source_obj', None))
        if self.sources.name is None:
            self._obj_type_lst.model().item(4).setEnabled(False)
            # Disable menu :
            self.menuDispSources.setChecked(False)
            self.menuTransform.setEnabled(False)
        self.sources.parent = self._vbNode
        PROFILER("Sources object", level=1)

        # ========================= CONNECTIVITY =========================
        self.connect = CombineConnect(kwargs.get('connect_obj', None))
        if self.connect.name is None:
            self._obj_type_lst.model().item(5).setEnabled(False)
            self.menuDispConnect.setEnabled(False)
        self.connect.parent = self._vbNode
        PROFILER("Connect object", level=1)

        # ========================= TIME-SERIES =========================
        self.tseries = CombineTimeSeries(kwargs.get('time_series_obj', None))
        if self.tseries.name is None:
            self._obj_type_lst.model().item(6).setEnabled(False)
        self.tseries.parent = self._vbNode
        PROFILER("Time-series object", level=1)

        # ========================= PICTURES =========================
        self.pic = CombinePictures(kwargs.get('picture_obj', None))
        if self.pic.name is None:
            self._obj_type_lst.model().item(7).setEnabled(False)
        self.pic.parent = self._vbNode
        PROFILER("Pictures object", level=1)

        # ========================= VECTORS =========================
        self.vectors = CombineVectors(kwargs.get('vector_obj', None))
        if self.vectors.name is None:
            self._obj_type_lst.model().item(8).setEnabled(False)
        self.vectors.parent = self._vbNode
        PROFILER("Vectors object", level=1)

        # ========================= VOLUME =========================
        # ----------------- Volume -----------------
        if kwargs.get('vol_obj', None) is None:
            self.volume = VolumeObj('brodmann')
            self.volume.visible_obj = False
        else:
            self.volume = kwargs.get('vol_obj')
        if self.volume.name not in self.volume.list():
            self.volume.save(tmpfile=True)
        self.volume.parent = self._vbNode
        PROFILER("Volume object", level=1)
        # ----------------- ROI -----------------
        if kwargs.get('roi_obj', None) is None:
            self.roi = RoiObj('brodmann')
            self.roi.visible_obj = False
        else:
            self.roi = kwargs.get('roi_obj')
        if self.roi.name not in self.roi.list():
            self.roi.save(tmpfile=True)
        self.roi.parent = self._vbNode
        PROFILER("ROI object", level=1)
        # ----------------- Cross-sections -----------------
        if kwargs.get('cross_sec_obj', None) is None:
            self.cross_sec = CrossSecObj('brodmann')
        else:
            self.cross_sec = kwargs.get('cross_sec_obj')
        if self.cross_sec.name not in self.cross_sec.list():
            self.cross_sec.save(tmpfile=True)
        self.cross_sec.visible_obj = False
        self.cross_sec.text_size = 2.
        self.cross_sec.parent = self._csView.wc.scene
        self._csView.camera = self.cross_sec._get_camera()
        self.cross_sec.set_shortcuts_to_canvas(self._csView)
        PROFILER("Cross-sections object", level=1)

        # ========================= ENGRAM =========================
        if kwargs.get('engram_obj', None) is None:
            self.atlas = BrainObj('B1')
        else:
            self.atlas = kwargs['engram_obj']
        if self.atlas.name not in self.atlas.list():
            self.atlas.save(tmpfile=True)
        self.atlas.scale = self._gl_scale
        self.atlas.parent = self._vbNode
        PROFILER("Engram object", level=1)
예제 #30
0
    def __init__(self,
                 xyz=None,
                 channels=None,
                 system='cartesian',
                 unit='degree',
                 title=None,
                 title_color='black',
                 title_size=20.,
                 line_color='black',
                 line_width=4.,
                 chan_size=12.,
                 chan_offset=(0., 0., 0.),
                 chan_mark_color='white',
                 chan_mark_symbol='disc',
                 chan_txt_color='black',
                 bgcolor='white',
                 cbar=True,
                 cb_txt_size=10.,
                 margin=.05,
                 parent=None):
        """Init."""
        # ======================== VARIABLES ========================
        self._bgcolor = color2vb(bgcolor)
        scale = 800.  # fix GL bugs for small plots
        pos = np.zeros((1, 3), dtype=np.float32)
        # Colors :
        title_color = color2vb(title_color)
        line_color = color2vb(line_color)
        chan_txt_color = color2vb(chan_txt_color)
        self._chan_mark_color = color2vb(chan_mark_color)
        self._chan_mark_symbol = chan_mark_symbol
        # Disc interpolation :
        self._interp = .1
        self._pix = 64
        csize = int(self._pix / self._interp) if self._interp else self._pix
        l = csize / 2  # noqa

        # ======================== NODES ========================
        # Main topoplot node :
        self.node = scene.Node(name='Topoplot', parent=parent)
        self.node.transform = vist.STTransform(scale=[scale] * 3)
        # Headset + channels :
        self.node_headfull = scene.Node(name='HeadChan', parent=self.node)
        # Headset node :
        self.node_head = scene.Node(name='Headset', parent=self.node_headfull)
        # Channel node :
        self.node_chan = scene.Node(name='Channels', parent=self.node_headfull)
        self.node_chan.transform = vist.STTransform(translate=(0., 0., -10.))
        # Cbar node :
        self.node_cbar = scene.Node(name='Channels', parent=self.node)
        # Dictionaries :
        kw_line = {
            'width': line_width,
            'color': line_color,
            'parent': self.node_head
        }

        # ======================== PARENT VISUALS ========================
        # Main disc :
        self.disc = visuals.Image(pos=pos,
                                  name='Disc',
                                  parent=self.node_head,
                                  interpolation='bilinear')
        # Title :
        self.title = visuals.Text(text=title,
                                  pos=(0., .6, 0.),
                                  name='Title',
                                  parent=self.node,
                                  font_size=title_size,
                                  color=title_color,
                                  bold=True)
        self.title.font_size *= 1.1

        # ======================== HEAD / NOSE / EAR ========================
        # ------------------ HEAD ------------------
        # Head visual :
        self.head = visuals.Line(pos=pos, name='Head', **kw_line)
        # Head circle :
        theta = np.arange(0, 2 * np.pi, 0.001)
        head = np.full((len(theta), 3), -1., dtype=np.float32)
        head[:, 0] = l * (1. + np.cos(theta))
        head[:, 1] = l * (1. + np.sin(theta))
        self.head.set_data(pos=head)

        # ------------------ NOSE ------------------
        # Nose visual :
        self.nose = visuals.Line(pos=pos, name='Nose', **kw_line)
        # Nose data :
        wn, hn = csize * 50. / 512., csize * 30. / 512.
        nose = np.array([[l - wn, 2 * l - wn, 2.], [l, 2 * l + hn, 2.],
                         [l, 2 * l + hn, 2.], [l + wn, 2 * l - wn, 2.]])
        self.nose.set_data(pos=nose, connect='segments')

        # ------------------ EAR ------------------
        we, he = csize * 10. / 512., csize * 30. / 512.
        ye = l + he * np.sin(theta)
        # Ear left data :
        self.earL = visuals.Line(pos=pos, name='EarLeft', **kw_line)
        # Ear left visual :
        ear_l = np.full((len(theta), 3), 3., dtype=np.float32)
        ear_l[:, 0] = 2 * l + we * np.cos(theta)
        ear_l[:, 1] = ye
        self.earL.set_data(pos=ear_l)

        # Ear right visual :
        self.earR = visuals.Line(pos=pos, name='EarRight', **kw_line)
        # Ear right data :
        ear_r = np.full((len(theta), 3), 3., dtype=np.float32)
        ear_r[:, 0] = 0. + we * np.cos(theta)
        ear_r[:, 1] = ye
        self.earR.set_data(pos=ear_r)

        # ================== CHANNELS ==================
        # Channel's markers :
        self.chanMarkers = visuals.Markers(pos=pos,
                                           name='ChanMarkers',
                                           parent=self.node_chan)
        # Channel's text :
        self.chanText = visuals.Text(pos=pos,
                                     name='ChanText',
                                     parent=self.node_chan,
                                     anchor_x='center',
                                     color=chan_txt_color,
                                     font_size=chan_size)

        # ================== CAMERA ==================
        self.rect = ((-scale / 2) * (1 + margin), (-scale / 2) * (1 + margin),
                     scale * (1. + cbar * .3 + margin),
                     scale * (1.11 + margin))

        # ================== CBAR ==================
        if cbar:
            self.cbar = CbarVisual(cbtxtsz=1.2 * cb_txt_size,
                                   txtsz=cb_txt_size,
                                   txtcolor=title_color,
                                   cbtxtsh=2.,
                                   parent=self.node_cbar)
            self.node_cbar.transform = vist.STTransform(scale=(.6, .4, 1.),
                                                        translate=(.6, 0., 0.))

        # ================== COORDINATES ==================
        auto = self._get_channel_coordinates(xyz, channels, system, unit)
        if auto:
            eucl = np.sqrt(self._xyz[:, 0]**2 + self._xyz[:, 1]**2).max()
            self.node_head.transform = vpnormalize(head, dist=2 * eucl)
            # Rescale between (-1:1, -1:1) = circle :
            circle = vist.STTransform(scale=(.5 / eucl, .5 / eucl, 1.))
            self.node_headfull.transform = circle
            # Text translation :
            tr = np.array([0., .8, 0.]) + np.array(chan_offset)
        else:
            # Get coordinates of references along the x and y-axis :
            ref_x, ref_y = self._get_ref_coordinates()
            # Recenter the topoplot :
            t = vist.ChainTransform()
            t.prepend(vprecenter(head))
            # Rescale (-ref_x:ref_x, -ref_y:ref_y) (ref_x != ref_y => ellipse)
            coef_x = 2 * ref_x / head[:, 0].max()
            coef_y = 2 * ref_y / head[:, 1].max()
            t.prepend(vist.STTransform(scale=(coef_x, coef_y, 1.)))
            self.node_head.transform = t
            # Rescale between (-1:1, -1:1) = circle :
            circle = vist.STTransform(scale=(.5 / ref_x, .5 / ref_y, 1.))
            self.node_headfull.transform = circle
            # Text translation :
            tr = np.array([0., .04, 0.]) + np.array(chan_offset)
        self.chanText.transform = vist.STTransform(translate=tr)

        # ================== GRID INTERPOLATION ==================
        # Interpolation vectors :
        x = y = np.arange(0, self._pix, 1)
        xnew = ynew = np.arange(0, self._pix, self._interp)

        # Grid interpolation function :
        def _grid_interpolation(grid):
            f = interp2d(x, y, grid, kind='linear')
            return f(xnew, ynew)

        self._grid_interpolation = _grid_interpolation