def test_application(): """Test application running""" app = use_app() print(app) # __repr__ without app app.create() wrong = 'glut' if app.backend_name.lower() != 'glut' else 'pyglet' assert_raises(RuntimeError, use_app, wrong) app.process_events() print(app) # test __repr__ assert_raises(ValueError, Canvas, keys='foo') assert_raises(TypeError, Canvas, keys=dict(escape=1)) assert_raises(ValueError, Canvas, keys=dict(escape='foo')) # not an attr pos = [0, 0] if app.backend_module.capability['position'] else None size = (100, 100) # Use "with" statement so failures don't leave open window # (and test context manager behavior) title = 'default' with Canvas(title=title, size=size, app=app, show=True, position=pos) as canvas: assert_true(canvas.create_native() is None) # should be done already assert_is(canvas.app, app) assert_true(canvas.native) assert_equal('swap_buffers', canvas.events.draw.callback_refs[-1]) canvas.measure_fps(0.001) sleep(0.002) canvas.update() app.process_events() assert_true(canvas.fps > 0) # Other methods print(canvas) # __repr__ assert_equal(canvas.title, title) canvas.title = 'you' with use_log_level('warning', record=True, print_msg=False) as l: if app.backend_module.capability['position']: # todo: disable more tests based on capability canvas.position = pos canvas.size = size if 'ipynb_vnc' in canvas.app.backend_name.lower(): assert_true(len(l) >= 1) else: assert_true(len(l) == 0) canvas.connect(on_mouse_move) assert_raises(ValueError, canvas.connect, _on_mouse_move) if sys.platform != 'darwin': # XXX knownfail, prob. needs warmup canvas.show(False) canvas.show() app.process_events() assert_raises(ValueError, canvas.connect, on_nonexist) # deprecation of "paint" with use_log_level('info', record=True, print_msg=False) as log: olderr = sys.stderr try: with open(os.devnull, 'w') as fid: sys.stderr = fid @canvas.events.paint.connect def fake(event): pass finally: sys.stderr = olderr assert_equal(len(log), 1) assert_in('deprecated', log[0]) # screenshots gl.glViewport(0, 0, *size) ss = _screenshot() assert_array_equal(ss.shape, size + (4,)) assert_equal(len(canvas._backend._vispy_get_geometry()), 4) if (app.backend_name.lower() != 'glut' and # XXX knownfail for Almar sys.platform != 'win32'): # XXX knownfail for windows assert_array_equal(canvas.size, size) assert_equal(len(canvas.position), 2) # XXX knawnfail, doesn't "take" # GLOO: should have an OpenGL context already, so these should work vert = VertexShader("void main (void) {gl_Position = pos;}") frag = FragmentShader("void main (void) {gl_FragColor = pos;}") program = Program(vert, frag) assert_raises(RuntimeError, program.activate) vert = VertexShader("uniform vec4 pos;" "void main (void) {gl_Position = pos;}") frag = FragmentShader("uniform vec4 pos;" "void main (void) {gl_FragColor = pos;}") program = Program(vert, frag) #uniform = program.uniforms[0] program['pos'] = [1, 2, 3, 4] program.activate() # should print #uniform.upload(program) program.detach(vert) program.detach(frag) assert_raises(RuntimeError, program.detach, vert) assert_raises(RuntimeError, program.detach, frag) vert = VertexShader("attribute vec4 pos;" "void main (void) {gl_Position = pos;}") frag = FragmentShader("void main (void) {}") program = Program(vert, frag) #attribute = program.attributes[0] program["pos"] = [1, 2, 3, 4] program.activate() #attribute.upload(program) # cannot get element count #assert_raises(RuntimeError, program.draw, 'POINTS') # use a real program vert = ("uniform mat4 u_model;" "attribute vec2 a_position; attribute vec4 a_color;" "varying vec4 v_color;" "void main (void) {v_color = a_color;" "gl_Position = u_model * vec4(a_position, 0.0, 1.0);" "v_color = a_color;}") frag = "void main() {gl_FragColor = vec4(0, 0, 0, 1);}" n, p = 250, 50 T = np.random.uniform(0, 2 * np.pi, n) position = np.zeros((n, 2), dtype=np.float32) position[:, 0] = np.cos(T) position[:, 1] = np.sin(T) color = np.ones((n, 4), dtype=np.float32) * (1, 1, 1, 1) data = np.zeros(n * p, [('a_position', np.float32, 2), ('a_color', np.float32, 4)]) data['a_position'] = np.repeat(position, p, axis=0) data['a_color'] = np.repeat(color, p, axis=0) program = Program(vert, frag) program.bind(VertexBuffer(data)) program['u_model'] = np.eye(4, dtype=np.float32) # different codepath if no call to activate() program.draw(gl.GL_POINTS) subset = IndexBuffer(np.arange(10, dtype=np.uint32)) program.draw(gl.GL_POINTS, subset) # bad programs frag_bad = ("varying vec4 v_colors") # no semicolon program = Program(vert, frag_bad) assert_raises(RuntimeError, program.activate) frag_bad = None # no fragment code. no main is not always enough program = Program(vert, frag_bad) assert_raises(ValueError, program.activate) # Timer timer = Timer(interval=0.001, connect=on_mouse_move, iterations=2, start=True, app=app) timer.start() timer.interval = 0.002 assert_equal(timer.interval, 0.002) assert_true(timer.running) sleep(.003) assert_true(timer.elapsed >= 0.002) timer.stop() assert_true(not timer.running) assert_true(timer.native) timer.disconnect() # test that callbacks take reasonable inputs _test_callbacks(canvas) # cleanup canvas.swap_buffers() canvas.update() app.process_events() # put this in even though __exit__ will call it to make sure we don't # have problems calling it multiple times canvas.close() # done by context
def test_application(): """Test application running""" app = use_app() print(app) # __repr__ without app app.create() wrong = 'glfw' if app.backend_name.lower() != 'glfw' else 'pyqt4' assert_raises(RuntimeError, use_app, wrong) app.process_events() print(app) # test __repr__ assert_raises(ValueError, Canvas, keys='foo') assert_raises(TypeError, Canvas, keys=dict(escape=1)) assert_raises(ValueError, Canvas, keys=dict(escape='foo')) # not an attr pos = [0, 0] if app.backend_module.capability['position'] else None size = (100, 100) # Use "with" statement so failures don't leave open window # (and test context manager behavior) title = 'default' with Canvas(title=title, size=size, app=app, show=True, position=pos) as canvas: context = canvas.context assert_true(canvas.create_native() is None) # should be done already assert_is(canvas.app, app) assert_true(canvas.native) assert_equal('swap_buffers', canvas.events.draw.callback_refs[-1]) canvas.measure_fps(0.001) sleep(0.002) canvas.update() app.process_events() assert_true(canvas.fps > 0) # Other methods print(canvas) # __repr__ assert_equal(canvas.title, title) canvas.title = 'you' with use_log_level('warning', record=True, print_msg=False) as l: if app.backend_module.capability['position']: # todo: disable more tests based on capability canvas.position = pos canvas.size = size if 'ipynb_vnc' in canvas.app.backend_name.lower(): assert_true(len(l) >= 1) else: assert_true(len(l) == 0) canvas.connect(on_mouse_move) assert_raises(ValueError, canvas.connect, _on_mouse_move) if sys.platform != 'darwin': # XXX knownfail, prob. needs warmup canvas.show(False) canvas.show() app.process_events() assert_raises(ValueError, canvas.connect, on_nonexist) # deprecation of "paint" with use_log_level('info', record=True, print_msg=False) as log: olderr = sys.stderr try: fid = StringIO() sys.stderr = fid @canvas.events.paint.connect def fake(event): pass finally: sys.stderr = olderr assert_equal(len(log), 1) assert_in('deprecated', log[0]) # screenshots gl.glViewport(0, 0, *size) ss = _screenshot() assert_array_equal(ss.shape, size + (4,)) assert_equal(len(canvas._backend._vispy_get_geometry()), 4) if sys.platform != 'win32': # XXX knownfail for windows assert_array_equal(canvas.size, size) assert_equal(len(canvas.position), 2) # XXX knawnfail, doesn't "take" # GLOO: should have an OpenGL context already, so these should work vert = "void main (void) {gl_Position = pos;}" frag = "void main (void) {gl_FragColor = pos;}" program = Program(vert, frag) assert_raises(RuntimeError, program.glir.flush, context.shared.parser) vert = "uniform vec4 pos;\nvoid main (void) {gl_Position = pos;}" frag = "uniform vec4 pos;\nvoid main (void) {gl_FragColor = pos;}" program = Program(vert, frag) #uniform = program.uniforms[0] program['pos'] = [1, 2, 3, 4] vert = "attribute vec4 pos;\nvoid main (void) {gl_Position = pos;}" frag = "void main (void) {}" program = Program(vert, frag) #attribute = program.attributes[0] program["pos"] = [1, 2, 3, 4] # use a real program program._glir.clear() vert = ("uniform mat4 u_model;" "attribute vec2 a_position; attribute vec4 a_color;" "varying vec4 v_color;" "void main (void) {v_color = a_color;" "gl_Position = u_model * vec4(a_position, 0.0, 1.0);" "v_color = a_color;}") frag = "void main() {gl_FragColor = vec4(0, 0, 0, 1);}" n, p = 250, 50 T = np.random.uniform(0, 2 * np.pi, n) position = np.zeros((n, 2), dtype=np.float32) position[:, 0] = np.cos(T) position[:, 1] = np.sin(T) color = np.ones((n, 4), dtype=np.float32) * (1, 1, 1, 1) data = np.zeros(n * p, [('a_position', np.float32, 2), ('a_color', np.float32, 4)]) data['a_position'] = np.repeat(position, p, axis=0) data['a_color'] = np.repeat(color, p, axis=0) program = Program(vert, frag) program.bind(VertexBuffer(data)) program['u_model'] = np.eye(4, dtype=np.float32) # different codepath if no call to activate() program.draw(gl.GL_POINTS) subset = IndexBuffer(np.arange(10, dtype=np.uint32)) program.draw(gl.GL_POINTS, subset) # bad programs frag_bad = ("varying vec4 v_colors") # no semicolon program = Program(vert, frag_bad) assert_raises(RuntimeError, program.glir.flush, context.shared.parser) frag_bad = None # no fragment code. no main is not always enough assert_raises(ValueError, Program, vert, frag_bad) # Timer timer = Timer(interval=0.001, connect=on_mouse_move, iterations=2, start=True, app=app) timer.start() timer.interval = 0.002 assert_equal(timer.interval, 0.002) assert_true(timer.running) sleep(.003) assert_true(timer.elapsed >= 0.002) timer.stop() assert_true(not timer.running) assert_true(timer.native) timer.disconnect() # test that callbacks take reasonable inputs _test_callbacks(canvas) # cleanup canvas.swap_buffers() canvas.update() app.process_events() # put this in even though __exit__ will call it to make sure we don't # have problems calling it multiple times canvas.close() # done by context
class MainWindow(BaseQtView): def __init__(self, title: str = "", volume_widget: Optional[QWidget] = None, slice_widget: Optional[QWidget] = None): self.title = title self.volume_widget = volume_widget if volume_widget else QWidget() self.slice_widget = slice_widget if slice_widget else QWidget() self._init() def _init(self): print("Building...") self.win = QMainWindow() self._default_window_title = self.title widget = QWidget() self.win.setCentralWidget(widget) main_layout = QHBoxLayout() widget.setLayout(main_layout) main_layout.addWidget(self.slice_widget) main_layout.addWidget(self.volume_widget) side_layout = QVBoxLayout() main_layout.addLayout(side_layout) load_image_button = QPushButton("Load Section") side_layout.addWidget(load_image_button) load_image_button.clicked.connect(self.show_load_image_dialog) # Atlas BUttons button_hbox = QHBoxLayout() side_layout.addLayout(button_hbox) atlas_buttons = QButtonGroup(self.win) atlas_buttons.setExclusive(True) atlas_buttons.buttonToggled.connect(self.atlas_button_toggled) for resolution in [100, 25, 10]: atlas_button = QPushButton(f"{resolution}um") atlas_button.setCheckable(True) button_hbox.addWidget(atlas_button) atlas_buttons.addButton(atlas_button) # The 10um atlas takes way too long to download at the moment. # It needs some kind of progress bar or async download feature to be useful. # The disabled button here shows it as an option for the future, but keeps it from being used. if resolution == 10: atlas_button.setDisabled(True) self.title_reset_timer = Timer(interval=2, connect=lambda e: self._show_default_window_title(), iterations=1, start=False) self._show_default_window_title() self.statusbar = self.win.statusBar() self.image_coord_label = QLabel(text="Image Coords") self.statusbar.addPermanentWidget(self.image_coord_label) self.win.show() @property def qt_widget(self) -> QWidget: return self.win def on_image_coordinate_highlighted(self, image_coords, atlas_coords): i, j = image_coords x, y, z = atlas_coords self.image_coord_label.setText(f"(i={i}, j={j}) (x={x:.1f}, y={y:.1f}, z={z:.1f})") def on_error_raised(self, msg: str): self.show_temp_title(msg) def atlas_button_toggled(self, button: QPushButton, is_checked: bool): if not is_checked: # Don't do anything for the button being unselected. return resolution_label = button.text() resolution = int("".join(filter(str.isdigit, resolution_label))) self.load_atlas(resolution=resolution) # Command Routing def show_load_image_dialog(self): filename, filetype = QFileDialog.getOpenFileName( parent=self.win, caption="Load Image", dir="../data/RA_10X_scans/MEA", filter="OME-TIFF (*.ome.tiff)" ) if not filename: return self.load_section(filename=filename) def load_atlas(self, resolution: int): raise NotImplementedError("Connect to LoadAtlasCommand before using.") def load_section(self, filename: str): raise NotImplementedError("Connect to a LoadImageCommand before using.") # View Code def _show_default_window_title(self): self.win.setWindowTitle(self._default_window_title) def show_temp_title(self, title: str) -> None: self.win.setWindowTitle(title) self.title_reset_timer.stop() self.title_reset_timer.start(iterations=1)
def _test_application(backend): """Test application running""" app = Application() assert_raises(ValueError, app.use, "foo") app.use(backend) wrong = "Glut" if app.backend_name != "Glut" else "Pyglet" assert_raises(RuntimeError, app.use, wrong) app.process_events() if backend is not None: # "in" b/c "qt" in "PySide (qt)" assert_in(backend, app.backend_name) print(app) # test __repr__ # Canvas pos = [0, 0] size = (100, 100) # Use "with" statement so failures don't leave open window # (and test context manager behavior) title = "default" if backend is None else backend with Canvas(title=title, size=size, app=app, show=True, position=pos) as canvas: assert_is(canvas.app, app) assert_true(canvas.native) assert_equal("swap_buffers", canvas.events.paint.callback_refs[-1]) print(canvas) # __repr__ assert_array_equal(canvas.size, size) assert_equal(canvas.title, title) canvas.title = "you" canvas.position = pos canvas.size = size canvas.connect(on_mouse_move) assert_raises(ValueError, canvas.connect, _on_mouse_move) if sys.platform != "darwin": # XXX knownfail, prob. needs warmup canvas.show(False) canvas.show() app.process_events() assert_raises(ValueError, canvas.connect, on_nonexist) # screenshots gl.glViewport(0, 0, *size) ss = _screenshot() assert_array_equal(ss.shape, size + (3,)) assert_equal(len(canvas._backend._vispy_get_geometry()), 4) assert_array_equal(canvas.size, size) assert_equal(len(canvas.position), 2) # XXX knawnfail, doesn't "take" # GLOO: should have an OpenGL context already, so these should work vert = VertexShader("void main (void) {gl_Position = pos;}") frag = FragmentShader("void main (void) {gl_FragColor = pos;}") program = Program(vert, frag) assert_raises(RuntimeError, program.activate) vert = VertexShader("uniform vec4 pos;" "void main (void) {gl_Position = pos;}") frag = FragmentShader("uniform vec4 pos;" "void main (void) {gl_FragColor = pos;}") program = Program(vert, frag) # uniform = program.uniforms[0] program["pos"] = [1, 2, 3, 4] program.activate() # should print # uniform.upload(program) program.detach(vert) program.detach(frag) assert_raises(RuntimeError, program.detach, vert) assert_raises(RuntimeError, program.detach, frag) vert = VertexShader("attribute vec4 pos;" "void main (void) {gl_Position = pos;}") frag = FragmentShader("void main (void) {}") program = Program(vert, frag) # attribute = program.attributes[0] program["pos"] = [1, 2, 3, 4] program.activate() # attribute.upload(program) # cannot get element count # assert_raises(RuntimeError, program.draw, 'POINTS') # use a real program vert = ( "uniform mat4 u_model;" "attribute vec2 a_position; attribute vec4 a_color;" "varying vec4 v_color;" "void main (void) {v_color = a_color;" "gl_Position = u_model * vec4(a_position, 0.0, 1.0);" "v_color = a_color;}" ) frag = "void main() {gl_FragColor = vec4(0, 0, 0, 1);}" n, p = 250, 50 T = np.random.uniform(0, 2 * np.pi, n) position = np.zeros((n, 2), dtype=np.float32) position[:, 0] = np.cos(T) position[:, 1] = np.sin(T) color = np.ones((n, 4), dtype=np.float32) * (1, 1, 1, 1) data = np.zeros(n * p, [("a_position", np.float32, 2), ("a_color", np.float32, 4)]) data["a_position"] = np.repeat(position, p, axis=0) data["a_color"] = np.repeat(color, p, axis=0) program = Program(vert, frag) program.bind(VertexBuffer(data)) program["u_model"] = np.eye(4, dtype=np.float32) # different codepath if no call to activate() program.draw(gl.GL_POINTS) subset = IndexBuffer(np.arange(10, dtype=np.uint32)) program.draw(gl.GL_POINTS, subset) # bad programs frag_bad = "varying vec4 v_colors" # no semicolon program = Program(vert, frag_bad) assert_raises(RuntimeError, program.activate) frag_bad = None # no fragment code. no main is not always enough program = Program(vert, frag_bad) assert_raises(ValueError, program.activate) # Timer timer = Timer(interval=0.001, connect=on_mouse_move, iterations=2, start=True, app=app) timer.start() timer.interval = 0.002 assert_equal(timer.interval, 0.002) assert_true(timer.running) timer.stop() assert_true(not timer.running) assert_true(timer.native) timer.disconnect() # test that callbacks take reasonable inputs _test_callbacks(canvas) # cleanup canvas.swap_buffers() canvas.update() app.process_events()
def _test_application(backend): """Test application running""" app = Application() assert_raises(ValueError, app.use, 'foo') app.use(backend) wrong = 'Glut' if app.backend_name != 'Glut' else 'Pyglet' assert_raises(RuntimeError, app.use, wrong) app.process_events() if backend is not None: # "in" b/c "qt" in "PySide (qt)" assert_true(backend in app.backend_name) print(app) # test __repr__ # Canvas pos = [0, 0, 1, 1] # Use "with" statement so failures don't leave open window # (and test context manager behavior) with Canvas(title='me', app=app, show=True, position=pos) as canvas: assert_true(canvas.app is app) assert_true(canvas.native) print(canvas.size >= (1, 1)) canvas.resize(90, 90) canvas.move(1, 1) assert_equal(canvas.title, 'me') canvas.title = 'you' canvas.position = (0, 0) canvas.size = (100, 100) canvas.connect(on_mouse_move) assert_raises(ValueError, canvas.connect, _on_mouse_move) canvas.show() assert_raises(ValueError, canvas.connect, on_nonexist) # screenshots ss = _screenshot() assert_array_equal(ss.shape[2], 3) # XXX other dimensions not correct? # XXX it would be good to do real checks, but sometimes the # repositionings don't "take" (i.e., lead to random errors) assert_equal(len(canvas._backend._vispy_get_geometry()), 4) assert_equal(len(canvas.size), 2) assert_equal(len(canvas.position), 2) # GLOO: should have an OpenGL context already, so these should work vert = VertexShader("void main (void) {gl_Position = pos;}") frag = FragmentShader("void main (void) {gl_FragColor = pos;}") program = Program(vert, frag) assert_raises(ShaderError, program.activate) vert = VertexShader("uniform vec4 pos;" "void main (void) {gl_Position = pos;}") frag = FragmentShader("uniform vec4 pos;" "void main (void) {gl_FragColor = pos;}") program = Program(vert, frag) uniform = program.uniforms[0] uniform.set_data([1, 2, 3, 4]) program.activate() # should print uniform.upload(program) program.detach(vert, frag) assert_raises(ShaderError, program.detach, vert) assert_raises(ShaderError, program.detach, frag) vert = VertexShader("attribute vec4 pos;" "void main (void) {gl_Position = pos;}") frag = FragmentShader("void main (void) {}") program = Program(vert, frag) attribute = program.attributes[0] attribute.set_data([1, 2, 3, 4]) program.activate() attribute.upload(program) # cannot get element count assert_raises(ProgramError, program.draw, 'POINTS') # use a real program vert = ("uniform mat4 u_model;" "attribute vec2 a_position; attribute vec4 a_color;" "varying vec4 v_color;" "void main (void) {v_color = a_color;" "gl_Position = u_model * vec4(a_position, 0.0, 1.0);" "v_color = a_color;}") frag = "void main() {gl_FragColor = vec4(0, 0, 0, 1);}" n, p = 250, 50 T = np.random.uniform(0, 2 * np.pi, n) position = np.zeros((n, 2), dtype=np.float32) position[:, 0] = np.cos(T) position[:, 1] = np.sin(T) color = np.ones((n, 4), dtype=np.float32) * (1, 1, 1, 1) data = np.zeros(n * p, [('a_position', np.float32, 2), ('a_color', np.float32, 4)]) data['a_position'] = np.repeat(position, p, axis=0) data['a_color'] = np.repeat(color, p, axis=0) program = Program(vert, frag) program.set_vars(VertexBuffer(data)) program['u_model'] = np.eye(4, dtype=np.float32) program.draw('POINTS') # different codepath if no call to activate() subset = ElementBuffer(np.arange(10, dtype=np.uint32)) program.draw('POINTS', subset=subset) # bad programs frag_bad = ("varying vec4 v_colors") # no semicolon program = Program(vert, frag_bad) assert_raises(ShaderError, program.activate) frag_bad = None # no fragment code. no main is not always enough program = Program(vert, frag_bad) assert_raises(ProgramError, program.activate) # Timer timer = Timer(interval=0.001, connect=on_mouse_move, iterations=2, start=True, app=app) timer.start() timer.interval = 0.002 assert_equal(timer.interval, 0.002) assert_true(timer.running) timer.stop() assert_true(not timer.running) assert_true(timer.native) timer.disconnect() # test that callbacks take reasonable inputs _test_callbacks(canvas) # cleanup canvas.swap_buffers() canvas.update() # put this in even though __exit__ will call it to make sure we don't # have problems calling it multiple times canvas.close() app.quit() app.quit() # make sure it doesn't break if a user does something silly
class SourceInspectCamera(PanZoomCamera): """ """ _state_props = PanZoomCamera._state_props + ('index', ) def __init__(self, image, img_data, sources, poslist, index=0, **kwargs): PanZoomCamera.__init__(self, **kwargs) self.index = index self.image = image self.img_data = img_data self.sources = sources self.poslist = poslist #self.smin = 0.9*np.nanmin(self.img_data) #self.smax = 1.02*np.nanmax(self.img_data) pcts = np.nanpercentile(self.img_data, [5.0, 99.0]) if np.all(np.isfinite(pcts)): self.smin = pcts[0] self.smax = pcts[1] self.accelerator = 5.0 self.nsrc = len(poslist) self._keymap = { keys.UP: +1, keys.DOWN: -1, keys.LEFT: -1, keys.RIGHT: +1, keys.SPACE: +1 } self._timer = Timer(0.2, start=False, connect=self.on_timer) @property def keymap(self): """ """ return self._keymap def update_index(self, val): self.index += val if (self.index > self.nsrc-1): self.index = 0 if (self.index < 0): self.index = self.nsrc - 1 def update_pan(self): newX = self.poslist[self.index][0] newY = self.poslist[self.index][1] curX = self.rect.left + self.rect.width/2.0 curY = self.rect.bottom + self.rect.height/2.0 self.pan((newX-curX,newY-curY)) # update image data imsect = self.img_data[int(self.rect.bottom):int(self.rect.top), int(self.rect.left):int(self.rect.right)] pcts = np.nanpercentile(imsect, [5.0, 99.0]) if np.all(np.isfinite(pcts)): self.smin = pcts[0] #cmin = -0.01 + 1.2*self.sources['background'][self.sources.index==self.index].values[0] if (is_pacs): self.smax = 1.2*self.sources['susflux']\ [self.sources.index==self.index].values[0]/1000.0/10.0 + self.smin else: self.smax = 1.2*self.sources['fluxtml']\ [self.sources.index==self.index].values[0]/1000.0/0.95 + self.smin self.update_scale() def update_scale(self): self.image.set_data(bytescale(self.img_data, cmin=self.smin, cmax=self.smax)) self.view_changed() def on_timer(self, event): """Timer event handler Parameters ---------- event : instance of Event The event. """ self.update_index(1) self.update_pan() self.view_changed() def viewbox_key_event(self, event): """ViewBox key event handler Parameters ---------- event : instance of Event The event. """ PanZoomCamera.viewbox_key_event(self, event) if event.handled or not self.interactive: return if event.type == 'key_press': if event.key in self._keymap: val = self._keymap[event.key] self.update_index(val) self.update_pan() self.view_changed() elif event.key == 'M': self._timer.start() elif event.key == 'S': self._timer.stop() #elif event.key == 'X': # ind = np.argsort(self.poslist[:,0]) # self.poslist = self.poslist[ind] #elif event.key == 'Y': # ind = np.argsort(self.poslist[:,1]) # self.poslist = self.poslist[ind] elif event.key == 'L': print(self.sources[self.sources.sourceid==self.sources['sourceid'][self.index]]) elif event.key == 'T': sdiff = self.accelerator*(self.smax - self.smin)/255.0 self.smax += sdiff self.smin += sdiff self.update_scale() elif event.key == 'B': sdiff = self.accelerator*(self.smax - self.smin)/255.0 self.smax -= sdiff self.smin -= sdiff self.update_scale() elif event.key == 'N': sdiff = self.accelerator*(self.smax - self.smin)/255.0 self.smax -= sdiff self.smin += sdiff self.update_scale() elif event.key == 'W': sdiff = self.accelerator*(self.smax - self.smin)/255.0 self.smax += sdiff self.smin -= sdiff self.update_scale() elif event.key == 'U': print("Current stretch limits: %10.4g, %10.4g"%(self.smin, self.smax)) self.smin = float(input("New lower value?")) self.smax = float(input("New upper value?")) self.update_scale()
class MainWindow(BaseQtView): def __init__( self, title: str = "", volume_widget: Optional[QWidget] = None, slice_widget: Optional[QWidget] = None, side_controls: Optional[QWidget] = None, ): self.title = title self.volume_widget = volume_widget if volume_widget else QWidget() self.slice_widget = slice_widget if slice_widget else QWidget() self.side_widget = side_controls if side_controls else QWidget() self._init() def _init(self): print("Building...") self.win = QMainWindow() self._default_window_title = self.title widget = QWidget() self.win.setCentralWidget(widget) main_layout = QHBoxLayout() widget.setLayout(main_layout) main_layout.addWidget(self.slice_widget) main_layout.addWidget(self.volume_widget) main_layout.addWidget(self.side_widget) self.title_reset_timer = Timer( interval=2, connect=lambda e: self._show_default_window_title(), iterations=1, start=False) self._show_default_window_title() self.statusbar = self.win.statusBar() self.image_coord_label = QLabel(text="Image Coords") self.statusbar.addPermanentWidget(self.image_coord_label) self.win.show() @property def qt_widget(self) -> QWidget: return self.win def on_image_coordinate_highlighted(self, image_coords, atlas_coords): i, j = image_coords x, y, z = atlas_coords self.image_coord_label.setText( f"(i={i}, j={j}) (x={x:.1f}, y={y:.1f}, z={z:.1f})") def on_error_raised(self, msg: str): self.show_temp_title(msg) # View Code def _show_default_window_title(self): self.win.setWindowTitle(self._default_window_title) def show_temp_title(self, title: str) -> None: self.win.setWindowTitle(title) self.title_reset_timer.stop() self.title_reset_timer.start(iterations=1)
scene.add_to_subplot(brain_obj, row=0, col=0, rotate='left', use_this_cam=True) # Finally, add the colorbar : colorbar = ColorbarObj(source_object, cblabel='Projection of niEEG data', **CBAR_STATE) scene.add_to_subplot(colorbar, row=0, col=1, width_max=200, rotate='up') # Animation app_timer = Timer(app=CONFIG['VISPY_APP'], interval='auto', iterations=-1) def on_timer(*args, **kwargs): if hasattr(brain_obj, 'camera'): brain_obj.camera.azimuth += 1 t = app_timer.elapsed frame = int(np.floor(t * sampling_frequency)) new_data = data[:, frame % data.shape[1]].ravel() source_object._data = vispy_array(new_data) source_object.update() source_object.project_sources(brain_obj) source_object.color_sources() app_timer.connect(on_timer) app_timer.start() scene.preview()
class VisbrainObject(_VisbrainObj): """Base class inherited by all of the Visbrain objects. Parameters ---------- name : string Object name. parent : VisPy.parent | None Markers object parent. transform : VisPy.visuals.transforms | None VisPy transformation to set to the parent node. verbose : string Verbosity level. """ def __init__(self, name, parent=None, transform=None, verbose=None, **kw): """Init.""" _VisbrainObj.__init__(self, **kw) self._node = vispy.scene.Node(name=name) self._node.parent = parent self._csize = None # canvas size self._shortcuts = {} # Name : assert isinstance(name, str) self._name = name # Transformation : if transform is None: transform = vist.STTransform() self._node.transform = transform # Verbose : set_log_level(verbose) logger.info('%s created' % repr(self)) def __repr__(self): """Represent ClassName(name='object_name').""" return type(self).__name__ + "(name='" + self._name + "')" def __str__(self): """Return the object name.""" return self._name def _get_parent(self, bgcolor, axis, show, obj=None, **kwargs): """Get the object parent for preview and screenshot.""" if hasattr(obj, '_get_camera'): camera = obj._get_camera() else: camera = self._get_camera() canvas = VisbrainCanvas(axis=axis, show=show, name=self._name, bgcolor=color2vb(bgcolor), camera=camera, shortcuts=self._shortcuts, **kwargs) self._csize = canvas.canvas.size self.set_shortcuts_to_canvas(canvas) if not hasattr(self._node.parent, 'name'): self._node.parent = canvas.wc.scene return canvas def preview(self, bgcolor='black', axis=False, xyz=False, show=True, obj=None, size=(1200, 800), mpl=False, **kwargs): """Previsualize the result. Parameters ---------- bgcolor : array_like/string/tuple | 'black' Background color for the preview. axis : bool | False Add x and y axis with ticks. xyz : bool | False Add an (x, y, z) axis to the scene. obj : VisbrainObj | None Pass a Visbrain object if you want to use the camera of an other object. size : tuple | (1200, 800) Default size of the window. mpl : bool | False Use Matplotlib to display the object. This result in a non interactive figure. kwargs : dict | {} Optional arguments are passed to the VisbrainCanvas class. """ if CONFIG['MPL_RENDER'] or mpl: canvas = self._get_parent(bgcolor, False, False, obj, **kwargs) mpl_preview(canvas.canvas, widget=canvas.canvas.central_widget) else: parent_bck = self._node.parent kwargs['cargs'] = {'size': size} canvas = self._get_parent(bgcolor, axis, show, obj, **kwargs) if xyz: vispy.scene.visuals.XYZAxis(parent=canvas.wc.scene) # view.camera = camera if (sys.flags.interactive != 1) and show: CONFIG['VISPY_APP'].run() # Reset orignial parent : self._node.parent = parent_bck def describe_tree(self): """Tree description.""" return self._node.describe_tree() def animate(self, step=1., interval='auto', iterations=-1): """Animate the object. Note that this method can only be used with 3D objects. Parameters ---------- step : float | 1. Rotation step. interval : float | 'auto' Time between events in seconds. The default is ‘auto’, which attempts to find the interval that matches the refresh rate of the current monitor. Currently this is simply 1/60. iterations : int | -1 Number of iterations. Can be -1 for infinite. """ from vispy.app import Timer def on_timer(*args, **kwargs): # noqa if hasattr(self, 'camera'): self.camera.azimuth += step # noqa kw = dict(connect=on_timer, app=CONFIG['VISPY_APP'], interval=interval, iterations=iterations) self._app_timer = Timer(**kw) self._app_timer.start() def record_animation(self, name, n_pic=10, bgcolor=None): """Record an animated object and save as a *.gif file. Note that this method : * Can only be used with 3D objects. * Requires the python package imageio Parameters ---------- name : string Name of the gif file (e.g 'myfile.gif') n_pic : int | 10 Number of pictures to use to render the gif. bgcolor : string, tuple, list | None Background color. """ import imageio writer = imageio.get_writer(name) canvas = self._get_parent(bgcolor, False, False) for k in range(n_pic): im = canvas.canvas.render() writer.append_data(im) self.camera.azimuth += 360. / n_pic writer.close() def render(self): """Render the canvas. Returns ------- img : array_like Array of shape (n_rows, n_columns, 4) where 4 describes the RGBA components. """ canvas = self._get_parent(None, False, False) return canvas.canvas.render() def screenshot(self, saveas, print_size=None, dpi=300., unit='centimeter', factor=None, region=None, autocrop=False, bgcolor=None, transparent=False, obj=None, line_width=1., **kwargs): """Take a screeshot of the scene. By default, the rendered canvas will have the size of your screen. The screenshot() method provides two ways to increase to exported image resolution : * Using print_size, unit and dpi inputs : specify the size of the image at a specific dpi level. For example, you might want to have an (10cm, 15cm) image at 300 dpi. * Using the factor input : multiply the default image size by this factor. For example, if you have a (1920, 1080) monitor and if factor is 2, the exported image should have a shape of (3840, 2160) pixels. Parameters ---------- saveas : str The name of the file to be saved. This file must contains a extension like .png, .tiff, .jpg... print_size : tuple | None The desired print size. This argument should be used in association with the dpi and unit inputs. print_size describe should be a tuple of two floats describing (width, height) of the exported image for a specific dpi level. The final image might not have the exact desired size but will try instead to find a compromize regarding to the proportion of width/height of the original image. dpi : float | 300. Dots per inch for printing the image. unit : {'centimeter', 'millimeter', 'pixel', 'inch'} Unit of the printed size. factor : float | None If you don't want to use the print_size input, factor simply multiply the resolution of your screen. region : tuple | None Select a specific region. Must be a tuple of four integers each one describing (x_start, y_start, width, height). autocrop : bool | False Automaticaly crop the figure in order to have the smallest space between the brain and the border of the picture. bgcolor : array_like/string | None The background color of the image. transparent : bool | False Specify if the exported figure have to contains a transparent background. obj : VisbrainObj | None Pass a Visbrain object if you want to use the camera of an other object for the sceen rendering. kwargs : dict | {} Optional arguments are passed to the VisbrainCanvas class. """ kw = dict(print_size=print_size, dpi=dpi, factor=factor, autocrop=autocrop, unit=unit, region=region, bgcolor=bgcolor, transparent=transparent) canvas = self._get_parent(bgcolor, False, False, obj, **kwargs) write_fig_canvas(saveas, canvas.canvas, widget=canvas.canvas.central_widget, **kw) self._node.parent = None def copy(self): """Get a copy of the object.""" from copy import copy return copy(self) # ----------- PARENT ----------- @property def parent(self): """Get the parent value.""" p_isnn = self._node.parent is not None return self._node.parent if p_isnn else self._node @parent.setter def parent(self, value): """Set parent value.""" self._node.parent = value # ----------- TRANSFORM ----------- @property def transform(self): """Get the transform value.""" return self._node.transform @transform.setter def transform(self, value): """Set transform value.""" self._node.transform = value # ----------- NAME ----------- @property def name(self): """Get the name value.""" return self._name # ----------- VISIBLE_OBJ ----------- @property def visible_obj(self): """Get the visible_obj value.""" return self._node.visible @visible_obj.setter def visible_obj(self, value): """Set visible_obj value.""" assert isinstance(value, bool) self._node.visible = value