def main(self, options, args): """ Main routine for running the reference viewer. `options` is a OptionParser object that has been populated with values from parsing the command line. It should at least include the options from add_default_options() `args` is a list of arguments to the viewer after parsing out options. It should contain a list of files or URLs to load. """ # Create a logger logger = log.get_logger(name='ginga', options=options) # Get settings (preferences) basedir = paths.ginga_home if not os.path.exists(basedir): try: os.mkdir(basedir) except OSError as e: logger.warning("Couldn't create ginga settings area (%s): %s" % (basedir, str(e))) logger.warning("Preferences will not be able to be saved") # Set up preferences prefs = Settings.Preferences(basefolder=basedir, logger=logger) settings = prefs.create_category('general') settings.set_defaults(useMatplotlibColormaps=False, widgetSet='choose', WCSpkg='choose', FITSpkg='choose', recursion_limit=2000, icc_working_profile=None, font_scaling_factor=None, save_layout=True, channel_prefix="Image") settings.load(onError='silent') # default of 1000 is a little too small sys.setrecursionlimit(settings.get('recursion_limit')) # So we can find our plugins sys.path.insert(0, basedir) package_home = os.path.split(sys.modules['ginga.version'].__file__)[0] child_dir = os.path.join(package_home, 'rv', 'plugins') sys.path.insert(0, child_dir) plugin_dir = os.path.join(basedir, 'plugins') sys.path.insert(0, plugin_dir) gc = os.path.join(basedir, "ginga_config.py") have_ginga_config = os.path.exists(gc) # User configuration, earliest possible intervention if have_ginga_config: try: import ginga_config if hasattr(ginga_config, 'init_config'): ginga_config.init_config(self) except Exception as e: try: (type, value, tb) = sys.exc_info() tb_str = "\n".join(traceback.format_tb(tb)) except Exception: tb_str = "Traceback information unavailable." logger.error("Error processing Ginga config file: %s" % (str(e))) logger.error("Traceback:\n%s" % (tb_str)) # Choose a toolkit if options.toolkit: toolkit = options.toolkit else: toolkit = settings.get('widgetSet', 'choose') if toolkit == 'choose': try: ginga_toolkit.choose() except ImportError as e: print("UI toolkit choose error: %s" % str(e)) sys.exit(1) else: ginga_toolkit.use(toolkit) tkname = ginga_toolkit.get_family() logger.info("Chosen toolkit (%s) family is '%s'" % (ginga_toolkit.toolkit, tkname)) # these imports have to be here, otherwise they force the choice # of toolkit too early from ginga.rv.Control import GingaShell, GuiLogHandler if settings.get('useMatplotlibColormaps', False): # Add matplotlib color maps if matplotlib is installed try: from ginga import cmap cmap.add_matplotlib_cmaps(fail_on_import_error=False) except Exception as e: logger.warning("failed to load matplotlib colormaps: %s" % (str(e))) # Set a working RGB ICC profile if user has one working_profile = settings.get('icc_working_profile', None) rgb_cms.working_profile = working_profile # User wants to customize the WCS package? if options.wcspkg: wcspkg = options.wcspkg else: wcspkg = settings.get('WCSpkg', 'choose') try: from ginga.util import wcsmod if wcspkg != 'choose': assert wcsmod.use(wcspkg) is True except Exception as e: logger.warning("failed to set WCS package preference: %s" % (str(e))) # User wants to customize the FITS package? if options.fitspkg: fitspkg = options.fitspkg else: fitspkg = settings.get('FITSpkg', 'choose') try: from ginga.util import io_fits, loader if fitspkg != 'choose': assert io_fits.use(fitspkg) is True # opener name is not necessarily the same opener = loader.get_opener(io_fits.fitsLoaderClass.name) # set this opener as the priority one opener.priority = -99 except Exception as e: logger.warning("failed to set FITS package preference: %s" % (str(e))) # Check whether user wants to use OpenCv use_opencv = settings.get('use_opencv', False) if use_opencv or options.opencv: from ginga import trcalc try: trcalc.use('opencv') except Exception as e: logger.warning("failed to set OpenCv preference: %s" % (str(e))) # Check whether user wants to use OpenCL use_opencl = settings.get('use_opencl', False) if use_opencl or options.opencl: from ginga import trcalc try: trcalc.use('opencl') except Exception as e: logger.warning("failed to set OpenCL preference: %s" % (str(e))) # Create the dynamic module manager mm = ModuleManager.ModuleManager(logger) # Create and start thread pool ev_quit = threading.Event() thread_pool = Task.ThreadPool(options.numthreads, logger, ev_quit=ev_quit) thread_pool.startall() # Create the Ginga main object ginga_shell = GingaShell(logger, thread_pool, mm, prefs, ev_quit=ev_quit) # user wants to set font scaling. # NOTE: this happens *after* creation of shell object, since # Application object constructor will also set this font_scaling = settings.get('font_scaling_factor', None) if font_scaling is not None: logger.debug( "overriding font_scaling_factor to {}".format(font_scaling)) from ginga.fonts import font_asst font_asst.default_scaling_factor = font_scaling layout_file = None if not options.norestore and settings.get('save_layout', False): layout_file = os.path.join(basedir, 'layout') ginga_shell.set_layout(self.layout, layout_file=layout_file) # User configuration (custom star catalogs, etc.) if have_ginga_config: try: if hasattr(ginga_config, 'pre_gui_config'): ginga_config.pre_gui_config(ginga_shell) except Exception as e: try: (type, value, tb) = sys.exc_info() tb_str = "\n".join(traceback.format_tb(tb)) except Exception: tb_str = "Traceback information unavailable." logger.error("Error importing Ginga config file: %s" % (str(e))) logger.error("Traceback:\n%s" % (tb_str)) # Build desired layout ginga_shell.build_toplevel() # Did user specify a particular geometry? if options.geometry: ginga_shell.set_geometry(options.geometry) # make the list of disabled plugins if options.disable_plugins is not None: disabled_plugins = options.disable_plugins.lower().split(',') else: disabled_plugins = settings.get('disable_plugins', []) if not isinstance(disabled_plugins, list): disabled_plugins = disabled_plugins.lower().split(',') # Add GUI log handler (for "Log" global plugin) guiHdlr = GuiLogHandler(ginga_shell) guiHdlr.setLevel(options.loglevel) fmt = logging.Formatter(log.LOG_FORMAT) guiHdlr.setFormatter(fmt) logger.addHandler(guiHdlr) # Load any custom modules if options.modules is not None: modules = options.modules.split(',') else: modules = settings.get('global_plugins', []) if not isinstance(modules, list): modules = modules.split(',') for long_plugin_name in modules: if '.' in long_plugin_name: tmpstr = long_plugin_name.split('.') plugin_name = tmpstr[-1] pfx = '.'.join(tmpstr[:-1]) else: plugin_name = long_plugin_name pfx = None menu_name = "%s [G]" % (plugin_name) spec = Bunch(name=plugin_name, module=plugin_name, ptype='global', tab=plugin_name, menu=menu_name, category="Custom", workspace='right', pfx=pfx) self.add_plugin_spec(spec) # Load any custom local plugins if options.plugins is not None: plugins = options.plugins.split(',') else: plugins = settings.get('local_plugins', []) if not isinstance(plugins, list): plugins = plugins.split(',') for long_plugin_name in plugins: if '.' in long_plugin_name: tmpstr = long_plugin_name.split('.') plugin_name = tmpstr[-1] pfx = '.'.join(tmpstr[:-1]) else: plugin_name = long_plugin_name pfx = None spec = Bunch(module=plugin_name, workspace='dialogs', ptype='local', category="Custom", hidden=False, pfx=pfx) self.add_plugin_spec(spec) # Add non-disabled plugins enabled_plugins = [ spec for spec in self.plugins if spec.module.lower() not in disabled_plugins ] ginga_shell.set_plugins(enabled_plugins) # start any plugins that have start=True ginga_shell.boot_plugins() ginga_shell.update_pending() # TEMP? tab_names = [ name.lower() for name in ginga_shell.ds.get_tabnames(group=None) ] if 'info' in tab_names: ginga_shell.ds.raise_tab('Info') if 'synopsis' in tab_names: ginga_shell.ds.raise_tab('Synopsis') if 'thumbs' in tab_names: ginga_shell.ds.raise_tab('Thumbs') # Add custom channels if options.channels is not None: channels = options.channels.split(',') else: channels = settings.get('channels', self.channels) if not isinstance(channels, list): channels = channels.split(',') if len(channels) == 0: # should provide at least one default channel? channels = [settings.get('channel_prefix', "Image")] # populate the initial channel lineup for item in channels: if isinstance(item, str): chname, wsname = item, None else: chname, wsname = item ginga_shell.add_channel(chname, workspace=wsname) ginga_shell.change_channel(chname) # User configuration (custom star catalogs, etc.) if have_ginga_config: try: if hasattr(ginga_config, 'post_gui_config'): ginga_config.post_gui_config(ginga_shell) except Exception as e: try: (type, value, tb) = sys.exc_info() tb_str = "\n".join(traceback.format_tb(tb)) except Exception: tb_str = "Traceback information unavailable." logger.error("Error processing Ginga config file: %s" % (str(e))) logger.error("Traceback:\n%s" % (tb_str)) # Redirect warnings to logger for hdlr in logger.handlers: logging.getLogger('py.warnings').addHandler(hdlr) # Display banner the first time run, unless suppressed show_banner = True try: show_banner = settings.get('showBanner') except KeyError: # disable for subsequent runs settings.set(showBanner=False) if not os.path.exists(settings.preffile): settings.save() if (not options.nosplash) and (len(args) == 0) and show_banner: ginga_shell.banner(raiseTab=True) # Handle inputs like "*.fits[ext]" that sys cmd cannot auto expand. expanded_args = [] for imgfile in args: if '*' in imgfile: if '[' in imgfile and imgfile.endswith(']'): s = imgfile.split('[') ext = '[' + s[1] imgfile = s[0] else: ext = '' for fname in glob.iglob(imgfile): expanded_args.append(fname + ext) else: expanded_args.append(imgfile) # Assume remaining arguments are fits files and load them. if not options.separate_channels: chname = channels[0] ginga_shell.gui_do(ginga_shell.open_uris, expanded_args, chname=chname) else: i = 0 num_channels = len(channels) for imgfile in expanded_args: if i < num_channels: chname = channels[i] i = i + 1 else: channel = ginga_shell.add_channel_auto() chname = channel.name ginga_shell.gui_do(ginga_shell.open_uris, [imgfile], chname=chname) try: try: # if there is a network component, start it if hasattr(ginga_shell, 'start'): logger.info("starting network interface...") task = Task.FuncTask2(ginga_shell.start) thread_pool.addTask(task) # Main loop to handle GUI events logger.info("entering mainloop...") ginga_shell.mainloop(timeout=0.001) except KeyboardInterrupt: logger.error("Received keyboard interrupt!") finally: logger.info("Shutting down...") ev_quit.set() sys.exit(0)
def __init__(self, exam=None, close_on_del=True, logger=None, port=None): """initialize a general ginga viewer object. Notes ----- Ginga viewers all need a logger, if none is provided it will create one The port option is for use in the Jupyter notebook since the server displays the image to a distict port. The user can choose to have multiple windows open at the same time as long as they have different ports. If no port is specified, this class will choose an open port. """ global _matplotlib_cmaps_added self._port = port self.exam = exam self._close_on_del = close_on_del # dictionary where each key is a frame number, and the values are a # dictionary of details about the image loaded in that frame self._viewer = dict() self._current_frame = 1 self._current_slice = None # ginga view object, created in subclass self.ginga_view = None # set up possible color maps self._define_cmaps() # for synchronizing on keystrokes self._rlock = threading.RLock() # this creates a thread lock self._keyvals = list() self._capturing = False # ginga objects need a logger, create a null one if we are not # handed one in the constructor self._log_level = 40 if logger is None: logger = log.get_logger(level=self._log_level, log_stderr=True) self.logger = logger # Establish settings (preferences) for ginga viewers basedir = paths.ginga_home self.prefs = Settings.Preferences( basefolder=basedir, logger=self.logger) # general preferences shared with other ginga viewers self.settings = self.prefs.createCategory('general') self.settings.load(onError='silent') self.settings.setDefaults(useMatplotlibColormaps=False, autocuts='on', autocut_method='zscale') # add matplotlib colormaps to ginga's own set if user has this # preference set if self.settings.get('useMatplotlibColormaps', False) and \ (not _matplotlib_cmaps_added): # Add matplotlib color maps if matplotlib is installed try: cmap.add_matplotlib_cmaps() _matplotlib_cmaps_added = True except Exception as e: print( "Failed to load matplotlib colormaps: {0}".format( str(e))) # bindings preferences shared with other ginga viewers bind_prefs = self.prefs.createCategory('bindings') bind_prefs.load(onError='silent') # viewer preferences unique to imexam ginga viewers viewer_prefs = self.prefs.createCategory('imexam') viewer_prefs.load(onError='silent') # create the viewer specific to this backend self._create_viewer(bind_prefs, viewer_prefs) # TODO: at some point, it might be better to simply add a custom # mode called "imexam"--that is a more robust way to do things # but we'd have to register the imexam key bindings in a different way # bm = self.ginga_view.get_bindmap() # bm.add_mode('i', 'imexam', mode_type='locked', # msg="Entering imexam mode...") # modifiers_set = bindmap.get_modifiers() # bm.map_event('imexam', modifiers_set, trigger, evname) # enable all interactive ginga features bindings = self.ginga_view.get_bindings() bindings.enable_all(True) # Add a callback to take us into imexam mode top_canvas = self.ginga_view.get_canvas() top_canvas.add_callback('key-press', self._key_press_normal) # Add a callback to our private canvas to take us out of imexam mode self.canvas.enable_draw(False) self.canvas.add_callback('key-press', self._key_press_imexam) self.canvas.set_surface(self.ginga_view) self.canvas.ui_setActive(True)
if len(macos_ver) > 0: # change this to "pass" if you want to force a different backend # On Mac OS X I found the default choice for matplotlib is not stable # with ginga matplotlib.use('Qt4Agg') import matplotlib.pyplot as plt import matplotlib.patches as patches import numpy as np from ginga.mplw.ImageViewCanvasMpl import ImageViewCanvas from ginga.misc import log from ginga.AstroImage import AstroImage from ginga import cmap # add matplotlib colormaps to ginga's own set cmap.add_matplotlib_cmaps() # Set to True to get diagnostic logging output use_logger = False logger = log.get_logger(null=not use_logger, log_stderr=True) # create a regular matplotlib figure fig = plt.figure() # create a ginga object, initialize some defaults and # tell it about the figure fi = ImageViewCanvas(logger) fi.enable_autocuts('on') fi.set_autocut_params('zscale') #fi.set_cmap(cmap.get_cmap('rainbow3')) fi.set_figure(fig)
def __init__(self, logger): super(FitsViewer, self).__init__() self.logger = logger menubar = self.menuBar() # create a File pulldown menu, and add it to the menu bar filemenu = menubar.addMenu("File") item = QtGui.QAction("Open File", menubar) item.triggered.connect(self.open_file) filemenu.addAction(item) sep = QtGui.QAction(menubar) sep.setSeparator(True) filemenu.addAction(sep) item = QtGui.QAction("Quit", menubar) item.triggered.connect(self.close) filemenu.addAction(item) # Add matplotlib color maps to our built in ones cmap.add_matplotlib_cmaps() self.cmaps = cmap.get_names() self.imaps = imap.get_names() wd, ht = 500, 500 # Create a Ginga widget fi = ImageViewCanvas(logger, render='widget') fi.enable_autocuts('on') fi.set_autocut_params('zscale') fi.enable_autozoom('on') fi.enable_draw(False) fi.set_callback('drag-drop', self.drop_file) fi.set_callback('none-move', self.motion) fi.set_bg(0.2, 0.2, 0.2) fi.ui_setActive(True) self.fitsimage = fi # enable various key and mouse controlled actions bd = fi.get_bindings() bd.enable_all(True) self.cp_tag = 'compass' # pack widget into layout gingaw = fi.get_widget() gingaw.resize(wd, ht) vbox1 = QtGui.QWidget() layout = QtGui.QVBoxLayout() layout.addWidget(gingaw, stretch=1) self.cm = cmap.get_cmap('gray') self.im = imap.get_imap('ramp') # add color bar rgbmap = fi.get_rgbmap() rgbmap.set_hash_size(256) cbar = ColorBar.ColorBar(self.logger, rgbmap=rgbmap, link=True) cbar.resize(-1, 15) #cbar.show() self.colorbar = cbar layout.addWidget(cbar, stretch=0) settings = fi.get_settings() settings.getSetting('cuts').add_callback('set', self.change_range_cb, fi, self.colorbar) # color map selection widget wcmap = QtGui.QComboBox() for name in self.cmaps: wcmap.addItem(name) index = self.cmaps.index('gray') wcmap.setCurrentIndex(index) wcmap.activated.connect(self.set_cmap_cb) self.wcmap = wcmap # intensity map selection widget wimap = QtGui.QComboBox() for name in self.imaps: wimap.addItem(name) index = self.imaps.index('ramp') wimap.setCurrentIndex(index) wimap.activated.connect(self.set_cmap_cb) self.wimap = wimap #wopen = QtGui.QPushButton("Open File") #wopen.clicked.connect(self.open_file) # add buttons to layout hbox = QtGui.QHBoxLayout() hbox.setContentsMargins(QtCore.QMargins(4, 2, 4, 2)) hbox.addStretch(1) for w in (wcmap, wimap): hbox.addWidget(w, stretch=0) hw = QtGui.QWidget() hw.setLayout(hbox) layout.addWidget(hw, stretch=0) vbox1.setLayout(layout) # Create a matplotlib Figure #self.fig = matplotlib.figure.Figure(figsize=(wd, ht)) self.fig = matplotlib.figure.Figure() self.canvas = FigureCanvas(self.fig) vbox2 = QtGui.QWidget() layout = QtGui.QVBoxLayout() # scrw = QtGui.QScrollArea() # scrw.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded) # scrw.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded) # scrw.setWidgetResizable(True) # layout.addWidget(scrw, stretch=1) # scrw.setWidget(self.canvas) layout.addWidget(self.canvas, stretch=1) # Add matplotlib buttons hbox = QtGui.QHBoxLayout() hbox.setContentsMargins(QtCore.QMargins(4, 2, 4, 2)) wgetimg = QtGui.QPushButton("Get Data") wgetimg.clicked.connect(self.get_image) wgetrgb = QtGui.QPushButton("Get RGB") wgetrgb.clicked.connect(self.get_rgb_image) #wquit = QtGui.QPushButton("Quit") #wquit.clicked.connect(self.close) hbox.addStretch(1) for w in (wgetimg, wgetrgb): hbox.addWidget(w, stretch=0) hw = QtGui.QWidget() hw.setLayout(hbox) layout.addWidget(hw, stretch=0) vbox2.setLayout(layout) vbox = QtGui.QVBoxLayout() vbox.setContentsMargins(QtCore.QMargins(2, 2, 2, 2)) vbox.setSpacing(1) w = QtGui.QWidget() layout = QtGui.QHBoxLayout() layout.addWidget(vbox1, stretch=1.0) layout.addWidget(vbox2, stretch=1.0) w.setLayout(layout) vbox.addWidget(w, stretch=1) self.readout = QtGui.QLabel("") vbox.addWidget(self.readout, stretch=0, alignment=QtCore.Qt.AlignCenter) vw = QtGui.QWidget() vw.setLayout(vbox) self.setCentralWidget(vw)
def main(self, options, args): """ Main routine for running the reference viewer. `options` is a OptionParser object that has been populated with values from parsing the command line. It should at least include the options from add_default_options() `args` is a list of arguments to the viewer after parsing out options. It should contain a list of files or URLs to load. """ # Create a logger logger = log.get_logger(name='ginga', options=options) # Get settings (preferences) basedir = paths.ginga_home if not os.path.exists(basedir): try: os.mkdir(basedir) except OSError as e: logger.warn("Couldn't create ginga settings area (%s): %s" % (basedir, str(e))) logger.warn("Preferences will not be able to be saved") # Set up preferences prefs = Settings.Preferences(basefolder=basedir, logger=logger) settings = prefs.createCategory('general') settings.load(onError='silent') settings.setDefaults(useMatplotlibColormaps=False, widgetSet='choose', WCSpkg='choose', FITSpkg='choose', recursion_limit=2000) # default of 1000 is a little too small sys.setrecursionlimit(settings.get('recursion_limit')) # So we can find our plugins sys.path.insert(0, basedir) moduleHome = os.path.split(sys.modules['ginga.version'].__file__)[0] childDir = os.path.join(moduleHome, 'misc', 'plugins') sys.path.insert(0, childDir) pluginDir = os.path.join(basedir, 'plugins') sys.path.insert(0, pluginDir) # Choose a toolkit if options.toolkit: toolkit = options.toolkit else: toolkit = settings.get('widgetSet', 'choose') if toolkit == 'choose': try: from ginga.qtw import QtHelp except ImportError: try: from ginga.gtkw import GtkHelp except ImportError: print("You need python-gtk or python-qt to run Ginga!") sys.exit(1) else: ginga_toolkit.use(toolkit) tkname = ginga_toolkit.get_family() logger.info("Chosen toolkit (%s) family is '%s'" % (ginga_toolkit.toolkit, tkname)) # these imports have to be here, otherwise they force the choice # of toolkit too early from ginga.gw.GingaGw import GingaView from ginga.Control import GingaControl, GuiLogHandler # Define class dynamically based on toolkit choice class GingaShell(GingaControl, GingaView): def __init__(self, logger, thread_pool, module_manager, prefs, ev_quit=None): GingaView.__init__(self, logger, ev_quit, thread_pool) GingaControl.__init__(self, logger, thread_pool, module_manager, prefs, ev_quit=ev_quit) if settings.get('useMatplotlibColormaps', False): # Add matplotlib color maps if matplotlib is installed try: from ginga import cmap cmap.add_matplotlib_cmaps() except Exception as e: logger.warn("failed to load matplotlib colormaps: %s" % (str(e))) # User wants to customize the WCS package? if options.wcspkg: wcspkg = options.wcspkg else: wcspkg = settings.get('WCSpkg', 'choose') try: from ginga.util import wcsmod assert wcsmod.use(wcspkg) == True except Exception as e: logger.warn("failed to set WCS package preference: %s" % (str(e))) # User wants to customize the FITS package? if options.fitspkg: fitspkg = options.fitspkg else: fitspkg = settings.get('FITSpkg', 'choose') try: from ginga.util import io_fits assert io_fits.use(fitspkg) == True except Exception as e: logger.warn("failed to set FITS package preference: %s" % (str(e))) # Check whether user wants to use OpenCv use_opencv = settings.get('use_opencv', False) if use_opencv or options.opencv: from ginga import trcalc try: trcalc.use('opencv') except Exception as e: logger.warn("failed to set OpenCv preference: %s" % (str(e))) # Create the dynamic module manager mm = ModuleManager.ModuleManager(logger) # Create and start thread pool ev_quit = threading.Event() thread_pool = Task.ThreadPool(options.numthreads, logger, ev_quit=ev_quit) thread_pool.startall() # Create the Ginga main object ginga_shell = GingaShell(logger, thread_pool, mm, prefs, ev_quit=ev_quit) ginga_shell.set_layout(self.layout) gc = os.path.join(basedir, "ginga_config.py") have_ginga_config = os.path.exists(gc) # User configuration (custom star catalogs, etc.) if have_ginga_config: try: import ginga_config ginga_config.pre_gui_config(ginga_shell) except Exception as e: try: (type, value, tb) = sys.exc_info() tb_str = "\n".join(traceback.format_tb(tb)) except Exception: tb_str = "Traceback information unavailable." logger.error("Error importing Ginga config file: %s" % (str(e))) logger.error("Traceback:\n%s" % (tb_str)) # Build desired layout ginga_shell.build_toplevel() # Did user specify a particular geometry? if options.geometry: ginga_shell.set_geometry(options.geometry) # make the list of disabled plugins disabled_plugins = [] if not (options.disable_plugins is None): disabled_plugins = options.disable_plugins.lower().split(',') # Add desired global plugins for spec in self.global_plugins: if not spec.module.lower() in disabled_plugins: ginga_shell.add_global_plugin(spec) # Add GUI log handler (for "Log" global plugin) guiHdlr = GuiLogHandler(ginga_shell) guiHdlr.setLevel(options.loglevel) fmt = logging.Formatter(log.LOG_FORMAT) guiHdlr.setFormatter(fmt) logger.addHandler(guiHdlr) # Load any custom modules if options.modules: modules = options.modules.split(',') for longPluginName in modules: if '.' in longPluginName: tmpstr = longPluginName.split('.') pluginName = tmpstr[-1] pfx = '.'.join(tmpstr[:-1]) else: pluginName = longPluginName pfx = None spec = Bunch(name=pluginName, module=pluginName, tab=pluginName, ws='right', pfx=pfx) ginga_shell.add_global_plugin(spec) # Load modules for "local" (per-channel) plug ins for spec in self.local_plugins: if not spec.module.lower() in disabled_plugins: ginga_shell.add_local_plugin(spec) # Load any custom plugins if options.plugins: plugins = options.plugins.split(',') for longPluginName in plugins: if '.' in longPluginName: tmpstr = longPluginName.split('.') pluginName = tmpstr[-1] pfx = '.'.join(tmpstr[:-1]) else: pluginName = longPluginName pfx = None spec = Bunch(module=pluginName, ws='dialogs', hidden=False, pfx=pfx) ginga_shell.add_local_plugin(spec) ginga_shell.update_pending() # TEMP? tab_names = list( map(lambda name: name.lower(), ginga_shell.ds.get_tabnames(group=None))) if 'info' in tab_names: ginga_shell.ds.raise_tab('Info') if 'thumbs' in tab_names: ginga_shell.ds.raise_tab('Thumbs') # Add custom channels channels = options.channels.split(',') for chname in channels: ginga_shell.add_channel(chname) ginga_shell.change_channel(channels[0]) # User configuration (custom star catalogs, etc.) if have_ginga_config: try: ginga_config.post_gui_config(ginga_shell) except Exception as e: try: (type, value, tb) = sys.exc_info() tb_str = "\n".join(traceback.format_tb(tb)) except Exception: tb_str = "Traceback information unavailable." logger.error("Error processing Ginga config file: %s" % (str(e))) logger.error("Traceback:\n%s" % (tb_str)) # Redirect warnings to logger for hdlr in logger.handlers: logging.getLogger('py.warnings').addHandler(hdlr) # Display banner the first time run, unless suppressed showBanner = True try: showBanner = settings.get('showBanner') except KeyError: # disable for subsequent runs settings.set(showBanner=False) settings.save() if (not options.nosplash) and (len(args) == 0) and showBanner: ginga_shell.banner(raiseTab=True) # Assume remaining arguments are fits files and load them. for imgfile in args: ginga_shell.nongui_do(ginga_shell.load_file, imgfile) try: try: # if there is a network component, start it if hasattr(ginga_shell, 'start'): task = Task.FuncTask2(ginga_shell.start) thread_pool.addTask(task) # Main loop to handle GUI events logger.info("Entering mainloop...") ginga_shell.mainloop(timeout=0.001) except KeyboardInterrupt: logger.error("Received keyboard interrupt!") finally: logger.info("Shutting down...") ev_quit.set() sys.exit(0)
def __init__(self, logger): super(FitsViewer, self).__init__() self.logger = logger menubar = self.menuBar() # create a File pulldown menu, and add it to the menu bar filemenu = menubar.addMenu("File") item = QtGui.QAction("Open File", menubar) item.triggered.connect(self.open_file) filemenu.addAction(item) sep = QtGui.QAction(menubar) sep.setSeparator(True) filemenu.addAction(sep) item = QtGui.QAction("Quit", menubar) item.triggered.connect(self.close) filemenu.addAction(item) # Add matplotlib color maps to our built in ones cmap.add_matplotlib_cmaps() self.cmaps = cmap.get_names() self.imaps = imap.get_names() wd, ht = 500, 500 # Create a Ginga widget fi = ImageViewCanvas(logger, render='widget') fi.enable_autocuts('on') fi.set_autocut_params('zscale') fi.enable_autozoom('on') fi.enable_draw(False) fi.set_callback('drag-drop', self.drop_file_cb) fi.set_callback('cursor-changed', self.cursor_cb) fi.set_bg(0.2, 0.2, 0.2) fi.ui_set_active(True) self.fitsimage = fi fi.show_color_bar(True) # enable various key and mouse controlled actions bd = fi.get_bindings() bd.enable_all(True) self.cp_tag = 'compass' # pack widget into layout gingaw = fi.get_widget() gingaw.resize(wd, ht) vbox1 = QtGui.QWidget() layout = QtGui.QVBoxLayout() layout.addWidget(gingaw, stretch=1) self.cm = cmap.get_cmap('gray') self.im = imap.get_imap('ramp') # color map selection widget wcmap = QtGui.QComboBox() for name in self.cmaps: wcmap.addItem(name) index = self.cmaps.index('gray') wcmap.setCurrentIndex(index) wcmap.activated.connect(self.set_cmap_cb) self.wcmap = wcmap # intensity map selection widget wimap = QtGui.QComboBox() for name in self.imaps: wimap.addItem(name) index = self.imaps.index('ramp') wimap.setCurrentIndex(index) wimap.activated.connect(self.set_cmap_cb) self.wimap = wimap #wopen = QtGui.QPushButton("Open File") #wopen.clicked.connect(self.open_file) # add buttons to layout hbox = QtGui.QHBoxLayout() hbox.setContentsMargins(QtCore.QMargins(4, 2, 4, 2)) hbox.addStretch(1) for w in (wcmap, wimap): hbox.addWidget(w, stretch=0) hw = QtGui.QWidget() hw.setLayout(hbox) layout.addWidget(hw, stretch=0) vbox1.setLayout(layout) # Create a matplotlib Figure #self.fig = matplotlib.figure.Figure(figsize=(wd, ht)) self.fig = matplotlib.figure.Figure() self.canvas = FigureCanvas(self.fig) vbox2 = QtGui.QWidget() layout = QtGui.QVBoxLayout() layout.addWidget(self.canvas, stretch=1) # Add matplotlib buttons hbox = QtGui.QHBoxLayout() hbox.setContentsMargins(QtCore.QMargins(4, 2, 4, 2)) wgetimg = QtGui.QPushButton("Get Data") wgetimg.clicked.connect(self.get_image) wgetrgb = QtGui.QPushButton("Get RGB") wgetrgb.clicked.connect(self.get_rgb_image) #wquit = QtGui.QPushButton("Quit") #wquit.clicked.connect(self.close) hbox.addStretch(1) for w in (wgetimg, wgetrgb): hbox.addWidget(w, stretch=0) hw = QtGui.QWidget() hw.setLayout(hbox) layout.addWidget(hw, stretch=0) vbox2.setLayout(layout) vbox = QtGui.QVBoxLayout() vbox.setContentsMargins(QtCore.QMargins(2, 2, 2, 2)) vbox.setSpacing(1) w = QtGui.QWidget() layout = QtGui.QHBoxLayout() layout.addWidget(vbox1, stretch=1.0) layout.addWidget(vbox2, stretch=1.0) w.setLayout(layout) vbox.addWidget(w, stretch=1) self.readout = QtGui.QLabel("") vbox.addWidget(self.readout, stretch=0, alignment=QtCore.Qt.AlignCenter) vw = QtGui.QWidget() vw.setLayout(vbox) self.setCentralWidget(vw)
def main(options, args): # default of 1000 is a little too small sys.setrecursionlimit(2000) # Create a logger logger = log.get_logger(name='ginga', options=options) # Get settings (preferences) basedir = paths.ginga_home if not os.path.exists(basedir): try: os.mkdir(basedir) except OSError as e: logger.warn("Couldn't create ginga settings area (%s): %s" % (basedir, str(e))) logger.warn("Preferences will not be able to be saved") # Set up preferences prefs = Settings.Preferences(basefolder=basedir, logger=logger) settings = prefs.createCategory('general') settings.load(onError='silent') settings.setDefaults(useMatplotlibColormaps=False, widgetSet='choose', WCSpkg='choose', FITSpkg='choose') # So we can find our plugins sys.path.insert(0, basedir) moduleHome = os.path.split(sys.modules['ginga.version'].__file__)[0] childDir = os.path.join(moduleHome, 'misc', 'plugins') sys.path.insert(0, childDir) pluginDir = os.path.join(basedir, 'plugins') sys.path.insert(0, pluginDir) # Choose a toolkit if options.toolkit: toolkit = options.toolkit else: toolkit = settings.get('widgetSet', 'choose') ginga_toolkit.use(toolkit) tkname = ginga_toolkit.get_family() if tkname == 'gtk': from ginga.gtkw.GingaGtk import GingaView elif tkname == 'qt': from ginga.qtw.GingaQt import GingaView else: try: from ginga.qtw.GingaQt import GingaView except ImportError: try: from ginga.gtkw.GingaGtk import GingaView except ImportError: print("You need python-gtk or python-qt4 to run Ginga!") sys.exit(1) # Define class dynamically based on toolkit choice class Ginga(GingaControl, GingaView): def __init__(self, logger, threadPool, module_manager, prefs, ev_quit=None): GingaView.__init__(self, logger, ev_quit) GingaControl.__init__(self, logger, threadPool, module_manager, prefs, ev_quit=ev_quit) if settings.get('useMatplotlibColormaps', False): # Add matplotlib color maps if matplotlib is installed try: from ginga import cmap cmap.add_matplotlib_cmaps() except Exception as e: logger.warn("failed to load matplotlib colormaps: %s" % (str(e))) # User wants to customize the WCS package? if options.wcs: wcspkg = options.wcs else: wcspkg = settings.get('WCSpkg', 'choose') try: from ginga.util import wcsmod assert wcsmod.use(wcspkg) == True except Exception as e: logger.warn("failed to set WCS package preference: %s" % (str(e))) # User wants to customize the FITS package? if options.fits: fitspkg = options.fits else: fitspkg = settings.get('FITSpkg', 'choose') try: from ginga.util import io_fits assert io_fits.use(fitspkg) == True except Exception as e: logger.warn("failed to set FITS package preference: %s" % (str(e))) # Create the dynamic module manager mm = ModuleManager.ModuleManager(logger) # Create and start thread pool ev_quit = threading.Event() threadPool = Task.ThreadPool(options.numthreads, logger, ev_quit=ev_quit) threadPool.startall() # Create the Ginga main object ginga = Ginga(logger, threadPool, mm, prefs, ev_quit=ev_quit) ginga.set_layout(default_layout) # User configuration (custom star catalogs, etc.) try: import ginga_config ginga_config.pre_gui_config(ginga) except Exception as e: try: (type, value, tb) = sys.exc_info() tb_str = "\n".join(traceback.format_tb(tb)) except Exception: tb_str = "Traceback information unavailable." logger.error("Error importing Ginga config file: %s" % (str(e))) logger.error("Traceback:\n%s" % (tb_str)) # Build desired layout ginga.build_toplevel() # Did user specify a particular geometry? if options.geometry: ginga.setGeometry(options.geometry) # Add desired global plugins for spec in global_plugins: ginga.add_global_plugin(spec) # Add GUI log handler (for "Log" global plugin) guiHdlr = GuiLogHandler(ginga) guiHdlr.setLevel(options.loglevel) fmt = logging.Formatter(log.LOG_FORMAT) guiHdlr.setFormatter(fmt) logger.addHandler(guiHdlr) # Load any custom modules if options.modules: modules = options.modules.split(',') for pluginName in modules: spec = Bunch(name=pluginName, module=pluginName, tab=pluginName, ws='right') ginga.add_global_plugin(spec) # Load modules for "local" (per-channel) plug ins for spec in local_plugins: ginga.add_local_plugin(spec) # Load any custom plugins if options.plugins: plugins = options.plugins.split(',') for pluginName in plugins: spec = Bunch(module=pluginName, ws='dialogs', hidden=False) ginga.add_local_plugin(spec) ginga.update_pending() # TEMP? ginga.ds.raise_tab('Info') ginga.ds.raise_tab('Thumbs') # Add custom channels channels = options.channels.split(',') for chname in channels: datasrc = Datasrc.Datasrc(length=options.bufsize) ginga.add_channel(chname, datasrc) ginga.change_channel(channels[0]) # User configuration (custom star catalogs, etc.) try: ginga_config.post_gui_config(ginga) except Exception as e: try: (type, value, tb) = sys.exc_info() tb_str = "\n".join(traceback.format_tb(tb)) except Exception: tb_str = "Traceback information unavailable." logger.error("Error processing Ginga config file: %s" % (str(e))) logger.error("Traceback:\n%s" % (tb_str)) # Display banner the first time run, unless suppressed showBanner = True try: showBanner = settings.get('showBanner') except KeyError: # disable for subsequent runs settings.set(showBanner=False) settings.save() if (not options.nosplash) and (len(args) == 0) and showBanner: ginga.banner() # Assume remaining arguments are fits files and load them. for imgfile in args: ginga.nongui_do(ginga.load_file, imgfile) try: try: # Main loop to handle GUI events logger.info("Entering mainloop...") ginga.mainloop(timeout=0.001) except KeyboardInterrupt: logger.error("Received keyboard interrupt!") finally: logger.info("Shutting down...") ev_quit.set() sys.exit(0)
def main(self, options, args): """ Main routine for running the reference viewer. `options` is a OptionParser object that has been populated with values from parsing the command line. It should at least include the options from add_default_options() `args` is a list of arguments to the viewer after parsing out options. It should contain a list of files or URLs to load. """ # Create a logger logger = log.get_logger(name='ginga', options=options) # Get settings (preferences) basedir = paths.ginga_home if not os.path.exists(basedir): try: os.mkdir(basedir) except OSError as e: logger.warning( "Couldn't create ginga settings area (%s): %s" % ( basedir, str(e))) logger.warning("Preferences will not be able to be saved") # Set up preferences prefs = Settings.Preferences(basefolder=basedir, logger=logger) settings = prefs.create_category('general') settings.set_defaults(useMatplotlibColormaps=False, widgetSet='choose', WCSpkg='choose', FITSpkg='choose', recursion_limit=2000, icc_working_profile=None, font_scaling_factor=None, save_layout=True, channel_prefix="Image") settings.load(onError='silent') # default of 1000 is a little too small sys.setrecursionlimit(settings.get('recursion_limit')) # So we can find our plugins sys.path.insert(0, basedir) package_home = os.path.split(sys.modules['ginga.version'].__file__)[0] child_dir = os.path.join(package_home, 'rv', 'plugins') sys.path.insert(0, child_dir) plugin_dir = os.path.join(basedir, 'plugins') sys.path.insert(0, plugin_dir) gc = os.path.join(basedir, "ginga_config.py") have_ginga_config = os.path.exists(gc) # User configuration, earliest possible intervention if have_ginga_config: try: import ginga_config if hasattr(ginga_config, 'init_config'): ginga_config.init_config(self) except Exception as e: try: (type, value, tb) = sys.exc_info() tb_str = "\n".join(traceback.format_tb(tb)) except Exception: tb_str = "Traceback information unavailable." logger.error("Error processing Ginga config file: %s" % ( str(e))) logger.error("Traceback:\n%s" % (tb_str)) # Choose a toolkit if options.toolkit: toolkit = options.toolkit else: toolkit = settings.get('widgetSet', 'choose') if toolkit == 'choose': try: ginga_toolkit.choose() except ImportError as e: print("UI toolkit choose error: %s" % str(e)) sys.exit(1) else: ginga_toolkit.use(toolkit) tkname = ginga_toolkit.get_family() logger.info("Chosen toolkit (%s) family is '%s'" % ( ginga_toolkit.toolkit, tkname)) # these imports have to be here, otherwise they force the choice # of toolkit too early from ginga.rv.Control import GingaShell, GuiLogHandler if settings.get('useMatplotlibColormaps', False): # Add matplotlib color maps if matplotlib is installed try: from ginga import cmap cmap.add_matplotlib_cmaps(fail_on_import_error=False) except Exception as e: logger.warning( "failed to load matplotlib colormaps: %s" % (str(e))) # user wants to set font scaling font_scaling = settings.get('font_scaling_factor', None) if font_scaling is not None: from ginga.fonts import font_asst font_asst.default_scaling_factor = font_scaling # Set a working RGB ICC profile if user has one working_profile = settings.get('icc_working_profile', None) rgb_cms.working_profile = working_profile # User wants to customize the WCS package? if options.wcspkg: wcspkg = options.wcspkg else: wcspkg = settings.get('WCSpkg', 'choose') try: from ginga.util import wcsmod if wcspkg != 'choose': assert wcsmod.use(wcspkg) is True except Exception as e: logger.warning( "failed to set WCS package preference: %s" % (str(e))) # User wants to customize the FITS package? if options.fitspkg: fitspkg = options.fitspkg else: fitspkg = settings.get('FITSpkg', 'choose') try: from ginga.util import io_fits if fitspkg != 'choose': assert io_fits.use(fitspkg) is True except Exception as e: logger.warning( "failed to set FITS package preference: %s" % (str(e))) # Check whether user wants to use OpenCv use_opencv = settings.get('use_opencv', False) if use_opencv or options.opencv: from ginga import trcalc try: trcalc.use('opencv') except Exception as e: logger.warning( "failed to set OpenCv preference: %s" % (str(e))) # Check whether user wants to use OpenCL use_opencl = settings.get('use_opencl', False) if use_opencl or options.opencl: from ginga import trcalc try: trcalc.use('opencl') except Exception as e: logger.warning( "failed to set OpenCL preference: %s" % (str(e))) # Create the dynamic module manager mm = ModuleManager.ModuleManager(logger) # Create and start thread pool ev_quit = threading.Event() thread_pool = Task.ThreadPool(options.numthreads, logger, ev_quit=ev_quit) thread_pool.startall() # Create the Ginga main object ginga_shell = GingaShell(logger, thread_pool, mm, prefs, ev_quit=ev_quit) layout_file = None if not options.norestore and settings.get('save_layout', False): layout_file = os.path.join(basedir, 'layout') ginga_shell.set_layout(self.layout, layout_file=layout_file) # User configuration (custom star catalogs, etc.) if have_ginga_config: try: if hasattr(ginga_config, 'pre_gui_config'): ginga_config.pre_gui_config(ginga_shell) except Exception as e: try: (type, value, tb) = sys.exc_info() tb_str = "\n".join(traceback.format_tb(tb)) except Exception: tb_str = "Traceback information unavailable." logger.error("Error importing Ginga config file: %s" % ( str(e))) logger.error("Traceback:\n%s" % (tb_str)) # Build desired layout ginga_shell.build_toplevel() # Did user specify a particular geometry? if options.geometry: ginga_shell.set_geometry(options.geometry) # make the list of disabled plugins if options.disable_plugins is not None: disabled_plugins = options.disable_plugins.lower().split(',') else: disabled_plugins = settings.get('disable_plugins', []) if not isinstance(disabled_plugins, list): disabled_plugins = disabled_plugins.lower().split(',') # Add GUI log handler (for "Log" global plugin) guiHdlr = GuiLogHandler(ginga_shell) guiHdlr.setLevel(options.loglevel) fmt = logging.Formatter(log.LOG_FORMAT) guiHdlr.setFormatter(fmt) logger.addHandler(guiHdlr) # Load any custom modules if options.modules is not None: modules = options.modules.split(',') else: modules = settings.get('global_plugins', []) if not isinstance(modules, list): modules = modules.split(',') for long_plugin_name in modules: if '.' in long_plugin_name: tmpstr = long_plugin_name.split('.') plugin_name = tmpstr[-1] pfx = '.'.join(tmpstr[:-1]) else: plugin_name = long_plugin_name pfx = None menu_name = "%s [G]" % (plugin_name) spec = Bunch(name=plugin_name, module=plugin_name, ptype='global', tab=plugin_name, menu=menu_name, category="Custom", workspace='right', pfx=pfx) self.add_plugin_spec(spec) # Load any custom local plugins if options.plugins is not None: plugins = options.plugins.split(',') else: plugins = settings.get('local_plugins', []) if not isinstance(plugins, list): plugins = plugins.split(',') for long_plugin_name in plugins: if '.' in long_plugin_name: tmpstr = long_plugin_name.split('.') plugin_name = tmpstr[-1] pfx = '.'.join(tmpstr[:-1]) else: plugin_name = long_plugin_name pfx = None spec = Bunch(module=plugin_name, workspace='dialogs', ptype='local', category="Custom", hidden=False, pfx=pfx) self.add_plugin_spec(spec) # Add non-disabled plugins enabled_plugins = [spec for spec in self.plugins if spec.module.lower() not in disabled_plugins] ginga_shell.set_plugins(enabled_plugins) # start any plugins that have start=True ginga_shell.boot_plugins() ginga_shell.update_pending() # TEMP? tab_names = [name.lower() for name in ginga_shell.ds.get_tabnames(group=None)] if 'info' in tab_names: ginga_shell.ds.raise_tab('Info') if 'synopsis' in tab_names: ginga_shell.ds.raise_tab('Synopsis') if 'thumbs' in tab_names: ginga_shell.ds.raise_tab('Thumbs') # Add custom channels if options.channels is not None: channels = options.channels.split(',') else: channels = settings.get('channels', []) if not isinstance(channels, list): channels = channels.split(',') if len(channels) == 0: # should provide at least one default channel? channels = [settings.get('channel_prefix', "Image")] for chname in channels: ginga_shell.add_channel(chname) ginga_shell.change_channel(channels[0]) # User configuration (custom star catalogs, etc.) if have_ginga_config: try: if hasattr(ginga_config, 'post_gui_config'): ginga_config.post_gui_config(ginga_shell) except Exception as e: try: (type, value, tb) = sys.exc_info() tb_str = "\n".join(traceback.format_tb(tb)) except Exception: tb_str = "Traceback information unavailable." logger.error("Error processing Ginga config file: %s" % ( str(e))) logger.error("Traceback:\n%s" % (tb_str)) # Redirect warnings to logger for hdlr in logger.handlers: logging.getLogger('py.warnings').addHandler(hdlr) # Display banner the first time run, unless suppressed showBanner = True try: showBanner = settings.get('showBanner') except KeyError: # disable for subsequent runs settings.set(showBanner=False) if not os.path.exists(settings.preffile): settings.save() if (not options.nosplash) and (len(args) == 0) and showBanner: ginga_shell.banner(raiseTab=True) # Handle inputs like "*.fits[ext]" that sys cmd cannot auto expand. expanded_args = [] for imgfile in args: if '*' in imgfile: if '[' in imgfile and imgfile.endswith(']'): s = imgfile.split('[') ext = '[' + s[1] imgfile = s[0] else: ext = '' for fname in glob.iglob(imgfile): expanded_args.append(fname + ext) else: expanded_args.append(imgfile) # Assume remaining arguments are fits files and load them. if not options.separate_channels: chname = channels[0] ginga_shell.gui_do(ginga_shell.open_uris, expanded_args, chname=chname) else: i = 0 num_channels = len(channels) for imgfile in expanded_args: if i < num_channels: chname = channels[i] i = i + 1 else: channel = ginga_shell.add_channel_auto() chname = channel.name ginga_shell.gui_do(ginga_shell.open_uris, [imgfile], chname=chname) try: try: # if there is a network component, start it if hasattr(ginga_shell, 'start'): task = Task.FuncTask2(ginga_shell.start) thread_pool.addTask(task) # Main loop to handle GUI events logger.info("Entering mainloop...") ginga_shell.mainloop(timeout=0.001) except KeyboardInterrupt: logger.error("Received keyboard interrupt!") finally: logger.info("Shutting down...") ev_quit.set() sys.exit(0)
import os import glob import time import math import numpy from astropy.io import fits from ginga.misc.plugins.Command import Command, CommandInterpreter from ginga import AstroImage, cmap from ginga.gw import Plot from ginga.util import iqcalc, plots, wcs, dp from ginga.misc import Bunch, Task # add any matplotlib colormaps we have lying around cmap.add_matplotlib_cmaps(fail_on_import_error=False) from naoj.spcam.spcam_dr import SuprimeCamDR from naoj.hsc.hsc_dr import HyperSuprimeCamDR, hsc_ccd_data # add "Jon Tonley" color map from naoj.cmap import jt cmap.add_cmap("jt", jt.cmap_jt) class GView(Command): def __init__(self, fv): # superclass defines some variables for us, like logger super(GView, self).__init__(fv)
import matplotlib.pyplot as plt import matplotlib.patches as patches import numpy as np from ginga.mplw.ImageViewCanvasMpl import ImageViewCanvas from ginga.misc import log from ginga.AstroImage import AstroImage from ginga import cmap # add matplotlib colormaps to ginga's own set cmap.add_matplotlib_cmaps() ## from IPython.display import Image ## from io import BytesIO class CustomMplViewer(ImageViewCanvas): def get_nb_image(self): return Image(data=bytes(self.get_rgb_image_as_bytes(format='png')), format='png', embed=True) def load(self, filepath): image = AstroImage(logger=self.logger) image.load_file(filepath) self.set_image(image) def show(self): self.figure.show() def add_canvas(self, tag=None):
def main(self, options, args): """ Main routine for running the reference viewer. `options` is a OptionParser object that has been populated with values from parsing the command line. It should at least include the options from add_default_options() `args` is a list of arguments to the viewer after parsing out options. It should contain a list of files or URLs to load. """ # Create a logger logger = log.get_logger(name='ginga', options=options) # Get settings (preferences) basedir = paths.ginga_home if not os.path.exists(basedir): try: os.mkdir(basedir) except OSError as e: logger.warn("Couldn't create ginga settings area (%s): %s" % ( basedir, str(e))) logger.warn("Preferences will not be able to be saved") # Set up preferences prefs = Settings.Preferences(basefolder=basedir, logger=logger) settings = prefs.createCategory('general') settings.load(onError='silent') settings.setDefaults(useMatplotlibColormaps=False, widgetSet='choose', WCSpkg='choose', FITSpkg='choose', recursion_limit=2000) # default of 1000 is a little too small sys.setrecursionlimit(settings.get('recursion_limit')) # So we can find our plugins sys.path.insert(0, basedir) moduleHome = os.path.split(sys.modules['ginga.version'].__file__)[0] childDir = os.path.join(moduleHome, 'misc', 'plugins') sys.path.insert(0, childDir) pluginDir = os.path.join(basedir, 'plugins') sys.path.insert(0, pluginDir) # Choose a toolkit if options.toolkit: toolkit = options.toolkit else: toolkit = settings.get('widgetSet', 'choose') ginga_toolkit.use(toolkit) tkname = ginga_toolkit.get_family() logger.info("Chosen toolkit (%s) family is '%s'" % ( ginga_toolkit.toolkit, tkname)) ##from ginga.gw.GingaGw import GingaView if tkname == 'gtk': from ginga.gtkw.GingaGtk import GingaView elif tkname == 'qt': from ginga.qtw.GingaQt import GingaView else: try: from ginga.qtw.GingaQt import GingaView except ImportError: try: from ginga.gtkw.GingaGtk import GingaView except ImportError: print("You need python-gtk or python-qt4 to run Ginga!") sys.exit(1) # these imports have to be here, otherwise they force the choice # of toolkit too early from ginga.Control import GingaControl, GuiLogHandler # Define class dynamically based on toolkit choice class Ginga(GingaControl, GingaView): def __init__(self, logger, thread_pool, module_manager, prefs, ev_quit=None): GingaView.__init__(self, logger, ev_quit) GingaControl.__init__(self, logger, thread_pool, module_manager, prefs, ev_quit=ev_quit) if settings.get('useMatplotlibColormaps', False): # Add matplotlib color maps if matplotlib is installed try: from ginga import cmap cmap.add_matplotlib_cmaps() except Exception as e: logger.warn("failed to load matplotlib colormaps: %s" % (str(e))) # User wants to customize the WCS package? if options.wcspkg: wcspkg = options.wcspkg else: wcspkg = settings.get('WCSpkg', 'choose') try: from ginga.util import wcsmod assert wcsmod.use(wcspkg) == True except Exception as e: logger.warn("failed to set WCS package preference: %s" % (str(e))) # User wants to customize the FITS package? if options.fitspkg: fitspkg = options.fitspkg else: fitspkg = settings.get('FITSpkg', 'choose') try: from ginga.util import io_fits assert io_fits.use(fitspkg) == True except Exception as e: logger.warn("failed to set FITS package preference: %s" % (str(e))) # Check whether user wants to use OpenCv use_opencv = settings.get('use_opencv', False) if use_opencv or options.opencv: from ginga import trcalc try: trcalc.use('opencv') except Exception as e: logger.warn("failed to set OpenCv preference: %s" % (str(e))) # Create the dynamic module manager mm = ModuleManager.ModuleManager(logger) # Create and start thread pool ev_quit = threading.Event() thread_pool = Task.ThreadPool(options.numthreads, logger, ev_quit=ev_quit) thread_pool.startall() # Create the Ginga main object ginga = Ginga(logger, thread_pool, mm, prefs, ev_quit=ev_quit) ginga.set_layout(self.layout) gc = os.path.join(basedir, "ginga_config.py") have_ginga_config = os.path.exists(gc) # User configuration (custom star catalogs, etc.) if have_ginga_config: try: import ginga_config ginga_config.pre_gui_config(ginga) except Exception as e: try: (type, value, tb) = sys.exc_info() tb_str = "\n".join(traceback.format_tb(tb)) except Exception: tb_str = "Traceback information unavailable." logger.error("Error importing Ginga config file: %s" % ( str(e))) logger.error("Traceback:\n%s" % (tb_str)) # Build desired layout ginga.build_toplevel() # Did user specify a particular geometry? if options.geometry: ginga.setGeometry(options.geometry) # make the list of disabled plugins disabled_plugins = [] if not (options.disable_plugins is None): disabled_plugins = options.disable_plugins.lower().split(',') # Add desired global plugins for spec in self.global_plugins: if not spec.module.lower() in disabled_plugins: ginga.add_global_plugin(spec) # Add GUI log handler (for "Log" global plugin) guiHdlr = GuiLogHandler(ginga) guiHdlr.setLevel(options.loglevel) fmt = logging.Formatter(log.LOG_FORMAT) guiHdlr.setFormatter(fmt) logger.addHandler(guiHdlr) # Load any custom modules if options.modules: modules = options.modules.split(',') for longPluginName in modules: if '.' in longPluginName: tmpstr = longPluginName.split('.') pluginName = tmpstr[-1] pfx = '.'.join(tmpstr[:-1]) else: pluginName = longPluginName pfx = None spec = Bunch(name=pluginName, module=pluginName, tab=pluginName, ws='right', pfx=pfx) ginga.add_global_plugin(spec) # Load modules for "local" (per-channel) plug ins for spec in self.local_plugins: if not spec.module.lower() in disabled_plugins: ginga.add_local_plugin(spec) # Load any custom plugins if options.plugins: plugins = options.plugins.split(',') for longPluginName in plugins: if '.' in longPluginName: tmpstr = longPluginName.split('.') pluginName = tmpstr[-1] pfx = '.'.join(tmpstr[:-1]) else: pluginName = longPluginName pfx = None spec = Bunch(module=pluginName, ws='dialogs', hidden=False, pfx=pfx) ginga.add_local_plugin(spec) ginga.update_pending() # TEMP? tab_names = list(map(lambda name: name.lower(), ginga.ds.get_tabnames(group=None))) if 'info' in tab_names: ginga.ds.raise_tab('Info') if 'thumbs' in tab_names: ginga.ds.raise_tab('Thumbs') # User configuration (custom star catalogs, etc.) if have_ginga_config: try: ginga_config.post_gui_config(ginga) except Exception as e: try: (type, value, tb) = sys.exc_info() tb_str = "\n".join(traceback.format_tb(tb)) except Exception: tb_str = "Traceback information unavailable." logger.error("Error processing Ginga config file: %s" % ( str(e))) logger.error("Traceback:\n%s" % (tb_str)) # Add custom channels channels = options.channels.split(',') for chname in channels: datasrc = Datasrc.Datasrc(length=options.bufsize) ginga.add_channel(chname, datasrc) ginga.change_channel(channels[0]) # Display banner the first time run, unless suppressed showBanner = True try: showBanner = settings.get('showBanner') except KeyError: # disable for subsequent runs settings.set(showBanner=False) settings.save() if (not options.nosplash) and (len(args) == 0) and showBanner: ginga.banner() # Assume remaining arguments are fits files and load them. for imgfile in args: ginga.nongui_do(ginga.load_file, imgfile) try: try: # if there is a network component, start it if hasattr(ginga, 'start'): task = Task.FuncTask2(ginga.start) thread_pool.addTask(task) # Main loop to handle GUI events logger.info("Entering mainloop...") ginga.mainloop(timeout=0.001) except KeyboardInterrupt: logger.error("Received keyboard interrupt!") finally: logger.info("Shutting down...") ev_quit.set() sys.exit(0)
def __init__(self, exam=None, close_on_del=True, logger=None, port=None): """initialize a general ginga viewer object. Parameters ---------- exam: imexam object This is the imexamine object which contains the examination functions close_on_del: bool If True, the window connection shuts down when the object is deleted logger: logger object Ginga viewers all need a logger, if none is provided it will create one port: int This is used as the communication port for the HTML5 viewer. The user can choose to have multiple windows open at the same time as long as they have different port designations. If no port is specified, this class will choose an open port. """ global _matplotlib_cmaps_added self._port = port self.exam = exam self._close_on_del = close_on_del # dictionary where each key is a frame number, and the values are a # dictionary of details about the image loaded in that frame self._viewer = dict() self._current_frame = 1 self._current_slice = None # ginga view object, created in subclass self.ginga_view = None # set up possible color maps self._define_cmaps() # for synchronizing on keystrokes self._rlock = threading.RLock() # this creates a thread lock self._keyvals = list() self._capturing = False # ginga objects need a logger, create a null one if we are not # handed one in the constructor self._log_level = 40 if logger is None: logger = log.get_logger(level=self._log_level, log_stderr=True) self.logger = logger # Establish settings (preferences) for ginga viewers basedir = paths.ginga_home self.prefs = Settings.Preferences(basefolder=basedir, logger=self.logger) # general preferences shared with other ginga viewers self.settings = self.prefs.createCategory('general') self.settings.load(onError='silent') self.settings.setDefaults(useMatplotlibColormaps=False, autocuts='on', autocut_method='zscale') # add matplotlib colormaps to ginga's own set if user has this # preference set if self.settings.get('useMatplotlibColormaps', False) and \ (not _matplotlib_cmaps_added): # Add matplotlib color maps if matplotlib is installed try: cmap.add_matplotlib_cmaps() _matplotlib_cmaps_added = True except Exception as e: print(f"Failed to load matplotlib colormaps: {repr(e)}") # bindings preferences shared with other ginga viewers bind_prefs = self.prefs.createCategory('bindings') bind_prefs.load(onError='silent') # viewer preferences unique to imexam ginga viewers viewer_prefs = self.prefs.createCategory('imexam') viewer_prefs.load(onError='silent') # create the viewer specific to this backend self._create_viewer(bind_prefs, viewer_prefs) # TODO: at some point, it might be better to simply add a custom # mode called "imexam"--that is a more robust way to do things # but we'd have to register the imexam key bindings in a different way # bm = self.ginga_view.get_bindmap() # bm.add_mode('i', 'imexam', mode_type='locked', # msg="Entering imexam mode...") # modifiers_set = bindmap.get_modifiers() # bm.map_event('imexam', modifiers_set, trigger, evname) # enable all interactive ginga features bindings = self.ginga_view.get_bindings() bindings.enable_all(True) # Add a callback to take us into imexam mode top_canvas = self.ginga_view.get_canvas() top_canvas.add_callback('key-press', self._key_press_normal) # Add a callback to our private canvas to take us out of imexam mode self.canvas.enable_draw(False) self.canvas.add_callback('key-press', self._key_press_imexam) self.canvas.set_surface(self.ginga_view) self.canvas.ui_setActive(True)
def main(options, args): # default of 1000 is a little too small sys.setrecursionlimit(2000) # Create a logger logger = log.get_logger(name='ginga', options=options) # Get settings (preferences) basedir = paths.ginga_home if not os.path.exists(basedir): try: os.mkdir(basedir) except OSError as e: logger.warn("Couldn't create ginga settings area (%s): %s" % ( basedir, str(e))) logger.warn("Preferences will not be able to be saved") # Set up preferences prefs = Settings.Preferences(basefolder=basedir, logger=logger) settings = prefs.createCategory('general') settings.load(onError='silent') settings.setDefaults(useMatplotlibColormaps=False, widgetSet='choose', WCSpkg='choose', FITSpkg='choose') # So we can find our plugins sys.path.insert(0, basedir) moduleHome = os.path.split(sys.modules['ginga.version'].__file__)[0] childDir = os.path.join(moduleHome, 'misc', 'plugins') sys.path.insert(0, childDir) pluginDir = os.path.join(basedir, 'plugins') sys.path.insert(0, pluginDir) # Choose a toolkit if options.toolkit: toolkit = options.toolkit else: toolkit = settings.get('widgetSet', 'choose') ginga_toolkit.use(toolkit) tkname = ginga_toolkit.get_family() if tkname == 'gtk': from ginga.gtkw.GingaGtk import GingaView elif tkname == 'qt': from ginga.qtw.GingaQt import GingaView else: try: from ginga.qtw.GingaQt import GingaView except ImportError: try: from ginga.gtkw.GingaGtk import GingaView except ImportError: print("You need python-gtk or python-qt4 to run Ginga!") sys.exit(1) # Define class dynamically based on toolkit choice class Ginga(GingaControl, GingaView): def __init__(self, logger, threadPool, module_manager, prefs, ev_quit=None): GingaView.__init__(self, logger, ev_quit) GingaControl.__init__(self, logger, threadPool, module_manager, prefs, ev_quit=ev_quit) if settings.get('useMatplotlibColormaps', False): # Add matplotlib color maps if matplotlib is installed try: from ginga import cmap cmap.add_matplotlib_cmaps() except Exception as e: logger.warn("failed to load matplotlib colormaps: %s" % (str(e))) # User wants to customize the WCS package? if options.wcs: wcspkg = options.wcs else: wcspkg = settings.get('WCSpkg', 'choose') try: from ginga.util import wcsmod assert wcsmod.use(wcspkg) == True except Exception as e: logger.warn("failed to set WCS package preference: %s" % (str(e))) # User wants to customize the FITS package? if options.fits: fitspkg = options.fits else: fitspkg = settings.get('FITSpkg', 'choose') try: from ginga.util import io_fits assert io_fits.use(fitspkg) == True except Exception as e: logger.warn("failed to set FITS package preference: %s" % (str(e))) # Create the dynamic module manager mm = ModuleManager.ModuleManager(logger) # Create and start thread pool ev_quit = threading.Event() threadPool = Task.ThreadPool(options.numthreads, logger, ev_quit=ev_quit) threadPool.startall() # Create the Ginga main object ginga = Ginga(logger, threadPool, mm, prefs, ev_quit=ev_quit) ginga.set_layout(default_layout) # User configuration (custom star catalogs, etc.) try: import ginga_config ginga_config.pre_gui_config(ginga) except Exception as e: try: (type, value, tb) = sys.exc_info() tb_str = "\n".join(traceback.format_tb(tb)) except Exception: tb_str = "Traceback information unavailable." logger.error("Error importing Ginga config file: %s" % ( str(e))) logger.error("Traceback:\n%s" % (tb_str)) # Build desired layout ginga.build_toplevel() # Did user specify a particular geometry? if options.geometry: ginga.setGeometry(options.geometry) # Add desired global plugins for spec in global_plugins: ginga.add_global_plugin(spec) # Add GUI log handler (for "Log" global plugin) guiHdlr = GuiLogHandler(ginga) guiHdlr.setLevel(options.loglevel) fmt = logging.Formatter(log.LOG_FORMAT) guiHdlr.setFormatter(fmt) logger.addHandler(guiHdlr) # Load any custom modules if options.modules: modules = options.modules.split(',') for pluginName in modules: spec = Bunch(name=pluginName, module=pluginName, tab=pluginName, ws='right') ginga.add_global_plugin(spec) # Load modules for "local" (per-channel) plug ins for spec in local_plugins: ginga.add_local_plugin(spec) # Load any custom plugins if options.plugins: plugins = options.plugins.split(',') for pluginName in plugins: spec = Bunch(module=pluginName, ws='dialogs', hidden=False) ginga.add_local_plugin(spec) ginga.update_pending() # TEMP? ginga.ds.raise_tab('Info') ginga.ds.raise_tab('Thumbs') # Add custom channels channels = options.channels.split(',') for chname in channels: datasrc = Datasrc.Datasrc(length=options.bufsize) ginga.add_channel(chname, datasrc) ginga.change_channel(channels[0]) # User configuration (custom star catalogs, etc.) try: ginga_config.post_gui_config(ginga) except Exception as e: try: (type, value, tb) = sys.exc_info() tb_str = "\n".join(traceback.format_tb(tb)) except Exception: tb_str = "Traceback information unavailable." logger.error("Error processing Ginga config file: %s" % ( str(e))) logger.error("Traceback:\n%s" % (tb_str)) # Display banner the first time run, unless suppressed showBanner = True try: showBanner = settings.get('showBanner') except KeyError: # disable for subsequent runs settings.set(showBanner=False) settings.save() if (not options.nosplash) and (len(args) == 0) and showBanner: ginga.banner() # Assume remaining arguments are fits files and load them. for imgfile in args: ginga.nongui_do(ginga.load_file, imgfile) try: try: # Main loop to handle GUI events logger.info("Entering mainloop...") ginga.mainloop(timeout=0.001) except KeyboardInterrupt: logger.error("Received keyboard interrupt!") finally: logger.info("Shutting down...") ev_quit.set() sys.exit(0)
def __init__(self, exam=None, close_on_del=True, logger=None): """ Notes ----- Ginga viewers all need a logger, if none is provided it will create one """ global _matplotlib_cmaps_added self.exam = exam self._close_on_del = close_on_del # dictionary where each key is a frame number, and the values are a # dictionary of details about the image loaded in that frame self._viewer = dict() self._current_frame = 1 self._current_slice = None self.ginga_view = None # ginga view object self._define_cmaps() # set up possible color maps # for synchronizing on keystrokes self._cv = threading.RLock() self._kv = [] self._capturing = False # ginga objects need a logger, create a null one if we are not # handed one in the constructor if logger is None: logger = log.get_logger(null=True) self.logger = logger self._saved_logger = logger self._debug_logger = log.get_logger(level=10, log_stderr=True) # Establish settings (preferences) for ginga viewers basedir = paths.ginga_home self.prefs = Settings.Preferences( basefolder=basedir, logger=self.logger) # general preferences shared with other ginga viewers settings = self.prefs.createCategory('general') settings.load(onError='silent') settings.setDefaults(useMatplotlibColormaps=False, autocuts='on', autocut_method='zscale') self.settings = settings # add matplotlib colormaps to ginga's own set if user has this # preference set if settings.get('useMatplotlibColormaps', False) and \ (not _matplotlib_cmaps_added): # Add matplotlib color maps if matplotlib is installed try: cmap.add_matplotlib_cmaps() _matplotlib_cmaps_added = True except Exception as e: print( "Failed to load matplotlib colormaps: {0}".format( str(e))) # bindings preferences shared with other ginga viewers bind_prefs = self.prefs.createCategory('bindings') bind_prefs.load(onError='silent') # viewer preferences unique to imexam ginga viewers viewer_prefs = self.prefs.createCategory('imexam') viewer_prefs.load(onError='silent') # create the viewer specific to this backend self._create_viewer(bind_prefs, viewer_prefs) # enable all interactive ginga features bindings = self.ginga_view.get_bindings() bindings.enable_all(True) self.ginga_view.add_callback('key-press', self._key_press_normal) canvas = self.canvas canvas.enable_draw(False) canvas.add_callback('key-press', self._key_press_imexam) canvas.setSurface(self.ginga_view) canvas.ui_setActive(True) self.canvas = canvas