Source code for iblviewer.launcher

import argparse
import numpy as np
from iblviewer.qt_application import ViewerApp
from iblviewer.application import Viewer
got_ibllib = True
try:
    from iblviewer.mouse_brain import MouseBrainViewer
except ModuleNotFoundError:
    got_ibllib = False


"""
Project: IBL Viewer

Description: this is a fast and interactive 3D viewer for exploring
and analysing volumes, surfaces, points and lines.
It's based on Python, VTK and partly on vedo (a VTK wrapper).

In the context of the International Brain Laboratory, this viewer is
used by neuroscientists to perform analysis of data models in the
context of the Allen Mouse CCF v3 atlas. 

Copyright: 2021 Nicolas Antille, International Brain Laboratory
License: MIT
"""
# From stackoverflow
[docs]def str2bool(v): if isinstance(v, bool): return v elif v.lower() in ('yes', 'true', 't', 'y', '1'): return True elif v.lower() in ('no', 'false', 'f', 'n', '0'): return False else: raise argparse.ArgumentTypeError('Boolean value expected.')
[docs]class IBLViewer(): def __init__(self): self.viewer = None self.qt_app = None self.args = None
[docs] def parse_args(self, parser=None): """ Standard argument parser for iblviewer. Make sure you do not use the below argument shortcuts: -s, -t, -ui, -r, -m, -d, -atlas, -dwi, -cm, -nc, -na :param parser: An existing ArgumentParser that will be updated with standard arguments. If None, a new one is created (default). :return: ArgumentParser """ if parser is None: parser = argparse.ArgumentParser(description='International Brain Viewer based on VTK') parser.add_argument('-neuro', dest='neuroscience', type=str2bool, default=True, help='Whether the viewer starts in Neuroscience mode with Mouse Brain volume preset (1) or as generic 3D viewer (0)') parser.add_argument('-t', dest='test_data', type=str2bool, default=False, help='Whether a simple random set of points is added as test data') parser.add_argument('-ui', dest='ui', type=int, default=1, help='User interface. 0 for none, 1 for Qt, 2 for embed') # More command-line options are given in the context of neuroscience parser.add_argument('-r', dest='resolution', type=int, default=50, help='Volume resolution. Possible values: 100, 50, 25, and 10. Units are in microns.\ The 10um volume takes a lot of RAM (and some time to load)') parser.add_argument('-m', dest='mapping', type=str, default='Allen', help='Volume mapping name. Either Allen (default value) or Beryl (IBL specific simplified mapping).') parser.add_argument('-d', dest='dark_mode', type=str2bool, default=True, help='Enable (1) or disable (0) dark mode.') parser.add_argument('-atlas', dest='add_atlas', type=str2bool, default=True, help='If the Allen Atlas volume should be added to the viewer') parser.add_argument('-dwi', dest='add_dwi', type=str2bool, default=False, help='If the Allen Atlas raw DWI volume should be added to the viewer') parser.add_argument('-cm', dest='color_map', type=str, default='viridis', help='Color map for custom data mapped on to the Allen atlas volume') parser.add_argument('-nc', dest='nan_color', type=float, default=0.65, help='Gray color (between 0 and 1) for regions that have no assigned value') parser.add_argument('-na', dest='nan_alpha', type=float, default=0.5, help='Alpha (opacity) value for regions that have no assigned value') args = parser.parse_args() self.args = args return args
[docs] def launch(self, callable=None, stats_callable=None, args=None, jupyter=False, neuroscience=True, **kwargs): """ Start the 3D viewer according to parameters given in the console :param callable: Function that will be called when the 3D viewer is initialized :param stats_callable: Function that will be called when statistics are updated, when a selection or sub selection changes in the 3D viewer. Available when you use the Qt UI only. :param args: Any existing ArgumentParser. If None, a new IBL standard one is created. :param jupyter: Whether you launch the viewer within a jupyter notebook or lab :param neuroscience: Whether the viewer in jupyter is started in neuroscience mode or not :param kwargs: All further keyword arguments set to viewer.initialize() method (for jupyter mode) :return: Either a qt_application.ViewerApp (if Qt) or a viewer instance (mouse_brain.MouseBrainViewer or application.) """ ibllib_msg = 'The viewer is set to start in neuroscience mode but you do not have ibllib ' ibllib_msg += 'optional module installed.\n\nPlease run pip install ibllib and run the viewer ' ibllib_msg += 'again if you want to start in neuroscience mode.\n\n' ibllib_msg += 'Alternatively, you may use the viewer in standard mode with random points for test: iblviewer -neuro 0 -t 1\n' if jupyter: if neuroscience and not got_ibllib: print(ibllib_msg) exit() if neuroscience: # This a computational neuroscience environment, in this case focused # on the Allen Brain Atlas and International Brain Laboratory data models self.viewer = MouseBrainViewer() else: # This is a generic 3D viewer, not related to neuroscience self.viewer = Viewer() self.viewer.initialize(**kwargs) return self.viewer.show() if args is None: args = self.args if args is None: args = self.parse_args() self.args = args if args.neuroscience and not got_ibllib: print(ibllib_msg) exit() # Fallback plan ? #args.neuroscience = False if args.neuroscience: # This a computational neuroscience environment, in this case focused # on the Allen Brain Atlas and International Brain Laboratory data models self.viewer = MouseBrainViewer() else: # This is a generic 3D viewer, not related to neuroscience self.viewer = Viewer() qt_mode = args.ui == 1 if qt_mode: self.qt_app = ViewerApp() if args.neuroscience: # viewer.initialize(...) method will be called internally with the expanded args self.qt_app.initialize(viewer=self.viewer, callable=callable, stats_callable=stats_callable, embed_ui=args.ui==2, offscreen=False, dark_mode=args.dark_mode, resolution=args.resolution, mapping=args.mapping, add_dwi=args.add_dwi, add_atlas=args.add_atlas) else: new_function = callable if args.test_data: # Test data points = np.random.random((500, 3)) * 1000 def new_function(viewer): if callable is not None: callable(viewer) viewer.add_spheres(points, radius=10) # viewer.initialize(...) method will be called internally with the expanded args self.qt_app.initialize(viewer=self.viewer, callable=new_function, stats_callable=stats_callable, embed_ui=args.ui==2, offscreen=False, dark_mode=args.dark_mode) return self.qt_app # Any code below here is only executed once you quit the Qt application else: if args.neuroscience: self.viewer.initialize(resolution=args.resolution, mapping=args.mapping, add_dwi=args.add_dwi, add_atlas=args.add_atlas, embed_ui=args.ui==2, offscreen=False, jupyter=jupyter, dark_mode=args.dark_mode) else: self.viewer.initialize(embed_ui=args.ui==2, offscreen=qt_mode, jupyter=jupyter) if args.test_data: # Test data points = np.random.random((500, 3)) * 1000 self.viewer.add_points(points, radius=10) if callable is not None: callable(self.viewer) self.viewer.show() return self.viewer
[docs]def main(auto_close_viewer=True): app = IBLViewer() app.launch() if auto_close_viewer: app.viewer.close() return app
if __name__ == '__main__': app = main()