def callGlobalPlugin2(self, tag, pluginName, methodName, args, kwdargs): self.logger.debug( "Command received: plugin=%s method=%s args=%s kwdargs=%s tag=%s" % (pluginName, methodName, str(args), str(kwdargs), tag)) # Get object associated with plugin if pluginName != 'ANA': raise AnaError("plugin name must be ANA") obj = self # Get method we should call if not hasattr(obj, methodName): raise Gen2Error("No such method '%s' in plugin object %s" % (methodName, pluginName)) method = getattr(obj, methodName) # Make a future that will be resolved by the GUI thread p = Bunch.Bunch() future = Future.Future(data=p) #future.freeze(method, *args, **kwdargs) newargs = [tag, future] newargs.extend(list(args)) future.add_callback( 'resolved', lambda f: self.fv.nongui_do(self.result_cb2, future, tag, p)) future = Future.Future(data=p) future.freeze(method, *newargs, **kwdargs) future.add_callback( 'resolved', lambda f: self.fv.nongui_do(self.result_cb1, future, tag, p)) self.fv.gui_do_future(future) return ro.OK
def add_history(self, imname, path, idx=None, image_loader=None, image_future=None): if not (imname in self.image_index): if image_loader is None: image_loader = self.fv.load_image # create an image_future if one does not exist if (image_future is None) and (path is not None): image_future = Future.Future() image_future.freeze(image_loader, path) info = Bunch.Bunch(name=imname, path=path, idx=idx, image_loader=image_loader, image_future=image_future, time_added=time.time(), time_modified=None, profile=None) self._add_info(info) else: # already in history info = self.image_index[imname] return info
def gui_do(self, method, *args, **kwdargs): future = Future.Future(priority=0) future.freeze(method, *args, **kwdargs) self.gui_queue.put(future) my_id = thread.get_ident() if my_id != self.gui_thread_id: return future
def gui_do(self, method, *args, **kwdargs): """General method for calling into the GUI. """ #gobject.idle_add(method, *args, **kwdargs) future = Future.Future() future.freeze(method, *args, **kwdargs) self.gui_queue.put(future) return future
def add_image_info(self, info): image_loader = info.get('image_loader', self.fv.load_image) # create an image_future if one does not exist image_future = info.get('image_future', None) if (image_future is None) and (info.path is not None): image_future = Future.Future() image_future.freeze(image_loader, info.path) info = self.add_history(info.name, info.path, image_loader=image_loader, image_future=image_future)
def gui_do(self, method, *args, **kwdargs): """General method for asynchronously calling into the GUI. It makes a future to call the given (method) with the given (args) and (kwdargs) inside the gui thread. If the calling thread is a non-gui thread the future is returned. """ future = Future.Future() future.freeze(method, *args, **kwdargs) self.gui_queue.put(future) my_id = thread.get_ident() if my_id != self.gui_thread_id: return future
def gui_do_oneshot(self, catname, method, *args, **kwdargs): if catname not in self.oneshots: deq = self.oneshots.setdefault(catname, deque([], 1)) else: deq = self.oneshots[catname] future = Future.Future() future.freeze(method, *args, **kwdargs) deq.append(future) my_id = thread.get_ident() if my_id != self.gui_thread_id: return future
def set_hdu(self, idx): self.logger.debug("Loading fits hdu #%d" % (idx)) # determine canonical index of this HDU info = self.file_obj.hdu_info[idx] aidx = (info.name, info.extver) if aidx not in self.file_obj.hdu_db: aidx = idx sfx = get_hdu_suffix(aidx) # See if this HDU is still in the channel's datasrc imname = self.name_pfx + sfx chname = self.chname chinfo = self.channel if imname in chinfo.datasrc: self.curhdu = idx image = chinfo.datasrc[imname] self.fv.switch_name(chname, imname) return # Nope, we'll have to load it self.logger.debug("HDU %d not in memory; refreshing from file" % (idx)) try: self.curhdu = idx dims = [0, 0] info = self.file_obj.hdu_info[idx] image = self.file_obj.get_hdu(idx) # create a future for reconstituting this HDU future = Future.Future() future.freeze(self.fv.load_image, self.img_path, idx=aidx) image.set(path=self.img_path, idx=aidx, name=imname, image_future=future) self.fv.add_image(imname, image, chname=chname) self.logger.debug("HDU #%d loaded." % (idx)) except Exception as e: errmsg = "Error loading FITS HDU #%d: %s" % (idx, str(e)) self.logger.error(errmsg) self.fv.show_error(errmsg, raisetab=True)
def _load_idx(image): try: # create a future for reconstituting this HDU future = Future.Future() future.freeze(self.fv.load_image, self.img_path, idx=aidx) image.set(path=self.img_path, idx=aidx, name=imname, image_future=future) self.fv.add_image(imname, image, chname=chname) self.curhdu = idx self.logger.debug("HDU #%d loaded." % (idx)) except Exception as e: errmsg = "Error loading FITS HDU #%d: %s" % (idx, str(e)) self.logger.error(errmsg) self.fv.show_error(errmsg, raisetab=True)
def set_hdu(self, idx): self.logger.debug("Loading fits hdu #%d" % (idx)) # determine canonical index of this HDU info = self.hdu_info[idx] aidx = (info.name, info.extver) sfx = '%s,%d' % aidx # See if this HDU is still in the channel's datasrc imname = self.get_name(sfx) chname = self.chname chinfo = self.chinfo if imname in chinfo.datasrc: self.curhdu = idx self.image = chinfo.datasrc[imname] self.fv.switch_name(chname, imname) # Still need to build datacube profile hdu = self.fits_f[idx] dims = list(hdu.data.shape) dims.reverse() self.build_naxis(dims) return # Nope, we'll have to load it self.logger.debug("HDU %d not in memory; refreshing from file" % (idx)) # inherit from primary header? inherit_prihdr = self.fv.settings.get('inherit_primary_header', False) image = AstroImage.AstroImage(logger=self.logger, inherit_primary_header=inherit_prihdr) self.image = image try: self.curhdu = idx dims = [0, 0] hdu = self.fits_f[idx] if hdu.data is None: # <- empty data part to this HDU self.logger.warning("Empty data part in HDU #%d" % (idx)) elif info['htype'].lower() not in ('imagehdu', 'primaryhdu'): self.logger.warning("HDU #%d is not an image" % (idx)) else: dims = list(hdu.data.shape) dims.reverse() image.load_hdu(hdu, fobj=self.fits_f) # create a future for reconstituting this HDU future = Future.Future() future.freeze(self.fv.load_image, self.path, idx=aidx) image.set(path=self.path, idx=aidx, name=imname, image_future=future) ## self.fitsimage.set_image(image, ## raise_initialize_errors=False) self.fv.add_image(imname, image, chname=chname) self.build_naxis(dims) self.logger.debug("HDU #%d loaded." % (idx)) except Exception as e: errmsg = "Error loading FITS HDU #%d: %s" % (idx, str(e)) self.logger.error(errmsg) self.fv.show_error(errmsg, raisetab=False)
def set_hdu(self, idx): self.logger.debug("Loading fits hdu #%d" % (idx)) # determine canonical index of this HDU info = self.hdu_info[idx] aidx = (info.name, info.extver) if aidx not in self.fits_f: aidx = idx sfx = get_hdu_suffix(aidx) # See if this HDU is still in the channel's datasrc imname = self.name_pfx + sfx chname = self.chname chinfo = self.channel if imname in chinfo.datasrc: self.curhdu = idx self.image = chinfo.datasrc[imname] self.fv.switch_name(chname, imname) # Still need to build datacube profile hdu = self.fits_f[idx] if hdu.data is not None: dims = list(hdu.data.shape) dims.reverse() self.build_naxis(dims) return # Nope, we'll have to load it self.logger.debug("HDU %d not in memory; refreshing from file" % (idx)) try: self.curhdu = idx dims = [0, 0] hdu = self.fits_f[idx] image = self.fv.fits_opener.load_hdu(hdu, fobj=self.fits_f) self.image = image if hdu.data is None: # <- empty data part to this HDU self.logger.warning("Empty data part in HDU #%d" % (idx)) elif info['htype'].lower() in ('bintablehdu', 'tablehdu',): dims = [0, 0] elif info['htype'].lower() not in ('imagehdu', 'primaryhdu'): self.logger.warning("HDU #%d is not an image" % (idx)) else: dims = list(hdu.data.shape) dims.reverse() image.load_hdu(hdu, fobj=self.fits_f) # create a future for reconstituting this HDU future = Future.Future() future.freeze(self.fv.load_image, self.path, idx=aidx) image.set(path=self.path, idx=aidx, name=imname, image_future=future) self.fv.add_image(imname, image, chname=chname) self.build_naxis(dims) self.logger.debug("HDU #%d loaded." % (idx)) except Exception as e: errmsg = "Error loading FITS HDU #%d: %s" % ( idx, str(e)) self.logger.error(errmsg) self.fv.show_error(errmsg, raisetab=False)
def redo(self): """This updates DQ flags from canvas selection.""" self.w.x.set_text(str(self.xcen)) self.w.y.set_text(str(self.ycen)) # Clear previous single-pixel results self.pxdqlist.clear() self.w.dq.set_text(self._no_keyword) image = self.fitsimage.get_image() depth = image.get_depth() if depth == 3: self.logger.error('DQ inspection for RGB image is not supported') return True header = image.get_header() extname = header.get(self._ext_key, self._no_keyword).upper() instrument = header.get(self._ins_key, None) # If displayed extension is not DQ, extract DQ array with same EXTVER if extname != self._dq_extname: imfile = image.metadata['path'] imname = image.metadata['name'].split('[')[0] extver = header.get(self._extver_key, self._dummy_value) dq_extnum = (self._dq_extname, extver) with fits.open(imfile) as pf: dqsrc = dq_extnum in pf # Do not continue if no DQ extension if not dqsrc: self.logger.error('{0} extension not found for {1}'.format( dq_extnum, imfile)) return True chname = self.fv.get_channelName(self.fitsimage) chinfo = self.fv.get_channelInfo(chname) dqname = '{0}[{1},{2}]'.format(imname, self._dq_extname, extver) if dqname in chinfo.datasrc: # DQ already loaded self.logger.debug('Loading {0} from cache'.format(dqname)) dqsrc = chinfo.datasrc[dqname] else: # Force load DQ data self.logger.debug('Loading {0} from {1}'.format( dqname, imfile)) dqsrc = self.fv.load_image(imfile, idx=dq_extnum) future = Future.Future() future.freeze(self.fv.load_image, imfile, idx=dq_extnum) dqsrc.set(path=imfile, idx=dq_extnum, name=dqname, image_future=future) chinfo.datasrc[dqname] = dqsrc self.fv.make_callback('add-image', chname, dqsrc) # Use displayed image else: dqname = image.metadata['name'] dqsrc = image data = dqsrc.get_data() if data.ndim != self._ndim: self.logger.error('Expected ndim={0} but data has ' 'ndim={1}'.format(self._ndim, data.ndim)) return True # Get cached DQ parser first, if available if instrument in self._dqparser: self.logger.debug( 'Using cached DQ parser for {0}'.format(instrument)) dqparser = self._dqparser[instrument] # Create new parser and cache it. # Look in package data first. If not found, assume external data. # If no data file provided, use default. else: self.logger.debug( 'Creating new DQ parser for {0}'.format(instrument)) if instrument in self.dqdict: dqfile = get_pkg_data_filename(self.dqdict[instrument]) if dqfile: self.logger.info('Using package data {0}'.format(dqfile)) elif os.path.isfile(self.dqdict[instrument]): dqfile = self.dqdict[instrument] self.logger.info('Using external data {0}'.format(dqfile)) else: dqfile = _def_tab self.logger.warn( '{0} not found for {1}, using default'.format( self.dqdict[instrument], instrument)) else: dqfile = _def_tab self.logger.warn( '{0} is not supported, using default'.format(instrument)) dqparser = DQParser(dqfile) self._dqparser[instrument] = dqparser # Get cached results first, if available if self._cache_key in dqsrc.metadata: self.logger.debug('Using cached DQ results for {0}'.format(dqname)) pixmask_by_flag = dqsrc.get(self._cache_key) # Interpret DQ flags for all pixels. # Cache {flag: np_index} else: self.logger.debug('Interpreting all DQs for {0}...'.format(dqname)) pixmask_by_flag = dqparser.interpret_array(data) dqsrc.metadata[self._cache_key] = pixmask_by_flag # Parse DQ into individual flag definitions pixval = data[int(self.ycen), int(self.xcen)] dqs = dqparser.interpret_dqval(pixval) self.w.dq.set_text(str(pixval)) for row in dqs: item = QtGui.QListWidgetItem('{0:<5d}\t{1}'.format( row[dqparser._dqcol], row[self.dqstr])) self.pxdqlist.addItem(item) # No need to do the rest if image has not changed if pixmask_by_flag is self._curpxmask: return True # Populate a list of all valid DQ flags for that image. # Only list DQ flags present anywhere in the image. self.imdqlist.clear() self.w.npix.set_text(self._no_keyword) self._curpxmask = pixmask_by_flag self._curshape = data.shape for key in sorted(self._curpxmask): if len(self._curpxmask[key][0]) == 0: continue row = dqparser.tab[dqparser.tab[dqparser._dqcol] == key] item = QtGui.QListWidgetItem('{0:<5d}\t{1}'.format( row[dqparser._dqcol][0], row[self.dqstr][0])) self.imdqlist.addItem(item) return True